aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--Android.bp17641
-rw-r--r--Android.bp.extras74
-rw-r--r--BUILD1487
-rw-r--r--BUILD.extras89
-rw-r--r--BUILD.gn31
-rw-r--r--CHANGELOG332
-rw-r--r--OWNERS35
-rw-r--r--PRESUBMIT.py94
-rw-r--r--TEST_MAPPING5
-rw-r--r--bazel/BUILD12
-rw-r--r--bazel/deps.bzl28
-rw-r--r--bazel/jsoncpp.BUILD1
-rw-r--r--bazel/llvm_demangle.BUILD39
-rw-r--r--bazel/rules.bzl99
-rw-r--r--bazel/sqlite.BUILD1
-rw-r--r--bazel/standalone/perfetto_cfg.bzl28
-rw-r--r--bazel/zlib.BUILD62
-rw-r--r--buildtools/.gitignore11
-rw-r--r--buildtools/BUILD.gn64
-rw-r--r--codereview.settings1
-rw-r--r--debian/control1
-rw-r--r--debian/perfetto.manpages1
-rwxr-xr-xdebian/postinst2
-rwxr-xr-xdebian/postrm2
-rwxr-xr-xdebian/rules2
-rw-r--r--docs/analysis/metrics.md305
-rw-r--r--docs/analysis/trace-processor.md138
-rw-r--r--docs/case-studies/android-boot-tracing.md79
-rw-r--r--docs/concepts/config.md7
-rw-r--r--docs/contributing/build-instructions.md294
-rw-r--r--docs/contributing/common-tasks.md1
-rw-r--r--docs/contributing/embedding.md2
-rw-r--r--docs/contributing/getting-started.md2
-rw-r--r--docs/contributing/sdk-releasing.md49
-rw-r--r--docs/contributing/testing.md33
-rw-r--r--docs/data-sources/atrace.md2
-rw-r--r--docs/data-sources/battery-counters.md12
-rw-r--r--docs/data-sources/cpu-freq.md57
-rw-r--r--docs/data-sources/cpu-scheduling.md42
-rw-r--r--docs/data-sources/frametimeline.md2
-rw-r--r--docs/data-sources/java-heap-profiler.md12
-rw-r--r--docs/data-sources/memory-counters.md4
-rw-r--r--docs/data-sources/native-heap-profiler.md26
-rw-r--r--docs/design-docs/api-and-abi.md2
-rw-r--r--docs/design-docs/checkpoint-atoms.md (renamed from docs/reference/checkpoint-atoms.md)0
-rw-r--r--docs/design-docs/heapprofd-design.md3
-rw-r--r--docs/design-docs/pivot-tables.md206
-rw-r--r--docs/images/cpu-profile-diamond.pngbin0 -> 67664 bytes
-rw-r--r--docs/images/cpu-profile-flame.pngbin0 -> 449901 bytes
-rw-r--r--docs/images/enable-profile-flame-graph.pngbin0 -> 268550 bytes
-rw-r--r--docs/images/perfetto-ui-channel-toggle.pngbin0 -> 234058 bytes
-rw-r--r--docs/images/perfetto-ui-channel.pngbin0 -> 68778 bytes
-rw-r--r--docs/images/perfetto-ui-version.pngbin0 -> 279101 bytes
-rw-r--r--docs/images/pivot-tables/pivot-table-area-selection.pngbin0 -> 211470 bytes
-rw-r--r--docs/images/pivot-tables/pivot-table-design.pngbin0 -> 25260 bytes
-rw-r--r--docs/images/pivot-tables/pivot-table-editor.pngbin0 -> 88117 bytes
-rw-r--r--docs/images/pivot-tables/pivot-table-expanded-cell.pngbin0 -> 74305 bytes
-rw-r--r--docs/images/pivot-tables/pivot-table-query.pngbin0 -> 32745 bytes
-rw-r--r--docs/images/pivot-tables/pivot-table.pngbin0 -> 123319 bytes
-rw-r--r--docs/instrumentation/tracing-sdk.md2
-rw-r--r--docs/quickstart/android-tracing.md17
-rw-r--r--docs/quickstart/callstack-sampling.md139
-rw-r--r--docs/quickstart/linux-tracing.md42
-rw-r--r--docs/quickstart/trace-analysis.md6
-rw-r--r--docs/quickstart/traceconv.md2
-rw-r--r--docs/reference/heap_profile-cli.md107
-rw-r--r--docs/reference/perfetto-cli.md140
-rw-r--r--docs/toc.md7
-rw-r--r--docs/visualization/deep-linking-to-perfetto-ui.md142
-rw-r--r--docs/visualization/perfetto-ui-release-process.md108
-rw-r--r--docs/visualization/perfetto-ui.md22
-rw-r--r--examples/sdk/BUILD.gn29
-rw-r--r--examples/sdk/README.md4
-rw-r--r--examples/sdk/example.cc17
-rw-r--r--examples/sdk/trace_categories.cc2
-rw-r--r--examples/sdk/trace_categories.h10
-rw-r--r--gn/BUILD.gn22
-rw-r--r--gn/gen_perfetto_version_header.gni13
-rw-r--r--gn/perfetto.gni56
-rw-r--r--gn/perfetto_integrationtests.gni2
-rw-r--r--gn/perfetto_unittests.gni4
-rw-r--r--gn/proto_library.gni22
-rw-r--r--gn/standalone/BUILD.gn33
-rw-r--r--gn/standalone/BUILDCONFIG.gn10
-rw-r--r--gn/standalone/libc++/BUILD.gn11
-rw-r--r--gn/standalone/sanitizers/BUILD.gn139
-rw-r--r--gn/standalone/sanitizers/vars.gni5
-rw-r--r--gn/standalone/toolchain/BUILD.gn79
-rwxr-xr-xgn/standalone/toolchain/llvm-strip.py34
-rw-r--r--gn/standalone/toolchain/llvm.gni2
-rw-r--r--gn/standalone/toolchain/msvc.gni10
-rw-r--r--gn/standalone/toolchain/win_find_msvc.py2
-rw-r--r--gn/standalone/wasm_typescript_declaration.d.ts2
-rw-r--r--heapprofd.rc4
-rw-r--r--include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h9
-rw-r--r--include/perfetto/base/build_configs/bazel/perfetto_build_flags.h9
-rw-r--r--include/perfetto/base/compiler.h7
-rw-r--r--include/perfetto/base/logging.h69
-rw-r--r--include/perfetto/base/proc_utils.h6
-rw-r--r--include/perfetto/base/thread_utils.h6
-rw-r--r--include/perfetto/ext/base/BUILD.gn6
-rw-r--r--include/perfetto/ext/base/android_utils.h39
-rw-r--r--include/perfetto/ext/base/base64.h68
-rw-r--r--include/perfetto/ext/base/circular_queue.h29
-rw-r--r--include/perfetto/ext/base/crash_keys.h162
-rw-r--r--include/perfetto/ext/base/file_utils.h18
-rw-r--r--include/perfetto/ext/base/flat_hash_map.h394
-rw-r--r--include/perfetto/ext/base/getopt.h2
-rw-r--r--include/perfetto/ext/base/getopt_compat.h2
-rw-r--r--include/perfetto/ext/base/hash.h39
-rw-r--r--include/perfetto/ext/base/http/BUILD.gn21
-rw-r--r--include/perfetto/ext/base/http/http_server.h189
-rw-r--r--include/perfetto/ext/base/http/sha1.h37
-rw-r--r--include/perfetto/ext/base/scoped_file.h2
-rw-r--r--include/perfetto/ext/base/small_vector.h188
-rw-r--r--include/perfetto/ext/base/string_utils.h91
-rw-r--r--include/perfetto/ext/base/string_view.h18
-rw-r--r--include/perfetto/ext/base/string_writer.h14
-rw-r--r--include/perfetto/ext/base/subprocess.h29
-rw-r--r--include/perfetto/ext/base/sys_types.h52
-rw-r--r--include/perfetto/ext/base/thread_utils.h4
-rw-r--r--include/perfetto/ext/base/unix_socket.h9
-rw-r--r--include/perfetto/ext/base/utils.h97
-rw-r--r--include/perfetto/ext/base/watchdog.h13
-rw-r--r--include/perfetto/ext/base/watchdog_noop.h6
-rw-r--r--include/perfetto/ext/base/watchdog_posix.h67
-rw-r--r--include/perfetto/ext/ipc/client_info.h8
-rw-r--r--include/perfetto/ext/trace_processor/BUILD.gn4
-rw-r--r--include/perfetto/ext/trace_processor/demangle.h34
-rw-r--r--include/perfetto/ext/tracing/core/basic_types.h9
-rw-r--r--include/perfetto/ext/tracing/core/tracing_service.h3
-rw-r--r--include/perfetto/profiling/BUILD.gn4
-rw-r--r--include/perfetto/profiling/OWNERS1
-rw-r--r--include/perfetto/profiling/normalize.h66
-rw-r--r--include/perfetto/profiling/parse_smaps.h5
-rw-r--r--include/perfetto/protozero/proto_decoder.h102
-rw-r--r--include/perfetto/protozero/proto_utils.h2
-rw-r--r--include/perfetto/public/consumer_api.h2
-rw-r--r--include/perfetto/trace_processor/BUILD.gn7
-rw-r--r--include/perfetto/trace_processor/OWNERS1
-rw-r--r--include/perfetto/trace_processor/basic_types.h36
-rw-r--r--include/perfetto/trace_processor/iterator.h24
-rw-r--r--include/perfetto/trace_processor/ref_counted.h135
-rw-r--r--include/perfetto/trace_processor/trace_blob.h92
-rw-r--r--include/perfetto/trace_processor/trace_blob_view.h124
-rw-r--r--include/perfetto/trace_processor/trace_processor.h31
-rw-r--r--include/perfetto/trace_processor/trace_processor_storage.h8
-rw-r--r--include/perfetto/tracing/BUILD.gn1
-rw-r--r--include/perfetto/tracing/OWNERS1
-rw-r--r--include/perfetto/tracing/data_source.h68
-rw-r--r--include/perfetto/tracing/event_context.h43
-rw-r--r--include/perfetto/tracing/internal/data_source_internal.h15
-rw-r--r--include/perfetto/tracing/internal/tracing_muxer.h4
-rw-r--r--include/perfetto/tracing/internal/tracing_tls.h2
-rw-r--r--include/perfetto/tracing/internal/track_event_data_source.h80
-rw-r--r--include/perfetto/tracing/internal/track_event_internal.h95
-rw-r--r--include/perfetto/tracing/internal/track_event_interned_fields.h14
-rw-r--r--include/perfetto/tracing/internal/track_event_macros.h37
-rw-r--r--include/perfetto/tracing/internal/write_track_event_args.h89
-rw-r--r--include/perfetto/tracing/platform.h30
-rw-r--r--include/perfetto/tracing/traced_proto.h372
-rw-r--r--include/perfetto/tracing/traced_value.h120
-rw-r--r--include/perfetto/tracing/traced_value_forward.h32
-rw-r--r--include/perfetto/tracing/tracing.h5
-rw-r--r--include/perfetto/tracing/track.h37
-rw-r--r--include/perfetto/tracing/track_event.h13
-rw-r--r--include/perfetto/tracing/track_event_args.h96
-rw-r--r--include/perfetto/tracing/track_event_legacy.h133
-rw-r--r--include/perfetto/tracing/track_event_state_tracker.h4
-rw-r--r--infra/OWNERS3
-rw-r--r--infra/ci/Makefile4
-rw-r--r--infra/ci/controller/Makefile4
-rw-r--r--infra/ci/frontend/Makefile4
-rw-r--r--infra/ci/frontend/static/script.js2
-rw-r--r--infra/ci/sandbox/Dockerfile14
-rwxr-xr-xinfra/ci/worker/run_job.py14
-rw-r--r--infra/config/recipes.cfg5
-rw-r--r--infra/discord-irc-bridge/Dockerfile25
-rw-r--r--infra/discord-irc-bridge/README.md21
-rw-r--r--infra/discord-irc-bridge/discord-irc.json23
-rw-r--r--infra/discord-irc-bridge/start.py37
-rw-r--r--infra/discord-irc-bridge/supervisord.conf13
-rw-r--r--infra/luci/README.recipes.md97
-rw-r--r--infra/luci/generated/cr-buildbucket.cfg98
-rw-r--r--infra/luci/generated/luci-logdog.cfg9
-rw-r--r--infra/luci/generated/luci-scheduler.cfg73
-rw-r--r--infra/luci/generated/project.cfg15
-rw-r--r--infra/luci/generated/realms.cfg52
-rwxr-xr-xinfra/luci/main.star110
-rw-r--r--infra/luci/recipe_modules/macos_sdk/__init__.py54
-rw-r--r--infra/luci/recipe_modules/macos_sdk/api.py108
-rw-r--r--infra/luci/recipe_modules/macos_sdk/examples/full.expected/linux.json21
-rw-r--r--infra/luci/recipe_modules/macos_sdk/examples/full.expected/mac.json83
-rw-r--r--infra/luci/recipe_modules/macos_sdk/examples/full.expected/win.json21
-rw-r--r--infra/luci/recipe_modules/macos_sdk/examples/full.py33
-rw-r--r--infra/luci/recipe_modules/windows_sdk/__init__.py41
-rw-r--r--infra/luci/recipe_modules/windows_sdk/api.py114
-rw-r--r--infra/luci/recipe_modules/windows_sdk/examples/full.expected/linux.json21
-rw-r--r--infra/luci/recipe_modules/windows_sdk/examples/full.expected/mac.json21
-rw-r--r--infra/luci/recipe_modules/windows_sdk/examples/full.expected/win.json98
-rw-r--r--infra/luci/recipe_modules/windows_sdk/examples/full.py35
-rw-r--r--infra/luci/recipes/perfetto.expected/ci_android.json1702
-rw-r--r--infra/luci/recipes/perfetto.expected/ci_linux.json1292
-rw-r--r--infra/luci/recipes/perfetto.expected/ci_mac.json1193
-rw-r--r--infra/luci/recipes/perfetto.expected/ci_tag.json1404
-rw-r--r--infra/luci/recipes/perfetto.expected/ci_win.json485
-rw-r--r--infra/luci/recipes/perfetto.expected/unofficial.json199
-rw-r--r--infra/luci/recipes/perfetto.py194
-rwxr-xr-xinfra/oss-fuzz/build_fuzzers6
-rw-r--r--infra/perfetto.dev/src/assets/style.scss2
-rw-r--r--infra/perfetto.dev/src/markdown_render.js9
-rw-r--r--meson.build1
-rw-r--r--perfetto.rc35
-rw-r--r--protos/perfetto/common/BUILD.gn1
-rw-r--r--protos/perfetto/common/builtin_clock.proto4
-rw-r--r--protos/perfetto/common/data_source_descriptor.proto10
-rw-r--r--protos/perfetto/common/ftrace_descriptor.proto31
-rw-r--r--protos/perfetto/common/perf_events.proto81
-rw-r--r--protos/perfetto/common/trace_stats.proto21
-rw-r--r--protos/perfetto/common/tracing_service_state.proto45
-rw-r--r--protos/perfetto/config/BUILD.gn13
-rw-r--r--protos/perfetto/config/ftrace/ftrace_config.proto25
-rw-r--r--protos/perfetto/config/perfetto_config.proto370
-rw-r--r--protos/perfetto/config/profiling/heapprofd_config.proto6
-rw-r--r--protos/perfetto/config/profiling/java_hprof_config.proto36
-rw-r--r--protos/perfetto/config/profiling/perf_event_config.proto46
-rw-r--r--protos/perfetto/config/sys_stats/sys_stats_config.proto4
-rw-r--r--protos/perfetto/config/trace_config.proto83
-rw-r--r--protos/perfetto/config/track_event/track_event_config.proto19
-rw-r--r--protos/perfetto/ipc/BUILD.gn2
-rw-r--r--protos/perfetto/ipc/OWNERS9
-rw-r--r--protos/perfetto/ipc/producer_port.proto48
-rw-r--r--protos/perfetto/metrics/BUILD.gn2
-rw-r--r--protos/perfetto/metrics/android/BUILD.gn12
-rw-r--r--protos/perfetto/metrics/android/android_trusty_workqueues.proto22
-rw-r--r--protos/perfetto/metrics/android/camera_metric.proto42
-rw-r--r--protos/perfetto/metrics/android/camera_unagg_metric.proto41
-rw-r--r--protos/perfetto/metrics/android/dvfs_metric.proto43
-rw-r--r--protos/perfetto/metrics/android/g2d_metric.proto23
-rw-r--r--protos/perfetto/metrics/android/gpu_metric.proto29
-rw-r--r--protos/perfetto/metrics/android/hwcomposer.proto20
-rw-r--r--protos/perfetto/metrics/android/irq_runtime_metric.proto54
-rw-r--r--protos/perfetto/metrics/android/java_heap_histogram.proto7
-rw-r--r--protos/perfetto/metrics/android/java_heap_stats.proto7
-rw-r--r--protos/perfetto/metrics/android/mem_metric.proto4
-rw-r--r--protos/perfetto/metrics/android/multiuser_metric.proto48
-rw-r--r--protos/perfetto/metrics/android/network_metric.proto123
-rw-r--r--protos/perfetto/metrics/android/other_traces.proto25
-rw-r--r--protos/perfetto/metrics/android/powrails_metric.proto3
-rw-r--r--protos/perfetto/metrics/android/profiler_smaps.proto36
-rw-r--r--protos/perfetto/metrics/android/rt_runtime_metric.proto39
-rw-r--r--protos/perfetto/metrics/android/simpleperf.proto25
-rw-r--r--protos/perfetto/metrics/android/startup_metric.proto11
-rw-r--r--protos/perfetto/metrics/android/surfaceflinger.proto15
-rw-r--r--protos/perfetto/metrics/android/trace_quality.proto32
-rw-r--r--protos/perfetto/metrics/android/unsymbolized_frames.proto7
-rw-r--r--protos/perfetto/metrics/chrome/BUILD.gn7
-rw-r--r--protos/perfetto/metrics/chrome/all_chrome_metrics.proto17
-rw-r--r--protos/perfetto/metrics/chrome/dropped_frames.proto29
-rw-r--r--protos/perfetto/metrics/chrome/histogram_hashes.proto26
-rw-r--r--protos/perfetto/metrics/chrome/long_latency.proto40
-rw-r--r--protos/perfetto/metrics/chrome/performance_mark_hashes.proto27
-rw-r--r--protos/perfetto/metrics/chrome/scroll_jank.proto1
-rw-r--r--protos/perfetto/metrics/chrome/slice_names.proto27
-rw-r--r--protos/perfetto/metrics/chrome/touch_jank.proto35
-rw-r--r--protos/perfetto/metrics/chrome/user_event_hashes.proto26
-rw-r--r--protos/perfetto/metrics/metrics.proto52
-rw-r--r--protos/perfetto/metrics/perfetto_merged_metrics.proto515
-rw-r--r--protos/perfetto/trace/BUILD.gn37
-rw-r--r--protos/perfetto/trace/android/BUILD.gn1
-rw-r--r--protos/perfetto/trace/android/camera_event.proto160
-rw-r--r--protos/perfetto/trace/chrome/BUILD.gn2
-rw-r--r--protos/perfetto/trace/ftrace/BUILD.gn5
-rw-r--r--protos/perfetto/trace/ftrace/all_protos.gni12
-rw-r--r--protos/perfetto/trace/ftrace/binder.proto1
-rw-r--r--protos/perfetto/trace/ftrace/block.proto1
-rw-r--r--protos/perfetto/trace/ftrace/cgroup.proto12
-rw-r--r--protos/perfetto/trace/ftrace/compaction.proto3
-rw-r--r--protos/perfetto/trace/ftrace/cros_ec.proto15
-rw-r--r--protos/perfetto/trace/ftrace/dma_fence.proto37
-rw-r--r--protos/perfetto/trace/ftrace/drm.proto18
-rw-r--r--protos/perfetto/trace/ftrace/ext4.proto13
-rw-r--r--protos/perfetto/trace/ftrace/f2fs.proto8
-rw-r--r--protos/perfetto/trace/ftrace/ftrace_event.proto72
-rw-r--r--protos/perfetto/trace/ftrace/ftrace_event_bundle.proto42
-rw-r--r--protos/perfetto/trace/ftrace/ftrace_stats.proto12
-rw-r--r--protos/perfetto/trace/ftrace/gpu_scheduler.proto26
-rw-r--r--protos/perfetto/trace/ftrace/kvm.proto170
-rw-r--r--protos/perfetto/trace/ftrace/net.proto42
-rw-r--r--protos/perfetto/trace/ftrace/power.proto8
-rw-r--r--protos/perfetto/trace/ftrace/printk.proto10
-rw-r--r--protos/perfetto/trace/ftrace/scm.proto3
-rw-r--r--protos/perfetto/trace/ftrace/skb.proto12
-rw-r--r--protos/perfetto/trace/ftrace/sock.proto18
-rw-r--r--protos/perfetto/trace/ftrace/synthetic.proto13
-rw-r--r--protos/perfetto/trace/ftrace/tcp.proto16
-rw-r--r--protos/perfetto/trace/ftrace/ufs.proto23
-rw-r--r--protos/perfetto/trace/ftrace/vmscan.proto1
-rw-r--r--protos/perfetto/trace/ftrace/workqueue.proto1
-rw-r--r--protos/perfetto/trace/interned_data/interned_data.proto3
-rw-r--r--protos/perfetto/trace/perfetto/perfetto_metatrace.proto2
-rw-r--r--protos/perfetto/trace/perfetto_trace.proto1294
-rw-r--r--protos/perfetto/trace/profiling/heap_graph.proto11
-rw-r--r--protos/perfetto/trace/profiling/profile_packet.proto80
-rw-r--r--protos/perfetto/trace/ps/process_tree.proto15
-rw-r--r--protos/perfetto/trace/sys_stats/sys_stats.proto5
-rw-r--r--protos/perfetto/trace/system_info.proto4
-rw-r--r--protos/perfetto/trace/test_event.proto4
-rw-r--r--protos/perfetto/trace/test_extensions.proto3
-rw-r--r--protos/perfetto/trace/trace_packet.proto11
-rw-r--r--protos/perfetto/trace/track_event/BUILD.gn2
-rw-r--r--protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto12
-rw-r--r--protos/perfetto/trace/track_event/chrome_frame_reporter.proto4
-rw-r--r--protos/perfetto/trace/track_event/chrome_latency_info.proto1
-rw-r--r--protos/perfetto/trace/track_event/chrome_process_descriptor.proto1
-rw-r--r--protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto3
-rw-r--r--protos/perfetto/trace/track_event/chrome_thread_descriptor.proto1
-rw-r--r--protos/perfetto/trace/track_event/debug_annotation.proto21
-rw-r--r--protos/perfetto/trace/track_event/process_descriptor.proto7
-rw-r--r--protos/perfetto/trace/translation/BUILD.gn19
-rw-r--r--protos/perfetto/trace/translation/translation_table.proto51
-rw-r--r--protos/perfetto/trace_processor/BUILD.gn12
-rw-r--r--protos/perfetto/trace_processor/trace_processor.proto133
-rw-r--r--protos/third_party/chromium/BUILD.gn9
-rw-r--r--protos/third_party/chromium/chrome_track_event.proto699
-rw-r--r--protos/third_party/pprof/BUILD.gn5
-rw-r--r--python/BUILD107
-rw-r--r--python/LICENSE (renamed from src/trace_processor/python/LICENSE)0
-rw-r--r--python/README.md (renamed from src/trace_processor/python/README.md)0
-rw-r--r--python/example.py69
-rw-r--r--python/perfetto/__init__.py (renamed from src/trace_processor/python/perfetto/__init__.py)0
-rw-r--r--python/perfetto/batch_trace_processor/__init__.py17
-rw-r--r--python/perfetto/batch_trace_processor/api.py368
-rw-r--r--python/perfetto/batch_trace_processor/platform.py28
-rw-r--r--python/perfetto/experimental/slice_breakdown/__init__.py16
-rw-r--r--python/perfetto/experimental/slice_breakdown/breakdown.py194
-rw-r--r--python/perfetto/trace_processor/__init__.py20
-rw-r--r--python/perfetto/trace_processor/api.py359
-rw-r--r--python/perfetto/trace_processor/http.py77
-rw-r--r--python/perfetto/trace_processor/metrics.descriptor775
-rw-r--r--python/perfetto/trace_processor/metrics.descriptor.sha16
-rw-r--r--python/perfetto/trace_processor/platform.py65
-rw-r--r--python/perfetto/trace_processor/protos.py63
-rw-r--r--python/perfetto/trace_processor/shell.py65
-rw-r--r--python/perfetto/trace_processor/trace_processor.descriptorbin0 -> 6103 bytes
-rw-r--r--python/perfetto/trace_processor/trace_processor.descriptor.sha16
-rw-r--r--python/perfetto/trace_uri_resolver/__init__.py (renamed from src/trace_processor/metrics/experimental/OWNERS)0
-rw-r--r--python/perfetto/trace_uri_resolver/path.py36
-rw-r--r--python/perfetto/trace_uri_resolver/registry.py81
-rw-r--r--python/perfetto/trace_uri_resolver/resolver.py134
-rw-r--r--python/perfetto/trace_uri_resolver/util.py57
-rwxr-xr-xpython/run_tests.py59
-rw-r--r--python/setup.py32
-rw-r--r--python/test/__init__.py0
-rw-r--r--python/test/api_integrationtest.py261
-rwxr-xr-xpython/test/api_unittest.py348
-rw-r--r--python/test/resolver_unittest.py155
-rw-r--r--python/tools/batch_trace_processor_shell.py140
-rw-r--r--python/tools/slice_breakdown.py75
-rw-r--r--src/android_internal/BUILD.gn2
-rw-r--r--src/android_internal/atrace_hal.cc8
-rw-r--r--src/android_internal/health_hal.cc127
-rw-r--r--src/android_internal/power_stats.cc18
-rw-r--r--src/android_internal/tracing_service_proxy.cc51
-rw-r--r--src/android_internal/tracing_service_proxy.h10
-rw-r--r--src/android_stats/perfetto_atoms.h28
-rw-r--r--src/base/BUILD.gn38
-rw-r--r--src/base/android_utils.cc62
-rw-r--r--src/base/base64.cc153
-rw-r--r--src/base/base64_unittest.cc361
-rw-r--r--src/base/crash_keys.cc97
-rw-r--r--src/base/debug_crash_stack_trace.cc19
-rw-r--r--src/base/event_fd.cc6
-rw-r--r--src/base/file_utils.cc119
-rw-r--r--src/base/flat_hash_map_benchmark.cc378
-rw-r--r--src/base/flat_hash_map_unittest.cc388
-rw-r--r--src/base/getopt_compat.cc21
-rw-r--r--src/base/getopt_compat_unittest.cc47
-rw-r--r--src/base/http/BUILD.gn47
-rw-r--r--src/base/http/http_server.cc580
-rw-r--r--src/base/http/http_server_unittest.cc325
-rw-r--r--src/base/http/sha1.cc242
-rw-r--r--src/base/http/sha1_unittest.cc56
-rw-r--r--src/base/log_ring_buffer.h160
-rw-r--r--src/base/logging.cc116
-rw-r--r--src/base/logging_unittest.cc209
-rw-r--r--src/base/paged_memory_unittest.cc8
-rw-r--r--src/base/scoped_file_unittest.cc66
-rw-r--r--src/base/small_vector_unittest.cc232
-rw-r--r--src/base/string_utils.cc126
-rw-r--r--src/base/string_utils_unittest.cc155
-rw-r--r--src/base/string_view_unittest.cc16
-rw-r--r--src/base/subprocess_posix.cc49
-rw-r--r--src/base/subprocess_unittest.cc88
-rw-r--r--src/base/subprocess_windows.cc58
-rw-r--r--src/base/test/tmp_dir_tree.cc55
-rw-r--r--src/base/test/tmp_dir_tree.h62
-rw-r--r--src/base/test/utils.cc69
-rw-r--r--src/base/test/utils.h8
-rw-r--r--src/base/unix_socket.cc79
-rw-r--r--src/base/unix_socket_unittest.cc106
-rw-r--r--src/base/utils.cc214
-rw-r--r--src/base/utils_unittest.cc13
-rw-r--r--src/base/watchdog_posix.cc232
-rw-r--r--src/base/watchdog_unittest.cc15
-rw-r--r--src/ipc/buffered_frame_deserializer.cc3
-rw-r--r--src/ipc/client_impl.cc2
-rw-r--r--src/ipc/host_impl.cc31
-rw-r--r--src/ipc/host_impl_unittest.cc33
-rw-r--r--src/ipc/test/test_socket.h3
-rw-r--r--src/kallsyms/kernel_symbol_map.cc12
-rw-r--r--src/kallsyms/kernel_symbol_map_benchmark.cc32
-rw-r--r--src/kallsyms/kernel_symbol_map_unittest.cc3
-rw-r--r--src/kallsyms/lazy_kernel_symbolizer_unittest.cc2
-rw-r--r--src/perfetto_cmd/BUILD.gn15
-rw-r--r--src/perfetto_cmd/config.cc1
-rw-r--r--src/perfetto_cmd/config_unittest.cc1
-rw-r--r--src/perfetto_cmd/pbtxt_to_pb.cc6
-rw-r--r--src/perfetto_cmd/perfetto_cmd.cc568
-rw-r--r--src/perfetto_cmd/perfetto_cmd.h55
-rw-r--r--src/perfetto_cmd/perfetto_cmd_android.cc64
-rw-r--r--src/perfetto_cmd/rate_limiter.cc2
-rw-r--r--src/profiling/OWNERS2
-rw-r--r--src/profiling/common/BUILD.gn16
-rw-r--r--src/profiling/common/callstack_trie.cc18
-rw-r--r--src/profiling/common/callstack_trie.h2
-rw-r--r--src/profiling/common/proc_cmdline.cc118
-rw-r--r--src/profiling/common/proc_cmdline.h56
-rw-r--r--src/profiling/common/proc_cmdline_unittest.cc117
-rw-r--r--src/profiling/common/proc_utils.cc204
-rw-r--r--src/profiling/common/proc_utils.h28
-rw-r--r--src/profiling/common/proc_utils_unittest.cc1
-rw-r--r--src/profiling/common/producer_support.cc162
-rw-r--r--src/profiling/common/producer_support.h2
-rw-r--r--src/profiling/common/producer_support_unittest.cc342
-rw-r--r--src/profiling/common/profiler_guardrails.h3
-rw-r--r--src/profiling/common/profiler_guardrails_unittest.cc2
-rw-r--r--src/profiling/common/unwind_support.cc26
-rw-r--r--src/profiling/deobfuscator.cc4
-rw-r--r--src/profiling/deobfuscator_unittest.cc24
-rw-r--r--src/profiling/memory/BUILD.gn19
-rw-r--r--src/profiling/memory/bookkeeping.cc3
-rw-r--r--src/profiling/memory/bookkeeping.h5
-rw-r--r--src/profiling/memory/bookkeeping_dump.h12
-rw-r--r--src/profiling/memory/bookkeeping_unittest.cc10
-rw-r--r--src/profiling/memory/client.cc14
-rw-r--r--src/profiling/memory/client_api.cc78
-rw-r--r--src/profiling/memory/client_api_factory_android.cc1
-rw-r--r--src/profiling/memory/client_api_factory_standalone.cc42
-rw-r--r--src/profiling/memory/client_api_noop.cc2
-rw-r--r--src/profiling/memory/heap_profile_internal.h3
-rw-r--r--src/profiling/memory/heapprofd.cc130
-rw-r--r--src/profiling/memory/heapprofd.h28
-rw-r--r--src/profiling/memory/heapprofd_end_to_end_test.cc26
-rw-r--r--src/profiling/memory/heapprofd_producer.cc109
-rw-r--r--src/profiling/memory/heapprofd_producer.h7
-rw-r--r--src/profiling/memory/heapprofd_producer_unittest.cc1
-rw-r--r--src/profiling/memory/include/perfetto/heap_profile.h19
-rw-r--r--src/profiling/memory/java_hprof_producer.cc66
-rw-r--r--src/profiling/memory/java_hprof_producer.h23
-rw-r--r--src/profiling/memory/log_histogram.cc2
-rw-r--r--src/profiling/memory/log_histogram.h2
-rw-r--r--src/profiling/memory/main.cc112
-rw-r--r--src/profiling/memory/malloc_interceptor_bionic_hooks.cc2
-rw-r--r--src/profiling/memory/parse_smaps_unittest.cc4
-rw-r--r--src/profiling/memory/sampler.cc23
-rw-r--r--src/profiling/memory/sampler.h11
-rw-r--r--src/profiling/memory/sampler_unittest.cc10
-rw-r--r--src/profiling/memory/shared_ring_buffer.cc8
-rw-r--r--src/profiling/memory/shared_ring_buffer_write_fuzzer.cc1
-rw-r--r--src/profiling/memory/unwinding.cc6
-rw-r--r--src/profiling/memory/unwinding_unittest.cc2
-rw-r--r--src/profiling/memory/wire_protocol.cc4
-rw-r--r--src/profiling/memory/wire_protocol.h3
-rw-r--r--src/profiling/memory/wire_protocol_unittest.cc6
-rw-r--r--src/profiling/memory/wrap_allocators.cc3
-rw-r--r--src/profiling/memory/wrap_allocators.h3
-rw-r--r--src/profiling/perf/BUILD.gn3
-rw-r--r--src/profiling/perf/event_config.cc240
-rw-r--r--src/profiling/perf/event_config.h73
-rw-r--r--src/profiling/perf/event_config_unittest.cc42
-rw-r--r--src/profiling/perf/event_reader.cc25
-rw-r--r--src/profiling/perf/perf_producer.cc105
-rw-r--r--src/profiling/perf/proc_descriptors.cc17
-rw-r--r--src/profiling/perf/regs_parsing.cc3
-rw-r--r--src/profiling/perf/unwinding.cc11
-rw-r--r--src/profiling/symbolizer/BUILD.gn14
-rw-r--r--src/profiling/symbolizer/breakpad_parser.cc215
-rw-r--r--src/profiling/symbolizer/breakpad_parser.h85
-rw-r--r--src/profiling/symbolizer/breakpad_parser_unittest.cc214
-rw-r--r--src/profiling/symbolizer/breakpad_symbolizer.cc99
-rw-r--r--src/profiling/symbolizer/breakpad_symbolizer.h60
-rw-r--r--src/profiling/symbolizer/breakpad_symbolizer_unittest.cc90
-rw-r--r--src/profiling/symbolizer/elf.h172
-rw-r--r--src/profiling/symbolizer/filesystem.h32
-rw-r--r--src/profiling/symbolizer/filesystem_posix.cc78
-rw-r--r--src/profiling/symbolizer/filesystem_windows.cc75
-rw-r--r--src/profiling/symbolizer/local_symbolizer.cc239
-rw-r--r--src/profiling/symbolizer/local_symbolizer.h2
-rw-r--r--src/profiling/symbolizer/local_symbolizer_unittest.cc140
-rw-r--r--src/profiling/symbolizer/symbolize_database.cc15
-rw-r--r--src/profiling/symbolizer/symbolizer.h8
-rw-r--r--src/protozero/BUILD.gn14
-rw-r--r--src/protozero/filtering/BUILD.gn14
-rw-r--r--src/protozero/filtering/filter_bytecode_parser.h2
-rw-r--r--src/protozero/filtering/filter_util.h8
-rw-r--r--src/protozero/filtering/message_filter.h2
-rw-r--r--src/protozero/proto_decoder.cc46
-rw-r--r--src/protozero/proto_decoder_unittest.cc7
-rw-r--r--src/protozero/proto_ring_buffer.cc186
-rw-r--r--src/protozero/proto_ring_buffer.h138
-rw-r--r--src/protozero/proto_ring_buffer_unittest.cc232
-rw-r--r--src/protozero/protoc_plugin/protozero_plugin.cc6
-rw-r--r--src/protozero/scattered_stream_writer.cc9
-rw-r--r--src/protozero/test/example_proto/test_messages.proto18
-rw-r--r--src/trace_processor/BUILD.gn62
-rw-r--r--src/trace_processor/OWNERS5
-rw-r--r--src/trace_processor/containers/bit_vector.h2
-rw-r--r--src/trace_processor/containers/nullable_vector.h32
-rw-r--r--src/trace_processor/containers/row_map.cc24
-rw-r--r--src/trace_processor/containers/row_map.h192
-rw-r--r--src/trace_processor/containers/row_map_unittest.cc38
-rw-r--r--src/trace_processor/containers/string_pool.cc19
-rw-r--r--src/trace_processor/containers/string_pool.h39
-rw-r--r--src/trace_processor/db/column.cc15
-rw-r--r--src/trace_processor/db/column.h29
-rw-r--r--src/trace_processor/db/table.cc52
-rw-r--r--src/trace_processor/db/table.h20
-rw-r--r--src/trace_processor/db/typed_column.h2
-rw-r--r--src/trace_processor/demangle.cc69
-rw-r--r--src/trace_processor/dynamic/ancestor_generator.cc146
-rw-r--r--src/trace_processor/dynamic/ancestor_generator.h15
-rw-r--r--src/trace_processor/dynamic/connected_flow_generator.cc33
-rw-r--r--src/trace_processor/dynamic/connected_flow_generator.h8
-rw-r--r--src/trace_processor/dynamic/descendant_generator.cc178
-rw-r--r--src/trace_processor/dynamic/descendant_generator.h65
-rw-r--r--src/trace_processor/dynamic/descendant_slice_generator.cc122
-rw-r--r--src/trace_processor/dynamic/descendant_slice_generator.h59
-rw-r--r--src/trace_processor/dynamic/describe_slice_generator.cc28
-rw-r--r--src/trace_processor/dynamic/describe_slice_generator.h8
-rw-r--r--src/trace_processor/dynamic/experimental_annotated_stack_generator.cc26
-rw-r--r--src/trace_processor/dynamic/experimental_annotated_stack_generator.h8
-rw-r--r--src/trace_processor/dynamic/experimental_counter_dur_generator.cc13
-rw-r--r--src/trace_processor/dynamic/experimental_counter_dur_generator.h8
-rw-r--r--src/trace_processor/dynamic/experimental_flamegraph_generator.cc126
-rw-r--r--src/trace_processor/dynamic/experimental_flamegraph_generator.h17
-rw-r--r--src/trace_processor/dynamic/experimental_flat_slice_generator.cc270
-rw-r--r--src/trace_processor/dynamic/experimental_flat_slice_generator.h83
-rw-r--r--src/trace_processor/dynamic/experimental_flat_slice_generator_unittest.cc202
-rw-r--r--src/trace_processor/dynamic/experimental_sched_upid_generator.cc18
-rw-r--r--src/trace_processor/dynamic/experimental_sched_upid_generator.h8
-rw-r--r--src/trace_processor/dynamic/experimental_slice_layout_generator.cc21
-rw-r--r--src/trace_processor/dynamic/experimental_slice_layout_generator.h8
-rw-r--r--src/trace_processor/dynamic/experimental_slice_layout_generator_unittest.cc43
-rw-r--r--src/trace_processor/dynamic/thread_state_generator.cc63
-rw-r--r--src/trace_processor/dynamic/thread_state_generator.h30
-rw-r--r--src/trace_processor/export_json.cc42
-rw-r--r--src/trace_processor/export_json_unittest.cc11
-rw-r--r--src/trace_processor/forwarding_trace_parser.cc49
-rw-r--r--src/trace_processor/forwarding_trace_parser.h4
-rw-r--r--src/trace_processor/forwarding_trace_parser_unittest.cc2
-rw-r--r--src/trace_processor/importers/BUILD.gn6
-rw-r--r--src/trace_processor/importers/additional_modules.cc2
-rw-r--r--src/trace_processor/importers/common/BUILD.gn9
-rw-r--r--src/trace_processor/importers/common/args_tracker.cc6
-rw-r--r--src/trace_processor/importers/common/args_tracker.h20
-rw-r--r--src/trace_processor/importers/common/args_translation_table.cc147
-rw-r--r--src/trace_processor/importers/common/args_translation_table.h130
-rw-r--r--src/trace_processor/importers/common/args_translation_table_unittest.cc83
-rw-r--r--src/trace_processor/importers/common/chunked_trace_reader.h4
-rw-r--r--src/trace_processor/importers/common/clock_tracker.cc3
-rw-r--r--src/trace_processor/importers/common/clock_tracker.h2
-rw-r--r--src/trace_processor/importers/common/flow_tracker.cc62
-rw-r--r--src/trace_processor/importers/common/flow_tracker.h43
-rw-r--r--src/trace_processor/importers/common/flow_tracker_unittest.cc13
-rw-r--r--src/trace_processor/importers/common/global_args_tracker.h44
-rw-r--r--src/trace_processor/importers/common/process_tracker.cc175
-rw-r--r--src/trace_processor/importers/common/process_tracker.h86
-rw-r--r--src/trace_processor/importers/common/process_tracker_unittest.cc133
-rw-r--r--src/trace_processor/importers/common/slice_tracker.cc70
-rw-r--r--src/trace_processor/importers/common/slice_tracker.h18
-rw-r--r--src/trace_processor/importers/common/slice_tracker_unittest.cc145
-rw-r--r--src/trace_processor/importers/common/slice_translation_table.cc26
-rw-r--r--src/trace_processor/importers/common/slice_translation_table.h57
-rw-r--r--src/trace_processor/importers/common/slice_translation_table_unittest.cc42
-rw-r--r--src/trace_processor/importers/common/trace_blob_view.h148
-rw-r--r--src/trace_processor/importers/common/track_tracker.cc24
-rw-r--r--src/trace_processor/importers/common/track_tracker.h23
-rw-r--r--src/trace_processor/importers/default_modules.cc2
-rw-r--r--src/trace_processor/importers/ftrace/binder_tracker.cc165
-rw-r--r--src/trace_processor/importers/ftrace/binder_tracker.h27
-rw-r--r--src/trace_processor/importers/ftrace/binder_tracker_unittest.cc140
-rw-r--r--src/trace_processor/importers/ftrace/ftrace_descriptors.cc716
-rw-r--r--src/trace_processor/importers/ftrace/ftrace_module_impl.cc9
-rw-r--r--src/trace_processor/importers/ftrace/ftrace_module_impl.h3
-rw-r--r--src/trace_processor/importers/ftrace/ftrace_parser.cc817
-rw-r--r--src/trace_processor/importers/ftrace/ftrace_parser.h75
-rw-r--r--src/trace_processor/importers/ftrace/ftrace_tokenizer.cc131
-rw-r--r--src/trace_processor/importers/ftrace/ftrace_tokenizer.h24
-rw-r--r--src/trace_processor/importers/ftrace/rss_stat_tracker.cc59
-rw-r--r--src/trace_processor/importers/ftrace/rss_stat_tracker.h10
-rw-r--r--src/trace_processor/importers/ftrace/sched_event_tracker.cc32
-rw-r--r--src/trace_processor/importers/ftrace/sched_event_tracker.h14
-rw-r--r--src/trace_processor/importers/ftrace/sched_event_tracker_unittest.cc3
-rw-r--r--src/trace_processor/importers/fuchsia/fuchsia_record.h4
-rw-r--r--src/trace_processor/importers/fuchsia/fuchsia_trace_parser.cc33
-rw-r--r--src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.cc37
-rw-r--r--src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.h3
-rw-r--r--src/trace_processor/importers/fuchsia/fuchsia_trace_utils.h2
-rw-r--r--src/trace_processor/importers/gzip/gzip_trace_parser.cc24
-rw-r--r--src/trace_processor/importers/gzip/gzip_trace_parser.h6
-rw-r--r--src/trace_processor/importers/gzip/gzip_utils.cc112
-rw-r--r--src/trace_processor/importers/gzip/gzip_utils.h72
-rw-r--r--src/trace_processor/importers/json/json_trace_parser.cc136
-rw-r--r--src/trace_processor/importers/json/json_trace_parser.h2
-rw-r--r--src/trace_processor/importers/json/json_trace_tokenizer.cc72
-rw-r--r--src/trace_processor/importers/json/json_trace_tokenizer.h7
-rw-r--r--src/trace_processor/importers/json/json_tracker.cc26
-rw-r--r--src/trace_processor/importers/json/json_tracker.h58
-rw-r--r--src/trace_processor/importers/json/json_tracker_unittest.cc40
-rw-r--r--src/trace_processor/importers/json/json_utils.cc56
-rw-r--r--src/trace_processor/importers/json/json_utils.h4
-rw-r--r--src/trace_processor/importers/json/json_utils_unittest.cc31
-rw-r--r--src/trace_processor/importers/memory_tracker/graph_processor_unittest.cc2
-rw-r--r--src/trace_processor/importers/memory_tracker/memory_allocator_node_id.cc9
-rw-r--r--src/trace_processor/importers/memory_tracker/raw_process_memory_node.cc2
-rw-r--r--src/trace_processor/importers/memory_tracker/raw_process_memory_node_unittest.cc2
-rw-r--r--src/trace_processor/importers/ninja/ninja_log_parser.cc11
-rw-r--r--src/trace_processor/importers/ninja/ninja_log_parser.h2
-rw-r--r--src/trace_processor/importers/proto/android_camera_event_module.cc92
-rw-r--r--src/trace_processor/importers/proto/android_camera_event_module.h58
-rw-r--r--src/trace_processor/importers/proto/android_probes_module.cc11
-rw-r--r--src/trace_processor/importers/proto/android_probes_parser.cc24
-rw-r--r--src/trace_processor/importers/proto/async_track_set_tracker.cc62
-rw-r--r--src/trace_processor/importers/proto/async_track_set_tracker.h54
-rw-r--r--src/trace_processor/importers/proto/async_track_set_tracker_unittest.cc7
-rw-r--r--src/trace_processor/importers/proto/chrome_string_lookup.cc2
-rw-r--r--src/trace_processor/importers/proto/flamegraph_construction_algorithms.cc436
-rw-r--r--src/trace_processor/importers/proto/flamegraph_construction_algorithms.h45
-rw-r--r--src/trace_processor/importers/proto/frame_timeline_event_parser.cc101
-rw-r--r--src/trace_processor/importers/proto/gpu_event_parser.cc7
-rw-r--r--src/trace_processor/importers/proto/graphics_frame_event_parser.cc2
-rw-r--r--src/trace_processor/importers/proto/heap_graph_module.cc11
-rw-r--r--src/trace_processor/importers/proto/heap_graph_tracker.cc225
-rw-r--r--src/trace_processor/importers/proto/heap_graph_tracker.h27
-rw-r--r--src/trace_processor/importers/proto/heap_graph_tracker_unittest.cc181
-rw-r--r--src/trace_processor/importers/proto/heap_profile_tracker.cc217
-rw-r--r--src/trace_processor/importers/proto/heap_profile_tracker.h4
-rw-r--r--src/trace_processor/importers/proto/metadata_module.cc26
-rw-r--r--src/trace_processor/importers/proto/metadata_module.h2
-rw-r--r--src/trace_processor/importers/proto/metadata_tracker.cc36
-rw-r--r--src/trace_processor/importers/proto/metadata_tracker.h4
-rw-r--r--src/trace_processor/importers/proto/packet_sequence_state.h120
-rw-r--r--src/trace_processor/importers/proto/perf_sample_tracker.cc72
-rw-r--r--src/trace_processor/importers/proto/perf_sample_tracker_unittest.cc34
-rw-r--r--src/trace_processor/importers/proto/profile_module.cc338
-rw-r--r--src/trace_processor/importers/proto/profile_module.h14
-rw-r--r--src/trace_processor/importers/proto/profile_packet_utils.h6
-rw-r--r--src/trace_processor/importers/proto/profiler_util.cc55
-rw-r--r--src/trace_processor/importers/proto/proto_importer_module.h2
-rw-r--r--src/trace_processor/importers/proto/proto_trace_parser.cc341
-rw-r--r--src/trace_processor/importers/proto/proto_trace_parser.h13
-rw-r--r--src/trace_processor/importers/proto/proto_trace_parser_unittest.cc194
-rw-r--r--src/trace_processor/importers/proto/proto_trace_reader.cc76
-rw-r--r--src/trace_processor/importers/proto/proto_trace_reader.h3
-rw-r--r--src/trace_processor/importers/proto/proto_trace_tokenizer.cc33
-rw-r--r--src/trace_processor/importers/proto/proto_trace_tokenizer.h62
-rw-r--r--src/trace_processor/importers/proto/stack_profile_tracker.cc2
-rw-r--r--src/trace_processor/importers/proto/system_probes_parser.cc120
-rw-r--r--src/trace_processor/importers/proto/system_probes_parser.h1
-rw-r--r--src/trace_processor/importers/proto/track_event_parser.cc302
-rw-r--r--src/trace_processor/importers/proto/track_event_parser.h1
-rw-r--r--src/trace_processor/importers/proto/track_event_tokenizer.cc7
-rw-r--r--src/trace_processor/importers/proto/track_event_tracker.cc27
-rw-r--r--src/trace_processor/importers/proto/translation_table_module.cc112
-rw-r--r--src/trace_processor/importers/proto/translation_table_module.h52
-rw-r--r--src/trace_processor/importers/syscalls/syscall_tracker.cc3
-rw-r--r--src/trace_processor/importers/systrace/systrace_line.h2
-rw-r--r--src/trace_processor/importers/systrace/systrace_line_parser.cc46
-rw-r--r--src/trace_processor/importers/systrace/systrace_line_parser.h4
-rw-r--r--src/trace_processor/importers/systrace/systrace_parser.cc101
-rw-r--r--src/trace_processor/importers/systrace/systrace_parser.h275
-rw-r--r--src/trace_processor/importers/systrace/systrace_parser_unittest.cc54
-rw-r--r--src/trace_processor/importers/systrace/systrace_trace_parser.cc21
-rw-r--r--src/trace_processor/importers/systrace/systrace_trace_parser.h2
-rw-r--r--src/trace_processor/iterator_impl.cc21
-rw-r--r--src/trace_processor/iterator_impl.h48
-rw-r--r--src/trace_processor/metrics/BUILD.gn138
-rw-r--r--src/trace_processor/metrics/android/android_batt.sql278
-rw-r--r--src/trace_processor/metrics/android/android_fastrpc.sql72
-rw-r--r--src/trace_processor/metrics/android/android_gpu.sql67
-rw-r--r--src/trace_processor/metrics/android/android_hwcomposer.sql83
-rw-r--r--src/trace_processor/metrics/android/android_hwui_metric.sql261
-rw-r--r--src/trace_processor/metrics/android/android_hwui_threads.sql122
-rw-r--r--src/trace_processor/metrics/android/android_ion.sql94
-rw-r--r--src/trace_processor/metrics/android/android_jank.sql284
-rw-r--r--src/trace_processor/metrics/android/android_lmk.sql93
-rw-r--r--src/trace_processor/metrics/android/android_powrails.sql51
-rw-r--r--src/trace_processor/metrics/android/android_startup.sql553
-rw-r--r--src/trace_processor/metrics/android/android_startup_launches.sql115
-rw-r--r--src/trace_processor/metrics/android/android_surfaceflinger.sql53
-rw-r--r--src/trace_processor/metrics/android/android_sysui_cuj.sql439
-rw-r--r--src/trace_processor/metrics/android/android_thread_time_in_state.sql206
-rw-r--r--src/trace_processor/metrics/android/cpu_info.sql50
-rw-r--r--src/trace_processor/metrics/android/g2d_duration.sql68
-rw-r--r--src/trace_processor/metrics/android/hsc_startups.sql259
-rw-r--r--src/trace_processor/metrics/android/java_heap_histogram.sql92
-rw-r--r--src/trace_processor/metrics/android/java_heap_stats.sql111
-rw-r--r--src/trace_processor/metrics/android/power_drain_in_watts.sql91
-rw-r--r--src/trace_processor/metrics/android/power_profile_data.sql1366
-rw-r--r--src/trace_processor/metrics/android/process_mem.sql111
-rw-r--r--src/trace_processor/metrics/android/process_metadata.sql85
-rw-r--r--src/trace_processor/metrics/android/span_view_stats.sql45
-rw-r--r--src/trace_processor/metrics/android/unsymbolized_frames.sql35
-rw-r--r--src/trace_processor/metrics/chrome/chrome_processes.sql128
-rw-r--r--src/trace_processor/metrics/chrome/chrome_thread_slice_with_cpu_time.sql98
-rw-r--r--src/trace_processor/metrics/chrome/rail_modes.sql562
-rw-r--r--src/trace_processor/metrics/chrome/scroll_flow_event.sql258
-rw-r--r--src/trace_processor/metrics/chrome/scroll_flow_event_queuing_delay.sql75
-rw-r--r--src/trace_processor/metrics/chrome/scroll_jank.sql303
-rw-r--r--src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_task.sql294
-rw-r--r--src/trace_processor/metrics/chrome/scroll_jank_cause_queuing_delay.sql306
-rw-r--r--src/trace_processor/metrics/experimental/blink_gc_metric.sql581
-rw-r--r--src/trace_processor/metrics/experimental/frame_times.sql184
-rw-r--r--src/trace_processor/metrics/experimental/reported_by_page.sql66
-rw-r--r--src/trace_processor/metrics/metrics.cc460
-rw-r--r--src/trace_processor/metrics/metrics.h82
-rw-r--r--src/trace_processor/metrics/metrics_unittest.cc66
-rw-r--r--src/trace_processor/metrics/protos/README.md11
-rw-r--r--src/trace_processor/metrics/sql/BUILD.gn140
-rw-r--r--src/trace_processor/metrics/sql/android/OWNERS (renamed from src/trace_processor/metrics/android/OWNERS)0
-rw-r--r--src/trace_processor/metrics/sql/android/android_batt.sql257
-rw-r--r--src/trace_processor/metrics/sql/android/android_camera.sql117
-rw-r--r--src/trace_processor/metrics/sql/android/android_camera_unagg.sql33
-rw-r--r--src/trace_processor/metrics/sql/android/android_cpu.sql (renamed from src/trace_processor/metrics/android/android_cpu.sql)0
-rw-r--r--src/trace_processor/metrics/sql/android/android_cpu_agg.sql (renamed from src/trace_processor/metrics/android/android_cpu_agg.sql)0
-rw-r--r--src/trace_processor/metrics/sql/android/android_cpu_raw_metrics_per_core.sql (renamed from src/trace_processor/metrics/android/android_cpu_raw_metrics_per_core.sql)0
-rw-r--r--src/trace_processor/metrics/sql/android/android_dma_heap.sql (renamed from src/trace_processor/metrics/android/android_dma_heap.sql)0
-rw-r--r--src/trace_processor/metrics/sql/android/android_dvfs.sql93
-rw-r--r--src/trace_processor/metrics/sql/android/android_fastrpc.sql72
-rw-r--r--src/trace_processor/metrics/sql/android/android_gpu.sql113
-rw-r--r--src/trace_processor/metrics/sql/android/android_hwcomposer.sql136
-rw-r--r--src/trace_processor/metrics/sql/android/android_hwui_metric.sql261
-rw-r--r--src/trace_processor/metrics/sql/android/android_hwui_threads.sql122
-rw-r--r--src/trace_processor/metrics/sql/android/android_ion.sql94
-rw-r--r--src/trace_processor/metrics/sql/android/android_irq_runtime.sql123
-rw-r--r--src/trace_processor/metrics/sql/android/android_jank.sql284
-rw-r--r--src/trace_processor/metrics/sql/android/android_lmk.sql100
-rw-r--r--src/trace_processor/metrics/sql/android/android_lmk_reason.sql (renamed from src/trace_processor/metrics/android/android_lmk_reason.sql)0
-rw-r--r--src/trace_processor/metrics/sql/android/android_mem.sql (renamed from src/trace_processor/metrics/android/android_mem.sql)0
-rw-r--r--src/trace_processor/metrics/sql/android/android_mem_unagg.sql (renamed from src/trace_processor/metrics/android/android_mem_unagg.sql)0
-rw-r--r--src/trace_processor/metrics/sql/android/android_multiuser.sql26
-rw-r--r--src/trace_processor/metrics/sql/android/android_multiuser_populator.sql135
-rw-r--r--src/trace_processor/metrics/sql/android/android_netperf.sql296
-rw-r--r--src/trace_processor/metrics/sql/android/android_other_traces.sql47
-rw-r--r--src/trace_processor/metrics/sql/android/android_package_list.sql (renamed from src/trace_processor/metrics/android/android_package_list.sql)0
-rw-r--r--src/trace_processor/metrics/sql/android/android_powrails.sql75
-rw-r--r--src/trace_processor/metrics/sql/android/android_proxy_power.sql (renamed from src/trace_processor/metrics/android/android_proxy_power.sql)0
-rw-r--r--src/trace_processor/metrics/sql/android/android_rt_runtime.sql46
-rw-r--r--src/trace_processor/metrics/sql/android/android_simpleperf.sql40
-rw-r--r--src/trace_processor/metrics/sql/android/android_startup.sql529
-rw-r--r--src/trace_processor/metrics/sql/android/android_surfaceflinger.sql103
-rw-r--r--src/trace_processor/metrics/sql/android/android_sysui_cuj.sql487
-rw-r--r--src/trace_processor/metrics/sql/android/android_sysui_cuj_jank_query.sql50
-rw-r--r--src/trace_processor/metrics/sql/android/android_sysui_cuj_surfaceflinger.sql260
-rw-r--r--src/trace_processor/metrics/sql/android/android_task_names.sql (renamed from src/trace_processor/metrics/android/android_task_names.sql)0
-rw-r--r--src/trace_processor/metrics/sql/android/android_thread_time_in_state.sql197
-rw-r--r--src/trace_processor/metrics/sql/android/android_trace_quality.sql35
-rw-r--r--src/trace_processor/metrics/sql/android/android_trusty_workqueues.sql21
-rw-r--r--src/trace_processor/metrics/sql/android/composer_execution.sql (renamed from src/trace_processor/metrics/android/composer_execution.sql)0
-rw-r--r--src/trace_processor/metrics/sql/android/composition_layers.sql (renamed from src/trace_processor/metrics/android/composition_layers.sql)0
-rw-r--r--src/trace_processor/metrics/sql/android/cpu_info.sql50
-rw-r--r--src/trace_processor/metrics/sql/android/display_metrics.sql (renamed from src/trace_processor/metrics/android/display_metrics.sql)0
-rw-r--r--src/trace_processor/metrics/sql/android/frame_missed.sql (renamed from src/trace_processor/metrics/android/frame_missed.sql)0
-rw-r--r--src/trace_processor/metrics/sql/android/g2d.sql (renamed from src/trace_processor/metrics/android/g2d.sql)0
-rw-r--r--src/trace_processor/metrics/sql/android/g2d_duration.sql68
-rw-r--r--src/trace_processor/metrics/sql/android/global_counter_span_view.sql (renamed from src/trace_processor/metrics/android/global_counter_span_view.sql)0
-rw-r--r--src/trace_processor/metrics/sql/android/gpu_counter_span_view.sql27
-rw-r--r--src/trace_processor/metrics/sql/android/java_heap_histogram.sql99
-rw-r--r--src/trace_processor/metrics/sql/android/java_heap_stats.sql115
-rw-r--r--src/trace_processor/metrics/sql/android/mem_stats_priority_breakdown.sql (renamed from src/trace_processor/metrics/android/mem_stats_priority_breakdown.sql)0
-rw-r--r--src/trace_processor/metrics/sql/android/power_drain_in_watts.sql90
-rw-r--r--src/trace_processor/metrics/sql/android/power_profile_data.sql1592
-rw-r--r--src/trace_processor/metrics/sql/android/process_counter_span_view.sql (renamed from src/trace_processor/metrics/android/process_counter_span_view.sql)0
-rw-r--r--src/trace_processor/metrics/sql/android/process_mem.sql115
-rw-r--r--src/trace_processor/metrics/sql/android/process_metadata.sql86
-rw-r--r--src/trace_processor/metrics/sql/android/process_oom_score.sql (renamed from src/trace_processor/metrics/android/process_oom_score.sql)0
-rw-r--r--src/trace_processor/metrics/sql/android/process_unagg_mem_view.sql (renamed from src/trace_processor/metrics/android/process_unagg_mem_view.sql)0
-rw-r--r--src/trace_processor/metrics/sql/android/profiler_smaps.sql53
-rw-r--r--src/trace_processor/metrics/sql/android/span_view_stats.sql71
-rw-r--r--src/trace_processor/metrics/sql/android/startup/hsc.sql259
-rw-r--r--src/trace_processor/metrics/sql/android/startup/launches.sql100
-rw-r--r--src/trace_processor/metrics/sql/android/startup/launches_maxsdk28.sql28
-rw-r--r--src/trace_processor/metrics/sql/android/startup/launches_minsdk29.sql73
-rw-r--r--src/trace_processor/metrics/sql/android/startup/launches_minsdk33.sql47
-rw-r--r--src/trace_processor/metrics/sql/android/thread_counter_span_view.sql32
-rw-r--r--src/trace_processor/metrics/sql/android/unsymbolized_frames.sql75
-rw-r--r--src/trace_processor/metrics/sql/chrome/OWNERS (renamed from src/trace_processor/metrics/chrome/OWNERS)0
-rw-r--r--src/trace_processor/metrics/sql/chrome/actual_power_by_category.sql (renamed from src/trace_processor/metrics/chrome/actual_power_by_category.sql)0
-rw-r--r--src/trace_processor/metrics/sql/chrome/actual_power_by_rail_mode.sql (renamed from src/trace_processor/metrics/chrome/actual_power_by_rail_mode.sql)0
-rw-r--r--src/trace_processor/metrics/sql/chrome/chrome_event_metadata.sql (renamed from src/trace_processor/metrics/chrome/chrome_event_metadata.sql)0
-rw-r--r--src/trace_processor/metrics/sql/chrome/chrome_histogram_hashes.sql26
-rw-r--r--src/trace_processor/metrics/sql/chrome/chrome_performance_mark_hashes.sql33
-rw-r--r--src/trace_processor/metrics/sql/chrome/chrome_processes.sql126
-rw-r--r--src/trace_processor/metrics/sql/chrome/chrome_slice_names.sql32
-rw-r--r--src/trace_processor/metrics/sql/chrome/chrome_thread_slice.sql38
-rw-r--r--src/trace_processor/metrics/sql/chrome/chrome_user_event_hashes.sql26
-rw-r--r--src/trace_processor/metrics/sql/chrome/cpu_time_by_category.sql (renamed from src/trace_processor/metrics/chrome/cpu_time_by_category.sql)0
-rw-r--r--src/trace_processor/metrics/sql/chrome/cpu_time_by_rail_mode.sql (renamed from src/trace_processor/metrics/chrome/cpu_time_by_rail_mode.sql)0
-rw-r--r--src/trace_processor/metrics/sql/chrome/estimated_power_by_category.sql (renamed from src/trace_processor/metrics/chrome/estimated_power_by_category.sql)0
-rw-r--r--src/trace_processor/metrics/sql/chrome/estimated_power_by_rail_mode.sql (renamed from src/trace_processor/metrics/chrome/estimated_power_by_rail_mode.sql)0
-rw-r--r--src/trace_processor/metrics/sql/chrome/gesture_flow_event.sql262
-rw-r--r--src/trace_processor/metrics/sql/chrome/gesture_flow_event_queuing_delay.sql76
-rw-r--r--src/trace_processor/metrics/sql/chrome/gesture_jank.sql293
-rw-r--r--src/trace_processor/metrics/sql/chrome/jank_utilities.sql83
-rw-r--r--src/trace_processor/metrics/sql/chrome/rail_modes.sql562
-rw-r--r--src/trace_processor/metrics/sql/chrome/scroll_flow_event.sql31
-rw-r--r--src/trace_processor/metrics/sql/chrome/scroll_flow_event_queuing_delay.sql27
-rw-r--r--src/trace_processor/metrics/sql/chrome/scroll_jank.sql38
-rw-r--r--src/trace_processor/metrics/sql/chrome/scroll_jank_cause.sql (renamed from src/trace_processor/metrics/chrome/scroll_jank_cause.sql)0
-rw-r--r--src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_task.sql294
-rw-r--r--src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_touch_move.sql (renamed from src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_touch_move.sql)0
-rw-r--r--src/trace_processor/metrics/sql/chrome/scroll_jank_cause_get_bitmap.sql (renamed from src/trace_processor/metrics/chrome/scroll_jank_cause_get_bitmap.sql)0
-rw-r--r--src/trace_processor/metrics/sql/chrome/scroll_jank_cause_queuing_delay.sql512
-rw-r--r--src/trace_processor/metrics/sql/chrome/sufficient_chrome_processes.sql48
-rw-r--r--src/trace_processor/metrics/sql/chrome/test_chrome_metric.sql (renamed from src/trace_processor/metrics/chrome/test_chrome_metric.sql)0
-rw-r--r--src/trace_processor/metrics/sql/chrome/touch_flow_event.sql31
-rw-r--r--src/trace_processor/metrics/sql/chrome/touch_flow_event_queuing_delay.sql26
-rw-r--r--src/trace_processor/metrics/sql/chrome/touch_jank.sql33
-rw-r--r--src/trace_processor/metrics/sql/experimental/OWNERS0
-rw-r--r--src/trace_processor/metrics/sql/experimental/blink_gc_metric.sql581
-rw-r--r--src/trace_processor/metrics/sql/experimental/chrome_dropped_frames.sql93
-rw-r--r--src/trace_processor/metrics/sql/experimental/chrome_long_latency.sql104
-rw-r--r--src/trace_processor/metrics/sql/experimental/frame_times.sql184
-rw-r--r--src/trace_processor/metrics/sql/experimental/media_metric.sql (renamed from src/trace_processor/metrics/experimental/media_metric.sql)0
-rw-r--r--src/trace_processor/metrics/sql/experimental/reported_by_page.sql66
-rw-r--r--src/trace_processor/metrics/sql/trace_metadata.sql61
-rw-r--r--src/trace_processor/metrics/sql/trace_stats.sql39
-rw-r--r--src/trace_processor/metrics/sql/webview/webview_power_usage.sql276
-rw-r--r--src/trace_processor/metrics/trace_metadata.sql49
-rw-r--r--src/trace_processor/metrics/trace_stats.sql39
-rw-r--r--src/trace_processor/metrics/webview/webview_power_usage.sql278
-rw-r--r--src/trace_processor/python/example.py68
-rw-r--r--src/trace_processor/python/perfetto/trace_processor/__init__.py17
-rw-r--r--src/trace_processor/python/perfetto/trace_processor/api.py245
-rw-r--r--src/trace_processor/python/perfetto/trace_processor/http.py74
-rw-r--r--src/trace_processor/python/perfetto/trace_processor/loader.py88
-rw-r--r--src/trace_processor/python/perfetto/trace_processor/metrics.descriptor572
-rw-r--r--src/trace_processor/python/perfetto/trace_processor/metrics.descriptor.sha16
-rw-r--r--src/trace_processor/python/perfetto/trace_processor/protos.py61
-rw-r--r--src/trace_processor/python/perfetto/trace_processor/shell.py46
-rw-r--r--src/trace_processor/python/perfetto/trace_processor/trace_processor.descriptorbin4304 -> 0 bytes
-rw-r--r--src/trace_processor/python/perfetto/trace_processor/trace_processor.descriptor.sha16
-rw-r--r--src/trace_processor/python/setup.py29
-rw-r--r--src/trace_processor/read_trace.cc171
-rw-r--r--src/trace_processor/read_trace_integrationtest.cc2
-rw-r--r--src/trace_processor/ref_counted_unittest.cc161
-rw-r--r--src/trace_processor/rpc/BUILD.gn10
-rw-r--r--src/trace_processor/rpc/httpd.cc437
-rw-r--r--src/trace_processor/rpc/proto_ring_buffer.cc188
-rw-r--r--src/trace_processor/rpc/proto_ring_buffer.h139
-rw-r--r--src/trace_processor/rpc/proto_ring_buffer_unittest.cc232
-rw-r--r--src/trace_processor/rpc/query_result_serializer.cc12
-rw-r--r--src/trace_processor/rpc/query_result_serializer.h7
-rw-r--r--src/trace_processor/rpc/query_result_serializer_unittest.cc2
-rw-r--r--src/trace_processor/rpc/rpc.cc357
-rw-r--r--src/trace_processor/rpc/rpc.h68
-rw-r--r--src/trace_processor/rpc/wasm_bridge.cc93
-rw-r--r--src/trace_processor/sqlite/BUILD.gn10
-rw-r--r--src/trace_processor/sqlite/create_function.cc254
-rw-r--r--src/trace_processor/sqlite/create_function.h67
-rw-r--r--src/trace_processor/sqlite/create_function_internal.cc169
-rw-r--r--src/trace_processor/sqlite/create_function_internal.h79
-rw-r--r--src/trace_processor/sqlite/create_view_function.cc349
-rw-r--r--src/trace_processor/sqlite/create_view_function.h49
-rw-r--r--src/trace_processor/sqlite/db_sqlite_table.cc125
-rw-r--r--src/trace_processor/sqlite/db_sqlite_table.h16
-rw-r--r--src/trace_processor/sqlite/query_constraints.cc92
-rw-r--r--src/trace_processor/sqlite/query_constraints.h14
-rw-r--r--src/trace_processor/sqlite/query_constraints_unittest.cc32
-rw-r--r--src/trace_processor/sqlite/register_function.cc29
-rw-r--r--src/trace_processor/sqlite/register_function.h191
-rw-r--r--src/trace_processor/sqlite/scoped_db.h7
-rw-r--r--src/trace_processor/sqlite/span_join_operator_table.cc53
-rw-r--r--src/trace_processor/sqlite/span_join_operator_table.h6
-rw-r--r--src/trace_processor/sqlite/sql_stats_table.cc7
-rw-r--r--src/trace_processor/sqlite/sql_stats_table.h7
-rw-r--r--src/trace_processor/sqlite/sqlite_raw_table.cc227
-rw-r--r--src/trace_processor/sqlite/sqlite_raw_table.h6
-rw-r--r--src/trace_processor/sqlite/sqlite_table.cc69
-rw-r--r--src/trace_processor/sqlite/sqlite_table.h2
-rw-r--r--src/trace_processor/sqlite/sqlite_utils.h419
-rw-r--r--src/trace_processor/storage/metadata.h24
-rw-r--r--src/trace_processor/storage/stats.h43
-rw-r--r--src/trace_processor/storage/trace_storage.cc3
-rw-r--r--src/trace_processor/storage/trace_storage.h16
-rw-r--r--src/trace_processor/tables/android_tables.h2
-rw-r--r--src/trace_processor/tables/metadata_tables.h69
-rw-r--r--src/trace_processor/tables/profiler_tables.h16
-rw-r--r--src/trace_processor/tables/slice_tables.h24
-rw-r--r--src/trace_processor/tables/table_destructors.cc1
-rw-r--r--src/trace_processor/tables/track_tables.h4
-rw-r--r--src/trace_processor/timestamped_trace_piece.h54
-rw-r--r--src/trace_processor/tp_metatrace.h4
-rw-r--r--src/trace_processor/trace_blob.cc107
-rw-r--r--src/trace_processor/trace_database_integrationtest.cc144
-rw-r--r--src/trace_processor/trace_processor_context.cc2
-rw-r--r--src/trace_processor/trace_processor_impl.cc676
-rw-r--r--src/trace_processor/trace_processor_impl.h44
-rw-r--r--src/trace_processor/trace_processor_shell.cc756
-rw-r--r--src/trace_processor/trace_processor_storage.cc6
-rw-r--r--src/trace_processor/trace_processor_storage_impl.cc28
-rw-r--r--src/trace_processor/trace_processor_storage_impl.h5
-rw-r--r--src/trace_processor/trace_sorter.cc74
-rw-r--r--src/trace_processor/trace_sorter.h213
-rw-r--r--src/trace_processor/trace_sorter_unittest.cc173
-rw-r--r--src/trace_processor/types/BUILD.gn1
-rw-r--r--src/trace_processor/types/tcp_state.h59
-rw-r--r--src/trace_processor/types/trace_processor_context.h11
-rw-r--r--src/trace_processor/types/variadic.h13
-rw-r--r--src/trace_processor/util/BUILD.gn45
-rw-r--r--src/trace_processor/util/debug_annotation_parser.cc245
-rw-r--r--src/trace_processor/util/debug_annotation_parser.h66
-rw-r--r--src/trace_processor/util/debug_annotation_parser_unittest.cc271
-rw-r--r--src/trace_processor/util/descriptors.cc52
-rw-r--r--src/trace_processor/util/descriptors.h47
-rw-r--r--src/trace_processor/util/gzip_utils.cc117
-rw-r--r--src/trace_processor/util/gzip_utils.h120
-rw-r--r--src/trace_processor/util/gzip_utils_unittest.cc145
-rw-r--r--src/trace_processor/util/interned_message_view.h136
-rw-r--r--src/trace_processor/util/proto_to_args_parser.cc158
-rw-r--r--src/trace_processor/util/proto_to_args_parser.h151
-rw-r--r--src/trace_processor/util/proto_to_args_parser_unittest.cc182
-rw-r--r--src/trace_processor/util/proto_to_json.cc39
-rw-r--r--src/trace_processor/util/protozero_to_text.cc451
-rw-r--r--src/trace_processor/util/protozero_to_text.h18
-rw-r--r--src/trace_processor/util/protozero_to_text_unittests.cc544
-rw-r--r--src/tracebox/BUILD.gn30
-rw-r--r--src/tracebox/tracebox.cc197
-rw-r--r--src/traced/probes/BUILD.gn1
-rw-r--r--src/traced/probes/android_log/android_log_data_source.cc3
-rw-r--r--src/traced/probes/common/BUILD.gn2
-rw-r--r--src/traced/probes/common/cpu_freq_info.cc37
-rw-r--r--src/traced/probes/common/cpu_freq_info.h6
-rw-r--r--src/traced/probes/common/cpu_freq_info_for_testing.cc59
-rw-r--r--src/traced/probes/common/cpu_freq_info_for_testing.h16
-rw-r--r--src/traced/probes/filesystem/inode_file_data_source.cc3
-rw-r--r--src/traced/probes/filesystem/inode_file_data_source.h2
-rw-r--r--src/traced/probes/filesystem/inode_file_data_source_unittest.cc2
-rw-r--r--src/traced/probes/ftrace/BUILD.gn1
-rw-r--r--src/traced/probes/ftrace/OWNERS5
-rw-r--r--src/traced/probes/ftrace/atrace_wrapper.cc46
-rw-r--r--src/traced/probes/ftrace/atrace_wrapper.h15
-rw-r--r--src/traced/probes/ftrace/cpu_reader.cc123
-rw-r--r--src/traced/probes/ftrace/cpu_reader.h32
-rw-r--r--src/traced/probes/ftrace/cpu_reader_benchmark.cc5
-rw-r--r--src/traced/probes/ftrace/cpu_reader_fuzzer.cc10
-rw-r--r--src/traced/probes/ftrace/cpu_reader_unittest.cc369
-rw-r--r--src/traced/probes/ftrace/event_info.cc1152
-rw-r--r--src/traced/probes/ftrace/ftrace_config_muxer.cc430
-rw-r--r--src/traced/probes/ftrace/ftrace_config_muxer.h23
-rw-r--r--src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc260
-rw-r--r--src/traced/probes/ftrace/ftrace_controller.cc97
-rw-r--r--src/traced/probes/ftrace/ftrace_controller.h21
-rw-r--r--src/traced/probes/ftrace/ftrace_data_source.cc51
-rw-r--r--src/traced/probes/ftrace/ftrace_data_source.h7
-rw-r--r--src/traced/probes/ftrace/ftrace_metadata.h4
-rw-r--r--src/traced/probes/ftrace/ftrace_procfs.cc141
-rw-r--r--src/traced/probes/ftrace/ftrace_procfs.h32
-rw-r--r--src/traced/probes/ftrace/ftrace_stats.cc6
-rw-r--r--src/traced/probes/ftrace/ftrace_stats.h11
-rw-r--r--src/traced/probes/ftrace/printk_formats_parser.cc3
-rw-r--r--src/traced/probes/ftrace/proto_translation_table.cc20
-rw-r--r--src/traced/probes/ftrace/proto_translation_table_unittest.cc8
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/available_events1533
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/alarmtimer/alarmtimer_cancel/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/alarmtimer/alarmtimer_fired/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/alarmtimer/alarmtimer_start/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/alarmtimer/alarmtimer_suspend/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/android_fs/android_fs_dataread_end/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/android_fs/android_fs_dataread_start/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/android_fs/android_fs_datawrite_end/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/android_fs/android_fs_datawrite_start/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_bias_level_done/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_bias_level_start/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_connected/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_done/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_path/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_start/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_walk_done/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_widget_event_done/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_widget_event_start/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_widget_power/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_jack_irq/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_jack_notify/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_jack_report/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/avc/selinux_audited/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_alloc_lru_end/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_alloc_lru_start/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_alloc_page_end/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_alloc_page_start/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_command/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_free_lru_end/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_free_lru_start/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_ioctl/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_ioctl_done/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_lock/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_locked/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_read_done/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_return/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_set_priority/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_alloc_buf/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_buffer_release/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_failed_buffer_release/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_fd_recv/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_fd_send/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_node_to_ref/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_received/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_ref_to_node/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_ref_to_ref/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_unlock/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_unmap_kernel_end/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_unmap_kernel_start/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_unmap_user_end/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_unmap_user_start/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_update_page_range/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_wait_for_work/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_write_done/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_backmerge/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_bounce/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_complete/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_frontmerge/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_queue/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_remap/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_dirty_buffer/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_getrq/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_plug/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_complete/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_insert/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_issue/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_merge/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_remap/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_requeue/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_sleeprq/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_split/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_touch_buffer/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_unplug/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bpf_test_run/bpf_test_finish/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bpf_trace/bpf_trace_printk/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bridge/br_fdb_add/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bridge/br_fdb_external_learn_add/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bridge/br_fdb_update/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bridge/fdb_delete/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_cac_event/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ch_switch_notify/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ch_switch_started_notify/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_chandef_dfs_required/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_control_port_tx_status/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_cqm_pktloss_notify/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_cqm_rssi_notify/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_del_sta/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ft_event/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_get_bss/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_gtk_rekey_notify/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ibss_joined/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_inform_bss_frame/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_mgmt_tx_status/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_michael_mic_failure/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_new_sta/format27
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_notify_new_peer_candidate/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_pmksa_candidate_notify/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_pmsr_complete/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_pmsr_report/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_probe_status/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_radar_event/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ready_on_channel/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ready_on_channel_expired/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_reg_can_beacon/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_report_obss_beacon/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_report_wowlan_wakeup/format22
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_return_bool/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_return_bss/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_return_u32/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_return_uint/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_control_port/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_mgmt/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_mlme_mgmt/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_spurious_frame/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_unexpected_4addr_frame/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_unprot_mlme_mgmt/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_scan_done/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_sched_scan_results/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_sched_scan_stopped/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_send_assoc_timeout/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_send_auth_timeout/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_send_rx_assoc/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_send_rx_auth/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_stop_iface/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_tdls_oper_request/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_tx_mgmt_expired/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_tx_mlme_mgmt/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_update_owe_info_event/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_abort_pmsr/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_abort_scan/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_key/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_mpath/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_nan_func/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_station/format33
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_tx_ts/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_virtual_intf/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_assoc/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_auth/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_cancel_remain_on_channel/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_change_beacon/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_change_bss/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_change_mpath/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_change_station/format33
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_change_virtual_intf/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_channel_switch/format25
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_connect/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_crit_proto_start/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_crit_proto_stop/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_deauth/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_key/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_mpath/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_nan_func/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_pmk/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_pmksa/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_station/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_tx_ts/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_virtual_intf/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_disassoc/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_disconnect/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_dump_mpath/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_dump_mpp/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_dump_station/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_dump_survey/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_end_cac/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_external_auth/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_flush_pmksa/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_antenna/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_channel/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_ftm_responder_stats/format23
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_key/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_mesh_config/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_mpath/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_mpp/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_station/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_tx_power/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_txq_stats/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_join_ibss/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_join_mesh/format39
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_join_ocb/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_leave_ibss/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_leave_mesh/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_leave_ocb/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_libertas_set_mesh_channel/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_mgmt_tx/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_mgmt_tx_cancel_wait/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_nan_change_conf/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_probe_client/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_probe_mesh_link/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_remain_on_channel/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_reset_tid_config/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_resume/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_chandef/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_cookie/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_int/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_mesh_config/format38
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_mpath_info/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_station_info/format26
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_survey_info/format23
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_tx_rx/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_void/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_void_tx_rx/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_wdev/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_rfkill_poll/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_scan/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_sched_scan_start/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_sched_scan_stop/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_antenna/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_ap_chanwidth/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_bitrate_mask/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_coalesce/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_cqm_rssi_config/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_cqm_rssi_range_config/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_cqm_txe_config/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_default_beacon_key/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_default_key/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_default_mgmt_key/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_mac_acl/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_mcast_rate/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_monitor_channel/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_multicast_to_unicast/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_noack_map/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_pmk/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_pmksa/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_power_mgmt/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_qos_map/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_rekey_data/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_tid_config/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_tx_power/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_txq_params/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_wakeup/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_wds_peer/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_wiphy_params/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_start_ap/format28
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_start_nan/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_start_p2p_device/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_start_pmsr/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_start_radar_detection/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_stop_ap/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_stop_nan/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_stop_p2p_device/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_suspend/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_tdls_cancel_channel_switch/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_tdls_channel_switch/format22
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_tdls_mgmt/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_tdls_oper/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_testmode_cmd/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_testmode_dump/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_tx_control_port/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_update_connect_params/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_update_ft_ies/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_update_mesh_config/format40
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_update_mgmt_frame_registrations/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_update_owe_info/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_add_virtual_intf/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_del_virtual_intf/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_resume/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_return_int/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_ackreq_default/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_backoff_exponent/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_cca_ed_level/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_cca_mode/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_channel/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_csma_backoffs/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_lbt_mode/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_max_frame_retries/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_pan_id/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_short_addr/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_tx_power/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_suspend/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_attach_task/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_destroy_root/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_freeze/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_mkdir/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_notify_frozen/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_notify_populated/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_release/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_remount/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_rename/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_rmdir/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_setup_root/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_transfer_tasks/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_unfreeze/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_disable/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_disable_complete/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_enable/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_enable_complete/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_prepare/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_prepare_complete/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_duty_cycle/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_duty_cycle_complete/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_parent/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_parent_complete/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_phase/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_phase_complete/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_rate/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_rate_complete/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_unprepare/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_unprepare_complete/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cma/cma_alloc_busy_retry/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cma/cma_alloc_finish/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cma/cma_alloc_info/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cma/cma_alloc_start/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cma/cma_release/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_begin/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_defer_compaction/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_defer_reset/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_deferred/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_end/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_finished/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_isolate_freepages/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_isolate_migratepages/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_kcompactd_sleep/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_kcompactd_wake/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_migratepages/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_suitable/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_try_to_compact_pages/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_wakeup_kcompactd/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cpuhp/cpuhp_enter/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cpuhp/cpuhp_exit/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cpuhp/cpuhp_multi_enter/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cpuhp/cpuhp_pause/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/devfreq/devfreq_monitor/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/devfreq/dvfs_read_ppc/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/devfreq/dvfs_update_load/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_destroy/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_emit/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_enable_signal/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_init/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_signaled/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_wait_end/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_wait_start/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dmabuf_heap/dma_heap_stat/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dpu/tracing_mark_write/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/drm/drm_vblank_event/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/drm/drm_vblank_event_delivered/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/drm/drm_vblank_event_queued/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_adjust_tx_power/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_check_operational_state/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_coex_gpio/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_coex_gpio_start/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_coex_gpio_stop/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_deep_sleep/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_deep_sleep_enter/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_get_counters_first_part/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_get_counters_second_part/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_isr/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_get_timestamp/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_idle/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_reset/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_rx_disable/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_rx_enable/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_rx_get_error_frame/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_rx_get_frame/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_set_channel/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_set_hw_addr_filt/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_set_sts_params/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_start/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_stop/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_tx_frame/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_clock_offset_payload_put/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_clock_sync_payload_put/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_disable/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_enable/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_err/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_header_check/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_isr/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_rx_msg_info/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_sleep/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_warn/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_watchdog/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_power_stats/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_rctu_convert_align/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_rctu_convert_rx/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_rctu_convert_synced/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_rctu_convert_tx/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_read_clockoffset/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_read_pdoa/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_read_rx_timestamp/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_resync_dtu_sys_time/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_return_int/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_return_int_u32/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_return_int_u64/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_return_void/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_rx_rssi/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_set_antenna_gpio/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_set_operational_state/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_set_pdoa/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_testmode_continuous_tx_start/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_testmode_continuous_tx_stop/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_tm_cmd/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_wakeup/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_wakeup_done/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_wakeup_timer_start/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_alloc_request/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_complete_trb/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_ctrl_req/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_ep_dequeue/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_ep_queue/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_event/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_free_request/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_gadget_ep_cmd/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_gadget_ep_disable/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_gadget_ep_enable/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_gadget_generic_cmd/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_gadget_giveback/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_prepare_trb/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_readl/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_writel/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/edgetpu/edgetpu_map_buffer_end/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/edgetpu/edgetpu_map_buffer_start/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/edgetpu/edgetpu_map_dmabuf_end/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/edgetpu/edgetpu_map_dmabuf_start/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/emulation/instruction_emulation/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_destroy_inode/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_fill_inode/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_lookup/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_map_blocks_flatmode_enter/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_map_blocks_flatmode_exit/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_readpage/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_readpages/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/z_erofs_map_blocks_iter_enter/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/z_erofs_map_blocks_iter_exit/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/error_report/error_report_end/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_alloc_da_blocks/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_allocate_blocks/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_allocate_inode/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_begin_ordered_truncate/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_collapse_range/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_release_space/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_reserve_space/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_update_reserve_space/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_write_begin/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_write_end/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_write_pages/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_write_pages_extent/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_direct_IO_enter/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_direct_IO_exit/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_discard_blocks/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_discard_preallocations/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_drop_inode/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_error/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_cache_extent/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_find_extent_range_enter/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_find_extent_range_exit/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_insert_delayed_block/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_insert_extent/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_lookup_extent_enter/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_lookup_extent_exit/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_remove_extent/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_shrink/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_shrink_count/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_shrink_scan_enter/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_shrink_scan_exit/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_evict_inode/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_convert_to_initialized_enter/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_convert_to_initialized_fastpath/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_handle_unwritten_extents/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_in_cache/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_load_extent/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_map_blocks_enter/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_map_blocks_exit/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_put_in_cache/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_remove_space/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_remove_space_done/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_rm_idx/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_rm_leaf/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_show_extent/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fallocate_enter/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fallocate_exit/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_commit_start/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_commit_stop/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_replay/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_replay_scan/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_stats/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_track_create/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_track_inode/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_track_link/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_track_range/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_track_unlink/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_find_delalloc_range/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_forget/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_free_blocks/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_free_inode/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fsmap_high_key/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fsmap_low_key/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fsmap_mapping/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_get_implied_cluster_alloc_exit/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_get_reserved_cluster_alloc/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_getfsmap_high_key/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_getfsmap_low_key/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_getfsmap_mapping/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ind_map_blocks_enter/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ind_map_blocks_exit/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_insert_range/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_invalidatepage/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_journal_start/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_journal_start_reserved/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_journalled_invalidatepage/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_journalled_write_end/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_lazy_itable_init/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_load_inode/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_load_inode_bitmap/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mark_inode_dirty/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_bitmap_load/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_buddy_bitmap_load/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_discard_preallocations/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_new_group_pa/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_new_inode_pa/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_release_group_pa/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_release_inode_pa/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mballoc_alloc/format30
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mballoc_discard/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mballoc_free/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mballoc_prealloc/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_nfs_commit_metadata/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_other_inode_update_time/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_prefetch_bitmaps/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_punch_hole/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_read_block_bitmap_load/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_readpage/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_releasepage/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_remove_blocks/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_request_blocks/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_request_inode/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_shutdown/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_sync_file_enter/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_sync_file_exit/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_sync_fs/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_trim_all_free/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_trim_extent/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_truncate_enter/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_truncate_exit/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_unlink_enter/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_unlink_exit/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_write_begin/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_write_end/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_writepage/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_writepages/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_writepages_result/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_zero_range/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_background_gc/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_bmap/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_commit_inmem_page/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_compress_pages_end/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_compress_pages_start/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_decompress_pages_end/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_decompress_pages_start/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_destroy_extent_tree/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_direct_IO_enter/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_direct_IO_exit/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_do_write_data_page/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_drop_inode/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_evict_inode/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_fallocate/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_fiemap/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_file_write_iter/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_filemap_fault/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_gc_begin/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_gc_end/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_get_victim/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_iget/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_iget_exit/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_iostat/format33
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_issue_discard/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_issue_flush/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_issue_reset_zone/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_lookup_end/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_lookup_extent_tree_end/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_lookup_extent_tree_start/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_lookup_start/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_map_blocks/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_new_inode/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_prepare_read_bio/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_prepare_write_bio/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_queue_discard/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_readdir/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_readpage/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_readpages/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_register_inmem_page/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_remove_discard/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_reserve_new_blocks/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_set_page_dirty/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_shrink_extent_tree/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_shutdown/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_submit_page_bio/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_submit_page_write/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_submit_read_bio/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_submit_write_bio/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_sync_dirty_inodes_enter/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_sync_dirty_inodes_exit/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_sync_file_enter/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_sync_file_exit/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_sync_fs/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_blocks_enter/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_blocks_exit/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_data_blocks_range/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_inode_blocks_enter/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_inode_blocks_exit/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_node/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_nodes_enter/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_nodes_exit/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_partial_nodes/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_unlink_enter/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_unlink_exit/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_update_extent_tree_range/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_vm_page_mkwrite/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_write_begin/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_write_checkpoint/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_write_end/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_writepage/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_writepages/format26
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/fib/fib_table_lookup/format25
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/fib6/fib6_table_lookup/format25
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/break_lease_block/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/break_lease_noblock/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/break_lease_unblock/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/fcntl_setlk/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/flock_lock_inode/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/generic_add_lease/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/generic_delete_lease/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/leases_conflict/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/locks_get_lock_context/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/locks_remove_posix/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/posix_lock_inode/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/time_out_leases/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filemap/file_check_and_advance_wb_err/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filemap/filemap_set_wb_err/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filemap/mm_filemap_add_to_page_cache/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filemap/mm_filemap_delete_from_page_cache/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/bprint/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/bputs/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/branch/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/context_switch/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/funcgraph_entry/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/funcgraph_exit/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/function/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/hwlat/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/kernel_stack/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/mmiotrace_map/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/mmiotrace_rw/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/print/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/raw_data/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/user_stack/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/wakeup/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/g2d/g2d_perf_update_qos/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/g2d/tracing_mark_write/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_alloc_request/format22
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_clear_halt/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_dequeue/format22
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_disable/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_enable/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_fifo_flush/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_fifo_status/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_free_request/format22
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_queue/format22
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_set_halt/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_set_maxpacket_limit/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_set_wedge/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_activate/format29
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_clear_selfpowered/format29
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_connect/format29
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_deactivate/format29
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_disconnect/format29
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_frame_number/format29
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_giveback_request/format22
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_set_selfpowered/format29
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_vbus_connect/format29
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_vbus_disconnect/format29
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_vbus_draw/format29
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_wakeup/format29
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gpio/gpio_direction/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gpio/gpio_value/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gpu_mem/gpu_mem_total/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/header_event9
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/header_page4
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/huge_memory/mm_collapse_huge_page/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/huge_memory/mm_collapse_huge_page_isolate/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/huge_memory/mm_collapse_huge_page_swapin/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/huge_memory/mm_khugepaged_scan_pmd/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/i2c/i2c_read/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/i2c/i2c_reply/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/i2c/i2c_result/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/i2c/i2c_write/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/initcall/initcall_finish/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/initcall/initcall_level/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/initcall/initcall_start/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/interconnect/icc_set_bw/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/interconnect/icc_set_bw_end/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_complete/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_cqring_wait/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_create/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_defer/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_fail_link/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_file_get/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_link/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_poll_arm/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_poll_wake/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_queue_async_work/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_register/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_submit_sqe/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_task_add/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_task_run/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_inuse_adjust/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_inuse_shortage/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_inuse_transfer/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_ioc_vrate_adj/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_iocg_activate/format22
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_iocg_forgive_debt/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_apply/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_apply_dstmap/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_apply_srcmap/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_dio_invalidate_fail/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_invalidatepage/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_readahead/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_readpage/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_releasepage/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_writepage/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/add_device_to_group/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/attach_device_to_domain/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/detach_device_from_domain/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/io_page_fault/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/map/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/remove_device_from_group/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/unmap/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ipi/ipi_entry/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ipi/ipi_exit/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ipi/ipi_raise/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/irq_handler_entry/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/irq_handler_exit/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/softirq_entry/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/softirq_exit/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/softirq_raise/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/tasklet_entry/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/tasklet_exit/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/tasklet_hi_entry/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/tasklet_hi_exit/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_checkpoint/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_checkpoint_stats/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_commit_flushing/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_commit_locking/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_commit_logging/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_drop_transaction/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_end_commit/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_handle_extend/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_handle_restart/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_handle_start/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_handle_stats/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_lock_buffer_stall/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_run_stats/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_start_commit/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_submit_inode_data/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_update_log_tail/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_write_superblock/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kfree/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kmalloc/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kmalloc_node/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kmem_cache_alloc/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kmem_cache_alloc_node/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kmem_cache_free/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_alloc/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_alloc_extfrag/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_alloc_zone_locked/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_free/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_free_batched/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_pcpu_drain/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/rss_stat/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_access_fault/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_ack_irq/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_age_hva/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_age_page/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_arm_clear_debug/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_arm_set_dreg32/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_arm_set_regset/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_arm_setup_debug/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_entry/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_exit/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_fpu/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_get_timer_map/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_guest_fault/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_halt_poll_ns/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_handle_sys_reg/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_hvc_arm64/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_irq_line/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_mmio/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_mmio_emulate/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_set_guest_debug/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_set_irq/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_set_spte_hva/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_set_way_flush/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_sys_access/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_test_age_hva/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_timer_emulate/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_timer_hrtimer_expire/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_timer_restore_state/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_timer_save_state/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_timer_update_irq/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_toggle_cache/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_unmap_hva_range/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_userspace_exit/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_vcpu_wakeup/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_wfx_arm64/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/trap_reg/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/vgic_update_irq_pending/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kyber/kyber_adjust/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kyber/kyber_latency/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kyber/kyber_throttled/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/delete_session/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/delete_tunnel/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/free_session/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/free_tunnel/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/register_session/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/register_tunnel/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_pkt_expired/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_pkt_oos/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_pkt_outside_rx_window/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_seqnum_lns_disable/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_seqnum_lns_enable/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_seqnum_reset/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_seqnum_update/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_beacon_loss/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_chswitch_done/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_connection_loss/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_cqm_beacon_loss_notify/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_cqm_rssi_notify/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_enable_rssi_reports/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_eosp/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_gtk_rekey_notify/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_radar_detected/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_ready_on_channel/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_remain_on_channel_expired/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_restart_hw/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_scan_completed/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_sched_scan_results/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_sched_scan_stopped/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_send_eosp_nullfunc/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_sta_block_awake/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_sta_set_buffered/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_start_tx_ba_cb/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_start_tx_ba_session/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_stop_tx_ba_cb/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_stop_tx_ba_session/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_abort_channel_switch/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_abort_pmsr/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_add_chanctx/format25
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_add_interface/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_add_nan_func/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_allow_buffered_frames/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_ampdu_action/format23
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_assign_vif_chanctx/format29
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_bss_info_changed/format47
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_cancel_hw_scan/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_cancel_remain_on_channel/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_change_chanctx/format26
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_change_interface/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_channel_switch/format25
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_channel_switch_beacon/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_channel_switch_rx_beacon/format25
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_conf_tx/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_config/format25
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_config_iface_filter/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_configure_filter/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_del_nan_func/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_event_callback/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_flush/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_antenna/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_et_sset_count/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_et_stats/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_et_strings/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_expected_throughput/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_ftm_responder_stats/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_key_seq/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_ringparam/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_stats/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_survey/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_tsf/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_txpower/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_hw_scan/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_ipv6_addr_change/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_join_ibss/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_leave_ibss/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_mgd_prepare_tx/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_mgd_protect_tdls_discover/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_nan_change_conf/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_offchannel_tx_cancel_wait/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_offset_tsf/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_post_channel_switch/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_pre_channel_switch/format25
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_prepare_multicast/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_reconfig_complete/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_release_buffered_frames/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_remain_on_channel/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_remove_chanctx/format25
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_remove_interface/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_reset_tsf/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_resume/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_return_bool/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_return_int/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_return_u32/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_return_u64/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_return_void/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sched_scan_start/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sched_scan_stop/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_antenna/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_bitrate_mask/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_coverage_class/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_default_unicast_key/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_frag_threshold/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_key/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_rekey_data/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_ringparam/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_rts_threshold/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_tim/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_tsf/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_wakeup/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_add/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_notify/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_pre_rcu_remove/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_rate_tbl_update/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_rc_update/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_remove/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_set_4addr/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_set_txpwr/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_state/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_statistics/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_start/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_start_ap/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_start_nan/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_start_pmsr/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_stop/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_stop_ap/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_stop_nan/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_suspend/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sw_scan_complete/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sw_scan_start/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_switch_vif_chanctx/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sync_rx_queues/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_tdls_cancel_channel_switch/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_tdls_channel_switch/format23
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_tdls_recv_channel_switch/format28
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_tx_frames_pending/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_tx_last_beacon/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_unassign_vif_chanctx/format29
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_update_tkip_key/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_update_vif_offload/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_wake_tx_queue/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/stop_queue/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/wake_queue/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_return_int/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_return_void/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_cca_ed_level/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_cca_mode/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_channel/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_csma_params/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_extended_addr/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_lbt_mode/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_max_frame_retries/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_pan_coord/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_pan_id/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_promiscuous_mode/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_short_addr/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_tx_power/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_start/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_stop/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/gpu_power_state/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_alloc/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_free/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_report/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_report_gpu_mem/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_report_pressure/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_trim/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_trim_from_region/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_job_slots_event/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_mmu_page_fault_grow/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_page_fault_insert_pages/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_pm_status/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_total_alloc_pages_change/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/sysgraph/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/sysgraph_gpu/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_get_access/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_return_int/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_scheduler_call/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_scheduler_call_region/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_scheduler_set_region_parameters/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_set_scheduler/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_set_scheduler_parameters/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_broken/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_done/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_rx_error/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_rx_frame/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_rx_timeout/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_timer_expired/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_tx_done/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_get_calibration/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_get_current_timestamp_dtu/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_idle/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_idle_timestamp/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_list_calibration/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_reset/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_return_int/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_return_rx_frame/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_return_timestamp_dtu/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_return_timestamp_rctu/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_return_void/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_rx_disable/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_rx_enable/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_rx_get_error_frame/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_rx_get_frame/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_calibration/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_cca_ed_level/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_cca_mode/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_channel/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_hrp_uwb_params/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_hw_addr_filt/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_promiscuous_mode/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_scanning_mode/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_sts_params/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_txpower/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_start/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_stop/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_testmode_cmd/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_tx_frame/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/region_get_access/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/schedule_update/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/schedule_update_done/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154_region_fira/region_fira_rx_message_type/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154_region_fira/region_fira_session_params/format40
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154_region_fira/region_fira_tx_message_type/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154_region_nfcc_coex/nfcc_coex_llhw_return_int/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154_region_nfcc_coex/nfcc_coex_llhw_vendor_cmd/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mdio/mdio_access/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_dcpp_end/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_dcpp_start/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_frame_bottom/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_frame_start/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_frame_top/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_loadfw_end/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_loadfw_start/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_node_close/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_node_open/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/migrate/mm_migrate_pages/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/migrate/mm_migrate_pages_start/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mmap/vm_unmapped_area/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mmc/mmc_request_done/format33
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mmc/mmc_request_start/format35
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/module/module_free/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/module/module_get/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/module/module_load/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/module/module_put/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/module/module_request/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/namei/inodepath/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/napi/napi_poll/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_cleanup_and_release/format25
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_create/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_event_send_dead/format25
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_event_send_done/format25
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_timer_handler/format25
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_update/format28
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_update_done/format25
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/napi_gro_frags_entry/format29
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/napi_gro_frags_exit/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/napi_gro_receive_entry/format29
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/napi_gro_receive_exit/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/net_dev_queue/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/net_dev_start_xmit/format27
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/net_dev_xmit/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/net_dev_xmit_timeout/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_receive_skb/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_receive_skb_entry/format29
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_receive_skb_exit/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_receive_skb_list_entry/format29
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_receive_skb_list_exit/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_rx/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_rx_entry/format29
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_rx_exit/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_rx_ni_entry/format29
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_rx_ni_exit/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/compact_retry/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/finish_task_reaping/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/mark_victim/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/oom_score_adj_update/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/reclaim_retry_zone/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/skip_task_reaping/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/start_task_reaping/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/wake_reaper/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/page_isolation/test_pages_isolated/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/page_pool/page_pool_release/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/page_pool/page_pool_state_hold/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/page_pool/page_pool_state_release/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/page_pool/page_pool_update_nid/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_pmd_changed/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_pte_lock/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_vma_access/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_vma_changed/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_vma_noanon/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_vma_notsup/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagemap/mm_lru_activate/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagemap/mm_lru_insertion/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/percpu/percpu_alloc_percpu/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/percpu/percpu_alloc_percpu_fail/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/percpu/percpu_create_chunk/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/percpu/percpu_destroy_chunk/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/percpu/percpu_free_percpu/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/clock_disable/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/clock_enable/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/clock_set_rate/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/cpu_frequency/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/cpu_frequency_limits/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/cpu_idle/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/dev_pm_qos_add_request/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/dev_pm_qos_remove_request/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/dev_pm_qos_update_request/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/device_pm_callback_end/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/device_pm_callback_start/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/gpu_frequency/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/memlat_dev_meas/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/memlat_dev_update/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pm_qos_add_request/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pm_qos_remove_request/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pm_qos_update_flags/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pm_qos_update_request/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pm_qos_update_target/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/power_domain_target/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/powernv_throttle/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pstate_sample/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/suspend_resume/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/wakeup_source_activate/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/wakeup_source_deactivate/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/preemptirq_long/irq_disable_long/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/preemptirq_long/preempt_disable_long/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/printk/console/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pt/pt_driver_log/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pt/pt_enable/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pt/pt_resize_callback/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pwm/pwm_apply/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pwm/pwm_get/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/qdisc/qdisc_create/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/qdisc/qdisc_dequeue/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/qdisc/qdisc_destroy/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/qdisc/qdisc_reset/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/add_device_randomness/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/add_disk_randomness/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/add_input_randomness/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/credit_entropy_bits/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/debit_entropy/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/extract_entropy/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/extract_entropy_user/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/get_random_bytes/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/get_random_bytes_arch/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/mix_pool_bytes/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/mix_pool_bytes_nolock/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/prandom_u32/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/push_to_pool/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/random_read/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/urandom_read/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/xfer_secondary_pool/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ras/aer_event/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ras/arm_event/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ras/mc_event/format22
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ras/non_standard_event/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/raw_syscalls/sys_enter/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/raw_syscalls/sys_exit/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_barrier/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_batch_end/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_batch_start/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_callback/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_dyntick/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_exp_funnel_lock/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_exp_grace_period/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_fqs/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_future_grace_period/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_grace_period/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_grace_period_init/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_invoke_callback/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_invoke_kfree_bulk_callback/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_invoke_kvfree_callback/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_kvfree_callback/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_nocb_wake/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_preempt_task/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_quiescent_state_report/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_stall_warning/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_torture_read/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_unlock_preempted_task/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_utilization/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regcache_drop_region/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regcache_sync/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_async_complete_done/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_async_complete_start/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_async_io_complete/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_async_write_start/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_cache_bypass/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_cache_only/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_hw_read_done/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_hw_read_start/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_hw_write_done/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_hw_write_start/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_reg_read/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_reg_read_cache/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_reg_write/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_bypass_disable/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_bypass_disable_complete/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_bypass_enable/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_bypass_enable_complete/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_disable/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_disable_complete/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_enable/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_enable_complete/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_enable_delay/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_set_voltage/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_set_voltage_complete/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rpm/rpm_idle/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rpm/rpm_resume/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rpm/rpm_return_int/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rpm/rpm_suspend/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rpm/rpm_usage/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_alarm_irq_enable/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_irq_set_freq/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_irq_set_state/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_read_alarm/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_read_offset/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_read_time/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_set_alarm/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_set_offset/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_set_time/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_timer_dequeue/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_timer_enqueue/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_timer_fired/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rwmmio/rwmmio_post_read/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rwmmio/rwmmio_read/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rwmmio/rwmmio_write/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_blocked_reason/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_cpu_capacity/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_cpu_util/format25
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_find_best_target/format23
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_find_energy_efficient_cpu/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_find_least_loaded_cpu/format23
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_kthread_stop/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_kthread_stop_ret/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_migrate_task/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_move_numa/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_overutilized/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pelt_cfs/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pelt_dl/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pelt_irq/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pelt_rt/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pelt_se/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pi_setprio/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_exec/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_exit/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_fork/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_free/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_hang/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_wait/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_rt_cpu_util/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_select_task_rq_rt/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_setscheduler_uclamp/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stat_blocked/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stat_iowait/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stat_runtime/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stat_sleep/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stat_wait/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stick_numa/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_swap_numa/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_switch/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_util_est_cfs/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_util_est_se/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_wait_task/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_wake_idle_without_ipi/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_wakeup/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_wakeup_new/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_waking/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/schedutil_cpu_util_clamp/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sugov_next_freq/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sugov_util_update/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scmi/scmi_rx_done/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scmi/scmi_xfer_begin/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scmi/scmi_xfer_end/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scsi/scsi_dispatch_cmd_done/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scsi/scsi_dispatch_cmd_error/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scsi/scsi_dispatch_cmd_start/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scsi/scsi_dispatch_cmd_timeout/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scsi/scsi_eh_wakeup/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/signal/signal_deliver/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/signal/signal_generate/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/skb/consume_skb/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/skb/kfree_skb/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/skb/skb_copy_datagram_iovec/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/smbus/smbus_read/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/smbus/smbus_reply/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/smbus/smbus_result/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/smbus/smbus_write/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sock/inet_sock_set_state/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sock/sock_exceed_buf_limit/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sock/sock_rcvqueue_full/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_controller_busy/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_controller_idle/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_message_done/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_message_start/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_message_submit/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_transfer_start/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_transfer_stop/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spmi/spmi_cmd/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spmi/spmi_read_begin/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spmi/spmi_read_end/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spmi/spmi_write_begin/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spmi/spmi_write_end/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/swiotlb/swiotlb_bounced/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/synthetic/rss_stat_throttled/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/systrace/0/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/task/task_newtask/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/task/task_rename/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_destroy_sock/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_probe/format24
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_rcv_space_adjust/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_receive_reset/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_retransmit_skb/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_retransmit_synack/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_send_reset/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/cdev_update/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_power_cpu_get_power/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_power_cpu_limit/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_power_devfreq_get_power/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_power_devfreq_limit/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_temperature/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_zone_trip/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_cpu_pressure/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_allow_max_power/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_arm_update/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_cpu_pause/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_hard_limit_cdev_update/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_allocator/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_allocator_pid/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_cpu_get_power/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_cpu_limit/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_gpu_get_power/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_gpu_limit/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_tpu_pause/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/vendor_cdev_update/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos_gpu/thermal_exynos_power_gpu_get_power/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos_gpu/thermal_exynos_power_gpu_limit/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos_gpu/vendor_cdev_update/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_power_allocator/thermal_power_allocator/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_power_allocator/thermal_power_allocator_pid/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/hrtimer_cancel/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/hrtimer_expire_entry/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/hrtimer_expire_exit/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/hrtimer_init/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/hrtimer_start/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/itimer_expire/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/itimer_state/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/tick_stop/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/timer_cancel/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/timer_expire_entry/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/timer_expire_exit/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/timer_init/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/timer_start/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_l2_device_event/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_bc_ack/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_conges/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_dump/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_fsm/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_reset/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_retrans/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_timeout/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_too_silent/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_list_dump/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_check_state/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_create/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_delete/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_dump/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_fsm/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_link_down/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_link_up/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_lost_contact/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_reset_links/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_timeout/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_proto_build/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_proto_rcv/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_advance_rx/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_create/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_drop_msg/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_dump/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_filter_rcv/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_overlimit1/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_overlimit2/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_poll/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_rej_msg/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_release/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_sendmcast/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_sendmsg/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_sendstream/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_shutdown/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_skb_dump/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ucsi/ucsi_connector_change/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ucsi/ucsi_register_altmode/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ucsi/ucsi_register_port/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ucsi/ucsi_reset_ppm/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ucsi/ucsi_run_command/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/udp/udp_fail_queue_rcv_skb/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_auto_bkops_state/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_clk_gating/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_clk_scaling/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_command/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_init/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_profile_clk_gating/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_profile_clk_scaling/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_profile_hibern8/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_runtime_resume/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_runtime_suspend/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_system_resume/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_system_suspend/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_uic_command/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_upiu/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs_pixel/ufs_stats/format29
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/v4l2_dqbuf/format28
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/v4l2_qbuf/format28
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/vb2_v4l2_buf_done/format25
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/vb2_v4l2_buf_queue/format25
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/vb2_v4l2_dqbuf/format25
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/vb2_v4l2_qbuf/format25
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vb2/vb2_buf_done/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vb2/vb2_buf_queue/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vb2/vb2_dqbuf/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vb2/vb2_qbuf/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_shrink_slab_end/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_shrink_slab_start/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_direct_reclaim_begin/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_direct_reclaim_end/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_inactive_list_is_low/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_kswapd_sleep/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_kswapd_wake/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_lru_isolate/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_lru_shrink_active/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_lru_shrink_inactive/format23
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_memcg_reclaim_begin/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_memcg_reclaim_end/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_memcg_softlimit_reclaim_begin/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_memcg_softlimit_reclaim_end/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_node_reclaim_begin/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_node_reclaim_end/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_wakeup_kswapd/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_writepage/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vsock/virtio_transport_alloc_pkt/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vsock/virtio_transport_recv_pkt/format20
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/workqueue/workqueue_activate_work/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/workqueue/workqueue_execute_end/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/workqueue/workqueue_execute_start/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/workqueue/workqueue_queue_work/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/balance_dirty_pages/format25
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/bdi_dirty_ratelimit/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/flush_foreign/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/global_dirty_state/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/inode_foreign_history/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/inode_switch_wbs/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/sb_clear_inode_writeback/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/sb_mark_inode_writeback/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/track_foreign_dirty/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/wait_on_page_writeback/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/wbc_writepage/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_bdi_register/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_congestion_wait/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_dirty_inode/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_dirty_inode_enqueue/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_dirty_inode_start/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_dirty_page/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_exec/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_lazytime/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_lazytime_iput/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_mark_inode_dirty/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_pages_written/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_queue/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_queue_io/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_sb_inodes_requeue/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_single_inode/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_single_inode_start/format18
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_start/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_wait/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_wait_iff_congested/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_wake_background/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_write_inode/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_write_inode_start/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_written/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/mem_connect/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/mem_disconnect/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/mem_return_failed/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_bulk_tx/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_cpumap_enqueue/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_cpumap_kthread/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_devmap_xmit/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_exception/format13
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_redirect/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_redirect_err/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_redirect_map/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_redirect_map_err/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_add_endpoint/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_address_ctrl_ctx/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_address_ctx/format17
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_alloc_dev/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_alloc_virt_device/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_configure_endpoint/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_configure_endpoint_ctrl_ctx/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_alloc_request/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_free_request/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_gadget_ep_queue/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_giveback_request/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_handle_event/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_handle_transfer/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_queue_request/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_address/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_cancel_urb/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_context_change/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_init/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_quirks/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_reset_ep/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_ring_expansion/format11
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_discover_or_reset_device/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_free_dev/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_free_virt_device/format16
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_get_port_status/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_addr_dev/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_config_ep/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_disable_slot/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_reset_dev/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_reset_ep/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_set_deq/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_set_deq_ep/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_stop_ep/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_command/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_event/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_port_status/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_transfer/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_hub_status_data/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_inc_deq/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_inc_enq/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_queue_trb/format15
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_ring_alloc/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_ring_ep_doorbell/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_ring_expansion/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_ring_free/format21
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_ring_host_doorbell/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_setup_addressable_virt_device/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_setup_device/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_setup_device_slot/format14
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_stop_device/format19
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_urb_dequeue/format23
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_urb_enqueue/format23
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_urb_giveback/format23
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/zram/zcomp_decompress_end/format12
-rw-r--r--src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/zram/zcomp_decompress_start/format12
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/cgroup/cgroup_attach_task/format16
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/cros_ec/cros_ec_sensorhub_data/format17
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/dma_fence/dma_fence_emit/format14
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/dma_fence/dma_fence_init/format14
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/dma_fence/dma_fence_signaled/format14
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/dma_fence/dma_fence_wait_end/format14
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/dma_fence/dma_fence_wait_start/format14
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/drm/drm_vblank_event/format14
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/drm/drm_vblank_event_delivered/format13
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/gpu_scheduler/drm_run_job/format16
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/gpu_scheduler/drm_sched_job/format16
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/gpu_scheduler/drm_sched_process_job/format11
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/net/napi_gro_receive_entry/format29
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/net/napi_gro_receive_exit/format11
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/net/net_dev_xmit/format14
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/net/netif_receive_skb/format13
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/power/wakeup_source_activate/format12
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/power/wakeup_source_deactivate/format12
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/skb/kfree_skb/format13
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/sock/inet_sock_set_state/format21
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/synthetic/rss_stat_throttled/format14
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/tcp/tcp_retransmit_skb/format19
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/ufs/ufshcd_clk_gating/format12
-rw-r--r--src/traced/probes/ftrace/test/data/synthetic/events/ufs/ufshcd_command/format19
-rw-r--r--src/traced/probes/initial_display_state/initial_display_state_data_source.cc13
-rw-r--r--src/traced/probes/metatrace/metatrace_data_source.cc1
-rw-r--r--src/traced/probes/packages_list/packages_list_data_source.cc1
-rw-r--r--src/traced/probes/packages_list/packages_list_parser.h2
-rw-r--r--src/traced/probes/power/BUILD.gn16
-rw-r--r--src/traced/probes/power/android_power_data_source.cc36
-rw-r--r--src/traced/probes/power/android_power_data_source.h19
-rw-r--r--src/traced/probes/power/linux_power_sysfs_data_source.cc174
-rw-r--r--src/traced/probes/power/linux_power_sysfs_data_source.h91
-rw-r--r--src/traced/probes/power/linux_power_sysfs_data_source_unittest.cc68
-rw-r--r--src/traced/probes/probes.cc36
-rw-r--r--src/traced/probes/probes_data_source.h4
-rw-r--r--src/traced/probes/probes_producer.cc407
-rw-r--r--src/traced/probes/probes_producer.h57
-rw-r--r--src/traced/probes/ps/process_stats_data_source.cc87
-rw-r--r--src/traced/probes/ps/process_stats_data_source.h14
-rw-r--r--src/traced/probes/ps/process_stats_data_source_unittest.cc36
-rw-r--r--src/traced/probes/sys_stats/BUILD.gn2
-rw-r--r--src/traced/probes/sys_stats/sys_stats_data_source.cc42
-rw-r--r--src/traced/probes/sys_stats/sys_stats_data_source.h6
-rw-r--r--src/traced/probes/sys_stats/sys_stats_data_source_unittest.cc33
-rw-r--r--src/traced/probes/system_info/system_info_data_source.cc1
-rw-r--r--src/traced/service/builtin_producer.cc16
-rw-r--r--src/traced/service/service.cc40
-rw-r--r--src/tracing/BUILD.gn8
-rw-r--r--src/tracing/OWNERS7
-rw-r--r--src/tracing/console_interceptor.cc28
-rw-r--r--src/tracing/consumer_api_deprecated/consumer_api_deprecated.cc11
-rw-r--r--src/tracing/consumer_api_deprecated/consumer_api_deprecated_test.cc3
-rw-r--r--src/tracing/core/BUILD.gn1
-rw-r--r--src/tracing/core/id_allocator.cc2
-rw-r--r--src/tracing/core/packet_stream_validator.cc4
-rw-r--r--src/tracing/core/packet_stream_validator_unittest.cc70
-rw-r--r--src/tracing/core/shared_memory_arbiter_impl.cc2
-rw-r--r--src/tracing/core/shared_memory_arbiter_impl_unittest.cc1
-rw-r--r--src/tracing/core/trace_buffer.cc44
-rw-r--r--src/tracing/core/trace_buffer.h16
-rw-r--r--src/tracing/core/trace_buffer_unittest.cc15
-rw-r--r--src/tracing/core/tracing_service_impl.cc710
-rw-r--r--src/tracing/core/tracing_service_impl.h81
-rw-r--r--src/tracing/core/tracing_service_impl_unittest.cc227
-rw-r--r--src/tracing/debug_annotation.cc2
-rw-r--r--src/tracing/event_context.cc15
-rw-r--r--src/tracing/internal/in_process_tracing_backend.cc7
-rw-r--r--src/tracing/internal/tracing_backend_fake.cc1
-rw-r--r--src/tracing/internal/tracing_muxer_fake.cc8
-rw-r--r--src/tracing/internal/tracing_muxer_fake.h3
-rw-r--r--src/tracing/internal/tracing_muxer_impl.cc227
-rw-r--r--src/tracing/internal/tracing_muxer_impl.h22
-rw-r--r--src/tracing/internal/track_event_internal.cc112
-rw-r--r--src/tracing/internal/track_event_interned_fields.cc13
-rw-r--r--src/tracing/ipc/BUILD.gn15
-rw-r--r--src/tracing/ipc/consumer/consumer_ipc_client_impl.cc5
-rw-r--r--src/tracing/ipc/default_socket.cc26
-rw-r--r--src/tracing/ipc/producer/producer_ipc_client_impl.cc58
-rw-r--r--src/tracing/ipc/producer/producer_ipc_client_impl.h1
-rw-r--r--src/tracing/ipc/service/consumer_ipc_service.cc2
-rw-r--r--src/tracing/ipc/service/producer_ipc_service.cc62
-rw-r--r--src/tracing/ipc/service/producer_ipc_service.h2
-rw-r--r--src/tracing/ipc/service/service_ipc_host_impl.cc12
-rw-r--r--src/tracing/ipc/shared_memory_windows.cc113
-rw-r--r--src/tracing/ipc/shared_memory_windows.h69
-rw-r--r--src/tracing/platform.cc3
-rw-r--r--src/tracing/platform_posix.cc26
-rw-r--r--src/tracing/platform_windows.cc175
-rw-r--r--src/tracing/test/api_integrationtest.cc1172
-rw-r--r--src/tracing/test/api_test_support.cc4
-rw-r--r--src/tracing/test/fake_packet.cc2
-rw-r--r--src/tracing/test/fake_packet.h2
-rw-r--r--src/tracing/test/fake_producer_endpoint.h1
-rw-r--r--src/tracing/test/mock_consumer.cc7
-rw-r--r--src/tracing/test/mock_consumer.h2
-rw-r--r--src/tracing/test/mock_producer.cc39
-rw-r--r--src/tracing/test/mock_producer.h8
-rw-r--r--src/tracing/test/tracing_integration_test.cc7
-rw-r--r--src/tracing/traced_proto_unittest.cc367
-rw-r--r--src/tracing/traced_value.cc72
-rw-r--r--src/tracing/traced_value_unittest.cc121
-rw-r--r--src/tracing/tracing.cc22
-rw-r--r--src/tracing/track.cc7
-rw-r--r--src/tracing/track_event_legacy.cc12
-rw-r--r--src/tracing/track_event_state_tracker.cc28
-rw-r--r--src/tracing/virtual_destructors.cc12
-rw-r--r--src/websocket_bridge/BUILD.gn35
-rw-r--r--src/websocket_bridge/websocket_bridge.cc190
-rw-r--r--src/websocket_bridge/websocket_bridge.h26
-rw-r--r--src/websocket_bridge/websocket_bridge_main.cc23
-rw-r--r--test/.gitignore8
-rw-r--r--test/BUILD.gn18
-rw-r--r--test/android_integrationtest.cc407
-rw-r--r--test/android_test_utils.cc14
-rwxr-xr-xtest/ci/bazel_tests.sh1
-rwxr-xr-xtest/ci/linux_tests.sh2
-rwxr-xr-xtest/ci/ui_tests.sh14
-rw-r--r--test/cmdline_integrationtest.cc763
-rw-r--r--test/configs/BUILD.gn3
-rw-r--r--test/configs/rss_stat.cfg17
-rw-r--r--test/cts/Android.bp14
-rw-r--r--test/cts/AndroidTest.xml3
-rw-r--r--test/cts/BUILD.gn2
-rw-r--r--test/cts/end_to_end_integrationtest_cts.cc7
-rw-r--r--test/cts/heapprofd_java_test_cts.cc60
-rw-r--r--test/cts/heapprofd_test_cts.cc146
-rw-r--r--test/cts/reporter/Android.bp30
-rwxr-xr-xtest/cts/reporter/AndroidManifest.xml28
-rw-r--r--test/cts/reporter/src/android/perfetto/cts/reporter/PerfettoReportService.java48
-rw-r--r--test/cts/reporter_test_cts.cc111
-rwxr-xr-xtest/cts/test_apps/AndroidManifest_debuggable.xml13
-rwxr-xr-xtest/cts/test_apps/AndroidManifest_nonprofileable.xml13
-rwxr-xr-xtest/cts/test_apps/AndroidManifest_profileable.xml13
-rwxr-xr-xtest/cts/test_apps/AndroidManifest_release.xml13
-rw-r--r--test/cts/test_apps/src/android/perfetto/cts/app/JavaAllocActivity.java56
-rw-r--r--test/cts/traced_perf_test_cts.cc15
-rw-r--r--test/data/README.md.sha2561
-rw-r--r--test/data/android_log.pb.sha2561
-rw-r--r--test/data/android_log_ring_buffer_mode.pb.sha2561
-rw-r--r--test/data/android_sched_and_ps.pb.sha2561
-rw-r--r--test/data/atrace_b_193721088.atr.sha2561
-rw-r--r--test/data/atrace_compressed.ctrace.sha2561
-rw-r--r--test/data/atrace_uncompressed_b_208691037.sha2561
-rw-r--r--test/data/callstack_sampling.pftrace.sha2561
-rw-r--r--test/data/camera-ion-mem-trace.sha2561
-rw-r--r--test/data/chrome_android_systrace.pftrace.sha2561
-rw-r--r--test/data/chrome_memory_snapshot.pftrace.sha2561
-rw-r--r--test/data/chrome_rendering_desktop.pftrace.sha2561
-rw-r--r--test/data/chrome_scroll_without_vsync.pftrace.sha2561
-rw-r--r--test/data/chrome_touch_gesture_scroll.pftrace.sha2561
-rw-r--r--test/data/clusterfuzz_14357.sha2561
-rw-r--r--test/data/clusterfuzz_14730.sha2561
-rw-r--r--test/data/clusterfuzz_14753.sha2561
-rw-r--r--test/data/clusterfuzz_14762.sha2561
-rw-r--r--test/data/clusterfuzz_14767.sha2561
-rw-r--r--test/data/clusterfuzz_14799.sha2561
-rw-r--r--test/data/clusterfuzz_15252.sha2561
-rw-r--r--test/data/clusterfuzz_17805.sha2561
-rw-r--r--test/data/clusterfuzz_20215.sha2561
-rw-r--r--test/data/clusterfuzz_20292.sha2561
-rw-r--r--test/data/clusterfuzz_21178.sha2561
-rw-r--r--test/data/clusterfuzz_21890.sha2561
-rw-r--r--test/data/clusterfuzz_23053.sha2561
-rw-r--r--test/data/clusterfuzz_28338.sha2561
-rw-r--r--test/data/clusterfuzz_28766.sha2561
-rw-r--r--test/data/compact_sched.pb.sha2561
-rw-r--r--test/data/compressed.pb.gz.sha2561
-rw-r--r--test/data/compressed.pb.sha2561
-rw-r--r--test/data/counters.json.sha2561
-rw-r--r--test/data/cpu_counters.pb.sha2561
-rw-r--r--test/data/decimal_timestamp.json.sha2561
-rw-r--r--test/data/display_time_unit.json.sha2561
-rw-r--r--test/data/example_android_trace_30s.pb.gz.sha2561
-rw-r--r--test/data/example_android_trace_30s.pb.sha2561
-rw-r--r--test/data/ftrace_error_stats.pftrace.sha2561
-rw-r--r--test/data/fuchsia_trace.fxt.sha2561
-rw-r--r--test/data/fuchsia_workstation.fxt.sha2561
-rw-r--r--test/data/full_trace_filter.bytecode.sha2561
-rw-r--r--test/data/gpu_counters.pb.sha2561
-rw-r--r--test/data/gpu_trace.pb.sha2561
-rw-r--r--test/data/heapprofd_standalone_client_example-trace.sha2561
-rw-r--r--test/data/heapprofd_standalone_client_example.sha2561
-rw-r--r--test/data/instants.json.sha2561
-rw-r--r--test/data/kallsyms.txt.sha2561
-rw-r--r--test/data/lmk_userspace.pb.sha2561
-rw-r--r--test/data/log.proto.sha2561
-rw-r--r--test/data/memory_counters.pb.sha2561
-rw-r--r--test/data/mm_event.pb.sha2561
-rw-r--r--test/data/ninja_log.sha2561
-rw-r--r--test/data/perf_sample.pb.sha2561
-rw-r--r--test/data/perf_sample_sc.pb.sha2561
-rw-r--r--test/data/power_rails.pb.sha2561
-rw-r--r--test/data/process_stats_poll.pb.sha2561
-rw-r--r--test/data/sched_switch_compact.pb.sha2561
-rw-r--r--test/data/sched_switch_original.pb.sha2561
-rw-r--r--test/data/sfgate.json.sha2561
-rw-r--r--test/data/synth_1.pb.sha2561
-rw-r--r--test/data/sys.pb.sha2561
-rw-r--r--test/data/system-server-heap-graph-new.pftrace.sha2561
-rw-r--r--test/data/system-server-heap-graph.pftrace.sha2561
-rw-r--r--test/data/system-server-native-profile.sha2561
-rw-r--r--test/data/systrace.html.sha2561
-rw-r--r--test/data/trace_with_descriptor.pftrace.sha2561
-rw-r--r--test/data/trace_with_uuid.pftrace.sha2561
-rw-r--r--test/data/track_event_typed_args.pb.sha2561
-rw-r--r--test/data/trailing_empty.systrace.sha2561
-rw-r--r--test/data/ui-screenshots/ui-android_trace_30s_expand_camera.png.sha2561
-rw-r--r--test/data/ui-screenshots/ui-android_trace_30s_load.png.sha2561
-rw-r--r--test/data/ui-screenshots/ui-android_trace_30s_search.png.sha2561
-rw-r--r--test/data/ui-screenshots/ui-chrome_rendering_desktop_expand_browser_proc.png.sha2561
-rw-r--r--test/data/ui-screenshots/ui-chrome_rendering_desktop_load.png.sha2561
-rw-r--r--test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha2561
-rw-r--r--test/data/ui-screenshots/ui-routing_navigate_navigate_back_and_forward.png.sha2561
-rw-r--r--test/data/ui-screenshots/ui-routing_navigate_open_trace_from_url.png.sha2561
-rw-r--r--test/data/ui-screenshots/ui-routing_open_invalid_trace_from_blank_page.png.sha2561
-rw-r--r--test/data/ui-screenshots/ui-routing_open_trace_and_go_back_to_landing_page.png.sha2561
-rw-r--r--test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_access_subpage_then_go_back.png.sha2561
-rw-r--r--test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_first_trace_from_url.png.sha2561
-rw-r--r--test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_second_trace_from_url.png.sha2561
-rw-r--r--test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_trace_from_url.png.sha2561
-rw-r--r--test/data/ui-screenshots/ui-routing_start_from_no_trace_go_back_to_first_trace.png.sha2561
-rw-r--r--test/data/ui-screenshots/ui-routing_start_from_no_trace_go_to_page_with_no_trace.png.sha2561
-rw-r--r--test/data/ui-screenshots/ui-routing_start_from_no_trace_open_invalid_trace.png.sha2561
-rw-r--r--test/data/ui-screenshots/ui-routing_start_from_no_trace_open_second_trace.png.sha2561
-rw-r--r--test/data/ui-screenshots/ui-routing_start_from_no_trace_open_trace_.png.sha2561
-rw-r--r--test/data/ui-screenshots/ui-routing_start_from_no_trace_refresh.png.sha2561
-rw-r--r--test/data/unsorted_trace.json.sha2561
-rw-r--r--test/end_to_end_integrationtest.cc1677
-rw-r--r--test/fake_producer.cc5
-rw-r--r--test/fake_producer.h1
-rw-r--r--test/ftrace_integrationtest.cc343
-rw-r--r--test/stress_test/stress_test.cc7
-rw-r--r--test/synth_common.py88
-rw-r--r--test/test_helper.cc29
-rw-r--r--test/test_helper.h133
-rw-r--r--test/trace_processor/atrace/android_async_slice.textproto (renamed from test/trace_processor/parsing/android_async_slice.textproto)0
-rw-r--r--test/trace_processor/atrace/android_b2b_async_begin.textproto (renamed from test/trace_processor/parsing/android_b2b_async_begin.textproto)0
-rw-r--r--test/trace_processor/atrace/android_b2b_async_begin_list_slices.out (renamed from test/trace_processor/parsing/android_b2b_async_begin_list_slices.out)0
-rw-r--r--test/trace_processor/atrace/async_track_atrace.py37
-rw-r--r--test/trace_processor/atrace/async_track_atrace_process_track_slices.out4
-rw-r--r--test/trace_processor/atrace/bad_print.systrace (renamed from test/trace_processor/parsing/bad_print.systrace)0
-rw-r--r--test/trace_processor/atrace/bad_print.textproto (renamed from test/trace_processor/parsing/bad_print.textproto)0
-rw-r--r--test/trace_processor/atrace/bad_print_systrace_list_slices.out (renamed from test/trace_processor/parsing/bad_print_systrace_list_slices.out)0
-rw-r--r--test/trace_processor/atrace/bad_print_textproto_list_slices.out (renamed from test/trace_processor/parsing/bad_print_textproto_list_slices.out)0
-rw-r--r--test/trace_processor/atrace/index13
-rw-r--r--test/trace_processor/atrace/instant_async.sql9
-rw-r--r--test/trace_processor/atrace/instant_async_atrace.py32
-rw-r--r--test/trace_processor/atrace/instant_async_atrace_instant_async.out3
-rw-r--r--test/trace_processor/atrace/instant_atrace.py28
-rw-r--r--test/trace_processor/atrace/instant_atrace_instant_with_thread.out3
-rw-r--r--test/trace_processor/atrace/instant_with_thread.sql5
-rw-r--r--test/trace_processor/atrace/process_track_slices_android_async_slice.out (renamed from test/trace_processor/parsing/process_track_slices_android_async_slice.out)0
-rw-r--r--test/trace_processor/camera/camera-ion-mem-trace_android_camera.out7
-rw-r--r--test/trace_processor/camera/camera-ion-mem-trace_android_camera_unagg.out35834
-rw-r--r--test/trace_processor/camera/index2
-rw-r--r--test/trace_processor/chrome/chrome_dropped_frames_metric.out12
-rw-r--r--test/trace_processor/chrome/chrome_dropped_frames_metric.sql18
-rw-r--r--test/trace_processor/chrome/chrome_histogram_hashes.out4
-rw-r--r--test/trace_processor/chrome/chrome_histogram_hashes.textproto27
-rw-r--r--test/trace_processor/chrome/chrome_long_latency_metric.out5
-rw-r--r--test/trace_processor/chrome/chrome_long_latency_metric.sql18
-rw-r--r--test/trace_processor/chrome/chrome_performance_mark_hashes.out6
-rw-r--r--test/trace_processor/chrome/chrome_performance_mark_hashes.textproto28
-rw-r--r--test/trace_processor/chrome/chrome_slice_names.out5
-rw-r--r--test/trace_processor/chrome/chrome_slice_names.textproto23
-rw-r--r--test/trace_processor/chrome/chrome_thread_slice.out7
-rw-r--r--test/trace_processor/chrome/chrome_thread_slice.sql27
-rw-r--r--test/trace_processor/chrome/chrome_thread_slice_repeated.out9
-rw-r--r--test/trace_processor/chrome/chrome_thread_slice_repeated.sql25
-rw-r--r--test/trace_processor/chrome/chrome_thread_slice_with_cpu_time.out7
-rw-r--r--test/trace_processor/chrome/chrome_thread_slice_with_cpu_time.sql29
-rw-r--r--test/trace_processor/chrome/chrome_thread_slice_with_cpu_time_repeated.out9
-rw-r--r--test/trace_processor/chrome/chrome_thread_slice_with_cpu_time_repeated.sql27
-rw-r--r--test/trace_processor/chrome/chrome_user_event_hashes.out5
-rw-r--r--test/trace_processor/chrome/chrome_user_event_hashes.textproto27
-rw-r--r--test/trace_processor/chrome/index30
-rw-r--r--test/trace_processor/chrome/long_event_latency.textproto212
-rw-r--r--test/trace_processor/chrome/scroll_flow_event.out32
-rw-r--r--test/trace_processor/chrome/scroll_flow_event_general_validation.out2
-rw-r--r--test/trace_processor/chrome/scroll_flow_event_queuing_delay.out50
-rw-r--r--test/trace_processor/chrome/scroll_flow_event_queuing_delay.sql5
-rw-r--r--test/trace_processor/chrome/scroll_jank.out280
-rw-r--r--test/trace_processor/chrome/scroll_jank.sql3
-rw-r--r--test/trace_processor/chrome/scroll_jank_cause.out2
-rw-r--r--test/trace_processor/chrome/scroll_jank_cause_queuing_delay.out4
-rw-r--r--test/trace_processor/chrome/scroll_jank_cause_queuing_delay_general_validation.out2
-rw-r--r--test/trace_processor/chrome/scroll_jank_cause_queuing_delay_restricted.out25
-rw-r--r--test/trace_processor/chrome/scroll_jank_cause_queuing_delay_restricted.sql27
-rw-r--r--test/trace_processor/chrome/scroll_jank_general_validation.out2
-rw-r--r--test/trace_processor/chrome/scroll_jank_general_validation.sql2
-rw-r--r--test/trace_processor/chrome/scroll_jank_gpu_check.out5
-rw-r--r--test/trace_processor/chrome/scroll_jank_gpu_check.py86
-rw-r--r--test/trace_processor/chrome/scroll_jank_gpu_check.sql20
-rw-r--r--test/trace_processor/chrome/scroll_jank_mojo_simple_watcher.out2
-rw-r--r--test/trace_processor/chrome/touch_flow_event.out170
-rw-r--r--test/trace_processor/chrome/touch_flow_event.sql29
-rw-r--r--test/trace_processor/chrome/touch_flow_event_queuing_delay.out38
-rw-r--r--test/trace_processor/chrome/touch_flow_event_queuing_delay.sql30
-rw-r--r--test/trace_processor/chrome/touch_flow_event_queuing_delay_full.sql29
-rw-r--r--test/trace_processor/chrome/touch_flow_event_queuing_delay_synth.out12
-rw-r--r--test/trace_processor/chrome/touch_flow_event_synth.out12
-rw-r--r--test/trace_processor/chrome/touch_jank.out16
-rw-r--r--test/trace_processor/chrome/touch_jank.py186
-rw-r--r--test/trace_processor/chrome/touch_jank.sql25
-rw-r--r--test/trace_processor/chrome/touch_jank_synth.out5
-rw-r--r--test/trace_processor/common/list_slices.sql2
-rw-r--r--test/trace_processor/common/process_track_slices.sql (renamed from test/trace_processor/parsing/process_track_slices.sql)0
-rw-r--r--test/trace_processor/cros/cros_ec_sensorhub_data.out2
-rw-r--r--test/trace_processor/cros/cros_ec_sensorhub_data.sql11
-rw-r--r--test/trace_processor/cros/cros_ec_sensorhub_data.textproto18
-rw-r--r--test/trace_processor/cros/index5
-rw-r--r--test/trace_processor/dynamic/ancestor_slice_by_stack.out5
-rw-r--r--test/trace_processor/dynamic/ancestor_slice_by_stack.sql5
-rw-r--r--test/trace_processor/dynamic/descendant_slice_by_stack.out5
-rw-r--r--test/trace_processor/dynamic/descendant_slice_by_stack.sql6
-rw-r--r--test/trace_processor/dynamic/index6
-rw-r--r--test/trace_processor/dynamic/slice_stacks.textproto154
-rw-r--r--test/trace_processor/fuchsia/fuchsia_smoke_instants.out22
-rw-r--r--test/trace_processor/fuchsia/fuchsia_smoke_slices.out4
-rw-r--r--test/trace_processor/fuchsia/fuchsia_smoke_type.out11
-rw-r--r--test/trace_processor/fuchsia/fuchsia_workstation_smoke_slices.out4
-rw-r--r--test/trace_processor/fuchsia/index1
-rw-r--r--test/trace_processor/fuchsia/smoke_instants.sql7
-rw-r--r--test/trace_processor/fuchsia/smoke_type.sql21
-rw-r--r--test/trace_processor/graphics/android_sysui_cuj.out24
-rw-r--r--test/trace_processor/graphics/android_sysui_cuj.py193
-rw-r--r--test/trace_processor/graphics/android_sysui_cuj_event.out2
-rw-r--r--test/trace_processor/graphics/clock_sync.sql2
-rw-r--r--test/trace_processor/graphics/dpu_vote_clock_bw.out17
-rw-r--r--test/trace_processor/graphics/dpu_vote_clock_bw.textproto127
-rw-r--r--test/trace_processor/graphics/frame_missed_metrics.out1
-rw-r--r--test/trace_processor/graphics/g2d_metrics.out30
-rw-r--r--test/trace_processor/graphics/g2d_metrics.textproto24
-rw-r--r--test/trace_processor/graphics/gpu_frequency_metric.out39
-rw-r--r--test/trace_processor/graphics/gpu_frequency_metric.textproto55
-rwxr-xr-xtest/trace_processor/graphics/gpu_mem_total.py8
-rw-r--r--test/trace_processor/graphics/gpu_mem_total_after_free.py38
-rw-r--r--test/trace_processor/graphics/gpu_mem_total_after_free_gpu_mem_total.out4
-rw-r--r--test/trace_processor/graphics/gpu_metric.py18
-rw-r--r--test/trace_processor/graphics/index8
-rw-r--r--test/trace_processor/graphics/surfaceflinger_gpu_invocation.out8
-rw-r--r--test/trace_processor/graphics/surfaceflinger_gpu_invocation.py51
-rw-r--r--test/trace_processor/include_index7
-rw-r--r--test/trace_processor/io/index2
-rw-r--r--test/trace_processor/io/ufshcd_command.out5
-rw-r--r--test/trace_processor/io/ufshcd_command.sql11
-rw-r--r--test/trace_processor/io/ufshcd_command.textproto52
-rw-r--r--test/trace_processor/memory/android_mem_by_priority.out8
-rw-r--r--test/trace_processor/memory/android_mem_counters.out3437
-rw-r--r--test/trace_processor/memory/android_mem_delta.out13
-rw-r--r--test/trace_processor/memory/android_mem_delta.py36
-rw-r--r--test/trace_processor/memory/android_systrace_lmk.py31
-rw-r--r--test/trace_processor/memory/index2
-rw-r--r--test/trace_processor/memory/trace_metadata.out3
-rw-r--r--test/trace_processor/network/index8
-rw-r--r--test/trace_processor/network/inet_sock_set_state.out7
-rw-r--r--test/trace_processor/network/inet_sock_set_state.sql12
-rw-r--r--test/trace_processor/network/inet_sock_set_state.textproto121
-rw-r--r--test/trace_processor/network/kfree_skb.out4
-rw-r--r--test/trace_processor/network/kfree_skb.sql12
-rw-r--r--test/trace_processor/network/kfree_skb.textproto48
-rw-r--r--test/trace_processor/network/napi_gro_receive.out4
-rw-r--r--test/trace_processor/network/napi_gro_receive.sql16
-rw-r--r--test/trace_processor/network/napi_gro_receive.textproto75
-rw-r--r--test/trace_processor/network/net_dev_xmit.out5
-rw-r--r--test/trace_processor/network/net_dev_xmit.sql13
-rw-r--r--test/trace_processor/network/net_dev_xmit.textproto70
-rw-r--r--test/trace_processor/network/netif_receive_skb.out6
-rw-r--r--test/trace_processor/network/netif_receive_skb.sql13
-rw-r--r--test/trace_processor/network/netif_receive_skb.textproto65
-rw-r--r--test/trace_processor/network/netperf_metric.out147
-rw-r--r--test/trace_processor/network/netperf_metric.textproto336
-rw-r--r--test/trace_processor/network/tcp_retransmit_skb.out3
-rw-r--r--test/trace_processor/network/tcp_retransmit_skb.sql11
-rw-r--r--test/trace_processor/network/tcp_retransmit_skb.textproto34
-rw-r--r--test/trace_processor/parsing/android_log_counts.sql6
-rw-r--r--test/trace_processor/parsing/android_log_msgs.sql10
-rw-r--r--test/trace_processor/parsing/android_multiuser_switch.out5
-rw-r--r--test/trace_processor/parsing/android_multiuser_switch.textproto114
-rw-r--r--test/trace_processor/parsing/android_sched_and_ps_stats.out129
-rw-r--r--test/trace_processor/parsing/args_string_filter_null.sql2
-rw-r--r--test/trace_processor/parsing/atrace_compressed_sched_count.out2
-rw-r--r--test/trace_processor/parsing/atrace_uncompressed_sched_count.out2
-rw-r--r--test/trace_processor/parsing/b120487929.sql10
-rw-r--r--test/trace_processor/parsing/cgroup_attach_task_post_s.textproto17
-rw-r--r--test/trace_processor/parsing/cgroup_attach_task_post_s_print_systrace.out2
-rw-r--r--test/trace_processor/parsing/cgroup_attach_task_pre_s.textproto16
-rw-r--r--test/trace_processor/parsing/cgroup_attach_task_pre_s_print_systrace.out2
-rw-r--r--test/trace_processor/parsing/chrome_metadata.out7
-rw-r--r--test/trace_processor/parsing/counters_json_counters.out4
-rw-r--r--test/trace_processor/parsing/display_time_unit_slices.out2
-rw-r--r--test/trace_processor/parsing/flow_events_json_v2.json32
-rw-r--r--test/trace_processor/parsing/index40
-rw-r--r--test/trace_processor/parsing/instants_json_instants.out5
-rw-r--r--test/trace_processor/parsing/ion_stat.sql2
-rw-r--r--test/trace_processor/parsing/json_counters.sql6
-rw-r--r--test/trace_processor/parsing/json_instants.sql12
-rw-r--r--test/trace_processor/parsing/kernel_dpu_tmw_counter.textproto47
-rw-r--r--test/trace_processor/parsing/kernel_dpu_tmw_counter_thread_counter_and_track.out5
-rw-r--r--test/trace_processor/parsing/list_slices.sql2
-rw-r--r--test/trace_processor/parsing/mm_event.sql2
-rw-r--r--test/trace_processor/parsing/otheruuids.textproto46
-rw-r--r--test/trace_processor/parsing/otheruuids_android_other_traces.out5
-rw-r--r--test/trace_processor/parsing/rss_stat_mm_id_clone.py2
-rw-r--r--test/trace_processor/parsing/stats.sql2
-rw-r--r--test/trace_processor/parsing/systrace_html.out4
-rw-r--r--test/trace_processor/parsing/systrace_html.sql5
-rw-r--r--test/trace_processor/parsing/thread_time_in_state_event.out24
-rw-r--r--test/trace_processor/parsing/thread_time_in_thread_slice.out8
-rw-r--r--test/trace_processor/parsing/thread_time_in_thread_slice.sql3
-rw-r--r--test/trace_processor/parsing/very_long_sched.py34
-rw-r--r--test/trace_processor/parsing/very_long_sched_android_trace_quality.out5
-rw-r--r--test/trace_processor/performance/cpu_frequency_limits.out13
-rw-r--r--test/trace_processor/performance/cpu_frequency_limits.sql12
-rw-r--r--test/trace_processor/performance/cpu_frequency_limits.textproto84
-rw-r--r--test/trace_processor/performance/index4
-rw-r--r--test/trace_processor/performance/irq_runtime_metric.out50
-rw-r--r--test/trace_processor/performance/irq_runtime_metric.textproto97
-rw-r--r--test/trace_processor/power/dvfs_metric.out33
-rw-r--r--test/trace_processor/power/dvfs_metric.textproto55
-rw-r--r--test/trace_processor/power/index6
-rw-r--r--test/trace_processor/power/power_rails.sql2
-rw-r--r--test/trace_processor/power/power_rails_event.sql2
-rw-r--r--test/trace_processor/power/suspend_resume.out3
-rw-r--r--test/trace_processor/power/suspend_resume.sql12
-rw-r--r--test/trace_processor/power/suspend_resume.textproto56
-rw-r--r--test/trace_processor/power/wakesource.sql5
-rw-r--r--test/trace_processor/power/wakesource.textproto88
-rw-r--r--test/trace_processor/power/wakesource_wakesource.out5
-rw-r--r--test/trace_processor/profiling/callstack_sampling_flamegraph.out11
-rw-r--r--test/trace_processor/profiling/callstack_sampling_flamegraph.sql5
-rw-r--r--test/trace_processor/profiling/callstack_sampling_flamegraph_multi_process.out4
-rw-r--r--test/trace_processor/profiling/callstack_sampling_flamegraph_multi_process.sql17
-rw-r--r--test/trace_processor/profiling/heap_graph.textproto2
-rw-r--r--test/trace_processor/profiling/heap_graph_baseapk.textproto2
-rw-r--r--test/trace_processor/profiling/heap_graph_deobfuscate_pkg.textproto141
-rw-r--r--test/trace_processor/profiling/heap_graph_flamegraph.sql8
-rw-r--r--test/trace_processor/profiling/heap_graph_flamegraph_focused.sql10
-rw-r--r--test/trace_processor/profiling/heap_graph_flamegraph_matches_objects.out2
-rw-r--r--test/trace_processor/profiling/heap_graph_flamegraph_matches_objects.sql23
-rw-r--r--test/trace_processor/profiling/heap_graph_huge_size.textproto76
-rw-r--r--test/trace_processor/profiling/heap_graph_legacy.textproto2
-rw-r--r--test/trace_processor/profiling/heap_graph_native_size.out3
-rw-r--r--test/trace_processor/profiling/heap_graph_native_size.sql19
-rw-r--r--test/trace_processor/profiling/heap_graph_native_size.textproto217
-rw-r--r--test/trace_processor/profiling/heap_graph_object.out2
-rw-r--r--test/trace_processor/profiling/heap_profile_flamegraph.sql6
-rw-r--r--test/trace_processor/profiling/heap_profile_flamegraph_system-server-native-profile.out22
-rw-r--r--test/trace_processor/profiling/heap_profile_no_symbols.textproto55
-rw-r--r--test/trace_processor/profiling/heap_stats_closest_proc.out6
-rw-r--r--test/trace_processor/profiling/index8
-rw-r--r--test/trace_processor/profiling/java_heap_histogram.out34
-rw-r--r--test/trace_processor/profiling/java_heap_stats.out4
-rw-r--r--test/trace_processor/profiling/profiler_smaps_metric.out20
-rw-r--r--test/trace_processor/profiling/unsymbolized_frames.out14
-rw-r--r--test/trace_processor/python/api_integrationtest.py50
-rwxr-xr-xtest/trace_processor/python/api_unittest.py292
-rw-r--r--test/trace_processor/span_join/index29
-rw-r--r--test/trace_processor/span_join/span_outer_join_empty.out (renamed from test/trace_processor/span_join/span_outer_join_empty_android_sched_and_ps.out)0
-rw-r--r--test/trace_processor/span_join/span_outer_join_mixed.out23
-rw-r--r--test/trace_processor/span_join/span_outer_join_mixed.sql49
-rw-r--r--test/trace_processor/span_join/span_outer_join_mixed_empty.out4
-rw-r--r--test/trace_processor/span_join/span_outer_join_mixed_empty.sql33
-rw-r--r--test/trace_processor/span_join/span_outer_join_mixed_left_empty.out5
-rw-r--r--test/trace_processor/span_join/span_outer_join_mixed_left_empty.sql37
-rw-r--r--test/trace_processor/span_join/span_outer_join_mixed_left_empty_rev.out8
-rw-r--r--test/trace_processor/span_join/span_outer_join_mixed_left_empty_rev.sql37
-rw-r--r--test/trace_processor/span_join/span_outer_join_mixed_right_empty.out8
-rw-r--r--test/trace_processor/span_join/span_outer_join_mixed_right_empty.sql38
-rw-r--r--test/trace_processor/span_join/span_outer_join_mixed_right_empty_rev.out5
-rw-r--r--test/trace_processor/span_join/span_outer_join_mixed_right_empty_rev.sql38
-rw-r--r--test/trace_processor/span_join/span_outer_join_unpartitioned.out14
-rw-r--r--test/trace_processor/span_join/span_outer_join_unpartitioned.sql47
-rw-r--r--test/trace_processor/span_join/span_outer_join_unpartitioned_empty.out4
-rw-r--r--test/trace_processor/span_join/span_outer_join_unpartitioned_empty.sql32
-rw-r--r--test/trace_processor/span_join/span_outer_join_unpartitioned_left_empty.out8
-rw-r--r--test/trace_processor/span_join/span_outer_join_unpartitioned_left_empty.sql37
-rw-r--r--test/trace_processor/span_join/span_outer_join_unpartitioned_right_empty.out8
-rw-r--r--test/trace_processor/span_join/span_outer_join_unpartitioned_right_empty.sql37
-rw-r--r--test/trace_processor/startup/android_startup.out10
-rw-r--r--test/trace_processor/startup/android_startup.py9
-rw-r--r--test/trace_processor/startup/android_startup_attribution.out11
-rw-r--r--test/trace_processor/startup/android_startup_attribution.py24
-rw-r--r--test/trace_processor/startup/android_startup_minsdk33.out25
-rw-r--r--test/trace_processor/startup/android_startup_minsdk33.py38
-rw-r--r--test/trace_processor/startup/android_startup_powrails.out3
-rw-r--r--test/trace_processor/startup/android_startup_process_track.out28
-rw-r--r--test/trace_processor/startup/android_startup_process_track.py6
-rw-r--r--test/trace_processor/startup/index1
-rw-r--r--test/trace_processor/tables/ftrace_setup_errors.out7
-rw-r--r--test/trace_processor/tables/ftrace_setup_errors.sql3
-rw-r--r--test/trace_processor/tables/index3
-rw-r--r--test/trace_processor/tables/nulls.sql2
-rw-r--r--test/trace_processor/tables/trace_metadata.json.out3
-rw-r--r--test/trace_processor/track_event/experimental_slice_layout_depth.out4
-rw-r--r--test/trace_processor/track_event/experimental_slice_layout_depth.py43
-rw-r--r--test/trace_processor/track_event/experimental_slice_layout_depth.sql14
-rw-r--r--test/trace_processor/track_event/flow_events_proto_v1.textproto2
-rw-r--r--test/trace_processor/track_event/flow_events_track_event.out3
-rw-r--r--test/trace_processor/track_event/flow_events_track_event.textproto88
-rw-r--r--test/trace_processor/track_event/index6
-rw-r--r--test/trace_processor/track_event/merging_regression.out11
-rw-r--r--test/trace_processor/track_event/merging_regression.sql19
-rw-r--r--test/trace_processor/track_event/track_event_merged_debug_annotations_args.out4
-rw-r--r--test/trace_processor/track_event/track_event_typed_args.textproto18
-rw-r--r--test/trace_processor/track_event/track_event_typed_args_args.out2
-rw-r--r--test/trace_processor/translation/chrome_args.sql16
-rw-r--r--test/trace_processor/translation/chrome_histogram.out10
-rw-r--r--test/trace_processor/translation/chrome_histogram.textproto53
-rw-r--r--test/trace_processor/translation/chrome_performance_mark.out8
-rw-r--r--test/trace_processor/translation/chrome_performance_mark.textproto23
-rw-r--r--test/trace_processor/translation/chrome_user_event.out9
-rw-r--r--test/trace_processor/translation/chrome_user_event.textproto52
-rw-r--r--test/trace_processor/translation/index4
-rw-r--r--test/trace_processor/translation/slice_name.out5
-rw-r--r--test/trace_processor/translation/slice_name.sql1
-rw-r--r--test/trace_processor/translation/slice_name.textproto72
-rw-r--r--test/traced_integrationtest.cc455
-rw-r--r--tools/BUILD.gn7
-rwxr-xr-xtools/add_test_trace.sh81
-rwxr-xr-xtools/add_tp_diff_test.py24
-rw-r--r--tools/busy_threads/busy_threads.cc10
-rwxr-xr-xtools/check_include_violations4
-rwxr-xr-xtools/check_proto_comments2
-rwxr-xr-xtools/check_sql_metrics.py20
-rw-r--r--tools/compact_reencode/main.cc63
-rwxr-xr-xtools/cpu_profile568
-rw-r--r--tools/cpu_utilization/cpu_utilization.cc2
-rwxr-xr-xtools/export_power_profiles.py2
-rw-r--r--tools/ftrace_proto_gen/event_list60
-rw-r--r--tools/ftrace_proto_gen/proto_gen_utils.cc4
-rwxr-xr-xtools/gen_all17
-rwxr-xr-xtools/gen_amalgamated5
-rwxr-xr-xtools/gen_amalgamated_sql_metrics.py131
-rwxr-xr-xtools/gen_android_bp303
-rwxr-xr-xtools/gen_bazel261
-rwxr-xr-xtools/gen_binary_descriptors22
-rwxr-xr-xtools/gen_merged_protos6
-rwxr-xr-xtools/gen_merged_sql_metrics.py131
-rwxr-xr-xtools/gen_ui_imports77
-rw-r--r--tools/get_perfetto_prebuilt.py122
-rwxr-xr-xtools/gn12
-rw-r--r--tools/gn_utils.py67
-rwxr-xr-xtools/heap_profile367
-rw-r--r--tools/idle_alloc.cc6
-rwxr-xr-xtools/install-build-deps206
-rwxr-xr-xtools/java_heap_dump42
-rwxr-xr-xtools/measure_tp_performance.py169
-rw-r--r--tools/multithreaded_alloc.cc2
-rwxr-xr-xtools/ninja12
-rwxr-xr-xtools/open_trace_in_ui102
-rwxr-xr-xtools/package-prebuilts-for-github-release55
-rw-r--r--tools/proto_filter/proto_filter.cc2
-rw-r--r--tools/proto_merger/BUILD.gn35
-rw-r--r--tools/proto_merger/allowlist.cc130
-rw-r--r--tools/proto_merger/allowlist.h60
-rw-r--r--tools/proto_merger/main.cc282
-rw-r--r--tools/proto_merger/proto_file.cc278
-rw-r--r--tools/proto_merger/proto_file.h91
-rw-r--r--tools/proto_merger/proto_file_serializer.cc222
-rw-r--r--tools/proto_merger/proto_file_serializer.h61
-rw-r--r--tools/proto_merger/proto_merger.cc357
-rw-r--r--tools/proto_merger/proto_merger.h46
-rwxr-xr-xtools/pull_ftrace_format_files.py11
-rwxr-xr-xtools/record_android_trace307
-rw-r--r--tools/repackage_llvm_demangler.sh57
-rwxr-xr-xtools/roll-prebuilts190
-rw-r--r--tools/run_buildtools_binary.py59
-rwxr-xr-xtools/run_python_api_tests.py55
-rwxr-xr-xtools/size-report106
-rwxr-xr-xtools/symbolize-ui-crash9
-rwxr-xr-xtools/test_data255
-rw-r--r--tools/test_data.txt9
-rwxr-xr-xtools/tmux22
-rwxr-xr-xtools/trace_processor244
-rw-r--r--tools/trace_to_text/BUILD.gn79
-rw-r--r--tools/trace_to_text/lite_fallbacks.cc2
-rw-r--r--tools/trace_to_text/main.cc5
-rw-r--r--tools/trace_to_text/pprof_builder.cc62
-rw-r--r--tools/trace_to_text/symbolize_profile.cc14
-rw-r--r--tools/trace_to_text/trace_to_profile.cc3
-rw-r--r--tools/trace_to_text/trace_to_systrace.cc196
-rw-r--r--tools/trace_to_text/trace_to_text.cc326
-rw-r--r--tools/trace_to_text/trace_to_text.h3
-rw-r--r--tools/trace_to_text/trace_to_text_unittest.cc65
-rw-r--r--tools/trace_to_text/utils.cc48
-rw-r--r--tools/trace_to_text/utils.h5
-rwxr-xr-xtools/tracebox208
-rwxr-xr-xtools/traceconv214
-rwxr-xr-xtools/update_trace_processor41
-rwxr-xr-xtools/update_traceconv46
-rwxr-xr-xtools/write_version_header.py53
-rw-r--r--traced_perf.rc2
-rw-r--r--ui/OWNERS8
-rw-r--r--ui/PRESUBMIT.py16
-rw-r--r--ui/README.md44
-rw-r--r--ui/build.js161
-rw-r--r--ui/config/.gitignore1
-rw-r--r--ui/config/headless_environment.js36
-rw-r--r--ui/config/headless_setup.js17
-rw-r--r--ui/config/headless_teardown.js17
-rw-r--r--ui/config/integrationtest_env.js65
-rw-r--r--ui/config/integrationtest_setup.js57
-rw-r--r--ui/config/integrationtest_teardown.js24
-rw-r--r--ui/config/jest.headless.config.js21
-rw-r--r--ui/config/jest.individual.unit.config.js22
-rw-r--r--ui/config/jest.integrationtest.config.js21
-rw-r--r--ui/config/jest.jsdom.config.js19
-rw-r--r--ui/config/jest.unit.config.js20
-rw-r--r--ui/config/jest.unittest.config.js19
-rw-r--r--ui/config/rollup.config.js27
-rw-r--r--ui/package-lock.json2089
-rw-r--r--ui/package.json20
-rw-r--r--ui/release/OWNERS4
-rw-r--r--ui/release/channels.json5
-rwxr-xr-xui/run-all-tests20
-rwxr-xr-xui/run-integrationtests18
-rwxr-xr-xui/run-tests18
-rwxr-xr-xui/run-unittests18
-rw-r--r--ui/src/assets/common.scss308
-rw-r--r--ui/src/assets/details.scss50
-rw-r--r--ui/src/assets/flags_page.scss73
-rw-r--r--ui/src/assets/home_page.scss5
-rw-r--r--ui/src/assets/index.html5
-rw-r--r--ui/src/assets/metrics_page.scss1
-rw-r--r--ui/src/assets/modal.scss44
-rw-r--r--ui/src/assets/perfetto.scss1
-rw-r--r--ui/src/assets/record.scss152
-rw-r--r--ui/src/assets/sidebar.scss39
-rw-r--r--ui/src/assets/topbar.scss2
-rw-r--r--ui/src/assets/trace_info_page.scss1
-rw-r--r--ui/src/assets/typefaces.scss47
-rw-r--r--ui/src/base/generic_set.ts46
-rw-r--r--ui/src/base/remote.ts107
-rw-r--r--ui/src/base/string_utils.ts27
-rw-r--r--ui/src/base/string_utils_unittest.ts6
-rw-r--r--ui/src/chrome_extension/chrome_tracing_controller.ts23
-rw-r--r--ui/src/chrome_extension/manifest.json2
-rw-r--r--ui/src/common/actions.ts366
-rw-r--r--ui/src/common/actions_unittest.ts38
-rw-r--r--ui/src/common/aggregation_data.ts4
-rw-r--r--ui/src/common/arg_types.ts4
-rw-r--r--ui/src/common/cache_manager.ts119
-rw-r--r--ui/src/common/canvas_utils.ts28
-rw-r--r--ui/src/common/channels.ts49
-rw-r--r--ui/src/common/colorizer.ts28
-rw-r--r--ui/src/common/conversion_jobs.ts26
-rw-r--r--ui/src/common/empty_state.ts109
-rw-r--r--ui/src/common/engine.ts352
-rw-r--r--ui/src/common/feature_flags.ts236
-rw-r--r--ui/src/common/feature_flags_unittest.ts118
-rw-r--r--ui/src/common/flamegraph_util.ts6
-rw-r--r--ui/src/common/http_rpc_engine.ts127
-rw-r--r--ui/src/common/immer_init.ts29
-rw-r--r--ui/src/common/pivot_table_common.ts186
-rw-r--r--ui/src/common/pivot_table_query_generator.ts320
-rw-r--r--ui/src/common/pivot_table_query_generator_unittest.ts306
-rw-r--r--ui/src/common/proto_ring_buffer.ts156
-rw-r--r--ui/src/common/proto_ring_buffer_unittest.ts140
-rw-r--r--ui/src/common/protos.ts70
-rw-r--r--ui/src/common/queries.ts54
-rw-r--r--ui/src/common/query_iterator.ts246
-rw-r--r--ui/src/common/query_iterator_unittest.ts235
-rw-r--r--ui/src/common/query_result.ts822
-rw-r--r--ui/src/common/query_result_unittest.ts302
-rw-r--r--ui/src/common/search_data.ts6
-rw-r--r--ui/src/common/state.ts426
-rw-r--r--ui/src/common/state_unittest.ts8
-rw-r--r--ui/src/common/time.ts2
-rw-r--r--ui/src/common/upload_utils.ts4
-rw-r--r--ui/src/common/wasm_engine_proxy.ts151
-rw-r--r--ui/src/common/worker_messages.ts44
-rw-r--r--ui/src/controller/adb.ts20
-rw-r--r--ui/src/controller/adb_base_controller.ts39
-rw-r--r--ui/src/controller/adb_shell_controller.ts4
-rw-r--r--ui/src/controller/adb_socket_controller.ts6
-rw-r--r--ui/src/controller/aggregation/aggregation_controller.ts67
-rw-r--r--ui/src/controller/aggregation/frame_aggregation_controller.ts103
-rw-r--r--ui/src/controller/aggregation/slice_aggregation_controller.ts72
-rw-r--r--ui/src/controller/aggregation/thread_aggregation_controller.ts30
-rw-r--r--ui/src/controller/area_selection_handler.ts57
-rw-r--r--ui/src/controller/area_selection_handler_unittest.ts136
-rw-r--r--ui/src/controller/chrome_proxy_record_controller.ts21
-rw-r--r--ui/src/controller/consumer_port_types.ts16
-rw-r--r--ui/src/controller/cpu_profile_controller.ts33
-rw-r--r--ui/src/controller/flamegraph_controller.ts481
-rw-r--r--ui/src/controller/flow_events_controller.ts191
-rw-r--r--ui/src/controller/globals.ts88
-rw-r--r--ui/src/controller/heap_profile_controller.ts357
-rw-r--r--ui/src/controller/index.ts48
-rw-r--r--ui/src/controller/loading_manager.ts4
-rw-r--r--ui/src/controller/logs_controller.ts82
-rw-r--r--ui/src/controller/metrics_controller.ts36
-rw-r--r--ui/src/controller/permalink_controller.ts43
-rw-r--r--ui/src/controller/pivot_table_controller.ts755
-rw-r--r--ui/src/controller/pivot_table_redux_controller.ts223
-rw-r--r--ui/src/controller/query_controller.ts46
-rw-r--r--ui/src/controller/record_config_types.ts112
-rw-r--r--ui/src/controller/record_controller.ts108
-rw-r--r--ui/src/controller/record_controller_interfaces.ts3
-rw-r--r--ui/src/controller/record_controller_jsdomtest.ts105
-rw-r--r--ui/src/controller/search_controller.ts102
-rw-r--r--ui/src/controller/selection_controller.ts424
-rw-r--r--ui/src/controller/trace_controller.ts508
-rw-r--r--ui/src/controller/trace_converter.ts122
-rw-r--r--ui/src/controller/trace_error_controller.ts12
-rw-r--r--ui/src/controller/trace_stream.ts8
-rw-r--r--ui/src/controller/track_controller.ts7
-rw-r--r--ui/src/controller/track_decider.ts699
-rw-r--r--ui/src/controller/validate_config.ts57
-rw-r--r--ui/src/controller/validate_config_jsdomtest.ts100
-rw-r--r--ui/src/controller/validators.ts267
-rw-r--r--ui/src/controller/validators_unittest.ts109
-rw-r--r--ui/src/engine/index.ts48
-rw-r--r--ui/src/engine/wasm_bridge.ts98
-rw-r--r--ui/src/frontend/analytics.ts25
-rw-r--r--ui/src/frontend/analyze_page.ts65
-rw-r--r--ui/src/frontend/android_bug_tool.ts16
-rw-r--r--ui/src/frontend/base_slice_track.ts735
-rw-r--r--ui/src/frontend/checkerboard.ts11
-rw-r--r--ui/src/frontend/chrome_slice_panel.ts147
-rw-r--r--ui/src/frontend/clipboard.ts42
-rw-r--r--ui/src/frontend/cookie_consent.ts11
-rw-r--r--ui/src/frontend/counter_panel.ts5
-rw-r--r--ui/src/frontend/details_panel.ts125
-rw-r--r--ui/src/frontend/error_dialog.ts21
-rw-r--r--ui/src/frontend/file_drop_handler.ts1
-rw-r--r--ui/src/frontend/flags_page.ts142
-rw-r--r--ui/src/frontend/flamegraph.ts51
-rw-r--r--ui/src/frontend/flamegraph_panel.ts340
-rw-r--r--ui/src/frontend/flow_events_panel.ts27
-rw-r--r--ui/src/frontend/flow_events_renderer.ts45
-rw-r--r--ui/src/frontend/frontend_local_state.ts96
-rw-r--r--ui/src/frontend/globals.ts163
-rw-r--r--ui/src/frontend/heap_profile_panel.ts278
-rw-r--r--ui/src/frontend/help_modal.ts7
-rw-r--r--ui/src/frontend/home_page.ts23
-rw-r--r--ui/src/frontend/index.ts440
-rw-r--r--ui/src/frontend/keyboard_event_handler.ts165
-rw-r--r--ui/src/frontend/live_reload.ts17
-rw-r--r--ui/src/frontend/logs_panel.ts4
-rw-r--r--ui/src/frontend/modal.ts10
-rw-r--r--ui/src/frontend/named_slice_track.ts85
-rw-r--r--ui/src/frontend/notes_panel.ts76
-rw-r--r--ui/src/frontend/pages.ts17
-rw-r--r--ui/src/frontend/pan_and_zoom_handler.ts3
-rw-r--r--ui/src/frontend/panel_container.ts112
-rw-r--r--ui/src/frontend/perf.ts5
-rw-r--r--ui/src/frontend/pivot_table.ts342
-rw-r--r--ui/src/frontend/pivot_table_editor.ts251
-rw-r--r--ui/src/frontend/pivot_table_helper.ts363
-rw-r--r--ui/src/frontend/pivot_table_helper_unittest.ts139
-rw-r--r--ui/src/frontend/pivot_table_redux.ts387
-rw-r--r--ui/src/frontend/pivot_table_redux_query_generator.ts234
-rw-r--r--ui/src/frontend/popup_menu.ts120
-rw-r--r--ui/src/frontend/post_message_handler.ts13
-rw-r--r--ui/src/frontend/publish.ts204
-rw-r--r--ui/src/frontend/query_table.ts82
-rw-r--r--ui/src/frontend/raf_scheduler.ts4
-rw-r--r--ui/src/frontend/record_config.ts182
-rw-r--r--ui/src/frontend/record_page.ts412
-rw-r--r--ui/src/frontend/record_widgets.ts108
-rw-r--r--ui/src/frontend/router.ts232
-rw-r--r--ui/src/frontend/router_jsdomtest.ts144
-rw-r--r--ui/src/frontend/router_unittest.ts106
-rw-r--r--ui/src/frontend/rpc_http_dialog.ts140
-rw-r--r--ui/src/frontend/scroll_helper.ts18
-rw-r--r--ui/src/frontend/search_handler.ts30
-rw-r--r--ui/src/frontend/service_worker_controller.ts13
-rw-r--r--ui/src/frontend/sidebar.ts377
-rw-r--r--ui/src/frontend/slice.ts31
-rw-r--r--ui/src/frontend/slice_details_panel.ts177
-rw-r--r--ui/src/frontend/slice_layout.ts76
-rw-r--r--ui/src/frontend/slice_panel.ts159
-rw-r--r--ui/src/frontend/tickmark_panel.ts2
-rw-r--r--ui/src/frontend/time_scale.ts2
-rw-r--r--ui/src/frontend/time_scale_unittest.ts2
-rw-r--r--ui/src/frontend/time_selection_panel.ts5
-rw-r--r--ui/src/frontend/topbar.ts14
-rw-r--r--ui/src/frontend/trace_attrs.ts5
-rw-r--r--ui/src/frontend/trace_converter.ts115
-rw-r--r--ui/src/frontend/trace_url_handler.ts239
-rw-r--r--ui/src/frontend/track.ts133
-rw-r--r--ui/src/frontend/track_group_panel.ts53
-rw-r--r--ui/src/frontend/track_panel.ts174
-rw-r--r--ui/src/frontend/video_panel.ts75
-rw-r--r--ui/src/frontend/viewer_page.ts7
-rw-r--r--ui/src/service_worker/service_worker.ts14
-rw-r--r--ui/src/test/example_async_unittest.ts18
-rw-r--r--ui/src/test/example_dingus_unittest.ts53
-rw-r--r--ui/src/test/example_headlesstest.ts21
-rw-r--r--ui/src/test/example_jsdomtest.ts18
-rw-r--r--ui/src/test/example_unittest.ts17
-rw-r--r--ui/src/test/perfetto_ui_test_helper.ts128
-rw-r--r--ui/src/test/ui_integrationtest.ts278
-rw-r--r--ui/src/traceconv/index.ts235
-rw-r--r--ui/src/tracks/actual_frames/controller.ts63
-rw-r--r--ui/src/tracks/actual_frames/frontend.ts7
-rw-r--r--ui/src/tracks/actual_frames/index.ts16
-rw-r--r--ui/src/tracks/all_controller.ts30
-rw-r--r--ui/src/tracks/all_frontend.ts30
-rw-r--r--ui/src/tracks/android_log/controller.ts28
-rw-r--r--ui/src/tracks/android_log/frontend.ts11
-rw-r--r--ui/src/tracks/android_log/index.ts16
-rw-r--r--ui/src/tracks/async_slices/controller.ts54
-rw-r--r--ui/src/tracks/async_slices/frontend.ts7
-rw-r--r--ui/src/tracks/async_slices/index.ts16
-rw-r--r--ui/src/tracks/chrome_slices/common.ts2
-rw-r--r--ui/src/tracks/chrome_slices/controller.ts110
-rw-r--r--ui/src/tracks/chrome_slices/frontend.ts47
-rw-r--r--ui/src/tracks/chrome_slices/index.ts16
-rw-r--r--ui/src/tracks/counter/controller.ts65
-rw-r--r--ui/src/tracks/counter/frontend.ts21
-rw-r--r--ui/src/tracks/counter/index.ts16
-rw-r--r--ui/src/tracks/cpu_freq/controller.ts128
-rw-r--r--ui/src/tracks/cpu_freq/frontend.ts23
-rw-r--r--ui/src/tracks/cpu_freq/index.ts16
-rw-r--r--ui/src/tracks/cpu_profile/controller.ts24
-rw-r--r--ui/src/tracks/cpu_profile/frontend.ts36
-rw-r--r--ui/src/tracks/cpu_profile/index.ts16
-rw-r--r--ui/src/tracks/cpu_slices/controller.ts40
-rw-r--r--ui/src/tracks/cpu_slices/frontend.ts42
-rw-r--r--ui/src/tracks/cpu_slices/index.ts16
-rw-r--r--ui/src/tracks/debug_slices/controller.ts57
-rw-r--r--ui/src/tracks/debug_slices/frontend.ts7
-rw-r--r--ui/src/tracks/debug_slices/index.ts16
-rw-r--r--ui/src/tracks/expected_frames/controller.ts50
-rw-r--r--ui/src/tracks/expected_frames/frontend.ts7
-rw-r--r--ui/src/tracks/expected_frames/index.ts16
-rw-r--r--ui/src/tracks/generic_slice_track/index.ts48
-rw-r--r--ui/src/tracks/heap_profile/controller.ts14
-rw-r--r--ui/src/tracks/heap_profile/frontend.ts17
-rw-r--r--ui/src/tracks/heap_profile/index.ts16
-rw-r--r--ui/src/tracks/perf_samples_profile/common.ts24
-rw-r--r--ui/src/tracks/perf_samples_profile/controller.ts62
-rw-r--r--ui/src/tracks/perf_samples_profile/frontend.ts152
-rw-r--r--ui/src/tracks/perf_samples_profile/index.ts16
-rw-r--r--ui/src/tracks/process_scheduling/controller.ts52
-rw-r--r--ui/src/tracks/process_scheduling/frontend.ts47
-rw-r--r--ui/src/tracks/process_scheduling/index.ts16
-rw-r--r--ui/src/tracks/process_summary/controller.ts28
-rw-r--r--ui/src/tracks/process_summary/frontend.ts11
-rw-r--r--ui/src/tracks/process_summary/index.ts16
-rw-r--r--ui/src/tracks/thread_state/controller.ts78
-rw-r--r--ui/src/tracks/thread_state/frontend.ts21
-rw-r--r--ui/src/tracks/thread_state/index.ts16
-rw-r--r--ui/tsconfig.base.json1
3374 files changed, 171483 insertions, 42449 deletions
diff --git a/.gitignore b/.gitignore
index 0dbc57842..edd13d312 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,5 +25,6 @@
/node_modules/
/out*
/ui/dist
+/venv/*
+perf.data*
TAGS
-/venv/* \ No newline at end of file
diff --git a/Android.bp b/Android.bp
index 090910dbd..5373c691f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -16,9968 +16,10867 @@
// GN: //src/profiling/memory:heapprofd
cc_binary {
- name: "heapprofd",
- srcs: [
- ":perfetto_include_perfetto_base_base",
- ":perfetto_include_perfetto_ext_base_base",
- ":perfetto_include_perfetto_ext_ipc_ipc",
- ":perfetto_include_perfetto_ext_tracing_core_core",
- ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
- ":perfetto_include_perfetto_profiling_normalize",
- ":perfetto_include_perfetto_protozero_protozero",
- ":perfetto_include_perfetto_tracing_core_core",
- ":perfetto_include_perfetto_tracing_core_forward_decls",
- ":perfetto_include_perfetto_tracing_tracing",
- ":perfetto_protos_perfetto_common_cpp_gen",
- ":perfetto_protos_perfetto_common_zero_gen",
- ":perfetto_protos_perfetto_config_android_cpp_gen",
- ":perfetto_protos_perfetto_config_android_zero_gen",
- ":perfetto_protos_perfetto_config_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_zero_gen",
- ":perfetto_protos_perfetto_config_gpu_cpp_gen",
- ":perfetto_protos_perfetto_config_gpu_zero_gen",
- ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
- ":perfetto_protos_perfetto_config_inode_file_zero_gen",
- ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
- ":perfetto_protos_perfetto_config_interceptors_zero_gen",
- ":perfetto_protos_perfetto_config_power_cpp_gen",
- ":perfetto_protos_perfetto_config_power_zero_gen",
- ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_process_stats_zero_gen",
- ":perfetto_protos_perfetto_config_profiling_cpp_gen",
- ":perfetto_protos_perfetto_config_profiling_zero_gen",
- ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_config_track_event_cpp_gen",
- ":perfetto_protos_perfetto_config_track_event_zero_gen",
- ":perfetto_protos_perfetto_config_zero_gen",
- ":perfetto_protos_perfetto_ipc_cpp_gen",
- ":perfetto_protos_perfetto_ipc_ipc_gen",
- ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
- ":perfetto_protos_perfetto_trace_android_zero_gen",
- ":perfetto_protos_perfetto_trace_chrome_zero_gen",
- ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
- ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
- ":perfetto_protos_perfetto_trace_gpu_zero_gen",
- ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
- ":perfetto_protos_perfetto_trace_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
- ":perfetto_protos_perfetto_trace_power_zero_gen",
- ":perfetto_protos_perfetto_trace_profiling_zero_gen",
- ":perfetto_protos_perfetto_trace_ps_zero_gen",
- ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_trace_system_info_zero_gen",
- ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
- ":perfetto_protos_perfetto_trace_track_event_zero_gen",
- ":perfetto_src_base_base",
- ":perfetto_src_base_unix_socket",
- ":perfetto_src_ipc_client",
- ":perfetto_src_ipc_common",
- ":perfetto_src_profiling_common_callstack_trie",
- ":perfetto_src_profiling_common_interner",
- ":perfetto_src_profiling_common_interning_output",
- ":perfetto_src_profiling_common_proc_utils",
- ":perfetto_src_profiling_common_producer_support",
- ":perfetto_src_profiling_common_profiler_guardrails",
- ":perfetto_src_profiling_common_unwind_support",
- ":perfetto_src_profiling_memory_daemon",
- ":perfetto_src_profiling_memory_ring_buffer",
- ":perfetto_src_profiling_memory_scoped_spinlock",
- ":perfetto_src_profiling_memory_wire_protocol",
- ":perfetto_src_protozero_protozero",
- ":perfetto_src_traced_probes_packages_list_packages_list_parser",
- ":perfetto_src_tracing_common",
- ":perfetto_src_tracing_core_core",
- ":perfetto_src_tracing_ipc_common",
- ":perfetto_src_tracing_ipc_producer_producer",
- "src/profiling/memory/main.cc",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- "libprocinfo",
- "libunwindstack",
- ],
- init_rc: [
- "heapprofd.rc",
- ],
- generated_headers: [
- "perfetto_protos_perfetto_common_cpp_gen_headers",
- "perfetto_protos_perfetto_common_zero_gen_headers",
- "perfetto_protos_perfetto_config_android_cpp_gen_headers",
- "perfetto_protos_perfetto_config_android_zero_gen_headers",
- "perfetto_protos_perfetto_config_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
- "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
- "perfetto_protos_perfetto_config_power_cpp_gen_headers",
- "perfetto_protos_perfetto_config_power_zero_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
- "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_config_zero_gen_headers",
- "perfetto_protos_perfetto_ipc_cpp_gen_headers",
- "perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_android_zero_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
- "perfetto_protos_perfetto_trace_power_zero_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_src_base_version_gen_h",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- cflags: [
- "-DGOOGLE_PROTOBUF_NO_RTTI",
- "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
- ],
- header_libs: [
- "bionic_libc_platform_headers",
- ],
+ name: "heapprofd",
+ srcs: [
+ ":perfetto_include_perfetto_base_base",
+ ":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_include_perfetto_ext_ipc_ipc",
+ ":perfetto_include_perfetto_ext_tracing_core_core",
+ ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
+ ":perfetto_include_perfetto_protozero_protozero",
+ ":perfetto_include_perfetto_tracing_core_core",
+ ":perfetto_include_perfetto_tracing_core_forward_decls",
+ ":perfetto_include_perfetto_tracing_tracing",
+ ":perfetto_protos_perfetto_common_cpp_gen",
+ ":perfetto_protos_perfetto_common_zero_gen",
+ ":perfetto_protos_perfetto_config_android_cpp_gen",
+ ":perfetto_protos_perfetto_config_android_zero_gen",
+ ":perfetto_protos_perfetto_config_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_config_gpu_cpp_gen",
+ ":perfetto_protos_perfetto_config_gpu_zero_gen",
+ ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
+ ":perfetto_protos_perfetto_config_inode_file_zero_gen",
+ ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
+ ":perfetto_protos_perfetto_config_interceptors_zero_gen",
+ ":perfetto_protos_perfetto_config_power_cpp_gen",
+ ":perfetto_protos_perfetto_config_power_zero_gen",
+ ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_process_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_profiling_cpp_gen",
+ ":perfetto_protos_perfetto_config_profiling_zero_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_config_track_event_zero_gen",
+ ":perfetto_protos_perfetto_config_zero_gen",
+ ":perfetto_protos_perfetto_ipc_cpp_gen",
+ ":perfetto_protos_perfetto_ipc_ipc_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
+ ":perfetto_protos_perfetto_trace_android_zero_gen",
+ ":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
+ ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_trace_gpu_zero_gen",
+ ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
+ ":perfetto_protos_perfetto_trace_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
+ ":perfetto_protos_perfetto_trace_power_zero_gen",
+ ":perfetto_protos_perfetto_trace_profiling_zero_gen",
+ ":perfetto_protos_perfetto_trace_ps_zero_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_trace_system_info_zero_gen",
+ ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_trace_track_event_zero_gen",
+ ":perfetto_protos_perfetto_trace_translation_zero_gen",
+ ":perfetto_src_base_base",
+ ":perfetto_src_base_unix_socket",
+ ":perfetto_src_ipc_client",
+ ":perfetto_src_ipc_common",
+ ":perfetto_src_profiling_common_callstack_trie",
+ ":perfetto_src_profiling_common_interner",
+ ":perfetto_src_profiling_common_interning_output",
+ ":perfetto_src_profiling_common_proc_cmdline",
+ ":perfetto_src_profiling_common_proc_utils",
+ ":perfetto_src_profiling_common_producer_support",
+ ":perfetto_src_profiling_common_profiler_guardrails",
+ ":perfetto_src_profiling_common_unwind_support",
+ ":perfetto_src_profiling_memory_daemon",
+ ":perfetto_src_profiling_memory_heapprofd_main",
+ ":perfetto_src_profiling_memory_ring_buffer",
+ ":perfetto_src_profiling_memory_scoped_spinlock",
+ ":perfetto_src_profiling_memory_wire_protocol",
+ ":perfetto_src_protozero_protozero",
+ ":perfetto_src_traced_probes_packages_list_packages_list_parser",
+ ":perfetto_src_tracing_common",
+ ":perfetto_src_tracing_core_core",
+ ":perfetto_src_tracing_ipc_common",
+ ":perfetto_src_tracing_ipc_default_socket",
+ ":perfetto_src_tracing_ipc_producer_producer",
+ "src/profiling/memory/main.cc",
+ ],
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "libprocinfo",
+ "libunwindstack",
+ ],
+ init_rc: [
+ "heapprofd.rc",
+ ],
+ generated_headers: [
+ "perfetto_protos_perfetto_common_cpp_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_android_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_android_zero_gen_headers",
+ "perfetto_protos_perfetto_config_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
+ "perfetto_protos_perfetto_config_power_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_power_zero_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
+ "perfetto_protos_perfetto_ipc_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_ipc_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_android_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_power_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_zero_gen_headers",
+ "perfetto_src_base_version_gen_h",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ cflags: [
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ ],
+ header_libs: [
+ "bionic_libc_platform_headers",
+ ],
}
// GN: //src/profiling/memory:heapprofd_api_noop
cc_library_shared {
- name: "heapprofd_api_noop",
- srcs: [
- "src/profiling/memory/client_api_noop.cc",
- ],
- export_include_dirs: [
- "src/profiling/memory/include",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- version_script: "src/profiling/memory/heapprofd_client_api.map.txt",
- stubs: {
- versions: [
- "S",
- ],
- symbol_file: "src/profiling/memory/heapprofd_client_api.map.txt",
- },
+ name: "heapprofd_api_noop",
+ srcs: [
+ "src/profiling/memory/client_api_noop.cc",
+ ],
+ export_include_dirs: [
+ "src/profiling/memory/include",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ version_script: "src/profiling/memory/heapprofd_client_api.map.txt",
+ stubs: {
+ versions: [
+ "S",
+ ],
+ symbol_file: "src/profiling/memory/heapprofd_client_api.map.txt",
+ },
}
// GN: //src/profiling/memory:heapprofd_client
cc_library_shared {
- name: "heapprofd_client",
- srcs: [
- ":perfetto_include_perfetto_base_base",
- ":perfetto_include_perfetto_ext_base_base",
- ":perfetto_src_base_base",
- ":perfetto_src_profiling_memory_malloc_interceptor_bionic_hooks",
- ":perfetto_src_profiling_memory_wrap_allocators",
- ],
- shared_libs: [
- "heapprofd_client_api",
- ],
- static_libs: [
- "libasync_safe",
- ],
- generated_headers: [
- "perfetto_src_base_version_gen_h",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- cflags: [
- "-DPERFETTO_ANDROID_ASYNC_SAFE_LOG",
- ],
- include_dirs: [
- "bionic/libc",
- ],
- header_libs: [
- "bionic_libc_platform_headers",
- ],
+ name: "heapprofd_client",
+ srcs: [
+ ":perfetto_include_perfetto_base_base",
+ ":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_src_base_base",
+ ":perfetto_src_profiling_memory_malloc_interceptor_bionic_hooks",
+ ":perfetto_src_profiling_memory_wrap_allocators",
+ ],
+ shared_libs: [
+ "heapprofd_client_api",
+ ],
+ static_libs: [
+ "libasync_safe",
+ ],
+ generated_headers: [
+ "perfetto_src_base_version_gen_h",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ cflags: [
+ "-DPERFETTO_ANDROID_ASYNC_SAFE_LOG",
+ ],
+ include_dirs: [
+ "bionic/libc",
+ ],
+ header_libs: [
+ "bionic_libc_platform_headers",
+ ],
}
// GN: //src/profiling/memory:heapprofd_client_api
cc_library_shared {
- name: "heapprofd_client_api",
- srcs: [
- ":perfetto_include_perfetto_base_base",
- ":perfetto_include_perfetto_ext_base_base",
- ":perfetto_include_perfetto_profiling_normalize",
- ":perfetto_src_base_base",
- ":perfetto_src_base_unix_socket",
- ":perfetto_src_profiling_common_proc_utils",
- ":perfetto_src_profiling_memory_client",
- ":perfetto_src_profiling_memory_client_api",
- ":perfetto_src_profiling_memory_ring_buffer",
- ":perfetto_src_profiling_memory_scoped_spinlock",
- ":perfetto_src_profiling_memory_wire_protocol",
- "src/profiling/memory/client_api_factory_android.cc",
- ],
- shared_libs: [
- "libbase",
- "libprocinfo",
- "libunwindstack",
- ],
- static_libs: [
- "libasync_safe",
- ],
- export_include_dirs: [
- "src/profiling/memory/include",
- ],
- generated_headers: [
- "perfetto_src_base_version_gen_h",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- cflags: [
- "-DPERFETTO_ANDROID_ASYNC_SAFE_LOG",
- "-Werror=global-constructors",
- "-Wglobal-constructors",
- ],
- header_libs: [
- "bionic_libc_platform_headers",
- ],
- version_script: "src/profiling/memory/heapprofd_client_api.map.txt",
- stubs: {
- versions: [
- "S",
- ],
- symbol_file: "src/profiling/memory/heapprofd_client_api.map.txt",
- },
+ name: "heapprofd_client_api",
+ srcs: [
+ ":perfetto_include_perfetto_base_base",
+ ":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_src_base_base",
+ ":perfetto_src_base_unix_socket",
+ ":perfetto_src_profiling_memory_client",
+ ":perfetto_src_profiling_memory_client_api",
+ ":perfetto_src_profiling_memory_ring_buffer",
+ ":perfetto_src_profiling_memory_scoped_spinlock",
+ ":perfetto_src_profiling_memory_wire_protocol",
+ "src/profiling/memory/client_api_factory_android.cc",
+ ],
+ shared_libs: [
+ "libbase",
+ "libprocinfo",
+ "libunwindstack",
+ ],
+ static_libs: [
+ "libasync_safe",
+ ],
+ export_include_dirs: [
+ "src/profiling/memory/include",
+ ],
+ generated_headers: [
+ "perfetto_src_base_version_gen_h",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ cflags: [
+ "-DPERFETTO_ANDROID_ASYNC_SAFE_LOG",
+ "-Werror=global-constructors",
+ "-Wglobal-constructors",
+ ],
+ header_libs: [
+ "bionic_libc_platform_headers",
+ ],
+ version_script: "src/profiling/memory/heapprofd_client_api.map.txt",
+ stubs: {
+ versions: [
+ "S",
+ ],
+ symbol_file: "src/profiling/memory/heapprofd_client_api.map.txt",
+ },
}
// GN: //src/profiling/memory:heapprofd_standalone_client
cc_library_shared {
- name: "heapprofd_standalone_client",
- srcs: [
- ":perfetto_include_perfetto_base_base",
- ":perfetto_include_perfetto_ext_base_base",
- ":perfetto_include_perfetto_ext_ipc_ipc",
- ":perfetto_include_perfetto_ext_tracing_core_core",
- ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
- ":perfetto_include_perfetto_profiling_normalize",
- ":perfetto_include_perfetto_protozero_protozero",
- ":perfetto_include_perfetto_tracing_core_core",
- ":perfetto_include_perfetto_tracing_core_forward_decls",
- ":perfetto_include_perfetto_tracing_tracing",
- ":perfetto_protos_perfetto_common_cpp_gen",
- ":perfetto_protos_perfetto_common_zero_gen",
- ":perfetto_protos_perfetto_config_android_cpp_gen",
- ":perfetto_protos_perfetto_config_android_zero_gen",
- ":perfetto_protos_perfetto_config_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_zero_gen",
- ":perfetto_protos_perfetto_config_gpu_cpp_gen",
- ":perfetto_protos_perfetto_config_gpu_zero_gen",
- ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
- ":perfetto_protos_perfetto_config_inode_file_zero_gen",
- ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
- ":perfetto_protos_perfetto_config_interceptors_zero_gen",
- ":perfetto_protos_perfetto_config_power_cpp_gen",
- ":perfetto_protos_perfetto_config_power_zero_gen",
- ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_process_stats_zero_gen",
- ":perfetto_protos_perfetto_config_profiling_cpp_gen",
- ":perfetto_protos_perfetto_config_profiling_zero_gen",
- ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_config_track_event_cpp_gen",
- ":perfetto_protos_perfetto_config_track_event_zero_gen",
- ":perfetto_protos_perfetto_config_zero_gen",
- ":perfetto_protos_perfetto_ipc_cpp_gen",
- ":perfetto_protos_perfetto_ipc_ipc_gen",
- ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
- ":perfetto_protos_perfetto_trace_android_zero_gen",
- ":perfetto_protos_perfetto_trace_chrome_zero_gen",
- ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
- ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
- ":perfetto_protos_perfetto_trace_gpu_zero_gen",
- ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
- ":perfetto_protos_perfetto_trace_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
- ":perfetto_protos_perfetto_trace_power_zero_gen",
- ":perfetto_protos_perfetto_trace_profiling_zero_gen",
- ":perfetto_protos_perfetto_trace_ps_zero_gen",
- ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_trace_system_info_zero_gen",
- ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
- ":perfetto_protos_perfetto_trace_track_event_zero_gen",
- ":perfetto_src_base_base",
- ":perfetto_src_base_unix_socket",
- ":perfetto_src_ipc_client",
- ":perfetto_src_ipc_common",
- ":perfetto_src_profiling_common_callstack_trie",
- ":perfetto_src_profiling_common_interner",
- ":perfetto_src_profiling_common_interning_output",
- ":perfetto_src_profiling_common_proc_utils",
- ":perfetto_src_profiling_common_producer_support",
- ":perfetto_src_profiling_common_profiler_guardrails",
- ":perfetto_src_profiling_common_unwind_support",
- ":perfetto_src_profiling_memory_client",
- ":perfetto_src_profiling_memory_client_api",
- ":perfetto_src_profiling_memory_client_api_standalone",
- ":perfetto_src_profiling_memory_daemon",
- ":perfetto_src_profiling_memory_ring_buffer",
- ":perfetto_src_profiling_memory_scoped_spinlock",
- ":perfetto_src_profiling_memory_wire_protocol",
- ":perfetto_src_protozero_protozero",
- ":perfetto_src_traced_probes_packages_list_packages_list_parser",
- ":perfetto_src_tracing_common",
- ":perfetto_src_tracing_core_core",
- ":perfetto_src_tracing_ipc_common",
- ":perfetto_src_tracing_ipc_producer_producer",
- ],
- shared_libs: [
- "liblog",
- ],
- static_libs: [
- "libasync_safe",
- "libbase",
- "libdexfile_support",
- "liblzma",
- "libprocinfo",
- "libunwindstack",
- ],
- export_include_dirs: [
- "src/profiling/memory/include",
- ],
- generated_headers: [
- "perfetto_protos_perfetto_common_cpp_gen_headers",
- "perfetto_protos_perfetto_common_zero_gen_headers",
- "perfetto_protos_perfetto_config_android_cpp_gen_headers",
- "perfetto_protos_perfetto_config_android_zero_gen_headers",
- "perfetto_protos_perfetto_config_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
- "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
- "perfetto_protos_perfetto_config_power_cpp_gen_headers",
- "perfetto_protos_perfetto_config_power_zero_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
- "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_config_zero_gen_headers",
- "perfetto_protos_perfetto_ipc_cpp_gen_headers",
- "perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_android_zero_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
- "perfetto_protos_perfetto_trace_power_zero_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_src_base_version_gen_h",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- cflags: [
- "-DGOOGLE_PROTOBUF_NO_RTTI",
- "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
- "-DPERFETTO_ANDROID_ASYNC_SAFE_LOG",
- ],
- header_libs: [
- "bionic_libc_platform_headers",
- ],
- stl: "libc++_static",
- version_script: "src/profiling/memory/heapprofd_client_api.map.txt",
+ name: "heapprofd_standalone_client",
+ srcs: [
+ ":perfetto_include_perfetto_base_base",
+ ":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_include_perfetto_ext_ipc_ipc",
+ ":perfetto_include_perfetto_ext_tracing_core_core",
+ ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
+ ":perfetto_include_perfetto_protozero_protozero",
+ ":perfetto_include_perfetto_tracing_core_core",
+ ":perfetto_include_perfetto_tracing_core_forward_decls",
+ ":perfetto_include_perfetto_tracing_tracing",
+ ":perfetto_protos_perfetto_common_cpp_gen",
+ ":perfetto_protos_perfetto_common_zero_gen",
+ ":perfetto_protos_perfetto_config_android_cpp_gen",
+ ":perfetto_protos_perfetto_config_android_zero_gen",
+ ":perfetto_protos_perfetto_config_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_config_gpu_cpp_gen",
+ ":perfetto_protos_perfetto_config_gpu_zero_gen",
+ ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
+ ":perfetto_protos_perfetto_config_inode_file_zero_gen",
+ ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
+ ":perfetto_protos_perfetto_config_interceptors_zero_gen",
+ ":perfetto_protos_perfetto_config_power_cpp_gen",
+ ":perfetto_protos_perfetto_config_power_zero_gen",
+ ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_process_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_profiling_cpp_gen",
+ ":perfetto_protos_perfetto_config_profiling_zero_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_config_track_event_zero_gen",
+ ":perfetto_protos_perfetto_config_zero_gen",
+ ":perfetto_protos_perfetto_ipc_cpp_gen",
+ ":perfetto_protos_perfetto_ipc_ipc_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
+ ":perfetto_protos_perfetto_trace_android_zero_gen",
+ ":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
+ ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_trace_gpu_zero_gen",
+ ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
+ ":perfetto_protos_perfetto_trace_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
+ ":perfetto_protos_perfetto_trace_power_zero_gen",
+ ":perfetto_protos_perfetto_trace_profiling_zero_gen",
+ ":perfetto_protos_perfetto_trace_ps_zero_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_trace_system_info_zero_gen",
+ ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_trace_track_event_zero_gen",
+ ":perfetto_protos_perfetto_trace_translation_zero_gen",
+ ":perfetto_src_base_base",
+ ":perfetto_src_base_unix_socket",
+ ":perfetto_src_ipc_client",
+ ":perfetto_src_ipc_common",
+ ":perfetto_src_profiling_common_callstack_trie",
+ ":perfetto_src_profiling_common_interner",
+ ":perfetto_src_profiling_common_interning_output",
+ ":perfetto_src_profiling_common_proc_cmdline",
+ ":perfetto_src_profiling_common_proc_utils",
+ ":perfetto_src_profiling_common_producer_support",
+ ":perfetto_src_profiling_common_profiler_guardrails",
+ ":perfetto_src_profiling_common_unwind_support",
+ ":perfetto_src_profiling_memory_client",
+ ":perfetto_src_profiling_memory_client_api",
+ ":perfetto_src_profiling_memory_client_api_standalone",
+ ":perfetto_src_profiling_memory_daemon",
+ ":perfetto_src_profiling_memory_ring_buffer",
+ ":perfetto_src_profiling_memory_scoped_spinlock",
+ ":perfetto_src_profiling_memory_wire_protocol",
+ ":perfetto_src_protozero_protozero",
+ ":perfetto_src_traced_probes_packages_list_packages_list_parser",
+ ":perfetto_src_tracing_common",
+ ":perfetto_src_tracing_core_core",
+ ":perfetto_src_tracing_ipc_common",
+ ":perfetto_src_tracing_ipc_default_socket",
+ ":perfetto_src_tracing_ipc_producer_producer",
+ ],
+ shared_libs: [
+ "liblog",
+ ],
+ static_libs: [
+ "libasync_safe",
+ "libbase",
+ "libdexfile_support",
+ "liblzma",
+ "libprocinfo",
+ "libunwindstack",
+ ],
+ runtime_libs: [
+ "libdexfile",
+ ],
+ export_include_dirs: [
+ "src/profiling/memory/include",
+ ],
+ generated_headers: [
+ "perfetto_protos_perfetto_common_cpp_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_android_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_android_zero_gen_headers",
+ "perfetto_protos_perfetto_config_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
+ "perfetto_protos_perfetto_config_power_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_power_zero_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
+ "perfetto_protos_perfetto_ipc_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_ipc_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_android_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_power_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_zero_gen_headers",
+ "perfetto_src_base_version_gen_h",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ cflags: [
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ "-DPERFETTO_ANDROID_ASYNC_SAFE_LOG",
+ ],
+ header_libs: [
+ "bionic_libc_platform_headers",
+ ],
+ stl: "libc++_static",
+ version_script: "src/profiling/memory/heapprofd_client_api.map.txt",
}
// GN: //src/ipc/protoc_plugin:ipc_plugin
cc_binary_host {
- name: "ipc_plugin",
- srcs: [
- ":perfetto_include_perfetto_base_base",
- ":perfetto_include_perfetto_ext_base_base",
- ":perfetto_src_base_base",
- "src/ipc/protoc_plugin/ipc_plugin.cc",
- ],
- static_libs: [
- "libprotoc",
- ],
- generated_headers: [
- "perfetto_src_base_version_gen_h",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- cflags: [
- "-DGOOGLE_PROTOBUF_NO_RTTI",
- "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
- ],
+ name: "ipc_plugin",
+ srcs: [
+ ":perfetto_include_perfetto_base_base",
+ ":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_src_base_base",
+ "src/ipc/protoc_plugin/ipc_plugin.cc",
+ ],
+ static_libs: [
+ "libprotoc",
+ ],
+ generated_headers: [
+ "perfetto_src_base_version_gen_h",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ cflags: [
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ ],
}
// GN: //:libperfetto
cc_library_shared {
- name: "libperfetto",
- srcs: [
- ":perfetto_include_perfetto_base_base",
- ":perfetto_include_perfetto_ext_base_base",
- ":perfetto_include_perfetto_ext_ipc_ipc",
- ":perfetto_include_perfetto_ext_traced_sys_stats_counters",
- ":perfetto_include_perfetto_ext_traced_traced",
- ":perfetto_include_perfetto_ext_tracing_core_core",
- ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
- ":perfetto_include_perfetto_protozero_protozero",
- ":perfetto_include_perfetto_public_public",
- ":perfetto_include_perfetto_tracing_core_core",
- ":perfetto_include_perfetto_tracing_core_forward_decls",
- ":perfetto_include_perfetto_tracing_tracing",
- ":perfetto_protos_perfetto_common_cpp_gen",
- ":perfetto_protos_perfetto_common_zero_gen",
- ":perfetto_protos_perfetto_config_android_cpp_gen",
- ":perfetto_protos_perfetto_config_android_zero_gen",
- ":perfetto_protos_perfetto_config_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_zero_gen",
- ":perfetto_protos_perfetto_config_gpu_cpp_gen",
- ":perfetto_protos_perfetto_config_gpu_zero_gen",
- ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
- ":perfetto_protos_perfetto_config_inode_file_zero_gen",
- ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
- ":perfetto_protos_perfetto_config_interceptors_zero_gen",
- ":perfetto_protos_perfetto_config_power_cpp_gen",
- ":perfetto_protos_perfetto_config_power_zero_gen",
- ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_process_stats_zero_gen",
- ":perfetto_protos_perfetto_config_profiling_cpp_gen",
- ":perfetto_protos_perfetto_config_profiling_zero_gen",
- ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_config_track_event_cpp_gen",
- ":perfetto_protos_perfetto_config_track_event_zero_gen",
- ":perfetto_protos_perfetto_config_zero_gen",
- ":perfetto_protos_perfetto_ipc_cpp_gen",
- ":perfetto_protos_perfetto_ipc_ipc_gen",
- ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
- ":perfetto_protos_perfetto_trace_android_zero_gen",
- ":perfetto_protos_perfetto_trace_chrome_zero_gen",
- ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
- ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
- ":perfetto_protos_perfetto_trace_gpu_zero_gen",
- ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
- ":perfetto_protos_perfetto_trace_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
- ":perfetto_protos_perfetto_trace_power_zero_gen",
- ":perfetto_protos_perfetto_trace_profiling_zero_gen",
- ":perfetto_protos_perfetto_trace_ps_zero_gen",
- ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_trace_system_info_zero_gen",
- ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
- ":perfetto_protos_perfetto_trace_track_event_zero_gen",
- ":perfetto_src_android_internal_headers",
- ":perfetto_src_android_internal_lazy_library_loader",
- ":perfetto_src_android_stats_android_stats",
- ":perfetto_src_android_stats_perfetto_atoms",
- ":perfetto_src_base_base",
- ":perfetto_src_base_unix_socket",
- ":perfetto_src_ipc_client",
- ":perfetto_src_ipc_common",
- ":perfetto_src_ipc_host",
- ":perfetto_src_kallsyms_kallsyms",
- ":perfetto_src_protozero_filtering_bytecode_common",
- ":perfetto_src_protozero_filtering_bytecode_parser",
- ":perfetto_src_protozero_filtering_message_filter",
- ":perfetto_src_protozero_protozero",
- ":perfetto_src_traced_probes_android_log_android_log",
- ":perfetto_src_traced_probes_common_common",
- ":perfetto_src_traced_probes_data_source",
- ":perfetto_src_traced_probes_filesystem_filesystem",
- ":perfetto_src_traced_probes_ftrace_format_parser_format_parser",
- ":perfetto_src_traced_probes_ftrace_ftrace",
- ":perfetto_src_traced_probes_ftrace_ftrace_procfs",
- ":perfetto_src_traced_probes_initial_display_state_initial_display_state",
- ":perfetto_src_traced_probes_metatrace_metatrace",
- ":perfetto_src_traced_probes_packages_list_packages_list",
- ":perfetto_src_traced_probes_packages_list_packages_list_parser",
- ":perfetto_src_traced_probes_power_power",
- ":perfetto_src_traced_probes_probes",
- ":perfetto_src_traced_probes_probes_src",
- ":perfetto_src_traced_probes_ps_ps",
- ":perfetto_src_traced_probes_sys_stats_sys_stats",
- ":perfetto_src_traced_probes_system_info_system_info",
- ":perfetto_src_traced_service_service",
- ":perfetto_src_tracing_common",
- ":perfetto_src_tracing_consumer_api_deprecated_consumer_api_deprecated",
- ":perfetto_src_tracing_core_core",
- ":perfetto_src_tracing_core_service",
- ":perfetto_src_tracing_ipc_common",
- ":perfetto_src_tracing_ipc_consumer_consumer",
- ":perfetto_src_tracing_ipc_producer_producer",
- ":perfetto_src_tracing_ipc_service_service",
- ],
- host_supported: true,
- export_include_dirs: [
- "include",
- "include/perfetto/base/build_configs/android_tree",
- ],
- generated_headers: [
- "perfetto_protos_perfetto_common_cpp_gen_headers",
- "perfetto_protos_perfetto_common_zero_gen_headers",
- "perfetto_protos_perfetto_config_android_cpp_gen_headers",
- "perfetto_protos_perfetto_config_android_zero_gen_headers",
- "perfetto_protos_perfetto_config_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
- "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
- "perfetto_protos_perfetto_config_power_cpp_gen_headers",
- "perfetto_protos_perfetto_config_power_zero_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
- "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_config_zero_gen_headers",
- "perfetto_protos_perfetto_ipc_cpp_gen_headers",
- "perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_android_zero_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
- "perfetto_protos_perfetto_trace_power_zero_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_src_base_version_gen_h",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- cflags: [
- "-DGOOGLE_PROTOBUF_NO_RTTI",
- "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
- ],
- target: {
- android: {
- shared_libs: [
- "liblog",
- ],
+ name: "libperfetto",
+ srcs: [
+ ":perfetto_include_perfetto_base_base",
+ ":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_include_perfetto_ext_ipc_ipc",
+ ":perfetto_include_perfetto_ext_traced_sys_stats_counters",
+ ":perfetto_include_perfetto_ext_traced_traced",
+ ":perfetto_include_perfetto_ext_tracing_core_core",
+ ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
+ ":perfetto_include_perfetto_protozero_protozero",
+ ":perfetto_include_perfetto_public_public",
+ ":perfetto_include_perfetto_tracing_core_core",
+ ":perfetto_include_perfetto_tracing_core_forward_decls",
+ ":perfetto_include_perfetto_tracing_tracing",
+ ":perfetto_protos_perfetto_common_cpp_gen",
+ ":perfetto_protos_perfetto_common_zero_gen",
+ ":perfetto_protos_perfetto_config_android_cpp_gen",
+ ":perfetto_protos_perfetto_config_android_zero_gen",
+ ":perfetto_protos_perfetto_config_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_config_gpu_cpp_gen",
+ ":perfetto_protos_perfetto_config_gpu_zero_gen",
+ ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
+ ":perfetto_protos_perfetto_config_inode_file_zero_gen",
+ ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
+ ":perfetto_protos_perfetto_config_interceptors_zero_gen",
+ ":perfetto_protos_perfetto_config_power_cpp_gen",
+ ":perfetto_protos_perfetto_config_power_zero_gen",
+ ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_process_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_profiling_cpp_gen",
+ ":perfetto_protos_perfetto_config_profiling_zero_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_config_track_event_zero_gen",
+ ":perfetto_protos_perfetto_config_zero_gen",
+ ":perfetto_protos_perfetto_ipc_cpp_gen",
+ ":perfetto_protos_perfetto_ipc_ipc_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
+ ":perfetto_protos_perfetto_trace_android_zero_gen",
+ ":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
+ ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_trace_gpu_zero_gen",
+ ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
+ ":perfetto_protos_perfetto_trace_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
+ ":perfetto_protos_perfetto_trace_power_zero_gen",
+ ":perfetto_protos_perfetto_trace_profiling_zero_gen",
+ ":perfetto_protos_perfetto_trace_ps_zero_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_trace_system_info_zero_gen",
+ ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_trace_track_event_zero_gen",
+ ":perfetto_protos_perfetto_trace_translation_zero_gen",
+ ":perfetto_src_android_internal_headers",
+ ":perfetto_src_android_internal_lazy_library_loader",
+ ":perfetto_src_android_stats_android_stats",
+ ":perfetto_src_android_stats_perfetto_atoms",
+ ":perfetto_src_base_base",
+ ":perfetto_src_base_unix_socket",
+ ":perfetto_src_ipc_client",
+ ":perfetto_src_ipc_common",
+ ":perfetto_src_ipc_host",
+ ":perfetto_src_kallsyms_kallsyms",
+ ":perfetto_src_protozero_filtering_bytecode_common",
+ ":perfetto_src_protozero_filtering_bytecode_parser",
+ ":perfetto_src_protozero_filtering_message_filter",
+ ":perfetto_src_protozero_protozero",
+ ":perfetto_src_traced_probes_android_log_android_log",
+ ":perfetto_src_traced_probes_common_common",
+ ":perfetto_src_traced_probes_data_source",
+ ":perfetto_src_traced_probes_filesystem_filesystem",
+ ":perfetto_src_traced_probes_ftrace_format_parser_format_parser",
+ ":perfetto_src_traced_probes_ftrace_ftrace",
+ ":perfetto_src_traced_probes_ftrace_ftrace_procfs",
+ ":perfetto_src_traced_probes_initial_display_state_initial_display_state",
+ ":perfetto_src_traced_probes_metatrace_metatrace",
+ ":perfetto_src_traced_probes_packages_list_packages_list",
+ ":perfetto_src_traced_probes_packages_list_packages_list_parser",
+ ":perfetto_src_traced_probes_power_power",
+ ":perfetto_src_traced_probes_probes",
+ ":perfetto_src_traced_probes_probes_src",
+ ":perfetto_src_traced_probes_ps_ps",
+ ":perfetto_src_traced_probes_sys_stats_sys_stats",
+ ":perfetto_src_traced_probes_system_info_system_info",
+ ":perfetto_src_traced_service_service",
+ ":perfetto_src_tracing_common",
+ ":perfetto_src_tracing_consumer_api_deprecated_consumer_api_deprecated",
+ ":perfetto_src_tracing_core_core",
+ ":perfetto_src_tracing_core_service",
+ ":perfetto_src_tracing_ipc_common",
+ ":perfetto_src_tracing_ipc_consumer_consumer",
+ ":perfetto_src_tracing_ipc_default_socket",
+ ":perfetto_src_tracing_ipc_producer_producer",
+ ":perfetto_src_tracing_ipc_service_service",
+ ],
+ host_supported: true,
+ export_include_dirs: [
+ "include",
+ "include/perfetto/base/build_configs/android_tree",
+ ],
+ generated_headers: [
+ "perfetto_protos_perfetto_common_cpp_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_android_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_android_zero_gen_headers",
+ "perfetto_protos_perfetto_config_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
+ "perfetto_protos_perfetto_config_power_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_power_zero_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
+ "perfetto_protos_perfetto_ipc_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_ipc_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_android_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_power_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_zero_gen_headers",
+ "perfetto_src_base_version_gen_h",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ cflags: [
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ ],
+ target: {
+ android: {
+ shared_libs: [
+ "liblog",
+ ],
+ },
},
- },
}
// GN: //src/android_internal:libperfetto_android_internal
cc_library_shared {
- name: "libperfetto_android_internal",
- srcs: [
- ":perfetto_src_android_internal_headers",
- ":perfetto_src_android_stats_perfetto_atoms",
- "src/android_internal/atrace_hal.cc",
- "src/android_internal/health_hal.cc",
- "src/android_internal/incident_service.cc",
- "src/android_internal/power_stats.cc",
- "src/android_internal/statsd_logging.cc",
- "src/android_internal/tracing_service_proxy.cc",
- ],
- shared_libs: [
- "android.hardware.atrace@1.0",
- "android.hardware.health@2.0",
- "android.hardware.power.stats-V1-cpp",
- "android.hardware.power.stats@1.0",
- "libbase",
- "libbinder",
- "libcutils",
- "libhidlbase",
- "libincident",
- "liblog",
- "libservices",
- "libstatssocket",
- "libtracingproxy",
- "libutils",
- ],
- static_libs: [
- "libhealthhalutils",
- "libstatslog_perfetto",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- product_variables: {
- pdk: {
- enabled: false,
- },
- },
+ name: "libperfetto_android_internal",
+ srcs: [
+ ":perfetto_src_android_internal_headers",
+ ":perfetto_src_android_stats_perfetto_atoms",
+ "src/android_internal/atrace_hal.cc",
+ "src/android_internal/health_hal.cc",
+ "src/android_internal/incident_service.cc",
+ "src/android_internal/power_stats.cc",
+ "src/android_internal/statsd_logging.cc",
+ "src/android_internal/tracing_service_proxy.cc",
+ ],
+ shared_libs: [
+ "android.hardware.atrace@1.0",
+ "android.hardware.health-V1-ndk",
+ "android.hardware.health@2.0",
+ "android.hardware.power.stats-V1-cpp",
+ "android.hardware.power.stats@1.0",
+ "libbase",
+ "libbinder",
+ "libbinder_ndk",
+ "libcutils",
+ "libhidlbase",
+ "libincident",
+ "liblog",
+ "libservices",
+ "libstatssocket",
+ "libtracingproxy",
+ "libutils",
+ ],
+ static_libs: [
+ "libhealthhalutils",
+ "libstatslog_perfetto",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
}
// GN: //:libperfetto_client_experimental
cc_library_static {
- name: "libperfetto_client_experimental",
- srcs: [
- ":perfetto_include_perfetto_base_base",
- ":perfetto_include_perfetto_ext_base_base",
- ":perfetto_include_perfetto_ext_ipc_ipc",
- ":perfetto_include_perfetto_ext_tracing_core_core",
- ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
- ":perfetto_include_perfetto_protozero_protozero",
- ":perfetto_include_perfetto_tracing_core_core",
- ":perfetto_include_perfetto_tracing_core_forward_decls",
- ":perfetto_include_perfetto_tracing_tracing",
- ":perfetto_protos_perfetto_common_cpp_gen",
- ":perfetto_protos_perfetto_common_zero_gen",
- ":perfetto_protos_perfetto_config_android_cpp_gen",
- ":perfetto_protos_perfetto_config_android_zero_gen",
- ":perfetto_protos_perfetto_config_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_zero_gen",
- ":perfetto_protos_perfetto_config_gpu_cpp_gen",
- ":perfetto_protos_perfetto_config_gpu_zero_gen",
- ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
- ":perfetto_protos_perfetto_config_inode_file_zero_gen",
- ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
- ":perfetto_protos_perfetto_config_interceptors_zero_gen",
- ":perfetto_protos_perfetto_config_power_cpp_gen",
- ":perfetto_protos_perfetto_config_power_zero_gen",
- ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_process_stats_zero_gen",
- ":perfetto_protos_perfetto_config_profiling_cpp_gen",
- ":perfetto_protos_perfetto_config_profiling_zero_gen",
- ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_config_track_event_cpp_gen",
- ":perfetto_protos_perfetto_config_track_event_zero_gen",
- ":perfetto_protos_perfetto_config_zero_gen",
- ":perfetto_protos_perfetto_ipc_cpp_gen",
- ":perfetto_protos_perfetto_ipc_ipc_gen",
- ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
- ":perfetto_protos_perfetto_trace_android_zero_gen",
- ":perfetto_protos_perfetto_trace_chrome_zero_gen",
- ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
- ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
- ":perfetto_protos_perfetto_trace_gpu_zero_gen",
- ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
- ":perfetto_protos_perfetto_trace_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
- ":perfetto_protos_perfetto_trace_power_zero_gen",
- ":perfetto_protos_perfetto_trace_profiling_zero_gen",
- ":perfetto_protos_perfetto_trace_ps_zero_gen",
- ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_trace_system_info_zero_gen",
- ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
- ":perfetto_protos_perfetto_trace_track_event_zero_gen",
- ":perfetto_src_android_internal_headers",
- ":perfetto_src_android_internal_lazy_library_loader",
- ":perfetto_src_android_stats_android_stats",
- ":perfetto_src_android_stats_perfetto_atoms",
- ":perfetto_src_base_base",
- ":perfetto_src_base_unix_socket",
- ":perfetto_src_ipc_client",
- ":perfetto_src_ipc_common",
- ":perfetto_src_ipc_host",
- ":perfetto_src_protozero_filtering_bytecode_common",
- ":perfetto_src_protozero_filtering_bytecode_parser",
- ":perfetto_src_protozero_filtering_message_filter",
- ":perfetto_src_protozero_protozero",
- ":perfetto_src_tracing_client_api_without_backends",
- ":perfetto_src_tracing_common",
- ":perfetto_src_tracing_core_core",
- ":perfetto_src_tracing_core_service",
- ":perfetto_src_tracing_in_process_backend",
- ":perfetto_src_tracing_ipc_common",
- ":perfetto_src_tracing_ipc_consumer_consumer",
- ":perfetto_src_tracing_ipc_producer_producer",
- ":perfetto_src_tracing_ipc_service_service",
- ":perfetto_src_tracing_platform_impl",
- ":perfetto_src_tracing_system_backend",
- ],
- shared_libs: [
- "liblog",
- ],
- export_include_dirs: [
- "include",
- "include/perfetto/base/build_configs/android_tree",
- ],
- generated_headers: [
- "perfetto_protos_perfetto_common_cpp_gen_headers",
- "perfetto_protos_perfetto_common_zero_gen_headers",
- "perfetto_protos_perfetto_config_android_cpp_gen_headers",
- "perfetto_protos_perfetto_config_android_zero_gen_headers",
- "perfetto_protos_perfetto_config_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
- "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
- "perfetto_protos_perfetto_config_power_cpp_gen_headers",
- "perfetto_protos_perfetto_config_power_zero_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
- "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_config_zero_gen_headers",
- "perfetto_protos_perfetto_ipc_cpp_gen_headers",
- "perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_android_zero_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
- "perfetto_protos_perfetto_trace_power_zero_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_src_base_version_gen_h",
- ],
- export_generated_headers: [
- "perfetto_protos_perfetto_common_cpp_gen_headers",
- "perfetto_protos_perfetto_common_zero_gen_headers",
- "perfetto_protos_perfetto_config_android_cpp_gen_headers",
- "perfetto_protos_perfetto_config_android_zero_gen_headers",
- "perfetto_protos_perfetto_config_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
- "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
- "perfetto_protos_perfetto_config_power_cpp_gen_headers",
- "perfetto_protos_perfetto_config_power_zero_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
- "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_config_zero_gen_headers",
- "perfetto_protos_perfetto_ipc_cpp_gen_headers",
- "perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_android_zero_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
- "perfetto_protos_perfetto_trace_power_zero_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_src_base_version_gen_h",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- cflags: [
- "-DGOOGLE_PROTOBUF_NO_RTTI",
- "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
- ],
- apex_available: [
- "//apex_available:platform",
- "com.android.art",
- "com.android.art.debug",
- ],
- min_sdk_version: "S",
+ name: "libperfetto_client_experimental",
+ srcs: [
+ ":perfetto_include_perfetto_base_base",
+ ":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_include_perfetto_ext_ipc_ipc",
+ ":perfetto_include_perfetto_ext_tracing_core_core",
+ ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
+ ":perfetto_include_perfetto_protozero_protozero",
+ ":perfetto_include_perfetto_tracing_core_core",
+ ":perfetto_include_perfetto_tracing_core_forward_decls",
+ ":perfetto_include_perfetto_tracing_tracing",
+ ":perfetto_protos_perfetto_common_cpp_gen",
+ ":perfetto_protos_perfetto_common_zero_gen",
+ ":perfetto_protos_perfetto_config_android_cpp_gen",
+ ":perfetto_protos_perfetto_config_android_zero_gen",
+ ":perfetto_protos_perfetto_config_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_config_gpu_cpp_gen",
+ ":perfetto_protos_perfetto_config_gpu_zero_gen",
+ ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
+ ":perfetto_protos_perfetto_config_inode_file_zero_gen",
+ ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
+ ":perfetto_protos_perfetto_config_interceptors_zero_gen",
+ ":perfetto_protos_perfetto_config_power_cpp_gen",
+ ":perfetto_protos_perfetto_config_power_zero_gen",
+ ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_process_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_profiling_cpp_gen",
+ ":perfetto_protos_perfetto_config_profiling_zero_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_config_track_event_zero_gen",
+ ":perfetto_protos_perfetto_config_zero_gen",
+ ":perfetto_protos_perfetto_ipc_cpp_gen",
+ ":perfetto_protos_perfetto_ipc_ipc_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
+ ":perfetto_protos_perfetto_trace_android_zero_gen",
+ ":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
+ ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_trace_gpu_zero_gen",
+ ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
+ ":perfetto_protos_perfetto_trace_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
+ ":perfetto_protos_perfetto_trace_power_zero_gen",
+ ":perfetto_protos_perfetto_trace_profiling_zero_gen",
+ ":perfetto_protos_perfetto_trace_ps_zero_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_trace_system_info_zero_gen",
+ ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_trace_track_event_zero_gen",
+ ":perfetto_protos_perfetto_trace_translation_zero_gen",
+ ":perfetto_src_android_internal_headers",
+ ":perfetto_src_android_internal_lazy_library_loader",
+ ":perfetto_src_android_stats_android_stats",
+ ":perfetto_src_android_stats_perfetto_atoms",
+ ":perfetto_src_base_base",
+ ":perfetto_src_base_unix_socket",
+ ":perfetto_src_ipc_client",
+ ":perfetto_src_ipc_common",
+ ":perfetto_src_ipc_host",
+ ":perfetto_src_protozero_filtering_bytecode_common",
+ ":perfetto_src_protozero_filtering_bytecode_parser",
+ ":perfetto_src_protozero_filtering_message_filter",
+ ":perfetto_src_protozero_protozero",
+ ":perfetto_src_tracing_client_api_without_backends",
+ ":perfetto_src_tracing_common",
+ ":perfetto_src_tracing_core_core",
+ ":perfetto_src_tracing_core_service",
+ ":perfetto_src_tracing_in_process_backend",
+ ":perfetto_src_tracing_ipc_common",
+ ":perfetto_src_tracing_ipc_consumer_consumer",
+ ":perfetto_src_tracing_ipc_default_socket",
+ ":perfetto_src_tracing_ipc_producer_producer",
+ ":perfetto_src_tracing_ipc_service_service",
+ ":perfetto_src_tracing_platform_impl",
+ ":perfetto_src_tracing_system_backend",
+ ],
+ shared_libs: [
+ "liblog",
+ ],
+ host_supported: true,
+ vendor_available: true,
+ export_include_dirs: [
+ "include",
+ "include/perfetto/base/build_configs/android_tree",
+ ],
+ generated_headers: [
+ "perfetto_protos_perfetto_common_cpp_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_android_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_android_zero_gen_headers",
+ "perfetto_protos_perfetto_config_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
+ "perfetto_protos_perfetto_config_power_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_power_zero_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
+ "perfetto_protos_perfetto_ipc_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_ipc_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_android_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_power_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_zero_gen_headers",
+ "perfetto_src_base_version_gen_h",
+ ],
+ export_generated_headers: [
+ "perfetto_protos_perfetto_common_cpp_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_android_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_android_zero_gen_headers",
+ "perfetto_protos_perfetto_config_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
+ "perfetto_protos_perfetto_config_power_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_power_zero_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
+ "perfetto_protos_perfetto_ipc_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_ipc_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_android_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_power_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_zero_gen_headers",
+ "perfetto_src_base_version_gen_h",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ cflags: [
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ ],
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.art",
+ "com.android.art.debug",
+ ],
+ min_sdk_version: "S",
}
// GN: //src/perfetto_cmd:perfetto
cc_binary {
- name: "perfetto",
- srcs: [
- ":perfetto_include_perfetto_base_base",
- ":perfetto_include_perfetto_ext_base_base",
- ":perfetto_include_perfetto_ext_ipc_ipc",
- ":perfetto_include_perfetto_ext_traced_traced",
- ":perfetto_include_perfetto_ext_tracing_core_core",
- ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
- ":perfetto_include_perfetto_protozero_protozero",
- ":perfetto_include_perfetto_tracing_core_core",
- ":perfetto_include_perfetto_tracing_core_forward_decls",
- ":perfetto_include_perfetto_tracing_tracing",
- ":perfetto_protos_perfetto_common_cpp_gen",
- ":perfetto_protos_perfetto_common_zero_gen",
- ":perfetto_protos_perfetto_config_android_cpp_gen",
- ":perfetto_protos_perfetto_config_android_zero_gen",
- ":perfetto_protos_perfetto_config_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_zero_gen",
- ":perfetto_protos_perfetto_config_gpu_cpp_gen",
- ":perfetto_protos_perfetto_config_gpu_zero_gen",
- ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
- ":perfetto_protos_perfetto_config_inode_file_zero_gen",
- ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
- ":perfetto_protos_perfetto_config_interceptors_zero_gen",
- ":perfetto_protos_perfetto_config_power_cpp_gen",
- ":perfetto_protos_perfetto_config_power_zero_gen",
- ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_process_stats_zero_gen",
- ":perfetto_protos_perfetto_config_profiling_cpp_gen",
- ":perfetto_protos_perfetto_config_profiling_zero_gen",
- ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_config_track_event_cpp_gen",
- ":perfetto_protos_perfetto_config_track_event_zero_gen",
- ":perfetto_protos_perfetto_config_zero_gen",
- ":perfetto_protos_perfetto_ipc_cpp_gen",
- ":perfetto_protos_perfetto_ipc_ipc_gen",
- ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
- ":perfetto_protos_perfetto_trace_android_zero_gen",
- ":perfetto_protos_perfetto_trace_chrome_zero_gen",
- ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
- ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
- ":perfetto_protos_perfetto_trace_gpu_zero_gen",
- ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
- ":perfetto_protos_perfetto_trace_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
- ":perfetto_protos_perfetto_trace_power_zero_gen",
- ":perfetto_protos_perfetto_trace_profiling_zero_gen",
- ":perfetto_protos_perfetto_trace_ps_zero_gen",
- ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_trace_system_info_zero_gen",
- ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
- ":perfetto_protos_perfetto_trace_track_event_zero_gen",
- ":perfetto_src_android_internal_headers",
- ":perfetto_src_android_internal_lazy_library_loader",
- ":perfetto_src_android_stats_android_stats",
- ":perfetto_src_android_stats_perfetto_atoms",
- ":perfetto_src_base_base",
- ":perfetto_src_base_unix_socket",
- ":perfetto_src_ipc_client",
- ":perfetto_src_ipc_common",
- ":perfetto_src_perfetto_cmd_perfetto_cmd",
- ":perfetto_src_perfetto_cmd_protos_gen",
- ":perfetto_src_perfetto_cmd_trigger_producer",
- ":perfetto_src_protozero_protozero",
- ":perfetto_src_tracing_common",
- ":perfetto_src_tracing_core_core",
- ":perfetto_src_tracing_ipc_common",
- ":perfetto_src_tracing_ipc_consumer_consumer",
- ":perfetto_src_tracing_ipc_producer_producer",
- "src/perfetto_cmd/main.cc",
- ],
- shared_libs: [
- "liblog",
- "libz",
- ],
- generated_headers: [
- "perfetto_protos_perfetto_common_cpp_gen_headers",
- "perfetto_protos_perfetto_common_zero_gen_headers",
- "perfetto_protos_perfetto_config_android_cpp_gen_headers",
- "perfetto_protos_perfetto_config_android_zero_gen_headers",
- "perfetto_protos_perfetto_config_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
- "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
- "perfetto_protos_perfetto_config_power_cpp_gen_headers",
- "perfetto_protos_perfetto_config_power_zero_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
- "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_config_zero_gen_headers",
- "perfetto_protos_perfetto_ipc_cpp_gen_headers",
- "perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_android_zero_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
- "perfetto_protos_perfetto_trace_power_zero_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_src_base_version_gen_h",
- "perfetto_src_perfetto_cmd_gen_cc_config_descriptor",
- "perfetto_src_perfetto_cmd_protos_gen_headers",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- cflags: [
- "-DGOOGLE_PROTOBUF_NO_RTTI",
- "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
- "-DHAVE_HIDDEN",
- ],
+ name: "perfetto",
+ srcs: [
+ ":perfetto_include_perfetto_base_base",
+ ":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_include_perfetto_ext_ipc_ipc",
+ ":perfetto_include_perfetto_ext_traced_traced",
+ ":perfetto_include_perfetto_ext_tracing_core_core",
+ ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
+ ":perfetto_include_perfetto_protozero_protozero",
+ ":perfetto_include_perfetto_tracing_core_core",
+ ":perfetto_include_perfetto_tracing_core_forward_decls",
+ ":perfetto_include_perfetto_tracing_tracing",
+ ":perfetto_protos_perfetto_common_cpp_gen",
+ ":perfetto_protos_perfetto_common_zero_gen",
+ ":perfetto_protos_perfetto_config_android_cpp_gen",
+ ":perfetto_protos_perfetto_config_android_zero_gen",
+ ":perfetto_protos_perfetto_config_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_config_gpu_cpp_gen",
+ ":perfetto_protos_perfetto_config_gpu_zero_gen",
+ ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
+ ":perfetto_protos_perfetto_config_inode_file_zero_gen",
+ ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
+ ":perfetto_protos_perfetto_config_interceptors_zero_gen",
+ ":perfetto_protos_perfetto_config_power_cpp_gen",
+ ":perfetto_protos_perfetto_config_power_zero_gen",
+ ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_process_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_profiling_cpp_gen",
+ ":perfetto_protos_perfetto_config_profiling_zero_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_config_track_event_zero_gen",
+ ":perfetto_protos_perfetto_config_zero_gen",
+ ":perfetto_protos_perfetto_ipc_cpp_gen",
+ ":perfetto_protos_perfetto_ipc_ipc_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
+ ":perfetto_protos_perfetto_trace_android_zero_gen",
+ ":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
+ ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_trace_gpu_zero_gen",
+ ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
+ ":perfetto_protos_perfetto_trace_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
+ ":perfetto_protos_perfetto_trace_power_zero_gen",
+ ":perfetto_protos_perfetto_trace_profiling_zero_gen",
+ ":perfetto_protos_perfetto_trace_ps_zero_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_trace_system_info_zero_gen",
+ ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_trace_track_event_zero_gen",
+ ":perfetto_protos_perfetto_trace_translation_zero_gen",
+ ":perfetto_src_android_internal_headers",
+ ":perfetto_src_android_internal_lazy_library_loader",
+ ":perfetto_src_android_stats_android_stats",
+ ":perfetto_src_android_stats_perfetto_atoms",
+ ":perfetto_src_base_base",
+ ":perfetto_src_base_unix_socket",
+ ":perfetto_src_ipc_client",
+ ":perfetto_src_ipc_common",
+ ":perfetto_src_perfetto_cmd_perfetto_cmd",
+ ":perfetto_src_perfetto_cmd_protos_cpp_gen",
+ ":perfetto_src_perfetto_cmd_trigger_producer",
+ ":perfetto_src_protozero_protozero",
+ ":perfetto_src_tracing_common",
+ ":perfetto_src_tracing_core_core",
+ ":perfetto_src_tracing_ipc_common",
+ ":perfetto_src_tracing_ipc_consumer_consumer",
+ ":perfetto_src_tracing_ipc_default_socket",
+ ":perfetto_src_tracing_ipc_producer_producer",
+ "src/perfetto_cmd/main.cc",
+ ],
+ shared_libs: [
+ "liblog",
+ "libz",
+ ],
+ generated_headers: [
+ "perfetto_protos_perfetto_common_cpp_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_android_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_android_zero_gen_headers",
+ "perfetto_protos_perfetto_config_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
+ "perfetto_protos_perfetto_config_power_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_power_zero_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
+ "perfetto_protos_perfetto_ipc_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_ipc_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_android_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_power_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_zero_gen_headers",
+ "perfetto_src_base_version_gen_h",
+ "perfetto_src_perfetto_cmd_gen_cc_config_descriptor",
+ "perfetto_src_perfetto_cmd_protos_cpp_gen_headers",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ cflags: [
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ "-DHAVE_HIDDEN",
+ ],
}
// GN: //test/cts:perfetto_cts_deps
cc_library_static {
- name: "perfetto_cts_deps",
- srcs: [
- ":perfetto_include_perfetto_base_base",
- ":perfetto_include_perfetto_ext_base_base",
- ":perfetto_include_perfetto_ext_ipc_ipc",
- ":perfetto_include_perfetto_ext_traced_sys_stats_counters",
- ":perfetto_include_perfetto_ext_traced_traced",
- ":perfetto_include_perfetto_ext_tracing_core_core",
- ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
- ":perfetto_include_perfetto_protozero_protozero",
- ":perfetto_include_perfetto_tracing_core_core",
- ":perfetto_include_perfetto_tracing_core_forward_decls",
- ":perfetto_include_perfetto_tracing_tracing",
- ":perfetto_protos_perfetto_common_cpp_gen",
- ":perfetto_protos_perfetto_common_zero_gen",
- ":perfetto_protos_perfetto_config_android_cpp_gen",
- ":perfetto_protos_perfetto_config_android_zero_gen",
- ":perfetto_protos_perfetto_config_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_zero_gen",
- ":perfetto_protos_perfetto_config_gpu_cpp_gen",
- ":perfetto_protos_perfetto_config_gpu_zero_gen",
- ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
- ":perfetto_protos_perfetto_config_inode_file_zero_gen",
- ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
- ":perfetto_protos_perfetto_config_interceptors_zero_gen",
- ":perfetto_protos_perfetto_config_power_cpp_gen",
- ":perfetto_protos_perfetto_config_power_zero_gen",
- ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_process_stats_zero_gen",
- ":perfetto_protos_perfetto_config_profiling_cpp_gen",
- ":perfetto_protos_perfetto_config_profiling_zero_gen",
- ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_config_track_event_cpp_gen",
- ":perfetto_protos_perfetto_config_track_event_zero_gen",
- ":perfetto_protos_perfetto_config_zero_gen",
- ":perfetto_protos_perfetto_ipc_cpp_gen",
- ":perfetto_protos_perfetto_ipc_ipc_gen",
- ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
- ":perfetto_protos_perfetto_trace_android_cpp_gen",
- ":perfetto_protos_perfetto_trace_android_zero_gen",
- ":perfetto_protos_perfetto_trace_chrome_cpp_gen",
- ":perfetto_protos_perfetto_trace_chrome_zero_gen",
- ":perfetto_protos_perfetto_trace_filesystem_cpp_gen",
- ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
- ":perfetto_protos_perfetto_trace_ftrace_cpp_gen",
- ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
- ":perfetto_protos_perfetto_trace_gpu_cpp_gen",
- ":perfetto_protos_perfetto_trace_gpu_zero_gen",
- ":perfetto_protos_perfetto_trace_interned_data_cpp_gen",
- ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
- ":perfetto_protos_perfetto_trace_minimal_cpp_gen",
- ":perfetto_protos_perfetto_trace_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_non_minimal_cpp_gen",
- ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_perfetto_cpp_gen",
- ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
- ":perfetto_protos_perfetto_trace_power_cpp_gen",
- ":perfetto_protos_perfetto_trace_power_zero_gen",
- ":perfetto_protos_perfetto_trace_profiling_cpp_gen",
- ":perfetto_protos_perfetto_trace_profiling_zero_gen",
- ":perfetto_protos_perfetto_trace_ps_cpp_gen",
- ":perfetto_protos_perfetto_trace_ps_zero_gen",
- ":perfetto_protos_perfetto_trace_sys_stats_cpp_gen",
- ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_trace_system_info_cpp_gen",
- ":perfetto_protos_perfetto_trace_system_info_zero_gen",
- ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
- ":perfetto_protos_perfetto_trace_track_event_zero_gen",
- ":perfetto_src_android_internal_headers",
- ":perfetto_src_android_internal_lazy_library_loader",
- ":perfetto_src_android_stats_android_stats",
- ":perfetto_src_android_stats_perfetto_atoms",
- ":perfetto_src_base_base",
- ":perfetto_src_base_test_support",
- ":perfetto_src_base_unix_socket",
- ":perfetto_src_ipc_client",
- ":perfetto_src_ipc_common",
- ":perfetto_src_ipc_host",
- ":perfetto_src_ipc_perfetto_ipc",
- ":perfetto_src_kallsyms_kallsyms",
- ":perfetto_src_protozero_filtering_bytecode_common",
- ":perfetto_src_protozero_filtering_bytecode_parser",
- ":perfetto_src_protozero_filtering_message_filter",
- ":perfetto_src_protozero_protozero",
- ":perfetto_src_traced_probes_android_log_android_log",
- ":perfetto_src_traced_probes_common_common",
- ":perfetto_src_traced_probes_data_source",
- ":perfetto_src_traced_probes_filesystem_filesystem",
- ":perfetto_src_traced_probes_ftrace_format_parser_format_parser",
- ":perfetto_src_traced_probes_ftrace_ftrace",
- ":perfetto_src_traced_probes_ftrace_ftrace_procfs",
- ":perfetto_src_traced_probes_initial_display_state_initial_display_state",
- ":perfetto_src_traced_probes_metatrace_metatrace",
- ":perfetto_src_traced_probes_packages_list_packages_list",
- ":perfetto_src_traced_probes_packages_list_packages_list_parser",
- ":perfetto_src_traced_probes_power_power",
- ":perfetto_src_traced_probes_probes_src",
- ":perfetto_src_traced_probes_ps_ps",
- ":perfetto_src_traced_probes_sys_stats_sys_stats",
- ":perfetto_src_traced_probes_system_info_system_info",
- ":perfetto_src_tracing_common",
- ":perfetto_src_tracing_core_core",
- ":perfetto_src_tracing_core_service",
- ":perfetto_src_tracing_ipc_common",
- ":perfetto_src_tracing_ipc_consumer_consumer",
- ":perfetto_src_tracing_ipc_producer_producer",
- ":perfetto_src_tracing_ipc_service_service",
- ":perfetto_test_end_to_end_integrationtests",
- ":perfetto_test_test_helper",
- "test/cts/device_feature_test_cts.cc",
- "test/cts/end_to_end_integrationtest_cts.cc",
- "test/cts/heapprofd_java_test_cts.cc",
- "test/cts/heapprofd_test_cts.cc",
- "test/cts/traced_perf_test_cts.cc",
- ],
- static_libs: [
- "libgmock",
- "libgtest",
- "libperfetto_client_experimental",
- ],
- whole_static_libs: [
- "perfetto_gtest_logcat_printer",
- ],
- generated_headers: [
- "perfetto_protos_perfetto_common_cpp_gen_headers",
- "perfetto_protos_perfetto_common_zero_gen_headers",
- "perfetto_protos_perfetto_config_android_cpp_gen_headers",
- "perfetto_protos_perfetto_config_android_zero_gen_headers",
- "perfetto_protos_perfetto_config_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
- "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
- "perfetto_protos_perfetto_config_power_cpp_gen_headers",
- "perfetto_protos_perfetto_config_power_zero_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
- "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_config_zero_gen_headers",
- "perfetto_protos_perfetto_ipc_cpp_gen_headers",
- "perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_android_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_android_zero_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
- "perfetto_protos_perfetto_trace_power_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_power_zero_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ps_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_src_base_version_gen_h",
- ],
- export_generated_headers: [
- "perfetto_protos_perfetto_common_cpp_gen_headers",
- "perfetto_protos_perfetto_common_zero_gen_headers",
- "perfetto_protos_perfetto_config_android_cpp_gen_headers",
- "perfetto_protos_perfetto_config_android_zero_gen_headers",
- "perfetto_protos_perfetto_config_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
- "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
- "perfetto_protos_perfetto_config_power_cpp_gen_headers",
- "perfetto_protos_perfetto_config_power_zero_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
- "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_config_zero_gen_headers",
- "perfetto_protos_perfetto_ipc_cpp_gen_headers",
- "perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_android_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_android_zero_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
- "perfetto_protos_perfetto_trace_power_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_power_zero_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ps_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_src_base_version_gen_h",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- cflags: [
- "-DGOOGLE_PROTOBUF_NO_RTTI",
- "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
- ],
+ name: "perfetto_cts_deps",
+ srcs: [
+ ":perfetto_include_perfetto_base_base",
+ ":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_include_perfetto_ext_ipc_ipc",
+ ":perfetto_include_perfetto_ext_traced_sys_stats_counters",
+ ":perfetto_include_perfetto_ext_traced_traced",
+ ":perfetto_include_perfetto_ext_tracing_core_core",
+ ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
+ ":perfetto_include_perfetto_protozero_protozero",
+ ":perfetto_include_perfetto_tracing_core_core",
+ ":perfetto_include_perfetto_tracing_core_forward_decls",
+ ":perfetto_include_perfetto_tracing_tracing",
+ ":perfetto_protos_perfetto_common_cpp_gen",
+ ":perfetto_protos_perfetto_common_zero_gen",
+ ":perfetto_protos_perfetto_config_android_cpp_gen",
+ ":perfetto_protos_perfetto_config_android_zero_gen",
+ ":perfetto_protos_perfetto_config_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_config_gpu_cpp_gen",
+ ":perfetto_protos_perfetto_config_gpu_zero_gen",
+ ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
+ ":perfetto_protos_perfetto_config_inode_file_zero_gen",
+ ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
+ ":perfetto_protos_perfetto_config_interceptors_zero_gen",
+ ":perfetto_protos_perfetto_config_power_cpp_gen",
+ ":perfetto_protos_perfetto_config_power_zero_gen",
+ ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_process_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_profiling_cpp_gen",
+ ":perfetto_protos_perfetto_config_profiling_zero_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_config_track_event_zero_gen",
+ ":perfetto_protos_perfetto_config_zero_gen",
+ ":perfetto_protos_perfetto_ipc_cpp_gen",
+ ":perfetto_protos_perfetto_ipc_ipc_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
+ ":perfetto_protos_perfetto_trace_android_cpp_gen",
+ ":perfetto_protos_perfetto_trace_android_zero_gen",
+ ":perfetto_protos_perfetto_trace_chrome_cpp_gen",
+ ":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_filesystem_cpp_gen",
+ ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
+ ":perfetto_protos_perfetto_trace_ftrace_cpp_gen",
+ ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_trace_gpu_cpp_gen",
+ ":perfetto_protos_perfetto_trace_gpu_zero_gen",
+ ":perfetto_protos_perfetto_trace_interned_data_cpp_gen",
+ ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
+ ":perfetto_protos_perfetto_trace_minimal_cpp_gen",
+ ":perfetto_protos_perfetto_trace_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_non_minimal_cpp_gen",
+ ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_perfetto_cpp_gen",
+ ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
+ ":perfetto_protos_perfetto_trace_power_cpp_gen",
+ ":perfetto_protos_perfetto_trace_power_zero_gen",
+ ":perfetto_protos_perfetto_trace_profiling_cpp_gen",
+ ":perfetto_protos_perfetto_trace_profiling_zero_gen",
+ ":perfetto_protos_perfetto_trace_ps_cpp_gen",
+ ":perfetto_protos_perfetto_trace_ps_zero_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_cpp_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_trace_system_info_cpp_gen",
+ ":perfetto_protos_perfetto_trace_system_info_zero_gen",
+ ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_trace_track_event_zero_gen",
+ ":perfetto_protos_perfetto_trace_translation_cpp_gen",
+ ":perfetto_protos_perfetto_trace_translation_zero_gen",
+ ":perfetto_src_android_internal_headers",
+ ":perfetto_src_android_internal_lazy_library_loader",
+ ":perfetto_src_android_stats_android_stats",
+ ":perfetto_src_android_stats_perfetto_atoms",
+ ":perfetto_src_base_base",
+ ":perfetto_src_base_test_support",
+ ":perfetto_src_base_unix_socket",
+ ":perfetto_src_ipc_client",
+ ":perfetto_src_ipc_common",
+ ":perfetto_src_ipc_host",
+ ":perfetto_src_ipc_perfetto_ipc",
+ ":perfetto_src_kallsyms_kallsyms",
+ ":perfetto_src_protozero_filtering_bytecode_common",
+ ":perfetto_src_protozero_filtering_bytecode_generator",
+ ":perfetto_src_protozero_filtering_bytecode_parser",
+ ":perfetto_src_protozero_filtering_message_filter",
+ ":perfetto_src_protozero_protozero",
+ ":perfetto_src_traced_probes_android_log_android_log",
+ ":perfetto_src_traced_probes_common_common",
+ ":perfetto_src_traced_probes_data_source",
+ ":perfetto_src_traced_probes_filesystem_filesystem",
+ ":perfetto_src_traced_probes_ftrace_format_parser_format_parser",
+ ":perfetto_src_traced_probes_ftrace_ftrace",
+ ":perfetto_src_traced_probes_ftrace_ftrace_procfs",
+ ":perfetto_src_traced_probes_initial_display_state_initial_display_state",
+ ":perfetto_src_traced_probes_metatrace_metatrace",
+ ":perfetto_src_traced_probes_packages_list_packages_list",
+ ":perfetto_src_traced_probes_packages_list_packages_list_parser",
+ ":perfetto_src_traced_probes_power_power",
+ ":perfetto_src_traced_probes_probes_src",
+ ":perfetto_src_traced_probes_ps_ps",
+ ":perfetto_src_traced_probes_sys_stats_sys_stats",
+ ":perfetto_src_traced_probes_system_info_system_info",
+ ":perfetto_src_tracing_common",
+ ":perfetto_src_tracing_core_core",
+ ":perfetto_src_tracing_core_service",
+ ":perfetto_src_tracing_ipc_common",
+ ":perfetto_src_tracing_ipc_consumer_consumer",
+ ":perfetto_src_tracing_ipc_default_socket",
+ ":perfetto_src_tracing_ipc_producer_producer",
+ ":perfetto_src_tracing_ipc_service_service",
+ ":perfetto_test_integrationtests",
+ ":perfetto_test_test_helper",
+ "test/cts/device_feature_test_cts.cc",
+ "test/cts/end_to_end_integrationtest_cts.cc",
+ "test/cts/heapprofd_java_test_cts.cc",
+ "test/cts/heapprofd_test_cts.cc",
+ "test/cts/traced_perf_test_cts.cc",
+ ],
+ static_libs: [
+ "libgmock",
+ "libgtest",
+ "libperfetto_client_experimental",
+ ],
+ whole_static_libs: [
+ "perfetto_gtest_logcat_printer",
+ ],
+ generated_headers: [
+ "perfetto_protos_perfetto_common_cpp_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_android_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_android_zero_gen_headers",
+ "perfetto_protos_perfetto_config_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
+ "perfetto_protos_perfetto_config_power_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_power_zero_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
+ "perfetto_protos_perfetto_ipc_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_ipc_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_android_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_android_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_power_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_power_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_zero_gen_headers",
+ "perfetto_src_base_version_gen_h",
+ ],
+ export_generated_headers: [
+ "perfetto_protos_perfetto_common_cpp_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_android_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_android_zero_gen_headers",
+ "perfetto_protos_perfetto_config_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
+ "perfetto_protos_perfetto_config_power_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_power_zero_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
+ "perfetto_protos_perfetto_ipc_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_ipc_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_android_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_android_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_power_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_power_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_zero_gen_headers",
+ "perfetto_src_base_version_gen_h",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ cflags: [
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ ],
}
// GN: //test/cts:perfetto_cts_jni_deps
cc_library_static {
- name: "perfetto_cts_jni_deps",
- srcs: [
- ":perfetto_include_perfetto_base_base",
- ":perfetto_include_perfetto_ext_base_base",
- ":perfetto_include_perfetto_ext_ipc_ipc",
- ":perfetto_include_perfetto_ext_traced_sys_stats_counters",
- ":perfetto_include_perfetto_ext_traced_traced",
- ":perfetto_include_perfetto_ext_tracing_core_core",
- ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
- ":perfetto_include_perfetto_protozero_protozero",
- ":perfetto_include_perfetto_tracing_core_core",
- ":perfetto_include_perfetto_tracing_core_forward_decls",
- ":perfetto_include_perfetto_tracing_tracing",
- ":perfetto_protos_perfetto_common_cpp_gen",
- ":perfetto_protos_perfetto_common_zero_gen",
- ":perfetto_protos_perfetto_config_android_cpp_gen",
- ":perfetto_protos_perfetto_config_android_zero_gen",
- ":perfetto_protos_perfetto_config_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_zero_gen",
- ":perfetto_protos_perfetto_config_gpu_cpp_gen",
- ":perfetto_protos_perfetto_config_gpu_zero_gen",
- ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
- ":perfetto_protos_perfetto_config_inode_file_zero_gen",
- ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
- ":perfetto_protos_perfetto_config_interceptors_zero_gen",
- ":perfetto_protos_perfetto_config_power_cpp_gen",
- ":perfetto_protos_perfetto_config_power_zero_gen",
- ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_process_stats_zero_gen",
- ":perfetto_protos_perfetto_config_profiling_cpp_gen",
- ":perfetto_protos_perfetto_config_profiling_zero_gen",
- ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_config_track_event_cpp_gen",
- ":perfetto_protos_perfetto_config_track_event_zero_gen",
- ":perfetto_protos_perfetto_config_zero_gen",
- ":perfetto_protos_perfetto_ipc_cpp_gen",
- ":perfetto_protos_perfetto_ipc_ipc_gen",
- ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
- ":perfetto_protos_perfetto_trace_android_cpp_gen",
- ":perfetto_protos_perfetto_trace_android_zero_gen",
- ":perfetto_protos_perfetto_trace_chrome_cpp_gen",
- ":perfetto_protos_perfetto_trace_chrome_zero_gen",
- ":perfetto_protos_perfetto_trace_filesystem_cpp_gen",
- ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
- ":perfetto_protos_perfetto_trace_ftrace_cpp_gen",
- ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
- ":perfetto_protos_perfetto_trace_gpu_cpp_gen",
- ":perfetto_protos_perfetto_trace_gpu_zero_gen",
- ":perfetto_protos_perfetto_trace_interned_data_cpp_gen",
- ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
- ":perfetto_protos_perfetto_trace_minimal_cpp_gen",
- ":perfetto_protos_perfetto_trace_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_non_minimal_cpp_gen",
- ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_perfetto_cpp_gen",
- ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
- ":perfetto_protos_perfetto_trace_power_cpp_gen",
- ":perfetto_protos_perfetto_trace_power_zero_gen",
- ":perfetto_protos_perfetto_trace_profiling_cpp_gen",
- ":perfetto_protos_perfetto_trace_profiling_zero_gen",
- ":perfetto_protos_perfetto_trace_ps_cpp_gen",
- ":perfetto_protos_perfetto_trace_ps_zero_gen",
- ":perfetto_protos_perfetto_trace_sys_stats_cpp_gen",
- ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_trace_system_info_cpp_gen",
- ":perfetto_protos_perfetto_trace_system_info_zero_gen",
- ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
- ":perfetto_protos_perfetto_trace_track_event_zero_gen",
- ":perfetto_src_android_internal_headers",
- ":perfetto_src_android_internal_lazy_library_loader",
- ":perfetto_src_android_stats_android_stats",
- ":perfetto_src_android_stats_perfetto_atoms",
- ":perfetto_src_base_base",
- ":perfetto_src_base_test_support",
- ":perfetto_src_base_unix_socket",
- ":perfetto_src_ipc_client",
- ":perfetto_src_ipc_common",
- ":perfetto_src_ipc_host",
- ":perfetto_src_ipc_perfetto_ipc",
- ":perfetto_src_kallsyms_kallsyms",
- ":perfetto_src_protozero_filtering_bytecode_common",
- ":perfetto_src_protozero_filtering_bytecode_parser",
- ":perfetto_src_protozero_filtering_message_filter",
- ":perfetto_src_protozero_protozero",
- ":perfetto_src_traced_probes_android_log_android_log",
- ":perfetto_src_traced_probes_common_common",
- ":perfetto_src_traced_probes_data_source",
- ":perfetto_src_traced_probes_filesystem_filesystem",
- ":perfetto_src_traced_probes_ftrace_format_parser_format_parser",
- ":perfetto_src_traced_probes_ftrace_ftrace",
- ":perfetto_src_traced_probes_ftrace_ftrace_procfs",
- ":perfetto_src_traced_probes_initial_display_state_initial_display_state",
- ":perfetto_src_traced_probes_metatrace_metatrace",
- ":perfetto_src_traced_probes_packages_list_packages_list",
- ":perfetto_src_traced_probes_packages_list_packages_list_parser",
- ":perfetto_src_traced_probes_power_power",
- ":perfetto_src_traced_probes_probes_src",
- ":perfetto_src_traced_probes_ps_ps",
- ":perfetto_src_traced_probes_sys_stats_sys_stats",
- ":perfetto_src_traced_probes_system_info_system_info",
- ":perfetto_src_tracing_common",
- ":perfetto_src_tracing_core_core",
- ":perfetto_src_tracing_core_service",
- ":perfetto_src_tracing_ipc_common",
- ":perfetto_src_tracing_ipc_consumer_consumer",
- ":perfetto_src_tracing_ipc_producer_producer",
- ":perfetto_src_tracing_ipc_service_service",
- ":perfetto_test_test_helper",
- ],
- generated_headers: [
- "perfetto_protos_perfetto_common_cpp_gen_headers",
- "perfetto_protos_perfetto_common_zero_gen_headers",
- "perfetto_protos_perfetto_config_android_cpp_gen_headers",
- "perfetto_protos_perfetto_config_android_zero_gen_headers",
- "perfetto_protos_perfetto_config_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
- "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
- "perfetto_protos_perfetto_config_power_cpp_gen_headers",
- "perfetto_protos_perfetto_config_power_zero_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
- "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_config_zero_gen_headers",
- "perfetto_protos_perfetto_ipc_cpp_gen_headers",
- "perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_android_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_android_zero_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
- "perfetto_protos_perfetto_trace_power_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_power_zero_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ps_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_src_base_version_gen_h",
- ],
- export_generated_headers: [
- "perfetto_protos_perfetto_common_cpp_gen_headers",
- "perfetto_protos_perfetto_common_zero_gen_headers",
- "perfetto_protos_perfetto_config_android_cpp_gen_headers",
- "perfetto_protos_perfetto_config_android_zero_gen_headers",
- "perfetto_protos_perfetto_config_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
- "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
- "perfetto_protos_perfetto_config_power_cpp_gen_headers",
- "perfetto_protos_perfetto_config_power_zero_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
- "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_config_zero_gen_headers",
- "perfetto_protos_perfetto_ipc_cpp_gen_headers",
- "perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_android_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_android_zero_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
- "perfetto_protos_perfetto_trace_power_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_power_zero_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ps_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_src_base_version_gen_h",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- cflags: [
- "-DGOOGLE_PROTOBUF_NO_RTTI",
- "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
- ],
+ name: "perfetto_cts_jni_deps",
+ srcs: [
+ ":perfetto_include_perfetto_base_base",
+ ":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_include_perfetto_ext_ipc_ipc",
+ ":perfetto_include_perfetto_ext_traced_sys_stats_counters",
+ ":perfetto_include_perfetto_ext_traced_traced",
+ ":perfetto_include_perfetto_ext_tracing_core_core",
+ ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
+ ":perfetto_include_perfetto_protozero_protozero",
+ ":perfetto_include_perfetto_tracing_core_core",
+ ":perfetto_include_perfetto_tracing_core_forward_decls",
+ ":perfetto_include_perfetto_tracing_tracing",
+ ":perfetto_protos_perfetto_common_cpp_gen",
+ ":perfetto_protos_perfetto_common_zero_gen",
+ ":perfetto_protos_perfetto_config_android_cpp_gen",
+ ":perfetto_protos_perfetto_config_android_zero_gen",
+ ":perfetto_protos_perfetto_config_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_config_gpu_cpp_gen",
+ ":perfetto_protos_perfetto_config_gpu_zero_gen",
+ ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
+ ":perfetto_protos_perfetto_config_inode_file_zero_gen",
+ ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
+ ":perfetto_protos_perfetto_config_interceptors_zero_gen",
+ ":perfetto_protos_perfetto_config_power_cpp_gen",
+ ":perfetto_protos_perfetto_config_power_zero_gen",
+ ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_process_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_profiling_cpp_gen",
+ ":perfetto_protos_perfetto_config_profiling_zero_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_config_track_event_zero_gen",
+ ":perfetto_protos_perfetto_config_zero_gen",
+ ":perfetto_protos_perfetto_ipc_cpp_gen",
+ ":perfetto_protos_perfetto_ipc_ipc_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
+ ":perfetto_protos_perfetto_trace_android_cpp_gen",
+ ":perfetto_protos_perfetto_trace_android_zero_gen",
+ ":perfetto_protos_perfetto_trace_chrome_cpp_gen",
+ ":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_filesystem_cpp_gen",
+ ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
+ ":perfetto_protos_perfetto_trace_ftrace_cpp_gen",
+ ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_trace_gpu_cpp_gen",
+ ":perfetto_protos_perfetto_trace_gpu_zero_gen",
+ ":perfetto_protos_perfetto_trace_interned_data_cpp_gen",
+ ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
+ ":perfetto_protos_perfetto_trace_minimal_cpp_gen",
+ ":perfetto_protos_perfetto_trace_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_non_minimal_cpp_gen",
+ ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_perfetto_cpp_gen",
+ ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
+ ":perfetto_protos_perfetto_trace_power_cpp_gen",
+ ":perfetto_protos_perfetto_trace_power_zero_gen",
+ ":perfetto_protos_perfetto_trace_profiling_cpp_gen",
+ ":perfetto_protos_perfetto_trace_profiling_zero_gen",
+ ":perfetto_protos_perfetto_trace_ps_cpp_gen",
+ ":perfetto_protos_perfetto_trace_ps_zero_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_cpp_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_trace_system_info_cpp_gen",
+ ":perfetto_protos_perfetto_trace_system_info_zero_gen",
+ ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_trace_track_event_zero_gen",
+ ":perfetto_protos_perfetto_trace_translation_cpp_gen",
+ ":perfetto_protos_perfetto_trace_translation_zero_gen",
+ ":perfetto_src_android_internal_headers",
+ ":perfetto_src_android_internal_lazy_library_loader",
+ ":perfetto_src_android_stats_android_stats",
+ ":perfetto_src_android_stats_perfetto_atoms",
+ ":perfetto_src_base_base",
+ ":perfetto_src_base_test_support",
+ ":perfetto_src_base_unix_socket",
+ ":perfetto_src_ipc_client",
+ ":perfetto_src_ipc_common",
+ ":perfetto_src_ipc_host",
+ ":perfetto_src_ipc_perfetto_ipc",
+ ":perfetto_src_kallsyms_kallsyms",
+ ":perfetto_src_protozero_filtering_bytecode_common",
+ ":perfetto_src_protozero_filtering_bytecode_parser",
+ ":perfetto_src_protozero_filtering_message_filter",
+ ":perfetto_src_protozero_protozero",
+ ":perfetto_src_traced_probes_android_log_android_log",
+ ":perfetto_src_traced_probes_common_common",
+ ":perfetto_src_traced_probes_data_source",
+ ":perfetto_src_traced_probes_filesystem_filesystem",
+ ":perfetto_src_traced_probes_ftrace_format_parser_format_parser",
+ ":perfetto_src_traced_probes_ftrace_ftrace",
+ ":perfetto_src_traced_probes_ftrace_ftrace_procfs",
+ ":perfetto_src_traced_probes_initial_display_state_initial_display_state",
+ ":perfetto_src_traced_probes_metatrace_metatrace",
+ ":perfetto_src_traced_probes_packages_list_packages_list",
+ ":perfetto_src_traced_probes_packages_list_packages_list_parser",
+ ":perfetto_src_traced_probes_power_power",
+ ":perfetto_src_traced_probes_probes_src",
+ ":perfetto_src_traced_probes_ps_ps",
+ ":perfetto_src_traced_probes_sys_stats_sys_stats",
+ ":perfetto_src_traced_probes_system_info_system_info",
+ ":perfetto_src_tracing_common",
+ ":perfetto_src_tracing_core_core",
+ ":perfetto_src_tracing_core_service",
+ ":perfetto_src_tracing_ipc_common",
+ ":perfetto_src_tracing_ipc_consumer_consumer",
+ ":perfetto_src_tracing_ipc_default_socket",
+ ":perfetto_src_tracing_ipc_producer_producer",
+ ":perfetto_src_tracing_ipc_service_service",
+ ":perfetto_test_test_helper",
+ ],
+ generated_headers: [
+ "perfetto_protos_perfetto_common_cpp_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_android_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_android_zero_gen_headers",
+ "perfetto_protos_perfetto_config_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
+ "perfetto_protos_perfetto_config_power_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_power_zero_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
+ "perfetto_protos_perfetto_ipc_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_ipc_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_android_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_android_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_power_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_power_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_zero_gen_headers",
+ "perfetto_src_base_version_gen_h",
+ ],
+ export_generated_headers: [
+ "perfetto_protos_perfetto_common_cpp_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_android_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_android_zero_gen_headers",
+ "perfetto_protos_perfetto_config_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
+ "perfetto_protos_perfetto_config_power_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_power_zero_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
+ "perfetto_protos_perfetto_ipc_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_ipc_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_android_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_android_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_power_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_power_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_zero_gen_headers",
+ "perfetto_src_base_version_gen_h",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ cflags: [
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ ],
}
// GN: //gn:default_deps
cc_defaults {
- name: "perfetto_defaults",
- cflags: [
- "-O2",
- "-Wno-error=return-type",
- "-Wno-sign-compare",
- "-Wno-sign-promo",
- "-Wno-unused-parameter",
- "-fvisibility=hidden",
- ],
- include_dirs: [
- "external/perfetto",
- "external/perfetto/include",
- "external/perfetto/include/perfetto/base/build_configs/android_tree",
- "external/perfetto/src/profiling/memory/include",
- ],
- product_variables: {
- debuggable: {
- cflags: ["-DPERFETTO_BUILD_WITH_ANDROID_USERDEBUG"],
+ name: "perfetto_defaults",
+ cflags: [
+ "-O2",
+ "-Wno-error=return-type",
+ "-Wno-sign-compare",
+ "-Wno-sign-promo",
+ "-Wno-unused-parameter",
+ "-fvisibility=hidden",
+ ],
+ include_dirs: [
+ "external/perfetto",
+ "external/perfetto/include",
+ "external/perfetto/include/perfetto/base/build_configs/android_tree",
+ "external/perfetto/src/profiling/memory/include",
+ ],
+ product_variables: {
+ debuggable: {
+ cflags: ["-DPERFETTO_BUILD_WITH_ANDROID_USERDEBUG"],
+ },
},
- },
- target: {
- android: {
- lto: {
- thin: true,
- },
+ target: {
+ android: {
+ lto: {
+ thin: true,
+ },
+ },
},
- },
}
// GN: //test:perfetto_gtest_logcat_printer
cc_library_static {
- name: "perfetto_gtest_logcat_printer",
- srcs: [
- "test/gtest_logcat_printer.cc",
- ],
- static_libs: [
- "libgmock",
- "libgtest",
- ],
- defaults: [
- "perfetto_defaults",
- ],
+ name: "perfetto_gtest_logcat_printer",
+ srcs: [
+ "test/gtest_logcat_printer.cc",
+ ],
+ static_libs: [
+ "libgmock",
+ "libgtest",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
}
// GN: //include/perfetto/base:base
filegroup {
- name: "perfetto_include_perfetto_base_base",
+ name: "perfetto_include_perfetto_base_base",
}
// GN: //include/perfetto/ext/base:base
filegroup {
- name: "perfetto_include_perfetto_ext_base_base",
+ name: "perfetto_include_perfetto_ext_base_base",
+}
+
+// GN: //include/perfetto/ext/base/http:http
+filegroup {
+ name: "perfetto_include_perfetto_ext_base_http_http",
}
// GN: //include/perfetto/ext/ipc:ipc
filegroup {
- name: "perfetto_include_perfetto_ext_ipc_ipc",
+ name: "perfetto_include_perfetto_ext_ipc_ipc",
+}
+
+// GN: //include/perfetto/ext/trace_processor:demangle
+filegroup {
+ name: "perfetto_include_perfetto_ext_trace_processor_demangle",
}
// GN: //include/perfetto/ext/trace_processor:export_json
filegroup {
- name: "perfetto_include_perfetto_ext_trace_processor_export_json",
+ name: "perfetto_include_perfetto_ext_trace_processor_export_json",
}
// GN: //include/perfetto/ext/trace_processor/importers/memory_tracker:memory_tracker
filegroup {
- name: "perfetto_include_perfetto_ext_trace_processor_importers_memory_tracker_memory_tracker",
+ name: "perfetto_include_perfetto_ext_trace_processor_importers_memory_tracker_memory_tracker",
}
// GN: //include/perfetto/ext/traced:sys_stats_counters
filegroup {
- name: "perfetto_include_perfetto_ext_traced_sys_stats_counters",
+ name: "perfetto_include_perfetto_ext_traced_sys_stats_counters",
}
// GN: //include/perfetto/ext/traced:traced
filegroup {
- name: "perfetto_include_perfetto_ext_traced_traced",
+ name: "perfetto_include_perfetto_ext_traced_traced",
}
// GN: //include/perfetto/ext/tracing/core:core
filegroup {
- name: "perfetto_include_perfetto_ext_tracing_core_core",
+ name: "perfetto_include_perfetto_ext_tracing_core_core",
}
// GN: //include/perfetto/ext/tracing/ipc:ipc
filegroup {
- name: "perfetto_include_perfetto_ext_tracing_ipc_ipc",
-}
-
-// GN: //include/perfetto/profiling:normalize
-filegroup {
- name: "perfetto_include_perfetto_profiling_normalize",
+ name: "perfetto_include_perfetto_ext_tracing_ipc_ipc",
}
// GN: //include/perfetto/profiling:pprof_builder
filegroup {
- name: "perfetto_include_perfetto_profiling_pprof_builder",
+ name: "perfetto_include_perfetto_profiling_pprof_builder",
}
// GN: //include/perfetto/protozero:protozero
filegroup {
- name: "perfetto_include_perfetto_protozero_protozero",
+ name: "perfetto_include_perfetto_protozero_protozero",
}
// GN: //include/perfetto/public:public
filegroup {
- name: "perfetto_include_perfetto_public_public",
+ name: "perfetto_include_perfetto_public_public",
}
// GN: //include/perfetto/test:test_support
filegroup {
- name: "perfetto_include_perfetto_test_test_support",
+ name: "perfetto_include_perfetto_test_test_support",
}
// GN: //include/perfetto/trace_processor:basic_types
filegroup {
- name: "perfetto_include_perfetto_trace_processor_basic_types",
+ name: "perfetto_include_perfetto_trace_processor_basic_types",
}
// GN: //include/perfetto/trace_processor:storage
filegroup {
- name: "perfetto_include_perfetto_trace_processor_storage",
+ name: "perfetto_include_perfetto_trace_processor_storage",
}
// GN: //include/perfetto/trace_processor:trace_processor
filegroup {
- name: "perfetto_include_perfetto_trace_processor_trace_processor",
+ name: "perfetto_include_perfetto_trace_processor_trace_processor",
}
// GN: //include/perfetto/tracing/core:core
filegroup {
- name: "perfetto_include_perfetto_tracing_core_core",
+ name: "perfetto_include_perfetto_tracing_core_core",
}
// GN: //include/perfetto/tracing/core:forward_decls
filegroup {
- name: "perfetto_include_perfetto_tracing_core_forward_decls",
+ name: "perfetto_include_perfetto_tracing_core_forward_decls",
}
// GN: //include/perfetto/tracing:tracing
filegroup {
- name: "perfetto_include_perfetto_tracing_tracing",
+ name: "perfetto_include_perfetto_tracing_tracing",
}
// GN: //:perfetto_integrationtests
cc_test {
- name: "perfetto_integrationtests",
- srcs: [
- ":perfetto_include_perfetto_base_base",
- ":perfetto_include_perfetto_ext_base_base",
- ":perfetto_include_perfetto_ext_ipc_ipc",
- ":perfetto_include_perfetto_ext_trace_processor_export_json",
- ":perfetto_include_perfetto_ext_trace_processor_importers_memory_tracker_memory_tracker",
- ":perfetto_include_perfetto_ext_traced_sys_stats_counters",
- ":perfetto_include_perfetto_ext_traced_traced",
- ":perfetto_include_perfetto_ext_tracing_core_core",
- ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
- ":perfetto_include_perfetto_profiling_normalize",
- ":perfetto_include_perfetto_protozero_protozero",
- ":perfetto_include_perfetto_trace_processor_basic_types",
- ":perfetto_include_perfetto_trace_processor_storage",
- ":perfetto_include_perfetto_trace_processor_trace_processor",
- ":perfetto_include_perfetto_tracing_core_core",
- ":perfetto_include_perfetto_tracing_core_forward_decls",
- ":perfetto_include_perfetto_tracing_tracing",
- ":perfetto_protos_perfetto_common_cpp_gen",
- ":perfetto_protos_perfetto_common_zero_gen",
- ":perfetto_protos_perfetto_config_android_cpp_gen",
- ":perfetto_protos_perfetto_config_android_zero_gen",
- ":perfetto_protos_perfetto_config_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_zero_gen",
- ":perfetto_protos_perfetto_config_gpu_cpp_gen",
- ":perfetto_protos_perfetto_config_gpu_zero_gen",
- ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
- ":perfetto_protos_perfetto_config_inode_file_zero_gen",
- ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
- ":perfetto_protos_perfetto_config_interceptors_zero_gen",
- ":perfetto_protos_perfetto_config_power_cpp_gen",
- ":perfetto_protos_perfetto_config_power_zero_gen",
- ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_process_stats_zero_gen",
- ":perfetto_protos_perfetto_config_profiling_cpp_gen",
- ":perfetto_protos_perfetto_config_profiling_zero_gen",
- ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_config_track_event_cpp_gen",
- ":perfetto_protos_perfetto_config_track_event_zero_gen",
- ":perfetto_protos_perfetto_config_zero_gen",
- ":perfetto_protos_perfetto_ipc_cpp_gen",
- ":perfetto_protos_perfetto_ipc_ipc_gen",
- ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
- ":perfetto_protos_perfetto_trace_android_cpp_gen",
- ":perfetto_protos_perfetto_trace_android_zero_gen",
- ":perfetto_protos_perfetto_trace_chrome_cpp_gen",
- ":perfetto_protos_perfetto_trace_chrome_zero_gen",
- ":perfetto_protos_perfetto_trace_filesystem_cpp_gen",
- ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
- ":perfetto_protos_perfetto_trace_ftrace_cpp_gen",
- ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
- ":perfetto_protos_perfetto_trace_gpu_cpp_gen",
- ":perfetto_protos_perfetto_trace_gpu_zero_gen",
- ":perfetto_protos_perfetto_trace_interned_data_cpp_gen",
- ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
- ":perfetto_protos_perfetto_trace_minimal_cpp_gen",
- ":perfetto_protos_perfetto_trace_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_non_minimal_cpp_gen",
- ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_perfetto_cpp_gen",
- ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
- ":perfetto_protos_perfetto_trace_power_cpp_gen",
- ":perfetto_protos_perfetto_trace_power_zero_gen",
- ":perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen",
- ":perfetto_protos_perfetto_trace_processor_zero_gen",
- ":perfetto_protos_perfetto_trace_profiling_cpp_gen",
- ":perfetto_protos_perfetto_trace_profiling_zero_gen",
- ":perfetto_protos_perfetto_trace_ps_cpp_gen",
- ":perfetto_protos_perfetto_trace_ps_zero_gen",
- ":perfetto_protos_perfetto_trace_sys_stats_cpp_gen",
- ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_trace_system_info_cpp_gen",
- ":perfetto_protos_perfetto_trace_system_info_zero_gen",
- ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
- ":perfetto_protos_perfetto_trace_track_event_zero_gen",
- ":perfetto_src_android_internal_headers",
- ":perfetto_src_android_internal_lazy_library_loader",
- ":perfetto_src_android_stats_android_stats",
- ":perfetto_src_android_stats_perfetto_atoms",
- ":perfetto_src_base_base",
- ":perfetto_src_base_test_support",
- ":perfetto_src_base_unix_socket",
- ":perfetto_src_ipc_client",
- ":perfetto_src_ipc_common",
- ":perfetto_src_ipc_host",
- ":perfetto_src_ipc_perfetto_ipc",
- ":perfetto_src_kallsyms_kallsyms",
- ":perfetto_src_profiling_common_callstack_trie",
- ":perfetto_src_profiling_common_interner",
- ":perfetto_src_profiling_common_interning_output",
- ":perfetto_src_profiling_common_proc_utils",
- ":perfetto_src_profiling_common_producer_support",
- ":perfetto_src_profiling_common_profiler_guardrails",
- ":perfetto_src_profiling_common_unwind_support",
- ":perfetto_src_profiling_memory_client",
- ":perfetto_src_profiling_memory_daemon",
- ":perfetto_src_profiling_memory_end_to_end_tests",
- ":perfetto_src_profiling_memory_ring_buffer",
- ":perfetto_src_profiling_memory_scoped_spinlock",
- ":perfetto_src_profiling_memory_wire_protocol",
- ":perfetto_src_protozero_filtering_bytecode_common",
- ":perfetto_src_protozero_filtering_bytecode_parser",
- ":perfetto_src_protozero_filtering_message_filter",
- ":perfetto_src_protozero_protozero",
- ":perfetto_src_trace_processor_analysis_analysis",
- ":perfetto_src_trace_processor_containers_containers",
- ":perfetto_src_trace_processor_db_db",
- ":perfetto_src_trace_processor_export_json",
- ":perfetto_src_trace_processor_ftrace_descriptors",
- ":perfetto_src_trace_processor_importers_common_common",
- ":perfetto_src_trace_processor_importers_memory_tracker_graph_processor",
- ":perfetto_src_trace_processor_lib",
- ":perfetto_src_trace_processor_metatrace",
- ":perfetto_src_trace_processor_metrics_lib",
- ":perfetto_src_trace_processor_sqlite_sqlite",
- ":perfetto_src_trace_processor_storage_full",
- ":perfetto_src_trace_processor_storage_minimal",
- ":perfetto_src_trace_processor_storage_storage",
- ":perfetto_src_trace_processor_tables_tables",
- ":perfetto_src_trace_processor_types_types",
- ":perfetto_src_trace_processor_util_descriptors",
- ":perfetto_src_trace_processor_util_proto_to_args_parser",
- ":perfetto_src_trace_processor_util_protozero_to_text",
- ":perfetto_src_trace_processor_util_util",
- ":perfetto_src_traced_probes_android_log_android_log",
- ":perfetto_src_traced_probes_common_common",
- ":perfetto_src_traced_probes_data_source",
- ":perfetto_src_traced_probes_filesystem_filesystem",
- ":perfetto_src_traced_probes_ftrace_format_parser_format_parser",
- ":perfetto_src_traced_probes_ftrace_ftrace",
- ":perfetto_src_traced_probes_ftrace_ftrace_procfs",
- ":perfetto_src_traced_probes_ftrace_integrationtests",
- ":perfetto_src_traced_probes_ftrace_test_support",
- ":perfetto_src_traced_probes_initial_display_state_initial_display_state",
- ":perfetto_src_traced_probes_metatrace_metatrace",
- ":perfetto_src_traced_probes_packages_list_packages_list",
- ":perfetto_src_traced_probes_packages_list_packages_list_parser",
- ":perfetto_src_traced_probes_power_power",
- ":perfetto_src_traced_probes_probes_src",
- ":perfetto_src_traced_probes_ps_ps",
- ":perfetto_src_traced_probes_sys_stats_sys_stats",
- ":perfetto_src_traced_probes_system_info_system_info",
- ":perfetto_src_tracing_client_api_without_backends",
- ":perfetto_src_tracing_common",
- ":perfetto_src_tracing_core_core",
- ":perfetto_src_tracing_core_service",
- ":perfetto_src_tracing_in_process_backend",
- ":perfetto_src_tracing_ipc_common",
- ":perfetto_src_tracing_ipc_consumer_consumer",
- ":perfetto_src_tracing_ipc_producer_producer",
- ":perfetto_src_tracing_ipc_service_service",
- ":perfetto_src_tracing_platform_impl",
- ":perfetto_src_tracing_system_backend",
- ":perfetto_src_tracing_test_api_test_support",
- ":perfetto_src_tracing_test_client_api_integrationtests",
- ":perfetto_test_end_to_end_integrationtests",
- ":perfetto_test_test_helper",
- ],
- shared_libs: [
- "heapprofd_client_api",
- "libandroidicu",
- "libbase",
- "liblog",
- "libprocinfo",
- "libsqlite",
- "libunwindstack",
- "libutils",
- "libz",
- ],
- static_libs: [
- "libgmock",
- "libgtest",
- "libperfetto_client_experimental",
- ],
- whole_static_libs: [
- "perfetto_gtest_logcat_printer",
- ],
- generated_headers: [
- "perfetto_protos_perfetto_common_cpp_gen_headers",
- "perfetto_protos_perfetto_common_zero_gen_headers",
- "perfetto_protos_perfetto_config_android_cpp_gen_headers",
- "perfetto_protos_perfetto_config_android_zero_gen_headers",
- "perfetto_protos_perfetto_config_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
- "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
- "perfetto_protos_perfetto_config_power_cpp_gen_headers",
- "perfetto_protos_perfetto_config_power_zero_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
- "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_config_zero_gen_headers",
- "perfetto_protos_perfetto_ipc_cpp_gen_headers",
- "perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_android_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_android_zero_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
- "perfetto_protos_perfetto_trace_power_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_power_zero_gen_headers",
- "perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen_headers",
- "perfetto_protos_perfetto_trace_processor_zero_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ps_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_src_base_version_gen_h",
- "perfetto_src_trace_processor_importers_gen_cc_chrome_track_event_descriptor",
- "perfetto_src_trace_processor_importers_gen_cc_config_descriptor",
- "perfetto_src_trace_processor_importers_gen_cc_track_event_descriptor",
- "perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
- "perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
- "perfetto_src_trace_processor_metrics_gen_merged_sql_metrics",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- cflags: [
- "-DGOOGLE_PROTOBUF_NO_RTTI",
- "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
- "-DHAVE_HIDDEN",
- ],
- header_libs: [
- "bionic_libc_platform_headers",
- ],
- test_suites: [
- "general-tests",
- ],
- test_config: "PerfettoIntegrationTests.xml",
+ name: "perfetto_integrationtests",
+ srcs: [
+ ":perfetto_include_perfetto_base_base",
+ ":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_include_perfetto_ext_ipc_ipc",
+ ":perfetto_include_perfetto_ext_trace_processor_export_json",
+ ":perfetto_include_perfetto_ext_trace_processor_importers_memory_tracker_memory_tracker",
+ ":perfetto_include_perfetto_ext_traced_sys_stats_counters",
+ ":perfetto_include_perfetto_ext_traced_traced",
+ ":perfetto_include_perfetto_ext_tracing_core_core",
+ ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
+ ":perfetto_include_perfetto_protozero_protozero",
+ ":perfetto_include_perfetto_trace_processor_basic_types",
+ ":perfetto_include_perfetto_trace_processor_storage",
+ ":perfetto_include_perfetto_trace_processor_trace_processor",
+ ":perfetto_include_perfetto_tracing_core_core",
+ ":perfetto_include_perfetto_tracing_core_forward_decls",
+ ":perfetto_include_perfetto_tracing_tracing",
+ ":perfetto_protos_perfetto_common_cpp_gen",
+ ":perfetto_protos_perfetto_common_zero_gen",
+ ":perfetto_protos_perfetto_config_android_cpp_gen",
+ ":perfetto_protos_perfetto_config_android_zero_gen",
+ ":perfetto_protos_perfetto_config_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_config_gpu_cpp_gen",
+ ":perfetto_protos_perfetto_config_gpu_zero_gen",
+ ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
+ ":perfetto_protos_perfetto_config_inode_file_zero_gen",
+ ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
+ ":perfetto_protos_perfetto_config_interceptors_zero_gen",
+ ":perfetto_protos_perfetto_config_power_cpp_gen",
+ ":perfetto_protos_perfetto_config_power_zero_gen",
+ ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_process_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_profiling_cpp_gen",
+ ":perfetto_protos_perfetto_config_profiling_zero_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_config_track_event_zero_gen",
+ ":perfetto_protos_perfetto_config_zero_gen",
+ ":perfetto_protos_perfetto_ipc_cpp_gen",
+ ":perfetto_protos_perfetto_ipc_ipc_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
+ ":perfetto_protos_perfetto_trace_android_cpp_gen",
+ ":perfetto_protos_perfetto_trace_android_zero_gen",
+ ":perfetto_protos_perfetto_trace_chrome_cpp_gen",
+ ":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_filesystem_cpp_gen",
+ ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
+ ":perfetto_protos_perfetto_trace_ftrace_cpp_gen",
+ ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_trace_gpu_cpp_gen",
+ ":perfetto_protos_perfetto_trace_gpu_zero_gen",
+ ":perfetto_protos_perfetto_trace_interned_data_cpp_gen",
+ ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
+ ":perfetto_protos_perfetto_trace_minimal_cpp_gen",
+ ":perfetto_protos_perfetto_trace_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_non_minimal_cpp_gen",
+ ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_perfetto_cpp_gen",
+ ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
+ ":perfetto_protos_perfetto_trace_power_cpp_gen",
+ ":perfetto_protos_perfetto_trace_power_zero_gen",
+ ":perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen",
+ ":perfetto_protos_perfetto_trace_processor_zero_gen",
+ ":perfetto_protos_perfetto_trace_profiling_cpp_gen",
+ ":perfetto_protos_perfetto_trace_profiling_zero_gen",
+ ":perfetto_protos_perfetto_trace_ps_cpp_gen",
+ ":perfetto_protos_perfetto_trace_ps_zero_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_cpp_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_trace_system_info_cpp_gen",
+ ":perfetto_protos_perfetto_trace_system_info_zero_gen",
+ ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_trace_track_event_zero_gen",
+ ":perfetto_protos_perfetto_trace_translation_cpp_gen",
+ ":perfetto_protos_perfetto_trace_translation_zero_gen",
+ ":perfetto_src_android_internal_headers",
+ ":perfetto_src_android_internal_lazy_library_loader",
+ ":perfetto_src_android_stats_android_stats",
+ ":perfetto_src_android_stats_perfetto_atoms",
+ ":perfetto_src_base_base",
+ ":perfetto_src_base_test_support",
+ ":perfetto_src_base_unix_socket",
+ ":perfetto_src_ipc_client",
+ ":perfetto_src_ipc_common",
+ ":perfetto_src_ipc_host",
+ ":perfetto_src_ipc_perfetto_ipc",
+ ":perfetto_src_kallsyms_kallsyms",
+ ":perfetto_src_profiling_common_callstack_trie",
+ ":perfetto_src_profiling_common_interner",
+ ":perfetto_src_profiling_common_interning_output",
+ ":perfetto_src_profiling_common_proc_cmdline",
+ ":perfetto_src_profiling_common_proc_utils",
+ ":perfetto_src_profiling_common_producer_support",
+ ":perfetto_src_profiling_common_profiler_guardrails",
+ ":perfetto_src_profiling_common_unwind_support",
+ ":perfetto_src_profiling_memory_client",
+ ":perfetto_src_profiling_memory_daemon",
+ ":perfetto_src_profiling_memory_end_to_end_tests",
+ ":perfetto_src_profiling_memory_ring_buffer",
+ ":perfetto_src_profiling_memory_scoped_spinlock",
+ ":perfetto_src_profiling_memory_wire_protocol",
+ ":perfetto_src_protozero_filtering_bytecode_common",
+ ":perfetto_src_protozero_filtering_bytecode_generator",
+ ":perfetto_src_protozero_filtering_bytecode_parser",
+ ":perfetto_src_protozero_filtering_message_filter",
+ ":perfetto_src_protozero_protozero",
+ ":perfetto_src_trace_processor_analysis_analysis",
+ ":perfetto_src_trace_processor_containers_containers",
+ ":perfetto_src_trace_processor_db_db",
+ ":perfetto_src_trace_processor_export_json",
+ ":perfetto_src_trace_processor_ftrace_descriptors",
+ ":perfetto_src_trace_processor_importers_common_common",
+ ":perfetto_src_trace_processor_importers_memory_tracker_graph_processor",
+ ":perfetto_src_trace_processor_lib",
+ ":perfetto_src_trace_processor_metatrace",
+ ":perfetto_src_trace_processor_metrics_metrics",
+ ":perfetto_src_trace_processor_sqlite_sqlite",
+ ":perfetto_src_trace_processor_storage_full",
+ ":perfetto_src_trace_processor_storage_minimal",
+ ":perfetto_src_trace_processor_storage_storage",
+ ":perfetto_src_trace_processor_tables_tables",
+ ":perfetto_src_trace_processor_types_types",
+ ":perfetto_src_trace_processor_util_descriptors",
+ ":perfetto_src_trace_processor_util_gzip",
+ ":perfetto_src_trace_processor_util_interned_message_view",
+ ":perfetto_src_trace_processor_util_proto_to_args_parser",
+ ":perfetto_src_trace_processor_util_protozero_to_text",
+ ":perfetto_src_trace_processor_util_util",
+ ":perfetto_src_traced_probes_android_log_android_log",
+ ":perfetto_src_traced_probes_common_common",
+ ":perfetto_src_traced_probes_data_source",
+ ":perfetto_src_traced_probes_filesystem_filesystem",
+ ":perfetto_src_traced_probes_ftrace_format_parser_format_parser",
+ ":perfetto_src_traced_probes_ftrace_ftrace",
+ ":perfetto_src_traced_probes_ftrace_ftrace_procfs",
+ ":perfetto_src_traced_probes_ftrace_integrationtests",
+ ":perfetto_src_traced_probes_ftrace_test_support",
+ ":perfetto_src_traced_probes_initial_display_state_initial_display_state",
+ ":perfetto_src_traced_probes_metatrace_metatrace",
+ ":perfetto_src_traced_probes_packages_list_packages_list",
+ ":perfetto_src_traced_probes_packages_list_packages_list_parser",
+ ":perfetto_src_traced_probes_power_power",
+ ":perfetto_src_traced_probes_probes_src",
+ ":perfetto_src_traced_probes_ps_ps",
+ ":perfetto_src_traced_probes_sys_stats_sys_stats",
+ ":perfetto_src_traced_probes_system_info_system_info",
+ ":perfetto_src_tracing_client_api_without_backends",
+ ":perfetto_src_tracing_common",
+ ":perfetto_src_tracing_core_core",
+ ":perfetto_src_tracing_core_service",
+ ":perfetto_src_tracing_in_process_backend",
+ ":perfetto_src_tracing_ipc_common",
+ ":perfetto_src_tracing_ipc_consumer_consumer",
+ ":perfetto_src_tracing_ipc_default_socket",
+ ":perfetto_src_tracing_ipc_producer_producer",
+ ":perfetto_src_tracing_ipc_service_service",
+ ":perfetto_src_tracing_platform_impl",
+ ":perfetto_src_tracing_system_backend",
+ ":perfetto_src_tracing_test_api_test_support",
+ ":perfetto_src_tracing_test_client_api_integrationtests",
+ ":perfetto_test_integrationtests",
+ ":perfetto_test_test_helper",
+ ],
+ shared_libs: [
+ "heapprofd_client_api",
+ "libbase",
+ "libicu",
+ "liblog",
+ "libprocinfo",
+ "libsqlite",
+ "libunwindstack",
+ "libutils",
+ "libz",
+ ],
+ static_libs: [
+ "libgmock",
+ "libgtest",
+ "libperfetto_client_experimental",
+ "perfetto_src_trace_processor_demangle",
+ ],
+ whole_static_libs: [
+ "perfetto_gtest_logcat_printer",
+ ],
+ generated_headers: [
+ "perfetto_protos_perfetto_common_cpp_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_android_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_android_zero_gen_headers",
+ "perfetto_protos_perfetto_config_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
+ "perfetto_protos_perfetto_config_power_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_power_zero_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
+ "perfetto_protos_perfetto_ipc_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_ipc_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_android_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_android_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_power_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_power_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_processor_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_zero_gen_headers",
+ "perfetto_src_base_version_gen_h",
+ "perfetto_src_trace_processor_importers_gen_cc_chrome_track_event_descriptor",
+ "perfetto_src_trace_processor_importers_gen_cc_config_descriptor",
+ "perfetto_src_trace_processor_importers_gen_cc_track_event_descriptor",
+ "perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
+ "perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
+ "perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ cflags: [
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ "-DHAVE_HIDDEN",
+ ],
+ header_libs: [
+ "bionic_libc_platform_headers",
+ ],
+ test_suites: [
+ "general-tests",
+ ],
+ test_config: "PerfettoIntegrationTests.xml",
}
// GN: //protos/perfetto/common:cpp
genrule {
- name: "perfetto_protos_perfetto_common_cpp_gen",
- srcs: [
- "protos/perfetto/common/android_energy_consumer_descriptor.proto",
- "protos/perfetto/common/android_log_constants.proto",
- "protos/perfetto/common/builtin_clock.proto",
- "protos/perfetto/common/commit_data_request.proto",
- "protos/perfetto/common/data_source_descriptor.proto",
- "protos/perfetto/common/descriptor.proto",
- "protos/perfetto/common/gpu_counter_descriptor.proto",
- "protos/perfetto/common/interceptor_descriptor.proto",
- "protos/perfetto/common/observable_events.proto",
- "protos/perfetto/common/perf_events.proto",
- "protos/perfetto/common/sys_stats_counters.proto",
- "protos/perfetto/common/trace_stats.proto",
- "protos/perfetto/common/tracing_service_capabilities.proto",
- "protos/perfetto/common/tracing_service_state.proto",
- "protos/perfetto/common/track_event_descriptor.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/common/android_energy_consumer_descriptor.gen.cc",
- "external/perfetto/protos/perfetto/common/android_log_constants.gen.cc",
- "external/perfetto/protos/perfetto/common/builtin_clock.gen.cc",
- "external/perfetto/protos/perfetto/common/commit_data_request.gen.cc",
- "external/perfetto/protos/perfetto/common/data_source_descriptor.gen.cc",
- "external/perfetto/protos/perfetto/common/descriptor.gen.cc",
- "external/perfetto/protos/perfetto/common/gpu_counter_descriptor.gen.cc",
- "external/perfetto/protos/perfetto/common/interceptor_descriptor.gen.cc",
- "external/perfetto/protos/perfetto/common/observable_events.gen.cc",
- "external/perfetto/protos/perfetto/common/perf_events.gen.cc",
- "external/perfetto/protos/perfetto/common/sys_stats_counters.gen.cc",
- "external/perfetto/protos/perfetto/common/trace_stats.gen.cc",
- "external/perfetto/protos/perfetto/common/tracing_service_capabilities.gen.cc",
- "external/perfetto/protos/perfetto/common/tracing_service_state.gen.cc",
- "external/perfetto/protos/perfetto/common/track_event_descriptor.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_common_cpp_gen",
+ srcs: [
+ "protos/perfetto/common/android_energy_consumer_descriptor.proto",
+ "protos/perfetto/common/android_log_constants.proto",
+ "protos/perfetto/common/builtin_clock.proto",
+ "protos/perfetto/common/commit_data_request.proto",
+ "protos/perfetto/common/data_source_descriptor.proto",
+ "protos/perfetto/common/descriptor.proto",
+ "protos/perfetto/common/ftrace_descriptor.proto",
+ "protos/perfetto/common/gpu_counter_descriptor.proto",
+ "protos/perfetto/common/interceptor_descriptor.proto",
+ "protos/perfetto/common/observable_events.proto",
+ "protos/perfetto/common/perf_events.proto",
+ "protos/perfetto/common/sys_stats_counters.proto",
+ "protos/perfetto/common/trace_stats.proto",
+ "protos/perfetto/common/tracing_service_capabilities.proto",
+ "protos/perfetto/common/tracing_service_state.proto",
+ "protos/perfetto/common/track_event_descriptor.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/common/android_energy_consumer_descriptor.gen.cc",
+ "external/perfetto/protos/perfetto/common/android_log_constants.gen.cc",
+ "external/perfetto/protos/perfetto/common/builtin_clock.gen.cc",
+ "external/perfetto/protos/perfetto/common/commit_data_request.gen.cc",
+ "external/perfetto/protos/perfetto/common/data_source_descriptor.gen.cc",
+ "external/perfetto/protos/perfetto/common/descriptor.gen.cc",
+ "external/perfetto/protos/perfetto/common/ftrace_descriptor.gen.cc",
+ "external/perfetto/protos/perfetto/common/gpu_counter_descriptor.gen.cc",
+ "external/perfetto/protos/perfetto/common/interceptor_descriptor.gen.cc",
+ "external/perfetto/protos/perfetto/common/observable_events.gen.cc",
+ "external/perfetto/protos/perfetto/common/perf_events.gen.cc",
+ "external/perfetto/protos/perfetto/common/sys_stats_counters.gen.cc",
+ "external/perfetto/protos/perfetto/common/trace_stats.gen.cc",
+ "external/perfetto/protos/perfetto/common/tracing_service_capabilities.gen.cc",
+ "external/perfetto/protos/perfetto/common/tracing_service_state.gen.cc",
+ "external/perfetto/protos/perfetto/common/track_event_descriptor.gen.cc",
+ ],
}
// GN: //protos/perfetto/common:cpp
genrule {
- name: "perfetto_protos_perfetto_common_cpp_gen_headers",
- srcs: [
- "protos/perfetto/common/android_energy_consumer_descriptor.proto",
- "protos/perfetto/common/android_log_constants.proto",
- "protos/perfetto/common/builtin_clock.proto",
- "protos/perfetto/common/commit_data_request.proto",
- "protos/perfetto/common/data_source_descriptor.proto",
- "protos/perfetto/common/descriptor.proto",
- "protos/perfetto/common/gpu_counter_descriptor.proto",
- "protos/perfetto/common/interceptor_descriptor.proto",
- "protos/perfetto/common/observable_events.proto",
- "protos/perfetto/common/perf_events.proto",
- "protos/perfetto/common/sys_stats_counters.proto",
- "protos/perfetto/common/trace_stats.proto",
- "protos/perfetto/common/tracing_service_capabilities.proto",
- "protos/perfetto/common/tracing_service_state.proto",
- "protos/perfetto/common/track_event_descriptor.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/common/android_energy_consumer_descriptor.gen.h",
- "external/perfetto/protos/perfetto/common/android_log_constants.gen.h",
- "external/perfetto/protos/perfetto/common/builtin_clock.gen.h",
- "external/perfetto/protos/perfetto/common/commit_data_request.gen.h",
- "external/perfetto/protos/perfetto/common/data_source_descriptor.gen.h",
- "external/perfetto/protos/perfetto/common/descriptor.gen.h",
- "external/perfetto/protos/perfetto/common/gpu_counter_descriptor.gen.h",
- "external/perfetto/protos/perfetto/common/interceptor_descriptor.gen.h",
- "external/perfetto/protos/perfetto/common/observable_events.gen.h",
- "external/perfetto/protos/perfetto/common/perf_events.gen.h",
- "external/perfetto/protos/perfetto/common/sys_stats_counters.gen.h",
- "external/perfetto/protos/perfetto/common/trace_stats.gen.h",
- "external/perfetto/protos/perfetto/common/tracing_service_capabilities.gen.h",
- "external/perfetto/protos/perfetto/common/tracing_service_state.gen.h",
- "external/perfetto/protos/perfetto/common/track_event_descriptor.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_common_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/common/android_energy_consumer_descriptor.proto",
+ "protos/perfetto/common/android_log_constants.proto",
+ "protos/perfetto/common/builtin_clock.proto",
+ "protos/perfetto/common/commit_data_request.proto",
+ "protos/perfetto/common/data_source_descriptor.proto",
+ "protos/perfetto/common/descriptor.proto",
+ "protos/perfetto/common/ftrace_descriptor.proto",
+ "protos/perfetto/common/gpu_counter_descriptor.proto",
+ "protos/perfetto/common/interceptor_descriptor.proto",
+ "protos/perfetto/common/observable_events.proto",
+ "protos/perfetto/common/perf_events.proto",
+ "protos/perfetto/common/sys_stats_counters.proto",
+ "protos/perfetto/common/trace_stats.proto",
+ "protos/perfetto/common/tracing_service_capabilities.proto",
+ "protos/perfetto/common/tracing_service_state.proto",
+ "protos/perfetto/common/track_event_descriptor.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/common/android_energy_consumer_descriptor.gen.h",
+ "external/perfetto/protos/perfetto/common/android_log_constants.gen.h",
+ "external/perfetto/protos/perfetto/common/builtin_clock.gen.h",
+ "external/perfetto/protos/perfetto/common/commit_data_request.gen.h",
+ "external/perfetto/protos/perfetto/common/data_source_descriptor.gen.h",
+ "external/perfetto/protos/perfetto/common/descriptor.gen.h",
+ "external/perfetto/protos/perfetto/common/ftrace_descriptor.gen.h",
+ "external/perfetto/protos/perfetto/common/gpu_counter_descriptor.gen.h",
+ "external/perfetto/protos/perfetto/common/interceptor_descriptor.gen.h",
+ "external/perfetto/protos/perfetto/common/observable_events.gen.h",
+ "external/perfetto/protos/perfetto/common/perf_events.gen.h",
+ "external/perfetto/protos/perfetto/common/sys_stats_counters.gen.h",
+ "external/perfetto/protos/perfetto/common/trace_stats.gen.h",
+ "external/perfetto/protos/perfetto/common/tracing_service_capabilities.gen.h",
+ "external/perfetto/protos/perfetto/common/tracing_service_state.gen.h",
+ "external/perfetto/protos/perfetto/common/track_event_descriptor.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/common:lite
genrule {
- name: "perfetto_protos_perfetto_common_lite_gen",
- srcs: [
- "protos/perfetto/common/android_energy_consumer_descriptor.proto",
- "protos/perfetto/common/android_log_constants.proto",
- "protos/perfetto/common/builtin_clock.proto",
- "protos/perfetto/common/commit_data_request.proto",
- "protos/perfetto/common/data_source_descriptor.proto",
- "protos/perfetto/common/descriptor.proto",
- "protos/perfetto/common/gpu_counter_descriptor.proto",
- "protos/perfetto/common/interceptor_descriptor.proto",
- "protos/perfetto/common/observable_events.proto",
- "protos/perfetto/common/perf_events.proto",
- "protos/perfetto/common/sys_stats_counters.proto",
- "protos/perfetto/common/trace_stats.proto",
- "protos/perfetto/common/tracing_service_capabilities.proto",
- "protos/perfetto/common/tracing_service_state.proto",
- "protos/perfetto/common/track_event_descriptor.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/common/android_energy_consumer_descriptor.pb.cc",
- "external/perfetto/protos/perfetto/common/android_log_constants.pb.cc",
- "external/perfetto/protos/perfetto/common/builtin_clock.pb.cc",
- "external/perfetto/protos/perfetto/common/commit_data_request.pb.cc",
- "external/perfetto/protos/perfetto/common/data_source_descriptor.pb.cc",
- "external/perfetto/protos/perfetto/common/descriptor.pb.cc",
- "external/perfetto/protos/perfetto/common/gpu_counter_descriptor.pb.cc",
- "external/perfetto/protos/perfetto/common/interceptor_descriptor.pb.cc",
- "external/perfetto/protos/perfetto/common/observable_events.pb.cc",
- "external/perfetto/protos/perfetto/common/perf_events.pb.cc",
- "external/perfetto/protos/perfetto/common/sys_stats_counters.pb.cc",
- "external/perfetto/protos/perfetto/common/trace_stats.pb.cc",
- "external/perfetto/protos/perfetto/common/tracing_service_capabilities.pb.cc",
- "external/perfetto/protos/perfetto/common/tracing_service_state.pb.cc",
- "external/perfetto/protos/perfetto/common/track_event_descriptor.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_common_lite_gen",
+ srcs: [
+ "protos/perfetto/common/android_energy_consumer_descriptor.proto",
+ "protos/perfetto/common/android_log_constants.proto",
+ "protos/perfetto/common/builtin_clock.proto",
+ "protos/perfetto/common/commit_data_request.proto",
+ "protos/perfetto/common/data_source_descriptor.proto",
+ "protos/perfetto/common/descriptor.proto",
+ "protos/perfetto/common/ftrace_descriptor.proto",
+ "protos/perfetto/common/gpu_counter_descriptor.proto",
+ "protos/perfetto/common/interceptor_descriptor.proto",
+ "protos/perfetto/common/observable_events.proto",
+ "protos/perfetto/common/perf_events.proto",
+ "protos/perfetto/common/sys_stats_counters.proto",
+ "protos/perfetto/common/trace_stats.proto",
+ "protos/perfetto/common/tracing_service_capabilities.proto",
+ "protos/perfetto/common/tracing_service_state.proto",
+ "protos/perfetto/common/track_event_descriptor.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/common/android_energy_consumer_descriptor.pb.cc",
+ "external/perfetto/protos/perfetto/common/android_log_constants.pb.cc",
+ "external/perfetto/protos/perfetto/common/builtin_clock.pb.cc",
+ "external/perfetto/protos/perfetto/common/commit_data_request.pb.cc",
+ "external/perfetto/protos/perfetto/common/data_source_descriptor.pb.cc",
+ "external/perfetto/protos/perfetto/common/descriptor.pb.cc",
+ "external/perfetto/protos/perfetto/common/ftrace_descriptor.pb.cc",
+ "external/perfetto/protos/perfetto/common/gpu_counter_descriptor.pb.cc",
+ "external/perfetto/protos/perfetto/common/interceptor_descriptor.pb.cc",
+ "external/perfetto/protos/perfetto/common/observable_events.pb.cc",
+ "external/perfetto/protos/perfetto/common/perf_events.pb.cc",
+ "external/perfetto/protos/perfetto/common/sys_stats_counters.pb.cc",
+ "external/perfetto/protos/perfetto/common/trace_stats.pb.cc",
+ "external/perfetto/protos/perfetto/common/tracing_service_capabilities.pb.cc",
+ "external/perfetto/protos/perfetto/common/tracing_service_state.pb.cc",
+ "external/perfetto/protos/perfetto/common/track_event_descriptor.pb.cc",
+ ],
}
// GN: //protos/perfetto/common:lite
genrule {
- name: "perfetto_protos_perfetto_common_lite_gen_headers",
- srcs: [
- "protos/perfetto/common/android_energy_consumer_descriptor.proto",
- "protos/perfetto/common/android_log_constants.proto",
- "protos/perfetto/common/builtin_clock.proto",
- "protos/perfetto/common/commit_data_request.proto",
- "protos/perfetto/common/data_source_descriptor.proto",
- "protos/perfetto/common/descriptor.proto",
- "protos/perfetto/common/gpu_counter_descriptor.proto",
- "protos/perfetto/common/interceptor_descriptor.proto",
- "protos/perfetto/common/observable_events.proto",
- "protos/perfetto/common/perf_events.proto",
- "protos/perfetto/common/sys_stats_counters.proto",
- "protos/perfetto/common/trace_stats.proto",
- "protos/perfetto/common/tracing_service_capabilities.proto",
- "protos/perfetto/common/tracing_service_state.proto",
- "protos/perfetto/common/track_event_descriptor.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/common/android_energy_consumer_descriptor.pb.h",
- "external/perfetto/protos/perfetto/common/android_log_constants.pb.h",
- "external/perfetto/protos/perfetto/common/builtin_clock.pb.h",
- "external/perfetto/protos/perfetto/common/commit_data_request.pb.h",
- "external/perfetto/protos/perfetto/common/data_source_descriptor.pb.h",
- "external/perfetto/protos/perfetto/common/descriptor.pb.h",
- "external/perfetto/protos/perfetto/common/gpu_counter_descriptor.pb.h",
- "external/perfetto/protos/perfetto/common/interceptor_descriptor.pb.h",
- "external/perfetto/protos/perfetto/common/observable_events.pb.h",
- "external/perfetto/protos/perfetto/common/perf_events.pb.h",
- "external/perfetto/protos/perfetto/common/sys_stats_counters.pb.h",
- "external/perfetto/protos/perfetto/common/trace_stats.pb.h",
- "external/perfetto/protos/perfetto/common/tracing_service_capabilities.pb.h",
- "external/perfetto/protos/perfetto/common/tracing_service_state.pb.h",
- "external/perfetto/protos/perfetto/common/track_event_descriptor.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_common_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/common/android_energy_consumer_descriptor.proto",
+ "protos/perfetto/common/android_log_constants.proto",
+ "protos/perfetto/common/builtin_clock.proto",
+ "protos/perfetto/common/commit_data_request.proto",
+ "protos/perfetto/common/data_source_descriptor.proto",
+ "protos/perfetto/common/descriptor.proto",
+ "protos/perfetto/common/ftrace_descriptor.proto",
+ "protos/perfetto/common/gpu_counter_descriptor.proto",
+ "protos/perfetto/common/interceptor_descriptor.proto",
+ "protos/perfetto/common/observable_events.proto",
+ "protos/perfetto/common/perf_events.proto",
+ "protos/perfetto/common/sys_stats_counters.proto",
+ "protos/perfetto/common/trace_stats.proto",
+ "protos/perfetto/common/tracing_service_capabilities.proto",
+ "protos/perfetto/common/tracing_service_state.proto",
+ "protos/perfetto/common/track_event_descriptor.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/common/android_energy_consumer_descriptor.pb.h",
+ "external/perfetto/protos/perfetto/common/android_log_constants.pb.h",
+ "external/perfetto/protos/perfetto/common/builtin_clock.pb.h",
+ "external/perfetto/protos/perfetto/common/commit_data_request.pb.h",
+ "external/perfetto/protos/perfetto/common/data_source_descriptor.pb.h",
+ "external/perfetto/protos/perfetto/common/descriptor.pb.h",
+ "external/perfetto/protos/perfetto/common/ftrace_descriptor.pb.h",
+ "external/perfetto/protos/perfetto/common/gpu_counter_descriptor.pb.h",
+ "external/perfetto/protos/perfetto/common/interceptor_descriptor.pb.h",
+ "external/perfetto/protos/perfetto/common/observable_events.pb.h",
+ "external/perfetto/protos/perfetto/common/perf_events.pb.h",
+ "external/perfetto/protos/perfetto/common/sys_stats_counters.pb.h",
+ "external/perfetto/protos/perfetto/common/trace_stats.pb.h",
+ "external/perfetto/protos/perfetto/common/tracing_service_capabilities.pb.h",
+ "external/perfetto/protos/perfetto/common/tracing_service_state.pb.h",
+ "external/perfetto/protos/perfetto/common/track_event_descriptor.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/common:zero
genrule {
- name: "perfetto_protos_perfetto_common_zero_gen",
- srcs: [
- "protos/perfetto/common/android_energy_consumer_descriptor.proto",
- "protos/perfetto/common/android_log_constants.proto",
- "protos/perfetto/common/builtin_clock.proto",
- "protos/perfetto/common/commit_data_request.proto",
- "protos/perfetto/common/data_source_descriptor.proto",
- "protos/perfetto/common/descriptor.proto",
- "protos/perfetto/common/gpu_counter_descriptor.proto",
- "protos/perfetto/common/interceptor_descriptor.proto",
- "protos/perfetto/common/observable_events.proto",
- "protos/perfetto/common/perf_events.proto",
- "protos/perfetto/common/sys_stats_counters.proto",
- "protos/perfetto/common/trace_stats.proto",
- "protos/perfetto/common/tracing_service_capabilities.proto",
- "protos/perfetto/common/tracing_service_state.proto",
- "protos/perfetto/common/track_event_descriptor.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/common/android_energy_consumer_descriptor.pbzero.cc",
- "external/perfetto/protos/perfetto/common/android_log_constants.pbzero.cc",
- "external/perfetto/protos/perfetto/common/builtin_clock.pbzero.cc",
- "external/perfetto/protos/perfetto/common/commit_data_request.pbzero.cc",
- "external/perfetto/protos/perfetto/common/data_source_descriptor.pbzero.cc",
- "external/perfetto/protos/perfetto/common/descriptor.pbzero.cc",
- "external/perfetto/protos/perfetto/common/gpu_counter_descriptor.pbzero.cc",
- "external/perfetto/protos/perfetto/common/interceptor_descriptor.pbzero.cc",
- "external/perfetto/protos/perfetto/common/observable_events.pbzero.cc",
- "external/perfetto/protos/perfetto/common/perf_events.pbzero.cc",
- "external/perfetto/protos/perfetto/common/sys_stats_counters.pbzero.cc",
- "external/perfetto/protos/perfetto/common/trace_stats.pbzero.cc",
- "external/perfetto/protos/perfetto/common/tracing_service_capabilities.pbzero.cc",
- "external/perfetto/protos/perfetto/common/tracing_service_state.pbzero.cc",
- "external/perfetto/protos/perfetto/common/track_event_descriptor.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_common_zero_gen",
+ srcs: [
+ "protos/perfetto/common/android_energy_consumer_descriptor.proto",
+ "protos/perfetto/common/android_log_constants.proto",
+ "protos/perfetto/common/builtin_clock.proto",
+ "protos/perfetto/common/commit_data_request.proto",
+ "protos/perfetto/common/data_source_descriptor.proto",
+ "protos/perfetto/common/descriptor.proto",
+ "protos/perfetto/common/ftrace_descriptor.proto",
+ "protos/perfetto/common/gpu_counter_descriptor.proto",
+ "protos/perfetto/common/interceptor_descriptor.proto",
+ "protos/perfetto/common/observable_events.proto",
+ "protos/perfetto/common/perf_events.proto",
+ "protos/perfetto/common/sys_stats_counters.proto",
+ "protos/perfetto/common/trace_stats.proto",
+ "protos/perfetto/common/tracing_service_capabilities.proto",
+ "protos/perfetto/common/tracing_service_state.proto",
+ "protos/perfetto/common/track_event_descriptor.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/common/android_energy_consumer_descriptor.pbzero.cc",
+ "external/perfetto/protos/perfetto/common/android_log_constants.pbzero.cc",
+ "external/perfetto/protos/perfetto/common/builtin_clock.pbzero.cc",
+ "external/perfetto/protos/perfetto/common/commit_data_request.pbzero.cc",
+ "external/perfetto/protos/perfetto/common/data_source_descriptor.pbzero.cc",
+ "external/perfetto/protos/perfetto/common/descriptor.pbzero.cc",
+ "external/perfetto/protos/perfetto/common/ftrace_descriptor.pbzero.cc",
+ "external/perfetto/protos/perfetto/common/gpu_counter_descriptor.pbzero.cc",
+ "external/perfetto/protos/perfetto/common/interceptor_descriptor.pbzero.cc",
+ "external/perfetto/protos/perfetto/common/observable_events.pbzero.cc",
+ "external/perfetto/protos/perfetto/common/perf_events.pbzero.cc",
+ "external/perfetto/protos/perfetto/common/sys_stats_counters.pbzero.cc",
+ "external/perfetto/protos/perfetto/common/trace_stats.pbzero.cc",
+ "external/perfetto/protos/perfetto/common/tracing_service_capabilities.pbzero.cc",
+ "external/perfetto/protos/perfetto/common/tracing_service_state.pbzero.cc",
+ "external/perfetto/protos/perfetto/common/track_event_descriptor.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/common:zero
genrule {
- name: "perfetto_protos_perfetto_common_zero_gen_headers",
- srcs: [
- "protos/perfetto/common/android_energy_consumer_descriptor.proto",
- "protos/perfetto/common/android_log_constants.proto",
- "protos/perfetto/common/builtin_clock.proto",
- "protos/perfetto/common/commit_data_request.proto",
- "protos/perfetto/common/data_source_descriptor.proto",
- "protos/perfetto/common/descriptor.proto",
- "protos/perfetto/common/gpu_counter_descriptor.proto",
- "protos/perfetto/common/interceptor_descriptor.proto",
- "protos/perfetto/common/observable_events.proto",
- "protos/perfetto/common/perf_events.proto",
- "protos/perfetto/common/sys_stats_counters.proto",
- "protos/perfetto/common/trace_stats.proto",
- "protos/perfetto/common/tracing_service_capabilities.proto",
- "protos/perfetto/common/tracing_service_state.proto",
- "protos/perfetto/common/track_event_descriptor.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/common/android_energy_consumer_descriptor.pbzero.h",
- "external/perfetto/protos/perfetto/common/android_log_constants.pbzero.h",
- "external/perfetto/protos/perfetto/common/builtin_clock.pbzero.h",
- "external/perfetto/protos/perfetto/common/commit_data_request.pbzero.h",
- "external/perfetto/protos/perfetto/common/data_source_descriptor.pbzero.h",
- "external/perfetto/protos/perfetto/common/descriptor.pbzero.h",
- "external/perfetto/protos/perfetto/common/gpu_counter_descriptor.pbzero.h",
- "external/perfetto/protos/perfetto/common/interceptor_descriptor.pbzero.h",
- "external/perfetto/protos/perfetto/common/observable_events.pbzero.h",
- "external/perfetto/protos/perfetto/common/perf_events.pbzero.h",
- "external/perfetto/protos/perfetto/common/sys_stats_counters.pbzero.h",
- "external/perfetto/protos/perfetto/common/trace_stats.pbzero.h",
- "external/perfetto/protos/perfetto/common/tracing_service_capabilities.pbzero.h",
- "external/perfetto/protos/perfetto/common/tracing_service_state.pbzero.h",
- "external/perfetto/protos/perfetto/common/track_event_descriptor.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_common_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/common/android_energy_consumer_descriptor.proto",
+ "protos/perfetto/common/android_log_constants.proto",
+ "protos/perfetto/common/builtin_clock.proto",
+ "protos/perfetto/common/commit_data_request.proto",
+ "protos/perfetto/common/data_source_descriptor.proto",
+ "protos/perfetto/common/descriptor.proto",
+ "protos/perfetto/common/ftrace_descriptor.proto",
+ "protos/perfetto/common/gpu_counter_descriptor.proto",
+ "protos/perfetto/common/interceptor_descriptor.proto",
+ "protos/perfetto/common/observable_events.proto",
+ "protos/perfetto/common/perf_events.proto",
+ "protos/perfetto/common/sys_stats_counters.proto",
+ "protos/perfetto/common/trace_stats.proto",
+ "protos/perfetto/common/tracing_service_capabilities.proto",
+ "protos/perfetto/common/tracing_service_state.proto",
+ "protos/perfetto/common/track_event_descriptor.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/common/android_energy_consumer_descriptor.pbzero.h",
+ "external/perfetto/protos/perfetto/common/android_log_constants.pbzero.h",
+ "external/perfetto/protos/perfetto/common/builtin_clock.pbzero.h",
+ "external/perfetto/protos/perfetto/common/commit_data_request.pbzero.h",
+ "external/perfetto/protos/perfetto/common/data_source_descriptor.pbzero.h",
+ "external/perfetto/protos/perfetto/common/descriptor.pbzero.h",
+ "external/perfetto/protos/perfetto/common/ftrace_descriptor.pbzero.h",
+ "external/perfetto/protos/perfetto/common/gpu_counter_descriptor.pbzero.h",
+ "external/perfetto/protos/perfetto/common/interceptor_descriptor.pbzero.h",
+ "external/perfetto/protos/perfetto/common/observable_events.pbzero.h",
+ "external/perfetto/protos/perfetto/common/perf_events.pbzero.h",
+ "external/perfetto/protos/perfetto/common/sys_stats_counters.pbzero.h",
+ "external/perfetto/protos/perfetto/common/trace_stats.pbzero.h",
+ "external/perfetto/protos/perfetto/common/tracing_service_capabilities.pbzero.h",
+ "external/perfetto/protos/perfetto/common/tracing_service_state.pbzero.h",
+ "external/perfetto/protos/perfetto/common/track_event_descriptor.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/android:cpp
genrule {
- name: "perfetto_protos_perfetto_config_android_cpp_gen",
- srcs: [
- "protos/perfetto/config/android/android_log_config.proto",
- "protos/perfetto/config/android/android_polled_state_config.proto",
- "protos/perfetto/config/android/packages_list_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/android/android_log_config.gen.cc",
- "external/perfetto/protos/perfetto/config/android/android_polled_state_config.gen.cc",
- "external/perfetto/protos/perfetto/config/android/packages_list_config.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_config_android_cpp_gen",
+ srcs: [
+ "protos/perfetto/config/android/android_log_config.proto",
+ "protos/perfetto/config/android/android_polled_state_config.proto",
+ "protos/perfetto/config/android/packages_list_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/android/android_log_config.gen.cc",
+ "external/perfetto/protos/perfetto/config/android/android_polled_state_config.gen.cc",
+ "external/perfetto/protos/perfetto/config/android/packages_list_config.gen.cc",
+ ],
}
// GN: //protos/perfetto/config/android:cpp
genrule {
- name: "perfetto_protos_perfetto_config_android_cpp_gen_headers",
- srcs: [
- "protos/perfetto/config/android/android_log_config.proto",
- "protos/perfetto/config/android/android_polled_state_config.proto",
- "protos/perfetto/config/android/packages_list_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/android/android_log_config.gen.h",
- "external/perfetto/protos/perfetto/config/android/android_polled_state_config.gen.h",
- "external/perfetto/protos/perfetto/config/android/packages_list_config.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_android_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/config/android/android_log_config.proto",
+ "protos/perfetto/config/android/android_polled_state_config.proto",
+ "protos/perfetto/config/android/packages_list_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/android/android_log_config.gen.h",
+ "external/perfetto/protos/perfetto/config/android/android_polled_state_config.gen.h",
+ "external/perfetto/protos/perfetto/config/android/packages_list_config.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/android:lite
genrule {
- name: "perfetto_protos_perfetto_config_android_lite_gen",
- srcs: [
- "protos/perfetto/config/android/android_log_config.proto",
- "protos/perfetto/config/android/android_polled_state_config.proto",
- "protos/perfetto/config/android/packages_list_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/android/android_log_config.pb.cc",
- "external/perfetto/protos/perfetto/config/android/android_polled_state_config.pb.cc",
- "external/perfetto/protos/perfetto/config/android/packages_list_config.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_config_android_lite_gen",
+ srcs: [
+ "protos/perfetto/config/android/android_log_config.proto",
+ "protos/perfetto/config/android/android_polled_state_config.proto",
+ "protos/perfetto/config/android/packages_list_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/android/android_log_config.pb.cc",
+ "external/perfetto/protos/perfetto/config/android/android_polled_state_config.pb.cc",
+ "external/perfetto/protos/perfetto/config/android/packages_list_config.pb.cc",
+ ],
}
// GN: //protos/perfetto/config/android:lite
genrule {
- name: "perfetto_protos_perfetto_config_android_lite_gen_headers",
- srcs: [
- "protos/perfetto/config/android/android_log_config.proto",
- "protos/perfetto/config/android/android_polled_state_config.proto",
- "protos/perfetto/config/android/packages_list_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/android/android_log_config.pb.h",
- "external/perfetto/protos/perfetto/config/android/android_polled_state_config.pb.h",
- "external/perfetto/protos/perfetto/config/android/packages_list_config.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_android_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/config/android/android_log_config.proto",
+ "protos/perfetto/config/android/android_polled_state_config.proto",
+ "protos/perfetto/config/android/packages_list_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/android/android_log_config.pb.h",
+ "external/perfetto/protos/perfetto/config/android/android_polled_state_config.pb.h",
+ "external/perfetto/protos/perfetto/config/android/packages_list_config.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/android:zero
genrule {
- name: "perfetto_protos_perfetto_config_android_zero_gen",
- srcs: [
- "protos/perfetto/config/android/android_log_config.proto",
- "protos/perfetto/config/android/android_polled_state_config.proto",
- "protos/perfetto/config/android/packages_list_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/android/android_log_config.pbzero.cc",
- "external/perfetto/protos/perfetto/config/android/android_polled_state_config.pbzero.cc",
- "external/perfetto/protos/perfetto/config/android/packages_list_config.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_config_android_zero_gen",
+ srcs: [
+ "protos/perfetto/config/android/android_log_config.proto",
+ "protos/perfetto/config/android/android_polled_state_config.proto",
+ "protos/perfetto/config/android/packages_list_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/android/android_log_config.pbzero.cc",
+ "external/perfetto/protos/perfetto/config/android/android_polled_state_config.pbzero.cc",
+ "external/perfetto/protos/perfetto/config/android/packages_list_config.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/config/android:zero
genrule {
- name: "perfetto_protos_perfetto_config_android_zero_gen_headers",
- srcs: [
- "protos/perfetto/config/android/android_log_config.proto",
- "protos/perfetto/config/android/android_polled_state_config.proto",
- "protos/perfetto/config/android/packages_list_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/android/android_log_config.pbzero.h",
- "external/perfetto/protos/perfetto/config/android/android_polled_state_config.pbzero.h",
- "external/perfetto/protos/perfetto/config/android/packages_list_config.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_android_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/config/android/android_log_config.proto",
+ "protos/perfetto/config/android/android_polled_state_config.proto",
+ "protos/perfetto/config/android/packages_list_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/android/android_log_config.pbzero.h",
+ "external/perfetto/protos/perfetto/config/android/android_polled_state_config.pbzero.h",
+ "external/perfetto/protos/perfetto/config/android/packages_list_config.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config:cpp
genrule {
- name: "perfetto_protos_perfetto_config_cpp_gen",
- srcs: [
- "protos/perfetto/config/chrome/chrome_config.proto",
- "protos/perfetto/config/data_source_config.proto",
- "protos/perfetto/config/interceptor_config.proto",
- "protos/perfetto/config/stress_test_config.proto",
- "protos/perfetto/config/test_config.proto",
- "protos/perfetto/config/trace_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/chrome/chrome_config.gen.cc",
- "external/perfetto/protos/perfetto/config/data_source_config.gen.cc",
- "external/perfetto/protos/perfetto/config/interceptor_config.gen.cc",
- "external/perfetto/protos/perfetto/config/stress_test_config.gen.cc",
- "external/perfetto/protos/perfetto/config/test_config.gen.cc",
- "external/perfetto/protos/perfetto/config/trace_config.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_config_cpp_gen",
+ srcs: [
+ "protos/perfetto/config/chrome/chrome_config.proto",
+ "protos/perfetto/config/data_source_config.proto",
+ "protos/perfetto/config/interceptor_config.proto",
+ "protos/perfetto/config/stress_test_config.proto",
+ "protos/perfetto/config/test_config.proto",
+ "protos/perfetto/config/trace_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/chrome/chrome_config.gen.cc",
+ "external/perfetto/protos/perfetto/config/data_source_config.gen.cc",
+ "external/perfetto/protos/perfetto/config/interceptor_config.gen.cc",
+ "external/perfetto/protos/perfetto/config/stress_test_config.gen.cc",
+ "external/perfetto/protos/perfetto/config/test_config.gen.cc",
+ "external/perfetto/protos/perfetto/config/trace_config.gen.cc",
+ ],
}
// GN: //protos/perfetto/config:cpp
genrule {
- name: "perfetto_protos_perfetto_config_cpp_gen_headers",
- srcs: [
- "protos/perfetto/config/chrome/chrome_config.proto",
- "protos/perfetto/config/data_source_config.proto",
- "protos/perfetto/config/interceptor_config.proto",
- "protos/perfetto/config/stress_test_config.proto",
- "protos/perfetto/config/test_config.proto",
- "protos/perfetto/config/trace_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/chrome/chrome_config.gen.h",
- "external/perfetto/protos/perfetto/config/data_source_config.gen.h",
- "external/perfetto/protos/perfetto/config/interceptor_config.gen.h",
- "external/perfetto/protos/perfetto/config/stress_test_config.gen.h",
- "external/perfetto/protos/perfetto/config/test_config.gen.h",
- "external/perfetto/protos/perfetto/config/trace_config.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/config/chrome/chrome_config.proto",
+ "protos/perfetto/config/data_source_config.proto",
+ "protos/perfetto/config/interceptor_config.proto",
+ "protos/perfetto/config/stress_test_config.proto",
+ "protos/perfetto/config/test_config.proto",
+ "protos/perfetto/config/trace_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/chrome/chrome_config.gen.h",
+ "external/perfetto/protos/perfetto/config/data_source_config.gen.h",
+ "external/perfetto/protos/perfetto/config/interceptor_config.gen.h",
+ "external/perfetto/protos/perfetto/config/stress_test_config.gen.h",
+ "external/perfetto/protos/perfetto/config/test_config.gen.h",
+ "external/perfetto/protos/perfetto/config/trace_config.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config:descriptor
genrule {
- name: "perfetto_protos_perfetto_config_descriptor",
- srcs: [
- "protos/perfetto/common/android_energy_consumer_descriptor.proto",
- "protos/perfetto/common/android_log_constants.proto",
- "protos/perfetto/common/builtin_clock.proto",
- "protos/perfetto/common/commit_data_request.proto",
- "protos/perfetto/common/data_source_descriptor.proto",
- "protos/perfetto/common/descriptor.proto",
- "protos/perfetto/common/gpu_counter_descriptor.proto",
- "protos/perfetto/common/interceptor_descriptor.proto",
- "protos/perfetto/common/observable_events.proto",
- "protos/perfetto/common/perf_events.proto",
- "protos/perfetto/common/sys_stats_counters.proto",
- "protos/perfetto/common/trace_stats.proto",
- "protos/perfetto/common/tracing_service_capabilities.proto",
- "protos/perfetto/common/tracing_service_state.proto",
- "protos/perfetto/common/track_event_descriptor.proto",
- "protos/perfetto/config/android/android_log_config.proto",
- "protos/perfetto/config/android/android_polled_state_config.proto",
- "protos/perfetto/config/android/packages_list_config.proto",
- "protos/perfetto/config/chrome/chrome_config.proto",
- "protos/perfetto/config/data_source_config.proto",
- "protos/perfetto/config/ftrace/ftrace_config.proto",
- "protos/perfetto/config/gpu/gpu_counter_config.proto",
- "protos/perfetto/config/gpu/vulkan_memory_config.proto",
- "protos/perfetto/config/inode_file/inode_file_config.proto",
- "protos/perfetto/config/interceptor_config.proto",
- "protos/perfetto/config/interceptors/console_config.proto",
- "protos/perfetto/config/power/android_power_config.proto",
- "protos/perfetto/config/process_stats/process_stats_config.proto",
- "protos/perfetto/config/profiling/heapprofd_config.proto",
- "protos/perfetto/config/profiling/java_hprof_config.proto",
- "protos/perfetto/config/profiling/perf_event_config.proto",
- "protos/perfetto/config/stress_test_config.proto",
- "protos/perfetto/config/sys_stats/sys_stats_config.proto",
- "protos/perfetto/config/test_config.proto",
- "protos/perfetto/config/trace_config.proto",
- "protos/perfetto/config/track_event/track_event_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --descriptor_set_out=$(out) $(in)",
- out: [
- "perfetto_protos_perfetto_config_descriptor.bin",
- ],
+ name: "perfetto_protos_perfetto_config_descriptor",
+ srcs: [
+ "protos/perfetto/common/android_energy_consumer_descriptor.proto",
+ "protos/perfetto/common/android_log_constants.proto",
+ "protos/perfetto/common/builtin_clock.proto",
+ "protos/perfetto/common/commit_data_request.proto",
+ "protos/perfetto/common/data_source_descriptor.proto",
+ "protos/perfetto/common/descriptor.proto",
+ "protos/perfetto/common/ftrace_descriptor.proto",
+ "protos/perfetto/common/gpu_counter_descriptor.proto",
+ "protos/perfetto/common/interceptor_descriptor.proto",
+ "protos/perfetto/common/observable_events.proto",
+ "protos/perfetto/common/perf_events.proto",
+ "protos/perfetto/common/sys_stats_counters.proto",
+ "protos/perfetto/common/trace_stats.proto",
+ "protos/perfetto/common/tracing_service_capabilities.proto",
+ "protos/perfetto/common/tracing_service_state.proto",
+ "protos/perfetto/common/track_event_descriptor.proto",
+ "protos/perfetto/config/android/android_log_config.proto",
+ "protos/perfetto/config/android/android_polled_state_config.proto",
+ "protos/perfetto/config/android/packages_list_config.proto",
+ "protos/perfetto/config/chrome/chrome_config.proto",
+ "protos/perfetto/config/data_source_config.proto",
+ "protos/perfetto/config/ftrace/ftrace_config.proto",
+ "protos/perfetto/config/gpu/gpu_counter_config.proto",
+ "protos/perfetto/config/gpu/vulkan_memory_config.proto",
+ "protos/perfetto/config/inode_file/inode_file_config.proto",
+ "protos/perfetto/config/interceptor_config.proto",
+ "protos/perfetto/config/interceptors/console_config.proto",
+ "protos/perfetto/config/power/android_power_config.proto",
+ "protos/perfetto/config/process_stats/process_stats_config.proto",
+ "protos/perfetto/config/profiling/heapprofd_config.proto",
+ "protos/perfetto/config/profiling/java_hprof_config.proto",
+ "protos/perfetto/config/profiling/perf_event_config.proto",
+ "protos/perfetto/config/stress_test_config.proto",
+ "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+ "protos/perfetto/config/test_config.proto",
+ "protos/perfetto/config/trace_config.proto",
+ "protos/perfetto/config/track_event/track_event_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --descriptor_set_out=$(out) $(in)",
+ out: [
+ "perfetto_protos_perfetto_config_descriptor.bin",
+ ],
}
// GN: //protos/perfetto/config/ftrace:cpp
genrule {
- name: "perfetto_protos_perfetto_config_ftrace_cpp_gen",
- srcs: [
- "protos/perfetto/config/ftrace/ftrace_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/ftrace/ftrace_config.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_config_ftrace_cpp_gen",
+ srcs: [
+ "protos/perfetto/config/ftrace/ftrace_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/ftrace/ftrace_config.gen.cc",
+ ],
}
// GN: //protos/perfetto/config/ftrace:cpp
genrule {
- name: "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
- srcs: [
- "protos/perfetto/config/ftrace/ftrace_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/ftrace/ftrace_config.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/config/ftrace/ftrace_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/ftrace/ftrace_config.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/ftrace:lite
genrule {
- name: "perfetto_protos_perfetto_config_ftrace_lite_gen",
- srcs: [
- "protos/perfetto/config/ftrace/ftrace_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/ftrace/ftrace_config.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_config_ftrace_lite_gen",
+ srcs: [
+ "protos/perfetto/config/ftrace/ftrace_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/ftrace/ftrace_config.pb.cc",
+ ],
}
// GN: //protos/perfetto/config/ftrace:lite
genrule {
- name: "perfetto_protos_perfetto_config_ftrace_lite_gen_headers",
- srcs: [
- "protos/perfetto/config/ftrace/ftrace_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/ftrace/ftrace_config.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_ftrace_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/config/ftrace/ftrace_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/ftrace/ftrace_config.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/ftrace:zero
genrule {
- name: "perfetto_protos_perfetto_config_ftrace_zero_gen",
- srcs: [
- "protos/perfetto/config/ftrace/ftrace_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/ftrace/ftrace_config.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_config_ftrace_zero_gen",
+ srcs: [
+ "protos/perfetto/config/ftrace/ftrace_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/ftrace/ftrace_config.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/config/ftrace:zero
genrule {
- name: "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
- srcs: [
- "protos/perfetto/config/ftrace/ftrace_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/ftrace/ftrace_config.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/config/ftrace/ftrace_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/ftrace/ftrace_config.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/gpu:cpp
genrule {
- name: "perfetto_protos_perfetto_config_gpu_cpp_gen",
- srcs: [
- "protos/perfetto/config/gpu/gpu_counter_config.proto",
- "protos/perfetto/config/gpu/vulkan_memory_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/gpu/gpu_counter_config.gen.cc",
- "external/perfetto/protos/perfetto/config/gpu/vulkan_memory_config.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_config_gpu_cpp_gen",
+ srcs: [
+ "protos/perfetto/config/gpu/gpu_counter_config.proto",
+ "protos/perfetto/config/gpu/vulkan_memory_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/gpu/gpu_counter_config.gen.cc",
+ "external/perfetto/protos/perfetto/config/gpu/vulkan_memory_config.gen.cc",
+ ],
}
// GN: //protos/perfetto/config/gpu:cpp
genrule {
- name: "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
- srcs: [
- "protos/perfetto/config/gpu/gpu_counter_config.proto",
- "protos/perfetto/config/gpu/vulkan_memory_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/gpu/gpu_counter_config.gen.h",
- "external/perfetto/protos/perfetto/config/gpu/vulkan_memory_config.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/config/gpu/gpu_counter_config.proto",
+ "protos/perfetto/config/gpu/vulkan_memory_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/gpu/gpu_counter_config.gen.h",
+ "external/perfetto/protos/perfetto/config/gpu/vulkan_memory_config.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/gpu:lite
genrule {
- name: "perfetto_protos_perfetto_config_gpu_lite_gen",
- srcs: [
- "protos/perfetto/config/gpu/gpu_counter_config.proto",
- "protos/perfetto/config/gpu/vulkan_memory_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/gpu/gpu_counter_config.pb.cc",
- "external/perfetto/protos/perfetto/config/gpu/vulkan_memory_config.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_config_gpu_lite_gen",
+ srcs: [
+ "protos/perfetto/config/gpu/gpu_counter_config.proto",
+ "protos/perfetto/config/gpu/vulkan_memory_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/gpu/gpu_counter_config.pb.cc",
+ "external/perfetto/protos/perfetto/config/gpu/vulkan_memory_config.pb.cc",
+ ],
}
// GN: //protos/perfetto/config/gpu:lite
genrule {
- name: "perfetto_protos_perfetto_config_gpu_lite_gen_headers",
- srcs: [
- "protos/perfetto/config/gpu/gpu_counter_config.proto",
- "protos/perfetto/config/gpu/vulkan_memory_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/gpu/gpu_counter_config.pb.h",
- "external/perfetto/protos/perfetto/config/gpu/vulkan_memory_config.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_gpu_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/config/gpu/gpu_counter_config.proto",
+ "protos/perfetto/config/gpu/vulkan_memory_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/gpu/gpu_counter_config.pb.h",
+ "external/perfetto/protos/perfetto/config/gpu/vulkan_memory_config.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/gpu:zero
genrule {
- name: "perfetto_protos_perfetto_config_gpu_zero_gen",
- srcs: [
- "protos/perfetto/config/gpu/gpu_counter_config.proto",
- "protos/perfetto/config/gpu/vulkan_memory_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/gpu/gpu_counter_config.pbzero.cc",
- "external/perfetto/protos/perfetto/config/gpu/vulkan_memory_config.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_config_gpu_zero_gen",
+ srcs: [
+ "protos/perfetto/config/gpu/gpu_counter_config.proto",
+ "protos/perfetto/config/gpu/vulkan_memory_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/gpu/gpu_counter_config.pbzero.cc",
+ "external/perfetto/protos/perfetto/config/gpu/vulkan_memory_config.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/config/gpu:zero
genrule {
- name: "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
- srcs: [
- "protos/perfetto/config/gpu/gpu_counter_config.proto",
- "protos/perfetto/config/gpu/vulkan_memory_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/gpu/gpu_counter_config.pbzero.h",
- "external/perfetto/protos/perfetto/config/gpu/vulkan_memory_config.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/config/gpu/gpu_counter_config.proto",
+ "protos/perfetto/config/gpu/vulkan_memory_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/gpu/gpu_counter_config.pbzero.h",
+ "external/perfetto/protos/perfetto/config/gpu/vulkan_memory_config.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/inode_file:cpp
genrule {
- name: "perfetto_protos_perfetto_config_inode_file_cpp_gen",
- srcs: [
- "protos/perfetto/config/inode_file/inode_file_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/inode_file/inode_file_config.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_config_inode_file_cpp_gen",
+ srcs: [
+ "protos/perfetto/config/inode_file/inode_file_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/inode_file/inode_file_config.gen.cc",
+ ],
}
// GN: //protos/perfetto/config/inode_file:cpp
genrule {
- name: "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
- srcs: [
- "protos/perfetto/config/inode_file/inode_file_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/inode_file/inode_file_config.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/config/inode_file/inode_file_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/inode_file/inode_file_config.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/inode_file:lite
genrule {
- name: "perfetto_protos_perfetto_config_inode_file_lite_gen",
- srcs: [
- "protos/perfetto/config/inode_file/inode_file_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/inode_file/inode_file_config.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_config_inode_file_lite_gen",
+ srcs: [
+ "protos/perfetto/config/inode_file/inode_file_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/inode_file/inode_file_config.pb.cc",
+ ],
}
// GN: //protos/perfetto/config/inode_file:lite
genrule {
- name: "perfetto_protos_perfetto_config_inode_file_lite_gen_headers",
- srcs: [
- "protos/perfetto/config/inode_file/inode_file_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/inode_file/inode_file_config.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_inode_file_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/config/inode_file/inode_file_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/inode_file/inode_file_config.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/inode_file:zero
genrule {
- name: "perfetto_protos_perfetto_config_inode_file_zero_gen",
- srcs: [
- "protos/perfetto/config/inode_file/inode_file_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/inode_file/inode_file_config.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_config_inode_file_zero_gen",
+ srcs: [
+ "protos/perfetto/config/inode_file/inode_file_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/inode_file/inode_file_config.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/config/inode_file:zero
genrule {
- name: "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
- srcs: [
- "protos/perfetto/config/inode_file/inode_file_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/inode_file/inode_file_config.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/config/inode_file/inode_file_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/inode_file/inode_file_config.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/interceptors:cpp
genrule {
- name: "perfetto_protos_perfetto_config_interceptors_cpp_gen",
- srcs: [
- "protos/perfetto/config/interceptors/console_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/interceptors/console_config.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_config_interceptors_cpp_gen",
+ srcs: [
+ "protos/perfetto/config/interceptors/console_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/interceptors/console_config.gen.cc",
+ ],
}
// GN: //protos/perfetto/config/interceptors:cpp
genrule {
- name: "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
- srcs: [
- "protos/perfetto/config/interceptors/console_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/interceptors/console_config.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/config/interceptors/console_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/interceptors/console_config.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/interceptors:lite
genrule {
- name: "perfetto_protos_perfetto_config_interceptors_lite_gen",
- srcs: [
- "protos/perfetto/config/interceptors/console_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/interceptors/console_config.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_config_interceptors_lite_gen",
+ srcs: [
+ "protos/perfetto/config/interceptors/console_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/interceptors/console_config.pb.cc",
+ ],
}
// GN: //protos/perfetto/config/interceptors:lite
genrule {
- name: "perfetto_protos_perfetto_config_interceptors_lite_gen_headers",
- srcs: [
- "protos/perfetto/config/interceptors/console_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/interceptors/console_config.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_interceptors_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/config/interceptors/console_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/interceptors/console_config.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/interceptors:zero
genrule {
- name: "perfetto_protos_perfetto_config_interceptors_zero_gen",
- srcs: [
- "protos/perfetto/config/interceptors/console_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/interceptors/console_config.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_config_interceptors_zero_gen",
+ srcs: [
+ "protos/perfetto/config/interceptors/console_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/interceptors/console_config.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/config/interceptors:zero
genrule {
- name: "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
- srcs: [
- "protos/perfetto/config/interceptors/console_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/interceptors/console_config.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/config/interceptors/console_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/interceptors/console_config.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config:lite
genrule {
- name: "perfetto_protos_perfetto_config_lite_gen",
- srcs: [
- "protos/perfetto/config/chrome/chrome_config.proto",
- "protos/perfetto/config/data_source_config.proto",
- "protos/perfetto/config/interceptor_config.proto",
- "protos/perfetto/config/stress_test_config.proto",
- "protos/perfetto/config/test_config.proto",
- "protos/perfetto/config/trace_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/chrome/chrome_config.pb.cc",
- "external/perfetto/protos/perfetto/config/data_source_config.pb.cc",
- "external/perfetto/protos/perfetto/config/interceptor_config.pb.cc",
- "external/perfetto/protos/perfetto/config/stress_test_config.pb.cc",
- "external/perfetto/protos/perfetto/config/test_config.pb.cc",
- "external/perfetto/protos/perfetto/config/trace_config.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_config_lite_gen",
+ srcs: [
+ "protos/perfetto/config/chrome/chrome_config.proto",
+ "protos/perfetto/config/data_source_config.proto",
+ "protos/perfetto/config/interceptor_config.proto",
+ "protos/perfetto/config/stress_test_config.proto",
+ "protos/perfetto/config/test_config.proto",
+ "protos/perfetto/config/trace_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/chrome/chrome_config.pb.cc",
+ "external/perfetto/protos/perfetto/config/data_source_config.pb.cc",
+ "external/perfetto/protos/perfetto/config/interceptor_config.pb.cc",
+ "external/perfetto/protos/perfetto/config/stress_test_config.pb.cc",
+ "external/perfetto/protos/perfetto/config/test_config.pb.cc",
+ "external/perfetto/protos/perfetto/config/trace_config.pb.cc",
+ ],
}
// GN: //protos/perfetto/config:lite
genrule {
- name: "perfetto_protos_perfetto_config_lite_gen_headers",
- srcs: [
- "protos/perfetto/config/chrome/chrome_config.proto",
- "protos/perfetto/config/data_source_config.proto",
- "protos/perfetto/config/interceptor_config.proto",
- "protos/perfetto/config/stress_test_config.proto",
- "protos/perfetto/config/test_config.proto",
- "protos/perfetto/config/trace_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/chrome/chrome_config.pb.h",
- "external/perfetto/protos/perfetto/config/data_source_config.pb.h",
- "external/perfetto/protos/perfetto/config/interceptor_config.pb.h",
- "external/perfetto/protos/perfetto/config/stress_test_config.pb.h",
- "external/perfetto/protos/perfetto/config/test_config.pb.h",
- "external/perfetto/protos/perfetto/config/trace_config.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
-}
-
-// GN: //protos/perfetto/config:perfetto_config_descriptor
-genrule {
- name: "perfetto_protos_perfetto_config_perfetto_config_descriptor",
- srcs: [
- "protos/perfetto/config/perfetto_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --descriptor_set_out=$(out) $(in)",
- out: [
- "perfetto_protos_perfetto_config_perfetto_config_descriptor.bin",
- ],
+ name: "perfetto_protos_perfetto_config_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/config/chrome/chrome_config.proto",
+ "protos/perfetto/config/data_source_config.proto",
+ "protos/perfetto/config/interceptor_config.proto",
+ "protos/perfetto/config/stress_test_config.proto",
+ "protos/perfetto/config/test_config.proto",
+ "protos/perfetto/config/trace_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/chrome/chrome_config.pb.h",
+ "external/perfetto/protos/perfetto/config/data_source_config.pb.h",
+ "external/perfetto/protos/perfetto/config/interceptor_config.pb.h",
+ "external/perfetto/protos/perfetto/config/stress_test_config.pb.h",
+ "external/perfetto/protos/perfetto/config/test_config.pb.h",
+ "external/perfetto/protos/perfetto/config/trace_config.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/power:cpp
genrule {
- name: "perfetto_protos_perfetto_config_power_cpp_gen",
- srcs: [
- "protos/perfetto/config/power/android_power_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/power/android_power_config.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_config_power_cpp_gen",
+ srcs: [
+ "protos/perfetto/config/power/android_power_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/power/android_power_config.gen.cc",
+ ],
}
// GN: //protos/perfetto/config/power:cpp
genrule {
- name: "perfetto_protos_perfetto_config_power_cpp_gen_headers",
- srcs: [
- "protos/perfetto/config/power/android_power_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/power/android_power_config.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_power_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/config/power/android_power_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/power/android_power_config.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/power:lite
genrule {
- name: "perfetto_protos_perfetto_config_power_lite_gen",
- srcs: [
- "protos/perfetto/config/power/android_power_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/power/android_power_config.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_config_power_lite_gen",
+ srcs: [
+ "protos/perfetto/config/power/android_power_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/power/android_power_config.pb.cc",
+ ],
}
// GN: //protos/perfetto/config/power:lite
genrule {
- name: "perfetto_protos_perfetto_config_power_lite_gen_headers",
- srcs: [
- "protos/perfetto/config/power/android_power_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/power/android_power_config.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_power_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/config/power/android_power_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/power/android_power_config.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/power:zero
genrule {
- name: "perfetto_protos_perfetto_config_power_zero_gen",
- srcs: [
- "protos/perfetto/config/power/android_power_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/power/android_power_config.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_config_power_zero_gen",
+ srcs: [
+ "protos/perfetto/config/power/android_power_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/power/android_power_config.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/config/power:zero
genrule {
- name: "perfetto_protos_perfetto_config_power_zero_gen_headers",
- srcs: [
- "protos/perfetto/config/power/android_power_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/power/android_power_config.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_power_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/config/power/android_power_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/power/android_power_config.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/process_stats:cpp
genrule {
- name: "perfetto_protos_perfetto_config_process_stats_cpp_gen",
- srcs: [
- "protos/perfetto/config/process_stats/process_stats_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/process_stats/process_stats_config.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_config_process_stats_cpp_gen",
+ srcs: [
+ "protos/perfetto/config/process_stats/process_stats_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/process_stats/process_stats_config.gen.cc",
+ ],
}
// GN: //protos/perfetto/config/process_stats:cpp
genrule {
- name: "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
- srcs: [
- "protos/perfetto/config/process_stats/process_stats_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/process_stats/process_stats_config.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/config/process_stats/process_stats_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/process_stats/process_stats_config.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/process_stats:lite
genrule {
- name: "perfetto_protos_perfetto_config_process_stats_lite_gen",
- srcs: [
- "protos/perfetto/config/process_stats/process_stats_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/process_stats/process_stats_config.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_config_process_stats_lite_gen",
+ srcs: [
+ "protos/perfetto/config/process_stats/process_stats_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/process_stats/process_stats_config.pb.cc",
+ ],
}
// GN: //protos/perfetto/config/process_stats:lite
genrule {
- name: "perfetto_protos_perfetto_config_process_stats_lite_gen_headers",
- srcs: [
- "protos/perfetto/config/process_stats/process_stats_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/process_stats/process_stats_config.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_process_stats_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/config/process_stats/process_stats_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/process_stats/process_stats_config.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/process_stats:zero
genrule {
- name: "perfetto_protos_perfetto_config_process_stats_zero_gen",
- srcs: [
- "protos/perfetto/config/process_stats/process_stats_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/process_stats/process_stats_config.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_config_process_stats_zero_gen",
+ srcs: [
+ "protos/perfetto/config/process_stats/process_stats_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/process_stats/process_stats_config.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/config/process_stats:zero
genrule {
- name: "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
- srcs: [
- "protos/perfetto/config/process_stats/process_stats_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/process_stats/process_stats_config.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/config/process_stats/process_stats_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/process_stats/process_stats_config.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/profiling:cpp
genrule {
- name: "perfetto_protos_perfetto_config_profiling_cpp_gen",
- srcs: [
- "protos/perfetto/config/profiling/heapprofd_config.proto",
- "protos/perfetto/config/profiling/java_hprof_config.proto",
- "protos/perfetto/config/profiling/perf_event_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/profiling/heapprofd_config.gen.cc",
- "external/perfetto/protos/perfetto/config/profiling/java_hprof_config.gen.cc",
- "external/perfetto/protos/perfetto/config/profiling/perf_event_config.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_config_profiling_cpp_gen",
+ srcs: [
+ "protos/perfetto/config/profiling/heapprofd_config.proto",
+ "protos/perfetto/config/profiling/java_hprof_config.proto",
+ "protos/perfetto/config/profiling/perf_event_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/profiling/heapprofd_config.gen.cc",
+ "external/perfetto/protos/perfetto/config/profiling/java_hprof_config.gen.cc",
+ "external/perfetto/protos/perfetto/config/profiling/perf_event_config.gen.cc",
+ ],
}
// GN: //protos/perfetto/config/profiling:cpp
genrule {
- name: "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
- srcs: [
- "protos/perfetto/config/profiling/heapprofd_config.proto",
- "protos/perfetto/config/profiling/java_hprof_config.proto",
- "protos/perfetto/config/profiling/perf_event_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/profiling/heapprofd_config.gen.h",
- "external/perfetto/protos/perfetto/config/profiling/java_hprof_config.gen.h",
- "external/perfetto/protos/perfetto/config/profiling/perf_event_config.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/config/profiling/heapprofd_config.proto",
+ "protos/perfetto/config/profiling/java_hprof_config.proto",
+ "protos/perfetto/config/profiling/perf_event_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/profiling/heapprofd_config.gen.h",
+ "external/perfetto/protos/perfetto/config/profiling/java_hprof_config.gen.h",
+ "external/perfetto/protos/perfetto/config/profiling/perf_event_config.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/profiling:lite
genrule {
- name: "perfetto_protos_perfetto_config_profiling_lite_gen",
- srcs: [
- "protos/perfetto/config/profiling/heapprofd_config.proto",
- "protos/perfetto/config/profiling/java_hprof_config.proto",
- "protos/perfetto/config/profiling/perf_event_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/profiling/heapprofd_config.pb.cc",
- "external/perfetto/protos/perfetto/config/profiling/java_hprof_config.pb.cc",
- "external/perfetto/protos/perfetto/config/profiling/perf_event_config.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_config_profiling_lite_gen",
+ srcs: [
+ "protos/perfetto/config/profiling/heapprofd_config.proto",
+ "protos/perfetto/config/profiling/java_hprof_config.proto",
+ "protos/perfetto/config/profiling/perf_event_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/profiling/heapprofd_config.pb.cc",
+ "external/perfetto/protos/perfetto/config/profiling/java_hprof_config.pb.cc",
+ "external/perfetto/protos/perfetto/config/profiling/perf_event_config.pb.cc",
+ ],
}
// GN: //protos/perfetto/config/profiling:lite
genrule {
- name: "perfetto_protos_perfetto_config_profiling_lite_gen_headers",
- srcs: [
- "protos/perfetto/config/profiling/heapprofd_config.proto",
- "protos/perfetto/config/profiling/java_hprof_config.proto",
- "protos/perfetto/config/profiling/perf_event_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/profiling/heapprofd_config.pb.h",
- "external/perfetto/protos/perfetto/config/profiling/java_hprof_config.pb.h",
- "external/perfetto/protos/perfetto/config/profiling/perf_event_config.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_profiling_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/config/profiling/heapprofd_config.proto",
+ "protos/perfetto/config/profiling/java_hprof_config.proto",
+ "protos/perfetto/config/profiling/perf_event_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/profiling/heapprofd_config.pb.h",
+ "external/perfetto/protos/perfetto/config/profiling/java_hprof_config.pb.h",
+ "external/perfetto/protos/perfetto/config/profiling/perf_event_config.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/profiling:zero
genrule {
- name: "perfetto_protos_perfetto_config_profiling_zero_gen",
- srcs: [
- "protos/perfetto/config/profiling/heapprofd_config.proto",
- "protos/perfetto/config/profiling/java_hprof_config.proto",
- "protos/perfetto/config/profiling/perf_event_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/profiling/heapprofd_config.pbzero.cc",
- "external/perfetto/protos/perfetto/config/profiling/java_hprof_config.pbzero.cc",
- "external/perfetto/protos/perfetto/config/profiling/perf_event_config.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_config_profiling_zero_gen",
+ srcs: [
+ "protos/perfetto/config/profiling/heapprofd_config.proto",
+ "protos/perfetto/config/profiling/java_hprof_config.proto",
+ "protos/perfetto/config/profiling/perf_event_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/profiling/heapprofd_config.pbzero.cc",
+ "external/perfetto/protos/perfetto/config/profiling/java_hprof_config.pbzero.cc",
+ "external/perfetto/protos/perfetto/config/profiling/perf_event_config.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/config/profiling:zero
genrule {
- name: "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
- srcs: [
- "protos/perfetto/config/profiling/heapprofd_config.proto",
- "protos/perfetto/config/profiling/java_hprof_config.proto",
- "protos/perfetto/config/profiling/perf_event_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/profiling/heapprofd_config.pbzero.h",
- "external/perfetto/protos/perfetto/config/profiling/java_hprof_config.pbzero.h",
- "external/perfetto/protos/perfetto/config/profiling/perf_event_config.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/config/profiling/heapprofd_config.proto",
+ "protos/perfetto/config/profiling/java_hprof_config.proto",
+ "protos/perfetto/config/profiling/perf_event_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/profiling/heapprofd_config.pbzero.h",
+ "external/perfetto/protos/perfetto/config/profiling/java_hprof_config.pbzero.h",
+ "external/perfetto/protos/perfetto/config/profiling/perf_event_config.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/sys_stats:cpp
genrule {
- name: "perfetto_protos_perfetto_config_sys_stats_cpp_gen",
- srcs: [
- "protos/perfetto/config/sys_stats/sys_stats_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_config_sys_stats_cpp_gen",
+ srcs: [
+ "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.gen.cc",
+ ],
}
// GN: //protos/perfetto/config/sys_stats:cpp
genrule {
- name: "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
- srcs: [
- "protos/perfetto/config/sys_stats/sys_stats_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/sys_stats:lite
genrule {
- name: "perfetto_protos_perfetto_config_sys_stats_lite_gen",
- srcs: [
- "protos/perfetto/config/sys_stats/sys_stats_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_config_sys_stats_lite_gen",
+ srcs: [
+ "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.pb.cc",
+ ],
}
// GN: //protos/perfetto/config/sys_stats:lite
genrule {
- name: "perfetto_protos_perfetto_config_sys_stats_lite_gen_headers",
- srcs: [
- "protos/perfetto/config/sys_stats/sys_stats_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_sys_stats_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/sys_stats:zero
genrule {
- name: "perfetto_protos_perfetto_config_sys_stats_zero_gen",
- srcs: [
- "protos/perfetto/config/sys_stats/sys_stats_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_config_sys_stats_zero_gen",
+ srcs: [
+ "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/config/sys_stats:zero
genrule {
- name: "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
- srcs: [
- "protos/perfetto/config/sys_stats/sys_stats_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/sys_stats/sys_stats_config.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/track_event:cpp
genrule {
- name: "perfetto_protos_perfetto_config_track_event_cpp_gen",
- srcs: [
- "protos/perfetto/config/track_event/track_event_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/track_event/track_event_config.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_config_track_event_cpp_gen",
+ srcs: [
+ "protos/perfetto/config/track_event/track_event_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/track_event/track_event_config.gen.cc",
+ ],
}
// GN: //protos/perfetto/config/track_event:cpp
genrule {
- name: "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
- srcs: [
- "protos/perfetto/config/track_event/track_event_config.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/track_event/track_event_config.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/config/track_event/track_event_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/track_event/track_event_config.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/track_event:lite
genrule {
- name: "perfetto_protos_perfetto_config_track_event_lite_gen",
- srcs: [
- "protos/perfetto/config/track_event/track_event_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/track_event/track_event_config.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_config_track_event_lite_gen",
+ srcs: [
+ "protos/perfetto/config/track_event/track_event_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/track_event/track_event_config.pb.cc",
+ ],
}
// GN: //protos/perfetto/config/track_event:lite
genrule {
- name: "perfetto_protos_perfetto_config_track_event_lite_gen_headers",
- srcs: [
- "protos/perfetto/config/track_event/track_event_config.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/track_event/track_event_config.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_track_event_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/config/track_event/track_event_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/track_event/track_event_config.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config/track_event:zero
genrule {
- name: "perfetto_protos_perfetto_config_track_event_zero_gen",
- srcs: [
- "protos/perfetto/config/track_event/track_event_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/track_event/track_event_config.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_config_track_event_zero_gen",
+ srcs: [
+ "protos/perfetto/config/track_event/track_event_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/track_event/track_event_config.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/config/track_event:zero
genrule {
- name: "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
- srcs: [
- "protos/perfetto/config/track_event/track_event_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/track_event/track_event_config.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/config/track_event/track_event_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/track_event/track_event_config.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/config:zero
genrule {
- name: "perfetto_protos_perfetto_config_zero_gen",
- srcs: [
- "protos/perfetto/config/chrome/chrome_config.proto",
- "protos/perfetto/config/data_source_config.proto",
- "protos/perfetto/config/interceptor_config.proto",
- "protos/perfetto/config/stress_test_config.proto",
- "protos/perfetto/config/test_config.proto",
- "protos/perfetto/config/trace_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/chrome/chrome_config.pbzero.cc",
- "external/perfetto/protos/perfetto/config/data_source_config.pbzero.cc",
- "external/perfetto/protos/perfetto/config/interceptor_config.pbzero.cc",
- "external/perfetto/protos/perfetto/config/stress_test_config.pbzero.cc",
- "external/perfetto/protos/perfetto/config/test_config.pbzero.cc",
- "external/perfetto/protos/perfetto/config/trace_config.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_config_zero_gen",
+ srcs: [
+ "protos/perfetto/config/chrome/chrome_config.proto",
+ "protos/perfetto/config/data_source_config.proto",
+ "protos/perfetto/config/interceptor_config.proto",
+ "protos/perfetto/config/stress_test_config.proto",
+ "protos/perfetto/config/test_config.proto",
+ "protos/perfetto/config/trace_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/chrome/chrome_config.pbzero.cc",
+ "external/perfetto/protos/perfetto/config/data_source_config.pbzero.cc",
+ "external/perfetto/protos/perfetto/config/interceptor_config.pbzero.cc",
+ "external/perfetto/protos/perfetto/config/stress_test_config.pbzero.cc",
+ "external/perfetto/protos/perfetto/config/test_config.pbzero.cc",
+ "external/perfetto/protos/perfetto/config/trace_config.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/config:zero
genrule {
- name: "perfetto_protos_perfetto_config_zero_gen_headers",
- srcs: [
- "protos/perfetto/config/chrome/chrome_config.proto",
- "protos/perfetto/config/data_source_config.proto",
- "protos/perfetto/config/interceptor_config.proto",
- "protos/perfetto/config/stress_test_config.proto",
- "protos/perfetto/config/test_config.proto",
- "protos/perfetto/config/trace_config.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/config/chrome/chrome_config.pbzero.h",
- "external/perfetto/protos/perfetto/config/data_source_config.pbzero.h",
- "external/perfetto/protos/perfetto/config/interceptor_config.pbzero.h",
- "external/perfetto/protos/perfetto/config/stress_test_config.pbzero.h",
- "external/perfetto/protos/perfetto/config/test_config.pbzero.h",
- "external/perfetto/protos/perfetto/config/trace_config.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_config_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/config/chrome/chrome_config.proto",
+ "protos/perfetto/config/data_source_config.proto",
+ "protos/perfetto/config/interceptor_config.proto",
+ "protos/perfetto/config/stress_test_config.proto",
+ "protos/perfetto/config/test_config.proto",
+ "protos/perfetto/config/trace_config.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/config/chrome/chrome_config.pbzero.h",
+ "external/perfetto/protos/perfetto/config/data_source_config.pbzero.h",
+ "external/perfetto/protos/perfetto/config/interceptor_config.pbzero.h",
+ "external/perfetto/protos/perfetto/config/stress_test_config.pbzero.h",
+ "external/perfetto/protos/perfetto/config/test_config.pbzero.h",
+ "external/perfetto/protos/perfetto/config/trace_config.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/ipc:cpp
genrule {
- name: "perfetto_protos_perfetto_ipc_cpp_gen",
- srcs: [
- "protos/perfetto/ipc/consumer_port.proto",
- "protos/perfetto/ipc/producer_port.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/ipc/consumer_port.gen.cc",
- "external/perfetto/protos/perfetto/ipc/producer_port.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_ipc_cpp_gen",
+ srcs: [
+ "protos/perfetto/ipc/consumer_port.proto",
+ "protos/perfetto/ipc/producer_port.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/ipc/consumer_port.gen.cc",
+ "external/perfetto/protos/perfetto/ipc/producer_port.gen.cc",
+ ],
}
// GN: //protos/perfetto/ipc:cpp
genrule {
- name: "perfetto_protos_perfetto_ipc_cpp_gen_headers",
- srcs: [
- "protos/perfetto/ipc/consumer_port.proto",
- "protos/perfetto/ipc/producer_port.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/ipc/consumer_port.gen.h",
- "external/perfetto/protos/perfetto/ipc/producer_port.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_ipc_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/ipc/consumer_port.proto",
+ "protos/perfetto/ipc/producer_port.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/ipc/consumer_port.gen.h",
+ "external/perfetto/protos/perfetto/ipc/producer_port.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/ipc:ipc
genrule {
- name: "perfetto_protos_perfetto_ipc_ipc_gen",
- srcs: [
- "protos/perfetto/ipc/consumer_port.proto",
- "protos/perfetto/ipc/producer_port.proto",
- ],
- tools: [
- "aprotoc",
- "ipc_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location ipc_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/ipc/consumer_port.ipc.cc",
- "external/perfetto/protos/perfetto/ipc/producer_port.ipc.cc",
- ],
+ name: "perfetto_protos_perfetto_ipc_ipc_gen",
+ srcs: [
+ "protos/perfetto/ipc/consumer_port.proto",
+ "protos/perfetto/ipc/producer_port.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "ipc_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location ipc_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/ipc/consumer_port.ipc.cc",
+ "external/perfetto/protos/perfetto/ipc/producer_port.ipc.cc",
+ ],
}
// GN: //protos/perfetto/ipc:ipc
genrule {
- name: "perfetto_protos_perfetto_ipc_ipc_gen_headers",
- srcs: [
- "protos/perfetto/ipc/consumer_port.proto",
- "protos/perfetto/ipc/producer_port.proto",
- ],
- tools: [
- "aprotoc",
- "ipc_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location ipc_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/ipc/consumer_port.ipc.h",
- "external/perfetto/protos/perfetto/ipc/producer_port.ipc.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_ipc_ipc_gen_headers",
+ srcs: [
+ "protos/perfetto/ipc/consumer_port.proto",
+ "protos/perfetto/ipc/producer_port.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "ipc_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location ipc_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/ipc/consumer_port.ipc.h",
+ "external/perfetto/protos/perfetto/ipc/producer_port.ipc.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/ipc:wire_protocol_cpp
genrule {
- name: "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
- srcs: [
- "protos/perfetto/ipc/wire_protocol.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/ipc/wire_protocol.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
+ srcs: [
+ "protos/perfetto/ipc/wire_protocol.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/ipc/wire_protocol.gen.cc",
+ ],
}
// GN: //protos/perfetto/ipc:wire_protocol_cpp
genrule {
- name: "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
- srcs: [
- "protos/perfetto/ipc/wire_protocol.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/ipc/wire_protocol.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/ipc/wire_protocol.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/ipc/wire_protocol.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/metrics/chrome:descriptor
genrule {
- name: "perfetto_protos_perfetto_metrics_chrome_descriptor",
- srcs: [
- "protos/perfetto/metrics/android/batt_metric.proto",
- "protos/perfetto/metrics/android/cpu_metric.proto",
- "protos/perfetto/metrics/android/display_metrics.proto",
- "protos/perfetto/metrics/android/dma_heap_metric.proto",
- "protos/perfetto/metrics/android/fastrpc_metric.proto",
- "protos/perfetto/metrics/android/g2d_metric.proto",
- "protos/perfetto/metrics/android/gpu_metric.proto",
- "protos/perfetto/metrics/android/hwcomposer.proto",
- "protos/perfetto/metrics/android/hwui_metric.proto",
- "protos/perfetto/metrics/android/ion_metric.proto",
- "protos/perfetto/metrics/android/jank_metric.proto",
- "protos/perfetto/metrics/android/java_heap_histogram.proto",
- "protos/perfetto/metrics/android/java_heap_stats.proto",
- "protos/perfetto/metrics/android/lmk_metric.proto",
- "protos/perfetto/metrics/android/lmk_reason_metric.proto",
- "protos/perfetto/metrics/android/mem_metric.proto",
- "protos/perfetto/metrics/android/mem_unagg_metric.proto",
- "protos/perfetto/metrics/android/package_list.proto",
- "protos/perfetto/metrics/android/powrails_metric.proto",
- "protos/perfetto/metrics/android/process_metadata.proto",
- "protos/perfetto/metrics/android/startup_metric.proto",
- "protos/perfetto/metrics/android/surfaceflinger.proto",
- "protos/perfetto/metrics/android/sysui_cuj_metrics.proto",
- "protos/perfetto/metrics/android/task_names.proto",
- "protos/perfetto/metrics/android/thread_time_in_state_metric.proto",
- "protos/perfetto/metrics/android/unsymbolized_frames.proto",
- "protos/perfetto/metrics/chrome/all_chrome_metrics.proto",
- "protos/perfetto/metrics/chrome/blink_gc_metric.proto",
- "protos/perfetto/metrics/chrome/frame_times.proto",
- "protos/perfetto/metrics/chrome/media_metric.proto",
- "protos/perfetto/metrics/chrome/reported_by_page.proto",
- "protos/perfetto/metrics/chrome/scroll_jank.proto",
- "protos/perfetto/metrics/chrome/test_chrome_metric.proto",
- "protos/perfetto/metrics/custom_options.proto",
- "protos/perfetto/metrics/metrics.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --proto_path=external/protobuf/src --descriptor_set_out=$(out) $(in)",
- out: [
- "perfetto_protos_perfetto_metrics_chrome_descriptor.bin",
- ],
+ name: "perfetto_protos_perfetto_metrics_chrome_descriptor",
+ srcs: [
+ "protos/perfetto/metrics/android/android_trusty_workqueues.proto",
+ "protos/perfetto/metrics/android/batt_metric.proto",
+ "protos/perfetto/metrics/android/camera_metric.proto",
+ "protos/perfetto/metrics/android/camera_unagg_metric.proto",
+ "protos/perfetto/metrics/android/cpu_metric.proto",
+ "protos/perfetto/metrics/android/display_metrics.proto",
+ "protos/perfetto/metrics/android/dma_heap_metric.proto",
+ "protos/perfetto/metrics/android/dvfs_metric.proto",
+ "protos/perfetto/metrics/android/fastrpc_metric.proto",
+ "protos/perfetto/metrics/android/g2d_metric.proto",
+ "protos/perfetto/metrics/android/gpu_metric.proto",
+ "protos/perfetto/metrics/android/hwcomposer.proto",
+ "protos/perfetto/metrics/android/hwui_metric.proto",
+ "protos/perfetto/metrics/android/ion_metric.proto",
+ "protos/perfetto/metrics/android/irq_runtime_metric.proto",
+ "protos/perfetto/metrics/android/jank_metric.proto",
+ "protos/perfetto/metrics/android/java_heap_histogram.proto",
+ "protos/perfetto/metrics/android/java_heap_stats.proto",
+ "protos/perfetto/metrics/android/lmk_metric.proto",
+ "protos/perfetto/metrics/android/lmk_reason_metric.proto",
+ "protos/perfetto/metrics/android/mem_metric.proto",
+ "protos/perfetto/metrics/android/mem_unagg_metric.proto",
+ "protos/perfetto/metrics/android/multiuser_metric.proto",
+ "protos/perfetto/metrics/android/network_metric.proto",
+ "protos/perfetto/metrics/android/other_traces.proto",
+ "protos/perfetto/metrics/android/package_list.proto",
+ "protos/perfetto/metrics/android/powrails_metric.proto",
+ "protos/perfetto/metrics/android/process_metadata.proto",
+ "protos/perfetto/metrics/android/profiler_smaps.proto",
+ "protos/perfetto/metrics/android/rt_runtime_metric.proto",
+ "protos/perfetto/metrics/android/simpleperf.proto",
+ "protos/perfetto/metrics/android/startup_metric.proto",
+ "protos/perfetto/metrics/android/surfaceflinger.proto",
+ "protos/perfetto/metrics/android/sysui_cuj_metrics.proto",
+ "protos/perfetto/metrics/android/task_names.proto",
+ "protos/perfetto/metrics/android/thread_time_in_state_metric.proto",
+ "protos/perfetto/metrics/android/trace_quality.proto",
+ "protos/perfetto/metrics/android/unsymbolized_frames.proto",
+ "protos/perfetto/metrics/chrome/all_chrome_metrics.proto",
+ "protos/perfetto/metrics/chrome/blink_gc_metric.proto",
+ "protos/perfetto/metrics/chrome/dropped_frames.proto",
+ "protos/perfetto/metrics/chrome/frame_times.proto",
+ "protos/perfetto/metrics/chrome/histogram_hashes.proto",
+ "protos/perfetto/metrics/chrome/long_latency.proto",
+ "protos/perfetto/metrics/chrome/media_metric.proto",
+ "protos/perfetto/metrics/chrome/performance_mark_hashes.proto",
+ "protos/perfetto/metrics/chrome/reported_by_page.proto",
+ "protos/perfetto/metrics/chrome/scroll_jank.proto",
+ "protos/perfetto/metrics/chrome/slice_names.proto",
+ "protos/perfetto/metrics/chrome/test_chrome_metric.proto",
+ "protos/perfetto/metrics/chrome/touch_jank.proto",
+ "protos/perfetto/metrics/chrome/user_event_hashes.proto",
+ "protos/perfetto/metrics/custom_options.proto",
+ "protos/perfetto/metrics/metrics.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --proto_path=external/protobuf/src --descriptor_set_out=$(out) $(in)",
+ out: [
+ "perfetto_protos_perfetto_metrics_chrome_descriptor.bin",
+ ],
}
// GN: //protos/perfetto/metrics:descriptor
genrule {
- name: "perfetto_protos_perfetto_metrics_descriptor",
- srcs: [
- "protos/perfetto/metrics/android/batt_metric.proto",
- "protos/perfetto/metrics/android/cpu_metric.proto",
- "protos/perfetto/metrics/android/display_metrics.proto",
- "protos/perfetto/metrics/android/dma_heap_metric.proto",
- "protos/perfetto/metrics/android/fastrpc_metric.proto",
- "protos/perfetto/metrics/android/g2d_metric.proto",
- "protos/perfetto/metrics/android/gpu_metric.proto",
- "protos/perfetto/metrics/android/hwcomposer.proto",
- "protos/perfetto/metrics/android/hwui_metric.proto",
- "protos/perfetto/metrics/android/ion_metric.proto",
- "protos/perfetto/metrics/android/jank_metric.proto",
- "protos/perfetto/metrics/android/java_heap_histogram.proto",
- "protos/perfetto/metrics/android/java_heap_stats.proto",
- "protos/perfetto/metrics/android/lmk_metric.proto",
- "protos/perfetto/metrics/android/lmk_reason_metric.proto",
- "protos/perfetto/metrics/android/mem_metric.proto",
- "protos/perfetto/metrics/android/mem_unagg_metric.proto",
- "protos/perfetto/metrics/android/package_list.proto",
- "protos/perfetto/metrics/android/powrails_metric.proto",
- "protos/perfetto/metrics/android/process_metadata.proto",
- "protos/perfetto/metrics/android/startup_metric.proto",
- "protos/perfetto/metrics/android/surfaceflinger.proto",
- "protos/perfetto/metrics/android/sysui_cuj_metrics.proto",
- "protos/perfetto/metrics/android/task_names.proto",
- "protos/perfetto/metrics/android/thread_time_in_state_metric.proto",
- "protos/perfetto/metrics/android/unsymbolized_frames.proto",
- "protos/perfetto/metrics/metrics.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --descriptor_set_out=$(out) $(in)",
- out: [
- "perfetto_protos_perfetto_metrics_descriptor.bin",
- ],
+ name: "perfetto_protos_perfetto_metrics_descriptor",
+ srcs: [
+ "protos/perfetto/metrics/android/android_trusty_workqueues.proto",
+ "protos/perfetto/metrics/android/batt_metric.proto",
+ "protos/perfetto/metrics/android/camera_metric.proto",
+ "protos/perfetto/metrics/android/camera_unagg_metric.proto",
+ "protos/perfetto/metrics/android/cpu_metric.proto",
+ "protos/perfetto/metrics/android/display_metrics.proto",
+ "protos/perfetto/metrics/android/dma_heap_metric.proto",
+ "protos/perfetto/metrics/android/dvfs_metric.proto",
+ "protos/perfetto/metrics/android/fastrpc_metric.proto",
+ "protos/perfetto/metrics/android/g2d_metric.proto",
+ "protos/perfetto/metrics/android/gpu_metric.proto",
+ "protos/perfetto/metrics/android/hwcomposer.proto",
+ "protos/perfetto/metrics/android/hwui_metric.proto",
+ "protos/perfetto/metrics/android/ion_metric.proto",
+ "protos/perfetto/metrics/android/irq_runtime_metric.proto",
+ "protos/perfetto/metrics/android/jank_metric.proto",
+ "protos/perfetto/metrics/android/java_heap_histogram.proto",
+ "protos/perfetto/metrics/android/java_heap_stats.proto",
+ "protos/perfetto/metrics/android/lmk_metric.proto",
+ "protos/perfetto/metrics/android/lmk_reason_metric.proto",
+ "protos/perfetto/metrics/android/mem_metric.proto",
+ "protos/perfetto/metrics/android/mem_unagg_metric.proto",
+ "protos/perfetto/metrics/android/multiuser_metric.proto",
+ "protos/perfetto/metrics/android/network_metric.proto",
+ "protos/perfetto/metrics/android/other_traces.proto",
+ "protos/perfetto/metrics/android/package_list.proto",
+ "protos/perfetto/metrics/android/powrails_metric.proto",
+ "protos/perfetto/metrics/android/process_metadata.proto",
+ "protos/perfetto/metrics/android/profiler_smaps.proto",
+ "protos/perfetto/metrics/android/rt_runtime_metric.proto",
+ "protos/perfetto/metrics/android/simpleperf.proto",
+ "protos/perfetto/metrics/android/startup_metric.proto",
+ "protos/perfetto/metrics/android/surfaceflinger.proto",
+ "protos/perfetto/metrics/android/sysui_cuj_metrics.proto",
+ "protos/perfetto/metrics/android/task_names.proto",
+ "protos/perfetto/metrics/android/thread_time_in_state_metric.proto",
+ "protos/perfetto/metrics/android/trace_quality.proto",
+ "protos/perfetto/metrics/android/unsymbolized_frames.proto",
+ "protos/perfetto/metrics/metrics.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --descriptor_set_out=$(out) $(in)",
+ out: [
+ "perfetto_protos_perfetto_metrics_descriptor.bin",
+ ],
}
// GN: //protos/perfetto/trace/android:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_android_cpp_gen",
- srcs: [
- "protos/perfetto/trace/android/android_log.proto",
- "protos/perfetto/trace/android/frame_timeline_event.proto",
- "protos/perfetto/trace/android/gpu_mem_event.proto",
- "protos/perfetto/trace/android/graphics_frame_event.proto",
- "protos/perfetto/trace/android/initial_display_state.proto",
- "protos/perfetto/trace/android/packages_list.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/android/android_log.gen.cc",
- "external/perfetto/protos/perfetto/trace/android/frame_timeline_event.gen.cc",
- "external/perfetto/protos/perfetto/trace/android/gpu_mem_event.gen.cc",
- "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.gen.cc",
- "external/perfetto/protos/perfetto/trace/android/initial_display_state.gen.cc",
- "external/perfetto/protos/perfetto/trace/android/packages_list.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_android_cpp_gen",
+ srcs: [
+ "protos/perfetto/trace/android/android_log.proto",
+ "protos/perfetto/trace/android/camera_event.proto",
+ "protos/perfetto/trace/android/frame_timeline_event.proto",
+ "protos/perfetto/trace/android/gpu_mem_event.proto",
+ "protos/perfetto/trace/android/graphics_frame_event.proto",
+ "protos/perfetto/trace/android/initial_display_state.proto",
+ "protos/perfetto/trace/android/packages_list.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/android/android_log.gen.cc",
+ "external/perfetto/protos/perfetto/trace/android/camera_event.gen.cc",
+ "external/perfetto/protos/perfetto/trace/android/frame_timeline_event.gen.cc",
+ "external/perfetto/protos/perfetto/trace/android/gpu_mem_event.gen.cc",
+ "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.gen.cc",
+ "external/perfetto/protos/perfetto/trace/android/initial_display_state.gen.cc",
+ "external/perfetto/protos/perfetto/trace/android/packages_list.gen.cc",
+ ],
}
// GN: //protos/perfetto/trace/android:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_android_cpp_gen_headers",
- srcs: [
- "protos/perfetto/trace/android/android_log.proto",
- "protos/perfetto/trace/android/frame_timeline_event.proto",
- "protos/perfetto/trace/android/gpu_mem_event.proto",
- "protos/perfetto/trace/android/graphics_frame_event.proto",
- "protos/perfetto/trace/android/initial_display_state.proto",
- "protos/perfetto/trace/android/packages_list.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/android/android_log.gen.h",
- "external/perfetto/protos/perfetto/trace/android/frame_timeline_event.gen.h",
- "external/perfetto/protos/perfetto/trace/android/gpu_mem_event.gen.h",
- "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.gen.h",
- "external/perfetto/protos/perfetto/trace/android/initial_display_state.gen.h",
- "external/perfetto/protos/perfetto/trace/android/packages_list.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_android_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/android/android_log.proto",
+ "protos/perfetto/trace/android/camera_event.proto",
+ "protos/perfetto/trace/android/frame_timeline_event.proto",
+ "protos/perfetto/trace/android/gpu_mem_event.proto",
+ "protos/perfetto/trace/android/graphics_frame_event.proto",
+ "protos/perfetto/trace/android/initial_display_state.proto",
+ "protos/perfetto/trace/android/packages_list.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/android/android_log.gen.h",
+ "external/perfetto/protos/perfetto/trace/android/camera_event.gen.h",
+ "external/perfetto/protos/perfetto/trace/android/frame_timeline_event.gen.h",
+ "external/perfetto/protos/perfetto/trace/android/gpu_mem_event.gen.h",
+ "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.gen.h",
+ "external/perfetto/protos/perfetto/trace/android/initial_display_state.gen.h",
+ "external/perfetto/protos/perfetto/trace/android/packages_list.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/android:lite
genrule {
- name: "perfetto_protos_perfetto_trace_android_lite_gen",
- srcs: [
- "protos/perfetto/trace/android/android_log.proto",
- "protos/perfetto/trace/android/frame_timeline_event.proto",
- "protos/perfetto/trace/android/gpu_mem_event.proto",
- "protos/perfetto/trace/android/graphics_frame_event.proto",
- "protos/perfetto/trace/android/initial_display_state.proto",
- "protos/perfetto/trace/android/packages_list.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/android/android_log.pb.cc",
- "external/perfetto/protos/perfetto/trace/android/frame_timeline_event.pb.cc",
- "external/perfetto/protos/perfetto/trace/android/gpu_mem_event.pb.cc",
- "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.pb.cc",
- "external/perfetto/protos/perfetto/trace/android/initial_display_state.pb.cc",
- "external/perfetto/protos/perfetto/trace/android/packages_list.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_android_lite_gen",
+ srcs: [
+ "protos/perfetto/trace/android/android_log.proto",
+ "protos/perfetto/trace/android/camera_event.proto",
+ "protos/perfetto/trace/android/frame_timeline_event.proto",
+ "protos/perfetto/trace/android/gpu_mem_event.proto",
+ "protos/perfetto/trace/android/graphics_frame_event.proto",
+ "protos/perfetto/trace/android/initial_display_state.proto",
+ "protos/perfetto/trace/android/packages_list.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/android/android_log.pb.cc",
+ "external/perfetto/protos/perfetto/trace/android/camera_event.pb.cc",
+ "external/perfetto/protos/perfetto/trace/android/frame_timeline_event.pb.cc",
+ "external/perfetto/protos/perfetto/trace/android/gpu_mem_event.pb.cc",
+ "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.pb.cc",
+ "external/perfetto/protos/perfetto/trace/android/initial_display_state.pb.cc",
+ "external/perfetto/protos/perfetto/trace/android/packages_list.pb.cc",
+ ],
}
// GN: //protos/perfetto/trace/android:lite
genrule {
- name: "perfetto_protos_perfetto_trace_android_lite_gen_headers",
- srcs: [
- "protos/perfetto/trace/android/android_log.proto",
- "protos/perfetto/trace/android/frame_timeline_event.proto",
- "protos/perfetto/trace/android/gpu_mem_event.proto",
- "protos/perfetto/trace/android/graphics_frame_event.proto",
- "protos/perfetto/trace/android/initial_display_state.proto",
- "protos/perfetto/trace/android/packages_list.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/android/android_log.pb.h",
- "external/perfetto/protos/perfetto/trace/android/frame_timeline_event.pb.h",
- "external/perfetto/protos/perfetto/trace/android/gpu_mem_event.pb.h",
- "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.pb.h",
- "external/perfetto/protos/perfetto/trace/android/initial_display_state.pb.h",
- "external/perfetto/protos/perfetto/trace/android/packages_list.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_android_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/android/android_log.proto",
+ "protos/perfetto/trace/android/camera_event.proto",
+ "protos/perfetto/trace/android/frame_timeline_event.proto",
+ "protos/perfetto/trace/android/gpu_mem_event.proto",
+ "protos/perfetto/trace/android/graphics_frame_event.proto",
+ "protos/perfetto/trace/android/initial_display_state.proto",
+ "protos/perfetto/trace/android/packages_list.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/android/android_log.pb.h",
+ "external/perfetto/protos/perfetto/trace/android/camera_event.pb.h",
+ "external/perfetto/protos/perfetto/trace/android/frame_timeline_event.pb.h",
+ "external/perfetto/protos/perfetto/trace/android/gpu_mem_event.pb.h",
+ "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.pb.h",
+ "external/perfetto/protos/perfetto/trace/android/initial_display_state.pb.h",
+ "external/perfetto/protos/perfetto/trace/android/packages_list.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/android:zero
genrule {
- name: "perfetto_protos_perfetto_trace_android_zero_gen",
- srcs: [
- "protos/perfetto/trace/android/android_log.proto",
- "protos/perfetto/trace/android/frame_timeline_event.proto",
- "protos/perfetto/trace/android/gpu_mem_event.proto",
- "protos/perfetto/trace/android/graphics_frame_event.proto",
- "protos/perfetto/trace/android/initial_display_state.proto",
- "protos/perfetto/trace/android/packages_list.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/android/android_log.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/android/frame_timeline_event.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/android/gpu_mem_event.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/android/initial_display_state.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/android/packages_list.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_android_zero_gen",
+ srcs: [
+ "protos/perfetto/trace/android/android_log.proto",
+ "protos/perfetto/trace/android/camera_event.proto",
+ "protos/perfetto/trace/android/frame_timeline_event.proto",
+ "protos/perfetto/trace/android/gpu_mem_event.proto",
+ "protos/perfetto/trace/android/graphics_frame_event.proto",
+ "protos/perfetto/trace/android/initial_display_state.proto",
+ "protos/perfetto/trace/android/packages_list.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/android/android_log.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/android/camera_event.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/android/frame_timeline_event.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/android/gpu_mem_event.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/android/initial_display_state.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/android/packages_list.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/trace/android:zero
genrule {
- name: "perfetto_protos_perfetto_trace_android_zero_gen_headers",
- srcs: [
- "protos/perfetto/trace/android/android_log.proto",
- "protos/perfetto/trace/android/frame_timeline_event.proto",
- "protos/perfetto/trace/android/gpu_mem_event.proto",
- "protos/perfetto/trace/android/graphics_frame_event.proto",
- "protos/perfetto/trace/android/initial_display_state.proto",
- "protos/perfetto/trace/android/packages_list.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/android/android_log.pbzero.h",
- "external/perfetto/protos/perfetto/trace/android/frame_timeline_event.pbzero.h",
- "external/perfetto/protos/perfetto/trace/android/gpu_mem_event.pbzero.h",
- "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.pbzero.h",
- "external/perfetto/protos/perfetto/trace/android/initial_display_state.pbzero.h",
- "external/perfetto/protos/perfetto/trace/android/packages_list.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_android_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/android/android_log.proto",
+ "protos/perfetto/trace/android/camera_event.proto",
+ "protos/perfetto/trace/android/frame_timeline_event.proto",
+ "protos/perfetto/trace/android/gpu_mem_event.proto",
+ "protos/perfetto/trace/android/graphics_frame_event.proto",
+ "protos/perfetto/trace/android/initial_display_state.proto",
+ "protos/perfetto/trace/android/packages_list.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/android/android_log.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/android/camera_event.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/android/frame_timeline_event.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/android/gpu_mem_event.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/android/graphics_frame_event.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/android/initial_display_state.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/android/packages_list.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/chrome:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_chrome_cpp_gen",
- srcs: [
- "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
- "protos/perfetto/trace/chrome/chrome_metadata.proto",
- "protos/perfetto/trace/chrome/chrome_trace_event.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.gen.cc",
- "external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.gen.cc",
- "external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_chrome_cpp_gen",
+ srcs: [
+ "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
+ "protos/perfetto/trace/chrome/chrome_metadata.proto",
+ "protos/perfetto/trace/chrome/chrome_trace_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.gen.cc",
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.gen.cc",
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.gen.cc",
+ ],
}
// GN: //protos/perfetto/trace/chrome:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
- srcs: [
- "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
- "protos/perfetto/trace/chrome/chrome_metadata.proto",
- "protos/perfetto/trace/chrome/chrome_trace_event.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.gen.h",
- "external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.gen.h",
- "external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
+ "protos/perfetto/trace/chrome/chrome_metadata.proto",
+ "protos/perfetto/trace/chrome/chrome_trace_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.gen.h",
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.gen.h",
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/chrome:lite
genrule {
- name: "perfetto_protos_perfetto_trace_chrome_lite_gen",
- srcs: [
- "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
- "protos/perfetto/trace/chrome/chrome_metadata.proto",
- "protos/perfetto/trace/chrome/chrome_trace_event.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pb.cc",
- "external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pb.cc",
- "external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_chrome_lite_gen",
+ srcs: [
+ "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
+ "protos/perfetto/trace/chrome/chrome_metadata.proto",
+ "protos/perfetto/trace/chrome/chrome_trace_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pb.cc",
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pb.cc",
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pb.cc",
+ ],
}
// GN: //protos/perfetto/trace/chrome:lite
genrule {
- name: "perfetto_protos_perfetto_trace_chrome_lite_gen_headers",
- srcs: [
- "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
- "protos/perfetto/trace/chrome/chrome_metadata.proto",
- "protos/perfetto/trace/chrome/chrome_trace_event.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pb.h",
- "external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pb.h",
- "external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_chrome_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
+ "protos/perfetto/trace/chrome/chrome_metadata.proto",
+ "protos/perfetto/trace/chrome/chrome_trace_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pb.h",
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pb.h",
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/chrome:zero
genrule {
- name: "perfetto_protos_perfetto_trace_chrome_zero_gen",
- srcs: [
- "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
- "protos/perfetto/trace/chrome/chrome_metadata.proto",
- "protos/perfetto/trace/chrome/chrome_trace_event.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_chrome_zero_gen",
+ srcs: [
+ "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
+ "protos/perfetto/trace/chrome/chrome_metadata.proto",
+ "protos/perfetto/trace/chrome/chrome_trace_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/trace/chrome:zero
genrule {
- name: "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
- srcs: [
- "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
- "protos/perfetto/trace/chrome/chrome_metadata.proto",
- "protos/perfetto/trace/chrome/chrome_trace_event.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.h",
- "external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pbzero.h",
- "external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
+ "protos/perfetto/trace/chrome/chrome_metadata.proto",
+ "protos/perfetto/trace/chrome/chrome_trace_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
+}
+
+// GN: //protos/perfetto/trace:descriptor
+genrule {
+ name: "perfetto_protos_perfetto_trace_descriptor",
+ srcs: [
+ "protos/perfetto/common/android_energy_consumer_descriptor.proto",
+ "protos/perfetto/common/android_log_constants.proto",
+ "protos/perfetto/common/builtin_clock.proto",
+ "protos/perfetto/common/commit_data_request.proto",
+ "protos/perfetto/common/data_source_descriptor.proto",
+ "protos/perfetto/common/descriptor.proto",
+ "protos/perfetto/common/ftrace_descriptor.proto",
+ "protos/perfetto/common/gpu_counter_descriptor.proto",
+ "protos/perfetto/common/interceptor_descriptor.proto",
+ "protos/perfetto/common/observable_events.proto",
+ "protos/perfetto/common/perf_events.proto",
+ "protos/perfetto/common/sys_stats_counters.proto",
+ "protos/perfetto/common/trace_stats.proto",
+ "protos/perfetto/common/tracing_service_capabilities.proto",
+ "protos/perfetto/common/tracing_service_state.proto",
+ "protos/perfetto/common/track_event_descriptor.proto",
+ "protos/perfetto/config/android/android_log_config.proto",
+ "protos/perfetto/config/android/android_polled_state_config.proto",
+ "protos/perfetto/config/android/packages_list_config.proto",
+ "protos/perfetto/config/chrome/chrome_config.proto",
+ "protos/perfetto/config/data_source_config.proto",
+ "protos/perfetto/config/ftrace/ftrace_config.proto",
+ "protos/perfetto/config/gpu/gpu_counter_config.proto",
+ "protos/perfetto/config/gpu/vulkan_memory_config.proto",
+ "protos/perfetto/config/inode_file/inode_file_config.proto",
+ "protos/perfetto/config/interceptor_config.proto",
+ "protos/perfetto/config/interceptors/console_config.proto",
+ "protos/perfetto/config/power/android_power_config.proto",
+ "protos/perfetto/config/process_stats/process_stats_config.proto",
+ "protos/perfetto/config/profiling/heapprofd_config.proto",
+ "protos/perfetto/config/profiling/java_hprof_config.proto",
+ "protos/perfetto/config/profiling/perf_event_config.proto",
+ "protos/perfetto/config/stress_test_config.proto",
+ "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+ "protos/perfetto/config/test_config.proto",
+ "protos/perfetto/config/trace_config.proto",
+ "protos/perfetto/config/track_event/track_event_config.proto",
+ "protos/perfetto/trace/android/android_log.proto",
+ "protos/perfetto/trace/android/camera_event.proto",
+ "protos/perfetto/trace/android/frame_timeline_event.proto",
+ "protos/perfetto/trace/android/gpu_mem_event.proto",
+ "protos/perfetto/trace/android/graphics_frame_event.proto",
+ "protos/perfetto/trace/android/initial_display_state.proto",
+ "protos/perfetto/trace/android/packages_list.proto",
+ "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
+ "protos/perfetto/trace/chrome/chrome_metadata.proto",
+ "protos/perfetto/trace/chrome/chrome_trace_event.proto",
+ "protos/perfetto/trace/clock_snapshot.proto",
+ "protos/perfetto/trace/extension_descriptor.proto",
+ "protos/perfetto/trace/filesystem/inode_file_map.proto",
+ "protos/perfetto/trace/ftrace/binder.proto",
+ "protos/perfetto/trace/ftrace/block.proto",
+ "protos/perfetto/trace/ftrace/cgroup.proto",
+ "protos/perfetto/trace/ftrace/clk.proto",
+ "protos/perfetto/trace/ftrace/compaction.proto",
+ "protos/perfetto/trace/ftrace/cpuhp.proto",
+ "protos/perfetto/trace/ftrace/cros_ec.proto",
+ "protos/perfetto/trace/ftrace/dma_fence.proto",
+ "protos/perfetto/trace/ftrace/dmabuf_heap.proto",
+ "protos/perfetto/trace/ftrace/dpu.proto",
+ "protos/perfetto/trace/ftrace/drm.proto",
+ "protos/perfetto/trace/ftrace/ext4.proto",
+ "protos/perfetto/trace/ftrace/f2fs.proto",
+ "protos/perfetto/trace/ftrace/fastrpc.proto",
+ "protos/perfetto/trace/ftrace/fence.proto",
+ "protos/perfetto/trace/ftrace/filemap.proto",
+ "protos/perfetto/trace/ftrace/ftrace.proto",
+ "protos/perfetto/trace/ftrace/ftrace_event.proto",
+ "protos/perfetto/trace/ftrace/ftrace_event_bundle.proto",
+ "protos/perfetto/trace/ftrace/ftrace_stats.proto",
+ "protos/perfetto/trace/ftrace/g2d.proto",
+ "protos/perfetto/trace/ftrace/generic.proto",
+ "protos/perfetto/trace/ftrace/gpu_mem.proto",
+ "protos/perfetto/trace/ftrace/gpu_scheduler.proto",
+ "protos/perfetto/trace/ftrace/i2c.proto",
+ "protos/perfetto/trace/ftrace/ion.proto",
+ "protos/perfetto/trace/ftrace/ipi.proto",
+ "protos/perfetto/trace/ftrace/irq.proto",
+ "protos/perfetto/trace/ftrace/kmem.proto",
+ "protos/perfetto/trace/ftrace/kvm.proto",
+ "protos/perfetto/trace/ftrace/lowmemorykiller.proto",
+ "protos/perfetto/trace/ftrace/mali.proto",
+ "protos/perfetto/trace/ftrace/mdss.proto",
+ "protos/perfetto/trace/ftrace/mm_event.proto",
+ "protos/perfetto/trace/ftrace/net.proto",
+ "protos/perfetto/trace/ftrace/oom.proto",
+ "protos/perfetto/trace/ftrace/power.proto",
+ "protos/perfetto/trace/ftrace/printk.proto",
+ "protos/perfetto/trace/ftrace/raw_syscalls.proto",
+ "protos/perfetto/trace/ftrace/regulator.proto",
+ "protos/perfetto/trace/ftrace/sched.proto",
+ "protos/perfetto/trace/ftrace/scm.proto",
+ "protos/perfetto/trace/ftrace/sde.proto",
+ "protos/perfetto/trace/ftrace/signal.proto",
+ "protos/perfetto/trace/ftrace/skb.proto",
+ "protos/perfetto/trace/ftrace/sock.proto",
+ "protos/perfetto/trace/ftrace/sync.proto",
+ "protos/perfetto/trace/ftrace/synthetic.proto",
+ "protos/perfetto/trace/ftrace/systrace.proto",
+ "protos/perfetto/trace/ftrace/task.proto",
+ "protos/perfetto/trace/ftrace/tcp.proto",
+ "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
+ "protos/perfetto/trace/ftrace/thermal.proto",
+ "protos/perfetto/trace/ftrace/ufs.proto",
+ "protos/perfetto/trace/ftrace/vmscan.proto",
+ "protos/perfetto/trace/ftrace/workqueue.proto",
+ "protos/perfetto/trace/gpu/gpu_counter_event.proto",
+ "protos/perfetto/trace/gpu/gpu_log.proto",
+ "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
+ "protos/perfetto/trace/gpu/vulkan_api_event.proto",
+ "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
+ "protos/perfetto/trace/interned_data/interned_data.proto",
+ "protos/perfetto/trace/memory_graph.proto",
+ "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
+ "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+ "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
+ "protos/perfetto/trace/power/battery_counters.proto",
+ "protos/perfetto/trace/power/power_rails.proto",
+ "protos/perfetto/trace/profiling/deobfuscation.proto",
+ "protos/perfetto/trace/profiling/heap_graph.proto",
+ "protos/perfetto/trace/profiling/profile_common.proto",
+ "protos/perfetto/trace/profiling/profile_packet.proto",
+ "protos/perfetto/trace/profiling/smaps.proto",
+ "protos/perfetto/trace/ps/process_stats.proto",
+ "protos/perfetto/trace/ps/process_tree.proto",
+ "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ "protos/perfetto/trace/system_info.proto",
+ "protos/perfetto/trace/system_info/cpu_info.proto",
+ "protos/perfetto/trace/test_event.proto",
+ "protos/perfetto/trace/test_extensions.proto",
+ "protos/perfetto/trace/trace.proto",
+ "protos/perfetto/trace/trace_packet.proto",
+ "protos/perfetto/trace/trace_packet_defaults.proto",
+ "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
+ "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
+ "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
+ "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
+ "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
+ "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
+ "protos/perfetto/trace/track_event/chrome_latency_info.proto",
+ "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
+ "protos/perfetto/trace/track_event/chrome_message_pump.proto",
+ "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
+ "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
+ "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
+ "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
+ "protos/perfetto/trace/track_event/chrome_user_event.proto",
+ "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
+ "protos/perfetto/trace/track_event/counter_descriptor.proto",
+ "protos/perfetto/trace/track_event/debug_annotation.proto",
+ "protos/perfetto/trace/track_event/log_message.proto",
+ "protos/perfetto/trace/track_event/process_descriptor.proto",
+ "protos/perfetto/trace/track_event/source_location.proto",
+ "protos/perfetto/trace/track_event/task_execution.proto",
+ "protos/perfetto/trace/track_event/thread_descriptor.proto",
+ "protos/perfetto/trace/track_event/track_descriptor.proto",
+ "protos/perfetto/trace/track_event/track_event.proto",
+ "protos/perfetto/trace/translation/translation_table.proto",
+ "protos/perfetto/trace/trigger.proto",
+ "protos/perfetto/trace/ui_state.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --descriptor_set_out=$(out) $(in)",
+ out: [
+ "perfetto_protos_perfetto_trace_descriptor.bin",
+ ],
}
// GN: //protos/perfetto/trace/filesystem:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_filesystem_cpp_gen",
- srcs: [
- "protos/perfetto/trace/filesystem/inode_file_map.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/filesystem/inode_file_map.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_filesystem_cpp_gen",
+ srcs: [
+ "protos/perfetto/trace/filesystem/inode_file_map.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/filesystem/inode_file_map.gen.cc",
+ ],
}
// GN: //protos/perfetto/trace/filesystem:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
- srcs: [
- "protos/perfetto/trace/filesystem/inode_file_map.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/filesystem/inode_file_map.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/filesystem/inode_file_map.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/filesystem/inode_file_map.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/filesystem:lite
genrule {
- name: "perfetto_protos_perfetto_trace_filesystem_lite_gen",
- srcs: [
- "protos/perfetto/trace/filesystem/inode_file_map.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/filesystem/inode_file_map.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_filesystem_lite_gen",
+ srcs: [
+ "protos/perfetto/trace/filesystem/inode_file_map.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/filesystem/inode_file_map.pb.cc",
+ ],
}
// GN: //protos/perfetto/trace/filesystem:lite
genrule {
- name: "perfetto_protos_perfetto_trace_filesystem_lite_gen_headers",
- srcs: [
- "protos/perfetto/trace/filesystem/inode_file_map.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/filesystem/inode_file_map.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_filesystem_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/filesystem/inode_file_map.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/filesystem/inode_file_map.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/filesystem:zero
genrule {
- name: "perfetto_protos_perfetto_trace_filesystem_zero_gen",
- srcs: [
- "protos/perfetto/trace/filesystem/inode_file_map.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/filesystem/inode_file_map.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_filesystem_zero_gen",
+ srcs: [
+ "protos/perfetto/trace/filesystem/inode_file_map.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/filesystem/inode_file_map.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/trace/filesystem:zero
genrule {
- name: "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
- srcs: [
- "protos/perfetto/trace/filesystem/inode_file_map.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/filesystem/inode_file_map.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/filesystem/inode_file_map.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/filesystem/inode_file_map.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/ftrace:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_ftrace_cpp_gen",
- srcs: [
- "protos/perfetto/trace/ftrace/binder.proto",
- "protos/perfetto/trace/ftrace/block.proto",
- "protos/perfetto/trace/ftrace/cgroup.proto",
- "protos/perfetto/trace/ftrace/clk.proto",
- "protos/perfetto/trace/ftrace/compaction.proto",
- "protos/perfetto/trace/ftrace/cpuhp.proto",
- "protos/perfetto/trace/ftrace/dmabuf_heap.proto",
- "protos/perfetto/trace/ftrace/dpu.proto",
- "protos/perfetto/trace/ftrace/ext4.proto",
- "protos/perfetto/trace/ftrace/f2fs.proto",
- "protos/perfetto/trace/ftrace/fastrpc.proto",
- "protos/perfetto/trace/ftrace/fence.proto",
- "protos/perfetto/trace/ftrace/filemap.proto",
- "protos/perfetto/trace/ftrace/ftrace.proto",
- "protos/perfetto/trace/ftrace/ftrace_event.proto",
- "protos/perfetto/trace/ftrace/ftrace_event_bundle.proto",
- "protos/perfetto/trace/ftrace/ftrace_stats.proto",
- "protos/perfetto/trace/ftrace/g2d.proto",
- "protos/perfetto/trace/ftrace/generic.proto",
- "protos/perfetto/trace/ftrace/gpu_mem.proto",
- "protos/perfetto/trace/ftrace/i2c.proto",
- "protos/perfetto/trace/ftrace/ion.proto",
- "protos/perfetto/trace/ftrace/ipi.proto",
- "protos/perfetto/trace/ftrace/irq.proto",
- "protos/perfetto/trace/ftrace/kmem.proto",
- "protos/perfetto/trace/ftrace/lowmemorykiller.proto",
- "protos/perfetto/trace/ftrace/mali.proto",
- "protos/perfetto/trace/ftrace/mdss.proto",
- "protos/perfetto/trace/ftrace/mm_event.proto",
- "protos/perfetto/trace/ftrace/oom.proto",
- "protos/perfetto/trace/ftrace/power.proto",
- "protos/perfetto/trace/ftrace/raw_syscalls.proto",
- "protos/perfetto/trace/ftrace/regulator.proto",
- "protos/perfetto/trace/ftrace/sched.proto",
- "protos/perfetto/trace/ftrace/scm.proto",
- "protos/perfetto/trace/ftrace/sde.proto",
- "protos/perfetto/trace/ftrace/signal.proto",
- "protos/perfetto/trace/ftrace/sync.proto",
- "protos/perfetto/trace/ftrace/systrace.proto",
- "protos/perfetto/trace/ftrace/task.proto",
- "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
- "protos/perfetto/trace/ftrace/thermal.proto",
- "protos/perfetto/trace/ftrace/vmscan.proto",
- "protos/perfetto/trace/ftrace/workqueue.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/ftrace/binder.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/block.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/cgroup.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/clk.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/compaction.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/cpuhp.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/dmabuf_heap.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/dpu.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ext4.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/f2fs.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/fastrpc.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/fence.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/filemap.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event_bundle.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace_stats.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/g2d.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/generic.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/gpu_mem.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/i2c.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ion.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ipi.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/irq.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/kmem.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/lowmemorykiller.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/mali.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/mdss.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/mm_event.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/oom.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/power.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/raw_syscalls.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/regulator.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/sched.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/scm.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/sde.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/signal.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/sync.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/systrace.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/task.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/test_bundle_wrapper.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/thermal.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/vmscan.gen.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/workqueue.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_ftrace_cpp_gen",
+ srcs: [
+ "protos/perfetto/trace/ftrace/binder.proto",
+ "protos/perfetto/trace/ftrace/block.proto",
+ "protos/perfetto/trace/ftrace/cgroup.proto",
+ "protos/perfetto/trace/ftrace/clk.proto",
+ "protos/perfetto/trace/ftrace/compaction.proto",
+ "protos/perfetto/trace/ftrace/cpuhp.proto",
+ "protos/perfetto/trace/ftrace/cros_ec.proto",
+ "protos/perfetto/trace/ftrace/dma_fence.proto",
+ "protos/perfetto/trace/ftrace/dmabuf_heap.proto",
+ "protos/perfetto/trace/ftrace/dpu.proto",
+ "protos/perfetto/trace/ftrace/drm.proto",
+ "protos/perfetto/trace/ftrace/ext4.proto",
+ "protos/perfetto/trace/ftrace/f2fs.proto",
+ "protos/perfetto/trace/ftrace/fastrpc.proto",
+ "protos/perfetto/trace/ftrace/fence.proto",
+ "protos/perfetto/trace/ftrace/filemap.proto",
+ "protos/perfetto/trace/ftrace/ftrace.proto",
+ "protos/perfetto/trace/ftrace/ftrace_event.proto",
+ "protos/perfetto/trace/ftrace/ftrace_event_bundle.proto",
+ "protos/perfetto/trace/ftrace/ftrace_stats.proto",
+ "protos/perfetto/trace/ftrace/g2d.proto",
+ "protos/perfetto/trace/ftrace/generic.proto",
+ "protos/perfetto/trace/ftrace/gpu_mem.proto",
+ "protos/perfetto/trace/ftrace/gpu_scheduler.proto",
+ "protos/perfetto/trace/ftrace/i2c.proto",
+ "protos/perfetto/trace/ftrace/ion.proto",
+ "protos/perfetto/trace/ftrace/ipi.proto",
+ "protos/perfetto/trace/ftrace/irq.proto",
+ "protos/perfetto/trace/ftrace/kmem.proto",
+ "protos/perfetto/trace/ftrace/kvm.proto",
+ "protos/perfetto/trace/ftrace/lowmemorykiller.proto",
+ "protos/perfetto/trace/ftrace/mali.proto",
+ "protos/perfetto/trace/ftrace/mdss.proto",
+ "protos/perfetto/trace/ftrace/mm_event.proto",
+ "protos/perfetto/trace/ftrace/net.proto",
+ "protos/perfetto/trace/ftrace/oom.proto",
+ "protos/perfetto/trace/ftrace/power.proto",
+ "protos/perfetto/trace/ftrace/printk.proto",
+ "protos/perfetto/trace/ftrace/raw_syscalls.proto",
+ "protos/perfetto/trace/ftrace/regulator.proto",
+ "protos/perfetto/trace/ftrace/sched.proto",
+ "protos/perfetto/trace/ftrace/scm.proto",
+ "protos/perfetto/trace/ftrace/sde.proto",
+ "protos/perfetto/trace/ftrace/signal.proto",
+ "protos/perfetto/trace/ftrace/skb.proto",
+ "protos/perfetto/trace/ftrace/sock.proto",
+ "protos/perfetto/trace/ftrace/sync.proto",
+ "protos/perfetto/trace/ftrace/synthetic.proto",
+ "protos/perfetto/trace/ftrace/systrace.proto",
+ "protos/perfetto/trace/ftrace/task.proto",
+ "protos/perfetto/trace/ftrace/tcp.proto",
+ "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
+ "protos/perfetto/trace/ftrace/thermal.proto",
+ "protos/perfetto/trace/ftrace/ufs.proto",
+ "protos/perfetto/trace/ftrace/vmscan.proto",
+ "protos/perfetto/trace/ftrace/workqueue.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/ftrace/binder.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/block.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/cgroup.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/clk.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/compaction.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/cpuhp.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/cros_ec.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/dma_fence.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/dmabuf_heap.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/dpu.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/drm.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ext4.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/f2fs.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/fastrpc.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/fence.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/filemap.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event_bundle.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace_stats.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/g2d.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/generic.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/gpu_mem.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/gpu_scheduler.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/i2c.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ion.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ipi.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/irq.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/kmem.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/kvm.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/lowmemorykiller.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/mali.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/mdss.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/mm_event.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/net.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/oom.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/power.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/printk.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/raw_syscalls.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/regulator.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/sched.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/scm.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/sde.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/signal.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/skb.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/sock.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/sync.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/synthetic.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/systrace.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/task.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/tcp.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/test_bundle_wrapper.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/thermal.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ufs.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/vmscan.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/workqueue.gen.cc",
+ ],
}
// GN: //protos/perfetto/trace/ftrace:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
- srcs: [
- "protos/perfetto/trace/ftrace/binder.proto",
- "protos/perfetto/trace/ftrace/block.proto",
- "protos/perfetto/trace/ftrace/cgroup.proto",
- "protos/perfetto/trace/ftrace/clk.proto",
- "protos/perfetto/trace/ftrace/compaction.proto",
- "protos/perfetto/trace/ftrace/cpuhp.proto",
- "protos/perfetto/trace/ftrace/dmabuf_heap.proto",
- "protos/perfetto/trace/ftrace/dpu.proto",
- "protos/perfetto/trace/ftrace/ext4.proto",
- "protos/perfetto/trace/ftrace/f2fs.proto",
- "protos/perfetto/trace/ftrace/fastrpc.proto",
- "protos/perfetto/trace/ftrace/fence.proto",
- "protos/perfetto/trace/ftrace/filemap.proto",
- "protos/perfetto/trace/ftrace/ftrace.proto",
- "protos/perfetto/trace/ftrace/ftrace_event.proto",
- "protos/perfetto/trace/ftrace/ftrace_event_bundle.proto",
- "protos/perfetto/trace/ftrace/ftrace_stats.proto",
- "protos/perfetto/trace/ftrace/g2d.proto",
- "protos/perfetto/trace/ftrace/generic.proto",
- "protos/perfetto/trace/ftrace/gpu_mem.proto",
- "protos/perfetto/trace/ftrace/i2c.proto",
- "protos/perfetto/trace/ftrace/ion.proto",
- "protos/perfetto/trace/ftrace/ipi.proto",
- "protos/perfetto/trace/ftrace/irq.proto",
- "protos/perfetto/trace/ftrace/kmem.proto",
- "protos/perfetto/trace/ftrace/lowmemorykiller.proto",
- "protos/perfetto/trace/ftrace/mali.proto",
- "protos/perfetto/trace/ftrace/mdss.proto",
- "protos/perfetto/trace/ftrace/mm_event.proto",
- "protos/perfetto/trace/ftrace/oom.proto",
- "protos/perfetto/trace/ftrace/power.proto",
- "protos/perfetto/trace/ftrace/raw_syscalls.proto",
- "protos/perfetto/trace/ftrace/regulator.proto",
- "protos/perfetto/trace/ftrace/sched.proto",
- "protos/perfetto/trace/ftrace/scm.proto",
- "protos/perfetto/trace/ftrace/sde.proto",
- "protos/perfetto/trace/ftrace/signal.proto",
- "protos/perfetto/trace/ftrace/sync.proto",
- "protos/perfetto/trace/ftrace/systrace.proto",
- "protos/perfetto/trace/ftrace/task.proto",
- "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
- "protos/perfetto/trace/ftrace/thermal.proto",
- "protos/perfetto/trace/ftrace/vmscan.proto",
- "protos/perfetto/trace/ftrace/workqueue.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/ftrace/binder.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/block.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/cgroup.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/clk.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/compaction.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/cpuhp.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/dmabuf_heap.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/dpu.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ext4.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/f2fs.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/fastrpc.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/fence.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/filemap.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event_bundle.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace_stats.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/g2d.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/generic.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/gpu_mem.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/i2c.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ion.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ipi.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/irq.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/kmem.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/lowmemorykiller.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/mali.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/mdss.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/mm_event.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/oom.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/power.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/raw_syscalls.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/regulator.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/sched.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/scm.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/sde.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/signal.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/sync.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/systrace.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/task.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/test_bundle_wrapper.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/thermal.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/vmscan.gen.h",
- "external/perfetto/protos/perfetto/trace/ftrace/workqueue.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/ftrace/binder.proto",
+ "protos/perfetto/trace/ftrace/block.proto",
+ "protos/perfetto/trace/ftrace/cgroup.proto",
+ "protos/perfetto/trace/ftrace/clk.proto",
+ "protos/perfetto/trace/ftrace/compaction.proto",
+ "protos/perfetto/trace/ftrace/cpuhp.proto",
+ "protos/perfetto/trace/ftrace/cros_ec.proto",
+ "protos/perfetto/trace/ftrace/dma_fence.proto",
+ "protos/perfetto/trace/ftrace/dmabuf_heap.proto",
+ "protos/perfetto/trace/ftrace/dpu.proto",
+ "protos/perfetto/trace/ftrace/drm.proto",
+ "protos/perfetto/trace/ftrace/ext4.proto",
+ "protos/perfetto/trace/ftrace/f2fs.proto",
+ "protos/perfetto/trace/ftrace/fastrpc.proto",
+ "protos/perfetto/trace/ftrace/fence.proto",
+ "protos/perfetto/trace/ftrace/filemap.proto",
+ "protos/perfetto/trace/ftrace/ftrace.proto",
+ "protos/perfetto/trace/ftrace/ftrace_event.proto",
+ "protos/perfetto/trace/ftrace/ftrace_event_bundle.proto",
+ "protos/perfetto/trace/ftrace/ftrace_stats.proto",
+ "protos/perfetto/trace/ftrace/g2d.proto",
+ "protos/perfetto/trace/ftrace/generic.proto",
+ "protos/perfetto/trace/ftrace/gpu_mem.proto",
+ "protos/perfetto/trace/ftrace/gpu_scheduler.proto",
+ "protos/perfetto/trace/ftrace/i2c.proto",
+ "protos/perfetto/trace/ftrace/ion.proto",
+ "protos/perfetto/trace/ftrace/ipi.proto",
+ "protos/perfetto/trace/ftrace/irq.proto",
+ "protos/perfetto/trace/ftrace/kmem.proto",
+ "protos/perfetto/trace/ftrace/kvm.proto",
+ "protos/perfetto/trace/ftrace/lowmemorykiller.proto",
+ "protos/perfetto/trace/ftrace/mali.proto",
+ "protos/perfetto/trace/ftrace/mdss.proto",
+ "protos/perfetto/trace/ftrace/mm_event.proto",
+ "protos/perfetto/trace/ftrace/net.proto",
+ "protos/perfetto/trace/ftrace/oom.proto",
+ "protos/perfetto/trace/ftrace/power.proto",
+ "protos/perfetto/trace/ftrace/printk.proto",
+ "protos/perfetto/trace/ftrace/raw_syscalls.proto",
+ "protos/perfetto/trace/ftrace/regulator.proto",
+ "protos/perfetto/trace/ftrace/sched.proto",
+ "protos/perfetto/trace/ftrace/scm.proto",
+ "protos/perfetto/trace/ftrace/sde.proto",
+ "protos/perfetto/trace/ftrace/signal.proto",
+ "protos/perfetto/trace/ftrace/skb.proto",
+ "protos/perfetto/trace/ftrace/sock.proto",
+ "protos/perfetto/trace/ftrace/sync.proto",
+ "protos/perfetto/trace/ftrace/synthetic.proto",
+ "protos/perfetto/trace/ftrace/systrace.proto",
+ "protos/perfetto/trace/ftrace/task.proto",
+ "protos/perfetto/trace/ftrace/tcp.proto",
+ "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
+ "protos/perfetto/trace/ftrace/thermal.proto",
+ "protos/perfetto/trace/ftrace/ufs.proto",
+ "protos/perfetto/trace/ftrace/vmscan.proto",
+ "protos/perfetto/trace/ftrace/workqueue.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/ftrace/binder.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/block.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/cgroup.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/clk.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/compaction.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/cpuhp.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/cros_ec.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/dma_fence.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/dmabuf_heap.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/dpu.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/drm.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ext4.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/f2fs.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/fastrpc.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/fence.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/filemap.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event_bundle.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace_stats.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/g2d.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/generic.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/gpu_mem.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/gpu_scheduler.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/i2c.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ion.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ipi.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/irq.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/kmem.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/kvm.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/lowmemorykiller.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/mali.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/mdss.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/mm_event.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/net.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/oom.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/power.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/printk.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/raw_syscalls.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/regulator.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/sched.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/scm.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/sde.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/signal.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/skb.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/sock.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/sync.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/synthetic.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/systrace.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/task.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/tcp.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/test_bundle_wrapper.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/thermal.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ufs.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/vmscan.gen.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/workqueue.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/ftrace:lite
genrule {
- name: "perfetto_protos_perfetto_trace_ftrace_lite_gen",
- srcs: [
- "protos/perfetto/trace/ftrace/binder.proto",
- "protos/perfetto/trace/ftrace/block.proto",
- "protos/perfetto/trace/ftrace/cgroup.proto",
- "protos/perfetto/trace/ftrace/clk.proto",
- "protos/perfetto/trace/ftrace/compaction.proto",
- "protos/perfetto/trace/ftrace/cpuhp.proto",
- "protos/perfetto/trace/ftrace/dmabuf_heap.proto",
- "protos/perfetto/trace/ftrace/dpu.proto",
- "protos/perfetto/trace/ftrace/ext4.proto",
- "protos/perfetto/trace/ftrace/f2fs.proto",
- "protos/perfetto/trace/ftrace/fastrpc.proto",
- "protos/perfetto/trace/ftrace/fence.proto",
- "protos/perfetto/trace/ftrace/filemap.proto",
- "protos/perfetto/trace/ftrace/ftrace.proto",
- "protos/perfetto/trace/ftrace/ftrace_event.proto",
- "protos/perfetto/trace/ftrace/ftrace_event_bundle.proto",
- "protos/perfetto/trace/ftrace/ftrace_stats.proto",
- "protos/perfetto/trace/ftrace/g2d.proto",
- "protos/perfetto/trace/ftrace/generic.proto",
- "protos/perfetto/trace/ftrace/gpu_mem.proto",
- "protos/perfetto/trace/ftrace/i2c.proto",
- "protos/perfetto/trace/ftrace/ion.proto",
- "protos/perfetto/trace/ftrace/ipi.proto",
- "protos/perfetto/trace/ftrace/irq.proto",
- "protos/perfetto/trace/ftrace/kmem.proto",
- "protos/perfetto/trace/ftrace/lowmemorykiller.proto",
- "protos/perfetto/trace/ftrace/mali.proto",
- "protos/perfetto/trace/ftrace/mdss.proto",
- "protos/perfetto/trace/ftrace/mm_event.proto",
- "protos/perfetto/trace/ftrace/oom.proto",
- "protos/perfetto/trace/ftrace/power.proto",
- "protos/perfetto/trace/ftrace/raw_syscalls.proto",
- "protos/perfetto/trace/ftrace/regulator.proto",
- "protos/perfetto/trace/ftrace/sched.proto",
- "protos/perfetto/trace/ftrace/scm.proto",
- "protos/perfetto/trace/ftrace/sde.proto",
- "protos/perfetto/trace/ftrace/signal.proto",
- "protos/perfetto/trace/ftrace/sync.proto",
- "protos/perfetto/trace/ftrace/systrace.proto",
- "protos/perfetto/trace/ftrace/task.proto",
- "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
- "protos/perfetto/trace/ftrace/thermal.proto",
- "protos/perfetto/trace/ftrace/vmscan.proto",
- "protos/perfetto/trace/ftrace/workqueue.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/ftrace/binder.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/block.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/cgroup.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/clk.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/compaction.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/cpuhp.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/dmabuf_heap.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/dpu.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ext4.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/f2fs.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/fastrpc.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/fence.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/filemap.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event_bundle.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace_stats.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/g2d.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/generic.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/gpu_mem.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/i2c.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ion.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ipi.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/irq.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/kmem.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/lowmemorykiller.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/mali.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/mdss.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/mm_event.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/oom.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/power.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/raw_syscalls.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/regulator.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/sched.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/scm.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/sde.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/signal.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/sync.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/systrace.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/task.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/test_bundle_wrapper.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/thermal.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/vmscan.pb.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/workqueue.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_ftrace_lite_gen",
+ srcs: [
+ "protos/perfetto/trace/ftrace/binder.proto",
+ "protos/perfetto/trace/ftrace/block.proto",
+ "protos/perfetto/trace/ftrace/cgroup.proto",
+ "protos/perfetto/trace/ftrace/clk.proto",
+ "protos/perfetto/trace/ftrace/compaction.proto",
+ "protos/perfetto/trace/ftrace/cpuhp.proto",
+ "protos/perfetto/trace/ftrace/cros_ec.proto",
+ "protos/perfetto/trace/ftrace/dma_fence.proto",
+ "protos/perfetto/trace/ftrace/dmabuf_heap.proto",
+ "protos/perfetto/trace/ftrace/dpu.proto",
+ "protos/perfetto/trace/ftrace/drm.proto",
+ "protos/perfetto/trace/ftrace/ext4.proto",
+ "protos/perfetto/trace/ftrace/f2fs.proto",
+ "protos/perfetto/trace/ftrace/fastrpc.proto",
+ "protos/perfetto/trace/ftrace/fence.proto",
+ "protos/perfetto/trace/ftrace/filemap.proto",
+ "protos/perfetto/trace/ftrace/ftrace.proto",
+ "protos/perfetto/trace/ftrace/ftrace_event.proto",
+ "protos/perfetto/trace/ftrace/ftrace_event_bundle.proto",
+ "protos/perfetto/trace/ftrace/ftrace_stats.proto",
+ "protos/perfetto/trace/ftrace/g2d.proto",
+ "protos/perfetto/trace/ftrace/generic.proto",
+ "protos/perfetto/trace/ftrace/gpu_mem.proto",
+ "protos/perfetto/trace/ftrace/gpu_scheduler.proto",
+ "protos/perfetto/trace/ftrace/i2c.proto",
+ "protos/perfetto/trace/ftrace/ion.proto",
+ "protos/perfetto/trace/ftrace/ipi.proto",
+ "protos/perfetto/trace/ftrace/irq.proto",
+ "protos/perfetto/trace/ftrace/kmem.proto",
+ "protos/perfetto/trace/ftrace/kvm.proto",
+ "protos/perfetto/trace/ftrace/lowmemorykiller.proto",
+ "protos/perfetto/trace/ftrace/mali.proto",
+ "protos/perfetto/trace/ftrace/mdss.proto",
+ "protos/perfetto/trace/ftrace/mm_event.proto",
+ "protos/perfetto/trace/ftrace/net.proto",
+ "protos/perfetto/trace/ftrace/oom.proto",
+ "protos/perfetto/trace/ftrace/power.proto",
+ "protos/perfetto/trace/ftrace/printk.proto",
+ "protos/perfetto/trace/ftrace/raw_syscalls.proto",
+ "protos/perfetto/trace/ftrace/regulator.proto",
+ "protos/perfetto/trace/ftrace/sched.proto",
+ "protos/perfetto/trace/ftrace/scm.proto",
+ "protos/perfetto/trace/ftrace/sde.proto",
+ "protos/perfetto/trace/ftrace/signal.proto",
+ "protos/perfetto/trace/ftrace/skb.proto",
+ "protos/perfetto/trace/ftrace/sock.proto",
+ "protos/perfetto/trace/ftrace/sync.proto",
+ "protos/perfetto/trace/ftrace/synthetic.proto",
+ "protos/perfetto/trace/ftrace/systrace.proto",
+ "protos/perfetto/trace/ftrace/task.proto",
+ "protos/perfetto/trace/ftrace/tcp.proto",
+ "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
+ "protos/perfetto/trace/ftrace/thermal.proto",
+ "protos/perfetto/trace/ftrace/ufs.proto",
+ "protos/perfetto/trace/ftrace/vmscan.proto",
+ "protos/perfetto/trace/ftrace/workqueue.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/ftrace/binder.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/block.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/cgroup.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/clk.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/compaction.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/cpuhp.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/cros_ec.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/dma_fence.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/dmabuf_heap.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/dpu.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/drm.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ext4.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/f2fs.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/fastrpc.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/fence.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/filemap.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event_bundle.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace_stats.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/g2d.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/generic.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/gpu_mem.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/gpu_scheduler.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/i2c.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ion.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ipi.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/irq.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/kmem.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/kvm.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/lowmemorykiller.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/mali.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/mdss.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/mm_event.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/net.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/oom.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/power.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/printk.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/raw_syscalls.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/regulator.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/sched.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/scm.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/sde.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/signal.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/skb.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/sock.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/sync.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/synthetic.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/systrace.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/task.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/tcp.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/test_bundle_wrapper.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/thermal.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ufs.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/vmscan.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/workqueue.pb.cc",
+ ],
}
// GN: //protos/perfetto/trace/ftrace:lite
genrule {
- name: "perfetto_protos_perfetto_trace_ftrace_lite_gen_headers",
- srcs: [
- "protos/perfetto/trace/ftrace/binder.proto",
- "protos/perfetto/trace/ftrace/block.proto",
- "protos/perfetto/trace/ftrace/cgroup.proto",
- "protos/perfetto/trace/ftrace/clk.proto",
- "protos/perfetto/trace/ftrace/compaction.proto",
- "protos/perfetto/trace/ftrace/cpuhp.proto",
- "protos/perfetto/trace/ftrace/dmabuf_heap.proto",
- "protos/perfetto/trace/ftrace/dpu.proto",
- "protos/perfetto/trace/ftrace/ext4.proto",
- "protos/perfetto/trace/ftrace/f2fs.proto",
- "protos/perfetto/trace/ftrace/fastrpc.proto",
- "protos/perfetto/trace/ftrace/fence.proto",
- "protos/perfetto/trace/ftrace/filemap.proto",
- "protos/perfetto/trace/ftrace/ftrace.proto",
- "protos/perfetto/trace/ftrace/ftrace_event.proto",
- "protos/perfetto/trace/ftrace/ftrace_event_bundle.proto",
- "protos/perfetto/trace/ftrace/ftrace_stats.proto",
- "protos/perfetto/trace/ftrace/g2d.proto",
- "protos/perfetto/trace/ftrace/generic.proto",
- "protos/perfetto/trace/ftrace/gpu_mem.proto",
- "protos/perfetto/trace/ftrace/i2c.proto",
- "protos/perfetto/trace/ftrace/ion.proto",
- "protos/perfetto/trace/ftrace/ipi.proto",
- "protos/perfetto/trace/ftrace/irq.proto",
- "protos/perfetto/trace/ftrace/kmem.proto",
- "protos/perfetto/trace/ftrace/lowmemorykiller.proto",
- "protos/perfetto/trace/ftrace/mali.proto",
- "protos/perfetto/trace/ftrace/mdss.proto",
- "protos/perfetto/trace/ftrace/mm_event.proto",
- "protos/perfetto/trace/ftrace/oom.proto",
- "protos/perfetto/trace/ftrace/power.proto",
- "protos/perfetto/trace/ftrace/raw_syscalls.proto",
- "protos/perfetto/trace/ftrace/regulator.proto",
- "protos/perfetto/trace/ftrace/sched.proto",
- "protos/perfetto/trace/ftrace/scm.proto",
- "protos/perfetto/trace/ftrace/sde.proto",
- "protos/perfetto/trace/ftrace/signal.proto",
- "protos/perfetto/trace/ftrace/sync.proto",
- "protos/perfetto/trace/ftrace/systrace.proto",
- "protos/perfetto/trace/ftrace/task.proto",
- "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
- "protos/perfetto/trace/ftrace/thermal.proto",
- "protos/perfetto/trace/ftrace/vmscan.proto",
- "protos/perfetto/trace/ftrace/workqueue.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/ftrace/binder.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/block.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/cgroup.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/clk.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/compaction.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/cpuhp.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/dmabuf_heap.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/dpu.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ext4.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/f2fs.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/fastrpc.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/fence.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/filemap.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event_bundle.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace_stats.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/g2d.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/generic.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/gpu_mem.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/i2c.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ion.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ipi.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/irq.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/kmem.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/lowmemorykiller.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/mali.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/mdss.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/mm_event.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/oom.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/power.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/raw_syscalls.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/regulator.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/sched.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/scm.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/sde.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/signal.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/sync.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/systrace.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/task.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/test_bundle_wrapper.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/thermal.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/vmscan.pb.h",
- "external/perfetto/protos/perfetto/trace/ftrace/workqueue.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_ftrace_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/ftrace/binder.proto",
+ "protos/perfetto/trace/ftrace/block.proto",
+ "protos/perfetto/trace/ftrace/cgroup.proto",
+ "protos/perfetto/trace/ftrace/clk.proto",
+ "protos/perfetto/trace/ftrace/compaction.proto",
+ "protos/perfetto/trace/ftrace/cpuhp.proto",
+ "protos/perfetto/trace/ftrace/cros_ec.proto",
+ "protos/perfetto/trace/ftrace/dma_fence.proto",
+ "protos/perfetto/trace/ftrace/dmabuf_heap.proto",
+ "protos/perfetto/trace/ftrace/dpu.proto",
+ "protos/perfetto/trace/ftrace/drm.proto",
+ "protos/perfetto/trace/ftrace/ext4.proto",
+ "protos/perfetto/trace/ftrace/f2fs.proto",
+ "protos/perfetto/trace/ftrace/fastrpc.proto",
+ "protos/perfetto/trace/ftrace/fence.proto",
+ "protos/perfetto/trace/ftrace/filemap.proto",
+ "protos/perfetto/trace/ftrace/ftrace.proto",
+ "protos/perfetto/trace/ftrace/ftrace_event.proto",
+ "protos/perfetto/trace/ftrace/ftrace_event_bundle.proto",
+ "protos/perfetto/trace/ftrace/ftrace_stats.proto",
+ "protos/perfetto/trace/ftrace/g2d.proto",
+ "protos/perfetto/trace/ftrace/generic.proto",
+ "protos/perfetto/trace/ftrace/gpu_mem.proto",
+ "protos/perfetto/trace/ftrace/gpu_scheduler.proto",
+ "protos/perfetto/trace/ftrace/i2c.proto",
+ "protos/perfetto/trace/ftrace/ion.proto",
+ "protos/perfetto/trace/ftrace/ipi.proto",
+ "protos/perfetto/trace/ftrace/irq.proto",
+ "protos/perfetto/trace/ftrace/kmem.proto",
+ "protos/perfetto/trace/ftrace/kvm.proto",
+ "protos/perfetto/trace/ftrace/lowmemorykiller.proto",
+ "protos/perfetto/trace/ftrace/mali.proto",
+ "protos/perfetto/trace/ftrace/mdss.proto",
+ "protos/perfetto/trace/ftrace/mm_event.proto",
+ "protos/perfetto/trace/ftrace/net.proto",
+ "protos/perfetto/trace/ftrace/oom.proto",
+ "protos/perfetto/trace/ftrace/power.proto",
+ "protos/perfetto/trace/ftrace/printk.proto",
+ "protos/perfetto/trace/ftrace/raw_syscalls.proto",
+ "protos/perfetto/trace/ftrace/regulator.proto",
+ "protos/perfetto/trace/ftrace/sched.proto",
+ "protos/perfetto/trace/ftrace/scm.proto",
+ "protos/perfetto/trace/ftrace/sde.proto",
+ "protos/perfetto/trace/ftrace/signal.proto",
+ "protos/perfetto/trace/ftrace/skb.proto",
+ "protos/perfetto/trace/ftrace/sock.proto",
+ "protos/perfetto/trace/ftrace/sync.proto",
+ "protos/perfetto/trace/ftrace/synthetic.proto",
+ "protos/perfetto/trace/ftrace/systrace.proto",
+ "protos/perfetto/trace/ftrace/task.proto",
+ "protos/perfetto/trace/ftrace/tcp.proto",
+ "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
+ "protos/perfetto/trace/ftrace/thermal.proto",
+ "protos/perfetto/trace/ftrace/ufs.proto",
+ "protos/perfetto/trace/ftrace/vmscan.proto",
+ "protos/perfetto/trace/ftrace/workqueue.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/ftrace/binder.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/block.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/cgroup.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/clk.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/compaction.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/cpuhp.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/cros_ec.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/dma_fence.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/dmabuf_heap.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/dpu.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/drm.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ext4.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/f2fs.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/fastrpc.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/fence.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/filemap.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event_bundle.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace_stats.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/g2d.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/generic.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/gpu_mem.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/gpu_scheduler.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/i2c.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ion.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ipi.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/irq.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/kmem.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/kvm.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/lowmemorykiller.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/mali.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/mdss.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/mm_event.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/net.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/oom.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/power.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/printk.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/raw_syscalls.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/regulator.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/sched.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/scm.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/sde.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/signal.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/skb.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/sock.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/sync.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/synthetic.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/systrace.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/task.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/tcp.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/test_bundle_wrapper.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/thermal.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ufs.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/vmscan.pb.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/workqueue.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/ftrace:zero
genrule {
- name: "perfetto_protos_perfetto_trace_ftrace_zero_gen",
- srcs: [
- "protos/perfetto/trace/ftrace/binder.proto",
- "protos/perfetto/trace/ftrace/block.proto",
- "protos/perfetto/trace/ftrace/cgroup.proto",
- "protos/perfetto/trace/ftrace/clk.proto",
- "protos/perfetto/trace/ftrace/compaction.proto",
- "protos/perfetto/trace/ftrace/cpuhp.proto",
- "protos/perfetto/trace/ftrace/dmabuf_heap.proto",
- "protos/perfetto/trace/ftrace/dpu.proto",
- "protos/perfetto/trace/ftrace/ext4.proto",
- "protos/perfetto/trace/ftrace/f2fs.proto",
- "protos/perfetto/trace/ftrace/fastrpc.proto",
- "protos/perfetto/trace/ftrace/fence.proto",
- "protos/perfetto/trace/ftrace/filemap.proto",
- "protos/perfetto/trace/ftrace/ftrace.proto",
- "protos/perfetto/trace/ftrace/ftrace_event.proto",
- "protos/perfetto/trace/ftrace/ftrace_event_bundle.proto",
- "protos/perfetto/trace/ftrace/ftrace_stats.proto",
- "protos/perfetto/trace/ftrace/g2d.proto",
- "protos/perfetto/trace/ftrace/generic.proto",
- "protos/perfetto/trace/ftrace/gpu_mem.proto",
- "protos/perfetto/trace/ftrace/i2c.proto",
- "protos/perfetto/trace/ftrace/ion.proto",
- "protos/perfetto/trace/ftrace/ipi.proto",
- "protos/perfetto/trace/ftrace/irq.proto",
- "protos/perfetto/trace/ftrace/kmem.proto",
- "protos/perfetto/trace/ftrace/lowmemorykiller.proto",
- "protos/perfetto/trace/ftrace/mali.proto",
- "protos/perfetto/trace/ftrace/mdss.proto",
- "protos/perfetto/trace/ftrace/mm_event.proto",
- "protos/perfetto/trace/ftrace/oom.proto",
- "protos/perfetto/trace/ftrace/power.proto",
- "protos/perfetto/trace/ftrace/raw_syscalls.proto",
- "protos/perfetto/trace/ftrace/regulator.proto",
- "protos/perfetto/trace/ftrace/sched.proto",
- "protos/perfetto/trace/ftrace/scm.proto",
- "protos/perfetto/trace/ftrace/sde.proto",
- "protos/perfetto/trace/ftrace/signal.proto",
- "protos/perfetto/trace/ftrace/sync.proto",
- "protos/perfetto/trace/ftrace/systrace.proto",
- "protos/perfetto/trace/ftrace/task.proto",
- "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
- "protos/perfetto/trace/ftrace/thermal.proto",
- "protos/perfetto/trace/ftrace/vmscan.proto",
- "protos/perfetto/trace/ftrace/workqueue.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/ftrace/binder.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/block.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/cgroup.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/clk.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/compaction.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/cpuhp.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/dmabuf_heap.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/dpu.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ext4.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/f2fs.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/fastrpc.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/fence.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/filemap.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace_stats.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/g2d.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/generic.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/gpu_mem.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/i2c.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ion.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/ipi.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/irq.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/kmem.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/lowmemorykiller.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/mali.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/mdss.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/mm_event.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/oom.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/power.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/raw_syscalls.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/regulator.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/sched.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/scm.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/sde.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/signal.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/sync.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/systrace.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/task.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/test_bundle_wrapper.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/thermal.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/vmscan.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ftrace/workqueue.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_ftrace_zero_gen",
+ srcs: [
+ "protos/perfetto/trace/ftrace/binder.proto",
+ "protos/perfetto/trace/ftrace/block.proto",
+ "protos/perfetto/trace/ftrace/cgroup.proto",
+ "protos/perfetto/trace/ftrace/clk.proto",
+ "protos/perfetto/trace/ftrace/compaction.proto",
+ "protos/perfetto/trace/ftrace/cpuhp.proto",
+ "protos/perfetto/trace/ftrace/cros_ec.proto",
+ "protos/perfetto/trace/ftrace/dma_fence.proto",
+ "protos/perfetto/trace/ftrace/dmabuf_heap.proto",
+ "protos/perfetto/trace/ftrace/dpu.proto",
+ "protos/perfetto/trace/ftrace/drm.proto",
+ "protos/perfetto/trace/ftrace/ext4.proto",
+ "protos/perfetto/trace/ftrace/f2fs.proto",
+ "protos/perfetto/trace/ftrace/fastrpc.proto",
+ "protos/perfetto/trace/ftrace/fence.proto",
+ "protos/perfetto/trace/ftrace/filemap.proto",
+ "protos/perfetto/trace/ftrace/ftrace.proto",
+ "protos/perfetto/trace/ftrace/ftrace_event.proto",
+ "protos/perfetto/trace/ftrace/ftrace_event_bundle.proto",
+ "protos/perfetto/trace/ftrace/ftrace_stats.proto",
+ "protos/perfetto/trace/ftrace/g2d.proto",
+ "protos/perfetto/trace/ftrace/generic.proto",
+ "protos/perfetto/trace/ftrace/gpu_mem.proto",
+ "protos/perfetto/trace/ftrace/gpu_scheduler.proto",
+ "protos/perfetto/trace/ftrace/i2c.proto",
+ "protos/perfetto/trace/ftrace/ion.proto",
+ "protos/perfetto/trace/ftrace/ipi.proto",
+ "protos/perfetto/trace/ftrace/irq.proto",
+ "protos/perfetto/trace/ftrace/kmem.proto",
+ "protos/perfetto/trace/ftrace/kvm.proto",
+ "protos/perfetto/trace/ftrace/lowmemorykiller.proto",
+ "protos/perfetto/trace/ftrace/mali.proto",
+ "protos/perfetto/trace/ftrace/mdss.proto",
+ "protos/perfetto/trace/ftrace/mm_event.proto",
+ "protos/perfetto/trace/ftrace/net.proto",
+ "protos/perfetto/trace/ftrace/oom.proto",
+ "protos/perfetto/trace/ftrace/power.proto",
+ "protos/perfetto/trace/ftrace/printk.proto",
+ "protos/perfetto/trace/ftrace/raw_syscalls.proto",
+ "protos/perfetto/trace/ftrace/regulator.proto",
+ "protos/perfetto/trace/ftrace/sched.proto",
+ "protos/perfetto/trace/ftrace/scm.proto",
+ "protos/perfetto/trace/ftrace/sde.proto",
+ "protos/perfetto/trace/ftrace/signal.proto",
+ "protos/perfetto/trace/ftrace/skb.proto",
+ "protos/perfetto/trace/ftrace/sock.proto",
+ "protos/perfetto/trace/ftrace/sync.proto",
+ "protos/perfetto/trace/ftrace/synthetic.proto",
+ "protos/perfetto/trace/ftrace/systrace.proto",
+ "protos/perfetto/trace/ftrace/task.proto",
+ "protos/perfetto/trace/ftrace/tcp.proto",
+ "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
+ "protos/perfetto/trace/ftrace/thermal.proto",
+ "protos/perfetto/trace/ftrace/ufs.proto",
+ "protos/perfetto/trace/ftrace/vmscan.proto",
+ "protos/perfetto/trace/ftrace/workqueue.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/ftrace/binder.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/block.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/cgroup.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/clk.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/compaction.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/cpuhp.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/cros_ec.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/dma_fence.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/dmabuf_heap.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/dpu.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/drm.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ext4.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/f2fs.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/fastrpc.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/fence.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/filemap.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace_stats.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/g2d.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/generic.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/gpu_mem.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/gpu_scheduler.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/i2c.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ion.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ipi.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/irq.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/kmem.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/kvm.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/lowmemorykiller.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/mali.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/mdss.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/mm_event.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/net.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/oom.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/power.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/printk.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/raw_syscalls.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/regulator.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/sched.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/scm.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/sde.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/signal.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/skb.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/sock.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/sync.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/synthetic.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/systrace.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/task.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/tcp.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/test_bundle_wrapper.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/thermal.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/ufs.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/vmscan.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ftrace/workqueue.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/trace/ftrace:zero
genrule {
- name: "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
- srcs: [
- "protos/perfetto/trace/ftrace/binder.proto",
- "protos/perfetto/trace/ftrace/block.proto",
- "protos/perfetto/trace/ftrace/cgroup.proto",
- "protos/perfetto/trace/ftrace/clk.proto",
- "protos/perfetto/trace/ftrace/compaction.proto",
- "protos/perfetto/trace/ftrace/cpuhp.proto",
- "protos/perfetto/trace/ftrace/dmabuf_heap.proto",
- "protos/perfetto/trace/ftrace/dpu.proto",
- "protos/perfetto/trace/ftrace/ext4.proto",
- "protos/perfetto/trace/ftrace/f2fs.proto",
- "protos/perfetto/trace/ftrace/fastrpc.proto",
- "protos/perfetto/trace/ftrace/fence.proto",
- "protos/perfetto/trace/ftrace/filemap.proto",
- "protos/perfetto/trace/ftrace/ftrace.proto",
- "protos/perfetto/trace/ftrace/ftrace_event.proto",
- "protos/perfetto/trace/ftrace/ftrace_event_bundle.proto",
- "protos/perfetto/trace/ftrace/ftrace_stats.proto",
- "protos/perfetto/trace/ftrace/g2d.proto",
- "protos/perfetto/trace/ftrace/generic.proto",
- "protos/perfetto/trace/ftrace/gpu_mem.proto",
- "protos/perfetto/trace/ftrace/i2c.proto",
- "protos/perfetto/trace/ftrace/ion.proto",
- "protos/perfetto/trace/ftrace/ipi.proto",
- "protos/perfetto/trace/ftrace/irq.proto",
- "protos/perfetto/trace/ftrace/kmem.proto",
- "protos/perfetto/trace/ftrace/lowmemorykiller.proto",
- "protos/perfetto/trace/ftrace/mali.proto",
- "protos/perfetto/trace/ftrace/mdss.proto",
- "protos/perfetto/trace/ftrace/mm_event.proto",
- "protos/perfetto/trace/ftrace/oom.proto",
- "protos/perfetto/trace/ftrace/power.proto",
- "protos/perfetto/trace/ftrace/raw_syscalls.proto",
- "protos/perfetto/trace/ftrace/regulator.proto",
- "protos/perfetto/trace/ftrace/sched.proto",
- "protos/perfetto/trace/ftrace/scm.proto",
- "protos/perfetto/trace/ftrace/sde.proto",
- "protos/perfetto/trace/ftrace/signal.proto",
- "protos/perfetto/trace/ftrace/sync.proto",
- "protos/perfetto/trace/ftrace/systrace.proto",
- "protos/perfetto/trace/ftrace/task.proto",
- "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
- "protos/perfetto/trace/ftrace/thermal.proto",
- "protos/perfetto/trace/ftrace/vmscan.proto",
- "protos/perfetto/trace/ftrace/workqueue.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/ftrace/binder.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/block.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/cgroup.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/clk.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/compaction.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/cpuhp.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/dmabuf_heap.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/dpu.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ext4.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/f2fs.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/fastrpc.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/fence.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/filemap.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ftrace_stats.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/g2d.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/generic.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/gpu_mem.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/i2c.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ion.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/ipi.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/irq.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/kmem.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/lowmemorykiller.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/mali.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/mdss.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/mm_event.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/oom.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/power.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/raw_syscalls.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/regulator.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/sched.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/scm.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/sde.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/signal.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/sync.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/systrace.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/task.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/test_bundle_wrapper.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/thermal.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/vmscan.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ftrace/workqueue.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/ftrace/binder.proto",
+ "protos/perfetto/trace/ftrace/block.proto",
+ "protos/perfetto/trace/ftrace/cgroup.proto",
+ "protos/perfetto/trace/ftrace/clk.proto",
+ "protos/perfetto/trace/ftrace/compaction.proto",
+ "protos/perfetto/trace/ftrace/cpuhp.proto",
+ "protos/perfetto/trace/ftrace/cros_ec.proto",
+ "protos/perfetto/trace/ftrace/dma_fence.proto",
+ "protos/perfetto/trace/ftrace/dmabuf_heap.proto",
+ "protos/perfetto/trace/ftrace/dpu.proto",
+ "protos/perfetto/trace/ftrace/drm.proto",
+ "protos/perfetto/trace/ftrace/ext4.proto",
+ "protos/perfetto/trace/ftrace/f2fs.proto",
+ "protos/perfetto/trace/ftrace/fastrpc.proto",
+ "protos/perfetto/trace/ftrace/fence.proto",
+ "protos/perfetto/trace/ftrace/filemap.proto",
+ "protos/perfetto/trace/ftrace/ftrace.proto",
+ "protos/perfetto/trace/ftrace/ftrace_event.proto",
+ "protos/perfetto/trace/ftrace/ftrace_event_bundle.proto",
+ "protos/perfetto/trace/ftrace/ftrace_stats.proto",
+ "protos/perfetto/trace/ftrace/g2d.proto",
+ "protos/perfetto/trace/ftrace/generic.proto",
+ "protos/perfetto/trace/ftrace/gpu_mem.proto",
+ "protos/perfetto/trace/ftrace/gpu_scheduler.proto",
+ "protos/perfetto/trace/ftrace/i2c.proto",
+ "protos/perfetto/trace/ftrace/ion.proto",
+ "protos/perfetto/trace/ftrace/ipi.proto",
+ "protos/perfetto/trace/ftrace/irq.proto",
+ "protos/perfetto/trace/ftrace/kmem.proto",
+ "protos/perfetto/trace/ftrace/kvm.proto",
+ "protos/perfetto/trace/ftrace/lowmemorykiller.proto",
+ "protos/perfetto/trace/ftrace/mali.proto",
+ "protos/perfetto/trace/ftrace/mdss.proto",
+ "protos/perfetto/trace/ftrace/mm_event.proto",
+ "protos/perfetto/trace/ftrace/net.proto",
+ "protos/perfetto/trace/ftrace/oom.proto",
+ "protos/perfetto/trace/ftrace/power.proto",
+ "protos/perfetto/trace/ftrace/printk.proto",
+ "protos/perfetto/trace/ftrace/raw_syscalls.proto",
+ "protos/perfetto/trace/ftrace/regulator.proto",
+ "protos/perfetto/trace/ftrace/sched.proto",
+ "protos/perfetto/trace/ftrace/scm.proto",
+ "protos/perfetto/trace/ftrace/sde.proto",
+ "protos/perfetto/trace/ftrace/signal.proto",
+ "protos/perfetto/trace/ftrace/skb.proto",
+ "protos/perfetto/trace/ftrace/sock.proto",
+ "protos/perfetto/trace/ftrace/sync.proto",
+ "protos/perfetto/trace/ftrace/synthetic.proto",
+ "protos/perfetto/trace/ftrace/systrace.proto",
+ "protos/perfetto/trace/ftrace/task.proto",
+ "protos/perfetto/trace/ftrace/tcp.proto",
+ "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
+ "protos/perfetto/trace/ftrace/thermal.proto",
+ "protos/perfetto/trace/ftrace/ufs.proto",
+ "protos/perfetto/trace/ftrace/vmscan.proto",
+ "protos/perfetto/trace/ftrace/workqueue.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/ftrace/binder.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/block.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/cgroup.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/clk.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/compaction.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/cpuhp.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/cros_ec.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/dma_fence.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/dmabuf_heap.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/dpu.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/drm.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ext4.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/f2fs.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/fastrpc.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/fence.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/filemap.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ftrace_stats.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/g2d.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/generic.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/gpu_mem.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/gpu_scheduler.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/i2c.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ion.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ipi.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/irq.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/kmem.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/kvm.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/lowmemorykiller.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/mali.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/mdss.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/mm_event.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/net.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/oom.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/power.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/printk.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/raw_syscalls.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/regulator.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/sched.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/scm.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/sde.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/signal.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/skb.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/sock.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/sync.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/synthetic.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/systrace.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/task.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/tcp.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/test_bundle_wrapper.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/thermal.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/ufs.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/vmscan.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ftrace/workqueue.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/gpu:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_gpu_cpp_gen",
- srcs: [
- "protos/perfetto/trace/gpu/gpu_counter_event.proto",
- "protos/perfetto/trace/gpu/gpu_log.proto",
- "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
- "protos/perfetto/trace/gpu/vulkan_api_event.proto",
- "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.gen.cc",
- "external/perfetto/protos/perfetto/trace/gpu/gpu_log.gen.cc",
- "external/perfetto/protos/perfetto/trace/gpu/gpu_render_stage_event.gen.cc",
- "external/perfetto/protos/perfetto/trace/gpu/vulkan_api_event.gen.cc",
- "external/perfetto/protos/perfetto/trace/gpu/vulkan_memory_event.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_gpu_cpp_gen",
+ srcs: [
+ "protos/perfetto/trace/gpu/gpu_counter_event.proto",
+ "protos/perfetto/trace/gpu/gpu_log.proto",
+ "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
+ "protos/perfetto/trace/gpu/vulkan_api_event.proto",
+ "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.gen.cc",
+ "external/perfetto/protos/perfetto/trace/gpu/gpu_log.gen.cc",
+ "external/perfetto/protos/perfetto/trace/gpu/gpu_render_stage_event.gen.cc",
+ "external/perfetto/protos/perfetto/trace/gpu/vulkan_api_event.gen.cc",
+ "external/perfetto/protos/perfetto/trace/gpu/vulkan_memory_event.gen.cc",
+ ],
}
// GN: //protos/perfetto/trace/gpu:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_gpu_cpp_gen_headers",
- srcs: [
- "protos/perfetto/trace/gpu/gpu_counter_event.proto",
- "protos/perfetto/trace/gpu/gpu_log.proto",
- "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
- "protos/perfetto/trace/gpu/vulkan_api_event.proto",
- "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.gen.h",
- "external/perfetto/protos/perfetto/trace/gpu/gpu_log.gen.h",
- "external/perfetto/protos/perfetto/trace/gpu/gpu_render_stage_event.gen.h",
- "external/perfetto/protos/perfetto/trace/gpu/vulkan_api_event.gen.h",
- "external/perfetto/protos/perfetto/trace/gpu/vulkan_memory_event.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_gpu_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/gpu/gpu_counter_event.proto",
+ "protos/perfetto/trace/gpu/gpu_log.proto",
+ "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
+ "protos/perfetto/trace/gpu/vulkan_api_event.proto",
+ "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.gen.h",
+ "external/perfetto/protos/perfetto/trace/gpu/gpu_log.gen.h",
+ "external/perfetto/protos/perfetto/trace/gpu/gpu_render_stage_event.gen.h",
+ "external/perfetto/protos/perfetto/trace/gpu/vulkan_api_event.gen.h",
+ "external/perfetto/protos/perfetto/trace/gpu/vulkan_memory_event.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/gpu:lite
genrule {
- name: "perfetto_protos_perfetto_trace_gpu_lite_gen",
- srcs: [
- "protos/perfetto/trace/gpu/gpu_counter_event.proto",
- "protos/perfetto/trace/gpu/gpu_log.proto",
- "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
- "protos/perfetto/trace/gpu/vulkan_api_event.proto",
- "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.pb.cc",
- "external/perfetto/protos/perfetto/trace/gpu/gpu_log.pb.cc",
- "external/perfetto/protos/perfetto/trace/gpu/gpu_render_stage_event.pb.cc",
- "external/perfetto/protos/perfetto/trace/gpu/vulkan_api_event.pb.cc",
- "external/perfetto/protos/perfetto/trace/gpu/vulkan_memory_event.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_gpu_lite_gen",
+ srcs: [
+ "protos/perfetto/trace/gpu/gpu_counter_event.proto",
+ "protos/perfetto/trace/gpu/gpu_log.proto",
+ "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
+ "protos/perfetto/trace/gpu/vulkan_api_event.proto",
+ "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.pb.cc",
+ "external/perfetto/protos/perfetto/trace/gpu/gpu_log.pb.cc",
+ "external/perfetto/protos/perfetto/trace/gpu/gpu_render_stage_event.pb.cc",
+ "external/perfetto/protos/perfetto/trace/gpu/vulkan_api_event.pb.cc",
+ "external/perfetto/protos/perfetto/trace/gpu/vulkan_memory_event.pb.cc",
+ ],
}
// GN: //protos/perfetto/trace/gpu:lite
genrule {
- name: "perfetto_protos_perfetto_trace_gpu_lite_gen_headers",
- srcs: [
- "protos/perfetto/trace/gpu/gpu_counter_event.proto",
- "protos/perfetto/trace/gpu/gpu_log.proto",
- "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
- "protos/perfetto/trace/gpu/vulkan_api_event.proto",
- "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.pb.h",
- "external/perfetto/protos/perfetto/trace/gpu/gpu_log.pb.h",
- "external/perfetto/protos/perfetto/trace/gpu/gpu_render_stage_event.pb.h",
- "external/perfetto/protos/perfetto/trace/gpu/vulkan_api_event.pb.h",
- "external/perfetto/protos/perfetto/trace/gpu/vulkan_memory_event.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_gpu_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/gpu/gpu_counter_event.proto",
+ "protos/perfetto/trace/gpu/gpu_log.proto",
+ "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
+ "protos/perfetto/trace/gpu/vulkan_api_event.proto",
+ "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.pb.h",
+ "external/perfetto/protos/perfetto/trace/gpu/gpu_log.pb.h",
+ "external/perfetto/protos/perfetto/trace/gpu/gpu_render_stage_event.pb.h",
+ "external/perfetto/protos/perfetto/trace/gpu/vulkan_api_event.pb.h",
+ "external/perfetto/protos/perfetto/trace/gpu/vulkan_memory_event.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/gpu:zero
genrule {
- name: "perfetto_protos_perfetto_trace_gpu_zero_gen",
- srcs: [
- "protos/perfetto/trace/gpu/gpu_counter_event.proto",
- "protos/perfetto/trace/gpu/gpu_log.proto",
- "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
- "protos/perfetto/trace/gpu/vulkan_api_event.proto",
- "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/gpu/gpu_log.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/gpu/gpu_render_stage_event.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/gpu/vulkan_api_event.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/gpu/vulkan_memory_event.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_gpu_zero_gen",
+ srcs: [
+ "protos/perfetto/trace/gpu/gpu_counter_event.proto",
+ "protos/perfetto/trace/gpu/gpu_log.proto",
+ "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
+ "protos/perfetto/trace/gpu/vulkan_api_event.proto",
+ "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/gpu/gpu_log.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/gpu/gpu_render_stage_event.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/gpu/vulkan_api_event.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/gpu/vulkan_memory_event.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/trace/gpu:zero
genrule {
- name: "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
- srcs: [
- "protos/perfetto/trace/gpu/gpu_counter_event.proto",
- "protos/perfetto/trace/gpu/gpu_log.proto",
- "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
- "protos/perfetto/trace/gpu/vulkan_api_event.proto",
- "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.pbzero.h",
- "external/perfetto/protos/perfetto/trace/gpu/gpu_log.pbzero.h",
- "external/perfetto/protos/perfetto/trace/gpu/gpu_render_stage_event.pbzero.h",
- "external/perfetto/protos/perfetto/trace/gpu/vulkan_api_event.pbzero.h",
- "external/perfetto/protos/perfetto/trace/gpu/vulkan_memory_event.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/gpu/gpu_counter_event.proto",
+ "protos/perfetto/trace/gpu/gpu_log.proto",
+ "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
+ "protos/perfetto/trace/gpu/vulkan_api_event.proto",
+ "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/gpu/gpu_log.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/gpu/gpu_render_stage_event.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/gpu/vulkan_api_event.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/gpu/vulkan_memory_event.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/interned_data:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_interned_data_cpp_gen",
- srcs: [
- "protos/perfetto/trace/interned_data/interned_data.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/interned_data/interned_data.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_interned_data_cpp_gen",
+ srcs: [
+ "protos/perfetto/trace/interned_data/interned_data.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/interned_data/interned_data.gen.cc",
+ ],
}
// GN: //protos/perfetto/trace/interned_data:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_interned_data_cpp_gen_headers",
- srcs: [
- "protos/perfetto/trace/interned_data/interned_data.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/interned_data/interned_data.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_interned_data_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/interned_data/interned_data.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/interned_data/interned_data.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/interned_data:lite
genrule {
- name: "perfetto_protos_perfetto_trace_interned_data_lite_gen",
- srcs: [
- "protos/perfetto/trace/interned_data/interned_data.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/interned_data/interned_data.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_interned_data_lite_gen",
+ srcs: [
+ "protos/perfetto/trace/interned_data/interned_data.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/interned_data/interned_data.pb.cc",
+ ],
}
// GN: //protos/perfetto/trace/interned_data:lite
genrule {
- name: "perfetto_protos_perfetto_trace_interned_data_lite_gen_headers",
- srcs: [
- "protos/perfetto/trace/interned_data/interned_data.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/interned_data/interned_data.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_interned_data_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/interned_data/interned_data.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/interned_data/interned_data.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/interned_data:zero
genrule {
- name: "perfetto_protos_perfetto_trace_interned_data_zero_gen",
- srcs: [
- "protos/perfetto/trace/interned_data/interned_data.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/interned_data/interned_data.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_interned_data_zero_gen",
+ srcs: [
+ "protos/perfetto/trace/interned_data/interned_data.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/interned_data/interned_data.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/trace/interned_data:zero
genrule {
- name: "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- srcs: [
- "protos/perfetto/trace/interned_data/interned_data.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/interned_data/interned_data.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/interned_data/interned_data.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/interned_data/interned_data.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace:minimal_cpp
genrule {
- name: "perfetto_protos_perfetto_trace_minimal_cpp_gen",
- srcs: [
- "protos/perfetto/trace/clock_snapshot.proto",
- "protos/perfetto/trace/system_info.proto",
- "protos/perfetto/trace/trigger.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/clock_snapshot.gen.cc",
- "external/perfetto/protos/perfetto/trace/system_info.gen.cc",
- "external/perfetto/protos/perfetto/trace/trigger.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_minimal_cpp_gen",
+ srcs: [
+ "protos/perfetto/trace/clock_snapshot.proto",
+ "protos/perfetto/trace/system_info.proto",
+ "protos/perfetto/trace/trigger.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/clock_snapshot.gen.cc",
+ "external/perfetto/protos/perfetto/trace/system_info.gen.cc",
+ "external/perfetto/protos/perfetto/trace/trigger.gen.cc",
+ ],
}
// GN: //protos/perfetto/trace:minimal_cpp
genrule {
- name: "perfetto_protos_perfetto_trace_minimal_cpp_gen_headers",
- srcs: [
- "protos/perfetto/trace/clock_snapshot.proto",
- "protos/perfetto/trace/system_info.proto",
- "protos/perfetto/trace/trigger.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/clock_snapshot.gen.h",
- "external/perfetto/protos/perfetto/trace/system_info.gen.h",
- "external/perfetto/protos/perfetto/trace/trigger.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_minimal_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/clock_snapshot.proto",
+ "protos/perfetto/trace/system_info.proto",
+ "protos/perfetto/trace/trigger.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/clock_snapshot.gen.h",
+ "external/perfetto/protos/perfetto/trace/system_info.gen.h",
+ "external/perfetto/protos/perfetto/trace/trigger.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace:minimal_lite
genrule {
- name: "perfetto_protos_perfetto_trace_minimal_lite_gen",
- srcs: [
- "protos/perfetto/trace/clock_snapshot.proto",
- "protos/perfetto/trace/system_info.proto",
- "protos/perfetto/trace/trigger.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/clock_snapshot.pb.cc",
- "external/perfetto/protos/perfetto/trace/system_info.pb.cc",
- "external/perfetto/protos/perfetto/trace/trigger.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_minimal_lite_gen",
+ srcs: [
+ "protos/perfetto/trace/clock_snapshot.proto",
+ "protos/perfetto/trace/system_info.proto",
+ "protos/perfetto/trace/trigger.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/clock_snapshot.pb.cc",
+ "external/perfetto/protos/perfetto/trace/system_info.pb.cc",
+ "external/perfetto/protos/perfetto/trace/trigger.pb.cc",
+ ],
}
// GN: //protos/perfetto/trace:minimal_lite
genrule {
- name: "perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
- srcs: [
- "protos/perfetto/trace/clock_snapshot.proto",
- "protos/perfetto/trace/system_info.proto",
- "protos/perfetto/trace/trigger.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/clock_snapshot.pb.h",
- "external/perfetto/protos/perfetto/trace/system_info.pb.h",
- "external/perfetto/protos/perfetto/trace/trigger.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/clock_snapshot.proto",
+ "protos/perfetto/trace/system_info.proto",
+ "protos/perfetto/trace/trigger.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/clock_snapshot.pb.h",
+ "external/perfetto/protos/perfetto/trace/system_info.pb.h",
+ "external/perfetto/protos/perfetto/trace/trigger.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace:minimal_zero
genrule {
- name: "perfetto_protos_perfetto_trace_minimal_zero_gen",
- srcs: [
- "protos/perfetto/trace/clock_snapshot.proto",
- "protos/perfetto/trace/system_info.proto",
- "protos/perfetto/trace/trigger.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/clock_snapshot.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/system_info.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/trigger.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_minimal_zero_gen",
+ srcs: [
+ "protos/perfetto/trace/clock_snapshot.proto",
+ "protos/perfetto/trace/system_info.proto",
+ "protos/perfetto/trace/trigger.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/clock_snapshot.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/system_info.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/trigger.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/trace:minimal_zero
genrule {
- name: "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
- srcs: [
- "protos/perfetto/trace/clock_snapshot.proto",
- "protos/perfetto/trace/system_info.proto",
- "protos/perfetto/trace/trigger.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/clock_snapshot.pbzero.h",
- "external/perfetto/protos/perfetto/trace/system_info.pbzero.h",
- "external/perfetto/protos/perfetto/trace/trigger.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/clock_snapshot.proto",
+ "protos/perfetto/trace/system_info.proto",
+ "protos/perfetto/trace/trigger.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/clock_snapshot.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/system_info.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/trigger.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace:non_minimal_cpp
genrule {
- name: "perfetto_protos_perfetto_trace_non_minimal_cpp_gen",
- srcs: [
- "protos/perfetto/trace/extension_descriptor.proto",
- "protos/perfetto/trace/memory_graph.proto",
- "protos/perfetto/trace/test_event.proto",
- "protos/perfetto/trace/test_extensions.proto",
- "protos/perfetto/trace/trace.proto",
- "protos/perfetto/trace/trace_packet.proto",
- "protos/perfetto/trace/trace_packet_defaults.proto",
- "protos/perfetto/trace/ui_state.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/extension_descriptor.gen.cc",
- "external/perfetto/protos/perfetto/trace/memory_graph.gen.cc",
- "external/perfetto/protos/perfetto/trace/test_event.gen.cc",
- "external/perfetto/protos/perfetto/trace/test_extensions.gen.cc",
- "external/perfetto/protos/perfetto/trace/trace.gen.cc",
- "external/perfetto/protos/perfetto/trace/trace_packet.gen.cc",
- "external/perfetto/protos/perfetto/trace/trace_packet_defaults.gen.cc",
- "external/perfetto/protos/perfetto/trace/ui_state.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_non_minimal_cpp_gen",
+ srcs: [
+ "protos/perfetto/trace/extension_descriptor.proto",
+ "protos/perfetto/trace/memory_graph.proto",
+ "protos/perfetto/trace/test_event.proto",
+ "protos/perfetto/trace/test_extensions.proto",
+ "protos/perfetto/trace/trace.proto",
+ "protos/perfetto/trace/trace_packet.proto",
+ "protos/perfetto/trace/trace_packet_defaults.proto",
+ "protos/perfetto/trace/ui_state.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/extension_descriptor.gen.cc",
+ "external/perfetto/protos/perfetto/trace/memory_graph.gen.cc",
+ "external/perfetto/protos/perfetto/trace/test_event.gen.cc",
+ "external/perfetto/protos/perfetto/trace/test_extensions.gen.cc",
+ "external/perfetto/protos/perfetto/trace/trace.gen.cc",
+ "external/perfetto/protos/perfetto/trace/trace_packet.gen.cc",
+ "external/perfetto/protos/perfetto/trace/trace_packet_defaults.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ui_state.gen.cc",
+ ],
}
// GN: //protos/perfetto/trace:non_minimal_cpp
genrule {
- name: "perfetto_protos_perfetto_trace_non_minimal_cpp_gen_headers",
- srcs: [
- "protos/perfetto/trace/extension_descriptor.proto",
- "protos/perfetto/trace/memory_graph.proto",
- "protos/perfetto/trace/test_event.proto",
- "protos/perfetto/trace/test_extensions.proto",
- "protos/perfetto/trace/trace.proto",
- "protos/perfetto/trace/trace_packet.proto",
- "protos/perfetto/trace/trace_packet_defaults.proto",
- "protos/perfetto/trace/ui_state.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/extension_descriptor.gen.h",
- "external/perfetto/protos/perfetto/trace/memory_graph.gen.h",
- "external/perfetto/protos/perfetto/trace/test_event.gen.h",
- "external/perfetto/protos/perfetto/trace/test_extensions.gen.h",
- "external/perfetto/protos/perfetto/trace/trace.gen.h",
- "external/perfetto/protos/perfetto/trace/trace_packet.gen.h",
- "external/perfetto/protos/perfetto/trace/trace_packet_defaults.gen.h",
- "external/perfetto/protos/perfetto/trace/ui_state.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_non_minimal_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/extension_descriptor.proto",
+ "protos/perfetto/trace/memory_graph.proto",
+ "protos/perfetto/trace/test_event.proto",
+ "protos/perfetto/trace/test_extensions.proto",
+ "protos/perfetto/trace/trace.proto",
+ "protos/perfetto/trace/trace_packet.proto",
+ "protos/perfetto/trace/trace_packet_defaults.proto",
+ "protos/perfetto/trace/ui_state.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/extension_descriptor.gen.h",
+ "external/perfetto/protos/perfetto/trace/memory_graph.gen.h",
+ "external/perfetto/protos/perfetto/trace/test_event.gen.h",
+ "external/perfetto/protos/perfetto/trace/test_extensions.gen.h",
+ "external/perfetto/protos/perfetto/trace/trace.gen.h",
+ "external/perfetto/protos/perfetto/trace/trace_packet.gen.h",
+ "external/perfetto/protos/perfetto/trace/trace_packet_defaults.gen.h",
+ "external/perfetto/protos/perfetto/trace/ui_state.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace:non_minimal_lite
genrule {
- name: "perfetto_protos_perfetto_trace_non_minimal_lite_gen",
- srcs: [
- "protos/perfetto/trace/extension_descriptor.proto",
- "protos/perfetto/trace/memory_graph.proto",
- "protos/perfetto/trace/test_event.proto",
- "protos/perfetto/trace/test_extensions.proto",
- "protos/perfetto/trace/trace.proto",
- "protos/perfetto/trace/trace_packet.proto",
- "protos/perfetto/trace/trace_packet_defaults.proto",
- "protos/perfetto/trace/ui_state.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/extension_descriptor.pb.cc",
- "external/perfetto/protos/perfetto/trace/memory_graph.pb.cc",
- "external/perfetto/protos/perfetto/trace/test_event.pb.cc",
- "external/perfetto/protos/perfetto/trace/test_extensions.pb.cc",
- "external/perfetto/protos/perfetto/trace/trace.pb.cc",
- "external/perfetto/protos/perfetto/trace/trace_packet.pb.cc",
- "external/perfetto/protos/perfetto/trace/trace_packet_defaults.pb.cc",
- "external/perfetto/protos/perfetto/trace/ui_state.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_non_minimal_lite_gen",
+ srcs: [
+ "protos/perfetto/trace/extension_descriptor.proto",
+ "protos/perfetto/trace/memory_graph.proto",
+ "protos/perfetto/trace/test_event.proto",
+ "protos/perfetto/trace/test_extensions.proto",
+ "protos/perfetto/trace/trace.proto",
+ "protos/perfetto/trace/trace_packet.proto",
+ "protos/perfetto/trace/trace_packet_defaults.proto",
+ "protos/perfetto/trace/ui_state.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/extension_descriptor.pb.cc",
+ "external/perfetto/protos/perfetto/trace/memory_graph.pb.cc",
+ "external/perfetto/protos/perfetto/trace/test_event.pb.cc",
+ "external/perfetto/protos/perfetto/trace/test_extensions.pb.cc",
+ "external/perfetto/protos/perfetto/trace/trace.pb.cc",
+ "external/perfetto/protos/perfetto/trace/trace_packet.pb.cc",
+ "external/perfetto/protos/perfetto/trace/trace_packet_defaults.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ui_state.pb.cc",
+ ],
}
// GN: //protos/perfetto/trace:non_minimal_lite
genrule {
- name: "perfetto_protos_perfetto_trace_non_minimal_lite_gen_headers",
- srcs: [
- "protos/perfetto/trace/extension_descriptor.proto",
- "protos/perfetto/trace/memory_graph.proto",
- "protos/perfetto/trace/test_event.proto",
- "protos/perfetto/trace/test_extensions.proto",
- "protos/perfetto/trace/trace.proto",
- "protos/perfetto/trace/trace_packet.proto",
- "protos/perfetto/trace/trace_packet_defaults.proto",
- "protos/perfetto/trace/ui_state.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/extension_descriptor.pb.h",
- "external/perfetto/protos/perfetto/trace/memory_graph.pb.h",
- "external/perfetto/protos/perfetto/trace/test_event.pb.h",
- "external/perfetto/protos/perfetto/trace/test_extensions.pb.h",
- "external/perfetto/protos/perfetto/trace/trace.pb.h",
- "external/perfetto/protos/perfetto/trace/trace_packet.pb.h",
- "external/perfetto/protos/perfetto/trace/trace_packet_defaults.pb.h",
- "external/perfetto/protos/perfetto/trace/ui_state.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_non_minimal_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/extension_descriptor.proto",
+ "protos/perfetto/trace/memory_graph.proto",
+ "protos/perfetto/trace/test_event.proto",
+ "protos/perfetto/trace/test_extensions.proto",
+ "protos/perfetto/trace/trace.proto",
+ "protos/perfetto/trace/trace_packet.proto",
+ "protos/perfetto/trace/trace_packet_defaults.proto",
+ "protos/perfetto/trace/ui_state.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/extension_descriptor.pb.h",
+ "external/perfetto/protos/perfetto/trace/memory_graph.pb.h",
+ "external/perfetto/protos/perfetto/trace/test_event.pb.h",
+ "external/perfetto/protos/perfetto/trace/test_extensions.pb.h",
+ "external/perfetto/protos/perfetto/trace/trace.pb.h",
+ "external/perfetto/protos/perfetto/trace/trace_packet.pb.h",
+ "external/perfetto/protos/perfetto/trace/trace_packet_defaults.pb.h",
+ "external/perfetto/protos/perfetto/trace/ui_state.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace:non_minimal_zero
genrule {
- name: "perfetto_protos_perfetto_trace_non_minimal_zero_gen",
- srcs: [
- "protos/perfetto/trace/extension_descriptor.proto",
- "protos/perfetto/trace/memory_graph.proto",
- "protos/perfetto/trace/test_event.proto",
- "protos/perfetto/trace/test_extensions.proto",
- "protos/perfetto/trace/trace.proto",
- "protos/perfetto/trace/trace_packet.proto",
- "protos/perfetto/trace/trace_packet_defaults.proto",
- "protos/perfetto/trace/ui_state.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/extension_descriptor.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/memory_graph.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/test_event.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/test_extensions.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/trace.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/trace_packet.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/trace_packet_defaults.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ui_state.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_non_minimal_zero_gen",
+ srcs: [
+ "protos/perfetto/trace/extension_descriptor.proto",
+ "protos/perfetto/trace/memory_graph.proto",
+ "protos/perfetto/trace/test_event.proto",
+ "protos/perfetto/trace/test_extensions.proto",
+ "protos/perfetto/trace/trace.proto",
+ "protos/perfetto/trace/trace_packet.proto",
+ "protos/perfetto/trace/trace_packet_defaults.proto",
+ "protos/perfetto/trace/ui_state.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/extension_descriptor.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/memory_graph.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/test_event.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/test_extensions.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/trace.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/trace_packet.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/trace_packet_defaults.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ui_state.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/trace:non_minimal_zero
genrule {
- name: "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
- srcs: [
- "protos/perfetto/trace/extension_descriptor.proto",
- "protos/perfetto/trace/memory_graph.proto",
- "protos/perfetto/trace/test_event.proto",
- "protos/perfetto/trace/test_extensions.proto",
- "protos/perfetto/trace/trace.proto",
- "protos/perfetto/trace/trace_packet.proto",
- "protos/perfetto/trace/trace_packet_defaults.proto",
- "protos/perfetto/trace/ui_state.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/extension_descriptor.pbzero.h",
- "external/perfetto/protos/perfetto/trace/memory_graph.pbzero.h",
- "external/perfetto/protos/perfetto/trace/test_event.pbzero.h",
- "external/perfetto/protos/perfetto/trace/test_extensions.pbzero.h",
- "external/perfetto/protos/perfetto/trace/trace.pbzero.h",
- "external/perfetto/protos/perfetto/trace/trace_packet.pbzero.h",
- "external/perfetto/protos/perfetto/trace/trace_packet_defaults.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ui_state.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/extension_descriptor.proto",
+ "protos/perfetto/trace/memory_graph.proto",
+ "protos/perfetto/trace/test_event.proto",
+ "protos/perfetto/trace/test_extensions.proto",
+ "protos/perfetto/trace/trace.proto",
+ "protos/perfetto/trace/trace_packet.proto",
+ "protos/perfetto/trace/trace_packet_defaults.proto",
+ "protos/perfetto/trace/ui_state.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/extension_descriptor.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/memory_graph.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/test_event.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/test_extensions.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/trace.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/trace_packet.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/trace_packet_defaults.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ui_state.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/perfetto:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_perfetto_cpp_gen",
- srcs: [
- "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
- "protos/perfetto/trace/perfetto/tracing_service_event.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.gen.cc",
- "external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_perfetto_cpp_gen",
+ srcs: [
+ "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
+ "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.gen.cc",
+ "external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.gen.cc",
+ ],
}
// GN: //protos/perfetto/trace/perfetto:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_perfetto_cpp_gen_headers",
- srcs: [
- "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
- "protos/perfetto/trace/perfetto/tracing_service_event.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.gen.h",
- "external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_perfetto_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
+ "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.gen.h",
+ "external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/perfetto:lite
genrule {
- name: "perfetto_protos_perfetto_trace_perfetto_lite_gen",
- srcs: [
- "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
- "protos/perfetto/trace/perfetto/tracing_service_event.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.pb.cc",
- "external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_perfetto_lite_gen",
+ srcs: [
+ "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
+ "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.pb.cc",
+ "external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.pb.cc",
+ ],
}
// GN: //protos/perfetto/trace/perfetto:lite
genrule {
- name: "perfetto_protos_perfetto_trace_perfetto_lite_gen_headers",
- srcs: [
- "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
- "protos/perfetto/trace/perfetto/tracing_service_event.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.pb.h",
- "external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_perfetto_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
+ "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.pb.h",
+ "external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/perfetto:zero
genrule {
- name: "perfetto_protos_perfetto_trace_perfetto_zero_gen",
- srcs: [
- "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
- "protos/perfetto/trace/perfetto/tracing_service_event.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_perfetto_zero_gen",
+ srcs: [
+ "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
+ "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/trace/perfetto:zero
genrule {
- name: "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
- srcs: [
- "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
- "protos/perfetto/trace/perfetto/tracing_service_event.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h",
- "external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
+ "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/power:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_power_cpp_gen",
- srcs: [
- "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
- "protos/perfetto/trace/power/battery_counters.proto",
- "protos/perfetto/trace/power/power_rails.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/power/android_energy_estimation_breakdown.gen.cc",
- "external/perfetto/protos/perfetto/trace/power/battery_counters.gen.cc",
- "external/perfetto/protos/perfetto/trace/power/power_rails.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_power_cpp_gen",
+ srcs: [
+ "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
+ "protos/perfetto/trace/power/battery_counters.proto",
+ "protos/perfetto/trace/power/power_rails.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/power/android_energy_estimation_breakdown.gen.cc",
+ "external/perfetto/protos/perfetto/trace/power/battery_counters.gen.cc",
+ "external/perfetto/protos/perfetto/trace/power/power_rails.gen.cc",
+ ],
}
// GN: //protos/perfetto/trace/power:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_power_cpp_gen_headers",
- srcs: [
- "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
- "protos/perfetto/trace/power/battery_counters.proto",
- "protos/perfetto/trace/power/power_rails.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/power/android_energy_estimation_breakdown.gen.h",
- "external/perfetto/protos/perfetto/trace/power/battery_counters.gen.h",
- "external/perfetto/protos/perfetto/trace/power/power_rails.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_power_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
+ "protos/perfetto/trace/power/battery_counters.proto",
+ "protos/perfetto/trace/power/power_rails.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/power/android_energy_estimation_breakdown.gen.h",
+ "external/perfetto/protos/perfetto/trace/power/battery_counters.gen.h",
+ "external/perfetto/protos/perfetto/trace/power/power_rails.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/power:lite
genrule {
- name: "perfetto_protos_perfetto_trace_power_lite_gen",
- srcs: [
- "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
- "protos/perfetto/trace/power/battery_counters.proto",
- "protos/perfetto/trace/power/power_rails.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/power/android_energy_estimation_breakdown.pb.cc",
- "external/perfetto/protos/perfetto/trace/power/battery_counters.pb.cc",
- "external/perfetto/protos/perfetto/trace/power/power_rails.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_power_lite_gen",
+ srcs: [
+ "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
+ "protos/perfetto/trace/power/battery_counters.proto",
+ "protos/perfetto/trace/power/power_rails.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/power/android_energy_estimation_breakdown.pb.cc",
+ "external/perfetto/protos/perfetto/trace/power/battery_counters.pb.cc",
+ "external/perfetto/protos/perfetto/trace/power/power_rails.pb.cc",
+ ],
}
// GN: //protos/perfetto/trace/power:lite
genrule {
- name: "perfetto_protos_perfetto_trace_power_lite_gen_headers",
- srcs: [
- "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
- "protos/perfetto/trace/power/battery_counters.proto",
- "protos/perfetto/trace/power/power_rails.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/power/android_energy_estimation_breakdown.pb.h",
- "external/perfetto/protos/perfetto/trace/power/battery_counters.pb.h",
- "external/perfetto/protos/perfetto/trace/power/power_rails.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_power_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
+ "protos/perfetto/trace/power/battery_counters.proto",
+ "protos/perfetto/trace/power/power_rails.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/power/android_energy_estimation_breakdown.pb.h",
+ "external/perfetto/protos/perfetto/trace/power/battery_counters.pb.h",
+ "external/perfetto/protos/perfetto/trace/power/power_rails.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/power:zero
genrule {
- name: "perfetto_protos_perfetto_trace_power_zero_gen",
- srcs: [
- "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
- "protos/perfetto/trace/power/battery_counters.proto",
- "protos/perfetto/trace/power/power_rails.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/power/android_energy_estimation_breakdown.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/power/battery_counters.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/power/power_rails.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_power_zero_gen",
+ srcs: [
+ "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
+ "protos/perfetto/trace/power/battery_counters.proto",
+ "protos/perfetto/trace/power/power_rails.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/power/android_energy_estimation_breakdown.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/power/battery_counters.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/power/power_rails.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/trace/power:zero
genrule {
- name: "perfetto_protos_perfetto_trace_power_zero_gen_headers",
- srcs: [
- "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
- "protos/perfetto/trace/power/battery_counters.proto",
- "protos/perfetto/trace/power/power_rails.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/power/android_energy_estimation_breakdown.pbzero.h",
- "external/perfetto/protos/perfetto/trace/power/battery_counters.pbzero.h",
- "external/perfetto/protos/perfetto/trace/power/power_rails.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_power_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
+ "protos/perfetto/trace/power/battery_counters.proto",
+ "protos/perfetto/trace/power/power_rails.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/power/android_energy_estimation_breakdown.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/power/battery_counters.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/power/power_rails.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace_processor:metrics_impl_zero
genrule {
- name: "perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen",
- srcs: [
- "protos/perfetto/trace_processor/metrics_impl.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace_processor/metrics_impl.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen",
+ srcs: [
+ "protos/perfetto/trace_processor/metrics_impl.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace_processor/metrics_impl.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/trace_processor:metrics_impl_zero
genrule {
- name: "perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen_headers",
- srcs: [
- "protos/perfetto/trace_processor/metrics_impl.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace_processor/metrics_impl.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/trace_processor/metrics_impl.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace_processor/metrics_impl.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace_processor:zero
genrule {
- name: "perfetto_protos_perfetto_trace_processor_zero_gen",
- srcs: [
- "protos/perfetto/trace_processor/trace_processor.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace_processor/trace_processor.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_processor_zero_gen",
+ srcs: [
+ "protos/perfetto/trace_processor/trace_processor.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace_processor/trace_processor.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/trace_processor:zero
genrule {
- name: "perfetto_protos_perfetto_trace_processor_zero_gen_headers",
- srcs: [
- "protos/perfetto/trace_processor/trace_processor.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace_processor/trace_processor.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_processor_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/trace_processor/trace_processor.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace_processor/trace_processor.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/profiling:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_profiling_cpp_gen",
- srcs: [
- "protos/perfetto/trace/profiling/deobfuscation.proto",
- "protos/perfetto/trace/profiling/heap_graph.proto",
- "protos/perfetto/trace/profiling/profile_common.proto",
- "protos/perfetto/trace/profiling/profile_packet.proto",
- "protos/perfetto/trace/profiling/smaps.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/profiling/deobfuscation.gen.cc",
- "external/perfetto/protos/perfetto/trace/profiling/heap_graph.gen.cc",
- "external/perfetto/protos/perfetto/trace/profiling/profile_common.gen.cc",
- "external/perfetto/protos/perfetto/trace/profiling/profile_packet.gen.cc",
- "external/perfetto/protos/perfetto/trace/profiling/smaps.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_profiling_cpp_gen",
+ srcs: [
+ "protos/perfetto/trace/profiling/deobfuscation.proto",
+ "protos/perfetto/trace/profiling/heap_graph.proto",
+ "protos/perfetto/trace/profiling/profile_common.proto",
+ "protos/perfetto/trace/profiling/profile_packet.proto",
+ "protos/perfetto/trace/profiling/smaps.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/profiling/deobfuscation.gen.cc",
+ "external/perfetto/protos/perfetto/trace/profiling/heap_graph.gen.cc",
+ "external/perfetto/protos/perfetto/trace/profiling/profile_common.gen.cc",
+ "external/perfetto/protos/perfetto/trace/profiling/profile_packet.gen.cc",
+ "external/perfetto/protos/perfetto/trace/profiling/smaps.gen.cc",
+ ],
}
// GN: //protos/perfetto/trace/profiling:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_profiling_cpp_gen_headers",
- srcs: [
- "protos/perfetto/trace/profiling/deobfuscation.proto",
- "protos/perfetto/trace/profiling/heap_graph.proto",
- "protos/perfetto/trace/profiling/profile_common.proto",
- "protos/perfetto/trace/profiling/profile_packet.proto",
- "protos/perfetto/trace/profiling/smaps.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/profiling/deobfuscation.gen.h",
- "external/perfetto/protos/perfetto/trace/profiling/heap_graph.gen.h",
- "external/perfetto/protos/perfetto/trace/profiling/profile_common.gen.h",
- "external/perfetto/protos/perfetto/trace/profiling/profile_packet.gen.h",
- "external/perfetto/protos/perfetto/trace/profiling/smaps.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_profiling_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/profiling/deobfuscation.proto",
+ "protos/perfetto/trace/profiling/heap_graph.proto",
+ "protos/perfetto/trace/profiling/profile_common.proto",
+ "protos/perfetto/trace/profiling/profile_packet.proto",
+ "protos/perfetto/trace/profiling/smaps.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/profiling/deobfuscation.gen.h",
+ "external/perfetto/protos/perfetto/trace/profiling/heap_graph.gen.h",
+ "external/perfetto/protos/perfetto/trace/profiling/profile_common.gen.h",
+ "external/perfetto/protos/perfetto/trace/profiling/profile_packet.gen.h",
+ "external/perfetto/protos/perfetto/trace/profiling/smaps.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/profiling:lite
genrule {
- name: "perfetto_protos_perfetto_trace_profiling_lite_gen",
- srcs: [
- "protos/perfetto/trace/profiling/deobfuscation.proto",
- "protos/perfetto/trace/profiling/heap_graph.proto",
- "protos/perfetto/trace/profiling/profile_common.proto",
- "protos/perfetto/trace/profiling/profile_packet.proto",
- "protos/perfetto/trace/profiling/smaps.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/profiling/deobfuscation.pb.cc",
- "external/perfetto/protos/perfetto/trace/profiling/heap_graph.pb.cc",
- "external/perfetto/protos/perfetto/trace/profiling/profile_common.pb.cc",
- "external/perfetto/protos/perfetto/trace/profiling/profile_packet.pb.cc",
- "external/perfetto/protos/perfetto/trace/profiling/smaps.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_profiling_lite_gen",
+ srcs: [
+ "protos/perfetto/trace/profiling/deobfuscation.proto",
+ "protos/perfetto/trace/profiling/heap_graph.proto",
+ "protos/perfetto/trace/profiling/profile_common.proto",
+ "protos/perfetto/trace/profiling/profile_packet.proto",
+ "protos/perfetto/trace/profiling/smaps.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/profiling/deobfuscation.pb.cc",
+ "external/perfetto/protos/perfetto/trace/profiling/heap_graph.pb.cc",
+ "external/perfetto/protos/perfetto/trace/profiling/profile_common.pb.cc",
+ "external/perfetto/protos/perfetto/trace/profiling/profile_packet.pb.cc",
+ "external/perfetto/protos/perfetto/trace/profiling/smaps.pb.cc",
+ ],
}
// GN: //protos/perfetto/trace/profiling:lite
genrule {
- name: "perfetto_protos_perfetto_trace_profiling_lite_gen_headers",
- srcs: [
- "protos/perfetto/trace/profiling/deobfuscation.proto",
- "protos/perfetto/trace/profiling/heap_graph.proto",
- "protos/perfetto/trace/profiling/profile_common.proto",
- "protos/perfetto/trace/profiling/profile_packet.proto",
- "protos/perfetto/trace/profiling/smaps.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/profiling/deobfuscation.pb.h",
- "external/perfetto/protos/perfetto/trace/profiling/heap_graph.pb.h",
- "external/perfetto/protos/perfetto/trace/profiling/profile_common.pb.h",
- "external/perfetto/protos/perfetto/trace/profiling/profile_packet.pb.h",
- "external/perfetto/protos/perfetto/trace/profiling/smaps.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_profiling_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/profiling/deobfuscation.proto",
+ "protos/perfetto/trace/profiling/heap_graph.proto",
+ "protos/perfetto/trace/profiling/profile_common.proto",
+ "protos/perfetto/trace/profiling/profile_packet.proto",
+ "protos/perfetto/trace/profiling/smaps.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/profiling/deobfuscation.pb.h",
+ "external/perfetto/protos/perfetto/trace/profiling/heap_graph.pb.h",
+ "external/perfetto/protos/perfetto/trace/profiling/profile_common.pb.h",
+ "external/perfetto/protos/perfetto/trace/profiling/profile_packet.pb.h",
+ "external/perfetto/protos/perfetto/trace/profiling/smaps.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/profiling:zero
genrule {
- name: "perfetto_protos_perfetto_trace_profiling_zero_gen",
- srcs: [
- "protos/perfetto/trace/profiling/deobfuscation.proto",
- "protos/perfetto/trace/profiling/heap_graph.proto",
- "protos/perfetto/trace/profiling/profile_common.proto",
- "protos/perfetto/trace/profiling/profile_packet.proto",
- "protos/perfetto/trace/profiling/smaps.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/profiling/deobfuscation.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/profiling/heap_graph.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/profiling/profile_common.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/profiling/profile_packet.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/profiling/smaps.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_profiling_zero_gen",
+ srcs: [
+ "protos/perfetto/trace/profiling/deobfuscation.proto",
+ "protos/perfetto/trace/profiling/heap_graph.proto",
+ "protos/perfetto/trace/profiling/profile_common.proto",
+ "protos/perfetto/trace/profiling/profile_packet.proto",
+ "protos/perfetto/trace/profiling/smaps.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/profiling/deobfuscation.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/profiling/heap_graph.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/profiling/profile_common.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/profiling/profile_packet.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/profiling/smaps.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/trace/profiling:zero
genrule {
- name: "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
- srcs: [
- "protos/perfetto/trace/profiling/deobfuscation.proto",
- "protos/perfetto/trace/profiling/heap_graph.proto",
- "protos/perfetto/trace/profiling/profile_common.proto",
- "protos/perfetto/trace/profiling/profile_packet.proto",
- "protos/perfetto/trace/profiling/smaps.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/profiling/deobfuscation.pbzero.h",
- "external/perfetto/protos/perfetto/trace/profiling/heap_graph.pbzero.h",
- "external/perfetto/protos/perfetto/trace/profiling/profile_common.pbzero.h",
- "external/perfetto/protos/perfetto/trace/profiling/profile_packet.pbzero.h",
- "external/perfetto/protos/perfetto/trace/profiling/smaps.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/profiling/deobfuscation.proto",
+ "protos/perfetto/trace/profiling/heap_graph.proto",
+ "protos/perfetto/trace/profiling/profile_common.proto",
+ "protos/perfetto/trace/profiling/profile_packet.proto",
+ "protos/perfetto/trace/profiling/smaps.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/profiling/deobfuscation.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/profiling/heap_graph.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/profiling/profile_common.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/profiling/profile_packet.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/profiling/smaps.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/ps:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_ps_cpp_gen",
- srcs: [
- "protos/perfetto/trace/ps/process_stats.proto",
- "protos/perfetto/trace/ps/process_tree.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/ps/process_stats.gen.cc",
- "external/perfetto/protos/perfetto/trace/ps/process_tree.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_ps_cpp_gen",
+ srcs: [
+ "protos/perfetto/trace/ps/process_stats.proto",
+ "protos/perfetto/trace/ps/process_tree.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/ps/process_stats.gen.cc",
+ "external/perfetto/protos/perfetto/trace/ps/process_tree.gen.cc",
+ ],
}
// GN: //protos/perfetto/trace/ps:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_ps_cpp_gen_headers",
- srcs: [
- "protos/perfetto/trace/ps/process_stats.proto",
- "protos/perfetto/trace/ps/process_tree.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/ps/process_stats.gen.h",
- "external/perfetto/protos/perfetto/trace/ps/process_tree.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_ps_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/ps/process_stats.proto",
+ "protos/perfetto/trace/ps/process_tree.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/ps/process_stats.gen.h",
+ "external/perfetto/protos/perfetto/trace/ps/process_tree.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/ps:lite
genrule {
- name: "perfetto_protos_perfetto_trace_ps_lite_gen",
- srcs: [
- "protos/perfetto/trace/ps/process_stats.proto",
- "protos/perfetto/trace/ps/process_tree.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/ps/process_stats.pb.cc",
- "external/perfetto/protos/perfetto/trace/ps/process_tree.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_ps_lite_gen",
+ srcs: [
+ "protos/perfetto/trace/ps/process_stats.proto",
+ "protos/perfetto/trace/ps/process_tree.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/ps/process_stats.pb.cc",
+ "external/perfetto/protos/perfetto/trace/ps/process_tree.pb.cc",
+ ],
}
// GN: //protos/perfetto/trace/ps:lite
genrule {
- name: "perfetto_protos_perfetto_trace_ps_lite_gen_headers",
- srcs: [
- "protos/perfetto/trace/ps/process_stats.proto",
- "protos/perfetto/trace/ps/process_tree.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/ps/process_stats.pb.h",
- "external/perfetto/protos/perfetto/trace/ps/process_tree.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_ps_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/ps/process_stats.proto",
+ "protos/perfetto/trace/ps/process_tree.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/ps/process_stats.pb.h",
+ "external/perfetto/protos/perfetto/trace/ps/process_tree.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/ps:zero
genrule {
- name: "perfetto_protos_perfetto_trace_ps_zero_gen",
- srcs: [
- "protos/perfetto/trace/ps/process_stats.proto",
- "protos/perfetto/trace/ps/process_tree.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/ps/process_stats.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/ps/process_tree.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_ps_zero_gen",
+ srcs: [
+ "protos/perfetto/trace/ps/process_stats.proto",
+ "protos/perfetto/trace/ps/process_tree.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/ps/process_stats.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/ps/process_tree.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/trace/ps:zero
genrule {
- name: "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
- srcs: [
- "protos/perfetto/trace/ps/process_stats.proto",
- "protos/perfetto/trace/ps/process_tree.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/ps/process_stats.pbzero.h",
- "external/perfetto/protos/perfetto/trace/ps/process_tree.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/ps/process_stats.proto",
+ "protos/perfetto/trace/ps/process_tree.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/ps/process_stats.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/ps/process_tree.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/sys_stats:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_sys_stats_cpp_gen",
- srcs: [
- "protos/perfetto/trace/sys_stats/sys_stats.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_sys_stats_cpp_gen",
+ srcs: [
+ "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.gen.cc",
+ ],
}
// GN: //protos/perfetto/trace/sys_stats:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_sys_stats_cpp_gen_headers",
- srcs: [
- "protos/perfetto/trace/sys_stats/sys_stats.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_sys_stats_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/sys_stats:lite
genrule {
- name: "perfetto_protos_perfetto_trace_sys_stats_lite_gen",
- srcs: [
- "protos/perfetto/trace/sys_stats/sys_stats.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_sys_stats_lite_gen",
+ srcs: [
+ "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.pb.cc",
+ ],
}
// GN: //protos/perfetto/trace/sys_stats:lite
genrule {
- name: "perfetto_protos_perfetto_trace_sys_stats_lite_gen_headers",
- srcs: [
- "protos/perfetto/trace/sys_stats/sys_stats.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_sys_stats_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/sys_stats:zero
genrule {
- name: "perfetto_protos_perfetto_trace_sys_stats_zero_gen",
- srcs: [
- "protos/perfetto/trace/sys_stats/sys_stats.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_sys_stats_zero_gen",
+ srcs: [
+ "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/trace/sys_stats:zero
genrule {
- name: "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
- srcs: [
- "protos/perfetto/trace/sys_stats/sys_stats.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/sys_stats/sys_stats.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/system_info:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_system_info_cpp_gen",
- srcs: [
- "protos/perfetto/trace/system_info/cpu_info.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/system_info/cpu_info.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_system_info_cpp_gen",
+ srcs: [
+ "protos/perfetto/trace/system_info/cpu_info.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/system_info/cpu_info.gen.cc",
+ ],
}
// GN: //protos/perfetto/trace/system_info:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_system_info_cpp_gen_headers",
- srcs: [
- "protos/perfetto/trace/system_info/cpu_info.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/system_info/cpu_info.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_system_info_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/system_info/cpu_info.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/system_info/cpu_info.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/system_info:lite
genrule {
- name: "perfetto_protos_perfetto_trace_system_info_lite_gen",
- srcs: [
- "protos/perfetto/trace/system_info/cpu_info.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/system_info/cpu_info.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_system_info_lite_gen",
+ srcs: [
+ "protos/perfetto/trace/system_info/cpu_info.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/system_info/cpu_info.pb.cc",
+ ],
}
// GN: //protos/perfetto/trace/system_info:lite
genrule {
- name: "perfetto_protos_perfetto_trace_system_info_lite_gen_headers",
- srcs: [
- "protos/perfetto/trace/system_info/cpu_info.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/system_info/cpu_info.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_system_info_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/system_info/cpu_info.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/system_info/cpu_info.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/system_info:zero
genrule {
- name: "perfetto_protos_perfetto_trace_system_info_zero_gen",
- srcs: [
- "protos/perfetto/trace/system_info/cpu_info.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/system_info/cpu_info.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_system_info_zero_gen",
+ srcs: [
+ "protos/perfetto/trace/system_info/cpu_info.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/system_info/cpu_info.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/trace/system_info:zero
genrule {
- name: "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
- srcs: [
- "protos/perfetto/trace/system_info/cpu_info.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/system_info/cpu_info.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/system_info/cpu_info.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/system_info/cpu_info.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/track_event:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_track_event_cpp_gen",
- srcs: [
- "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
- "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
- "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
- "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
- "protos/perfetto/trace/track_event/chrome_latency_info.proto",
- "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
- "protos/perfetto/trace/track_event/chrome_message_pump.proto",
- "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_user_event.proto",
- "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
- "protos/perfetto/trace/track_event/counter_descriptor.proto",
- "protos/perfetto/trace/track_event/debug_annotation.proto",
- "protos/perfetto/trace/track_event/log_message.proto",
- "protos/perfetto/trace/track_event/process_descriptor.proto",
- "protos/perfetto/trace/track_event/source_location.proto",
- "protos/perfetto/trace/track_event/task_execution.proto",
- "protos/perfetto/trace/track_event/thread_descriptor.proto",
- "protos/perfetto/trace/track_event/track_descriptor.proto",
- "protos/perfetto/trace/track_event/track_event.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/track_event/chrome_application_state_info.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_frame_reporter.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_histogram_sample.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_keyed_service.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_latency_info.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_message_pump.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_process_descriptor.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_user_event.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/counter_descriptor.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/debug_annotation.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/log_message.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/process_descriptor.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/source_location.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/task_execution.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/thread_descriptor.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/track_descriptor.gen.cc",
- "external/perfetto/protos/perfetto/trace/track_event/track_event.gen.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_track_event_cpp_gen",
+ srcs: [
+ "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
+ "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
+ "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
+ "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
+ "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
+ "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
+ "protos/perfetto/trace/track_event/chrome_latency_info.proto",
+ "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
+ "protos/perfetto/trace/track_event/chrome_message_pump.proto",
+ "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
+ "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
+ "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
+ "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
+ "protos/perfetto/trace/track_event/chrome_user_event.proto",
+ "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
+ "protos/perfetto/trace/track_event/counter_descriptor.proto",
+ "protos/perfetto/trace/track_event/debug_annotation.proto",
+ "protos/perfetto/trace/track_event/log_message.proto",
+ "protos/perfetto/trace/track_event/process_descriptor.proto",
+ "protos/perfetto/trace/track_event/source_location.proto",
+ "protos/perfetto/trace/track_event/task_execution.proto",
+ "protos/perfetto/trace/track_event/thread_descriptor.proto",
+ "protos/perfetto/trace/track_event/track_descriptor.proto",
+ "protos/perfetto/trace/track_event/track_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_application_state_info.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_frame_reporter.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_histogram_sample.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_keyed_service.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_latency_info.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_message_pump.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_process_descriptor.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_user_event.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/counter_descriptor.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/debug_annotation.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/log_message.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/process_descriptor.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/source_location.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/task_execution.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/thread_descriptor.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/track_descriptor.gen.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/track_event.gen.cc",
+ ],
}
// GN: //protos/perfetto/trace/track_event:cpp
genrule {
- name: "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
- srcs: [
- "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
- "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
- "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
- "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
- "protos/perfetto/trace/track_event/chrome_latency_info.proto",
- "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
- "protos/perfetto/trace/track_event/chrome_message_pump.proto",
- "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_user_event.proto",
- "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
- "protos/perfetto/trace/track_event/counter_descriptor.proto",
- "protos/perfetto/trace/track_event/debug_annotation.proto",
- "protos/perfetto/trace/track_event/log_message.proto",
- "protos/perfetto/trace/track_event/process_descriptor.proto",
- "protos/perfetto/trace/track_event/source_location.proto",
- "protos/perfetto/trace/track_event/task_execution.proto",
- "protos/perfetto/trace/track_event/thread_descriptor.proto",
- "protos/perfetto/trace/track_event/track_descriptor.proto",
- "protos/perfetto/trace/track_event/track_event.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/track_event/chrome_application_state_info.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_frame_reporter.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_histogram_sample.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_keyed_service.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_latency_info.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_message_pump.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_user_event.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/counter_descriptor.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/debug_annotation.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/log_message.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/process_descriptor.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/source_location.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/task_execution.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/thread_descriptor.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/track_descriptor.gen.h",
- "external/perfetto/protos/perfetto/trace/track_event/track_event.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
+ "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
+ "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
+ "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
+ "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
+ "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
+ "protos/perfetto/trace/track_event/chrome_latency_info.proto",
+ "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
+ "protos/perfetto/trace/track_event/chrome_message_pump.proto",
+ "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
+ "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
+ "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
+ "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
+ "protos/perfetto/trace/track_event/chrome_user_event.proto",
+ "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
+ "protos/perfetto/trace/track_event/counter_descriptor.proto",
+ "protos/perfetto/trace/track_event/debug_annotation.proto",
+ "protos/perfetto/trace/track_event/log_message.proto",
+ "protos/perfetto/trace/track_event/process_descriptor.proto",
+ "protos/perfetto/trace/track_event/source_location.proto",
+ "protos/perfetto/trace/track_event/task_execution.proto",
+ "protos/perfetto/trace/track_event/thread_descriptor.proto",
+ "protos/perfetto/trace/track_event/track_descriptor.proto",
+ "protos/perfetto/trace/track_event/track_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_application_state_info.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_frame_reporter.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_histogram_sample.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_keyed_service.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_latency_info.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_message_pump.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_user_event.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/counter_descriptor.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/debug_annotation.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/log_message.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/process_descriptor.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/source_location.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/task_execution.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/thread_descriptor.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/track_descriptor.gen.h",
+ "external/perfetto/protos/perfetto/trace/track_event/track_event.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
+}
+
+// GN: //protos/perfetto/trace/track_event:descriptor
+genrule {
+ name: "perfetto_protos_perfetto_trace_track_event_descriptor",
+ srcs: [
+ "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
+ "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
+ "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
+ "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
+ "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
+ "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
+ "protos/perfetto/trace/track_event/chrome_latency_info.proto",
+ "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
+ "protos/perfetto/trace/track_event/chrome_message_pump.proto",
+ "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
+ "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
+ "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
+ "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
+ "protos/perfetto/trace/track_event/chrome_user_event.proto",
+ "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
+ "protos/perfetto/trace/track_event/counter_descriptor.proto",
+ "protos/perfetto/trace/track_event/debug_annotation.proto",
+ "protos/perfetto/trace/track_event/log_message.proto",
+ "protos/perfetto/trace/track_event/process_descriptor.proto",
+ "protos/perfetto/trace/track_event/source_location.proto",
+ "protos/perfetto/trace/track_event/task_execution.proto",
+ "protos/perfetto/trace/track_event/thread_descriptor.proto",
+ "protos/perfetto/trace/track_event/track_descriptor.proto",
+ "protos/perfetto/trace/track_event/track_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --descriptor_set_out=$(out) $(in)",
+ out: [
+ "perfetto_protos_perfetto_trace_track_event_descriptor.bin",
+ ],
}
// GN: //protos/perfetto/trace/track_event:lite
genrule {
- name: "perfetto_protos_perfetto_trace_track_event_lite_gen",
- srcs: [
- "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
- "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
- "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
- "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
- "protos/perfetto/trace/track_event/chrome_latency_info.proto",
- "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
- "protos/perfetto/trace/track_event/chrome_message_pump.proto",
- "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_user_event.proto",
- "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
- "protos/perfetto/trace/track_event/counter_descriptor.proto",
- "protos/perfetto/trace/track_event/debug_annotation.proto",
- "protos/perfetto/trace/track_event/log_message.proto",
- "protos/perfetto/trace/track_event/process_descriptor.proto",
- "protos/perfetto/trace/track_event/source_location.proto",
- "protos/perfetto/trace/track_event/task_execution.proto",
- "protos/perfetto/trace/track_event/thread_descriptor.proto",
- "protos/perfetto/trace/track_event/track_descriptor.proto",
- "protos/perfetto/trace/track_event/track_event.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/track_event/chrome_application_state_info.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_content_settings_event_info.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_frame_reporter.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_histogram_sample.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_keyed_service.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_latency_info.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_legacy_ipc.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_message_pump.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_mojo_event_info.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_process_descriptor.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_thread_descriptor.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_user_event.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_window_handle_event_info.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/counter_descriptor.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/debug_annotation.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/log_message.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/process_descriptor.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/source_location.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/task_execution.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/thread_descriptor.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/track_descriptor.pb.cc",
- "external/perfetto/protos/perfetto/trace/track_event/track_event.pb.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_track_event_lite_gen",
+ srcs: [
+ "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
+ "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
+ "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
+ "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
+ "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
+ "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
+ "protos/perfetto/trace/track_event/chrome_latency_info.proto",
+ "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
+ "protos/perfetto/trace/track_event/chrome_message_pump.proto",
+ "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
+ "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
+ "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
+ "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
+ "protos/perfetto/trace/track_event/chrome_user_event.proto",
+ "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
+ "protos/perfetto/trace/track_event/counter_descriptor.proto",
+ "protos/perfetto/trace/track_event/debug_annotation.proto",
+ "protos/perfetto/trace/track_event/log_message.proto",
+ "protos/perfetto/trace/track_event/process_descriptor.proto",
+ "protos/perfetto/trace/track_event/source_location.proto",
+ "protos/perfetto/trace/track_event/task_execution.proto",
+ "protos/perfetto/trace/track_event/thread_descriptor.proto",
+ "protos/perfetto/trace/track_event/track_descriptor.proto",
+ "protos/perfetto/trace/track_event/track_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_application_state_info.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_content_settings_event_info.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_frame_reporter.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_histogram_sample.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_keyed_service.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_latency_info.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_legacy_ipc.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_message_pump.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_mojo_event_info.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_process_descriptor.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_thread_descriptor.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_user_event.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_window_handle_event_info.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/counter_descriptor.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/debug_annotation.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/log_message.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/process_descriptor.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/source_location.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/task_execution.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/thread_descriptor.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/track_descriptor.pb.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/track_event.pb.cc",
+ ],
}
// GN: //protos/perfetto/trace/track_event:lite
genrule {
- name: "perfetto_protos_perfetto_trace_track_event_lite_gen_headers",
- srcs: [
- "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
- "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
- "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
- "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
- "protos/perfetto/trace/track_event/chrome_latency_info.proto",
- "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
- "protos/perfetto/trace/track_event/chrome_message_pump.proto",
- "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_user_event.proto",
- "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
- "protos/perfetto/trace/track_event/counter_descriptor.proto",
- "protos/perfetto/trace/track_event/debug_annotation.proto",
- "protos/perfetto/trace/track_event/log_message.proto",
- "protos/perfetto/trace/track_event/process_descriptor.proto",
- "protos/perfetto/trace/track_event/source_location.proto",
- "protos/perfetto/trace/track_event/task_execution.proto",
- "protos/perfetto/trace/track_event/thread_descriptor.proto",
- "protos/perfetto/trace/track_event/track_descriptor.proto",
- "protos/perfetto/trace/track_event/track_event.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/track_event/chrome_application_state_info.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_content_settings_event_info.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_frame_reporter.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_histogram_sample.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_keyed_service.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_latency_info.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_legacy_ipc.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_message_pump.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_mojo_event_info.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_process_descriptor.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_thread_descriptor.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_user_event.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_window_handle_event_info.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/counter_descriptor.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/debug_annotation.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/log_message.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/process_descriptor.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/source_location.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/task_execution.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/thread_descriptor.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/track_descriptor.pb.h",
- "external/perfetto/protos/perfetto/trace/track_event/track_event.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
-}
-
-// GN: //protos/perfetto/trace/track_event:track_event_descriptor
-genrule {
- name: "perfetto_protos_perfetto_trace_track_event_track_event_descriptor",
- srcs: [
- "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
- "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
- "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
- "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
- "protos/perfetto/trace/track_event/chrome_latency_info.proto",
- "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
- "protos/perfetto/trace/track_event/chrome_message_pump.proto",
- "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_user_event.proto",
- "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
- "protos/perfetto/trace/track_event/counter_descriptor.proto",
- "protos/perfetto/trace/track_event/debug_annotation.proto",
- "protos/perfetto/trace/track_event/log_message.proto",
- "protos/perfetto/trace/track_event/process_descriptor.proto",
- "protos/perfetto/trace/track_event/source_location.proto",
- "protos/perfetto/trace/track_event/task_execution.proto",
- "protos/perfetto/trace/track_event/thread_descriptor.proto",
- "protos/perfetto/trace/track_event/track_descriptor.proto",
- "protos/perfetto/trace/track_event/track_event.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --descriptor_set_out=$(out) $(in)",
- out: [
- "perfetto_protos_perfetto_trace_track_event_track_event_descriptor.bin",
- ],
+ name: "perfetto_protos_perfetto_trace_track_event_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
+ "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
+ "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
+ "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
+ "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
+ "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
+ "protos/perfetto/trace/track_event/chrome_latency_info.proto",
+ "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
+ "protos/perfetto/trace/track_event/chrome_message_pump.proto",
+ "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
+ "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
+ "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
+ "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
+ "protos/perfetto/trace/track_event/chrome_user_event.proto",
+ "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
+ "protos/perfetto/trace/track_event/counter_descriptor.proto",
+ "protos/perfetto/trace/track_event/debug_annotation.proto",
+ "protos/perfetto/trace/track_event/log_message.proto",
+ "protos/perfetto/trace/track_event/process_descriptor.proto",
+ "protos/perfetto/trace/track_event/source_location.proto",
+ "protos/perfetto/trace/track_event/task_execution.proto",
+ "protos/perfetto/trace/track_event/thread_descriptor.proto",
+ "protos/perfetto/trace/track_event/track_descriptor.proto",
+ "protos/perfetto/trace/track_event/track_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_application_state_info.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_content_settings_event_info.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_frame_reporter.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_histogram_sample.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_keyed_service.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_latency_info.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_legacy_ipc.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_message_pump.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_mojo_event_info.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_process_descriptor.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_thread_descriptor.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_user_event.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_window_handle_event_info.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/counter_descriptor.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/debug_annotation.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/log_message.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/process_descriptor.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/source_location.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/task_execution.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/thread_descriptor.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/track_descriptor.pb.h",
+ "external/perfetto/protos/perfetto/trace/track_event/track_event.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //protos/perfetto/trace/track_event:zero
genrule {
- name: "perfetto_protos_perfetto_trace_track_event_zero_gen",
- srcs: [
- "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
- "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
- "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
- "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
- "protos/perfetto/trace/track_event/chrome_latency_info.proto",
- "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
- "protos/perfetto/trace/track_event/chrome_message_pump.proto",
- "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_user_event.proto",
- "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
- "protos/perfetto/trace/track_event/counter_descriptor.proto",
- "protos/perfetto/trace/track_event/debug_annotation.proto",
- "protos/perfetto/trace/track_event/log_message.proto",
- "protos/perfetto/trace/track_event/process_descriptor.proto",
- "protos/perfetto/trace/track_event/source_location.proto",
- "protos/perfetto/trace/track_event/task_execution.proto",
- "protos/perfetto/trace/track_event/thread_descriptor.proto",
- "protos/perfetto/trace/track_event/track_descriptor.proto",
- "protos/perfetto/trace/track_event/track_event.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/track_event/chrome_application_state_info.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_content_settings_event_info.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_frame_reporter.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_histogram_sample.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_keyed_service.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_latency_info.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_legacy_ipc.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_message_pump.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_mojo_event_info.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_process_descriptor.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_thread_descriptor.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_user_event.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_window_handle_event_info.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/counter_descriptor.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/debug_annotation.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/log_message.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/process_descriptor.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/source_location.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/task_execution.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/thread_descriptor.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/track_descriptor.pbzero.cc",
- "external/perfetto/protos/perfetto/trace/track_event/track_event.pbzero.cc",
- ],
+ name: "perfetto_protos_perfetto_trace_track_event_zero_gen",
+ srcs: [
+ "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
+ "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
+ "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
+ "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
+ "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
+ "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
+ "protos/perfetto/trace/track_event/chrome_latency_info.proto",
+ "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
+ "protos/perfetto/trace/track_event/chrome_message_pump.proto",
+ "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
+ "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
+ "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
+ "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
+ "protos/perfetto/trace/track_event/chrome_user_event.proto",
+ "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
+ "protos/perfetto/trace/track_event/counter_descriptor.proto",
+ "protos/perfetto/trace/track_event/debug_annotation.proto",
+ "protos/perfetto/trace/track_event/log_message.proto",
+ "protos/perfetto/trace/track_event/process_descriptor.proto",
+ "protos/perfetto/trace/track_event/source_location.proto",
+ "protos/perfetto/trace/track_event/task_execution.proto",
+ "protos/perfetto/trace/track_event/thread_descriptor.proto",
+ "protos/perfetto/trace/track_event/track_descriptor.proto",
+ "protos/perfetto/trace/track_event/track_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_application_state_info.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_content_settings_event_info.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_frame_reporter.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_histogram_sample.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_keyed_service.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_latency_info.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_legacy_ipc.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_message_pump.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_mojo_event_info.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_process_descriptor.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_thread_descriptor.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_user_event.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_window_handle_event_info.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/counter_descriptor.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/debug_annotation.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/log_message.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/process_descriptor.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/source_location.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/task_execution.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/thread_descriptor.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/track_descriptor.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/track_event/track_event.pbzero.cc",
+ ],
}
// GN: //protos/perfetto/trace/track_event:zero
genrule {
- name: "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- srcs: [
- "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
- "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
- "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
- "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
- "protos/perfetto/trace/track_event/chrome_latency_info.proto",
- "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
- "protos/perfetto/trace/track_event/chrome_message_pump.proto",
- "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_user_event.proto",
- "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
- "protos/perfetto/trace/track_event/counter_descriptor.proto",
- "protos/perfetto/trace/track_event/debug_annotation.proto",
- "protos/perfetto/trace/track_event/log_message.proto",
- "protos/perfetto/trace/track_event/process_descriptor.proto",
- "protos/perfetto/trace/track_event/source_location.proto",
- "protos/perfetto/trace/track_event/task_execution.proto",
- "protos/perfetto/trace/track_event/thread_descriptor.proto",
- "protos/perfetto/trace/track_event/track_descriptor.proto",
- "protos/perfetto/trace/track_event/track_event.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/perfetto/trace/track_event/chrome_application_state_info.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_content_settings_event_info.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_frame_reporter.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_histogram_sample.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_keyed_service.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_latency_info.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_legacy_ipc.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_message_pump.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_mojo_event_info.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_process_descriptor.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_thread_descriptor.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_user_event.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/chrome_window_handle_event_info.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/counter_descriptor.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/debug_annotation.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/log_message.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/process_descriptor.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/source_location.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/task_execution.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/thread_descriptor.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/track_descriptor.pbzero.h",
- "external/perfetto/protos/perfetto/trace/track_event/track_event.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
-}
-
-// GN: //protos/third_party/chromium:chrome_track_event_descriptor
-genrule {
- name: "perfetto_protos_third_party_chromium_chrome_track_event_descriptor",
- srcs: [
- "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
- "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
- "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
- "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
- "protos/perfetto/trace/track_event/chrome_latency_info.proto",
- "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
- "protos/perfetto/trace/track_event/chrome_message_pump.proto",
- "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
- "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
- "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
- "protos/perfetto/trace/track_event/chrome_user_event.proto",
- "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
- "protos/perfetto/trace/track_event/counter_descriptor.proto",
- "protos/perfetto/trace/track_event/debug_annotation.proto",
- "protos/perfetto/trace/track_event/log_message.proto",
- "protos/perfetto/trace/track_event/process_descriptor.proto",
- "protos/perfetto/trace/track_event/source_location.proto",
- "protos/perfetto/trace/track_event/task_execution.proto",
- "protos/perfetto/trace/track_event/thread_descriptor.proto",
- "protos/perfetto/trace/track_event/track_descriptor.proto",
- "protos/perfetto/trace/track_event/track_event.proto",
- "protos/third_party/chromium/chrome_track_event.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --descriptor_set_out=$(out) $(in)",
- out: [
- "perfetto_protos_third_party_chromium_chrome_track_event_descriptor.bin",
- ],
+ name: "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
+ "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
+ "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
+ "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
+ "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
+ "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
+ "protos/perfetto/trace/track_event/chrome_latency_info.proto",
+ "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
+ "protos/perfetto/trace/track_event/chrome_message_pump.proto",
+ "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
+ "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
+ "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
+ "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
+ "protos/perfetto/trace/track_event/chrome_user_event.proto",
+ "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
+ "protos/perfetto/trace/track_event/counter_descriptor.proto",
+ "protos/perfetto/trace/track_event/debug_annotation.proto",
+ "protos/perfetto/trace/track_event/log_message.proto",
+ "protos/perfetto/trace/track_event/process_descriptor.proto",
+ "protos/perfetto/trace/track_event/source_location.proto",
+ "protos/perfetto/trace/track_event/task_execution.proto",
+ "protos/perfetto/trace/track_event/thread_descriptor.proto",
+ "protos/perfetto/trace/track_event/track_descriptor.proto",
+ "protos/perfetto/trace/track_event/track_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_application_state_info.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_content_settings_event_info.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_frame_reporter.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_histogram_sample.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_keyed_service.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_latency_info.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_legacy_ipc.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_message_pump.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_mojo_event_info.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_process_descriptor.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_thread_descriptor.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_user_event.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/chrome_window_handle_event_info.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/counter_descriptor.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/debug_annotation.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/log_message.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/process_descriptor.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/source_location.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/task_execution.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/thread_descriptor.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/track_descriptor.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/track_event/track_event.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
+}
+
+// GN: //protos/perfetto/trace/translation:cpp
+genrule {
+ name: "perfetto_protos_perfetto_trace_translation_cpp_gen",
+ srcs: [
+ "protos/perfetto/trace/translation/translation_table.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/translation/translation_table.gen.cc",
+ ],
+}
+
+// GN: //protos/perfetto/trace/translation:cpp
+genrule {
+ name: "perfetto_protos_perfetto_trace_translation_cpp_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/translation/translation_table.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/translation/translation_table.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
+}
+
+// GN: //protos/perfetto/trace/translation:lite
+genrule {
+ name: "perfetto_protos_perfetto_trace_translation_lite_gen",
+ srcs: [
+ "protos/perfetto/trace/translation/translation_table.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/translation/translation_table.pb.cc",
+ ],
+}
+
+// GN: //protos/perfetto/trace/translation:lite
+genrule {
+ name: "perfetto_protos_perfetto_trace_translation_lite_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/translation/translation_table.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/translation/translation_table.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
+}
+
+// GN: //protos/perfetto/trace/translation:zero
+genrule {
+ name: "perfetto_protos_perfetto_trace_translation_zero_gen",
+ srcs: [
+ "protos/perfetto/trace/translation/translation_table.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/translation/translation_table.pbzero.cc",
+ ],
+}
+
+// GN: //protos/perfetto/trace/translation:zero
+genrule {
+ name: "perfetto_protos_perfetto_trace_translation_zero_gen_headers",
+ srcs: [
+ "protos/perfetto/trace/translation/translation_table.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/perfetto/trace/translation/translation_table.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
+}
+
+// GN: //protos/third_party/chromium:descriptor
+genrule {
+ name: "perfetto_protos_third_party_chromium_descriptor",
+ srcs: [
+ "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
+ "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
+ "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
+ "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
+ "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
+ "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
+ "protos/perfetto/trace/track_event/chrome_latency_info.proto",
+ "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
+ "protos/perfetto/trace/track_event/chrome_message_pump.proto",
+ "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
+ "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
+ "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
+ "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
+ "protos/perfetto/trace/track_event/chrome_user_event.proto",
+ "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
+ "protos/perfetto/trace/track_event/counter_descriptor.proto",
+ "protos/perfetto/trace/track_event/debug_annotation.proto",
+ "protos/perfetto/trace/track_event/log_message.proto",
+ "protos/perfetto/trace/track_event/process_descriptor.proto",
+ "protos/perfetto/trace/track_event/source_location.proto",
+ "protos/perfetto/trace/track_event/task_execution.proto",
+ "protos/perfetto/trace/track_event/thread_descriptor.proto",
+ "protos/perfetto/trace/track_event/track_descriptor.proto",
+ "protos/perfetto/trace/track_event/track_event.proto",
+ "protos/third_party/chromium/chrome_track_event.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --descriptor_set_out=$(out) $(in)",
+ out: [
+ "perfetto_protos_third_party_chromium_descriptor.bin",
+ ],
}
// GN: //protos/third_party/pprof:zero
genrule {
- name: "perfetto_protos_third_party_pprof_zero_gen",
- srcs: [
- "protos/third_party/pprof/profile.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/third_party/pprof/profile.pbzero.cc",
- ],
+ name: "perfetto_protos_third_party_pprof_zero_gen",
+ srcs: [
+ "protos/third_party/pprof/profile.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/third_party/pprof/profile.pbzero.cc",
+ ],
}
// GN: //protos/third_party/pprof:zero
genrule {
- name: "perfetto_protos_third_party_pprof_zero_gen_headers",
- srcs: [
- "protos/third_party/pprof/profile.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/protos/third_party/pprof/profile.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_protos_third_party_pprof_zero_gen_headers",
+ srcs: [
+ "protos/third_party/pprof/profile.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/protos/third_party/pprof/profile.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //src/android_internal:headers
filegroup {
- name: "perfetto_src_android_internal_headers",
+ name: "perfetto_src_android_internal_headers",
}
// GN: //src/android_internal:lazy_library_loader
filegroup {
- name: "perfetto_src_android_internal_lazy_library_loader",
- srcs: [
- "src/android_internal/lazy_library_loader.cc",
- ],
+ name: "perfetto_src_android_internal_lazy_library_loader",
+ srcs: [
+ "src/android_internal/lazy_library_loader.cc",
+ ],
}
// GN: //src/android_stats:android_stats
filegroup {
- name: "perfetto_src_android_stats_android_stats",
- srcs: [
- "src/android_stats/statsd_logging_helper.cc",
- ],
+ name: "perfetto_src_android_stats_android_stats",
+ srcs: [
+ "src/android_stats/statsd_logging_helper.cc",
+ ],
}
// GN: //src/android_stats:perfetto_atoms
filegroup {
- name: "perfetto_src_android_stats_perfetto_atoms",
+ name: "perfetto_src_android_stats_perfetto_atoms",
}
// GN: //src/base:base
filegroup {
- name: "perfetto_src_base_base",
- srcs: [
- "src/base/ctrl_c_handler.cc",
- "src/base/event_fd.cc",
- "src/base/file_utils.cc",
- "src/base/getopt_compat.cc",
- "src/base/logging.cc",
- "src/base/metatrace.cc",
- "src/base/paged_memory.cc",
- "src/base/periodic_task.cc",
- "src/base/pipe.cc",
- "src/base/status.cc",
- "src/base/string_splitter.cc",
- "src/base/string_utils.cc",
- "src/base/string_view.cc",
- "src/base/subprocess.cc",
- "src/base/subprocess_posix.cc",
- "src/base/subprocess_windows.cc",
- "src/base/temp_file.cc",
- "src/base/thread_checker.cc",
- "src/base/thread_task_runner.cc",
- "src/base/time.cc",
- "src/base/unix_task_runner.cc",
- "src/base/utils.cc",
- "src/base/uuid.cc",
- "src/base/version.cc",
- "src/base/virtual_destructors.cc",
- "src/base/waitable_event.cc",
- "src/base/watchdog_posix.cc",
- ],
+ name: "perfetto_src_base_base",
+ srcs: [
+ "src/base/android_utils.cc",
+ "src/base/base64.cc",
+ "src/base/crash_keys.cc",
+ "src/base/ctrl_c_handler.cc",
+ "src/base/event_fd.cc",
+ "src/base/file_utils.cc",
+ "src/base/getopt_compat.cc",
+ "src/base/logging.cc",
+ "src/base/metatrace.cc",
+ "src/base/paged_memory.cc",
+ "src/base/periodic_task.cc",
+ "src/base/pipe.cc",
+ "src/base/status.cc",
+ "src/base/string_splitter.cc",
+ "src/base/string_utils.cc",
+ "src/base/string_view.cc",
+ "src/base/subprocess.cc",
+ "src/base/subprocess_posix.cc",
+ "src/base/subprocess_windows.cc",
+ "src/base/temp_file.cc",
+ "src/base/thread_checker.cc",
+ "src/base/thread_task_runner.cc",
+ "src/base/time.cc",
+ "src/base/unix_task_runner.cc",
+ "src/base/utils.cc",
+ "src/base/uuid.cc",
+ "src/base/version.cc",
+ "src/base/virtual_destructors.cc",
+ "src/base/waitable_event.cc",
+ "src/base/watchdog_posix.cc",
+ ],
+}
+
+// GN: //src/base/http:http
+filegroup {
+ name: "perfetto_src_base_http_http",
+ srcs: [
+ "src/base/http/http_server.cc",
+ "src/base/http/sha1.cc",
+ ],
+}
+
+// GN: //src/base/http:unittests
+filegroup {
+ name: "perfetto_src_base_http_unittests",
+ srcs: [
+ "src/base/http/http_server_unittest.cc",
+ "src/base/http/sha1_unittest.cc",
+ ],
}
// GN: //src/base:test_support
filegroup {
- name: "perfetto_src_base_test_support",
- srcs: [
- "src/base/test/test_task_runner.cc",
- "src/base/test/utils.cc",
- "src/base/test/vm_test_utils.cc",
- ],
+ name: "perfetto_src_base_test_support",
+ srcs: [
+ "src/base/test/test_task_runner.cc",
+ "src/base/test/tmp_dir_tree.cc",
+ "src/base/test/utils.cc",
+ "src/base/test/vm_test_utils.cc",
+ ],
}
// GN: //src/base:unittests
filegroup {
- name: "perfetto_src_base_unittests",
- srcs: [
- "src/base/circular_queue_unittest.cc",
- "src/base/flat_set_unittest.cc",
- "src/base/getopt_compat_unittest.cc",
- "src/base/logging_unittest.cc",
- "src/base/metatrace_unittest.cc",
- "src/base/no_destructor_unittest.cc",
- "src/base/optional_unittest.cc",
- "src/base/paged_memory_unittest.cc",
- "src/base/periodic_task_unittest.cc",
- "src/base/scoped_file_unittest.cc",
- "src/base/string_splitter_unittest.cc",
- "src/base/string_utils_unittest.cc",
- "src/base/string_view_unittest.cc",
- "src/base/string_writer_unittest.cc",
- "src/base/subprocess_unittest.cc",
- "src/base/task_runner_unittest.cc",
- "src/base/temp_file_unittest.cc",
- "src/base/thread_checker_unittest.cc",
- "src/base/thread_task_runner_unittest.cc",
- "src/base/time_unittest.cc",
- "src/base/unix_socket_unittest.cc",
- "src/base/utils_unittest.cc",
- "src/base/uuid_unittest.cc",
- "src/base/watchdog_posix_unittest.cc",
- "src/base/watchdog_unittest.cc",
- "src/base/weak_ptr_unittest.cc",
- ],
+ name: "perfetto_src_base_unittests",
+ srcs: [
+ "src/base/base64_unittest.cc",
+ "src/base/circular_queue_unittest.cc",
+ "src/base/flat_hash_map_unittest.cc",
+ "src/base/flat_set_unittest.cc",
+ "src/base/getopt_compat_unittest.cc",
+ "src/base/logging_unittest.cc",
+ "src/base/metatrace_unittest.cc",
+ "src/base/no_destructor_unittest.cc",
+ "src/base/optional_unittest.cc",
+ "src/base/paged_memory_unittest.cc",
+ "src/base/periodic_task_unittest.cc",
+ "src/base/scoped_file_unittest.cc",
+ "src/base/small_vector_unittest.cc",
+ "src/base/string_splitter_unittest.cc",
+ "src/base/string_utils_unittest.cc",
+ "src/base/string_view_unittest.cc",
+ "src/base/string_writer_unittest.cc",
+ "src/base/subprocess_unittest.cc",
+ "src/base/task_runner_unittest.cc",
+ "src/base/temp_file_unittest.cc",
+ "src/base/thread_checker_unittest.cc",
+ "src/base/thread_task_runner_unittest.cc",
+ "src/base/time_unittest.cc",
+ "src/base/unix_socket_unittest.cc",
+ "src/base/utils_unittest.cc",
+ "src/base/uuid_unittest.cc",
+ "src/base/watchdog_posix_unittest.cc",
+ "src/base/watchdog_unittest.cc",
+ "src/base/weak_ptr_unittest.cc",
+ ],
}
// GN: //src/base:unix_socket
filegroup {
- name: "perfetto_src_base_unix_socket",
- srcs: [
- "src/base/unix_socket.cc",
- ],
+ name: "perfetto_src_base_unix_socket",
+ srcs: [
+ "src/base/unix_socket.cc",
+ ],
}
// GN: //src/base:version_gen_h
genrule {
- name: "perfetto_src_base_version_gen_h",
- srcs: [
- "CHANGELOG",
- ],
- cmd: "python3 $(location tools/write_version_header.py) --no_git --changelog=$(location CHANGELOG) --cpp_out=$(out)",
- out: [
- "perfetto_version.gen.h",
- ],
- tool_files: [
- "tools/write_version_header.py",
- ],
+ name: "perfetto_src_base_version_gen_h",
+ srcs: [
+ "CHANGELOG",
+ ],
+ cmd: "python3 $(location tools/write_version_header.py) --no_git --changelog=$(location CHANGELOG) --cpp_out=$(out)",
+ out: [
+ "perfetto_version.gen.h",
+ ],
+ tool_files: [
+ "tools/write_version_header.py",
+ ],
}
// GN: //src/ipc:client
filegroup {
- name: "perfetto_src_ipc_client",
- srcs: [
- "src/ipc/client_impl.cc",
- "src/ipc/service_proxy.cc",
- ],
+ name: "perfetto_src_ipc_client",
+ srcs: [
+ "src/ipc/client_impl.cc",
+ "src/ipc/service_proxy.cc",
+ ],
}
// GN: //src/ipc:common
filegroup {
- name: "perfetto_src_ipc_common",
- srcs: [
- "src/ipc/buffered_frame_deserializer.cc",
- "src/ipc/deferred.cc",
- "src/ipc/virtual_destructors.cc",
- ],
+ name: "perfetto_src_ipc_common",
+ srcs: [
+ "src/ipc/buffered_frame_deserializer.cc",
+ "src/ipc/deferred.cc",
+ "src/ipc/virtual_destructors.cc",
+ ],
}
// GN: //src/ipc:host
filegroup {
- name: "perfetto_src_ipc_host",
- srcs: [
- "src/ipc/host_impl.cc",
- ],
+ name: "perfetto_src_ipc_host",
+ srcs: [
+ "src/ipc/host_impl.cc",
+ ],
}
// GN: //src/ipc:perfetto_ipc
filegroup {
- name: "perfetto_src_ipc_perfetto_ipc",
+ name: "perfetto_src_ipc_perfetto_ipc",
}
// GN: //src/ipc:test_messages_cpp
genrule {
- name: "perfetto_src_ipc_test_messages_cpp_gen",
- srcs: [
- "src/ipc/test/client_unittest_messages.proto",
- "src/ipc/test/deferred_unittest_messages.proto",
- "src/ipc/test/greeter_service.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/src/ipc/test/client_unittest_messages.gen.cc",
- "external/perfetto/src/ipc/test/deferred_unittest_messages.gen.cc",
- "external/perfetto/src/ipc/test/greeter_service.gen.cc",
- ],
+ name: "perfetto_src_ipc_test_messages_cpp_gen",
+ srcs: [
+ "src/ipc/test/client_unittest_messages.proto",
+ "src/ipc/test/deferred_unittest_messages.proto",
+ "src/ipc/test/greeter_service.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/src/ipc/test/client_unittest_messages.gen.cc",
+ "external/perfetto/src/ipc/test/deferred_unittest_messages.gen.cc",
+ "external/perfetto/src/ipc/test/greeter_service.gen.cc",
+ ],
}
// GN: //src/ipc:test_messages_cpp
genrule {
- name: "perfetto_src_ipc_test_messages_cpp_gen_headers",
- srcs: [
- "src/ipc/test/client_unittest_messages.proto",
- "src/ipc/test/deferred_unittest_messages.proto",
- "src/ipc/test/greeter_service.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/src/ipc/test/client_unittest_messages.gen.h",
- "external/perfetto/src/ipc/test/deferred_unittest_messages.gen.h",
- "external/perfetto/src/ipc/test/greeter_service.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_src_ipc_test_messages_cpp_gen_headers",
+ srcs: [
+ "src/ipc/test/client_unittest_messages.proto",
+ "src/ipc/test/deferred_unittest_messages.proto",
+ "src/ipc/test/greeter_service.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/src/ipc/test/client_unittest_messages.gen.h",
+ "external/perfetto/src/ipc/test/deferred_unittest_messages.gen.h",
+ "external/perfetto/src/ipc/test/greeter_service.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //src/ipc:test_messages_ipc
genrule {
- name: "perfetto_src_ipc_test_messages_ipc_gen",
- srcs: [
- "src/ipc/test/client_unittest_messages.proto",
- "src/ipc/test/deferred_unittest_messages.proto",
- "src/ipc/test/greeter_service.proto",
- ],
- tools: [
- "aprotoc",
- "ipc_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location ipc_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/src/ipc/test/client_unittest_messages.ipc.cc",
- "external/perfetto/src/ipc/test/deferred_unittest_messages.ipc.cc",
- "external/perfetto/src/ipc/test/greeter_service.ipc.cc",
- ],
+ name: "perfetto_src_ipc_test_messages_ipc_gen",
+ srcs: [
+ "src/ipc/test/client_unittest_messages.proto",
+ "src/ipc/test/deferred_unittest_messages.proto",
+ "src/ipc/test/greeter_service.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "ipc_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location ipc_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/src/ipc/test/client_unittest_messages.ipc.cc",
+ "external/perfetto/src/ipc/test/deferred_unittest_messages.ipc.cc",
+ "external/perfetto/src/ipc/test/greeter_service.ipc.cc",
+ ],
}
// GN: //src/ipc:test_messages_ipc
genrule {
- name: "perfetto_src_ipc_test_messages_ipc_gen_headers",
- srcs: [
- "src/ipc/test/client_unittest_messages.proto",
- "src/ipc/test/deferred_unittest_messages.proto",
- "src/ipc/test/greeter_service.proto",
- ],
- tools: [
- "aprotoc",
- "ipc_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location ipc_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/src/ipc/test/client_unittest_messages.ipc.h",
- "external/perfetto/src/ipc/test/deferred_unittest_messages.ipc.h",
- "external/perfetto/src/ipc/test/greeter_service.ipc.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_src_ipc_test_messages_ipc_gen_headers",
+ srcs: [
+ "src/ipc/test/client_unittest_messages.proto",
+ "src/ipc/test/deferred_unittest_messages.proto",
+ "src/ipc/test/greeter_service.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "ipc_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location ipc_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/src/ipc/test/client_unittest_messages.ipc.h",
+ "external/perfetto/src/ipc/test/deferred_unittest_messages.ipc.h",
+ "external/perfetto/src/ipc/test/greeter_service.ipc.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //src/ipc:unittests
filegroup {
- name: "perfetto_src_ipc_unittests",
- srcs: [
- "src/ipc/buffered_frame_deserializer_unittest.cc",
- "src/ipc/client_impl_unittest.cc",
- "src/ipc/deferred_unittest.cc",
- "src/ipc/host_impl_unittest.cc",
- "src/ipc/test/ipc_integrationtest.cc",
- ],
+ name: "perfetto_src_ipc_unittests",
+ srcs: [
+ "src/ipc/buffered_frame_deserializer_unittest.cc",
+ "src/ipc/client_impl_unittest.cc",
+ "src/ipc/deferred_unittest.cc",
+ "src/ipc/host_impl_unittest.cc",
+ "src/ipc/test/ipc_integrationtest.cc",
+ ],
}
// GN: //src/kallsyms:kallsyms
filegroup {
- name: "perfetto_src_kallsyms_kallsyms",
- srcs: [
- "src/kallsyms/kernel_symbol_map.cc",
- "src/kallsyms/lazy_kernel_symbolizer.cc",
- ],
+ name: "perfetto_src_kallsyms_kallsyms",
+ srcs: [
+ "src/kallsyms/kernel_symbol_map.cc",
+ "src/kallsyms/lazy_kernel_symbolizer.cc",
+ ],
}
// GN: //src/kallsyms:unittests
filegroup {
- name: "perfetto_src_kallsyms_unittests",
- srcs: [
- "src/kallsyms/kernel_symbol_map_unittest.cc",
- "src/kallsyms/lazy_kernel_symbolizer_unittest.cc",
- ],
+ name: "perfetto_src_kallsyms_unittests",
+ srcs: [
+ "src/kallsyms/kernel_symbol_map_unittest.cc",
+ "src/kallsyms/lazy_kernel_symbolizer_unittest.cc",
+ ],
}
// GN: //src/perfetto_cmd:gen_cc_config_descriptor
genrule {
- name: "perfetto_src_perfetto_cmd_gen_cc_config_descriptor",
- srcs: [
- ":perfetto_protos_perfetto_config_perfetto_config_descriptor",
- ],
- cmd: "$(location tools/gen_cc_proto_descriptor.py) --gen_dir=$(genDir) --cpp_out=$(out) $(in)",
- out: [
- "src/perfetto_cmd/perfetto_config.descriptor.h",
- ],
- tool_files: [
- "tools/gen_cc_proto_descriptor.py",
- ],
+ name: "perfetto_src_perfetto_cmd_gen_cc_config_descriptor",
+ srcs: [
+ ":perfetto_protos_perfetto_config_descriptor",
+ ],
+ cmd: "$(location tools/gen_cc_proto_descriptor.py) --gen_dir=$(genDir) --cpp_out=$(out) $(in)",
+ out: [
+ "src/perfetto_cmd/config.descriptor.h",
+ ],
+ tool_files: [
+ "tools/gen_cc_proto_descriptor.py",
+ ],
}
// GN: //src/perfetto_cmd:perfetto_cmd
filegroup {
- name: "perfetto_src_perfetto_cmd_perfetto_cmd",
- srcs: [
- "src/perfetto_cmd/config.cc",
- "src/perfetto_cmd/packet_writer.cc",
- "src/perfetto_cmd/pbtxt_to_pb.cc",
- "src/perfetto_cmd/perfetto_cmd.cc",
- "src/perfetto_cmd/perfetto_cmd_android.cc",
- "src/perfetto_cmd/rate_limiter.cc",
- ],
-}
-
-// GN: //src/perfetto_cmd:protos
-genrule {
- name: "perfetto_src_perfetto_cmd_protos_gen",
- srcs: [
- "src/perfetto_cmd/perfetto_cmd_state.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/src/perfetto_cmd/perfetto_cmd_state.gen.cc",
- ],
-}
-
-// GN: //src/perfetto_cmd:protos
-genrule {
- name: "perfetto_src_perfetto_cmd_protos_gen_headers",
- srcs: [
- "src/perfetto_cmd/perfetto_cmd_state.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/src/perfetto_cmd/perfetto_cmd_state.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_src_perfetto_cmd_perfetto_cmd",
+ srcs: [
+ "src/perfetto_cmd/config.cc",
+ "src/perfetto_cmd/packet_writer.cc",
+ "src/perfetto_cmd/pbtxt_to_pb.cc",
+ "src/perfetto_cmd/perfetto_cmd.cc",
+ "src/perfetto_cmd/perfetto_cmd_android.cc",
+ "src/perfetto_cmd/rate_limiter.cc",
+ ],
+}
+
+// GN: //src/perfetto_cmd:protos_cpp
+genrule {
+ name: "perfetto_src_perfetto_cmd_protos_cpp_gen",
+ srcs: [
+ "src/perfetto_cmd/perfetto_cmd_state.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/src/perfetto_cmd/perfetto_cmd_state.gen.cc",
+ ],
+}
+
+// GN: //src/perfetto_cmd:protos_cpp
+genrule {
+ name: "perfetto_src_perfetto_cmd_protos_cpp_gen_headers",
+ srcs: [
+ "src/perfetto_cmd/perfetto_cmd_state.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/src/perfetto_cmd/perfetto_cmd_state.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //src/perfetto_cmd:trigger_perfetto_cmd
filegroup {
- name: "perfetto_src_perfetto_cmd_trigger_perfetto_cmd",
- srcs: [
- "src/perfetto_cmd/trigger_perfetto.cc",
- ],
+ name: "perfetto_src_perfetto_cmd_trigger_perfetto_cmd",
+ srcs: [
+ "src/perfetto_cmd/trigger_perfetto.cc",
+ ],
}
// GN: //src/perfetto_cmd:trigger_producer
filegroup {
- name: "perfetto_src_perfetto_cmd_trigger_producer",
- srcs: [
- "src/perfetto_cmd/trigger_producer.cc",
- ],
+ name: "perfetto_src_perfetto_cmd_trigger_producer",
+ srcs: [
+ "src/perfetto_cmd/trigger_producer.cc",
+ ],
}
// GN: //src/perfetto_cmd:unittests
filegroup {
- name: "perfetto_src_perfetto_cmd_unittests",
- srcs: [
- "src/perfetto_cmd/config_unittest.cc",
- "src/perfetto_cmd/packet_writer_unittest.cc",
- "src/perfetto_cmd/pbtxt_to_pb_unittest.cc",
- "src/perfetto_cmd/rate_limiter_unittest.cc",
- ],
+ name: "perfetto_src_perfetto_cmd_unittests",
+ srcs: [
+ "src/perfetto_cmd/config_unittest.cc",
+ "src/perfetto_cmd/packet_writer_unittest.cc",
+ "src/perfetto_cmd/pbtxt_to_pb_unittest.cc",
+ "src/perfetto_cmd/rate_limiter_unittest.cc",
+ ],
}
// GN: //src/profiling/common:callstack_trie
filegroup {
- name: "perfetto_src_profiling_common_callstack_trie",
- srcs: [
- "src/profiling/common/callstack_trie.cc",
- ],
+ name: "perfetto_src_profiling_common_callstack_trie",
+ srcs: [
+ "src/profiling/common/callstack_trie.cc",
+ ],
}
// GN: //src/profiling/common:interner
filegroup {
- name: "perfetto_src_profiling_common_interner",
+ name: "perfetto_src_profiling_common_interner",
}
// GN: //src/profiling/common:interning_output
filegroup {
- name: "perfetto_src_profiling_common_interning_output",
- srcs: [
- "src/profiling/common/interning_output.cc",
- ],
+ name: "perfetto_src_profiling_common_interning_output",
+ srcs: [
+ "src/profiling/common/interning_output.cc",
+ ],
+}
+
+// GN: //src/profiling/common:proc_cmdline
+filegroup {
+ name: "perfetto_src_profiling_common_proc_cmdline",
+ srcs: [
+ "src/profiling/common/proc_cmdline.cc",
+ ],
}
// GN: //src/profiling/common:proc_utils
filegroup {
- name: "perfetto_src_profiling_common_proc_utils",
- srcs: [
- "src/profiling/common/proc_utils.cc",
- ],
+ name: "perfetto_src_profiling_common_proc_utils",
+ srcs: [
+ "src/profiling/common/proc_utils.cc",
+ ],
}
// GN: //src/profiling/common:producer_support
filegroup {
- name: "perfetto_src_profiling_common_producer_support",
- srcs: [
- "src/profiling/common/producer_support.cc",
- ],
+ name: "perfetto_src_profiling_common_producer_support",
+ srcs: [
+ "src/profiling/common/producer_support.cc",
+ ],
}
// GN: //src/profiling/common:profiler_guardrails
filegroup {
- name: "perfetto_src_profiling_common_profiler_guardrails",
- srcs: [
- "src/profiling/common/profiler_guardrails.cc",
- ],
+ name: "perfetto_src_profiling_common_profiler_guardrails",
+ srcs: [
+ "src/profiling/common/profiler_guardrails.cc",
+ ],
}
// GN: //src/profiling/common:unittests
filegroup {
- name: "perfetto_src_profiling_common_unittests",
- srcs: [
- "src/profiling/common/interner_unittest.cc",
- "src/profiling/common/proc_utils_unittest.cc",
- "src/profiling/common/producer_support_unittest.cc",
- "src/profiling/common/profiler_guardrails_unittest.cc",
- ],
+ name: "perfetto_src_profiling_common_unittests",
+ srcs: [
+ "src/profiling/common/interner_unittest.cc",
+ "src/profiling/common/proc_cmdline_unittest.cc",
+ "src/profiling/common/proc_utils_unittest.cc",
+ "src/profiling/common/producer_support_unittest.cc",
+ "src/profiling/common/profiler_guardrails_unittest.cc",
+ ],
}
// GN: //src/profiling/common:unwind_support
filegroup {
- name: "perfetto_src_profiling_common_unwind_support",
- srcs: [
- "src/profiling/common/unwind_support.cc",
- ],
+ name: "perfetto_src_profiling_common_unwind_support",
+ srcs: [
+ "src/profiling/common/unwind_support.cc",
+ ],
}
// GN: //src/profiling:deobfuscator
filegroup {
- name: "perfetto_src_profiling_deobfuscator",
- srcs: [
- "src/profiling/deobfuscator.cc",
- ],
+ name: "perfetto_src_profiling_deobfuscator",
+ srcs: [
+ "src/profiling/deobfuscator.cc",
+ ],
}
// GN: //src/profiling/memory:bionic_libc_platform_headers_on_android
filegroup {
- name: "perfetto_src_profiling_memory_bionic_libc_platform_headers_on_android",
+ name: "perfetto_src_profiling_memory_bionic_libc_platform_headers_on_android",
}
// GN: //src/profiling/memory:client
filegroup {
- name: "perfetto_src_profiling_memory_client",
- srcs: [
- "src/profiling/memory/client.cc",
- "src/profiling/memory/sampler.cc",
- ],
+ name: "perfetto_src_profiling_memory_client",
+ srcs: [
+ "src/profiling/memory/client.cc",
+ "src/profiling/memory/sampler.cc",
+ ],
}
// GN: //src/profiling/memory:client_api
filegroup {
- name: "perfetto_src_profiling_memory_client_api",
- srcs: [
- "src/profiling/memory/client_api.cc",
- ],
+ name: "perfetto_src_profiling_memory_client_api",
+ srcs: [
+ "src/profiling/memory/client_api.cc",
+ ],
}
// GN: //src/profiling/memory:client_api_standalone
filegroup {
- name: "perfetto_src_profiling_memory_client_api_standalone",
- srcs: [
- "src/profiling/memory/client_api_factory_standalone.cc",
- ],
+ name: "perfetto_src_profiling_memory_client_api_standalone",
+ srcs: [
+ "src/profiling/memory/client_api_factory_standalone.cc",
+ ],
}
// GN: //src/profiling/memory:daemon
filegroup {
- name: "perfetto_src_profiling_memory_daemon",
- srcs: [
- "src/profiling/memory/bookkeeping.cc",
- "src/profiling/memory/bookkeeping_dump.cc",
- "src/profiling/memory/heapprofd_producer.cc",
- "src/profiling/memory/java_hprof_producer.cc",
- "src/profiling/memory/log_histogram.cc",
- "src/profiling/memory/system_property.cc",
- "src/profiling/memory/unwinding.cc",
- ],
+ name: "perfetto_src_profiling_memory_daemon",
+ srcs: [
+ "src/profiling/memory/bookkeeping.cc",
+ "src/profiling/memory/bookkeeping_dump.cc",
+ "src/profiling/memory/heapprofd_producer.cc",
+ "src/profiling/memory/java_hprof_producer.cc",
+ "src/profiling/memory/log_histogram.cc",
+ "src/profiling/memory/system_property.cc",
+ "src/profiling/memory/unwinding.cc",
+ ],
}
// GN: //src/profiling/memory:end_to_end_tests
filegroup {
- name: "perfetto_src_profiling_memory_end_to_end_tests",
- srcs: [
- "src/profiling/memory/heapprofd_end_to_end_test.cc",
- ],
+ name: "perfetto_src_profiling_memory_end_to_end_tests",
+ srcs: [
+ "src/profiling/memory/heapprofd_end_to_end_test.cc",
+ ],
+}
+
+// GN: //src/profiling/memory:heapprofd_main
+filegroup {
+ name: "perfetto_src_profiling_memory_heapprofd_main",
+ srcs: [
+ "src/profiling/memory/heapprofd.cc",
+ ],
}
// GN: //src/profiling/memory:malloc_interceptor_bionic_hooks
filegroup {
- name: "perfetto_src_profiling_memory_malloc_interceptor_bionic_hooks",
- srcs: [
- "src/profiling/memory/malloc_interceptor_bionic_hooks.cc",
- ],
+ name: "perfetto_src_profiling_memory_malloc_interceptor_bionic_hooks",
+ srcs: [
+ "src/profiling/memory/malloc_interceptor_bionic_hooks.cc",
+ ],
}
// GN: //src/profiling/memory:ring_buffer
filegroup {
- name: "perfetto_src_profiling_memory_ring_buffer",
- srcs: [
- "src/profiling/memory/shared_ring_buffer.cc",
- ],
+ name: "perfetto_src_profiling_memory_ring_buffer",
+ srcs: [
+ "src/profiling/memory/shared_ring_buffer.cc",
+ ],
}
// GN: //src/profiling/memory:ring_buffer_unittests
filegroup {
- name: "perfetto_src_profiling_memory_ring_buffer_unittests",
- srcs: [
- "src/profiling/memory/shared_ring_buffer_unittest.cc",
- ],
+ name: "perfetto_src_profiling_memory_ring_buffer_unittests",
+ srcs: [
+ "src/profiling/memory/shared_ring_buffer_unittest.cc",
+ ],
}
// GN: //src/profiling/memory:scoped_spinlock
filegroup {
- name: "perfetto_src_profiling_memory_scoped_spinlock",
- srcs: [
- "src/profiling/memory/scoped_spinlock.cc",
- ],
+ name: "perfetto_src_profiling_memory_scoped_spinlock",
+ srcs: [
+ "src/profiling/memory/scoped_spinlock.cc",
+ ],
}
// GN: //src/profiling/memory:unittests
filegroup {
- name: "perfetto_src_profiling_memory_unittests",
- srcs: [
- "src/profiling/memory/bookkeeping_unittest.cc",
- "src/profiling/memory/client_unittest.cc",
- "src/profiling/memory/heapprofd_producer_unittest.cc",
- "src/profiling/memory/parse_smaps_unittest.cc",
- "src/profiling/memory/sampler_unittest.cc",
- "src/profiling/memory/system_property_unittest.cc",
- "src/profiling/memory/unwinding_unittest.cc",
- "src/profiling/memory/wire_protocol_unittest.cc",
- ],
+ name: "perfetto_src_profiling_memory_unittests",
+ srcs: [
+ "src/profiling/memory/bookkeeping_unittest.cc",
+ "src/profiling/memory/client_unittest.cc",
+ "src/profiling/memory/heapprofd_producer_unittest.cc",
+ "src/profiling/memory/parse_smaps_unittest.cc",
+ "src/profiling/memory/sampler_unittest.cc",
+ "src/profiling/memory/system_property_unittest.cc",
+ "src/profiling/memory/unwinding_unittest.cc",
+ "src/profiling/memory/wire_protocol_unittest.cc",
+ ],
}
// GN: //src/profiling/memory:wire_protocol
filegroup {
- name: "perfetto_src_profiling_memory_wire_protocol",
- srcs: [
- "src/profiling/memory/wire_protocol.cc",
- ],
+ name: "perfetto_src_profiling_memory_wire_protocol",
+ srcs: [
+ "src/profiling/memory/wire_protocol.cc",
+ ],
}
// GN: //src/profiling/memory:wrap_allocators
filegroup {
- name: "perfetto_src_profiling_memory_wrap_allocators",
- srcs: [
- "src/profiling/memory/wrap_allocators.cc",
- ],
+ name: "perfetto_src_profiling_memory_wrap_allocators",
+ srcs: [
+ "src/profiling/memory/wrap_allocators.cc",
+ ],
}
// GN: //src/profiling/perf:common_types
filegroup {
- name: "perfetto_src_profiling_perf_common_types",
+ name: "perfetto_src_profiling_perf_common_types",
}
// GN: //src/profiling/perf:proc_descriptors
filegroup {
- name: "perfetto_src_profiling_perf_proc_descriptors",
- srcs: [
- "src/profiling/perf/proc_descriptors.cc",
- ],
+ name: "perfetto_src_profiling_perf_proc_descriptors",
+ srcs: [
+ "src/profiling/perf/proc_descriptors.cc",
+ ],
}
// GN: //src/profiling/perf:producer
filegroup {
- name: "perfetto_src_profiling_perf_producer",
- srcs: [
- "src/profiling/perf/event_config.cc",
- "src/profiling/perf/event_reader.cc",
- "src/profiling/perf/perf_producer.cc",
- ],
+ name: "perfetto_src_profiling_perf_producer",
+ srcs: [
+ "src/profiling/perf/event_config.cc",
+ "src/profiling/perf/event_reader.cc",
+ "src/profiling/perf/perf_producer.cc",
+ ],
}
// GN: //src/profiling/perf:producer_unittests
filegroup {
- name: "perfetto_src_profiling_perf_producer_unittests",
- srcs: [
- "src/profiling/perf/event_config_unittest.cc",
- "src/profiling/perf/unwind_queue_unittest.cc",
- ],
+ name: "perfetto_src_profiling_perf_producer_unittests",
+ srcs: [
+ "src/profiling/perf/event_config_unittest.cc",
+ "src/profiling/perf/unwind_queue_unittest.cc",
+ ],
}
// GN: //src/profiling/perf:regs_parsing
filegroup {
- name: "perfetto_src_profiling_perf_regs_parsing",
- srcs: [
- "src/profiling/perf/regs_parsing.cc",
- ],
+ name: "perfetto_src_profiling_perf_regs_parsing",
+ srcs: [
+ "src/profiling/perf/regs_parsing.cc",
+ ],
}
// GN: //src/profiling/perf:traced_perf_main
filegroup {
- name: "perfetto_src_profiling_perf_traced_perf_main",
- srcs: [
- "src/profiling/perf/traced_perf.cc",
- ],
+ name: "perfetto_src_profiling_perf_traced_perf_main",
+ srcs: [
+ "src/profiling/perf/traced_perf.cc",
+ ],
}
// GN: //src/profiling/perf:unwinding
filegroup {
- name: "perfetto_src_profiling_perf_unwinding",
- srcs: [
- "src/profiling/perf/unwinding.cc",
- ],
+ name: "perfetto_src_profiling_perf_unwinding",
+ srcs: [
+ "src/profiling/perf/unwinding.cc",
+ ],
}
// GN: //src/profiling/symbolizer:symbolize_database
filegroup {
- name: "perfetto_src_profiling_symbolizer_symbolize_database",
- srcs: [
- "src/profiling/symbolizer/symbolize_database.cc",
- ],
+ name: "perfetto_src_profiling_symbolizer_symbolize_database",
+ srcs: [
+ "src/profiling/symbolizer/symbolize_database.cc",
+ ],
}
// GN: //src/profiling/symbolizer:symbolizer
filegroup {
- name: "perfetto_src_profiling_symbolizer_symbolizer",
- srcs: [
- "src/profiling/symbolizer/filesystem_posix.cc",
- "src/profiling/symbolizer/filesystem_windows.cc",
- "src/profiling/symbolizer/local_symbolizer.cc",
- "src/profiling/symbolizer/scoped_read_mmap_posix.cc",
- "src/profiling/symbolizer/scoped_read_mmap_windows.cc",
- "src/profiling/symbolizer/subprocess_posix.cc",
- "src/profiling/symbolizer/subprocess_windows.cc",
- "src/profiling/symbolizer/symbolizer.cc",
- ],
+ name: "perfetto_src_profiling_symbolizer_symbolizer",
+ srcs: [
+ "src/profiling/symbolizer/breakpad_parser.cc",
+ "src/profiling/symbolizer/breakpad_symbolizer.cc",
+ "src/profiling/symbolizer/local_symbolizer.cc",
+ "src/profiling/symbolizer/scoped_read_mmap_posix.cc",
+ "src/profiling/symbolizer/scoped_read_mmap_windows.cc",
+ "src/profiling/symbolizer/subprocess_posix.cc",
+ "src/profiling/symbolizer/subprocess_windows.cc",
+ "src/profiling/symbolizer/symbolizer.cc",
+ ],
}
// GN: //src/profiling/symbolizer:unittests
filegroup {
- name: "perfetto_src_profiling_symbolizer_unittests",
- srcs: [
- "src/profiling/symbolizer/local_symbolizer_unittest.cc",
- ],
+ name: "perfetto_src_profiling_symbolizer_unittests",
+ srcs: [
+ "src/profiling/symbolizer/breakpad_parser_unittest.cc",
+ "src/profiling/symbolizer/breakpad_symbolizer_unittest.cc",
+ "src/profiling/symbolizer/local_symbolizer_unittest.cc",
+ ],
}
// GN: //src/profiling:unittests
filegroup {
- name: "perfetto_src_profiling_unittests",
- srcs: [
- "src/profiling/deobfuscator_unittest.cc",
- ],
+ name: "perfetto_src_profiling_unittests",
+ srcs: [
+ "src/profiling/deobfuscator_unittest.cc",
+ ],
}
// GN: //src/protozero/filtering:bytecode_common
filegroup {
- name: "perfetto_src_protozero_filtering_bytecode_common",
+ name: "perfetto_src_protozero_filtering_bytecode_common",
}
// GN: //src/protozero/filtering:bytecode_generator
filegroup {
- name: "perfetto_src_protozero_filtering_bytecode_generator",
- srcs: [
- "src/protozero/filtering/filter_bytecode_generator.cc",
- ],
+ name: "perfetto_src_protozero_filtering_bytecode_generator",
+ srcs: [
+ "src/protozero/filtering/filter_bytecode_generator.cc",
+ ],
}
// GN: //src/protozero/filtering:bytecode_parser
filegroup {
- name: "perfetto_src_protozero_filtering_bytecode_parser",
- srcs: [
- "src/protozero/filtering/filter_bytecode_parser.cc",
- ],
+ name: "perfetto_src_protozero_filtering_bytecode_parser",
+ srcs: [
+ "src/protozero/filtering/filter_bytecode_parser.cc",
+ ],
}
// GN: //src/protozero/filtering:filter_util
filegroup {
- name: "perfetto_src_protozero_filtering_filter_util",
- srcs: [
- "src/protozero/filtering/filter_util.cc",
- ],
+ name: "perfetto_src_protozero_filtering_filter_util",
+ srcs: [
+ "src/protozero/filtering/filter_util.cc",
+ ],
}
// GN: //src/protozero/filtering:message_filter
filegroup {
- name: "perfetto_src_protozero_filtering_message_filter",
- srcs: [
- "src/protozero/filtering/message_filter.cc",
- ],
+ name: "perfetto_src_protozero_filtering_message_filter",
+ srcs: [
+ "src/protozero/filtering/message_filter.cc",
+ ],
}
// GN: //src/protozero/filtering:unittests
filegroup {
- name: "perfetto_src_protozero_filtering_unittests",
- srcs: [
- "src/protozero/filtering/filter_bytecode_generator_unittest.cc",
- "src/protozero/filtering/filter_bytecode_parser_unittest.cc",
- "src/protozero/filtering/filter_util_unittest.cc",
- "src/protozero/filtering/message_filter_unittest.cc",
- "src/protozero/filtering/message_tokenizer_unittest.cc",
- ],
+ name: "perfetto_src_protozero_filtering_unittests",
+ srcs: [
+ "src/protozero/filtering/filter_bytecode_generator_unittest.cc",
+ "src/protozero/filtering/filter_bytecode_parser_unittest.cc",
+ "src/protozero/filtering/filter_util_unittest.cc",
+ "src/protozero/filtering/message_filter_unittest.cc",
+ "src/protozero/filtering/message_tokenizer_unittest.cc",
+ ],
+}
+
+// GN: //src/protozero:proto_ring_buffer
+filegroup {
+ name: "perfetto_src_protozero_proto_ring_buffer",
+ srcs: [
+ "src/protozero/proto_ring_buffer.cc",
+ ],
}
// GN: //src/protozero/protoc_plugin:cppgen_plugin
cc_binary_host {
- name: "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- srcs: [
- ":perfetto_include_perfetto_base_base",
- ":perfetto_include_perfetto_ext_base_base",
- ":perfetto_src_base_base",
- "src/protozero/protoc_plugin/cppgen_plugin.cc",
- ],
- static_libs: [
- "libprotoc",
- ],
- generated_headers: [
- "perfetto_src_base_version_gen_h",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- cflags: [
- "-DGOOGLE_PROTOBUF_NO_RTTI",
- "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
- ],
+ name: "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ srcs: [
+ ":perfetto_include_perfetto_base_base",
+ ":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_src_base_base",
+ "src/protozero/protoc_plugin/cppgen_plugin.cc",
+ ],
+ static_libs: [
+ "libprotoc",
+ ],
+ generated_headers: [
+ "perfetto_src_base_version_gen_h",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ cflags: [
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ ],
}
// GN: //src/protozero:protozero
filegroup {
- name: "perfetto_src_protozero_protozero",
- srcs: [
- "src/protozero/field.cc",
- "src/protozero/message.cc",
- "src/protozero/message_arena.cc",
- "src/protozero/message_handle.cc",
- "src/protozero/packed_repeated_fields.cc",
- "src/protozero/proto_decoder.cc",
- "src/protozero/scattered_heap_buffer.cc",
- "src/protozero/scattered_stream_null_delegate.cc",
- "src/protozero/scattered_stream_writer.cc",
- "src/protozero/static_buffer.cc",
- "src/protozero/virtual_destructors.cc",
- ],
+ name: "perfetto_src_protozero_protozero",
+ srcs: [
+ "src/protozero/field.cc",
+ "src/protozero/message.cc",
+ "src/protozero/message_arena.cc",
+ "src/protozero/message_handle.cc",
+ "src/protozero/packed_repeated_fields.cc",
+ "src/protozero/proto_decoder.cc",
+ "src/protozero/scattered_heap_buffer.cc",
+ "src/protozero/scattered_stream_null_delegate.cc",
+ "src/protozero/scattered_stream_writer.cc",
+ "src/protozero/static_buffer.cc",
+ "src/protozero/virtual_destructors.cc",
+ ],
}
// GN: //src/protozero:test_messages_descriptor
genrule {
- name: "perfetto_src_protozero_test_messages_descriptor",
- srcs: [
- "src/protozero/test/example_proto/extensions.proto",
- "src/protozero/test/example_proto/library.proto",
- "src/protozero/test/example_proto/library_internals/galaxies.proto",
- "src/protozero/test/example_proto/test_messages.proto",
- "src/protozero/test/example_proto/upper_import.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --descriptor_set_out=$(out) $(in)",
- out: [
- "perfetto_src_protozero_test_messages_descriptor.bin",
- ],
+ name: "perfetto_src_protozero_test_messages_descriptor",
+ srcs: [
+ "src/protozero/test/example_proto/extensions.proto",
+ "src/protozero/test/example_proto/library.proto",
+ "src/protozero/test/example_proto/library_internals/galaxies.proto",
+ "src/protozero/test/example_proto/test_messages.proto",
+ "src/protozero/test/example_proto/upper_import.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --descriptor_set_out=$(out) $(in)",
+ out: [
+ "perfetto_src_protozero_test_messages_descriptor.bin",
+ ],
}
// GN: //src/protozero:testing_messages_cpp
genrule {
- name: "perfetto_src_protozero_testing_messages_cpp_gen",
- srcs: [
- "src/protozero/test/example_proto/extensions.proto",
- "src/protozero/test/example_proto/library.proto",
- "src/protozero/test/example_proto/library_internals/galaxies.proto",
- "src/protozero/test/example_proto/test_messages.proto",
- "src/protozero/test/example_proto/upper_import.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/src/protozero/test/example_proto/extensions.gen.cc",
- "external/perfetto/src/protozero/test/example_proto/library.gen.cc",
- "external/perfetto/src/protozero/test/example_proto/library_internals/galaxies.gen.cc",
- "external/perfetto/src/protozero/test/example_proto/test_messages.gen.cc",
- "external/perfetto/src/protozero/test/example_proto/upper_import.gen.cc",
- ],
+ name: "perfetto_src_protozero_testing_messages_cpp_gen",
+ srcs: [
+ "src/protozero/test/example_proto/extensions.proto",
+ "src/protozero/test/example_proto/library.proto",
+ "src/protozero/test/example_proto/library_internals/galaxies.proto",
+ "src/protozero/test/example_proto/test_messages.proto",
+ "src/protozero/test/example_proto/upper_import.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/src/protozero/test/example_proto/extensions.gen.cc",
+ "external/perfetto/src/protozero/test/example_proto/library.gen.cc",
+ "external/perfetto/src/protozero/test/example_proto/library_internals/galaxies.gen.cc",
+ "external/perfetto/src/protozero/test/example_proto/test_messages.gen.cc",
+ "external/perfetto/src/protozero/test/example_proto/upper_import.gen.cc",
+ ],
}
// GN: //src/protozero:testing_messages_cpp
genrule {
- name: "perfetto_src_protozero_testing_messages_cpp_gen_headers",
- srcs: [
- "src/protozero/test/example_proto/extensions.proto",
- "src/protozero/test/example_proto/library.proto",
- "src/protozero/test/example_proto/library_internals/galaxies.proto",
- "src/protozero/test/example_proto/test_messages.proto",
- "src/protozero/test/example_proto/upper_import.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/src/protozero/test/example_proto/extensions.gen.h",
- "external/perfetto/src/protozero/test/example_proto/library.gen.h",
- "external/perfetto/src/protozero/test/example_proto/library_internals/galaxies.gen.h",
- "external/perfetto/src/protozero/test/example_proto/test_messages.gen.h",
- "external/perfetto/src/protozero/test/example_proto/upper_import.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_src_protozero_testing_messages_cpp_gen_headers",
+ srcs: [
+ "src/protozero/test/example_proto/extensions.proto",
+ "src/protozero/test/example_proto/library.proto",
+ "src/protozero/test/example_proto/library_internals/galaxies.proto",
+ "src/protozero/test/example_proto/test_messages.proto",
+ "src/protozero/test/example_proto/upper_import.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/src/protozero/test/example_proto/extensions.gen.h",
+ "external/perfetto/src/protozero/test/example_proto/library.gen.h",
+ "external/perfetto/src/protozero/test/example_proto/library_internals/galaxies.gen.h",
+ "external/perfetto/src/protozero/test/example_proto/test_messages.gen.h",
+ "external/perfetto/src/protozero/test/example_proto/upper_import.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //src/protozero:testing_messages_lite
genrule {
- name: "perfetto_src_protozero_testing_messages_lite_gen",
- srcs: [
- "src/protozero/test/example_proto/extensions.proto",
- "src/protozero/test/example_proto/library.proto",
- "src/protozero/test/example_proto/library_internals/galaxies.proto",
- "src/protozero/test/example_proto/test_messages.proto",
- "src/protozero/test/example_proto/upper_import.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/src/protozero/test/example_proto/extensions.pb.cc",
- "external/perfetto/src/protozero/test/example_proto/library.pb.cc",
- "external/perfetto/src/protozero/test/example_proto/library_internals/galaxies.pb.cc",
- "external/perfetto/src/protozero/test/example_proto/test_messages.pb.cc",
- "external/perfetto/src/protozero/test/example_proto/upper_import.pb.cc",
- ],
+ name: "perfetto_src_protozero_testing_messages_lite_gen",
+ srcs: [
+ "src/protozero/test/example_proto/extensions.proto",
+ "src/protozero/test/example_proto/library.proto",
+ "src/protozero/test/example_proto/library_internals/galaxies.proto",
+ "src/protozero/test/example_proto/test_messages.proto",
+ "src/protozero/test/example_proto/upper_import.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/src/protozero/test/example_proto/extensions.pb.cc",
+ "external/perfetto/src/protozero/test/example_proto/library.pb.cc",
+ "external/perfetto/src/protozero/test/example_proto/library_internals/galaxies.pb.cc",
+ "external/perfetto/src/protozero/test/example_proto/test_messages.pb.cc",
+ "external/perfetto/src/protozero/test/example_proto/upper_import.pb.cc",
+ ],
}
// GN: //src/protozero:testing_messages_lite
genrule {
- name: "perfetto_src_protozero_testing_messages_lite_gen_headers",
- srcs: [
- "src/protozero/test/example_proto/extensions.proto",
- "src/protozero/test/example_proto/library.proto",
- "src/protozero/test/example_proto/library_internals/galaxies.proto",
- "src/protozero/test/example_proto/test_messages.proto",
- "src/protozero/test/example_proto/upper_import.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/src/protozero/test/example_proto/extensions.pb.h",
- "external/perfetto/src/protozero/test/example_proto/library.pb.h",
- "external/perfetto/src/protozero/test/example_proto/library_internals/galaxies.pb.h",
- "external/perfetto/src/protozero/test/example_proto/test_messages.pb.h",
- "external/perfetto/src/protozero/test/example_proto/upper_import.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_src_protozero_testing_messages_lite_gen_headers",
+ srcs: [
+ "src/protozero/test/example_proto/extensions.proto",
+ "src/protozero/test/example_proto/library.proto",
+ "src/protozero/test/example_proto/library_internals/galaxies.proto",
+ "src/protozero/test/example_proto/test_messages.proto",
+ "src/protozero/test/example_proto/upper_import.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/src/protozero/test/example_proto/extensions.pb.h",
+ "external/perfetto/src/protozero/test/example_proto/library.pb.h",
+ "external/perfetto/src/protozero/test/example_proto/library_internals/galaxies.pb.h",
+ "external/perfetto/src/protozero/test/example_proto/test_messages.pb.h",
+ "external/perfetto/src/protozero/test/example_proto/upper_import.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //src/protozero:testing_messages_zero
genrule {
- name: "perfetto_src_protozero_testing_messages_zero_gen",
- srcs: [
- "src/protozero/test/example_proto/extensions.proto",
- "src/protozero/test/example_proto/library.proto",
- "src/protozero/test/example_proto/library_internals/galaxies.proto",
- "src/protozero/test/example_proto/test_messages.proto",
- "src/protozero/test/example_proto/upper_import.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/src/protozero/test/example_proto/extensions.pbzero.cc",
- "external/perfetto/src/protozero/test/example_proto/library.pbzero.cc",
- "external/perfetto/src/protozero/test/example_proto/library_internals/galaxies.pbzero.cc",
- "external/perfetto/src/protozero/test/example_proto/test_messages.pbzero.cc",
- "external/perfetto/src/protozero/test/example_proto/upper_import.pbzero.cc",
- ],
+ name: "perfetto_src_protozero_testing_messages_zero_gen",
+ srcs: [
+ "src/protozero/test/example_proto/extensions.proto",
+ "src/protozero/test/example_proto/library.proto",
+ "src/protozero/test/example_proto/library_internals/galaxies.proto",
+ "src/protozero/test/example_proto/test_messages.proto",
+ "src/protozero/test/example_proto/upper_import.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/src/protozero/test/example_proto/extensions.pbzero.cc",
+ "external/perfetto/src/protozero/test/example_proto/library.pbzero.cc",
+ "external/perfetto/src/protozero/test/example_proto/library_internals/galaxies.pbzero.cc",
+ "external/perfetto/src/protozero/test/example_proto/test_messages.pbzero.cc",
+ "external/perfetto/src/protozero/test/example_proto/upper_import.pbzero.cc",
+ ],
}
// GN: //src/protozero:testing_messages_zero
genrule {
- name: "perfetto_src_protozero_testing_messages_zero_gen_headers",
- srcs: [
- "src/protozero/test/example_proto/extensions.proto",
- "src/protozero/test/example_proto/library.proto",
- "src/protozero/test/example_proto/library_internals/galaxies.proto",
- "src/protozero/test/example_proto/test_messages.proto",
- "src/protozero/test/example_proto/upper_import.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/src/protozero/test/example_proto/extensions.pbzero.h",
- "external/perfetto/src/protozero/test/example_proto/library.pbzero.h",
- "external/perfetto/src/protozero/test/example_proto/library_internals/galaxies.pbzero.h",
- "external/perfetto/src/protozero/test/example_proto/test_messages.pbzero.h",
- "external/perfetto/src/protozero/test/example_proto/upper_import.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_src_protozero_testing_messages_zero_gen_headers",
+ srcs: [
+ "src/protozero/test/example_proto/extensions.proto",
+ "src/protozero/test/example_proto/library.proto",
+ "src/protozero/test/example_proto/library_internals/galaxies.proto",
+ "src/protozero/test/example_proto/test_messages.proto",
+ "src/protozero/test/example_proto/upper_import.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/src/protozero/test/example_proto/extensions.pbzero.h",
+ "external/perfetto/src/protozero/test/example_proto/library.pbzero.h",
+ "external/perfetto/src/protozero/test/example_proto/library_internals/galaxies.pbzero.h",
+ "external/perfetto/src/protozero/test/example_proto/test_messages.pbzero.h",
+ "external/perfetto/src/protozero/test/example_proto/upper_import.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //src/protozero:unittests
filegroup {
- name: "perfetto_src_protozero_unittests",
- srcs: [
- "src/protozero/copyable_ptr_unittest.cc",
- "src/protozero/message_handle_unittest.cc",
- "src/protozero/message_unittest.cc",
- "src/protozero/proto_decoder_unittest.cc",
- "src/protozero/proto_utils_unittest.cc",
- "src/protozero/scattered_stream_writer_unittest.cc",
- "src/protozero/test/cppgen_conformance_unittest.cc",
- "src/protozero/test/fake_scattered_buffer.cc",
- "src/protozero/test/protozero_conformance_unittest.cc",
- ],
+ name: "perfetto_src_protozero_unittests",
+ srcs: [
+ "src/protozero/copyable_ptr_unittest.cc",
+ "src/protozero/message_handle_unittest.cc",
+ "src/protozero/message_unittest.cc",
+ "src/protozero/proto_decoder_unittest.cc",
+ "src/protozero/proto_ring_buffer_unittest.cc",
+ "src/protozero/proto_utils_unittest.cc",
+ "src/protozero/scattered_stream_writer_unittest.cc",
+ "src/protozero/test/cppgen_conformance_unittest.cc",
+ "src/protozero/test/fake_scattered_buffer.cc",
+ "src/protozero/test/protozero_conformance_unittest.cc",
+ ],
}
// GN: //src/trace_processor/analysis:analysis
filegroup {
- name: "perfetto_src_trace_processor_analysis_analysis",
- srcs: [
- "src/trace_processor/analysis/describe_slice.cc",
- ],
+ name: "perfetto_src_trace_processor_analysis_analysis",
+ srcs: [
+ "src/trace_processor/analysis/describe_slice.cc",
+ ],
}
// GN: //src/trace_processor/containers:containers
filegroup {
- name: "perfetto_src_trace_processor_containers_containers",
- srcs: [
- "src/trace_processor/containers/bit_vector.cc",
- "src/trace_processor/containers/bit_vector_iterators.cc",
- "src/trace_processor/containers/nullable_vector.cc",
- "src/trace_processor/containers/row_map.cc",
- "src/trace_processor/containers/string_pool.cc",
- ],
+ name: "perfetto_src_trace_processor_containers_containers",
+ srcs: [
+ "src/trace_processor/containers/bit_vector.cc",
+ "src/trace_processor/containers/bit_vector_iterators.cc",
+ "src/trace_processor/containers/nullable_vector.cc",
+ "src/trace_processor/containers/row_map.cc",
+ "src/trace_processor/containers/string_pool.cc",
+ ],
}
// GN: //src/trace_processor/containers:unittests
filegroup {
- name: "perfetto_src_trace_processor_containers_unittests",
- srcs: [
- "src/trace_processor/containers/bit_vector_unittest.cc",
- "src/trace_processor/containers/null_term_string_view_unittest.cc",
- "src/trace_processor/containers/nullable_vector_unittest.cc",
- "src/trace_processor/containers/row_map_unittest.cc",
- "src/trace_processor/containers/string_pool_unittest.cc",
- ],
+ name: "perfetto_src_trace_processor_containers_unittests",
+ srcs: [
+ "src/trace_processor/containers/bit_vector_unittest.cc",
+ "src/trace_processor/containers/null_term_string_view_unittest.cc",
+ "src/trace_processor/containers/nullable_vector_unittest.cc",
+ "src/trace_processor/containers/row_map_unittest.cc",
+ "src/trace_processor/containers/string_pool_unittest.cc",
+ ],
}
// GN: //src/trace_processor/db:db
filegroup {
- name: "perfetto_src_trace_processor_db_db",
- srcs: [
- "src/trace_processor/db/column.cc",
- "src/trace_processor/db/table.cc",
- ],
+ name: "perfetto_src_trace_processor_db_db",
+ srcs: [
+ "src/trace_processor/db/column.cc",
+ "src/trace_processor/db/table.cc",
+ ],
}
// GN: //src/trace_processor/db:unittests
filegroup {
- name: "perfetto_src_trace_processor_db_unittests",
- srcs: [
- "src/trace_processor/db/compare_unittest.cc",
- "src/trace_processor/db/table_unittest.cc",
- ],
+ name: "perfetto_src_trace_processor_db_unittests",
+ srcs: [
+ "src/trace_processor/db/compare_unittest.cc",
+ "src/trace_processor/db/table_unittest.cc",
+ ],
+}
+
+// GN: //src/trace_processor:demangle
+cc_library_static {
+ name: "perfetto_src_trace_processor_demangle",
+ srcs: [
+ ":perfetto_include_perfetto_base_base",
+ ":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_include_perfetto_ext_trace_processor_demangle",
+ "src/trace_processor/demangle.cc",
+ ],
+ host_supported: true,
+ defaults: [
+ "perfetto_defaults",
+ ],
}
// GN: //src/trace_processor:export_json
filegroup {
- name: "perfetto_src_trace_processor_export_json",
- srcs: [
- "src/trace_processor/export_json.cc",
- ],
+ name: "perfetto_src_trace_processor_export_json",
+ srcs: [
+ "src/trace_processor/export_json.cc",
+ ],
}
// GN: //src/trace_processor:ftrace_descriptors
filegroup {
- name: "perfetto_src_trace_processor_ftrace_descriptors",
- srcs: [
- "src/trace_processor/importers/ftrace/ftrace_descriptors.cc",
- ],
+ name: "perfetto_src_trace_processor_ftrace_descriptors",
+ srcs: [
+ "src/trace_processor/importers/ftrace/ftrace_descriptors.cc",
+ ],
}
// GN: //src/trace_processor:gen_cc_test_messages_descriptor
genrule {
- name: "perfetto_src_trace_processor_gen_cc_test_messages_descriptor",
- srcs: [
- ":perfetto_src_protozero_test_messages_descriptor",
- ],
- cmd: "$(location tools/gen_cc_proto_descriptor.py) --gen_dir=$(genDir) --cpp_out=$(out) $(in)",
- out: [
- "src/trace_processor/test_messages.descriptor.h",
- ],
- tool_files: [
- "tools/gen_cc_proto_descriptor.py",
- ],
+ name: "perfetto_src_trace_processor_gen_cc_test_messages_descriptor",
+ srcs: [
+ ":perfetto_src_protozero_test_messages_descriptor",
+ ],
+ cmd: "$(location tools/gen_cc_proto_descriptor.py) --gen_dir=$(genDir) --cpp_out=$(out) $(in)",
+ out: [
+ "src/trace_processor/test_messages.descriptor.h",
+ ],
+ tool_files: [
+ "tools/gen_cc_proto_descriptor.py",
+ ],
}
// GN: //src/trace_processor/importers/common:common
filegroup {
- name: "perfetto_src_trace_processor_importers_common_common",
- srcs: [
- "src/trace_processor/importers/common/args_tracker.cc",
- "src/trace_processor/importers/common/clock_tracker.cc",
- "src/trace_processor/importers/common/event_tracker.cc",
- "src/trace_processor/importers/common/flow_tracker.cc",
- "src/trace_processor/importers/common/global_args_tracker.cc",
- "src/trace_processor/importers/common/process_tracker.cc",
- "src/trace_processor/importers/common/slice_tracker.cc",
- "src/trace_processor/importers/common/system_info_tracker.cc",
- "src/trace_processor/importers/common/track_tracker.cc",
- ],
+ name: "perfetto_src_trace_processor_importers_common_common",
+ srcs: [
+ "src/trace_processor/importers/common/args_tracker.cc",
+ "src/trace_processor/importers/common/args_translation_table.cc",
+ "src/trace_processor/importers/common/clock_tracker.cc",
+ "src/trace_processor/importers/common/event_tracker.cc",
+ "src/trace_processor/importers/common/flow_tracker.cc",
+ "src/trace_processor/importers/common/global_args_tracker.cc",
+ "src/trace_processor/importers/common/process_tracker.cc",
+ "src/trace_processor/importers/common/slice_tracker.cc",
+ "src/trace_processor/importers/common/slice_translation_table.cc",
+ "src/trace_processor/importers/common/system_info_tracker.cc",
+ "src/trace_processor/importers/common/track_tracker.cc",
+ ],
}
// GN: //src/trace_processor/importers/common:unittests
filegroup {
- name: "perfetto_src_trace_processor_importers_common_unittests",
- srcs: [
- "src/trace_processor/importers/common/clock_tracker_unittest.cc",
- "src/trace_processor/importers/common/event_tracker_unittest.cc",
- "src/trace_processor/importers/common/flow_tracker_unittest.cc",
- "src/trace_processor/importers/common/process_tracker_unittest.cc",
- "src/trace_processor/importers/common/slice_tracker_unittest.cc",
- ],
+ name: "perfetto_src_trace_processor_importers_common_unittests",
+ srcs: [
+ "src/trace_processor/importers/common/args_translation_table_unittest.cc",
+ "src/trace_processor/importers/common/clock_tracker_unittest.cc",
+ "src/trace_processor/importers/common/event_tracker_unittest.cc",
+ "src/trace_processor/importers/common/flow_tracker_unittest.cc",
+ "src/trace_processor/importers/common/process_tracker_unittest.cc",
+ "src/trace_processor/importers/common/slice_tracker_unittest.cc",
+ "src/trace_processor/importers/common/slice_translation_table_unittest.cc",
+ ],
}
// GN: //src/trace_processor/importers:gen_cc_chrome_track_event_descriptor
genrule {
- name: "perfetto_src_trace_processor_importers_gen_cc_chrome_track_event_descriptor",
- srcs: [
- ":perfetto_protos_third_party_chromium_chrome_track_event_descriptor",
- ],
- cmd: "$(location tools/gen_cc_proto_descriptor.py) --gen_dir=$(genDir) --cpp_out=$(out) $(in)",
- out: [
- "src/trace_processor/importers/chrome_track_event.descriptor.h",
- ],
- tool_files: [
- "tools/gen_cc_proto_descriptor.py",
- ],
+ name: "perfetto_src_trace_processor_importers_gen_cc_chrome_track_event_descriptor",
+ srcs: [
+ ":perfetto_protos_third_party_chromium_descriptor",
+ ],
+ cmd: "$(location tools/gen_cc_proto_descriptor.py) --gen_dir=$(genDir) --cpp_out=$(out) $(in)",
+ out: [
+ "src/trace_processor/importers/chrome_track_event.descriptor.h",
+ ],
+ tool_files: [
+ "tools/gen_cc_proto_descriptor.py",
+ ],
}
// GN: //src/trace_processor/importers:gen_cc_config_descriptor
genrule {
- name: "perfetto_src_trace_processor_importers_gen_cc_config_descriptor",
- srcs: [
- ":perfetto_protos_perfetto_config_descriptor",
- ],
- cmd: "$(location tools/gen_cc_proto_descriptor.py) --gen_dir=$(genDir) --cpp_out=$(out) $(in)",
- out: [
- "src/trace_processor/importers/config.descriptor.h",
- ],
- tool_files: [
- "tools/gen_cc_proto_descriptor.py",
- ],
+ name: "perfetto_src_trace_processor_importers_gen_cc_config_descriptor",
+ srcs: [
+ ":perfetto_protos_perfetto_config_descriptor",
+ ],
+ cmd: "$(location tools/gen_cc_proto_descriptor.py) --gen_dir=$(genDir) --cpp_out=$(out) $(in)",
+ out: [
+ "src/trace_processor/importers/config.descriptor.h",
+ ],
+ tool_files: [
+ "tools/gen_cc_proto_descriptor.py",
+ ],
}
// GN: //src/trace_processor/importers:gen_cc_track_event_descriptor
genrule {
- name: "perfetto_src_trace_processor_importers_gen_cc_track_event_descriptor",
- srcs: [
- ":perfetto_protos_perfetto_trace_track_event_track_event_descriptor",
- ],
- cmd: "$(location tools/gen_cc_proto_descriptor.py) --gen_dir=$(genDir) --cpp_out=$(out) $(in)",
- out: [
- "src/trace_processor/importers/track_event.descriptor.h",
- ],
- tool_files: [
- "tools/gen_cc_proto_descriptor.py",
- ],
+ name: "perfetto_src_trace_processor_importers_gen_cc_track_event_descriptor",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_track_event_descriptor",
+ ],
+ cmd: "$(location tools/gen_cc_proto_descriptor.py) --gen_dir=$(genDir) --cpp_out=$(out) $(in)",
+ out: [
+ "src/trace_processor/importers/track_event.descriptor.h",
+ ],
+ tool_files: [
+ "tools/gen_cc_proto_descriptor.py",
+ ],
}
// GN: //src/trace_processor/importers/memory_tracker:graph_processor
filegroup {
- name: "perfetto_src_trace_processor_importers_memory_tracker_graph_processor",
- srcs: [
- "src/trace_processor/importers/memory_tracker/graph.cc",
- "src/trace_processor/importers/memory_tracker/graph_processor.cc",
- "src/trace_processor/importers/memory_tracker/memory_allocator_node_id.cc",
- "src/trace_processor/importers/memory_tracker/raw_memory_graph_node.cc",
- "src/trace_processor/importers/memory_tracker/raw_process_memory_node.cc",
- ],
+ name: "perfetto_src_trace_processor_importers_memory_tracker_graph_processor",
+ srcs: [
+ "src/trace_processor/importers/memory_tracker/graph.cc",
+ "src/trace_processor/importers/memory_tracker/graph_processor.cc",
+ "src/trace_processor/importers/memory_tracker/memory_allocator_node_id.cc",
+ "src/trace_processor/importers/memory_tracker/raw_memory_graph_node.cc",
+ "src/trace_processor/importers/memory_tracker/raw_process_memory_node.cc",
+ ],
}
// GN: //src/trace_processor:lib
filegroup {
- name: "perfetto_src_trace_processor_lib",
- srcs: [
- "src/trace_processor/dynamic/ancestor_generator.cc",
- "src/trace_processor/dynamic/connected_flow_generator.cc",
- "src/trace_processor/dynamic/descendant_slice_generator.cc",
- "src/trace_processor/dynamic/describe_slice_generator.cc",
- "src/trace_processor/dynamic/experimental_annotated_stack_generator.cc",
- "src/trace_processor/dynamic/experimental_counter_dur_generator.cc",
- "src/trace_processor/dynamic/experimental_flamegraph_generator.cc",
- "src/trace_processor/dynamic/experimental_sched_upid_generator.cc",
- "src/trace_processor/dynamic/experimental_slice_layout_generator.cc",
- "src/trace_processor/dynamic/thread_state_generator.cc",
- "src/trace_processor/iterator_impl.cc",
- "src/trace_processor/read_trace.cc",
- "src/trace_processor/trace_processor.cc",
- "src/trace_processor/trace_processor_impl.cc",
- ],
+ name: "perfetto_src_trace_processor_lib",
+ srcs: [
+ "src/trace_processor/dynamic/ancestor_generator.cc",
+ "src/trace_processor/dynamic/connected_flow_generator.cc",
+ "src/trace_processor/dynamic/descendant_generator.cc",
+ "src/trace_processor/dynamic/describe_slice_generator.cc",
+ "src/trace_processor/dynamic/experimental_annotated_stack_generator.cc",
+ "src/trace_processor/dynamic/experimental_counter_dur_generator.cc",
+ "src/trace_processor/dynamic/experimental_flamegraph_generator.cc",
+ "src/trace_processor/dynamic/experimental_flat_slice_generator.cc",
+ "src/trace_processor/dynamic/experimental_sched_upid_generator.cc",
+ "src/trace_processor/dynamic/experimental_slice_layout_generator.cc",
+ "src/trace_processor/dynamic/thread_state_generator.cc",
+ "src/trace_processor/iterator_impl.cc",
+ "src/trace_processor/read_trace.cc",
+ "src/trace_processor/trace_processor.cc",
+ "src/trace_processor/trace_processor_impl.cc",
+ ],
}
// GN: //src/trace_processor:metatrace
filegroup {
- name: "perfetto_src_trace_processor_metatrace",
- srcs: [
- "src/trace_processor/tp_metatrace.cc",
- ],
+ name: "perfetto_src_trace_processor_metatrace",
+ srcs: [
+ "src/trace_processor/tp_metatrace.cc",
+ ],
}
// GN: //src/trace_processor/metrics:gen_cc_all_chrome_metrics_descriptor
genrule {
- name: "perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
- srcs: [
- ":perfetto_protos_perfetto_metrics_chrome_descriptor",
- ],
- cmd: "$(location tools/gen_cc_proto_descriptor.py) --gen_dir=$(genDir) --cpp_out=$(out) $(in)",
- out: [
- "src/trace_processor/metrics/chrome/all_chrome_metrics.descriptor.h",
- ],
- tool_files: [
- "tools/gen_cc_proto_descriptor.py",
- ],
+ name: "perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
+ srcs: [
+ ":perfetto_protos_perfetto_metrics_chrome_descriptor",
+ ],
+ cmd: "$(location tools/gen_cc_proto_descriptor.py) --gen_dir=$(genDir) --cpp_out=$(out) $(in)",
+ out: [
+ "src/trace_processor/metrics/all_chrome_metrics.descriptor.h",
+ ],
+ tool_files: [
+ "tools/gen_cc_proto_descriptor.py",
+ ],
}
// GN: //src/trace_processor/metrics:gen_cc_metrics_descriptor
genrule {
- name: "perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
- srcs: [
- ":perfetto_protos_perfetto_metrics_descriptor",
- ],
- cmd: "$(location tools/gen_cc_proto_descriptor.py) --gen_dir=$(genDir) --cpp_out=$(out) $(in)",
- out: [
- "src/trace_processor/metrics/metrics.descriptor.h",
- ],
- tool_files: [
- "tools/gen_cc_proto_descriptor.py",
- ],
-}
-
-// GN: //src/trace_processor/metrics:gen_merged_sql_metrics
-genrule {
- name: "perfetto_src_trace_processor_metrics_gen_merged_sql_metrics",
- srcs: [
- "src/trace_processor/metrics/android/android_batt.sql",
- "src/trace_processor/metrics/android/android_cpu.sql",
- "src/trace_processor/metrics/android/android_cpu_agg.sql",
- "src/trace_processor/metrics/android/android_cpu_raw_metrics_per_core.sql",
- "src/trace_processor/metrics/android/android_dma_heap.sql",
- "src/trace_processor/metrics/android/android_fastrpc.sql",
- "src/trace_processor/metrics/android/android_gpu.sql",
- "src/trace_processor/metrics/android/android_hwcomposer.sql",
- "src/trace_processor/metrics/android/android_hwui_metric.sql",
- "src/trace_processor/metrics/android/android_hwui_threads.sql",
- "src/trace_processor/metrics/android/android_ion.sql",
- "src/trace_processor/metrics/android/android_jank.sql",
- "src/trace_processor/metrics/android/android_lmk.sql",
- "src/trace_processor/metrics/android/android_lmk_reason.sql",
- "src/trace_processor/metrics/android/android_mem.sql",
- "src/trace_processor/metrics/android/android_mem_unagg.sql",
- "src/trace_processor/metrics/android/android_package_list.sql",
- "src/trace_processor/metrics/android/android_powrails.sql",
- "src/trace_processor/metrics/android/android_proxy_power.sql",
- "src/trace_processor/metrics/android/android_startup.sql",
- "src/trace_processor/metrics/android/android_startup_launches.sql",
- "src/trace_processor/metrics/android/android_surfaceflinger.sql",
- "src/trace_processor/metrics/android/android_sysui_cuj.sql",
- "src/trace_processor/metrics/android/android_task_names.sql",
- "src/trace_processor/metrics/android/android_thread_time_in_state.sql",
- "src/trace_processor/metrics/android/composer_execution.sql",
- "src/trace_processor/metrics/android/composition_layers.sql",
- "src/trace_processor/metrics/android/cpu_info.sql",
- "src/trace_processor/metrics/android/display_metrics.sql",
- "src/trace_processor/metrics/android/frame_missed.sql",
- "src/trace_processor/metrics/android/g2d.sql",
- "src/trace_processor/metrics/android/g2d_duration.sql",
- "src/trace_processor/metrics/android/global_counter_span_view.sql",
- "src/trace_processor/metrics/android/hsc_startups.sql",
- "src/trace_processor/metrics/android/java_heap_histogram.sql",
- "src/trace_processor/metrics/android/java_heap_stats.sql",
- "src/trace_processor/metrics/android/mem_stats_priority_breakdown.sql",
- "src/trace_processor/metrics/android/power_drain_in_watts.sql",
- "src/trace_processor/metrics/android/power_profile_data.sql",
- "src/trace_processor/metrics/android/process_counter_span_view.sql",
- "src/trace_processor/metrics/android/process_mem.sql",
- "src/trace_processor/metrics/android/process_metadata.sql",
- "src/trace_processor/metrics/android/process_oom_score.sql",
- "src/trace_processor/metrics/android/process_unagg_mem_view.sql",
- "src/trace_processor/metrics/android/span_view_stats.sql",
- "src/trace_processor/metrics/android/unsymbolized_frames.sql",
- "src/trace_processor/metrics/chrome/actual_power_by_category.sql",
- "src/trace_processor/metrics/chrome/actual_power_by_rail_mode.sql",
- "src/trace_processor/metrics/chrome/chrome_event_metadata.sql",
- "src/trace_processor/metrics/chrome/chrome_processes.sql",
- "src/trace_processor/metrics/chrome/chrome_thread_slice_with_cpu_time.sql",
- "src/trace_processor/metrics/chrome/cpu_time_by_category.sql",
- "src/trace_processor/metrics/chrome/cpu_time_by_rail_mode.sql",
- "src/trace_processor/metrics/chrome/estimated_power_by_category.sql",
- "src/trace_processor/metrics/chrome/estimated_power_by_rail_mode.sql",
- "src/trace_processor/metrics/chrome/rail_modes.sql",
- "src/trace_processor/metrics/chrome/scroll_flow_event.sql",
- "src/trace_processor/metrics/chrome/scroll_flow_event_queuing_delay.sql",
- "src/trace_processor/metrics/chrome/scroll_jank.sql",
- "src/trace_processor/metrics/chrome/scroll_jank_cause.sql",
- "src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_task.sql",
- "src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_touch_move.sql",
- "src/trace_processor/metrics/chrome/scroll_jank_cause_get_bitmap.sql",
- "src/trace_processor/metrics/chrome/scroll_jank_cause_queuing_delay.sql",
- "src/trace_processor/metrics/chrome/test_chrome_metric.sql",
- "src/trace_processor/metrics/experimental/blink_gc_metric.sql",
- "src/trace_processor/metrics/experimental/frame_times.sql",
- "src/trace_processor/metrics/experimental/media_metric.sql",
- "src/trace_processor/metrics/experimental/reported_by_page.sql",
- "src/trace_processor/metrics/trace_metadata.sql",
- "src/trace_processor/metrics/trace_stats.sql",
- "src/trace_processor/metrics/webview/webview_power_usage.sql",
- ],
- cmd: "$(location tools/gen_merged_sql_metrics.py) --cpp_out=$(out) $(in)",
- out: [
- "src/trace_processor/metrics/sql_metrics.h",
- ],
- tool_files: [
- "tools/gen_merged_sql_metrics.py",
- ],
-}
-
-// GN: //src/trace_processor/metrics:lib
-filegroup {
- name: "perfetto_src_trace_processor_metrics_lib",
- srcs: [
- "src/trace_processor/metrics/metrics.cc",
- ],
+ name: "perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
+ srcs: [
+ ":perfetto_protos_perfetto_metrics_descriptor",
+ ],
+ cmd: "$(location tools/gen_cc_proto_descriptor.py) --gen_dir=$(genDir) --cpp_out=$(out) $(in)",
+ out: [
+ "src/trace_processor/metrics/metrics.descriptor.h",
+ ],
+ tool_files: [
+ "tools/gen_cc_proto_descriptor.py",
+ ],
+}
+
+// GN: //src/trace_processor/metrics:metrics
+filegroup {
+ name: "perfetto_src_trace_processor_metrics_metrics",
+ srcs: [
+ "src/trace_processor/metrics/metrics.cc",
+ ],
+}
+
+// GN: //src/trace_processor/metrics/sql:gen_amalgamated_sql_metrics
+genrule {
+ name: "perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
+ srcs: [
+ "src/trace_processor/metrics/sql/android/android_batt.sql",
+ "src/trace_processor/metrics/sql/android/android_camera.sql",
+ "src/trace_processor/metrics/sql/android/android_camera_unagg.sql",
+ "src/trace_processor/metrics/sql/android/android_cpu.sql",
+ "src/trace_processor/metrics/sql/android/android_cpu_agg.sql",
+ "src/trace_processor/metrics/sql/android/android_cpu_raw_metrics_per_core.sql",
+ "src/trace_processor/metrics/sql/android/android_dma_heap.sql",
+ "src/trace_processor/metrics/sql/android/android_dvfs.sql",
+ "src/trace_processor/metrics/sql/android/android_fastrpc.sql",
+ "src/trace_processor/metrics/sql/android/android_gpu.sql",
+ "src/trace_processor/metrics/sql/android/android_hwcomposer.sql",
+ "src/trace_processor/metrics/sql/android/android_hwui_metric.sql",
+ "src/trace_processor/metrics/sql/android/android_hwui_threads.sql",
+ "src/trace_processor/metrics/sql/android/android_ion.sql",
+ "src/trace_processor/metrics/sql/android/android_irq_runtime.sql",
+ "src/trace_processor/metrics/sql/android/android_jank.sql",
+ "src/trace_processor/metrics/sql/android/android_lmk.sql",
+ "src/trace_processor/metrics/sql/android/android_lmk_reason.sql",
+ "src/trace_processor/metrics/sql/android/android_mem.sql",
+ "src/trace_processor/metrics/sql/android/android_mem_unagg.sql",
+ "src/trace_processor/metrics/sql/android/android_multiuser.sql",
+ "src/trace_processor/metrics/sql/android/android_multiuser_populator.sql",
+ "src/trace_processor/metrics/sql/android/android_netperf.sql",
+ "src/trace_processor/metrics/sql/android/android_other_traces.sql",
+ "src/trace_processor/metrics/sql/android/android_package_list.sql",
+ "src/trace_processor/metrics/sql/android/android_powrails.sql",
+ "src/trace_processor/metrics/sql/android/android_proxy_power.sql",
+ "src/trace_processor/metrics/sql/android/android_rt_runtime.sql",
+ "src/trace_processor/metrics/sql/android/android_simpleperf.sql",
+ "src/trace_processor/metrics/sql/android/android_startup.sql",
+ "src/trace_processor/metrics/sql/android/android_surfaceflinger.sql",
+ "src/trace_processor/metrics/sql/android/android_sysui_cuj.sql",
+ "src/trace_processor/metrics/sql/android/android_sysui_cuj_jank_query.sql",
+ "src/trace_processor/metrics/sql/android/android_sysui_cuj_surfaceflinger.sql",
+ "src/trace_processor/metrics/sql/android/android_task_names.sql",
+ "src/trace_processor/metrics/sql/android/android_thread_time_in_state.sql",
+ "src/trace_processor/metrics/sql/android/android_trace_quality.sql",
+ "src/trace_processor/metrics/sql/android/android_trusty_workqueues.sql",
+ "src/trace_processor/metrics/sql/android/composer_execution.sql",
+ "src/trace_processor/metrics/sql/android/composition_layers.sql",
+ "src/trace_processor/metrics/sql/android/cpu_info.sql",
+ "src/trace_processor/metrics/sql/android/display_metrics.sql",
+ "src/trace_processor/metrics/sql/android/frame_missed.sql",
+ "src/trace_processor/metrics/sql/android/g2d.sql",
+ "src/trace_processor/metrics/sql/android/g2d_duration.sql",
+ "src/trace_processor/metrics/sql/android/global_counter_span_view.sql",
+ "src/trace_processor/metrics/sql/android/gpu_counter_span_view.sql",
+ "src/trace_processor/metrics/sql/android/java_heap_histogram.sql",
+ "src/trace_processor/metrics/sql/android/java_heap_stats.sql",
+ "src/trace_processor/metrics/sql/android/mem_stats_priority_breakdown.sql",
+ "src/trace_processor/metrics/sql/android/power_drain_in_watts.sql",
+ "src/trace_processor/metrics/sql/android/power_profile_data.sql",
+ "src/trace_processor/metrics/sql/android/process_counter_span_view.sql",
+ "src/trace_processor/metrics/sql/android/process_mem.sql",
+ "src/trace_processor/metrics/sql/android/process_metadata.sql",
+ "src/trace_processor/metrics/sql/android/process_oom_score.sql",
+ "src/trace_processor/metrics/sql/android/process_unagg_mem_view.sql",
+ "src/trace_processor/metrics/sql/android/profiler_smaps.sql",
+ "src/trace_processor/metrics/sql/android/span_view_stats.sql",
+ "src/trace_processor/metrics/sql/android/startup/hsc.sql",
+ "src/trace_processor/metrics/sql/android/startup/launches.sql",
+ "src/trace_processor/metrics/sql/android/startup/launches_maxsdk28.sql",
+ "src/trace_processor/metrics/sql/android/startup/launches_minsdk29.sql",
+ "src/trace_processor/metrics/sql/android/startup/launches_minsdk33.sql",
+ "src/trace_processor/metrics/sql/android/thread_counter_span_view.sql",
+ "src/trace_processor/metrics/sql/android/unsymbolized_frames.sql",
+ "src/trace_processor/metrics/sql/chrome/actual_power_by_category.sql",
+ "src/trace_processor/metrics/sql/chrome/actual_power_by_rail_mode.sql",
+ "src/trace_processor/metrics/sql/chrome/chrome_event_metadata.sql",
+ "src/trace_processor/metrics/sql/chrome/chrome_histogram_hashes.sql",
+ "src/trace_processor/metrics/sql/chrome/chrome_performance_mark_hashes.sql",
+ "src/trace_processor/metrics/sql/chrome/chrome_processes.sql",
+ "src/trace_processor/metrics/sql/chrome/chrome_slice_names.sql",
+ "src/trace_processor/metrics/sql/chrome/chrome_thread_slice.sql",
+ "src/trace_processor/metrics/sql/chrome/chrome_user_event_hashes.sql",
+ "src/trace_processor/metrics/sql/chrome/cpu_time_by_category.sql",
+ "src/trace_processor/metrics/sql/chrome/cpu_time_by_rail_mode.sql",
+ "src/trace_processor/metrics/sql/chrome/estimated_power_by_category.sql",
+ "src/trace_processor/metrics/sql/chrome/estimated_power_by_rail_mode.sql",
+ "src/trace_processor/metrics/sql/chrome/gesture_flow_event.sql",
+ "src/trace_processor/metrics/sql/chrome/gesture_flow_event_queuing_delay.sql",
+ "src/trace_processor/metrics/sql/chrome/gesture_jank.sql",
+ "src/trace_processor/metrics/sql/chrome/jank_utilities.sql",
+ "src/trace_processor/metrics/sql/chrome/rail_modes.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_flow_event.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_flow_event_queuing_delay.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank_cause.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_task.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_touch_move.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_get_bitmap.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_queuing_delay.sql",
+ "src/trace_processor/metrics/sql/chrome/sufficient_chrome_processes.sql",
+ "src/trace_processor/metrics/sql/chrome/test_chrome_metric.sql",
+ "src/trace_processor/metrics/sql/chrome/touch_flow_event.sql",
+ "src/trace_processor/metrics/sql/chrome/touch_flow_event_queuing_delay.sql",
+ "src/trace_processor/metrics/sql/chrome/touch_jank.sql",
+ "src/trace_processor/metrics/sql/experimental/blink_gc_metric.sql",
+ "src/trace_processor/metrics/sql/experimental/chrome_dropped_frames.sql",
+ "src/trace_processor/metrics/sql/experimental/chrome_long_latency.sql",
+ "src/trace_processor/metrics/sql/experimental/frame_times.sql",
+ "src/trace_processor/metrics/sql/experimental/media_metric.sql",
+ "src/trace_processor/metrics/sql/experimental/reported_by_page.sql",
+ "src/trace_processor/metrics/sql/trace_metadata.sql",
+ "src/trace_processor/metrics/sql/trace_stats.sql",
+ "src/trace_processor/metrics/sql/webview/webview_power_usage.sql",
+ ],
+ cmd: "$(location tools/gen_amalgamated_sql_metrics.py) --cpp_out=$(out) $(in)",
+ out: [
+ "src/trace_processor/metrics/sql/amalgamated_sql_metrics.h",
+ ],
+ tool_files: [
+ "tools/gen_amalgamated_sql_metrics.py",
+ ],
}
// GN: //src/trace_processor/metrics:unittests
filegroup {
- name: "perfetto_src_trace_processor_metrics_unittests",
- srcs: [
- "src/trace_processor/metrics/metrics_unittest.cc",
- ],
+ name: "perfetto_src_trace_processor_metrics_unittests",
+ srcs: [
+ "src/trace_processor/metrics/metrics_unittest.cc",
+ ],
+}
+
+// GN: //src/trace_processor/rpc:httpd
+filegroup {
+ name: "perfetto_src_trace_processor_rpc_httpd",
+ srcs: [
+ "src/trace_processor/rpc/httpd.cc",
+ ],
}
// GN: //src/trace_processor/rpc:rpc
filegroup {
- name: "perfetto_src_trace_processor_rpc_rpc",
- srcs: [
- "src/trace_processor/rpc/proto_ring_buffer.cc",
- "src/trace_processor/rpc/query_result_serializer.cc",
- "src/trace_processor/rpc/rpc.cc",
- ],
+ name: "perfetto_src_trace_processor_rpc_rpc",
+ srcs: [
+ "src/trace_processor/rpc/query_result_serializer.cc",
+ "src/trace_processor/rpc/rpc.cc",
+ ],
}
// GN: //src/trace_processor/rpc:unittests
filegroup {
- name: "perfetto_src_trace_processor_rpc_unittests",
- srcs: [
- "src/trace_processor/rpc/proto_ring_buffer_unittest.cc",
- "src/trace_processor/rpc/query_result_serializer_unittest.cc",
- ],
+ name: "perfetto_src_trace_processor_rpc_unittests",
+ srcs: [
+ "src/trace_processor/rpc/query_result_serializer_unittest.cc",
+ ],
}
// GN: //src/trace_processor/sqlite:sqlite
filegroup {
- name: "perfetto_src_trace_processor_sqlite_sqlite",
- srcs: [
- "src/trace_processor/sqlite/db_sqlite_table.cc",
- "src/trace_processor/sqlite/query_constraints.cc",
- "src/trace_processor/sqlite/span_join_operator_table.cc",
- "src/trace_processor/sqlite/sql_stats_table.cc",
- "src/trace_processor/sqlite/sqlite3_str_split.cc",
- "src/trace_processor/sqlite/sqlite_raw_table.cc",
- "src/trace_processor/sqlite/sqlite_table.cc",
- "src/trace_processor/sqlite/stats_table.cc",
- "src/trace_processor/sqlite/window_operator_table.cc",
- ],
+ name: "perfetto_src_trace_processor_sqlite_sqlite",
+ srcs: [
+ "src/trace_processor/sqlite/create_function.cc",
+ "src/trace_processor/sqlite/create_function_internal.cc",
+ "src/trace_processor/sqlite/create_view_function.cc",
+ "src/trace_processor/sqlite/db_sqlite_table.cc",
+ "src/trace_processor/sqlite/query_constraints.cc",
+ "src/trace_processor/sqlite/register_function.cc",
+ "src/trace_processor/sqlite/span_join_operator_table.cc",
+ "src/trace_processor/sqlite/sql_stats_table.cc",
+ "src/trace_processor/sqlite/sqlite3_str_split.cc",
+ "src/trace_processor/sqlite/sqlite_raw_table.cc",
+ "src/trace_processor/sqlite/sqlite_table.cc",
+ "src/trace_processor/sqlite/stats_table.cc",
+ "src/trace_processor/sqlite/window_operator_table.cc",
+ ],
}
// GN: //src/trace_processor/sqlite:unittests
filegroup {
- name: "perfetto_src_trace_processor_sqlite_unittests",
- srcs: [
- "src/trace_processor/sqlite/db_sqlite_table_unittest.cc",
- "src/trace_processor/sqlite/query_constraints_unittest.cc",
- "src/trace_processor/sqlite/span_join_operator_table_unittest.cc",
- "src/trace_processor/sqlite/sqlite3_str_split_unittest.cc",
- "src/trace_processor/sqlite/sqlite_utils_unittest.cc",
- ],
+ name: "perfetto_src_trace_processor_sqlite_unittests",
+ srcs: [
+ "src/trace_processor/sqlite/db_sqlite_table_unittest.cc",
+ "src/trace_processor/sqlite/query_constraints_unittest.cc",
+ "src/trace_processor/sqlite/span_join_operator_table_unittest.cc",
+ "src/trace_processor/sqlite/sqlite3_str_split_unittest.cc",
+ "src/trace_processor/sqlite/sqlite_utils_unittest.cc",
+ ],
}
// GN: //src/trace_processor:storage_full
filegroup {
- name: "perfetto_src_trace_processor_storage_full",
- srcs: [
- "src/trace_processor/importers/additional_modules.cc",
- "src/trace_processor/importers/ftrace/binder_tracker.cc",
- "src/trace_processor/importers/ftrace/ftrace_module_impl.cc",
- "src/trace_processor/importers/ftrace/ftrace_parser.cc",
- "src/trace_processor/importers/ftrace/ftrace_tokenizer.cc",
- "src/trace_processor/importers/ftrace/rss_stat_tracker.cc",
- "src/trace_processor/importers/ftrace/sched_event_tracker.cc",
- "src/trace_processor/importers/fuchsia/fuchsia_record.cc",
- "src/trace_processor/importers/fuchsia/fuchsia_trace_parser.cc",
- "src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.cc",
- "src/trace_processor/importers/fuchsia/fuchsia_trace_utils.cc",
- "src/trace_processor/importers/gzip/gzip_trace_parser.cc",
- "src/trace_processor/importers/json/json_trace_parser.cc",
- "src/trace_processor/importers/json/json_trace_tokenizer.cc",
- "src/trace_processor/importers/json/json_tracker.cc",
- "src/trace_processor/importers/proto/android_probes_module.cc",
- "src/trace_processor/importers/proto/android_probes_parser.cc",
- "src/trace_processor/importers/proto/android_probes_tracker.cc",
- "src/trace_processor/importers/proto/frame_timeline_event_parser.cc",
- "src/trace_processor/importers/proto/gpu_event_parser.cc",
- "src/trace_processor/importers/proto/graphics_event_module.cc",
- "src/trace_processor/importers/proto/graphics_frame_event_parser.cc",
- "src/trace_processor/importers/proto/heap_graph_module.cc",
- "src/trace_processor/importers/proto/heap_graph_tracker.cc",
- "src/trace_processor/importers/proto/system_probes_module.cc",
- "src/trace_processor/importers/proto/system_probes_parser.cc",
- "src/trace_processor/importers/proto/vulkan_memory_tracker.cc",
- "src/trace_processor/importers/syscalls/syscall_tracker.cc",
- "src/trace_processor/importers/systrace/systrace_line_parser.cc",
- "src/trace_processor/importers/systrace/systrace_line_tokenizer.cc",
- "src/trace_processor/importers/systrace/systrace_parser.cc",
- "src/trace_processor/importers/systrace/systrace_trace_parser.cc",
- ],
+ name: "perfetto_src_trace_processor_storage_full",
+ srcs: [
+ "src/trace_processor/importers/additional_modules.cc",
+ "src/trace_processor/importers/ftrace/binder_tracker.cc",
+ "src/trace_processor/importers/ftrace/ftrace_module_impl.cc",
+ "src/trace_processor/importers/ftrace/ftrace_parser.cc",
+ "src/trace_processor/importers/ftrace/ftrace_tokenizer.cc",
+ "src/trace_processor/importers/ftrace/rss_stat_tracker.cc",
+ "src/trace_processor/importers/ftrace/sched_event_tracker.cc",
+ "src/trace_processor/importers/fuchsia/fuchsia_record.cc",
+ "src/trace_processor/importers/fuchsia/fuchsia_trace_parser.cc",
+ "src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.cc",
+ "src/trace_processor/importers/fuchsia/fuchsia_trace_utils.cc",
+ "src/trace_processor/importers/gzip/gzip_trace_parser.cc",
+ "src/trace_processor/importers/json/json_trace_parser.cc",
+ "src/trace_processor/importers/json/json_trace_tokenizer.cc",
+ "src/trace_processor/importers/proto/android_probes_module.cc",
+ "src/trace_processor/importers/proto/android_probes_parser.cc",
+ "src/trace_processor/importers/proto/android_probes_tracker.cc",
+ "src/trace_processor/importers/proto/frame_timeline_event_parser.cc",
+ "src/trace_processor/importers/proto/gpu_event_parser.cc",
+ "src/trace_processor/importers/proto/graphics_event_module.cc",
+ "src/trace_processor/importers/proto/graphics_frame_event_parser.cc",
+ "src/trace_processor/importers/proto/heap_graph_module.cc",
+ "src/trace_processor/importers/proto/heap_graph_tracker.cc",
+ "src/trace_processor/importers/proto/system_probes_module.cc",
+ "src/trace_processor/importers/proto/system_probes_parser.cc",
+ "src/trace_processor/importers/proto/vulkan_memory_tracker.cc",
+ "src/trace_processor/importers/syscalls/syscall_tracker.cc",
+ "src/trace_processor/importers/systrace/systrace_line_parser.cc",
+ "src/trace_processor/importers/systrace/systrace_line_tokenizer.cc",
+ "src/trace_processor/importers/systrace/systrace_parser.cc",
+ "src/trace_processor/importers/systrace/systrace_trace_parser.cc",
+ ],
}
// GN: //src/trace_processor:storage_minimal
filegroup {
- name: "perfetto_src_trace_processor_storage_minimal",
- srcs: [
- "src/trace_processor/forwarding_trace_parser.cc",
- "src/trace_processor/importers/default_modules.cc",
- "src/trace_processor/importers/ftrace/ftrace_module.cc",
- "src/trace_processor/importers/gzip/gzip_utils.cc",
- "src/trace_processor/importers/json/json_utils.cc",
- "src/trace_processor/importers/ninja/ninja_log_parser.cc",
- "src/trace_processor/importers/proto/async_track_set_tracker.cc",
- "src/trace_processor/importers/proto/chrome_string_lookup.cc",
- "src/trace_processor/importers/proto/chrome_system_probes_module.cc",
- "src/trace_processor/importers/proto/chrome_system_probes_parser.cc",
- "src/trace_processor/importers/proto/heap_profile_tracker.cc",
- "src/trace_processor/importers/proto/memory_tracker_snapshot_module.cc",
- "src/trace_processor/importers/proto/memory_tracker_snapshot_parser.cc",
- "src/trace_processor/importers/proto/metadata_module.cc",
- "src/trace_processor/importers/proto/metadata_tracker.cc",
- "src/trace_processor/importers/proto/packet_sequence_state.cc",
- "src/trace_processor/importers/proto/perf_sample_tracker.cc",
- "src/trace_processor/importers/proto/profile_module.cc",
- "src/trace_processor/importers/proto/profile_packet_utils.cc",
- "src/trace_processor/importers/proto/profiler_util.cc",
- "src/trace_processor/importers/proto/proto_importer_module.cc",
- "src/trace_processor/importers/proto/proto_trace_parser.cc",
- "src/trace_processor/importers/proto/proto_trace_reader.cc",
- "src/trace_processor/importers/proto/proto_trace_tokenizer.cc",
- "src/trace_processor/importers/proto/stack_profile_tracker.cc",
- "src/trace_processor/importers/proto/track_event_module.cc",
- "src/trace_processor/importers/proto/track_event_parser.cc",
- "src/trace_processor/importers/proto/track_event_tokenizer.cc",
- "src/trace_processor/importers/proto/track_event_tracker.cc",
- "src/trace_processor/trace_processor_context.cc",
- "src/trace_processor/trace_processor_storage.cc",
- "src/trace_processor/trace_processor_storage_impl.cc",
- "src/trace_processor/trace_sorter.cc",
- "src/trace_processor/virtual_destructors.cc",
- ],
+ name: "perfetto_src_trace_processor_storage_minimal",
+ srcs: [
+ "src/trace_processor/forwarding_trace_parser.cc",
+ "src/trace_processor/importers/default_modules.cc",
+ "src/trace_processor/importers/ftrace/ftrace_module.cc",
+ "src/trace_processor/importers/json/json_utils.cc",
+ "src/trace_processor/importers/ninja/ninja_log_parser.cc",
+ "src/trace_processor/importers/proto/android_camera_event_module.cc",
+ "src/trace_processor/importers/proto/async_track_set_tracker.cc",
+ "src/trace_processor/importers/proto/chrome_string_lookup.cc",
+ "src/trace_processor/importers/proto/chrome_system_probes_module.cc",
+ "src/trace_processor/importers/proto/chrome_system_probes_parser.cc",
+ "src/trace_processor/importers/proto/flamegraph_construction_algorithms.cc",
+ "src/trace_processor/importers/proto/heap_profile_tracker.cc",
+ "src/trace_processor/importers/proto/memory_tracker_snapshot_module.cc",
+ "src/trace_processor/importers/proto/memory_tracker_snapshot_parser.cc",
+ "src/trace_processor/importers/proto/metadata_module.cc",
+ "src/trace_processor/importers/proto/metadata_tracker.cc",
+ "src/trace_processor/importers/proto/packet_sequence_state.cc",
+ "src/trace_processor/importers/proto/perf_sample_tracker.cc",
+ "src/trace_processor/importers/proto/profile_module.cc",
+ "src/trace_processor/importers/proto/profile_packet_utils.cc",
+ "src/trace_processor/importers/proto/profiler_util.cc",
+ "src/trace_processor/importers/proto/proto_importer_module.cc",
+ "src/trace_processor/importers/proto/proto_trace_parser.cc",
+ "src/trace_processor/importers/proto/proto_trace_reader.cc",
+ "src/trace_processor/importers/proto/proto_trace_tokenizer.cc",
+ "src/trace_processor/importers/proto/stack_profile_tracker.cc",
+ "src/trace_processor/importers/proto/track_event_module.cc",
+ "src/trace_processor/importers/proto/track_event_parser.cc",
+ "src/trace_processor/importers/proto/track_event_tokenizer.cc",
+ "src/trace_processor/importers/proto/track_event_tracker.cc",
+ "src/trace_processor/importers/proto/translation_table_module.cc",
+ "src/trace_processor/trace_blob.cc",
+ "src/trace_processor/trace_processor_context.cc",
+ "src/trace_processor/trace_processor_storage.cc",
+ "src/trace_processor/trace_processor_storage_impl.cc",
+ "src/trace_processor/trace_sorter.cc",
+ "src/trace_processor/virtual_destructors.cc",
+ ],
}
// GN: //src/trace_processor/storage:storage
filegroup {
- name: "perfetto_src_trace_processor_storage_storage",
- srcs: [
- "src/trace_processor/storage/trace_storage.cc",
- ],
+ name: "perfetto_src_trace_processor_storage_storage",
+ srcs: [
+ "src/trace_processor/storage/trace_storage.cc",
+ ],
}
// GN: //src/trace_processor/tables:tables
filegroup {
- name: "perfetto_src_trace_processor_tables_tables",
- srcs: [
- "src/trace_processor/tables/table_destructors.cc",
- ],
+ name: "perfetto_src_trace_processor_tables_tables",
+ srcs: [
+ "src/trace_processor/tables/table_destructors.cc",
+ ],
}
// GN: //src/trace_processor/tables:unittests
filegroup {
- name: "perfetto_src_trace_processor_tables_unittests",
- srcs: [
- "src/trace_processor/tables/macros_unittest.cc",
- ],
+ name: "perfetto_src_trace_processor_tables_unittests",
+ srcs: [
+ "src/trace_processor/tables/macros_unittest.cc",
+ ],
}
// GN: //src/trace_processor/types:types
filegroup {
- name: "perfetto_src_trace_processor_types_types",
- srcs: [
- "src/trace_processor/types/destructible.cc",
- "src/trace_processor/types/gfp_flags.cc",
- "src/trace_processor/types/task_state.cc",
- "src/trace_processor/types/variadic.cc",
- ],
+ name: "perfetto_src_trace_processor_types_types",
+ srcs: [
+ "src/trace_processor/types/destructible.cc",
+ "src/trace_processor/types/gfp_flags.cc",
+ "src/trace_processor/types/task_state.cc",
+ "src/trace_processor/types/variadic.cc",
+ ],
}
// GN: //src/trace_processor/types:unittests
filegroup {
- name: "perfetto_src_trace_processor_types_unittests",
- srcs: [
- "src/trace_processor/types/task_state_unittests.cc",
- ],
+ name: "perfetto_src_trace_processor_types_unittests",
+ srcs: [
+ "src/trace_processor/types/task_state_unittests.cc",
+ ],
}
// GN: //src/trace_processor:unittests
filegroup {
- name: "perfetto_src_trace_processor_unittests",
- srcs: [
- "src/trace_processor/dynamic/experimental_counter_dur_generator_unittest.cc",
- "src/trace_processor/dynamic/experimental_slice_layout_generator_unittest.cc",
- "src/trace_processor/dynamic/thread_state_generator_unittest.cc",
- "src/trace_processor/forwarding_trace_parser_unittest.cc",
- "src/trace_processor/importers/ftrace/sched_event_tracker_unittest.cc",
- "src/trace_processor/importers/fuchsia/fuchsia_trace_utils_unittest.cc",
- "src/trace_processor/importers/memory_tracker/graph_processor_unittest.cc",
- "src/trace_processor/importers/memory_tracker/graph_unittest.cc",
- "src/trace_processor/importers/memory_tracker/raw_process_memory_node_unittest.cc",
- "src/trace_processor/importers/proto/async_track_set_tracker_unittest.cc",
- "src/trace_processor/importers/proto/heap_graph_tracker_unittest.cc",
- "src/trace_processor/importers/proto/heap_profile_tracker_unittest.cc",
- "src/trace_processor/importers/proto/perf_sample_tracker_unittest.cc",
- "src/trace_processor/importers/proto/proto_trace_parser_unittest.cc",
- "src/trace_processor/importers/syscalls/syscall_tracker_unittest.cc",
- "src/trace_processor/importers/systrace/systrace_parser_unittest.cc",
- "src/trace_processor/trace_sorter_unittest.cc",
- ],
+ name: "perfetto_src_trace_processor_unittests",
+ srcs: [
+ "src/trace_processor/dynamic/experimental_counter_dur_generator_unittest.cc",
+ "src/trace_processor/dynamic/experimental_flat_slice_generator_unittest.cc",
+ "src/trace_processor/dynamic/experimental_slice_layout_generator_unittest.cc",
+ "src/trace_processor/dynamic/thread_state_generator_unittest.cc",
+ "src/trace_processor/forwarding_trace_parser_unittest.cc",
+ "src/trace_processor/importers/ftrace/binder_tracker_unittest.cc",
+ "src/trace_processor/importers/ftrace/sched_event_tracker_unittest.cc",
+ "src/trace_processor/importers/fuchsia/fuchsia_trace_utils_unittest.cc",
+ "src/trace_processor/importers/memory_tracker/graph_processor_unittest.cc",
+ "src/trace_processor/importers/memory_tracker/graph_unittest.cc",
+ "src/trace_processor/importers/memory_tracker/raw_process_memory_node_unittest.cc",
+ "src/trace_processor/importers/proto/async_track_set_tracker_unittest.cc",
+ "src/trace_processor/importers/proto/heap_graph_tracker_unittest.cc",
+ "src/trace_processor/importers/proto/heap_profile_tracker_unittest.cc",
+ "src/trace_processor/importers/proto/perf_sample_tracker_unittest.cc",
+ "src/trace_processor/importers/proto/proto_trace_parser_unittest.cc",
+ "src/trace_processor/importers/syscalls/syscall_tracker_unittest.cc",
+ "src/trace_processor/importers/systrace/systrace_parser_unittest.cc",
+ "src/trace_processor/ref_counted_unittest.cc",
+ "src/trace_processor/trace_sorter_unittest.cc",
+ ],
}
// GN: //src/trace_processor/util:descriptors
filegroup {
- name: "perfetto_src_trace_processor_util_descriptors",
- srcs: [
- "src/trace_processor/util/descriptors.cc",
- ],
+ name: "perfetto_src_trace_processor_util_descriptors",
+ srcs: [
+ "src/trace_processor/util/descriptors.cc",
+ ],
+}
+
+// GN: //src/trace_processor/util:gzip
+filegroup {
+ name: "perfetto_src_trace_processor_util_gzip",
+ srcs: [
+ "src/trace_processor/util/gzip_utils.cc",
+ ],
+}
+
+// GN: //src/trace_processor/util:interned_message_view
+filegroup {
+ name: "perfetto_src_trace_processor_util_interned_message_view",
}
// GN: //src/trace_processor/util:proto_to_args_parser
filegroup {
- name: "perfetto_src_trace_processor_util_proto_to_args_parser",
- srcs: [
- "src/trace_processor/util/proto_to_args_parser.cc",
- ],
+ name: "perfetto_src_trace_processor_util_proto_to_args_parser",
+ srcs: [
+ "src/trace_processor/util/debug_annotation_parser.cc",
+ "src/trace_processor/util/proto_to_args_parser.cc",
+ ],
}
// GN: //src/trace_processor/util:protozero_to_text
filegroup {
- name: "perfetto_src_trace_processor_util_protozero_to_text",
- srcs: [
- "src/trace_processor/util/protozero_to_text.cc",
- ],
+ name: "perfetto_src_trace_processor_util_protozero_to_text",
+ srcs: [
+ "src/trace_processor/util/protozero_to_text.cc",
+ ],
}
// GN: //src/trace_processor/util:unittests
filegroup {
- name: "perfetto_src_trace_processor_util_unittests",
- srcs: [
- "src/trace_processor/util/proto_to_args_parser_unittest.cc",
- "src/trace_processor/util/protozero_to_text_unittests.cc",
- ],
+ name: "perfetto_src_trace_processor_util_unittests",
+ srcs: [
+ "src/trace_processor/util/debug_annotation_parser_unittest.cc",
+ "src/trace_processor/util/gzip_utils_unittest.cc",
+ "src/trace_processor/util/proto_to_args_parser_unittest.cc",
+ "src/trace_processor/util/protozero_to_text_unittests.cc",
+ ],
}
// GN: //src/trace_processor/util:util
filegroup {
- name: "perfetto_src_trace_processor_util_util",
+ name: "perfetto_src_trace_processor_util_util",
}
// GN: //src/traced/probes/android_log:android_log
filegroup {
- name: "perfetto_src_traced_probes_android_log_android_log",
- srcs: [
- "src/traced/probes/android_log/android_log_data_source.cc",
- ],
+ name: "perfetto_src_traced_probes_android_log_android_log",
+ srcs: [
+ "src/traced/probes/android_log/android_log_data_source.cc",
+ ],
}
// GN: //src/traced/probes/android_log:unittests
filegroup {
- name: "perfetto_src_traced_probes_android_log_unittests",
- srcs: [
- "src/traced/probes/android_log/android_log_data_source_unittest.cc",
- ],
+ name: "perfetto_src_traced_probes_android_log_unittests",
+ srcs: [
+ "src/traced/probes/android_log/android_log_data_source_unittest.cc",
+ ],
}
// GN: //src/traced/probes/common:common
filegroup {
- name: "perfetto_src_traced_probes_common_common",
- srcs: [
- "src/traced/probes/common/cpu_freq_info.cc",
- ],
+ name: "perfetto_src_traced_probes_common_common",
+ srcs: [
+ "src/traced/probes/common/cpu_freq_info.cc",
+ ],
}
// GN: //src/traced/probes/common:test_support
filegroup {
- name: "perfetto_src_traced_probes_common_test_support",
- srcs: [
- "src/traced/probes/common/cpu_freq_info_for_testing.cc",
- ],
+ name: "perfetto_src_traced_probes_common_test_support",
+ srcs: [
+ "src/traced/probes/common/cpu_freq_info_for_testing.cc",
+ ],
}
// GN: //src/traced/probes/common:unittests
filegroup {
- name: "perfetto_src_traced_probes_common_unittests",
- srcs: [
- "src/traced/probes/common/cpu_freq_info_unittest.cc",
- ],
+ name: "perfetto_src_traced_probes_common_unittests",
+ srcs: [
+ "src/traced/probes/common/cpu_freq_info_unittest.cc",
+ ],
}
// GN: //src/traced/probes:data_source
filegroup {
- name: "perfetto_src_traced_probes_data_source",
- srcs: [
- "src/traced/probes/probes_data_source.cc",
- ],
+ name: "perfetto_src_traced_probes_data_source",
+ srcs: [
+ "src/traced/probes/probes_data_source.cc",
+ ],
}
// GN: //src/traced/probes/filesystem:filesystem
filegroup {
- name: "perfetto_src_traced_probes_filesystem_filesystem",
- srcs: [
- "src/traced/probes/filesystem/file_scanner.cc",
- "src/traced/probes/filesystem/fs_mount.cc",
- "src/traced/probes/filesystem/inode_file_data_source.cc",
- "src/traced/probes/filesystem/lru_inode_cache.cc",
- "src/traced/probes/filesystem/prefix_finder.cc",
- "src/traced/probes/filesystem/range_tree.cc",
- ],
+ name: "perfetto_src_traced_probes_filesystem_filesystem",
+ srcs: [
+ "src/traced/probes/filesystem/file_scanner.cc",
+ "src/traced/probes/filesystem/fs_mount.cc",
+ "src/traced/probes/filesystem/inode_file_data_source.cc",
+ "src/traced/probes/filesystem/lru_inode_cache.cc",
+ "src/traced/probes/filesystem/prefix_finder.cc",
+ "src/traced/probes/filesystem/range_tree.cc",
+ ],
}
// GN: //src/traced/probes/filesystem:unittests
filegroup {
- name: "perfetto_src_traced_probes_filesystem_unittests",
- srcs: [
- "src/traced/probes/filesystem/file_scanner_unittest.cc",
- "src/traced/probes/filesystem/fs_mount_unittest.cc",
- "src/traced/probes/filesystem/inode_file_data_source_unittest.cc",
- "src/traced/probes/filesystem/lru_inode_cache_unittest.cc",
- "src/traced/probes/filesystem/prefix_finder_unittest.cc",
- "src/traced/probes/filesystem/range_tree_unittest.cc",
- ],
+ name: "perfetto_src_traced_probes_filesystem_unittests",
+ srcs: [
+ "src/traced/probes/filesystem/file_scanner_unittest.cc",
+ "src/traced/probes/filesystem/fs_mount_unittest.cc",
+ "src/traced/probes/filesystem/inode_file_data_source_unittest.cc",
+ "src/traced/probes/filesystem/lru_inode_cache_unittest.cc",
+ "src/traced/probes/filesystem/prefix_finder_unittest.cc",
+ "src/traced/probes/filesystem/range_tree_unittest.cc",
+ ],
}
// GN: //src/traced/probes/ftrace/format_parser:format_parser
filegroup {
- name: "perfetto_src_traced_probes_ftrace_format_parser_format_parser",
- srcs: [
- "src/traced/probes/ftrace/format_parser/format_parser.cc",
- ],
+ name: "perfetto_src_traced_probes_ftrace_format_parser_format_parser",
+ srcs: [
+ "src/traced/probes/ftrace/format_parser/format_parser.cc",
+ ],
}
// GN: //src/traced/probes/ftrace/format_parser:unittests
filegroup {
- name: "perfetto_src_traced_probes_ftrace_format_parser_unittests",
- srcs: [
- "src/traced/probes/ftrace/format_parser/format_parser_unittest.cc",
- ],
+ name: "perfetto_src_traced_probes_ftrace_format_parser_unittests",
+ srcs: [
+ "src/traced/probes/ftrace/format_parser/format_parser_unittest.cc",
+ ],
}
// GN: //src/traced/probes/ftrace:ftrace
filegroup {
- name: "perfetto_src_traced_probes_ftrace_ftrace",
- srcs: [
- "src/traced/probes/ftrace/atrace_hal_wrapper.cc",
- "src/traced/probes/ftrace/atrace_wrapper.cc",
- "src/traced/probes/ftrace/compact_sched.cc",
- "src/traced/probes/ftrace/cpu_reader.cc",
- "src/traced/probes/ftrace/cpu_stats_parser.cc",
- "src/traced/probes/ftrace/discover_vendor_tracepoints.cc",
- "src/traced/probes/ftrace/event_info.cc",
- "src/traced/probes/ftrace/event_info_constants.cc",
- "src/traced/probes/ftrace/ftrace_config_muxer.cc",
- "src/traced/probes/ftrace/ftrace_config_utils.cc",
- "src/traced/probes/ftrace/ftrace_controller.cc",
- "src/traced/probes/ftrace/ftrace_data_source.cc",
- "src/traced/probes/ftrace/ftrace_stats.cc",
- "src/traced/probes/ftrace/printk_formats_parser.cc",
- "src/traced/probes/ftrace/proto_translation_table.cc",
- ],
+ name: "perfetto_src_traced_probes_ftrace_ftrace",
+ srcs: [
+ "src/traced/probes/ftrace/atrace_hal_wrapper.cc",
+ "src/traced/probes/ftrace/atrace_wrapper.cc",
+ "src/traced/probes/ftrace/compact_sched.cc",
+ "src/traced/probes/ftrace/cpu_reader.cc",
+ "src/traced/probes/ftrace/cpu_stats_parser.cc",
+ "src/traced/probes/ftrace/discover_vendor_tracepoints.cc",
+ "src/traced/probes/ftrace/event_info.cc",
+ "src/traced/probes/ftrace/event_info_constants.cc",
+ "src/traced/probes/ftrace/ftrace_config_muxer.cc",
+ "src/traced/probes/ftrace/ftrace_config_utils.cc",
+ "src/traced/probes/ftrace/ftrace_controller.cc",
+ "src/traced/probes/ftrace/ftrace_data_source.cc",
+ "src/traced/probes/ftrace/ftrace_stats.cc",
+ "src/traced/probes/ftrace/printk_formats_parser.cc",
+ "src/traced/probes/ftrace/proto_translation_table.cc",
+ ],
}
// GN: //src/traced/probes/ftrace:ftrace_procfs
filegroup {
- name: "perfetto_src_traced_probes_ftrace_ftrace_procfs",
- srcs: [
- "src/traced/probes/ftrace/ftrace_procfs.cc",
- ],
+ name: "perfetto_src_traced_probes_ftrace_ftrace_procfs",
+ srcs: [
+ "src/traced/probes/ftrace/ftrace_procfs.cc",
+ ],
}
// GN: //src/traced/probes/ftrace:integrationtests
filegroup {
- name: "perfetto_src_traced_probes_ftrace_integrationtests",
- srcs: [
- "src/traced/probes/ftrace/ftrace_procfs_integrationtest.cc",
- ],
+ name: "perfetto_src_traced_probes_ftrace_integrationtests",
+ srcs: [
+ "src/traced/probes/ftrace/ftrace_procfs_integrationtest.cc",
+ ],
}
// GN: //src/traced/probes/ftrace:test_messages_cpp
genrule {
- name: "perfetto_src_traced_probes_ftrace_test_messages_cpp_gen",
- srcs: [
- "src/traced/probes/ftrace/test/test_messages.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/src/traced/probes/ftrace/test/test_messages.gen.cc",
- ],
+ name: "perfetto_src_traced_probes_ftrace_test_messages_cpp_gen",
+ srcs: [
+ "src/traced/probes/ftrace/test/test_messages.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/src/traced/probes/ftrace/test/test_messages.gen.cc",
+ ],
}
// GN: //src/traced/probes/ftrace:test_messages_cpp
genrule {
- name: "perfetto_src_traced_probes_ftrace_test_messages_cpp_gen_headers",
- srcs: [
- "src/traced/probes/ftrace/test/test_messages.proto",
- ],
- tools: [
- "aprotoc",
- "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/src/traced/probes/ftrace/test/test_messages.gen.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_src_traced_probes_ftrace_test_messages_cpp_gen_headers",
+ srcs: [
+ "src/traced/probes/ftrace/test/test_messages.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "perfetto_src_protozero_protoc_plugin_cppgen_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location perfetto_src_protozero_protoc_plugin_cppgen_plugin) --plugin_out=wrapper_namespace=gen:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/src/traced/probes/ftrace/test/test_messages.gen.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //src/traced/probes/ftrace:test_messages_lite
genrule {
- name: "perfetto_src_traced_probes_ftrace_test_messages_lite_gen",
- srcs: [
- "src/traced/probes/ftrace/test/test_messages.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/src/traced/probes/ftrace/test/test_messages.pb.cc",
- ],
+ name: "perfetto_src_traced_probes_ftrace_test_messages_lite_gen",
+ srcs: [
+ "src/traced/probes/ftrace/test/test_messages.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/src/traced/probes/ftrace/test/test_messages.pb.cc",
+ ],
}
// GN: //src/traced/probes/ftrace:test_messages_lite
genrule {
- name: "perfetto_src_traced_probes_ftrace_test_messages_lite_gen_headers",
- srcs: [
- "src/traced/probes/ftrace/test/test_messages.proto",
- ],
- tools: [
- "aprotoc",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/src/traced/probes/ftrace/test/test_messages.pb.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_src_traced_probes_ftrace_test_messages_lite_gen_headers",
+ srcs: [
+ "src/traced/probes/ftrace/test/test_messages.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --cpp_out=lite=true:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/src/traced/probes/ftrace/test/test_messages.pb.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //src/traced/probes/ftrace:test_messages_zero
genrule {
- name: "perfetto_src_traced_probes_ftrace_test_messages_zero_gen",
- srcs: [
- "src/traced/probes/ftrace/test/test_messages.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/src/traced/probes/ftrace/test/test_messages.pbzero.cc",
- ],
+ name: "perfetto_src_traced_probes_ftrace_test_messages_zero_gen",
+ srcs: [
+ "src/traced/probes/ftrace/test/test_messages.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/src/traced/probes/ftrace/test/test_messages.pbzero.cc",
+ ],
}
// GN: //src/traced/probes/ftrace:test_messages_zero
genrule {
- name: "perfetto_src_traced_probes_ftrace_test_messages_zero_gen_headers",
- srcs: [
- "src/traced/probes/ftrace/test/test_messages.proto",
- ],
- tools: [
- "aprotoc",
- "protozero_plugin",
- ],
- cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
- out: [
- "external/perfetto/src/traced/probes/ftrace/test/test_messages.pbzero.h",
- ],
- export_include_dirs: [
- ".",
- "protos",
- ],
+ name: "perfetto_src_traced_probes_ftrace_test_messages_zero_gen_headers",
+ srcs: [
+ "src/traced/probes/ftrace/test/test_messages.proto",
+ ],
+ tools: [
+ "aprotoc",
+ "protozero_plugin",
+ ],
+ cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --plugin=protoc-gen-plugin=$(location protozero_plugin) --plugin_out=wrapper_namespace=pbzero:$(genDir)/external/perfetto/ $(in)",
+ out: [
+ "external/perfetto/src/traced/probes/ftrace/test/test_messages.pbzero.h",
+ ],
+ export_include_dirs: [
+ ".",
+ "protos",
+ ],
}
// GN: //src/traced/probes/ftrace:test_support
filegroup {
- name: "perfetto_src_traced_probes_ftrace_test_support",
- srcs: [
- "src/traced/probes/ftrace/test/cpu_reader_support.cc",
- ],
+ name: "perfetto_src_traced_probes_ftrace_test_support",
+ srcs: [
+ "src/traced/probes/ftrace/test/cpu_reader_support.cc",
+ ],
}
// GN: //src/traced/probes/ftrace:unittests
filegroup {
- name: "perfetto_src_traced_probes_ftrace_unittests",
- srcs: [
- "src/traced/probes/ftrace/cpu_reader_unittest.cc",
- "src/traced/probes/ftrace/cpu_stats_parser_unittest.cc",
- "src/traced/probes/ftrace/discover_vendor_tracepoints_unittest.cc",
- "src/traced/probes/ftrace/event_info_unittest.cc",
- "src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc",
- "src/traced/probes/ftrace/ftrace_config_unittest.cc",
- "src/traced/probes/ftrace/ftrace_controller_unittest.cc",
- "src/traced/probes/ftrace/ftrace_procfs_unittest.cc",
- "src/traced/probes/ftrace/printk_formats_parser_unittest.cc",
- "src/traced/probes/ftrace/proto_translation_table_unittest.cc",
- ],
+ name: "perfetto_src_traced_probes_ftrace_unittests",
+ srcs: [
+ "src/traced/probes/ftrace/cpu_reader_unittest.cc",
+ "src/traced/probes/ftrace/cpu_stats_parser_unittest.cc",
+ "src/traced/probes/ftrace/discover_vendor_tracepoints_unittest.cc",
+ "src/traced/probes/ftrace/event_info_unittest.cc",
+ "src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc",
+ "src/traced/probes/ftrace/ftrace_config_unittest.cc",
+ "src/traced/probes/ftrace/ftrace_controller_unittest.cc",
+ "src/traced/probes/ftrace/ftrace_procfs_unittest.cc",
+ "src/traced/probes/ftrace/printk_formats_parser_unittest.cc",
+ "src/traced/probes/ftrace/proto_translation_table_unittest.cc",
+ ],
}
// GN: //src/traced/probes/initial_display_state:initial_display_state
filegroup {
- name: "perfetto_src_traced_probes_initial_display_state_initial_display_state",
- srcs: [
- "src/traced/probes/initial_display_state/initial_display_state_data_source.cc",
- ],
+ name: "perfetto_src_traced_probes_initial_display_state_initial_display_state",
+ srcs: [
+ "src/traced/probes/initial_display_state/initial_display_state_data_source.cc",
+ ],
}
// GN: //src/traced/probes/initial_display_state:unittests
filegroup {
- name: "perfetto_src_traced_probes_initial_display_state_unittests",
- srcs: [
- "src/traced/probes/initial_display_state/initial_display_state_data_source_unittest.cc",
- ],
+ name: "perfetto_src_traced_probes_initial_display_state_unittests",
+ srcs: [
+ "src/traced/probes/initial_display_state/initial_display_state_data_source_unittest.cc",
+ ],
}
// GN: //src/traced/probes/metatrace:metatrace
filegroup {
- name: "perfetto_src_traced_probes_metatrace_metatrace",
- srcs: [
- "src/traced/probes/metatrace/metatrace_data_source.cc",
- ],
+ name: "perfetto_src_traced_probes_metatrace_metatrace",
+ srcs: [
+ "src/traced/probes/metatrace/metatrace_data_source.cc",
+ ],
}
// GN: //src/traced/probes/packages_list:packages_list
filegroup {
- name: "perfetto_src_traced_probes_packages_list_packages_list",
- srcs: [
- "src/traced/probes/packages_list/packages_list_data_source.cc",
- ],
+ name: "perfetto_src_traced_probes_packages_list_packages_list",
+ srcs: [
+ "src/traced/probes/packages_list/packages_list_data_source.cc",
+ ],
}
// GN: //src/traced/probes/packages_list:packages_list_parser
filegroup {
- name: "perfetto_src_traced_probes_packages_list_packages_list_parser",
- srcs: [
- "src/traced/probes/packages_list/packages_list_parser.cc",
- ],
+ name: "perfetto_src_traced_probes_packages_list_packages_list_parser",
+ srcs: [
+ "src/traced/probes/packages_list/packages_list_parser.cc",
+ ],
}
// GN: //src/traced/probes/packages_list:unittests
filegroup {
- name: "perfetto_src_traced_probes_packages_list_unittests",
- srcs: [
- "src/traced/probes/packages_list/packages_list_unittest.cc",
- ],
+ name: "perfetto_src_traced_probes_packages_list_unittests",
+ srcs: [
+ "src/traced/probes/packages_list/packages_list_unittest.cc",
+ ],
}
// GN: //src/traced/probes/power:power
filegroup {
- name: "perfetto_src_traced_probes_power_power",
- srcs: [
- "src/traced/probes/power/android_power_data_source.cc",
- ],
+ name: "perfetto_src_traced_probes_power_power",
+ srcs: [
+ "src/traced/probes/power/android_power_data_source.cc",
+ "src/traced/probes/power/linux_power_sysfs_data_source.cc",
+ ],
+}
+
+// GN: //src/traced/probes/power:unittests
+filegroup {
+ name: "perfetto_src_traced_probes_power_unittests",
+ srcs: [
+ "src/traced/probes/power/linux_power_sysfs_data_source_unittest.cc",
+ ],
}
// GN: //src/traced/probes:probes
filegroup {
- name: "perfetto_src_traced_probes_probes",
- srcs: [
- "src/traced/probes/probes.cc",
- ],
+ name: "perfetto_src_traced_probes_probes",
+ srcs: [
+ "src/traced/probes/probes.cc",
+ ],
}
// GN: //src/traced/probes:probes_src
filegroup {
- name: "perfetto_src_traced_probes_probes_src",
- srcs: [
- "src/traced/probes/kmem_activity_trigger.cc",
- "src/traced/probes/probes_producer.cc",
- ],
+ name: "perfetto_src_traced_probes_probes_src",
+ srcs: [
+ "src/traced/probes/kmem_activity_trigger.cc",
+ "src/traced/probes/probes_producer.cc",
+ ],
}
// GN: //src/traced/probes/ps:ps
filegroup {
- name: "perfetto_src_traced_probes_ps_ps",
- srcs: [
- "src/traced/probes/ps/process_stats_data_source.cc",
- ],
+ name: "perfetto_src_traced_probes_ps_ps",
+ srcs: [
+ "src/traced/probes/ps/process_stats_data_source.cc",
+ ],
}
// GN: //src/traced/probes/ps:unittests
filegroup {
- name: "perfetto_src_traced_probes_ps_unittests",
- srcs: [
- "src/traced/probes/ps/process_stats_data_source_unittest.cc",
- ],
+ name: "perfetto_src_traced_probes_ps_unittests",
+ srcs: [
+ "src/traced/probes/ps/process_stats_data_source_unittest.cc",
+ ],
}
// GN: //src/traced/probes/sys_stats:sys_stats
filegroup {
- name: "perfetto_src_traced_probes_sys_stats_sys_stats",
- srcs: [
- "src/traced/probes/sys_stats/sys_stats_data_source.cc",
- ],
+ name: "perfetto_src_traced_probes_sys_stats_sys_stats",
+ srcs: [
+ "src/traced/probes/sys_stats/sys_stats_data_source.cc",
+ ],
}
// GN: //src/traced/probes/sys_stats:unittests
filegroup {
- name: "perfetto_src_traced_probes_sys_stats_unittests",
- srcs: [
- "src/traced/probes/sys_stats/sys_stats_data_source_unittest.cc",
- ],
+ name: "perfetto_src_traced_probes_sys_stats_unittests",
+ srcs: [
+ "src/traced/probes/sys_stats/sys_stats_data_source_unittest.cc",
+ ],
}
// GN: //src/traced/probes/system_info:system_info
filegroup {
- name: "perfetto_src_traced_probes_system_info_system_info",
- srcs: [
- "src/traced/probes/system_info/system_info_data_source.cc",
- ],
+ name: "perfetto_src_traced_probes_system_info_system_info",
+ srcs: [
+ "src/traced/probes/system_info/system_info_data_source.cc",
+ ],
}
// GN: //src/traced/probes/system_info:unittests
filegroup {
- name: "perfetto_src_traced_probes_system_info_unittests",
- srcs: [
- "src/traced/probes/system_info/system_info_data_source_unittest.cc",
- ],
+ name: "perfetto_src_traced_probes_system_info_unittests",
+ srcs: [
+ "src/traced/probes/system_info/system_info_data_source_unittest.cc",
+ ],
}
// GN: //src/traced/probes:unittests
filegroup {
- name: "perfetto_src_traced_probes_unittests",
+ name: "perfetto_src_traced_probes_unittests",
}
// GN: //src/traced/service:service
filegroup {
- name: "perfetto_src_traced_service_service",
- srcs: [
- "src/traced/service/builtin_producer.cc",
- "src/traced/service/service.cc",
- ],
+ name: "perfetto_src_traced_service_service",
+ srcs: [
+ "src/traced/service/builtin_producer.cc",
+ "src/traced/service/service.cc",
+ ],
}
// GN: //src/traced/service:unittests
filegroup {
- name: "perfetto_src_traced_service_unittests",
- srcs: [
- "src/traced/service/builtin_producer_unittest.cc",
- ],
+ name: "perfetto_src_traced_service_unittests",
+ srcs: [
+ "src/traced/service/builtin_producer_unittest.cc",
+ ],
}
// GN: //src/tracing:client_api_without_backends
filegroup {
- name: "perfetto_src_tracing_client_api_without_backends",
- srcs: [
- "src/tracing/console_interceptor.cc",
- "src/tracing/data_source.cc",
- "src/tracing/debug_annotation.cc",
- "src/tracing/event_context.cc",
- "src/tracing/interceptor.cc",
- "src/tracing/internal/checked_scope.cc",
- "src/tracing/internal/interceptor_trace_writer.cc",
- "src/tracing/internal/tracing_backend_fake.cc",
- "src/tracing/internal/tracing_muxer_fake.cc",
- "src/tracing/internal/tracing_muxer_impl.cc",
- "src/tracing/internal/track_event_internal.cc",
- "src/tracing/internal/track_event_interned_fields.cc",
- "src/tracing/platform.cc",
- "src/tracing/traced_value.cc",
- "src/tracing/tracing.cc",
- "src/tracing/tracing_policy.cc",
- "src/tracing/track.cc",
- "src/tracing/track_event_category_registry.cc",
- "src/tracing/track_event_legacy.cc",
- "src/tracing/track_event_state_tracker.cc",
- "src/tracing/virtual_destructors.cc",
- ],
+ name: "perfetto_src_tracing_client_api_without_backends",
+ srcs: [
+ "src/tracing/console_interceptor.cc",
+ "src/tracing/data_source.cc",
+ "src/tracing/debug_annotation.cc",
+ "src/tracing/event_context.cc",
+ "src/tracing/interceptor.cc",
+ "src/tracing/internal/checked_scope.cc",
+ "src/tracing/internal/interceptor_trace_writer.cc",
+ "src/tracing/internal/tracing_backend_fake.cc",
+ "src/tracing/internal/tracing_muxer_fake.cc",
+ "src/tracing/internal/tracing_muxer_impl.cc",
+ "src/tracing/internal/track_event_internal.cc",
+ "src/tracing/internal/track_event_interned_fields.cc",
+ "src/tracing/platform.cc",
+ "src/tracing/traced_value.cc",
+ "src/tracing/tracing.cc",
+ "src/tracing/tracing_policy.cc",
+ "src/tracing/track.cc",
+ "src/tracing/track_event_category_registry.cc",
+ "src/tracing/track_event_legacy.cc",
+ "src/tracing/track_event_state_tracker.cc",
+ "src/tracing/virtual_destructors.cc",
+ ],
}
// GN: //src/tracing:common
filegroup {
- name: "perfetto_src_tracing_common",
- srcs: [
- "src/tracing/trace_writer_base.cc",
- ],
+ name: "perfetto_src_tracing_common",
+ srcs: [
+ "src/tracing/trace_writer_base.cc",
+ ],
}
// GN: //src/tracing/consumer_api_deprecated:consumer_api_deprecated
filegroup {
- name: "perfetto_src_tracing_consumer_api_deprecated_consumer_api_deprecated",
- srcs: [
- "src/tracing/consumer_api_deprecated/consumer_api_deprecated.cc",
- ],
+ name: "perfetto_src_tracing_consumer_api_deprecated_consumer_api_deprecated",
+ srcs: [
+ "src/tracing/consumer_api_deprecated/consumer_api_deprecated.cc",
+ ],
}
// GN: //src/tracing/core:core
filegroup {
- name: "perfetto_src_tracing_core_core",
- srcs: [
- "src/tracing/core/id_allocator.cc",
- "src/tracing/core/null_trace_writer.cc",
- "src/tracing/core/shared_memory_abi.cc",
- "src/tracing/core/shared_memory_arbiter_impl.cc",
- "src/tracing/core/trace_packet.cc",
- "src/tracing/core/trace_writer_impl.cc",
- "src/tracing/core/virtual_destructors.cc",
- ],
+ name: "perfetto_src_tracing_core_core",
+ srcs: [
+ "src/tracing/core/id_allocator.cc",
+ "src/tracing/core/null_trace_writer.cc",
+ "src/tracing/core/shared_memory_abi.cc",
+ "src/tracing/core/shared_memory_arbiter_impl.cc",
+ "src/tracing/core/trace_packet.cc",
+ "src/tracing/core/trace_writer_impl.cc",
+ "src/tracing/core/virtual_destructors.cc",
+ ],
}
// GN: //src/tracing/core:service
filegroup {
- name: "perfetto_src_tracing_core_service",
- srcs: [
- "src/tracing/core/metatrace_writer.cc",
- "src/tracing/core/packet_stream_validator.cc",
- "src/tracing/core/trace_buffer.cc",
- "src/tracing/core/tracing_service_impl.cc",
- ],
+ name: "perfetto_src_tracing_core_service",
+ srcs: [
+ "src/tracing/core/metatrace_writer.cc",
+ "src/tracing/core/packet_stream_validator.cc",
+ "src/tracing/core/trace_buffer.cc",
+ "src/tracing/core/tracing_service_impl.cc",
+ ],
}
// GN: //src/tracing/core:test_support
filegroup {
- name: "perfetto_src_tracing_core_test_support",
- srcs: [
- "src/tracing/core/trace_writer_for_testing.cc",
- ],
+ name: "perfetto_src_tracing_core_test_support",
+ srcs: [
+ "src/tracing/core/trace_writer_for_testing.cc",
+ ],
}
// GN: //src/tracing/core:unittests
filegroup {
- name: "perfetto_src_tracing_core_unittests",
- srcs: [
- "src/tracing/core/id_allocator_unittest.cc",
- "src/tracing/core/null_trace_writer_unittest.cc",
- "src/tracing/core/packet_stream_validator_unittest.cc",
- "src/tracing/core/patch_list_unittest.cc",
- "src/tracing/core/shared_memory_abi_unittest.cc",
- "src/tracing/core/shared_memory_arbiter_impl_unittest.cc",
- "src/tracing/core/trace_buffer_unittest.cc",
- "src/tracing/core/trace_packet_unittest.cc",
- "src/tracing/core/trace_writer_impl_unittest.cc",
- "src/tracing/core/tracing_service_impl_unittest.cc",
- ],
+ name: "perfetto_src_tracing_core_unittests",
+ srcs: [
+ "src/tracing/core/id_allocator_unittest.cc",
+ "src/tracing/core/null_trace_writer_unittest.cc",
+ "src/tracing/core/packet_stream_validator_unittest.cc",
+ "src/tracing/core/patch_list_unittest.cc",
+ "src/tracing/core/shared_memory_abi_unittest.cc",
+ "src/tracing/core/shared_memory_arbiter_impl_unittest.cc",
+ "src/tracing/core/trace_buffer_unittest.cc",
+ "src/tracing/core/trace_packet_unittest.cc",
+ "src/tracing/core/trace_writer_impl_unittest.cc",
+ "src/tracing/core/tracing_service_impl_unittest.cc",
+ ],
}
// GN: //src/tracing:in_process_backend
filegroup {
- name: "perfetto_src_tracing_in_process_backend",
- srcs: [
- "src/tracing/internal/in_process_tracing_backend.cc",
- ],
+ name: "perfetto_src_tracing_in_process_backend",
+ srcs: [
+ "src/tracing/internal/in_process_tracing_backend.cc",
+ ],
}
// GN: //src/tracing/ipc:common
filegroup {
- name: "perfetto_src_tracing_ipc_common",
- srcs: [
- "src/tracing/ipc/default_socket.cc",
- "src/tracing/ipc/memfd.cc",
- "src/tracing/ipc/posix_shared_memory.cc",
- ],
+ name: "perfetto_src_tracing_ipc_common",
+ srcs: [
+ "src/tracing/ipc/memfd.cc",
+ "src/tracing/ipc/posix_shared_memory.cc",
+ "src/tracing/ipc/shared_memory_windows.cc",
+ ],
}
// GN: //src/tracing/ipc/consumer:consumer
filegroup {
- name: "perfetto_src_tracing_ipc_consumer_consumer",
- srcs: [
- "src/tracing/ipc/consumer/consumer_ipc_client_impl.cc",
- ],
+ name: "perfetto_src_tracing_ipc_consumer_consumer",
+ srcs: [
+ "src/tracing/ipc/consumer/consumer_ipc_client_impl.cc",
+ ],
+}
+
+// GN: //src/tracing/ipc:default_socket
+filegroup {
+ name: "perfetto_src_tracing_ipc_default_socket",
+ srcs: [
+ "src/tracing/ipc/default_socket.cc",
+ ],
}
// GN: //src/tracing/ipc/producer:producer
filegroup {
- name: "perfetto_src_tracing_ipc_producer_producer",
- srcs: [
- "src/tracing/ipc/producer/producer_ipc_client_impl.cc",
- ],
+ name: "perfetto_src_tracing_ipc_producer_producer",
+ srcs: [
+ "src/tracing/ipc/producer/producer_ipc_client_impl.cc",
+ ],
}
// GN: //src/tracing/ipc/service:service
filegroup {
- name: "perfetto_src_tracing_ipc_service_service",
- srcs: [
- "src/tracing/ipc/service/consumer_ipc_service.cc",
- "src/tracing/ipc/service/producer_ipc_service.cc",
- "src/tracing/ipc/service/service_ipc_host_impl.cc",
- ],
+ name: "perfetto_src_tracing_ipc_service_service",
+ srcs: [
+ "src/tracing/ipc/service/consumer_ipc_service.cc",
+ "src/tracing/ipc/service/producer_ipc_service.cc",
+ "src/tracing/ipc/service/service_ipc_host_impl.cc",
+ ],
}
// GN: //src/tracing/ipc:unittests
filegroup {
- name: "perfetto_src_tracing_ipc_unittests",
- srcs: [
- "src/tracing/ipc/posix_shared_memory_unittest.cc",
- ],
+ name: "perfetto_src_tracing_ipc_unittests",
+ srcs: [
+ "src/tracing/ipc/posix_shared_memory_unittest.cc",
+ ],
}
// GN: //src/tracing:platform_impl
filegroup {
- name: "perfetto_src_tracing_platform_impl",
- srcs: [
- "src/tracing/platform_posix.cc",
- ],
+ name: "perfetto_src_tracing_platform_impl",
+ srcs: [
+ "src/tracing/platform_posix.cc",
+ "src/tracing/platform_windows.cc",
+ ],
}
// GN: //src/tracing:system_backend
filegroup {
- name: "perfetto_src_tracing_system_backend",
- srcs: [
- "src/tracing/internal/system_tracing_backend.cc",
- ],
+ name: "perfetto_src_tracing_system_backend",
+ srcs: [
+ "src/tracing/internal/system_tracing_backend.cc",
+ ],
}
// GN: //src/tracing/test:api_test_support
filegroup {
- name: "perfetto_src_tracing_test_api_test_support",
- srcs: [
- "src/tracing/test/api_test_support.cc",
- ],
+ name: "perfetto_src_tracing_test_api_test_support",
+ srcs: [
+ "src/tracing/test/api_test_support.cc",
+ ],
}
// GN: //src/tracing/test:client_api_integrationtests
filegroup {
- name: "perfetto_src_tracing_test_client_api_integrationtests",
- srcs: [
- "src/tracing/test/api_integrationtest.cc",
- "src/tracing/test/tracing_module.cc",
- "src/tracing/test/tracing_module2.cc",
- ],
+ name: "perfetto_src_tracing_test_client_api_integrationtests",
+ srcs: [
+ "src/tracing/test/api_integrationtest.cc",
+ "src/tracing/test/tracing_module.cc",
+ "src/tracing/test/tracing_module2.cc",
+ ],
}
// GN: //src/tracing/test:test_support
filegroup {
- name: "perfetto_src_tracing_test_test_support",
- srcs: [
- "src/tracing/test/aligned_buffer_test.cc",
- "src/tracing/test/fake_packet.cc",
- "src/tracing/test/mock_consumer.cc",
- "src/tracing/test/mock_producer.cc",
- "src/tracing/test/test_shared_memory.cc",
- "src/tracing/test/traced_value_test_support.cc",
- ],
+ name: "perfetto_src_tracing_test_test_support",
+ srcs: [
+ "src/tracing/test/aligned_buffer_test.cc",
+ "src/tracing/test/fake_packet.cc",
+ "src/tracing/test/mock_consumer.cc",
+ "src/tracing/test/mock_producer.cc",
+ "src/tracing/test/test_shared_memory.cc",
+ "src/tracing/test/traced_value_test_support.cc",
+ ],
}
// GN: //src/tracing/test:tracing_integration_test
filegroup {
- name: "perfetto_src_tracing_test_tracing_integration_test",
- srcs: [
- "src/tracing/test/platform_unittest.cc",
- "src/tracing/test/tracing_integration_test.cc",
- ],
+ name: "perfetto_src_tracing_test_tracing_integration_test",
+ srcs: [
+ "src/tracing/test/platform_unittest.cc",
+ "src/tracing/test/tracing_integration_test.cc",
+ ],
}
// GN: //src/tracing:unittests
filegroup {
- name: "perfetto_src_tracing_unittests",
- srcs: [
- "src/tracing/traced_proto_unittest.cc",
- "src/tracing/traced_value_unittest.cc",
- ],
+ name: "perfetto_src_tracing_unittests",
+ srcs: [
+ "src/tracing/traced_proto_unittest.cc",
+ "src/tracing/traced_value_unittest.cc",
+ ],
}
-// GN: //test:end_to_end_integrationtests
+// GN: //test:integrationtests
filegroup {
- name: "perfetto_test_end_to_end_integrationtests",
- srcs: [
- "test/end_to_end_integrationtest.cc",
- ],
+ name: "perfetto_test_integrationtests",
+ srcs: [
+ "test/android_integrationtest.cc",
+ "test/cmdline_integrationtest.cc",
+ "test/ftrace_integrationtest.cc",
+ "test/traced_integrationtest.cc",
+ ],
}
// GN: //test:test_helper
filegroup {
- name: "perfetto_test_test_helper",
- srcs: [
- "test/android_test_utils.cc",
- "test/fake_producer.cc",
- "test/test_helper.cc",
- ],
+ name: "perfetto_test_test_helper",
+ srcs: [
+ "test/android_test_utils.cc",
+ "test/fake_producer.cc",
+ "test/test_helper.cc",
+ ],
}
// GN: //tools/sanitizers_unittests:sanitizers_unittests
filegroup {
- name: "perfetto_tools_sanitizers_unittests_sanitizers_unittests",
- srcs: [
- "tools/sanitizers_unittests/sanitizers_unittest.cc",
- ],
+ name: "perfetto_tools_sanitizers_unittests_sanitizers_unittests",
+ srcs: [
+ "tools/sanitizers_unittests/sanitizers_unittest.cc",
+ ],
+}
+
+// GN: //tools/trace_to_text:gen_cc_trace_descriptor
+genrule {
+ name: "perfetto_tools_trace_to_text_gen_cc_trace_descriptor",
+ srcs: [
+ ":perfetto_protos_perfetto_trace_descriptor",
+ ],
+ cmd: "$(location tools/gen_cc_proto_descriptor.py) --gen_dir=$(genDir) --cpp_out=$(out) $(in)",
+ out: [
+ "tools/trace_to_text/trace.descriptor.h",
+ ],
+ tool_files: [
+ "tools/gen_cc_proto_descriptor.py",
+ ],
}
-// GN: //tools/trace_to_text:common
+// GN: //tools/trace_to_text:lib
filegroup {
- name: "perfetto_tools_trace_to_text_common",
- srcs: [
- "tools/trace_to_text/deobfuscate_profile.cc",
- "tools/trace_to_text/main.cc",
- "tools/trace_to_text/symbolize_profile.cc",
- "tools/trace_to_text/trace_to_hprof.cc",
- "tools/trace_to_text/trace_to_json.cc",
- "tools/trace_to_text/trace_to_profile.cc",
- "tools/trace_to_text/trace_to_systrace.cc",
- ],
+ name: "perfetto_tools_trace_to_text_lib",
+ srcs: [
+ "tools/trace_to_text/deobfuscate_profile.cc",
+ "tools/trace_to_text/symbolize_profile.cc",
+ "tools/trace_to_text/trace_to_hprof.cc",
+ "tools/trace_to_text/trace_to_json.cc",
+ "tools/trace_to_text/trace_to_profile.cc",
+ "tools/trace_to_text/trace_to_systrace.cc",
+ "tools/trace_to_text/trace_to_text.cc",
+ ],
}
-// GN: //tools/trace_to_text:full
+// GN: //tools/trace_to_text:main
filegroup {
- name: "perfetto_tools_trace_to_text_full",
- srcs: [
- "tools/trace_to_text/proto_full_utils.cc",
- "tools/trace_to_text/trace_to_text.cc",
- ],
+ name: "perfetto_tools_trace_to_text_main",
+ srcs: [
+ "tools/trace_to_text/main.cc",
+ ],
}
// GN: //tools/trace_to_text:pprofbuilder
filegroup {
- name: "perfetto_tools_trace_to_text_pprofbuilder",
- srcs: [
- "tools/trace_to_text/pprof_builder.cc",
- ],
+ name: "perfetto_tools_trace_to_text_pprofbuilder",
+ srcs: [
+ "tools/trace_to_text/pprof_builder.cc",
+ ],
}
// GN: //tools/trace_to_text:utils
filegroup {
- name: "perfetto_tools_trace_to_text_utils",
- srcs: [
- "tools/trace_to_text/utils.cc",
- ],
+ name: "perfetto_tools_trace_to_text_utils",
+ srcs: [
+ "tools/trace_to_text/utils.cc",
+ ],
+}
+
+// GN: [//protos/perfetto/trace:non_minimal_source_set, //protos/perfetto/trace:minimal_source_set]
+java_library {
+ name: "perfetto_trace_java_protos",
+ srcs: [
+ "protos/perfetto/common/android_energy_consumer_descriptor.proto",
+ "protos/perfetto/common/android_log_constants.proto",
+ "protos/perfetto/common/builtin_clock.proto",
+ "protos/perfetto/common/commit_data_request.proto",
+ "protos/perfetto/common/data_source_descriptor.proto",
+ "protos/perfetto/common/descriptor.proto",
+ "protos/perfetto/common/ftrace_descriptor.proto",
+ "protos/perfetto/common/gpu_counter_descriptor.proto",
+ "protos/perfetto/common/interceptor_descriptor.proto",
+ "protos/perfetto/common/observable_events.proto",
+ "protos/perfetto/common/perf_events.proto",
+ "protos/perfetto/common/sys_stats_counters.proto",
+ "protos/perfetto/common/trace_stats.proto",
+ "protos/perfetto/common/tracing_service_capabilities.proto",
+ "protos/perfetto/common/tracing_service_state.proto",
+ "protos/perfetto/common/track_event_descriptor.proto",
+ "protos/perfetto/config/android/android_log_config.proto",
+ "protos/perfetto/config/android/android_polled_state_config.proto",
+ "protos/perfetto/config/android/packages_list_config.proto",
+ "protos/perfetto/config/chrome/chrome_config.proto",
+ "protos/perfetto/config/data_source_config.proto",
+ "protos/perfetto/config/ftrace/ftrace_config.proto",
+ "protos/perfetto/config/gpu/gpu_counter_config.proto",
+ "protos/perfetto/config/gpu/vulkan_memory_config.proto",
+ "protos/perfetto/config/inode_file/inode_file_config.proto",
+ "protos/perfetto/config/interceptor_config.proto",
+ "protos/perfetto/config/interceptors/console_config.proto",
+ "protos/perfetto/config/power/android_power_config.proto",
+ "protos/perfetto/config/process_stats/process_stats_config.proto",
+ "protos/perfetto/config/profiling/heapprofd_config.proto",
+ "protos/perfetto/config/profiling/java_hprof_config.proto",
+ "protos/perfetto/config/profiling/perf_event_config.proto",
+ "protos/perfetto/config/stress_test_config.proto",
+ "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+ "protos/perfetto/config/test_config.proto",
+ "protos/perfetto/config/trace_config.proto",
+ "protos/perfetto/config/track_event/track_event_config.proto",
+ "protos/perfetto/trace/android/android_log.proto",
+ "protos/perfetto/trace/android/camera_event.proto",
+ "protos/perfetto/trace/android/frame_timeline_event.proto",
+ "protos/perfetto/trace/android/gpu_mem_event.proto",
+ "protos/perfetto/trace/android/graphics_frame_event.proto",
+ "protos/perfetto/trace/android/initial_display_state.proto",
+ "protos/perfetto/trace/android/packages_list.proto",
+ "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
+ "protos/perfetto/trace/chrome/chrome_metadata.proto",
+ "protos/perfetto/trace/chrome/chrome_trace_event.proto",
+ "protos/perfetto/trace/clock_snapshot.proto",
+ "protos/perfetto/trace/extension_descriptor.proto",
+ "protos/perfetto/trace/filesystem/inode_file_map.proto",
+ "protos/perfetto/trace/ftrace/binder.proto",
+ "protos/perfetto/trace/ftrace/block.proto",
+ "protos/perfetto/trace/ftrace/cgroup.proto",
+ "protos/perfetto/trace/ftrace/clk.proto",
+ "protos/perfetto/trace/ftrace/compaction.proto",
+ "protos/perfetto/trace/ftrace/cpuhp.proto",
+ "protos/perfetto/trace/ftrace/cros_ec.proto",
+ "protos/perfetto/trace/ftrace/dma_fence.proto",
+ "protos/perfetto/trace/ftrace/dmabuf_heap.proto",
+ "protos/perfetto/trace/ftrace/dpu.proto",
+ "protos/perfetto/trace/ftrace/drm.proto",
+ "protos/perfetto/trace/ftrace/ext4.proto",
+ "protos/perfetto/trace/ftrace/f2fs.proto",
+ "protos/perfetto/trace/ftrace/fastrpc.proto",
+ "protos/perfetto/trace/ftrace/fence.proto",
+ "protos/perfetto/trace/ftrace/filemap.proto",
+ "protos/perfetto/trace/ftrace/ftrace.proto",
+ "protos/perfetto/trace/ftrace/ftrace_event.proto",
+ "protos/perfetto/trace/ftrace/ftrace_event_bundle.proto",
+ "protos/perfetto/trace/ftrace/ftrace_stats.proto",
+ "protos/perfetto/trace/ftrace/g2d.proto",
+ "protos/perfetto/trace/ftrace/generic.proto",
+ "protos/perfetto/trace/ftrace/gpu_mem.proto",
+ "protos/perfetto/trace/ftrace/gpu_scheduler.proto",
+ "protos/perfetto/trace/ftrace/i2c.proto",
+ "protos/perfetto/trace/ftrace/ion.proto",
+ "protos/perfetto/trace/ftrace/ipi.proto",
+ "protos/perfetto/trace/ftrace/irq.proto",
+ "protos/perfetto/trace/ftrace/kmem.proto",
+ "protos/perfetto/trace/ftrace/kvm.proto",
+ "protos/perfetto/trace/ftrace/lowmemorykiller.proto",
+ "protos/perfetto/trace/ftrace/mali.proto",
+ "protos/perfetto/trace/ftrace/mdss.proto",
+ "protos/perfetto/trace/ftrace/mm_event.proto",
+ "protos/perfetto/trace/ftrace/net.proto",
+ "protos/perfetto/trace/ftrace/oom.proto",
+ "protos/perfetto/trace/ftrace/power.proto",
+ "protos/perfetto/trace/ftrace/printk.proto",
+ "protos/perfetto/trace/ftrace/raw_syscalls.proto",
+ "protos/perfetto/trace/ftrace/regulator.proto",
+ "protos/perfetto/trace/ftrace/sched.proto",
+ "protos/perfetto/trace/ftrace/scm.proto",
+ "protos/perfetto/trace/ftrace/sde.proto",
+ "protos/perfetto/trace/ftrace/signal.proto",
+ "protos/perfetto/trace/ftrace/skb.proto",
+ "protos/perfetto/trace/ftrace/sock.proto",
+ "protos/perfetto/trace/ftrace/sync.proto",
+ "protos/perfetto/trace/ftrace/synthetic.proto",
+ "protos/perfetto/trace/ftrace/systrace.proto",
+ "protos/perfetto/trace/ftrace/task.proto",
+ "protos/perfetto/trace/ftrace/tcp.proto",
+ "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
+ "protos/perfetto/trace/ftrace/thermal.proto",
+ "protos/perfetto/trace/ftrace/ufs.proto",
+ "protos/perfetto/trace/ftrace/vmscan.proto",
+ "protos/perfetto/trace/ftrace/workqueue.proto",
+ "protos/perfetto/trace/gpu/gpu_counter_event.proto",
+ "protos/perfetto/trace/gpu/gpu_log.proto",
+ "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
+ "protos/perfetto/trace/gpu/vulkan_api_event.proto",
+ "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
+ "protos/perfetto/trace/interned_data/interned_data.proto",
+ "protos/perfetto/trace/memory_graph.proto",
+ "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
+ "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+ "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
+ "protos/perfetto/trace/power/battery_counters.proto",
+ "protos/perfetto/trace/power/power_rails.proto",
+ "protos/perfetto/trace/profiling/deobfuscation.proto",
+ "protos/perfetto/trace/profiling/heap_graph.proto",
+ "protos/perfetto/trace/profiling/profile_common.proto",
+ "protos/perfetto/trace/profiling/profile_packet.proto",
+ "protos/perfetto/trace/profiling/smaps.proto",
+ "protos/perfetto/trace/ps/process_stats.proto",
+ "protos/perfetto/trace/ps/process_tree.proto",
+ "protos/perfetto/trace/sys_stats/sys_stats.proto",
+ "protos/perfetto/trace/system_info.proto",
+ "protos/perfetto/trace/system_info/cpu_info.proto",
+ "protos/perfetto/trace/test_event.proto",
+ "protos/perfetto/trace/test_extensions.proto",
+ "protos/perfetto/trace/trace.proto",
+ "protos/perfetto/trace/trace_packet.proto",
+ "protos/perfetto/trace/trace_packet_defaults.proto",
+ "protos/perfetto/trace/track_event/chrome_application_state_info.proto",
+ "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
+ "protos/perfetto/trace/track_event/chrome_content_settings_event_info.proto",
+ "protos/perfetto/trace/track_event/chrome_frame_reporter.proto",
+ "protos/perfetto/trace/track_event/chrome_histogram_sample.proto",
+ "protos/perfetto/trace/track_event/chrome_keyed_service.proto",
+ "protos/perfetto/trace/track_event/chrome_latency_info.proto",
+ "protos/perfetto/trace/track_event/chrome_legacy_ipc.proto",
+ "protos/perfetto/trace/track_event/chrome_message_pump.proto",
+ "protos/perfetto/trace/track_event/chrome_mojo_event_info.proto",
+ "protos/perfetto/trace/track_event/chrome_process_descriptor.proto",
+ "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
+ "protos/perfetto/trace/track_event/chrome_thread_descriptor.proto",
+ "protos/perfetto/trace/track_event/chrome_user_event.proto",
+ "protos/perfetto/trace/track_event/chrome_window_handle_event_info.proto",
+ "protos/perfetto/trace/track_event/counter_descriptor.proto",
+ "protos/perfetto/trace/track_event/debug_annotation.proto",
+ "protos/perfetto/trace/track_event/log_message.proto",
+ "protos/perfetto/trace/track_event/process_descriptor.proto",
+ "protos/perfetto/trace/track_event/source_location.proto",
+ "protos/perfetto/trace/track_event/task_execution.proto",
+ "protos/perfetto/trace/track_event/thread_descriptor.proto",
+ "protos/perfetto/trace/track_event/track_descriptor.proto",
+ "protos/perfetto/trace/track_event/track_event.proto",
+ "protos/perfetto/trace/translation/translation_table.proto",
+ "protos/perfetto/trace/trigger.proto",
+ "protos/perfetto/trace/ui_state.proto",
+ ],
+ proto: {
+ type: "lite",
+ canonical_path_from_root: false,
+ },
}
// GN: //protos/perfetto/trace:perfetto_trace_protos
cc_library_static {
- name: "perfetto_trace_protos",
- srcs: [
- ":perfetto_protos_perfetto_common_lite_gen",
- ":perfetto_protos_perfetto_config_android_lite_gen",
- ":perfetto_protos_perfetto_config_ftrace_lite_gen",
- ":perfetto_protos_perfetto_config_gpu_lite_gen",
- ":perfetto_protos_perfetto_config_inode_file_lite_gen",
- ":perfetto_protos_perfetto_config_interceptors_lite_gen",
- ":perfetto_protos_perfetto_config_lite_gen",
- ":perfetto_protos_perfetto_config_power_lite_gen",
- ":perfetto_protos_perfetto_config_process_stats_lite_gen",
- ":perfetto_protos_perfetto_config_profiling_lite_gen",
- ":perfetto_protos_perfetto_config_sys_stats_lite_gen",
- ":perfetto_protos_perfetto_config_track_event_lite_gen",
- ":perfetto_protos_perfetto_trace_android_lite_gen",
- ":perfetto_protos_perfetto_trace_chrome_lite_gen",
- ":perfetto_protos_perfetto_trace_filesystem_lite_gen",
- ":perfetto_protos_perfetto_trace_ftrace_lite_gen",
- ":perfetto_protos_perfetto_trace_gpu_lite_gen",
- ":perfetto_protos_perfetto_trace_interned_data_lite_gen",
- ":perfetto_protos_perfetto_trace_minimal_lite_gen",
- ":perfetto_protos_perfetto_trace_non_minimal_lite_gen",
- ":perfetto_protos_perfetto_trace_perfetto_lite_gen",
- ":perfetto_protos_perfetto_trace_power_lite_gen",
- ":perfetto_protos_perfetto_trace_profiling_lite_gen",
- ":perfetto_protos_perfetto_trace_ps_lite_gen",
- ":perfetto_protos_perfetto_trace_sys_stats_lite_gen",
- ":perfetto_protos_perfetto_trace_system_info_lite_gen",
- ":perfetto_protos_perfetto_trace_track_event_lite_gen",
- ],
- shared_libs: [
- "libprotobuf-cpp-lite",
- ],
- host_supported: true,
- generated_headers: [
- "perfetto_protos_perfetto_common_lite_gen_headers",
- "perfetto_protos_perfetto_config_android_lite_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_lite_gen_headers",
- "perfetto_protos_perfetto_config_gpu_lite_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_lite_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_lite_gen_headers",
- "perfetto_protos_perfetto_config_lite_gen_headers",
- "perfetto_protos_perfetto_config_power_lite_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_lite_gen_headers",
- "perfetto_protos_perfetto_config_profiling_lite_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_lite_gen_headers",
- "perfetto_protos_perfetto_config_track_event_lite_gen_headers",
- "perfetto_protos_perfetto_trace_android_lite_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_lite_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_lite_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_lite_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_lite_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_lite_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_lite_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_lite_gen_headers",
- "perfetto_protos_perfetto_trace_power_lite_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_lite_gen_headers",
- "perfetto_protos_perfetto_trace_ps_lite_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_lite_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_lite_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_lite_gen_headers",
- ],
- export_generated_headers: [
- "perfetto_protos_perfetto_common_lite_gen_headers",
- "perfetto_protos_perfetto_config_android_lite_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_lite_gen_headers",
- "perfetto_protos_perfetto_config_gpu_lite_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_lite_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_lite_gen_headers",
- "perfetto_protos_perfetto_config_lite_gen_headers",
- "perfetto_protos_perfetto_config_power_lite_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_lite_gen_headers",
- "perfetto_protos_perfetto_config_profiling_lite_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_lite_gen_headers",
- "perfetto_protos_perfetto_config_track_event_lite_gen_headers",
- "perfetto_protos_perfetto_trace_android_lite_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_lite_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_lite_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_lite_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_lite_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_lite_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_lite_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_lite_gen_headers",
- "perfetto_protos_perfetto_trace_power_lite_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_lite_gen_headers",
- "perfetto_protos_perfetto_trace_ps_lite_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_lite_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_lite_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_lite_gen_headers",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- cflags: [
- "-DGOOGLE_PROTOBUF_NO_RTTI",
- "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
- ],
- apex_available: [
- "//apex_available:platform",
- "com.android.art",
- "com.android.art.debug",
- ],
- min_sdk_version: "S",
+ name: "perfetto_trace_protos",
+ srcs: [
+ ":perfetto_protos_perfetto_common_lite_gen",
+ ":perfetto_protos_perfetto_config_android_lite_gen",
+ ":perfetto_protos_perfetto_config_ftrace_lite_gen",
+ ":perfetto_protos_perfetto_config_gpu_lite_gen",
+ ":perfetto_protos_perfetto_config_inode_file_lite_gen",
+ ":perfetto_protos_perfetto_config_interceptors_lite_gen",
+ ":perfetto_protos_perfetto_config_lite_gen",
+ ":perfetto_protos_perfetto_config_power_lite_gen",
+ ":perfetto_protos_perfetto_config_process_stats_lite_gen",
+ ":perfetto_protos_perfetto_config_profiling_lite_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_lite_gen",
+ ":perfetto_protos_perfetto_config_track_event_lite_gen",
+ ":perfetto_protos_perfetto_trace_android_lite_gen",
+ ":perfetto_protos_perfetto_trace_chrome_lite_gen",
+ ":perfetto_protos_perfetto_trace_filesystem_lite_gen",
+ ":perfetto_protos_perfetto_trace_ftrace_lite_gen",
+ ":perfetto_protos_perfetto_trace_gpu_lite_gen",
+ ":perfetto_protos_perfetto_trace_interned_data_lite_gen",
+ ":perfetto_protos_perfetto_trace_minimal_lite_gen",
+ ":perfetto_protos_perfetto_trace_non_minimal_lite_gen",
+ ":perfetto_protos_perfetto_trace_perfetto_lite_gen",
+ ":perfetto_protos_perfetto_trace_power_lite_gen",
+ ":perfetto_protos_perfetto_trace_profiling_lite_gen",
+ ":perfetto_protos_perfetto_trace_ps_lite_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_lite_gen",
+ ":perfetto_protos_perfetto_trace_system_info_lite_gen",
+ ":perfetto_protos_perfetto_trace_track_event_lite_gen",
+ ":perfetto_protos_perfetto_trace_translation_lite_gen",
+ ],
+ shared_libs: [
+ "libprotobuf-cpp-lite",
+ ],
+ host_supported: true,
+ generated_headers: [
+ "perfetto_protos_perfetto_common_lite_gen_headers",
+ "perfetto_protos_perfetto_config_android_lite_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_lite_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_lite_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_lite_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_lite_gen_headers",
+ "perfetto_protos_perfetto_config_lite_gen_headers",
+ "perfetto_protos_perfetto_config_power_lite_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_lite_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_lite_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_lite_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_android_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_power_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_lite_gen_headers",
+ ],
+ export_generated_headers: [
+ "perfetto_protos_perfetto_common_lite_gen_headers",
+ "perfetto_protos_perfetto_config_android_lite_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_lite_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_lite_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_lite_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_lite_gen_headers",
+ "perfetto_protos_perfetto_config_lite_gen_headers",
+ "perfetto_protos_perfetto_config_power_lite_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_lite_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_lite_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_lite_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_android_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_power_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_lite_gen_headers",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ cflags: [
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ ],
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.art",
+ "com.android.art.debug",
+ ],
+ min_sdk_version: "S",
}
// GN: //:perfetto_unittests
cc_test {
- name: "perfetto_unittests",
- srcs: [
- ":perfetto_include_perfetto_base_base",
- ":perfetto_include_perfetto_ext_base_base",
- ":perfetto_include_perfetto_ext_ipc_ipc",
- ":perfetto_include_perfetto_ext_trace_processor_export_json",
- ":perfetto_include_perfetto_ext_trace_processor_importers_memory_tracker_memory_tracker",
- ":perfetto_include_perfetto_ext_traced_sys_stats_counters",
- ":perfetto_include_perfetto_ext_traced_traced",
- ":perfetto_include_perfetto_ext_tracing_core_core",
- ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
- ":perfetto_include_perfetto_profiling_normalize",
- ":perfetto_include_perfetto_protozero_protozero",
- ":perfetto_include_perfetto_test_test_support",
- ":perfetto_include_perfetto_trace_processor_basic_types",
- ":perfetto_include_perfetto_trace_processor_storage",
- ":perfetto_include_perfetto_trace_processor_trace_processor",
- ":perfetto_include_perfetto_tracing_core_core",
- ":perfetto_include_perfetto_tracing_core_forward_decls",
- ":perfetto_include_perfetto_tracing_tracing",
- ":perfetto_protos_perfetto_common_cpp_gen",
- ":perfetto_protos_perfetto_common_lite_gen",
- ":perfetto_protos_perfetto_common_zero_gen",
- ":perfetto_protos_perfetto_config_android_cpp_gen",
- ":perfetto_protos_perfetto_config_android_lite_gen",
- ":perfetto_protos_perfetto_config_android_zero_gen",
- ":perfetto_protos_perfetto_config_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_lite_gen",
- ":perfetto_protos_perfetto_config_ftrace_zero_gen",
- ":perfetto_protos_perfetto_config_gpu_cpp_gen",
- ":perfetto_protos_perfetto_config_gpu_lite_gen",
- ":perfetto_protos_perfetto_config_gpu_zero_gen",
- ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
- ":perfetto_protos_perfetto_config_inode_file_lite_gen",
- ":perfetto_protos_perfetto_config_inode_file_zero_gen",
- ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
- ":perfetto_protos_perfetto_config_interceptors_lite_gen",
- ":perfetto_protos_perfetto_config_interceptors_zero_gen",
- ":perfetto_protos_perfetto_config_lite_gen",
- ":perfetto_protos_perfetto_config_power_cpp_gen",
- ":perfetto_protos_perfetto_config_power_lite_gen",
- ":perfetto_protos_perfetto_config_power_zero_gen",
- ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_process_stats_lite_gen",
- ":perfetto_protos_perfetto_config_process_stats_zero_gen",
- ":perfetto_protos_perfetto_config_profiling_cpp_gen",
- ":perfetto_protos_perfetto_config_profiling_lite_gen",
- ":perfetto_protos_perfetto_config_profiling_zero_gen",
- ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_sys_stats_lite_gen",
- ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_config_track_event_cpp_gen",
- ":perfetto_protos_perfetto_config_track_event_lite_gen",
- ":perfetto_protos_perfetto_config_track_event_zero_gen",
- ":perfetto_protos_perfetto_config_zero_gen",
- ":perfetto_protos_perfetto_ipc_cpp_gen",
- ":perfetto_protos_perfetto_ipc_ipc_gen",
- ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
- ":perfetto_protos_perfetto_trace_android_cpp_gen",
- ":perfetto_protos_perfetto_trace_android_lite_gen",
- ":perfetto_protos_perfetto_trace_android_zero_gen",
- ":perfetto_protos_perfetto_trace_chrome_cpp_gen",
- ":perfetto_protos_perfetto_trace_chrome_lite_gen",
- ":perfetto_protos_perfetto_trace_chrome_zero_gen",
- ":perfetto_protos_perfetto_trace_filesystem_cpp_gen",
- ":perfetto_protos_perfetto_trace_filesystem_lite_gen",
- ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
- ":perfetto_protos_perfetto_trace_ftrace_cpp_gen",
- ":perfetto_protos_perfetto_trace_ftrace_lite_gen",
- ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
- ":perfetto_protos_perfetto_trace_gpu_cpp_gen",
- ":perfetto_protos_perfetto_trace_gpu_lite_gen",
- ":perfetto_protos_perfetto_trace_gpu_zero_gen",
- ":perfetto_protos_perfetto_trace_interned_data_cpp_gen",
- ":perfetto_protos_perfetto_trace_interned_data_lite_gen",
- ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
- ":perfetto_protos_perfetto_trace_minimal_cpp_gen",
- ":perfetto_protos_perfetto_trace_minimal_lite_gen",
- ":perfetto_protos_perfetto_trace_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_non_minimal_cpp_gen",
- ":perfetto_protos_perfetto_trace_non_minimal_lite_gen",
- ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_perfetto_cpp_gen",
- ":perfetto_protos_perfetto_trace_perfetto_lite_gen",
- ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
- ":perfetto_protos_perfetto_trace_power_cpp_gen",
- ":perfetto_protos_perfetto_trace_power_lite_gen",
- ":perfetto_protos_perfetto_trace_power_zero_gen",
- ":perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen",
- ":perfetto_protos_perfetto_trace_processor_zero_gen",
- ":perfetto_protos_perfetto_trace_profiling_cpp_gen",
- ":perfetto_protos_perfetto_trace_profiling_lite_gen",
- ":perfetto_protos_perfetto_trace_profiling_zero_gen",
- ":perfetto_protos_perfetto_trace_ps_cpp_gen",
- ":perfetto_protos_perfetto_trace_ps_lite_gen",
- ":perfetto_protos_perfetto_trace_ps_zero_gen",
- ":perfetto_protos_perfetto_trace_sys_stats_cpp_gen",
- ":perfetto_protos_perfetto_trace_sys_stats_lite_gen",
- ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_trace_system_info_cpp_gen",
- ":perfetto_protos_perfetto_trace_system_info_lite_gen",
- ":perfetto_protos_perfetto_trace_system_info_zero_gen",
- ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
- ":perfetto_protos_perfetto_trace_track_event_lite_gen",
- ":perfetto_protos_perfetto_trace_track_event_zero_gen",
- ":perfetto_src_android_internal_headers",
- ":perfetto_src_android_internal_lazy_library_loader",
- ":perfetto_src_android_stats_android_stats",
- ":perfetto_src_android_stats_perfetto_atoms",
- ":perfetto_src_base_base",
- ":perfetto_src_base_test_support",
- ":perfetto_src_base_unittests",
- ":perfetto_src_base_unix_socket",
- ":perfetto_src_ipc_client",
- ":perfetto_src_ipc_common",
- ":perfetto_src_ipc_host",
- ":perfetto_src_ipc_test_messages_cpp_gen",
- ":perfetto_src_ipc_test_messages_ipc_gen",
- ":perfetto_src_ipc_unittests",
- ":perfetto_src_kallsyms_kallsyms",
- ":perfetto_src_kallsyms_unittests",
- ":perfetto_src_perfetto_cmd_perfetto_cmd",
- ":perfetto_src_perfetto_cmd_protos_gen",
- ":perfetto_src_perfetto_cmd_trigger_producer",
- ":perfetto_src_perfetto_cmd_unittests",
- ":perfetto_src_profiling_common_callstack_trie",
- ":perfetto_src_profiling_common_interner",
- ":perfetto_src_profiling_common_interning_output",
- ":perfetto_src_profiling_common_proc_utils",
- ":perfetto_src_profiling_common_producer_support",
- ":perfetto_src_profiling_common_profiler_guardrails",
- ":perfetto_src_profiling_common_unittests",
- ":perfetto_src_profiling_common_unwind_support",
- ":perfetto_src_profiling_deobfuscator",
- ":perfetto_src_profiling_memory_client",
- ":perfetto_src_profiling_memory_daemon",
- ":perfetto_src_profiling_memory_ring_buffer",
- ":perfetto_src_profiling_memory_ring_buffer_unittests",
- ":perfetto_src_profiling_memory_scoped_spinlock",
- ":perfetto_src_profiling_memory_unittests",
- ":perfetto_src_profiling_memory_wire_protocol",
- ":perfetto_src_profiling_perf_common_types",
- ":perfetto_src_profiling_perf_proc_descriptors",
- ":perfetto_src_profiling_perf_producer",
- ":perfetto_src_profiling_perf_producer_unittests",
- ":perfetto_src_profiling_perf_regs_parsing",
- ":perfetto_src_profiling_perf_unwinding",
- ":perfetto_src_profiling_symbolizer_symbolizer",
- ":perfetto_src_profiling_symbolizer_unittests",
- ":perfetto_src_profiling_unittests",
- ":perfetto_src_protozero_filtering_bytecode_common",
- ":perfetto_src_protozero_filtering_bytecode_generator",
- ":perfetto_src_protozero_filtering_bytecode_parser",
- ":perfetto_src_protozero_filtering_filter_util",
- ":perfetto_src_protozero_filtering_message_filter",
- ":perfetto_src_protozero_filtering_unittests",
- ":perfetto_src_protozero_protozero",
- ":perfetto_src_protozero_testing_messages_cpp_gen",
- ":perfetto_src_protozero_testing_messages_lite_gen",
- ":perfetto_src_protozero_testing_messages_zero_gen",
- ":perfetto_src_protozero_unittests",
- ":perfetto_src_trace_processor_analysis_analysis",
- ":perfetto_src_trace_processor_containers_containers",
- ":perfetto_src_trace_processor_containers_unittests",
- ":perfetto_src_trace_processor_db_db",
- ":perfetto_src_trace_processor_db_unittests",
- ":perfetto_src_trace_processor_export_json",
- ":perfetto_src_trace_processor_ftrace_descriptors",
- ":perfetto_src_trace_processor_importers_common_common",
- ":perfetto_src_trace_processor_importers_common_unittests",
- ":perfetto_src_trace_processor_importers_memory_tracker_graph_processor",
- ":perfetto_src_trace_processor_lib",
- ":perfetto_src_trace_processor_metatrace",
- ":perfetto_src_trace_processor_metrics_lib",
- ":perfetto_src_trace_processor_metrics_unittests",
- ":perfetto_src_trace_processor_rpc_rpc",
- ":perfetto_src_trace_processor_rpc_unittests",
- ":perfetto_src_trace_processor_sqlite_sqlite",
- ":perfetto_src_trace_processor_sqlite_unittests",
- ":perfetto_src_trace_processor_storage_full",
- ":perfetto_src_trace_processor_storage_minimal",
- ":perfetto_src_trace_processor_storage_storage",
- ":perfetto_src_trace_processor_tables_tables",
- ":perfetto_src_trace_processor_tables_unittests",
- ":perfetto_src_trace_processor_types_types",
- ":perfetto_src_trace_processor_types_unittests",
- ":perfetto_src_trace_processor_unittests",
- ":perfetto_src_trace_processor_util_descriptors",
- ":perfetto_src_trace_processor_util_proto_to_args_parser",
- ":perfetto_src_trace_processor_util_protozero_to_text",
- ":perfetto_src_trace_processor_util_unittests",
- ":perfetto_src_trace_processor_util_util",
- ":perfetto_src_traced_probes_android_log_android_log",
- ":perfetto_src_traced_probes_android_log_unittests",
- ":perfetto_src_traced_probes_common_common",
- ":perfetto_src_traced_probes_common_test_support",
- ":perfetto_src_traced_probes_common_unittests",
- ":perfetto_src_traced_probes_data_source",
- ":perfetto_src_traced_probes_filesystem_filesystem",
- ":perfetto_src_traced_probes_filesystem_unittests",
- ":perfetto_src_traced_probes_ftrace_format_parser_format_parser",
- ":perfetto_src_traced_probes_ftrace_format_parser_unittests",
- ":perfetto_src_traced_probes_ftrace_ftrace",
- ":perfetto_src_traced_probes_ftrace_ftrace_procfs",
- ":perfetto_src_traced_probes_ftrace_test_messages_cpp_gen",
- ":perfetto_src_traced_probes_ftrace_test_messages_lite_gen",
- ":perfetto_src_traced_probes_ftrace_test_messages_zero_gen",
- ":perfetto_src_traced_probes_ftrace_test_support",
- ":perfetto_src_traced_probes_ftrace_unittests",
- ":perfetto_src_traced_probes_initial_display_state_initial_display_state",
- ":perfetto_src_traced_probes_initial_display_state_unittests",
- ":perfetto_src_traced_probes_metatrace_metatrace",
- ":perfetto_src_traced_probes_packages_list_packages_list",
- ":perfetto_src_traced_probes_packages_list_packages_list_parser",
- ":perfetto_src_traced_probes_packages_list_unittests",
- ":perfetto_src_traced_probes_power_power",
- ":perfetto_src_traced_probes_probes_src",
- ":perfetto_src_traced_probes_ps_ps",
- ":perfetto_src_traced_probes_ps_unittests",
- ":perfetto_src_traced_probes_sys_stats_sys_stats",
- ":perfetto_src_traced_probes_sys_stats_unittests",
- ":perfetto_src_traced_probes_system_info_system_info",
- ":perfetto_src_traced_probes_system_info_unittests",
- ":perfetto_src_traced_probes_unittests",
- ":perfetto_src_traced_service_service",
- ":perfetto_src_traced_service_unittests",
- ":perfetto_src_tracing_client_api_without_backends",
- ":perfetto_src_tracing_common",
- ":perfetto_src_tracing_core_core",
- ":perfetto_src_tracing_core_service",
- ":perfetto_src_tracing_core_test_support",
- ":perfetto_src_tracing_core_unittests",
- ":perfetto_src_tracing_ipc_common",
- ":perfetto_src_tracing_ipc_consumer_consumer",
- ":perfetto_src_tracing_ipc_producer_producer",
- ":perfetto_src_tracing_ipc_service_service",
- ":perfetto_src_tracing_ipc_unittests",
- ":perfetto_src_tracing_platform_impl",
- ":perfetto_src_tracing_test_test_support",
- ":perfetto_src_tracing_test_tracing_integration_test",
- ":perfetto_src_tracing_unittests",
- ":perfetto_tools_sanitizers_unittests_sanitizers_unittests",
- ],
- shared_libs: [
- "libandroidicu",
- "libbase",
- "liblog",
- "libprocinfo",
- "libprotobuf-cpp-full",
- "libprotobuf-cpp-lite",
- "libsqlite",
- "libunwindstack",
- "libutils",
- "libz",
- ],
- static_libs: [
- "libgmock",
- "libgtest",
- ],
- whole_static_libs: [
- "perfetto_gtest_logcat_printer",
- ],
- generated_headers: [
- "perfetto_protos_perfetto_common_cpp_gen_headers",
- "perfetto_protos_perfetto_common_lite_gen_headers",
- "perfetto_protos_perfetto_common_zero_gen_headers",
- "perfetto_protos_perfetto_config_android_cpp_gen_headers",
- "perfetto_protos_perfetto_config_android_lite_gen_headers",
- "perfetto_protos_perfetto_config_android_zero_gen_headers",
- "perfetto_protos_perfetto_config_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_lite_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
- "perfetto_protos_perfetto_config_gpu_lite_gen_headers",
- "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_lite_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_lite_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
- "perfetto_protos_perfetto_config_lite_gen_headers",
- "perfetto_protos_perfetto_config_power_cpp_gen_headers",
- "perfetto_protos_perfetto_config_power_lite_gen_headers",
- "perfetto_protos_perfetto_config_power_zero_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_lite_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
- "perfetto_protos_perfetto_config_profiling_lite_gen_headers",
- "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_lite_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_config_track_event_lite_gen_headers",
- "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_config_zero_gen_headers",
- "perfetto_protos_perfetto_ipc_cpp_gen_headers",
- "perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_android_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_android_lite_gen_headers",
- "perfetto_protos_perfetto_trace_android_zero_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_lite_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_lite_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_lite_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_lite_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_lite_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_lite_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_lite_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
- "perfetto_protos_perfetto_trace_power_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_power_lite_gen_headers",
- "perfetto_protos_perfetto_trace_power_zero_gen_headers",
- "perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen_headers",
- "perfetto_protos_perfetto_trace_processor_zero_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_lite_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ps_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_ps_lite_gen_headers",
- "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_lite_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_lite_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_lite_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_src_base_version_gen_h",
- "perfetto_src_ipc_test_messages_cpp_gen_headers",
- "perfetto_src_ipc_test_messages_ipc_gen_headers",
- "perfetto_src_perfetto_cmd_gen_cc_config_descriptor",
- "perfetto_src_perfetto_cmd_protos_gen_headers",
- "perfetto_src_protozero_testing_messages_cpp_gen_headers",
- "perfetto_src_protozero_testing_messages_lite_gen_headers",
- "perfetto_src_protozero_testing_messages_zero_gen_headers",
- "perfetto_src_trace_processor_gen_cc_test_messages_descriptor",
- "perfetto_src_trace_processor_importers_gen_cc_chrome_track_event_descriptor",
- "perfetto_src_trace_processor_importers_gen_cc_config_descriptor",
- "perfetto_src_trace_processor_importers_gen_cc_track_event_descriptor",
- "perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
- "perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
- "perfetto_src_trace_processor_metrics_gen_merged_sql_metrics",
- "perfetto_src_traced_probes_ftrace_test_messages_cpp_gen_headers",
- "perfetto_src_traced_probes_ftrace_test_messages_lite_gen_headers",
- "perfetto_src_traced_probes_ftrace_test_messages_zero_gen_headers",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- cflags: [
- "-DGOOGLE_PROTOBUF_NO_RTTI",
- "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
- "-DHAVE_HIDDEN",
- ],
- include_dirs: [
- "bionic/libc/kernel",
- ],
- header_libs: [
- "bionic_libc_platform_headers",
- ],
- data: [
- "src/traced/probes/filesystem/testdata/**/*",
- "src/traced/probes/ftrace/test/data/**/*",
- ],
+ name: "perfetto_unittests",
+ srcs: [
+ ":perfetto_include_perfetto_base_base",
+ ":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_include_perfetto_ext_base_http_http",
+ ":perfetto_include_perfetto_ext_ipc_ipc",
+ ":perfetto_include_perfetto_ext_trace_processor_export_json",
+ ":perfetto_include_perfetto_ext_trace_processor_importers_memory_tracker_memory_tracker",
+ ":perfetto_include_perfetto_ext_traced_sys_stats_counters",
+ ":perfetto_include_perfetto_ext_traced_traced",
+ ":perfetto_include_perfetto_ext_tracing_core_core",
+ ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
+ ":perfetto_include_perfetto_protozero_protozero",
+ ":perfetto_include_perfetto_test_test_support",
+ ":perfetto_include_perfetto_trace_processor_basic_types",
+ ":perfetto_include_perfetto_trace_processor_storage",
+ ":perfetto_include_perfetto_trace_processor_trace_processor",
+ ":perfetto_include_perfetto_tracing_core_core",
+ ":perfetto_include_perfetto_tracing_core_forward_decls",
+ ":perfetto_include_perfetto_tracing_tracing",
+ ":perfetto_protos_perfetto_common_cpp_gen",
+ ":perfetto_protos_perfetto_common_lite_gen",
+ ":perfetto_protos_perfetto_common_zero_gen",
+ ":perfetto_protos_perfetto_config_android_cpp_gen",
+ ":perfetto_protos_perfetto_config_android_lite_gen",
+ ":perfetto_protos_perfetto_config_android_zero_gen",
+ ":perfetto_protos_perfetto_config_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_lite_gen",
+ ":perfetto_protos_perfetto_config_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_config_gpu_cpp_gen",
+ ":perfetto_protos_perfetto_config_gpu_lite_gen",
+ ":perfetto_protos_perfetto_config_gpu_zero_gen",
+ ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
+ ":perfetto_protos_perfetto_config_inode_file_lite_gen",
+ ":perfetto_protos_perfetto_config_inode_file_zero_gen",
+ ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
+ ":perfetto_protos_perfetto_config_interceptors_lite_gen",
+ ":perfetto_protos_perfetto_config_interceptors_zero_gen",
+ ":perfetto_protos_perfetto_config_lite_gen",
+ ":perfetto_protos_perfetto_config_power_cpp_gen",
+ ":perfetto_protos_perfetto_config_power_lite_gen",
+ ":perfetto_protos_perfetto_config_power_zero_gen",
+ ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_process_stats_lite_gen",
+ ":perfetto_protos_perfetto_config_process_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_profiling_cpp_gen",
+ ":perfetto_protos_perfetto_config_profiling_lite_gen",
+ ":perfetto_protos_perfetto_config_profiling_zero_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_lite_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_config_track_event_lite_gen",
+ ":perfetto_protos_perfetto_config_track_event_zero_gen",
+ ":perfetto_protos_perfetto_config_zero_gen",
+ ":perfetto_protos_perfetto_ipc_cpp_gen",
+ ":perfetto_protos_perfetto_ipc_ipc_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
+ ":perfetto_protos_perfetto_trace_android_cpp_gen",
+ ":perfetto_protos_perfetto_trace_android_lite_gen",
+ ":perfetto_protos_perfetto_trace_android_zero_gen",
+ ":perfetto_protos_perfetto_trace_chrome_cpp_gen",
+ ":perfetto_protos_perfetto_trace_chrome_lite_gen",
+ ":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_filesystem_cpp_gen",
+ ":perfetto_protos_perfetto_trace_filesystem_lite_gen",
+ ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
+ ":perfetto_protos_perfetto_trace_ftrace_cpp_gen",
+ ":perfetto_protos_perfetto_trace_ftrace_lite_gen",
+ ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_trace_gpu_cpp_gen",
+ ":perfetto_protos_perfetto_trace_gpu_lite_gen",
+ ":perfetto_protos_perfetto_trace_gpu_zero_gen",
+ ":perfetto_protos_perfetto_trace_interned_data_cpp_gen",
+ ":perfetto_protos_perfetto_trace_interned_data_lite_gen",
+ ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
+ ":perfetto_protos_perfetto_trace_minimal_cpp_gen",
+ ":perfetto_protos_perfetto_trace_minimal_lite_gen",
+ ":perfetto_protos_perfetto_trace_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_non_minimal_cpp_gen",
+ ":perfetto_protos_perfetto_trace_non_minimal_lite_gen",
+ ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_perfetto_cpp_gen",
+ ":perfetto_protos_perfetto_trace_perfetto_lite_gen",
+ ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
+ ":perfetto_protos_perfetto_trace_power_cpp_gen",
+ ":perfetto_protos_perfetto_trace_power_lite_gen",
+ ":perfetto_protos_perfetto_trace_power_zero_gen",
+ ":perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen",
+ ":perfetto_protos_perfetto_trace_processor_zero_gen",
+ ":perfetto_protos_perfetto_trace_profiling_cpp_gen",
+ ":perfetto_protos_perfetto_trace_profiling_lite_gen",
+ ":perfetto_protos_perfetto_trace_profiling_zero_gen",
+ ":perfetto_protos_perfetto_trace_ps_cpp_gen",
+ ":perfetto_protos_perfetto_trace_ps_lite_gen",
+ ":perfetto_protos_perfetto_trace_ps_zero_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_cpp_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_lite_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_trace_system_info_cpp_gen",
+ ":perfetto_protos_perfetto_trace_system_info_lite_gen",
+ ":perfetto_protos_perfetto_trace_system_info_zero_gen",
+ ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_trace_track_event_lite_gen",
+ ":perfetto_protos_perfetto_trace_track_event_zero_gen",
+ ":perfetto_protos_perfetto_trace_translation_cpp_gen",
+ ":perfetto_protos_perfetto_trace_translation_lite_gen",
+ ":perfetto_protos_perfetto_trace_translation_zero_gen",
+ ":perfetto_src_android_internal_headers",
+ ":perfetto_src_android_internal_lazy_library_loader",
+ ":perfetto_src_android_stats_android_stats",
+ ":perfetto_src_android_stats_perfetto_atoms",
+ ":perfetto_src_base_base",
+ ":perfetto_src_base_http_http",
+ ":perfetto_src_base_http_unittests",
+ ":perfetto_src_base_test_support",
+ ":perfetto_src_base_unittests",
+ ":perfetto_src_base_unix_socket",
+ ":perfetto_src_ipc_client",
+ ":perfetto_src_ipc_common",
+ ":perfetto_src_ipc_host",
+ ":perfetto_src_ipc_test_messages_cpp_gen",
+ ":perfetto_src_ipc_test_messages_ipc_gen",
+ ":perfetto_src_ipc_unittests",
+ ":perfetto_src_kallsyms_kallsyms",
+ ":perfetto_src_kallsyms_unittests",
+ ":perfetto_src_perfetto_cmd_perfetto_cmd",
+ ":perfetto_src_perfetto_cmd_protos_cpp_gen",
+ ":perfetto_src_perfetto_cmd_trigger_producer",
+ ":perfetto_src_perfetto_cmd_unittests",
+ ":perfetto_src_profiling_common_callstack_trie",
+ ":perfetto_src_profiling_common_interner",
+ ":perfetto_src_profiling_common_interning_output",
+ ":perfetto_src_profiling_common_proc_cmdline",
+ ":perfetto_src_profiling_common_proc_utils",
+ ":perfetto_src_profiling_common_producer_support",
+ ":perfetto_src_profiling_common_profiler_guardrails",
+ ":perfetto_src_profiling_common_unittests",
+ ":perfetto_src_profiling_common_unwind_support",
+ ":perfetto_src_profiling_deobfuscator",
+ ":perfetto_src_profiling_memory_client",
+ ":perfetto_src_profiling_memory_daemon",
+ ":perfetto_src_profiling_memory_ring_buffer",
+ ":perfetto_src_profiling_memory_ring_buffer_unittests",
+ ":perfetto_src_profiling_memory_scoped_spinlock",
+ ":perfetto_src_profiling_memory_unittests",
+ ":perfetto_src_profiling_memory_wire_protocol",
+ ":perfetto_src_profiling_perf_common_types",
+ ":perfetto_src_profiling_perf_proc_descriptors",
+ ":perfetto_src_profiling_perf_producer",
+ ":perfetto_src_profiling_perf_producer_unittests",
+ ":perfetto_src_profiling_perf_regs_parsing",
+ ":perfetto_src_profiling_perf_unwinding",
+ ":perfetto_src_profiling_symbolizer_symbolizer",
+ ":perfetto_src_profiling_symbolizer_unittests",
+ ":perfetto_src_profiling_unittests",
+ ":perfetto_src_protozero_filtering_bytecode_common",
+ ":perfetto_src_protozero_filtering_bytecode_generator",
+ ":perfetto_src_protozero_filtering_bytecode_parser",
+ ":perfetto_src_protozero_filtering_filter_util",
+ ":perfetto_src_protozero_filtering_message_filter",
+ ":perfetto_src_protozero_filtering_unittests",
+ ":perfetto_src_protozero_proto_ring_buffer",
+ ":perfetto_src_protozero_protozero",
+ ":perfetto_src_protozero_testing_messages_cpp_gen",
+ ":perfetto_src_protozero_testing_messages_lite_gen",
+ ":perfetto_src_protozero_testing_messages_zero_gen",
+ ":perfetto_src_protozero_unittests",
+ ":perfetto_src_trace_processor_analysis_analysis",
+ ":perfetto_src_trace_processor_containers_containers",
+ ":perfetto_src_trace_processor_containers_unittests",
+ ":perfetto_src_trace_processor_db_db",
+ ":perfetto_src_trace_processor_db_unittests",
+ ":perfetto_src_trace_processor_export_json",
+ ":perfetto_src_trace_processor_ftrace_descriptors",
+ ":perfetto_src_trace_processor_importers_common_common",
+ ":perfetto_src_trace_processor_importers_common_unittests",
+ ":perfetto_src_trace_processor_importers_memory_tracker_graph_processor",
+ ":perfetto_src_trace_processor_lib",
+ ":perfetto_src_trace_processor_metatrace",
+ ":perfetto_src_trace_processor_metrics_metrics",
+ ":perfetto_src_trace_processor_metrics_unittests",
+ ":perfetto_src_trace_processor_rpc_rpc",
+ ":perfetto_src_trace_processor_rpc_unittests",
+ ":perfetto_src_trace_processor_sqlite_sqlite",
+ ":perfetto_src_trace_processor_sqlite_unittests",
+ ":perfetto_src_trace_processor_storage_full",
+ ":perfetto_src_trace_processor_storage_minimal",
+ ":perfetto_src_trace_processor_storage_storage",
+ ":perfetto_src_trace_processor_tables_tables",
+ ":perfetto_src_trace_processor_tables_unittests",
+ ":perfetto_src_trace_processor_types_types",
+ ":perfetto_src_trace_processor_types_unittests",
+ ":perfetto_src_trace_processor_unittests",
+ ":perfetto_src_trace_processor_util_descriptors",
+ ":perfetto_src_trace_processor_util_gzip",
+ ":perfetto_src_trace_processor_util_interned_message_view",
+ ":perfetto_src_trace_processor_util_proto_to_args_parser",
+ ":perfetto_src_trace_processor_util_protozero_to_text",
+ ":perfetto_src_trace_processor_util_unittests",
+ ":perfetto_src_trace_processor_util_util",
+ ":perfetto_src_traced_probes_android_log_android_log",
+ ":perfetto_src_traced_probes_android_log_unittests",
+ ":perfetto_src_traced_probes_common_common",
+ ":perfetto_src_traced_probes_common_test_support",
+ ":perfetto_src_traced_probes_common_unittests",
+ ":perfetto_src_traced_probes_data_source",
+ ":perfetto_src_traced_probes_filesystem_filesystem",
+ ":perfetto_src_traced_probes_filesystem_unittests",
+ ":perfetto_src_traced_probes_ftrace_format_parser_format_parser",
+ ":perfetto_src_traced_probes_ftrace_format_parser_unittests",
+ ":perfetto_src_traced_probes_ftrace_ftrace",
+ ":perfetto_src_traced_probes_ftrace_ftrace_procfs",
+ ":perfetto_src_traced_probes_ftrace_test_messages_cpp_gen",
+ ":perfetto_src_traced_probes_ftrace_test_messages_lite_gen",
+ ":perfetto_src_traced_probes_ftrace_test_messages_zero_gen",
+ ":perfetto_src_traced_probes_ftrace_test_support",
+ ":perfetto_src_traced_probes_ftrace_unittests",
+ ":perfetto_src_traced_probes_initial_display_state_initial_display_state",
+ ":perfetto_src_traced_probes_initial_display_state_unittests",
+ ":perfetto_src_traced_probes_metatrace_metatrace",
+ ":perfetto_src_traced_probes_packages_list_packages_list",
+ ":perfetto_src_traced_probes_packages_list_packages_list_parser",
+ ":perfetto_src_traced_probes_packages_list_unittests",
+ ":perfetto_src_traced_probes_power_power",
+ ":perfetto_src_traced_probes_power_unittests",
+ ":perfetto_src_traced_probes_probes_src",
+ ":perfetto_src_traced_probes_ps_ps",
+ ":perfetto_src_traced_probes_ps_unittests",
+ ":perfetto_src_traced_probes_sys_stats_sys_stats",
+ ":perfetto_src_traced_probes_sys_stats_unittests",
+ ":perfetto_src_traced_probes_system_info_system_info",
+ ":perfetto_src_traced_probes_system_info_unittests",
+ ":perfetto_src_traced_probes_unittests",
+ ":perfetto_src_traced_service_service",
+ ":perfetto_src_traced_service_unittests",
+ ":perfetto_src_tracing_client_api_without_backends",
+ ":perfetto_src_tracing_common",
+ ":perfetto_src_tracing_core_core",
+ ":perfetto_src_tracing_core_service",
+ ":perfetto_src_tracing_core_test_support",
+ ":perfetto_src_tracing_core_unittests",
+ ":perfetto_src_tracing_ipc_common",
+ ":perfetto_src_tracing_ipc_consumer_consumer",
+ ":perfetto_src_tracing_ipc_default_socket",
+ ":perfetto_src_tracing_ipc_producer_producer",
+ ":perfetto_src_tracing_ipc_service_service",
+ ":perfetto_src_tracing_ipc_unittests",
+ ":perfetto_src_tracing_platform_impl",
+ ":perfetto_src_tracing_test_test_support",
+ ":perfetto_src_tracing_test_tracing_integration_test",
+ ":perfetto_src_tracing_unittests",
+ ":perfetto_tools_sanitizers_unittests_sanitizers_unittests",
+ ],
+ shared_libs: [
+ "libbase",
+ "libicu",
+ "liblog",
+ "libprocinfo",
+ "libprotobuf-cpp-full",
+ "libprotobuf-cpp-lite",
+ "libsqlite",
+ "libunwindstack",
+ "libutils",
+ "libz",
+ ],
+ static_libs: [
+ "libgmock",
+ "libgtest",
+ "perfetto_src_trace_processor_demangle",
+ ],
+ whole_static_libs: [
+ "perfetto_gtest_logcat_printer",
+ ],
+ generated_headers: [
+ "perfetto_protos_perfetto_common_cpp_gen_headers",
+ "perfetto_protos_perfetto_common_lite_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_android_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_android_lite_gen_headers",
+ "perfetto_protos_perfetto_config_android_zero_gen_headers",
+ "perfetto_protos_perfetto_config_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_lite_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_lite_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_lite_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_lite_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
+ "perfetto_protos_perfetto_config_lite_gen_headers",
+ "perfetto_protos_perfetto_config_power_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_power_lite_gen_headers",
+ "perfetto_protos_perfetto_config_power_zero_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_lite_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_lite_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_lite_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_lite_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
+ "perfetto_protos_perfetto_ipc_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_ipc_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_android_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_android_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_android_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_power_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_power_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_power_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_processor_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_lite_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_zero_gen_headers",
+ "perfetto_src_base_version_gen_h",
+ "perfetto_src_ipc_test_messages_cpp_gen_headers",
+ "perfetto_src_ipc_test_messages_ipc_gen_headers",
+ "perfetto_src_perfetto_cmd_gen_cc_config_descriptor",
+ "perfetto_src_perfetto_cmd_protos_cpp_gen_headers",
+ "perfetto_src_protozero_testing_messages_cpp_gen_headers",
+ "perfetto_src_protozero_testing_messages_lite_gen_headers",
+ "perfetto_src_protozero_testing_messages_zero_gen_headers",
+ "perfetto_src_trace_processor_gen_cc_test_messages_descriptor",
+ "perfetto_src_trace_processor_importers_gen_cc_chrome_track_event_descriptor",
+ "perfetto_src_trace_processor_importers_gen_cc_config_descriptor",
+ "perfetto_src_trace_processor_importers_gen_cc_track_event_descriptor",
+ "perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
+ "perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
+ "perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
+ "perfetto_src_traced_probes_ftrace_test_messages_cpp_gen_headers",
+ "perfetto_src_traced_probes_ftrace_test_messages_lite_gen_headers",
+ "perfetto_src_traced_probes_ftrace_test_messages_zero_gen_headers",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ cflags: [
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ "-DHAVE_HIDDEN",
+ ],
+ include_dirs: [
+ "bionic/libc/kernel",
+ ],
+ header_libs: [
+ "bionic_libc_platform_headers",
+ ],
+ data: [
+ "src/profiling/memory/test/data/**/*",
+ "src/traced/probes/filesystem/testdata/**/*",
+ "src/traced/probes/ftrace/test/data/**/*",
+ ],
}
// GN: //src/protozero/protoc_plugin:protozero_plugin
cc_binary_host {
- name: "protozero_plugin",
- srcs: [
- ":perfetto_include_perfetto_base_base",
- ":perfetto_include_perfetto_ext_base_base",
- ":perfetto_src_base_base",
- "src/protozero/protoc_plugin/protozero_plugin.cc",
- ],
- static_libs: [
- "libprotoc",
- ],
- generated_headers: [
- "perfetto_src_base_version_gen_h",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- cflags: [
- "-DGOOGLE_PROTOBUF_NO_RTTI",
- "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
- ],
+ name: "protozero_plugin",
+ srcs: [
+ ":perfetto_include_perfetto_base_base",
+ ":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_src_base_base",
+ "src/protozero/protoc_plugin/protozero_plugin.cc",
+ ],
+ static_libs: [
+ "libprotoc",
+ ],
+ generated_headers: [
+ "perfetto_src_base_version_gen_h",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ cflags: [
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ ],
}
// GN: //src/trace_processor:trace_processor_shell
cc_binary {
- name: "trace_processor_shell",
- srcs: [
- ":perfetto_include_perfetto_base_base",
- ":perfetto_include_perfetto_ext_base_base",
- ":perfetto_include_perfetto_ext_trace_processor_export_json",
- ":perfetto_include_perfetto_ext_trace_processor_importers_memory_tracker_memory_tracker",
- ":perfetto_include_perfetto_ext_traced_sys_stats_counters",
- ":perfetto_include_perfetto_protozero_protozero",
- ":perfetto_include_perfetto_trace_processor_basic_types",
- ":perfetto_include_perfetto_trace_processor_storage",
- ":perfetto_include_perfetto_trace_processor_trace_processor",
- ":perfetto_protos_perfetto_common_zero_gen",
- ":perfetto_protos_perfetto_config_android_zero_gen",
- ":perfetto_protos_perfetto_config_ftrace_zero_gen",
- ":perfetto_protos_perfetto_config_gpu_zero_gen",
- ":perfetto_protos_perfetto_config_inode_file_zero_gen",
- ":perfetto_protos_perfetto_config_interceptors_zero_gen",
- ":perfetto_protos_perfetto_config_power_zero_gen",
- ":perfetto_protos_perfetto_config_process_stats_zero_gen",
- ":perfetto_protos_perfetto_config_profiling_zero_gen",
- ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_config_track_event_zero_gen",
- ":perfetto_protos_perfetto_config_zero_gen",
- ":perfetto_protos_perfetto_trace_android_zero_gen",
- ":perfetto_protos_perfetto_trace_chrome_zero_gen",
- ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
- ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
- ":perfetto_protos_perfetto_trace_gpu_zero_gen",
- ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
- ":perfetto_protos_perfetto_trace_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
- ":perfetto_protos_perfetto_trace_power_zero_gen",
- ":perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen",
- ":perfetto_protos_perfetto_trace_processor_zero_gen",
- ":perfetto_protos_perfetto_trace_profiling_zero_gen",
- ":perfetto_protos_perfetto_trace_ps_zero_gen",
- ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_trace_system_info_zero_gen",
- ":perfetto_protos_perfetto_trace_track_event_zero_gen",
- ":perfetto_src_base_base",
- ":perfetto_src_profiling_deobfuscator",
- ":perfetto_src_profiling_symbolizer_symbolize_database",
- ":perfetto_src_profiling_symbolizer_symbolizer",
- ":perfetto_src_protozero_protozero",
- ":perfetto_src_trace_processor_analysis_analysis",
- ":perfetto_src_trace_processor_containers_containers",
- ":perfetto_src_trace_processor_db_db",
- ":perfetto_src_trace_processor_export_json",
- ":perfetto_src_trace_processor_ftrace_descriptors",
- ":perfetto_src_trace_processor_importers_common_common",
- ":perfetto_src_trace_processor_importers_memory_tracker_graph_processor",
- ":perfetto_src_trace_processor_lib",
- ":perfetto_src_trace_processor_metatrace",
- ":perfetto_src_trace_processor_metrics_lib",
- ":perfetto_src_trace_processor_sqlite_sqlite",
- ":perfetto_src_trace_processor_storage_full",
- ":perfetto_src_trace_processor_storage_minimal",
- ":perfetto_src_trace_processor_storage_storage",
- ":perfetto_src_trace_processor_tables_tables",
- ":perfetto_src_trace_processor_types_types",
- ":perfetto_src_trace_processor_util_descriptors",
- ":perfetto_src_trace_processor_util_proto_to_args_parser",
- ":perfetto_src_trace_processor_util_protozero_to_text",
- ":perfetto_src_trace_processor_util_util",
- "src/trace_processor/trace_processor_shell.cc",
- "src/trace_processor/util/proto_to_json.cc",
- ],
- host_supported: true,
- generated_headers: [
- "perfetto_protos_perfetto_common_zero_gen_headers",
- "perfetto_protos_perfetto_config_android_zero_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
- "perfetto_protos_perfetto_config_power_zero_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_config_zero_gen_headers",
- "perfetto_protos_perfetto_trace_android_zero_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
- "perfetto_protos_perfetto_trace_power_zero_gen_headers",
- "perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen_headers",
- "perfetto_protos_perfetto_trace_processor_zero_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_src_base_version_gen_h",
- "perfetto_src_trace_processor_importers_gen_cc_chrome_track_event_descriptor",
- "perfetto_src_trace_processor_importers_gen_cc_config_descriptor",
- "perfetto_src_trace_processor_importers_gen_cc_track_event_descriptor",
- "perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
- "perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
- "perfetto_src_trace_processor_metrics_gen_merged_sql_metrics",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- cflags: [
- "-DGOOGLE_PROTOBUF_NO_RTTI",
- "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
- "-DHAVE_HIDDEN",
- ],
- strip: {
- all: true,
- },
- target: {
- android: {
- shared_libs: [
- "libandroidicu",
- "liblog",
- "libprotobuf-cpp-full",
- "libsqlite",
- "libutils",
- "libz",
- ],
+ name: "trace_processor_shell",
+ srcs: [
+ ":perfetto_include_perfetto_base_base",
+ ":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_include_perfetto_ext_base_http_http",
+ ":perfetto_include_perfetto_ext_trace_processor_export_json",
+ ":perfetto_include_perfetto_ext_trace_processor_importers_memory_tracker_memory_tracker",
+ ":perfetto_include_perfetto_ext_traced_sys_stats_counters",
+ ":perfetto_include_perfetto_protozero_protozero",
+ ":perfetto_include_perfetto_trace_processor_basic_types",
+ ":perfetto_include_perfetto_trace_processor_storage",
+ ":perfetto_include_perfetto_trace_processor_trace_processor",
+ ":perfetto_protos_perfetto_common_zero_gen",
+ ":perfetto_protos_perfetto_config_android_zero_gen",
+ ":perfetto_protos_perfetto_config_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_config_gpu_zero_gen",
+ ":perfetto_protos_perfetto_config_inode_file_zero_gen",
+ ":perfetto_protos_perfetto_config_interceptors_zero_gen",
+ ":perfetto_protos_perfetto_config_power_zero_gen",
+ ":perfetto_protos_perfetto_config_process_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_profiling_zero_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_track_event_zero_gen",
+ ":perfetto_protos_perfetto_config_zero_gen",
+ ":perfetto_protos_perfetto_trace_android_zero_gen",
+ ":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
+ ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_trace_gpu_zero_gen",
+ ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
+ ":perfetto_protos_perfetto_trace_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
+ ":perfetto_protos_perfetto_trace_power_zero_gen",
+ ":perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen",
+ ":perfetto_protos_perfetto_trace_processor_zero_gen",
+ ":perfetto_protos_perfetto_trace_profiling_zero_gen",
+ ":perfetto_protos_perfetto_trace_ps_zero_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_trace_system_info_zero_gen",
+ ":perfetto_protos_perfetto_trace_track_event_zero_gen",
+ ":perfetto_protos_perfetto_trace_translation_zero_gen",
+ ":perfetto_src_base_base",
+ ":perfetto_src_base_http_http",
+ ":perfetto_src_base_unix_socket",
+ ":perfetto_src_profiling_deobfuscator",
+ ":perfetto_src_profiling_symbolizer_symbolize_database",
+ ":perfetto_src_profiling_symbolizer_symbolizer",
+ ":perfetto_src_protozero_proto_ring_buffer",
+ ":perfetto_src_protozero_protozero",
+ ":perfetto_src_trace_processor_analysis_analysis",
+ ":perfetto_src_trace_processor_containers_containers",
+ ":perfetto_src_trace_processor_db_db",
+ ":perfetto_src_trace_processor_export_json",
+ ":perfetto_src_trace_processor_ftrace_descriptors",
+ ":perfetto_src_trace_processor_importers_common_common",
+ ":perfetto_src_trace_processor_importers_memory_tracker_graph_processor",
+ ":perfetto_src_trace_processor_lib",
+ ":perfetto_src_trace_processor_metatrace",
+ ":perfetto_src_trace_processor_metrics_metrics",
+ ":perfetto_src_trace_processor_rpc_httpd",
+ ":perfetto_src_trace_processor_rpc_rpc",
+ ":perfetto_src_trace_processor_sqlite_sqlite",
+ ":perfetto_src_trace_processor_storage_full",
+ ":perfetto_src_trace_processor_storage_minimal",
+ ":perfetto_src_trace_processor_storage_storage",
+ ":perfetto_src_trace_processor_tables_tables",
+ ":perfetto_src_trace_processor_types_types",
+ ":perfetto_src_trace_processor_util_descriptors",
+ ":perfetto_src_trace_processor_util_gzip",
+ ":perfetto_src_trace_processor_util_interned_message_view",
+ ":perfetto_src_trace_processor_util_proto_to_args_parser",
+ ":perfetto_src_trace_processor_util_protozero_to_text",
+ ":perfetto_src_trace_processor_util_util",
+ "src/trace_processor/trace_processor_shell.cc",
+ "src/trace_processor/util/proto_to_json.cc",
+ ],
+ static_libs: [
+ "perfetto_src_trace_processor_demangle",
+ ],
+ host_supported: true,
+ generated_headers: [
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_android_zero_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
+ "perfetto_protos_perfetto_config_power_zero_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_android_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_power_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_processor_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_zero_gen_headers",
+ "perfetto_src_base_version_gen_h",
+ "perfetto_src_trace_processor_importers_gen_cc_chrome_track_event_descriptor",
+ "perfetto_src_trace_processor_importers_gen_cc_config_descriptor",
+ "perfetto_src_trace_processor_importers_gen_cc_track_event_descriptor",
+ "perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
+ "perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
+ "perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ cflags: [
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ "-DHAVE_HIDDEN",
+ ],
+ strip: {
+ all: true,
},
- host: {
- static_libs: [
- "libprotobuf-cpp-full",
- "libsqlite",
- "libz",
- ],
- stl: "libc++_static",
- dist: {
- targets: [
- "sdk_repo",
- ],
- },
+ target: {
+ android: {
+ shared_libs: [
+ "libicu",
+ "liblog",
+ "libprotobuf-cpp-full",
+ "libsqlite",
+ "libutils",
+ "libz",
+ ],
+ },
+ host: {
+ static_libs: [
+ "libprotobuf-cpp-full",
+ "libsqlite",
+ "libz",
+ ],
+ stl: "libc++_static",
+ dist: {
+ targets: [
+ "sdk_repo",
+ ],
+ },
+ },
},
- },
}
// GN: //tools/trace_to_text:trace_to_text
cc_binary_host {
- name: "trace_to_text",
- srcs: [
- ":perfetto_include_perfetto_base_base",
- ":perfetto_include_perfetto_ext_base_base",
- ":perfetto_include_perfetto_ext_trace_processor_export_json",
- ":perfetto_include_perfetto_ext_trace_processor_importers_memory_tracker_memory_tracker",
- ":perfetto_include_perfetto_ext_traced_sys_stats_counters",
- ":perfetto_include_perfetto_profiling_pprof_builder",
- ":perfetto_include_perfetto_protozero_protozero",
- ":perfetto_include_perfetto_trace_processor_basic_types",
- ":perfetto_include_perfetto_trace_processor_storage",
- ":perfetto_include_perfetto_trace_processor_trace_processor",
- ":perfetto_protos_perfetto_common_zero_gen",
- ":perfetto_protos_perfetto_config_android_zero_gen",
- ":perfetto_protos_perfetto_config_ftrace_zero_gen",
- ":perfetto_protos_perfetto_config_gpu_zero_gen",
- ":perfetto_protos_perfetto_config_inode_file_zero_gen",
- ":perfetto_protos_perfetto_config_interceptors_zero_gen",
- ":perfetto_protos_perfetto_config_power_zero_gen",
- ":perfetto_protos_perfetto_config_process_stats_zero_gen",
- ":perfetto_protos_perfetto_config_profiling_zero_gen",
- ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_config_track_event_zero_gen",
- ":perfetto_protos_perfetto_config_zero_gen",
- ":perfetto_protos_perfetto_trace_android_zero_gen",
- ":perfetto_protos_perfetto_trace_chrome_zero_gen",
- ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
- ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
- ":perfetto_protos_perfetto_trace_gpu_zero_gen",
- ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
- ":perfetto_protos_perfetto_trace_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
- ":perfetto_protos_perfetto_trace_power_zero_gen",
- ":perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen",
- ":perfetto_protos_perfetto_trace_processor_zero_gen",
- ":perfetto_protos_perfetto_trace_profiling_zero_gen",
- ":perfetto_protos_perfetto_trace_ps_zero_gen",
- ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_trace_system_info_zero_gen",
- ":perfetto_protos_perfetto_trace_track_event_zero_gen",
- ":perfetto_protos_third_party_pprof_zero_gen",
- ":perfetto_src_base_base",
- ":perfetto_src_profiling_deobfuscator",
- ":perfetto_src_profiling_symbolizer_symbolize_database",
- ":perfetto_src_profiling_symbolizer_symbolizer",
- ":perfetto_src_protozero_protozero",
- ":perfetto_src_trace_processor_analysis_analysis",
- ":perfetto_src_trace_processor_containers_containers",
- ":perfetto_src_trace_processor_db_db",
- ":perfetto_src_trace_processor_export_json",
- ":perfetto_src_trace_processor_ftrace_descriptors",
- ":perfetto_src_trace_processor_importers_common_common",
- ":perfetto_src_trace_processor_importers_memory_tracker_graph_processor",
- ":perfetto_src_trace_processor_lib",
- ":perfetto_src_trace_processor_metatrace",
- ":perfetto_src_trace_processor_metrics_lib",
- ":perfetto_src_trace_processor_sqlite_sqlite",
- ":perfetto_src_trace_processor_storage_full",
- ":perfetto_src_trace_processor_storage_minimal",
- ":perfetto_src_trace_processor_storage_storage",
- ":perfetto_src_trace_processor_tables_tables",
- ":perfetto_src_trace_processor_types_types",
- ":perfetto_src_trace_processor_util_descriptors",
- ":perfetto_src_trace_processor_util_proto_to_args_parser",
- ":perfetto_src_trace_processor_util_protozero_to_text",
- ":perfetto_src_trace_processor_util_util",
- ":perfetto_tools_trace_to_text_common",
- ":perfetto_tools_trace_to_text_full",
- ":perfetto_tools_trace_to_text_pprofbuilder",
- ":perfetto_tools_trace_to_text_utils",
- ],
- static_libs: [
- "libprotobuf-cpp-full",
- "libsqlite",
- "libz",
- ],
- generated_headers: [
- "perfetto_protos_perfetto_common_zero_gen_headers",
- "perfetto_protos_perfetto_config_android_zero_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
- "perfetto_protos_perfetto_config_power_zero_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_config_zero_gen_headers",
- "perfetto_protos_perfetto_trace_android_zero_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
- "perfetto_protos_perfetto_trace_power_zero_gen_headers",
- "perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen_headers",
- "perfetto_protos_perfetto_trace_processor_zero_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_protos_third_party_pprof_zero_gen_headers",
- "perfetto_src_base_version_gen_h",
- "perfetto_src_trace_processor_importers_gen_cc_chrome_track_event_descriptor",
- "perfetto_src_trace_processor_importers_gen_cc_config_descriptor",
- "perfetto_src_trace_processor_importers_gen_cc_track_event_descriptor",
- "perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
- "perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
- "perfetto_src_trace_processor_metrics_gen_merged_sql_metrics",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- cflags: [
- "-DGOOGLE_PROTOBUF_NO_RTTI",
- "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
- "-DHAVE_HIDDEN",
- ],
+ name: "trace_to_text",
+ srcs: [
+ ":perfetto_include_perfetto_base_base",
+ ":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_include_perfetto_ext_trace_processor_export_json",
+ ":perfetto_include_perfetto_ext_trace_processor_importers_memory_tracker_memory_tracker",
+ ":perfetto_include_perfetto_ext_traced_sys_stats_counters",
+ ":perfetto_include_perfetto_profiling_pprof_builder",
+ ":perfetto_include_perfetto_protozero_protozero",
+ ":perfetto_include_perfetto_trace_processor_basic_types",
+ ":perfetto_include_perfetto_trace_processor_storage",
+ ":perfetto_include_perfetto_trace_processor_trace_processor",
+ ":perfetto_protos_perfetto_common_zero_gen",
+ ":perfetto_protos_perfetto_config_android_zero_gen",
+ ":perfetto_protos_perfetto_config_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_config_gpu_zero_gen",
+ ":perfetto_protos_perfetto_config_inode_file_zero_gen",
+ ":perfetto_protos_perfetto_config_interceptors_zero_gen",
+ ":perfetto_protos_perfetto_config_power_zero_gen",
+ ":perfetto_protos_perfetto_config_process_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_profiling_zero_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_track_event_zero_gen",
+ ":perfetto_protos_perfetto_config_zero_gen",
+ ":perfetto_protos_perfetto_trace_android_zero_gen",
+ ":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
+ ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_trace_gpu_zero_gen",
+ ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
+ ":perfetto_protos_perfetto_trace_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
+ ":perfetto_protos_perfetto_trace_power_zero_gen",
+ ":perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen",
+ ":perfetto_protos_perfetto_trace_processor_zero_gen",
+ ":perfetto_protos_perfetto_trace_profiling_zero_gen",
+ ":perfetto_protos_perfetto_trace_ps_zero_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_trace_system_info_zero_gen",
+ ":perfetto_protos_perfetto_trace_track_event_zero_gen",
+ ":perfetto_protos_perfetto_trace_translation_zero_gen",
+ ":perfetto_protos_third_party_pprof_zero_gen",
+ ":perfetto_src_base_base",
+ ":perfetto_src_profiling_deobfuscator",
+ ":perfetto_src_profiling_symbolizer_symbolize_database",
+ ":perfetto_src_profiling_symbolizer_symbolizer",
+ ":perfetto_src_protozero_proto_ring_buffer",
+ ":perfetto_src_protozero_protozero",
+ ":perfetto_src_trace_processor_analysis_analysis",
+ ":perfetto_src_trace_processor_containers_containers",
+ ":perfetto_src_trace_processor_db_db",
+ ":perfetto_src_trace_processor_export_json",
+ ":perfetto_src_trace_processor_ftrace_descriptors",
+ ":perfetto_src_trace_processor_importers_common_common",
+ ":perfetto_src_trace_processor_importers_memory_tracker_graph_processor",
+ ":perfetto_src_trace_processor_lib",
+ ":perfetto_src_trace_processor_metatrace",
+ ":perfetto_src_trace_processor_metrics_metrics",
+ ":perfetto_src_trace_processor_sqlite_sqlite",
+ ":perfetto_src_trace_processor_storage_full",
+ ":perfetto_src_trace_processor_storage_minimal",
+ ":perfetto_src_trace_processor_storage_storage",
+ ":perfetto_src_trace_processor_tables_tables",
+ ":perfetto_src_trace_processor_types_types",
+ ":perfetto_src_trace_processor_util_descriptors",
+ ":perfetto_src_trace_processor_util_gzip",
+ ":perfetto_src_trace_processor_util_interned_message_view",
+ ":perfetto_src_trace_processor_util_proto_to_args_parser",
+ ":perfetto_src_trace_processor_util_protozero_to_text",
+ ":perfetto_src_trace_processor_util_util",
+ ":perfetto_tools_trace_to_text_lib",
+ ":perfetto_tools_trace_to_text_main",
+ ":perfetto_tools_trace_to_text_pprofbuilder",
+ ":perfetto_tools_trace_to_text_utils",
+ ],
+ static_libs: [
+ "libsqlite",
+ "libz",
+ "perfetto_src_trace_processor_demangle",
+ ],
+ generated_headers: [
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_android_zero_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
+ "perfetto_protos_perfetto_config_power_zero_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_android_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_power_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_processor_metrics_impl_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_processor_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_zero_gen_headers",
+ "perfetto_protos_third_party_pprof_zero_gen_headers",
+ "perfetto_src_base_version_gen_h",
+ "perfetto_src_trace_processor_importers_gen_cc_chrome_track_event_descriptor",
+ "perfetto_src_trace_processor_importers_gen_cc_config_descriptor",
+ "perfetto_src_trace_processor_importers_gen_cc_track_event_descriptor",
+ "perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
+ "perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
+ "perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
+ "perfetto_tools_trace_to_text_gen_cc_trace_descriptor",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ cflags: [
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ "-DHAVE_HIDDEN",
+ ],
}
// GN: //src/traced/service:traced
cc_binary {
- name: "traced",
- srcs: [
- ":perfetto_include_perfetto_ext_traced_traced",
- "src/traced/service/main.cc",
- ],
- shared_libs: [
- "liblog",
- "libperfetto",
- ],
- init_rc: [
- "perfetto.rc",
- ],
- defaults: [
- "perfetto_defaults",
- ],
+ name: "traced",
+ srcs: [
+ ":perfetto_include_perfetto_ext_traced_traced",
+ "src/traced/service/main.cc",
+ ],
+ shared_libs: [
+ "liblog",
+ "libperfetto",
+ ],
+ init_rc: [
+ "perfetto.rc",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
}
// GN: //src/profiling/perf:traced_perf
cc_binary {
- name: "traced_perf",
- srcs: [
- ":perfetto_include_perfetto_base_base",
- ":perfetto_include_perfetto_ext_base_base",
- ":perfetto_include_perfetto_ext_ipc_ipc",
- ":perfetto_include_perfetto_ext_tracing_core_core",
- ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
- ":perfetto_include_perfetto_profiling_normalize",
- ":perfetto_include_perfetto_protozero_protozero",
- ":perfetto_include_perfetto_tracing_core_core",
- ":perfetto_include_perfetto_tracing_core_forward_decls",
- ":perfetto_include_perfetto_tracing_tracing",
- ":perfetto_protos_perfetto_common_cpp_gen",
- ":perfetto_protos_perfetto_common_zero_gen",
- ":perfetto_protos_perfetto_config_android_cpp_gen",
- ":perfetto_protos_perfetto_config_android_zero_gen",
- ":perfetto_protos_perfetto_config_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_zero_gen",
- ":perfetto_protos_perfetto_config_gpu_cpp_gen",
- ":perfetto_protos_perfetto_config_gpu_zero_gen",
- ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
- ":perfetto_protos_perfetto_config_inode_file_zero_gen",
- ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
- ":perfetto_protos_perfetto_config_interceptors_zero_gen",
- ":perfetto_protos_perfetto_config_power_cpp_gen",
- ":perfetto_protos_perfetto_config_power_zero_gen",
- ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_process_stats_zero_gen",
- ":perfetto_protos_perfetto_config_profiling_cpp_gen",
- ":perfetto_protos_perfetto_config_profiling_zero_gen",
- ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_config_track_event_cpp_gen",
- ":perfetto_protos_perfetto_config_track_event_zero_gen",
- ":perfetto_protos_perfetto_config_zero_gen",
- ":perfetto_protos_perfetto_ipc_cpp_gen",
- ":perfetto_protos_perfetto_ipc_ipc_gen",
- ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
- ":perfetto_protos_perfetto_trace_android_zero_gen",
- ":perfetto_protos_perfetto_trace_chrome_zero_gen",
- ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
- ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
- ":perfetto_protos_perfetto_trace_gpu_zero_gen",
- ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
- ":perfetto_protos_perfetto_trace_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
- ":perfetto_protos_perfetto_trace_power_zero_gen",
- ":perfetto_protos_perfetto_trace_profiling_zero_gen",
- ":perfetto_protos_perfetto_trace_ps_zero_gen",
- ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_trace_system_info_zero_gen",
- ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
- ":perfetto_protos_perfetto_trace_track_event_zero_gen",
- ":perfetto_src_android_internal_headers",
- ":perfetto_src_android_internal_lazy_library_loader",
- ":perfetto_src_android_stats_android_stats",
- ":perfetto_src_android_stats_perfetto_atoms",
- ":perfetto_src_base_base",
- ":perfetto_src_base_unix_socket",
- ":perfetto_src_ipc_client",
- ":perfetto_src_ipc_common",
- ":perfetto_src_kallsyms_kallsyms",
- ":perfetto_src_profiling_common_callstack_trie",
- ":perfetto_src_profiling_common_interner",
- ":perfetto_src_profiling_common_interning_output",
- ":perfetto_src_profiling_common_proc_utils",
- ":perfetto_src_profiling_common_producer_support",
- ":perfetto_src_profiling_common_profiler_guardrails",
- ":perfetto_src_profiling_common_unwind_support",
- ":perfetto_src_profiling_perf_common_types",
- ":perfetto_src_profiling_perf_proc_descriptors",
- ":perfetto_src_profiling_perf_producer",
- ":perfetto_src_profiling_perf_regs_parsing",
- ":perfetto_src_profiling_perf_traced_perf_main",
- ":perfetto_src_profiling_perf_unwinding",
- ":perfetto_src_protozero_filtering_bytecode_common",
- ":perfetto_src_protozero_filtering_bytecode_parser",
- ":perfetto_src_protozero_filtering_message_filter",
- ":perfetto_src_protozero_protozero",
- ":perfetto_src_traced_probes_ftrace_ftrace_procfs",
- ":perfetto_src_traced_probes_packages_list_packages_list_parser",
- ":perfetto_src_tracing_common",
- ":perfetto_src_tracing_core_core",
- ":perfetto_src_tracing_core_service",
- ":perfetto_src_tracing_ipc_common",
- ":perfetto_src_tracing_ipc_producer_producer",
- "src/profiling/perf/main.cc",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- "libprocinfo",
- "libunwindstack",
- ],
- init_rc: [
- "traced_perf.rc",
- ],
- generated_headers: [
- "perfetto_protos_perfetto_common_cpp_gen_headers",
- "perfetto_protos_perfetto_common_zero_gen_headers",
- "perfetto_protos_perfetto_config_android_cpp_gen_headers",
- "perfetto_protos_perfetto_config_android_zero_gen_headers",
- "perfetto_protos_perfetto_config_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
- "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
- "perfetto_protos_perfetto_config_power_cpp_gen_headers",
- "perfetto_protos_perfetto_config_power_zero_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
- "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_config_zero_gen_headers",
- "perfetto_protos_perfetto_ipc_cpp_gen_headers",
- "perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_android_zero_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
- "perfetto_protos_perfetto_trace_power_zero_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_src_base_version_gen_h",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- cflags: [
- "-DGOOGLE_PROTOBUF_NO_RTTI",
- "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
- ],
- include_dirs: [
- "bionic/libc/kernel",
- ],
+ name: "traced_perf",
+ srcs: [
+ ":perfetto_include_perfetto_base_base",
+ ":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_include_perfetto_ext_ipc_ipc",
+ ":perfetto_include_perfetto_ext_tracing_core_core",
+ ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
+ ":perfetto_include_perfetto_protozero_protozero",
+ ":perfetto_include_perfetto_tracing_core_core",
+ ":perfetto_include_perfetto_tracing_core_forward_decls",
+ ":perfetto_include_perfetto_tracing_tracing",
+ ":perfetto_protos_perfetto_common_cpp_gen",
+ ":perfetto_protos_perfetto_common_zero_gen",
+ ":perfetto_protos_perfetto_config_android_cpp_gen",
+ ":perfetto_protos_perfetto_config_android_zero_gen",
+ ":perfetto_protos_perfetto_config_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_config_gpu_cpp_gen",
+ ":perfetto_protos_perfetto_config_gpu_zero_gen",
+ ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
+ ":perfetto_protos_perfetto_config_inode_file_zero_gen",
+ ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
+ ":perfetto_protos_perfetto_config_interceptors_zero_gen",
+ ":perfetto_protos_perfetto_config_power_cpp_gen",
+ ":perfetto_protos_perfetto_config_power_zero_gen",
+ ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_process_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_profiling_cpp_gen",
+ ":perfetto_protos_perfetto_config_profiling_zero_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_config_track_event_zero_gen",
+ ":perfetto_protos_perfetto_config_zero_gen",
+ ":perfetto_protos_perfetto_ipc_cpp_gen",
+ ":perfetto_protos_perfetto_ipc_ipc_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
+ ":perfetto_protos_perfetto_trace_android_zero_gen",
+ ":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
+ ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_trace_gpu_zero_gen",
+ ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
+ ":perfetto_protos_perfetto_trace_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
+ ":perfetto_protos_perfetto_trace_power_zero_gen",
+ ":perfetto_protos_perfetto_trace_profiling_zero_gen",
+ ":perfetto_protos_perfetto_trace_ps_zero_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_trace_system_info_zero_gen",
+ ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_trace_track_event_zero_gen",
+ ":perfetto_protos_perfetto_trace_translation_zero_gen",
+ ":perfetto_src_android_internal_headers",
+ ":perfetto_src_android_internal_lazy_library_loader",
+ ":perfetto_src_android_stats_android_stats",
+ ":perfetto_src_android_stats_perfetto_atoms",
+ ":perfetto_src_base_base",
+ ":perfetto_src_base_unix_socket",
+ ":perfetto_src_ipc_client",
+ ":perfetto_src_ipc_common",
+ ":perfetto_src_kallsyms_kallsyms",
+ ":perfetto_src_profiling_common_callstack_trie",
+ ":perfetto_src_profiling_common_interner",
+ ":perfetto_src_profiling_common_interning_output",
+ ":perfetto_src_profiling_common_proc_cmdline",
+ ":perfetto_src_profiling_common_proc_utils",
+ ":perfetto_src_profiling_common_producer_support",
+ ":perfetto_src_profiling_common_profiler_guardrails",
+ ":perfetto_src_profiling_common_unwind_support",
+ ":perfetto_src_profiling_perf_common_types",
+ ":perfetto_src_profiling_perf_proc_descriptors",
+ ":perfetto_src_profiling_perf_producer",
+ ":perfetto_src_profiling_perf_regs_parsing",
+ ":perfetto_src_profiling_perf_traced_perf_main",
+ ":perfetto_src_profiling_perf_unwinding",
+ ":perfetto_src_protozero_filtering_bytecode_common",
+ ":perfetto_src_protozero_filtering_bytecode_parser",
+ ":perfetto_src_protozero_filtering_message_filter",
+ ":perfetto_src_protozero_protozero",
+ ":perfetto_src_traced_probes_ftrace_ftrace_procfs",
+ ":perfetto_src_traced_probes_packages_list_packages_list_parser",
+ ":perfetto_src_tracing_common",
+ ":perfetto_src_tracing_core_core",
+ ":perfetto_src_tracing_core_service",
+ ":perfetto_src_tracing_ipc_common",
+ ":perfetto_src_tracing_ipc_default_socket",
+ ":perfetto_src_tracing_ipc_producer_producer",
+ "src/profiling/perf/main.cc",
+ ],
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "libprocinfo",
+ "libunwindstack",
+ ],
+ init_rc: [
+ "traced_perf.rc",
+ ],
+ generated_headers: [
+ "perfetto_protos_perfetto_common_cpp_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_android_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_android_zero_gen_headers",
+ "perfetto_protos_perfetto_config_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
+ "perfetto_protos_perfetto_config_power_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_power_zero_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
+ "perfetto_protos_perfetto_ipc_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_ipc_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_android_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_power_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_zero_gen_headers",
+ "perfetto_src_base_version_gen_h",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ cflags: [
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ ],
+ include_dirs: [
+ "bionic/libc/kernel",
+ ],
}
// GN: //src/traced/probes:traced_probes
cc_binary {
- name: "traced_probes",
- srcs: [
- ":perfetto_include_perfetto_ext_traced_traced",
- "src/traced/probes/main.cc",
- ],
- shared_libs: [
- "liblog",
- "libperfetto",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- required: [
- "libperfetto_android_internal",
- "mm_events",
- "traced_perf",
- "trigger_perfetto",
- ],
+ name: "traced_probes",
+ srcs: [
+ ":perfetto_include_perfetto_ext_traced_traced",
+ "src/traced/probes/main.cc",
+ ],
+ shared_libs: [
+ "liblog",
+ "libperfetto",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ required: [
+ "libperfetto_android_internal",
+ "mm_events",
+ "traced_perf",
+ "trigger_perfetto",
+ ],
}
// GN: //src/perfetto_cmd:trigger_perfetto
cc_binary {
- name: "trigger_perfetto",
- srcs: [
- ":perfetto_include_perfetto_base_base",
- ":perfetto_include_perfetto_ext_base_base",
- ":perfetto_include_perfetto_ext_ipc_ipc",
- ":perfetto_include_perfetto_ext_traced_traced",
- ":perfetto_include_perfetto_ext_tracing_core_core",
- ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
- ":perfetto_include_perfetto_protozero_protozero",
- ":perfetto_include_perfetto_tracing_core_core",
- ":perfetto_include_perfetto_tracing_core_forward_decls",
- ":perfetto_include_perfetto_tracing_tracing",
- ":perfetto_protos_perfetto_common_cpp_gen",
- ":perfetto_protos_perfetto_common_zero_gen",
- ":perfetto_protos_perfetto_config_android_cpp_gen",
- ":perfetto_protos_perfetto_config_android_zero_gen",
- ":perfetto_protos_perfetto_config_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
- ":perfetto_protos_perfetto_config_ftrace_zero_gen",
- ":perfetto_protos_perfetto_config_gpu_cpp_gen",
- ":perfetto_protos_perfetto_config_gpu_zero_gen",
- ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
- ":perfetto_protos_perfetto_config_inode_file_zero_gen",
- ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
- ":perfetto_protos_perfetto_config_interceptors_zero_gen",
- ":perfetto_protos_perfetto_config_power_cpp_gen",
- ":perfetto_protos_perfetto_config_power_zero_gen",
- ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_process_stats_zero_gen",
- ":perfetto_protos_perfetto_config_profiling_cpp_gen",
- ":perfetto_protos_perfetto_config_profiling_zero_gen",
- ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
- ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_config_track_event_cpp_gen",
- ":perfetto_protos_perfetto_config_track_event_zero_gen",
- ":perfetto_protos_perfetto_config_zero_gen",
- ":perfetto_protos_perfetto_ipc_cpp_gen",
- ":perfetto_protos_perfetto_ipc_ipc_gen",
- ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
- ":perfetto_protos_perfetto_trace_android_zero_gen",
- ":perfetto_protos_perfetto_trace_chrome_zero_gen",
- ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
- ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
- ":perfetto_protos_perfetto_trace_gpu_zero_gen",
- ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
- ":perfetto_protos_perfetto_trace_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
- ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
- ":perfetto_protos_perfetto_trace_power_zero_gen",
- ":perfetto_protos_perfetto_trace_profiling_zero_gen",
- ":perfetto_protos_perfetto_trace_ps_zero_gen",
- ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
- ":perfetto_protos_perfetto_trace_system_info_zero_gen",
- ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
- ":perfetto_protos_perfetto_trace_track_event_zero_gen",
- ":perfetto_src_android_internal_headers",
- ":perfetto_src_android_internal_lazy_library_loader",
- ":perfetto_src_android_stats_android_stats",
- ":perfetto_src_android_stats_perfetto_atoms",
- ":perfetto_src_base_base",
- ":perfetto_src_base_unix_socket",
- ":perfetto_src_ipc_client",
- ":perfetto_src_ipc_common",
- ":perfetto_src_perfetto_cmd_protos_gen",
- ":perfetto_src_perfetto_cmd_trigger_perfetto_cmd",
- ":perfetto_src_perfetto_cmd_trigger_producer",
- ":perfetto_src_protozero_protozero",
- ":perfetto_src_tracing_common",
- ":perfetto_src_tracing_core_core",
- ":perfetto_src_tracing_ipc_common",
- ":perfetto_src_tracing_ipc_producer_producer",
- "src/perfetto_cmd/trigger_perfetto_main.cc",
- ],
- shared_libs: [
- "liblog",
- ],
- generated_headers: [
- "perfetto_protos_perfetto_common_cpp_gen_headers",
- "perfetto_protos_perfetto_common_zero_gen_headers",
- "perfetto_protos_perfetto_config_android_cpp_gen_headers",
- "perfetto_protos_perfetto_config_android_zero_gen_headers",
- "perfetto_protos_perfetto_config_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
- "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
- "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
- "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
- "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
- "perfetto_protos_perfetto_config_power_cpp_gen_headers",
- "perfetto_protos_perfetto_config_power_zero_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
- "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
- "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
- "perfetto_protos_perfetto_config_zero_gen_headers",
- "perfetto_protos_perfetto_ipc_cpp_gen_headers",
- "perfetto_protos_perfetto_ipc_ipc_gen_headers",
- "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_android_zero_gen_headers",
- "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
- "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
- "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
- "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
- "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
- "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
- "perfetto_protos_perfetto_trace_power_zero_gen_headers",
- "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
- "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
- "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
- "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
- "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
- "perfetto_src_base_version_gen_h",
- "perfetto_src_perfetto_cmd_protos_gen_headers",
- ],
- defaults: [
- "perfetto_defaults",
- ],
- cflags: [
- "-DGOOGLE_PROTOBUF_NO_RTTI",
- "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
- ],
+ name: "trigger_perfetto",
+ srcs: [
+ ":perfetto_include_perfetto_base_base",
+ ":perfetto_include_perfetto_ext_base_base",
+ ":perfetto_include_perfetto_ext_ipc_ipc",
+ ":perfetto_include_perfetto_ext_traced_traced",
+ ":perfetto_include_perfetto_ext_tracing_core_core",
+ ":perfetto_include_perfetto_ext_tracing_ipc_ipc",
+ ":perfetto_include_perfetto_protozero_protozero",
+ ":perfetto_include_perfetto_tracing_core_core",
+ ":perfetto_include_perfetto_tracing_core_forward_decls",
+ ":perfetto_include_perfetto_tracing_tracing",
+ ":perfetto_protos_perfetto_common_cpp_gen",
+ ":perfetto_protos_perfetto_common_zero_gen",
+ ":perfetto_protos_perfetto_config_android_cpp_gen",
+ ":perfetto_protos_perfetto_config_android_zero_gen",
+ ":perfetto_protos_perfetto_config_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_cpp_gen",
+ ":perfetto_protos_perfetto_config_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_config_gpu_cpp_gen",
+ ":perfetto_protos_perfetto_config_gpu_zero_gen",
+ ":perfetto_protos_perfetto_config_inode_file_cpp_gen",
+ ":perfetto_protos_perfetto_config_inode_file_zero_gen",
+ ":perfetto_protos_perfetto_config_interceptors_cpp_gen",
+ ":perfetto_protos_perfetto_config_interceptors_zero_gen",
+ ":perfetto_protos_perfetto_config_power_cpp_gen",
+ ":perfetto_protos_perfetto_config_power_zero_gen",
+ ":perfetto_protos_perfetto_config_process_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_process_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_profiling_cpp_gen",
+ ":perfetto_protos_perfetto_config_profiling_zero_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_cpp_gen",
+ ":perfetto_protos_perfetto_config_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_config_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_config_track_event_zero_gen",
+ ":perfetto_protos_perfetto_config_zero_gen",
+ ":perfetto_protos_perfetto_ipc_cpp_gen",
+ ":perfetto_protos_perfetto_ipc_ipc_gen",
+ ":perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen",
+ ":perfetto_protos_perfetto_trace_android_zero_gen",
+ ":perfetto_protos_perfetto_trace_chrome_zero_gen",
+ ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
+ ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
+ ":perfetto_protos_perfetto_trace_gpu_zero_gen",
+ ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
+ ":perfetto_protos_perfetto_trace_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
+ ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
+ ":perfetto_protos_perfetto_trace_power_zero_gen",
+ ":perfetto_protos_perfetto_trace_profiling_zero_gen",
+ ":perfetto_protos_perfetto_trace_ps_zero_gen",
+ ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
+ ":perfetto_protos_perfetto_trace_system_info_zero_gen",
+ ":perfetto_protos_perfetto_trace_track_event_cpp_gen",
+ ":perfetto_protos_perfetto_trace_track_event_zero_gen",
+ ":perfetto_protos_perfetto_trace_translation_zero_gen",
+ ":perfetto_src_android_internal_headers",
+ ":perfetto_src_android_internal_lazy_library_loader",
+ ":perfetto_src_android_stats_android_stats",
+ ":perfetto_src_android_stats_perfetto_atoms",
+ ":perfetto_src_base_base",
+ ":perfetto_src_base_unix_socket",
+ ":perfetto_src_ipc_client",
+ ":perfetto_src_ipc_common",
+ ":perfetto_src_perfetto_cmd_protos_cpp_gen",
+ ":perfetto_src_perfetto_cmd_trigger_perfetto_cmd",
+ ":perfetto_src_perfetto_cmd_trigger_producer",
+ ":perfetto_src_protozero_protozero",
+ ":perfetto_src_tracing_common",
+ ":perfetto_src_tracing_core_core",
+ ":perfetto_src_tracing_ipc_common",
+ ":perfetto_src_tracing_ipc_default_socket",
+ ":perfetto_src_tracing_ipc_producer_producer",
+ "src/perfetto_cmd/trigger_perfetto_main.cc",
+ ],
+ shared_libs: [
+ "liblog",
+ ],
+ generated_headers: [
+ "perfetto_protos_perfetto_common_cpp_gen_headers",
+ "perfetto_protos_perfetto_common_zero_gen_headers",
+ "perfetto_protos_perfetto_config_android_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_android_zero_gen_headers",
+ "perfetto_protos_perfetto_config_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_inode_file_zero_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_interceptors_zero_gen_headers",
+ "perfetto_protos_perfetto_config_power_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_power_zero_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_process_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_config_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_config_zero_gen_headers",
+ "perfetto_protos_perfetto_ipc_cpp_gen_headers",
+ "perfetto_protos_perfetto_ipc_ipc_gen_headers",
+ "perfetto_protos_perfetto_ipc_wire_protocol_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_android_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_gpu_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_power_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_system_info_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_cpp_gen_headers",
+ "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
+ "perfetto_protos_perfetto_trace_translation_zero_gen_headers",
+ "perfetto_src_base_version_gen_h",
+ "perfetto_src_perfetto_cmd_protos_cpp_gen_headers",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
+ cflags: [
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ ],
}
// These targets are appended to the autogenerated Android.bp by tools/gen_android_bp.
java_library_host {
- name: "perfetto_config-full",
- proto: {
- type: "full",
- },
- srcs: [
- "protos/perfetto/config/perfetto_config.proto",
- ],
+ name: "perfetto_config-full",
+ proto: {
+ type: "full",
+ },
+ srcs: [
+ "protos/perfetto/config/perfetto_config.proto",
+ ],
}
java_library_host {
- name: "perfetto_metrics-full",
- proto: {
- type: "full",
- },
- srcs: [
- "protos/perfetto/metrics/perfetto_merged_metrics.proto",
- ],
+ name: "perfetto_metrics-full",
+ proto: {
+ type: "full",
+ },
+ srcs: [
+ "protos/perfetto/metrics/perfetto_merged_metrics.proto",
+ ],
}
// This sample target shows how to use the perfetto client API from within the
// Android tree.
cc_binary {
- name: "libperfetto_client_example",
- srcs: [
- "test/client_api_example.cc",
- ],
- static_libs: [
- "libperfetto_client_experimental",
- "perfetto_trace_protos",
- ],
- shared_libs: [
- "libprotobuf-cpp-lite",
- "liblog",
- ],
- cflags: [
- "-DGOOGLE_PROTOBUF_NO_RTTI",
- "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
- ],
- defaults: [
- "perfetto_defaults",
- ],
+ name: "libperfetto_client_example",
+ srcs: [
+ "test/client_api_example.cc",
+ ],
+ static_libs: [
+ "libperfetto_client_experimental",
+ "perfetto_trace_protos",
+ ],
+ shared_libs: [
+ "libprotobuf-cpp-lite",
+ "liblog",
+ ],
+ cflags: [
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
}
cc_library_static {
@@ -10048,14 +10947,14 @@ python_library {
filegroup {
name: "perfetto-trace-processor-python-srcs",
- srcs: ["src/trace_processor/python/perfetto/**/*.py"],
- path: "src/trace_processor/python",
+ srcs: ["python/perfetto/trace_processor/*.py"],
+ path: "python",
}
filegroup {
name: "perfetto-trace-processor-python-data",
- srcs: ["src/trace_processor/python/perfetto/**/*.descriptor*"],
- path: "src/trace_processor/python",
+ srcs: ["python/perfetto/trace_processor/*.descriptor*"],
+ path: "python",
}
// Added automatically by a large-scale-change that took the approach of
diff --git a/Android.bp.extras b/Android.bp.extras
index 53140dd4b..d6deb9728 100644
--- a/Android.bp.extras
+++ b/Android.bp.extras
@@ -1,47 +1,47 @@
// These targets are appended to the autogenerated Android.bp by tools/gen_android_bp.
java_library_host {
- name: "perfetto_config-full",
- proto: {
- type: "full",
- },
- srcs: [
- "protos/perfetto/config/perfetto_config.proto",
- ],
+ name: "perfetto_config-full",
+ proto: {
+ type: "full",
+ },
+ srcs: [
+ "protos/perfetto/config/perfetto_config.proto",
+ ],
}
java_library_host {
- name: "perfetto_metrics-full",
- proto: {
- type: "full",
- },
- srcs: [
- "protos/perfetto/metrics/perfetto_merged_metrics.proto",
- ],
+ name: "perfetto_metrics-full",
+ proto: {
+ type: "full",
+ },
+ srcs: [
+ "protos/perfetto/metrics/perfetto_merged_metrics.proto",
+ ],
}
// This sample target shows how to use the perfetto client API from within the
// Android tree.
cc_binary {
- name: "libperfetto_client_example",
- srcs: [
- "test/client_api_example.cc",
- ],
- static_libs: [
- "libperfetto_client_experimental",
- "perfetto_trace_protos",
- ],
- shared_libs: [
- "libprotobuf-cpp-lite",
- "liblog",
- ],
- cflags: [
- "-DGOOGLE_PROTOBUF_NO_RTTI",
- "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
- ],
- defaults: [
- "perfetto_defaults",
- ],
+ name: "libperfetto_client_example",
+ srcs: [
+ "test/client_api_example.cc",
+ ],
+ static_libs: [
+ "libperfetto_client_experimental",
+ "perfetto_trace_protos",
+ ],
+ shared_libs: [
+ "libprotobuf-cpp-lite",
+ "liblog",
+ ],
+ cflags: [
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ ],
+ defaults: [
+ "perfetto_defaults",
+ ],
}
cc_library_static {
@@ -112,14 +112,14 @@ python_library {
filegroup {
name: "perfetto-trace-processor-python-srcs",
- srcs: ["src/trace_processor/python/perfetto/**/*.py"],
- path: "src/trace_processor/python",
+ srcs: ["python/perfetto/trace_processor/*.py"],
+ path: "python",
}
filegroup {
name: "perfetto-trace-processor-python-data",
- srcs: ["src/trace_processor/python/perfetto/**/*.descriptor*"],
- path: "src/trace_processor/python",
+ srcs: ["python/perfetto/trace_processor/*.descriptor*"],
+ path: "python",
}
// Added automatically by a large-scale-change that took the approach of
diff --git a/BUILD b/BUILD
index 0e006ec12..8fa787487 100644
--- a/BUILD
+++ b/BUILD
@@ -17,7 +17,10 @@
load("@perfetto_cfg//:perfetto_cfg.bzl", "PERFETTO_CONFIG")
load(
"@perfetto//bazel:rules.bzl",
+ "perfetto_build_config_cc_library",
"perfetto_cc_binary",
+ "perfetto_filegroup",
+ "perfetto_genrule",
"perfetto_cc_ipc_library",
"perfetto_cc_library",
"perfetto_cc_proto_descriptor",
@@ -30,6 +33,7 @@ load(
"perfetto_proto_descriptor",
"perfetto_py_binary",
"perfetto_py_library",
+ "perfetto_py_proto_library",
"perfetto_gensignature_internal_only",
)
@@ -166,9 +170,46 @@ perfetto_cc_binary(
":protos_perfetto_trace_system_info_zero",
":protos_perfetto_trace_track_event_cpp",
":protos_perfetto_trace_track_event_zero",
+ ":protos_perfetto_trace_translation_zero",
],
)
+# GN target: //tools/proto_filter:proto_filter
+perfetto_cc_binary(
+ name = "proto_filter",
+ srcs = [
+ ":src_protozero_filtering_bytecode_common",
+ ":src_protozero_filtering_bytecode_generator",
+ ":src_protozero_filtering_bytecode_parser",
+ ":src_protozero_filtering_filter_util",
+ ":src_protozero_filtering_message_filter",
+ "tools/proto_filter/proto_filter.cc",
+ ],
+ deps = [
+ ":protozero",
+ ":src_base_base",
+ ] + PERFETTO_CONFIG.deps.protobuf_full,
+)
+
+# GN target: //tools/proto_merger:proto_merger
+perfetto_cc_binary(
+ name = "proto_merger",
+ srcs = [
+ "tools/proto_merger/allowlist.cc",
+ "tools/proto_merger/allowlist.h",
+ "tools/proto_merger/main.cc",
+ "tools/proto_merger/proto_file.cc",
+ "tools/proto_merger/proto_file.h",
+ "tools/proto_merger/proto_file_serializer.cc",
+ "tools/proto_merger/proto_file_serializer.h",
+ "tools/proto_merger/proto_merger.cc",
+ "tools/proto_merger/proto_merger.h",
+ ],
+ deps = [
+ ":src_base_base",
+ ] + PERFETTO_CONFIG.deps.protobuf_full,
+)
+
# GN target: //:libperfetto
perfetto_cc_library(
name = "libperfetto",
@@ -205,6 +246,7 @@ perfetto_cc_library(
":src_tracing_core_service",
":src_tracing_ipc_common",
":src_tracing_ipc_consumer_consumer",
+ ":src_tracing_ipc_default_socket",
":src_tracing_ipc_producer_producer",
":src_tracing_ipc_service_service",
],
@@ -266,6 +308,7 @@ perfetto_cc_library(
":protos_perfetto_trace_system_info_zero",
":protos_perfetto_trace_track_event_cpp",
":protos_perfetto_trace_track_event_zero",
+ ":protos_perfetto_trace_translation_zero",
":protozero",
":src_base_base",
],
@@ -273,7 +316,7 @@ perfetto_cc_library(
)
# GN target: //include/perfetto/base:base
-filegroup(
+perfetto_filegroup(
name = "include_perfetto_base_base",
srcs = [
"include/perfetto/base/build_config.h",
@@ -291,16 +334,29 @@ filegroup(
],
)
+# GN target: //include/perfetto/ext/base/http:http
+perfetto_filegroup(
+ name = "include_perfetto_ext_base_http_http",
+ srcs = [
+ "include/perfetto/ext/base/http/http_server.h",
+ "include/perfetto/ext/base/http/sha1.h",
+ ],
+)
+
# GN target: //include/perfetto/ext/base:base
-filegroup(
+perfetto_filegroup(
name = "include_perfetto_ext_base_base",
srcs = [
+ "include/perfetto/ext/base/android_utils.h",
+ "include/perfetto/ext/base/base64.h",
"include/perfetto/ext/base/circular_queue.h",
"include/perfetto/ext/base/container_annotations.h",
+ "include/perfetto/ext/base/crash_keys.h",
"include/perfetto/ext/base/ctrl_c_handler.h",
"include/perfetto/ext/base/endian.h",
"include/perfetto/ext/base/event_fd.h",
"include/perfetto/ext/base/file_utils.h",
+ "include/perfetto/ext/base/flat_hash_map.h",
"include/perfetto/ext/base/getopt.h",
"include/perfetto/ext/base/getopt_compat.h",
"include/perfetto/ext/base/hash.h",
@@ -313,11 +369,13 @@ filegroup(
"include/perfetto/ext/base/pipe.h",
"include/perfetto/ext/base/scoped_file.h",
"include/perfetto/ext/base/small_set.h",
+ "include/perfetto/ext/base/small_vector.h",
"include/perfetto/ext/base/string_splitter.h",
"include/perfetto/ext/base/string_utils.h",
"include/perfetto/ext/base/string_view.h",
"include/perfetto/ext/base/string_writer.h",
"include/perfetto/ext/base/subprocess.h",
+ "include/perfetto/ext/base/sys_types.h",
"include/perfetto/ext/base/temp_file.h",
"include/perfetto/ext/base/thread_annotations.h",
"include/perfetto/ext/base/thread_checker.h",
@@ -337,7 +395,7 @@ filegroup(
)
# GN target: //include/perfetto/ext/ipc:ipc
-filegroup(
+perfetto_filegroup(
name = "include_perfetto_ext_ipc_ipc",
srcs = [
"include/perfetto/ext/ipc/async_result.h",
@@ -354,7 +412,7 @@ filegroup(
)
# GN target: //include/perfetto/ext/trace_processor/importers/memory_tracker:memory_tracker
-filegroup(
+perfetto_filegroup(
name = "include_perfetto_ext_trace_processor_importers_memory_tracker_memory_tracker",
srcs = [
"include/perfetto/ext/trace_processor/importers/memory_tracker/graph.h",
@@ -366,8 +424,16 @@ filegroup(
],
)
+# GN target: //include/perfetto/ext/trace_processor:demangle
+perfetto_filegroup(
+ name = "include_perfetto_ext_trace_processor_demangle",
+ srcs = [
+ "include/perfetto/ext/trace_processor/demangle.h",
+ ],
+)
+
# GN target: //include/perfetto/ext/trace_processor:export_json
-filegroup(
+perfetto_filegroup(
name = "include_perfetto_ext_trace_processor_export_json",
srcs = [
"include/perfetto/ext/trace_processor/export_json.h",
@@ -375,7 +441,7 @@ filegroup(
)
# GN target: //include/perfetto/ext/traced:sys_stats_counters
-filegroup(
+perfetto_filegroup(
name = "include_perfetto_ext_traced_sys_stats_counters",
srcs = [
"include/perfetto/ext/traced/sys_stats_counters.h",
@@ -383,7 +449,7 @@ filegroup(
)
# GN target: //include/perfetto/ext/traced:traced
-filegroup(
+perfetto_filegroup(
name = "include_perfetto_ext_traced_traced",
srcs = [
"include/perfetto/ext/traced/data_source_types.h",
@@ -392,7 +458,7 @@ filegroup(
)
# GN target: //include/perfetto/ext/tracing/core:core
-filegroup(
+perfetto_filegroup(
name = "include_perfetto_ext_tracing_core_core",
srcs = [
"include/perfetto/ext/tracing/core/basic_types.h",
@@ -412,7 +478,7 @@ filegroup(
)
# GN target: //include/perfetto/ext/tracing/ipc:ipc
-filegroup(
+perfetto_filegroup(
name = "include_perfetto_ext_tracing_ipc_ipc",
srcs = [
"include/perfetto/ext/tracing/ipc/consumer_ipc_client.h",
@@ -423,7 +489,7 @@ filegroup(
)
# GN target: //include/perfetto/profiling:pprof_builder
-filegroup(
+perfetto_filegroup(
name = "include_perfetto_profiling_pprof_builder",
srcs = [
"include/perfetto/profiling/pprof_builder.h",
@@ -431,7 +497,7 @@ filegroup(
)
# GN target: //include/perfetto/protozero:protozero
-filegroup(
+perfetto_filegroup(
name = "include_perfetto_protozero_protozero",
srcs = [
"include/perfetto/protozero/contiguous_memory_range.h",
@@ -454,7 +520,7 @@ filegroup(
)
# GN target: //include/perfetto/public:public
-filegroup(
+perfetto_filegroup(
name = "include_perfetto_public_public",
srcs = [
"include/perfetto/public/consumer_api.h",
@@ -462,7 +528,7 @@ filegroup(
)
# GN target: //include/perfetto/trace_processor:basic_types
-filegroup(
+perfetto_filegroup(
name = "include_perfetto_trace_processor_basic_types",
srcs = [
"include/perfetto/trace_processor/basic_types.h",
@@ -471,25 +537,28 @@ filegroup(
)
# GN target: //include/perfetto/trace_processor:storage
-filegroup(
+perfetto_filegroup(
name = "include_perfetto_trace_processor_storage",
srcs = [
+ "include/perfetto/trace_processor/trace_blob.h",
+ "include/perfetto/trace_processor/trace_blob_view.h",
"include/perfetto/trace_processor/trace_processor_storage.h",
],
)
# GN target: //include/perfetto/trace_processor:trace_processor
-filegroup(
+perfetto_filegroup(
name = "include_perfetto_trace_processor_trace_processor",
srcs = [
"include/perfetto/trace_processor/iterator.h",
"include/perfetto/trace_processor/read_trace.h",
+ "include/perfetto/trace_processor/ref_counted.h",
"include/perfetto/trace_processor/trace_processor.h",
],
)
# GN target: //include/perfetto/tracing/core:core
-filegroup(
+perfetto_filegroup(
name = "include_perfetto_tracing_core_core",
srcs = [
"include/perfetto/tracing/core/chrome_config.h",
@@ -502,7 +571,7 @@ filegroup(
)
# GN target: //include/perfetto/tracing/core:forward_decls
-filegroup(
+perfetto_filegroup(
name = "include_perfetto_tracing_core_forward_decls",
srcs = [
"include/perfetto/tracing/core/forward_decls.h",
@@ -510,7 +579,7 @@ filegroup(
)
# GN target: //include/perfetto/tracing:tracing
-filegroup(
+perfetto_filegroup(
name = "include_perfetto_tracing_tracing",
srcs = [
"include/perfetto/tracing/backend_type.h",
@@ -547,6 +616,7 @@ filegroup(
"include/perfetto/tracing/tracing_policy.h",
"include/perfetto/tracing/track.h",
"include/perfetto/tracing/track_event.h",
+ "include/perfetto/tracing/track_event_args.h",
"include/perfetto/tracing/track_event_category_registry.h",
"include/perfetto/tracing/track_event_interned_data_index.h",
"include/perfetto/tracing/track_event_legacy.h",
@@ -555,7 +625,7 @@ filegroup(
)
# GN target: //src/android_internal:headers
-filegroup(
+perfetto_filegroup(
name = "src_android_internal_headers",
srcs = [
"src/android_internal/atrace_hal.h",
@@ -568,7 +638,7 @@ filegroup(
)
# GN target: //src/android_internal:lazy_library_loader
-filegroup(
+perfetto_filegroup(
name = "src_android_internal_lazy_library_loader",
srcs = [
"src/android_internal/lazy_library_loader.cc",
@@ -577,7 +647,7 @@ filegroup(
)
# GN target: //src/android_stats:android_stats
-filegroup(
+perfetto_filegroup(
name = "src_android_stats_android_stats",
srcs = [
"src/android_stats/statsd_logging_helper.cc",
@@ -586,21 +656,44 @@ filegroup(
)
# GN target: //src/android_stats:perfetto_atoms
-filegroup(
+perfetto_filegroup(
name = "src_android_stats_perfetto_atoms",
srcs = [
"src/android_stats/perfetto_atoms.h",
],
)
+# GN target: //src/base/http:http
+perfetto_cc_library(
+ name = "src_base_http_http",
+ srcs = [
+ "src/base/http/http_server.cc",
+ "src/base/http/sha1.cc",
+ ],
+ hdrs = [
+ ":include_perfetto_base_base",
+ ":include_perfetto_ext_base_base",
+ ":include_perfetto_ext_base_http_http",
+ ],
+ deps = [
+ ":src_base_base",
+ ":src_base_unix_socket",
+ ],
+ linkstatic = True,
+)
+
# GN target: //src/base:base
perfetto_cc_library(
name = "src_base_base",
srcs = [
+ "src/base/android_utils.cc",
+ "src/base/base64.cc",
+ "src/base/crash_keys.cc",
"src/base/ctrl_c_handler.cc",
"src/base/event_fd.cc",
"src/base/file_utils.cc",
"src/base/getopt_compat.cc",
+ "src/base/log_ring_buffer.h",
"src/base/logging.cc",
"src/base/metatrace.cc",
"src/base/paged_memory.cc",
@@ -647,7 +740,7 @@ perfetto_cc_library(
linkstatic = True,
)
-genrule(
+perfetto_genrule(
name = "src_base_version_gen_h",
srcs = [
"CHANGELOG",
@@ -662,7 +755,7 @@ genrule(
)
# GN target: //src/ipc:client
-filegroup(
+perfetto_filegroup(
name = "src_ipc_client",
srcs = [
"src/ipc/client_impl.cc",
@@ -672,7 +765,7 @@ filegroup(
)
# GN target: //src/ipc:common
-filegroup(
+perfetto_filegroup(
name = "src_ipc_common",
srcs = [
"src/ipc/buffered_frame_deserializer.cc",
@@ -683,7 +776,7 @@ filegroup(
)
# GN target: //src/ipc:host
-filegroup(
+perfetto_filegroup(
name = "src_ipc_host",
srcs = [
"src/ipc/host_impl.cc",
@@ -692,7 +785,7 @@ filegroup(
)
# GN target: //src/kallsyms:kallsyms
-filegroup(
+perfetto_filegroup(
name = "src_kallsyms_kallsyms",
srcs = [
"src/kallsyms/kernel_symbol_map.cc",
@@ -705,15 +798,15 @@ filegroup(
perfetto_cc_proto_descriptor(
name = "src_perfetto_cmd_gen_cc_config_descriptor",
deps = [
- ":protos_perfetto_config_perfetto_config_descriptor",
+ ":protos_perfetto_config_descriptor",
],
outs = [
- "src/perfetto_cmd/perfetto_config.descriptor.h",
+ "src/perfetto_cmd/config.descriptor.h",
],
)
# GN target: //src/perfetto_cmd:perfetto_cmd
-filegroup(
+perfetto_filegroup(
name = "src_perfetto_cmd_perfetto_cmd",
srcs = [
"src/perfetto_cmd/config.cc",
@@ -730,7 +823,7 @@ filegroup(
)
# GN target: //src/perfetto_cmd:trigger_producer
-filegroup(
+perfetto_filegroup(
name = "src_perfetto_cmd_trigger_producer",
srcs = [
"src/perfetto_cmd/trigger_producer.cc",
@@ -739,7 +832,7 @@ filegroup(
)
# GN target: //src/profiling/symbolizer:symbolize_database
-filegroup(
+perfetto_filegroup(
name = "src_profiling_symbolizer_symbolize_database",
srcs = [
"src/profiling/symbolizer/symbolize_database.cc",
@@ -748,12 +841,14 @@ filegroup(
)
# GN target: //src/profiling/symbolizer:symbolizer
-filegroup(
+perfetto_filegroup(
name = "src_profiling_symbolizer_symbolizer",
srcs = [
- "src/profiling/symbolizer/filesystem.h",
- "src/profiling/symbolizer/filesystem_posix.cc",
- "src/profiling/symbolizer/filesystem_windows.cc",
+ "src/profiling/symbolizer/breakpad_parser.cc",
+ "src/profiling/symbolizer/breakpad_parser.h",
+ "src/profiling/symbolizer/breakpad_symbolizer.cc",
+ "src/profiling/symbolizer/breakpad_symbolizer.h",
+ "src/profiling/symbolizer/elf.h",
"src/profiling/symbolizer/local_symbolizer.cc",
"src/profiling/symbolizer/local_symbolizer.h",
"src/profiling/symbolizer/scoped_read_mmap.h",
@@ -768,7 +863,7 @@ filegroup(
)
# GN target: //src/profiling:deobfuscator
-filegroup(
+perfetto_filegroup(
name = "src_profiling_deobfuscator",
srcs = [
"src/profiling/deobfuscator.cc",
@@ -777,15 +872,24 @@ filegroup(
)
# GN target: //src/protozero/filtering:bytecode_common
-filegroup(
+perfetto_filegroup(
name = "src_protozero_filtering_bytecode_common",
srcs = [
"src/protozero/filtering/filter_bytecode_common.h",
],
)
+# GN target: //src/protozero/filtering:bytecode_generator
+perfetto_filegroup(
+ name = "src_protozero_filtering_bytecode_generator",
+ srcs = [
+ "src/protozero/filtering/filter_bytecode_generator.cc",
+ "src/protozero/filtering/filter_bytecode_generator.h",
+ ],
+)
+
# GN target: //src/protozero/filtering:bytecode_parser
-filegroup(
+perfetto_filegroup(
name = "src_protozero_filtering_bytecode_parser",
srcs = [
"src/protozero/filtering/filter_bytecode_parser.cc",
@@ -793,8 +897,17 @@ filegroup(
],
)
+# GN target: //src/protozero/filtering:filter_util
+perfetto_filegroup(
+ name = "src_protozero_filtering_filter_util",
+ srcs = [
+ "src/protozero/filtering/filter_util.cc",
+ "src/protozero/filtering/filter_util.h",
+ ],
+)
+
# GN target: //src/protozero/filtering:message_filter
-filegroup(
+perfetto_filegroup(
name = "src_protozero_filtering_message_filter",
srcs = [
"src/protozero/filtering/message_filter.cc",
@@ -803,8 +916,17 @@ filegroup(
],
)
+# GN target: //src/protozero:proto_ring_buffer
+perfetto_filegroup(
+ name = "src_protozero_proto_ring_buffer",
+ srcs = [
+ "src/protozero/proto_ring_buffer.cc",
+ "src/protozero/proto_ring_buffer.h",
+ ],
+)
+
# GN target: //src/trace_processor/analysis:analysis
-filegroup(
+perfetto_filegroup(
name = "src_trace_processor_analysis_analysis",
srcs = [
"src/trace_processor/analysis/describe_slice.cc",
@@ -839,7 +961,7 @@ perfetto_cc_library(
)
# GN target: //src/trace_processor/db:db
-filegroup(
+perfetto_filegroup(
name = "src_trace_processor_db_db",
srcs = [
"src/trace_processor/db/column.cc",
@@ -853,11 +975,13 @@ filegroup(
)
# GN target: //src/trace_processor/importers/common:common
-filegroup(
+perfetto_filegroup(
name = "src_trace_processor_importers_common_common",
srcs = [
"src/trace_processor/importers/common/args_tracker.cc",
"src/trace_processor/importers/common/args_tracker.h",
+ "src/trace_processor/importers/common/args_translation_table.cc",
+ "src/trace_processor/importers/common/args_translation_table.h",
"src/trace_processor/importers/common/chunked_trace_reader.h",
"src/trace_processor/importers/common/clock_tracker.cc",
"src/trace_processor/importers/common/clock_tracker.h",
@@ -871,9 +995,10 @@ filegroup(
"src/trace_processor/importers/common/process_tracker.h",
"src/trace_processor/importers/common/slice_tracker.cc",
"src/trace_processor/importers/common/slice_tracker.h",
+ "src/trace_processor/importers/common/slice_translation_table.cc",
+ "src/trace_processor/importers/common/slice_translation_table.h",
"src/trace_processor/importers/common/system_info_tracker.cc",
"src/trace_processor/importers/common/system_info_tracker.h",
- "src/trace_processor/importers/common/trace_blob_view.h",
"src/trace_processor/importers/common/trace_parser.h",
"src/trace_processor/importers/common/track_tracker.cc",
"src/trace_processor/importers/common/track_tracker.h",
@@ -881,7 +1006,7 @@ filegroup(
)
# GN target: //src/trace_processor/importers/memory_tracker:graph_processor
-filegroup(
+perfetto_filegroup(
name = "src_trace_processor_importers_memory_tracker_graph_processor",
srcs = [
"src/trace_processor/importers/memory_tracker/graph.cc",
@@ -895,7 +1020,7 @@ filegroup(
perfetto_cc_proto_descriptor(
name = "src_trace_processor_importers_gen_cc_chrome_track_event_descriptor",
deps = [
- ":protos_third_party_chromium_chrome_track_event_descriptor",
+ ":protos_third_party_chromium_descriptor",
],
outs = [
"src/trace_processor/importers/chrome_track_event.descriptor.h",
@@ -915,20 +1040,139 @@ perfetto_cc_proto_descriptor(
perfetto_cc_proto_descriptor(
name = "src_trace_processor_importers_gen_cc_track_event_descriptor",
deps = [
- ":protos_perfetto_trace_track_event_track_event_descriptor",
+ ":protos_perfetto_trace_track_event_descriptor",
],
outs = [
"src/trace_processor/importers/track_event.descriptor.h",
],
)
+perfetto_genrule(
+ name = "src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
+ srcs = [
+ "src/trace_processor/metrics/sql/android/android_batt.sql",
+ "src/trace_processor/metrics/sql/android/android_camera.sql",
+ "src/trace_processor/metrics/sql/android/android_camera_unagg.sql",
+ "src/trace_processor/metrics/sql/android/android_cpu.sql",
+ "src/trace_processor/metrics/sql/android/android_cpu_agg.sql",
+ "src/trace_processor/metrics/sql/android/android_cpu_raw_metrics_per_core.sql",
+ "src/trace_processor/metrics/sql/android/android_dma_heap.sql",
+ "src/trace_processor/metrics/sql/android/android_dvfs.sql",
+ "src/trace_processor/metrics/sql/android/android_fastrpc.sql",
+ "src/trace_processor/metrics/sql/android/android_gpu.sql",
+ "src/trace_processor/metrics/sql/android/android_hwcomposer.sql",
+ "src/trace_processor/metrics/sql/android/android_hwui_metric.sql",
+ "src/trace_processor/metrics/sql/android/android_hwui_threads.sql",
+ "src/trace_processor/metrics/sql/android/android_ion.sql",
+ "src/trace_processor/metrics/sql/android/android_irq_runtime.sql",
+ "src/trace_processor/metrics/sql/android/android_jank.sql",
+ "src/trace_processor/metrics/sql/android/android_lmk.sql",
+ "src/trace_processor/metrics/sql/android/android_lmk_reason.sql",
+ "src/trace_processor/metrics/sql/android/android_mem.sql",
+ "src/trace_processor/metrics/sql/android/android_mem_unagg.sql",
+ "src/trace_processor/metrics/sql/android/android_multiuser.sql",
+ "src/trace_processor/metrics/sql/android/android_multiuser_populator.sql",
+ "src/trace_processor/metrics/sql/android/android_netperf.sql",
+ "src/trace_processor/metrics/sql/android/android_other_traces.sql",
+ "src/trace_processor/metrics/sql/android/android_package_list.sql",
+ "src/trace_processor/metrics/sql/android/android_powrails.sql",
+ "src/trace_processor/metrics/sql/android/android_proxy_power.sql",
+ "src/trace_processor/metrics/sql/android/android_rt_runtime.sql",
+ "src/trace_processor/metrics/sql/android/android_simpleperf.sql",
+ "src/trace_processor/metrics/sql/android/android_startup.sql",
+ "src/trace_processor/metrics/sql/android/android_surfaceflinger.sql",
+ "src/trace_processor/metrics/sql/android/android_sysui_cuj.sql",
+ "src/trace_processor/metrics/sql/android/android_sysui_cuj_jank_query.sql",
+ "src/trace_processor/metrics/sql/android/android_sysui_cuj_surfaceflinger.sql",
+ "src/trace_processor/metrics/sql/android/android_task_names.sql",
+ "src/trace_processor/metrics/sql/android/android_thread_time_in_state.sql",
+ "src/trace_processor/metrics/sql/android/android_trace_quality.sql",
+ "src/trace_processor/metrics/sql/android/android_trusty_workqueues.sql",
+ "src/trace_processor/metrics/sql/android/composer_execution.sql",
+ "src/trace_processor/metrics/sql/android/composition_layers.sql",
+ "src/trace_processor/metrics/sql/android/cpu_info.sql",
+ "src/trace_processor/metrics/sql/android/display_metrics.sql",
+ "src/trace_processor/metrics/sql/android/frame_missed.sql",
+ "src/trace_processor/metrics/sql/android/g2d.sql",
+ "src/trace_processor/metrics/sql/android/g2d_duration.sql",
+ "src/trace_processor/metrics/sql/android/global_counter_span_view.sql",
+ "src/trace_processor/metrics/sql/android/gpu_counter_span_view.sql",
+ "src/trace_processor/metrics/sql/android/java_heap_histogram.sql",
+ "src/trace_processor/metrics/sql/android/java_heap_stats.sql",
+ "src/trace_processor/metrics/sql/android/mem_stats_priority_breakdown.sql",
+ "src/trace_processor/metrics/sql/android/power_drain_in_watts.sql",
+ "src/trace_processor/metrics/sql/android/power_profile_data.sql",
+ "src/trace_processor/metrics/sql/android/process_counter_span_view.sql",
+ "src/trace_processor/metrics/sql/android/process_mem.sql",
+ "src/trace_processor/metrics/sql/android/process_metadata.sql",
+ "src/trace_processor/metrics/sql/android/process_oom_score.sql",
+ "src/trace_processor/metrics/sql/android/process_unagg_mem_view.sql",
+ "src/trace_processor/metrics/sql/android/profiler_smaps.sql",
+ "src/trace_processor/metrics/sql/android/span_view_stats.sql",
+ "src/trace_processor/metrics/sql/android/startup/hsc.sql",
+ "src/trace_processor/metrics/sql/android/startup/launches.sql",
+ "src/trace_processor/metrics/sql/android/startup/launches_maxsdk28.sql",
+ "src/trace_processor/metrics/sql/android/startup/launches_minsdk29.sql",
+ "src/trace_processor/metrics/sql/android/startup/launches_minsdk33.sql",
+ "src/trace_processor/metrics/sql/android/thread_counter_span_view.sql",
+ "src/trace_processor/metrics/sql/android/unsymbolized_frames.sql",
+ "src/trace_processor/metrics/sql/chrome/actual_power_by_category.sql",
+ "src/trace_processor/metrics/sql/chrome/actual_power_by_rail_mode.sql",
+ "src/trace_processor/metrics/sql/chrome/chrome_event_metadata.sql",
+ "src/trace_processor/metrics/sql/chrome/chrome_histogram_hashes.sql",
+ "src/trace_processor/metrics/sql/chrome/chrome_performance_mark_hashes.sql",
+ "src/trace_processor/metrics/sql/chrome/chrome_processes.sql",
+ "src/trace_processor/metrics/sql/chrome/chrome_slice_names.sql",
+ "src/trace_processor/metrics/sql/chrome/chrome_thread_slice.sql",
+ "src/trace_processor/metrics/sql/chrome/chrome_user_event_hashes.sql",
+ "src/trace_processor/metrics/sql/chrome/cpu_time_by_category.sql",
+ "src/trace_processor/metrics/sql/chrome/cpu_time_by_rail_mode.sql",
+ "src/trace_processor/metrics/sql/chrome/estimated_power_by_category.sql",
+ "src/trace_processor/metrics/sql/chrome/estimated_power_by_rail_mode.sql",
+ "src/trace_processor/metrics/sql/chrome/gesture_flow_event.sql",
+ "src/trace_processor/metrics/sql/chrome/gesture_flow_event_queuing_delay.sql",
+ "src/trace_processor/metrics/sql/chrome/gesture_jank.sql",
+ "src/trace_processor/metrics/sql/chrome/jank_utilities.sql",
+ "src/trace_processor/metrics/sql/chrome/rail_modes.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_flow_event.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_flow_event_queuing_delay.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank_cause.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_task.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_touch_move.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_get_bitmap.sql",
+ "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_queuing_delay.sql",
+ "src/trace_processor/metrics/sql/chrome/sufficient_chrome_processes.sql",
+ "src/trace_processor/metrics/sql/chrome/test_chrome_metric.sql",
+ "src/trace_processor/metrics/sql/chrome/touch_flow_event.sql",
+ "src/trace_processor/metrics/sql/chrome/touch_flow_event_queuing_delay.sql",
+ "src/trace_processor/metrics/sql/chrome/touch_jank.sql",
+ "src/trace_processor/metrics/sql/experimental/blink_gc_metric.sql",
+ "src/trace_processor/metrics/sql/experimental/chrome_dropped_frames.sql",
+ "src/trace_processor/metrics/sql/experimental/chrome_long_latency.sql",
+ "src/trace_processor/metrics/sql/experimental/frame_times.sql",
+ "src/trace_processor/metrics/sql/experimental/media_metric.sql",
+ "src/trace_processor/metrics/sql/experimental/reported_by_page.sql",
+ "src/trace_processor/metrics/sql/trace_metadata.sql",
+ "src/trace_processor/metrics/sql/trace_stats.sql",
+ "src/trace_processor/metrics/sql/webview/webview_power_usage.sql",
+ ],
+ outs = [
+ "src/trace_processor/metrics/sql/amalgamated_sql_metrics.h",
+ ],
+ cmd = "$(location gen_amalgamated_sql_metrics_py) --cpp_out=$@ $(SRCS)",
+ exec_tools = [
+ ":gen_amalgamated_sql_metrics_py",
+ ],
+)
+
perfetto_cc_proto_descriptor(
name = "src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
deps = [
":protos_perfetto_metrics_chrome_descriptor",
],
outs = [
- "src/trace_processor/metrics/chrome/all_chrome_metrics.descriptor.h",
+ "src/trace_processor/metrics/all_chrome_metrics.descriptor.h",
],
)
@@ -942,94 +1186,9 @@ perfetto_cc_proto_descriptor(
],
)
-genrule(
- name = "src_trace_processor_metrics_gen_merged_sql_metrics",
- srcs = [
- "src/trace_processor/metrics/android/android_batt.sql",
- "src/trace_processor/metrics/android/android_cpu.sql",
- "src/trace_processor/metrics/android/android_cpu_agg.sql",
- "src/trace_processor/metrics/android/android_cpu_raw_metrics_per_core.sql",
- "src/trace_processor/metrics/android/android_dma_heap.sql",
- "src/trace_processor/metrics/android/android_fastrpc.sql",
- "src/trace_processor/metrics/android/android_gpu.sql",
- "src/trace_processor/metrics/android/android_hwcomposer.sql",
- "src/trace_processor/metrics/android/android_hwui_metric.sql",
- "src/trace_processor/metrics/android/android_hwui_threads.sql",
- "src/trace_processor/metrics/android/android_ion.sql",
- "src/trace_processor/metrics/android/android_jank.sql",
- "src/trace_processor/metrics/android/android_lmk.sql",
- "src/trace_processor/metrics/android/android_lmk_reason.sql",
- "src/trace_processor/metrics/android/android_mem.sql",
- "src/trace_processor/metrics/android/android_mem_unagg.sql",
- "src/trace_processor/metrics/android/android_package_list.sql",
- "src/trace_processor/metrics/android/android_powrails.sql",
- "src/trace_processor/metrics/android/android_proxy_power.sql",
- "src/trace_processor/metrics/android/android_startup.sql",
- "src/trace_processor/metrics/android/android_startup_launches.sql",
- "src/trace_processor/metrics/android/android_surfaceflinger.sql",
- "src/trace_processor/metrics/android/android_sysui_cuj.sql",
- "src/trace_processor/metrics/android/android_task_names.sql",
- "src/trace_processor/metrics/android/android_thread_time_in_state.sql",
- "src/trace_processor/metrics/android/composer_execution.sql",
- "src/trace_processor/metrics/android/composition_layers.sql",
- "src/trace_processor/metrics/android/cpu_info.sql",
- "src/trace_processor/metrics/android/display_metrics.sql",
- "src/trace_processor/metrics/android/frame_missed.sql",
- "src/trace_processor/metrics/android/g2d.sql",
- "src/trace_processor/metrics/android/g2d_duration.sql",
- "src/trace_processor/metrics/android/global_counter_span_view.sql",
- "src/trace_processor/metrics/android/hsc_startups.sql",
- "src/trace_processor/metrics/android/java_heap_histogram.sql",
- "src/trace_processor/metrics/android/java_heap_stats.sql",
- "src/trace_processor/metrics/android/mem_stats_priority_breakdown.sql",
- "src/trace_processor/metrics/android/power_drain_in_watts.sql",
- "src/trace_processor/metrics/android/power_profile_data.sql",
- "src/trace_processor/metrics/android/process_counter_span_view.sql",
- "src/trace_processor/metrics/android/process_mem.sql",
- "src/trace_processor/metrics/android/process_metadata.sql",
- "src/trace_processor/metrics/android/process_oom_score.sql",
- "src/trace_processor/metrics/android/process_unagg_mem_view.sql",
- "src/trace_processor/metrics/android/span_view_stats.sql",
- "src/trace_processor/metrics/android/unsymbolized_frames.sql",
- "src/trace_processor/metrics/chrome/actual_power_by_category.sql",
- "src/trace_processor/metrics/chrome/actual_power_by_rail_mode.sql",
- "src/trace_processor/metrics/chrome/chrome_event_metadata.sql",
- "src/trace_processor/metrics/chrome/chrome_processes.sql",
- "src/trace_processor/metrics/chrome/chrome_thread_slice_with_cpu_time.sql",
- "src/trace_processor/metrics/chrome/cpu_time_by_category.sql",
- "src/trace_processor/metrics/chrome/cpu_time_by_rail_mode.sql",
- "src/trace_processor/metrics/chrome/estimated_power_by_category.sql",
- "src/trace_processor/metrics/chrome/estimated_power_by_rail_mode.sql",
- "src/trace_processor/metrics/chrome/rail_modes.sql",
- "src/trace_processor/metrics/chrome/scroll_flow_event.sql",
- "src/trace_processor/metrics/chrome/scroll_flow_event_queuing_delay.sql",
- "src/trace_processor/metrics/chrome/scroll_jank.sql",
- "src/trace_processor/metrics/chrome/scroll_jank_cause.sql",
- "src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_task.sql",
- "src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_touch_move.sql",
- "src/trace_processor/metrics/chrome/scroll_jank_cause_get_bitmap.sql",
- "src/trace_processor/metrics/chrome/scroll_jank_cause_queuing_delay.sql",
- "src/trace_processor/metrics/chrome/test_chrome_metric.sql",
- "src/trace_processor/metrics/experimental/blink_gc_metric.sql",
- "src/trace_processor/metrics/experimental/frame_times.sql",
- "src/trace_processor/metrics/experimental/media_metric.sql",
- "src/trace_processor/metrics/experimental/reported_by_page.sql",
- "src/trace_processor/metrics/trace_metadata.sql",
- "src/trace_processor/metrics/trace_stats.sql",
- "src/trace_processor/metrics/webview/webview_power_usage.sql",
- ],
- outs = [
- "src/trace_processor/metrics/sql_metrics.h",
- ],
- cmd = "$(location gen_merged_sql_metrics_py) --cpp_out=$@ $(SRCS)",
- exec_tools = [
- ":gen_merged_sql_metrics_py",
- ],
-)
-
-# GN target: //src/trace_processor/metrics:lib
-filegroup(
- name = "src_trace_processor_metrics_lib",
+# GN target: //src/trace_processor/metrics:metrics
+perfetto_filegroup(
+ name = "src_trace_processor_metrics_metrics",
srcs = [
"src/trace_processor/metrics/metrics.cc",
"src/trace_processor/metrics/metrics.h",
@@ -1037,7 +1196,7 @@ filegroup(
)
# GN target: //src/trace_processor/rpc:httpd
-filegroup(
+perfetto_filegroup(
name = "src_trace_processor_rpc_httpd",
srcs = [
"src/trace_processor/rpc/httpd.cc",
@@ -1046,11 +1205,9 @@ filegroup(
)
# GN target: //src/trace_processor/rpc:rpc
-filegroup(
+perfetto_filegroup(
name = "src_trace_processor_rpc_rpc",
srcs = [
- "src/trace_processor/rpc/proto_ring_buffer.cc",
- "src/trace_processor/rpc/proto_ring_buffer.h",
"src/trace_processor/rpc/query_result_serializer.cc",
"src/trace_processor/rpc/query_result_serializer.h",
"src/trace_processor/rpc/rpc.cc",
@@ -1059,14 +1216,22 @@ filegroup(
)
# GN target: //src/trace_processor/sqlite:sqlite
-filegroup(
+perfetto_filegroup(
name = "src_trace_processor_sqlite_sqlite",
srcs = [
+ "src/trace_processor/sqlite/create_function.cc",
+ "src/trace_processor/sqlite/create_function.h",
+ "src/trace_processor/sqlite/create_function_internal.cc",
+ "src/trace_processor/sqlite/create_function_internal.h",
+ "src/trace_processor/sqlite/create_view_function.cc",
+ "src/trace_processor/sqlite/create_view_function.h",
"src/trace_processor/sqlite/db_sqlite_table.cc",
"src/trace_processor/sqlite/db_sqlite_table.h",
"src/trace_processor/sqlite/query_cache.h",
"src/trace_processor/sqlite/query_constraints.cc",
"src/trace_processor/sqlite/query_constraints.h",
+ "src/trace_processor/sqlite/register_function.cc",
+ "src/trace_processor/sqlite/register_function.h",
"src/trace_processor/sqlite/scoped_db.h",
"src/trace_processor/sqlite/span_join_operator_table.cc",
"src/trace_processor/sqlite/span_join_operator_table.h",
@@ -1087,7 +1252,7 @@ filegroup(
)
# GN target: //src/trace_processor/storage:storage
-filegroup(
+perfetto_filegroup(
name = "src_trace_processor_storage_storage",
srcs = [
"src/trace_processor/storage/metadata.h",
@@ -1098,7 +1263,7 @@ filegroup(
)
# GN target: //src/trace_processor/tables:tables
-filegroup(
+perfetto_filegroup(
name = "src_trace_processor_tables_tables",
srcs = [
"src/trace_processor/tables/android_tables.h",
@@ -1116,7 +1281,7 @@ filegroup(
)
# GN target: //src/trace_processor/types:types
-filegroup(
+perfetto_filegroup(
name = "src_trace_processor_types_types",
srcs = [
"src/trace_processor/types/destructible.cc",
@@ -1126,6 +1291,7 @@ filegroup(
"src/trace_processor/types/softirq_action.h",
"src/trace_processor/types/task_state.cc",
"src/trace_processor/types/task_state.h",
+ "src/trace_processor/types/tcp_state.h",
"src/trace_processor/types/trace_processor_context.h",
"src/trace_processor/types/variadic.cc",
"src/trace_processor/types/variadic.h",
@@ -1134,7 +1300,7 @@ filegroup(
)
# GN target: //src/trace_processor/util:descriptors
-filegroup(
+perfetto_filegroup(
name = "src_trace_processor_util_descriptors",
srcs = [
"src/trace_processor/util/descriptors.cc",
@@ -1142,17 +1308,36 @@ filegroup(
],
)
+# GN target: //src/trace_processor/util:gzip
+perfetto_filegroup(
+ name = "src_trace_processor_util_gzip",
+ srcs = [
+ "src/trace_processor/util/gzip_utils.cc",
+ "src/trace_processor/util/gzip_utils.h",
+ ],
+)
+
+# GN target: //src/trace_processor/util:interned_message_view
+perfetto_filegroup(
+ name = "src_trace_processor_util_interned_message_view",
+ srcs = [
+ "src/trace_processor/util/interned_message_view.h",
+ ],
+)
+
# GN target: //src/trace_processor/util:proto_to_args_parser
-filegroup(
+perfetto_filegroup(
name = "src_trace_processor_util_proto_to_args_parser",
srcs = [
+ "src/trace_processor/util/debug_annotation_parser.cc",
+ "src/trace_processor/util/debug_annotation_parser.h",
"src/trace_processor/util/proto_to_args_parser.cc",
"src/trace_processor/util/proto_to_args_parser.h",
],
)
# GN target: //src/trace_processor/util:protozero_to_text
-filegroup(
+perfetto_filegroup(
name = "src_trace_processor_util_protozero_to_text",
srcs = [
"src/trace_processor/util/protozero_to_text.cc",
@@ -1161,15 +1346,31 @@ filegroup(
)
# GN target: //src/trace_processor/util:util
-filegroup(
+perfetto_filegroup(
name = "src_trace_processor_util_util",
srcs = [
"src/trace_processor/util/status_macros.h",
],
)
+# GN target: //src/trace_processor:demangle
+perfetto_cc_library(
+ name = "src_trace_processor_demangle",
+ srcs = [
+ "src/trace_processor/demangle.cc",
+ ],
+ hdrs = [
+ ":include_perfetto_base_base",
+ ":include_perfetto_ext_base_base",
+ ":include_perfetto_ext_trace_processor_demangle",
+ ],
+ deps = [
+ ] + PERFETTO_CONFIG.deps.llvm_demangle,
+ linkstatic = True,
+)
+
# GN target: //src/trace_processor:export_json
-filegroup(
+perfetto_filegroup(
name = "src_trace_processor_export_json",
srcs = [
"src/trace_processor/export_json.cc",
@@ -1178,7 +1379,7 @@ filegroup(
)
# GN target: //src/trace_processor:ftrace_descriptors
-filegroup(
+perfetto_filegroup(
name = "src_trace_processor_ftrace_descriptors",
srcs = [
"src/trace_processor/importers/ftrace/ftrace_descriptors.cc",
@@ -1187,15 +1388,15 @@ filegroup(
)
# GN target: //src/trace_processor:lib
-filegroup(
+perfetto_filegroup(
name = "src_trace_processor_lib",
srcs = [
"src/trace_processor/dynamic/ancestor_generator.cc",
"src/trace_processor/dynamic/ancestor_generator.h",
"src/trace_processor/dynamic/connected_flow_generator.cc",
"src/trace_processor/dynamic/connected_flow_generator.h",
- "src/trace_processor/dynamic/descendant_slice_generator.cc",
- "src/trace_processor/dynamic/descendant_slice_generator.h",
+ "src/trace_processor/dynamic/descendant_generator.cc",
+ "src/trace_processor/dynamic/descendant_generator.h",
"src/trace_processor/dynamic/describe_slice_generator.cc",
"src/trace_processor/dynamic/describe_slice_generator.h",
"src/trace_processor/dynamic/experimental_annotated_stack_generator.cc",
@@ -1204,6 +1405,8 @@ filegroup(
"src/trace_processor/dynamic/experimental_counter_dur_generator.h",
"src/trace_processor/dynamic/experimental_flamegraph_generator.cc",
"src/trace_processor/dynamic/experimental_flamegraph_generator.h",
+ "src/trace_processor/dynamic/experimental_flat_slice_generator.cc",
+ "src/trace_processor/dynamic/experimental_flat_slice_generator.h",
"src/trace_processor/dynamic/experimental_sched_upid_generator.cc",
"src/trace_processor/dynamic/experimental_sched_upid_generator.h",
"src/trace_processor/dynamic/experimental_slice_layout_generator.cc",
@@ -1220,7 +1423,7 @@ filegroup(
)
# GN target: //src/trace_processor:metatrace
-filegroup(
+perfetto_filegroup(
name = "src_trace_processor_metatrace",
srcs = [
"src/trace_processor/tp_metatrace.cc",
@@ -1229,7 +1432,7 @@ filegroup(
)
# GN target: //src/trace_processor:storage_full
-filegroup(
+perfetto_filegroup(
name = "src_trace_processor_storage_full",
srcs = [
"src/trace_processor/importers/additional_modules.cc",
@@ -1258,8 +1461,6 @@ filegroup(
"src/trace_processor/importers/json/json_trace_parser.h",
"src/trace_processor/importers/json/json_trace_tokenizer.cc",
"src/trace_processor/importers/json/json_trace_tokenizer.h",
- "src/trace_processor/importers/json/json_tracker.cc",
- "src/trace_processor/importers/json/json_tracker.h",
"src/trace_processor/importers/proto/android_probes_module.cc",
"src/trace_processor/importers/proto/android_probes_module.h",
"src/trace_processor/importers/proto/android_probes_parser.cc",
@@ -1302,7 +1503,7 @@ filegroup(
)
# GN target: //src/trace_processor:storage_minimal
-filegroup(
+perfetto_filegroup(
name = "src_trace_processor_storage_minimal",
srcs = [
"src/trace_processor/forwarding_trace_parser.cc",
@@ -1313,12 +1514,12 @@ filegroup(
"src/trace_processor/importers/ftrace/ftrace_module.h",
"src/trace_processor/importers/fuchsia/fuchsia_record.h",
"src/trace_processor/importers/fuchsia/fuchsia_trace_utils.h",
- "src/trace_processor/importers/gzip/gzip_utils.cc",
- "src/trace_processor/importers/gzip/gzip_utils.h",
"src/trace_processor/importers/json/json_utils.cc",
"src/trace_processor/importers/json/json_utils.h",
"src/trace_processor/importers/ninja/ninja_log_parser.cc",
"src/trace_processor/importers/ninja/ninja_log_parser.h",
+ "src/trace_processor/importers/proto/android_camera_event_module.cc",
+ "src/trace_processor/importers/proto/android_camera_event_module.h",
"src/trace_processor/importers/proto/async_track_set_tracker.cc",
"src/trace_processor/importers/proto/async_track_set_tracker.h",
"src/trace_processor/importers/proto/chrome_string_lookup.cc",
@@ -1327,6 +1528,8 @@ filegroup(
"src/trace_processor/importers/proto/chrome_system_probes_module.h",
"src/trace_processor/importers/proto/chrome_system_probes_parser.cc",
"src/trace_processor/importers/proto/chrome_system_probes_parser.h",
+ "src/trace_processor/importers/proto/flamegraph_construction_algorithms.cc",
+ "src/trace_processor/importers/proto/flamegraph_construction_algorithms.h",
"src/trace_processor/importers/proto/heap_profile_tracker.cc",
"src/trace_processor/importers/proto/heap_profile_tracker.h",
"src/trace_processor/importers/proto/memory_tracker_snapshot_module.cc",
@@ -1366,9 +1569,12 @@ filegroup(
"src/trace_processor/importers/proto/track_event_tokenizer.h",
"src/trace_processor/importers/proto/track_event_tracker.cc",
"src/trace_processor/importers/proto/track_event_tracker.h",
+ "src/trace_processor/importers/proto/translation_table_module.cc",
+ "src/trace_processor/importers/proto/translation_table_module.h",
"src/trace_processor/importers/syscalls/syscall_tracker.h",
"src/trace_processor/importers/systrace/systrace_line.h",
"src/trace_processor/timestamped_trace_piece.h",
+ "src/trace_processor/trace_blob.cc",
"src/trace_processor/trace_processor_context.cc",
"src/trace_processor/trace_processor_storage.cc",
"src/trace_processor/trace_processor_storage_impl.cc",
@@ -1380,7 +1586,7 @@ filegroup(
)
# GN target: //src/traced/probes/android_log:android_log
-filegroup(
+perfetto_filegroup(
name = "src_traced_probes_android_log_android_log",
srcs = [
"src/traced/probes/android_log/android_log_data_source.cc",
@@ -1389,7 +1595,7 @@ filegroup(
)
# GN target: //src/traced/probes/common:common
-filegroup(
+perfetto_filegroup(
name = "src_traced_probes_common_common",
srcs = [
"src/traced/probes/common/cpu_freq_info.cc",
@@ -1398,7 +1604,7 @@ filegroup(
)
# GN target: //src/traced/probes/filesystem:filesystem
-filegroup(
+perfetto_filegroup(
name = "src_traced_probes_filesystem_filesystem",
srcs = [
"src/traced/probes/filesystem/file_scanner.cc",
@@ -1417,7 +1623,7 @@ filegroup(
)
# GN target: //src/traced/probes/ftrace/format_parser:format_parser
-filegroup(
+perfetto_filegroup(
name = "src_traced_probes_ftrace_format_parser_format_parser",
srcs = [
"src/traced/probes/ftrace/format_parser/format_parser.cc",
@@ -1426,7 +1632,7 @@ filegroup(
)
# GN target: //src/traced/probes/ftrace:ftrace
-filegroup(
+perfetto_filegroup(
name = "src_traced_probes_ftrace_ftrace",
srcs = [
"src/traced/probes/ftrace/atrace_hal_wrapper.cc",
@@ -1464,7 +1670,7 @@ filegroup(
)
# GN target: //src/traced/probes/ftrace:ftrace_procfs
-filegroup(
+perfetto_filegroup(
name = "src_traced_probes_ftrace_ftrace_procfs",
srcs = [
"src/traced/probes/ftrace/ftrace_procfs.cc",
@@ -1473,7 +1679,7 @@ filegroup(
)
# GN target: //src/traced/probes/initial_display_state:initial_display_state
-filegroup(
+perfetto_filegroup(
name = "src_traced_probes_initial_display_state_initial_display_state",
srcs = [
"src/traced/probes/initial_display_state/initial_display_state_data_source.cc",
@@ -1482,7 +1688,7 @@ filegroup(
)
# GN target: //src/traced/probes/metatrace:metatrace
-filegroup(
+perfetto_filegroup(
name = "src_traced_probes_metatrace_metatrace",
srcs = [
"src/traced/probes/metatrace/metatrace_data_source.cc",
@@ -1491,7 +1697,7 @@ filegroup(
)
# GN target: //src/traced/probes/packages_list:packages_list
-filegroup(
+perfetto_filegroup(
name = "src_traced_probes_packages_list_packages_list",
srcs = [
"src/traced/probes/packages_list/packages_list_data_source.cc",
@@ -1500,7 +1706,7 @@ filegroup(
)
# GN target: //src/traced/probes/packages_list:packages_list_parser
-filegroup(
+perfetto_filegroup(
name = "src_traced_probes_packages_list_packages_list_parser",
srcs = [
"src/traced/probes/packages_list/packages_list_parser.cc",
@@ -1509,16 +1715,18 @@ filegroup(
)
# GN target: //src/traced/probes/power:power
-filegroup(
+perfetto_filegroup(
name = "src_traced_probes_power_power",
srcs = [
"src/traced/probes/power/android_power_data_source.cc",
"src/traced/probes/power/android_power_data_source.h",
+ "src/traced/probes/power/linux_power_sysfs_data_source.cc",
+ "src/traced/probes/power/linux_power_sysfs_data_source.h",
],
)
# GN target: //src/traced/probes/ps:ps
-filegroup(
+perfetto_filegroup(
name = "src_traced_probes_ps_ps",
srcs = [
"src/traced/probes/ps/process_stats_data_source.cc",
@@ -1527,7 +1735,7 @@ filegroup(
)
# GN target: //src/traced/probes/sys_stats:sys_stats
-filegroup(
+perfetto_filegroup(
name = "src_traced_probes_sys_stats_sys_stats",
srcs = [
"src/traced/probes/sys_stats/sys_stats_data_source.cc",
@@ -1536,7 +1744,7 @@ filegroup(
)
# GN target: //src/traced/probes/system_info:system_info
-filegroup(
+perfetto_filegroup(
name = "src_traced_probes_system_info_system_info",
srcs = [
"src/traced/probes/system_info/system_info_data_source.cc",
@@ -1545,7 +1753,7 @@ filegroup(
)
# GN target: //src/traced/probes:data_source
-filegroup(
+perfetto_filegroup(
name = "src_traced_probes_data_source",
srcs = [
"src/traced/probes/probes_data_source.cc",
@@ -1554,7 +1762,7 @@ filegroup(
)
# GN target: //src/traced/probes:probes
-filegroup(
+perfetto_filegroup(
name = "src_traced_probes_probes",
srcs = [
"src/traced/probes/probes.cc",
@@ -1562,7 +1770,7 @@ filegroup(
)
# GN target: //src/traced/probes:probes_src
-filegroup(
+perfetto_filegroup(
name = "src_traced_probes_probes_src",
srcs = [
"src/traced/probes/kmem_activity_trigger.cc",
@@ -1573,7 +1781,7 @@ filegroup(
)
# GN target: //src/traced/service:service
-filegroup(
+perfetto_filegroup(
name = "src_traced_service_service",
srcs = [
"src/traced/service/builtin_producer.cc",
@@ -1583,7 +1791,7 @@ filegroup(
)
# GN target: //src/tracing/consumer_api_deprecated:consumer_api_deprecated
-filegroup(
+perfetto_filegroup(
name = "src_tracing_consumer_api_deprecated_consumer_api_deprecated",
srcs = [
"src/tracing/consumer_api_deprecated/consumer_api_deprecated.cc",
@@ -1591,7 +1799,7 @@ filegroup(
)
# GN target: //src/tracing/core:core
-filegroup(
+perfetto_filegroup(
name = "src_tracing_core_core",
srcs = [
"src/tracing/core/id_allocator.cc",
@@ -1610,7 +1818,7 @@ filegroup(
)
# GN target: //src/tracing/core:service
-filegroup(
+perfetto_filegroup(
name = "src_tracing_core_service",
srcs = [
"src/tracing/core/metatrace_writer.cc",
@@ -1625,7 +1833,7 @@ filegroup(
)
# GN target: //src/tracing/ipc/consumer:consumer
-filegroup(
+perfetto_filegroup(
name = "src_tracing_ipc_consumer_consumer",
srcs = [
"src/tracing/ipc/consumer/consumer_ipc_client_impl.cc",
@@ -1634,7 +1842,7 @@ filegroup(
)
# GN target: //src/tracing/ipc/producer:producer
-filegroup(
+perfetto_filegroup(
name = "src_tracing_ipc_producer_producer",
srcs = [
"src/tracing/ipc/producer/producer_ipc_client_impl.cc",
@@ -1643,7 +1851,7 @@ filegroup(
)
# GN target: //src/tracing/ipc/service:service
-filegroup(
+perfetto_filegroup(
name = "src_tracing_ipc_service_service",
srcs = [
"src/tracing/ipc/service/consumer_ipc_service.cc",
@@ -1656,19 +1864,28 @@ filegroup(
)
# GN target: //src/tracing/ipc:common
-filegroup(
+perfetto_filegroup(
name = "src_tracing_ipc_common",
srcs = [
- "src/tracing/ipc/default_socket.cc",
"src/tracing/ipc/memfd.cc",
"src/tracing/ipc/memfd.h",
"src/tracing/ipc/posix_shared_memory.cc",
"src/tracing/ipc/posix_shared_memory.h",
+ "src/tracing/ipc/shared_memory_windows.cc",
+ "src/tracing/ipc/shared_memory_windows.h",
+ ],
+)
+
+# GN target: //src/tracing/ipc:default_socket
+perfetto_filegroup(
+ name = "src_tracing_ipc_default_socket",
+ srcs = [
+ "src/tracing/ipc/default_socket.cc",
],
)
# GN target: //src/tracing:client_api_without_backends
-filegroup(
+perfetto_filegroup(
name = "src_tracing_client_api_without_backends",
srcs = [
"src/tracing/console_interceptor.cc",
@@ -1698,7 +1915,7 @@ filegroup(
)
# GN target: //src/tracing:common
-filegroup(
+perfetto_filegroup(
name = "src_tracing_common",
srcs = [
"src/tracing/trace_writer_base.cc",
@@ -1706,7 +1923,7 @@ filegroup(
)
# GN target: //src/tracing:in_process_backend
-filegroup(
+perfetto_filegroup(
name = "src_tracing_in_process_backend",
srcs = [
"src/tracing/internal/in_process_tracing_backend.cc",
@@ -1714,28 +1931,38 @@ filegroup(
)
# GN target: //src/tracing:platform_impl
-filegroup(
+perfetto_filegroup(
name = "src_tracing_platform_impl",
srcs = [
"src/tracing/platform_posix.cc",
+ "src/tracing/platform_windows.cc",
],
)
# GN target: //src/tracing:system_backend
-filegroup(
+perfetto_filegroup(
name = "src_tracing_system_backend",
srcs = [
"src/tracing/internal/system_tracing_backend.cc",
],
)
-# GN target: //tools/trace_to_text:common
-filegroup(
- name = "tools_trace_to_text_common",
+perfetto_cc_proto_descriptor(
+ name = "tools_trace_to_text_gen_cc_trace_descriptor",
+ deps = [
+ ":protos_perfetto_trace_descriptor",
+ ],
+ outs = [
+ "tools/trace_to_text/trace.descriptor.h",
+ ],
+)
+
+# GN target: //tools/trace_to_text:lib
+perfetto_filegroup(
+ name = "tools_trace_to_text_lib",
srcs = [
"tools/trace_to_text/deobfuscate_profile.cc",
"tools/trace_to_text/deobfuscate_profile.h",
- "tools/trace_to_text/main.cc",
"tools/trace_to_text/symbolize_profile.cc",
"tools/trace_to_text/symbolize_profile.h",
"tools/trace_to_text/trace_to_hprof.cc",
@@ -1746,22 +1973,21 @@ filegroup(
"tools/trace_to_text/trace_to_profile.h",
"tools/trace_to_text/trace_to_systrace.cc",
"tools/trace_to_text/trace_to_systrace.h",
+ "tools/trace_to_text/trace_to_text.cc",
"tools/trace_to_text/trace_to_text.h",
],
)
-# GN target: //tools/trace_to_text:full
-filegroup(
- name = "tools_trace_to_text_full",
+# GN target: //tools/trace_to_text:main
+perfetto_filegroup(
+ name = "tools_trace_to_text_main",
srcs = [
- "tools/trace_to_text/proto_full_utils.cc",
- "tools/trace_to_text/proto_full_utils.h",
- "tools/trace_to_text/trace_to_text.cc",
+ "tools/trace_to_text/main.cc",
],
)
# GN target: //tools/trace_to_text:pprofbuilder
-filegroup(
+perfetto_filegroup(
name = "tools_trace_to_text_pprofbuilder",
srcs = [
"tools/trace_to_text/pprof_builder.cc",
@@ -1769,7 +1995,7 @@ filegroup(
)
# GN target: //tools/trace_to_text:utils
-filegroup(
+perfetto_filegroup(
name = "tools_trace_to_text_utils",
srcs = [
"tools/trace_to_text/utils.cc",
@@ -1781,23 +2007,283 @@ filegroup(
# Proto libraries
# ##############################################################################
-# GN target: //protos/perfetto/common:cpp
-perfetto_cc_protocpp_library(
- name = "protos_perfetto_common_cpp",
+# GN target: [//protos/perfetto/config:source_set]
+perfetto_proto_library(
+ name = "config_proto",
+ visibility = PERFETTO_CONFIG.public_visibility,
deps = [
":protos_perfetto_common_protos",
+ ":protos_perfetto_config_android_protos",
+ ":protos_perfetto_config_ftrace_protos",
+ ":protos_perfetto_config_gpu_protos",
+ ":protos_perfetto_config_inode_file_protos",
+ ":protos_perfetto_config_interceptors_protos",
+ ":protos_perfetto_config_power_protos",
+ ":protos_perfetto_config_process_stats_protos",
+ ":protos_perfetto_config_profiling_protos",
+ ":protos_perfetto_config_protos",
+ ":protos_perfetto_config_sys_stats_protos",
+ ":protos_perfetto_config_track_event_protos",
],
)
-# GN target: //protos/perfetto/common:lite
+# GN target: [//protos/perfetto/config:source_set]
perfetto_cc_proto_library(
- name = "protos_perfetto_common_lite",
+ name = "config_cc_proto",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":config_proto",
+ ],
+)
+
+# GN target: [//protos/perfetto/config:source_set]
+perfetto_java_proto_library(
+ name = "config_java_proto",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":config_proto",
+ ],
+)
+
+# GN target: [//protos/perfetto/config:source_set]
+perfetto_java_lite_proto_library(
+ name = "config_java_proto_lite",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":config_proto",
+ ],
+)
+
+# GN target: [//protos/perfetto/config:source_set]
+perfetto_py_proto_library(
+ name = "config_py_pb2",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":config_proto",
+ ],
+)
+
+# GN target: [//protos/perfetto/trace:non_minimal_source_set, //protos/perfetto/trace:minimal_source_set]
+perfetto_proto_library(
+ name = "trace_proto",
+ visibility = PERFETTO_CONFIG.public_visibility,
deps = [
":protos_perfetto_common_protos",
+ ":protos_perfetto_config_android_protos",
+ ":protos_perfetto_config_ftrace_protos",
+ ":protos_perfetto_config_gpu_protos",
+ ":protos_perfetto_config_inode_file_protos",
+ ":protos_perfetto_config_interceptors_protos",
+ ":protos_perfetto_config_power_protos",
+ ":protos_perfetto_config_process_stats_protos",
+ ":protos_perfetto_config_profiling_protos",
+ ":protos_perfetto_config_protos",
+ ":protos_perfetto_config_sys_stats_protos",
+ ":protos_perfetto_config_track_event_protos",
+ ":protos_perfetto_trace_android_protos",
+ ":protos_perfetto_trace_chrome_protos",
+ ":protos_perfetto_trace_filesystem_protos",
+ ":protos_perfetto_trace_ftrace_protos",
+ ":protos_perfetto_trace_gpu_protos",
+ ":protos_perfetto_trace_interned_data_protos",
+ ":protos_perfetto_trace_minimal_protos",
+ ":protos_perfetto_trace_non_minimal_protos",
+ ":protos_perfetto_trace_perfetto_protos",
+ ":protos_perfetto_trace_power_protos",
+ ":protos_perfetto_trace_profiling_protos",
+ ":protos_perfetto_trace_ps_protos",
+ ":protos_perfetto_trace_sys_stats_protos",
+ ":protos_perfetto_trace_system_info_protos",
+ ":protos_perfetto_trace_track_event_protos",
+ ":protos_perfetto_trace_translation_protos",
],
)
-# GN target: //protos/perfetto/common:zero
+# GN target: [//protos/perfetto/trace:non_minimal_source_set, //protos/perfetto/trace:minimal_source_set]
+perfetto_cc_proto_library(
+ name = "trace_cc_proto",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":trace_proto",
+ ],
+)
+
+# GN target: [//protos/perfetto/trace:non_minimal_source_set, //protos/perfetto/trace:minimal_source_set]
+perfetto_java_proto_library(
+ name = "trace_java_proto",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":trace_proto",
+ ],
+)
+
+# GN target: [//protos/perfetto/trace:non_minimal_source_set, //protos/perfetto/trace:minimal_source_set]
+perfetto_java_lite_proto_library(
+ name = "trace_java_proto_lite",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":trace_proto",
+ ],
+)
+
+# GN target: [//protos/perfetto/trace:non_minimal_source_set, //protos/perfetto/trace:minimal_source_set]
+perfetto_py_proto_library(
+ name = "trace_py_pb2",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":trace_proto",
+ ],
+)
+
+# GN target: [//protos/perfetto/metrics:source_set]
+perfetto_proto_library(
+ name = "metrics_proto",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":protos_perfetto_metrics_android_protos",
+ ":protos_perfetto_metrics_protos",
+ ],
+)
+
+# GN target: [//protos/perfetto/metrics:source_set]
+perfetto_cc_proto_library(
+ name = "metrics_cc_proto",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":metrics_proto",
+ ],
+)
+
+# GN target: [//protos/perfetto/metrics:source_set]
+perfetto_java_proto_library(
+ name = "metrics_java_proto",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":metrics_proto",
+ ],
+)
+
+# GN target: [//protos/perfetto/metrics:source_set]
+perfetto_java_lite_proto_library(
+ name = "metrics_java_proto_lite",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":metrics_proto",
+ ],
+)
+
+# GN target: [//protos/perfetto/metrics:source_set]
+perfetto_py_proto_library(
+ name = "metrics_py_pb2",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":metrics_proto",
+ ],
+)
+
+# GN target: [//protos/third_party/chromium:source_set]
+perfetto_proto_library(
+ name = "chromium_proto",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":protos_perfetto_trace_track_event_protos",
+ ":protos_third_party_chromium_protos",
+ ],
+)
+
+# GN target: [//protos/third_party/chromium:source_set]
+perfetto_cc_proto_library(
+ name = "chromium_cc_proto",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":chromium_proto",
+ ],
+)
+
+# GN target: [//protos/third_party/chromium:source_set]
+perfetto_java_proto_library(
+ name = "chromium_java_proto",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":chromium_proto",
+ ],
+)
+
+# GN target: [//protos/third_party/chromium:source_set]
+perfetto_java_lite_proto_library(
+ name = "chromium_java_proto_lite",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":chromium_proto",
+ ],
+)
+
+# GN target: [//protos/third_party/chromium:source_set]
+perfetto_py_proto_library(
+ name = "chromium_py_pb2",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":chromium_proto",
+ ],
+)
+
+# GN target: [//protos/perfetto/metrics/chrome:source_set]
+perfetto_proto_library(
+ name = "chrome_metrics_proto",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":protos_perfetto_metrics_android_protos",
+ ":protos_perfetto_metrics_chrome_protos",
+ ":protos_perfetto_metrics_custom_options_protos",
+ ":protos_perfetto_metrics_protos",
+ ],
+)
+
+# GN target: [//protos/perfetto/metrics/chrome:source_set]
+perfetto_cc_proto_library(
+ name = "chrome_metrics_cc_proto",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":chrome_metrics_proto",
+ ],
+)
+
+# GN target: [//protos/perfetto/metrics/chrome:source_set]
+perfetto_java_proto_library(
+ name = "chrome_metrics_java_proto",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":chrome_metrics_proto",
+ ],
+)
+
+# GN target: [//protos/perfetto/metrics/chrome:source_set]
+perfetto_java_lite_proto_library(
+ name = "chrome_metrics_java_proto_lite",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":chrome_metrics_proto",
+ ],
+)
+
+# GN target: [//protos/perfetto/metrics/chrome:source_set]
+perfetto_py_proto_library(
+ name = "chrome_metrics_py_pb2",
+ visibility = PERFETTO_CONFIG.public_visibility,
+ deps = [
+ ":chrome_metrics_proto",
+ ],
+)
+
+# GN target: //protos/perfetto/common:cpp
+perfetto_cc_protocpp_library(
+ name = "protos_perfetto_common_cpp",
+ deps = [
+ ":protos_perfetto_common_protos",
+ ],
+)
+
+# GN target: //protos/perfetto/common:source_set
perfetto_proto_library(
name = "protos_perfetto_common_protos",
srcs = [
@@ -1807,6 +2293,7 @@ perfetto_proto_library(
"protos/perfetto/common/commit_data_request.proto",
"protos/perfetto/common/data_source_descriptor.proto",
"protos/perfetto/common/descriptor.proto",
+ "protos/perfetto/common/ftrace_descriptor.proto",
"protos/perfetto/common/gpu_counter_descriptor.proto",
"protos/perfetto/common/interceptor_descriptor.proto",
"protos/perfetto/common/observable_events.proto",
@@ -1839,15 +2326,7 @@ perfetto_cc_protocpp_library(
],
)
-# GN target: //protos/perfetto/config/android:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_config_android_lite",
- deps = [
- ":protos_perfetto_config_android_protos",
- ],
-)
-
-# GN target: //protos/perfetto/config/android:zero
+# GN target: //protos/perfetto/config/android:source_set
perfetto_proto_library(
name = "protos_perfetto_config_android_protos",
srcs = [
@@ -1910,15 +2389,7 @@ perfetto_cc_protocpp_library(
],
)
-# GN target: //protos/perfetto/config/ftrace:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_config_ftrace_lite",
- deps = [
- ":protos_perfetto_config_ftrace_protos",
- ],
-)
-
-# GN target: //protos/perfetto/config/ftrace:zero
+# GN target: //protos/perfetto/config/ftrace:source_set
perfetto_proto_library(
name = "protos_perfetto_config_ftrace_protos",
srcs = [
@@ -1945,15 +2416,7 @@ perfetto_cc_protocpp_library(
],
)
-# GN target: //protos/perfetto/config/gpu:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_config_gpu_lite",
- deps = [
- ":protos_perfetto_config_gpu_protos",
- ],
-)
-
-# GN target: //protos/perfetto/config/gpu:zero
+# GN target: //protos/perfetto/config/gpu:source_set
perfetto_proto_library(
name = "protos_perfetto_config_gpu_protos",
srcs = [
@@ -1981,15 +2444,7 @@ perfetto_cc_protocpp_library(
],
)
-# GN target: //protos/perfetto/config/inode_file:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_config_inode_file_lite",
- deps = [
- ":protos_perfetto_config_inode_file_protos",
- ],
-)
-
-# GN target: //protos/perfetto/config/inode_file:zero
+# GN target: //protos/perfetto/config/inode_file:source_set
perfetto_proto_library(
name = "protos_perfetto_config_inode_file_protos",
srcs = [
@@ -2017,15 +2472,7 @@ perfetto_cc_protocpp_library(
],
)
-# GN target: //protos/perfetto/config/interceptors:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_config_interceptors_lite",
- deps = [
- ":protos_perfetto_config_interceptors_protos",
- ],
-)
-
-# GN target: //protos/perfetto/config/interceptors:zero
+# GN target: //protos/perfetto/config/interceptors:source_set
perfetto_proto_library(
name = "protos_perfetto_config_interceptors_protos",
srcs = [
@@ -2048,53 +2495,6 @@ perfetto_cc_protozero_library(
],
)
-# GN target: //protos/perfetto/config:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_config_lite",
- deps = [
- ":protos_perfetto_config_protos",
- ],
-)
-
-# GN target: //protos/perfetto/config:merged_config
-perfetto_cc_proto_library(
- name = "protos_perfetto_config_merged_config",
- deps = [
- ":protos_perfetto_config_merged_config_protos",
- ],
-)
-
-# GN target: //protos/perfetto/config:merged_config
-perfetto_proto_library(
- name = "protos_perfetto_config_merged_config_protos",
- srcs = [
- "protos/perfetto/config/perfetto_config.proto",
- ],
- visibility = PERFETTO_CONFIG.public_visibility,
-)
-
-# GN target: //protos/perfetto/config:perfetto_config_descriptor
-perfetto_proto_descriptor(
- name = "protos_perfetto_config_perfetto_config_descriptor",
- deps = [
- ":protos_perfetto_config_perfetto_config_protos",
- ],
- outs = [
- "protos_perfetto_config_perfetto_config_descriptor.bin",
- ],
-)
-
-# GN target: //protos/perfetto/config:perfetto_config_descriptor
-perfetto_proto_library(
- name = "protos_perfetto_config_perfetto_config_protos",
- srcs = [
- "protos/perfetto/config/perfetto_config.proto",
- ],
- visibility = [
- PERFETTO_CONFIG.proto_library_visibility,
- ],
-)
-
# GN target: //protos/perfetto/config/power:cpp
perfetto_cc_protocpp_library(
name = "protos_perfetto_config_power_cpp",
@@ -2103,15 +2503,7 @@ perfetto_cc_protocpp_library(
],
)
-# GN target: //protos/perfetto/config/power:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_config_power_lite",
- deps = [
- ":protos_perfetto_config_power_protos",
- ],
-)
-
-# GN target: //protos/perfetto/config/power:zero
+# GN target: //protos/perfetto/config/power:source_set
perfetto_proto_library(
name = "protos_perfetto_config_power_protos",
srcs = [
@@ -2138,15 +2530,7 @@ perfetto_cc_protocpp_library(
],
)
-# GN target: //protos/perfetto/config/process_stats:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_config_process_stats_lite",
- deps = [
- ":protos_perfetto_config_process_stats_protos",
- ],
-)
-
-# GN target: //protos/perfetto/config/process_stats:zero
+# GN target: //protos/perfetto/config/process_stats:source_set
perfetto_proto_library(
name = "protos_perfetto_config_process_stats_protos",
srcs = [
@@ -2174,15 +2558,7 @@ perfetto_cc_protocpp_library(
],
)
-# GN target: //protos/perfetto/config/profiling:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_config_profiling_lite",
- deps = [
- ":protos_perfetto_config_profiling_protos",
- ],
-)
-
-# GN target: //protos/perfetto/config/profiling:zero
+# GN target: //protos/perfetto/config/profiling:source_set
perfetto_proto_library(
name = "protos_perfetto_config_profiling_protos",
srcs = [
@@ -2207,7 +2583,7 @@ perfetto_cc_protozero_library(
],
)
-# GN target: //protos/perfetto/config:zero
+# GN target: //protos/perfetto/config:source_set
perfetto_proto_library(
name = "protos_perfetto_config_protos",
srcs = [
@@ -2218,7 +2594,9 @@ perfetto_proto_library(
"protos/perfetto/config/test_config.proto",
"protos/perfetto/config/trace_config.proto",
],
- visibility = PERFETTO_CONFIG.public_visibility,
+ visibility = [
+ PERFETTO_CONFIG.proto_library_visibility,
+ ],
deps = [
":protos_perfetto_common_protos",
":protos_perfetto_config_android_protos",
@@ -2243,15 +2621,7 @@ perfetto_cc_protocpp_library(
],
)
-# GN target: //protos/perfetto/config/sys_stats:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_config_sys_stats_lite",
- deps = [
- ":protos_perfetto_config_sys_stats_protos",
- ],
-)
-
-# GN target: //protos/perfetto/config/sys_stats:zero
+# GN target: //protos/perfetto/config/sys_stats:source_set
perfetto_proto_library(
name = "protos_perfetto_config_sys_stats_protos",
srcs = [
@@ -2282,15 +2652,7 @@ perfetto_cc_protocpp_library(
],
)
-# GN target: //protos/perfetto/config/track_event:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_config_track_event_lite",
- deps = [
- ":protos_perfetto_config_track_event_protos",
- ],
-)
-
-# GN target: //protos/perfetto/config/track_event:zero
+# GN target: //protos/perfetto/config/track_event:source_set
perfetto_proto_library(
name = "protos_perfetto_config_track_event_protos",
srcs = [
@@ -2369,7 +2731,7 @@ perfetto_cc_ipc_library(
],
)
-# GN target: //protos/perfetto/ipc:ipc
+# GN target: //protos/perfetto/ipc:source_set
perfetto_proto_library(
name = "protos_perfetto_ipc_protos",
srcs = [
@@ -2403,7 +2765,7 @@ perfetto_cc_protocpp_library(
],
)
-# GN target: //protos/perfetto/ipc:wire_protocol_cpp
+# GN target: //protos/perfetto/ipc:wire_protocol_source_set
perfetto_proto_library(
name = "protos_perfetto_ipc_wire_protocol_protos",
srcs = [
@@ -2414,28 +2776,25 @@ perfetto_proto_library(
],
)
-# GN target: //protos/perfetto/metrics/android:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_metrics_android_lite",
- deps = [
- ":protos_perfetto_metrics_android_protos",
- ],
-)
-
# GN target: //protos/perfetto/metrics/android:source_set
perfetto_proto_library(
name = "protos_perfetto_metrics_android_protos",
srcs = [
+ "protos/perfetto/metrics/android/android_trusty_workqueues.proto",
"protos/perfetto/metrics/android/batt_metric.proto",
+ "protos/perfetto/metrics/android/camera_metric.proto",
+ "protos/perfetto/metrics/android/camera_unagg_metric.proto",
"protos/perfetto/metrics/android/cpu_metric.proto",
"protos/perfetto/metrics/android/display_metrics.proto",
"protos/perfetto/metrics/android/dma_heap_metric.proto",
+ "protos/perfetto/metrics/android/dvfs_metric.proto",
"protos/perfetto/metrics/android/fastrpc_metric.proto",
"protos/perfetto/metrics/android/g2d_metric.proto",
"protos/perfetto/metrics/android/gpu_metric.proto",
"protos/perfetto/metrics/android/hwcomposer.proto",
"protos/perfetto/metrics/android/hwui_metric.proto",
"protos/perfetto/metrics/android/ion_metric.proto",
+ "protos/perfetto/metrics/android/irq_runtime_metric.proto",
"protos/perfetto/metrics/android/jank_metric.proto",
"protos/perfetto/metrics/android/java_heap_histogram.proto",
"protos/perfetto/metrics/android/java_heap_stats.proto",
@@ -2443,17 +2802,26 @@ perfetto_proto_library(
"protos/perfetto/metrics/android/lmk_reason_metric.proto",
"protos/perfetto/metrics/android/mem_metric.proto",
"protos/perfetto/metrics/android/mem_unagg_metric.proto",
+ "protos/perfetto/metrics/android/multiuser_metric.proto",
+ "protos/perfetto/metrics/android/network_metric.proto",
+ "protos/perfetto/metrics/android/other_traces.proto",
"protos/perfetto/metrics/android/package_list.proto",
"protos/perfetto/metrics/android/powrails_metric.proto",
"protos/perfetto/metrics/android/process_metadata.proto",
+ "protos/perfetto/metrics/android/profiler_smaps.proto",
+ "protos/perfetto/metrics/android/rt_runtime_metric.proto",
+ "protos/perfetto/metrics/android/simpleperf.proto",
"protos/perfetto/metrics/android/startup_metric.proto",
"protos/perfetto/metrics/android/surfaceflinger.proto",
"protos/perfetto/metrics/android/sysui_cuj_metrics.proto",
"protos/perfetto/metrics/android/task_names.proto",
"protos/perfetto/metrics/android/thread_time_in_state_metric.proto",
+ "protos/perfetto/metrics/android/trace_quality.proto",
"protos/perfetto/metrics/android/unsymbolized_frames.proto",
],
- visibility = PERFETTO_CONFIG.public_visibility,
+ visibility = [
+ PERFETTO_CONFIG.proto_library_visibility,
+ ],
)
# GN target: //protos/perfetto/metrics/chrome:descriptor
@@ -2473,11 +2841,18 @@ perfetto_proto_library(
srcs = [
"protos/perfetto/metrics/chrome/all_chrome_metrics.proto",
"protos/perfetto/metrics/chrome/blink_gc_metric.proto",
+ "protos/perfetto/metrics/chrome/dropped_frames.proto",
"protos/perfetto/metrics/chrome/frame_times.proto",
+ "protos/perfetto/metrics/chrome/histogram_hashes.proto",
+ "protos/perfetto/metrics/chrome/long_latency.proto",
"protos/perfetto/metrics/chrome/media_metric.proto",
+ "protos/perfetto/metrics/chrome/performance_mark_hashes.proto",
"protos/perfetto/metrics/chrome/reported_by_page.proto",
"protos/perfetto/metrics/chrome/scroll_jank.proto",
+ "protos/perfetto/metrics/chrome/slice_names.proto",
"protos/perfetto/metrics/chrome/test_chrome_metric.proto",
+ "protos/perfetto/metrics/chrome/touch_jank.proto",
+ "protos/perfetto/metrics/chrome/user_event_hashes.proto",
],
visibility = [
PERFETTO_CONFIG.proto_library_visibility,
@@ -2513,39 +2888,26 @@ perfetto_proto_descriptor(
],
)
-# GN target: //protos/perfetto/metrics:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_metrics_lite",
- deps = [
- ":protos_perfetto_metrics_protos",
- ],
-)
-
# GN target: //protos/perfetto/metrics:source_set
perfetto_proto_library(
name = "protos_perfetto_metrics_protos",
srcs = [
"protos/perfetto/metrics/metrics.proto",
],
- visibility = PERFETTO_CONFIG.public_visibility,
- deps = [
- ":protos_perfetto_metrics_android_protos",
+ visibility = [
+ PERFETTO_CONFIG.proto_library_visibility,
],
-)
-
-# GN target: //protos/perfetto/trace/android:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_trace_android_lite",
deps = [
- ":protos_perfetto_trace_android_protos",
+ ":protos_perfetto_metrics_android_protos",
],
)
-# GN target: //protos/perfetto/trace/android:zero
+# GN target: //protos/perfetto/trace/android:source_set
perfetto_proto_library(
name = "protos_perfetto_trace_android_protos",
srcs = [
"protos/perfetto/trace/android/android_log.proto",
+ "protos/perfetto/trace/android/camera_event.proto",
"protos/perfetto/trace/android/frame_timeline_event.proto",
"protos/perfetto/trace/android/gpu_mem_event.proto",
"protos/perfetto/trace/android/graphics_frame_event.proto",
@@ -2569,15 +2931,7 @@ perfetto_cc_protozero_library(
],
)
-# GN target: //protos/perfetto/trace/chrome:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_trace_chrome_lite",
- deps = [
- ":protos_perfetto_trace_chrome_protos",
- ],
-)
-
-# GN target: //protos/perfetto/trace/chrome:zero
+# GN target: //protos/perfetto/trace/chrome:source_set
perfetto_proto_library(
name = "protos_perfetto_trace_chrome_protos",
srcs = [
@@ -2598,15 +2952,18 @@ perfetto_cc_protozero_library(
],
)
-# GN target: //protos/perfetto/trace/filesystem:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_trace_filesystem_lite",
+# GN target: //protos/perfetto/trace:descriptor
+perfetto_proto_descriptor(
+ name = "protos_perfetto_trace_descriptor",
deps = [
- ":protos_perfetto_trace_filesystem_protos",
+ ":protos_perfetto_trace_non_minimal_protos",
+ ],
+ outs = [
+ "protos_perfetto_trace_descriptor.bin",
],
)
-# GN target: //protos/perfetto/trace/filesystem:zero
+# GN target: //protos/perfetto/trace/filesystem:source_set
perfetto_proto_library(
name = "protos_perfetto_trace_filesystem_protos",
srcs = [
@@ -2625,15 +2982,7 @@ perfetto_cc_protozero_library(
],
)
-# GN target: //protos/perfetto/trace/ftrace:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_trace_ftrace_lite",
- deps = [
- ":protos_perfetto_trace_ftrace_protos",
- ],
-)
-
-# GN target: //protos/perfetto/trace/ftrace:zero
+# GN target: //protos/perfetto/trace/ftrace:source_set
perfetto_proto_library(
name = "protos_perfetto_trace_ftrace_protos",
srcs = [
@@ -2643,8 +2992,11 @@ perfetto_proto_library(
"protos/perfetto/trace/ftrace/clk.proto",
"protos/perfetto/trace/ftrace/compaction.proto",
"protos/perfetto/trace/ftrace/cpuhp.proto",
+ "protos/perfetto/trace/ftrace/cros_ec.proto",
+ "protos/perfetto/trace/ftrace/dma_fence.proto",
"protos/perfetto/trace/ftrace/dmabuf_heap.proto",
"protos/perfetto/trace/ftrace/dpu.proto",
+ "protos/perfetto/trace/ftrace/drm.proto",
"protos/perfetto/trace/ftrace/ext4.proto",
"protos/perfetto/trace/ftrace/f2fs.proto",
"protos/perfetto/trace/ftrace/fastrpc.proto",
@@ -2657,28 +3009,37 @@ perfetto_proto_library(
"protos/perfetto/trace/ftrace/g2d.proto",
"protos/perfetto/trace/ftrace/generic.proto",
"protos/perfetto/trace/ftrace/gpu_mem.proto",
+ "protos/perfetto/trace/ftrace/gpu_scheduler.proto",
"protos/perfetto/trace/ftrace/i2c.proto",
"protos/perfetto/trace/ftrace/ion.proto",
"protos/perfetto/trace/ftrace/ipi.proto",
"protos/perfetto/trace/ftrace/irq.proto",
"protos/perfetto/trace/ftrace/kmem.proto",
+ "protos/perfetto/trace/ftrace/kvm.proto",
"protos/perfetto/trace/ftrace/lowmemorykiller.proto",
"protos/perfetto/trace/ftrace/mali.proto",
"protos/perfetto/trace/ftrace/mdss.proto",
"protos/perfetto/trace/ftrace/mm_event.proto",
+ "protos/perfetto/trace/ftrace/net.proto",
"protos/perfetto/trace/ftrace/oom.proto",
"protos/perfetto/trace/ftrace/power.proto",
+ "protos/perfetto/trace/ftrace/printk.proto",
"protos/perfetto/trace/ftrace/raw_syscalls.proto",
"protos/perfetto/trace/ftrace/regulator.proto",
"protos/perfetto/trace/ftrace/sched.proto",
"protos/perfetto/trace/ftrace/scm.proto",
"protos/perfetto/trace/ftrace/sde.proto",
"protos/perfetto/trace/ftrace/signal.proto",
+ "protos/perfetto/trace/ftrace/skb.proto",
+ "protos/perfetto/trace/ftrace/sock.proto",
"protos/perfetto/trace/ftrace/sync.proto",
+ "protos/perfetto/trace/ftrace/synthetic.proto",
"protos/perfetto/trace/ftrace/systrace.proto",
"protos/perfetto/trace/ftrace/task.proto",
+ "protos/perfetto/trace/ftrace/tcp.proto",
"protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
"protos/perfetto/trace/ftrace/thermal.proto",
+ "protos/perfetto/trace/ftrace/ufs.proto",
"protos/perfetto/trace/ftrace/vmscan.proto",
"protos/perfetto/trace/ftrace/workqueue.proto",
],
@@ -2695,15 +3056,7 @@ perfetto_cc_protozero_library(
],
)
-# GN target: //protos/perfetto/trace/gpu:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_trace_gpu_lite",
- deps = [
- ":protos_perfetto_trace_gpu_protos",
- ],
-)
-
-# GN target: //protos/perfetto/trace/gpu:zero
+# GN target: //protos/perfetto/trace/gpu:source_set
perfetto_proto_library(
name = "protos_perfetto_trace_gpu_protos",
srcs = [
@@ -2730,15 +3083,7 @@ perfetto_cc_protozero_library(
],
)
-# GN target: //protos/perfetto/trace/interned_data:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_trace_interned_data_lite",
- deps = [
- ":protos_perfetto_trace_interned_data_protos",
- ],
-)
-
-# GN target: //protos/perfetto/trace/interned_data:zero
+# GN target: //protos/perfetto/trace/interned_data:source_set
perfetto_proto_library(
name = "protos_perfetto_trace_interned_data_protos",
srcs = [
@@ -2767,32 +3112,7 @@ perfetto_cc_protozero_library(
],
)
-# GN target: //protos/perfetto/trace:merged_trace
-perfetto_cc_proto_library(
- name = "protos_perfetto_trace_merged_trace",
- deps = [
- ":protos_perfetto_trace_merged_trace_protos",
- ],
-)
-
-# GN target: //protos/perfetto/trace:merged_trace
-perfetto_proto_library(
- name = "protos_perfetto_trace_merged_trace_protos",
- srcs = [
- "protos/perfetto/trace/perfetto_trace.proto",
- ],
- visibility = PERFETTO_CONFIG.public_visibility,
-)
-
-# GN target: //protos/perfetto/trace:minimal_lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_trace_minimal_lite",
- deps = [
- ":protos_perfetto_trace_minimal_protos",
- ],
-)
-
-# GN target: //protos/perfetto/trace:minimal_zero
+# GN target: //protos/perfetto/trace:minimal_source_set
perfetto_proto_library(
name = "protos_perfetto_trace_minimal_protos",
srcs = [
@@ -2839,15 +3159,7 @@ perfetto_cc_protozero_library(
],
)
-# GN target: //protos/perfetto/trace:non_minimal_lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_trace_non_minimal_lite",
- deps = [
- ":protos_perfetto_trace_non_minimal_protos",
- ],
-)
-
-# GN target: //protos/perfetto/trace:non_minimal_zero
+# GN target: //protos/perfetto/trace:non_minimal_source_set
perfetto_proto_library(
name = "protos_perfetto_trace_non_minimal_protos",
srcs = [
@@ -2860,7 +3172,9 @@ perfetto_proto_library(
"protos/perfetto/trace/trace_packet_defaults.proto",
"protos/perfetto/trace/ui_state.proto",
],
- visibility = PERFETTO_CONFIG.public_visibility,
+ visibility = [
+ PERFETTO_CONFIG.proto_library_visibility,
+ ],
deps = [
":protos_perfetto_common_protos",
":protos_perfetto_config_android_protos",
@@ -2888,6 +3202,10 @@ perfetto_proto_library(
":protos_perfetto_trace_sys_stats_protos",
":protos_perfetto_trace_system_info_protos",
":protos_perfetto_trace_track_event_protos",
+ ":protos_perfetto_trace_translation_protos",
+ ],
+ exports = [
+ ":protos_perfetto_trace_track_event_protos",
],
)
@@ -2922,18 +3240,11 @@ perfetto_cc_protozero_library(
":protos_perfetto_trace_sys_stats_zero",
":protos_perfetto_trace_system_info_zero",
":protos_perfetto_trace_track_event_zero",
+ ":protos_perfetto_trace_translation_zero",
],
)
-# GN target: //protos/perfetto/trace/perfetto:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_trace_perfetto_lite",
- deps = [
- ":protos_perfetto_trace_perfetto_protos",
- ],
-)
-
-# GN target: //protos/perfetto/trace/perfetto:zero
+# GN target: //protos/perfetto/trace/perfetto:source_set
perfetto_proto_library(
name = "protos_perfetto_trace_perfetto_protos",
srcs = [
@@ -2953,15 +3264,7 @@ perfetto_cc_protozero_library(
],
)
-# GN target: //protos/perfetto/trace/power:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_trace_power_lite",
- deps = [
- ":protos_perfetto_trace_power_protos",
- ],
-)
-
-# GN target: //protos/perfetto/trace/power:zero
+# GN target: //protos/perfetto/trace/power:source_set
perfetto_proto_library(
name = "protos_perfetto_trace_power_protos",
srcs = [
@@ -2986,7 +3289,7 @@ perfetto_cc_protozero_library(
],
)
-# GN target: //protos/perfetto/trace_processor:metrics_impl_zero
+# GN target: //protos/perfetto/trace_processor:metrics_impl_source_set
perfetto_proto_library(
name = "protos_perfetto_trace_processor_metrics_impl_protos",
srcs = [
@@ -3005,7 +3308,7 @@ perfetto_cc_protozero_library(
],
)
-# GN target: //protos/perfetto/trace_processor:zero
+# GN target: //protos/perfetto/trace_processor:source_set
perfetto_proto_library(
name = "protos_perfetto_trace_processor_protos",
srcs = [
@@ -3028,15 +3331,7 @@ perfetto_cc_protozero_library(
],
)
-# GN target: //protos/perfetto/trace/profiling:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_trace_profiling_lite",
- deps = [
- ":protos_perfetto_trace_profiling_protos",
- ],
-)
-
-# GN target: //protos/perfetto/trace/profiling:zero
+# GN target: //protos/perfetto/trace/profiling:source_set
perfetto_proto_library(
name = "protos_perfetto_trace_profiling_protos",
srcs = [
@@ -3063,15 +3358,7 @@ perfetto_cc_protozero_library(
],
)
-# GN target: //protos/perfetto/trace/ps:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_trace_ps_lite",
- deps = [
- ":protos_perfetto_trace_ps_protos",
- ],
-)
-
-# GN target: //protos/perfetto/trace/ps:zero
+# GN target: //protos/perfetto/trace/ps:source_set
perfetto_proto_library(
name = "protos_perfetto_trace_ps_protos",
srcs = [
@@ -3091,15 +3378,7 @@ perfetto_cc_protozero_library(
],
)
-# GN target: //protos/perfetto/trace/sys_stats:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_trace_sys_stats_lite",
- deps = [
- ":protos_perfetto_trace_sys_stats_protos",
- ],
-)
-
-# GN target: //protos/perfetto/trace/sys_stats:zero
+# GN target: //protos/perfetto/trace/sys_stats:source_set
perfetto_proto_library(
name = "protos_perfetto_trace_sys_stats_protos",
srcs = [
@@ -3122,15 +3401,7 @@ perfetto_cc_protozero_library(
],
)
-# GN target: //protos/perfetto/trace/system_info:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_trace_system_info_lite",
- deps = [
- ":protos_perfetto_trace_system_info_protos",
- ],
-)
-
-# GN target: //protos/perfetto/trace/system_info:zero
+# GN target: //protos/perfetto/trace/system_info:source_set
perfetto_proto_library(
name = "protos_perfetto_trace_system_info_protos",
srcs = [
@@ -3157,15 +3428,18 @@ perfetto_cc_protocpp_library(
],
)
-# GN target: //protos/perfetto/trace/track_event:lite
-perfetto_cc_proto_library(
- name = "protos_perfetto_trace_track_event_lite",
+# GN target: //protos/perfetto/trace/track_event:descriptor
+perfetto_proto_descriptor(
+ name = "protos_perfetto_trace_track_event_descriptor",
deps = [
":protos_perfetto_trace_track_event_protos",
],
+ outs = [
+ "protos_perfetto_trace_track_event_descriptor.bin",
+ ],
)
-# GN target: //protos/perfetto/trace/track_event:zero
+# GN target: //protos/perfetto/trace/track_event:source_set
perfetto_proto_library(
name = "protos_perfetto_trace_track_event_protos",
srcs = [
@@ -3199,53 +3473,47 @@ perfetto_proto_library(
],
)
-# GN target: //protos/perfetto/trace/track_event:track_event_descriptor
-perfetto_proto_descriptor(
- name = "protos_perfetto_trace_track_event_track_event_descriptor",
+# GN target: //protos/perfetto/trace/track_event:zero
+perfetto_cc_protozero_library(
+ name = "protos_perfetto_trace_track_event_zero",
deps = [
- ":protos_perfetto_trace_track_event_track_event_protos",
- ],
- outs = [
- "protos_perfetto_trace_track_event_track_event_descriptor.bin",
+ ":protos_perfetto_trace_track_event_protos",
],
)
-# GN target: //protos/perfetto/trace/track_event:track_event_descriptor
+# GN target: //protos/perfetto/trace/translation:source_set
perfetto_proto_library(
- name = "protos_perfetto_trace_track_event_track_event_protos",
+ name = "protos_perfetto_trace_translation_protos",
srcs = [
- "protos/perfetto/trace/track_event/track_event.proto",
+ "protos/perfetto/trace/translation/translation_table.proto",
],
visibility = [
PERFETTO_CONFIG.proto_library_visibility,
],
- deps = [
- ":protos_perfetto_trace_track_event_protos",
- ],
)
-# GN target: //protos/perfetto/trace/track_event:zero
+# GN target: //protos/perfetto/trace/translation:zero
perfetto_cc_protozero_library(
- name = "protos_perfetto_trace_track_event_zero",
+ name = "protos_perfetto_trace_translation_zero",
deps = [
- ":protos_perfetto_trace_track_event_protos",
+ ":protos_perfetto_trace_translation_protos",
],
)
-# GN target: //protos/third_party/chromium:chrome_track_event_descriptor
+# GN target: //protos/third_party/chromium:descriptor
perfetto_proto_descriptor(
- name = "protos_third_party_chromium_chrome_track_event_descriptor",
+ name = "protos_third_party_chromium_descriptor",
deps = [
- ":protos_third_party_chromium_chrome_track_event_protos",
+ ":protos_third_party_chromium_protos",
],
outs = [
- "protos_third_party_chromium_chrome_track_event_descriptor.bin",
+ "protos_third_party_chromium_descriptor.bin",
],
)
-# GN target: //protos/third_party/chromium:chrome_track_event_descriptor
+# GN target: //protos/third_party/chromium:source_set
perfetto_proto_library(
- name = "protos_third_party_chromium_chrome_track_event_protos",
+ name = "protos_third_party_chromium_protos",
srcs = [
"protos/third_party/chromium/chrome_track_event.proto",
],
@@ -3255,9 +3523,12 @@ perfetto_proto_library(
deps = [
":protos_perfetto_trace_track_event_protos",
],
+ exports = [
+ ":protos_perfetto_trace_track_event_protos",
+ ],
)
-# GN target: //protos/third_party/pprof:zero
+# GN target: //protos/third_party/pprof:source_set
perfetto_proto_library(
name = "protos_third_party_pprof_protos",
srcs = [
@@ -3276,15 +3547,15 @@ perfetto_cc_protozero_library(
],
)
-# GN target: //src/perfetto_cmd:protos
+# GN target: //src/perfetto_cmd:protos_cpp
perfetto_cc_protocpp_library(
- name = "src_perfetto_cmd_protos",
+ name = "src_perfetto_cmd_protos_cpp",
deps = [
":src_perfetto_cmd_protos_protos",
],
)
-# GN target: //src/perfetto_cmd:protos
+# GN target: //src/perfetto_cmd:protos_source_set
perfetto_proto_library(
name = "src_perfetto_cmd_protos_protos",
srcs = [
@@ -3315,6 +3586,7 @@ perfetto_cc_library(
":src_tracing_in_process_backend",
":src_tracing_ipc_common",
":src_tracing_ipc_consumer_consumer",
+ ":src_tracing_ipc_default_socket",
":src_tracing_ipc_producer_producer",
":src_tracing_ipc_service_service",
":src_tracing_platform_impl",
@@ -3379,6 +3651,7 @@ perfetto_cc_library(
":protos_perfetto_trace_system_info_zero",
":protos_perfetto_trace_track_event_cpp",
":protos_perfetto_trace_track_event_zero",
+ ":protos_perfetto_trace_translation_zero",
":protozero",
":src_base_base",
],
@@ -3407,6 +3680,7 @@ perfetto_cc_binary(
":src_tracing_core_core",
":src_tracing_ipc_common",
":src_tracing_ipc_consumer_consumer",
+ ":src_tracing_ipc_default_socket",
":src_tracing_ipc_producer_producer",
"src/perfetto_cmd/main.cc",
],
@@ -3457,10 +3731,11 @@ perfetto_cc_binary(
":protos_perfetto_trace_system_info_zero",
":protos_perfetto_trace_track_event_cpp",
":protos_perfetto_trace_track_event_zero",
+ ":protos_perfetto_trace_translation_zero",
":protozero",
":src_base_base",
":src_perfetto_cmd_gen_cc_config_descriptor",
- ":src_perfetto_cmd_protos",
+ ":src_perfetto_cmd_protos_cpp",
] + PERFETTO_CONFIG.deps.zlib,
)
@@ -3476,7 +3751,7 @@ perfetto_cc_library(
":src_trace_processor_importers_memory_tracker_graph_processor",
":src_trace_processor_lib",
":src_trace_processor_metatrace",
- ":src_trace_processor_metrics_lib",
+ ":src_trace_processor_metrics_metrics",
":src_trace_processor_sqlite_sqlite",
":src_trace_processor_storage_full",
":src_trace_processor_storage_minimal",
@@ -3484,6 +3759,8 @@ perfetto_cc_library(
":src_trace_processor_tables_tables",
":src_trace_processor_types_types",
":src_trace_processor_util_descriptors",
+ ":src_trace_processor_util_gzip",
+ ":src_trace_processor_util_interned_message_view",
":src_trace_processor_util_proto_to_args_parser",
":src_trace_processor_util_protozero_to_text",
":src_trace_processor_util_util",
@@ -3531,6 +3808,7 @@ perfetto_cc_library(
":protos_perfetto_trace_sys_stats_zero",
":protos_perfetto_trace_system_info_zero",
":protos_perfetto_trace_track_event_zero",
+ ":protos_perfetto_trace_translation_zero",
":protozero",
":src_base_base",
":src_trace_processor_containers_containers",
@@ -3543,8 +3821,9 @@ perfetto_cc_library(
PERFETTO_CONFIG.deps.sqlite +
PERFETTO_CONFIG.deps.sqlite_ext_percentile +
PERFETTO_CONFIG.deps.zlib + [
- ":cc_merged_sql_metrics",
- ],
+ ":cc_amalgamated_sql_metrics",
+ ] +
+ PERFETTO_CONFIG.deps.demangle_wrapper,
linkstatic = True,
)
@@ -3564,6 +3843,7 @@ perfetto_cc_binary(
":src_profiling_deobfuscator",
":src_profiling_symbolizer_symbolize_database",
":src_profiling_symbolizer_symbolizer",
+ ":src_protozero_proto_ring_buffer",
":src_trace_processor_analysis_analysis",
":src_trace_processor_db_db",
":src_trace_processor_export_json",
@@ -3572,7 +3852,7 @@ perfetto_cc_binary(
":src_trace_processor_importers_memory_tracker_graph_processor",
":src_trace_processor_lib",
":src_trace_processor_metatrace",
- ":src_trace_processor_metrics_lib",
+ ":src_trace_processor_metrics_metrics",
":src_trace_processor_rpc_httpd",
":src_trace_processor_rpc_rpc",
":src_trace_processor_sqlite_sqlite",
@@ -3582,6 +3862,8 @@ perfetto_cc_binary(
":src_trace_processor_tables_tables",
":src_trace_processor_types_types",
":src_trace_processor_util_descriptors",
+ ":src_trace_processor_util_gzip",
+ ":src_trace_processor_util_interned_message_view",
":src_trace_processor_util_proto_to_args_parser",
":src_trace_processor_util_protozero_to_text",
":src_trace_processor_util_util",
@@ -3622,9 +3904,10 @@ perfetto_cc_binary(
":protos_perfetto_trace_sys_stats_zero",
":protos_perfetto_trace_system_info_zero",
":protos_perfetto_trace_track_event_zero",
+ ":protos_perfetto_trace_translation_zero",
":protozero",
":src_base_base",
- ":src_base_unix_socket",
+ ":src_base_http_http",
":src_trace_processor_containers_containers",
":src_trace_processor_importers_gen_cc_chrome_track_event_descriptor",
":src_trace_processor_importers_gen_cc_config_descriptor",
@@ -3637,8 +3920,9 @@ perfetto_cc_binary(
PERFETTO_CONFIG.deps.sqlite +
PERFETTO_CONFIG.deps.sqlite_ext_percentile +
PERFETTO_CONFIG.deps.zlib + [
- ":cc_merged_sql_metrics",
- ],
+ ":cc_amalgamated_sql_metrics",
+ ] +
+ PERFETTO_CONFIG.deps.demangle_wrapper,
)
# GN target: //src/traced/probes:traced_probes
@@ -3721,6 +4005,7 @@ perfetto_cc_library(
":protos_perfetto_trace_sys_stats_zero",
":protos_perfetto_trace_system_info_zero",
":protos_perfetto_trace_track_event_zero",
+ ":protos_perfetto_trace_translation_zero",
":protos_third_party_pprof_zero",
":protozero",
":src_trace_processor_containers_containers",
@@ -3745,6 +4030,7 @@ perfetto_cc_binary(
":src_profiling_deobfuscator",
":src_profiling_symbolizer_symbolize_database",
":src_profiling_symbolizer_symbolizer",
+ ":src_protozero_proto_ring_buffer",
":src_trace_processor_analysis_analysis",
":src_trace_processor_db_db",
":src_trace_processor_export_json",
@@ -3753,7 +4039,7 @@ perfetto_cc_binary(
":src_trace_processor_importers_memory_tracker_graph_processor",
":src_trace_processor_lib",
":src_trace_processor_metatrace",
- ":src_trace_processor_metrics_lib",
+ ":src_trace_processor_metrics_metrics",
":src_trace_processor_sqlite_sqlite",
":src_trace_processor_storage_full",
":src_trace_processor_storage_minimal",
@@ -3761,11 +4047,13 @@ perfetto_cc_binary(
":src_trace_processor_tables_tables",
":src_trace_processor_types_types",
":src_trace_processor_util_descriptors",
+ ":src_trace_processor_util_gzip",
+ ":src_trace_processor_util_interned_message_view",
":src_trace_processor_util_proto_to_args_parser",
":src_trace_processor_util_protozero_to_text",
":src_trace_processor_util_util",
- ":tools_trace_to_text_common",
- ":tools_trace_to_text_full",
+ ":tools_trace_to_text_lib",
+ ":tools_trace_to_text_main",
":tools_trace_to_text_pprofbuilder",
":tools_trace_to_text_utils",
],
@@ -3802,6 +4090,7 @@ perfetto_cc_binary(
":protos_perfetto_trace_sys_stats_zero",
":protos_perfetto_trace_system_info_zero",
":protos_perfetto_trace_track_event_zero",
+ ":protos_perfetto_trace_translation_zero",
":protos_third_party_pprof_zero",
":protozero",
":src_base_base",
@@ -3811,13 +4100,14 @@ perfetto_cc_binary(
":src_trace_processor_importers_gen_cc_track_event_descriptor",
":src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
":src_trace_processor_metrics_gen_cc_metrics_descriptor",
+ ":tools_trace_to_text_gen_cc_trace_descriptor",
] + PERFETTO_CONFIG.deps.jsoncpp +
- PERFETTO_CONFIG.deps.protobuf_full +
PERFETTO_CONFIG.deps.sqlite +
PERFETTO_CONFIG.deps.sqlite_ext_percentile +
PERFETTO_CONFIG.deps.zlib + [
- ":cc_merged_sql_metrics",
- ],
+ ":cc_amalgamated_sql_metrics",
+ ] +
+ PERFETTO_CONFIG.deps.demangle_wrapper,
)
# Content from BUILD.extras
@@ -3826,23 +4116,23 @@ build_config_dir_ = "include/perfetto/base/build_configs/bazel"
# Deliberately NOT a perfetto_cc_library, to avoid cyclic deps.
# This is pulled as a default dep by all targets.
-cc_library(
+perfetto_build_config_cc_library(
name = "build_config_hdr",
hdrs = [build_config_dir_ + "/perfetto_build_flags.h"],
includes = [build_config_dir_],
)
perfetto_cc_library(
- name = "cc_merged_sql_metrics",
- hdrs = ["src/trace_processor/metrics/sql_metrics.h"],
+ name = "cc_amalgamated_sql_metrics",
+ hdrs = ["src/trace_processor/metrics/sql/amalgamated_sql_metrics.h"],
)
perfetto_py_binary(
- name = "gen_merged_sql_metrics_py",
+ name = "gen_amalgamated_sql_metrics_py",
srcs = [
- "tools/gen_merged_sql_metrics.py",
+ "tools/gen_amalgamated_sql_metrics.py",
],
- main = "tools/gen_merged_sql_metrics.py",
+ main = "tools/gen_amalgamated_sql_metrics.py",
python_version = "PY3",
)
@@ -3860,6 +4150,7 @@ perfetto_java_proto_library(
deps = [
":protos_perfetto_metrics_protos",
],
+ visibility = PERFETTO_CONFIG.public_visibility,
)
perfetto_java_proto_library(
@@ -3867,27 +4158,7 @@ perfetto_java_proto_library(
deps = [
":protos_perfetto_metrics_android_protos",
],
-)
-
-perfetto_java_proto_library(
- name = "protos_perfetto_trace_merged_trace_java",
- deps = [
- ":protos_perfetto_trace_merged_trace_protos",
- ],
-)
-
-perfetto_java_proto_library(
- name = "protos_perfetto_config_merged_config_java",
- deps = [
- ":protos_perfetto_config_merged_config_protos",
- ],
-)
-
-perfetto_java_lite_proto_library(
- name = "protos_perfetto_config_merged_config_java_lite",
- deps = [
- ":protos_perfetto_config_merged_config_protos",
- ],
+ visibility = PERFETTO_CONFIG.public_visibility,
)
perfetto_gensignature_internal_only(
@@ -3916,57 +4187,3 @@ perfetto_py_binary(
main = "tools/write_version_header.py",
python_version = "PY3",
)
-
-# Noop targets used to represent targets of the protobuf library.
-# These will be rewritten in Google3 to be dependencies on the real targets.
-
-perfetto_py_library(
- name = "pyglib_noop",
- srcs = [],
-)
-
-perfetto_py_library(
- name = "protobuf_noop",
- srcs = [],
-)
-
-perfetto_py_library(
- name = "protobuf_descriptor_pb2_noop",
- srcs = [],
-)
-
-perfetto_py_library(
- name = "gfile_noop",
- srcs = [],
-)
-
-perfetto_py_library(
- name = "trace_processor_init_noop",
- srcs = [],
-)
-
-perfetto_py_binary(
- name = "trace_processor_py_example",
- srcs = ["src/trace_processor/python/example.py"],
- deps = [":trace_processor_py"],
- main = "src/trace_processor/python/example.py",
- python_version = "PY3",
-)
-
-perfetto_py_library(
- name = "trace_processor_py",
- srcs = glob(["src/trace_processor/python/perfetto/trace_processor/*.py"]),
- data = [
- ":trace_processor_init_noop",
- "src/trace_processor/python/perfetto/trace_processor/trace_processor.descriptor",
- "src/trace_processor/python/perfetto/trace_processor/metrics.descriptor",
- ":trace_processor_shell",
- ],
- deps = [
- ":gfile_noop",
- ":protobuf_noop",
- ":protobuf_descriptor_pb2_noop",
- ":pyglib_noop",
- ],
- visibility = PERFETTO_CONFIG.public_visibility,
-)
diff --git a/BUILD.extras b/BUILD.extras
index 53392a73a..dbf18af8b 100644
--- a/BUILD.extras
+++ b/BUILD.extras
@@ -2,23 +2,23 @@ build_config_dir_ = "include/perfetto/base/build_configs/bazel"
# Deliberately NOT a perfetto_cc_library, to avoid cyclic deps.
# This is pulled as a default dep by all targets.
-cc_library(
+perfetto_build_config_cc_library(
name = "build_config_hdr",
hdrs = [build_config_dir_ + "/perfetto_build_flags.h"],
includes = [build_config_dir_],
)
perfetto_cc_library(
- name = "cc_merged_sql_metrics",
- hdrs = ["src/trace_processor/metrics/sql_metrics.h"],
+ name = "cc_amalgamated_sql_metrics",
+ hdrs = ["src/trace_processor/metrics/sql/amalgamated_sql_metrics.h"],
)
perfetto_py_binary(
- name = "gen_merged_sql_metrics_py",
+ name = "gen_amalgamated_sql_metrics_py",
srcs = [
- "tools/gen_merged_sql_metrics.py",
+ "tools/gen_amalgamated_sql_metrics.py",
],
- main = "tools/gen_merged_sql_metrics.py",
+ main = "tools/gen_amalgamated_sql_metrics.py",
python_version = "PY3",
)
@@ -36,6 +36,7 @@ perfetto_java_proto_library(
deps = [
":protos_perfetto_metrics_protos",
],
+ visibility = PERFETTO_CONFIG.public_visibility,
)
perfetto_java_proto_library(
@@ -43,27 +44,7 @@ perfetto_java_proto_library(
deps = [
":protos_perfetto_metrics_android_protos",
],
-)
-
-perfetto_java_proto_library(
- name = "protos_perfetto_trace_merged_trace_java",
- deps = [
- ":protos_perfetto_trace_merged_trace_protos",
- ],
-)
-
-perfetto_java_proto_library(
- name = "protos_perfetto_config_merged_config_java",
- deps = [
- ":protos_perfetto_config_merged_config_protos",
- ],
-)
-
-perfetto_java_lite_proto_library(
- name = "protos_perfetto_config_merged_config_java_lite",
- deps = [
- ":protos_perfetto_config_merged_config_protos",
- ],
+ visibility = PERFETTO_CONFIG.public_visibility,
)
perfetto_gensignature_internal_only(
@@ -92,57 +73,3 @@ perfetto_py_binary(
main = "tools/write_version_header.py",
python_version = "PY3",
)
-
-# Noop targets used to represent targets of the protobuf library.
-# These will be rewritten in Google3 to be dependencies on the real targets.
-
-perfetto_py_library(
- name = "pyglib_noop",
- srcs = [],
-)
-
-perfetto_py_library(
- name = "protobuf_noop",
- srcs = [],
-)
-
-perfetto_py_library(
- name = "protobuf_descriptor_pb2_noop",
- srcs = [],
-)
-
-perfetto_py_library(
- name = "gfile_noop",
- srcs = [],
-)
-
-perfetto_py_library(
- name = "trace_processor_init_noop",
- srcs = [],
-)
-
-perfetto_py_binary(
- name = "trace_processor_py_example",
- srcs = ["src/trace_processor/python/example.py"],
- deps = [":trace_processor_py"],
- main = "src/trace_processor/python/example.py",
- python_version = "PY3",
-)
-
-perfetto_py_library(
- name = "trace_processor_py",
- srcs = glob(["src/trace_processor/python/perfetto/trace_processor/*.py"]),
- data = [
- ":trace_processor_init_noop",
- "src/trace_processor/python/perfetto/trace_processor/trace_processor.descriptor",
- "src/trace_processor/python/perfetto/trace_processor/metrics.descriptor",
- ":trace_processor_shell",
- ],
- deps = [
- ":gfile_noop",
- ":protobuf_noop",
- ":protobuf_descriptor_pb2_noop",
- ":pyglib_noop",
- ],
- visibility = PERFETTO_CONFIG.public_visibility,
-)
diff --git a/BUILD.gn b/BUILD.gn
index 6f6cc7d62..6760137dc 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -45,6 +45,20 @@ if (enable_perfetto_trace_processor && enable_perfetto_trace_processor_sqlite) {
all_targets += [ "src/trace_processor:trace_processor_shell" ]
}
+if (enable_perfetto_tools_trace_to_text) {
+ all_targets += [ "tools/trace_to_text" ]
+ if (is_cross_compiling) {
+ # In many cross-compilation scenarios (typically Android) developers expect
+ # the host version of trace_to_text to be available somewhere in out/, so
+ # they can convert Android traces on their dev machine. Also
+ # tools/gen_android_bp explicitly depends on the host version for the
+ # cc_binary_host("trace_to_text") target in Android.bp.
+ # Note that when cross-compiling the host executable will be available in
+ # out/xxx/gcc_like_host/trace_to_text NOT just out/xxx/trace_to_text.
+ all_targets += [ "tools/trace_to_text($host_toolchain)" ]
+ }
+}
+
if (enable_perfetto_heapprofd) {
all_targets += [ "src/profiling/memory:heapprofd" ]
@@ -68,12 +82,18 @@ if (perfetto_build_with_android) {
}
if (enable_perfetto_tools) {
- all_targets += [ "tools" ]
+ all_targets += [
+ "tools",
+ "src/websocket_bridge",
+ ]
}
if (enable_perfetto_unittests) {
import("gn/perfetto_unittests.gni")
test("perfetto_unittests") {
+ if (is_fuchsia) {
+ use_cfv2 = false
+ }
deps = perfetto_unittests_targets
}
all_targets += [ ":perfetto_unittests" ]
@@ -86,6 +106,7 @@ if (enable_perfetto_integration_tests) {
}
all_targets += [
":perfetto_integrationtests",
+ "examples/sdk:sdk_example",
"test:client_api_example",
"test/stress_test",
]
@@ -126,9 +147,8 @@ if (perfetto_build_standalone) {
all_targets += [
"test/configs",
- # For syntax-checking the proto.
- "protos/perfetto/config:merged_config",
- "protos/perfetto/trace:merged_trace", # For syntax-checking the proto.
+ # For syntax-checking the protos.
+ "protos/perfetto/trace:merged_trace_lite",
# For checking all generated xxx.gen.{cc,h} files without waiting for
# embedders to try to use them and fail.
@@ -144,6 +164,9 @@ if (perfetto_build_standalone) {
if (is_linux || is_android) {
all_targets += [ "src/tracing/consumer_api_deprecated:consumer_api_test" ]
}
+ if (is_linux || is_android || is_mac) {
+ all_targets += [ "src/tracebox" ]
+ }
}
# The CTS code is built (but not ran) also in standalone builds. This is to
diff --git a/CHANGELOG b/CHANGELOG
index 114c03d81..99e6c4b91 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,8 @@
Unreleased:
Tracing service and probes:
- *
+ * Android perf profiler ("linux.perf" data source) and Java heap snapshots
+ ("android.java_hprof") now support a single wildcard (*) in the config
+ options that name process command lines to target.
Trace Processor:
*
UI:
@@ -9,6 +11,334 @@ Unreleased:
*
+v25.0 - 2022-04-01:
+ Tracing service and probes:
+ * Added prebuilts for mac-arm64.
+ * Removed merged trace and config protos from Bazel. Embedder should
+ instead depend on the non-merged proto targets.
+ * Added FtraceConfig.disable_generic_events. If set, the ftrace data source
+ will not emit events for which it doesn't have a compile-time proto
+ message.
+ * Added ingestion support for cros_ec (CrOS sensors) ftrace events.
+ * Added ingestion support for kvm trace events.
+ * Added reporting of atrace failures. Now they are bubbled up to the UI
+ rather than causing atrace data to be silently missing.
+ Trace Processor:
+ * Added prebuilts for mac-arm64.
+ * Changed LIKE comparisions to be case-insenstive. This reverts the change
+ introduced in v22. GLOB should be used where case senstive searches are
+ desired; built-in metrics continue to require the use of GLOB.
+ * Added an optional dependency from trace processor onto a subset of
+ sources from llvm-project for function name demangling. Bazel embedders
+ might need to update their PERFETTO_CONFIG in perfetto_cfg.bzl to opt in
+ or out of the new dependency. See
+ perfetto/bazel/standalone/perfetto_cfg.bzl for details.
+ UI:
+ * Added flow arrows between binder transaction pairs (request/reply
+ and async send/async recv).
+ SDK:
+ * Added support for writing typed proto messages inside DebugAnnotations.
+ * Added support for delta encoding of timestamps for TrackEvents.
+ To disable it, refer to `disable_incremental_timestamps` flag in
+ `track_event_config.proto`.
+ Tools:
+ * Added support of gzip-compressed traces to traceconv.
+ * Changed `traceconv text` to use an internal proto->pbtx converter rather
+ than relying on libprotobuf. It could cause some small divergencies in the
+ output format vs past releases.
+ * Added tools/cpu_profile helper script to capture traces with callstack
+ samples.
+
+
+v24.2 - 2022-02-10:
+ SDK:
+ * Revert of incremental timestamps, introduced in v24.0.
+ Some clients were depending on non-incremental timestamps.
+ Future releases will re-enable this but offer an opt-out.
+
+
+v24.1 - 2022-02-09:
+ Tracing service and probes:
+ * Fixed build failures on Windows.
+ Trace Processor:
+ * Fixed build failures on Windows.
+
+
+v24.0 - 2022-02-08:
+ Tracing service and probes:
+ * Added "cpufreq_period_ms" in data source "linux.sys_stats" to poll
+ /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq periodically.
+ * Added support for Trusty TEE workqueue events.
+ * Added support for more PMU events in traced_perf.
+ * Changed output format of perfetto --query. Made the output more compact
+ and added a summary of ongoing tracing sessions for the caller UID.
+ * Changed timeout for traced stall detection from 2s to 4s.
+ * Changed internal buffer management to split trace filtering in smaller
+ tasks and avoid too large memory allocation when filtering.
+ * Fixed a bug that could cause producers to see Flush() requests after an
+ OnStop() and mis-behave if the tracing session is extremely short.
+ Trace Processor:
+ * Added support for passing multiple SQL statements to ExecuteQuery(). All
+ queries will be executed fully, with the returned iterator yielding rows
+ for the final statement.
+ * Added support for multi-line SQL comments; previously only single line
+ comments were supported.
+ UI:
+ * Added support for parsing instant events from legacy systrace formats.
+ * Added ingestion and visualization for inet_sock_set_state and
+ tcp_retransmit_skb events, showing TCP connections on dedicated tracks.
+ * Changed HTTP+RPC to use the /websocket endpoint available in newer
+ versions of trace_processor --httpd.
+ * Changed text selection/copy: now allowed by default for DOM elements.
+ * Changed search to also lookup slices by ID when the term is a number.
+ * Changed postMessage() API, suppressed confirmation dialog when the opener
+ is in the same origin, for cases when the UI is self-hosted.
+ SDK:
+ * Changed timestamps emitted by the SDK to be incremental by default, using
+ ClockSnapshot + TracePacketDefaults.
+
+
+v23.0 - 2022-01-11:
+ Tracing service and probes:
+ * Added workaround for a kernel ftrace bug causing some "comm" fields to be
+ not null-terminated. https://github.com/torvalds/linux/commit/f0a5157803 .
+ * Added ability to talk to the newer AIDL-based health hal in traced_probes.
+ It still falls back on the older HIDL interface for older devices.
+ Trace Processor:
+ * Changed the argument for the trace path in constructor of TraceProcessor
+ in the Python API from |file_path| to |trace|.
+ |file_path| is deprecated and may be removed in the future.
+ * Changed the Python API constructor. Now it takes a TraceProcessorConfig
+ instead of passing parameters directly. This may break existing code
+ but migration should be trivial (all current options are still
+ supported).
+ * Fixed a HTTP keepalive bug in trace_processor --httpd. The bug, introduced
+ in v22.0, caused each RPC request to close the connection, effectively
+ defeating the 'Connection: Keep-Alive', after each query made by the UI.
+ * Added parsing of netif_receive_skb events from proto traces.
+ * Added android_netperf metric based on netif events.
+ * Fixed a bug that would cause fetch errors when loading traces > 32 MB when
+ using trace_processor --httpd.
+ * Added a workaround to tokenize properly /proc/pid/cmdline for chrome
+ processes on Linux/CrOS. Chrome rewrites its cmdline replacing \0 -> ' '.
+ UI:
+ *
+ SDK:
+ *
+
+
+v22.1 - 2021-12-07:
+ Tracing service and probes:
+ * Added workaround for a Linux kernel bug causing some ftrace strings to
+ be non-null-terminated (https://github.com/torvalds/linux/commit/f0a5157).
+ Trace Processor:
+ * Fixed build failures on Windows.
+
+
+v22.0 - 2021-12-03:
+ Tracing service and probes:
+ * Added Android SDK version to the SystemInfo trace packet.
+ * Changed compiler flags. Assume recent x64 CPUs (-msse4.2 -mavx -mpopcnt).
+ This behavior affects only standalone builds and can be changed by setting
+ enable_perfetto_x64_cpu_opt=false in the GN args.
+ * The java heap profiler now rescans all the processes every time for
+ continous_dump_config. The scan_pids_only_on_start can be used to restore
+ the old behavior.
+ * Added support for building on ARM Macs.
+ * Added support for the rss_stat_throttled event on Android via
+ FtraceConfig.throttle_rss_stat. In newer Android kernels the base rss_stat
+ event is now unthrottled. rss_stat used to be throttled by a downstream
+ kernel change, unnecessary after https://lkml.org/lkml/2021/10/25/1411 .
+ atrace.rc configures throttling from userspace at boot.
+ * Fixed a bug that caused IPCs to stall traced and hit the watchdog if in
+ the middle of a suspend/resume. Switched from SND_TIMEO to poll(POLLOUT).
+ * Added "linux.sysfs_power" data source to poll /sys/class/power_supply/
+ and report periodically battery charge and drain rate if supported.
+ * Add snapshotting for non-BOOTTIME ftrace clocks. This fixes handling of
+ ftrace events from old Linux kernel versions (i.e. 3.x) and adds
+ proper support for using the "global" clock rather than "boot".
+ Trace Processor:
+ * Speeded up proto trace ingestion by 2x (~20 MB/s -> ~40 MB/s).
+ * Changed LIKE comparisions to be case-senstive. This may break existing
+ queries but was a necessary from a performance perspective.
+ Going forward, GLOB must be used, instead of LIKE, for checked in metrics
+ to avoid unnecessary slowdowns.
+ * Changed compiler flags, assume recent x64 CPUs (see above).
+ * Changed how displayTimeUnit is handled in JSON traces to match catapult.
+ * Added websocket endpoint to RPC interface to reduce query latency.
+ * Added support for hot-reloading metrics (see //docs/analysis/metrics.md).
+ * Added ingestion support for non-BOOTTIME ftrace clocks.
+ UI:
+ * Added ability to save/restore record config. Remember last used config.
+ * Fixed bug causing the recording page to hold onto the USB interface making
+ adb unusable after a recording session.
+ SDK:
+ * Added UpdateDataSource() descriptor IPC endpoint to allow updates of the
+ data source capabilities (e.g., category list for track event).
+
+
+v21.0 - 2021-11-01:
+ Tracing service and probes:
+ * Added reporting of last 8 PERFETTO_LOG() entries and crash keys to
+ crash tombstones on Android.
+ * Changed kallsym parser to save 100ms for starting a tracing session with
+ enable_ksyms=true.
+ * Removed advertisement of the built-in data sources "android.heapprofd",
+ "android.java_hprof", "linux.perf" on Linux and other platforms. Built-in
+ data sources are only used to lazy-start daemons on Android OS.
+ * Changed ACL files on Android atrace.rc to support to up to 24 ftrace cpus.
+ No change on Linux which remains unlimited.
+ Trace Processor:
+ * Changed protobuf decoders to use less stack and fall back on heap sooner
+ (before: 16KB of stack per decoder, after: 1.6KB). It caused problems with
+ some embedders which use smaller per-thread stacks.
+ * Added support for SPAN OUTER JOIN on unpartitioned tables.
+ * Improved performance of as_pandas_dataframe() in the Python API by 16x.
+ UI:
+ * Added visualization of direct_reclaim ftrace events.
+ SDK:
+ * Added perfetto::{Flow,TerminatingFlow} to the track-event library.
+
+
+v20.1 - 2021-10-05:
+ Tracing service and probes:
+ * Fixed standalone Windows build. Updated the llvm-win toolchain.
+
+
+v20.0 - 2021-10-03:
+ Tracing service and probes:
+ * Removed DCHECK that would cause crashes when a debug build of the service
+ is used with a producer built with -DNDEBUG.
+ * Changed the service-side field-level filtering configuration protobuf
+ field number, because the feature had a bug. This is effectively
+ equivalent to deprecating the feature and reintroducing it under a
+ different name.
+ * Added support for boot tracing on Android. Early kernel tracing (prior to
+ the point when /data is mounted) is not yet supported. For instructions
+ see /docs/case-studies/android-boot-tracing.md .
+ Trace Processor:
+ * Added reqiurement of separating queries by semi-colon (;) followed by
+ new-line when specifying a query file with -q to trace processor shell.
+ * Added "ancestor_slice_by_stack" and "descendant_slice_by_stack" table
+ functions to walk up and down the slice stacks.
+ * Overhauled windowed sorting to be based on packet ordering and
+ lifecycle events inside the trace instead of time-based ordering.
+ * Removed |SortingMode::kForceFlushPeriodWindowedSort| due to changes to the
+ sorting algorithm, which is now based on Flush events rather than time.
+ Embedders should switch to |SortingMode::kDefaultHeuristics|. Other
+ SortingMode enum values are no-ops and will be removed in future versions.
+ UI:
+ * Added initial flamegraph support for traced_perf callstack samples.
+ * Added initial Pivot table for aggregation of userspace slices. The feature
+ is disabled by default for and requires manual enabling via
+ https://ui.perfetto.dev/#!/flags .
+ SDK:
+ * Changed DCHECK and DLOGs to be always disabled in SDK builds, regardless
+ of NDEBUG.
+
+
+v19.0 - 2021-09-02:
+ Tracing service and probes:
+ * Added ftrace clock reporting to the trace.
+ Trace Processor:
+ * Added support for longs/doubles to RUN_METRIC.
+ * Added power profile data for sunfish, redfin, and bramble.
+ * Added experimental Python library for computing slice breakdowns.
+ * Fixed parsing of JSON escape sequences.
+ * Fixed JSON trace detection.
+ UI:
+ * Added local cacheing of traces. Traces are reloaded in case of refresh or
+ tab being discarded by the browser.
+ * Added icon to distinguish metric-derived tracks.
+ * Added release channel selector to feature flags page.
+ * Fixed crash with null slice names.
+ SDK:
+ * Added some missing NESTABLE_ASYNC legacy trace macros.
+ * Fixed reporting of producer uid in --query.
+ * Fixed version numbering scheme for minor versions. Previously versions
+ were numbered as like v19.0.42 where 42 represented the number of commits
+ since the last major version release. This was ambiguous in the presence
+ of branches. Now versions are numbered like v19.0-ab12cd34 where ab12cd34
+ is the shortened Git commit-ish.
+
+
+v18.0 - 2021-08-02:
+ Tracing service and probes:
+ * Added cross-compiler toolchains for Linux-{arm,64} based on Debian Sid.
+ These will be used for generating monthly releases' prebuilts via LUCI.
+ Trace Processor:
+ * Added 'android_gpu' metric to report residency information for each GPU
+ frequency (via `trace_processor_shell --run-metrics android_gpu`).
+ * Removed the RawQuery RPC interface.
+ UI:
+ * Added a highlighted section to thread slices to visualize CPU time
+ (darker) verses wall time (lighter).
+ * Added global counter tracks for perf counters (e.g. "CPU 0 cycles", "CPU 0
+ instructions") when the 'linux.perf' data source (traced_perf) is used.
+ * Added a (feature) 'Flags' page to enable/disable individual metrics.
+ * Fixed races that could cause occasional crashes when loading a trace
+ from a permalink.
+ SDK:
+ * Fix undefined reference on ~TracingMuxerFake when building the SDK.
+
+
+v17.0 - 2021-07-02:
+ Tracing service and probes:
+ * Fixed a bug in ftrace parsing of absolute timestamps
+ (RINGBUF_TYPE_TIME_STAMP), encountered on Linux kernels 5.9+.
+ * Fixed a bug in --save-for-bugreport causing 0-length traces if the
+ selected trace declared one or more triggers in the config.
+ * Fixed a bug in tracebox causing the PERFETTO_PRODUCER_SOCK_NAME env
+ var to be ignored.
+ Trace Processor:
+ * Changed CORS headers of --httpd mode to allow only https://ui.perfetto.dev
+ and http://localhost:10000. This affects only CORS-aware browser clients.
+ * Added GPU frequency metrics.
+ UI:
+ * Fixed ADB connection issues ("unable to reset device") on Windows and Mac.
+ * Added caching of tracing in the cache storage so that the trace is
+ re-opened if a tab is killed (Chrome tab discarding or accidental CTRL+W).
+ SDK:
+ * Added support for writing track events using custom clock timestamps.
+
+
+v16.1 - 2021-06-08:
+ Tracing service and probes:
+ * Cherry-pick of r.android.com/1716718 which missed the v16 branch cut and
+ fixed MSVC 2019 builds.
+
+
+v16.0 - 2021-06-01:
+ Tracing service and probes:
+ * Added support for building most targets (including traced, SDK and
+ trace_processor_shell) from Windows using either clang-cl or MSVC 2019.
+ * Added tracebox, a monolithic binary to capture traces with one command
+ on Linux and older versions of Android (tested on Android Oreo).
+ * Added support for service-side field-level filtering of traces. The
+ consumer can pass a filter bytecode and ensure that non-allowed fields
+ are never emitted in output.
+ * Added reporting of service version and producer SDK version into the trace
+ and `perfetto --query`.
+ * Fixed compatibility with Android versions older than Pie (for sideloading)
+ which cause failures when trying to enable atrace categories.
+ Trace Processor:
+ * Added new RPC interface based on a bidirectional binary pipe. This allows
+ to simplify integration with out-of-process users. The existing --httpd
+ interface now exposes a single /rpc endpoint. Older endpoints are still
+ available for legacy clients.
+ * Added support for counters and instant events in JSON traces.
+ * Fixed support of displayTimeUnit in JSON traces.
+ UI:
+ * Added warning dialog when trying to use a trace_processor_shell --httpd
+ which is too old.
+ * Added warning dialog when trying to use a trace_processor_shell --httpd
+ RPC instance from more than one tab.
+ * Added links to convert the trace to JSON or systrace directly from the UI.
+ * Changed track sorting logic. Tracks are now sorted in groups (e.g.,
+ scheduling tracks, summary tracks, frame timeline tracks).
+ * Fixed crashes happening flakily when pushing traces via window.open().
+
+
v15.0 - 2021-05-05:
Tracing service and probes:
* Added support for {host,target}=aarch64 standalone builds.
diff --git a/OWNERS b/OWNERS
index 9e51e7442..0da623cfe 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,22 +1,35 @@
-hjd@google.com
+# Global OWNERS that can approve Perfetto changes.
+# Please look first at OWNERS in the various subdirectories before falling back
+# on this, as the former tend to be more brain-cache-hot.
+
+# Perfetto tracing internals and API/ABI boundaries.
primiano@google.com
skyostil@google.com
+
+# UI, Ftrace interop, traced_probes, protozero, Android internals.
+hjd@google.com
+
+# Trace Processor, metrics, infra.
lalitm@google.com
-fmayer@google.com
-taylori@google.com
+
+# Callstack / memory profilers, traced_probes & Linux internals.
+ddiproietto@google.com
rsavitski@google.com
-ilkos@google.com
-# For Chrome-related reviews.
-oysteine@google.com
+# Chromium-related things and tracing SDK.
eseckler@google.com
nuskos@google.com
-khokhlov@google.com
-ssid@google.com
-ddrone@google.com
-altimin@google.com
+oysteine@google.com
+
+# Most Android-related metrics.
+ilkos@google.com
+
+# fmayer@ left the team. Please try first rsavitski@, ddiproietto@ or primiano@
+# and leave fmayer@ as an emergency-only escalation on profilers.
+fmayer@google.com
-# chromium.org aliases for DEPS on third_party/perfetto.
+# chromium.org aliases for adding DEPS entries from chromium subprojects to
+# third_party/perfetto.
eseckler@chromium.org
nuskos@chromium.org
skyostil@chromium.org
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 97acb3eb4..27b4e882a 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -12,8 +12,22 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from __future__ import print_function
import itertools
import subprocess
+import time
+
+
+def RunAndReportIfLong(func, *args, **kargs):
+ start = time.time()
+ results = func(*args, **kargs)
+ end = time.time()
+ limit = 0.5 # seconds
+ name = func.__name__
+ runtime = end - start
+ if runtime > limit:
+ print("{} took >{:.2}s ({:.2}s)".format(name, limit, runtime))
+ return results
def CheckChange(input, output):
@@ -24,29 +38,44 @@ def CheckChange(input, output):
x,
files_to_check='.*',
files_to_skip=[
- 'Android[.]bp', '.*[.]json$', '.*[.]sql$', '.*[.]out$',
- 'test/trace_processor/.*/index$', '(.*/)?BUILD$', 'WORKSPACE',
- '.*/Makefile$', '/perfetto_build_flags.h$'
+ 'Android[.]bp',
+ '.*[.]json$',
+ '.*[.]sql$',
+ '.*[.]out$',
+ 'test/trace_processor/.*/index$',
+ '(.*/)?BUILD$',
+ 'WORKSPACE',
+ '.*/Makefile$',
+ '/perfetto_build_flags.h$',
+ "infra/luci/.*",
])
results = []
- results += input.canned_checks.CheckDoNotSubmit(input, output)
- results += input.canned_checks.CheckChangeHasNoTabs(input, output)
- results += input.canned_checks.CheckLongLines(
- input, output, 80, source_file_filter=long_line_sources)
- results += input.canned_checks.CheckPatchFormatted(
- input, output, check_js=True)
- results += input.canned_checks.CheckGNFormatted(input, output)
- results += CheckIncludeGuards(input, output)
- results += CheckIncludeViolations(input, output)
- results += CheckProtoComments(input, output)
- results += CheckBuild(input, output)
- results += CheckAndroidBlueprint(input, output)
- results += CheckBinaryDescriptors(input, output)
- results += CheckMergedTraceConfigProto(input, output)
- results += CheckProtoEventList(input, output)
- results += CheckBannedCpp(input, output)
- results += CheckSqlMetrics(input, output)
+ results += RunAndReportIfLong(input.canned_checks.CheckDoNotSubmit, input,
+ output)
+ results += RunAndReportIfLong(input.canned_checks.CheckChangeHasNoTabs, input,
+ output)
+ results += RunAndReportIfLong(
+ input.canned_checks.CheckLongLines,
+ input,
+ output,
+ 80,
+ source_file_filter=long_line_sources)
+ results += RunAndReportIfLong(
+ input.canned_checks.CheckPatchFormatted, input, output, check_js=True)
+ results += RunAndReportIfLong(input.canned_checks.CheckGNFormatted, input,
+ output)
+ results += RunAndReportIfLong(CheckIncludeGuards, input, output)
+ results += RunAndReportIfLong(CheckIncludeViolations, input, output)
+ results += RunAndReportIfLong(CheckProtoComments, input, output)
+ results += RunAndReportIfLong(CheckBuild, input, output)
+ results += RunAndReportIfLong(CheckAndroidBlueprint, input, output)
+ results += RunAndReportIfLong(CheckBinaryDescriptors, input, output)
+ results += RunAndReportIfLong(CheckMergedTraceConfigProto, input, output)
+ results += RunAndReportIfLong(CheckProtoEventList, input, output)
+ results += RunAndReportIfLong(CheckBannedCpp, input, output)
+ results += RunAndReportIfLong(CheckSqlMetrics, input, output)
+ results += RunAndReportIfLong(CheckTestData, input, output)
return results
@@ -129,9 +158,17 @@ def CheckBannedCpp(input_api, output_api):
'std::stod throws exceptions prefer base::StringToDouble()'),
(r'\bstd::stold\b',
'std::stold throws exceptions prefer base::StringToDouble()'),
+ (r'\bstrncpy\b',
+ 'strncpy does not null-terminate if src > dst. Use base::StringCopy'),
+ (r'[(=]\s*snprintf\(',
+ 'snprintf can return > dst_size. Use base::SprintfTrunc'),
+ (r'//.*\bDNS\b',
+ '// DNS (Do Not Ship) found. Did you mean to remove some testing code?'),
(r'\bPERFETTO_EINTR\(close\(',
'close(2) must not be retried on EINTR on Linux and other OSes '
'that we run on, as the fd will be closed.'),
+ (r'^#include <inttypes.h>', 'Use <cinttypes> rather than <inttypes.h>. ' +
+ 'See https://github.com/google/perfetto/issues/146'),
]
def file_filter(x):
@@ -140,6 +177,8 @@ def CheckBannedCpp(input_api, output_api):
errors = []
for f in input_api.AffectedSourceFiles(file_filter):
for line_number, line in f.ChangedContents():
+ if input_api.re.search(r'^\s*//', line):
+ continue # Skip comments
for regex, message in bad_cpp:
if input_api.re.search(regex, line):
errors.append(
@@ -203,8 +242,7 @@ def CheckProtoEventList(input_api, output_api):
if f.LocalPath() != 'tools/ftrace_proto_gen/event_list':
continue
if any((not new_line.startswith('removed')) and new_line != old_line
- for old_line, new_line in itertools.izip(f.OldContents(),
- f.NewContents())):
+ for old_line, new_line in zip(f.OldContents(), f.NewContents())):
return [
output_api.PresubmitError(
'event_list only has two supported changes: '
@@ -239,3 +277,15 @@ def CheckSqlMetrics(input_api, output_api):
if subprocess.call([tool]):
return [output_api.PresubmitError(tool + ' failed')]
return []
+
+
+def CheckTestData(input_api, output_api):
+ tool = 'tools/test_data'
+ if subprocess.call([tool, 'status', '--quiet']):
+ return [
+ output_api.PresubmitError(
+ '//test/data is out of sync. Run ' + tool + ' status for more. \n' +
+ 'If you rebaselined UI tests or added a new test trace, run: \n' +
+ 'tools/test_data upload')
+ ]
+ return []
diff --git a/TEST_MAPPING b/TEST_MAPPING
index d971a20fc..785bb2a21 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -8,5 +8,10 @@
{
"name": "libsurfaceflinger_unittest"
}
+ ],
+ "hwasan-postsubmit": [
+ {
+ "name": "CtsPerfettoTestCases"
+ }
]
}
diff --git a/bazel/BUILD b/bazel/BUILD
index 1bf33a4c9..bf64b6917 100644
--- a/bazel/BUILD
+++ b/bazel/BUILD
@@ -14,19 +14,25 @@
config_setting(
name = "os_osx",
- values = {"cpu": "darwin"},
+ constraint_values = [
+ "@platforms//os:macos",
+ ],
visibility = ["//visibility:public"],
)
config_setting(
name = "os_linux",
- values = {"cpu": "k8"},
+ constraint_values = [
+ "@platforms//os:linux",
+ ],
visibility = ["//visibility:public"],
)
# Note this config does not imply MSVC.
config_setting(
name = "os_windows",
- values = {"cpu": "x64_windows"},
+ constraint_values = [
+ "@platforms//os:windows",
+ ],
visibility = ["//visibility:public"],
)
diff --git a/bazel/deps.bzl b/bazel/deps.bzl
index 63cbde2d6..a15ecfa6c 100644
--- a/bazel/deps.bzl
+++ b/bazel/deps.bzl
@@ -17,6 +17,9 @@ load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository")
# This file must be kept in sync with tools/install-build-deps.
+# To generate shallow_since fields for git repos, use:
+# git show --date=raw COMMIT
+
def perfetto_deps():
# Note: this is more recent than the version of protobuf we use in the
# GN and Android builds. This is because older versions of protobuf don't
@@ -24,17 +27,17 @@ def perfetto_deps():
_add_repo_if_not_existing(
http_archive,
name = "com_google_protobuf",
- strip_prefix = "protobuf-3.9.0",
- url = "https://github.com/google/protobuf/archive/v3.9.0.tar.gz",
- sha256 = "2ee9dcec820352671eb83e081295ba43f7a4157181dad549024d7070d079cf65",
+ strip_prefix = "protobuf-3.10.1",
+ url = "https://github.com/protocolbuffers/protobuf/archive/v3.10.1.tar.gz",
+ sha256 = "6adf73fd7f90409e479d6ac86529ade2d45f50494c5c10f539226693cb8fe4f7",
)
_add_repo_if_not_existing(
http_archive,
name = "perfetto_dep_sqlite",
- url = "https://storage.googleapis.com/perfetto/sqlite-amalgamation-3250300.zip",
- sha256 = "2ad5379f3b665b60599492cc8a13ac480ea6d819f91b1ef32ed0e1ad152fafef",
- strip_prefix = "sqlite-amalgamation-3250300",
+ url = "https://storage.googleapis.com/perfetto/sqlite-amalgamation-3350400.zip",
+ sha256 = "f3bf0df69f5de0675196f4644e05d07dbc698d674dc563a12eff17d5b215cdf5",
+ strip_prefix = "sqlite-amalgamation-3350400",
build_file = "//bazel:sqlite.BUILD",
)
@@ -69,9 +72,18 @@ def perfetto_deps():
new_git_repository,
name = "perfetto_dep_zlib",
remote = "https://android.googlesource.com/platform/external/zlib.git",
- commit = "dfa0646a03b4e1707469e04dc931b09774968fe6",
+ commit = "5c85a2da4c13eda07f69d81a1579a5afddd35f59",
build_file = "//bazel:zlib.BUILD",
- shallow_since = "1557160162 -0700",
+ shallow_since = "1605147005 +0000",
+ )
+
+ _add_repo_if_not_existing(
+ http_archive,
+ name = "perfetto_dep_llvm_demangle",
+ url = "https://storage.googleapis.com/perfetto/llvm-project-3b4c59c156919902c785ce3cbae0eee2ee53064d.tgz",
+ sha256 = "f4a52e7f36edd7cacc844d5ae0e5f60b6f57c5afc40683e99f295886c9ce8ff4",
+ strip_prefix = "llvm-project",
+ build_file = "//bazel:llvm_demangle.BUILD",
)
# Without this protobuf.bzl fails. This seems a bug in protobuf_deps().
diff --git a/bazel/jsoncpp.BUILD b/bazel/jsoncpp.BUILD
index ec5a48b94..321a94f1b 100644
--- a/bazel/jsoncpp.BUILD
+++ b/bazel/jsoncpp.BUILD
@@ -36,6 +36,7 @@ cc_library(
"include/json/writer.h",
],
copts = [
+ "-Wno-deprecated-declarations",
"-Isrc/lib_json",
] + PERFETTO_CONFIG.deps_copts.jsoncpp,
defines = [
diff --git a/bazel/llvm_demangle.BUILD b/bazel/llvm_demangle.BUILD
new file mode 100644
index 000000000..fe406faf6
--- /dev/null
+++ b/bazel/llvm_demangle.BUILD
@@ -0,0 +1,39 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+load("@perfetto_cfg//:perfetto_cfg.bzl", "PERFETTO_CONFIG")
+
+cc_library(
+ name = "llvm_demangle",
+ srcs = [
+ "llvm/lib/Demangle/DLangDemangle.cpp",
+ "llvm/lib/Demangle/Demangle.cpp",
+ "llvm/lib/Demangle/ItaniumDemangle.cpp",
+ "llvm/lib/Demangle/MicrosoftDemangle.cpp",
+ "llvm/lib/Demangle/MicrosoftDemangleNodes.cpp",
+ "llvm/lib/Demangle/RustDemangle.cpp",
+ ],
+ hdrs = [
+ "llvm/include/llvm/Demangle/Demangle.h",
+ "llvm/include/llvm/Demangle/DemangleConfig.h",
+ "llvm/include/llvm/Demangle/ItaniumDemangle.h",
+ "llvm/include/llvm/Demangle/MicrosoftDemangle.h",
+ "llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h",
+ "llvm/include/llvm/Demangle/StringView.h",
+ "llvm/include/llvm/Demangle/Utility.h",
+ ],
+ copts = ["-std=c++14"] + PERFETTO_CONFIG.deps_copts.llvm_demangle,
+ includes = ["llvm/include"],
+ visibility = ["//visibility:public"],
+)
diff --git a/bazel/rules.bzl b/bazel/rules.bzl
index 4503867b8..4ece12c8d 100644
--- a/bazel/rules.bzl
+++ b/bazel/rules.bzl
@@ -34,6 +34,18 @@ def default_cc_args():
}),
}
+def perfetto_build_config_cc_library(**kwargs):
+ if not _rule_override("cc_library", **kwargs):
+ native.cc_library(**kwargs)
+
+def perfetto_filegroup(**kwargs):
+ if not _rule_override("filegroup", **kwargs):
+ native.filegroup(**kwargs)
+
+def perfetto_genrule(**kwargs):
+ if not _rule_override("genrule", **kwargs):
+ native.genrule(**kwargs)
+
def perfetto_cc_library(**kwargs):
args = _merge_dicts(default_cc_args(), kwargs)
if not _rule_override("cc_library", **args):
@@ -72,11 +84,16 @@ def perfetto_java_lite_proto_library(**kwargs):
if not _rule_override("java_lite_proto_library", **kwargs):
native.java_lite_proto_library(**kwargs)
+# Unlike the other rules, this is an noop by default because Bazel does not
+# support Python proto libraries.
+def perfetto_py_proto_library(**kwargs):
+ _rule_override("py_proto_library", **kwargs)
+
# +----------------------------------------------------------------------------+
# | Misc rules. |
# +----------------------------------------------------------------------------+
-# Unlike all the other rules, this is an noop by default because Bazel does not
+# Unlike the other rules, this is an noop by default because Bazel does not
# support gensignature.
def perfetto_gensignature_internal_only(**kwargs):
_rule_override("gensignature_internal_only", **kwargs)
@@ -104,17 +121,19 @@ def perfetto_cc_protozero_library(name, deps, **kwargs):
if len(_proto_deps) != 1:
fail("Too many proto deps for target %s" % name)
- proto_gen(
- name = name + "_src",
- deps = _proto_deps,
- suffix = "pbzero",
- plugin = PERFETTO_CONFIG.root + ":protozero_plugin",
- wrapper_namespace = "pbzero",
- protoc = PERFETTO_CONFIG.deps.protoc[0],
- root = PERFETTO_CONFIG.root,
- )
+ args = {
+ 'name': name + "_src",
+ 'deps': _proto_deps,
+ 'suffix': "pbzero",
+ 'plugin': PERFETTO_CONFIG.root + ":protozero_plugin",
+ 'wrapper_namespace': "pbzero",
+ 'protoc': PERFETTO_CONFIG.deps.protoc[0],
+ 'root': PERFETTO_CONFIG.root,
+ }
+ if not _rule_override("proto_gen", **args):
+ proto_gen(**args)
- native.filegroup(
+ perfetto_filegroup(
name = name + "_h",
srcs = [":" + name + "_src"],
output_group = "h",
@@ -146,17 +165,19 @@ def perfetto_cc_ipc_library(name, deps, **kwargs):
fail("Too many proto deps for target %s" % name)
# Generates .ipc.{cc,h}.
- proto_gen(
- name = name + "_src",
- deps = _proto_deps,
- suffix = "ipc",
- plugin = PERFETTO_CONFIG.root + ":ipc_plugin",
- wrapper_namespace = "gen",
- protoc = PERFETTO_CONFIG.deps.protoc[0],
- root = PERFETTO_CONFIG.root,
- )
+ args = {
+ 'name': name + "_src",
+ 'deps': _proto_deps,
+ 'suffix': "ipc",
+ 'plugin': PERFETTO_CONFIG.root + ":ipc_plugin",
+ 'wrapper_namespace': "gen",
+ 'protoc': PERFETTO_CONFIG.deps.protoc[0],
+ 'root': PERFETTO_CONFIG.root,
+ }
+ if not _rule_override("proto_gen", **args):
+ proto_gen(**args)
- native.filegroup(
+ perfetto_filegroup(
name = name + "_h",
srcs = [":" + name + "_src"],
output_group = "h",
@@ -195,17 +216,19 @@ def perfetto_cc_protocpp_library(name, deps, **kwargs):
if len(_proto_deps) != 1:
fail("Too many proto deps for target %s" % name)
- proto_gen(
- name = name + "_gen",
- deps = _proto_deps,
- suffix = "gen",
- plugin = PERFETTO_CONFIG.root + ":cppgen_plugin",
- wrapper_namespace = "gen",
- protoc = PERFETTO_CONFIG.deps.protoc[0],
- root = PERFETTO_CONFIG.root,
- )
+ args = {
+ 'name': name + "_gen",
+ 'deps': _proto_deps,
+ 'suffix': "gen",
+ 'plugin': PERFETTO_CONFIG.root + ":cppgen_plugin",
+ 'wrapper_namespace': "gen",
+ 'protoc': PERFETTO_CONFIG.deps.protoc[0],
+ 'root': PERFETTO_CONFIG.root,
+ }
+ if not _rule_override("proto_gen", **args):
+ proto_gen(**args)
- native.filegroup(
+ perfetto_filegroup(
name = name + "_gen_h",
srcs = [":" + name + "_gen"],
output_group = "h",
@@ -225,11 +248,13 @@ def perfetto_cc_protocpp_library(name, deps, **kwargs):
)
def perfetto_proto_descriptor(name, deps, outs, **kwargs):
- proto_descriptor_gen(
- name = name,
- deps = deps,
- outs = outs,
- )
+ args = {
+ 'name': name,
+ 'deps': deps,
+ 'outs': outs,
+ }
+ if not _rule_override("proto_descriptor_gen", **args):
+ proto_descriptor_gen(**args)
# Generator .descriptor.h from protos
def perfetto_cc_proto_descriptor(name, deps, outs, **kwargs):
@@ -239,7 +264,7 @@ def perfetto_cc_proto_descriptor(name, deps, outs, **kwargs):
"--gen_dir=$(GENDIR)",
"$<"
]
- native.genrule(
+ perfetto_genrule(
name = name + "_gen",
cmd = " ".join(cmd),
exec_tools = [
diff --git a/bazel/sqlite.BUILD b/bazel/sqlite.BUILD
index 8b02c6de9..acf99a148 100644
--- a/bazel/sqlite.BUILD
+++ b/bazel/sqlite.BUILD
@@ -35,6 +35,7 @@ include_sqlite = [
]
sqlite_copts = [
+ "-Wno-misleading-indentation",
"-DSQLITE_THREADSAFE=0",
"-DQLITE_DEFAULT_MEMSTATUS=0",
"-DSQLITE_LIKE_DOESNT_MATCH_BLOBS",
diff --git a/bazel/standalone/perfetto_cfg.bzl b/bazel/standalone/perfetto_cfg.bzl
index 2d71aa8d9..9f2675e6a 100644
--- a/bazel/standalone/perfetto_cfg.bzl
+++ b/bazel/standalone/perfetto_cfg.bzl
@@ -49,7 +49,28 @@ PERFETTO_CONFIG = struct(
protoc_lib = ["@com_google_protobuf//:protoc_lib"],
protobuf_lite = ["@com_google_protobuf//:protobuf_lite"],
protobuf_full = ["@com_google_protobuf//:protobuf"],
- protobuf_descriptor_proto = ["@com_google_protobuf//:descriptor_proto"]
+ protobuf_descriptor_proto = ["@com_google_protobuf//:descriptor_proto"],
+
+ # The Python targets are empty on the standalone build because we assume
+ # any relevant deps are installed on the system or are not applicable.
+ protobuf_py = [],
+ pandas_py = [],
+ tp_vendor_py = [],
+
+ # There are multiple configurations for the function name demangling
+ # logic in trace processor:
+ # (1) The following defaults include a subset of demangling sources
+ # from llvm-project. This is the most complete implementation.
+ # (2) You can avoid the llvm dependency by setting "llvm_demangle = []"
+ # here and PERFETTO_LLVM_DEMANGLE to false in your
+ # perfetto_build_flags.h. Then the implementation will use a
+ # demangler from the c++ runtime, which will most likely handle
+ # only itanium mangling, and is unavailable on some platforms (e.g.
+ # Windows, where it becomes a nop).
+ # (3) You can override the whole demangle_wrapper below, and provide
+ # your own demangling implementation.
+ demangle_wrapper = [ "//:src_trace_processor_demangle" ],
+ llvm_demangle = ["@perfetto_dep_llvm_demangle//:llvm_demangle"],
),
# This struct allows embedders to customize the cc_opts for Perfetto
@@ -60,6 +81,7 @@ PERFETTO_CONFIG = struct(
jsoncpp = [],
linenoise = [],
sqlite = [],
+ llvm_demangle = [],
),
# Allow Bazel embedders to change the visibility of "public" targets.
@@ -81,6 +103,8 @@ PERFETTO_CONFIG = struct(
# |rule_overrides| or invidivual keys. They are assigned to None or noop
# actions here just for documentation purposes.
rule_overrides = struct(
+ proto_library = None,
+
cc_binary = None,
cc_library = None,
cc_proto_library = None,
@@ -90,9 +114,9 @@ PERFETTO_CONFIG = struct(
java_proto_library = _noop_override,
java_lite_proto_library = _noop_override,
- proto_library = None,
py_binary = None,
py_library = None,
+ py_proto_library = None,
# We only need this for internal binaries. No other embeedder should
# care about this.
diff --git a/bazel/zlib.BUILD b/bazel/zlib.BUILD
index 5c723cef3..cd4a6d369 100644
--- a/bazel/zlib.BUILD
+++ b/bazel/zlib.BUILD
@@ -17,39 +17,45 @@ load("@perfetto_cfg//:perfetto_cfg.bzl", "PERFETTO_CONFIG")
cc_library(
name = "zlib",
srcs = [
- "src/adler32.c",
- "src/compress.c",
- "src/crc32.c",
- "src/crc32.h",
- "src/deflate.c",
- "src/deflate.h",
- "src/gzclose.c",
- "src/gzguts.h",
- "src/gzlib.c",
- "src/gzread.c",
- "src/gzwrite.c",
- "src/infback.c",
- "src/inffast.c",
- "src/inffast.h",
- "src/inffixed.h",
- "src/inflate.c",
- "src/inflate.h",
- "src/inftrees.c",
- "src/inftrees.h",
- "src/trees.c",
- "src/trees.h",
- "src/uncompr.c",
- "src/zconf.h",
- "src/zlib.h",
- "src/zutil.c",
- "src/zutil.h",
+ "adler32.c",
+ "compress.c",
+ "contrib/optimizations/insert_string.h",
+ "cpu_features.c",
+ "cpu_features.h",
+ "crc32.c",
+ "crc32.h",
+ "deflate.c",
+ "deflate.h",
+ "gzclose.c",
+ "gzguts.h",
+ "gzlib.c",
+ "gzread.c",
+ "gzwrite.c",
+ "infback.c",
+ "inffast.c",
+ "inffast.h",
+ "inffixed.h",
+ "inflate.c",
+ "inflate.h",
+ "inftrees.c",
+ "inftrees.h",
+ "trees.c",
+ "trees.h",
+ "uncompr.c",
+ "zconf.h",
+ "zlib.h",
+ "zutil.c",
+ "zutil.h",
],
hdrs = [
"zlib.h",
],
- copts = [
+ copts = select({
+ "@perfetto//bazel:os_windows": ["-DX86_WINDOWS"],
+ "//conditions:default": [],
+ }) + [
+ "-Wno-unused-function",
"-DHAVE_HIDDEN",
- "-Isrc",
] + PERFETTO_CONFIG.deps_copts.zlib,
includes = ["zlib"],
visibility = ["//visibility:public"],
diff --git a/buildtools/.gitignore b/buildtools/.gitignore
index 0888b62c7..869315f15 100644
--- a/buildtools/.gitignore
+++ b/buildtools/.gitignore
@@ -1,16 +1,20 @@
+android_sdk/
android-core/
android-libbase/
android-libprocinfo/
android-logging/
android-unwinding/
-android_sdk/
aosp-*/
benchmark/
bionic/
+bloaty/
catapult_trace_viewer/
-clang/
clang_format/
+clang/
d8/
+debian_sid_arm-sysroot/
+debian_sid_arm64-sysroot/
+debian_sid_armel-sysroot/
emulator/
googletest/
jsoncpp/
@@ -23,13 +27,14 @@ libunwind/
linenoise/
linux/
linux64/
+llvm-project/
lzma/
mac/
ndk/
nodejs/
protobuf/
-sqlite/
sqlite_src/
+sqlite/
test_data/
typefaces/
win/
diff --git a/buildtools/BUILD.gn b/buildtools/BUILD.gn
index 98022c9b5..299519224 100644
--- a/buildtools/BUILD.gn
+++ b/buildtools/BUILD.gn
@@ -724,7 +724,8 @@ if (use_custom_libcxx) {
"//gn/standalone/sanitizers:sanitizer_options_link_helper",
]
defines = [ "_LIBCPP_BUILDING_LIBRARY" ]
- if ((is_linux || is_android) && (is_asan || is_tsan || is_msan)) {
+ if ((is_linux || is_android) && using_sanitizer &&
+ (is_asan || is_tsan || is_msan)) {
# In {a,t,m}san configurations, operator new and operator delete will be
# provided by the sanitizer runtime library. Since libc++ defines these
# symbols with weak linkage, and the *san runtime uses strong linkage, it
@@ -788,7 +789,9 @@ source_set("benchmark") {
defines = [ "HAVE_POSIX_REGEX" ]
public_configs = [ ":benchmark_config" ]
all_dependent_configs = [ ":benchmark_config" ]
- cflags = [ "-Wno-deprecated-declarations" ]
+ if (!is_win) {
+ cflags = [ "-Wno-deprecated-declarations" ]
+ }
configs -= [ "//gn/standalone:extra_warnings" ]
deps = [ "//gn:default_deps" ]
}
@@ -971,6 +974,12 @@ config("zlib_config") {
]
}
+# Here be dragons. Used only by standalone profiler builds, which are
+# considered best effort. Since the headers use c++17 features, this source_set
+# pushes -std=c++17 flags up the dependency tree, whereas the rest of the
+# project continues to build under c++11. So the profilers end up linking
+# together code built under different standards, and rely on that to be ABI
+# compatible.
source_set("libunwindstack") {
visibility = _buildtools_visibility
include_dirs = [
@@ -1004,11 +1013,10 @@ source_set("libunwindstack") {
"android-unwinding/libunwindstack/ElfInterfaceArm.cpp",
"android-unwinding/libunwindstack/Global.cpp",
"android-unwinding/libunwindstack/JitDebug.cpp",
- "android-unwinding/libunwindstack/LocalUnwinder.cpp",
- "android-unwinding/libunwindstack/Log.cpp",
"android-unwinding/libunwindstack/MapInfo.cpp",
"android-unwinding/libunwindstack/Maps.cpp",
"android-unwinding/libunwindstack/Memory.cpp",
+ "android-unwinding/libunwindstack/MemoryXz.cpp",
"android-unwinding/libunwindstack/Regs.cpp",
"android-unwinding/libunwindstack/RegsArm.cpp",
"android-unwinding/libunwindstack/RegsArm64.cpp",
@@ -1026,8 +1034,11 @@ source_set("libunwindstack") {
"android-libbase/threads.cpp",
"android-logging/liblog/logger_write.cpp",
"android-logging/liblog/properties.cpp",
+ "android-unwinding/libunwindstack/LogStdout.cpp",
"android-unwinding/libunwindstack/MemoryMte.cpp",
]
+ } else {
+ sources += [ "android-unwinding/libunwindstack/LogAndroid.cpp" ]
}
if (current_cpu == "x86") {
sources += [ "android-unwinding/libunwindstack/AsmGetRegsX86.S" ]
@@ -1056,10 +1067,11 @@ config("bionic_kernel_uapi_headers") {
config("jsoncpp_config") {
visibility = _buildtools_visibility
- cflags = [
- "-DJSON_USE_EXCEPTION=0",
- "-Wno-deprecated-declarations",
-
+ cflags = [ "-DJSON_USE_EXCEPTION=0" ]
+ if (!is_win) {
+ cflags += [ "-Wno-deprecated-declarations" ]
+ }
+ cflags += [
# Using -isystem instead of include_dirs (-I), so we don't need to suppress
# warnings coming from third-party headers. Doing so would mask warnings in
# our own code.
@@ -1138,3 +1150,39 @@ if (use_libfuzzer) {
deps = [ "//gn:default_deps" ]
}
}
+
+config("llvm_demangle_config") {
+ visibility = _buildtools_visibility
+ include_dirs = [ "llvm-project/llvm/include" ]
+}
+
+# NB: this is built under c++14 and linked into code that is c++11 by default.
+# We rely on the ABIs being compatible for this to be sane. At the time of
+# writing, the only c++14 specific code is behind an #ifndef NDEBUG, so we
+# could keep building as c++11 in non-debug builds, but we always use c++14 for
+# consistency.
+source_set("llvm_demangle") {
+ visibility = _buildtools_visibility
+ configs -= [
+ "//gn/standalone:extra_warnings",
+ "//gn/standalone:c++11",
+ ]
+ configs += [ "//gn/standalone:c++14" ]
+ public_configs = [ ":llvm_demangle_config" ]
+ sources = [
+ "llvm-project/llvm/include/llvm/Demangle/Demangle.h",
+ "llvm-project/llvm/include/llvm/Demangle/DemangleConfig.h",
+ "llvm-project/llvm/include/llvm/Demangle/ItaniumDemangle.h",
+ "llvm-project/llvm/include/llvm/Demangle/MicrosoftDemangle.h",
+ "llvm-project/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h",
+ "llvm-project/llvm/include/llvm/Demangle/StringView.h",
+ "llvm-project/llvm/include/llvm/Demangle/Utility.h",
+ "llvm-project/llvm/lib/Demangle/DLangDemangle.cpp",
+ "llvm-project/llvm/lib/Demangle/Demangle.cpp",
+ "llvm-project/llvm/lib/Demangle/ItaniumDemangle.cpp",
+ "llvm-project/llvm/lib/Demangle/MicrosoftDemangle.cpp",
+ "llvm-project/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp",
+ "llvm-project/llvm/lib/Demangle/RustDemangle.cpp",
+ ]
+ deps = [ "//gn:default_deps" ]
+}
diff --git a/codereview.settings b/codereview.settings
index f6b44a52e..06bf28768 100644
--- a/codereview.settings
+++ b/codereview.settings
@@ -2,3 +2,4 @@
GERRIT_HOST: True
CODE_REVIEW_SERVER: https://android-review.googlesource.com
PROJECT: platform/external/perfetto
+USE_PYTHON3: True
diff --git a/debian/control b/debian/control
index 94a03bb38..00f1346bc 100644
--- a/debian/control
+++ b/debian/control
@@ -7,6 +7,7 @@ Build-Depends: debhelper (>= 13),
git,
libprotoc-dev,
ninja-build,
+ pandoc,
protobuf-compiler,
python3,
zlib1g-dev,
diff --git a/debian/perfetto.manpages b/debian/perfetto.manpages
new file mode 100644
index 000000000..07cb459ee
--- /dev/null
+++ b/debian/perfetto.manpages
@@ -0,0 +1 @@
+debian/perfetto.1
diff --git a/debian/postinst b/debian/postinst
index e6cdff56a..a583930bc 100755
--- a/debian/postinst
+++ b/debian/postinst
@@ -3,5 +3,7 @@ set -e
adduser --home /nonexistent --quiet --system --no-create-home --group traced
addgroup --quiet --system traced-consumer
usermod -a -G traced-consumer traced
+mkdir -m 755 /run/perfetto
+chown traced:traced /run/perfetto
#DEBHELPER#
diff --git a/debian/postrm b/debian/postrm
index efa15906d..8f8abc072 100755
--- a/debian/postrm
+++ b/debian/postrm
@@ -1,5 +1,5 @@
#!/bin/sh
set -e
-rm -f /tmp/perfetto-consumer /tmp/perfetto-producer
+rm -rf /run/perfetto
#DEBHELPER#
diff --git a/debian/rules b/debian/rules
index a081c5caf..f8d21e0c8 100755
--- a/debian/rules
+++ b/debian/rules
@@ -34,6 +34,8 @@ override_dh_auto_configure:
override_dh_auto_build:
ninja -C out/release perfetto traced traced_probes
+ pandoc docs/reference/perfetto-cli.md -s -t man --shift-heading-level-by=-1 >\
+ debian/perfetto.1
override_dh_auto_clean:
rm -rf out/release
diff --git a/docs/analysis/metrics.md b/docs/analysis/metrics.md
index 6798ae2f7..abc01f915 100644
--- a/docs/analysis/metrics.md
+++ b/docs/analysis/metrics.md
@@ -63,28 +63,272 @@ android_cpu {
}
```
-### Case for upstreaming
+## Metric development guide
-NOTE: Googlers: for internal usage of metrics in Google3 (i.e. metrics which are
-confidential), please see [this internal page](https://goto.google.com/viecd).
+As metric writing requires a lot of iterations to get right, there are several
+tips which make the experience a lot smoother.
-Authors are strongly encouraged to add all metrics derived on Perfetto traces to
-the Perfetto repo unless there is a clear usecase (e.g. confidentiality) why
-these metrics should not be publicly available.
+### Hot reloading metrics
+To obtain the fastest possible iteration time when developing metrics,
+it's possible to hot reload any changes to SQL; this will skip over both
+recompilation (for builtin metrics) and trace load (for both builtin and
+custom metrics).
-In return for upstreaming metrics, authors will have first class support for
-running metrics locally and the confidence that their metrics will remain stable
-as trace processor is developed.
+To do this, trace processor is started in *interactive mode* while
+still specifying command line flags about which metrics should be run and
+the paths of any extensions. Then, in the REPL shell, the commands
+`.load-metrics-sql` (which causes any SQL on disk to be re-read) and
+`.run-metrics` (to run the metrics and print the result).
-As well as scaling upwards while developing from running on a single trace
-locally to running on a large set of traces, the reverse is also very useful.
-When an anomaly is observed in the metrics of a lab benchmark, a representative
-trace can be downloaded and the same metric can be run locally in trace
-processor.
+For example, suppose we want to iterate on the `android_startup` metric. We
+can run the following commands from a Perfetto checkout:
+```python
+> ./tools/trace_processor --interactive \
+ --run_metrics android_startup \
+ --metric-extension src/trace_processor/metric@/
+ --dev \
+ <trace>
+android_startup {
+ <contents of startup metric>
+}
-Since the same code is running locally and remotely, developers can be confident
-in reproducing the issue and use the trace processor and/or the Perfetto UI to
-identify the problem.
+# Now make any changes you want to the SQL files related to the startup
+# metric. Even adding new files in the src/trace_processor/metric works.
+
+# Then, we can reload the changes using `.load-metrics-sql`.
+> .load-metrics-sql
+
+# We can rerun the changed metric using `.run-metrics`
+> .run-metrics
+android_startup {
+ <contents of changed startup metric>
+}
+```
+
+NOTE: see below about why `--dev` was required for this command.
+
+This also works for custom metrics specified on the command line:
+```python
+> ./tools/trace_processor -i --run_metrics /tmp/my_custom_metric.sql <trace>
+my_custom_metric {
+ <contents of my_custom_metric>
+}
+
+# Change the SQL file as before.
+
+> .load-metrics-sql
+> .run-metrics
+my_custom_metric {
+ <contents of changed my_custom_metric>
+}
+```
+
+WARNING: it is currently not possible to reload protos in the same way. If
+protos are changed, a recompile (for built-in metrics) and reinvoking
+trace processor is necessary to pick up the changes.
+
+WARNING: Deleted files from `--metric-extension` folders are *not* removed
+and will remain available e.g. to RUN_METRIC invocations.
+
+### Modifying built-in metric SQL without recompiling
+It is possible to override the SQL of built-in metrics at runtime without
+needing to recompile trace processor. To do this, the flag `--metric-extension`
+needs to be specified with the disk path where the built-metrics live and the
+special string `/` for the virtual path.
+
+For example, from inside a Perfetto checkout:
+```python
+> ./tools/trace_processor \
+ --run_metrics android_cpu \
+ --metric-extension src/trace_processor/metrics@/
+ --dev
+ <trace>
+```
+This will run the CPU metric using the live SQL in the repo *not* the SQL
+defintion built into the binary.
+
+NOTE: protos are *not* overriden in the same way - if any proto messages are
+changed a recompile of trace processor is required for the changes to be
+available.
+
+NOTE: the `--dev` flag is required for the use of this feature. This
+flag ensures that this feature is not accidentally in production as it is only
+intended for local development.
+
+WARNING: protos are *not* overriden in the same way - if any proto messages are
+changed a recompile of trace processor is required for the changes to be
+available.
+
+## Metric helper functions
+
+There are several useful helpers functions which are available when writing a metric.
+
+### CREATE_FUNCTION.
+`CREATE_FUNCTION` allows you to define a parameterized SQL statement which
+is executable as a function. The inspiration from this function is the
+`CREATE FUNCTION` syntax which is available in other SQL engines (e.g.
+[Postgres](https://www.postgresql.org/docs/current/sql-createfunction.html)).
+
+NOTE: CREATE_FUNCTION only supports returning *exactly* a single value (i.e.
+single row and single column). For returning multiple a single row with
+multiple columns or multiples rows, see `CREATE_VIEW_FUNCTION` instead.
+
+Usage of `CREATE_FUNCTION` is as follows:
+```sql
+-- First, we define the function we'll use in the following statement.
+SELECT CREATE_FUNCTION(
+ -- First argument: prototype of the function; this is very similar to
+ -- function definitions in other languages - you set the function name
+ -- (IS_TS_IN_RANGE in this example) and the arguments
+ -- (ts, begin_ts and end_ts) along with their types (LONG for all
+ -- arguments here).
+ 'IS_TS_IN_RANGE(ts LONG, begin_ts LONG, end_ts LONG)',
+ -- Second argument: the return type of the function. Only single values
+ -- can be returned in CREATE_FUNCTION. See CREATE_VIEW_FUNCTION for defining
+ -- a function returning multiple rows/columns.
+ 'BOOL',
+ -- Third argument: the SQL body of the function. This should always be a
+ -- SELECT statement (even if you're not selecting from a table as in this
+ -- example). Arguments can be accessed by prefixing argument names
+ -- with $ (e.g. $ts, $begin_ts, $end_ts).
+ 'SELECT $ts >= $begin_ts AND $ts <= $end_ts'
+);
+
+-- Now we can actually use the function in queries as if it was any other
+-- function.
+
+-- For example, it can appear in the SELECT to produce a column:
+SELECT ts, IS_TS_IN_RANGE(slice.ts, 100000, 200000) AS in_range
+FROM slice
+
+-- It can also appear in a where clause:
+SELECT ts
+FROM counter
+WHERE IS_TS_IN_RANGE(counter.ts, 100000, 200000) AS in_range
+
+-- It can even appear in a join on clause:
+SELECT slice.ts
+FROM launches
+JOIN slice ON IS_TS_IN_RANGE(slice.ts, launches.ts, launches.end_ts)
+```
+
+### CREATE_VIEW_FUNCTION.
+Similar to `CREATE_FUNCTION`, `CREATE_VIEW_FUNCTION` can be used to
+define a parameterized SQL statement but returning multiple rows and
+columns. Such functions can be invoked any place where a table or
+view is used.
+
+Usage of `CREATE_VIEW_FUNCTION` is as follows:
+```sql
+-- First, we define the view function we'll use in the following
+-- statement.
+SELECT CREATE_VIEW_FUNCTION(
+ -- First argument: prototype of the function; this is very similar to
+ -- function definitions in other languages - you set the function name
+ -- (NAMED_SLICE_IN_RANGE in this example) and the arguments
+ -- (name_glob, begin_ts and end_ts) along with their types (STRING and
+ -- LONG for arguments here).
+ 'NAMED_SLICE_IN_RANGE(name_glob STRING, begin_ts LONG, end_ts LONG)',
+ -- Second argument: the columns returned by the function; both the
+ -- name and type is specified.
+ 'id INT, ts LONG, ts_end LONG, name STRING, track_id STRING',
+ -- Third argument: the SQL body of the function. This should always be a
+ -- SELECT statement. Arguments can be accessed by prefixing argument names
+ -- with $ (e.g. $ts, $begin_ts, $end_ts).
+ 'SELECT id, ts, ts + dur as ts_end, name, track_id
+ FROM slice
+ WHERE name GLOB $name_glob AND ts >= $begin_ts and ts <= $end_ts'
+);
+
+-- Now we can use the function in queries in the same way we'd query a
+-- table or view.
+SELECT id, ts, ts_end, name
+FROM NAMED_SLICE_IN_RANGE('launching:*', 12345, 67890);
+
+-- This is exactly equivalent to the query:
+SELECT id, ts, ts + dur as ts_end, name
+FROM slice
+WHERE name GLOB 'launching:*' AND ts >= 12345 AND ts <= 67890;
+
+-- View functions can also be used in joins.
+SELECT sl.id, sl.ts, sl.ts_end, sl.name
+FROM trace_bounds AS b
+JOIN NAMED_SLICE_IN_RANGE('launching:*', b.start_ts, b.end_ts) AS sl;
+```
+
+### RUN_METRIC
+`RUN_METRIC` allows you to run another metric file. This allows you to use views
+or tables defined in that file without repeatition.
+
+Conceptually, `RUN_METRIC` adds *composability* for SQL queries to break a big SQL
+metric into smaller, reusable files. This is similar to how functions allow decomposing
+large chunks in traditional programming languages.
+
+A simple usage of `RUN_METRIC` would be as follows:
+
+In file android/foo.sql:
+```sql
+CREATE VIEW view_defined_in_foo AS
+SELECT *
+FROM slice
+LIMIT 1;
+```
+
+In file android/bar.sql
+```sql
+SELECT RUN_METRIC('android/foo.sql');
+
+CREATE VIEW view_depending_on_view_from_foo AS
+SELECT *
+FROM view_defined_in_foo
+LIMIT 1;
+```
+
+`RUN_METRIC` also supports running *templated* metric files. Here's an example of
+what that looks like:
+
+In file android/slice_template.sql:
+```sql
+CREATE VIEW {{view_name}} AS
+SELECT *
+FROM slice
+WHERE slice.name = '{{slice_name}}';
+```
+
+In file android/metric.sql:
+```sql
+SELECT RUN_METRIC(
+ 'android/slice_template.sql',
+ 'view_name', 'choreographer_slices',
+ 'slice_name', 'Chroeographer#doFrame'
+);
+
+CREATE VIEW long_choreographer_slices AS
+SELECT *
+FROM choreographer_slices
+WHERE dur > 1e6;
+```
+
+When running `slice_template.sql`, trace processor will substitute the arguments
+passed to `RUN_METRIC` into the templated file *before* executing the file using
+SQLite.
+
+In other words, this is what SQLite sees and executes in practice for the above
+example:
+```sql
+CREATE VIEW choreographer_slices AS
+SELECT *
+FROM slice
+WHERE slice.name = 'Chroeographer#doFrame';
+
+CREATE VIEW long_choreographer_slices AS
+SELECT *
+FROM choreographer_slices
+WHERE dur > 1e6;
+```
+
+The syntax for templated metric files is essentially a highly simplified version of
+[Jinja's](https://jinja.palletsprojects.com/en/3.0.x/) syntax.
## Walkthrough: prototyping a metric
@@ -296,7 +540,7 @@ GROUP BY process.name
ORDER BY cpu_time_ms DESC
LIMIT 5;
-CREATE top_five_processes_output AS
+CREATE VIEW top_five_processes_output AS
SELECT TopProcesses(
'process_info', (
SELECT RepeatedField(
@@ -366,7 +610,30 @@ If everything went successfully, the following output should be visible (specifi
}
```
-### Next steps
+## Next steps
* The [common tasks](/docs/contributing/common-tasks.md) page gives a list of
steps on how new metrics can be added to the trace processor.
+
+## Appendix: Case for upstreaming
+
+NOTE: Googlers: for internal usage of metrics in Google3 (i.e. metrics which are
+confidential), please see [this internal page](https://goto.google.com/viecd).
+
+Authors are strongly encouraged to add all metrics derived on Perfetto traces to
+the Perfetto repo unless there is a clear usecase (e.g. confidentiality) why
+these metrics should not be publicly available.
+
+In return for upstreaming metrics, authors will have first class support for
+running metrics locally and the confidence that their metrics will remain stable
+as trace processor is developed.
+
+As well as scaling upwards while developing from running on a single trace
+locally to running on a large set of traces, the reverse is also very useful.
+When an anomaly is observed in the metrics of a lab benchmark, a representative
+trace can be downloaded and the same metric can be run locally in trace
+processor.
+
+Since the same code is running locally and remotely, developers can be confident
+in reproducing the issue and use the trace processor and/or the Perfetto UI to
+identify the problem.
diff --git a/docs/analysis/trace-processor.md b/docs/analysis/trace-processor.md
index f12afb6fd..6287d5a83 100644
--- a/docs/analysis/trace-processor.md
+++ b/docs/analysis/trace-processor.md
@@ -49,7 +49,7 @@ The trace processor is embedded in a wide variety of trace analysis tools, inclu
* [trace_processor](/docs/analysis/trace-processor.md), a standalone binary
providing a shell interface (and the reference embedder).
* [Perfetto UI](https://ui.perfetto.dev), in the form of a WebAssembly module.
-* [Android Graphics Inspector](https://gpuinspector.dev/).
+* [Android GPU Inspector](https://gpuinspector.dev/).
* [Android Studio](https://developer.android.com/studio/).
## Concepts
@@ -184,7 +184,7 @@ greater than 1000
```sql
SELECT upid
FROM counter
-JOIN process_counter_track ON process_counter_track.id = slice.track_id
+JOIN process_counter_track ON process_counter_track.id = counter.track_id
WHERE process_counter_track.name = 'mem.swap' AND value > 1000
```
@@ -244,6 +244,41 @@ WHERE slice.name = 'measure'
GROUP BY thread_name
```
+## Helper functions
+Helper functions are functions built into C++ which reduce the amount of
+boilerplate which needs to be written in SQL.
+
+### Extract args
+`EXTRACT_ARG` is a helper function which retreives a property of an
+event (e.g. slice or counter) from the `args` table.
+
+It takes an `arg_set_id` and `key` as input and returns the value looked
+up in the `args` table.
+
+For example, to retrieve the `prev_comm` field for `sched_switch` events in
+the `raw` table.
+```sql
+SELECT EXTRACT_ARG(arg_set_id, 'prev_comm')
+FROM raw
+WHERE name = 'sched_switch'
+```
+
+Behind the scenes, the above query would desugar to the following:
+```sql
+SELECT
+ (
+ SELECT string_value
+ FROM args
+ WHERE key = 'prev_comm' AND args.arg_set_id = raw.arg_set_id
+ )
+FROM raw
+WHERE name = 'sched_switch'
+```
+
+NOTE: while convinient, `EXTRACT_ARG` can inefficient compared to a `JOIN`
+when working with very large tables; a function call is required for every
+row which will be slower than the batch filters/sorts used by `JOIN`.
+
## Operator tables
SQL queries are usually sufficient to retrieve data from trace processor.
Sometimes though, certain constructs can be difficult to express pure SQL.
@@ -264,26 +299,27 @@ partitions before computing the intersection.
-- Get all the scheduling slices
CREATE VIEW sp_sched AS
SELECT ts, dur, cpu, utid
-FROM sched
+FROM sched;
-- Get all the cpu frequency slices
CREATE VIEW sp_frequency AS
SELECT
ts,
- lead(ts) OVER (PARTITION BY cpu ORDER BY ts) - ts as dur,
+ lead(ts) OVER (PARTITION BY track_id ORDER BY ts) - ts as dur,
cpu,
value as freq
FROM counter
+JOIN cpu_counter_track ON counter.track_id = cpu_counter_track.id;
-- Create the span joined table which combines cpu frequency with
-- scheduling slices.
CREATE VIRTUAL TABLE sched_with_frequency
-USING SPAN_JOIN(sp_sched PARTITIONED cpu, sp_frequency PARTITIONED cpu)
+USING SPAN_JOIN(sp_sched PARTITIONED cpu, sp_frequency PARTITIONED cpu);
-- This span joined table can be queried as normal and has the columns from both
-- tables.
SELECT ts, dur, cpu, utid, freq
-FROM sched_with_frequency
+FROM sched_with_frequency;
```
NOTE: A partition can be specified on neither, either or both tables. If
@@ -294,6 +330,24 @@ the same table in the same partition *cannot* overlap. For performance
reasons, span join does not attempt to detect and error out in this situation;
instead, incorrect rows will silently be produced.
+Left and outer span joins are also supported; both function analogously to
+the left and outer joins from SQL.
+```sql
+-- Left table partitioned + right table unpartitioned.
+CREATE VIRTUAL TABLE left_join
+USING SPAN_LEFT_JOIN(table_a PARTITIONED a, table_b);
+
+-- Both tables unpartitioned.
+CREATE VIRTUAL TABLE outer_join
+USING SPAN_OUTER_JOIN(table_x, table_y);
+```
+
+NOTE: there is a subtlety if the partitioned table is empty and is
+either a) part of an outer join b) on the right side of a left join.
+In this case, *no* slices will be emitted even if the other table is
+non-empty. This approach was decided as being the most natural
+after considering how span joins are used in practice.
+
### Ancestor slice
ancestor_slice is a custom operator table that takes a
[slice table's id column](/docs/analysis/sql-tables.autogen#slice) and computes
@@ -319,6 +373,32 @@ FROM
ancestor_slice(interesting_slices.id) AS ancestor ON ancestor.depth = 0
```
+### Ancestor slice by stack
+ancestor_slice_by_stack is a custom operator table that takes a
+[slice table's stack_id column](/docs/analysis/sql-tables.autogen#slice) and
+finds all slice ids with that stack_id, then, for each id it computes
+all the ancestor slices similarly to
+[ancestor_slice](/docs/analysis/trace-processor#ancestor-slice).
+
+The returned format is the same as the
+[slice table](/docs/analysis/sql-tables.autogen#slice)
+
+For example, the following finds the top level slice of all slices with the
+given name.
+
+```sql
+CREATE VIEW interesting_stack_ids AS
+SELECT stack_id
+FROM slice WHERE name LIKE "%interesting slice name%";
+
+SELECT
+ *
+FROM
+ interesting_stack_ids LEFT JOIN
+ ancestor_slice_by_stack(interesting_stack_ids.stack_id) AS ancestor
+ ON ancestor.depth = 0
+```
+
### Descendant slice
descendant_slice is a custom operator table that takes a
[slice table's id column](/docs/analysis/sql-tables.autogen#slice) and
@@ -347,6 +427,32 @@ SELECT
FROM interesting_slices
```
+### Descendant slice by stack
+descendant_slice_by_stack is a custom operator table that takes a
+[slice table's stack_id column](/docs/analysis/sql-tables.autogen#slice) and
+finds all slice ids with that stack_id, then, for each id it computes
+all the descendant slices similarly to
+[descendant_slice](/docs/analysis/trace-processor#descendant-slice).
+
+The returned format is the same as the
+[slice table](/docs/analysis/sql-tables.autogen#slice)
+
+For example, the following finds the next level descendant of all slices with
+the given name.
+
+```sql
+CREATE VIEW interesting_stacks AS
+SELECT stack_id, depth
+FROM slice WHERE name LIKE "%interesting slice name%";
+
+SELECT
+ *
+FROM
+ interesting_stacks LEFT JOIN
+ descendant_slice_by_stack(interesting_stacks.stack_id) AS descendant
+ ON descendant.depth = interesting_stacks.depth + 1
+```
+
### Connected/Following/Preceding flows
DIRECTLY_CONNECTED_FLOW, FOLLOWING_FLOW and PRECEDING_FLOW are custom operator
@@ -438,7 +544,7 @@ Creating derived events is tied very closely to
create higher-level abstractions from raw events as intermediate artifacts.
From previous example, the
-[startup metric](/src/trace_processor/metrics/android/android_startup.sql)
+[startup metric](/src/trace_processor/metrics/sql/android/android_startup.sql)
creates the exact `launching` slice we want to display in the UI.
The other benefit of aligning the two is that changes in metrics are
@@ -477,24 +583,24 @@ NOTE: The API is only compatible with Python3.
```python
from perfetto.trace_processor import TraceProcessor
# Initialise TraceProcessor with a trace file
-tp = TraceProcessor(file_path='trace.perfetto-trace')
+tp = TraceProcessor(trace='trace.perfetto-trace')
```
NOTE: The TraceProcessor can be initialized in a combination of ways including:
<br> - An address at which there exists a running instance of `trace_processor` with a
- loaded trace (e.g. `TraceProcessor(addr='localhost:9001')`)
+ loaded trace (e.g.`TraceProcessor(addr='localhost:9001')`)
<br> - An address at which there exists a running instance of `trace_processor` and
needs a trace to be loaded in
- (e.g. `TraceProcessor(addr='localhost:9001', file_path='trace.perfetto-trace')`)
+ (e.g. `TraceProcessor(trace='trace.perfetto-trace', addr='localhost:9001')`)
<br> - A path to a `trace_processor` binary and the trace to be loaded in
- (e.g. `TraceProcessor(bin_path='./trace_processor', file_path='trace.perfetto-trace')`)
+ (e.g. `TraceProcessor(trace='trace.perfetto-trace', config=TraceProcessorConfig(bin_path='./trace_processor'))`)
### API
The `trace_processor.api` module contains the `TraceProcessor` class which provides various
functions that can be called on the loaded trace. For more information on how to use
-these functions, see this [`example`](/src/trace_processor/python/example.py).
+these functions, see this [`example`](/python/example.py).
#### Query
The query() function takes an SQL query as input and returns an iterator through the rows
@@ -502,7 +608,7 @@ of the result.
```python
from perfetto.trace_processor import TraceProcessor
-tp = TraceProcessor(file_path='trace.perfetto-trace')
+tp = TraceProcessor(trace='trace.perfetto-trace')
qr_it = tp.query('SELECT ts, dur, name FROM slice')
for row in qr_it:
@@ -521,7 +627,7 @@ The QueryResultIterator can also be converted to a Pandas DataFrame, although th
requires you to have both the `NumPy` and `Pandas` modules installed.
```python
from perfetto.trace_processor import TraceProcessor
-tp = TraceProcessor(file_path='trace.perfetto-trace')
+tp = TraceProcessor(trace='trace.perfetto-trace')
qr_it = tp.query('SELECT ts, dur, name FROM slice')
qr_df = qr_it.as_pandas_dataframe()
@@ -542,7 +648,7 @@ Furthermore, you can use the query result in a Pandas DataFrame format to easily
make visualisations from the trace data.
```python
from perfetto.trace_processor import TraceProcessor
-tp = TraceProcessor(file_path='trace.perfetto-trace')
+tp = TraceProcessor(trace='trace.perfetto-trace')
qr_it = tp.query('SELECT ts, value FROM counter WHERE track_id=50')
qr_df = qr_it.as_pandas_dataframe()
@@ -559,7 +665,7 @@ The metric() function takes in a list of trace metrics and returns the results a
```python
from perfetto.trace_processor import TraceProcessor
-tp = TraceProcessor(file_path='trace.perfetto-trace')
+tp = TraceProcessor(trace='trace.perfetto-trace')
ad_cpu_metrics = tp.metric(['android_cpu'])
print(ad_cpu_metrics)
diff --git a/docs/case-studies/android-boot-tracing.md b/docs/case-studies/android-boot-tracing.md
new file mode 100644
index 000000000..3abc76a3d
--- /dev/null
+++ b/docs/case-studies/android-boot-tracing.md
@@ -0,0 +1,79 @@
+# Recording traces on Android boot
+
+Since Android 13 (T), perfetto can be configured to automatically start
+recording traces on boot. This can be useful to profile the boot process.
+
+## Steps
+
+* Create a file with the desired [trace configuration](/docs/concepts/config.md)
+ in Text format (not binary). Example (more in [/test/configs/](/test/configs/)):
+ ```
+ # One buffer allocated within the central tracing binary for the entire trace,
+ # shared by the two data sources below.
+ buffers {
+ size_kb: 32768
+ fill_policy: DISCARD
+ }
+
+ # Ftrace data from the kernel, mainly the process scheduling events.
+ data_sources {
+ config {
+ name: "linux.ftrace"
+ target_buffer: 0
+ ftrace_config {
+ ftrace_events: "sched_switch"
+ ftrace_events: "sched_waking"
+ ftrace_events: "sched_wakeup_new"
+
+ ftrace_events: "task_newtask"
+ ftrace_events: "task_rename"
+
+ ftrace_events: "sched_process_exec"
+ ftrace_events: "sched_process_exit"
+ ftrace_events: "sched_process_fork"
+ ftrace_events: "sched_process_free"
+ ftrace_events: "sched_process_hang"
+ ftrace_events: "sched_process_wait"
+ }
+ }
+ }
+
+ # Resolve process commandlines and parent/child relationships, to better
+ # interpret the ftrace events, which are in terms of pids.
+ data_sources {
+ config {
+ name: "linux.process_stats"
+ target_buffer: 0
+ }
+ }
+
+ # 10s trace, but can be stopped prematurely via `adb shell pkill -u perfetto`.
+ duration_ms: 10000
+ ```
+* Put the file on the device at `/data/misc/perfetto-configs/boottrace.pbtxt`:
+ ```
+ adb push <yourfile> /data/misc/perfetto-configs/boottrace.pbtxt
+ ```
+* Enable the `perfetto_trace_on_boot` service:
+ ```
+ adb shell setprop persist.debug.perfetto.boottrace 1
+ ```
+ The property is reset on boot. In order to trace the next boot, the command
+ must be reissued.
+* Reboot the device.
+* The output trace will be written at
+ `/data/misc/perfetto-traces/boottrace.perfetto-trace`. The file will be
+ removed before a new trace is started.
+ ```
+ adb pull /data/misc/perfetto-traces/boottrace.perfetto-trace
+ ```
+ **N.B.:** The file will appear after the recording has stopped (be sure to set
+ `duration_ms` to a reasonable value in the config) or after the first
+ `flush_period_ms`.
+* `boottrace.perfetto-trace` can now be opened in
+ [ui.perfetto.dev](https://ui.perfetto.dev/)
+
+## Implementation details
+* The trace will start only after persistent properties are loaded, which
+ happens after /data has been mounted.
+* The command to start the trace is implemented as oneshot init service.
diff --git a/docs/concepts/config.md b/docs/concepts/config.md
index 99f4cbc27..43082b0b8 100644
--- a/docs/concepts/config.md
+++ b/docs/concepts/config.md
@@ -424,10 +424,6 @@ the trigger is hit or the `trigger_timeout_ms` timeout is hit.
Example config:
```protobuf
-# If no trigger is hit, the trace will end without having recorded any data
-# after 30s.
-trigger_timeout_ms: 30000
-
# If the "myapp_is_slow" is hit, the trace starts recording data and will be
# stopped after 5s.
trigger_config {
@@ -436,6 +432,9 @@ trigger_config {
name: "myapp_is_slow"
stop_delay_ms: 5000
}
+ # If no trigger is hit, the trace will end without having recorded any data
+ # after 30s.
+ trigger_timeout_ms: 30000
}
# The rest of the config is as usual.
diff --git a/docs/contributing/build-instructions.md b/docs/contributing/build-instructions.md
index 0c129021c..e439315df 100644
--- a/docs/contributing/build-instructions.md
+++ b/docs/contributing/build-instructions.md
@@ -7,64 +7,105 @@ A read-only mirror is also available at https://github.com/google/perfetto .
Perfetto can be built both from the Android tree (AOSP) and standalone.
Standalone builds are meant only for local testing and are not shipped.
-Due to the reduced dependencies they are faster to iterate on and the
-suggested way to work on Perfetto.
+Due to the reduced dependencies, the standalone workflow is faster to iterate on
+and the suggested way to work on Perfetto, unless you are working on code that
+has non-NDK depedencies into Android internals. Profilers and internal HAL/AIDL
+dependencies will not be built in the standalone build.
-## Get the code
+If you are chromium contributor, AOSP is still the place you should send CLs to.
+The code inside chromium's
+[third_party/perfetto](https://source.chromium.org/chromium/chromium/src/+/main:third_party/perfetto/?q=f:third_party%2Fperfetto&ss=chromium)
+is a direct mirror of the AOSP repo. The
+[AOSP->Chromium autoroller](https://autoroll.skia.org/r/perfetto-chromium-autoroll)
+takes care of keeping chromium's DEPS up to date.
-**Standalone checkout**:
+## Standalone builds
+
+#### Get the code
```bash
git clone https://android.googlesource.com/platform/external/perfetto/
```
-**Android tree**:
-
-Perfetto lives in [`external/perfetto` in the AOSP tree](https://cs.android.com/android/platform/superproject/+/master:external/perfetto/).
-
-## Prerequisites
-
-**Standalone checkout**:
-
-All dependent libraries are self-hosted and pulled through:
+#### Pull dependent libraries and toolchains
```bash
-tools/install-build-deps [--android] [--ui]
+tools/install-build-deps [--android] [--ui] [--linux-arm]
```
-**Android tree**:
+`--android` will pull the Android NDK, emulator and other deps required
+to build for `target_os = "android"`.
+
+`--ui` will pull NodeJS and all the NPM modules required to build the
+Web UI. See the [UI Development](#ui-development) section below for more.
-See https://source.android.com/setup
+`--linux-arm` will pull the sysroots for cross-compiling for Linux ARM/64.
-## Building
+WARNING: Note that if you're using an M1 or any later ARM Mac, your Python
+version should be at least 3.9.1 to work around
+[this Python Bug](https://bugs.python.org/issue42704).
-**Standalone checkout**:
+#### Generate the build files via GN
-If you are a chromium developer and have depot_tools installed you can avoid
-the `tools/` prefix below and just use gn/ninja from depot_tools.
+Perfetto uses [GN](https://gn.googlesource.com/gn/+/HEAD/docs/quick_start.md)
+as primary build system. See the [Build files](#build-files) section below for
+more.
-`$ tools/gn args out/android` to generate build files and enter in the editor:
+```bash
+tools/gn args out/android
+```
+
+This will open an editor to customize the GN args. Enter:
```python
-target_os = "android" # Only when building for Android
+# Set only when building for Android, omit when building for linux, mac or win.
+target_os = "android"
target_cpu = "arm" / "arm64" / "x64"
+
is_debug = true / false
-cc_wrapper = "ccache" # Optionally speed repeated builds with ccache
+cc_wrapper = "ccache" # [Optional] speed up rebuilds with ccache.
```
-(See the [Build Configurations](#build-configurations) section below for more)
+See the [Build Configurations](#build-configurations) and
+[Building on Windows](#building-on-windows) sections below for more.
+
+TIP: If you are a chromium developer and have depot_tools installed you can
+avoid the `tools/` prefix below and just use gn/ninja from depot_tools.
+
+#### Build native C/C++ targets
```bash
+# This will build all the targets.
tools/ninja -C out/android
+
+# Alternatively, list targets explicitly.
+tools/ninja -C out/android \
+ traced \ # Tracing service.
+ traced_probes \ # Ftrace interop and /proc poller.
+ perfetto \ # Cmdline client.
+ trace_processor_shell \ # Trace parsing.
+ trace_to_text # Trace conversion.
+...
```
-**Android tree**
+## Android tree builds
+
+Follow these instructions if you are an AOSP contributor.
+
+The source code lives in [`external/perfetto` in the AOSP tree](https://cs.android.com/android/platform/superproject/+/master:external/perfetto/).
-`mmma external/perfetto`
-or
-`m perfetto traced traced_probes`
+Follow the instructions on https://source.android.com/setup/build/building .
+
+Then:
+
+```bash
+mmma external/perfetto
+# or
+m traced traced_probes perfetto
+```
This will generate artifacts `out/target/product/XXX/system/`.
+
Executables and shared libraries are stripped by default by the Android build
system. The unstripped artifacts are kept into `out/target/product/XXX/symbols`.
@@ -100,19 +141,6 @@ The server supports live reloading of CSS and TS/JS contents. Whenever a ui
source file is changed it, the script will automatically re-build it and show a
prompt in the web page.
-## IDE setup
-
-Use a following command in the checkout directory in order to generate the
-compilation database file:
-
-```bash
-tools/gn gen out/default --export-compile-commands
-```
-
-After generating, it can be used in CLion (File -> Open -> Open As Project),
-Visual Studio Code with C/C++ extension and any other tool and editor that
-supports the compilation database format.
-
## Build files
The source of truth of our build file is in the BUILD.gn files, which are based
@@ -120,6 +148,8 @@ on [GN][gn-quickstart].
The Android build file ([Android.bp](/Android.bp)) is autogenerated from the GN
files through `tools/gen_android_bp`, which needs to be invoked whenever a
change touches GN files or introduces new ones.
+Likewise, the Bazel build file ([BUILD](/BUILD)) is autogenerated through the
+`tools/gen_bazel` script.
A presubmit check checks that the Android.bp is consistent with GN files when
submitting a CL through `git cl upload`.
@@ -130,10 +160,11 @@ Android.bp file. If you are adding a new target, add a new entry to the
## Supported platforms
-**Linux desktop** (Debian Rodete)
+**Linux desktop** (Debian Testing/Rodete)
- Hermetic clang + libcxx toolchain (both following chromium's revisions)
- GCC-7 and libstdc++ 6
+- Cross-compiling for arm and arm64 (more below).
**Android**
@@ -142,15 +173,112 @@ Android.bp file. If you are adding a new target, add a new entry to the
**Mac**
-- XCode 9 / clang (currently maintained best-effort).
+- XCode 9 / clang (maintained best-effort).
**Windows**
-Windows builds are not currently supported when using the standalone checkout
-and GN. Windows is supported only for a subset of the targets (mainly
-`trace_processor` and the in-process version of the
-[Tracing SDK](/docs/instrumentation/tracing-sdk.md)) in two ways:
-(1) when building through Bazel; (2) when building as part of Chromium.
+- Windows 10 with either MSVC 2019 or clang-cl (maintained best-effort).
+
+### Building on Windows
+
+Building on Windows is possible using both the MSVC 2019 compiler (you don't
+need the full IDE, just the build tools) or the LLVM clang-cl compiler.
+
+The Windows support in standalone builds has been introduced in v16 by
+[r.android.com/1711913](https://r.android.com/1711913).
+
+clang-cl support is more stable because that build configuration is actively
+covered by the Chromium project (Perfetto rolls into chromium and underpins
+chrome://tracing). The MSVC build is maintained best-effort.
+
+The following targets are supported on Windows:
+
+- `trace_processor_shell`: the trace importer and SQL query engine.
+- `trace_to_text`: the trace conversion tool.
+- `traced` and `perfetto`: the tracing service and cmdline client. They use an
+ alternative implementation of the [inter-process tracing protocol](/docs/design-docs/api-and-abi.md#tracing-protocol-abi)
+ based on a TCP socket and named shared memory. This configuration is only for
+ testing / benchmarks and is not shipped in production.
+ Googlers: see [go/perfetto-win](http://go/perfetto-win) for details.
+- `perfetto_unittests` / `perfetto_integrationtests`: although they support only
+ the subset of code that is supported on Windows (e.g. no ftrace).
+
+It is NOT possible to build the Perfetto UI from Windows.
+
+#### Prerequisites
+
+You need all of these both for MSVC and clang-cl:
+
+- [Build Tools for Visual Studio 2019](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019)
+- [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk/)
+- [Python 3](https://www.python.org/downloads/windows/)
+
+The [`win_find_msvc.py`](/gn/standalone/toolchain/win_find_msvc.py) script will
+locate the higest version numbers available from
+`C:\Program Files (x86)\Windows Kits\10` and
+`C:\Program Files (x86)\Microsoft Visual Studio\2019`.
+
+#### Pull dependent libraries and toolchains
+
+```bash
+# This will download also the LLVM clang-cl prebuilt used by chromium.
+python3 tools/install-build-deps
+```
+
+#### Generate build files
+
+```bash
+python3 tools/gn gen out/win
+```
+
+In the editor type:
+
+```bash
+is_debug = true | false
+
+is_clang = true # Will use the hermetic clang-cl toolchain.
+# or
+is_clang = false # Will use MSVC 2019.
+```
+
+#### Build
+
+```bash
+python3 tools/ninja -C out/win perfetto traced trace_processor_shell
+```
+
+### Cross-compiling for Linux ARM/64
+
+When cross-compiling for Linux you will need a sysroot. You have two options:
+
+#### 1. Use the built-in sysroots based on Debian Sid
+
+```bash
+tools/install-build-deps --linux-arm
+```
+
+Then set the following GN args:
+
+```python
+target_os = "linux"
+target_cpu = "arm"
+# or
+target_cpu = "arm64"
+```
+
+#### 2. Use your own sysroot
+
+In this case you need to manually specify the sysroot location and the
+toolchain prefix triplet to use.
+
+```python
+target_os = "linux"
+target_sysroot = "/path/to/sysroot"
+target_triplet = "aarch64-linux-gnu" # Or any other supported triplet.
+```
+
+For more details see the [Using cutom toolchains](#custom-toolchain) section
+below.
## Build configurations
@@ -304,3 +432,73 @@ extra_target_ldflags="${LDFLAGS}"
```
[gn-quickstart]: https://gn.googlesource.com/gn/+/master/docs/quick_start.md
+
+## IDE setup
+
+Use a following command in the checkout directory in order to generate the
+compilation database file:
+
+```bash
+tools/gn gen out/default --export-compile-commands
+```
+
+After generating, it can be used in CLion (File -> Open -> Open As Project),
+Visual Studio Code with C/C++ extension and any other tool and editor that
+supports the compilation database format.
+
+#### Useful extensions
+
+If you are using VS Code we suggest the following extensions:
+
+- [Clang-Format](https://marketplace.visualstudio.com/items?itemName=xaver.clang-format)
+- [C/C++](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)
+- [clangd](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd)
+- [Native Debug](https://marketplace.visualstudio.com/items?itemName=webfreak.debug)
+- [GNFormat](https://marketplace.visualstudio.com/items?itemName=persidskiy.vscode-gnformat)
+- [ESlint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)
+- [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint)
+
+#### Useful settings
+
+In `.vscode/settings.json`:
+
+```json
+{
+ "C_Cpp.clang_format_path": "${workspaceRoot}/buildtools/mac/clang-format",
+ "C_Cpp.clang_format_sortIncludes": true,
+ "files.exclude": {
+ "out/*/obj": true,
+ "out/*/gen": true,
+ },
+ "clangd.arguments": [
+ "--compile-commands-dir=${workspaceFolder}/out/mac_debug",
+ "--completion-style=detailed",
+ "--header-insertion=never"
+ ],
+}
+```
+
+Replace `/mac/` with `/linux64/` on Linux.
+
+### Debugging with VSCode
+
+Edit `.vscode/launch.json`:
+
+```json
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "request": "launch",
+ "type": "cppdbg",
+ "name": "Perfetto unittests",
+ "program": "${workspaceRoot}/out/mac_debug/perfetto_unittests",
+ "args": ["--gtest_filter=TracingServiceImplTest.StopTracingTriggerRingBuffer"],
+ "cwd": "${workspaceFolder}/out/mac_debug",
+ "MIMode": "lldb",
+ },
+ ]
+}
+```
+
+Then open the command palette `Meta`+`Shift`+`P` -> `Debug: Start debugging`.
diff --git a/docs/contributing/common-tasks.md b/docs/contributing/common-tasks.md
index d0724c948..39a36c779 100644
--- a/docs/contributing/common-tasks.md
+++ b/docs/contributing/common-tasks.md
@@ -78,6 +78,7 @@ The schema of the `<metric name>_event` table/view is as follows:
| `dur` | `int64` | Mandatory for slice, NULL for counter | The duration of the slice |
| `slice_name` | `string` | Mandatory for slice, NULL for counter | The name of the slice |
| `value` | `double` | Mandatory for counter, NULL for slice | The value of the counter |
+| `group_name` | `string` | Optional | Name of the track group under which the track appears. All tracks with the same `group_name` are placed under the same group by that name. Tracks that lack this field or have NULL value in this field are displayed without any grouping. |
#### Known issues:
diff --git a/docs/contributing/embedding.md b/docs/contributing/embedding.md
index ad3ac8859..dbf6c5691 100644
--- a/docs/contributing/embedding.md
+++ b/docs/contributing/embedding.md
@@ -42,7 +42,7 @@ Any registered metrics can be computed using using the `ComputeMetric` function.
Metrics can also be registered at run time using the `RegisterMetric` and `ExtendMetricsProto` functions. These can subsequently be executed with `ComputeMetric`.
-WARNING: embedders should ensure that the path of any registered metric is consistent with the the name used to execute the metric and output view in the SQL.
+WARNING: embedders should ensure that the path of any registered metric is consistent with the name used to execute the metric and output view in the SQL.
### Annotations
diff --git a/docs/contributing/getting-started.md b/docs/contributing/getting-started.md
index 8cb27ec1c..9696e7e08 100644
--- a/docs/contributing/getting-started.md
+++ b/docs/contributing/getting-started.md
@@ -47,8 +47,6 @@ can be bypassed, as those are not built as part of the Android tree.
## Community
You can reach us on our [Discord channel](https://discord.gg/35ShE3A).
-If you prefer using IRC we have an experimental Discord <> IRC bridge
-synced with `#perfetto-dev` on [Freenode](https://webchat.freenode.net/).
Mailing list: https://groups.google.com/forum/#!forum/perfetto-dev
diff --git a/docs/contributing/sdk-releasing.md b/docs/contributing/sdk-releasing.md
index baccd058e..5e62cca70 100644
--- a/docs/contributing/sdk-releasing.md
+++ b/docs/contributing/sdk-releasing.md
@@ -15,7 +15,7 @@ cd perfetto
Next, decide the version number for the new release (vX.Y).
The major version number (X) is incremented on every release (monthly).
The minor version number is incremented only for minor changes / fixes on top of the monthly
-release (cherry-picks on the releases/vN.x branch).
+release (cherry-picks on the releases/vN.x branch).
Continue with the appropriate section below.
@@ -54,6 +54,24 @@ Otherwise, you can do a full merge:
git merge <sha1>
```
+Update the CHANGELOG with a dedicated entry for the new minor version.
+This is important because the
+[write_version_header.py](/tools/write_version_header.py) script, which is
+invoked by the build system, looks at the CHANGELOG to work out the latest
+v${maj}.${min} version.
+
+For an example see [r.android.com/1730332](https://r.android.com/1730332)
+
+```txt
+v16.1 - 2021-06-08:
+ Tracing service and probes:
+ * Cherry-pick of r.android.com/1716718 which missed the v16 branch ... .
+
+
+v16.0 - 2021-06-01:
+ ...
+```
+
## Building and tagging the release
1. Generate and commit the amalgamated source files.
@@ -108,6 +126,31 @@ git push origin vX.Y
- [docs/instrumentation/tracing-sdk.md](/docs/instrumentation/tracing-sdk.md)
- [examples/sdk/README.md](/examples/sdk/README.md)
-6. Send an email with the CHANGELOG to perfetto-dev@ (internal) and perfetto-dev@googlegroups.com.
+6. Send an email with the CHANGELOG to perfetto-dev@ (internal) and to the
+ [public perfetto-dev](https://groups.google.com/forum/#!forum/perfetto-dev).
+
+## Creating a GitHub release with prebuilts
+
+7. Within few mins the LUCI scheduler will trigger builds of prebuilt binaries
+ on https://luci-scheduler.appspot.com/jobs/perfetto . Wait for all the bots
+ to have completed successfully and be back into the WAITING state.
+
+8. Run `tools/package-prebuilts-for-github-release vX.Y`. It will pull the
+ prebuilts under `/tmp/perfetto-prebuilts-vX.Y`.
+ - There must be 10 zips in total: linux-{arm,arm64,amd64},
+ android-{arm,arm64,x86,x64}, mac-{amd64,arm64}, win-amd64.
+ - If one or more are missing it means that one of the LUCI bots failed,
+ check the logs (follow the "Task URL: " link) from the invocation log.
+ - If this happens you'll need to respin a vX.(Y+1) release with the fix
+ (look at the history v20.1, where a Windows failure required a respin).
+
+9. Open https://github.com/google/perfetto/releases/new and
+ - Select "Choose Tag" -> vX.Y
+ - "Release title" -> "Perfetto vX.Y"
+ - "Describe release" -> Copy the CHANGELOG, wrapping it in triple backticks.
+ - "Attach binaries" -> Attach the ten .zip files from the previous step.
+
+10. Run `tools/roll-prebuilts vX.Y`. It will update the SHA256 into the various
+ scripts under `tools/`. Upload a CL with the changes.
-Phew, you're done!
+11. Phew, you're done!
diff --git a/docs/contributing/testing.md b/docs/contributing/testing.md
index 98f0812a0..f45d665af 100644
--- a/docs/contributing/testing.md
+++ b/docs/contributing/testing.md
@@ -120,9 +120,38 @@ TIP: Query diff tests are expected to only have a single query which produces
output in the whole file (usually at the end). Calling
`SELECT RUN_METRIC('metric file')` can trip up this check as this query
generates some hidden output. To address this issue, if a query only has
-column is named `supress_query_output`, even if it has output, this will
+column is named `suppress_query_output`, even if it has output, this will
be ignored (for example,
-`SELECT RUN_METRIC('metric file') as surpress_query_output`)
+`SELECT RUN_METRIC('metric file') as suppress_query_output`)
+
+UI pixel diff tests
+-----------------
+The pixel tests are used to ensure core user journeys work by verifying they
+are the same pixel to pixel against a golden screenshot. They use a headless
+chrome to load the webpage and take a screenshot and compare pixel by pixel a
+golden screenshot. You can run these tests by using `ui/run-integrationtests`.
+
+
+These test fail when a certain number of pixels are different. If these tests
+fail, you'll need to investigate the diff and determine if its intentional. If
+its a desired change you will need to update the screenshots on a linux machine
+to get the CI to pass. You can update them by generating and uploading a new
+baseline (this requires access to a google bucket through gcloud which only
+googlers have access to, googlers can install gcloud
+[here](https://g3doc.corp.google.com/cloud/sdk/g3doc/index.md#installing-and-using-the-cloud-sdk)).
+
+```
+ui/run-integrationtests --rebaseline
+tools/test_data upload
+```
+
+Once finished you can commit and upload as part of your CL to cause the CI to
+use your new screenshots.
+
+NOTE: If you see a failing diff test you can see the pixel differences on the CI
+by using the link to the UI and replace `/ui/index.html` with
+`/ui-test-artifacts/<name_of_failing_png_test_from_logs>.png`. This allows you
+to tell where in the picture the change was introduced.
Android CTS tests
-----------------
diff --git a/docs/data-sources/atrace.md b/docs/data-sources/atrace.md
index 51e50f1f4..a54bd1a90 100644
--- a/docs/data-sources/atrace.md
+++ b/docs/data-sources/atrace.md
@@ -42,7 +42,7 @@ a managed execution environment, and a user-space <-> kernel-space roundtrip to
write the marker into `/sys/kernel/debug/tracing/trace_marker` (which is the
most expensive part).
-Our team is are looking into a migration path for Android, in light of the newly
+Our team is looking into a migration path for Android, in light of the newly
introduced [Tracing SDK](/docs/instrumentation/tracing-sdk.md). At the moment
the advice is to keep using the existing ATrace API on Android.
diff --git a/docs/data-sources/battery-counters.md b/docs/data-sources/battery-counters.md
index 89f66687e..5cc837cd8 100644
--- a/docs/data-sources/battery-counters.md
+++ b/docs/data-sources/battery-counters.md
@@ -85,7 +85,7 @@ Trace proto:
Config proto:
[AndroidPowerConfig](/docs/reference/trace-config-proto.autogen#AndroidPowerConfig)
-Sample config:
+Sample config (Android):
```protobuf
data_sources: {
@@ -101,6 +101,16 @@ data_sources: {
}
```
+Sample Config (Chrome OS or Linux):
+
+```protobuf
+data_sources: {
+ config {
+ name: "linux.sysfs_power"
+ }
+}
+```
+
## Power rails
_This data source has been introduced in Android 10 (Q) and requires the
diff --git a/docs/data-sources/cpu-freq.md b/docs/data-sources/cpu-freq.md
index 73a7f8e5b..5f67b24d9 100644
--- a/docs/data-sources/cpu-freq.md
+++ b/docs/data-sources/cpu-freq.md
@@ -7,14 +7,44 @@ It involves three aspects:
#### Frequency scaling
-Records changes in the frequency of a CPU. An event is emitted every time the
-scaling governor scales the CPU frequency up or down.
+There are two way to get CPU frequency data:
+
+1. Enabling the `power/cpu_frequency` ftrace event. (See
+ [TraceConfig](#traceconfig) below). This will record an event every time the
+ in-kernel cpufreq scaling driver changes the frequency. Note that this is not
+ supported on all platforms. In our experience it works reliably on ARM-based
+ SoCs but produces no data on most modern Intel-based platforms. This is
+ because recent Intel CPUs use an internal DVFS which is directly controlled
+ by the CPU, and that doesn't expose frequency change events to the kernel.
+ Also note that even on ARM-based platforms, the event is emitted only
+ when a CPU frequency changes. In many cases the CPU frequency won't
+ change for several seconds, which will show up as an empty block at the start
+ of the trace.
+ We suggest always combining this with polling (below) to get a reliable
+ snapshot of the initial frequency.
+2. Polling sysfs by enabling the `linux.sys_stats` data source and setting
+ `cpufreq_period_ms` to a value > 0. This will periodically poll
+ `/sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_cur_freq` and record the
+ current value in the trace buffer. Works on both Intel and ARM-based
+ platforms.
On most Android devices the frequency scaling is per-cluster (group of
big/little cores) so it's not unusual to see groups of four CPUs changing
frequency at the same time.
-#### idle states
+#### Available frequencies
+
+It is possible to record one-off also the full list of frequencies supported by
+each CPU by enabling the `linux.system_info` data source. This will
+record `/sys/devices/system/cpu/cpu*/cpufreq/scaling_available_frequencies` when
+the trace recording start. This information is typically used to tell apart
+big/little cores by inspecting the
+[`cpu_freq` table](/docs/analysis/sql-tables.autogen#cpu_freq).
+
+This is not supported on modern Intel platforms for the same aforementioned
+reasons of `power/cpu_frequency`.
+
+#### Idle states
When no threads are eligible to be executed (e.g. they are all in sleep states)
the kernel sets the CPU into an idle state, turning off some of the circuitry
@@ -85,9 +115,13 @@ ts | name | cpu | value
261187013665683 | cpuidle | 1 | 0
261187013845058 | cpufreq | 0 | 1900800
+The list of known CPU frequencies, can be queried using the
+[`cpu_freq` table](/docs/analysis/sql-tables.autogen#cpu_freq).
+
### TraceConfig
```protobuf
+// Event-driven recording of frequency and idle state changes.
data_sources: {
config {
name: "linux.ftrace"
@@ -98,6 +132,23 @@ data_sources: {
}
}
}
+
+// Polling the current cpu frequency.
+data_sources: {
+ config {
+ name: "linux.sys_stats"
+ sys_stats_config {
+ cpufreq_period_ms: 500
+ }
+ }
+}
+
+// Reporting the list of available frequency for each CPU.
+data_sources {
+ config {
+ name: "linux.system_info"
+ }
+}
```
### Full-device suspend
diff --git a/docs/data-sources/cpu-scheduling.md b/docs/data-sources/cpu-scheduling.md
index 8b771e8b5..29a214462 100644
--- a/docs/data-sources/cpu-scheduling.md
+++ b/docs/data-sources/cpu-scheduling.md
@@ -147,3 +147,45 @@ selecting a CPU slice:
![](/docs/images/latency.png "Scheduling wake-up events in the UI")
+### Decoding `end_state`
+
+The [sched_slice](/docs/analysis/sql-tables.autogen#sched_slice) table contains
+information on scheduling activity of the system:
+
+```
+> select * from sched_slice limit 1
+id type ts dur cpu utid end_state priority
+0 sched_slice 70730062200 125364 0 1 S 130
+```
+
+Each row of the table shows when a given thread (`utid`) began running
+(`ts`), on which core it ran (`cpu`), for how long it ran (`dur`),
+and why it stopped running: `end_state`.
+
+`end_state` is encoded as one or more ascii characters. The UI uses
+the following translations to convert `end_state` into human readable
+text:
+
+| end_state | Translation |
+|------------|------------------------|
+| R | Runnable |
+| S | Sleeping |
+| D | Uninterruptible Sleep |
+| T | Stopped |
+| t | Traced |
+| X | Exit (Dead) |
+| Z | Exit (Zombie) |
+| x | Task Dead |
+| I | Task Dead |
+| K | Wake Kill |
+| W | Waking |
+| P | Parked |
+| N | No Load |
+| + | (Preempted) |
+
+Not all combinations of characters are meaningful.
+
+If we do not know when the scheduling ended (for example because the
+trace ended while the thread was still running) `end_state` will be
+`NULL` and `dur` will be -1.
+
diff --git a/docs/data-sources/frametimeline.md b/docs/data-sources/frametimeline.md
index 6b711bf85..f23522a93 100644
--- a/docs/data-sources/frametimeline.md
+++ b/docs/data-sources/frametimeline.md
@@ -117,7 +117,7 @@ multiple processes.
## Janks explained
The jank types are defined in
-[JankInfo.h](http://cs/android/frameworks/native/libs/gui/include/gui/JankInfo.h?l=22).
+[JankInfo.h](https://cs.android.com/android/platform/superproject/+/master:frameworks/native/libs/gui/include/gui/JankInfo.h?l=22).
Since each app is written differently, there is no common way to go into the
internals of the apps and specify what the reason for the jank was. Our goal is
not to do this but rather, provide a quick way to tell if app was janky or if
diff --git a/docs/data-sources/java-heap-profiler.md b/docs/data-sources/java-heap-profiler.md
index f03977e37..f67cf0389 100644
--- a/docs/data-sources/java-heap-profiler.md
+++ b/docs/data-sources/java-heap-profiler.md
@@ -21,6 +21,10 @@ a heap dump.
![Flamegraph of a Java heap profiler](/docs/images/java-flamegraph.png)
+The native size of certain objects is represented as an extra child node in the
+flamegraph, prefixed with "[native]". The extra node counts as an extra object.
+This is available only on Android T+.
+
## SQL
Information about the Java Heap is written to the following tables:
@@ -29,6 +33,9 @@ Information about the Java Heap is written to the following tables:
* [`heap_graph_object`](/docs/analysis/sql-tables.autogen#heap_graph_object)
* [`heap_graph_reference`](/docs/analysis/sql-tables.autogen#heap_graph_reference)
+`native_size` (available only on Android T+) is extracted from the related
+`libcore.util.NativeAllocationRegistry` and is not included in `self_size`.
+
For instance, to get the bytes used by class name, run the following query.
As-is this query will often return un-actionable information, as most of the
bytes in the Java heap end up being primitive arrays or strings.
@@ -67,7 +74,10 @@ We can then use them to get the flamegraph data.
```sql
select name, cumulative_size
- from experimental_flamegraph(56785646801, 1, 'graph')
+ from experimental_flamegraph
+ where ts = 56785646801
+ and upid = 1
+ and profile_type = 'graph'
order by 2 desc;
```
diff --git a/docs/data-sources/memory-counters.md b/docs/data-sources/memory-counters.md
index f2bbabda4..d5c6a42ea 100644
--- a/docs/data-sources/memory-counters.md
+++ b/docs/data-sources/memory-counters.md
@@ -201,7 +201,7 @@ data_sources: {
vmstat_counters: VMSTAT_NR_INACTIVE_ANON
vmstat_counters: VMSTAT_NR_ACTIVE_ANON
- stat_period_ms: 2500
+ stat_period_ms: 1000
stat_counters: STAT_CPU_TIMES
stat_counters: STAT_FORK_COUNT
}
@@ -282,7 +282,7 @@ TODO: we are working on a better UI support for LMKs.
### SQL
-Both newer lmkd and legacy kernel-driven lowmemorykiler events are normalized
+Both newer lmkd and legacy kernel-driven lowmemorykiller events are normalized
at import time and available under the `mem.lmk` key in the `instants` table.
```sql
diff --git a/docs/data-sources/native-heap-profiler.md b/docs/data-sources/native-heap-profiler.md
index cff52e2e0..d0813139a 100644
--- a/docs/data-sources/native-heap-profiler.md
+++ b/docs/data-sources/native-heap-profiler.md
@@ -70,7 +70,7 @@ For the full arguments list see the
#### Using the Recording page of Perfetto UI
-You can also use the [Perfetto UI](https://ui.perfetto.dev/#!/record?p=memory)
+You can also use the [Perfetto UI](https://ui.perfetto.dev/#!/record/memory)
to record heapprofd profiles. Tick "Heap profiling" in the trace configuration,
enter the processes you want to target, click "Add Device" to pair your phone,
and record profiles straight from your browser. This is also possible on
@@ -116,6 +116,8 @@ probability of being selected as a sample, and the corresponding callstack
gets attributed the complete n bytes. For more accuracy, allocations larger than
the sampling interval bypass the sampling logic and are recorded with their true
size.
+See the [heapprofd Sampling](/docs/design-docs/heapprofd-sampling) document for
+details.
## Startup profiling
@@ -237,8 +239,6 @@ enumerated in the output directory.
## Symbolization
-NOTE: Symbolization is currently only available on Linux and MacOS.
-
### Set up llvm-symbolizer
You only need to do this once.
@@ -424,6 +424,13 @@ LD_PRELOAD=out/linux_clang_release/libheapprofd_glibc_preload.so out/linux_clang
Then, Ctrl-C the Perfetto invocation and upload ~/heapprofd-trace to the
[Perfetto UI](https://ui.perfetto.dev).
+NOTE: by default, heapprofd lazily initalizes to avoid blocking your program's
+main thread. However, if your program makes memory allocations on startup,
+these can be missed. To avoid this from happening, set the enironment variable
+`PERFETTO_HEAPPROFD_BLOCKING_INIT=1`; on the first malloc, your program will
+be blocked until heapprofd initializes fully but means every allocation will
+be correctly tracked.
+
## Known Issues
### {#known-issues-android11} Android 11
@@ -436,6 +443,8 @@ Then, Ctrl-C the Perfetto invocation and upload ~/heapprofd-trace to the
* `Failed to send control socket byte.` is displayed in logcat at the end of
every profile. This is benign.
* The object count may be incorrect in `dump_at_max` profiles.
+* Choosing a low shared memory buffer size and `block_client` mode might
+ lock up the target process.
### {#known-issues-android10} Android 10
* Function names in libraries with load bias might be incorrect. Use
@@ -462,6 +471,8 @@ _Cuttlefish_.
* `Failed to send control socket byte.` is displayed in logcat at the end of
every profile. This is benign.
* The object count may be incorrect in `dump_at_max` profiles.
+* Choosing a low shared memory buffer size and `block_client` mode might
+ lock up the target process.
## Heapprofd vs malloc_info() vs RSS
@@ -500,7 +511,7 @@ the memory of the process get swapped out onto ZRAM.
| fragmentation | | | x |
If you observe high RSS or malloc\_info metrics but heapprofd does not match,
-you might be hitting some patological fragmentation problem in the allocator.
+you might be hitting some pathological fragmentation problem in the allocator.
## Convert to pprof
@@ -562,9 +573,12 @@ subject to change**.
```sql
select name, map_name, cumulative_size
- from experimental_flamegraph(8300973884377,1,'native')
+ from experimental_flamegraph
+ where ts = 8300973884377
+ and upid = 1
+ and profile_type = 'native'
order by abs(cumulative_size) desc;
-```
+```
| name | map_name | cumulative_size |
|------|----------|----------------|
diff --git a/docs/design-docs/api-and-abi.md b/docs/design-docs/api-and-abi.md
index 2c8a6b6e8..29f47a5c6 100644
--- a/docs/design-docs/api-and-abi.md
+++ b/docs/design-docs/api-and-abi.md
@@ -272,7 +272,7 @@ The producer specifies the desired SMB size and memory layout when sending the
[`InitializeConnectionRequest`][producer_port.proto] request to the
service, which is the very first IPC sent after connection.
By default, the service creates the SMB and passes back its file descriptor to
-the producer with the the [`InitializeConnectionResponse`][producer_port.proto]
+the producer with the [`InitializeConnectionResponse`][producer_port.proto]
IPC reply. Recent versions of the service (Android R / 11) allow the FD to be
created by the producer and passed down to the service in the request. When the
service supports this, it acks the request setting
diff --git a/docs/reference/checkpoint-atoms.md b/docs/design-docs/checkpoint-atoms.md
index a00ebfdba..a00ebfdba 100644
--- a/docs/reference/checkpoint-atoms.md
+++ b/docs/design-docs/checkpoint-atoms.md
diff --git a/docs/design-docs/heapprofd-design.md b/docs/design-docs/heapprofd-design.md
index fe5a8ef73..005b0d3d1 100644
--- a/docs/design-docs/heapprofd-design.md
+++ b/docs/design-docs/heapprofd-design.md
@@ -182,6 +182,9 @@ Unwinding the stack on every `malloc` call has a high cost that is not always wo
The sampling rate is configurable as part of the initial handshake. A sampling rate == 1 will degenerate into the fully-accurate high-overhead mode.
+See [Sampling for Memory Profiles](/docs/design-docs/heapprofd-sampling) for
+more details.
+
Prior art: [crbug.com/812262](http://crbug.com/812262), [crbug.com/803276](http://crbug.com/803276).
## Implementation Plan
diff --git a/docs/design-docs/pivot-tables.md b/docs/design-docs/pivot-tables.md
new file mode 100644
index 000000000..ddc340cd2
--- /dev/null
+++ b/docs/design-docs/pivot-tables.md
@@ -0,0 +1,206 @@
+# Pivot Tables
+
+_**Project Plan**: [Perfetto: Pivot tables for slices](https://docs.google.com/document/d/1RuEGQKLgOA8YWjZJHD6CTA3ghRRg6o5Phg3_rFCJEDE/)_
+_**How to Use**: [Pivot Table Usage](/docs/visualization/perfetto-ui#pivot-tables)_
+_**For Googlers**: [Perfetto: Pivot Table Use Cases](https://docs.google.com/document/d/1_iR-JjD7m19Q9GQtMk1_5NLSYXFicB_gg4S9D-6Q8lU/)_
+
+## Objective
+Pivot tables give a simplified aggregated view of more complex data. They are
+made up of a number of pivots and aggregations that are grouped around these
+pivots. You can add more columns/aggregations and drag and drop the columns to
+explore the underlying data.
+
+## Motivation
+Pivot tables are useful in debugging hangs, stalls, and digging into traces
+which usually have too much data to clearly see the problems.
+The pivot table allows users to create custom tables to view specific
+information about traces in a summarized and less complex way.
+
+## Main Components
+
+![Pivot table design](/docs/images/pivot-tables/pivot-table-design.png)
+
+### Details Panel (Frontend)
+The [DetailsPanel](https://cs.android.com/android/_/android/platform/external/perfetto/+/0ae7c36fd528824ee9fdea6cfd4494e9f05183b5:ui/src/frontend/details_panel.ts)
+searches for active PivotTables to display on screen. It also syncs the
+PivotTableHelper with data from the State. (PivotTableHelper only syncs when the
+PivotTableEditor modal is not open).
+
+
+### Pivot Table (Frontend)
+The [PivotTable](https://cs.android.com/android/_/android/platform/external/perfetto/+/0ae7c36fd528824ee9fdea6cfd4494e9f05183b5:ui/src/frontend/pivot_table.ts) builds
+the pivot table tab and the table. It also handles user requests (like opening
+the pivot table editor, drag and drop columns, expand, etc) by calling the
+PivotTableHelper and updating the table.
+
+
+### PivotTableEditor (Frontend)
+The [PivotTableEditor](https://cs.android.com/android/_/android/platform/external/perfetto/+/0ae7c36fd528824ee9fdea6cfd4494e9f05183b5:ui/src/frontend/pivot_table_editor.ts)
+consists of ColumnPicker and ColumnDisplay classes.
+ColumnPicker allows the user to select column type, name and aggregation. Edits
+made through the ColumnPicker are saved temporarily in the PivotTableHelper
+without updating the state.
+ColumnDisplay displays the selected column from the ColumnPicker, it also allows
+users to manipulate the columns after selection (like delete, reorder, change
+the default sorting, etc...).
+In this stage the user is able to query the selected columns and update the
+table or discard the changes made and the PivotTableHelper will resync with the
+data in state.
+
+
+### PivotTableHelper (Frontend)
+The [PivotTableHelper](https://cs.android.com/android/_/android/platform/external/perfetto/+/0ae7c36fd528824ee9fdea6cfd4494e9f05183b5:ui/src/frontend/pivot_table_helper.ts)
+is created by every PivotTableController for every PivotTableId. It stores a
+copy of the selectedPivots and selectedAggregations from state. It also holds
+the logic for manipulating the data locally, which are used by the PivotTable
+and PivotTableEditor.
+It also replaces the data in the State with the changes upon request.
+The PivotTableHelper also checks for special “stack†columns, called stackPivots
+(`name (stack)` for [slice table](/docs/analysis/sql-tables.autogen#slice) is
+currently the only special column), as it sets the column attributes which are
+then used to identify them by other components.
+
+
+### State (Common)
+[PivotTableState](https://cs.android.com/android/_/android/platform/external/perfetto/+/0ae7c36fd528824ee9fdea6cfd4494e9f05183b5:ui/src/common/state.ts;l=303) holds the
+information that needs to be transferred to and from the frontend and the
+controller for each pivot table instance (PivotTableId). It also includes the
+global PivotTableConfigs (like the availableColumns and availableAggregations).
+
+
+### PivotTableController (Controller)
+A new [PivotTableController](https://cs.android.com/android/_/android/platform/external/perfetto/+/0ae7c36fd528824ee9fdea6cfd4494e9f05183b5:ui/src/controller/pivot_table_controller.ts)
+is created for every PivotTableId.
+The PivotTableController handles the setup of the pivot table once added, it
+queries for the columns for all tables and sets the PivotTableConfig. It also
+creates and initializes a PivotTableHelper for every PivotTableId and publishes
+it to the frontend.
+Additionally, the PivotTableController handles the collection and the
+computation of all data needed by the PivotTableQueryGenerator.
+It constantly checks if a request has been set in the PivotTableState and acts
+on it if so.
+It decides what columns to query, what whereFilters and tables to include and
+how to reformat the query result into a PivotTableQueryResponse based on the
+request type.
+
+There are four types of requests implemented in the controller:
+
+**_QUERY:_**
+Queries the first pivot of the selectedPivots and all the aggregations,
+including any global or table-wide whereFilters (Like the start and end
+timestamp and selected track_ids that are set by the pivot table generated
+through area selection).
+It also adds a whereFilter (Filter in the where clause of the query) if the
+pivot is a stackPivot to restrict the result to the top level slices only, since
+descendants can be generated by expanding the cell and issuing the DESCENDANTS
+request, and returns the result as a PivotTableQueryResponse.
+
+![Pivot table query](/docs/images/pivot-tables/pivot-table-query.png)
+
+Returned PivotTableQueryResponse:
+
+```typescript
+pivotTableQueryResponse = {
+ columns: ['slice type', 'slice category', 'slice name'];
+ rows: [
+ {
+ row: 'internal_slice',
+ expandableColumns: ['slice type'],
+ expandedRows = [],
+ }, {
+ row: 'thread_slice',
+ expandableColumns: ['slice type'],
+ expandedRows = [],
+ };
+ ]
+}
+```
+
+**_EXPAND:_**
+The [PivotTableBody](https://cs.android.com/android/_/android/platform/external/perfetto/+/a9118d769009349da7f264abb392f4207e66602b:ui/src/frontend/pivot_table.ts;l=235;drc=0bc8ff07f372a58ca4d0399d88567a66ef5b591b) generates the nested structure by
+recursively displaying the rows and checking if the row contains any expanded
+rows with the isExpanded flag set to true. As it goes through the nested rows,
+it passes the row index that it's about to expand, along with the column it's
+expanding for till it reaches a [PivotTableRow](https://cs.android.com/android/_/android/platform/external/perfetto/+/0ae7c36fd528824ee9fdea6cfd4494e9f05183b5:ui/src/frontend/pivot_table.ts;l=192).
+The PivotTableRow creates a cell for each column. If the cell is at a column
+that can be expanded, it is created as an [ExpandableCell](https://cs.android.com/android/_/android/platform/external/perfetto/+/0ae7c36fd528824ee9fdea6cfd4494e9f05183b5:ui/src/frontend/pivot_table.ts;l=121).
+When an 'EXPAND' request is issued on an ExpandableCell, it sets the
+requestedAction in the PivotTableState and provides it with the SubQueryAttrs.
+
+Given a columnIdx, value, and an array of rowIndicies (SubQueryAttrs) from
+the requestedAction in the PivotTableState, it finds the exact row that called
+this request from the main PivotTableQueryResponse, and finds the next pivot
+to query. It then generates the query similarly to the ‘QUERY’ request, but
+includes the whereFilter of the previous column (column name = column value).
+The rows of the query result are then nested into the caller row’s expandedRows,
+to build a tree view structure while expanding.
+
+![Pivot table expanded cell](/docs/images/pivot-tables/pivot-table-expanded-cell.png)
+
+Passed value:
+
+```typescript
+subQueryAttrs = {
+ rowIndices: [0, 3],
+ columnIdx: 1,
+ value: 'blink,benchmark',
+ expandedRowColumns: ['slice category'],
+}
+```
+
+Returned expanded rows:
+
+```typescript
+rows = [
+ {
+ row: 'LocalFrameView::RunAccessibilityLifecyclePhase',
+ expandableColumns: [],
+ expandedRows: []
+ },
+ {
+ row: 'LocalFrameView::RunCompositingInputsLifecyclePhase',
+ expandableColumns: [],
+ expandedRows: []
+ },
+ {
+ row: 'LocalFrameView::RunStyleAndLayoutLifecyclePhases',
+ expandableColumns: [],
+ expandedRows: []
+ },
+ ...
+]
+```
+
+The returned rows are saved inside the caller row expandedRows map.
+
+```typescript
+rows = {
+ row: 'blink,benchmark',
+ expandableColumns: ['slice category'],
+ expandedRows: [
+ 'slice name' => {
+ isExpanded: true,
+ rows
+ }
+ ]
+}
+```
+
+**_UNEXPAND:_**
+Sets the caller row’s isExpanded flag to false, to hide it from the display but
+also keeping its expandedRows saved so as to not have to query them again if
+requested.
+
+**_DESCENDANTS:_**
+Should only be called for stackPivots, generates a query containing the
+stackPivot and the next pivot, if it exists, and all the aggregations. It also
+requests the PivotTableQueryGenerator to order by depth first, which is then
+used to refactor the resulting rows into the PivotTableQueryResponse tree view
+structure.
+The returned format is similar to the EXPAND request.
+
+### PivotTableQueryGenerator (Common)
+[PivotTableQueryGenerator](https://cs.android.com/android/_/android/platform/external/perfetto/+/0ae7c36fd528824ee9fdea6cfd4494e9f05183b5:ui/src/common/pivot_table_query_generator.ts)
+generates an sql query based on the given data, along with any hidden columns
+that may need to be added. It also creates an alias for each pivot and
+aggregation that is used to identify the resulting cells in the rows.
diff --git a/docs/images/cpu-profile-diamond.png b/docs/images/cpu-profile-diamond.png
new file mode 100644
index 000000000..97bd44b69
--- /dev/null
+++ b/docs/images/cpu-profile-diamond.png
Binary files differ
diff --git a/docs/images/cpu-profile-flame.png b/docs/images/cpu-profile-flame.png
new file mode 100644
index 000000000..b5da446a8
--- /dev/null
+++ b/docs/images/cpu-profile-flame.png
Binary files differ
diff --git a/docs/images/enable-profile-flame-graph.png b/docs/images/enable-profile-flame-graph.png
new file mode 100644
index 000000000..642ce73e3
--- /dev/null
+++ b/docs/images/enable-profile-flame-graph.png
Binary files differ
diff --git a/docs/images/perfetto-ui-channel-toggle.png b/docs/images/perfetto-ui-channel-toggle.png
new file mode 100644
index 000000000..e530c0d1c
--- /dev/null
+++ b/docs/images/perfetto-ui-channel-toggle.png
Binary files differ
diff --git a/docs/images/perfetto-ui-channel.png b/docs/images/perfetto-ui-channel.png
new file mode 100644
index 000000000..aed8ac4d0
--- /dev/null
+++ b/docs/images/perfetto-ui-channel.png
Binary files differ
diff --git a/docs/images/perfetto-ui-version.png b/docs/images/perfetto-ui-version.png
new file mode 100644
index 000000000..00b523e5f
--- /dev/null
+++ b/docs/images/perfetto-ui-version.png
Binary files differ
diff --git a/docs/images/pivot-tables/pivot-table-area-selection.png b/docs/images/pivot-tables/pivot-table-area-selection.png
new file mode 100644
index 000000000..f2c84d313
--- /dev/null
+++ b/docs/images/pivot-tables/pivot-table-area-selection.png
Binary files differ
diff --git a/docs/images/pivot-tables/pivot-table-design.png b/docs/images/pivot-tables/pivot-table-design.png
new file mode 100644
index 000000000..e38da25d9
--- /dev/null
+++ b/docs/images/pivot-tables/pivot-table-design.png
Binary files differ
diff --git a/docs/images/pivot-tables/pivot-table-editor.png b/docs/images/pivot-tables/pivot-table-editor.png
new file mode 100644
index 000000000..8db7ff9d8
--- /dev/null
+++ b/docs/images/pivot-tables/pivot-table-editor.png
Binary files differ
diff --git a/docs/images/pivot-tables/pivot-table-expanded-cell.png b/docs/images/pivot-tables/pivot-table-expanded-cell.png
new file mode 100644
index 000000000..462827281
--- /dev/null
+++ b/docs/images/pivot-tables/pivot-table-expanded-cell.png
Binary files differ
diff --git a/docs/images/pivot-tables/pivot-table-query.png b/docs/images/pivot-tables/pivot-table-query.png
new file mode 100644
index 000000000..e50ae9d19
--- /dev/null
+++ b/docs/images/pivot-tables/pivot-table-query.png
Binary files differ
diff --git a/docs/images/pivot-tables/pivot-table.png b/docs/images/pivot-tables/pivot-table.png
new file mode 100644
index 000000000..3e842f971
--- /dev/null
+++ b/docs/images/pivot-tables/pivot-table.png
Binary files differ
diff --git a/docs/instrumentation/tracing-sdk.md b/docs/instrumentation/tracing-sdk.md
index cc4e6c42f..0af249c74 100644
--- a/docs/instrumentation/tracing-sdk.md
+++ b/docs/instrumentation/tracing-sdk.md
@@ -30,7 +30,7 @@ repository](/examples/sdk/README.md).
To start using the Client API, first check out the latest SDK release:
```bash
-git clone https://android.googlesource.com/platform/external/perfetto -b v14.0
+git clone https://android.googlesource.com/platform/external/perfetto -b v23.0
```
The SDK consists of two files, `sdk/perfetto.h` and `sdk/perfetto.cc`. These are
diff --git a/docs/quickstart/android-tracing.md b/docs/quickstart/android-tracing.md
index 2c65d3038..f27fe7f6e 100644
--- a/docs/quickstart/android-tracing.md
+++ b/docs/quickstart/android-tracing.md
@@ -17,6 +17,12 @@ tracing services are enabled before getting started:
adb shell setprop persist.traced.enable 1
```
+If you are running a version of Android older than P, you can still capture a
+trace with Perfetto using the `record_android_trace` script. See instructions
+below in the
+[Recording a trace through the cmdline](#recording-a-trace-through-the-cmdline)
+section.
+
## Recording a trace
Command line tools (usage examples below in this page):
@@ -65,6 +71,8 @@ We suggest using the `tools/record_android_trace` script to record traces from
the command line. It is the equivalent of running `adb shell perfetto` but it
helps with getting the paths right, auto-pulling the trace once done and opening
it on the browser.
+Furthermore, on older versions of Android it takes care of sideloading the
+`tracebox` binary to make up for the lack of tracing system services.
If you are already familiar with `systrace` or `atrace`, both cmdline tools
support a systrace-equivalent syntax:
@@ -76,14 +84,16 @@ curl -O https://raw.githubusercontent.com/google/perfetto/master/tools/record_an
chmod u+x record_android_trace
# See ./record_android_trace --help for more
-./record_android_trace -o trace_file.perfetto-trace -t 10s -b 32mb sched gfx wm
+./record_android_trace -o trace_file.perfetto-trace -t 10s -b 32mb \
+sched freq idle am wm gfx view binder_driver hal dalvik camera input res memory
```
On Windows:
```bash
curl -O https://raw.githubusercontent.com/google/perfetto/master/tools/record_android_trace
-python3 record_android_trace -o trace_file.perfetto-trace -t 10s -b 32mb sched gfx wm
+python3 record_android_trace -o trace_file.perfetto-trace -t 10s -b 32mb \
+sched freq idle am wm gfx view binder_driver hal dalvik camera input res memory
```
**Using the on-device /system/bin/perfetto command**
@@ -91,7 +101,8 @@ python3 record_android_trace -o trace_file.perfetto-trace -t 10s -b 32mb sched g
Or, if you want to use directly the on-device binary do instead:
```bash
-adb shell perfetto -o /data/misc/perfetto-traces/trace_file.perfetto-trace -t 20s sched freq idle am wm gfx view
+adb shell perfetto -o /data/misc/perfetto-traces/trace_file.perfetto-trace -t 20s \
+sched freq idle am wm gfx view binder_driver hal dalvik camera input res memory
```
Caveats when using directly the `adb shell perfetto` workflow:
diff --git a/docs/quickstart/callstack-sampling.md b/docs/quickstart/callstack-sampling.md
new file mode 100644
index 000000000..a2b3e8afb
--- /dev/null
+++ b/docs/quickstart/callstack-sampling.md
@@ -0,0 +1,139 @@
+# Quickstart: Callstack sampling on Android
+
+## Prerequisites
+
+* [ADB](https://developer.android.com/studio/command-line/adb) installed.
+* A device running Android R+.
+* Either a debuggable (`userdebug`/`eng`) Android image, or the apps to be
+ profiled need to be
+ [marked as profileable or debuggable](https://developer.android.com/guide/topics/manifest/profileable-element)
+ in their manifests.
+
+## Capture a CPU profile
+
+### Linux or macOS
+
+Make sure `adb` is installed and in your `PATH`.
+
+```bash
+adb devices -l
+```
+
+If more than one device or emulator is reported you must select one upfront as
+follows:
+
+```bash
+export ANDROID_SERIAL=SER123456
+```
+
+Download `cpu_profile` (if you don't have a Perfetto checkout):
+
+```bash
+curl -LO https://raw.githubusercontent.com/google/perfetto/master/tools/cpu_profile
+chmod +x cpu_profile
+```
+
+Then, start profiling. For example, to profile the processes `com.android.foo`
+and `com.android.bar`, use:
+
+```bash
+./cpu_profile -n "com.android.foo,com.android.bar"
+```
+
+By default, profiling runs until manually terminated manually. To set a specific
+duration for recording (e.g. 30 seconds), use:
+
+```bash
+./cpu_profile -n "com.android.foo,com.android.bar" -d 30000
+```
+
+To change how frequently stack samples are recorded (e.g. 120 samples per
+second), set the `-f` argument:
+
+```bash
+./cpu_profile -n "com.android.foo,com.android.bar" -f 120
+```
+
+You can also pass in parts of the names of the processes you want to profile by
+enabling `--partial-matching/-p`. This matches processes that are already
+running when profiling is started. For instance, to profile the processes
+`com.android.foo` and `com.android.bar`, run:
+
+```bash
+./cpu_profile -n "foo,bar" -p
+```
+
+You can also pass in a custom [Perfetto config](/docs/concepts/config.md), which
+overrides all of the options above, using the `-c` argument:
+
+```bash
+./cpu_profile -c "path/to/perfetto.config"
+```
+
+To change where profiles are output, use the `-o` argument:
+
+```bash
+./cpu_profile -n "com.android.foo,com.android.bar" -o "path/to/output/directory"
+```
+
+### Windows
+
+Make sure that the downloaded `adb.exe` is in the `PATH`.
+
+```bash
+set PATH=%PATH%;%USERPROFILE%\Downloads\platform-tools
+
+adb devices -l
+```
+
+If more than one device or emulator is reported you must select one upfront as
+follows:
+
+```bash
+set ANDROID_SERIAL=SER123456
+```
+
+Download the
+[`cpu_profile`](https://raw.githubusercontent.com/google/perfetto/master/tools/cpu_profile)
+script. Then, start profiling. For example, to profile the processes
+`com.android.foo` and `com.android.bar`, use:
+
+```bash
+python3 /path/to/cpu_profile -n "com.android.foo,com.android.bar"
+```
+
+Please see the [Linux or maxOS section](#linux-or-macos) for more examples.
+
+## Symbolization
+
+You may need to symbolize the collected profiles if they are missing symbols.
+See [this](/docs/data-sources/native-heap-profiler#symbolize-your-profile) for
+more details on how to do this.
+
+For example, to profile and symbolize the profiles for the process
+`com.android.foo`, run:
+
+```bash
+PERFETTO_SYMBOLIZER_MODE=index PERFETTO_BINARY_PATH=path/to/directory/with/symbols/ ./cpu_profile -n "com.android.foo"
+```
+
+## View profile
+
+Visualizing callstacks in the Perfetto UI is currently disabled behind a
+flag. Please enable it before proceeding further:
+
+![Enable flame graph flag](/docs/images/enable-profile-flame-graph.png)
+
+Upload the `raw-trace` or `symbolized-trace` file from the output directory to
+the [Perfetto UI](https://ui.perfetto.dev) and click on one of the diamond
+markers in the UI track named "Perf Samples" for the processes that you selected
+for profiling. Each diamond marker represents a profile with stack samples
+recorded from the beginning of the trace up until that diamond marker on the
+timeline.
+
+![Profile Diamond](/docs/images/cpu-profile-diamond.png)
+![Native Flamegraph](/docs/images/cpu-profile-flame.png)
+
+`cpu_profile` will also write separate profiles for each process that it
+profiled in the output directory, and those can be visualized using
+[`pprof`](https://github.com/google/pprof).
diff --git a/docs/quickstart/linux-tracing.md b/docs/quickstart/linux-tracing.md
index 93fa82355..d60822a9c 100644
--- a/docs/quickstart/linux-tracing.md
+++ b/docs/quickstart/linux-tracing.md
@@ -17,24 +17,42 @@ git clone https://android.googlesource.com/platform/external/perfetto/ && cd per
```bash
tools/install-build-deps
```
-_If the script fails with SSL errors, try invoking it as `python3 tools/install-build-deps`, or upgrading your openssl libraries._
+_If the script fails with SSL errors, try upgrading your openssl package._
-3. Generate all most common GN build configurations:
+3. Generate the build configuration
```bash
-tools/build_all_configs.py
+tools/gn gen --args='is_debug=false' out/linux
+# Or use `tools/build_all_configs.py` to generate more build configs.
```
4. Build the Linux tracing binaries (On Linux it uses a hermetic clang toolchain, downloaded as part of step 2):
```bash
-tools/ninja -C out/linux_clang_release traced traced_probes perfetto
+tools/ninja -C out/linux tracebox traced traced_probes perfetto
```
-_This step is optional when using the convenience `tools/tmux` script below._
## Capturing a trace
Due to Perfetto's [service-based architecture](/docs/concepts/service-model.md),
in order to capture a trace, the `traced` (session daemon) and `traced_probes`
(probes and ftrace-interop daemon) need to be running.
+As per Perfetto v16, the `tracebox` binary bundles together all the binaries you
+need in a single executable (a bit like `toybox` or `busybox`).
+
+#### Capturing a trace with ftrace and /proc pollers, no SDK
+
+If you are interested in overall system tracing and are not interested in
+testing the SDK, you can use `tracebox` in autostart mode as follows:
+
+```bash
+out/linux/tracebox -o trace_file.perfetto-trace --txt -c test/configs/scheduling.cfg
+```
+
+#### Testing the SDK integration in out-of-process tracing mode (system mode)
+
+If you are using the Perfetto [tracing SDK](/docs/instrumentation/tracing-sdk)
+and want to capture a fused trace that contains both system traces events and
+your custom app trace events, you need to start the `traced` and `traced_probes`
+services ahead of time and then use the `perfetto` cmdline client.
For a quick start, the [tools/tmux](/tools/tmux) script takes care of building,
setting up and running everything.
@@ -44,8 +62,8 @@ from the Linux kernel via the [ftrace] interface.
[ftrace]: https://www.kernel.org/doc/Documentation/trace/ftrace.txt
1. Run the convenience script with an example tracing config (10s duration):
-```
-OUT=out/linux_clang_release CONFIG=test/configs/scheduling.cfg tools/tmux -n
+```bash
+tools/tmux -c test/configs/scheduling.cfg -C out/linux -n
```
This will open a tmux window with three panes, one per the binary involved in
tracing: `traced`, `traced_probes` and the `perfetto` client cmdline.
@@ -55,25 +73,25 @@ tracing: `traced`, `traced_probes` and the `perfetto` client cmdline.
3. Detach from the tmux session with `Ctrl-B D`,or shut it down with
`tmux kill-session -t demo`. The script will then copy the trace to
- `/tmp/trace.protobuf`, as a binary-encoded protobuf (see
+ `/tmp/trace.perfetto-trace`, as a binary-encoded protobuf (see
[TracePacket reference](/docs/reference/trace-packet-proto.autogen)).
## Visualizing the trace
We can now explore the captured trace visually by using a dedicated web-based UI.
-NOTE: The UI runs fully in-browser using JavaScript + Web Assembly. The trace
+NOTE: The UI runs in-browser using JavaScript + Web Assembly. The trace
file is **not** uploaded anywhere by default, unless you explicitly click
- on the 'Share' link.
+ on the 'Share' link. The 'Share' link is available only to Googlers.
1. Navigate to [ui.perfetto.dev](https://ui.perfetto.dev) in a browser.
2. Click the **Open trace file** on the left-hand menu, and load the captured
- trace (by default at `/tmp/trace.protobuf`).
+ trace (by default at `/tmp/trace.perfetto-trace`).
3. Explore the trace by zooming/panning using WASD, and mouse for expanding
process tracks (rows) into their constituent thread tracks.
Press "?" for further navigation controls.
-Alternatively, you can explore the trace contents issuing SQL queries through
+Alternatively, you can explore the trace contents issuing SQL queries through
the [trace processor](/docs/analysis/trace-processor).
diff --git a/docs/quickstart/trace-analysis.md b/docs/quickstart/trace-analysis.md
index 714139446..62269dc66 100644
--- a/docs/quickstart/trace-analysis.md
+++ b/docs/quickstart/trace-analysis.md
@@ -334,7 +334,7 @@ more details on all available functions.
#### Query
```python
from perfetto.trace_processor import TraceProcessor
-tp = TraceProcessor(file_path='trace.perfetto-trace')
+tp = TraceProcessor(trace='trace.perfetto-trace')
qr_it = tp.query('SELECT name FROM slice')
for row in qr_it:
@@ -352,7 +352,7 @@ query
#### Query as Pandas DataFrame
```python
from perfetto.trace_processor import TraceProcessor
-tp = TraceProcessor(file_path='trace.perfetto-trace')
+tp = TraceProcessor(trace='trace.perfetto-trace')
qr_it = tp.query('SELECT ts, name FROM slice')
qr_df = qr_it.as_pandas_dataframe()
@@ -372,7 +372,7 @@ ts name
#### Metric
```python
from perfetto.trace_processor import TraceProcessor
-tp = TraceProcessor(file_path='trace.perfetto-trace')
+tp = TraceProcessor(trace='trace.perfetto-trace')
cpu_metrics = tp.metric(['android_cpu'])
print(cpu_metrics)
diff --git a/docs/quickstart/traceconv.md b/docs/quickstart/traceconv.md
index 226e5b206..83cf97590 100644
--- a/docs/quickstart/traceconv.md
+++ b/docs/quickstart/traceconv.md
@@ -38,6 +38,6 @@ chmod +x traceconv
If you just want to open a Perfetto trace with the legacy (Catapult) trace
viewer, you can just navigate to [ui.perfetto.dev](https://ui.perfetto.dev),
-and use the the _"Open with legacy UI"_ link. This runs `traceconv` within
+and use the _"Open with legacy UI"_ link. This runs `traceconv` within
the browser using WebAssembly and passes the converted trace seamlessly to
chrome://tracing.
diff --git a/docs/reference/heap_profile-cli.md b/docs/reference/heap_profile-cli.md
index 457b69966..7a68ea2b4 100644
--- a/docs/reference/heap_profile-cli.md
+++ b/docs/reference/heap_profile-cli.md
@@ -1,4 +1,10 @@
-# heap_profile
+# HEAP_PROFILE(1)
+
+## NAME
+
+heap_profile - record heap profile on Android device
+
+## DESCRIPTION
`tools/heap_profile` allows to collect native memory profiles on Android.
See [Recording traces](/docs/data-sources/native-heap-profiler.md) for more
@@ -16,27 +22,78 @@ usage: heap_profile [-h] [-i INTERVAL] [-d DURATION] [--no-start] [-p PIDS]
[--print-config] [-o DIRECTORY]
```
-## Options
-|Option|Description|
-|---|---|
-| -n, --name | Comma-separated list of process names to profile. |
-| -p, --pid | Comma-separated list of PIDs to profile. |
-| -i, --interval | Sampling interval. Default 4096 (4KiB) |
-| -o, --output | Output directory. |
-| -d, --duration | Duration of profile (ms). Default 7 days. |
-| --block-client | When buffer is full, block the client to wait for buffer space. Use with caution as this can significantly slow down the client. This is the default |
-| --no-block-client | When buffer is full, stop the profile early. |
-| --block-client-timeout | If --block-client is given, do not block any allocation for longer than this timeout (us). |
-| -h, --help | Show this help message and exit |
-| --no-start | Do not start heapprofd. |
-| -c, --continuous-dump | Dump interval in ms. 0 to disable continuous dump. |
-| --disable-selinux | Disable SELinux enforcement for duration of profile. |
-| --no-versions | Do not get version information about APKs. |
-| --no-running | Do not target already running processes. Requires Android 11. |
-| --no-startup | Do not target processes that start during the profile. Requires Android 11. |
-| --shmem-size | Size of buffer between client and heapprofd. Default 8MiB. Needs to be a power of two multiple of 4096, at least 8192. |
-| --dump-at-max | Dump the maximum memory usage rather than at the time of the dump. |
-| --disable-fork-teardown | Do not tear down client in forks. This can be useful for programs that use vfork. Android 11+ only. |
-| --simpleperf | Get simpleperf profile of heapprofd. This is only for heapprofd development. |
-| --trace-to-text-binary | Path to local trace to text. For debugging. |
-| --print-config | Print config instead of running. For debugging. |
+## OPTIONS
+`-n`, `--name` _NAMES_
+: Comma-separated list of process names to profile.
+
+`-p`, `--pid` _PIDS_
+: Comma-separated list of PIDs to profile.
+
+`-i`, `--interval`
+: Sampling interval. Default 4096 (4KiB)
+
+`-o`, `--output` _DIRECTORY_
+: Output directory.
+
+`--all-heaps`
+: Collect allocations from all heaps registered by target.
+
+`--block-client`
+: When buffer is full, block the client to wait for buffer space. Use with caution as this can significantly slow down the client. This is the default
+
+`--block-client-timeout`
+: If --block-client is given, do not block any allocation for longer than this timeout (us).
+
+`-c`, `--continuous-dump`
+: Dump interval in ms. 0 to disable continuous dump.
+
+`-d`, `--duration`
+: Duration of profile (ms). 0 to run until interrupted. Default: until interrupted by user.
+
+`--disable-fork-teardown`
+: Do not tear down client in forks. This can be useful for programs that use vfork. Android 11+ only.
+
+`--disable-selinux`
+: Disable SELinux enforcement for duration of profile.
+
+`--dump-at-max`
+: Dump the maximum memory usage rather than at the time of the dump.
+
+`-h`, `--help`
+: show this help message and exit
+
+`--heaps` _HEAPS_
+: Comma-separated list of heaps to collect, e.g: malloc,art. Requires Android 12.
+
+`--idle-allocations`
+: Keep track of how many bytes were unused since the last dump, per callstack
+
+`--no-android-tree-symbolization`
+: Do not symbolize using currently lunched target in the Android tree.
+
+`--no-block-client`
+: When buffer is full, stop the profile early.
+
+`--no-running`
+: Do not target already running processes. Requires Android 11.
+
+`--no-start`
+: Do not start heapprofd.
+
+`--no-startup`
+: Do not target processes that start during the profile. Requires Android 11.
+
+`--no-versions`
+: Do not get version information about APKs.
+
+`--print-config`
+: Print config instead of running. For debugging.
+
+`--shmem-size`
+: Size of buffer between client and heapprofd. Default 8MiB. Needs to be a power of two multiple of 4096, at least 8192.
+
+`--simpleperf`
+: Get simpleperf profile of heapprofd. This is only for heapprofd development.
+
+`--trace-to-text-binary`
+: Path to local trace to text. For debugging.
diff --git a/docs/reference/perfetto-cli.md b/docs/reference/perfetto-cli.md
index f0771d6a7..3d57ced1f 100644
--- a/docs/reference/perfetto-cli.md
+++ b/docs/reference/perfetto-cli.md
@@ -1,4 +1,10 @@
-# Perfetto CLI
+# PERFETTO(1)
+
+## NAME
+
+perfetto - capture traces
+
+## DESCRIPTION
This section describes how to use the `perfetto` commandline binary to capture
traces. Examples are given in terms of an Android device connected over ADB.
@@ -6,70 +12,122 @@ traces. Examples are given in terms of an Android device connected over ADB.
`perfetto` has two modes for configuring the tracing session (i.e. what and how
to collect):
-* __lightweight mode__: all config options are supplied as commandline flags,
+__lightweight mode__
+: all config options are supplied as commandline flags,
but the available data sources are restricted to ftrace and atrace. This mode
is similar to
[`systrace`](https://developer.android.com/topic/performance/tracing/command-line).
-* __normal mode__: the configuration is specified in a protocol buffer. This
- allows for full customisation of collected traces.
+__normal mode__
+: the configuration is specified in a protocol buffer. This allows for full
+ customisation of collected traces.
-## General options
+
+## GENERAL OPTIONS
The following table lists the available options when using `perfetto` in either
mode.
-|Option|Description|
-|---|---|
-| `--background \| -d` |Perfetto immediately exits the command-line interface and continues recording your trace in background.|
-|`--out OUT_FILE \| -o OUT_FILE`|Specifies the desired path to the output trace file, or `-` for stdout. `perfetto` writes the output to the file described in the flags above. The output format compiles with the format defined in [AOSP `trace.proto`](/protos/perfetto/trace/trace.proto).|
-|`--dropbox TAG`|Uploads your trace via the [DropBoxManager API](https://developer.android.com/reference/android/os/DropBoxManager.html) using the tag you specify.|
-|`--no-guardrails`|Disables protections against excessive resource usage when enabling the `--dropbox` flag during testing.|
-|`--reset-guardrails`|Resets the persistent state of the guardrails and exits (for testing).|
-|`--query`|Queries the service state and prints it as human-readable text.|
-|`--query-raw`|Similar to `--query`, but prints raw proto-encoded bytes of `tracing_service_state.proto`.|
-|`--help \| -h`|Prints out help text for the `perfetto` tool.|
+`-d`, `--background`
+: Perfetto immediately exits the command-line interface and continues
+ recording your trace in background.
+
+`-o`, `--out` _OUT_FILE_
+: Specifies the desired path to the output trace file, or `-` for stdout.
+ `perfetto` writes the output to the file described in the flags above.
+ The output format compiles with the format defined in
+ [AOSP `trace.proto`](/protos/perfetto/trace/trace.proto).
+
+`--dropbox` _TAG_
+: Uploads your trace via the
+ [DropBoxManager API](https://developer.android.com/reference/android/os/DropBoxManager.html)
+ using the tag you specify. Android only.
+
+`--no-guardrails`
+: Disables protections against excessive resource usage when enabling the
+ `--dropbox` flag during testing.
+
+
+`--reset-guardrails`
+: Resets the persistent state of the guardrails and exits (for testing).
+`--query`
+: Queries the service state and prints it as human-readable text.
-## Lightweight mode
+`--query-raw`
+: Similar to `--query`, but prints raw proto-encoded bytes of
+ `tracing_service_state.proto`.
-The general syntax for using `perfetto` in *lightweight mode* is as follows:
+`-h`, `--help`
+: Prints out help text for the `perfetto` tool.
-<pre class="none">
- adb shell perfetto [ --time <var>TIMESPEC</var> ] [ --buffer <var>SIZE</var> ] [ --size <var>SIZE</var> ]
- [ <var>ATRACE_CAT</var> | <var>FTRACE_GROUP/FTRACE_NAME</var>]...
-</pre>
+
+## SIMPLE MODE
+
+For ease of use, the `perfetto` command includes support for a subset of
+configurations via command line arguments. On-device, these
+configurations behave equivalently to the same configurations provided
+by a *CONFIG_FILE* (see below).
+
+The general syntax for using `perfetto` in *simple mode* is as follows:
+
+```
+ adb shell perfetto [ --time TIMESPEC ] [ --buffer SIZE ] [ --size SIZE ]
+ [ ATRACE_CAT | FTRACE_GROUP/FTRACE_NAME]...
+```
The following table lists the available options when using `perfetto` in
-*lightweight mode*.
+*simple mode*.
+
+`-t`, `--time` _TIME[s|m|h]_
+: Specifies the trace duration in seconds, minutes, or hours.
+ For example, `--time 1m` specifies a trace duration of 1 minute.
+ The default duration is 10 seconds.
-|Option|Description|
-|--- |--- |
-|`--time TIME[s\|m\|h] \| -t TIME[s\|m\|h]`|Specifies the trace duration in seconds, minutes, or hours. For example, `--time 1m` specifies a trace duration of 1 minute. The default duration is 10 seconds.|
-|`--buffer SIZE[mb\|gb] \| -b SIZE[mb\|gb`]|Specifies the ring buffer size in megabytes (mb) or gigabytes (gb). The default parameter is `--buffer 32mb`.|
-|`--size SIZE[mb\|gb] \| -s SIZE[mb\|gb]`|Specifies the max file size in megabytes (mb) or gigabytes (gb). By default `perfetto` uses only in-memory ring-buffer.|
+`-b`, `--buffer` _SIZE[mb|gb]_
+: Specifies the ring buffer size in megabytes (mb) or gigabytes (gb).
+ The default parameter is `--buffer 32mb`.
+
+`-s`, `--size` _SIZE[mb|gb]_
+: Specifies the max file size in megabytes (mb) or gigabytes (gb).
+ By default `perfetto` uses only in-memory ring-buffer.
This is followed by a list of event specifiers:
-|Event|Description|
-|--- |--- |
-|`ATRACE_CAT`|Specifies the atrace categories you want to record a trace for. For example, the following command traces Window Manager using atrace: `adb shell perfetto --out FILE wm`. To record other categories, see this [list of atrace categories](https://android.googlesource.com/platform/frameworks/native/+/refs/tags/android-q-preview-5/cmds/atrace/atrace.cpp#100).|
-|`FTRACE_GROUP/FTRACE_NAME`|Specifies the ftrace events you want to record a trace for. For example, the following command traces sched/sched_switch events: `adb shell perfetto --out FILE sched/sched_switch`|
+`ATRACE_CAT`
+: Specifies the atrace categories you want to record a trace for.
+ For example, the following command traces Window Manager using atrace:
+ `adb shell perfetto --out FILE wm`. To record other categories, see this
+ [list of atrace categories](https://android.googlesource.com/platform/frameworks/native/+/refs/tags/android-q-preview-5/cmds/atrace/atrace.cpp#100).
+`FTRACE_GROUP/FTRACE_NAME`
+: Specifies the ftrace events you want to record a trace for.
+ For example, the following command traces sched/sched_switch events:
+ `adb shell perfetto --out FILE sched/sched_switch`
-## Normal mode
-The general syntax for using `perfetto` in *normal mode* is as follows:
+## NORMAL MODE
-<pre class="none">
- adb shell perfetto [ --txt ] --config <var>CONFIG_FILE</var>
-</pre>
+The general syntax for using `perfetto` in *normal mode* is as follows:
-The following table lists the available options when using `perfetto` in *normal* mode.
+```
+ adb shell perfetto [ --txt ] --config CONFIG_FILE
+```
-|Option|Description|
-|--- |--- |
-|`--config CONFIG_FILE \| -c CONFIG_FILE`|Specifies the path to a configuration file. In normal mode, some configurations may be encoded in a configuration protocol buffer. This file must comply with the protocol buffer schema defined in [AOSP `trace_config.proto`](/protos/perfetto/config/data_source_config.proto). You select and configure the data sources using the DataSourceConfig member of the TraceConfig, as defined in [AOSP `data_source_config.proto`](/protos/perfetto/config/data_source_config.proto).|
-|`--txt`|Instructs `perfetto` to parse the config file as pbtxt. This flag is experimental, and it's not recommended that you enable it for production.|
+The following table lists the available options when using `perfetto` in
+*normal* mode.
+
+`-c`, `--config` _CONFIG_FILE_
+: Specifies the path to a configuration file. In normal mode, some
+ configurations may be encoded in a configuration protocol buffer.
+ This file must comply with the protocol buffer schema defined in AOSP
+ [`trace_config.proto`](/protos/perfetto/config/data_source_config.proto).
+ You select and configure the data sources using the DataSourceConfig member
+ of the TraceConfig, as defined in AOSP
+ [`data_source_config.proto`](/protos/perfetto/config/data_source_config.proto).
+
+`--txt`
+: Instructs `perfetto` to parse the config file as pbtxt. This flag is
+ experimental, and it's not recommended that you enable it for production.
diff --git a/docs/toc.md b/docs/toc.md
index 15c1cae7f..0142029dd 100644
--- a/docs/toc.md
+++ b/docs/toc.md
@@ -6,8 +6,10 @@
* [SQL analysis and metrics](quickstart/trace-analysis.md)
* [Trace conversion](quickstart/traceconv.md)
* [Heap profiling](quickstart/heap-profiling.md)
+ * [Callstack sampling on Android](quickstart/callstack-sampling.md)
* [Case studies](#)
+ * [Android boot tracing](case-studies/android-boot-tracing.md)
* [Debugging memory usage](case-studies/memory.md)
* [Data sources](#)
@@ -40,6 +42,8 @@
* [Trace visualization](#)
* [Perfetto UI](visualization/perfetto-ui.md)
* [Visualising large traces](visualization/large-traces.md)
+ * [Deep linking to Perfetto UI](visualization/deep-linking-to-perfetto-ui.md)
+ * [Perfetto UI release process](visualization/perfetto-ui-release-process.md)
* [Core concepts](#)
* [Trace configuration](concepts/config.md)
@@ -70,5 +74,8 @@
* [Heapprofd sampling](design-docs/heapprofd-sampling.md)
* [Life of a tracing session](design-docs/life-of-a-tracing-session.md)
* [Perfetto CI](design-docs/continuous-integration.md)
+ * [Pivot tables](design-docs/pivot-tables.md)
* [ProtoZero](design-docs/protozero.md)
* [Security model](design-docs/security-model.md)
+ * [Statsd Checkpoint Atoms](design-docs/checkpoint-atoms.md)
+
diff --git a/docs/visualization/deep-linking-to-perfetto-ui.md b/docs/visualization/deep-linking-to-perfetto-ui.md
new file mode 100644
index 000000000..5f0148f0a
--- /dev/null
+++ b/docs/visualization/deep-linking-to-perfetto-ui.md
@@ -0,0 +1,142 @@
+# Deep linking to the Perfetto UI
+
+This document describes how to open traces hosted on external servers with the
+Perfetto UI. This can help integrating the Perfetto UI with custom dashboards
+and implement _'Open with Perfetto UI'_-like features.
+
+## Using window.open and postMessage
+
+The supported way of doing this is to _inject_ the trace as an ArrayBuffer
+via `window.open('https://ui.perfetto.dev')` and `postMessage()`.
+In order to do this you need some minimal JavaScript code running on some
+hosting infrastructure you control which can access the trace file. In most
+cases this is some dashboard which you want to deep-link to the Perfetto UI.
+
+#### Open ui.perfetto.dev via window.open
+
+The source dashboard, the one that knows how to locate a trace and deal with
+ACL checking / oauth authentication and the like, creates a new tab by doing
+
+```js
+var handle = window.open('https://ui.perfetto.dev');
+```
+
+The window handle allows bidirectional communication using `postMessage()`
+between the source dashboard and the Perfetto UI.
+
+#### Wait for the UI to be ready via PING/PONG
+
+Wait for the UI to be ready. The `window.open()` message channel is not
+buffered. If you send a message before the opened page has registered an
+`onmessage` listener the messagge will be dropped on the floor.
+In order to avoid this race, you can use a very basic PING/PONG protocol: keep
+sending a 'PING' message until the opened window replies with a 'PONG'.
+When this happens, that is the signal that the Perfetto UI is ready to open
+traces.
+
+#### Post a message the following JavaScript object
+
+```js
+ {
+ 'perfetto': {
+ buffer: ArrayBuffer;
+ title: string;
+ fileName?: string; // Optional
+ url?: string; // Optional
+ }
+ }
+```
+
+`buffer` is the ArrayBuffer with the actual trace file content. This is
+typically something that you obtain by doing a `fetch()` on your backend
+storage.
+
+`title` is the human friendly trace title that will be shown in the
+sidebar. This can help people to disambiguate traces from several tabs.
+
+`fileName` will be used if the user clicks on "Download". A generic name will
+be used if omitted.
+
+`url` is used if the user clicks on the "Share" link in the sidebar. This should
+print to a URL owned by you that would cause your dashboard to re-open the
+current trace, by re-kicking-off the window.open() process herein described.
+If omitted traces won't be shareable.
+
+### Code samples
+
+See [this example caller](https://gistcdn.rawgit.org/primiano/e164868b617844ef8fa4770eb3b323b9/1d9aa2bf52cf903709ea7dd4d583fd2d07d7a255/open_with_perfetto_ui.html),
+for which the code is in
+[this GitHub gist](https://gist.github.com/primiano/e164868b617844ef8fa4770eb3b323b9).
+
+Googlers: take a look at the
+[existing examples in the internal codesearch](http://go/perfetto-ui-deeplink-cs)
+
+### Common pitfalls
+
+Many browsers sometimes block window.open() requests prompting the user to allow
+popups for the site. This usually happens if:
+
+- The window.open() is NOT initiated by a user gesture.
+- Too much time is passed from the user gesture to the window.open()
+
+If the trace file is big enough, the fetch() might take long time and pass the
+user gesture threshold. This can be detected by observing that the window.open()
+returned `null`. When this happens the best option is to show another clickable
+element and bind the fetched trace ArrayBuffer to the new onclick handler, like
+the code in the example above does.
+
+Some browser can have a variable time threshold for the user gesture timeout
+which depends on the website engagement score (how much the user has visited
+the page that does the window.open() before). It's quite common when testing
+this code to see a popup blocker the first time the new feature is used and
+then not see it again.
+
+### Where does the posted trace go?
+
+The Perfetto UI is client-only and doesn't require any server-side interaction.
+Traces pushed via postMessage() are kept only in the browser memory/cache and
+are not sent to any server.
+
+## Why can't I just pass a URL?
+
+_"Why you don't let me just pass a URL to the Perfetto UI (e.g. ui.perfetto.dev?url=...) and you deal with all this?"_
+
+The answer to this is manifold and boils down to security.
+
+#### Cross origin requests blocking
+
+If ui.perfetto.dev had to do a `fetch('https://yourwebsite.com/trace')` that
+would be a cross-origin request. Browsers disallow by default cross-origin
+fetch requests.
+In order for this to work, the web server that hosts yourwebsite.com would have
+to expose a custom HTTP response header
+ (`Access-Control-Allow-Origin: https://ui.perfetto.dev`) to allow the fetch.
+In most cases customizing the HTTP response headers is outside of dashboard's
+owners control.
+
+You can learn more about CORS at
+https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
+
+#### Content Security Policy
+
+Perfetto UI uses a strict Content Security Policy which disallows foreign
+fetches and subresources, as a security mitigation about common attacks.
+Even assuming that CORS headers are properly set and your trace files are
+publicly accessible, fetching the trace from the Perfetto UI would require
+allow-listing your origin in our CSP policy. This is not scalable.
+
+You can learn more about CSP at
+https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
+
+#### Dealing with OAuth2 or other authentication mechanisms
+
+Even ignoring CORS, the Perfetto UI would have to deal with OAuth2 or other
+authentication mechanisms to fetch the trace file. Even if all the dashboards
+out there used OAuth2, that would still mean that Perfetto UI would have to know
+about all the possible OAuth2 scopes, one for each dashboard. This is not
+scalable.
+
+## Source links
+
+The source code that deals with the postMessage() in the Perfetto UI is
+[`post_message_handler.ts`](/ui/src/frontend/post_message_handler.ts)
diff --git a/docs/visualization/perfetto-ui-release-process.md b/docs/visualization/perfetto-ui-release-process.md
new file mode 100644
index 000000000..ed0af8d56
--- /dev/null
+++ b/docs/visualization/perfetto-ui-release-process.md
@@ -0,0 +1,108 @@
+# Perfetto UI Release Process
+
+The UI has three release channels which are configured by the
+[channels.json](/ui/release/channels.json) file. The channels are:
+
+- `stable`, the version served by default on ui.perfetto.dev.
+ Updated every four weeks.
+- `canary`, a less stable but fresher release. Updated every 1-2 weeks.
+- `autopush`, the current HEAD version of the UI. Unstable.
+
+The release process is based around a four week cycle.
+
+- Week 1: Update `canary` to `HEAD`.
+- Week 2: Update `canary` to `HEAD`.
+ Canary stabilization week 1/2 starts here.
+ Only critical bug fixes can be cherry-picked onto `canary`.
+- Week 3: Canary stabilization week 2/2.
+- Week 4: Update `stable` to current `canary`, update `canary` to `HEAD`.
+
+After the fourth week the cycle repeats from week one.
+This is so that:
+
+- Canary soaks for two weeks before being promoted to stable.
+- Newer features can be tried out in Canary within a week, or two at most (if
+ in the stabilization weeks).
+- Stable users aren't disrupted more than once per month.
+
+## Changing release channel
+
+NOTE: The channel setting is persistent across page reloads.
+
+The channel the UI is currently using is displayed in the top left corner.
+If the tag after the logo shows `autopush` or `canary` that is the current channel
+and if no tag is displayed the current channel is `stable`.
+
+![perfetto-ui-channel.png](/docs/images/perfetto-ui-channel.png)
+
+To change the channel the UI is using between `stable` and `canary` you can use the toggle on the [entrance page](https://ui.perfetto.dev).
+
+![perfetto-ui-channel-toggle.png](/docs/images/perfetto-ui-channel-toggle.png)
+
+To change to the `autopush` channel, open the `Flags` screen in the `Support`
+section of the sidebar, and choose `Autopush` in `Release channel`.
+
+## Which version am I using?
+
+You can see the version of the UI you are currently using in the bottom left hand corner of the UI.
+
+![perfetto-ui-version.png](/docs/images/perfetto-ui-version.png)
+
+Clicking on the version number takes you to Github where you can see which commits are part of this version. The version number format is `v<maj>.<min>.<Commit SHA1 prefix>` where `<maj>.<min>` are extracted from the top entry in the
+[CHANGELOG](/CHANGELOG).
+
+## Cherry-picking a change
+
+If a change needs to be backported onto canary or stable branches, do the
+following:
+
+```bash
+git fetch origin
+git co -b ui-canary -t origin/ui-canary
+git cherry-pick -x $SHA1_OF_ORIGINAL_CL
+git cl upload
+
+# Repeat for origin/ui-stable branch if needed.
+```
+
+Once the cherry-picks are landed, send out a CL to update the
+[channels.json](/ui/release/channels.json) in the `master` branch. See
+[r.android.com/1726101](https://r.android.com/1726101) for an example.
+
+```json
+{
+ "channels": [
+ {
+ "name": "stable",
+ "rev": "6dd6756ffbdff4f845c4db28e1fd5aed9ba77b56"
+ // ^ This should point to the HEAD of origin/ui-stable.
+ },
+ {
+ "name": "canary",
+ "rev": "3e21f613f20779c04b0bcc937f2605b9b05556ad"
+ // ^ This should point to the HEAD of origin/ui-canary.
+ },
+ {
+ "name": "autopush",
+ "rev": "HEAD"
+ // ^ Don't touch this one.
+ }
+ ]
+}
+```
+
+The state of `channels.json` in the other branches is irrelevant, the release
+infrastructure only looks at the `master` branch to determine the pinning of
+each channel.
+
+After the `channels.json` CL lands, the build infrastructure will pick it up
+and update ui.perfetto.dev within ~30 mins.
+
+Googlers: You can check build progress and logs on
+[go/perfetto-ui-build-status](http://go/perfetto-ui-build-status). See also
+[go/perfetto-ui-autopush](http://go/perfetto-ui-autopush) and
+[go/perfetto-ui-channels](http://go/perfetto-ui-channels) for the design docs of
+the serving infrastructure.
+
+## Publishing the Perfetto Chrome extension
+Googlers: see go/perfetto-release-chrome-extension
diff --git a/docs/visualization/perfetto-ui.md b/docs/visualization/perfetto-ui.md
index 426f2dce8..a3f16ba24 100644
--- a/docs/visualization/perfetto-ui.md
+++ b/docs/visualization/perfetto-ui.md
@@ -71,3 +71,25 @@ This produces a visualization like this:
Note: There is no equivalent debug counters feature yet, but the feature request
is tracked on [b/168886909](http://b/168886909)).
+
+### Pivot Tables
+
+To use pivot tables in the Perfetto UI, you will need to enable the
+"Pivot tables" feature flag in the "Flags" tab under "Support" in the Sidebar.
+You can pop up a pivot table over the entire trace when clicking "p" on your
+keyboard. The "Edit" button opens a pop up window to add/remove and reorder
+columns and change the default sorting of aggregations.
+
+![Pivot table editor](/docs/images/pivot-tables/pivot-table-editor.png)
+
+Clicking on "Query" generates a table with the selected columns.
+Table cells with the expand icon can be expanded to show the next column values.
+The "name (stack)" column displays top level slices that can be expanded to show
+their descendants down to the last child.
+
+![Pivot table](/docs/images/pivot-tables/pivot-table.png)
+
+Area selection pops up a pre-filled pivot table restricted over the selected
+timestamps and track ids.
+
+![Pivot table area selection](/docs/images/pivot-tables/pivot-table-area-selection.png)
diff --git a/examples/sdk/BUILD.gn b/examples/sdk/BUILD.gn
new file mode 100644
index 000000000..a801d29a0
--- /dev/null
+++ b/examples/sdk/BUILD.gn
@@ -0,0 +1,29 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("../../gn/perfetto.gni")
+
+executable("sdk_example") {
+ sources = [
+ "example.cc",
+ "trace_categories.cc",
+ "trace_categories.h",
+ ]
+ cflags = [ "-DPERFETTO_SDK_EXAMPLE_USE_INTERNAL_HEADERS" ]
+ testonly = true
+ deps = [
+ "../..:libperfetto_client_experimental",
+ "../../gn:default_deps",
+ ]
+}
diff --git a/examples/sdk/README.md b/examples/sdk/README.md
index 3b8295f05..aa881715a 100644
--- a/examples/sdk/README.md
+++ b/examples/sdk/README.md
@@ -15,7 +15,7 @@ Dependencies:
First, check out the latest Perfetto release:
```bash
-git clone https://android.googlesource.com/platform/external/perfetto -b v14.0
+git clone https://android.googlesource.com/platform/external/perfetto -b v23.0
```
Then, build using CMake:
@@ -98,7 +98,7 @@ information such as CPU frequencies and kernel scheduler information.
> Tip: You can generate a new trace config with additional data sources using
> the [Perfetto UI](https://ui.perfetto.dev/#!/record) and replace
> `system_wide_trace_cfg.pbtxt` with the [generated config](
-> https://ui.perfetto.dev/#!/record?p=instructions).
+> https://ui.perfetto.dev/#!/record/instructions).
## Custom data source example
diff --git a/examples/sdk/example.cc b/examples/sdk/example.cc
index b2826176c..8ac92ab62 100644
--- a/examples/sdk/example.cc
+++ b/examples/sdk/example.cc
@@ -15,6 +15,14 @@
*/
// This example demonstrates in-process tracing with Perfetto.
+// This program adds trace in a few example functions like DrawPlayer DrawGame
+// etc. and collect the trace in file `example.pftrace`.
+// This output file is not readable directly. It can be read after converting
+// it to text, by running the command:
+// `./tools/traceconv text example.pftrace`
+// or it can be opened in UI : https://ui.perfetto.dev
+//
+// To compile this file, run: `./tools/ninja -C out/default sdk_example`.
#include "trace_categories.h"
@@ -22,6 +30,8 @@
#include <fstream>
#include <thread>
+namespace {
+
void InitializePerfetto() {
perfetto::TracingInitArgs args;
// The backends determine where trace events are recorded. For this example we
@@ -61,8 +71,11 @@ void StopTracing(std::unique_ptr<perfetto::TracingSession> tracing_session) {
// directly into a file by passing a file descriptor into Setup() above.
std::ofstream output;
output.open("example.pftrace", std::ios::out | std::ios::binary);
- output.write(&trace_data[0], trace_data.size());
+ output.write(&trace_data[0], std::streamsize(trace_data.size()));
output.close();
+ PERFETTO_LOG(
+ "Trace written in example.pftrace file. To read this trace in "
+ "text form, run `./tools/traceconv text example.pftrace`");
}
void DrawPlayer(int player_number) {
@@ -83,6 +96,8 @@ void DrawGame() {
TRACE_COUNTER("rendering", "Framerate", 120);
}
+} // namespace
+
int main(int, const char**) {
InitializePerfetto();
auto tracing_session = StartTracing();
diff --git a/examples/sdk/trace_categories.cc b/examples/sdk/trace_categories.cc
index cce90f865..646af7a4b 100644
--- a/examples/sdk/trace_categories.cc
+++ b/examples/sdk/trace_categories.cc
@@ -17,4 +17,4 @@
#include "trace_categories.h"
// Reserves internal static storage for our tracing categories.
-PERFETTO_TRACK_EVENT_STATIC_STORAGE(); \ No newline at end of file
+PERFETTO_TRACK_EVENT_STATIC_STORAGE();
diff --git a/examples/sdk/trace_categories.h b/examples/sdk/trace_categories.h
index c2dd852af..2fbfe1214 100644
--- a/examples/sdk/trace_categories.h
+++ b/examples/sdk/trace_categories.h
@@ -17,7 +17,17 @@
#ifndef TRACE_CATEGORIES_H
#define TRACE_CATEGORIES_H
+// This source file can be built in two ways:
+// 1. As part of the regular GN build, against standard includes.
+// 2. To test that the amalgmated SDK works, against the perfetto.h source.
+#ifdef PERFETTO_SDK_EXAMPLE_USE_INTERNAL_HEADERS
+#include "perfetto/tracing/core/trace_config.h"
+#include "perfetto/tracing/tracing.h"
+#include "perfetto/tracing/track_event.h"
+#include "protos/perfetto/trace/track_event/process_descriptor.gen.h"
+#else
#include <perfetto.h>
+#endif
// The set of track event categories that the example is using.
PERFETTO_DEFINE_CATEGORIES(
diff --git a/gn/BUILD.gn b/gn/BUILD.gn
index 1f799ade3..b0e61b1b9 100644
--- a/gn/BUILD.gn
+++ b/gn/BUILD.gn
@@ -43,6 +43,9 @@ action("gen_buildflags") {
perfetto_force_dlog_on = perfetto_force_dlog == "on"
perfetto_force_dlog_off = perfetto_force_dlog == "off"
+ perfetto_force_dcheck_on = perfetto_force_dcheck == "on"
+ perfetto_force_dcheck_off = perfetto_force_dcheck == "off"
+
# We can't just use (is_linux || is_android) in perfetto.gni because that
# doesn't work in Android Mac host builds. We lose the GN notion of OS once
# we run the tools/gen_xxx generators.
@@ -71,6 +74,8 @@ action("gen_buildflags") {
"PERFETTO_COMPONENT_BUILD=$perfetto_component_build",
"PERFETTO_FORCE_DLOG_ON=$perfetto_force_dlog_on",
"PERFETTO_FORCE_DLOG_OFF=$perfetto_force_dlog_off",
+ "PERFETTO_FORCE_DCHECK_ON=$perfetto_force_dcheck_on",
+ "PERFETTO_FORCE_DCHECK_OFF=$perfetto_force_dcheck_off",
"PERFETTO_VERBOSE_LOGS=$perfetto_verbose_logs_enabled",
"PERFETTO_VERSION_GEN=$enable_perfetto_version_gen",
"PERFETTO_TP_PERCENTILE=$enable_perfetto_trace_processor_percentile",
@@ -79,6 +84,11 @@ action("gen_buildflags") {
"PERFETTO_TP_JSON=$enable_perfetto_trace_processor_json",
"PERFETTO_LOCAL_SYMBOLIZER=$perfetto_local_symbolizer",
"PERFETTO_ZLIB=$enable_perfetto_zlib",
+ "PERFETTO_TRACED_PERF=$enable_perfetto_traced_perf",
+ "PERFETTO_HEAPPROFD=$enable_perfetto_heapprofd",
+ "PERFETTO_STDERR_CRASH_DUMP=$enable_perfetto_stderr_crash_dump",
+ "PERFETTO_X64_CPU_OPT=$enable_perfetto_x64_cpu_opt",
+ "PERFETTO_LLVM_DEMANGLE=$enable_perfetto_llvm_demangle",
]
rel_out_path = rebase_path(gen_header_path, "$root_build_dir")
@@ -95,7 +105,8 @@ action("gen_buildflags") {
# All targets should depend on this target to inherit the right flags and
# include directories.
group("default_deps") {
- visibility = [ "../*" ] # Prevent chromium targets from depending on this (breaks component).
+ visibility = [ "../*" ] # Prevent chromium targets from depending on this
+ # (breaks component).
public_configs = [ ":default_config" ]
deps = [ ":gen_buildflags" ]
if (perfetto_build_standalone) {
@@ -115,7 +126,8 @@ group("default_deps") {
# embedders that depend on perfetto (e.g. chrome). :public_config (see below) is
# used for that.
config("default_config") {
- visibility = [ "../*" ] # Prevent chromium targets from depending on this (breaks component).
+ visibility = [ "../*" ] # Prevent chromium targets from depending on this
+ # (breaks component).
configs = [ ":public_config" ]
defines = [ "PERFETTO_IMPLEMENTATION" ]
include_dirs = [
@@ -384,6 +396,12 @@ if (enable_perfetto_zlib) {
}
}
+if (enable_perfetto_llvm_demangle) {
+ group("llvm_demangle") {
+ public_deps = [ "//buildtools:llvm_demangle" ]
+ }
+}
+
# Used by fuzzers.
if (enable_perfetto_fuzzers && use_libfuzzer) {
group("libfuzzer") {
diff --git a/gn/gen_perfetto_version_header.gni b/gn/gen_perfetto_version_header.gni
index 17c879f74..59cd6819c 100644
--- a/gn/gen_perfetto_version_header.gni
+++ b/gn/gen_perfetto_version_header.gni
@@ -21,15 +21,20 @@
import("perfetto.gni")
+_ver_script = "${perfetto_root_path}tools/write_version_header.py"
+_has_git = false
+if (perfetto_enable_git_rev_version_header) {
+ _has_git = "1" == exec_script(_ver_script, [ "--check_git" ], "trim string")
+}
+
template("gen_perfetto_version_header") {
action(target_name) {
- script = "${perfetto_root_path}tools/write_version_header.py"
+ script = _ver_script
changelog = "${perfetto_root_path}CHANGELOG"
inputs = [ changelog ]
outputs = []
args = []
- if (perfetto_build_standalone && !is_perfetto_build_generator &&
- perfetto_enable_git_rev_version_header) {
+ if (_has_git) {
inputs += [ "${perfetto_root_path}.git/HEAD" ]
}
@@ -49,7 +54,7 @@ template("gen_perfetto_version_header") {
]
outputs += [ invoker.ts_out ]
}
- if (!perfetto_enable_git_rev_version_header) {
+ if (!_has_git) {
args += [ "--no_git" ]
}
}
diff --git a/gn/perfetto.gni b/gn/perfetto.gni
index c1ff723a8..9c4ebe2fc 100644
--- a/gn/perfetto.gni
+++ b/gn/perfetto.gni
@@ -100,7 +100,7 @@ perfetto_build_standalone =
# Only relevant for GN builds. Sets the path where perfetto lives. This is //
# for standalone builds and //third_party/perfetto/ in embedders. The embedder
-# can ovverride it in its GN files.
+# can override it in its GN files.
if (perfetto_build_standalone || is_perfetto_build_generator) {
perfetto_root_path = "//"
import("//gn/standalone/android.gni") # For android_api_level
@@ -144,9 +144,12 @@ declare_args() {
# system backend in the client library.
# This includes building things that rely on POSIX sockets, this places
# limitations on the supported operating systems.
- enable_perfetto_ipc = !is_win && !is_fuchsia && !is_nacl &&
- (perfetto_build_standalone ||
- perfetto_build_with_android || build_with_chromium)
+ # For now the IPC layer is conservatively not enabled on Chromium+Windows
+ # builds.
+ enable_perfetto_ipc =
+ !is_fuchsia && !is_nacl &&
+ (perfetto_build_standalone || perfetto_build_with_android ||
+ (build_with_chromium && !is_win))
# Makes the heap profiling daemon target reachable. It works only on Android,
# but is built on Linux as well for test/compiler coverage.
@@ -157,7 +160,6 @@ declare_args() {
(is_linux || (is_android && android_api_level >= 26)))
# Build the perf event profiler (traced_perf).
- # TODO(b/144281346): under development.
# TODO(rsavitski): figure out how to make the android-core dependencies build
# under gcc (_Atomic and other issues).
enable_perfetto_traced_perf =
@@ -172,11 +174,13 @@ declare_args() {
is_perfetto_build_generator
}
- # Enables base::Watchdog. Is supported only on Linux-based platforms.
+ # Enables base::Watchdog. Is supported only on Linux-based platforms in
+ # standalone GN builds (NOT in bazel/blaze).
# gn/BUILD.gn further restricts this to OS_LINUX || OS_ANDROID when generating
# the perfetto_build_flags.h header.
enable_perfetto_watchdog =
- perfetto_build_with_android || perfetto_build_standalone
+ perfetto_build_with_android ||
+ (perfetto_build_standalone && !is_perfetto_build_generator)
# Misc host executable under tools/.
enable_perfetto_tools =
@@ -186,7 +190,7 @@ declare_args() {
build_with_chromium || perfetto_build_with_android
enable_perfetto_integration_tests =
- (perfetto_build_standalone && !is_win) || perfetto_build_with_android
+ perfetto_build_standalone || perfetto_build_with_android
enable_perfetto_benchmarks = perfetto_build_standalone && !is_win
@@ -214,15 +218,34 @@ declare_args() {
# console.
perfetto_force_dlog = perfetto_force_dlog_default
+ # Whether DCHECKs should be enabled or not. Values: "on" | "off" | "".
+ # By default ("") DCHECKs are enabled only:
+ # - If DCHECK_ALWAYS_ON is defined (which is mainly a Chromium-ism).
+ # - On debug builds (i.e. if NDEBUG is NOT defined) but only in Chromium,
+ # Android and standalone builds.
+ # - On all other builds (e.g., SDK) it's off regardless of NDEBUG (unless
+ # DCHECK_ALWAYS_ON is defined).
+ # See base/logging.h for the implementation of all this.
+ perfetto_force_dcheck = ""
+
# Installs a signal handler for the most common crash signals which unwinds
# the stack and prints the stack trace on stderr. Requires a dependency on
# libbacktrace when enabled.
enable_perfetto_stderr_crash_dump =
is_debug && perfetto_build_standalone && !is_wasm && !is_win
+
+ # Enables more aggressive compiler flags that assume recent Intel CPUs.
+ # Runtime checks during initialization will print an error message and exit
+ # if the CPU doesn't support those flags.
+ enable_perfetto_x64_cpu_opt =
+ current_cpu == "x64" && (is_linux || is_mac) && !is_wasm &&
+ perfetto_build_standalone && !is_perfetto_build_generator
}
declare_args() {
- perfetto_enable_git_rev_version_header = enable_perfetto_version_gen
+ perfetto_enable_git_rev_version_header =
+ enable_perfetto_version_gen && perfetto_build_standalone &&
+ !is_perfetto_build_generator
# The traced_probes daemon is very Linux-specific, as it depends on ftrace and
# various /proc interfaces. There is no point making its code platform-neutral
@@ -259,12 +282,20 @@ declare_args() {
# Enables httpd RPC support in the trace processor.
# Further per-OS conditionals are applied in gn/BUILD.gn.
enable_perfetto_trace_processor_httpd =
- enable_perfetto_trace_processor && perfetto_build_standalone
+ enable_perfetto_trace_processor &&
+ (perfetto_build_standalone || perfetto_build_with_android)
# Enables Zlib support. This is used both by the "perfetto" cmdline client
# (for compressing traces) and by trace processor (for compressed traces).
enable_perfetto_zlib =
- enable_perfetto_trace_processor || enable_perfetto_platform_services
+ (enable_perfetto_trace_processor && !build_with_chromium) ||
+ enable_perfetto_platform_services
+
+ # Enables function name demangling using sources from llvm. Otherwise
+ # trace_processor falls back onto using the c++ runtime demangler, which
+ # typically handles only itanium mangling.
+ enable_perfetto_llvm_demangle =
+ enable_perfetto_trace_processor && perfetto_build_standalone
}
declare_args() {
@@ -314,9 +345,6 @@ assert(!build_with_chromium || perfetto_build_with_embedder)
# |is_perfetto_build_generator| must be true.
assert(!perfetto_build_with_android || is_perfetto_build_generator)
-# The IPC layer based on UNIX sockets can't be built on Win.
-assert(!enable_perfetto_ipc || !is_win)
-
# We should never end up in a state where is_perfetto_embedder=true but
# perfetto_build_with_embedder=false.
assert(!is_perfetto_embedder || perfetto_build_with_embedder)
diff --git a/gn/perfetto_integrationtests.gni b/gn/perfetto_integrationtests.gni
index d1005fdb3..7527a55d4 100644
--- a/gn/perfetto_integrationtests.gni
+++ b/gn/perfetto_integrationtests.gni
@@ -24,7 +24,7 @@ if (enable_perfetto_traced_probes) {
# enable_perfetto_traced_probes implies enable_perfetto_platform_services.
perfetto_integrationtests_targets += [
"src/traced/probes/ftrace:integrationtests",
- "test:end_to_end_integrationtests",
+ "test:integrationtests",
]
}
diff --git a/gn/perfetto_unittests.gni b/gn/perfetto_unittests.gni
index 1a2b48219..dec85bc87 100644
--- a/gn/perfetto_unittests.gni
+++ b/gn/perfetto_unittests.gni
@@ -81,6 +81,10 @@ if (enable_perfetto_traced_perf) {
if (enable_perfetto_trace_processor) {
perfetto_unittests_targets += [ "src/trace_processor:unittests" ]
+ # TODO(mohitms): reenable this once we no longer link lite and full protobuf
+ # simultaneously.
+ # perfetto_unittests_targets += [ "tools/trace_to_text:unittests" ]
+
if (enable_perfetto_trace_processor_sqlite) {
perfetto_unittests_targets += [ "src/trace_processor/metrics:unittests" ]
}
diff --git a/gn/proto_library.gni b/gn/proto_library.gni
index 03d645540..d1794d565 100644
--- a/gn/proto_library.gni
+++ b/gn/proto_library.gni
@@ -173,6 +173,17 @@ template("ipc_library") {
} else {
deps += [ "$perfetto_root_path/src/ipc:common" ]
}
+ if (is_win) {
+ # TODO(primiano): investigate this. In Windows standalone builds, some
+ # executable targets end up in a state where no code pulls a dep on the
+ # ipc:client (in turn that seems a subtle consequence of not having
+ # traced_probes on Windows). This dep here is effectively needed because
+ # the client-side code in the generated .ipc.cc effectively depends on the
+ # client-side IPC library. Perhaps we just should do this unconditionally
+ # on all platforms?
+ deps += [ "$perfetto_root_path/src/ipc:client" ]
+ }
+
if (defined(invoker.deps)) {
deps += invoker.deps
}
@@ -243,6 +254,16 @@ template("perfetto_proto_library") {
}
}
+ # The distinction between deps and public_deps does not matter for GN
+ # but Bazel cares about the difference so we distinguish between the two.
+ public_deps_ = []
+ if (defined(invoker.public_deps)) {
+ foreach(dep, invoker.public_deps) {
+ public_deps_ = [ string_replace(dep, expansion_token, gen_type) ]
+ }
+ }
+ deps_ += public_deps_
+
if (gen_type == "zero") {
protozero_library(target_name_) {
proto_in_dir = proto_path
@@ -317,6 +338,7 @@ template("perfetto_proto_library") {
metadata = {
proto_library_sources = invoker.sources
import_dirs = import_dirs_
+ exports = get_path_info(public_deps_, "abspath")
}
forward_variables_from(invoker, vars_to_forward)
}
diff --git a/gn/standalone/BUILD.gn b/gn/standalone/BUILD.gn
index af70070f7..ab21e5877 100644
--- a/gn/standalone/BUILD.gn
+++ b/gn/standalone/BUILD.gn
@@ -81,6 +81,7 @@ config("extra_warnings") {
"-Wno-padded",
"-Wno-poison-system-directories",
"-Wno-reserved-id-macro",
+ "-Wno-reserved-identifier",
"-Wno-unknown-sanitizers",
"-Wno-unknown-warning-option",
]
@@ -115,7 +116,16 @@ config("c++11") {
}
}
-# This is needed to compile libunwindstack.
+# Used in buildtools dependencies for standalone builds.
+config("c++14") {
+ if (is_win) {
+ cflags_cc = [ "/std:c++14" ]
+ } else {
+ cflags_cc = [ "-std=c++14" ]
+ }
+}
+
+# Used in buildtools dependencies for standalone builds.
config("c++17") {
if (is_win) {
cflags_cc = [ "/std:c++17" ]
@@ -161,6 +171,8 @@ config("default") {
cflags += [
"/bigobj", # Some of our files are bigger than the regular limits.
"/Gy", # Enable function-level linking.
+ "/FS", # Preserve previous PDB behavior.
+ "/utf-8", # Assume UTF-8 by default to avoid code page dependencies.
]
defines += [
"_CRT_NONSTDC_NO_WARNINGS",
@@ -207,10 +219,10 @@ config("default") {
ldflags += [ "-flto=full" ]
}
- # We support only x64 builds on Windows.
- assert(!is_win || current_cpu == "x64")
-
- if (current_cpu == "arm") {
+ if (is_win) {
+ # We support only x86/x64 builds on Windows.
+ assert(current_cpu == "x64" || current_cpu == "x86")
+ } else if (current_cpu == "arm") {
cflags += [
"-march=armv7-a",
"-mfpu=neon",
@@ -229,6 +241,17 @@ config("default") {
]
} else if (current_cpu == "arm64") {
cflags += [ "-fno-omit-frame-pointer" ]
+ } else if (current_cpu == "x64") {
+ cflags += [ "-fno-omit-frame-pointer" ] # For perf profiling.
+ if (enable_perfetto_x64_cpu_opt) {
+ # When updating these flags, the CheckCpuOptimizations() in utils.cc must
+ # be updated accordingly.
+ cflags += [
+ "-mavx",
+ "-mpopcnt",
+ "-msse4.2",
+ ]
+ }
}
if (is_linux) {
diff --git a/gn/standalone/BUILDCONFIG.gn b/gn/standalone/BUILDCONFIG.gn
index e0807004a..6f32686c1 100644
--- a/gn/standalone/BUILDCONFIG.gn
+++ b/gn/standalone/BUILDCONFIG.gn
@@ -55,9 +55,13 @@ if (current_cpu == "") {
current_cpu = target_cpu
}
-is_cross_compiling =
- target_cpu != host_cpu || target_os != host_os || target_triplet != ""
-
+declare_args() {
+ # the ossfuzz sanitizer overrides this to true. In that config the
+ # host/target cpu and arch are identical, but we want to build only the
+ # targets with the sanitizer/fuzzer flags
+ is_cross_compiling =
+ target_cpu != host_cpu || target_os != host_os || target_triplet != ""
+}
default_configs = [
"//gn/standalone:debug_symbols",
"//gn/standalone:default",
diff --git a/gn/standalone/libc++/BUILD.gn b/gn/standalone/libc++/BUILD.gn
index 809a448ee..f6b61313a 100644
--- a/gn/standalone/libc++/BUILD.gn
+++ b/gn/standalone/libc++/BUILD.gn
@@ -20,6 +20,13 @@ config("config") {
"_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
"_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
]
+ if (is_debug) {
+ # libc++ has two levels of debug mode. Setting _LIBCPP_DEBUG to zero
+ # enables most assertions. Setting it to one additionally enables iterator
+ # debugging, but that seems to require some extra link-time dependencies.
+ # See https://libcxx.llvm.org/docs/DesignDocs/DebugMode.html
+ defines += [ "_LIBCPP_DEBUG=0" ]
+ }
cflags_cc = [
"-nostdinc++",
"-isystem" + rebase_path("$libcxx_prefix/include", root_build_dir),
@@ -28,9 +35,7 @@ config("config") {
# Avoid linking both libc++ and libstdc++.
ldflags = [ "-nostdlib++" ]
- libs = [
- "dl", # libdl: dynamic linking.
- ]
+ libs = [ "dl" ] # libdl: dynamic linking.
}
}
diff --git a/gn/standalone/sanitizers/BUILD.gn b/gn/standalone/sanitizers/BUILD.gn
index d3374deec..574dcfb2d 100644
--- a/gn/standalone/sanitizers/BUILD.gn
+++ b/gn/standalone/sanitizers/BUILD.gn
@@ -33,60 +33,59 @@ if (is_android && sanitizer_lib != "" && !sanitizer_lib_dir_is_static) {
}
config("sanitizers_cflags") {
- cflags = []
- defines = []
if (using_sanitizer) {
- cflags += [ "-fno-omit-frame-pointer" ]
- }
+ cflags = [ "-fno-omit-frame-pointer" ]
+ defines = []
- if (is_asan) {
- cflags += [ "-fsanitize=address" ]
- defines += [ "ADDRESS_SANITIZER" ]
- }
- if (is_lsan) {
- cflags += [ "-fsanitize=leak" ]
- defines += [ "LEAK_SANITIZER" ]
- }
- if (is_tsan) {
- cflags += [ "-fsanitize=thread" ]
- defines += [
- "THREAD_SANITIZER",
- "DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL=1",
- ]
- }
- if (is_msan) {
- cflags += [
- "-fsanitize=memory",
- "-fsanitize-memory-track-origins=2",
- ]
- defines += [ "MEMORY_SANITIZER" ]
- }
- if (is_ubsan) {
- cflags += [
- "-fsanitize=bounds",
- "-fsanitize=float-divide-by-zero",
- "-fsanitize=integer-divide-by-zero",
- "-fsanitize=null",
- "-fsanitize=object-size",
- "-fsanitize=return",
- "-fsanitize=returns-nonnull-attribute",
- "-fsanitize=shift-exponent",
- "-fsanitize=signed-integer-overflow",
- "-fsanitize=unreachable",
- "-fsanitize=vla-bound",
- ]
- defines += [ "UNDEFINED_SANITIZER" ]
- }
- if (is_fuzzer) {
- # FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION is also defined by oss-fuzz,
- # so using the same name.
- defines += [ "FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" ]
- cflags += [ "-fsanitize=fuzzer-no-link" ]
if (is_asan) {
+ cflags += [ "-fsanitize=address" ]
+ defines += [ "ADDRESS_SANITIZER" ]
+ }
+ if (is_lsan) {
+ cflags += [ "-fsanitize=leak" ]
+ defines += [ "LEAK_SANITIZER" ]
+ }
+ if (is_tsan) {
+ cflags += [ "-fsanitize=thread" ]
+ defines += [
+ "THREAD_SANITIZER",
+ "DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL=1",
+ ]
+ }
+ if (is_msan) {
+ cflags += [
+ "-fsanitize=memory",
+ "-fsanitize-memory-track-origins=2",
+ ]
+ defines += [ "MEMORY_SANITIZER" ]
+ }
+ if (is_ubsan) {
cflags += [
- "-mllvm",
- "-asan-use-private-alias",
+ "-fsanitize=bounds",
+ "-fsanitize=float-divide-by-zero",
+ "-fsanitize=integer-divide-by-zero",
+ "-fsanitize=null",
+ "-fsanitize=object-size",
+ "-fsanitize=return",
+ "-fsanitize=returns-nonnull-attribute",
+ "-fsanitize=shift-exponent",
+ "-fsanitize=signed-integer-overflow",
+ "-fsanitize=unreachable",
+ "-fsanitize=vla-bound",
]
+ defines += [ "UNDEFINED_SANITIZER" ]
+ }
+ if (is_fuzzer) {
+ # FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION is also defined by oss-fuzz,
+ # so using the same name.
+ defines += [ "FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" ]
+ cflags += [ "-fsanitize=fuzzer-no-link" ]
+ if (is_asan) {
+ cflags += [
+ "-mllvm",
+ "-asan-use-private-alias",
+ ]
+ }
}
}
}
@@ -98,25 +97,27 @@ config("sanitizer_options_link_helper") {
}
config("sanitizers_ldflags") {
- visibility = [ ":deps" ]
- ldflags = []
- if (is_asan) {
- ldflags += [ "-fsanitize=address" ]
- }
- if (is_lsan) {
- # This is not a copy/paste mistake. The LSan runtime library has
- # moved into asan. So in order to make LSan work one has to build
- # .cc files with -fsanitize=leak but link with -fsanitize=address.
- ldflags += [ "-fsanitize=address" ]
- }
- if (is_tsan) {
- ldflags += [ "-fsanitize=thread" ]
- }
- if (is_msan) {
- ldflags += [ "-fsanitize=memory" ]
- }
- if (is_ubsan) {
- ldflags += [ "-fsanitize=undefined" ]
+ if (using_sanitizer) {
+ visibility = [ ":deps" ]
+ ldflags = []
+ if (is_asan) {
+ ldflags += [ "-fsanitize=address" ]
+ }
+ if (is_lsan) {
+ # This is not a copy/paste mistake. The LSan runtime library has
+ # moved into asan. So in order to make LSan work one has to build
+ # .cc files with -fsanitize=leak but link with -fsanitize=address.
+ ldflags += [ "-fsanitize=address" ]
+ }
+ if (is_tsan) {
+ ldflags += [ "-fsanitize=thread" ]
+ }
+ if (is_msan) {
+ ldflags += [ "-fsanitize=memory" ]
+ }
+ if (is_ubsan) {
+ ldflags += [ "-fsanitize=undefined" ]
+ }
+ configs = [ ":sanitizer_options_link_helper" ]
}
- configs = [ ":sanitizer_options_link_helper" ]
}
diff --git a/gn/standalone/sanitizers/vars.gni b/gn/standalone/sanitizers/vars.gni
index 9dada7875..228908faa 100644
--- a/gn/standalone/sanitizers/vars.gni
+++ b/gn/standalone/sanitizers/vars.gni
@@ -47,8 +47,9 @@ declare_args() {
}
declare_args() {
- using_sanitizer =
- is_asan || is_lsan || is_tsan || is_msan || is_ubsan || use_libfuzzer
+ # Don't build host artifacts with sanitizers/fuzzers, only target toolchain.
+ using_sanitizer = (is_asan || is_lsan || is_tsan || is_msan || is_ubsan ||
+ use_libfuzzer) && current_toolchain == default_toolchain
}
assert(!using_sanitizer || is_clang || is_system_compiler,
diff --git a/gn/standalone/toolchain/BUILD.gn b/gn/standalone/toolchain/BUILD.gn
index f72c6068c..408f1f611 100644
--- a/gn/standalone/toolchain/BUILD.gn
+++ b/gn/standalone/toolchain/BUILD.gn
@@ -49,14 +49,28 @@ declare_args() {
# 2. setting is_system_compiler=true in args.gn and the env vars AR/CC/CXX.
# This is used by OSSFuzz and CrOS ebuilds.
+_llvm_strip_wrapper = rebase_path("llvm-strip.py", root_build_dir)
+
declare_args() {
sysroot = ""
gcc_toolchain = ""
ar = "ar"
linker = ""
+ strip = ""
if (is_linux_host) {
linker = "gold"
+ if (linux_llvm_objcopy != "") {
+ # If we are using the hermetic clang toolchain llvm-objcopy from there as
+ # it works with Linux-arm cross toolchains. The |_llvm_strip_wrapper| is
+ # to set argv0 as llvm-strip. llvm-objcopy's frontend works differently
+ # when invoked as llvm-strip, pretending to be just 'strip'.
+ strip = "${_llvm_strip_wrapper} ${linux_llvm_objcopy}"
+ } else {
+ strip = "strip"
+ }
+ } else if (is_mac_host) {
+ strip = "strip -x"
}
if (is_clang) {
@@ -86,7 +100,7 @@ declare_args() {
# Then determine the target toolchain.
declare_args() {
- target_sysroot = sysroot
+ _default_target_sysroot = ""
target_gcc_toolchain = ""
# |target_triplet| is the variable that the user can set via GN args. The user
@@ -105,10 +119,16 @@ declare_args() {
_target_triplet = "x86_64-apple-darwin"
} else if (target_os == "mac" && target_cpu == "x86") {
_target_triplet = "i686-apple-darwin"
+ } else if (target_os == "mac" && target_cpu == "arm64") {
+ _target_triplet = "aarch64-apple-darwin"
} else if (target_os == "linux" && target_cpu == "arm64") {
_target_triplet = "aarch64-linux-gnu"
+ _default_target_sysroot =
+ rebase_path("//buildtools/debian_sid_arm64-sysroot", root_build_dir)
} else if (target_os == "linux" && target_cpu == "arm") {
- _target_triplet = "arm-linux-gnueabi"
+ _target_triplet = "arm-linux-gnueabihf"
+ _default_target_sysroot =
+ rebase_path("//buildtools/debian_sid_arm-sysroot", root_build_dir)
} else if (target_os == "linux" && target_cpu == "x64") {
_target_triplet = "x86_64-linux-gnu"
} else if (target_os == "linux" && target_cpu == "x86") {
@@ -129,6 +149,18 @@ declare_args() {
}
declare_args() {
+ if (sysroot != "") {
+ # If the user specifies a sysroot, use that for both host and target.
+ target_sysroot = sysroot
+ } else {
+ # If no explicit sysroot has been set, use the guessed sysroot from the ones
+ # pulled by //tools/install-build-deps (only for Linux).
+ target_sysroot = _default_target_sysroot
+ }
+}
+
+declare_args() {
+ target_strip = ""
if (is_linux || is_android) {
target_linker = "gold"
} else {
@@ -141,6 +173,7 @@ declare_args() {
target_cc = cc
target_cxx = cxx
target_linker = linker
+ target_strip = strip
} else {
target_ar = "ar"
if (is_android) {
@@ -148,9 +181,11 @@ declare_args() {
target_cc = "$android_llvm_dir/bin/clang"
target_cxx = "$android_llvm_dir/bin/clang++"
target_linker = "$android_llvm_dir/bin/ld.lld"
+ target_strip = "$android_toolchain_root/bin/$android_abi_target-strip"
} else {
assert(_target_triplet != "",
"target_triplet must be non-empty when cross-compiling")
+ target_strip = strip
if (is_clang) {
if (is_linux_host) {
target_cc = "${linux_clang_bin} --target=${_target_triplet}"
@@ -180,6 +215,7 @@ template("gcc_like_toolchain") {
external_cflags = ""
external_cxxflags = ""
external_ldflags = ""
+ strip = ""
if (defined(invoker.linker) && invoker.linker != "") {
_invoker_linker = invoker.linker
ld_arg = "-fuse-ld=$_invoker_linker"
@@ -203,6 +239,9 @@ template("gcc_like_toolchain") {
if (defined(invoker.external_ldflags)) {
external_ldflags = invoker.external_ldflags
}
+ if (defined(invoker.strip)) {
+ strip = invoker.strip
+ }
tool("cc") {
depfile = "{{output}}.d"
@@ -249,24 +288,34 @@ template("gcc_like_toolchain") {
tool("solink") {
soname = "{{target_output_name}}{{output_extension}}"
-
+ unstripped_so = "{{root_out_dir}}/$soname"
rpath = "-Wl,-soname,$soname"
if (is_mac) {
rpath = "-Wl,-install_name,@rpath/$soname"
}
-
- command = "$cc_wrapper $cxx $ld_arg -shared {{ldflags}} ${external_ldflags} {{inputs}} {{solibs}} {{libs}} $rpath -o {{output}}"
- outputs = [ "{{root_out_dir}}/$soname" ]
+ command = "$cc_wrapper $cxx $ld_arg -shared {{ldflags}} ${external_ldflags} {{inputs}} {{solibs}} {{libs}} $rpath -o $unstripped_so"
+ outputs = [ unstripped_so ]
output_prefix = "lib"
default_output_extension = ".so"
- description = "link {{output}}"
+ description = "link $unstripped_so"
+ if (strip != "") {
+ stripped_so = "{{root_out_dir}}/stripped/$soname"
+ outputs += [ stripped_so ]
+ command += " && $strip -o $stripped_so $unstripped_so"
+ }
}
tool("link") {
- command = "$cc_wrapper $cxx $ld_arg {{ldflags}} ${external_ldflags} {{inputs}} {{solibs}} {{libs}} -o {{output}}"
- outputs =
- [ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" ]
- description = "link {{output}}"
+ unstripped_exe =
+ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}"
+ command = "$cc_wrapper $cxx $ld_arg {{ldflags}} ${external_ldflags} {{inputs}} {{solibs}} {{libs}} -o $unstripped_exe"
+ outputs = [ unstripped_exe ]
+ description = "link $unstripped_exe"
+ if (strip != "") {
+ stripped_exe = "{{root_out_dir}}/stripped/{{target_output_name}}{{output_extension}}"
+ outputs += [ stripped_exe ]
+ command += " && $strip -o $stripped_exe $unstripped_exe"
+ }
}
tool("stamp") {
@@ -293,6 +342,7 @@ gcc_like_toolchain("gcc_like") {
cc = target_cc
cxx = target_cxx
linker = target_linker
+ strip = target_strip
sysroot = target_sysroot
gcc_toolchain = target_gcc_toolchain
external_cflags = string_join(" ",
@@ -319,6 +369,7 @@ gcc_like_toolchain("gcc_like_host") {
cc = cc
cxx = cxx
linker = linker
+ strip = strip
sysroot = sysroot
gcc_toolchain = gcc_toolchain
external_cflags = string_join(" ",
@@ -345,6 +396,7 @@ gcc_like_toolchain("wasm") {
ar = "$emsdk_dir/emscripten/emar --em-config $em_config"
cc = "$emsdk_dir/emscripten/emcc --em-config $em_config"
cxx = "$emsdk_dir/emscripten/em++ --em-config $em_config"
+ strip = ""
}
# This is used both for MSVC anc clang-cl. clang-cl cmdline interface pretends
@@ -352,10 +404,7 @@ gcc_like_toolchain("wasm") {
toolchain("msvc") {
lib_switch = ""
lib_dir_switch = "/LIBPATH:"
-
- sys_lib_flags = "/LIBPATH:\"${win_sdk_lib_dir}\\ucrt\\x64\" "
- sys_lib_flags += "/LIBPATH:\"${win_sdk_lib_dir}\\um\\x64\" "
- sys_lib_flags += "/LIBPATH:\"${win_msvc_lib_dir}\" "
+ sys_lib_flags = string_join(" ", win_msvc_sys_lib_flags)
# Note: /showIncludes below is required for ninja, to build a complete
# dependency graph for headers. Removing it breaks incremental builds.
diff --git a/gn/standalone/toolchain/llvm-strip.py b/gn/standalone/toolchain/llvm-strip.py
new file mode 100755
index 000000000..bc2b7d885
--- /dev/null
+++ b/gn/standalone/toolchain/llvm-strip.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python3
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""This is really a wrapper around exec() for llvm-objcopy.
+
+It is used to execute llvm-objcopy passing "llvm-strip" as argv0. This is
+because llvm-objcopy frontend behaves differently and emulates the "strip"
+binary when its argv0 is set as llvm-strip.
+"""
+
+import os
+import sys
+
+
+def main():
+ if (len(sys.argv) < 3):
+ sys.stderr.write('Usage: %s /path/to/llvm-objcopy [args]\n' % (__file__))
+ return 1
+ os.execlp(sys.argv[1], "llvm-strip", *sys.argv[2:])
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/gn/standalone/toolchain/llvm.gni b/gn/standalone/toolchain/llvm.gni
index e3fc350ba..75bc5ff1c 100644
--- a/gn/standalone/toolchain/llvm.gni
+++ b/gn/standalone/toolchain/llvm.gni
@@ -20,12 +20,14 @@ declare_args() {
assert(!is_hermetic_clang || is_clang, "is_hermetic_clang requires is_clang")
+linux_llvm_objcopy = ""
if (is_linux_host) {
if (is_hermetic_clang) {
_hermetic_llvm_dir =
rebase_path("//buildtools/linux64/clang", root_build_dir)
linux_clang_bin = "$_hermetic_llvm_dir/bin/clang"
linux_clangxx_bin = "$_hermetic_llvm_dir/bin/clang++"
+ linux_llvm_objcopy = "$_hermetic_llvm_dir/bin/llvm-objcopy"
linux_clang_linker = "lld"
} else if (is_clang && !is_system_compiler) {
# Guess the path for the system clang.
diff --git a/gn/standalone/toolchain/msvc.gni b/gn/standalone/toolchain/msvc.gni
index 34c0a5011..7ec731365 100644
--- a/gn/standalone/toolchain/msvc.gni
+++ b/gn/standalone/toolchain/msvc.gni
@@ -36,22 +36,28 @@ if (is_win_host) {
# These variables are required both for clang-cl.exe and MSVC (cl.exe).
win_sdk_lib_dir = _win_sdk_base + "\\Lib\\" + _win_sdk_ver
- win_msvc_lib_dir = _win_msvc_base + "\\lib\\x64"
+ win_msvc_lib_dir = _win_msvc_base + "\\lib\\${target_cpu}"
# These variables are only required when building with MSVC.
# Clang is clever enough to figure out the right include path by querying the
# registry and detect the Windows SDK path (it still needs the /LIBPATH
# though, hence the _lib_dir above).
- win_msvc_bin_dir = _win_msvc_base + "\\bin\\Hostx64\\x64"
+ win_msvc_bin_dir = _win_msvc_base + "\\bin\\Host${host_cpu}\\${target_cpu}"
win_msvc_inc_dirs = [
_win_msvc_base + "\\include",
_win_sdk_base + "\\Include\\" + _win_sdk_ver + "\\ucrt",
_win_sdk_base + "\\Include\\" + _win_sdk_ver + "\\um",
_win_sdk_base + "\\Include\\" + _win_sdk_ver + "\\shared",
]
+ win_msvc_sys_lib_flags = [
+ "/LIBPATH:\"${win_sdk_lib_dir}\\ucrt\\${target_cpu}\"",
+ "/LIBPATH:\"${win_sdk_lib_dir}\\um\\${target_cpu}\"",
+ "/LIBPATH:\"${win_msvc_lib_dir}\"",
+ ]
} else {
win_sdk_lib_dir = ""
win_msvc_lib_dir = ""
win_msvc_bin_dir = ""
win_msvc_inc_dirs = []
+ win_msvc_sys_lib_flags = []
}
diff --git a/gn/standalone/toolchain/win_find_msvc.py b/gn/standalone/toolchain/win_find_msvc.py
index 41b347684..0badd1be4 100644
--- a/gn/standalone/toolchain/win_find_msvc.py
+++ b/gn/standalone/toolchain/win_find_msvc.py
@@ -63,7 +63,7 @@ def main():
filt = lambda x: os.path.exists(os.path.join(x, 'ucrt', 'x64', 'ucrt.lib'))
out[1] = find_max_subdir(lib_base, filt)
- for version in ['BuildTools', 'Community']:
+ for version in ['BuildTools', 'Community', 'Professional']:
msvc_base = ('C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\'
'{}\\VC\\Tools\\MSVC').format(version)
if os.path.exists(msvc_base):
diff --git a/gn/standalone/wasm_typescript_declaration.d.ts b/gn/standalone/wasm_typescript_declaration.d.ts
index 67b0c9bfe..3f8547d61 100644
--- a/gn/standalone/wasm_typescript_declaration.d.ts
+++ b/gn/standalone/wasm_typescript_declaration.d.ts
@@ -32,7 +32,7 @@ declare namespace Wasm {
export interface FileSystemNode {
contents: Uint8Array;
- usedBytes: number;
+ usedBytes?: number;
}
export interface FileSystem {
diff --git a/heapprofd.rc b/heapprofd.rc
index bf313b14b..d63e3bea1 100644
--- a/heapprofd.rc
+++ b/heapprofd.rc
@@ -19,7 +19,7 @@ service heapprofd /system/bin/heapprofd
group nobody readproc
# By default, this daemon is idle. When profiling an app, we should unwind
# as fast as possible in the interest of the app being profiled.
- writepid /dev/cpuset/foreground/tasks
+ task_profiles ProcessCapacityHigh
onrestart exec_background - nobody shell -- /system/bin/heapprofd --cleanup-after-crash
# DAC_READ_SEARCH is denied by SELinux on user builds because the SELinux
# permission is userdebug_or_eng only.
@@ -35,7 +35,7 @@ service heapprofd_secondary /system/bin/heapprofd
group nobody readproc
# By default, this daemon is idle. When profiling an app, we should unwind
# as fast as possible in the interest of the app being profiled.
- writepid /dev/cpuset/foreground/tasks
+ task_profiles ProcessCapacityHigh
# DAC_READ_SEARCH is denied by SELinux on user builds because the SELinux
# permission is userdebug_or_eng only.
capabilities KILL DAC_READ_SEARCH
diff --git a/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h b/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h
index f0179c6a8..502e9bfa5 100644
--- a/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h
+++ b/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h
@@ -30,14 +30,21 @@
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPONENT_BUILD() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_ON() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_OFF() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DCHECK_ON() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DCHECK_OFF() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_VERBOSE_LOGS() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_VERSION_GEN() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_PERCENTILE() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_LINENOISE() (0)
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_HTTPD() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_HTTPD() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_JSON() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_LOCAL_SYMBOLIZER() (PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() || PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() ||PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN())
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ZLIB() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TRACED_PERF() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_HEAPPROFD() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_STDERR_CRASH_DUMP() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_X64_CPU_OPT() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_LLVM_DEMANGLE() (0)
// clang-format on
#endif // GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
diff --git a/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h b/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h
index 6745b3f05..e0958d451 100644
--- a/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h
+++ b/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h
@@ -26,10 +26,12 @@
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_STANDALONE_BUILD() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_START_DAEMONS() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_IPC() (1)
-#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_WATCHDOG() (PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() || PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX())
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_WATCHDOG() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPONENT_BUILD() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_ON() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_OFF() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DCHECK_ON() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DCHECK_OFF() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_VERBOSE_LOGS() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_VERSION_GEN() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_PERCENTILE() (1)
@@ -38,6 +40,11 @@
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_JSON() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_LOCAL_SYMBOLIZER() (PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() || PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() ||PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN())
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ZLIB() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TRACED_PERF() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_HEAPPROFD() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_STDERR_CRASH_DUMP() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_X64_CPU_OPT() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_LLVM_DEMANGLE() (1)
// clang-format on
#endif // GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
diff --git a/include/perfetto/base/compiler.h b/include/perfetto/base/compiler.h
index b060810c5..b30dda6ce 100644
--- a/include/perfetto/base/compiler.h
+++ b/include/perfetto/base/compiler.h
@@ -147,6 +147,13 @@ extern "C" void __asan_unpoison_memory_region(void const volatile*, size_t);
#define PERFETTO_NO_DESTROY
#endif
+// Macro for telling -Wimplicit-fallthrough that a fallthrough is intentional.
+#if defined(__clang__)
+#define PERFETTO_FALLTHROUGH [[clang::fallthrough]]
+#else
+#define PERFETTO_FALLTHROUGH
+#endif
+
namespace perfetto {
namespace base {
diff --git a/include/perfetto/base/logging.h b/include/perfetto/base/logging.h
index 8641a1c60..3599ddaa6 100644
--- a/include/perfetto/base/logging.h
+++ b/include/perfetto/base/logging.h
@@ -29,12 +29,17 @@
#pragma GCC system_header
#endif
-// TODO(primiano): move this to base/build_config.h, turn into
-// PERFETTO_BUILDFLAG(DCHECK_IS_ON) and update call sites to use that instead.
-#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
+#if PERFETTO_BUILDFLAG(PERFETTO_FORCE_DCHECK_ON)
+#define PERFETTO_DCHECK_IS_ON() 1
+#elif PERFETTO_BUILDFLAG(PERFETTO_FORCE_DCHECK_OFF)
#define PERFETTO_DCHECK_IS_ON() 0
-#else
+#elif defined(DCHECK_ALWAYS_ON) || \
+ (!defined(NDEBUG) && (PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) || \
+ PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD) || \
+ PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)))
#define PERFETTO_DCHECK_IS_ON() 1
+#else
+#define PERFETTO_DCHECK_IS_ON() 0
#endif
#if PERFETTO_BUILDFLAG(PERFETTO_FORCE_DLOG_ON)
@@ -58,6 +63,24 @@
#include <android/log.h>
#endif
+// Enable the "Print the most recent PERFETTO_LOG(s) before crashing" feature
+// on Android in-tree builds and on standalone builds (mainly for testing).
+// This is deliberately no PERFETTO_OS_ANDROID because we don't want this
+// feature when perfetto is embedded in other Android projects (e.g. SDK).
+// TODO(b/203795298): TFLite is using the client library in blaze builds and is
+// targeting API 19. For now disable the feature based on API level.
+#if defined(PERFETTO_ANDROID_ASYNC_SAFE_LOG)
+#define PERFETTO_ENABLE_LOG_RING_BUFFER() 0
+#elif PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+#define PERFETTO_ENABLE_LOG_RING_BUFFER() 1
+#elif PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) && \
+ (!PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+ (defined(__ANDROID_API__) && __ANDROID_API__ >= 21))
+#define PERFETTO_ENABLE_LOG_RING_BUFFER() 1
+#else
+#define PERFETTO_ENABLE_LOG_RING_BUFFER() 0
+#endif
+
namespace perfetto {
namespace base {
@@ -99,6 +122,23 @@ PERFETTO_EXPORT void LogMessage(LogLev,
const char* fmt,
...) PERFETTO_PRINTF_FORMAT(4, 5);
+// This is defined in debug_crash_stack_trace.cc, but that is only linked in
+// standalone && debug builds, see enable_perfetto_stderr_crash_dump in
+// perfetto.gni.
+PERFETTO_EXPORT void EnableStacktraceOnCrashForDebug();
+
+#if PERFETTO_ENABLE_LOG_RING_BUFFER()
+// Gets a snapshot of the logs from the internal log ring buffer and:
+// - On Android in-tree builds: Passes that to android_set_abort_message().
+// That will attach the logs to the crash report.
+// - On standalone builds (all otther OSes) prints that on stderr.
+// This function must called only once, right before inducing a crash (This is
+// because android_set_abort_message() can only be called once).
+PERFETTO_EXPORT void MaybeSerializeLastLogsForCrashReporting();
+#else
+inline void MaybeSerializeLastLogsForCrashReporting() {}
+#endif
+
#if defined(PERFETTO_ANDROID_ASYNC_SAFE_LOG)
#define PERFETTO_XLOG(level, fmt, ...) \
do { \
@@ -107,7 +147,8 @@ PERFETTO_EXPORT void LogMessage(LogLev,
__LINE__, ##__VA_ARGS__); \
} while (0)
#elif defined(PERFETTO_DISABLE_LOG)
-#define PERFETTO_XLOG(...) ::perfetto::base::ignore_result(__VA_ARGS__)
+#define PERFETTO_XLOG(level, fmt, ...) ::perfetto::base::ignore_result(level, \
+ fmt, ##__VA_ARGS__)
#else
#define PERFETTO_XLOG(level, fmt, ...) \
::perfetto::base::LogMessage(level, ::perfetto::base::Basename(__FILE__), \
@@ -115,16 +156,18 @@ PERFETTO_EXPORT void LogMessage(LogLev,
#endif
#if defined(_MSC_VER)
-#define PERFETTO_IMMEDIATE_CRASH() \
- do { \
- __debugbreak(); \
- __assume(0); \
+#define PERFETTO_IMMEDIATE_CRASH() \
+ do { \
+ ::perfetto::base::MaybeSerializeLastLogsForCrashReporting(); \
+ __debugbreak(); \
+ __assume(0); \
} while (0)
#else
-#define PERFETTO_IMMEDIATE_CRASH() \
- do { \
- __builtin_trap(); \
- __builtin_unreachable(); \
+#define PERFETTO_IMMEDIATE_CRASH() \
+ do { \
+ ::perfetto::base::MaybeSerializeLastLogsForCrashReporting(); \
+ __builtin_trap(); \
+ __builtin_unreachable(); \
} while (0)
#endif
diff --git a/include/perfetto/base/proc_utils.h b/include/perfetto/base/proc_utils.h
index 8818ec034..cb8e13a58 100644
--- a/include/perfetto/base/proc_utils.h
+++ b/include/perfetto/base/proc_utils.h
@@ -22,8 +22,10 @@
#include "perfetto/base/build_config.h"
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
-#include <Windows.h>
-#include <processthreadsapi.h>
+extern "C" {
+// Prototype extracted from the Windows SDK to avoid including windows.h.
+__declspec(dllimport) unsigned long __stdcall GetCurrentProcessId();
+}
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
#include <zircon/process.h>
#include <zircon/types.h>
diff --git a/include/perfetto/base/thread_utils.h b/include/perfetto/base/thread_utils.h
index 48a6508bb..6af9a57f7 100644
--- a/include/perfetto/base/thread_utils.h
+++ b/include/perfetto/base/thread_utils.h
@@ -22,8 +22,10 @@
#include "perfetto/base/build_config.h"
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
-#include <Windows.h>
-#include <processthreadsapi.h>
+extern "C" {
+// Prototype extracted from the Windows SDK to avoid including windows.h.
+__declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();
+}
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
#include <zircon/process.h>
#include <zircon/types.h>
diff --git a/include/perfetto/ext/base/BUILD.gn b/include/perfetto/ext/base/BUILD.gn
index ec8cca8df..8f95e394f 100644
--- a/include/perfetto/ext/base/BUILD.gn
+++ b/include/perfetto/ext/base/BUILD.gn
@@ -16,12 +16,16 @@ import("../../../../gn/perfetto.gni")
source_set("base") {
sources = [
+ "android_utils.h",
+ "base64.h",
"circular_queue.h",
"container_annotations.h",
+ "crash_keys.h",
"ctrl_c_handler.h",
"endian.h",
"event_fd.h",
"file_utils.h",
+ "flat_hash_map.h",
"getopt.h",
"getopt_compat.h",
"hash.h",
@@ -34,11 +38,13 @@ source_set("base") {
"pipe.h",
"scoped_file.h",
"small_set.h",
+ "small_vector.h",
"string_splitter.h",
"string_utils.h",
"string_view.h",
"string_writer.h",
"subprocess.h",
+ "sys_types.h",
"temp_file.h",
"thread_annotations.h",
"thread_checker.h",
diff --git a/include/perfetto/ext/base/android_utils.h b/include/perfetto/ext/base/android_utils.h
new file mode 100644
index 000000000..c1f83ef39
--- /dev/null
+++ b/include/perfetto/ext/base/android_utils.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_ANDROID_UTILS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_ANDROID_UTILS_H_
+
+#include <string>
+
+#include "perfetto/base/build_config.h"
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+// Returns the value of the Android system property named `name`. If the
+// property does not exist, returns an empty string (a non-existing property is
+// the same as a property with an empty value for this API).
+std::string GetAndroidProp(const char* name);
+
+#endif // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+} // namespace base
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_EXT_BASE_ANDROID_UTILS_H_
diff --git a/include/perfetto/ext/base/base64.h b/include/perfetto/ext/base/base64.h
new file mode 100644
index 000000000..030a83dc4
--- /dev/null
+++ b/include/perfetto/ext/base/base64.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
+#define INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
+
+#include <string>
+
+#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/string_view.h"
+#include "perfetto/ext/base/utils.h" // For ssize_t.
+
+namespace perfetto {
+namespace base {
+
+// Returns the length of the destination string (included '=' padding).
+// Does NOT include the size of the string null terminator.
+inline size_t Base64EncSize(size_t src_size) {
+ return (src_size + 2) / 3 * 4;
+}
+
+// Returns the upper bound on the length of the destination buffer.
+// The actual decoded length might be <= the number returned here.
+inline size_t Base64DecSize(size_t src_size) {
+ return (src_size + 3) / 4 * 3;
+}
+
+// Does NOT null-terminate |dst|.
+ssize_t Base64Encode(const void* src,
+ size_t src_size,
+ char* dst,
+ size_t dst_size);
+
+std::string Base64Encode(const void* src, size_t src_size);
+
+inline std::string Base64Encode(StringView sv) {
+ return Base64Encode(sv.data(), sv.size());
+}
+
+// Returns -1 in case of failure.
+ssize_t Base64Decode(const char* src,
+ size_t src_size,
+ uint8_t* dst,
+ size_t dst_size);
+
+Optional<std::string> Base64Decode(const char* src, size_t src_size);
+
+inline Optional<std::string> Base64Decode(StringView sv) {
+ return Base64Decode(sv.data(), sv.size());
+}
+
+} // namespace base
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
diff --git a/include/perfetto/ext/base/circular_queue.h b/include/perfetto/ext/base/circular_queue.h
index 8d1f1b7e3..8b48d229b 100644
--- a/include/perfetto/ext/base/circular_queue.h
+++ b/include/perfetto/ext/base/circular_queue.h
@@ -18,6 +18,8 @@
#define INCLUDE_PERFETTO_EXT_BASE_CIRCULAR_QUEUE_H_
#include <stdint.h>
+#include <stdlib.h>
+
#include <iterator>
#include "perfetto/base/logging.h"
@@ -170,16 +172,20 @@ class CircularQueue {
#endif
};
- CircularQueue(size_t initial_capacity = 1024) { Grow(initial_capacity); }
+ explicit CircularQueue(size_t initial_capacity = 1024) {
+ Grow(initial_capacity);
+ }
- CircularQueue(CircularQueue&& other) noexcept {
- // Copy all fields using the (private) default copy assignment operator.
- *this = other;
+ CircularQueue(CircularQueue&& other) noexcept
+ : entries_(std::move(other.entries_)),
+ capacity_(other.capacity_),
+ begin_(other.begin_),
+ end_(other.end_) {
increment_generation();
new (&other) CircularQueue(); // Reset the old queue so it's still usable.
}
- CircularQueue& operator=(CircularQueue&& other) {
+ CircularQueue& operator=(CircularQueue&& other) noexcept {
this->~CircularQueue(); // Destroy the current state.
new (this) CircularQueue(std::move(other)); // Use the move ctor above.
return *this;
@@ -192,7 +198,6 @@ class CircularQueue {
}
clear(); // Invoke destructors on all alive entries.
PERFETTO_DCHECK(empty());
- free(entries_);
}
template <typename... Args>
@@ -245,7 +250,7 @@ class CircularQueue {
private:
CircularQueue(const CircularQueue&) = delete;
- CircularQueue& operator=(const CircularQueue&) = default;
+ CircularQueue& operator=(const CircularQueue&) = delete;
void Grow(size_t new_capacity = 0) {
// Capacity must be always a power of two. This allows Get() to use a simple
@@ -256,9 +261,8 @@ class CircularQueue {
// On 32-bit systems this might hit the 4GB wall and overflow. We can't do
// anything other than crash in this case.
PERFETTO_CHECK(new_capacity > capacity_);
- size_t malloc_size = new_capacity * sizeof(T);
- PERFETTO_CHECK(malloc_size > new_capacity);
- auto* new_vec = static_cast<T*>(malloc(malloc_size));
+
+ AlignedUniquePtr<T[]> new_vec = AlignedAllocTyped<T[]>(new_capacity);
// Move all elements in the expanded array.
size_t new_size = 0;
@@ -269,12 +273,11 @@ class CircularQueue {
// required to call the dtor for them.
for (uint64_t i = begin_; i < end_; i++)
Get(i)->~T();
- free(entries_); // It's fine to free(nullptr) (for the ctor call case).
begin_ = 0;
end_ = new_size;
capacity_ = new_capacity;
- entries_ = new_vec;
+ entries_ = std::move(new_vec);
}
inline T* Get(uint64_t pos) {
@@ -286,7 +289,7 @@ class CircularQueue {
// Underlying storage. It's raw malloc-ed rather than being a unique_ptr<T[]>
// to allow having uninitialized entries inside it.
- T* entries_ = nullptr;
+ AlignedUniquePtr<T[]> entries_;
size_t capacity_ = 0; // Number of allocated slots (NOT bytes) in |entries_|.
// The |begin_| and |end_| indexes are monotonic and never wrap. Modular arith
diff --git a/include/perfetto/ext/base/crash_keys.h b/include/perfetto/ext/base/crash_keys.h
new file mode 100644
index 000000000..36ef35874
--- /dev/null
+++ b/include/perfetto/ext/base/crash_keys.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_CRASH_KEYS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_CRASH_KEYS_H_
+
+#include <algorithm>
+#include <atomic>
+
+#include <stdint.h>
+#include <string.h>
+
+#include "perfetto/base/compiler.h"
+#include "perfetto/ext/base/string_view.h"
+
+// Crash keys are very simple global variables with static-storage that
+// are reported on crash time for managed crashes (CHECK/FATAL/Watchdog).
+// - Translation units can define a CrashKey and register it at some point
+// during initialization.
+// - CrashKey instances must be long-lived. They should really be just global
+// static variable in the anonymous namespace.
+// Example:
+// subsystem_1.cc
+// CrashKey g_client_id("ipc_client_id");
+// ...
+// OnIpcReceived(client_id) {
+// g_client_id.Set(client_id);
+// ... // Process the IPC
+// g_client_id.Clear();
+// }
+// Or equivalently:
+// OnIpcReceived(client_id) {
+// auto scoped_key = g_client_id.SetScoped(client_id);
+// ... // Process the IPC
+// }
+//
+// If a crash happens while processing the IPC, the crash report will
+// have a line "ipc_client_id: 42".
+//
+// Thread safety considerations:
+// CrashKeys can be registered and set/cleared from any thread.
+// There is no compelling use-case to have full acquire/release consistency when
+// setting a key. This means that if a thread crashes immediately after a
+// crash key has been set on another thread, the value printed on the crash
+// report could be incomplete. The code guarantees defined behavior and does
+// not rely on null-terminated string (in the worst case 32 bytes of random
+// garbage will be printed out).
+
+// The tests live in logging_unittest.cc.
+
+namespace perfetto {
+namespace base {
+
+constexpr size_t kCrashKeyMaxStrSize = 32;
+
+// CrashKey instances must be long lived
+class CrashKey {
+ public:
+ class ScopedClear {
+ public:
+ explicit ScopedClear(CrashKey* k) : key_(k) {}
+ ~ScopedClear() {
+ if (key_)
+ key_->Clear();
+ }
+ ScopedClear(const ScopedClear&) = delete;
+ ScopedClear& operator=(const ScopedClear&) = delete;
+ ScopedClear& operator=(ScopedClear&&) = delete;
+ ScopedClear(ScopedClear&& other) noexcept : key_(other.key_) {
+ other.key_ = nullptr;
+ }
+
+ private:
+ CrashKey* key_;
+ };
+
+ // constexpr so it can be used in the anon namespace without requiring a
+ // global constructor.
+ // |name| must be a long-lived string.
+ constexpr explicit CrashKey(const char* name)
+ : registered_{}, type_(Type::kUnset), name_(name), str_value_{} {}
+ CrashKey(const CrashKey&) = delete;
+ CrashKey& operator=(const CrashKey&) = delete;
+ CrashKey(CrashKey&&) = delete;
+ CrashKey& operator=(CrashKey&&) = delete;
+
+ enum class Type : uint8_t { kUnset = 0, kInt, kStr };
+
+ void Clear() {
+ int_value_.store(0, std::memory_order_relaxed);
+ type_.store(Type::kUnset, std::memory_order_relaxed);
+ }
+
+ void Set(int64_t value) {
+ int_value_.store(value, std::memory_order_relaxed);
+ type_.store(Type::kInt, std::memory_order_relaxed);
+ if (PERFETTO_UNLIKELY(!registered_.load(std::memory_order_relaxed)))
+ Register();
+ }
+
+ void Set(StringView sv) {
+ size_t len = std::min(sv.size(), sizeof(str_value_) - 1);
+ for (size_t i = 0; i < len; ++i)
+ str_value_[i].store(sv.data()[i], std::memory_order_relaxed);
+ str_value_[len].store('\0', std::memory_order_relaxed);
+ type_.store(Type::kStr, std::memory_order_relaxed);
+ if (PERFETTO_UNLIKELY(!registered_.load(std::memory_order_relaxed)))
+ Register();
+ }
+
+ ScopedClear SetScoped(int64_t value) PERFETTO_WARN_UNUSED_RESULT {
+ Set(value);
+ return ScopedClear(this);
+ }
+
+ ScopedClear SetScoped(StringView sv) PERFETTO_WARN_UNUSED_RESULT {
+ Set(sv);
+ return ScopedClear(this);
+ }
+
+ void Register();
+
+ int64_t int_value() const {
+ return int_value_.load(std::memory_order_relaxed);
+ }
+ size_t ToString(char* dst, size_t len);
+
+ private:
+ std::atomic<bool> registered_;
+ std::atomic<Type> type_;
+ const char* const name_;
+ union {
+ std::atomic<char> str_value_[kCrashKeyMaxStrSize];
+ std::atomic<int64_t> int_value_;
+ };
+};
+
+// Fills |dst| with a string containing one line for each crash key
+// (excluding the unset ones).
+// Returns number of chars written, without counting the NUL terminator.
+// This is used in logging.cc when emitting the crash report abort message.
+size_t SerializeCrashKeys(char* dst, size_t len);
+
+void UnregisterAllCrashKeysForTesting();
+
+} // namespace base
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_EXT_BASE_CRASH_KEYS_H_
diff --git a/include/perfetto/ext/base/file_utils.h b/include/perfetto/ext/base/file_utils.h
index bf33d70be..5920196d5 100644
--- a/include/perfetto/ext/base/file_utils.h
+++ b/include/perfetto/ext/base/file_utils.h
@@ -21,10 +21,13 @@
#include <stddef.h>
#include <string>
+#include <vector>
#include "perfetto/base/build_config.h"
#include "perfetto/base/export.h"
+#include "perfetto/base/status.h"
#include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/utils.h"
namespace perfetto {
@@ -78,6 +81,21 @@ bool Rmdir(const std::string& path);
// Wrapper around access(path, F_OK).
bool FileExists(const std::string& path);
+// Gets the extension for a filename. If the file has two extensions, returns
+// only the last one (foo.pb.gz => .gz). Returns empty string if there is no
+// extension.
+std::string GetFileExtension(const std::string& filename);
+
+// Puts the path to all files under |dir_path| in |output|, recursively walking
+// subdirectories. File paths are relative to |dir_path|. Only files are
+// included, not directories. Path separator is always '/', even on windows (not
+// '\').
+base::Status ListFilesRecursive(const std::string& dir_path,
+ std::vector<std::string>& output);
+
+// Returns the size of the file at `path` or nullopt in case of error.
+Optional<size_t> GetFileSize(const std::string& path);
+
} // namespace base
} // namespace perfetto
diff --git a/include/perfetto/ext/base/flat_hash_map.h b/include/perfetto/ext/base/flat_hash_map.h
new file mode 100644
index 000000000..7759dbb1c
--- /dev/null
+++ b/include/perfetto/ext/base/flat_hash_map.h
@@ -0,0 +1,394 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_FLAT_HASH_MAP_H_
+#define INCLUDE_PERFETTO_EXT_BASE_FLAT_HASH_MAP_H_
+
+#include "perfetto/base/compiler.h"
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/utils.h"
+
+#include <algorithm>
+#include <functional>
+#include <limits>
+
+namespace perfetto {
+namespace base {
+
+// An open-addressing hashmap implementation.
+// Pointers are not stable, neither for keys nor values.
+// Has similar performances of a RobinHood hash (without the complications)
+// and 2x an unordered map.
+// Doc: http://go/perfetto-hashtables .
+//
+// When used to implement a string pool in TraceProcessor, the performance
+// characteristics obtained by replaying the set of strings seeen in a 4GB trace
+// (226M strings, 1M unique) are the following (see flat_hash_map_benchmark.cc):
+// This(Linear+AppendOnly) 879,383,676 ns 258.013M insertions/s
+// This(LinearProbe): 909,206,047 ns 249.546M insertions/s
+// This(QuadraticProbe): 1,083,844,388 ns 209.363M insertions/s
+// std::unordered_map: 6,203,351,870 ns 36.5811M insertions/s
+// tsl::robin_map: 931,403,397 ns 243.622M insertions/s
+// absl::flat_hash_map: 998,013,459 ns 227.379M insertions/s
+// FollyF14FastMap: 1,181,480,602 ns 192.074M insertions/s
+
+// The structs below define the probing algorithm used to probe slots upon a
+// collision. They are guaranteed to visit all slots as our table size is always
+// a power of two (see https://en.wikipedia.org/wiki/Quadratic_probing).
+
+// Linear probing can be faster if the hashing is well distributed and the load
+// is not high. For TraceProcessor's StringPool this is the fastest. It can
+// degenerate badly if the hashing doesn't spread (e.g., if using directly pids
+// as keys, with a no-op hashing function).
+struct LinearProbe {
+ static inline size_t Calc(size_t key_hash, size_t step, size_t capacity) {
+ return (key_hash + step) & (capacity - 1); // Linear probe
+ }
+};
+
+// Generates the sequence: 0, 3, 10, 21, 36, 55, ...
+// Can be a bit (~5%) slower than LinearProbe because it's less cache hot, but
+// avoids degenerating badly if the hash function is bad and causes clusters.
+// A good default choice unless benchmarks prove otherwise.
+struct QuadraticProbe {
+ static inline size_t Calc(size_t key_hash, size_t step, size_t capacity) {
+ return (key_hash + 2 * step * step + step) & (capacity - 1);
+ }
+};
+
+// Tends to perform in the middle between linear and quadratic.
+// It's a bit more cache-effective than the QuadraticProbe but can create more
+// clustering if the hash function doesn't spread well.
+// Generates the sequence: 0, 1, 3, 6, 10, 15, 21, ...
+struct QuadraticHalfProbe {
+ static inline size_t Calc(size_t key_hash, size_t step, size_t capacity) {
+ return (key_hash + (step * step + step) / 2) & (capacity - 1);
+ }
+};
+
+template <typename Key,
+ typename Value,
+ typename Hasher = std::hash<Key>,
+ typename Probe = QuadraticProbe,
+ bool AppendOnly = false>
+class FlatHashMap {
+ public:
+ class Iterator {
+ public:
+ explicit Iterator(const FlatHashMap* map) : map_(map) { FindNextNonFree(); }
+ ~Iterator() = default;
+ Iterator(const Iterator&) = default;
+ Iterator& operator=(const Iterator&) = default;
+ Iterator(Iterator&&) noexcept = default;
+ Iterator& operator=(Iterator&&) noexcept = default;
+
+ Key& key() { return map_->keys_[idx_]; }
+ Value& value() { return map_->values_[idx_]; }
+ const Key& key() const { return map_->keys_[idx_]; }
+ const Value& value() const { return map_->values_[idx_]; }
+
+ explicit operator bool() const { return idx_ != kEnd; }
+ Iterator& operator++() {
+ PERFETTO_DCHECK(idx_ < map_->capacity_);
+ ++idx_;
+ FindNextNonFree();
+ return *this;
+ }
+
+ private:
+ static constexpr size_t kEnd = std::numeric_limits<size_t>::max();
+
+ void FindNextNonFree() {
+ const auto& tags = map_->tags_;
+ for (; idx_ < map_->capacity_; idx_++) {
+ if (tags[idx_] != kFreeSlot && (AppendOnly || tags[idx_] != kTombstone))
+ return;
+ }
+ idx_ = kEnd;
+ }
+
+ const FlatHashMap* map_ = nullptr;
+ size_t idx_ = 0;
+ }; // Iterator
+
+ static constexpr int kDefaultLoadLimitPct = 75;
+ explicit FlatHashMap(size_t initial_capacity = 0,
+ int load_limit_pct = kDefaultLoadLimitPct)
+ : load_limit_percent_(load_limit_pct) {
+ if (initial_capacity > 0)
+ Reset(initial_capacity);
+ }
+
+ // We are calling Clear() so that the destructors for the inserted entries are
+ // called (unless they are trivial, in which case it will be a no-op).
+ ~FlatHashMap() { Clear(); }
+
+ FlatHashMap(FlatHashMap&& other) noexcept {
+ tags_ = std::move(other.tags_);
+ keys_ = std::move(other.keys_);
+ values_ = std::move(other.values_);
+ capacity_ = other.capacity_;
+ size_ = other.size_;
+ max_probe_length_ = other.max_probe_length_;
+ load_limit_ = other.load_limit_;
+ load_limit_percent_ = other.load_limit_percent_;
+
+ new (&other) FlatHashMap();
+ }
+
+ FlatHashMap& operator=(FlatHashMap&& other) noexcept {
+ this->~FlatHashMap();
+ new (this) FlatHashMap(std::move(other));
+ return *this;
+ }
+
+ FlatHashMap(const FlatHashMap&) = delete;
+ FlatHashMap& operator=(const FlatHashMap&) = delete;
+
+ std::pair<Value*, bool> Insert(Key key, Value value) {
+ const size_t key_hash = Hasher{}(key);
+ const uint8_t tag = HashToTag(key_hash);
+ static constexpr size_t kSlotNotFound = std::numeric_limits<size_t>::max();
+
+ // This for loop does in reality at most two attempts:
+ // The first iteration either:
+ // - Early-returns, because the key exists already,
+ // - Finds an insertion slot and proceeds because the load is < limit.
+ // The second iteration is only hit in the unlikely case of this insertion
+ // bringing the table beyond the target |load_limit_| (or the edge case
+ // of the HT being full, if |load_limit_pct_| = 100).
+ // We cannot simply pre-grow the table before insertion, because we must
+ // guarantee that calling Insert() with a key that already exists doesn't
+ // invalidate iterators.
+ size_t insertion_slot;
+ size_t probe_len;
+ for (;;) {
+ PERFETTO_DCHECK((capacity_ & (capacity_ - 1)) == 0); // Must be a pow2.
+ insertion_slot = kSlotNotFound;
+ // Start the iteration at the desired slot (key_hash % capacity_)
+ // searching either for a free slot or a tombstone. In the worst case we
+ // might end up scanning the whole array of slots. The Probe functions are
+ // guaranteed to visit all the slots within |capacity_| steps. If we find
+ // a free slot, we can stop the search immediately (a free slot acts as an
+ // "end of chain for entries having the same hash". If we find a
+ // tombstones (a deleted slot) we remember its position, but have to keep
+ // searching until a free slot to make sure we don't insert a duplicate
+ // key.
+ for (probe_len = 0; probe_len < capacity_;) {
+ const size_t idx = Probe::Calc(key_hash, probe_len, capacity_);
+ PERFETTO_DCHECK(idx < capacity_);
+ const uint8_t tag_idx = tags_[idx];
+ ++probe_len;
+ if (tag_idx == kFreeSlot) {
+ // Rationale for "insertion_slot == kSlotNotFound": if we encountered
+ // a tombstone while iterating we should reuse that rather than
+ // taking another slot.
+ if (AppendOnly || insertion_slot == kSlotNotFound)
+ insertion_slot = idx;
+ break;
+ }
+ // We should never encounter tombstones in AppendOnly mode.
+ PERFETTO_DCHECK(!(tag_idx == kTombstone && AppendOnly));
+ if (!AppendOnly && tag_idx == kTombstone) {
+ insertion_slot = idx;
+ continue;
+ }
+ if (tag_idx == tag && keys_[idx] == key) {
+ // The key is already in the map.
+ return std::make_pair(&values_[idx], false);
+ }
+ } // for (idx)
+
+ // If we got to this point the key does not exist (otherwise we would have
+ // hit the the return above) and we are going to insert a new entry.
+ // Before doing so, ensure we stay under the target load limit.
+ if (PERFETTO_UNLIKELY(size_ >= load_limit_)) {
+ MaybeGrowAndRehash(/*grow=*/true);
+ continue;
+ }
+ PERFETTO_DCHECK(insertion_slot != kSlotNotFound);
+ break;
+ } // for (attempt)
+
+ PERFETTO_CHECK(insertion_slot < capacity_);
+
+ // We found a free slot (or a tombstone). Proceed with the insertion.
+ Value* value_idx = &values_[insertion_slot];
+ new (&keys_[insertion_slot]) Key(std::move(key));
+ new (value_idx) Value(std::move(value));
+ tags_[insertion_slot] = tag;
+ PERFETTO_DCHECK(probe_len > 0 && probe_len <= capacity_);
+ max_probe_length_ = std::max(max_probe_length_, probe_len);
+ size_++;
+
+ return std::make_pair(value_idx, true);
+ }
+
+ Value* Find(const Key& key) const {
+ const size_t idx = FindInternal(key);
+ if (idx == kNotFound)
+ return nullptr;
+ return &values_[idx];
+ }
+
+ bool Erase(const Key& key) {
+ if (AppendOnly)
+ PERFETTO_FATAL("Erase() not supported because AppendOnly=true");
+ size_t idx = FindInternal(key);
+ if (idx == kNotFound)
+ return false;
+ EraseInternal(idx);
+ return true;
+ }
+
+ void Clear() {
+ // Avoid trivial heap operations on zero-capacity std::move()-d objects.
+ if (PERFETTO_UNLIKELY(capacity_ == 0))
+ return;
+
+ for (size_t i = 0; i < capacity_; ++i) {
+ const uint8_t tag = tags_[i];
+ if (tag != kFreeSlot && tag != kTombstone)
+ EraseInternal(i);
+ }
+ // Clear all tombstones. We really need to do this for AppendOnly.
+ MaybeGrowAndRehash(/*grow=*/false);
+ }
+
+ Value& operator[](Key key) {
+ auto it_and_inserted = Insert(std::move(key), Value{});
+ return *it_and_inserted.first;
+ }
+
+ Iterator GetIterator() { return Iterator(this); }
+ const Iterator GetIterator() const { return Iterator(this); }
+
+ size_t size() const { return size_; }
+ size_t capacity() const { return capacity_; }
+
+ // "protected" here is only for the flat_hash_map_benchmark.cc. Everything
+ // below is by all means private.
+ protected:
+ enum ReservedTags : uint8_t { kFreeSlot = 0, kTombstone = 1 };
+ static constexpr size_t kNotFound = std::numeric_limits<size_t>::max();
+
+ size_t FindInternal(const Key& key) const {
+ const size_t key_hash = Hasher{}(key);
+ const uint8_t tag = HashToTag(key_hash);
+ PERFETTO_DCHECK((capacity_ & (capacity_ - 1)) == 0); // Must be a pow2.
+ PERFETTO_DCHECK(max_probe_length_ <= capacity_);
+ for (size_t i = 0; i < max_probe_length_; ++i) {
+ const size_t idx = Probe::Calc(key_hash, i, capacity_);
+ const uint8_t tag_idx = tags_[idx];
+
+ if (tag_idx == kFreeSlot)
+ return kNotFound;
+ // HashToTag() never returns kTombstone, so the tag-check below cannot
+ // possibly match. Also we just want to skip tombstones.
+ if (tag_idx == tag && keys_[idx] == key) {
+ PERFETTO_DCHECK(tag_idx > kTombstone);
+ return idx;
+ }
+ } // for (idx)
+ return kNotFound;
+ }
+
+ void EraseInternal(size_t idx) {
+ PERFETTO_DCHECK(tags_[idx] > kTombstone);
+ PERFETTO_DCHECK(size_ > 0);
+ tags_[idx] = kTombstone;
+ keys_[idx].~Key();
+ values_[idx].~Value();
+ size_--;
+ }
+
+ PERFETTO_NO_INLINE void MaybeGrowAndRehash(bool grow) {
+ PERFETTO_DCHECK(size_ <= capacity_);
+ const size_t old_capacity = capacity_;
+
+ // Grow quickly up to 1MB, then chill.
+ const size_t old_size_bytes = old_capacity * (sizeof(Key) + sizeof(Value));
+ const size_t grow_factor = old_size_bytes < (1024u * 1024u) ? 8 : 2;
+ const size_t new_capacity =
+ grow ? std::max(old_capacity * grow_factor, size_t(1024))
+ : old_capacity;
+
+ auto old_tags(std::move(tags_));
+ auto old_keys(std::move(keys_));
+ auto old_values(std::move(values_));
+ size_t old_size = size_;
+
+ // This must be a CHECK (i.e. not just a DCHECK) to prevent UAF attacks on
+ // 32-bit archs that try to double the size of the table until wrapping.
+ PERFETTO_CHECK(new_capacity >= old_capacity);
+ Reset(new_capacity);
+
+ size_t new_size = 0; // Recompute the size.
+ for (size_t i = 0; i < old_capacity; ++i) {
+ const uint8_t old_tag = old_tags[i];
+ if (old_tag != kFreeSlot && old_tag != kTombstone) {
+ Insert(std::move(old_keys[i]), std::move(old_values[i]));
+ old_keys[i].~Key(); // Destroy the old objects.
+ old_values[i].~Value();
+ new_size++;
+ }
+ }
+ PERFETTO_DCHECK(new_size == old_size);
+ size_ = new_size;
+ }
+
+ // Doesn't call destructors. Use Clear() for that.
+ PERFETTO_NO_INLINE void Reset(size_t n) {
+ PERFETTO_DCHECK((n & (n - 1)) == 0); // Must be a pow2.
+
+ capacity_ = n;
+ max_probe_length_ = 0;
+ size_ = 0;
+ load_limit_ = n * static_cast<size_t>(load_limit_percent_) / 100;
+ load_limit_ = std::min(load_limit_, n);
+
+ tags_.reset(new uint8_t[n]);
+ memset(&tags_[0], 0, n); // Clear all tags.
+ keys_ = AlignedAllocTyped<Key[]>(n); // Deliberately not 0-initialized.
+ values_ = AlignedAllocTyped<Value[]>(n); // Deliberately not 0-initialized.
+ }
+
+ static inline uint8_t HashToTag(size_t full_hash) {
+ uint8_t tag = full_hash >> (sizeof(full_hash) * 8 - 8);
+ // Ensure the hash is always >= 2. We use 0, 1 for kFreeSlot and kTombstone.
+ tag += (tag <= kTombstone) << 1;
+ PERFETTO_DCHECK(tag > kTombstone);
+ return tag;
+ }
+
+ size_t capacity_ = 0;
+ size_t size_ = 0;
+ size_t max_probe_length_ = 0;
+ size_t load_limit_ = 0; // Updated every time |capacity_| changes.
+ int load_limit_percent_ =
+ kDefaultLoadLimitPct; // Load factor limit in % of |capacity_|.
+
+ // These arrays have always the |capacity_| elements.
+ // Note: AlignedUniquePtr just allocates memory, doesn't invoke any ctor/dtor.
+ std::unique_ptr<uint8_t[]> tags_;
+ AlignedUniquePtr<Key[]> keys_;
+ AlignedUniquePtr<Value[]> values_;
+};
+
+} // namespace base
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_EXT_BASE_FLAT_HASH_MAP_H_
diff --git a/include/perfetto/ext/base/getopt.h b/include/perfetto/ext/base/getopt.h
index 77c149032..bf993fc1f 100644
--- a/include/perfetto/ext/base/getopt.h
+++ b/include/perfetto/ext/base/getopt.h
@@ -34,8 +34,10 @@
// replacement to the various main.cc, which can't know about the nested
// namespace.
using ::perfetto::base::getopt_compat::optarg;
+using ::perfetto::base::getopt_compat::opterr;
using ::perfetto::base::getopt_compat::optind;
using ::perfetto::base::getopt_compat::option;
+using ::perfetto::base::getopt_compat::optopt;
constexpr auto getopt = ::perfetto::base::getopt_compat::getopt;
constexpr auto getopt_long = ::perfetto::base::getopt_compat::getopt_long;
constexpr auto no_argument = ::perfetto::base::getopt_compat::no_argument;
diff --git a/include/perfetto/ext/base/getopt_compat.h b/include/perfetto/ext/base/getopt_compat.h
index d1f5436d0..d854ff022 100644
--- a/include/perfetto/ext/base/getopt_compat.h
+++ b/include/perfetto/ext/base/getopt_compat.h
@@ -53,6 +53,8 @@ struct option {
extern char* optarg;
extern int optind;
+extern int optopt;
+extern int opterr;
int getopt_long(int argc,
char** argv,
diff --git a/include/perfetto/ext/base/hash.h b/include/perfetto/ext/base/hash.h
index 6ec9fbeee..1717b3d5b 100644
--- a/include/perfetto/ext/base/hash.h
+++ b/include/perfetto/ext/base/hash.h
@@ -20,6 +20,7 @@
#include <stddef.h>
#include <stdint.h>
#include <type_traits>
+#include <utility>
namespace perfetto {
namespace base {
@@ -41,15 +42,43 @@ class Hash {
Update(reinterpret_cast<const char*>(&data), sizeof(data));
}
+ // Using the loop instead of "Update(str, strlen(str))" to avoid looping twice
+ void Update(const char* str) {
+ for (const auto* p = str; *p; ++p)
+ Update(*p);
+ }
+
// Hashes a byte array.
void Update(const char* data, size_t size) {
for (size_t i = 0; i < size; i++) {
result_ ^= static_cast<uint8_t>(data[i]);
+ // Note: Arithmetic overflow of unsigned integers is well defined in C++
+ // standard unlike signed integers.
+ // https://stackoverflow.com/a/41280273
result_ *= kFnv1a64Prime;
}
}
- uint64_t digest() { return result_; }
+ uint64_t digest() const { return result_; }
+
+ // Usage:
+ // uint64_t hashed_value = Hash::Combine(33, false, "ABC", 458L, 3u, 'x');
+ template <typename... Ts>
+ static uint64_t Combine(Ts&&... args) {
+ Hash hasher;
+ hasher.UpdateAll(std::forward<Ts>(args)...);
+ return hasher.digest();
+ }
+
+ // `hasher.UpdateAll(33, false, "ABC")` is shorthand for:
+ // `hasher.Update(33); hasher.Update(false); hasher.Update("ABC");`
+ void UpdateAll() {}
+
+ template <typename T, typename... Ts>
+ void UpdateAll(T&& arg, Ts&&... args) {
+ Update(arg);
+ UpdateAll(std::forward<Ts>(args)...);
+ }
private:
static constexpr uint64_t kFnv1a64OffsetBasis = 0xcbf29ce484222325;
@@ -58,6 +87,14 @@ class Hash {
uint64_t result_ = kFnv1a64OffsetBasis;
};
+// This is for using already-hashed key into std::unordered_map and avoid the
+// cost of re-hashing. Example:
+// unordered_map<uint64_t, Value, AlreadyHashed> my_map.
+template <typename T>
+struct AlreadyHashed {
+ size_t operator()(const T& x) const { return static_cast<size_t>(x); }
+};
+
} // namespace base
} // namespace perfetto
diff --git a/include/perfetto/ext/base/http/BUILD.gn b/include/perfetto/ext/base/http/BUILD.gn
new file mode 100644
index 000000000..3e4260777
--- /dev/null
+++ b/include/perfetto/ext/base/http/BUILD.gn
@@ -0,0 +1,21 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source_set("http") {
+ sources = [
+ "http_server.h",
+ "sha1.h",
+ ]
+ public_deps = [ "..:base" ]
+}
diff --git a/include/perfetto/ext/base/http/http_server.h b/include/perfetto/ext/base/http/http_server.h
new file mode 100644
index 000000000..c251061d7
--- /dev/null
+++ b/include/perfetto/ext/base/http/http_server.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_HTTP_HTTP_SERVER_H_
+#define INCLUDE_PERFETTO_EXT_BASE_HTTP_HTTP_SERVER_H_
+
+#include <array>
+#include <initializer_list>
+#include <list>
+#include <memory>
+#include <string>
+
+#include "perfetto/base/task_runner.h"
+#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/paged_memory.h"
+#include "perfetto/ext/base/string_view.h"
+#include "perfetto/ext/base/unix_socket.h"
+
+namespace perfetto {
+namespace base {
+
+class HttpServerConnection;
+
+struct HttpRequest {
+ explicit HttpRequest(HttpServerConnection* c) : conn(c) {}
+
+ Optional<StringView> GetHeader(StringView name) const;
+
+ HttpServerConnection* conn;
+
+ // These StringViews point to memory in the rxbuf owned by |conn|. They are
+ // valid only within the OnHttpRequest() call.
+ StringView method;
+ StringView uri;
+ StringView origin;
+ StringView body;
+ bool is_websocket_handshake = false;
+
+ private:
+ friend class HttpServer;
+ struct Header {
+ StringView name;
+ StringView value;
+ };
+
+ static constexpr uint32_t kMaxHeaders = 32;
+ std::array<Header, kMaxHeaders> headers{};
+ size_t num_headers = 0;
+};
+
+struct WebsocketMessage {
+ explicit WebsocketMessage(HttpServerConnection* c) : conn(c) {}
+
+ HttpServerConnection* conn;
+
+ // Note: message boundaries are not respected in case of fragmentation.
+ // This websocket implementation preserves only the byte stream, but not the
+ // atomicity of inbound messages (like SOCK_STREAM, unlike SOCK_DGRAM).
+ // Holds onto the connection's |rxbuf|. This is valid only within the scope
+ // of the OnWebsocketMessage() callback.
+ StringView data;
+
+ // If false the payload contains binary data. If true it's supposed to contain
+ // text. Note that there is no guarantee this will be the case. This merely
+ // reflect the opcode that the client sets on each message.
+ bool is_text = false;
+};
+
+class HttpServerConnection {
+ public:
+ static constexpr size_t kOmitContentLength = static_cast<size_t>(-1);
+
+ explicit HttpServerConnection(std::unique_ptr<UnixSocket>);
+ ~HttpServerConnection();
+
+ void SendResponseHeaders(const char* http_code,
+ std::initializer_list<const char*> headers = {},
+ size_t content_length = 0);
+
+ // Works also for websockets.
+ void SendResponseBody(const void* content, size_t content_length);
+ void Close();
+
+ // All the above in one shot.
+ void SendResponse(const char* http_code,
+ std::initializer_list<const char*> headers = {},
+ StringView content = {},
+ bool force_close = false);
+ void SendResponseAndClose(const char* http_code,
+ std::initializer_list<const char*> headers = {},
+ StringView content = {}) {
+ SendResponse(http_code, headers, content, true);
+ }
+
+ // The metods below are only valid for websocket connections.
+
+ // Upgrade an existing connection to a websocket. This can be called only in
+ // the context of OnHttpRequest(req) if req.is_websocket_handshake == true.
+ // If the origin is not in the |allowed_origins_|, the request will fail with
+ // a 403 error (this is because there is no browser-side CORS support for
+ // websockets).
+ void UpgradeToWebsocket(const HttpRequest&);
+ void SendWebsocketMessage(const void* data, size_t len);
+ void SendWebsocketMessage(StringView sv) {
+ SendWebsocketMessage(sv.data(), sv.size());
+ }
+ void SendWebsocketFrame(uint8_t opcode,
+ const void* payload,
+ size_t payload_len);
+
+ bool is_websocket() const { return is_websocket_; }
+
+ private:
+ friend class HttpServer;
+
+ size_t rxbuf_avail() { return rxbuf.size() - rxbuf_used; }
+
+ std::unique_ptr<UnixSocket> sock;
+ PagedMemory rxbuf;
+ size_t rxbuf_used = 0;
+ bool is_websocket_ = false;
+ bool headers_sent_ = false;
+ size_t content_len_headers_ = 0;
+ size_t content_len_actual_ = 0;
+
+ // If the origin is in the server's |allowed_origins_| this contains the
+ // origin itself. This is used to handle CORS headers.
+ std::string origin_allowed_;
+
+ // By default treat connections as keep-alive unless the client says
+ // explicitly 'Connection: close'. This improves TraceProcessor's python API.
+ // This is consistent with that nginx does.
+ bool keepalive_ = true;
+};
+
+class HttpRequestHandler {
+ public:
+ virtual ~HttpRequestHandler();
+ virtual void OnHttpRequest(const HttpRequest&) = 0;
+ virtual void OnWebsocketMessage(const WebsocketMessage&);
+ virtual void OnHttpConnectionClosed(HttpServerConnection*);
+};
+
+class HttpServer : public UnixSocket::EventListener {
+ public:
+ HttpServer(TaskRunner*, HttpRequestHandler*);
+ ~HttpServer() override;
+ void Start(int port);
+ void AddAllowedOrigin(const std::string&);
+
+ private:
+ size_t ParseOneHttpRequest(HttpServerConnection*);
+ size_t ParseOneWebsocketFrame(HttpServerConnection*);
+ void HandleCorsPreflightRequest(const HttpRequest&);
+ bool IsOriginAllowed(StringView);
+
+ // UnixSocket::EventListener implementation.
+ void OnNewIncomingConnection(UnixSocket*,
+ std::unique_ptr<UnixSocket>) override;
+ void OnConnect(UnixSocket* self, bool connected) override;
+ void OnDisconnect(UnixSocket* self) override;
+ void OnDataAvailable(UnixSocket* self) override;
+
+ TaskRunner* const task_runner_;
+ HttpRequestHandler* req_handler_;
+ std::unique_ptr<UnixSocket> sock4_;
+ std::unique_ptr<UnixSocket> sock6_;
+ std::list<HttpServerConnection> clients_;
+ std::list<std::string> allowed_origins_;
+ bool origin_error_logged_ = false;
+};
+
+} // namespace base
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_EXT_BASE_HTTP_HTTP_SERVER_H_
diff --git a/include/perfetto/ext/base/http/sha1.h b/include/perfetto/ext/base/http/sha1.h
new file mode 100644
index 000000000..c583d69d4
--- /dev/null
+++ b/include/perfetto/ext/base/http/sha1.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_HTTP_SHA1_H_
+#define INCLUDE_PERFETTO_EXT_BASE_HTTP_SHA1_H_
+
+#include <stddef.h>
+
+#include <array>
+#include <string>
+
+namespace perfetto {
+namespace base {
+
+constexpr size_t kSHA1Length = 20;
+using SHA1Digest = std::array<uint8_t, kSHA1Length>;
+
+SHA1Digest SHA1Hash(const std::string& str);
+SHA1Digest SHA1Hash(const void* data, size_t size);
+
+} // namespace base
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_EXT_BASE_HTTP_SHA1_H_
diff --git a/include/perfetto/ext/base/scoped_file.h b/include/perfetto/ext/base/scoped_file.h
index 5a99de64c..53d21b14b 100644
--- a/include/perfetto/ext/base/scoped_file.h
+++ b/include/perfetto/ext/base/scoped_file.h
@@ -51,7 +51,7 @@ template <typename T,
T InvalidValue,
bool CheckClose = true,
class Checker = internal::DefaultValidityChecker<T, InvalidValue>>
-class PERFETTO_EXPORT ScopedResource {
+class ScopedResource {
public:
using ValidityChecker = Checker;
static constexpr T kInvalid = InvalidValue;
diff --git a/include/perfetto/ext/base/small_vector.h b/include/perfetto/ext/base/small_vector.h
new file mode 100644
index 000000000..15b177341
--- /dev/null
+++ b/include/perfetto/ext/base/small_vector.h
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_SMALL_VECTOR_H_
+#define INCLUDE_PERFETTO_EXT_BASE_SMALL_VECTOR_H_
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "perfetto/base/compiler.h"
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/utils.h"
+
+namespace perfetto {
+namespace base {
+
+// Uses inline storage first, switches to dynamic storage when it overflows.
+template <typename T, size_t kSize>
+class SmallVector {
+ public:
+ static constexpr size_t kInlineSize = kSize;
+
+ explicit SmallVector() = default;
+
+ ~SmallVector() {
+ clear();
+ if (PERFETTO_UNLIKELY(is_using_heap()))
+ AlignedFree(begin_);
+ begin_ = end_ = end_of_storage_ = nullptr;
+ }
+
+ // Move operators.
+ SmallVector(SmallVector&& other) noexcept(
+ std::is_nothrow_move_constructible<T>::value) {
+ if (other.is_using_heap()) {
+ // Move the heap content, no need to move the individual objects as their
+ // location won't change.
+ begin_ = other.begin_;
+ end_ = other.end_;
+ end_of_storage_ = other.end_of_storage_;
+ } else {
+ const size_t other_size = other.size();
+ PERFETTO_DCHECK(other_size <= capacity());
+ for (size_t i = 0; i < other_size; i++) {
+ // Move the entries and destroy the ones in the moved-from object.
+ new (&begin_[i]) T(std::move(other.begin_[i]));
+ other.begin_[i].~T();
+ }
+ end_ = begin_ + other_size;
+ }
+ auto* const other_inline_storage = other.inline_storage_begin();
+ other.end_ = other.begin_ = other_inline_storage;
+ other.end_of_storage_ = other_inline_storage + kInlineSize;
+ }
+
+ SmallVector& operator=(SmallVector&& other) noexcept(
+ std::is_nothrow_move_constructible<T>::value) {
+ this->~SmallVector();
+ new (this) SmallVector<T, kSize>(std::move(other));
+ return *this;
+ }
+
+ // Copy operators.
+ SmallVector(const SmallVector& other) {
+ const size_t other_size = other.size();
+ if (other_size > capacity())
+ Grow(other_size);
+ // Copy-construct the elements.
+ for (size_t i = 0; i < other_size; ++i)
+ new (&begin_[i]) T(other.begin_[i]);
+ end_ = begin_ + other_size;
+ }
+
+ SmallVector& operator=(const SmallVector& other) {
+ if (PERFETTO_UNLIKELY(this == &other))
+ return *this;
+ this->~SmallVector();
+ new (this) SmallVector<T, kSize>(other);
+ return *this;
+ }
+
+ T* data() { return begin_; }
+ const T* data() const { return begin_; }
+
+ T* begin() { return begin_; }
+ const T* begin() const { return begin_; }
+
+ T* end() { return end_; }
+ const T* end() const { return end_; }
+
+ size_t size() const { return static_cast<size_t>(end_ - begin_); }
+
+ bool empty() const { return end_ == begin_; }
+
+ size_t capacity() const {
+ return static_cast<size_t>(end_of_storage_ - begin_);
+ }
+
+ T& back() {
+ PERFETTO_DCHECK(!empty());
+ return end_[-1];
+ }
+ const T& back() const {
+ PERFETTO_DCHECK(!empty());
+ return end_[-1];
+ }
+
+ T& operator[](size_t index) {
+ PERFETTO_DCHECK(index < size());
+ return begin_[index];
+ }
+
+ const T& operator[](size_t index) const {
+ PERFETTO_DCHECK(index < size());
+ return begin_[index];
+ }
+
+ template <typename... Args>
+ void emplace_back(Args&&... args) {
+ T* end = end_;
+ if (PERFETTO_UNLIKELY(end == end_of_storage_))
+ end = Grow();
+ new (end) T(std::forward<Args>(args)...);
+ end_ = end + 1;
+ }
+
+ void pop_back() {
+ PERFETTO_DCHECK(!empty());
+ back().~T();
+ --end_;
+ }
+
+ // Clear without reverting back to inline storage.
+ void clear() {
+ while (!empty())
+ pop_back();
+ }
+
+ private:
+ PERFETTO_NO_INLINE T* Grow(size_t desired_capacity = 0) {
+ size_t cur_size = size();
+ size_t new_capacity = desired_capacity;
+ if (desired_capacity <= cur_size)
+ new_capacity = std::max(capacity() * 2, size_t(128));
+ T* new_storage =
+ static_cast<T*>(AlignedAlloc(alignof(T), new_capacity * sizeof(T)));
+ for (size_t i = 0; i < cur_size; ++i) {
+ // Move the elements into the new heap buffer and destroy the old ones.
+ new (&new_storage[i]) T(std::move(begin_[i]));
+ begin_[i].~T();
+ }
+ if (is_using_heap())
+ AlignedFree(begin_);
+ begin_ = new_storage;
+ end_ = new_storage + cur_size;
+ end_of_storage_ = new_storage + new_capacity;
+ return end_;
+ }
+
+ T* inline_storage_begin() { return reinterpret_cast<T*>(&inline_storage_); }
+ bool is_using_heap() { return begin_ != inline_storage_begin(); }
+
+ T* begin_ = inline_storage_begin();
+ T* end_ = begin_;
+ T* end_of_storage_ = begin_ + kInlineSize;
+
+ typename std::aligned_storage<sizeof(T) * kInlineSize, alignof(T)>::type
+ inline_storage_;
+};
+
+} // namespace base
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_EXT_BASE_SMALL_VECTOR_H_
diff --git a/include/perfetto/ext/base/string_utils.h b/include/perfetto/ext/base/string_utils.h
index bd4f1f6ef..593204fa7 100644
--- a/include/perfetto/ext/base/string_utils.h
+++ b/include/perfetto/ext/base/string_utils.h
@@ -17,20 +17,20 @@
#ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
#define INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <cinttypes>
#include <string>
#include <vector>
-#include <inttypes.h>
-#include <stdlib.h>
-
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/string_view.h"
namespace perfetto {
namespace base {
-std::string QuoteAndEscapeControlCodes(const std::string& raw);
-
inline char Lowercase(char c) {
return ('A' <= c && c <= 'Z') ? static_cast<char>(c - ('A' - 'a')) : c;
}
@@ -97,6 +97,8 @@ inline Optional<double> StringToDouble(const std::string& s) {
bool StartsWith(const std::string& str, const std::string& prefix);
bool EndsWith(const std::string& str, const std::string& suffix);
+bool StartsWithAny(const std::string& str,
+ const std::vector<std::string>& prefixes);
bool Contains(const std::string& haystack, const std::string& needle);
bool Contains(const std::string& haystack, char needle);
size_t Find(const StringView& needle, const StringView& haystack);
@@ -122,8 +124,83 @@ std::string Uint64ToHexStringNoPrefix(uint64_t number);
std::string ReplaceAll(std::string str,
const std::string& to_replace,
const std::string& replacement);
-std::string TrimLeading(const std::string& str);
-std::string Base64Encode(const void* raw, size_t size);
+
+// A BSD-style strlcpy without the return value.
+// Copies at most |dst_size|-1 characters. Unlike strncpy, it always \0
+// terminates |dst|, as long as |dst_size| is not 0.
+// Unlike strncpy and like strlcpy it does not zero-pad the rest of |dst|.
+// Returns nothing. The BSD strlcpy returns the size of |src|, which might
+// be > |dst_size|. Anecdotal experience suggests people assume the return value
+// is the number of bytes written in |dst|. That assumption can lead to
+// dangerous bugs.
+// In order to avoid being subtly uncompliant with strlcpy AND avoid misuse,
+// the choice here is to return nothing.
+inline void StringCopy(char* dst, const char* src, size_t dst_size) {
+ for (size_t i = 0; i < dst_size; ++i) {
+ if ((dst[i] = src[i]) == '\0') {
+ return; // We hit and copied the null terminator.
+ }
+ }
+
+ // We were left off at dst_size. We over copied 1 byte. Null terminate.
+ if (PERFETTO_LIKELY(dst_size > 0))
+ dst[dst_size - 1] = 0;
+}
+
+// Like snprintf() but returns the number of chars *actually* written (without
+// counting the null terminator) NOT "the number of chars which would have been
+// written to the final string if enough space had been available".
+// This should be used in almost all cases when the caller uses the return value
+// of snprintf(). If the return value is not used, there is no benefit in using
+// this wrapper, as this just calls snprintf() and mangles the return value.
+// It always null-terminates |dst| (even in case of errors), unless
+// |dst_size| == 0.
+// Examples:
+// SprintfTrunc(x, 4, "123whatever"): returns 3 and writes "123\0".
+// SprintfTrunc(x, 4, "123"): returns 3 and writes "123\0".
+// SprintfTrunc(x, 3, "123"): returns 2 and writes "12\0".
+// SprintfTrunc(x, 2, "123"): returns 1 and writes "1\0".
+// SprintfTrunc(x, 1, "123"): returns 0 and writes "\0".
+// SprintfTrunc(x, 0, "123"): returns 0 and writes nothing.
+// NOTE: This means that the caller has no way to tell when truncation happens
+// vs the edge case of *just* fitting in the buffer.
+size_t SprintfTrunc(char* dst, size_t dst_size, const char* fmt, ...)
+ PERFETTO_PRINTF_FORMAT(3, 4);
+
+// A helper class to facilitate construction and usage of write-once stack
+// strings.
+// Example usage:
+// StackString<32> x("format %d %s", 42, string_arg);
+// TakeString(x.c_str() | x.string_view() | x.ToStdString());
+// Rather than char x[32] + sprintf.
+// Advantages:
+// - Avoids useless zero-fills caused by people doing `char buf[32] {}` (mainly
+// by fearing unknown snprintf failure modes).
+// - Makes the code more robust in case of snprintf truncations (len() and
+// string_view() will return the truncated length, unlike snprintf).
+template <size_t N>
+class StackString {
+ public:
+ explicit PERFETTO_PRINTF_FORMAT(/* 1=this */ 2, 3)
+ StackString(const char* fmt, ...) {
+ buf_[0] = '\0';
+ va_list args;
+ va_start(args, fmt);
+ int res = vsnprintf(buf_, sizeof(buf_), fmt, args);
+ va_end(args);
+ buf_[sizeof(buf_) - 1] = '\0';
+ len_ = res < 0 ? 0 : std::min(static_cast<size_t>(res), sizeof(buf_) - 1);
+ }
+
+ StringView string_view() const { return StringView(buf_, len_); }
+ std::string ToStdString() const { return std::string(buf_, len_); }
+ const char* c_str() const { return buf_; }
+ size_t len() const { return len_; }
+
+ private:
+ char buf_[N];
+ size_t len_ = 0; // Does not include the \0.
+};
} // namespace base
} // namespace perfetto
diff --git a/include/perfetto/ext/base/string_view.h b/include/perfetto/ext/base/string_view.h
index dce2fdce2..81c1a75ac 100644
--- a/include/perfetto/ext/base/string_view.h
+++ b/include/perfetto/ext/base/string_view.h
@@ -106,7 +106,7 @@ class StringView {
return StringView(data_ + pos, rcount);
}
- bool CaseInsensitiveEq(const StringView& other) {
+ bool CaseInsensitiveEq(const StringView& other) const {
if (size() != other.size())
return false;
if (size() == 0)
@@ -118,8 +118,22 @@ class StringView {
#endif
}
+ bool StartsWith(const StringView& other) {
+ if (other.size() == 0)
+ return true;
+ if (size() == 0)
+ return false;
+ if (other.size() > size())
+ return false;
+ for (uint32_t i = 0; i < other.size(); ++i) {
+ if (at(i) != other.at(i))
+ return false;
+ }
+ return true;
+ }
+
std::string ToStdString() const {
- return data_ == nullptr ? "" : std::string(data_, size_);
+ return size_ == 0 ? "" : std::string(data_, size_);
}
uint64_t Hash() const {
diff --git a/include/perfetto/ext/base/string_writer.h b/include/perfetto/ext/base/string_writer.h
index cee3198f6..587b2f932 100644
--- a/include/perfetto/ext/base/string_writer.h
+++ b/include/perfetto/ext/base/string_writer.h
@@ -17,14 +17,15 @@
#ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_WRITER_H_
#define INCLUDE_PERFETTO_EXT_BASE_STRING_WRITER_H_
-#include <inttypes.h>
-#include <math.h>
#include <string.h>
+
+#include <cinttypes>
#include <cmath>
#include <cstdlib>
#include <limits>
#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/string_view.h"
namespace perfetto {
@@ -97,8 +98,8 @@ class StringWriter {
void AppendHexInt(IntType value) {
// TODO(lalitm): trying to optimize this is premature given we almost never
// print hex ints. Reevaluate this in the future if we do print them more.
- size_t res = static_cast<size_t>(
- snprintf(buffer_ + pos_, size_ - pos_, "%" PRIx64, value));
+ size_t res =
+ base::SprintfTrunc(buffer_ + pos_, size_ - pos_, "%" PRIx64, value);
PERFETTO_DCHECK(pos_ + res <= size_);
pos_ += res;
}
@@ -107,8 +108,7 @@ class StringWriter {
void AppendDouble(double value) {
// TODO(lalitm): trying to optimize this is premature given we almost never
// print doubles. Reevaluate this in the future if we do print them more.
- size_t res = static_cast<size_t>(
- snprintf(buffer_ + pos_, size_ - pos_, "%lf", value));
+ size_t res = base::SprintfTrunc(buffer_ + pos_, size_ - pos_, "%lf", value);
PERFETTO_DCHECK(pos_ + res <= size_);
pos_ += res;
}
@@ -129,7 +129,7 @@ class StringWriter {
char* CreateStringCopy() {
char* dup = reinterpret_cast<char*>(malloc(pos_ + 1));
if (dup) {
- strncpy(dup, buffer_, pos_);
+ memcpy(dup, buffer_, pos_);
dup[pos_] = '\0';
}
return dup;
diff --git a/include/perfetto/ext/base/subprocess.h b/include/perfetto/ext/base/subprocess.h
index 77b2dfdbb..cca6c2900 100644
--- a/include/perfetto/ext/base/subprocess.h
+++ b/include/perfetto/ext/base/subprocess.h
@@ -30,6 +30,7 @@
#include "perfetto/base/platform_handle.h"
#include "perfetto/base/proc_utils.h"
#include "perfetto/ext/base/event_fd.h"
+#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/pipe.h"
#include "perfetto/ext/base/scoped_file.h"
@@ -105,13 +106,18 @@ class Subprocess {
// This includes crashes or other signals on UNIX.
};
- enum OutputMode {
+ enum class OutputMode {
kInherit = 0, // Inherit's the caller process stdout/stderr.
- kDevNull, // dup() onto /dev/null
+ kDevNull, // dup() onto /dev/null.
kBuffer, // dup() onto a pipe and move it into the output() buffer.
kFd, // dup() onto the passed args.fd.
};
+ enum class InputMode {
+ kBuffer = 0, // dup() onto a pipe and write args.input on it.
+ kDevNull, // dup() onto /dev/null.
+ };
+
// Input arguments for configuring the subprocess behavior.
struct Args {
Args(std::initializer_list<std::string> _cmd = {}) : exec_cmd(_cmd) {}
@@ -133,6 +139,13 @@ class Subprocess {
// just before the exec() call, but after having closed all fds % stdin/o/e.
// This is for synchronization barriers in tests.
std::function<void()> posix_entrypoint_for_testing;
+
+ // When set, will will move the process to the given process group. If set
+ // and zero, it will create a new process group. Effectively this calls
+ // setpgid(0 /*self_pid*/, posix_proc_group_id).
+ // This can be used to avoid that subprocesses receive CTRL-C from the
+ // terminal, while still living in the same session.
+ base::Optional<pid_t> posix_proc_group_id{};
#endif
// If non-empty, replaces the environment passed to exec().
@@ -141,11 +154,13 @@ class Subprocess {
// The file descriptors in this list will not be closed.
std::vector<int> preserve_fds;
- // The data to push in the child process stdin.
+ // The data to push in the child process stdin, if input_mode ==
+ // InputMode::kBuffer.
std::string input;
- OutputMode stdout_mode = kInherit;
- OutputMode stderr_mode = kInherit;
+ InputMode stdin_mode = InputMode::kBuffer;
+ OutputMode stdout_mode = OutputMode::kInherit;
+ OutputMode stderr_mode = OutputMode::kInherit;
base::ScopedPlatformHandle out_fd;
@@ -205,7 +220,7 @@ class Subprocess {
bool timed_out() const { return s_->timed_out; }
// This contains both stdout and stderr (if the corresponding _mode ==
- // kBuffer). It's non-const so the caller can std::move() it.
+ // OutputMode::kBuffer). It's non-const so the caller can std::move() it.
std::string& output() { return s_->output; }
const std::string& output() const { return s_->output; }
@@ -228,7 +243,7 @@ class Subprocess {
PlatformProcessId pid;
Status status = kNotStarted;
int returncode = -1;
- std::string output; // Stdin+stderr. Only when kBuffer.
+ std::string output; // Stdin+stderr. Only when OutputMode::kBuffer.
std::unique_ptr<ResourceUsage> rusage{new ResourceUsage()};
bool timed_out = false;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
diff --git a/include/perfetto/ext/base/sys_types.h b/include/perfetto/ext/base/sys_types.h
new file mode 100644
index 000000000..999a1522f
--- /dev/null
+++ b/include/perfetto/ext/base/sys_types.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_SYS_TYPES_H_
+#define INCLUDE_PERFETTO_EXT_BASE_SYS_TYPES_H_
+
+// This headers deals with sys types commonly used in the codebase that are
+// missing on Windows.
+
+#include <sys/types.h>
+
+#include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
+// MinGW has these. clang-cl and MSVC, which use just the Windows SDK, don't.
+using uid_t = unsigned int;
+using pid_t = int;
+#endif // !GCC
+
+#if defined(_WIN64)
+using ssize_t = int64_t;
+#else
+using ssize_t = long;
+#endif // _WIN64
+
+#endif // OS_WIN
+
+namespace perfetto {
+namespace base {
+
+constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
+constexpr pid_t kInvalidPid = static_cast<pid_t>(-1);
+
+} // namespace base
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_EXT_BASE_SYS_TYPES_H_
diff --git a/include/perfetto/ext/base/thread_utils.h b/include/perfetto/ext/base/thread_utils.h
index 2e9c4e54e..4a1f0b665 100644
--- a/include/perfetto/ext/base/thread_utils.h
+++ b/include/perfetto/ext/base/thread_utils.h
@@ -20,6 +20,7 @@
#include <string>
#include "perfetto/base/build_config.h"
+#include "perfetto/ext/base/string_utils.h"
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
@@ -46,8 +47,7 @@ namespace base {
// string.
inline bool MaybeSetThreadName(const std::string& name) {
char buf[16] = {};
- size_t sz = std::min(name.size(), static_cast<size_t>(15));
- strncpy(buf, name.c_str(), sz);
+ StringCopy(buf, name.c_str(), sizeof(buf));
#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
return pthread_setname_np(buf) == 0;
diff --git a/include/perfetto/ext/base/unix_socket.h b/include/perfetto/ext/base/unix_socket.h
index 0d679e529..a76942320 100644
--- a/include/perfetto/ext/base/unix_socket.h
+++ b/include/perfetto/ext/base/unix_socket.h
@@ -140,6 +140,10 @@ class UnixSocketRaw {
const int* send_fds = nullptr,
size_t num_fds = 0);
+ ssize_t SendStr(const std::string& str) {
+ return Send(str.data(), str.size());
+ }
+
// |fd_vec| and |max_files| are ignored on Windows.
ssize_t Receive(void* msg,
size_t len,
@@ -171,6 +175,7 @@ class UnixSocketRaw {
#endif
SockFamily family_ = SockFamily::kUnix;
SockType type_ = SockType::kStream;
+ uint32_t tx_timeout_ms_ = 0;
};
// A non-blocking UNIX domain socket. Allows also to transfer file descriptors.
@@ -321,8 +326,8 @@ class PERFETTO_EXPORT UnixSocket {
return Send(msg, len, nullptr, 0);
}
- inline bool Send(const std::string& msg) {
- return Send(msg.c_str(), msg.size() + 1, -1);
+ inline bool SendStr(const std::string& msg) {
+ return Send(msg.data(), msg.size(), -1);
}
// Returns the number of bytes (<= |len|) written in |msg| or 0 if there
diff --git a/include/perfetto/ext/base/utils.h b/include/perfetto/ext/base/utils.h
index af39b37fa..1535c5e3a 100644
--- a/include/perfetto/ext/base/utils.h
+++ b/include/perfetto/ext/base/utils.h
@@ -17,18 +17,20 @@
#ifndef INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
#define INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
-#include "perfetto/base/build_config.h"
-#include "perfetto/base/compiler.h"
-
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
-#include <sys/types.h>
#include <atomic>
+#include <functional>
+#include <memory>
#include <string>
+#include "perfetto/base/build_config.h"
+#include "perfetto/base/compiler.h"
+#include "perfetto/ext/base/sys_types.h"
+
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
// Even if Windows has errno.h, the all syscall-restart behavior does not apply.
// Trying to handle EINTR can cause more harm than good if errno is left stale.
@@ -45,24 +47,9 @@
}())
#endif
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
-using uid_t = unsigned int;
-#if !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
-using pid_t = unsigned int;
-#endif
-#if defined(_WIN64)
-using ssize_t = int64_t;
-#else
-using ssize_t = long;
-#endif
-#endif
-
namespace perfetto {
namespace base {
-constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
-constexpr pid_t kInvalidPid = static_cast<pid_t>(-1);
-
// Do not add new usages of kPageSize, consider using GetSysPageSize() below.
// TODO(primiano): over time the semantic of kPageSize became too ambiguous.
// Strictly speaking, this constant is incorrect on some new devices where the
@@ -120,9 +107,75 @@ void MaybeReleaseAllocatorMemToOS();
uid_t GetCurrentUserId();
// Forks the process.
-// Parent: prints the PID of the child and exit(0).
-// Child: redirects stdio onto /dev/null and chdirs into .
-void Daemonize();
+// Parent: prints the PID of the child, calls |parent_cb| and exits from the
+// process with its return value.
+// Child: redirects stdio onto /dev/null, chdirs into / and returns.
+void Daemonize(std::function<int()> parent_cb);
+
+// Returns the path of the current executable, e.g. /foo/bar/exe.
+std::string GetCurExecutablePath();
+
+// Returns the directory where the current executable lives in, e.g. /foo/bar.
+// This is independent of cwd().
+std::string GetCurExecutableDir();
+
+// Memory returned by AlignedAlloc() must be freed via AlignedFree() not just
+// free. It makes a difference on Windows where _aligned_malloc() and
+// _aligned_free() must be paired.
+// Prefer using the AlignedAllocTyped() below which takes care of the pairing.
+void* AlignedAlloc(size_t alignment, size_t size);
+void AlignedFree(void*);
+
+// A RAII version of the above, which takes care of pairing Aligned{Alloc,Free}.
+template <typename T>
+struct AlignedDeleter {
+ inline void operator()(T* ptr) const { AlignedFree(ptr); }
+};
+
+// The remove_extent<T> here and below is to allow defining unique_ptr<T[]>.
+// As per https://en.cppreference.com/w/cpp/memory/unique_ptr the Deleter takes
+// always a T*, not a T[]*.
+template <typename T>
+using AlignedUniquePtr =
+ std::unique_ptr<T, AlignedDeleter<typename std::remove_extent<T>::type>>;
+
+template <typename T>
+AlignedUniquePtr<T> AlignedAllocTyped(size_t n_membs) {
+ using TU = typename std::remove_extent<T>::type;
+ return AlignedUniquePtr<T>(
+ static_cast<TU*>(AlignedAlloc(alignof(TU), sizeof(TU) * n_membs)));
+}
+
+// A RAII wrapper to invoke a function when leaving a function/scope.
+template <typename Func>
+class OnScopeExitWrapper {
+ public:
+ explicit OnScopeExitWrapper(Func f) : f_(std::move(f)), active_(true) {}
+ OnScopeExitWrapper(OnScopeExitWrapper&& other) noexcept
+ : f_(std::move(other.f_)), active_(other.active_) {
+ other.active_ = false;
+ }
+ ~OnScopeExitWrapper() {
+ if (active_)
+ f_();
+ }
+
+ private:
+ Func f_;
+ bool active_;
+};
+
+template <typename Func>
+PERFETTO_WARN_UNUSED_RESULT OnScopeExitWrapper<Func> OnScopeExit(Func f) {
+ return OnScopeExitWrapper<Func>(std::move(f));
+}
+
+// Returns a xxd-style hex dump (hex + ascii chars) of the input data.
+std::string HexDump(const void* data, size_t len, size_t bytes_per_line = 16);
+inline std::string HexDump(const std::string& data,
+ size_t bytes_per_line = 16) {
+ return HexDump(data.data(), data.size(), bytes_per_line);
+}
} // namespace base
} // namespace perfetto
diff --git a/include/perfetto/ext/base/watchdog.h b/include/perfetto/ext/base/watchdog.h
index 58ab8e528..9bb422724 100644
--- a/include/perfetto/ext/base/watchdog.h
+++ b/include/perfetto/ext/base/watchdog.h
@@ -32,6 +32,15 @@
namespace perfetto {
namespace base {
+// Used only to add more details to crash reporting.
+enum class WatchdogCrashReason {
+ kUnspecified = 0,
+ kCpuGuardrail = 1,
+ kMemGuardrail = 2,
+ kTaskRunnerHung = 3,
+ kTraceDidntStop = 4,
+};
+
// Make the limits more relaxed on desktop, where multi-GB traces are likely.
// Multi-GB traces can take bursts of cpu time to write into disk at the end of
// the trace.
@@ -53,8 +62,8 @@ inline void RunTaskWithWatchdogGuard(const std::function<void()>& task) {
// program suicides.
constexpr int64_t kWatchdogMillis = 30000; // 30s
- Watchdog::Timer handle =
- base::Watchdog::GetInstance()->CreateFatalTimer(kWatchdogMillis);
+ Watchdog::Timer handle = base::Watchdog::GetInstance()->CreateFatalTimer(
+ kWatchdogMillis, WatchdogCrashReason::kTaskRunnerHung);
task();
// Suppress unused variable warnings in the client library amalgamated build.
diff --git a/include/perfetto/ext/base/watchdog_noop.h b/include/perfetto/ext/base/watchdog_noop.h
index 52a44c6b5..231705c64 100644
--- a/include/perfetto/ext/base/watchdog_noop.h
+++ b/include/perfetto/ext/base/watchdog_noop.h
@@ -22,6 +22,8 @@
namespace perfetto {
namespace base {
+enum class WatchdogCrashReason; // Defined in watchdog.h.
+
class Watchdog {
public:
class Timer {
@@ -35,7 +37,9 @@ class Watchdog {
static Watchdog* watchdog = new Watchdog();
return watchdog;
}
- Timer CreateFatalTimer(uint32_t /*ms*/) { return Timer(); }
+ Timer CreateFatalTimer(uint32_t /*ms*/, WatchdogCrashReason) {
+ return Timer();
+ }
void Start() {}
void SetMemoryLimit(uint64_t /*bytes*/, uint32_t /*window_ms*/) {}
void SetCpuLimit(uint32_t /*percentage*/, uint32_t /*window_ms*/) {}
diff --git a/include/perfetto/ext/base/watchdog_posix.h b/include/perfetto/ext/base/watchdog_posix.h
index 3c673c38b..fef4074b6 100644
--- a/include/perfetto/ext/base/watchdog_posix.h
+++ b/include/perfetto/ext/base/watchdog_posix.h
@@ -17,17 +17,19 @@
#ifndef INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_POSIX_H_
#define INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_POSIX_H_
-#include "perfetto/ext/base/optional.h"
-#include "perfetto/ext/base/thread_checker.h"
+#include "perfetto/base/time.h"
+#include "perfetto/ext/base/scoped_file.h"
#include <atomic>
-#include <condition_variable>
#include <mutex>
#include <thread>
+#include <vector>
namespace perfetto {
namespace base {
+enum class WatchdogCrashReason; // Defined in watchdog.h.
+
struct ProcStat {
unsigned long int utime = 0l;
unsigned long int stime = 0l;
@@ -41,6 +43,21 @@ bool ReadProcStat(int fd, ProcStat* out);
// crashed.
class Watchdog {
public:
+ struct TimerData {
+ TimeMillis deadline{}; // Absolute deadline, CLOCK_MONOTONIC.
+ int thread_id = 0; // The tid we'll send a SIGABRT to on expiry.
+ WatchdogCrashReason crash_reason{}; // Becomes a crash key.
+
+ TimerData() = default;
+ TimerData(TimeMillis d, int t) : deadline(d), thread_id(t) {}
+ bool operator<(const TimerData& x) const {
+ return std::tie(deadline, thread_id) < std::tie(x.deadline, x.thread_id);
+ }
+ bool operator==(const TimerData& x) const {
+ return std::tie(deadline, thread_id) == std::tie(x.deadline, x.thread_id);
+ }
+ };
+
// Handle to the timer set to crash the program. If the handle is dropped,
// the timer is removed so the program does not crash.
class Timer {
@@ -51,11 +68,14 @@ class Watchdog {
private:
friend class Watchdog;
- explicit Timer(uint32_t ms);
+ explicit Timer(Watchdog*, uint32_t ms, WatchdogCrashReason);
Timer(const Timer&) = delete;
Timer& operator=(const Timer&) = delete;
- Optional<timer_t> timerid_;
+ // In production this is always Watchdog::GetInstance(), which is long
+ // lived. However unittests use a non-global instance.
+ Watchdog* watchdog_ = nullptr;
+ TimerData timer_data_;
};
virtual ~Watchdog();
@@ -63,7 +83,9 @@ class Watchdog {
// Sets a timer which will crash the program in |ms| milliseconds if the
// returned handle is not destroyed before this point.
- Timer CreateFatalTimer(uint32_t ms);
+ // WatchdogCrashReason is used only to set a crash key in the case of a crash,
+ // to disambiguate different timer types.
+ Timer CreateFatalTimer(uint32_t ms, WatchdogCrashReason);
// Starts the watchdog thread which monitors the memory and CPU usage
// of the program.
@@ -81,10 +103,6 @@ class Watchdog {
// Note: |window_ms| has to be a multiple of |polling_interval_ms_|.
void SetCpuLimit(uint32_t percentage, uint32_t window_ms);
- protected:
- // Protected for testing.
- Watchdog(uint32_t polling_interval_ms);
-
private:
// Represents a ring buffer in which integer values can be stored.
class WindowedInterval {
@@ -126,15 +144,23 @@ class Watchdog {
std::unique_ptr<uint64_t[]> buffer_;
};
- explicit Watchdog(const Watchdog&) = delete;
+ Watchdog(const Watchdog&) = delete;
Watchdog& operator=(const Watchdog&) = delete;
+ Watchdog(Watchdog&&) = delete;
+ Watchdog& operator=(Watchdog&&) = delete;
// Main method for the watchdog thread.
void ThreadMain();
// Check each type of resource every |polling_interval_ms_| miillis.
- void CheckMemory(uint64_t rss_bytes);
- void CheckCpu(uint64_t cpu_time);
+ // Returns true if the threshold is exceeded and the process should be killed.
+ bool CheckMemory_Locked(uint64_t rss_bytes);
+ bool CheckCpu_Locked(uint64_t cpu_time);
+
+ void AddFatalTimer(TimerData);
+ void RemoveFatalTimer(TimerData);
+ void RearmTimerFd_Locked();
+ void SerializeLogsAndKillThread(int tid, WatchdogCrashReason);
// Computes the time interval spanned by a given ring buffer with respect
// to |polling_interval_ms_|.
@@ -143,7 +169,7 @@ class Watchdog {
const uint32_t polling_interval_ms_;
std::atomic<bool> enabled_{false};
std::thread thread_;
- std::condition_variable exit_signal_;
+ ScopedPlatformHandle timer_fd_;
// --- Begin lock-protected members ---
@@ -155,7 +181,20 @@ class Watchdog {
uint32_t cpu_limit_percentage_ = 0;
WindowedInterval cpu_window_time_ticks_;
+ // Outstanding timers created via CreateFatalTimer() and not yet destroyed.
+ // The vector is not sorted. In most cases there are only 1-2 timers, we can
+ // afford O(N) operations.
+ // All the timers in the list share the same |timer_fd_|, which is keeped
+ // armed on the min(timers_) through RearmTimerFd_Locked().
+ std::vector<TimerData> timers_;
+
// --- End lock-protected members ---
+
+ protected:
+ // Protected for testing.
+ explicit Watchdog(uint32_t polling_interval_ms);
+
+ bool disable_kill_failsafe_for_testing_ = false;
};
} // namespace base
diff --git a/include/perfetto/ext/ipc/client_info.h b/include/perfetto/ext/ipc/client_info.h
index 6988d1813..4537916cd 100644
--- a/include/perfetto/ext/ipc/client_info.h
+++ b/include/perfetto/ext/ipc/client_info.h
@@ -28,8 +28,8 @@ namespace ipc {
class ClientInfo {
public:
ClientInfo() = default;
- ClientInfo(ClientID client_id, uid_t uid)
- : client_id_(client_id), uid_(uid) {}
+ ClientInfo(ClientID client_id, uid_t uid, pid_t pid)
+ : client_id_(client_id), uid_(uid), pid_(pid) {}
bool operator==(const ClientInfo& other) const {
return (client_id_ == other.client_id_ && uid_ == other.uid_);
@@ -50,9 +50,13 @@ class ClientInfo {
// Posix User ID. Comes from the kernel, can be trusted.
uid_t uid() const { return uid_; }
+ // Posix process ID. Comes from the kernel and can be trusted.
+ int32_t pid() const { return pid_; }
+
private:
ClientID client_id_ = 0;
uid_t uid_ = kInvalidUid;
+ pid_t pid_ = base::kInvalidPid;
};
} // namespace ipc
diff --git a/include/perfetto/ext/trace_processor/BUILD.gn b/include/perfetto/ext/trace_processor/BUILD.gn
index a2fd7fae2..6df0cca76 100644
--- a/include/perfetto/ext/trace_processor/BUILD.gn
+++ b/include/perfetto/ext/trace_processor/BUILD.gn
@@ -21,3 +21,7 @@ source_set("export_json") {
sources += [ "export_json.h" ]
}
}
+
+source_set("demangle") {
+ sources = [ "demangle.h" ]
+}
diff --git a/include/perfetto/ext/trace_processor/demangle.h b/include/perfetto/ext/trace_processor/demangle.h
new file mode 100644
index 000000000..f3c337ffd
--- /dev/null
+++ b/include/perfetto/ext/trace_processor/demangle.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACE_PROCESSOR_DEMANGLE_H_
+#define INCLUDE_PERFETTO_EXT_TRACE_PROCESSOR_DEMANGLE_H_
+
+#include "perfetto/ext/base/utils.h"
+
+namespace perfetto {
+namespace trace_processor {
+namespace demangle {
+
+// Returns a |malloc|-allocated C string with the demangled name.
+// Returns an empty pointer if demangling was unsuccessful.
+std::unique_ptr<char, base::FreeDeleter> Demangle(const char* mangled_name);
+
+} // namespace demangle
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_EXT_TRACE_PROCESSOR_DEMANGLE_H_
diff --git a/include/perfetto/ext/tracing/core/basic_types.h b/include/perfetto/ext/tracing/core/basic_types.h
index 99005ce8f..08f405d22 100644
--- a/include/perfetto/ext/tracing/core/basic_types.h
+++ b/include/perfetto/ext/tracing/core/basic_types.h
@@ -17,15 +17,10 @@
#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_
#define INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_
-#include "perfetto/base/build_config.h"
-
#include <stddef.h>
#include <stdint.h>
-#include <sys/types.h>
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
-using uid_t = unsigned int;
-#endif
+#include "perfetto/ext/base/sys_types.h"
namespace perfetto {
@@ -76,7 +71,7 @@ static constexpr PacketSequenceID kServicePacketSequenceID = 1;
static constexpr PacketSequenceID kMaxPacketSequenceID =
static_cast<PacketSequenceID>(-1);
-constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
+constexpr uid_t kInvalidUid = ::perfetto::base::kInvalidUid;
constexpr uint32_t kDefaultFlushTimeoutMs = 5000;
diff --git a/include/perfetto/ext/tracing/core/tracing_service.h b/include/perfetto/ext/tracing/core/tracing_service.h
index 9636cdf7e..49c070ced 100644
--- a/include/perfetto/ext/tracing/core/tracing_service.h
+++ b/include/perfetto/ext/tracing/core/tracing_service.h
@@ -25,6 +25,7 @@
#include "perfetto/base/export.h"
#include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/sys_types.h"
#include "perfetto/ext/tracing/core/basic_types.h"
#include "perfetto/ext/tracing/core/shared_memory.h"
#include "perfetto/tracing/buffer_exhausted_policy.h"
@@ -60,6 +61,7 @@ class PERFETTO_EXPORT ProducerEndpoint {
// Called by the Producer to (un)register data sources. Data sources are
// identified by their name (i.e. DataSourceDescriptor.name)
virtual void RegisterDataSource(const DataSourceDescriptor&) = 0;
+ virtual void UpdateDataSource(const DataSourceDescriptor&) = 0;
virtual void UnregisterDataSource(const std::string& name) = 0;
// Associate the trace writer with the given |writer_id| with
@@ -320,6 +322,7 @@ class PERFETTO_EXPORT TracingService {
virtual std::unique_ptr<ProducerEndpoint> ConnectProducer(
Producer*,
uid_t uid,
+ pid_t pid,
const std::string& name,
size_t shared_memory_size_hint_bytes = 0,
bool in_process = false,
diff --git a/include/perfetto/profiling/BUILD.gn b/include/perfetto/profiling/BUILD.gn
index e7f9ddfe2..1fd2092a5 100644
--- a/include/perfetto/profiling/BUILD.gn
+++ b/include/perfetto/profiling/BUILD.gn
@@ -15,7 +15,3 @@
source_set("pprof_builder") {
sources = [ "pprof_builder.h" ]
}
-
-source_set("normalize") {
- sources = [ "normalize.h" ]
-}
diff --git a/include/perfetto/profiling/OWNERS b/include/perfetto/profiling/OWNERS
new file mode 100644
index 000000000..276064ee0
--- /dev/null
+++ b/include/perfetto/profiling/OWNERS
@@ -0,0 +1 @@
+file:/src/profiling/OWNERS
diff --git a/include/perfetto/profiling/normalize.h b/include/perfetto/profiling/normalize.h
deleted file mode 100644
index 7b7da1d3c..000000000
--- a/include/perfetto/profiling/normalize.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef INCLUDE_PERFETTO_PROFILING_NORMALIZE_H_
-#define INCLUDE_PERFETTO_PROFILING_NORMALIZE_H_
-
-// Header only code that gets used in other projects.
-// This is currently used in
-// * ART
-// * Bionic
-// * Heapprofd
-//
-// DO NOT USE THE STL HERE. This gets used in parts of Bionic that do not
-// use the STL.
-
-#include <string.h>
-
-namespace perfetto {
-namespace profiling {
-
-// Normalize cmdline in place. Stores new beginning of string in *cmdline_ptr.
-// Returns new size of string (from new beginning).
-// Modifies string in *cmdline_ptr.
-static ssize_t NormalizeCmdLine(char** cmdline_ptr, size_t size) {
- char* cmdline = *cmdline_ptr;
- char* first_arg = static_cast<char*>(memchr(cmdline, '\0', size));
- if (first_arg == nullptr) {
- errno = EOVERFLOW;
- return -1;
- }
- // For consistency with what we do with Java app cmdlines, trim everything
- // after the @ sign of the first arg.
- char* first_at = static_cast<char*>(memchr(cmdline, '@', size));
- if (first_at != nullptr && first_at < first_arg) {
- *first_at = '\0';
- first_arg = first_at;
- }
- char* start = static_cast<char*>(
- memrchr(cmdline, '/', static_cast<size_t>(first_arg - cmdline)));
- if (start == nullptr) {
- start = cmdline;
- } else {
- // Skip the /.
- start++;
- }
- *cmdline_ptr = start;
- return first_arg - start;
-}
-
-} // namespace profiling
-} // namespace perfetto
-
-#endif // INCLUDE_PERFETTO_PROFILING_NORMALIZE_H_
diff --git a/include/perfetto/profiling/parse_smaps.h b/include/perfetto/profiling/parse_smaps.h
index e6c260ccb..9623c3810 100644
--- a/include/perfetto/profiling/parse_smaps.h
+++ b/include/perfetto/profiling/parse_smaps.h
@@ -21,14 +21,13 @@
#ifndef INCLUDE_PERFETTO_PROFILING_PARSE_SMAPS_H_
#define INCLUDE_PERFETTO_PROFILING_PARSE_SMAPS_H_
-#include <string>
-
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-#include <inttypes.h>
+#include <cinttypes>
+#include <string>
namespace perfetto {
namespace profiling {
diff --git a/include/perfetto/protozero/proto_decoder.h b/include/perfetto/protozero/proto_decoder.h
index d23af33c4..c8e46dd27 100644
--- a/include/perfetto/protozero/proto_decoder.h
+++ b/include/perfetto/protozero/proto_decoder.h
@@ -277,12 +277,21 @@ class PackedRepeatedFieldIterator {
// [ field 0 (invalid) ] [ fields 1 .. N ] [ repeated fields ]
// ^ ^
// num_fields_ size_
+// Note that if a message has high field numbers, upon creation |size_| can be
+// < |num_fields_| (until a heap expansion is hit while inserting).
class PERFETTO_EXPORT TypedProtoDecoderBase : public ProtoDecoder {
public:
// If the field |id| is known at compile time, prefer the templated
// specialization at<kFieldNumber>().
const Field& Get(uint32_t id) const {
- return PERFETTO_LIKELY(id < num_fields_) ? fields_[id] : fields_[0];
+ if (PERFETTO_LIKELY(id < num_fields_ && id < size_))
+ return fields_[id];
+ // If id >= num_fields_, the field id is invalid (was not known in the
+ // .proto) and we return the 0th field, which is always !valid().
+ // If id >= size_ and <= num_fields, the id is valid but the field has not
+ // been seen while decoding (hence the stack storage has not been expanded)
+ // so we return the 0th invalid field.
+ return fields_[0];
}
// Returns an object that allows to iterate over all instances of a repeated
@@ -290,8 +299,27 @@ class PERFETTO_EXPORT TypedProtoDecoderBase : public ProtoDecoder {
// for (auto it = decoder.GetRepeated<int32_t>(N); it; ++it) { ... }
template <typename T>
RepeatedFieldIterator<T> GetRepeated(uint32_t field_id) const {
- return RepeatedFieldIterator<T>(field_id, &fields_[num_fields_],
- &fields_[size_], &fields_[field_id]);
+ const Field* repeated_begin;
+ // The storage for repeated fields starts after the slot for the highest
+ // field id (refer to the diagram in the class-level comment). However, if
+ // a message has more than INITIAL_STACK_CAPACITY field there will be no
+ // slots available for the repeated fields (if ExpandHeapStorage() was not
+ // called). Imagine a message that has highest field id = 102 and that is
+ // still using the stack:
+ // [ F0 ] [ F1 ] ... [ F100 ] [ F101 ] [ F1012] [ repeated fields ]
+ // ^ num_fields_
+ // ^ size (== capacity)
+ if (PERFETTO_LIKELY(num_fields_ < size_)) {
+ repeated_begin = &fields_[num_fields_];
+ } else {
+ // This is the case of not having any storage space for repeated fields.
+ // This makes it so begin == end, so the iterator will just skip @ last.
+ repeated_begin = &fields_[size_];
+ }
+ const Field* repeated_end = &fields_[size_];
+ const Field* last = &Get(field_id);
+ return RepeatedFieldIterator<T>(field_id, repeated_begin, repeated_end,
+ last);
}
// Returns an objects that allows to iterate over all entries of a packed
@@ -315,10 +343,9 @@ class PERFETTO_EXPORT TypedProtoDecoderBase : public ProtoDecoder {
if (field.valid()) {
return PackedRepeatedFieldIterator<wire_type, cpp_type>(
field.data(), field.size(), parse_error_location);
- } else {
- return PackedRepeatedFieldIterator<wire_type, cpp_type>(
- nullptr, 0, parse_error_location);
}
+ return PackedRepeatedFieldIterator<wire_type, cpp_type>(
+ nullptr, 0, parse_error_location);
}
protected:
@@ -330,7 +357,10 @@ class PERFETTO_EXPORT TypedProtoDecoderBase : public ProtoDecoder {
: ProtoDecoder(buffer, length),
fields_(storage),
num_fields_(num_fields),
- size_(num_fields),
+ // The reason for "capacity -1" is to avoid hitting the expansion path
+ // in TypedProtoDecoderBase::ParseAllFields() when we are just setting
+ // fields < INITIAL_STACK_CAPACITY (which is the most common case).
+ size_(std::min(num_fields, capacity - 1)),
capacity_(capacity) {
// The reason why Field needs to be trivially de/constructible is to avoid
// implicit initializers on all the ~1000 entries. We need it to initialize
@@ -340,7 +370,8 @@ class PERFETTO_EXPORT TypedProtoDecoderBase : public ProtoDecoder {
std::is_trivially_destructible<Field>::value &&
std::is_trivial<Field>::value,
"Field must be a trivial aggregate type");
- memset(fields_, 0, sizeof(Field) * num_fields_);
+ memset(fields_, 0, sizeof(Field) * capacity_);
+ PERFETTO_DCHECK(capacity > 0);
}
void ParseAllFields();
@@ -358,14 +389,23 @@ class PERFETTO_EXPORT TypedProtoDecoderBase : public ProtoDecoder {
// case of a large number of repeated fields.
Field* fields_;
- // Number of fields without accounting repeated storage. This is equal to
- // MAX_FIELD_ID + 1 (to account for the invalid 0th field).
- // This value is always <= size_ (and hence <= capacity);
+ // Number of known fields, without accounting repeated storage. This is equal
+ // to MAX_FIELD_ID + 1 (to account for the invalid 0th field). It never
+ // changes after construction.
+ // This is unrelated with |size_| and |capacity_|. If the highest field id of
+ // a proto message is 131, |num_fields_| will be = 132 but, on initialization,
+ // |size_| = |capacity_| = 100 (INITIAL_STACK_CAPACITY).
+ // One cannot generally assume that |fields_| has enough storage to
+ // dereference every field. That is only true:
+ // - For field ids < INITIAL_STACK_CAPACITY.
+ // - After the first call to ExpandHeapStorage().
uint32_t num_fields_;
- // Number of active |fields_| entries. This is initially equal to the highest
- // number of fields for the message (num_fields_ == MAX_FIELD_ID + 1) and can
- // grow up to |capacity_| in the case of repeated fields.
+ // Number of active |fields_| entries. This is initially equal to
+ // min(num_fields_, INITIAL_STACK_CAPACITY - 1) and after ExpandHeapStorage()
+ // becomes == |num_fields_|. If the message has non-packed repeated fields, it
+ // can grow further, up to |capacity_|.
+ // |size_| is always <= |capacity_|. But |num_fields_| can be > |size_|.
uint32_t size_;
// Initially equal to kFieldsCapacity of the TypedProtoDecoder
@@ -375,6 +415,11 @@ class PERFETTO_EXPORT TypedProtoDecoderBase : public ProtoDecoder {
uint32_t capacity_;
};
+// This constant is a tradeoff between having a larger stack frame and being
+// able to decode field IDs up to N (or N - num_fields repeated fields) without
+// falling back on the heap.
+#define PROTOZERO_DECODER_INITIAL_STACK_CAPACITY 100
+
// Template class instantiated by the auto-generated decoder classes declared in
// xxx.pbzero.h files.
template <int MAX_FIELD_ID, bool HAS_NONPACKED_REPEATED_FIELDS>
@@ -383,17 +428,25 @@ class TypedProtoDecoder : public TypedProtoDecoderBase {
TypedProtoDecoder(const uint8_t* buffer, size_t length)
: TypedProtoDecoderBase(on_stack_storage_,
/*num_fields=*/MAX_FIELD_ID + 1,
- kCapacity,
+ PROTOZERO_DECODER_INITIAL_STACK_CAPACITY,
buffer,
length) {
- static_assert(MAX_FIELD_ID <= kMaxDecoderFieldId, "Field ordinal too high");
TypedProtoDecoderBase::ParseAllFields();
}
template <uint32_t FIELD_ID>
const Field& at() const {
static_assert(FIELD_ID <= MAX_FIELD_ID, "FIELD_ID > MAX_FIELD_ID");
- return fields_[FIELD_ID];
+ // If the field id is < the on-stack capacity, it's safe to always
+ // dereference |fields_|, whether it's still using the stack or it fell
+ // back on the heap. Because both terms of the if () are known at compile
+ // time, the compiler elides the branch for ids < INITIAL_STACK_CAPACITY.
+ if (FIELD_ID < PROTOZERO_DECODER_INITIAL_STACK_CAPACITY) {
+ return fields_[FIELD_ID];
+ } else {
+ // Otherwise use the slowpath Get() which will do a runtime check.
+ return Get(FIELD_ID);
+ }
}
TypedProtoDecoder(TypedProtoDecoder&& other) noexcept
@@ -408,20 +461,7 @@ class TypedProtoDecoder : public TypedProtoDecoderBase {
}
private:
- // In the case of non-repeated fields, this constant defines the highest field
- // id we are able to decode. This is to limit the on-stack storage.
- // In the case of repeated fields, this constant defines the max number of
- // repeated fields that we'll be able to store before falling back on the
- // heap. Keep this value in sync with the one in protozero_generator.cc.
- static constexpr size_t kMaxDecoderFieldId = 999;
-
- // If we the message has no repeated fields we need at most N Field entries
- // in the on-stack storage, where N is the highest field id.
- // Otherwise we need some room to store repeated fields.
- static constexpr size_t kCapacity =
- 1 + (HAS_NONPACKED_REPEATED_FIELDS ? kMaxDecoderFieldId : MAX_FIELD_ID);
-
- Field on_stack_storage_[kCapacity];
+ Field on_stack_storage_[PROTOZERO_DECODER_INITIAL_STACK_CAPACITY];
};
} // namespace protozero
diff --git a/include/perfetto/protozero/proto_utils.h b/include/perfetto/protozero/proto_utils.h
index 6b195cb1e..fe64da3fe 100644
--- a/include/perfetto/protozero/proto_utils.h
+++ b/include/perfetto/protozero/proto_utils.h
@@ -17,9 +17,9 @@
#ifndef INCLUDE_PERFETTO_PROTOZERO_PROTO_UTILS_H_
#define INCLUDE_PERFETTO_PROTOZERO_PROTO_UTILS_H_
-#include <inttypes.h>
#include <stddef.h>
+#include <cinttypes>
#include <type_traits>
#include "perfetto/base/logging.h"
diff --git a/include/perfetto/public/consumer_api.h b/include/perfetto/public/consumer_api.h
index 0dd86c9bb..1a943669d 100644
--- a/include/perfetto/public/consumer_api.h
+++ b/include/perfetto/public/consumer_api.h
@@ -83,7 +83,7 @@ enum class State {
// either to the kTraceEnded state (if successful) or an error state.
kTracing = 3,
- // Tracing ended succesfully. The trace buffer can now be retrieved through
+ // Tracing ended successfully. The trace buffer can now be retrieved through
// the ReadTrace() call.
// This state is final.
kTraceEnded = 4,
diff --git a/include/perfetto/trace_processor/BUILD.gn b/include/perfetto/trace_processor/BUILD.gn
index ed1f3a948..e6e013114 100644
--- a/include/perfetto/trace_processor/BUILD.gn
+++ b/include/perfetto/trace_processor/BUILD.gn
@@ -16,6 +16,7 @@ source_set("trace_processor") {
sources = [
"iterator.h",
"read_trace.h",
+ "ref_counted.h",
"trace_processor.h",
]
public_deps = [
@@ -25,7 +26,11 @@ source_set("trace_processor") {
}
source_set("storage") {
- sources = [ "trace_processor_storage.h" ]
+ sources = [
+ "trace_blob.h",
+ "trace_blob_view.h",
+ "trace_processor_storage.h",
+ ]
public_deps = [ ":basic_types" ]
}
diff --git a/include/perfetto/trace_processor/OWNERS b/include/perfetto/trace_processor/OWNERS
new file mode 100644
index 000000000..a60c8ec97
--- /dev/null
+++ b/include/perfetto/trace_processor/OWNERS
@@ -0,0 +1 @@
+file:/src/trace_processor/OWNERS
diff --git a/include/perfetto/trace_processor/basic_types.h b/include/perfetto/trace_processor/basic_types.h
index 2b38b6d8e..e4177792c 100644
--- a/include/perfetto/trace_processor/basic_types.h
+++ b/include/perfetto/trace_processor/basic_types.h
@@ -23,23 +23,26 @@
#include <stdint.h>
#include <functional>
#include <string>
+#include <vector>
+#include "perfetto/base/build_config.h"
#include "perfetto/base/export.h"
#include "perfetto/base/logging.h"
namespace perfetto {
namespace trace_processor {
-// Various places in trace processor assume a max number of CPUs to keep code
-// simpler (e.g. use arrays instead of vectors).
-constexpr size_t kMaxCpus = 128;
+// All metrics protos are in this directory. When loading metric extensions, the
+// protos are mounted onto a virtual path inside this directory.
+constexpr char kMetricProtoRoot[] = "protos/perfetto/metrics/";
// Enum which encodes how trace processor should try to sort the ingested data.
+// Note that these options are only applicable to proto traces; other trace
+// types (e.g. JSON, Fuchsia) use full sorts.
enum class SortingMode {
// This option allows trace processor to use built-in heuristics about how to
// sort the data. Generally, this option is correct for most embedders as
- // trace processor reads information from the trace (e.g. TraceConfig) to make
- // the best decision.
+ // trace processor reads information from the trace to make the best decision.
//
// The exact heuristics are implementation details but will ensure that all
// relevant tables are sorted by timestamp.
@@ -53,14 +56,19 @@ enum class SortingMode {
// data to be skipped.
kForceFullSort = 1,
- // This option forces trace processor to use the |flush_period_ms| specified
- // in the TraceConfig to perform a windowed sort of the data. The window size
- // is not guaranteed to be exactly |flush_period_ms| but will be of the same
- // order of magnitude; the exact value is an implementation detail and should
- // not be relied upon.
+ // This option is deprecated in v18; trace processor will ignore it and
+ // use |kDefaultHeuristics|.
//
- // If a |flush_period_ms| is not specified in the TraceConfig, this mode will
- // act the same as |SortingMode::kDefaultHeuristics|.
+ // Rationale for deprecation:
+ // The new windowed sorting logic in trace processor uses a combination of
+ // flush and buffer-read lifecycle events inside the trace instead of
+ // using time-periods from the config.
+ //
+ // Recommended migration:
+ // Users of this option should switch to using |kDefaultHeuristics| which
+ // will act very similarly to the pre-v20 behaviour of this option.
+ //
+ // This option is scheduled to be removed in v21.
kForceFlushPeriodWindowedSort = 2
};
@@ -106,6 +114,10 @@ struct PERFETTO_EXPORT Config {
// the trace before that event. See the ennu documenetation for more details.
DropFtraceDataBefore drop_ftrace_data_before =
DropFtraceDataBefore::kTracingStarted;
+
+ // Any built-in metric proto or sql files matching these paths are skipped
+ // during trace processor metric initialization.
+ std::vector<std::string> skip_builtin_metric_paths;
};
// Represents a dynamically typed value returned by SQL.
diff --git a/include/perfetto/trace_processor/iterator.h b/include/perfetto/trace_processor/iterator.h
index c3373f3b7..95aa4c557 100644
--- a/include/perfetto/trace_processor/iterator.h
+++ b/include/perfetto/trace_processor/iterator.h
@@ -31,6 +31,15 @@ namespace trace_processor {
class IteratorImpl;
// Iterator returning SQL rows satisfied by a query.
+//
+// Example usage:
+// auto sql = "select name, ifnull(cat, "[NULL]") from slice";
+// for (auto it = tp.ExecuteQuery(sql); it.Next();)
+// for (uint32_t i = 0; i < it.ColumnCount(); ++i) {
+// printf("%s ", it.Get(i).AsString());
+// }
+// printf("\n");
+// }
class PERFETTO_EXPORT Iterator {
public:
explicit Iterator(std::unique_ptr<IteratorImpl>);
@@ -40,7 +49,7 @@ class PERFETTO_EXPORT Iterator {
Iterator& operator=(Iterator&) = delete;
Iterator(Iterator&&) noexcept;
- Iterator& operator=(Iterator&&);
+ Iterator& operator=(Iterator&&) noexcept;
// Forwards the iterator to the next result row and returns a boolean of
// whether there is a next row. If this method returns false,
@@ -61,6 +70,19 @@ class PERFETTO_EXPORT Iterator {
// even before calling |Next()|.
uint32_t ColumnCount();
+ // Returns the number of statements in the provided SQL (including the final
+ // statement which is iterated using this iterator). Comments and empty
+ // statements are *not* counted i.e.
+ // "SELECT 1; /* comment */; select 2; -- comment"
+ // returns 2 not 4.
+ uint32_t StatementCount();
+
+ // Returns the number of statements which produced output rows in the provided
+ // SQL (including, potentially, the final statement which is iterated using
+ // this iterator).
+ // This value is guaranteed to be <= |StatementCount()|.
+ uint32_t StatementWithOutputCount();
+
// Returns the status of the iterator.
util::Status Status();
diff --git a/include/perfetto/trace_processor/ref_counted.h b/include/perfetto/trace_processor/ref_counted.h
new file mode 100644
index 000000000..4eb27c994
--- /dev/null
+++ b/include/perfetto/trace_processor/ref_counted.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACE_PROCESSOR_REF_COUNTED_H_
+#define INCLUDE_PERFETTO_TRACE_PROCESSOR_REF_COUNTED_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <memory>
+
+#include "perfetto/base/logging.h"
+
+// A non-thread-safe refcounted implementation.
+// Unlike std::shared_ptr The target class needs to explicitly derive
+// RefCounted.
+
+// Usage:
+// class MyRefcountedThing : public RefCounted {};
+// ...
+// RefPtr<MyRefcountedThing> shareable_ptr(new MyRefcountedThing());
+// auto copy = shareable_ptr;
+
+namespace perfetto {
+namespace trace_processor {
+
+// The base class that refcounted classes should inherit.
+class RefCounted {
+ public:
+ RefCounted() = default;
+ RefCounted(RefCounted&&) noexcept = default;
+ RefCounted& operator=(RefCounted&&) noexcept = default;
+ RefCounted(const RefCounted&) = delete;
+ RefCounted& operator=(const RefCounted&) = delete;
+
+ private:
+ template <typename T>
+ friend class RefPtr;
+
+ void AddRef() const {
+ PERFETTO_DCHECK(refcount_ >= 0);
+ ++refcount_;
+ }
+ bool Release() const {
+ PERFETTO_DCHECK(refcount_ > 0);
+ return --refcount_ == 0;
+ }
+
+ mutable intptr_t refcount_ = 0;
+};
+
+// The RAII smart-pointer.
+template <typename T>
+class RefPtr {
+ public:
+ static_assert(std::is_base_of<RefCounted, T>::value,
+ "T must be a descendant of RefCounted");
+
+ // Adopt a newly created object.
+ RefPtr() : ptr_(nullptr) {}
+ explicit RefPtr(T* ptr) : ptr_(ptr) {
+ if (ptr_)
+ ptr_->AddRef();
+ }
+
+ ~RefPtr() { reset(); }
+
+ void reset() {
+ auto* old_ptr = ptr_;
+ ptr_ = nullptr;
+ if (old_ptr && old_ptr->Release())
+ delete old_ptr;
+ }
+
+ // This case is really the move-assignment operator=(&&).
+ void reset(T* new_obj) { *this = RefPtr<T>(new_obj); }
+
+ // Move operators.
+ RefPtr(RefPtr&& move_from) noexcept {
+ ptr_ = move_from.ptr_;
+ move_from.ptr_ = nullptr;
+ }
+
+ RefPtr& operator=(RefPtr&& move_from) noexcept {
+ this->~RefPtr();
+ new (this) RefPtr(std::move(move_from));
+ return *this;
+ }
+
+ // Copy operators.
+ RefPtr(const RefPtr& copy_from) {
+ ptr_ = copy_from.ptr_;
+ if (ptr_)
+ ptr_->AddRef();
+ }
+
+ RefPtr& operator=(const RefPtr& copy_from) {
+ if (this != &copy_from) {
+ this->~RefPtr();
+ new (this) RefPtr(copy_from);
+ }
+ return *this;
+ }
+
+ template <typename U>
+ bool operator==(const RefPtr<U>& rhs) const {
+ return ptr_ == rhs.ptr_;
+ }
+
+ T* get() const { return ptr_; }
+ T* operator->() const { return ptr_; }
+ T& operator*() const { return *ptr_; }
+ explicit operator bool() const { return ptr_ != nullptr; }
+
+ private:
+ T* ptr_ = nullptr;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_TRACE_PROCESSOR_REF_COUNTED_H_
diff --git a/include/perfetto/trace_processor/trace_blob.h b/include/perfetto/trace_processor/trace_blob.h
new file mode 100644
index 000000000..108bb7aa7
--- /dev/null
+++ b/include/perfetto/trace_processor/trace_blob.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACE_PROCESSOR_TRACE_BLOB_H_
+#define INCLUDE_PERFETTO_TRACE_PROCESSOR_TRACE_BLOB_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <memory>
+#include <utility>
+
+#include "perfetto/base/build_config.h"
+#include "perfetto/base/export.h"
+#include "perfetto/base/logging.h"
+#include "perfetto/trace_processor/ref_counted.h"
+
+// TODO(primiano): implement file mmap on Windows.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+ PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) || \
+ PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#define TRACE_PROCESSOR_HAS_MMAP() 1
+#else
+#define TRACE_PROCESSOR_HAS_MMAP() 0
+#endif
+
+namespace perfetto {
+namespace trace_processor {
+
+// TraceBlob is a move-only buffer that owns a portion of memory containing
+// trace data (not necessarily aligned at trace packet boundaries). Think of
+// this as a std::pair<std::unique_ptr<uint8_t[]>, size_t>.
+// TraceBlob can be instantiated and moved around when it's written/altered
+// by the initial ingestion stages. In this mode, no refcounting is used
+// (i.e. refcount_ is always == 0).
+// When it comes to parsing stages, the TraceBlob can be turned into a read-only
+// object wrapping it in a TraceBlobView. Once wrapped in a TraceBlobView, the
+// TraceBlob becomes refcounted (TBV handles the inc/dec of refcount).
+// TraceBlobView allows to have multiple instances pointing at (different
+// sub-offsets of) the same TraceBlob.
+// The neat thing about TraceBlob is that it deals transparently with owned
+// memory (in the case of Allocate and TakeOwnership) and memory-mapped memory.
+class PERFETTO_EXPORT TraceBlob : public RefCounted {
+ public:
+ static TraceBlob Allocate(size_t size);
+ static TraceBlob CopyFrom(const void*, size_t size);
+ static TraceBlob TakeOwnership(std::unique_ptr<uint8_t[]>, size_t size);
+
+ // Takes ownership of the mmap region. Will call munmap() on destruction.
+ static TraceBlob FromMmap(void* data, size_t size);
+
+ ~TraceBlob();
+
+ // Allow move.
+ TraceBlob(TraceBlob&& other) noexcept { *this = std::move(other); }
+ TraceBlob& operator=(TraceBlob&&) noexcept;
+
+ // Disallow copy.
+ TraceBlob(const TraceBlob&) = delete;
+ TraceBlob& operator=(const TraceBlob&) = delete;
+
+ uint8_t* data() const { return data_; }
+ size_t size() const { return size_; }
+
+ private:
+ enum class Ownership { kNull = 0, kHeapBuf, kMmaped };
+
+ TraceBlob(Ownership ownership, uint8_t* data, size_t size)
+ : ownership_(ownership), data_(data), size_(size) {}
+
+ Ownership ownership_ = Ownership::kNull;
+ uint8_t* data_ = nullptr;
+ size_t size_ = 0;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_TRACE_PROCESSOR_TRACE_BLOB_H_
diff --git a/include/perfetto/trace_processor/trace_blob_view.h b/include/perfetto/trace_processor/trace_blob_view.h
new file mode 100644
index 000000000..884d3a8aa
--- /dev/null
+++ b/include/perfetto/trace_processor/trace_blob_view.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACE_PROCESSOR_TRACE_BLOB_VIEW_H_
+#define INCLUDE_PERFETTO_TRACE_PROCESSOR_TRACE_BLOB_VIEW_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <limits>
+#include <memory>
+
+#include "perfetto/base/logging.h"
+#include "perfetto/trace_processor/ref_counted.h"
+#include "perfetto/trace_processor/trace_blob.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+// A read-only view of a TraceBlob.
+// This class is an equivalent of std::string_view for trace binary data, with
+// a twist: it supports turning a TraceBlob into a refcounted reference. In this
+// case the TraceBlobView acts directly as a shared_ptr, without requiring extra
+// layers of indirection.
+// The underlying TraceBlob will be freed once all the TraceBlobViews that refer
+// to the same buffer have passed through the pipeline and been parsed.
+// The overall idea is that a TraceBlob is passed around until it's written.
+// When writing is done it transforms into a shared refcounted object which is
+// held onto by one or more read-only TraceBlobView instances.
+//
+// In summary:
+// - TraceBlob: writable, move-only, single-instance.
+// - TraceBlobView: readable, copyable, multiple-instances can hold onto
+// (different sub-slices of) the same refcounted TraceBlob.
+class TraceBlobView {
+ public:
+ // Takes ownership of the passed |blob|.
+ static constexpr size_t kWholeBlob = std::numeric_limits<size_t>::max();
+ explicit TraceBlobView(TraceBlob blob,
+ size_t offset = 0,
+ size_t length = kWholeBlob) {
+ PERFETTO_DCHECK(offset <= std::numeric_limits<uint32_t>::max());
+ data_ = blob.data() + offset;
+ if (length == kWholeBlob) {
+ length_ = static_cast<uint32_t>(blob.size() - offset);
+ } else {
+ PERFETTO_DCHECK(length <= std::numeric_limits<uint32_t>::max());
+ PERFETTO_DCHECK(offset + length_ <= blob.size());
+ length_ = static_cast<uint32_t>(length);
+ }
+ blob_.reset(new TraceBlob(std::move(blob)));
+ }
+
+ // Trivial empty ctor.
+ TraceBlobView() : data_(nullptr), length_(0) {}
+
+ ~TraceBlobView() = default;
+
+ // Allow std::move().
+ TraceBlobView(TraceBlobView&& other) noexcept { *this = std::move(other); }
+
+ TraceBlobView& operator=(TraceBlobView&& other) noexcept {
+ data_ = other.data_;
+ length_ = other.length_;
+ blob_ = std::move(other.blob_);
+ return *this;
+ }
+
+ // Disable copy operators. Use x.Copy() to get a copy.
+ TraceBlobView(const TraceBlobView&) = delete;
+ TraceBlobView& operator=(const TraceBlobView&) = delete;
+
+ // [data, data+length] must be <= the current TraceBlobView.
+ TraceBlobView slice(const uint8_t* data, size_t length) const {
+ PERFETTO_DCHECK(data >= data_);
+ PERFETTO_DCHECK(data + length <= data_ + length_);
+ return TraceBlobView(data, static_cast<uint32_t>(length), blob_);
+ }
+
+ // Like slice() but takes an offset rather than a pointer as 1st argument.
+ TraceBlobView slice_off(size_t off, size_t length) const {
+ PERFETTO_DCHECK(off + length <= length_);
+ return TraceBlobView(data_ + off, static_cast<uint32_t>(length), blob_);
+ }
+
+ TraceBlobView copy() const { return slice(data_, length_); }
+
+ bool operator==(const TraceBlobView& rhs) const {
+ return (data_ == rhs.data_) && (length_ == rhs.length_) &&
+ (blob_ == rhs.blob_);
+ }
+ bool operator!=(const TraceBlobView& rhs) const { return !(*this == rhs); }
+
+ const uint8_t* data() const { return data_; }
+ // TODO(primiano): normalize length() vs size() usage.
+ size_t length() const { return length_; }
+ size_t size() const { return length_; }
+
+ private:
+ TraceBlobView(const uint8_t* data, uint32_t length, RefPtr<TraceBlob> blob)
+ : data_(data), length_(length), blob_(std::move(blob)) {}
+
+ const uint8_t* data_ = nullptr;
+ uint32_t length_ = 0;
+ RefPtr<TraceBlob> blob_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_TRACE_PROCESSOR_TRACE_BLOB_VIEW_H_
diff --git a/include/perfetto/trace_processor/trace_processor.h b/include/perfetto/trace_processor/trace_processor.h
index c949695e5..972761d7c 100644
--- a/include/perfetto/trace_processor/trace_processor.h
+++ b/include/perfetto/trace_processor/trace_processor.h
@@ -43,25 +43,38 @@ class PERFETTO_EXPORT TraceProcessor : public TraceProcessorStorage {
~TraceProcessor() override;
- // Executes a SQLite query on the loaded portion of the trace. The returned
- // iterator can be used to load rows from the result.
- virtual Iterator ExecuteQuery(const std::string& sql,
- int64_t time_queued = 0) = 0;
+ // Executes the SQL on the loaded portion of the trace.
+ //
+ // More than one SQL statement can be passed to this function; all but the
+ // last will be fully executed by this function before retuning. The last
+ // statement will be executed and will yield rows as the caller calls Next()
+ // over the returned Iterator.
+ //
+ // See documentation of the Iterator class for an example on how to use
+ // the returned iterator.
+ virtual Iterator ExecuteQuery(const std::string& sql) = 0;
// Registers a metric at the given path which will run the specified SQL.
- virtual util::Status RegisterMetric(const std::string& path,
+ virtual base::Status RegisterMetric(const std::string& path,
const std::string& sql) = 0;
// Reads the FileDescriptorSet proto message given by |data| and |size| and
// adds any extensions to the metrics proto to allow them to be available as
// proto builder functions when computing metrics.
- virtual util::Status ExtendMetricsProto(const uint8_t* data, size_t size) = 0;
+ virtual base::Status ExtendMetricsProto(const uint8_t* data, size_t size) = 0;
+
+ // Behaves exactly as ExtendMetricsProto, except any FileDescriptor with
+ // filename matching a prefix in |skip_prefixes| is skipped.
+ virtual base::Status ExtendMetricsProto(
+ const uint8_t* data,
+ size_t size,
+ const std::vector<std::string>& skip_prefixes) = 0;
// Computes the given metrics on the loded portion of the trace. If
// successful, the output argument |metrics_proto| will be filled with the
// proto-encoded bytes for the message TraceMetrics in
// perfetto/metrics/metrics.proto.
- virtual util::Status ComputeMetric(
+ virtual base::Status ComputeMetric(
const std::vector<std::string>& metric_names,
std::vector<uint8_t>* metrics_proto) = 0;
@@ -73,7 +86,7 @@ class PERFETTO_EXPORT TraceProcessor : public TraceProcessorStorage {
// Computes metrics as the ComputeMetric function above, but instead of
// producing proto encoded bytes, the output argument |metrics_string| is
// filled with the metric formatted in the requested |format|.
- virtual util::Status ComputeMetricText(
+ virtual base::Status ComputeMetricText(
const std::vector<std::string>& metric_names,
MetricResultFormat format,
std::string* metrics_string) = 0;
@@ -103,7 +116,7 @@ class PERFETTO_EXPORT TraceProcessor : public TraceProcessorStorage {
// Disables "meta-tracing" of trace processor and writes the trace as a
// sequence of |TracePackets| into |trace_proto| returning the status of this
// read.
- virtual util::Status DisableAndReadMetatrace(
+ virtual base::Status DisableAndReadMetatrace(
std::vector<uint8_t>* trace_proto) = 0;
// Gets all the currently loaded proto descriptors used in metric computation.
diff --git a/include/perfetto/trace_processor/trace_processor_storage.h b/include/perfetto/trace_processor/trace_processor_storage.h
index 9d27edbdc..82a55d0f0 100644
--- a/include/perfetto/trace_processor/trace_processor_storage.h
+++ b/include/perfetto/trace_processor/trace_processor_storage.h
@@ -24,6 +24,8 @@
#include "perfetto/base/export.h"
#include "perfetto/trace_processor/basic_types.h"
#include "perfetto/trace_processor/status.h"
+#include "perfetto/trace_processor/trace_blob.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
namespace perfetto {
namespace trace_processor {
@@ -43,7 +45,11 @@ class PERFETTO_EXPORT TraceProcessorStorage {
// status if some unrecoverable error happened. If this happens, the
// TraceProcessor will ignore the following Parse() requests, drop data on the
// floor and return errors forever.
- virtual util::Status Parse(std::unique_ptr<uint8_t[]>, size_t) = 0;
+ virtual util::Status Parse(TraceBlobView) = 0;
+
+ // Shorthand for Parse(TraceBlobView(TraceBlob(TakeOwnership(buf, size))).
+ // For compatibility with older API clients.
+ util::Status Parse(std::unique_ptr<uint8_t[]> buf, size_t size);
// When parsing a bounded file (as opposite to streaming from a device) this
// function should be called when the last chunk of the file has been passed
diff --git a/include/perfetto/tracing/BUILD.gn b/include/perfetto/tracing/BUILD.gn
index b7a91d00b..f73dafdae 100644
--- a/include/perfetto/tracing/BUILD.gn
+++ b/include/perfetto/tracing/BUILD.gn
@@ -61,6 +61,7 @@ source_set("tracing") {
"tracing_policy.h",
"track.h",
"track_event.h",
+ "track_event_args.h",
"track_event_category_registry.h",
"track_event_interned_data_index.h",
"track_event_legacy.h",
diff --git a/include/perfetto/tracing/OWNERS b/include/perfetto/tracing/OWNERS
new file mode 100644
index 000000000..a9903d2fc
--- /dev/null
+++ b/include/perfetto/tracing/OWNERS
@@ -0,0 +1 @@
+file:/src/tracing/OWNERS
diff --git a/include/perfetto/tracing/data_source.h b/include/perfetto/tracing/data_source.h
index c4c668143..020708a05 100644
--- a/include/perfetto/tracing/data_source.h
+++ b/include/perfetto/tracing/data_source.h
@@ -129,6 +129,10 @@ struct DefaultDataSourceTraits {
// for when incremental state needs to be cleared. See
// TraceContext::GetIncrementalState().
using IncrementalStateType = void;
+ // |TlsStateType| can optionally be used to store custom per-sequence
+ // session data, which is not reset when incremental state is cleared
+ // (e.g. configuration options).
+ using TlsStateType = void;
// Allows overriding what type of thread-local state configuration the data
// source uses. By default every data source gets independent thread-local
@@ -214,7 +218,7 @@ class DataSource : public DataSourceBase {
// immediately before calling this. The caller is supposed to check for its
// validity before using it. After checking, the handle is guaranteed to
// remain valid until the handle goes out of scope.
- LockedHandle<DataSourceType> GetDataSourceLocked() {
+ LockedHandle<DataSourceType> GetDataSourceLocked() const {
auto* internal_state = static_state_.TryGet(instance_index_);
if (!internal_state)
return LockedHandle<DataSourceType>();
@@ -223,6 +227,13 @@ class DataSource : public DataSourceBase {
static_cast<DataSourceType*>(internal_state->data_source.get()));
}
+ // Post-condition: returned ptr will be non-null.
+ typename DataSourceTraits::TlsStateType* GetCustomTlsState() {
+ PERFETTO_DCHECK(tls_inst_->data_source_custom_tls);
+ return reinterpret_cast<typename DataSourceTraits::TlsStateType*>(
+ tls_inst_->data_source_custom_tls.get());
+ }
+
typename DataSourceTraits::IncrementalStateType* GetIncrementalState() {
// Recreate incremental state data if it has been reset by the service.
if (tls_inst_->incremental_state_generation !=
@@ -387,6 +398,7 @@ class DataSource : public DataSourceBase {
instance_state = static_state_.TryGetCached(instances, i);
if (!instance_state || !instance_state->trace_lambda_enabled)
continue;
+ tls_inst.muxer_id_for_testing = instance_state->muxer_id_for_testing;
tls_inst.backend_id = instance_state->backend_id;
tls_inst.backend_connection_id = instance_state->backend_connection_id;
tls_inst.buffer_id = instance_state->buffer_id;
@@ -397,7 +409,7 @@ class DataSource : public DataSourceBase {
&static_state_, i, instance_state,
DataSourceType::kBufferExhaustedPolicy);
CreateIncrementalState(&tls_inst);
-
+ CreateDataSourceCustomTLS(TraceContext(&tls_inst, i));
// Even in the case of out-of-IDs, SharedMemoryArbiterImpl returns a
// NullTraceWriter. The returned pointer should never be null.
assert(tls_inst.trace_writer);
@@ -434,6 +446,12 @@ class DataSource : public DataSourceBase {
&static_state_);
}
+ // Updates the data source descriptor.
+ static void UpdateDescriptor(const DataSourceDescriptor& descriptor) {
+ auto* tracing_impl = internal::TracingMuxer::Get();
+ tracing_impl->UpdateDataSourceDescriptor(descriptor, &static_state_);
+ }
+
private:
// Traits for customizing the behavior of a specific trace point.
struct DefaultTracePointTraits {
@@ -467,7 +485,7 @@ class DataSource : public DataSourceBase {
static_state_.incremental_state_generation.load(
std::memory_order_relaxed);
tls_inst->incremental_state =
- internal::DataSourceInstanceThreadLocalState::IncrementalStatePointer(
+ internal::DataSourceInstanceThreadLocalState::ObjectWithDeleter(
reinterpret_cast<void*>(new T()),
[](void* p) { delete reinterpret_cast<T*>(p); });
}
@@ -483,6 +501,27 @@ class DataSource : public DataSourceBase {
static_cast<typename DataSourceTraits::IncrementalStateType*>(nullptr));
}
+ // Create the user provided custom tls state in the given TraceContext's
+ // thread-local storage. Note: The second parameter here is used to
+ // specialize the case where there is no incremental state type.
+ template <typename T>
+ static void CreateDataSourceCustomTLSImpl(const TraceContext& trace_context,
+ const T*) {
+ PERFETTO_DCHECK(!trace_context.tls_inst_->data_source_custom_tls);
+ trace_context.tls_inst_->data_source_custom_tls =
+ internal::DataSourceInstanceThreadLocalState::ObjectWithDeleter(
+ reinterpret_cast<void*>(new T(trace_context)),
+ [](void* p) { delete reinterpret_cast<T*>(p); });
+ }
+
+ static void CreateDataSourceCustomTLSImpl(const TraceContext&, const void*) {}
+
+ static void CreateDataSourceCustomTLS(const TraceContext& trace_context) {
+ CreateDataSourceCustomTLSImpl(
+ trace_context,
+ static_cast<typename DataSourceTraits::TlsStateType*>(nullptr));
+ }
+
// Note that the returned object is one per-thread per-data-source-type, NOT
// per data-source *instance*.
static internal::DataSourceThreadLocalState* GetOrCreateDataSourceTLS(
@@ -536,22 +575,7 @@ PERFETTO_THREAD_LOCAL internal::DataSourceThreadLocalState*
#define PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(...) \
template <> \
PERFETTO_COMPONENT_EXPORT perfetto::internal::DataSourceStaticState \
- perfetto::DataSource<__VA_ARGS__>::static_state_; \
- template <> \
- PERFETTO_COMPONENT_EXPORT PERFETTO_THREAD_LOCAL \
- perfetto::internal::DataSourceThreadLocalState* \
- perfetto::DataSource<__VA_ARGS__>::tls_state_
-
-// MSVC has a bug where explicit template member specialization declarations
-// can't have thread_local as the storage class specifier. The generated code
-// seems correct without the specifier, so drop it until the bug gets fixed.
-// See https://developercommunity2.visualstudio.com/t/Unable-to-specialize-
-// static-thread_local/1302689.
-#if PERFETTO_BUILDFLAG(PERFETTO_COMPILER_MSVC)
-#define PERFETTO_TEMPLATE_THREAD_LOCAL
-#else
-#define PERFETTO_TEMPLATE_THREAD_LOCAL PERFETTO_THREAD_LOCAL
-#endif
+ perfetto::DataSource<__VA_ARGS__>::static_state_
// This macro must be used once for each data source in one source file to
// allocate static storage for the data source's static state.
@@ -563,10 +587,6 @@ PERFETTO_THREAD_LOCAL internal::DataSourceThreadLocalState*
#define PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(...) \
template <> \
PERFETTO_COMPONENT_EXPORT perfetto::internal::DataSourceStaticState \
- perfetto::DataSource<__VA_ARGS__>::static_state_{}; \
- template <> \
- PERFETTO_COMPONENT_EXPORT PERFETTO_TEMPLATE_THREAD_LOCAL \
- perfetto::internal::DataSourceThreadLocalState* \
- perfetto::DataSource<__VA_ARGS__>::tls_state_ = nullptr
+ perfetto::DataSource<__VA_ARGS__>::static_state_ {}
#endif // INCLUDE_PERFETTO_TRACING_DATA_SOURCE_H_
diff --git a/include/perfetto/tracing/event_context.h b/include/perfetto/tracing/event_context.h
index 21cb7885d..02120bd67 100644
--- a/include/perfetto/tracing/event_context.h
+++ b/include/perfetto/tracing/event_context.h
@@ -23,6 +23,12 @@
#include "protos/perfetto/trace/trace_packet.pbzero.h"
namespace perfetto {
+namespace protos {
+namespace pbzero {
+class DebugAnnotation;
+} // namespace pbzero
+} // namespace protos
+
namespace internal {
class TrackEventInternal;
}
@@ -31,9 +37,10 @@ class TrackEventInternal;
//
// TRACE_EVENT_BEGIN("category", "Title",
// [](perfetto::EventContext ctx) {
-// auto* dbg = ctx.event()->add_debug_annotations();
-// dbg->set_name("name");
-// dbg->set_int_value(1234);
+// auto* log = ctx.event()->set_log_message();
+// log->set_body_iid(1234);
+//
+// ctx.AddDebugAnnotation("name", 1234);
// });
//
class PERFETTO_EXPORT EventContext {
@@ -49,6 +56,10 @@ class PERFETTO_EXPORT EventContext {
~EventContext();
+ internal::TrackEventIncrementalState* GetIncrementalState() const {
+ return incremental_state_;
+ }
+
// Get a TrackEvent message to write typed arguments to.
//
// event() is a template method to allow callers to specify a subclass of
@@ -72,7 +83,21 @@ class PERFETTO_EXPORT EventContext {
static_assert(std::is_base_of<protozero::Message, MessageType>::value,
"TracedProto can be used only with protozero messages");
- return TracedProto<MessageType>(message, *this);
+ return TracedProto<MessageType>(message, this);
+ }
+
+ // Add a new `debug_annotation` proto message and populate it from |value|
+ // using perfetto::TracedValue API. Users should generally prefer passing
+ // values directly to TRACE_EVENT (i.e. TRACE_EVENT(..., "arg", value, ...);)
+ // but in rare cases (e.g. when an argument should be written conditionally)
+ // EventContext::AddDebugAnnotation provides an explicit equivalent.
+ template <typename T>
+ void AddDebugAnnotation(const char* name, T&& value) {
+ if (tls_state_ && tls_state_->filter_debug_annotations)
+ return;
+ auto annotation = AddDebugAnnotation(name);
+ WriteIntoTracedValue(internal::CreateTracedValueFromProto(annotation, this),
+ std::forward<T>(value));
}
private:
@@ -83,12 +108,20 @@ class PERFETTO_EXPORT EventContext {
using TracePacketHandle =
::protozero::MessageHandle<protos::pbzero::TracePacket>;
- EventContext(TracePacketHandle, internal::TrackEventIncrementalState*);
+ EventContext(TracePacketHandle,
+ internal::TrackEventIncrementalState*,
+ const internal::TrackEventTlsState*);
EventContext(const EventContext&) = delete;
+ protos::pbzero::DebugAnnotation* AddDebugAnnotation(const char* name);
+
TracePacketHandle trace_packet_;
protos::pbzero::TrackEvent* event_;
internal::TrackEventIncrementalState* incremental_state_;
+ // TODO(mohitms): Make it const-reference instead of pointer, once we
+ // are certain that it cannot be nullptr. Once we switch to client library in
+ // chrome, we can make that happen.
+ const internal::TrackEventTlsState* tls_state_ = nullptr;
};
} // namespace perfetto
diff --git a/include/perfetto/tracing/internal/data_source_internal.h b/include/perfetto/tracing/internal/data_source_internal.h
index cb052c64d..2be191aa9 100644
--- a/include/perfetto/tracing/internal/data_source_internal.h
+++ b/include/perfetto/tracing/internal/data_source_internal.h
@@ -61,6 +61,10 @@ struct DataSourceState {
// doing extra pointr arithmetic.
bool trace_lambda_enabled = false;
+ // The overall TracingMuxerImpl instance id, which gets incremented by
+ // ResetForTesting.
+ uint32_t muxer_id_for_testing = 0;
+
// The central buffer id that all TraceWriter(s) created by this data source
// must target.
BufferId buffer_id = 0;
@@ -114,6 +118,9 @@ struct DataSourceStateStorage {
// Per-DataSource-type global state.
struct DataSourceStaticState {
+ // System-wide unique id of the data source.
+ uint64_t id = 0;
+
// Unique index of the data source, assigned at registration time.
uint32_t index = kMaxDataSources;
@@ -145,11 +152,12 @@ struct DataSourceStaticState {
// Per-DataSource-instance thread-local state.
struct DataSourceInstanceThreadLocalState {
- using IncrementalStatePointer = std::unique_ptr<void, void (*)(void*)>;
void Reset() {
trace_writer.reset();
incremental_state.reset();
+ data_source_custom_tls.reset();
+ muxer_id_for_testing = 0;
backend_id = 0;
backend_connection_id = 0;
buffer_id = 0;
@@ -159,8 +167,11 @@ struct DataSourceInstanceThreadLocalState {
}
std::unique_ptr<TraceWriterBase> trace_writer;
- IncrementalStatePointer incremental_state = {nullptr, [](void*) {}};
+ using ObjectWithDeleter = std::unique_ptr<void, void (*)(void*)>;
+ ObjectWithDeleter incremental_state = {nullptr, [](void*) {}};
+ ObjectWithDeleter data_source_custom_tls = {nullptr, [](void*) {}};
uint32_t incremental_state_generation;
+ uint32_t muxer_id_for_testing;
TracingBackendId backend_id;
uint32_t backend_connection_id;
BufferId buffer_id;
diff --git a/include/perfetto/tracing/internal/tracing_muxer.h b/include/perfetto/tracing/internal/tracing_muxer.h
index a0b464cc2..bef7191f3 100644
--- a/include/perfetto/tracing/internal/tracing_muxer.h
+++ b/include/perfetto/tracing/internal/tracing_muxer.h
@@ -64,6 +64,10 @@ class PERFETTO_EXPORT TracingMuxer {
DataSourceFactory,
DataSourceStaticState*) = 0;
+ // Updates the DataSourceDescriptor for the DataSource.
+ virtual void UpdateDataSourceDescriptor(const DataSourceDescriptor&,
+ const DataSourceStaticState*) = 0;
+
// It identifies the right backend and forwards the call to it.
// The returned TraceWriter must be used within the same sequence (for most
// projects this means "same thread"). Alternatively the client needs to take
diff --git a/include/perfetto/tracing/internal/tracing_tls.h b/include/perfetto/tracing/internal/tracing_tls.h
index 68515a4b1..b2340a4d7 100644
--- a/include/perfetto/tracing/internal/tracing_tls.h
+++ b/include/perfetto/tracing/internal/tracing_tls.h
@@ -77,6 +77,8 @@ class TracingTLS : public Platform::ThreadLocalObject {
// This flag is true while this thread is inside a trace point for any data
// source or in other delicate parts of the tracing machinery during which we
// should not try to trace. Used to prevent unexpected re-entrancy.
+ // This flag is also load-bearing when handling re-entrancy during thread-exit
+ // handlers. See comment in TracingTLS::~TracingTLS().
bool is_in_trace_point = false;
// By default all data source instances have independent thread-local state
diff --git a/include/perfetto/tracing/internal/track_event_data_source.h b/include/perfetto/tracing/internal/track_event_data_source.h
index 12a5a85df..69cc958c7 100644
--- a/include/perfetto/tracing/internal/track_event_data_source.h
+++ b/include/perfetto/tracing/internal/track_event_data_source.h
@@ -35,19 +35,16 @@
namespace perfetto {
-struct TraceTimestamp {
- protos::pbzero::BuiltinClock clock_id;
- uint64_t nanoseconds;
-};
-
-// This template provides a way to convert an abstract timestamp into the trace
-// clock timebase in nanoseconds. By specialising this template and defining
+// A function for converting an abstract timestamp into a
+// perfetto::TraceTimestamp struct. By specialising this template and defining
// static ConvertTimestampToTraceTimeNs function in it the user can register
-// additional timestamp types. The return value should specify the clock used by
-// the timestamp as well as its value in nanoseconds.
+// additional timestamp types. The return value should specify the
+// clock domain used by the timestamp as well as its value.
//
-// The users should see the specialisation for uint64_t below as an example.
-// Note that the specialisation should be defined in perfetto namespace.
+// The supported clock domains are the ones described in
+// perfetto.protos.ClockSnapshot. However, custom clock IDs (>=64) are
+// reserved for internal use by the SDK for the time being.
+// The timestamp value should be in nanoseconds regardless of the clock domain.
template <typename T>
struct TraceTimestampTraits;
@@ -56,7 +53,16 @@ template <>
struct TraceTimestampTraits<uint64_t> {
static inline TraceTimestamp ConvertTimestampToTraceTimeNs(
const uint64_t& timestamp) {
- return {internal::TrackEventInternal::GetClockId(), timestamp};
+ return {static_cast<uint32_t>(internal::TrackEventInternal::GetClockId()), timestamp};
+ }
+};
+
+// A pass-through implementation for the trace timestamp structure.
+template <>
+struct TraceTimestampTraits<TraceTimestamp> {
+ static inline TraceTimestamp ConvertTimestampToTraceTimeNs(
+ const TraceTimestamp& timestamp) {
+ return timestamp;
}
};
@@ -131,6 +137,7 @@ struct CategoryTraits<size_t> {
struct TrackEventDataSourceTraits : public perfetto::DefaultDataSourceTraits {
using IncrementalStateType = TrackEventIncrementalState;
+ using TlsStateType = TrackEventTlsState;
// Use a one shared TLS slot so that all track event data sources write into
// the same sequence and share interning dictionaries.
@@ -150,7 +157,7 @@ class TrackEventDataSource
public:
// Add or remove a session observer for this track event data source. The
// observer will be notified about started and stopped tracing sessions.
- // Returns |true| if the observer was succesfully added (i.e., the maximum
+ // Returns |true| if the observer was successfully added (i.e., the maximum
// number of observers wasn't exceeded).
static bool AddSessionObserver(TrackEventSessionObserver* observer) {
return TrackEventInternal::AddSessionObserver(observer);
@@ -235,7 +242,7 @@ class TrackEventDataSource
Arguments&&... args) PERFETTO_NO_INLINE {
TraceForCategoryImpl(instances, category, event_name, type,
TrackEventInternal::kDefaultTrack,
- TrackEventInternal::GetTimeNs(),
+ TrackEventInternal::GetTraceTime(),
std::forward<Arguments>(args)...);
}
@@ -257,7 +264,7 @@ class TrackEventDataSource
Arguments&&... args) PERFETTO_NO_INLINE {
TraceForCategoryImpl(
instances, category, event_name, type, std::forward<TrackType>(track),
- TrackEventInternal::GetTimeNs(), std::forward<Arguments>(args)...);
+ TrackEventInternal::GetTraceTime(), std::forward<Arguments>(args)...);
}
// Trace point which takes a timestamp, but not track.
@@ -310,7 +317,7 @@ class TrackEventDataSource
ValueType value) PERFETTO_ALWAYS_INLINE {
PERFETTO_DCHECK(type == perfetto::protos::pbzero::TrackEvent::TYPE_COUNTER);
TraceForCategory(instances, category, /*name=*/nullptr, type, track,
- TrackEventInternal::GetTimeNs(), value);
+ TrackEventInternal::GetTraceTime(), value);
}
// Trace point with with a timestamp and a counter sample.
@@ -331,7 +338,19 @@ class TrackEventDataSource
instances, category, /*name=*/nullptr, type, track, timestamp,
[&](EventContext event_ctx) {
if (std::is_integral<ValueType>::value) {
- event_ctx.event()->set_counter_value(static_cast<int64_t>(value));
+ int64_t value_int64 = static_cast<int64_t>(value);
+ if (track.is_incremental()) {
+ TrackEventIncrementalState* incr_state =
+ event_ctx.GetIncrementalState();
+ PERFETTO_DCHECK(incr_state != nullptr);
+ auto prv_value =
+ incr_state->last_counter_value_per_track[track.uuid];
+ event_ctx.event()->set_counter_value(value_int64 - prv_value);
+ prv_value = value_int64;
+ incr_state->last_counter_value_per_track[track.uuid] = prv_value;
+ } else {
+ event_ctx.event()->set_counter_value(value_int64);
+ }
} else {
event_ctx.event()->set_double_counter_value(
static_cast<double>(value));
@@ -356,7 +375,8 @@ class TrackEventDataSource
TrackRegistry::Get()->UpdateTrack(track, desc.SerializeAsString());
Base::template Trace([&](typename Base::TraceContext ctx) {
TrackEventInternal::WriteTrackDescriptor(
- track, ctx.tls_inst_->trace_writer.get());
+ track, ctx.tls_inst_->trace_writer.get(), ctx.GetIncrementalState(),
+ *ctx.GetCustomTlsState(), TrackEventInternal::GetTraceTime());
});
}
@@ -395,6 +415,8 @@ class TrackEventDataSource
return TrackEventInternal::GetClockId();
}
+ const protos::gen::TrackEventConfig& GetConfig() const { return config_; }
+
private:
// Each category has its own enabled/disabled state, stored in the category
// registry.
@@ -440,32 +462,27 @@ class TrackEventDataSource
return;
}
- // TODO(skyostil): Support additional clock ids.
+ const TrackEventTlsState& tls_state = *ctx.GetCustomTlsState();
TraceTimestamp trace_timestamp = ::perfetto::TraceTimestampTraits<
TimestampType>::ConvertTimestampToTraceTimeNs(timestamp);
- PERFETTO_DCHECK(trace_timestamp.clock_id ==
- TrackEventInternal::GetClockId());
- // Make sure incremental state is valid.
TraceWriterBase* trace_writer = ctx.tls_inst_->trace_writer.get();
+ // Make sure incremental state is valid.
TrackEventIncrementalState* incr_state = ctx.GetIncrementalState();
- if (incr_state->was_cleared) {
- incr_state->was_cleared = false;
- TrackEventInternal::ResetIncrementalState(
- trace_writer, trace_timestamp.nanoseconds);
- }
+ TrackEventInternal::ResetIncrementalStateIfRequired(
+ trace_writer, incr_state, tls_state, trace_timestamp);
// Write the track descriptor before any event on the track.
if (track) {
TrackEventInternal::WriteTrackDescriptorIfNeeded(
- track, trace_writer, incr_state);
+ track, trace_writer, incr_state, tls_state, trace_timestamp);
}
// Write the event itself.
{
auto event_ctx = TrackEventInternal::WriteEvent(
- trace_writer, incr_state, static_category, event_name, type,
- trace_timestamp.nanoseconds);
+ trace_writer, incr_state, tls_state, static_category,
+ event_name, type, trace_timestamp);
// Write dynamic categories (except for events that don't require
// categories). For counter events, the counter name (and optional
// category) is stored as part of the track descriptor instead being
@@ -512,7 +529,8 @@ class TrackEventDataSource
TrackRegistry::Get()->UpdateTrack(track, std::move(callback));
Base::template Trace([&](typename Base::TraceContext ctx) {
TrackEventInternal::WriteTrackDescriptor(
- track, ctx.tls_inst_->trace_writer.get());
+ track, ctx.tls_inst_->trace_writer.get(), ctx.GetIncrementalState(),
+ *ctx.GetCustomTlsState(), TrackEventInternal::GetTraceTime());
});
}
diff --git a/include/perfetto/tracing/internal/track_event_internal.h b/include/perfetto/tracing/internal/track_event_internal.h
index d29303988..dc3a617ff 100644
--- a/include/perfetto/tracing/internal/track_event_internal.h
+++ b/include/perfetto/tracing/internal/track_event_internal.h
@@ -32,9 +32,27 @@
#include <unordered_map>
namespace perfetto {
+
+// Represents a point in time for the clock specified by |clock_id|.
+struct TraceTimestamp {
+ // Clock IDs have the following semantic:
+ // [1, 63]: Builtin types, see BuiltinClock from
+ // ../common/builtin_clock.proto.
+ // [64, 127]: User-defined clocks. These clocks are sequence-scoped. They
+ // are only valid within the same |trusted_packet_sequence_id|
+ // (i.e. only for TracePacket(s) emitted by the same TraceWriter
+ // that emitted the clock snapshot).
+ // [128, MAX]: Reserved for future use. The idea is to allow global clock
+ // IDs and setting this ID to hash(full_clock_name) & ~127.
+ // Learn more: `clock_snapshot.proto`
+ uint32_t clock_id;
+ uint64_t value;
+};
+
class EventContext;
class TrackEventSessionObserver;
struct Category;
+struct TraceTimestamp;
namespace protos {
namespace gen {
class TrackEventConfig;
@@ -75,9 +93,29 @@ class PERFETTO_EXPORT BaseTrackEventInternedDataIndex {
#endif // PERFETTO_DCHECK_IS_ON()
};
+struct TrackEventTlsState {
+ template <typename TraceContext>
+ explicit TrackEventTlsState(const TraceContext& trace_context) {
+ auto locked_ds = trace_context.GetDataSourceLocked();
+ if (locked_ds.valid()) {
+ const auto& config = locked_ds->GetConfig();
+ disable_incremental_timestamps = config.disable_incremental_timestamps();
+ filter_debug_annotations = config.filter_debug_annotations();
+ }
+ }
+ bool disable_incremental_timestamps = false;
+ bool filter_debug_annotations = false;
+};
+
struct TrackEventIncrementalState {
static constexpr size_t kMaxInternedDataFields = 32;
+ // Packet-sequence-scoped clock that encodes microsecond timestamps in the
+ // domain of the clock returned by GetClockId() as delta values - see
+ // Clock::is_incremental in perfetto/trace/clock_snapshot.proto.
+ // Default unit: nanoseconds.
+ static constexpr uint32_t kClockIdIncremental = 64;
+
bool was_cleared = true;
// A heap-allocated message for storing newly seen interned data while we are
@@ -109,6 +147,16 @@ struct TrackEventIncrementalState {
// this tracing session. The value in the map indicates whether the category
// is enabled or disabled.
std::unordered_map<std::string, bool> dynamic_categories;
+
+ // The latest reference timestamp that was used in a TracePacket or in a
+ // ClockSnapshot. The increment between this timestamp and the current trace
+ // time (GetTimeNs) is a value in kClockIdIncremental's domain.
+ uint64_t last_timestamp_ns = 0;
+
+ // The latest known counter values that was used in a TracePacket for each
+ // counter track. The key (uint64_t) is the uuid of counter track.
+ // The value is used for delta encoding of counter values.
+ std::unordered_map<uint64_t, int64_t> last_counter_value_per_track;
};
// The backend portion of the track event trace point implemention. Outlined to
@@ -136,20 +184,33 @@ class PERFETTO_EXPORT TrackEventInternal {
static perfetto::EventContext WriteEvent(
TraceWriterBase*,
TrackEventIncrementalState*,
+ const TrackEventTlsState& tls_state,
const Category* category,
const char* name,
perfetto::protos::pbzero::TrackEvent::Type,
- uint64_t timestamp = GetTimeNs());
+ const TraceTimestamp& timestamp);
- static void ResetIncrementalState(TraceWriterBase*, uint64_t timestamp);
+ static void ResetIncrementalStateIfRequired(
+ TraceWriterBase* trace_writer,
+ TrackEventIncrementalState* incr_state,
+ const TrackEventTlsState& tls_state,
+ const TraceTimestamp& timestamp) {
+ if (incr_state->was_cleared) {
+ incr_state->was_cleared = false;
+ ResetIncrementalState(trace_writer, incr_state, tls_state, timestamp);
+ }
+ }
+ // TODO(altimin): Remove this method once Chrome uses
+ // EventContext::AddDebugAnnotation directly.
template <typename T>
static void AddDebugAnnotation(perfetto::EventContext* event_ctx,
const char* name,
T&& value) {
auto annotation = AddDebugAnnotation(event_ctx, name);
- WriteIntoTracedValue(internal::CreateTracedValueFromProto(annotation),
- std::forward<T>(value));
+ WriteIntoTracedValue(
+ internal::CreateTracedValueFromProto(annotation, event_ctx),
+ std::forward<T>(value));
}
// If the given track hasn't been seen by the trace writer yet, write a
@@ -159,24 +220,33 @@ class PERFETTO_EXPORT TrackEventInternal {
static void WriteTrackDescriptorIfNeeded(
const TrackType& track,
TraceWriterBase* trace_writer,
- TrackEventIncrementalState* incr_state) {
+ TrackEventIncrementalState* incr_state,
+ const TrackEventTlsState& tls_state,
+ const TraceTimestamp& timestamp) {
auto it_and_inserted = incr_state->seen_tracks.insert(track.uuid);
if (PERFETTO_LIKELY(!it_and_inserted.second))
return;
- WriteTrackDescriptor(track, trace_writer);
+ WriteTrackDescriptor(track, trace_writer, incr_state, tls_state, timestamp);
}
// Unconditionally write a track descriptor into the trace.
template <typename TrackType>
static void WriteTrackDescriptor(const TrackType& track,
- TraceWriterBase* trace_writer) {
+ TraceWriterBase* trace_writer,
+ TrackEventIncrementalState* incr_state,
+ const TrackEventTlsState& tls_state,
+ const TraceTimestamp& timestamp) {
+ ResetIncrementalStateIfRequired(trace_writer, incr_state, tls_state,
+ timestamp);
TrackRegistry::Get()->SerializeTrack(
- track, NewTracePacket(trace_writer, GetTimeNs()));
+ track, NewTracePacket(trace_writer, incr_state, tls_state, timestamp));
}
// Get the current time in nanoseconds in the trace clock timebase.
static uint64_t GetTimeNs();
+ static TraceTimestamp GetTraceTime();
+
// Get the clock used by GetTimeNs().
static constexpr protos::pbzero::BuiltinClock GetClockId() {
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) && \
@@ -193,9 +263,16 @@ class PERFETTO_EXPORT TrackEventInternal {
static const Track kDefaultTrack;
private:
+ static void ResetIncrementalState(TraceWriterBase* trace_writer,
+ TrackEventIncrementalState* incr_state,
+ const TrackEventTlsState& tls_state,
+ const TraceTimestamp& timestamp);
+
static protozero::MessageHandle<protos::pbzero::TracePacket> NewTracePacket(
TraceWriterBase*,
- uint64_t timestamp,
+ TrackEventIncrementalState*,
+ const TrackEventTlsState& tls_state,
+ TraceTimestamp,
uint32_t seq_flags =
protos::pbzero::TracePacket::SEQ_NEEDS_INCREMENTAL_STATE);
static protos::pbzero::DebugAnnotation* AddDebugAnnotation(
diff --git a/include/perfetto/tracing/internal/track_event_interned_fields.h b/include/perfetto/tracing/internal/track_event_interned_fields.h
index 81bfd9800..50e337001 100644
--- a/include/perfetto/tracing/internal/track_event_interned_fields.h
+++ b/include/perfetto/tracing/internal/track_event_interned_fields.h
@@ -68,6 +68,20 @@ struct PERFETTO_EXPORT InternedDebugAnnotationName
const char* value);
};
+struct PERFETTO_EXPORT InternedDebugAnnotationValueTypeName
+ : public TrackEventInternedDataIndex<
+ InternedDebugAnnotationValueTypeName,
+ perfetto::protos::pbzero::InternedData::
+ kDebugAnnotationValueTypeNamesFieldNumber,
+ const char*,
+ SmallInternedDataTraits> {
+ ~InternedDebugAnnotationValueTypeName() override;
+
+ static void Add(protos::pbzero::InternedData* interned_data,
+ size_t iid,
+ const char* value);
+};
+
} // namespace internal
} // namespace perfetto
diff --git a/include/perfetto/tracing/internal/track_event_macros.h b/include/perfetto/tracing/internal/track_event_macros.h
index 0c7ffb778..05dd5af8b 100644
--- a/include/perfetto/tracing/internal/track_event_macros.h
+++ b/include/perfetto/tracing/internal/track_event_macros.h
@@ -59,11 +59,15 @@
/* variable), we need two separate copies of the registry with different */ \
/* storage specifiers. */ \
/**/ \
+ /* Note that because of a Clang/Windows bug, the constexpr category */ \
+ /* registry isn't given the enabled/disabled state array. All access */ \
+ /* to the category states should therefore be done through the */ \
+ /* non-constexpr registry. See */ \
+ /* https://bugs.llvm.org/show_bug.cgi?id=51558 */ \
+ /**/ \
/* TODO(skyostil): Unify these using a C++17 inline constexpr variable. */ \
constexpr ::perfetto::internal::TrackEventCategoryRegistry \
- kConstExprCategoryRegistry(kCategoryCount, \
- &kCategories[0], \
- &g_category_state_storage[0]); \
+ kConstExprCategoryRegistry(kCategoryCount, &kCategories[0], nullptr); \
PERFETTO_COMPONENT_EXPORT extern const ::perfetto::internal:: \
TrackEventCategoryRegistry kCategoryRegistry; \
static_assert(kConstExprCategoryRegistry.ValidateCategories(), \
@@ -83,10 +87,17 @@
} // namespace internal
// Defines the TrackEvent data source for the current track event namespace.
+// `virtual ~TrackEvent` is added to avoid `-Wweak-vtables` warning.
+// Learn more : aosp/2019906
#define PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE() \
struct PERFETTO_COMPONENT_EXPORT TrackEvent \
: public ::perfetto::internal::TrackEventDataSource< \
- TrackEvent, &internal::kCategoryRegistry> {}
+ TrackEvent, &internal::kCategoryRegistry> { \
+ virtual ~TrackEvent(); \
+ }
+
+#define PERFETTO_INTERNAL_DEFINE_TRACK_EVENT_DATA_SOURCE() \
+ TrackEvent::~TrackEvent() = default;
// At compile time, turns a category name represented by a static string into an
// index into the current category registry. A build error will be generated if
@@ -158,4 +169,22 @@
: ::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::IsCategoryEnabled( \
PERFETTO_GET_CATEGORY_INDEX(category)))
+// Emits an empty trace packet into the trace to ensure that the service can
+// safely read the last event from the trace buffer. This can be used to
+// periodically "flush" the last event on threads that don't support explicit
+// flushing of the shared memory buffer chunk when the tracing session stops
+// (e.g. thread pool workers in Chromium).
+//
+// This workaround is only required because the tracing service cannot safely
+// read the last trace packet from an incomplete SMB chunk (crbug.com/1021571
+// and b/162206162) when scraping the SMB. Adding an empty trace packet ensures
+// that all prior events can be scraped by the service.
+#define PERFETTO_INTERNAL_ADD_EMPTY_EVENT() \
+ do { \
+ ::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::Trace( \
+ [](::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::TraceContext ctx) { \
+ ctx.NewTracePacket(); \
+ }); \
+ } while (false)
+
#endif // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_MACROS_H_
diff --git a/include/perfetto/tracing/internal/write_track_event_args.h b/include/perfetto/tracing/internal/write_track_event_args.h
index 2f848784d..ba6c4e8e8 100644
--- a/include/perfetto/tracing/internal/write_track_event_args.h
+++ b/include/perfetto/tracing/internal/write_track_event_args.h
@@ -20,23 +20,12 @@
#include "perfetto/base/compiler.h"
#include "perfetto/tracing/event_context.h"
#include "perfetto/tracing/traced_proto.h"
+#include "perfetto/tracing/track_event_args.h"
namespace perfetto {
namespace internal {
-// Helper function handling filling provided |EventContext| from the provided
-// arguments, which include:
-// - Lambda functions,
-// - Debug annotations.
-//
-// TRACE_EVENT parameters which do not translate to directly writing something
-// into TrackEvent proto (like tracks and timestamps are _not_ covered by this
-// function).
-template <typename... Args, typename TypeCheck = void>
-void WriteTrackEventArgs(EventContext event_context, Args&&... args);
-
// No arguments means that we don't have to write anything.
-template <>
PERFETTO_ALWAYS_INLINE inline void WriteTrackEventArgs(EventContext) {}
namespace {
@@ -66,11 +55,28 @@ static constexpr bool IsValidTraceLambda() {
return IsValidTraceLambdaImpl<T>(nullptr);
}
+template <typename T>
+static constexpr bool IsValidTraceLambdaTakingReferenceImpl(
+ typename std::enable_if<static_cast<bool>(
+ sizeof(std::declval<T>()(std::declval<EventContext&>()), 0))>::type* =
+ nullptr) {
+ return true;
+}
+
+template <typename T>
+static constexpr bool IsValidTraceLambdaTakingReferenceImpl(...) {
+ return false;
+}
+
+template <typename T>
+static constexpr bool IsValidTraceLambdaTakingReference() {
+ return IsValidTraceLambdaTakingReferenceImpl<T>(nullptr);
+}
+
} // namespace
-// Write a lambda.
-// TODO(altimin): At the moment lambda takes EventContext, which is
-// non-copyable, so only one lambda is supported and it has to be the last
+// Write an old-style lambda taking an EventContext (without a reference)
+// as it will consume EventContext via std::move, it can only be the last
// argument.
template <typename ArgumentFunction,
typename ArgFunctionCheck = typename std::enable_if<
@@ -80,39 +86,66 @@ PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(EventContext event_ctx,
arg_function(std::move(event_ctx));
}
-// Write one debug annotation and recursively write the rest of the arguments.
+// Forward-declare the specification for writing untyped arguments to ensure
+// that typed specification could recursively pick it up.
template <typename ArgValue, typename... Args>
PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(EventContext event_ctx,
const char* arg_name,
ArgValue&& arg_value,
+ Args&&... args);
+
+template <typename FieldMetadataType, typename ArgValue, typename... Args>
+PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(
+ EventContext event_ctx,
+ protozero::proto_utils::internal::FieldMetadataHelper<FieldMetadataType>
+ field_name,
+ ArgValue&& arg_value,
+ Args&&... args);
+
+template <typename ArgumentFunction,
+ typename... Args,
+ typename ArgFunctionCheck = typename std::enable_if<
+ IsValidTraceLambdaTakingReference<ArgumentFunction>()>::type>
+PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(EventContext event_ctx,
+ ArgumentFunction arg_function,
Args&&... args) {
- TrackEventInternal::AddDebugAnnotation(&event_ctx, arg_name,
- std::forward<ArgValue>(arg_value));
+ // |arg_function| will capture EventContext by reference, so std::move isn't
+ // needed.
+ arg_function(event_ctx);
+
WriteTrackEventArgs(std::move(event_ctx), std::forward<Args>(args)...);
}
// Write one typed message and recursively write the rest of the arguments.
-template <typename FieldMetadataType,
- typename ArgValue,
- typename... Args,
- typename Check = base::enable_if_t<
- std::is_base_of<protozero::proto_utils::FieldMetadataBase,
- FieldMetadataType>::value>>
+template <typename FieldMetadataType, typename ArgValue, typename... Args>
PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(
EventContext event_ctx,
protozero::proto_utils::internal::FieldMetadataHelper<FieldMetadataType>
field_name,
ArgValue&& arg_value,
Args&&... args) {
+ static_assert(std::is_base_of<protozero::proto_utils::FieldMetadataBase,
+ FieldMetadataType>::value,
+ "");
static_assert(
std::is_base_of<protos::pbzero::TrackEvent,
typename FieldMetadataType::message_type>::value,
"Only fields of TrackEvent (and TrackEvent's extensions) can "
"be passed to TRACE_EVENT");
- WriteIntoTracedProto(
- event_ctx.Wrap(
- event_ctx.event<typename FieldMetadataType::message_type>()),
- field_name, std::forward<ArgValue>(arg_value));
+ auto track_event_proto = event_ctx.Wrap(
+ event_ctx.event<typename FieldMetadataType::message_type>());
+ WriteTracedProtoField(track_event_proto, field_name,
+ std::forward<ArgValue>(arg_value));
+ WriteTrackEventArgs(std::move(event_ctx), std::forward<Args>(args)...);
+}
+
+// Write one debug annotation and recursively write the rest of the arguments.
+template <typename ArgValue, typename... Args>
+PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(EventContext event_ctx,
+ const char* arg_name,
+ ArgValue&& arg_value,
+ Args&&... args) {
+ event_ctx.AddDebugAnnotation(arg_name, std::forward<ArgValue>(arg_value));
WriteTrackEventArgs(std::move(event_ctx), std::forward<Args>(args)...);
}
diff --git a/include/perfetto/tracing/platform.h b/include/perfetto/tracing/platform.h
index ecd74d929..f54f056af 100644
--- a/include/perfetto/tracing/platform.h
+++ b/include/perfetto/tracing/platform.h
@@ -25,6 +25,9 @@
#include <string>
#include "perfetto/base/export.h"
+#include "perfetto/base/logging.h"
+#include "perfetto/base/proc_utils.h"
+#include "perfetto/tracing/tracing.h"
namespace perfetto {
@@ -56,6 +59,23 @@ class PERFETTO_EXPORT Platform {
// to use its own base class for TLS).
static Platform* GetDefaultPlatform();
+ // Embedders can call this to set process ID in those cases where getpid()
+ // returns incorrect values (e.g. for sandboxed processes in Chromium).
+ // Should only be called once, before tracing has been initialized.
+ static void SetCurrentProcessId(base::PlatformProcessId process_id) {
+ PERFETTO_CHECK(!process_id_);
+ PERFETTO_DCHECK(!Tracing::IsInitialized());
+ process_id_ = process_id;
+ }
+
+ // Returns process ID previously set by SetCurrentProcessId, or the process
+ // ID provided by the OS if no custom ID was provided.
+ static base::PlatformProcessId GetCurrentProcessId() {
+ if (process_id_)
+ return process_id_;
+ return base::GetProcessId();
+ }
+
virtual ~Platform();
// Creates a thread-local object. The embedder must:
@@ -70,7 +90,12 @@ class PERFETTO_EXPORT Platform {
// Creates a sequenced task runner. The easiest implementation is to create
// a new thread (e.g. use base::ThreadTaskRunner) but this can also be
// implemented in some more clever way (e.g. using chromiums's scheduler).
- struct CreateTaskRunnerArgs {};
+ struct CreateTaskRunnerArgs {
+ // Optional. Sets the name to the newly created task runner. In the default
+ // PosixPlatform implementation this causes a pthread_setname_np(). This is
+ // only for ease of debugging, it does not affect the tracing behavior.
+ std::string name_for_debugging;
+ };
virtual std::unique_ptr<base::TaskRunner> CreateTaskRunner(
const CreateTaskRunnerArgs&) = 0;
@@ -78,6 +103,9 @@ class PERFETTO_EXPORT Platform {
// kSystemBackend mode. It can be an arbitrary string when using the
// in-process mode.
virtual std::string GetCurrentProcessName() = 0;
+
+ private:
+ static base::PlatformProcessId process_id_;
};
} // namespace perfetto
diff --git a/include/perfetto/tracing/traced_proto.h b/include/perfetto/tracing/traced_proto.h
index 44e4fb2d3..042b96eab 100644
--- a/include/perfetto/tracing/traced_proto.h
+++ b/include/perfetto/tracing/traced_proto.h
@@ -20,9 +20,16 @@
#include "perfetto/base/template_util.h"
#include "perfetto/protozero/field_writer.h"
#include "perfetto/protozero/proto_utils.h"
+#include "perfetto/tracing/traced_value.h"
namespace perfetto {
class EventContext;
+namespace internal {
+template <typename FieldMetadata,
+ bool is_message,
+ protozero::proto_utils::RepetitionType repetition_type>
+struct TypedProtoWriterImpl;
+}
// A Wrapper around a protozero message to allow C++ classes to specify how it
// should be serialised into the trace:
@@ -45,34 +52,276 @@ class EventContext;
// TracedValue::WriteProto<T>() or implicitly.
// - If a proto message has a repeating DebugAnnotation debug_annotations
// field, it can be filled using the TracedDictionary obtained from
-// TracedProto::WriteDebugAnnotations.
+// TracedProto::AddDebugAnnotations.
template <typename MessageType>
class TracedProto {
public:
+ // implicit
+ TracedProto(TracedValue&& value)
+ : TracedProto(std::move(value).WriteProto<MessageType>()) {}
+ ~TracedProto() = default;
+
TracedProto(const TracedProto&) = delete;
TracedProto& operator=(const TracedProto&) = delete;
TracedProto& operator=(TracedProto&&) = delete;
TracedProto(TracedProto&&) = default;
- ~TracedProto() = default;
MessageType* operator->() const { return message_; }
MessageType* message() { return message_; }
- EventContext& context() const { return context_; }
+ // Write additional untyped values into the same context, which is useful
+ // when a given C++ class has a typed representation, but also either has
+ // members which can only be written into an untyped context (e.g. they are
+ // autogenerated) or it's desirable to have a way to quickly extend the
+ // trace representation of this class (e.g. for debugging).
+ //
+ // The usage of the returned TracedDictionary should not be interleaved with
+ // writing into |message| as this results in an inefficient proto layout. To
+ // enforce this, AddDebugAnnotations should be called on TracedProto&&, i.e.
+ // std::move(message).AddDebugAnnotations().
+ //
+ // This requires a 'repeated DebugAnnotations debug_annotations' field in
+ // MessageType.
+ template <typename Check = void>
+ TracedDictionary AddDebugAnnotations() && {
+ static_assert(
+ std::is_base_of<
+ protozero::proto_utils::FieldMetadataBase,
+ typename MessageType::FieldMetadata_DebugAnnotations>::value,
+ "This message does not have a |debug_annotations| field. Please add a"
+ "'repeated perfetto.protos.DebugAnnotation debug_annnotations = N;' "
+ "field to your message.");
+ return TracedDictionary(message_, MessageType::kDebugAnnotations, context_,
+ nullptr);
+ }
+
+ // Start writing a single entry corresponding to the given |field| and return
+ // TracedProto should be used to populate this further.
+ // This method requires |field|'s type to be a nested message, but both
+ // repeated and non-repeated complex fields are supported.
+ template <typename FieldMetadata>
+ TracedProto<typename FieldMetadata::cpp_field_type> WriteNestedMessage(
+ protozero::proto_utils::internal::FieldMetadataHelper<FieldMetadata>) {
+ static_assert(std::is_base_of<MessageType,
+ typename FieldMetadata::message_type>::value,
+ "Field should belong to the current message");
+ static_assert(
+ FieldMetadata::kProtoFieldType ==
+ protozero::proto_utils::ProtoSchemaType::kMessage,
+ "AddItem() can be used only for nested message fields. To write a "
+ "primitive field, use traced_proto->set_field() or traced_proto.Set()");
+ return Wrap(
+ message_->template BeginNestedMessage<
+ typename FieldMetadata::cpp_field_type>(FieldMetadata::kFieldId));
+ }
+
+ // Write a given |value| into proto as a new |field| of the current message.
+ // This method supports both nested messages and primitive types (i.e. int or
+ // string), but requires the |field| to be non-repeateable (i.e. optional).
+ // For repeatable fields, AppendValue or AppendFrom should be used.
+ template <typename FieldMetadata, typename ValueType>
+ void Set(protozero::proto_utils::internal::FieldMetadataHelper<FieldMetadata>,
+ ValueType&& value) {
+ static_assert(std::is_base_of<MessageType,
+ typename FieldMetadata::message_type>::value,
+ "Field should belong to the current message");
+ static_assert(
+ FieldMetadata::kRepetitionType ==
+ protozero::proto_utils::RepetitionType::kNotRepeated,
+ "Set() can't be used with repeated fields due to ambiguity between "
+ "writing |value| as a single entry or treating |value| as a container "
+ "and writing all contained items as multiple entries. Please use "
+ "dedicated AppendValue() or AppendFrom() methods to differentiate "
+ "between "
+ "these two situations");
+
+ internal::TypedProtoWriterImpl<
+ FieldMetadata,
+ FieldMetadata::kProtoFieldType ==
+ protozero::proto_utils::ProtoSchemaType::kMessage,
+ protozero::proto_utils::RepetitionType::kNotRepeated>::
+ Write(*this, std::forward<ValueType>(value));
+ }
+
+ // Write a given |value| a single entry into the repeated |field| of the
+ // current message. If the field is not repeated, Set() should be used
+ // instead.
+ template <typename FieldMetadata, typename ValueType>
+ void AppendValue(
+ protozero::proto_utils::internal::FieldMetadataHelper<FieldMetadata>,
+ ValueType&& value) {
+ static_assert(std::is_base_of<MessageType,
+ typename FieldMetadata::message_type>::value,
+ "Field should belong to the current message");
+ static_assert(
+ FieldMetadata::kRepetitionType ==
+ protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+ "Append*() methods can be used only with repeated fields. "
+ "Please use Set() for non-repeated");
+
+ // Write a single value into a given repeated field by explicitly passing
+ // "kNotRepeated" to the TypedProtoWriterImpl.
+ internal::TypedProtoWriterImpl<
+ FieldMetadata,
+ FieldMetadata::kProtoFieldType ==
+ protozero::proto_utils::ProtoSchemaType::kMessage,
+ protozero::proto_utils::RepetitionType::kNotRepeated>::
+ Write(*this, std::forward<ValueType>(value));
+ }
+
+ // Write a given |value| as a set of entries into the repeated |field| of the
+ // current message. If the field is not repeated, Set() should be used
+ // instead.
+ template <typename FieldMetadata, typename ValueType>
+ void AppendFrom(
+ protozero::proto_utils::internal::FieldMetadataHelper<FieldMetadata>,
+ ValueType&& value) {
+ static_assert(std::is_base_of<MessageType,
+ typename FieldMetadata::message_type>::value,
+ "Field should belong to the current message");
+ static_assert(
+ FieldMetadata::kRepetitionType ==
+ protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+ "Append*() methods can be used only with repeated fields. "
+ "Please use Set() for non-repeated");
+
+ internal::TypedProtoWriterImpl<
+ FieldMetadata,
+ FieldMetadata::kProtoFieldType ==
+ protozero::proto_utils::ProtoSchemaType::kMessage,
+ protozero::proto_utils::RepetitionType::kRepeatedNotPacked>::
+ Write(*this, std::forward<ValueType>(value));
+ }
+
+ // Write a nested message into a field according to the provided metadata.
+ // TODO(altimin): Replace the current usages in Chrome with the functions
+ // above and make these methods private.
+ template <typename FieldMetadata>
+ TracedProto<typename FieldMetadata::cpp_field_type> WriteNestedMessage() {
+ return WriteNestedMessage(
+ protozero::proto_utils::internal::FieldMetadataHelper<FieldMetadata>());
+ }
private:
friend class EventContext;
+ friend class TracedValue;
+ // Allow TracedProto<Foo> to create TracedProto<Bar>.
+ template <typename T>
+ friend class TracedProto;
- TracedProto(MessageType* message, EventContext& context)
+ // Wraps a raw protozero message using the same context as the current object.
+ template <typename ChildMessageType>
+ TracedProto<ChildMessageType> Wrap(ChildMessageType* message) {
+ return TracedProto<ChildMessageType>(message, context_);
+ }
+
+ // Context might be null here when writing typed message which is
+ // nested into untyped legacy trace event macro argument.
+ // TODO(altimin): Turn this into EventContext& when this case is eliminated
+ // and expose it in public API.
+ EventContext* context() const { return context_; }
+
+ TracedProto(MessageType* message, EventContext* context)
: message_(message), context_(context) {}
MessageType* const message_;
- EventContext& context_;
+ EventContext* context_;
};
+template <typename MessageType, typename ValueType>
+void WriteIntoTracedProto(TracedProto<MessageType> message, ValueType&& value);
+
namespace internal {
+template <typename FieldMetadata,
+ bool is_message,
+ protozero::proto_utils::RepetitionType repetition_type>
+struct TypedProtoWriterImpl;
+
+// Simple non-repeated field.
+template <typename FieldMetadata>
+struct TypedProtoWriterImpl<
+ FieldMetadata,
+ /*is_message=*/false,
+ protozero::proto_utils::RepetitionType::kNotRepeated> {
+ template <typename Proto, typename ValueType>
+ static void Write(TracedProto<Proto>& context, ValueType&& value) {
+ protozero::internal::FieldWriter<FieldMetadata::kProtoFieldType>::Append(
+ *context.message(), FieldMetadata::kFieldId, value);
+ }
+};
+
+// Simple repeated non-packed field.
+template <typename FieldMetadata>
+struct TypedProtoWriterImpl<
+ FieldMetadata,
+ /*is_message=*/false,
+ protozero::proto_utils::RepetitionType::kRepeatedNotPacked> {
+ template <typename Proto, typename ValueType>
+ static void Write(TracedProto<Proto>& context, ValueType&& value) {
+ for (auto&& item : value) {
+ protozero::internal::FieldWriter<FieldMetadata::kProtoFieldType>::Append(
+ *context.message(), FieldMetadata::kFieldId, item);
+ }
+ }
+};
+
+// Nested repeated non-packed field.
+template <typename FieldMetadata>
+struct TypedProtoWriterImpl<
+ FieldMetadata,
+ /*is_message=*/true,
+ protozero::proto_utils::RepetitionType::kNotRepeated> {
+ template <typename Proto, typename ValueType>
+ static void Write(TracedProto<Proto>& context, ValueType&& value) {
+ WriteIntoTracedProto(context.template WriteNestedMessage<FieldMetadata>(),
+ std::forward<ValueType>(value));
+ }
+};
+
+// Nested repeated non-packed field.
+template <typename FieldMetadata>
+struct TypedProtoWriterImpl<
+ FieldMetadata,
+ /*is_message=*/true,
+ protozero::proto_utils::RepetitionType::kRepeatedNotPacked> {
+ template <typename Proto, typename ValueType>
+ static void Write(TracedProto<Proto>& context, ValueType&& value) {
+ for (auto&& item : value) {
+ WriteIntoTracedProto(context.template WriteNestedMessage<FieldMetadata>(),
+ item);
+ }
+ }
+};
+
+constexpr int kMaxWriteTracedProtoImplPriority = 1;
+
+// If perfetto::TraceFormatTraits<T>::WriteIntoTrace(TracedProto<MessageType>,
+// T) is available, use it.
+template <typename MessageType, typename T>
+decltype(TraceFormatTraits<base::remove_cvref_t<T>>::WriteIntoTrace(
+ std::declval<TracedProto<MessageType>>(),
+ std::declval<T>()),
+ void())
+WriteIntoTracedProtoImpl(base::priority_tag<1>,
+ TracedProto<MessageType> message,
+ T&& value) {
+ TraceFormatTraits<base::remove_cvref_t<T>>::WriteIntoTrace(
+ std::move(message), std::forward<T>(value));
+}
+
+// If T has WriteIntoTrace(TracedProto<MessageType>) method, use it.
+template <typename MessageType, typename T>
+decltype(
+ std::declval<T>().WriteIntoTrace(std::declval<TracedProto<MessageType>>()),
+ void())
+WriteIntoTracedProtoImpl(base::priority_tag<0>,
+ TracedProto<MessageType> message,
+ T&& value) {
+ value.WriteIntoTrace(std::move(message));
+}
+
// TypedProtoWriter takes the protozero message (TracedProto<MessageType>),
// field description (FieldMetadata) and value and writes the given value
// into the given field of the given protozero message.
@@ -93,74 +342,67 @@ struct TypedProtoWriter {
RepetitionType::kRepeatedPacked,
"writing packed fields isn't supported yet");
+ template <bool is_message, RepetitionType repetition_type>
+ struct Writer;
+
public:
- // Implementation note: typename Check=void is used to ensure that SFINAE
- // kicks in and the methods which do not match FieldMetadata do not fail
- // to compile. std::is_same<Check,void> prevents early evaluation of the
- // first enable_if_t argument.
-
- // Simple non-repeated field.
- template <typename Proto, typename ValueType, typename Check = void>
- static typename base::enable_if_t<
- FieldMetadata::kProtoFieldType != ProtoSchemaType::kMessage &&
- FieldMetadata::kRepetitionType == RepetitionType::kNotRepeated &&
- std::is_same<Check, void>::value>
- Write(TracedProto<Proto> context, ValueType&& value) {
- protozero::internal::FieldWriter<FieldMetadata::kProtoFieldType>::Append(
- *context.message(), FieldMetadata::kFieldId, value);
+ template <typename Proto, typename ValueType>
+ static void Write(TracedProto<Proto>& context, ValueType&& value) {
+ TypedProtoWriterImpl<
+ FieldMetadata,
+ FieldMetadata::kProtoFieldType == ProtoSchemaType::kMessage,
+ FieldMetadata::kRepetitionType>::Write(context,
+ std::forward<ValueType>(value));
}
+};
- // Simple repeated non-packed field.
- template <typename Proto, typename ValueType, typename Check = void>
- static typename base::enable_if_t<
- FieldMetadata::kProtoFieldType != ProtoSchemaType::kMessage &&
- FieldMetadata::kRepetitionType == RepetitionType::kRepeatedNotPacked &&
- std::is_same<Check, void>::value>
- Write(TracedProto<Proto> context, ValueType&& value) {
- for (auto&& item : value) {
- protozero::internal::FieldWriter<FieldMetadata::kProtoFieldType>::Append(
- *context.message(), FieldMetadata::kFieldId, item);
- }
- }
+} // namespace internal
- // Nested non-repeated field.
- template <typename Proto, typename ValueType, typename Check = void>
- static typename base::enable_if_t<
- FieldMetadata::kProtoFieldType == ProtoSchemaType::kMessage &&
- FieldMetadata::kRepetitionType == RepetitionType::kNotRepeated &&
- std::is_same<Check, void>::value>
- Write(TracedProto<Proto> context, ValueType&& value) {
- // TODO(altimin): support TraceFormatTraits here.
- value.WriteIntoTrace(
- context.context().Wrap(context.message()
- ->template BeginNestedMessage<
- typename FieldMetadata::cpp_field_type>(
- FieldMetadata::kFieldId)));
- }
+// Helper template to determine if a given type can be passed to
+// perfetto::WriteIntoTracedProto. These templates will fail to resolve if the
+// class does not have necesary support, so they are useful for SFINAE and for
+// producing helpful compiler error messages.
+template <typename MessageType, typename ValueType, typename Result = void>
+using check_traced_proto_support_t =
+ decltype(internal::WriteIntoTracedProtoImpl(
+ std::declval<
+ base::priority_tag<internal::kMaxWriteTracedProtoImplPriority>>(),
+ std::declval<TracedProto<MessageType>>(),
+ std::declval<ValueType>()));
- // Nested repeated non-packed field.
- template <typename Proto, typename ValueType, typename Check = void>
- static typename base::enable_if_t<
- FieldMetadata::kProtoFieldType == ProtoSchemaType::kMessage &&
- FieldMetadata::kRepetitionType == RepetitionType::kRepeatedNotPacked &&
- std::is_same<Check, void>::value>
- Write(TracedProto<Proto> context, ValueType&& value) {
- // TODO(altimin): support TraceFormatTraits here.
- for (auto&& item : value) {
- item.WriteIntoTrace(context.context().Wrap(
- context.message()
- ->template BeginNestedMessage<
- typename FieldMetadata::cpp_field_type>(
- FieldMetadata::kFieldId)));
- }
- }
+// check_traced_proto_support<MessageType, T, V>::type is defined (and equal to
+// V) iff T supports being passed to WriteIntoTracedProto together with
+// TracedProto<MessageType>. See the comment in traced_value_forward.h for more
+// details.
+template <typename MessageType, typename ValueType, class Result>
+struct check_traced_proto_support<
+ MessageType,
+ ValueType,
+ Result,
+ check_traced_proto_support_t<MessageType, ValueType, Result>> {
+ static constexpr bool value = true;
+ using type = Result;
};
-} // namespace internal
+template <typename MessageType, typename ValueType>
+void WriteIntoTracedProto(TracedProto<MessageType> message, ValueType&& value) {
+ // TODO(altimin): Add a URL to the documentation and a list of common failure
+ // patterns.
+ static_assert(
+ std::is_same<check_traced_proto_support_t<MessageType, ValueType>,
+ void>::value,
+ "The provided type does not support being serialised into the "
+ "provided protozero message. Please see the comment in traced_proto.h "
+ "for more details.");
+
+ internal::WriteIntoTracedProtoImpl(
+ base::priority_tag<internal::kMaxWriteTracedProtoImplPriority>(),
+ std::move(message), std::forward<ValueType>(value));
+}
template <typename MessageType, typename FieldMetadataType, typename ValueType>
-void WriteIntoTracedProto(
- TracedProto<MessageType> message,
+void WriteTracedProtoField(
+ TracedProto<MessageType>& message,
protozero::proto_utils::internal::FieldMetadataHelper<FieldMetadataType>,
ValueType&& value) {
static_assert(
@@ -173,7 +415,7 @@ void WriteIntoTracedProto(
"Field's parent type should match the context.");
internal::TypedProtoWriter<FieldMetadataType>::Write(
- std::move(message), std::forward<ValueType>(value));
+ message, std::forward<ValueType>(value));
}
} // namespace perfetto
diff --git a/include/perfetto/tracing/traced_value.h b/include/perfetto/tracing/traced_value.h
index b1a14d31e..cb659bc07 100644
--- a/include/perfetto/tracing/traced_value.h
+++ b/include/perfetto/tracing/traced_value.h
@@ -20,6 +20,8 @@
#include "perfetto/base/compiler.h"
#include "perfetto/base/export.h"
#include "perfetto/base/template_util.h"
+#include "perfetto/protozero/message.h"
+#include "perfetto/protozero/proto_utils.h"
#include "perfetto/tracing/internal/checked_scope.h"
#include "perfetto/tracing/string_helpers.h"
#include "perfetto/tracing/traced_value_forward.h"
@@ -37,6 +39,7 @@ class DebugAnnotation;
} // namespace protos
class DebugAnnotation;
+class EventContext;
// These classes provide a JSON-inspired way to write structed data into traces.
//
@@ -114,8 +117,12 @@ class DebugAnnotation;
// }
// }
namespace internal {
+// TODO(altimin): Currently EventContext can be null due the need to support
+// TracedValue-based serialisation with the Chrome's TraceLog. After this is
+// gone, the second parameter should be changed to EventContext&.
PERFETTO_EXPORT TracedValue
-CreateTracedValueFromProto(protos::pbzero::DebugAnnotation*);
+CreateTracedValueFromProto(protos::pbzero::DebugAnnotation*,
+ EventContext* = nullptr);
}
class PERFETTO_EXPORT TracedValue {
@@ -123,8 +130,8 @@ class PERFETTO_EXPORT TracedValue {
TracedValue(const TracedValue&) = delete;
TracedValue& operator=(const TracedValue&) = delete;
TracedValue& operator=(TracedValue&&) = delete;
- TracedValue(TracedValue&&) = default;
- ~TracedValue() = default;
+ TracedValue(TracedValue&&);
+ ~TracedValue();
// TracedValue represents a context into which a single value can be written
// (either by writing it directly for primitive types, or by creating a
@@ -139,6 +146,8 @@ class PERFETTO_EXPORT TracedValue {
void WriteString(const char*, size_t len) &&;
void WriteString(const std::string&) &&;
void WritePointer(const void* value) &&;
+ template <typename MessageType>
+ TracedProto<MessageType> WriteProto() &&;
// Rules for writing nested dictionaries and arrays:
// - Only one scope (TracedArray, TracedDictionary or TracedValue) can be
@@ -162,26 +171,44 @@ class PERFETTO_EXPORT TracedValue {
friend class TracedArray;
friend class TracedDictionary;
friend TracedValue internal::CreateTracedValueFromProto(
- protos::pbzero::DebugAnnotation*);
+ protos::pbzero::DebugAnnotation*,
+ EventContext*);
- static TracedValue CreateFromProto(protos::pbzero::DebugAnnotation*);
+ static TracedValue CreateFromProto(protos::pbzero::DebugAnnotation* proto,
+ EventContext* event_context = nullptr);
- inline explicit TracedValue(protos::pbzero::DebugAnnotation* context,
+ inline explicit TracedValue(protos::pbzero::DebugAnnotation* annotation,
+ EventContext* event_context,
internal::CheckedScope* parent_scope)
- : context_(context), checked_scope_(parent_scope) {}
+ : annotation_(annotation),
+ event_context_(event_context),
+ checked_scope_(parent_scope) {}
+
+ protozero::Message* WriteProtoInternal(const char* name);
// Temporary support for perfetto::DebugAnnotation C++ class before it's going
// to be replaced by TracedValue.
// TODO(altimin): Convert v8 to use TracedValue directly and delete it.
friend class DebugAnnotation;
- protos::pbzero::DebugAnnotation* const context_ = nullptr;
+ protos::pbzero::DebugAnnotation* const annotation_ = nullptr;
+ EventContext* const event_context_ = nullptr;
internal::CheckedScope checked_scope_;
};
+template <typename MessageType>
+TracedProto<MessageType> TracedValue::WriteProto() && {
+ return TracedProto<MessageType>(
+ static_cast<MessageType*>(WriteProtoInternal(MessageType::GetName())),
+ event_context_);
+}
+
class PERFETTO_EXPORT TracedArray {
public:
+ // implicit
+ TracedArray(TracedValue);
+
TracedArray(const TracedArray&) = delete;
TracedArray& operator=(const TracedArray&) = delete;
TracedArray& operator=(TracedArray&&) = delete;
@@ -201,17 +228,24 @@ class PERFETTO_EXPORT TracedArray {
private:
friend class TracedValue;
- inline explicit TracedArray(protos::pbzero::DebugAnnotation* context,
+ inline explicit TracedArray(protos::pbzero::DebugAnnotation* annotation,
+ EventContext* event_context,
internal::CheckedScope* parent_scope)
- : context_(context), checked_scope_(parent_scope) {}
+ : annotation_(annotation),
+ event_context_(event_context),
+ checked_scope_(parent_scope) {}
- protos::pbzero::DebugAnnotation* context_;
+ protos::pbzero::DebugAnnotation* annotation_;
+ EventContext* const event_context_;
internal::CheckedScope checked_scope_;
};
class PERFETTO_EXPORT TracedDictionary {
public:
+ // implicit
+ TracedDictionary(TracedValue);
+
TracedDictionary(const TracedDictionary&) = delete;
TracedDictionary& operator=(const TracedDictionary&) = delete;
TracedDictionary& operator=(TracedDictionary&&) = delete;
@@ -246,12 +280,42 @@ class PERFETTO_EXPORT TracedDictionary {
private:
friend class TracedValue;
+ template <typename T>
+ friend class TracedProto;
+
+ // Create a |TracedDictionary| which will populate the given field of the
+ // given |message|.
+ template <typename MessageType, typename FieldMetadata>
+ inline explicit TracedDictionary(
+ MessageType* message,
+ protozero::proto_utils::internal::FieldMetadataHelper<FieldMetadata>,
+ EventContext* event_context,
+ internal::CheckedScope* parent_scope)
+ : message_(message),
+ field_id_(FieldMetadata::kFieldId),
+ event_context_(event_context),
+ checked_scope_(parent_scope) {
+ static_assert(std::is_base_of<protozero::Message, MessageType>::value,
+ "Message should be a subclass of protozero::Message");
+ static_assert(std::is_base_of<protozero::proto_utils::FieldMetadataBase,
+ FieldMetadata>::value,
+ "FieldMetadata should be a subclass of FieldMetadataBase");
+ static_assert(
+ std::is_same<typename FieldMetadata::message_type, MessageType>::value,
+ "Field does not belong to this message");
+ static_assert(
+ std::is_same<typename FieldMetadata::cpp_field_type,
+ ::perfetto::protos::pbzero::DebugAnnotation>::value,
+ "Field should be of DebugAnnotation type");
+ static_assert(
+ FieldMetadata::kRepetitionType ==
+ protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+ "Field should be non-packed repeated");
+ }
- inline explicit TracedDictionary(protos::pbzero::DebugAnnotation* context,
- internal::CheckedScope* parent_scope)
- : context_(context), checked_scope_(parent_scope) {}
-
- protos::pbzero::DebugAnnotation* context_;
+ protozero::Message* const message_;
+ const uint32_t field_id_;
+ EventContext* event_context_;
internal::CheckedScope checked_scope_;
};
@@ -570,6 +634,12 @@ struct TraceFormatTraits<std::unique_ptr<T>, check_traced_value_support_t<T>> {
const std::unique_ptr<T>& value) {
::perfetto::WriteIntoTracedValue(std::move(context), value.get());
}
+
+ template <typename MessageType>
+ inline static void WriteIntoTrace(TracedProto<MessageType> message,
+ const std::unique_ptr<T>& value) {
+ ::perfetto::WriteIntoTracedProto(std::move(message), value.get());
+ }
};
// Specialisation for raw pointer, which writes either nullptr or the object it
@@ -583,6 +653,18 @@ struct TraceFormatTraits<T*, check_traced_value_support_t<T>> {
}
::perfetto::WriteIntoTracedValue(std::move(context), *value);
}
+
+ template <typename MessageType>
+ inline static void WriteIntoTrace(TracedProto<MessageType> message,
+ T* value) {
+ if (!value) {
+ // Start the message, but do not write anything. TraceProcessor will emit
+ // a NULL value.
+ return;
+ }
+
+ ::perfetto::WriteIntoTracedProto(std::move(message), *value);
+ }
};
// Specialisation for nullptr.
@@ -591,6 +673,12 @@ struct TraceFormatTraits<std::nullptr_t> {
inline static void WriteIntoTrace(TracedValue context, std::nullptr_t) {
std::move(context).WritePointer(nullptr);
}
+
+ template <typename MessageType>
+ inline static void WriteIntoTrace(TracedProto<MessageType>, std::nullptr_t) {
+ // Start the message, but do not write anything. TraceProcessor will emit a
+ // NULL value.
+ }
};
} // namespace perfetto
diff --git a/include/perfetto/tracing/traced_value_forward.h b/include/perfetto/tracing/traced_value_forward.h
index 7a91712d8..ee009f96a 100644
--- a/include/perfetto/tracing/traced_value_forward.h
+++ b/include/perfetto/tracing/traced_value_forward.h
@@ -22,31 +22,53 @@ namespace perfetto {
class TracedValue;
class TracedArray;
class TracedDictionary;
+template <typename MessageType>
+class TracedProto;
template <typename T>
void WriteIntoTracedValue(TracedValue context, T&& value);
+template <typename MessageType, typename T>
+void WriteIntoTracedProto(TracedProto<MessageType> context, T&& value);
template <typename T, class = void>
struct TraceFormatTraits;
-// Write support checker to allow it to be used when matching.
+// Helpers to check whether a given type T can be written into a TracedValue /
+// TracedProto<MessageType>.
//
// Intended to be used for types like smart pointers, who should support
-// AsTracedValueInto only iff their inner type supports being written into
+// WriteIntoTrace only iff their inner type supports being written into
// a TracedValue.
//
// template <typename T>
// class SmartPtr {
// ...
//
-// typename check_traced_value_support<T, void>::value
-// AsTracedValueInto(perfetto::TracedValue context) const {
+// // Note: |Check| is needed to ensure that using
+// SmartPtr<ClassWhichDoesNotSupportTracedValue> does not generate a
+// compilation error.
+//
+// template <typename Check=void>
+// typename check_traced_value_support<T, Check>::value
+// WriteIntoTrace(perfetto::TracedValue context) const {
// WriteIntoTracedValue(std::move(context), *ptr_);
// }
+//
+// template <typename MessageType>
+// typename check_traced_value_support<T, MessageType>::value
+// WriteIntoTrace(perfetto::TracedProto<MessageType> message) const {
+// WriteIntoTracedProto(std::move(message), *ptr_);
+// }
// };
-template <typename T, typename ResultType = void, class = void>
+template <typename T, typename ResultType = void, typename = void>
struct check_traced_value_support;
+template <typename MessageType,
+ typename T,
+ typename ResultType = void,
+ typename = void>
+struct check_traced_proto_support;
+
} // namespace perfetto
#endif // INCLUDE_PERFETTO_TRACING_TRACED_VALUE_FORWARD_H_
diff --git a/include/perfetto/tracing/tracing.h b/include/perfetto/tracing/tracing.h
index 8a688f27f..9aae9e8fe 100644
--- a/include/perfetto/tracing/tracing.h
+++ b/include/perfetto/tracing/tracing.h
@@ -177,6 +177,11 @@ class PERFETTO_EXPORT Tracing {
static std::unique_ptr<TracingSession> NewTrace(
BackendType = kUnspecifiedBackend);
+ // Uninitialize Perfetto. Only exposed for testing scenarios where it can be
+ // guaranteed that no tracing sessions or other operations are happening when
+ // this call is made.
+ static void ResetForTesting();
+
private:
static void InitializeInternal(const TracingInitArgs&);
diff --git a/include/perfetto/tracing/track.h b/include/perfetto/tracing/track.h
index 0ff225d69..1ddb85edc 100644
--- a/include/perfetto/tracing/track.h
+++ b/include/perfetto/tracing/track.h
@@ -23,6 +23,7 @@
#include "perfetto/protozero/message_handle.h"
#include "perfetto/protozero/scattered_heap_buffer.h"
#include "perfetto/tracing/internal/compile_time_hash.h"
+#include "perfetto/tracing/platform.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
#include "protos/perfetto/trace/track_event/counter_descriptor.pbzero.h"
#include "protos/perfetto/trace/track_event/track_descriptor.gen.h"
@@ -36,6 +37,8 @@ namespace perfetto {
namespace internal {
class TrackRegistry;
}
+class Flow;
+class TerminatingFlow;
// Track events are recorded on a timeline track, which maintains the relative
// time ordering of all events on that track. Each thread has its own default
@@ -104,13 +107,23 @@ struct PERFETTO_EXPORT Track {
static Track FromPointer(const void* ptr, Track parent = MakeProcessTrack()) {
// Using pointers as global TrackIds isn't supported as pointers are
// per-proccess and the same pointer value can be used in different
- // processes.
+ // processes. If you hit this check but are providing no |parent| track,
+ // verify that Tracing::Initialize() was called for the current process.
PERFETTO_DCHECK(parent.uuid != Track().uuid);
return Track(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(ptr)),
parent);
}
+ // Construct a track using |ptr| as identifier within thread-scope.
+ // Shorthand for `Track::FromPointer(ptr, ThreadTrack::Current())`
+ // Usage: TRACE_EVENT_BEGIN("...", "...", perfetto::Track::ThreadScoped(this))
+ static Track ThreadScoped(
+ const void* ptr,
+ Track parent = MakeThreadTrack(base::GetThreadId())) {
+ return Track::FromPointer(ptr, parent);
+ }
+
protected:
constexpr Track(uint64_t uuid_, uint64_t parent_uuid_)
: uuid(uuid_), parent_uuid(parent_uuid_) {}
@@ -132,6 +145,8 @@ struct PERFETTO_EXPORT Track {
private:
friend class internal::TrackRegistry;
+ friend class Flow;
+ friend class TerminatingFlow;
static uint64_t process_uuid;
};
@@ -147,7 +162,8 @@ struct PERFETTO_EXPORT ProcessTrack : public Track {
protos::gen::TrackDescriptor Serialize() const;
private:
- ProcessTrack() : Track(MakeProcessTrack()), pid(base::GetProcessId()) {}
+ ProcessTrack()
+ : Track(MakeProcessTrack()), pid(Platform::GetCurrentProcessId()) {}
};
// A thread track is associated with a specific thread of execution. Currently
@@ -242,6 +258,13 @@ class CounterTrack : public Track {
unit_multiplier_, is_incremental_);
}
+ constexpr CounterTrack set_is_incremental(bool is_incremental = true) const {
+ return CounterTrack(uuid, parent_uuid, name_, category_, unit_, unit_name_,
+ unit_multiplier_, is_incremental);
+ }
+
+ constexpr bool is_incremental() const { return is_incremental_; }
+
void Serialize(protos::pbzero::TrackDescriptor*) const;
protos::gen::TrackDescriptor Serialize() const;
@@ -262,19 +285,12 @@ class CounterTrack : public Track {
unit_multiplier_(unit_multiplier),
is_incremental_(is_incremental) {}
- // TODO(skyostil): Expose incremental counters once we decide how to manage
- // their incremental state.
- constexpr CounterTrack set_is_incremental(bool is_incremental = true) const {
- return CounterTrack(uuid, parent_uuid, name_, category_, unit_, unit_name_,
- unit_multiplier_, is_incremental);
- }
-
const char* const name_;
const char* const category_;
Unit unit_ = perfetto::protos::pbzero::CounterDescriptor::UNIT_UNSPECIFIED;
const char* const unit_name_ = nullptr;
int64_t unit_multiplier_ = 1;
- bool is_incremental_ = false;
+ const bool is_incremental_ = false;
};
namespace internal {
@@ -297,6 +313,7 @@ class PERFETTO_EXPORT TrackRegistry {
~TrackRegistry();
static void InitializeInstance();
+ static void ResetForTesting();
static TrackRegistry* Get() { return instance_; }
void EraseTrack(Track);
diff --git a/include/perfetto/tracing/track_event.h b/include/perfetto/tracing/track_event.h
index 7e226f0d1..45499ebfc 100644
--- a/include/perfetto/tracing/track_event.h
+++ b/include/perfetto/tracing/track_event.h
@@ -184,12 +184,13 @@ constexpr bool IsDynamicCategory(const ::perfetto::DynamicCategory&) {
// Allocate storage for each category by using this macro once per track event
// namespace.
-#define PERFETTO_TRACK_EVENT_STATIC_STORAGE() \
- namespace PERFETTO_TRACK_EVENT_NAMESPACE { \
- PERFETTO_INTERNAL_CATEGORY_STORAGE() \
- } /* namespace PERFETTO_TRACK_EVENT_NAMESPACE */ \
- PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS( \
- PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent, \
+#define PERFETTO_TRACK_EVENT_STATIC_STORAGE() \
+ namespace PERFETTO_TRACK_EVENT_NAMESPACE { \
+ PERFETTO_INTERNAL_CATEGORY_STORAGE() \
+ PERFETTO_INTERNAL_DEFINE_TRACK_EVENT_DATA_SOURCE() \
+ } /* namespace PERFETTO_TRACK_EVENT_NAMESPACE */ \
+ PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS( \
+ PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent, \
perfetto::internal::TrackEventDataSourceTraits)
// Ignore GCC warning about a missing argument for a variadic macro parameter.
diff --git a/include/perfetto/tracing/track_event_args.h b/include/perfetto/tracing/track_event_args.h
new file mode 100644
index 000000000..21bda02af
--- /dev/null
+++ b/include/perfetto/tracing/track_event_args.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACK_EVENT_ARGS_H_
+#define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_ARGS_H_
+
+#include "perfetto/tracing/event_context.h"
+#include "perfetto/tracing/track.h"
+
+#include <functional>
+
+namespace perfetto {
+
+// A helper to add |flow_id| as a non-terminating flow id to TRACE_EVENT
+// inline: TRACE_EVENT(..., perfetto::Flow::ProcessScoped(42));
+class Flow {
+ public:
+ // |flow_id| which is local within a given process (e.g. atomic counter xor'ed
+ // with feature-specific value). This value is xor'ed with Perfetto's internal
+ // process track id to attempt to ensure that it's globally-unique.
+ static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)>
+ ProcessScoped(uint64_t flow_id) {
+ return Global(flow_id ^ Track::process_uuid);
+ }
+
+ // Same as above, but construct an id from a pointer.
+ // NOTE: After the object is destroyed, the value of |ptr| can be reused for a
+ // different object (in particular if the object is allocated on a stack).
+ // Please ensure that you emit a trace event with the flow id of
+ // perfetto::TerminatingFlow::FromPointer(this) from the destructor of the
+ // object to avoid accidental conflicts.
+ static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)>
+ FromPointer(void* ptr) {
+ return ProcessScoped(reinterpret_cast<uintptr_t>(ptr));
+ }
+
+ // Add the |flow_id|. The caller is responsible for ensuring that it's
+ // globally-unique (e.g. by generating a random value). This should be used
+ // only for flow events which cross the process boundary (e.g. IPCs).
+ static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)>
+ Global(uint64_t flow_id) {
+ return [flow_id](perfetto::EventContext& ctx) {
+ ctx.event()->add_flow_ids(flow_id);
+ };
+ }
+
+ // TODO(altimin): Remove once converting a single usage in Chromium.
+ explicit constexpr Flow(uint64_t flow_id) : flow_id_(flow_id) {}
+
+ void operator()(EventContext& ctx) { ctx.event()->add_flow_ids(flow_id_); }
+
+ private:
+ uint64_t flow_id_;
+};
+
+// A helper to add a given |flow_id| as a terminating flow to TRACE_EVENT
+// inline.
+class TerminatingFlow {
+ public:
+ // See `Flow::ProcessScoped(uint64_t)`.
+ static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)>
+ ProcessScoped(uint64_t flow_id) {
+ return Global(flow_id ^ Track::process_uuid);
+ }
+
+ // See `Flow::FromPointer(void*)`.
+ static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)>
+ FromPointer(void* ptr) {
+ return ProcessScoped(reinterpret_cast<uintptr_t>(ptr));
+ }
+
+ // See `Flow::Global(uint64_t)`.
+ static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)>
+ Global(uint64_t flow_id) {
+ return [flow_id](perfetto::EventContext& ctx) {
+ ctx.event()->add_terminating_flow_ids(flow_id);
+ };
+ }
+};
+
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_ARGS_H_
diff --git a/include/perfetto/tracing/track_event_legacy.h b/include/perfetto/tracing/track_event_legacy.h
index cd8651021..197d559ef 100644
--- a/include/perfetto/tracing/track_event_legacy.h
+++ b/include/perfetto/tracing/track_event_legacy.h
@@ -158,8 +158,7 @@ static constexpr char TRACE_EVENT_SCOPE_NAME_GLOBAL = 'g';
static constexpr char TRACE_EVENT_SCOPE_NAME_PROCESS = 'p';
static constexpr char TRACE_EVENT_SCOPE_NAME_THREAD = 't';
-static constexpr auto TRACE_EVENT_API_CURRENT_THREAD_ID =
- perfetto::legacy::kCurrentThreadId;
+#define TRACE_EVENT_API_CURRENT_THREAD_ID ::perfetto::legacy::kCurrentThreadId
#endif // PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
@@ -451,46 +450,46 @@ class PERFETTO_EXPORT TrackEventLegacy {
// The main entrypoint for writing unscoped legacy events. This macro
// determines the right track to write the event on based on |flags| and
// |thread_id|.
-#define PERFETTO_INTERNAL_LEGACY_EVENT(phase, category, name, flags, \
- thread_id, ...) \
- [&]() { \
- constexpr auto& kDefaultTrack = \
- ::perfetto::internal::TrackEventInternal::kDefaultTrack; \
- /* First check the scope for instant events. */ \
- if ((phase) == TRACE_EVENT_PHASE_INSTANT) { \
- /* Note: Avoids the need to set LegacyEvent::instant_event_scope. */ \
- auto scope = (flags)&TRACE_EVENT_FLAG_SCOPE_MASK; \
- switch (scope) { \
- case TRACE_EVENT_SCOPE_GLOBAL: \
- PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK( \
- phase, category, name, ::perfetto::Track::Global(0), \
- ##__VA_ARGS__); \
- return; \
- case TRACE_EVENT_SCOPE_PROCESS: \
- PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK( \
- phase, category, name, ::perfetto::ProcessTrack::Current(), \
- ##__VA_ARGS__); \
- return; \
- default: \
- case TRACE_EVENT_SCOPE_THREAD: \
- /* Fallthrough. */ \
- break; \
- } \
- } \
- /* If an event targets the current thread or another process, write \
- * it on the current thread's track. The process override case is \
- * handled through |pid_override| in WriteLegacyEvent. */ \
- if (std::is_same< \
- decltype(thread_id), \
- ::perfetto::legacy::PerfettoLegacyCurrentThreadId>::value || \
- ((flags)&TRACE_EVENT_FLAG_HAS_PROCESS_ID)) { \
- PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK(phase, category, name, \
- kDefaultTrack, ##__VA_ARGS__); \
- } else { \
- PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK( \
- phase, category, name, \
- ::perfetto::legacy::ConvertThreadId(thread_id), ##__VA_ARGS__); \
- } \
+#define PERFETTO_INTERNAL_LEGACY_EVENT(phase, category, name, flags, \
+ thread_id, ...) \
+ [&]() { \
+ using ::perfetto::internal::TrackEventInternal; \
+ /* First check the scope for instant events. */ \
+ if ((phase) == TRACE_EVENT_PHASE_INSTANT) { \
+ /* Note: Avoids the need to set LegacyEvent::instant_event_scope. */ \
+ auto scope = (flags)&TRACE_EVENT_FLAG_SCOPE_MASK; \
+ switch (scope) { \
+ case TRACE_EVENT_SCOPE_GLOBAL: \
+ PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK( \
+ phase, category, name, ::perfetto::Track::Global(0), \
+ ##__VA_ARGS__); \
+ return; \
+ case TRACE_EVENT_SCOPE_PROCESS: \
+ PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK( \
+ phase, category, name, ::perfetto::ProcessTrack::Current(), \
+ ##__VA_ARGS__); \
+ return; \
+ default: \
+ case TRACE_EVENT_SCOPE_THREAD: \
+ /* Fallthrough. */ \
+ break; \
+ } \
+ } \
+ /* If an event targets the current thread or another process, write \
+ * it on the current thread's track. The process override case is \
+ * handled through |pid_override| in WriteLegacyEvent. */ \
+ if (std::is_same< \
+ decltype(thread_id), \
+ ::perfetto::legacy::PerfettoLegacyCurrentThreadId>::value || \
+ ((flags)&TRACE_EVENT_FLAG_HAS_PROCESS_ID)) { \
+ PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK( \
+ phase, category, name, TrackEventInternal::kDefaultTrack, \
+ ##__VA_ARGS__); \
+ } else { \
+ PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK( \
+ phase, category, name, \
+ ::perfetto::legacy::ConvertThreadId(thread_id), ##__VA_ARGS__); \
+ } \
}()
#define INTERNAL_TRACE_EVENT_ADD(phase, category, name, flags, ...) \
@@ -879,6 +878,16 @@ class PERFETTO_EXPORT TrackEventLegacy {
TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \
TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
arg1_name, arg1_val)
+#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP_AND_FLAGS0( \
+ category_group, name, id, timestamp, flags) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
+ TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id, \
+ TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags)
+#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0(category_group, name, \
+ id, timestamp) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
+ TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id, \
+ TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
#define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP2(category_group, name, id, \
timestamp, arg1_name, \
arg1_val, arg2_name, arg2_val) \
@@ -1004,6 +1013,10 @@ class PERFETTO_EXPORT TrackEventLegacy {
INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id, \
TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
+#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_FLAGS0(category_group, name, id, \
+ flags) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, \
+ category_group, name, id, flags)
#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP1( \
category_group, name, id, timestamp, arg1_name, arg1_val) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
@@ -1026,6 +1039,10 @@ class PERFETTO_EXPORT TrackEventLegacy {
INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id, \
TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
+#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_FLAGS0(category_group, name, id, \
+ flags) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, \
+ category_group, name, id, flags)
// Async instant events.
#define TRACE_EVENT_NESTABLE_ASYNC_INSTANT0(category_group, name, id) \
@@ -1072,6 +1089,18 @@ class PERFETTO_EXPORT TrackEventLegacy {
TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id, \
TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
arg1_name, arg1_val)
+#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP2( \
+ category_group, name, id, timestamp, arg1_name, arg1_val, arg2_name, \
+ arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
+ TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id, \
+ TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
+ arg1_name, arg1_val, arg2_name, arg2_val)
+#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP_AND_FLAGS0( \
+ category_group, name, id, timestamp, flags) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
+ TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id, \
+ TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags)
#define TRACE_EVENT_NESTABLE_ASYNC_INSTANT_WITH_TIMESTAMP0( \
category_group, name, id, timestamp) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
@@ -1081,6 +1110,16 @@ class PERFETTO_EXPORT TrackEventLegacy {
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, \
category_group, name, id, \
TRACE_EVENT_FLAG_COPY)
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN1(category_group, name, id, \
+ arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, \
+ category_group, name, id, \
+ TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN2( \
+ category_group, name, id, arg1_name, arg1_val, arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
+ TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id, \
+ TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, arg2_val)
#define TRACE_EVENT_COPY_NESTABLE_ASYNC_END0(category_group, name, id) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, \
category_group, name, id, \
@@ -1090,6 +1129,12 @@ class PERFETTO_EXPORT TrackEventLegacy {
INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id, \
TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY)
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP1( \
+ category_group, name, id, timestamp, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
+ TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id, \
+ TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY, \
+ arg1_name, arg1_val)
#define TRACE_EVENT_COPY_NESTABLE_ASYNC_END_WITH_TIMESTAMP0( \
category_group, name, id, timestamp) \
INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
@@ -1212,7 +1257,7 @@ class PERFETTO_EXPORT TrackEventLegacy {
"Enabled flag pointers are not supported for dynamic trace " \
"categories."); \
}, \
- PERFETTO_TRACK_EVENT_NAMESPACE::internal::kConstExprCategoryRegistry \
+ PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry \
.GetCategoryState( \
::PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry \
.Find(category, /*is_dynamic=*/false)))
@@ -1220,7 +1265,7 @@ class PERFETTO_EXPORT TrackEventLegacy {
// Given a pointer returned by TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED,
// yields a pointer to the name of the corresponding category group.
#define TRACE_EVENT_API_GET_CATEGORY_GROUP_NAME(category_enabled_ptr) \
- ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::kConstExprCategoryRegistry \
+ ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry \
.GetCategory( \
category_enabled_ptr - \
reinterpret_cast<const uint8_t*>( \
diff --git a/include/perfetto/tracing/track_event_state_tracker.h b/include/perfetto/tracing/track_event_state_tracker.h
index 7b2437e16..e97f03578 100644
--- a/include/perfetto/tracing/track_event_state_tracker.h
+++ b/include/perfetto/tracing/track_event_state_tracker.h
@@ -80,6 +80,10 @@ class PERFETTO_EXPORT TrackEventStateTracker {
std::map<uint64_t /*iid*/, std::string> event_names;
std::map<uint64_t /*iid*/, std::string> event_categories;
std::map<uint64_t /*iid*/, std::string> debug_annotation_names;
+ // Current absolute timestamp of the incremental clock.
+ uint64_t most_recent_absolute_time_ns = 0;
+ // default_clock_id == 0 means, no default clock_id is set.
+ uint32_t default_clock_id = 0;
};
// State for the entire tracing session. Shared by all trace writer sequences
diff --git a/infra/OWNERS b/infra/OWNERS
new file mode 100644
index 000000000..a4b3fef71
--- /dev/null
+++ b/infra/OWNERS
@@ -0,0 +1,3 @@
+hjd@google.com
+lalitm@google.com
+primiano@google.com
diff --git a/infra/ci/Makefile b/infra/ci/Makefile
index d4a3e165c..09c57a0ab 100644
--- a/infra/ci/Makefile
+++ b/infra/ci/Makefile
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-include $(shell python config.py makefile)
+include $(shell python3 config.py makefile)
override COMMON_DEPS := Makefile *.py
override GCE_LOCAL_STARTUP_SCRIPT := worker/gce-startup-script.sh
@@ -142,7 +142,7 @@ start-worker-for-testing: .deps/gce-template
.PHONY: cli
cli:
GOOGLE_APPLICATION_CREDENTIALS=test-credentials.json \
- python -i -c 'from common_utils import *; from config import *; \
+ python3 -i -c 'from common_utils import *; from config import *; \
SCOPES += ["https://www.googleapis.com/auth/firebase.database", \
"https://www.googleapis.com/auth/userinfo.email", \
"https://www.googleapis.com/auth/datastore"]'
diff --git a/infra/ci/controller/Makefile b/infra/ci/controller/Makefile
index f72394d70..66a159bf3 100644
--- a/infra/ci/controller/Makefile
+++ b/infra/ci/controller/Makefile
@@ -13,11 +13,11 @@
# limitations under the License.
-include $(shell python ../config.py makefile)
+include $(shell python3 ../config.py makefile)
test: lib/.stamp config.py common_utils.py
GOOGLE_APPLICATION_CREDENTIALS=../test-credentials.json \
- dev_appserver.py app.yaml --dev_appserver_log_level ${LOGLEVEL}
+ python3 `which dev_appserver.py` app.yaml --dev_appserver_log_level ${LOGLEVEL}
deploy: lib/.stamp config.py common_utils.py
gcloud app deploy -q app.yaml queue.yaml cron.yaml \
diff --git a/infra/ci/frontend/Makefile b/infra/ci/frontend/Makefile
index 400b5eb78..14a000026 100644
--- a/infra/ci/frontend/Makefile
+++ b/infra/ci/frontend/Makefile
@@ -13,13 +13,13 @@
# limitations under the License.
-include $(shell python ../config.py makefile)
+include $(shell python3 ../config.py makefile)
SHASUM=shasum
test: LOGLEVEL=info
test: static_3p config.py common_utils.py static/config.js
- dev_appserver.py app.yaml --dev_appserver_log_level ${LOGLEVEL}
+ python3 `which dev_appserver.py` app.yaml --dev_appserver_log_level ${LOGLEVEL}
deploy: static_3p config.py common_utils.py static/config.js
gcloud app deploy -q app.yaml \
diff --git a/infra/ci/frontend/static/script.js b/infra/ci/frontend/static/script.js
index 152048545..18c36bf96 100644
--- a/infra/ci/frontend/static/script.js
+++ b/infra/ci/frontend/static/script.js
@@ -254,7 +254,7 @@ function renderCLRow(cl) {
`${cl.subject}`, m('span.ps', `#${cl.psNum}`))
),
m('td', cl.status),
- m('td', stripEmail(cl.owner)),
+ m('td', stripEmail(cl.owner || '')),
m('td', getLastUpdate(cl.lastUpdate)),
JOB_TYPES.map(x => renderClJobCell(`cls/${cl.num}-${cl.psNum}`, x.id))
));
diff --git a/infra/ci/sandbox/Dockerfile b/infra/ci/sandbox/Dockerfile
index 6f14c9069..79da8d49e 100644
--- a/infra/ci/sandbox/Dockerfile
+++ b/infra/ci/sandbox/Dockerfile
@@ -45,6 +45,20 @@ RUN set -ex; \
rm bazel-*-installer-linux-x86_64.sh; \
bazel version;
+# Chrome/puppeteer deps.
+RUN set -ex; \
+ export DEBIAN_FRONTEND=noninteractive; \
+ apt-get update; \
+ apt-get -y install gconf-service libasound2 libatk1.0-0 libc6 libcairo2 \
+ libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 \
+ libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 \
+ libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 \
+ libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 \
+ libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 \
+ libxtst6 ca-certificates libappindicator1 libnss3 lsb-release \
+ xdg-utils fonts-liberation fonts-ipafont-gothic fonts-wqy-zenhei \
+ fonts-thai-tlwg fonts-kacst fonts-freefont-ttf
+
COPY testrunner.sh /ci/testrunner.sh
COPY init.sh /ci/init.sh
RUN chmod -R a+rx /ci/
diff --git a/infra/ci/worker/run_job.py b/infra/ci/worker/run_job.py
index 4706120d9..e5353c9fb 100755
--- a/infra/ci/worker/run_job.py
+++ b/infra/ci/worker/run_job.py
@@ -19,12 +19,10 @@ Also streams stdout/err onto the firebase realtime DB.
import fcntl
import logging
-import json
import os
import queue
import signal
import socket
-import shutil
import subprocess
import sys
import threading
@@ -45,10 +43,18 @@ def read_nonblock(fd):
res = ''
while True:
try:
- buf = os.read(fd.fileno(), 1024)
+ buf = os.read(fd.fileno(), 8192)
if not buf:
break
- res += buf.decode()
+ # There are two reasons for the errors='ignore' here:
+ # 1: By reading the pipe in chunks of N bytes, we can end up truncating
+ # a valid multi-byte character and cause an "unexpected end of data".
+ # This means that we will skip valid unicode chars if they happen to
+ # span across two read() chunks.
+ # 2: The job output might just emit some invalid unicode in stdout. We
+ # don't want to crash when that happens.
+ # See b/194053229 for more context.
+ res += buf.decode('utf-8', errors='ignore')
except OSError:
break
return res
diff --git a/infra/config/recipes.cfg b/infra/config/recipes.cfg
index 5743902c6..0b9c6c6b2 100644
--- a/infra/config/recipes.cfg
+++ b/infra/config/recipes.cfg
@@ -5,6 +5,11 @@
"branch": "refs/heads/master",
"revision": "2030661a4ff2a6b64b0651f2c44aabed8c71223f",
"url": "https://chromium.googlesource.com/infra/luci/recipes-py"
+ },
+ "depot_tools": {
+ "branch": "refs/heads/main",
+ "revision": "5345b34aaf50107d0a07146b9319ef19203f65a0",
+ "url": "https://chromium.googlesource.com/chromium/tools/depot_tools.git"
}
},
"project_id": "perfetto",
diff --git a/infra/discord-irc-bridge/Dockerfile b/infra/discord-irc-bridge/Dockerfile
deleted file mode 100644
index 5591da24b..000000000
--- a/infra/discord-irc-bridge/Dockerfile
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-FROM node:latest
-
-RUN useradd -m discord_irc
-RUN npm install -g discord-irc
-RUN apt-get -y update && apt-get -y install supervisor
-COPY supervisord.conf /etc/
-COPY discord-irc.json /etc/
-COPY start.py /
-USER discord_irc
-
-CMD ["python", "start.py"] \ No newline at end of file
diff --git a/infra/discord-irc-bridge/README.md b/infra/discord-irc-bridge/README.md
deleted file mode 100644
index 9c79d2daf..000000000
--- a/infra/discord-irc-bridge/README.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# IRC <> Discord bridge
-
-This directory contains the docker image for the discord<>IRC bot.
-The docker container is built and pushed running:
-
-```bash
-docker build -t gcr.io/perfetto-irc/discord-irc-bridge .
-docker push gcr.io/perfetto-irc/discord-irc-bridge
-```
-
-The docker container requires two environment variables to be set (see below).
-These are set at the GCE project level (project: perfetto-irc).
-There is a VM template in the GCE project which has the right env vars set.
-If a VM restart is required use the template, don't create the VM from scratch.
-
-NICKNAME: This must be set to perfetto_discord:password. The password can be
- obtained on the usual internal website for passwords. Look for the account
- "perfetto_discord@freenode".
-
-DISCORD_TOKEN: This must be set to the Discord token for the bot. Look for
- the account "perfetto-discord-bot-token" in the internal password website.
diff --git a/infra/discord-irc-bridge/discord-irc.json b/infra/discord-irc-bridge/discord-irc.json
deleted file mode 100644
index bf71f2a1c..000000000
--- a/infra/discord-irc-bridge/discord-irc.json
+++ /dev/null
@@ -1,23 +0,0 @@
-[
- {
- "server": "irc.freenode.org",
- "autoSendCommands": [
- ],
- "channelMapping": {
- "629013441096450058": "#perfetto-dev"
- },
- "ircOptions": {
- "port": "6697",
- "secure": true
- },
- "ircNickColor": false,
- "ircPreventMention": true,
- "commandCharacters": [],
- "ignoreUsers": {
- "irc": [],
- "discord": []
- },
- "webhooks": {
- }
- }
-]
diff --git a/infra/discord-irc-bridge/start.py b/infra/discord-irc-bridge/start.py
deleted file mode 100644
index 35bbb932b..000000000
--- a/infra/discord-irc-bridge/start.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python
-# Copyright (C) 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import json
-import os
-import sys
-
-with open("/etc/discord-irc.json") as f:
- cfg = json.load(f)
-
-cfg[0]["nickname"] = os.getenv("NICKNAME")
-cfg[0]["discordToken"] = os.getenv("DISCORD_TOKEN")
-
-if cfg[0]["nickname"] is None:
- sys.stderr.write("NICKNAME env var not set\n")
- sys.exit(1)
-
-if cfg[0]["discordToken"] is None:
- sys.stderr.write("DISCORD_TOKEN env var not set\n")
- sys.exit(1)
-
-with open("/tmp/discord-irc-merged.json", "w") as f:
- json.dump(cfg, f)
-
-os.execl("/usr/bin/supervisord", "supervisord")
diff --git a/infra/discord-irc-bridge/supervisord.conf b/infra/discord-irc-bridge/supervisord.conf
deleted file mode 100644
index 713b332f3..000000000
--- a/infra/discord-irc-bridge/supervisord.conf
+++ /dev/null
@@ -1,13 +0,0 @@
-[supervisord]
-nodaemon=true
-logfile=/dev/stdout
-logfile_maxbytes=0
-
-[program:discord_irc]
-command=discord-irc --config /tmp/discord-irc-merged.json
-stdout_logfile=/dev/stdout
-stdout_logfile_maxbytes=0
-stdout_logfile_backups=0
-stderr_logfile=/dev/stderr
-stderr_logfile_maxbytes=0
-stderr_logfile_backups=0
diff --git a/infra/luci/README.recipes.md b/infra/luci/README.recipes.md
index 8d601e92b..0965828f8 100644
--- a/infra/luci/README.recipes.md
+++ b/infra/luci/README.recipes.md
@@ -2,22 +2,115 @@
# Repo documentation for [perfetto]()
## Table of Contents
+**[Recipe Modules](#Recipe-Modules)**
+ * [macos_sdk](#recipe_modules-macos_sdk) &mdash; The `macos_sdk` module provides safe functions to access a semi-hermetic XCode installation.
+ * [windows_sdk](#recipe_modules-windows_sdk)
+
**[Recipes](#Recipes)**
+ * [macos_sdk:examples/full](#recipes-macos_sdk_examples_full)
* [perfetto](#recipes-perfetto) &mdash; Recipe for building Perfetto.
+ * [windows_sdk:examples/full](#recipes-windows_sdk_examples_full)
+## Recipe Modules
+
+### *recipe_modules* / [macos\_sdk](/infra/luci/recipe_modules/macos_sdk)
+
+[DEPS](/infra/luci/recipe_modules/macos_sdk/__init__.py#15): [recipe\_engine/cipd][recipe_engine/recipe_modules/cipd], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/step][recipe_engine/recipe_modules/step]
+
+The `macos_sdk` module provides safe functions to access a semi-hermetic
+XCode installation.
+
+Available only to Google-run bots.
+
+#### **class [MacOSSDKApi](/infra/luci/recipe_modules/macos_sdk/api.py#24)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
+
+API for using OS X SDK distributed via CIPD.
+
+&emsp; **@contextmanager**<br>&mdash; **def [\_\_call\_\_](/infra/luci/recipe_modules/macos_sdk/api.py#40)(self):**
+
+Sets up the XCode SDK environment.
+
+This call is a no-op on non-Mac platforms.
+
+This will deploy the helper tool and the XCode.app bundle at
+`[START_DIR]/cache/macos_sdk`.
+
+To avoid machines rebuilding these on every run, set up a named cache in
+your cr-buildbucket.cfg file like:
+
+ caches: {
+ # Cache for mac_toolchain tool and XCode.app
+ name: "macos_sdk"
+ path: "macos_sdk"
+ }
+
+If you have builders which e.g. use a non-current SDK, you can give them
+a uniqely named cache:
+
+ caches: {
+ # Cache for N-1 version mac_toolchain tool and XCode.app
+ name: "macos_sdk_old"
+ path: "macos_sdk"
+ }
+
+Usage:
+ with api.macos_sdk():
+ # sdk with mac build bits
+
+Raises:
+ StepFailure or InfraFailure.
+
+&emsp; **@property**<br>&mdash; **def [sdk\_dir](/infra/luci/recipe_modules/macos_sdk/api.py#35)(self):**
+### *recipe_modules* / [windows\_sdk](/infra/luci/recipe_modules/windows_sdk)
+
+[DEPS](/infra/luci/recipe_modules/windows_sdk/__init__.py#15): [recipe\_engine/cipd][recipe_engine/recipe_modules/cipd], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/step][recipe_engine/recipe_modules/step]
+
+#### **class [WindowsSDKApi](/infra/luci/recipe_modules/windows_sdk/api.py#20)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
+
+API for using Windows SDK distributed via CIPD.
+
+&emsp; **@contextmanager**<br>&mdash; **def [\_\_call\_\_](/infra/luci/recipe_modules/windows_sdk/api.py#29)(self):**
+
+Setups the Windows SDK environment.
+
+This call is a no-op on non-Windows platforms.
+
+Raises:
+ StepFailure or InfraFailure.
## Recipes
+### *recipes* / [macos\_sdk:examples/full](/infra/luci/recipe_modules/macos_sdk/examples/full.py)
+
+[DEPS](/infra/luci/recipe_modules/macos_sdk/examples/full.py#15): [macos\_sdk](#recipe_modules-macos_sdk), [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step]
+
+&mdash; **def [RunSteps](/infra/luci/recipe_modules/macos_sdk/examples/full.py#23)(api):**
### *recipes* / [perfetto](/infra/luci/recipes/perfetto.py)
-[DEPS](/infra/luci/recipes/perfetto.py#18): [recipe\_engine/buildbucket][recipe_engine/recipe_modules/buildbucket], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step]
+[DEPS](/infra/luci/recipes/perfetto.py#18): [depot\_tools/gsutil][depot_tools/recipe_modules/gsutil], [macos\_sdk](#recipe_modules-macos_sdk), [windows\_sdk](#recipe_modules-windows_sdk), [recipe\_engine/buildbucket][recipe_engine/recipe_modules/buildbucket], [recipe\_engine/cipd][recipe_engine/recipe_modules/cipd], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step]
Recipe for building Perfetto.
-&mdash; **def [RunSteps](/infra/luci/recipes/perfetto.py#39)(api, repository):**
+&mdash; **def [BuildForPlatform](/infra/luci/recipes/perfetto.py#138)(api, ctx, platform):**
+
+&mdash; **def [GnArgs](/infra/luci/recipes/perfetto.py#81)(platform):**
+
+&mdash; **def [RunSteps](/infra/luci/recipes/perfetto.py#164)(api, repository):**
+
+&mdash; **def [UploadArtifact](/infra/luci/recipes/perfetto.py#90)(api, ctx, platform, out_dir, artifact):**
+### *recipes* / [windows\_sdk:examples/full](/infra/luci/recipe_modules/windows_sdk/examples/full.py)
+
+[DEPS](/infra/luci/recipe_modules/windows_sdk/examples/full.py#15): [windows\_sdk](#recipe_modules-windows_sdk), [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step]
+
+&mdash; **def [RunSteps](/infra/luci/recipe_modules/windows_sdk/examples/full.py#23)(api):**
+[depot_tools/recipe_modules/gsutil]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/5345b34aaf50107d0a07146b9319ef19203f65a0/recipes/README.recipes.md#recipe_modules-gsutil
[recipe_engine/recipe_modules/buildbucket]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/2030661a4ff2a6b64b0651f2c44aabed8c71223f/README.recipes.md#recipe_modules-buildbucket
+[recipe_engine/recipe_modules/cipd]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/2030661a4ff2a6b64b0651f2c44aabed8c71223f/README.recipes.md#recipe_modules-cipd
[recipe_engine/recipe_modules/context]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/2030661a4ff2a6b64b0651f2c44aabed8c71223f/README.recipes.md#recipe_modules-context
[recipe_engine/recipe_modules/file]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/2030661a4ff2a6b64b0651f2c44aabed8c71223f/README.recipes.md#recipe_modules-file
+[recipe_engine/recipe_modules/json]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/2030661a4ff2a6b64b0651f2c44aabed8c71223f/README.recipes.md#recipe_modules-json
[recipe_engine/recipe_modules/path]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/2030661a4ff2a6b64b0651f2c44aabed8c71223f/README.recipes.md#recipe_modules-path
[recipe_engine/recipe_modules/platform]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/2030661a4ff2a6b64b0651f2c44aabed8c71223f/README.recipes.md#recipe_modules-platform
[recipe_engine/recipe_modules/properties]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/2030661a4ff2a6b64b0651f2c44aabed8c71223f/README.recipes.md#recipe_modules-properties
+[recipe_engine/recipe_modules/raw_io]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/2030661a4ff2a6b64b0651f2c44aabed8c71223f/README.recipes.md#recipe_modules-raw_io
[recipe_engine/recipe_modules/step]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/2030661a4ff2a6b64b0651f2c44aabed8c71223f/README.recipes.md#recipe_modules-step
+[recipe_engine/wkt/RecipeApi]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/2030661a4ff2a6b64b0651f2c44aabed8c71223f/recipe_engine/recipe_api.py#856
diff --git a/infra/luci/generated/cr-buildbucket.cfg b/infra/luci/generated/cr-buildbucket.cfg
new file mode 100644
index 000000000..a835dad3b
--- /dev/null
+++ b/infra/luci/generated/cr-buildbucket.cfg
@@ -0,0 +1,98 @@
+# Auto-generated by lucicfg.
+# Do not modify manually.
+#
+# For the schema of this file, see BuildbucketCfg message:
+# https://luci-config.appspot.com/schemas/projects:buildbucket.cfg
+
+buckets {
+ name: "official"
+ acls {
+ group: "all"
+ }
+ acls {
+ role: SCHEDULER
+ group: "mdb/chrome-troopers"
+ }
+ acls {
+ role: SCHEDULER
+ group: "mdb/perfetto-cloud-infra"
+ }
+ swarming {
+ builders {
+ name: "perfetto-official-builder-android"
+ swarming_host: "chrome-swarming.appspot.com"
+ dimensions: "cpu:x86-64"
+ dimensions: "os:Linux"
+ dimensions: "pool:luci.perfetto.official"
+ exe {
+ cipd_package: "infra/recipe_bundles/android.googlesource.com/platform/external/perfetto"
+ cipd_version: "refs/heads/master"
+ cmd: "luciexe"
+ }
+ properties:
+ '{'
+ ' "recipe": "perfetto"'
+ '}'
+ service_account: "perfetto-luci-official-builder@chops-service-accounts.iam.gserviceaccount.com"
+ }
+ builders {
+ name: "perfetto-official-builder-linux"
+ swarming_host: "chrome-swarming.appspot.com"
+ dimensions: "cpu:x86-64"
+ dimensions: "os:Linux"
+ dimensions: "pool:luci.perfetto.official"
+ exe {
+ cipd_package: "infra/recipe_bundles/android.googlesource.com/platform/external/perfetto"
+ cipd_version: "refs/heads/master"
+ cmd: "luciexe"
+ }
+ properties:
+ '{'
+ ' "recipe": "perfetto"'
+ '}'
+ service_account: "perfetto-luci-official-builder@chops-service-accounts.iam.gserviceaccount.com"
+ }
+ builders {
+ name: "perfetto-official-builder-mac"
+ swarming_host: "chrome-swarming.appspot.com"
+ dimensions: "cpu:x86-64"
+ dimensions: "os:Mac"
+ dimensions: "pool:luci.perfetto.official"
+ exe {
+ cipd_package: "infra/recipe_bundles/android.googlesource.com/platform/external/perfetto"
+ cipd_version: "refs/heads/master"
+ cmd: "luciexe"
+ }
+ properties:
+ '{'
+ ' "recipe": "perfetto"'
+ '}'
+ caches {
+ name: "macos_sdk"
+ path: "macos_sdk"
+ }
+ service_account: "perfetto-luci-official-builder@chops-service-accounts.iam.gserviceaccount.com"
+ }
+ builders {
+ name: "perfetto-official-builder-windows"
+ swarming_host: "chrome-swarming.appspot.com"
+ dimensions: "cpu:x86-64"
+ dimensions: "os:Windows"
+ dimensions: "pool:luci.perfetto.official"
+ exe {
+ cipd_package: "infra/recipe_bundles/android.googlesource.com/platform/external/perfetto"
+ cipd_version: "refs/heads/master"
+ cmd: "luciexe"
+ }
+ properties:
+ '{'
+ ' "recipe": "perfetto"'
+ '}'
+ caches {
+ name: "windows_sdk"
+ path: "windows_sdk"
+ }
+ service_account: "perfetto-luci-official-builder@chops-service-accounts.iam.gserviceaccount.com"
+ }
+ }
+}
diff --git a/infra/luci/generated/luci-logdog.cfg b/infra/luci/generated/luci-logdog.cfg
new file mode 100644
index 000000000..adc75bef4
--- /dev/null
+++ b/infra/luci/generated/luci-logdog.cfg
@@ -0,0 +1,9 @@
+# Auto-generated by lucicfg.
+# Do not modify manually.
+#
+# For the schema of this file, see ProjectConfig message:
+# https://luci-config.appspot.com/schemas/projects:luci-logdog.cfg
+
+reader_auth_groups: "all"
+writer_auth_groups: "luci-logdog-chromium-writers"
+archive_gs_bucket: "chromium-luci-logdog"
diff --git a/infra/luci/generated/luci-scheduler.cfg b/infra/luci/generated/luci-scheduler.cfg
new file mode 100644
index 000000000..dd7f20bf1
--- /dev/null
+++ b/infra/luci/generated/luci-scheduler.cfg
@@ -0,0 +1,73 @@
+# Auto-generated by lucicfg.
+# Do not modify manually.
+#
+# For the schema of this file, see ProjectConfig message:
+# https://luci-config.appspot.com/schemas/projects:luci-scheduler.cfg
+
+job {
+ id: "perfetto-official-builder-android"
+ realm: "official"
+ acl_sets: "official"
+ buildbucket {
+ server: "cr-buildbucket.appspot.com"
+ bucket: "official"
+ builder: "perfetto-official-builder-android"
+ }
+}
+job {
+ id: "perfetto-official-builder-linux"
+ realm: "official"
+ acl_sets: "official"
+ buildbucket {
+ server: "cr-buildbucket.appspot.com"
+ bucket: "official"
+ builder: "perfetto-official-builder-linux"
+ }
+}
+job {
+ id: "perfetto-official-builder-mac"
+ realm: "official"
+ acl_sets: "official"
+ buildbucket {
+ server: "cr-buildbucket.appspot.com"
+ bucket: "official"
+ builder: "perfetto-official-builder-mac"
+ }
+}
+job {
+ id: "perfetto-official-builder-windows"
+ realm: "official"
+ acl_sets: "official"
+ buildbucket {
+ server: "cr-buildbucket.appspot.com"
+ bucket: "official"
+ builder: "perfetto-official-builder-windows"
+ }
+}
+trigger {
+ id: "perfetto-gitiles-trigger"
+ realm: "official"
+ acl_sets: "official"
+ triggers: "perfetto-official-builder-android"
+ triggers: "perfetto-official-builder-linux"
+ triggers: "perfetto-official-builder-mac"
+ triggers: "perfetto-official-builder-windows"
+ gitiles {
+ repo: "https://android.googlesource.com/platform/external/perfetto"
+ refs: "regexp:refs/tags/v.+"
+ }
+}
+acl_sets {
+ name: "official"
+ acls {
+ role: OWNER
+ granted_to: "group:mdb/perfetto-cloud-infra"
+ }
+ acls {
+ granted_to: "group:all"
+ }
+ acls {
+ role: TRIGGERER
+ granted_to: "group:mdb/chrome-troopers"
+ }
+}
diff --git a/infra/luci/generated/project.cfg b/infra/luci/generated/project.cfg
new file mode 100644
index 000000000..2aad4e14b
--- /dev/null
+++ b/infra/luci/generated/project.cfg
@@ -0,0 +1,15 @@
+# Auto-generated by lucicfg.
+# Do not modify manually.
+#
+# For the schema of this file, see ProjectCfg message:
+# https://luci-config.appspot.com/schemas/projects:project.cfg
+
+name: "perfetto"
+access: "group:all"
+lucicfg {
+ version: "1.30.9"
+ package_dir: ".."
+ config_dir: "generated"
+ entry_point: "main.star"
+ experiments: "crbug.com/1182002"
+}
diff --git a/infra/luci/generated/realms.cfg b/infra/luci/generated/realms.cfg
new file mode 100644
index 000000000..522d5c635
--- /dev/null
+++ b/infra/luci/generated/realms.cfg
@@ -0,0 +1,52 @@
+# Auto-generated by lucicfg.
+# Do not modify manually.
+#
+# For the schema of this file, see RealmsCfg message:
+# https://luci-config.appspot.com/schemas/projects:realms.cfg
+
+realms {
+ name: "@root"
+ bindings {
+ role: "role/buildbucket.reader"
+ principals: "group:all"
+ }
+ bindings {
+ role: "role/configs.reader"
+ principals: "group:all"
+ }
+ bindings {
+ role: "role/logdog.reader"
+ principals: "group:all"
+ }
+ bindings {
+ role: "role/logdog.writer"
+ principals: "group:luci-logdog-chromium-writers"
+ }
+ bindings {
+ role: "role/scheduler.owner"
+ principals: "group:mdb/perfetto-cloud-infra"
+ }
+ bindings {
+ role: "role/scheduler.reader"
+ principals: "group:all"
+ }
+}
+realms {
+ name: "official"
+ bindings {
+ role: "role/buildbucket.builderServiceAccount"
+ principals: "user:perfetto-luci-official-builder@chops-service-accounts.iam.gserviceaccount.com"
+ }
+ bindings {
+ role: "role/buildbucket.triggerer"
+ principals: "group:mdb/chrome-troopers"
+ principals: "group:mdb/perfetto-cloud-infra"
+ }
+ bindings {
+ role: "role/scheduler.triggerer"
+ principals: "group:mdb/chrome-troopers"
+ }
+}
+realms {
+ name: "pools/official"
+}
diff --git a/infra/luci/main.star b/infra/luci/main.star
new file mode 100755
index 000000000..e7c01e490
--- /dev/null
+++ b/infra/luci/main.star
@@ -0,0 +1,110 @@
+#!/usr/bin/env lucicfg
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+lucicfg.check_version("1.30.9", "Please update depot_tools")
+
+# Use LUCI Scheduler BBv2 names and add Scheduler realms configs.
+lucicfg.enable_experiment("crbug.com/1182002")
+
+# Enable bbagent.
+luci.recipe.defaults.use_bbagent.set(True)
+
+lucicfg.config(
+ config_dir = "generated",
+ fail_on_warnings = True,
+)
+
+luci.project(
+ name = "perfetto",
+ buildbucket = "cr-buildbucket.appspot.com",
+ logdog = "luci-logdog",
+ milo = "luci-milo",
+ scheduler = "luci-scheduler",
+ swarming = "chrome-swarming.appspot.com",
+ acls = [
+ acl.entry(
+ [
+ acl.BUILDBUCKET_READER,
+ acl.LOGDOG_READER,
+ acl.PROJECT_CONFIGS_READER,
+ acl.SCHEDULER_READER,
+ ],
+ groups = ["all"],
+ ),
+ acl.entry(roles = acl.SCHEDULER_OWNER, groups = "mdb/perfetto-cloud-infra"),
+ acl.entry([acl.LOGDOG_WRITER], groups = ["luci-logdog-chromium-writers"]),
+ ],
+)
+
+# Use the default Chromium logdog instance as:
+# a) we expect our logs to be very minimal
+# b) we are open source so there's nothing special in our logs.
+luci.logdog(
+ gs_bucket = "chromium-luci-logdog",
+)
+
+# Create a realm for the official pool.
+# Used by LUCI infra (Googlers: see pools.cfg) to enforce ACLs.
+luci.realm(name = "pools/official")
+
+# Bucket used by all official builders.
+luci.bucket(
+ name = "official",
+ acls = [
+ acl.entry(
+ roles = [acl.BUILDBUCKET_TRIGGERER],
+ groups = ["mdb/perfetto-cloud-infra"],
+ ),
+ acl.entry(
+ roles = [acl.SCHEDULER_TRIGGERER, acl.BUILDBUCKET_TRIGGERER],
+ groups = ["mdb/chrome-troopers"],
+ ),
+ ],
+)
+
+def official_builder(name, os, caches=[]):
+ luci.builder(
+ name = name,
+ bucket = "official",
+ executable = luci.recipe(
+ name = "perfetto",
+ cipd_package = "infra/recipe_bundles/android.googlesource.com/platform/external/perfetto",
+ cipd_version = "refs/heads/master",
+ use_python3 = True,
+ ),
+ dimensions = {
+ "pool": "luci.perfetto.official",
+ "os": os,
+ "cpu": "x86-64",
+ },
+ service_account = "perfetto-luci-official-builder@chops-service-accounts.iam.gserviceaccount.com",
+ triggered_by = [
+ luci.gitiles_poller(
+ name = "perfetto-gitiles-trigger",
+ bucket = "official",
+ repo = "https://android.googlesource.com/platform/external/perfetto",
+ refs = ["refs/tags/v.+"],
+ ),
+ ],
+ caches = [
+ swarming.cache(cache, name = cache)
+ for cache in caches
+ ]
+ )
+
+official_builder("perfetto-official-builder-linux", "Linux")
+official_builder("perfetto-official-builder-mac", "Mac", ["macos_sdk"])
+official_builder("perfetto-official-builder-windows", "Windows", ["windows_sdk"])
+official_builder("perfetto-official-builder-android", "Linux")
diff --git a/infra/luci/recipe_modules/macos_sdk/__init__.py b/infra/luci/recipe_modules/macos_sdk/__init__.py
new file mode 100644
index 000000000..6a20ec1da
--- /dev/null
+++ b/infra/luci/recipe_modules/macos_sdk/__init__.py
@@ -0,0 +1,54 @@
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DEPS = [
+ 'recipe_engine/cipd',
+ 'recipe_engine/context',
+ 'recipe_engine/json',
+ 'recipe_engine/path',
+ 'recipe_engine/platform',
+ 'recipe_engine/step',
+]
+
+from recipe_engine.recipe_api import Property
+from recipe_engine.config import ConfigGroup, Single
+
+PROPERTIES = {
+ '$perfetto/macos_sdk':
+ Property(
+ help='Properties specifically for the macos_sdk module.',
+ param_name='sdk_properties',
+ kind=ConfigGroup( # pylint: disable=line-too-long
+ # XCode build version number. Internally maps to an XCode build id like
+ # '9c40b'. See
+ #
+ # https://chrome-infra-packages.appspot.com/p/infra_internal/ios/xcode/mac/+/
+ #
+ # For an up to date list of the latest SDK builds.
+ sdk_version=Single(str),
+
+ # The CIPD toolchain tool package and version.
+ tool_pkg=Single(str),
+ tool_ver=Single(str),
+ ),
+ default={
+ 'sdk_version':
+ '13C5066c',
+ 'tool_package':
+ 'infra/tools/mac_toolchain/${platform}',
+ 'tool_version':
+ 'git_revision:e9b1fe29fe21a1cd36428c43ea2aba244bd31280',
+ },
+ )
+}
diff --git a/infra/luci/recipe_modules/macos_sdk/api.py b/infra/luci/recipe_modules/macos_sdk/api.py
new file mode 100644
index 000000000..06feafb39
--- /dev/null
+++ b/infra/luci/recipe_modules/macos_sdk/api.py
@@ -0,0 +1,108 @@
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""The `macos_sdk` module provides safe functions to access a semi-hermetic
+XCode installation.
+
+Available only to Google-run bots."""
+
+from contextlib import contextmanager
+
+from recipe_engine import recipe_api
+
+
+class MacOSSDKApi(recipe_api.RecipeApi):
+ """API for using OS X SDK distributed via CIPD."""
+
+ def __init__(self, sdk_properties, *args, **kwargs):
+ super(MacOSSDKApi, self).__init__(*args, **kwargs)
+
+ self._sdk_dir = None
+ self._sdk_version = sdk_properties['sdk_version'].lower()
+ self._tool_package = sdk_properties['tool_package']
+ self._tool_version = sdk_properties['tool_version']
+
+ @property
+ def sdk_dir(self):
+ assert self._sdk_dir
+ return self._sdk_dir
+
+ @contextmanager
+ def __call__(self):
+ """Sets up the XCode SDK environment.
+
+ This call is a no-op on non-Mac platforms.
+
+ This will deploy the helper tool and the XCode.app bundle at
+ `[START_DIR]/cache/macos_sdk`.
+
+ To avoid machines rebuilding these on every run, set up a named cache in
+ your cr-buildbucket.cfg file like:
+
+ caches: {
+ # Cache for mac_toolchain tool and XCode.app
+ name: "macos_sdk"
+ path: "macos_sdk"
+ }
+
+ If you have builders which e.g. use a non-current SDK, you can give them
+ a uniqely named cache:
+
+ caches: {
+ # Cache for N-1 version mac_toolchain tool and XCode.app
+ name: "macos_sdk_old"
+ path: "macos_sdk"
+ }
+
+ Usage:
+ with api.macos_sdk():
+ # sdk with mac build bits
+
+ Raises:
+ StepFailure or InfraFailure.
+ """
+ if not self.m.platform.is_mac:
+ yield
+ return
+
+ try:
+ with self.m.context(infra_steps=True):
+ self._sdk_dir = self._ensure_sdk()
+ self.m.step('select XCode',
+ ['sudo', 'xcode-select', '--switch', self._sdk_dir])
+ yield
+ finally:
+ with self.m.context(infra_steps=True):
+ self.m.step('reset XCode', ['sudo', 'xcode-select', '--reset'])
+
+ def _ensure_sdk(self):
+ """Ensures the mac_toolchain tool and MacOS SDK packages are installed.
+
+ Returns Path to the installed sdk app bundle."""
+ cache_dir = self.m.path['cache'].join('macos_sdk')
+ pkgs = self.m.cipd.EnsureFile()
+ pkgs.add_package(self._tool_package, self._tool_version)
+ self.m.cipd.ensure(cache_dir, pkgs)
+
+ sdk_dir = cache_dir.join('XCode.app')
+ self.m.step('install xcode', [
+ cache_dir.join('mac_toolchain'),
+ 'install',
+ '-kind',
+ 'mac',
+ '-xcode-version',
+ self._sdk_version,
+ '-output-dir',
+ sdk_dir,
+ ])
+ return sdk_dir
diff --git a/infra/luci/recipe_modules/macos_sdk/examples/full.expected/linux.json b/infra/luci/recipe_modules/macos_sdk/examples/full.expected/linux.json
new file mode 100644
index 000000000..5b0f35212
--- /dev/null
+++ b/infra/luci/recipe_modules/macos_sdk/examples/full.expected/linux.json
@@ -0,0 +1,21 @@
+[
+ {
+ "cmd": [
+ "gn",
+ "gen",
+ "out/Release"
+ ],
+ "name": "gn"
+ },
+ {
+ "cmd": [
+ "ninja",
+ "-C",
+ "out/Release"
+ ],
+ "name": "ninja"
+ },
+ {
+ "name": "$result"
+ }
+] \ No newline at end of file
diff --git a/infra/luci/recipe_modules/macos_sdk/examples/full.expected/mac.json b/infra/luci/recipe_modules/macos_sdk/examples/full.expected/mac.json
new file mode 100644
index 000000000..7d0f197ae
--- /dev/null
+++ b/infra/luci/recipe_modules/macos_sdk/examples/full.expected/mac.json
@@ -0,0 +1,83 @@
+[
+ {
+ "cmd": [
+ "cipd",
+ "ensure",
+ "-root",
+ "[CACHE]/macos_sdk",
+ "-ensure-file",
+ "infra/tools/mac_toolchain/${platform} git_revision:e9b1fe29fe21a1cd36428c43ea2aba244bd31280",
+ "-max-threads",
+ "0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "infra_step": true,
+ "name": "ensure_installed",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"resolved-instance_id-of-git_revision:e9b\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"infra/tools/mac_toolchain/resolved-platform\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ ]@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "[CACHE]/macos_sdk/mac_toolchain",
+ "install",
+ "-kind",
+ "mac",
+ "-xcode-version",
+ "13c5066c",
+ "-output-dir",
+ "[CACHE]/macos_sdk/XCode.app"
+ ],
+ "infra_step": true,
+ "name": "install xcode"
+ },
+ {
+ "cmd": [
+ "sudo",
+ "xcode-select",
+ "--switch",
+ "[CACHE]/macos_sdk/XCode.app"
+ ],
+ "infra_step": true,
+ "name": "select XCode"
+ },
+ {
+ "cmd": [
+ "gn",
+ "gen",
+ "out/Release"
+ ],
+ "name": "gn"
+ },
+ {
+ "cmd": [
+ "ninja",
+ "-C",
+ "out/Release"
+ ],
+ "name": "ninja"
+ },
+ {
+ "cmd": [
+ "sudo",
+ "xcode-select",
+ "--reset"
+ ],
+ "infra_step": true,
+ "name": "reset XCode"
+ },
+ {
+ "name": "$result"
+ }
+] \ No newline at end of file
diff --git a/infra/luci/recipe_modules/macos_sdk/examples/full.expected/win.json b/infra/luci/recipe_modules/macos_sdk/examples/full.expected/win.json
new file mode 100644
index 000000000..5b0f35212
--- /dev/null
+++ b/infra/luci/recipe_modules/macos_sdk/examples/full.expected/win.json
@@ -0,0 +1,21 @@
+[
+ {
+ "cmd": [
+ "gn",
+ "gen",
+ "out/Release"
+ ],
+ "name": "gn"
+ },
+ {
+ "cmd": [
+ "ninja",
+ "-C",
+ "out/Release"
+ ],
+ "name": "ninja"
+ },
+ {
+ "name": "$result"
+ }
+] \ No newline at end of file
diff --git a/infra/luci/recipe_modules/macos_sdk/examples/full.py b/infra/luci/recipe_modules/macos_sdk/examples/full.py
new file mode 100644
index 000000000..6d7ded38c
--- /dev/null
+++ b/infra/luci/recipe_modules/macos_sdk/examples/full.py
@@ -0,0 +1,33 @@
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DEPS = [
+ 'macos_sdk',
+ 'recipe_engine/platform',
+ 'recipe_engine/properties',
+ 'recipe_engine/step',
+]
+
+
+def RunSteps(api):
+ with api.macos_sdk():
+ sdk_dir = api.macos_sdk.sdk_dir if api.platform.is_mac else None
+ api.step('gn', ['gn', 'gen', 'out/Release'])
+ api.step('ninja', ['ninja', '-C', 'out/Release'])
+
+
+def GenTests(api):
+ for platform in ('linux', 'mac', 'win'):
+ yield (api.test(platform) + api.platform.name(platform) +
+ api.properties.generic(buildername='test_builder')) \ No newline at end of file
diff --git a/infra/luci/recipe_modules/windows_sdk/__init__.py b/infra/luci/recipe_modules/windows_sdk/__init__.py
new file mode 100644
index 000000000..f86fd542b
--- /dev/null
+++ b/infra/luci/recipe_modules/windows_sdk/__init__.py
@@ -0,0 +1,41 @@
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DEPS = [
+ 'recipe_engine/cipd',
+ 'recipe_engine/context',
+ 'recipe_engine/json',
+ 'recipe_engine/path',
+ 'recipe_engine/platform',
+ 'recipe_engine/step',
+]
+
+from recipe_engine.recipe_api import Property
+from recipe_engine.config import ConfigGroup, Single
+
+PROPERTIES = {
+ '$perfetto/windows_sdk':
+ Property(
+ help='Properties specifically for the windows_sdk module.',
+ param_name='sdk_properties',
+ kind=ConfigGroup(
+ # The CIPD package and version.
+ sdk_package=Single(str),
+ sdk_version=Single(str)),
+ default={
+ 'sdk_package': 'chrome_internal/third_party/sdk/windows',
+ 'sdk_version': 'uploaded:2019-09-06'
+ },
+ )
+} \ No newline at end of file
diff --git a/infra/luci/recipe_modules/windows_sdk/api.py b/infra/luci/recipe_modules/windows_sdk/api.py
new file mode 100644
index 000000000..921f37a4b
--- /dev/null
+++ b/infra/luci/recipe_modules/windows_sdk/api.py
@@ -0,0 +1,114 @@
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from contextlib import contextmanager
+
+from recipe_engine import recipe_api
+
+
+class WindowsSDKApi(recipe_api.RecipeApi):
+ """API for using Windows SDK distributed via CIPD."""
+
+ def __init__(self, sdk_properties, *args, **kwargs):
+ super(WindowsSDKApi, self).__init__(*args, **kwargs)
+
+ self._sdk_package = sdk_properties['sdk_package']
+ self._sdk_version = sdk_properties['sdk_version']
+
+ @contextmanager
+ def __call__(self):
+ """Setups the Windows SDK environment.
+
+ This call is a no-op on non-Windows platforms.
+
+ Raises:
+ StepFailure or InfraFailure.
+ """
+ if not self.m.platform.is_win:
+ yield
+ return
+
+ with self.m.context(infra_steps=True):
+ sdk_dir = self._ensure_sdk()
+ with self.m.context(**self._sdk_env(sdk_dir)):
+ yield
+
+ def _ensure_sdk(self):
+ """Ensures the Windows SDK CIPD package is installed.
+
+ Returns the directory where the SDK package has been installed.
+
+ Args:
+ path (path): Path to a directory.
+ version (str): CIPD instance ID, tag or ref.
+ """
+ sdk_dir = self.m.path['cache'].join('windows_sdk')
+ pkgs = self.m.cipd.EnsureFile()
+ pkgs.add_package(self._sdk_package, self._sdk_version)
+ self.m.cipd.ensure(sdk_dir, pkgs)
+ return sdk_dir
+
+ def _sdk_env(self, sdk_dir):
+ """Constructs the environment for the SDK.
+
+ Returns environment and environment prefixes.
+
+ Args:
+ sdk_dir (path): Path to a directory containing the SDK.
+ """
+ env = {}
+ env_prefixes = {}
+
+ # Load .../win_sdk/bin/SetEnv.${arch}.json to extract the required
+ # environment. It contains a dict that looks like this:
+ # {
+ # "env": {
+ # "VAR": [["..", "..", "x"], ["..", "..", "y"]],
+ # ...
+ # }
+ # }
+ # All these environment variables need to be added to the environment
+ # for the compiler and linker to work.
+ filename = 'SetEnv.%s.json' % {32: 'x86', 64: 'x64'}[self.m.platform.bits]
+ step_result = self.m.json.read(
+ 'read %s' % filename,
+ sdk_dir.join('win_sdk', 'bin', filename),
+ step_test_data=lambda: self.m.json.test_api.output({
+ 'env': {
+ 'PATH': [['..', '..', 'win_sdk', 'bin', 'x64']],
+ 'VSINSTALLDIR': [['..', '..\\']],
+ },
+ }))
+ data = step_result.json.output.get('env')
+ for key in data:
+ # recipes' Path() does not like .., ., \, or /, so this is cumbersome.
+ # What we want to do is:
+ # [sdk_bin_dir.join(*e) for e in env[k]]
+ # Instead do that badly, and rely (but verify) on the fact that the paths
+ # are all specified relative to the root, but specified relative to
+ # win_sdk/bin (i.e. everything starts with "../../".)
+ results = []
+ for value in data[key]:
+ assert value[0] == '..' and (value[1] == '..' or value[1] == '..\\')
+ results.append('%s' % sdk_dir.join(*value[2:]))
+
+ # PATH is special-cased because we don't want to overwrite other things
+ # like C:\Windows\System32. Others are replacements because prepending
+ # doesn't necessarily makes sense, like VSINSTALLDIR.
+ if key.lower() == 'path':
+ env_prefixes[key] = results
+ else:
+ env[key] = ';'.join(results)
+
+ return {'env': env, 'env_prefixes': env_prefixes}
diff --git a/infra/luci/recipe_modules/windows_sdk/examples/full.expected/linux.json b/infra/luci/recipe_modules/windows_sdk/examples/full.expected/linux.json
new file mode 100644
index 000000000..5b0f35212
--- /dev/null
+++ b/infra/luci/recipe_modules/windows_sdk/examples/full.expected/linux.json
@@ -0,0 +1,21 @@
+[
+ {
+ "cmd": [
+ "gn",
+ "gen",
+ "out/Release"
+ ],
+ "name": "gn"
+ },
+ {
+ "cmd": [
+ "ninja",
+ "-C",
+ "out/Release"
+ ],
+ "name": "ninja"
+ },
+ {
+ "name": "$result"
+ }
+] \ No newline at end of file
diff --git a/infra/luci/recipe_modules/windows_sdk/examples/full.expected/mac.json b/infra/luci/recipe_modules/windows_sdk/examples/full.expected/mac.json
new file mode 100644
index 000000000..5b0f35212
--- /dev/null
+++ b/infra/luci/recipe_modules/windows_sdk/examples/full.expected/mac.json
@@ -0,0 +1,21 @@
+[
+ {
+ "cmd": [
+ "gn",
+ "gen",
+ "out/Release"
+ ],
+ "name": "gn"
+ },
+ {
+ "cmd": [
+ "ninja",
+ "-C",
+ "out/Release"
+ ],
+ "name": "ninja"
+ },
+ {
+ "name": "$result"
+ }
+] \ No newline at end of file
diff --git a/infra/luci/recipe_modules/windows_sdk/examples/full.expected/win.json b/infra/luci/recipe_modules/windows_sdk/examples/full.expected/win.json
new file mode 100644
index 000000000..b3252755f
--- /dev/null
+++ b/infra/luci/recipe_modules/windows_sdk/examples/full.expected/win.json
@@ -0,0 +1,98 @@
+[
+ {
+ "cmd": [
+ "cipd.bat",
+ "ensure",
+ "-root",
+ "[CACHE]\\windows_sdk",
+ "-ensure-file",
+ "chrome_internal/third_party/sdk/windows uploaded:2019-09-06",
+ "-max-threads",
+ "0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "infra_step": true,
+ "name": "ensure_installed",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"resolved-instance_id-of-uploaded:2019-09\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"chrome_internal/third_party/sdk/windows\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ ]@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "\nimport shutil\nimport sys\nshutil.copy(sys.argv[1], sys.argv[2])\n",
+ "[CACHE]\\windows_sdk\\win_sdk\\bin\\SetEnv.x64.json",
+ "/path/to/tmp/json"
+ ],
+ "name": "read SetEnv.x64.json",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"env\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"PATH\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ [@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"..\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"..\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"win_sdk\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"bin\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"x64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ ]@@@",
+ "@@@STEP_LOG_LINE@json.output@ ], @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"VSINSTALLDIR\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ [@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"..\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"..\\\\\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ ]@@@",
+ "@@@STEP_LOG_LINE@json.output@ ]@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "gn",
+ "gen",
+ "out/Release"
+ ],
+ "env": {
+ "VSINSTALLDIR": "[CACHE]\\windows_sdk"
+ },
+ "env_prefixes": {
+ "PATH": [
+ "[CACHE]\\windows_sdk\\win_sdk\\bin\\x64"
+ ]
+ },
+ "name": "gn"
+ },
+ {
+ "cmd": [
+ "ninja",
+ "-C",
+ "out/Release"
+ ],
+ "env": {
+ "VSINSTALLDIR": "[CACHE]\\windows_sdk"
+ },
+ "env_prefixes": {
+ "PATH": [
+ "[CACHE]\\windows_sdk\\win_sdk\\bin\\x64"
+ ]
+ },
+ "name": "ninja"
+ },
+ {
+ "name": "$result"
+ }
+] \ No newline at end of file
diff --git a/infra/luci/recipe_modules/windows_sdk/examples/full.py b/infra/luci/recipe_modules/windows_sdk/examples/full.py
new file mode 100644
index 000000000..82ab06baa
--- /dev/null
+++ b/infra/luci/recipe_modules/windows_sdk/examples/full.py
@@ -0,0 +1,35 @@
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DEPS = [
+ 'windows_sdk',
+ 'recipe_engine/platform',
+ 'recipe_engine/properties',
+ 'recipe_engine/step',
+]
+
+
+def RunSteps(api):
+ with api.windows_sdk():
+ api.step('gn', ['gn', 'gen', 'out/Release'])
+ api.step('ninja', ['ninja', '-C', 'out/Release'])
+
+
+def GenTests(api):
+ for platform in ('linux', 'mac', 'win'):
+ properties = {
+ 'buildername': 'test_builder',
+ }
+ yield (api.test(platform) + api.platform.name(platform) +
+ api.properties.generic(**properties)) \ No newline at end of file
diff --git a/infra/luci/recipes/perfetto.expected/ci_android.json b/infra/luci/recipes/perfetto.expected/ci_android.json
new file mode 100644
index 000000000..3cad1f084
--- /dev/null
+++ b/infra/luci/recipes/perfetto.expected/ci_android.json
@@ -0,0 +1,1702 @@
+[
+ {
+ "cmd": [],
+ "name": "git"
+ },
+ {
+ "cmd": [
+ "vpython",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "ensure-directory",
+ "--mode",
+ "0777",
+ "[CACHE]/builder/perfetto"
+ ],
+ "infra_step": true,
+ "name": "git.ensure source dir",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "init",
+ "[CACHE]/builder/perfetto"
+ ],
+ "infra_step": true,
+ "name": "git.init",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "fetch",
+ "--tags",
+ "https://android.googlesource.com/platform/external/perfetto",
+ "refs/heads/master"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "git.fetch",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "checkout",
+ "FETCH_HEAD"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "git.checkout",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "rev-parse",
+ "HEAD"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "git.rev-parse",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/install-build-deps",
+ "--android"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "build-deps"
+ },
+ {
+ "cmd": [],
+ "name": "android-arm"
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/gn",
+ "gen",
+ "[CACHE]/builder/perfetto/out/android-arm",
+ "--args=is_debug=false monolithic_binaries=true target_os=\"android\" target_cpu=\"arm\""
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm.gn gen",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/ninja",
+ "-C",
+ "[CACHE]/builder/perfetto/out/android-arm",
+ "trace_processor_shell",
+ "tracebox",
+ "perfetto",
+ "traced",
+ "traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm.ninja",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "android-arm.Artifact upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/android-arm/stripped/trace_processor_shell",
+ "gs://perfetto-luci-artifacts//android-arm/trace_processor_shell"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "android-arm.Artifact upload.gsutil upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//android-arm/trace_processor_shell@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"trace_processor_shell\"}], \"install_mode\": \"\", \"package\": \"perfetto/trace_processor_shell/android-arm\", \"root\": \"[CACHE]/builder/perfetto/out/android-arm/stripped\"}",
+ "-out",
+ "[CLEANUP]/trace_processor_shell-android-arm.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm.Artifact upload.build perfetto/trace_processor_shell/android-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/android-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/trace_processor_shell-android-arm.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm.Artifact upload.register perfetto/trace_processor_shell/android-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/android-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/trace_processor_shell/android-arm@https://chrome-infra-packages.appspot.com/p/perfetto/trace_processor_shell/android-arm/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/android-arm/stripped/tracebox",
+ "gs://perfetto-luci-artifacts//android-arm/tracebox"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "android-arm.Artifact upload.gsutil upload (2)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//android-arm/tracebox@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"tracebox\"}], \"install_mode\": \"\", \"package\": \"perfetto/tracebox/android-arm\", \"root\": \"[CACHE]/builder/perfetto/out/android-arm/stripped\"}",
+ "-out",
+ "[CLEANUP]/tracebox-android-arm.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm.Artifact upload.build perfetto/tracebox/android-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/android-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/tracebox-android-arm.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm.Artifact upload.register perfetto/tracebox/android-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/android-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/tracebox/android-arm@https://chrome-infra-packages.appspot.com/p/perfetto/tracebox/android-arm/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/android-arm/stripped/perfetto",
+ "gs://perfetto-luci-artifacts//android-arm/perfetto"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "android-arm.Artifact upload.gsutil upload (3)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//android-arm/perfetto@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"perfetto\"}], \"install_mode\": \"\", \"package\": \"perfetto/perfetto/android-arm\", \"root\": \"[CACHE]/builder/perfetto/out/android-arm/stripped\"}",
+ "-out",
+ "[CLEANUP]/perfetto-android-arm.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm.Artifact upload.build perfetto/perfetto/android-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/android-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/perfetto-android-arm.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm.Artifact upload.register perfetto/perfetto/android-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/android-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/perfetto/android-arm@https://chrome-infra-packages.appspot.com/p/perfetto/perfetto/android-arm/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/android-arm/stripped/traced",
+ "gs://perfetto-luci-artifacts//android-arm/traced"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "android-arm.Artifact upload.gsutil upload (4)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//android-arm/traced@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced/android-arm\", \"root\": \"[CACHE]/builder/perfetto/out/android-arm/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced-android-arm.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm.Artifact upload.build perfetto/traced/android-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/android-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced-android-arm.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm.Artifact upload.register perfetto/traced/android-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/android-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced/android-arm@https://chrome-infra-packages.appspot.com/p/perfetto/traced/android-arm/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/android-arm/stripped/traced_probes",
+ "gs://perfetto-luci-artifacts//android-arm/traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "android-arm.Artifact upload.gsutil upload (5)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//android-arm/traced_probes@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced_probes\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced_probes/android-arm\", \"root\": \"[CACHE]/builder/perfetto/out/android-arm/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced_probes-android-arm.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm.Artifact upload.build perfetto/traced_probes/android-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/android-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced_probes-android-arm.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm.Artifact upload.register perfetto/traced_probes/android-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/android-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced_probes/android-arm@https://chrome-infra-packages.appspot.com/p/perfetto/traced_probes/android-arm/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "android-arm64"
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/gn",
+ "gen",
+ "[CACHE]/builder/perfetto/out/android-arm64",
+ "--args=is_debug=false monolithic_binaries=true target_os=\"android\" target_cpu=\"arm64\""
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm64.gn gen",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/ninja",
+ "-C",
+ "[CACHE]/builder/perfetto/out/android-arm64",
+ "trace_processor_shell",
+ "tracebox",
+ "perfetto",
+ "traced",
+ "traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm64.ninja",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "android-arm64.Artifact upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/android-arm64/stripped/trace_processor_shell",
+ "gs://perfetto-luci-artifacts//android-arm64/trace_processor_shell"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "android-arm64.Artifact upload.gsutil upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//android-arm64/trace_processor_shell@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"trace_processor_shell\"}], \"install_mode\": \"\", \"package\": \"perfetto/trace_processor_shell/android-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/android-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/trace_processor_shell-android-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm64.Artifact upload.build perfetto/trace_processor_shell/android-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/android-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/trace_processor_shell-android-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm64.Artifact upload.register perfetto/trace_processor_shell/android-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/android-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/trace_processor_shell/android-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/trace_processor_shell/android-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/android-arm64/stripped/tracebox",
+ "gs://perfetto-luci-artifacts//android-arm64/tracebox"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "android-arm64.Artifact upload.gsutil upload (2)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//android-arm64/tracebox@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"tracebox\"}], \"install_mode\": \"\", \"package\": \"perfetto/tracebox/android-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/android-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/tracebox-android-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm64.Artifact upload.build perfetto/tracebox/android-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/android-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/tracebox-android-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm64.Artifact upload.register perfetto/tracebox/android-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/android-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/tracebox/android-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/tracebox/android-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/android-arm64/stripped/perfetto",
+ "gs://perfetto-luci-artifacts//android-arm64/perfetto"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "android-arm64.Artifact upload.gsutil upload (3)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//android-arm64/perfetto@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"perfetto\"}], \"install_mode\": \"\", \"package\": \"perfetto/perfetto/android-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/android-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/perfetto-android-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm64.Artifact upload.build perfetto/perfetto/android-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/android-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/perfetto-android-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm64.Artifact upload.register perfetto/perfetto/android-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/android-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/perfetto/android-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/perfetto/android-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/android-arm64/stripped/traced",
+ "gs://perfetto-luci-artifacts//android-arm64/traced"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "android-arm64.Artifact upload.gsutil upload (4)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//android-arm64/traced@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced/android-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/android-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced-android-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm64.Artifact upload.build perfetto/traced/android-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/android-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced-android-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm64.Artifact upload.register perfetto/traced/android-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/android-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced/android-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/traced/android-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/android-arm64/stripped/traced_probes",
+ "gs://perfetto-luci-artifacts//android-arm64/traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "android-arm64.Artifact upload.gsutil upload (5)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//android-arm64/traced_probes@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced_probes\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced_probes/android-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/android-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced_probes-android-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm64.Artifact upload.build perfetto/traced_probes/android-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/android-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced_probes-android-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-arm64.Artifact upload.register perfetto/traced_probes/android-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/android-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced_probes/android-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/traced_probes/android-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "android-x86"
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/gn",
+ "gen",
+ "[CACHE]/builder/perfetto/out/android-x86",
+ "--args=is_debug=false monolithic_binaries=true target_os=\"android\" target_cpu=\"x86\""
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x86.gn gen",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/ninja",
+ "-C",
+ "[CACHE]/builder/perfetto/out/android-x86",
+ "trace_processor_shell",
+ "tracebox",
+ "perfetto",
+ "traced",
+ "traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x86.ninja",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "android-x86.Artifact upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/android-x86/stripped/trace_processor_shell",
+ "gs://perfetto-luci-artifacts//android-x86/trace_processor_shell"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "android-x86.Artifact upload.gsutil upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//android-x86/trace_processor_shell@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"trace_processor_shell\"}], \"install_mode\": \"\", \"package\": \"perfetto/trace_processor_shell/android-x86\", \"root\": \"[CACHE]/builder/perfetto/out/android-x86/stripped\"}",
+ "-out",
+ "[CLEANUP]/trace_processor_shell-android-x86.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x86.Artifact upload.build perfetto/trace_processor_shell/android-x86",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/android-x86\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/trace_processor_shell-android-x86.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x86.Artifact upload.register perfetto/trace_processor_shell/android-x86",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/android-x86\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/trace_processor_shell/android-x86@https://chrome-infra-packages.appspot.com/p/perfetto/trace_processor_shell/android-x86/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/android-x86/stripped/tracebox",
+ "gs://perfetto-luci-artifacts//android-x86/tracebox"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "android-x86.Artifact upload.gsutil upload (2)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//android-x86/tracebox@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"tracebox\"}], \"install_mode\": \"\", \"package\": \"perfetto/tracebox/android-x86\", \"root\": \"[CACHE]/builder/perfetto/out/android-x86/stripped\"}",
+ "-out",
+ "[CLEANUP]/tracebox-android-x86.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x86.Artifact upload.build perfetto/tracebox/android-x86",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/android-x86\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/tracebox-android-x86.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x86.Artifact upload.register perfetto/tracebox/android-x86",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/android-x86\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/tracebox/android-x86@https://chrome-infra-packages.appspot.com/p/perfetto/tracebox/android-x86/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/android-x86/stripped/perfetto",
+ "gs://perfetto-luci-artifacts//android-x86/perfetto"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "android-x86.Artifact upload.gsutil upload (3)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//android-x86/perfetto@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"perfetto\"}], \"install_mode\": \"\", \"package\": \"perfetto/perfetto/android-x86\", \"root\": \"[CACHE]/builder/perfetto/out/android-x86/stripped\"}",
+ "-out",
+ "[CLEANUP]/perfetto-android-x86.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x86.Artifact upload.build perfetto/perfetto/android-x86",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/android-x86\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/perfetto-android-x86.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x86.Artifact upload.register perfetto/perfetto/android-x86",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/android-x86\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/perfetto/android-x86@https://chrome-infra-packages.appspot.com/p/perfetto/perfetto/android-x86/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/android-x86/stripped/traced",
+ "gs://perfetto-luci-artifacts//android-x86/traced"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "android-x86.Artifact upload.gsutil upload (4)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//android-x86/traced@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced/android-x86\", \"root\": \"[CACHE]/builder/perfetto/out/android-x86/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced-android-x86.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x86.Artifact upload.build perfetto/traced/android-x86",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/android-x86\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced-android-x86.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x86.Artifact upload.register perfetto/traced/android-x86",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/android-x86\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced/android-x86@https://chrome-infra-packages.appspot.com/p/perfetto/traced/android-x86/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/android-x86/stripped/traced_probes",
+ "gs://perfetto-luci-artifacts//android-x86/traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "android-x86.Artifact upload.gsutil upload (5)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//android-x86/traced_probes@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced_probes\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced_probes/android-x86\", \"root\": \"[CACHE]/builder/perfetto/out/android-x86/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced_probes-android-x86.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x86.Artifact upload.build perfetto/traced_probes/android-x86",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/android-x86\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced_probes-android-x86.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x86.Artifact upload.register perfetto/traced_probes/android-x86",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/android-x86\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced_probes/android-x86@https://chrome-infra-packages.appspot.com/p/perfetto/traced_probes/android-x86/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "android-x64"
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/gn",
+ "gen",
+ "[CACHE]/builder/perfetto/out/android-x64",
+ "--args=is_debug=false monolithic_binaries=true target_os=\"android\" target_cpu=\"x64\""
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x64.gn gen",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/ninja",
+ "-C",
+ "[CACHE]/builder/perfetto/out/android-x64",
+ "trace_processor_shell",
+ "tracebox",
+ "perfetto",
+ "traced",
+ "traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x64.ninja",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "android-x64.Artifact upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/android-x64/stripped/trace_processor_shell",
+ "gs://perfetto-luci-artifacts//android-x64/trace_processor_shell"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "android-x64.Artifact upload.gsutil upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//android-x64/trace_processor_shell@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"trace_processor_shell\"}], \"install_mode\": \"\", \"package\": \"perfetto/trace_processor_shell/android-x64\", \"root\": \"[CACHE]/builder/perfetto/out/android-x64/stripped\"}",
+ "-out",
+ "[CLEANUP]/trace_processor_shell-android-x64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x64.Artifact upload.build perfetto/trace_processor_shell/android-x64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/android-x64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/trace_processor_shell-android-x64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x64.Artifact upload.register perfetto/trace_processor_shell/android-x64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/android-x64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/trace_processor_shell/android-x64@https://chrome-infra-packages.appspot.com/p/perfetto/trace_processor_shell/android-x64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/android-x64/stripped/tracebox",
+ "gs://perfetto-luci-artifacts//android-x64/tracebox"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "android-x64.Artifact upload.gsutil upload (2)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//android-x64/tracebox@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"tracebox\"}], \"install_mode\": \"\", \"package\": \"perfetto/tracebox/android-x64\", \"root\": \"[CACHE]/builder/perfetto/out/android-x64/stripped\"}",
+ "-out",
+ "[CLEANUP]/tracebox-android-x64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x64.Artifact upload.build perfetto/tracebox/android-x64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/android-x64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/tracebox-android-x64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x64.Artifact upload.register perfetto/tracebox/android-x64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/android-x64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/tracebox/android-x64@https://chrome-infra-packages.appspot.com/p/perfetto/tracebox/android-x64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/android-x64/stripped/perfetto",
+ "gs://perfetto-luci-artifacts//android-x64/perfetto"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "android-x64.Artifact upload.gsutil upload (3)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//android-x64/perfetto@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"perfetto\"}], \"install_mode\": \"\", \"package\": \"perfetto/perfetto/android-x64\", \"root\": \"[CACHE]/builder/perfetto/out/android-x64/stripped\"}",
+ "-out",
+ "[CLEANUP]/perfetto-android-x64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x64.Artifact upload.build perfetto/perfetto/android-x64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/android-x64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/perfetto-android-x64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x64.Artifact upload.register perfetto/perfetto/android-x64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/android-x64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/perfetto/android-x64@https://chrome-infra-packages.appspot.com/p/perfetto/perfetto/android-x64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/android-x64/stripped/traced",
+ "gs://perfetto-luci-artifacts//android-x64/traced"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "android-x64.Artifact upload.gsutil upload (4)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//android-x64/traced@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced/android-x64\", \"root\": \"[CACHE]/builder/perfetto/out/android-x64/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced-android-x64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x64.Artifact upload.build perfetto/traced/android-x64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/android-x64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced-android-x64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x64.Artifact upload.register perfetto/traced/android-x64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/android-x64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced/android-x64@https://chrome-infra-packages.appspot.com/p/perfetto/traced/android-x64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/android-x64/stripped/traced_probes",
+ "gs://perfetto-luci-artifacts//android-x64/traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "android-x64.Artifact upload.gsutil upload (5)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//android-x64/traced_probes@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced_probes\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced_probes/android-x64\", \"root\": \"[CACHE]/builder/perfetto/out/android-x64/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced_probes-android-x64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x64.Artifact upload.build perfetto/traced_probes/android-x64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/android-x64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced_probes-android-x64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "android-x64.Artifact upload.register perfetto/traced_probes/android-x64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/android-x64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced_probes/android-x64@https://chrome-infra-packages.appspot.com/p/perfetto/traced_probes/android-x64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "name": "$result"
+ }
+] \ No newline at end of file
diff --git a/infra/luci/recipes/perfetto.expected/ci_linux.json b/infra/luci/recipes/perfetto.expected/ci_linux.json
index eebe765c2..70056324e 100644
--- a/infra/luci/recipes/perfetto.expected/ci_linux.json
+++ b/infra/luci/recipes/perfetto.expected/ci_linux.json
@@ -39,7 +39,7 @@
"fetch",
"--tags",
"https://android.googlesource.com/platform/external/perfetto",
- "2d72510e447ab60a9728aeea2362d8be2cbd7789"
+ "refs/heads/master"
],
"cwd": "[CACHE]/builder/perfetto",
"infra_step": true,
@@ -63,32 +63,1308 @@
},
{
"cmd": [
+ "git",
+ "rev-parse",
+ "HEAD"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "git.rev-parse",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
"tools/install-build-deps",
- "--ui",
- "--android"
+ "--linux-arm"
],
"cwd": "[CACHE]/builder/perfetto",
"infra_step": true,
"name": "build-deps"
},
{
+ "cmd": [],
+ "name": "linux-amd64"
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/gn",
+ "gen",
+ "[CACHE]/builder/perfetto/out/linux-amd64",
+ "--args=is_debug=false monolithic_binaries=true target_os=\"linux\" target_cpu=\"x64\""
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.gn gen",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/ninja",
+ "-C",
+ "[CACHE]/builder/perfetto/out/linux-amd64",
+ "trace_processor_shell",
+ "trace_to_text",
+ "tracebox",
+ "perfetto",
+ "traced",
+ "traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.ninja",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "linux-amd64.Artifact upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-amd64/stripped/trace_processor_shell",
+ "gs://perfetto-luci-artifacts//linux-amd64/trace_processor_shell"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-amd64.Artifact upload.gsutil upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//linux-amd64/trace_processor_shell@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"trace_processor_shell\"}], \"install_mode\": \"\", \"package\": \"perfetto/trace_processor_shell/linux-amd64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-amd64/stripped\"}",
+ "-out",
+ "[CLEANUP]/trace_processor_shell-linux-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.build perfetto/trace_processor_shell/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/trace_processor_shell-linux-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.register perfetto/trace_processor_shell/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/trace_processor_shell/linux-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/trace_processor_shell/linux-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-amd64/stripped/trace_to_text",
+ "gs://perfetto-luci-artifacts//linux-amd64/trace_to_text"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-amd64.Artifact upload.gsutil upload (2)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//linux-amd64/trace_to_text@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"trace_to_text\"}], \"install_mode\": \"\", \"package\": \"perfetto/trace_to_text/linux-amd64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-amd64/stripped\"}",
+ "-out",
+ "[CLEANUP]/trace_to_text-linux-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.build perfetto/trace_to_text/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_to_text/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/trace_to_text-linux-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.register perfetto/trace_to_text/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_to_text/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/trace_to_text/linux-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/trace_to_text/linux-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-amd64/stripped/tracebox",
+ "gs://perfetto-luci-artifacts//linux-amd64/tracebox"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-amd64.Artifact upload.gsutil upload (3)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//linux-amd64/tracebox@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"tracebox\"}], \"install_mode\": \"\", \"package\": \"perfetto/tracebox/linux-amd64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-amd64/stripped\"}",
+ "-out",
+ "[CLEANUP]/tracebox-linux-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.build perfetto/tracebox/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/tracebox-linux-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.register perfetto/tracebox/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/tracebox/linux-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/tracebox/linux-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-amd64/stripped/perfetto",
+ "gs://perfetto-luci-artifacts//linux-amd64/perfetto"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-amd64.Artifact upload.gsutil upload (4)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//linux-amd64/perfetto@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"perfetto\"}], \"install_mode\": \"\", \"package\": \"perfetto/perfetto/linux-amd64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-amd64/stripped\"}",
+ "-out",
+ "[CLEANUP]/perfetto-linux-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.build perfetto/perfetto/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/perfetto-linux-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.register perfetto/perfetto/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/perfetto/linux-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/perfetto/linux-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-amd64/stripped/traced",
+ "gs://perfetto-luci-artifacts//linux-amd64/traced"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-amd64.Artifact upload.gsutil upload (5)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//linux-amd64/traced@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced/linux-amd64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-amd64/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced-linux-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.build perfetto/traced/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced-linux-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.register perfetto/traced/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced/linux-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/traced/linux-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-amd64/stripped/traced_probes",
+ "gs://perfetto-luci-artifacts//linux-amd64/traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-amd64.Artifact upload.gsutil upload (6)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//linux-amd64/traced_probes@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced_probes\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced_probes/linux-amd64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-amd64/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced_probes-linux-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.build perfetto/traced_probes/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
"cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced_probes-linux-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.register perfetto/traced_probes/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced_probes/linux-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/traced_probes/linux-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "linux-arm"
+ },
+ {
+ "cmd": [
+ "python3",
"tools/gn",
"gen",
- "out/dist",
- "--args=is_debug=false"
+ "[CACHE]/builder/perfetto/out/linux-arm",
+ "--args=is_debug=false monolithic_binaries=true target_os=\"linux\" target_cpu=\"arm\""
],
"cwd": "[CACHE]/builder/perfetto",
- "name": "gn gen"
+ "name": "linux-arm.gn gen",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
},
{
"cmd": [
+ "python3",
"tools/ninja",
"-C",
- "out/dist"
+ "[CACHE]/builder/perfetto/out/linux-arm",
+ "trace_processor_shell",
+ "tracebox",
+ "perfetto",
+ "traced",
+ "traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.ninja",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "linux-arm.Artifact upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-arm/stripped/trace_processor_shell",
+ "gs://perfetto-luci-artifacts//linux-arm/trace_processor_shell"
],
"cwd": "[CACHE]/builder/perfetto",
- "name": "ninja"
+ "infra_step": true,
+ "name": "linux-arm.Artifact upload.gsutil upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//linux-arm/trace_processor_shell@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"trace_processor_shell\"}], \"install_mode\": \"\", \"package\": \"perfetto/trace_processor_shell/linux-arm\", \"root\": \"[CACHE]/builder/perfetto/out/linux-arm/stripped\"}",
+ "-out",
+ "[CLEANUP]/trace_processor_shell-linux-arm.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.Artifact upload.build perfetto/trace_processor_shell/linux-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/linux-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/trace_processor_shell-linux-arm.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.Artifact upload.register perfetto/trace_processor_shell/linux-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/linux-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/trace_processor_shell/linux-arm@https://chrome-infra-packages.appspot.com/p/perfetto/trace_processor_shell/linux-arm/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-arm/stripped/tracebox",
+ "gs://perfetto-luci-artifacts//linux-arm/tracebox"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-arm.Artifact upload.gsutil upload (2)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//linux-arm/tracebox@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"tracebox\"}], \"install_mode\": \"\", \"package\": \"perfetto/tracebox/linux-arm\", \"root\": \"[CACHE]/builder/perfetto/out/linux-arm/stripped\"}",
+ "-out",
+ "[CLEANUP]/tracebox-linux-arm.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.Artifact upload.build perfetto/tracebox/linux-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/linux-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/tracebox-linux-arm.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.Artifact upload.register perfetto/tracebox/linux-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/linux-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/tracebox/linux-arm@https://chrome-infra-packages.appspot.com/p/perfetto/tracebox/linux-arm/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-arm/stripped/perfetto",
+ "gs://perfetto-luci-artifacts//linux-arm/perfetto"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-arm.Artifact upload.gsutil upload (3)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//linux-arm/perfetto@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"perfetto\"}], \"install_mode\": \"\", \"package\": \"perfetto/perfetto/linux-arm\", \"root\": \"[CACHE]/builder/perfetto/out/linux-arm/stripped\"}",
+ "-out",
+ "[CLEANUP]/perfetto-linux-arm.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.Artifact upload.build perfetto/perfetto/linux-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/linux-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/perfetto-linux-arm.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.Artifact upload.register perfetto/perfetto/linux-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/linux-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/perfetto/linux-arm@https://chrome-infra-packages.appspot.com/p/perfetto/perfetto/linux-arm/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-arm/stripped/traced",
+ "gs://perfetto-luci-artifacts//linux-arm/traced"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-arm.Artifact upload.gsutil upload (4)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//linux-arm/traced@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced/linux-arm\", \"root\": \"[CACHE]/builder/perfetto/out/linux-arm/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced-linux-arm.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.Artifact upload.build perfetto/traced/linux-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/linux-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced-linux-arm.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.Artifact upload.register perfetto/traced/linux-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/linux-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced/linux-arm@https://chrome-infra-packages.appspot.com/p/perfetto/traced/linux-arm/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-arm/stripped/traced_probes",
+ "gs://perfetto-luci-artifacts//linux-arm/traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-arm.Artifact upload.gsutil upload (5)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//linux-arm/traced_probes@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced_probes\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced_probes/linux-arm\", \"root\": \"[CACHE]/builder/perfetto/out/linux-arm/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced_probes-linux-arm.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.Artifact upload.build perfetto/traced_probes/linux-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/linux-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced_probes-linux-arm.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.Artifact upload.register perfetto/traced_probes/linux-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/linux-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced_probes/linux-arm@https://chrome-infra-packages.appspot.com/p/perfetto/traced_probes/linux-arm/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "linux-arm64"
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/gn",
+ "gen",
+ "[CACHE]/builder/perfetto/out/linux-arm64",
+ "--args=is_debug=false monolithic_binaries=true target_os=\"linux\" target_cpu=\"arm64\""
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.gn gen",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/ninja",
+ "-C",
+ "[CACHE]/builder/perfetto/out/linux-arm64",
+ "trace_processor_shell",
+ "tracebox",
+ "perfetto",
+ "traced",
+ "traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.ninja",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "linux-arm64.Artifact upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-arm64/stripped/trace_processor_shell",
+ "gs://perfetto-luci-artifacts//linux-arm64/trace_processor_shell"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-arm64.Artifact upload.gsutil upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//linux-arm64/trace_processor_shell@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"trace_processor_shell\"}], \"install_mode\": \"\", \"package\": \"perfetto/trace_processor_shell/linux-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/trace_processor_shell-linux-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.Artifact upload.build perfetto/trace_processor_shell/linux-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/linux-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/trace_processor_shell-linux-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.Artifact upload.register perfetto/trace_processor_shell/linux-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/linux-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/trace_processor_shell/linux-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/trace_processor_shell/linux-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-arm64/stripped/tracebox",
+ "gs://perfetto-luci-artifacts//linux-arm64/tracebox"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-arm64.Artifact upload.gsutil upload (2)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//linux-arm64/tracebox@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"tracebox\"}], \"install_mode\": \"\", \"package\": \"perfetto/tracebox/linux-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/tracebox-linux-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.Artifact upload.build perfetto/tracebox/linux-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/linux-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/tracebox-linux-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.Artifact upload.register perfetto/tracebox/linux-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/linux-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/tracebox/linux-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/tracebox/linux-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-arm64/stripped/perfetto",
+ "gs://perfetto-luci-artifacts//linux-arm64/perfetto"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-arm64.Artifact upload.gsutil upload (3)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//linux-arm64/perfetto@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"perfetto\"}], \"install_mode\": \"\", \"package\": \"perfetto/perfetto/linux-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/perfetto-linux-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.Artifact upload.build perfetto/perfetto/linux-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/linux-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/perfetto-linux-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.Artifact upload.register perfetto/perfetto/linux-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/linux-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/perfetto/linux-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/perfetto/linux-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-arm64/stripped/traced",
+ "gs://perfetto-luci-artifacts//linux-arm64/traced"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-arm64.Artifact upload.gsutil upload (4)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//linux-arm64/traced@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced/linux-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced-linux-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.Artifact upload.build perfetto/traced/linux-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/linux-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced-linux-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.Artifact upload.register perfetto/traced/linux-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/linux-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced/linux-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/traced/linux-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-arm64/stripped/traced_probes",
+ "gs://perfetto-luci-artifacts//linux-arm64/traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-arm64.Artifact upload.gsutil upload (5)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//linux-arm64/traced_probes@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced_probes\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced_probes/linux-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced_probes-linux-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.Artifact upload.build perfetto/traced_probes/linux-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/linux-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced_probes-linux-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.Artifact upload.register perfetto/traced_probes/linux-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/linux-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced_probes/linux-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/traced_probes/linux-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
},
{
"name": "$result"
diff --git a/infra/luci/recipes/perfetto.expected/ci_mac.json b/infra/luci/recipes/perfetto.expected/ci_mac.json
new file mode 100644
index 000000000..4c9f89f3b
--- /dev/null
+++ b/infra/luci/recipes/perfetto.expected/ci_mac.json
@@ -0,0 +1,1193 @@
+[
+ {
+ "cmd": [],
+ "name": "git"
+ },
+ {
+ "cmd": [
+ "vpython",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "ensure-directory",
+ "--mode",
+ "0777",
+ "[CACHE]/builder/perfetto"
+ ],
+ "infra_step": true,
+ "name": "git.ensure source dir",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "init",
+ "[CACHE]/builder/perfetto"
+ ],
+ "infra_step": true,
+ "name": "git.init",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "fetch",
+ "--tags",
+ "https://android.googlesource.com/platform/external/perfetto",
+ "refs/heads/master"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "git.fetch",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "checkout",
+ "FETCH_HEAD"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "git.checkout",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "rev-parse",
+ "HEAD"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "git.rev-parse",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/install-build-deps"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "build-deps"
+ },
+ {
+ "cmd": [],
+ "name": "mac-amd64"
+ },
+ {
+ "cmd": [
+ "cipd",
+ "ensure",
+ "-root",
+ "[CACHE]/macos_sdk",
+ "-ensure-file",
+ "infra/tools/mac_toolchain/${platform} git_revision:e9b1fe29fe21a1cd36428c43ea2aba244bd31280",
+ "-max-threads",
+ "0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "mac-amd64.ensure_installed",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"resolved-instance_id-of-git_revision:e9b\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"infra/tools/mac_toolchain/resolved-platform\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ ]@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "[CACHE]/macos_sdk/mac_toolchain",
+ "install",
+ "-kind",
+ "mac",
+ "-xcode-version",
+ "13c5066c",
+ "-output-dir",
+ "[CACHE]/macos_sdk/XCode.app"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "mac-amd64.install xcode",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "sudo",
+ "xcode-select",
+ "--switch",
+ "[CACHE]/macos_sdk/XCode.app"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "mac-amd64.select XCode",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/gn",
+ "gen",
+ "[CACHE]/builder/perfetto/out/mac-amd64",
+ "--args=is_debug=false monolithic_binaries=true target_os=\"mac\" target_cpu=\"x64\""
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-amd64.gn gen",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/ninja",
+ "-C",
+ "[CACHE]/builder/perfetto/out/mac-amd64",
+ "trace_processor_shell",
+ "trace_to_text",
+ "tracebox",
+ "perfetto",
+ "traced",
+ "traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-amd64.ninja",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "sudo",
+ "xcode-select",
+ "--reset"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "mac-amd64.reset XCode",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "mac-amd64.Artifact upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/mac-amd64/stripped/trace_processor_shell",
+ "gs://perfetto-luci-artifacts//mac-amd64/trace_processor_shell"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "mac-amd64.Artifact upload.gsutil upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//mac-amd64/trace_processor_shell@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"trace_processor_shell\"}], \"install_mode\": \"\", \"package\": \"perfetto/trace_processor_shell/mac-amd64\", \"root\": \"[CACHE]/builder/perfetto/out/mac-amd64/stripped\"}",
+ "-out",
+ "[CLEANUP]/trace_processor_shell-mac-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-amd64.Artifact upload.build perfetto/trace_processor_shell/mac-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/mac-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/trace_processor_shell-mac-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-amd64.Artifact upload.register perfetto/trace_processor_shell/mac-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/mac-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/trace_processor_shell/mac-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/trace_processor_shell/mac-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/mac-amd64/stripped/trace_to_text",
+ "gs://perfetto-luci-artifacts//mac-amd64/trace_to_text"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "mac-amd64.Artifact upload.gsutil upload (2)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//mac-amd64/trace_to_text@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"trace_to_text\"}], \"install_mode\": \"\", \"package\": \"perfetto/trace_to_text/mac-amd64\", \"root\": \"[CACHE]/builder/perfetto/out/mac-amd64/stripped\"}",
+ "-out",
+ "[CLEANUP]/trace_to_text-mac-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-amd64.Artifact upload.build perfetto/trace_to_text/mac-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_to_text/mac-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/trace_to_text-mac-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-amd64.Artifact upload.register perfetto/trace_to_text/mac-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_to_text/mac-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/trace_to_text/mac-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/trace_to_text/mac-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/mac-amd64/stripped/tracebox",
+ "gs://perfetto-luci-artifacts//mac-amd64/tracebox"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "mac-amd64.Artifact upload.gsutil upload (3)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//mac-amd64/tracebox@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"tracebox\"}], \"install_mode\": \"\", \"package\": \"perfetto/tracebox/mac-amd64\", \"root\": \"[CACHE]/builder/perfetto/out/mac-amd64/stripped\"}",
+ "-out",
+ "[CLEANUP]/tracebox-mac-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-amd64.Artifact upload.build perfetto/tracebox/mac-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/mac-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/tracebox-mac-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-amd64.Artifact upload.register perfetto/tracebox/mac-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/mac-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/tracebox/mac-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/tracebox/mac-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/mac-amd64/stripped/perfetto",
+ "gs://perfetto-luci-artifacts//mac-amd64/perfetto"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "mac-amd64.Artifact upload.gsutil upload (4)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//mac-amd64/perfetto@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"perfetto\"}], \"install_mode\": \"\", \"package\": \"perfetto/perfetto/mac-amd64\", \"root\": \"[CACHE]/builder/perfetto/out/mac-amd64/stripped\"}",
+ "-out",
+ "[CLEANUP]/perfetto-mac-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-amd64.Artifact upload.build perfetto/perfetto/mac-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/mac-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/perfetto-mac-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-amd64.Artifact upload.register perfetto/perfetto/mac-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/mac-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/perfetto/mac-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/perfetto/mac-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/mac-amd64/stripped/traced",
+ "gs://perfetto-luci-artifacts//mac-amd64/traced"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "mac-amd64.Artifact upload.gsutil upload (5)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//mac-amd64/traced@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced/mac-amd64\", \"root\": \"[CACHE]/builder/perfetto/out/mac-amd64/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced-mac-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-amd64.Artifact upload.build perfetto/traced/mac-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/mac-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced-mac-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-amd64.Artifact upload.register perfetto/traced/mac-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/mac-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced/mac-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/traced/mac-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/mac-amd64/stripped/traced_probes",
+ "gs://perfetto-luci-artifacts//mac-amd64/traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "mac-amd64.Artifact upload.gsutil upload (6)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//mac-amd64/traced_probes@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced_probes\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced_probes/mac-amd64\", \"root\": \"[CACHE]/builder/perfetto/out/mac-amd64/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced_probes-mac-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-amd64.Artifact upload.build perfetto/traced_probes/mac-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/mac-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced_probes-mac-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-amd64.Artifact upload.register perfetto/traced_probes/mac-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/mac-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced_probes/mac-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/traced_probes/mac-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "mac-arm64"
+ },
+ {
+ "cmd": [
+ "cipd",
+ "ensure",
+ "-root",
+ "[CACHE]/macos_sdk",
+ "-ensure-file",
+ "infra/tools/mac_toolchain/${platform} git_revision:e9b1fe29fe21a1cd36428c43ea2aba244bd31280",
+ "-max-threads",
+ "0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "mac-arm64.ensure_installed",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"resolved-instance_id-of-git_revision:e9b\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"infra/tools/mac_toolchain/resolved-platform\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ ]@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "[CACHE]/macos_sdk/mac_toolchain",
+ "install",
+ "-kind",
+ "mac",
+ "-xcode-version",
+ "13c5066c",
+ "-output-dir",
+ "[CACHE]/macos_sdk/XCode.app"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "mac-arm64.install xcode",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "sudo",
+ "xcode-select",
+ "--switch",
+ "[CACHE]/macos_sdk/XCode.app"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "mac-arm64.select XCode",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/gn",
+ "gen",
+ "[CACHE]/builder/perfetto/out/mac-arm64",
+ "--args=is_debug=false monolithic_binaries=true target_os=\"mac\" target_cpu=\"arm64\""
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-arm64.gn gen",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/ninja",
+ "-C",
+ "[CACHE]/builder/perfetto/out/mac-arm64",
+ "trace_processor_shell",
+ "trace_to_text",
+ "tracebox",
+ "perfetto",
+ "traced",
+ "traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-arm64.ninja",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "sudo",
+ "xcode-select",
+ "--reset"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "mac-arm64.reset XCode",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "mac-arm64.Artifact upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/mac-arm64/stripped/trace_processor_shell",
+ "gs://perfetto-luci-artifacts//mac-arm64/trace_processor_shell"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "mac-arm64.Artifact upload.gsutil upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//mac-arm64/trace_processor_shell@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"trace_processor_shell\"}], \"install_mode\": \"\", \"package\": \"perfetto/trace_processor_shell/mac-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/mac-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/trace_processor_shell-mac-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-arm64.Artifact upload.build perfetto/trace_processor_shell/mac-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/mac-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/trace_processor_shell-mac-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-arm64.Artifact upload.register perfetto/trace_processor_shell/mac-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/mac-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/trace_processor_shell/mac-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/trace_processor_shell/mac-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/mac-arm64/stripped/trace_to_text",
+ "gs://perfetto-luci-artifacts//mac-arm64/trace_to_text"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "mac-arm64.Artifact upload.gsutil upload (2)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//mac-arm64/trace_to_text@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"trace_to_text\"}], \"install_mode\": \"\", \"package\": \"perfetto/trace_to_text/mac-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/mac-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/trace_to_text-mac-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-arm64.Artifact upload.build perfetto/trace_to_text/mac-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_to_text/mac-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/trace_to_text-mac-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-arm64.Artifact upload.register perfetto/trace_to_text/mac-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_to_text/mac-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/trace_to_text/mac-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/trace_to_text/mac-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/mac-arm64/stripped/tracebox",
+ "gs://perfetto-luci-artifacts//mac-arm64/tracebox"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "mac-arm64.Artifact upload.gsutil upload (3)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//mac-arm64/tracebox@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"tracebox\"}], \"install_mode\": \"\", \"package\": \"perfetto/tracebox/mac-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/mac-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/tracebox-mac-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-arm64.Artifact upload.build perfetto/tracebox/mac-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/mac-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/tracebox-mac-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-arm64.Artifact upload.register perfetto/tracebox/mac-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/mac-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/tracebox/mac-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/tracebox/mac-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/mac-arm64/stripped/perfetto",
+ "gs://perfetto-luci-artifacts//mac-arm64/perfetto"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "mac-arm64.Artifact upload.gsutil upload (4)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//mac-arm64/perfetto@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"perfetto\"}], \"install_mode\": \"\", \"package\": \"perfetto/perfetto/mac-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/mac-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/perfetto-mac-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-arm64.Artifact upload.build perfetto/perfetto/mac-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/mac-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/perfetto-mac-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-arm64.Artifact upload.register perfetto/perfetto/mac-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/mac-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/perfetto/mac-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/perfetto/mac-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/mac-arm64/stripped/traced",
+ "gs://perfetto-luci-artifacts//mac-arm64/traced"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "mac-arm64.Artifact upload.gsutil upload (5)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//mac-arm64/traced@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced/mac-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/mac-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced-mac-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-arm64.Artifact upload.build perfetto/traced/mac-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/mac-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced-mac-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-arm64.Artifact upload.register perfetto/traced/mac-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/mac-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced/mac-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/traced/mac-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/mac-arm64/stripped/traced_probes",
+ "gs://perfetto-luci-artifacts//mac-arm64/traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "mac-arm64.Artifact upload.gsutil upload (6)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//mac-arm64/traced_probes@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced_probes\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced_probes/mac-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/mac-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced_probes-mac-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-arm64.Artifact upload.build perfetto/traced_probes/mac-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/mac-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced_probes-mac-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "mac-arm64.Artifact upload.register perfetto/traced_probes/mac-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/mac-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced_probes/mac-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/traced_probes/mac-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "name": "$result"
+ }
+] \ No newline at end of file
diff --git a/infra/luci/recipes/perfetto.expected/ci_tag.json b/infra/luci/recipes/perfetto.expected/ci_tag.json
new file mode 100644
index 000000000..1c0720003
--- /dev/null
+++ b/infra/luci/recipes/perfetto.expected/ci_tag.json
@@ -0,0 +1,1404 @@
+[
+ {
+ "cmd": [],
+ "name": "git"
+ },
+ {
+ "cmd": [
+ "vpython",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "ensure-directory",
+ "--mode",
+ "0777",
+ "[CACHE]/builder/perfetto"
+ ],
+ "infra_step": true,
+ "name": "git.ensure source dir",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "init",
+ "[CACHE]/builder/perfetto"
+ ],
+ "infra_step": true,
+ "name": "git.init",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "fetch",
+ "--tags",
+ "https://android.googlesource.com/platform/external/perfetto",
+ "refs/tags/v13.0"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "git.fetch",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "checkout",
+ "FETCH_HEAD"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "git.checkout",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "rev-parse",
+ "HEAD"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "git.rev-parse",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/install-build-deps",
+ "--linux-arm"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "build-deps"
+ },
+ {
+ "cmd": [],
+ "name": "linux-amd64"
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/gn",
+ "gen",
+ "[CACHE]/builder/perfetto/out/linux-amd64",
+ "--args=is_debug=false monolithic_binaries=true target_os=\"linux\" target_cpu=\"x64\""
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.gn gen",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/ninja",
+ "-C",
+ "[CACHE]/builder/perfetto/out/linux-amd64",
+ "trace_processor_shell",
+ "trace_to_text",
+ "tracebox",
+ "perfetto",
+ "traced",
+ "traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.ninja",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "linux-amd64.Artifact upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-amd64/stripped/trace_processor_shell",
+ "gs://perfetto-luci-artifacts/v13.0/linux-amd64/trace_processor_shell"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-amd64.Artifact upload.gsutil upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts/v13.0/linux-amd64/trace_processor_shell@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"trace_processor_shell\"}], \"install_mode\": \"\", \"package\": \"perfetto/trace_processor_shell/linux-amd64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-amd64/stripped\"}",
+ "-out",
+ "[CLEANUP]/trace_processor_shell-linux-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.build perfetto/trace_processor_shell/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/trace_processor_shell-linux-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-tag",
+ "git_tag:v13.0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.register perfetto/trace_processor_shell/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/trace_processor_shell/linux-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/trace_processor_shell/linux-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-amd64/stripped/trace_to_text",
+ "gs://perfetto-luci-artifacts/v13.0/linux-amd64/trace_to_text"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-amd64.Artifact upload.gsutil upload (2)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts/v13.0/linux-amd64/trace_to_text@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"trace_to_text\"}], \"install_mode\": \"\", \"package\": \"perfetto/trace_to_text/linux-amd64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-amd64/stripped\"}",
+ "-out",
+ "[CLEANUP]/trace_to_text-linux-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.build perfetto/trace_to_text/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_to_text/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/trace_to_text-linux-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-tag",
+ "git_tag:v13.0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.register perfetto/trace_to_text/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_to_text/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/trace_to_text/linux-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/trace_to_text/linux-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-amd64/stripped/tracebox",
+ "gs://perfetto-luci-artifacts/v13.0/linux-amd64/tracebox"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-amd64.Artifact upload.gsutil upload (3)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts/v13.0/linux-amd64/tracebox@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"tracebox\"}], \"install_mode\": \"\", \"package\": \"perfetto/tracebox/linux-amd64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-amd64/stripped\"}",
+ "-out",
+ "[CLEANUP]/tracebox-linux-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.build perfetto/tracebox/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/tracebox-linux-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-tag",
+ "git_tag:v13.0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.register perfetto/tracebox/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/tracebox/linux-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/tracebox/linux-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-amd64/stripped/perfetto",
+ "gs://perfetto-luci-artifacts/v13.0/linux-amd64/perfetto"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-amd64.Artifact upload.gsutil upload (4)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts/v13.0/linux-amd64/perfetto@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"perfetto\"}], \"install_mode\": \"\", \"package\": \"perfetto/perfetto/linux-amd64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-amd64/stripped\"}",
+ "-out",
+ "[CLEANUP]/perfetto-linux-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.build perfetto/perfetto/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/perfetto-linux-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-tag",
+ "git_tag:v13.0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.register perfetto/perfetto/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/perfetto/linux-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/perfetto/linux-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-amd64/stripped/traced",
+ "gs://perfetto-luci-artifacts/v13.0/linux-amd64/traced"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-amd64.Artifact upload.gsutil upload (5)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts/v13.0/linux-amd64/traced@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced/linux-amd64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-amd64/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced-linux-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.build perfetto/traced/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced-linux-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-tag",
+ "git_tag:v13.0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.register perfetto/traced/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced/linux-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/traced/linux-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-amd64/stripped/traced_probes",
+ "gs://perfetto-luci-artifacts/v13.0/linux-amd64/traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-amd64.Artifact upload.gsutil upload (6)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts/v13.0/linux-amd64/traced_probes@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced_probes\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced_probes/linux-amd64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-amd64/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced_probes-linux-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.build perfetto/traced_probes/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced_probes-linux-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-tag",
+ "git_tag:v13.0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.Artifact upload.register perfetto/traced_probes/linux-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/linux-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced_probes/linux-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/traced_probes/linux-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "linux-arm"
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/gn",
+ "gen",
+ "[CACHE]/builder/perfetto/out/linux-arm",
+ "--args=is_debug=false monolithic_binaries=true target_os=\"linux\" target_cpu=\"arm\""
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.gn gen",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/ninja",
+ "-C",
+ "[CACHE]/builder/perfetto/out/linux-arm",
+ "trace_processor_shell",
+ "tracebox",
+ "perfetto",
+ "traced",
+ "traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.ninja",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "linux-arm.Artifact upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-arm/stripped/trace_processor_shell",
+ "gs://perfetto-luci-artifacts/v13.0/linux-arm/trace_processor_shell"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-arm.Artifact upload.gsutil upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts/v13.0/linux-arm/trace_processor_shell@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"trace_processor_shell\"}], \"install_mode\": \"\", \"package\": \"perfetto/trace_processor_shell/linux-arm\", \"root\": \"[CACHE]/builder/perfetto/out/linux-arm/stripped\"}",
+ "-out",
+ "[CLEANUP]/trace_processor_shell-linux-arm.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.Artifact upload.build perfetto/trace_processor_shell/linux-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/linux-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/trace_processor_shell-linux-arm.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-tag",
+ "git_tag:v13.0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.Artifact upload.register perfetto/trace_processor_shell/linux-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/linux-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/trace_processor_shell/linux-arm@https://chrome-infra-packages.appspot.com/p/perfetto/trace_processor_shell/linux-arm/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-arm/stripped/tracebox",
+ "gs://perfetto-luci-artifacts/v13.0/linux-arm/tracebox"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-arm.Artifact upload.gsutil upload (2)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts/v13.0/linux-arm/tracebox@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"tracebox\"}], \"install_mode\": \"\", \"package\": \"perfetto/tracebox/linux-arm\", \"root\": \"[CACHE]/builder/perfetto/out/linux-arm/stripped\"}",
+ "-out",
+ "[CLEANUP]/tracebox-linux-arm.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.Artifact upload.build perfetto/tracebox/linux-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/linux-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/tracebox-linux-arm.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-tag",
+ "git_tag:v13.0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.Artifact upload.register perfetto/tracebox/linux-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/linux-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/tracebox/linux-arm@https://chrome-infra-packages.appspot.com/p/perfetto/tracebox/linux-arm/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-arm/stripped/perfetto",
+ "gs://perfetto-luci-artifacts/v13.0/linux-arm/perfetto"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-arm.Artifact upload.gsutil upload (3)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts/v13.0/linux-arm/perfetto@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"perfetto\"}], \"install_mode\": \"\", \"package\": \"perfetto/perfetto/linux-arm\", \"root\": \"[CACHE]/builder/perfetto/out/linux-arm/stripped\"}",
+ "-out",
+ "[CLEANUP]/perfetto-linux-arm.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.Artifact upload.build perfetto/perfetto/linux-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/linux-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/perfetto-linux-arm.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-tag",
+ "git_tag:v13.0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.Artifact upload.register perfetto/perfetto/linux-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/linux-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/perfetto/linux-arm@https://chrome-infra-packages.appspot.com/p/perfetto/perfetto/linux-arm/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-arm/stripped/traced",
+ "gs://perfetto-luci-artifacts/v13.0/linux-arm/traced"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-arm.Artifact upload.gsutil upload (4)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts/v13.0/linux-arm/traced@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced/linux-arm\", \"root\": \"[CACHE]/builder/perfetto/out/linux-arm/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced-linux-arm.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.Artifact upload.build perfetto/traced/linux-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/linux-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced-linux-arm.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-tag",
+ "git_tag:v13.0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.Artifact upload.register perfetto/traced/linux-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/linux-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced/linux-arm@https://chrome-infra-packages.appspot.com/p/perfetto/traced/linux-arm/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-arm/stripped/traced_probes",
+ "gs://perfetto-luci-artifacts/v13.0/linux-arm/traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-arm.Artifact upload.gsutil upload (5)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts/v13.0/linux-arm/traced_probes@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced_probes\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced_probes/linux-arm\", \"root\": \"[CACHE]/builder/perfetto/out/linux-arm/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced_probes-linux-arm.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.Artifact upload.build perfetto/traced_probes/linux-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/linux-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced_probes-linux-arm.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-tag",
+ "git_tag:v13.0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.Artifact upload.register perfetto/traced_probes/linux-arm",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/linux-arm\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced_probes/linux-arm@https://chrome-infra-packages.appspot.com/p/perfetto/traced_probes/linux-arm/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "linux-arm64"
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/gn",
+ "gen",
+ "[CACHE]/builder/perfetto/out/linux-arm64",
+ "--args=is_debug=false monolithic_binaries=true target_os=\"linux\" target_cpu=\"arm64\""
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.gn gen",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/ninja",
+ "-C",
+ "[CACHE]/builder/perfetto/out/linux-arm64",
+ "trace_processor_shell",
+ "tracebox",
+ "perfetto",
+ "traced",
+ "traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.ninja",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "linux-arm64.Artifact upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-arm64/stripped/trace_processor_shell",
+ "gs://perfetto-luci-artifacts/v13.0/linux-arm64/trace_processor_shell"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-arm64.Artifact upload.gsutil upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts/v13.0/linux-arm64/trace_processor_shell@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"trace_processor_shell\"}], \"install_mode\": \"\", \"package\": \"perfetto/trace_processor_shell/linux-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/trace_processor_shell-linux-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.Artifact upload.build perfetto/trace_processor_shell/linux-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/linux-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/trace_processor_shell-linux-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-tag",
+ "git_tag:v13.0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.Artifact upload.register perfetto/trace_processor_shell/linux-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/linux-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/trace_processor_shell/linux-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/trace_processor_shell/linux-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-arm64/stripped/tracebox",
+ "gs://perfetto-luci-artifacts/v13.0/linux-arm64/tracebox"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-arm64.Artifact upload.gsutil upload (2)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts/v13.0/linux-arm64/tracebox@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"tracebox\"}], \"install_mode\": \"\", \"package\": \"perfetto/tracebox/linux-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/tracebox-linux-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.Artifact upload.build perfetto/tracebox/linux-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/linux-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/tracebox-linux-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-tag",
+ "git_tag:v13.0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.Artifact upload.register perfetto/tracebox/linux-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/tracebox/linux-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/tracebox/linux-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/tracebox/linux-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-arm64/stripped/perfetto",
+ "gs://perfetto-luci-artifacts/v13.0/linux-arm64/perfetto"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-arm64.Artifact upload.gsutil upload (3)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts/v13.0/linux-arm64/perfetto@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"perfetto\"}], \"install_mode\": \"\", \"package\": \"perfetto/perfetto/linux-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/perfetto-linux-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.Artifact upload.build perfetto/perfetto/linux-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/linux-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/perfetto-linux-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-tag",
+ "git_tag:v13.0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.Artifact upload.register perfetto/perfetto/linux-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/linux-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/perfetto/linux-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/perfetto/linux-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-arm64/stripped/traced",
+ "gs://perfetto-luci-artifacts/v13.0/linux-arm64/traced"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-arm64.Artifact upload.gsutil upload (4)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts/v13.0/linux-arm64/traced@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced/linux-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced-linux-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.Artifact upload.build perfetto/traced/linux-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/linux-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced-linux-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-tag",
+ "git_tag:v13.0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.Artifact upload.register perfetto/traced/linux-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/linux-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced/linux-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/traced/linux-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]/builder/perfetto/out/linux-arm64/stripped/traced_probes",
+ "gs://perfetto-luci-artifacts/v13.0/linux-arm64/traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "linux-arm64.Artifact upload.gsutil upload (5)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts/v13.0/linux-arm64/traced_probes@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced_probes\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced_probes/linux-arm64\", \"root\": \"[CACHE]/builder/perfetto/out/linux-arm64/stripped\"}",
+ "-out",
+ "[CLEANUP]/traced_probes-linux-arm64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.Artifact upload.build perfetto/traced_probes/linux-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/linux-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "pkg-register",
+ "[CLEANUP]/traced_probes-linux-arm64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-tag",
+ "git_tag:v13.0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.Artifact upload.register perfetto/traced_probes/linux-arm64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced_probes/linux-arm64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced_probes/linux-arm64@https://chrome-infra-packages.appspot.com/p/perfetto/traced_probes/linux-arm64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "name": "$result"
+ }
+] \ No newline at end of file
diff --git a/infra/luci/recipes/perfetto.expected/ci_win.json b/infra/luci/recipes/perfetto.expected/ci_win.json
new file mode 100644
index 000000000..cb93f1672
--- /dev/null
+++ b/infra/luci/recipes/perfetto.expected/ci_win.json
@@ -0,0 +1,485 @@
+[
+ {
+ "cmd": [],
+ "name": "git"
+ },
+ {
+ "cmd": [
+ "vpython",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]\\resources\\fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "ensure-directory",
+ "--mode",
+ "0777",
+ "[CACHE]\\builder\\perfetto"
+ ],
+ "infra_step": true,
+ "name": "git.ensure source dir",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "init",
+ "[CACHE]\\builder\\perfetto"
+ ],
+ "infra_step": true,
+ "name": "git.init",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "fetch",
+ "--tags",
+ "https://android.googlesource.com/platform/external/perfetto",
+ "refs/heads/master"
+ ],
+ "cwd": "[CACHE]\\builder\\perfetto",
+ "infra_step": true,
+ "name": "git.fetch",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "checkout",
+ "FETCH_HEAD"
+ ],
+ "cwd": "[CACHE]\\builder\\perfetto",
+ "infra_step": true,
+ "name": "git.checkout",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "rev-parse",
+ "HEAD"
+ ],
+ "cwd": "[CACHE]\\builder\\perfetto",
+ "infra_step": true,
+ "name": "git.rev-parse",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/install-build-deps"
+ ],
+ "cwd": "[CACHE]\\builder\\perfetto",
+ "infra_step": true,
+ "name": "build-deps"
+ },
+ {
+ "cmd": [
+ "cipd.bat",
+ "ensure",
+ "-root",
+ "[CACHE]\\windows_sdk",
+ "-ensure-file",
+ "chrome_internal/third_party/sdk/windows uploaded:2019-09-06",
+ "-max-threads",
+ "0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]\\builder\\perfetto",
+ "infra_step": true,
+ "name": "ensure_installed",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"resolved-instance_id-of-uploaded:2019-09\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"chrome_internal/third_party/sdk/windows\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ ]@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "\nimport shutil\nimport sys\nshutil.copy(sys.argv[1], sys.argv[2])\n",
+ "[CACHE]\\windows_sdk\\win_sdk\\bin\\SetEnv.x64.json",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]\\builder\\perfetto",
+ "name": "read SetEnv.x64.json",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"env\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"PATH\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ [@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"..\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"..\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"win_sdk\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"bin\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"x64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ ]@@@",
+ "@@@STEP_LOG_LINE@json.output@ ], @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"VSINSTALLDIR\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ [@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"..\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"..\\\\\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ ]@@@",
+ "@@@STEP_LOG_LINE@json.output@ ]@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/gn",
+ "gen",
+ "[CACHE]\\builder\\perfetto\\out\\windows-amd64",
+ "--args=is_debug=false monolithic_binaries=true"
+ ],
+ "cwd": "[CACHE]\\builder\\perfetto",
+ "env": {
+ "VSINSTALLDIR": "[CACHE]\\windows_sdk"
+ },
+ "env_prefixes": {
+ "PATH": [
+ "[CACHE]\\windows_sdk\\win_sdk\\bin\\x64"
+ ]
+ },
+ "name": "gn gen"
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/ninja",
+ "-C",
+ "[CACHE]\\builder\\perfetto\\out\\windows-amd64",
+ "trace_processor_shell",
+ "trace_to_text",
+ "perfetto",
+ "traced"
+ ],
+ "cwd": "[CACHE]\\builder\\perfetto",
+ "env": {
+ "VSINSTALLDIR": "[CACHE]\\windows_sdk"
+ },
+ "env_prefixes": {
+ "PATH": [
+ "[CACHE]\\windows_sdk\\win_sdk\\bin\\x64"
+ ]
+ },
+ "name": "ninja"
+ },
+ {
+ "cmd": [],
+ "name": "Artifact upload"
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]\\resources\\gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]\\gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]\\builder\\perfetto\\out\\windows-amd64\\trace_processor_shell.exe",
+ "gs://perfetto-luci-artifacts//windows-amd64/trace_processor_shell.exe"
+ ],
+ "cwd": "[CACHE]\\builder\\perfetto",
+ "infra_step": true,
+ "name": "Artifact upload.gsutil upload",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//windows-amd64/trace_processor_shell.exe@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd.bat",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"trace_processor_shell.exe\"}], \"install_mode\": \"\", \"package\": \"perfetto/trace_processor_shell/windows-amd64\", \"root\": \"[CACHE]\\\\builder\\\\perfetto\\\\out\\\\windows-amd64\"}",
+ "-out",
+ "[CLEANUP]\\trace_processor_shell-windows-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]\\builder\\perfetto",
+ "name": "Artifact upload.build perfetto/trace_processor_shell/windows-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/windows-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd.bat",
+ "pkg-register",
+ "[CLEANUP]\\trace_processor_shell-windows-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]\\builder\\perfetto",
+ "name": "Artifact upload.register perfetto/trace_processor_shell/windows-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_processor_shell/windows-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/trace_processor_shell/windows-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/trace_processor_shell/windows-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]\\resources\\gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]\\gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]\\builder\\perfetto\\out\\windows-amd64\\trace_to_text.exe",
+ "gs://perfetto-luci-artifacts//windows-amd64/trace_to_text.exe"
+ ],
+ "cwd": "[CACHE]\\builder\\perfetto",
+ "infra_step": true,
+ "name": "Artifact upload.gsutil upload (2)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//windows-amd64/trace_to_text.exe@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd.bat",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"trace_to_text.exe\"}], \"install_mode\": \"\", \"package\": \"perfetto/trace_to_text/windows-amd64\", \"root\": \"[CACHE]\\\\builder\\\\perfetto\\\\out\\\\windows-amd64\"}",
+ "-out",
+ "[CLEANUP]\\trace_to_text-windows-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]\\builder\\perfetto",
+ "name": "Artifact upload.build perfetto/trace_to_text/windows-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_to_text/windows-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd.bat",
+ "pkg-register",
+ "[CLEANUP]\\trace_to_text-windows-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]\\builder\\perfetto",
+ "name": "Artifact upload.register perfetto/trace_to_text/windows-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/trace_to_text/windows-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/trace_to_text/windows-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/trace_to_text/windows-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]\\resources\\gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]\\gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]\\builder\\perfetto\\out\\windows-amd64\\perfetto.exe",
+ "gs://perfetto-luci-artifacts//windows-amd64/perfetto.exe"
+ ],
+ "cwd": "[CACHE]\\builder\\perfetto",
+ "infra_step": true,
+ "name": "Artifact upload.gsutil upload (3)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//windows-amd64/perfetto.exe@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd.bat",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"perfetto.exe\"}], \"install_mode\": \"\", \"package\": \"perfetto/perfetto/windows-amd64\", \"root\": \"[CACHE]\\\\builder\\\\perfetto\\\\out\\\\windows-amd64\"}",
+ "-out",
+ "[CLEANUP]\\perfetto-windows-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]\\builder\\perfetto",
+ "name": "Artifact upload.build perfetto/perfetto/windows-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/windows-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd.bat",
+ "pkg-register",
+ "[CLEANUP]\\perfetto-windows-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]\\builder\\perfetto",
+ "name": "Artifact upload.register perfetto/perfetto/windows-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/perfetto/windows-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/perfetto/windows-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/perfetto/windows-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]\\resources\\gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]\\gsutil.py",
+ "----",
+ "cp",
+ "[CACHE]\\builder\\perfetto\\out\\windows-amd64\\traced.exe",
+ "gs://perfetto-luci-artifacts//windows-amd64/traced.exe"
+ ],
+ "cwd": "[CACHE]\\builder\\perfetto",
+ "infra_step": true,
+ "name": "Artifact upload.gsutil upload (4)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_LINK@gsutil.upload@https://storage.cloud.google.com/perfetto-luci-artifacts//windows-amd64/traced.exe@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd.bat",
+ "pkg-build",
+ "-pkg-def",
+ "{\"data\": [{\"file\": \"traced.exe\"}], \"install_mode\": \"\", \"package\": \"perfetto/traced/windows-amd64\", \"root\": \"[CACHE]\\\\builder\\\\perfetto\\\\out\\\\windows-amd64\"}",
+ "-out",
+ "[CLEANUP]\\traced-windows-amd64.cipd",
+ "-hash-algo",
+ "sha256",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]\\builder\\perfetto",
+ "name": "Artifact upload.build perfetto/traced/windows-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/windows-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd.bat",
+ "pkg-register",
+ "[CLEANUP]\\traced-windows-amd64.cipd",
+ "-ref",
+ "latest",
+ "-tag",
+ "git_revision:",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[CACHE]\\builder\\perfetto",
+ "name": "Artifact upload.register perfetto/traced/windows-amd64",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"40-chars-fake-of-the-package-instance_id\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"perfetto/traced/windows-amd64\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LINK@perfetto/traced/windows-amd64@https://chrome-infra-packages.appspot.com/p/perfetto/traced/windows-amd64/+/40-chars-fake-of-the-package-instance_id@@@"
+ ]
+ },
+ {
+ "name": "$result"
+ }
+] \ No newline at end of file
diff --git a/infra/luci/recipes/perfetto.expected/unofficial.json b/infra/luci/recipes/perfetto.expected/unofficial.json
new file mode 100644
index 000000000..497a920ed
--- /dev/null
+++ b/infra/luci/recipes/perfetto.expected/unofficial.json
@@ -0,0 +1,199 @@
+[
+ {
+ "cmd": [],
+ "name": "git"
+ },
+ {
+ "cmd": [
+ "vpython",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "ensure-directory",
+ "--mode",
+ "0777",
+ "[CACHE]/builder/perfetto"
+ ],
+ "infra_step": true,
+ "name": "git.ensure source dir",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "init",
+ "[CACHE]/builder/perfetto"
+ ],
+ "infra_step": true,
+ "name": "git.init",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "fetch",
+ "--tags",
+ "https://android.googlesource.com/platform/external/perfetto",
+ "refs/heads/master"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "git.fetch",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "checkout",
+ "FETCH_HEAD"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "git.checkout",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "rev-parse",
+ "HEAD"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "git.rev-parse",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/install-build-deps",
+ "--linux-arm"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "infra_step": true,
+ "name": "build-deps"
+ },
+ {
+ "cmd": [],
+ "name": "linux-amd64"
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/gn",
+ "gen",
+ "[CACHE]/builder/perfetto/out/linux-amd64",
+ "--args=is_debug=false monolithic_binaries=true target_os=\"linux\" target_cpu=\"x64\""
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.gn gen",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/ninja",
+ "-C",
+ "[CACHE]/builder/perfetto/out/linux-amd64",
+ "trace_processor_shell",
+ "trace_to_text",
+ "tracebox",
+ "perfetto",
+ "traced",
+ "traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-amd64.ninja",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "linux-arm"
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/gn",
+ "gen",
+ "[CACHE]/builder/perfetto/out/linux-arm",
+ "--args=is_debug=false monolithic_binaries=true target_os=\"linux\" target_cpu=\"arm\""
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.gn gen",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/ninja",
+ "-C",
+ "[CACHE]/builder/perfetto/out/linux-arm",
+ "trace_processor_shell",
+ "tracebox",
+ "perfetto",
+ "traced",
+ "traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm.ninja",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "linux-arm64"
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/gn",
+ "gen",
+ "[CACHE]/builder/perfetto/out/linux-arm64",
+ "--args=is_debug=false monolithic_binaries=true target_os=\"linux\" target_cpu=\"arm64\""
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.gn gen",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python3",
+ "tools/ninja",
+ "-C",
+ "[CACHE]/builder/perfetto/out/linux-arm64",
+ "trace_processor_shell",
+ "tracebox",
+ "perfetto",
+ "traced",
+ "traced_probes"
+ ],
+ "cwd": "[CACHE]/builder/perfetto",
+ "name": "linux-arm64.ninja",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "name": "$result"
+ }
+] \ No newline at end of file
diff --git a/infra/luci/recipes/perfetto.py b/infra/luci/recipes/perfetto.py
index e4552d857..6e7faf5f6 100644
--- a/infra/luci/recipes/perfetto.py
+++ b/infra/luci/recipes/perfetto.py
@@ -16,13 +16,18 @@
from recipe_engine.recipe_api import Property
DEPS = [
+ 'depot_tools/gsutil',
'recipe_engine/buildbucket',
+ 'recipe_engine/cipd',
'recipe_engine/context',
'recipe_engine/file',
'recipe_engine/path',
'recipe_engine/platform',
'recipe_engine/properties',
+ 'recipe_engine/raw_io',
'recipe_engine/step',
+ 'macos_sdk',
+ 'windows_sdk',
]
PROPERTIES = {
@@ -33,13 +38,136 @@ PROPERTIES = {
),
}
-ARTIFACTS = ['trace_processor_shell']
+ARTIFACTS = [
+ {
+ 'name': 'trace_processor_shell'
+ },
+ {
+ 'name':
+ 'trace_to_text',
+
+ # trace_to_text is really a host exeutable, doesn't make sense to build
+ # it when cross-compiling .
+ 'exclude_platforms': [
+ 'android-arm', 'android-arm64', 'android-x86', 'android-x64',
+ 'linux-arm', 'linux-arm64'
+ ]
+ },
+ {
+ 'name': 'tracebox',
+ 'exclude_platforms': ['windows-amd64']
+ },
+ {
+ 'name': 'perfetto'
+ },
+ {
+ 'name': 'traced'
+ },
+ {
+ 'name': 'traced_probes',
+ 'exclude_platforms': ['windows-amd64']
+ },
+]
+
+
+class BuildContext:
+
+ def __init__(self, src_dir):
+ self.src_dir = src_dir
+ self.git_revision = None
+ self.maybe_git_tag = None
+
+
+def GnArgs(platform):
+ (os, cpu) = platform.split('-')
+ base_args = 'is_debug=false monolithic_binaries=true'
+ if os not in ('android', 'linux', 'mac'):
+ return base_args # No cross-compiling on Windows.
+ cpu = 'x64' if cpu == 'amd64' else cpu # GN calls it "x64".
+ return base_args + ' target_os="{}" target_cpu="{}"'.format(os, cpu)
+
+
+def UploadArtifact(api, ctx, platform, out_dir, artifact):
+ exclude_platforms = artifact.get('exclude_platforms', [])
+ if platform in exclude_platforms:
+ return
+
+ # We want to use the stripped binaries except on Windows where we don't generate
+ # them.
+ exe_dir = out_dir if api.platform.is_win else out_dir.join('stripped')
+
+ # Compute the exact artifact path
+ gcs_upload_dir = ctx.maybe_git_tag if ctx.maybe_git_tag else ctx.git_revision
+ artifact_ext = artifact['name'] + ('.exe' if api.platform.is_win else '')
+ source_path = exe_dir.join(artifact_ext)
+
+ # Upload to GCS bucket.
+ gcs_target_path = '{}/{}/{}'.format(gcs_upload_dir, platform, artifact_ext)
+ api.gsutil.upload(source_path, 'perfetto-luci-artifacts', gcs_target_path)
+
+ # Create the CIPD package definition from the artifact path.
+ cipd_pkg_name = 'perfetto/{}/{}'.format(artifact['name'], platform)
+ pkg_def = api.cipd.PackageDefinition(
+ package_name=cipd_pkg_name, package_root=exe_dir)
+ pkg_def.add_file(source_path)
+
+ # Actually build the CIPD pakcage
+ cipd_pkg_file_name = '{}-{}.cipd'.format(artifact['name'], platform)
+ cipd_pkg_file = api.path['cleanup'].join(cipd_pkg_file_name)
+ api.cipd.build_from_pkg(
+ pkg_def=pkg_def,
+ output_package=cipd_pkg_file,
+ )
+
+ # If we have a git tag, add that to the CIPD tags.
+ tags = {
+ 'git_revision': ctx.git_revision,
+ }
+ if ctx.maybe_git_tag:
+ tags['git_tag'] = ctx.maybe_git_tag
+
+ # Upload the package and regisiter with the 'latest' tag.
+ api.cipd.register(
+ package_name=cipd_pkg_name,
+ package_path=cipd_pkg_file,
+ refs=['latest'],
+ tags=tags,
+ )
+
+
+def BuildForPlatform(api, ctx, platform):
+ out_dir = ctx.src_dir.join('out', platform)
+
+ # Build Perfetto.
+ # There should be no need for internet access here.
+
+ with api.context(cwd=ctx.src_dir), api.macos_sdk(), api.windows_sdk():
+ targets = [
+ x['name']
+ for x in ARTIFACTS
+ if platform not in x.get('exclude_platforms', [])
+ ]
+ args = GnArgs(platform)
+ api.step('gn gen',
+ ['python3', 'tools/gn', 'gen', out_dir, '--args={}'.format(args)])
+ api.step('ninja', ['python3', 'tools/ninja', '-C', out_dir] + targets)
+
+ # Upload stripped artifacts using gsutil if we're on the official builder.
+ if 'official' not in api.buildbucket.builder_id.builder:
+ return
+
+ with api.step.nest('Artifact upload'), api.context(cwd=ctx.src_dir):
+ for artifact in ARTIFACTS:
+ UploadArtifact(api, ctx, platform, out_dir, artifact)
def RunSteps(api, repository):
builder_cache_dir = api.path['cache'].join('builder')
src_dir = builder_cache_dir.join('perfetto')
+ # Crate the context we use in all the building stages.
+ ctx = BuildContext(src_dir)
+
# Fetch the Perfetto repo.
with api.step.nest('git'), api.context(infra_steps=True):
api.file.ensure_directory('ensure source dir', src_dir)
@@ -47,28 +175,72 @@ def RunSteps(api, repository):
with api.context(cwd=src_dir):
build_input = api.buildbucket.build_input
ref = (
- build_input.gitiles_commit.id
+ build_input.gitiles_commit.ref
if build_input.gitiles_commit else 'refs/heads/master')
# Fetch tags so `git describe` works.
api.step('fetch', ['git', 'fetch', '--tags', repository, ref])
api.step('checkout', ['git', 'checkout', 'FETCH_HEAD'])
+ # Store information about the git revision and the tag if available.
+ ctx.git_revision = api.step(
+ 'rev-parse', ['git', 'rev-parse', 'HEAD'],
+ stdout=api.raw_io.output()).stdout.strip()
+ ctx.maybe_git_tag = ref.replace(
+ 'refs/tags/', '') if ref.startswith('refs/tags/') else None
+
# Pull all deps here.
- # There should be no need for internet access for building Perfetto beyond
- # this point.
with api.context(cwd=src_dir, infra_steps=True):
- api.step('build-deps', ['tools/install-build-deps', '--ui', '--android'])
+ extra_args = []
+ if 'android' in api.buildbucket.builder_id.builder:
+ extra_args += ['--android']
+ elif api.platform.is_linux:
+ # Pull the cross-toolchains for building for linux-arm{,64}.
+ extra_args += ['--linux-arm']
+ api.step('build-deps', ['python3', 'tools/install-build-deps'] + extra_args)
- # Buld Perfetto.
- with api.context(cwd=src_dir):
- api.step('gn gen', ['tools/gn', 'gen', 'out/dist', '--args=is_debug=false'])
- api.step('ninja', ['tools/ninja', '-C', 'out/dist'])
+ if api.platform.is_win:
+ BuildForPlatform(api, ctx, 'windows-amd64')
+ elif api.platform.is_mac:
+ with api.step.nest('mac-amd64'):
+ BuildForPlatform(api, ctx, 'mac-amd64')
+ with api.step.nest('mac-arm64'):
+ BuildForPlatform(api, ctx, 'mac-arm64')
+ elif 'android' in api.buildbucket.builder_id.builder:
+ with api.step.nest('android-arm'):
+ BuildForPlatform(api, ctx, 'android-arm')
+ with api.step.nest('android-arm64'):
+ BuildForPlatform(api, ctx, 'android-arm64')
+ with api.step.nest('android-x86'):
+ BuildForPlatform(api, ctx, 'android-x86')
+ with api.step.nest('android-x64'):
+ BuildForPlatform(api, ctx, 'android-x64')
+ elif api.platform.is_linux:
+ with api.step.nest('linux-amd64'):
+ BuildForPlatform(api, ctx, 'linux-amd64')
+ with api.step.nest('linux-arm'):
+ BuildForPlatform(api, ctx, 'linux-arm')
+ with api.step.nest('linux-arm64'):
+ BuildForPlatform(api, ctx, 'linux-arm64')
def GenTests(api):
- for platform in ('linux',):
- yield (api.test('ci_' + platform) + api.platform.name(platform) +
+ for target in ('android', 'linux', 'mac', 'win'):
+ host = 'linux' if target == 'android' else target
+ yield (api.test('ci_' + target) + api.platform.name(host) +
api.buildbucket.ci_build(
project='perfetto',
+ builder='perfetto-official-builder-%s' % target,
git_repo='android.googlesource.com/platform/external/perfetto',
))
+
+ yield (api.test('ci_tag') + api.platform.name('linux') +
+ api.buildbucket.ci_build(
+ project='perfetto',
+ builder='official',
+ git_repo='android.googlesource.com/platform/external/perfetto',
+ git_ref='refs/tags/v13.0'))
+
+ yield (api.test('unofficial') + api.platform.name('linux') +
+ api.buildbucket.ci_build(
+ project='perfetto',
+ git_repo='android.googlesource.com/platform/external/perfetto'))
diff --git a/infra/oss-fuzz/build_fuzzers b/infra/oss-fuzz/build_fuzzers
index 7f1fe48f2..95d9383c5 100755
--- a/infra/oss-fuzz/build_fuzzers
+++ b/infra/oss-fuzz/build_fuzzers
@@ -11,9 +11,9 @@ CXXFLAGS="$CXXFLAGS -fno-sanitize=vptr"
GN_ARGS="is_clang=true is_debug=false is_fuzzer=true use_libfuzzer=false \
link_fuzzer=\"-lFuzzingEngine\" is_hermetic_clang=false \
-use_custom_libcxx=false \
-extra_cflags=\"$CFLAGS -Wno-implicit-int-float-conversion\" \
-extra_cxxflags=\"$CXXFLAGS\" extra_ldflags=\"$CXXFLAGS\" \
+use_custom_libcxx=false is_cross_compiling=true \
+extra_target_cflags=\"$CFLAGS -Wno-implicit-int-float-conversion\" \
+extra_target_cxxflags=\"$CXXFLAGS\" extra_target_ldflags=\"$CXXFLAGS\" \
is_system_compiler=true cc=\"$CC\" cxx=\"$CXX\" linker=\"gold\""
if [ "$SANITIZER" = "address" ]; then
diff --git a/infra/perfetto.dev/src/assets/style.scss b/infra/perfetto.dev/src/assets/style.scss
index 0d0bbbea0..7f23862aa 100644
--- a/infra/perfetto.dev/src/assets/style.scss
+++ b/infra/perfetto.dev/src/assets/style.scss
@@ -86,7 +86,7 @@ h3 {
--sh-padding-y: 5px;
max-height: var(--site-header-height);
padding: var(--sh-padding-y) 30px;
- box-shadow: rgba(0, 0, 0, 0.3) 0px 3px 3px 0px;
+ box-shadow: rgba(0, 0, 0, 0.3) 0 3px 3px 0;
overflow: hidden;
display: flex;
z-index: 10;
diff --git a/infra/perfetto.dev/src/markdown_render.js b/infra/perfetto.dev/src/markdown_render.js
index 8fe5cc9fc..21d03edd6 100644
--- a/infra/perfetto.dev/src/markdown_render.js
+++ b/infra/perfetto.dev/src/markdown_render.js
@@ -158,6 +158,15 @@ function renderParagraph(text) {
if (cssClass != '') {
cssClass = ` class="callout ${cssClass}"`;
}
+
+ // Rudimentary support of definition lists.
+ var colonStart = text.search("\n:")
+ if (colonStart != -1) {
+ var key = text.substring(0, colonStart);
+ var value = text.substring(colonStart + 2);
+ return `<dl><dt><p>${key}</p></dt><dd><p>${value}</p></dd></dl>`
+ }
+
return `<p${cssClass}>${text}</p>\n`;
}
diff --git a/meson.build b/meson.build
index 13d603b44..06015141c 100644
--- a/meson.build
+++ b/meson.build
@@ -34,6 +34,7 @@ lib_perfetto = static_library(
'perfetto',
sources: 'sdk/perfetto.cc',
dependencies: dep_threads,
+ install: true,
)
inc_perfetto = include_directories('sdk')
diff --git a/perfetto.rc b/perfetto.rc
index 11cc42e9f..58f03f78b 100644
--- a/perfetto.rc
+++ b/perfetto.rc
@@ -19,7 +19,7 @@ service traced /system/bin/traced
socket traced_producer stream 0666 root root
user nobody
group nobody
- writepid /dev/cpuset/system-background/tasks
+ task_profiles ServiceCapacityLow
service traced_probes /system/bin/traced_probes
class late_start
@@ -28,7 +28,7 @@ service traced_probes /system/bin/traced_probes
# Despite the "log" group below, traced_probes is allowed to read log
# only on userdebug/eng via selinux (see traced_probes.te).
group nobody readproc log readtracefs
- writepid /dev/cpuset/system-background/tasks
+ task_profiles ServiceCapacityLow
# Clean up procfs configuration even if traced_probes crashes
# unexpectedly.
onrestart exec_background - nobody shell -- /system/bin/traced_probes --cleanup-after-crash
@@ -90,3 +90,34 @@ on property:persist.mm_events.enabled=true && property:persist.traced.enable=1
on property:persist.mm_events.enabled=false
stop mm_events
+
+#############################################################################
+# perfetto_trace_on_boot - Starts a perfetto trace on boot
+#############################################################################
+#
+# There are two separate actions (a trigger action and a start action) to make
+# sure that perfetto_trace_on_boot is started only once on boot (otherwise,
+# whenever persist.debug.perfetto.boottrace=1 is set, perfetto_trace_on_boot
+# would start immediately).
+#
+# persist.debug.perfetto.boottrace=1 can be manually set after boot (to record
+# a trace on the next reboot) and we don't want to immediately start a trace
+# when setting the debug property. So we turn "ro.persistent_properties.ready"
+# into a trigger, and then check whether we should start tracing when the
+# trigger fires.
+on perfetto_maybe_trace_on_boot && property:persist.debug.perfetto.boottrace=1 && property:persist.traced.enable=1
+ setprop persist.debug.perfetto.boottrace ""
+ rm /data/misc/perfetto-traces/boottrace.perfetto-trace
+ # Set by traced after listen()ing on the consumer socket. Without this,
+ # perfetto could try to connect to traced before traced is ready to listen.
+ wait_for_prop sys.trace.traced_started 1
+ start perfetto_trace_on_boot
+
+on property:ro.persistent_properties.ready=true
+ trigger perfetto_maybe_trace_on_boot
+
+service perfetto_trace_on_boot /system/bin/perfetto -c /data/misc/perfetto-configs/boottrace.pbtxt --txt -o /data/misc/perfetto-traces/boottrace.perfetto-trace
+ disabled
+ oneshot
+ user shell
+ group nobody
diff --git a/protos/perfetto/common/BUILD.gn b/protos/perfetto/common/BUILD.gn
index 1af189de2..5ecc0de9b 100644
--- a/protos/perfetto/common/BUILD.gn
+++ b/protos/perfetto/common/BUILD.gn
@@ -25,6 +25,7 @@ perfetto_proto_library("@TYPE@") {
"commit_data_request.proto",
"data_source_descriptor.proto",
"descriptor.proto",
+ "ftrace_descriptor.proto",
"gpu_counter_descriptor.proto",
"interceptor_descriptor.proto",
"observable_events.proto",
diff --git a/protos/perfetto/common/builtin_clock.proto b/protos/perfetto/common/builtin_clock.proto
index 153c5b2f8..dba9ec9f7 100644
--- a/protos/perfetto/common/builtin_clock.proto
+++ b/protos/perfetto/common/builtin_clock.proto
@@ -29,4 +29,8 @@ enum BuiltinClock {
BUILTIN_CLOCK_MAX_ID = 63;
reserved 7, 8;
+
+ // An internal CL (ag/16521245) has taken this for BUILTIN_CLOCK_TSC.
+ // That might get upstreamed later on. Avoid diverging on this ID in future.
+ reserved 9;
}
diff --git a/protos/perfetto/common/data_source_descriptor.proto b/protos/perfetto/common/data_source_descriptor.proto
index d35c6418b..dc2d74274 100644
--- a/protos/perfetto/common/data_source_descriptor.proto
+++ b/protos/perfetto/common/data_source_descriptor.proto
@@ -18,6 +18,7 @@ syntax = "proto2";
package perfetto.protos;
+import "protos/perfetto/common/ftrace_descriptor.proto";
import "protos/perfetto/common/gpu_counter_descriptor.proto";
import "protos/perfetto/common/track_event_descriptor.proto";
@@ -28,6 +29,13 @@ message DataSourceDescriptor {
// e.g., "linux.ftrace", "chromium.tracing"
optional string name = 1;
+ // When non-zero, this is a unique ID within the scope of the Producer for
+ // this data source (it is NOT globally unique). This is useful to
+ // differentiate between data sources with matching names when calling
+ // UpdateDataSource(). This field has been introduced in November 2021
+ // (v22, Android T) and is not supported on older versions.
+ optional uint64 id = 7;
+
// When true the data source is expected to ack the stop request through the
// NotifyDataSourceStopped() IPC. This field has been introduced after
// Android P in Jul 2018 and is not supported on older versions.
@@ -47,4 +55,6 @@ message DataSourceDescriptor {
optional GpuCounterDescriptor gpu_counter_descriptor = 5 [lazy = true];
optional TrackEventDescriptor track_event_descriptor = 6 [lazy = true];
+
+ optional FtraceDescriptor ftrace_descriptor = 8 [lazy = true];
}
diff --git a/protos/perfetto/common/ftrace_descriptor.proto b/protos/perfetto/common/ftrace_descriptor.proto
new file mode 100644
index 000000000..5406d6d00
--- /dev/null
+++ b/protos/perfetto/common/ftrace_descriptor.proto
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+message FtraceDescriptor {
+ message AtraceCategory {
+ optional string name = 1;
+ optional string description = 2;
+ }
+
+ // Report the available atrace categories.
+ //
+ // Used by Traceur via `perfetto --query`.
+ repeated AtraceCategory atrace_categories = 1;
+}
diff --git a/protos/perfetto/common/perf_events.proto b/protos/perfetto/common/perf_events.proto
index 77f3a1ebf..270bacb12 100644
--- a/protos/perfetto/common/perf_events.proto
+++ b/protos/perfetto/common/perf_events.proto
@@ -18,6 +18,7 @@ syntax = "proto2";
package perfetto.protos;
+// Next id: 12
message PerfEvents {
// What event to sample on, and how often. Commented from the perspective of
// its use in |PerfEventConfig|.
@@ -47,17 +48,72 @@ message PerfEvents {
oneof event {
Counter counter = 4;
Tracepoint tracepoint = 3;
+ RawEvent raw_event = 5;
}
+
+ // If set, samples will be timestamped with the given clock.
+ // If unset, the clock is chosen by the implementation.
+ // For software events, prefer PERF_CLOCK_BOOTTIME. However it cannot be
+ // used for hardware events (due to interrupt safety), for which the
+ // recommendation is to use one of the monotonic clocks.
+ optional PerfClock timestamp_clock = 11;
+
+ // Optional arbitrary name for the event, to identify it in the parsed
+ // trace. Does *not* affect the profiling itself. If unset, the trace
+ // parser will choose a suitable name.
+ optional string name = 10;
}
+ // Builtin counter names from the uapi header. Commented with their perf tool
+ // aliases.
+ // TODO(rsavitski): consider generating enums for cache events (should be
+ // finite), and generally make this list as extensive as possible. Excluding
+ // things like dynamic PMUs since those don't fit into a static enum.
+ // Next id: 21
enum Counter {
UNKNOWN_COUNTER = 0;
- // software:
+
+ // cpu-clock
SW_CPU_CLOCK = 1;
+ // page-faults, faults
SW_PAGE_FAULTS = 2;
- // hardware:
+ // task-clock
+ SW_TASK_CLOCK = 3;
+ // context-switches, cs
+ SW_CONTEXT_SWITCHES = 4;
+ // cpu-migrations, migrations
+ SW_CPU_MIGRATIONS = 5;
+ // minor-faults
+ SW_PAGE_FAULTS_MIN = 6;
+ // major-faults
+ SW_PAGE_FAULTS_MAJ = 7;
+ // alignment-faults
+ SW_ALIGNMENT_FAULTS = 8;
+ // emulation-faults
+ SW_EMULATION_FAULTS = 9;
+ // dummy
+ SW_DUMMY = 20;
+
+ // cpu-cycles, cycles
HW_CPU_CYCLES = 10;
+ // instructions
HW_INSTRUCTIONS = 11;
+ // cache-references
+ HW_CACHE_REFERENCES = 12;
+ // cache-misses
+ HW_CACHE_MISSES = 13;
+ // branch-instructions, branches
+ HW_BRANCH_INSTRUCTIONS = 14;
+ // branch-misses
+ HW_BRANCH_MISSES = 15;
+ // bus-cycles
+ HW_BUS_CYCLES = 16;
+ // stalled-cycles-frontend, idle-cycles-frontend
+ HW_STALLED_CYCLES_FRONTEND = 17;
+ // stalled-cycles-backend, idle-cycles-backend
+ HW_STALLED_CYCLES_BACKEND = 18;
+ // ref-cycles
+ HW_REF_CPU_CYCLES = 19;
}
message Tracepoint {
@@ -73,4 +129,25 @@ message PerfEvents {
// https://www.kernel.org/doc/Documentation/trace/events.txt
optional string filter = 2;
}
+
+ // Syscall-level description of the event, propagated to the perf_event_attr
+ // struct. Primarily for local use-cases, since the event availability and
+ // encoding is hardware-specific.
+ message RawEvent {
+ optional uint32 type = 1;
+ optional uint64 config = 2;
+ optional uint64 config1 = 3;
+ optional uint64 config2 = 4;
+ }
+
+ // Subset of clocks that is supported by perf timestamping.
+ // CLOCK_TAI is excluded since it's not expected to be used in practice, but
+ // would require additions to the trace clock synchronisation logic.
+ enum PerfClock {
+ UNKNOWN_PERF_CLOCK = 0;
+ PERF_CLOCK_REALTIME = 1;
+ PERF_CLOCK_MONOTONIC = 2;
+ PERF_CLOCK_MONOTONIC_RAW = 3;
+ PERF_CLOCK_BOOTTIME = 4;
+ }
}
diff --git a/protos/perfetto/common/trace_stats.proto b/protos/perfetto/common/trace_stats.proto
index c6a9fbfa1..6a6bb7cac 100644
--- a/protos/perfetto/common/trace_stats.proto
+++ b/protos/perfetto/common/trace_stats.proto
@@ -20,7 +20,7 @@ package perfetto.protos;
// Statistics for the internals of the tracing service.
//
-// Next id: 11.
+// Next id: 16.
message TraceStats {
// From TraceBuffer::Stats.
//
@@ -167,4 +167,23 @@ message TraceStats {
optional uint64 errors = 4;
}
optional FilterStats filter_stats = 11;
+
+ // Count of Flush() requests (either from the Consumer, or self-induced
+ // periodic flushes). The final Flush() is also included in the count.
+ optional uint64 flushes_requested = 12;
+
+ // The count of the Flush() requests that were completed successfully.
+ // In a well behaving trace this should always be == `flush_requests`.
+ optional uint64 flushes_succeeded = 13;
+
+ // The count of the Flush() requests that failed (in most timed out).
+ // In a well behaving trace this should always be == 0.
+ optional uint64 flushes_failed = 14;
+
+ enum FinalFlushOutcome {
+ FINAL_FLUSH_UNSPECIFIED = 0;
+ FINAL_FLUSH_SUCCEEDED = 1;
+ FINAL_FLUSH_FAILED = 2;
+ }
+ optional FinalFlushOutcome final_flush_outcome = 15;
}
diff --git a/protos/perfetto/common/tracing_service_state.proto b/protos/perfetto/common/tracing_service_state.proto
index 1ef4c56c1..6d796bc64 100644
--- a/protos/perfetto/common/tracing_service_state.proto
+++ b/protos/perfetto/common/tracing_service_state.proto
@@ -32,6 +32,10 @@ message TracingServiceState {
// Typically matches the process name.
optional string name = 2;
+ // Unix pid of the remote process. Supported only on Linux-based systems.
+ // Introduced in v24 / Android T.
+ optional int32 pid = 5;
+
// Unix uid of the remote process.
optional int32 uid = 3;
@@ -52,12 +56,53 @@ message TracingServiceState {
optional int32 producer_id = 2;
}
+ message TracingSession {
+ // The TracingSessionID.
+ optional uint64 id = 1;
+
+ // The Unix uid of the consumer that started the session.
+ // This is meaningful only if the caller is root. In all other cases only
+ // tracing sessions that match the caller UID will be displayed.
+ optional int32 consumer_uid = 2;
+
+ // Internal state of the tracing session.
+ // These strings are FYI only and subjected to change.
+ optional string state = 3;
+
+ // The unique_session_name as set in the trace config (might be empty).
+ optional string unique_session_name = 4;
+
+ // The number and size of each buffer.
+ repeated uint32 buffer_size_kb = 5;
+
+ // Duration, as specified in the TraceConfig.duration_ms.
+ optional uint32 duration_ms = 6;
+
+ // Number of data sources involved in the session.
+ optional uint32 num_data_sources = 7;
+
+ // Time when the session was started, in the CLOCK_REALTIME domain.
+ // Available only on Linux-based systems.
+ optional int64 start_realtime_ns = 8;
+ }
+
// Lists all the producers connected.
repeated Producer producers = 1;
// Lists the data sources available.
repeated DataSource data_sources = 2;
+ // Lists the tracing sessions active AND owned by a consumer that has the same
+ // UID of the caller (or all of them if the caller is root).
+ // Introduced in v24 / Android T.
+ repeated TracingSession tracing_sessions = 6;
+
+ // This is always set to true from v24 and beyond. This flag is only used to
+ // tell the difference between: (1) talking to a recent service which happens
+ // to have no tracing session active; (2) talking to an older version of the
+ // service which will never report any tracing session.
+ optional bool supports_tracing_sessions = 7;
+
// Total number of tracing sessions.
optional int32 num_sessions = 3;
diff --git a/protos/perfetto/config/BUILD.gn b/protos/perfetto/config/BUILD.gn
index de9c1f542..4b9685968 100644
--- a/protos/perfetto/config/BUILD.gn
+++ b/protos/perfetto/config/BUILD.gn
@@ -43,22 +43,9 @@ perfetto_proto_library("@TYPE@") {
]
}
-# This target is not used in the tree and is built only to guarantee that the
-# autogenerated merged proto has a valid syntax.
-perfetto_proto_library("merged_config") {
- proto_generators = [ "lite" ]
- sources = [ "perfetto_config.proto" ]
-}
-
perfetto_proto_library("descriptor") {
proto_generators = [ "descriptor" ]
generate_descriptor = "config.descriptor"
deps = [ ":source_set" ]
sources = [ "trace_config.proto" ]
}
-
-perfetto_proto_library("perfetto_config_descriptor") {
- proto_generators = [ "descriptor" ]
- generate_descriptor = "perfetto_config.descriptor"
- sources = [ "perfetto_config.proto" ]
-}
diff --git a/protos/perfetto/config/ftrace/ftrace_config.proto b/protos/perfetto/config/ftrace/ftrace_config.proto
index 070b4810d..917ac6831 100644
--- a/protos/perfetto/config/ftrace/ftrace_config.proto
+++ b/protos/perfetto/config/ftrace/ftrace_config.proto
@@ -48,4 +48,29 @@ message FtraceConfig {
// initialized synchronously on the data source start and hence avoiding
// timing races in tests.
optional bool initialize_ksyms_synchronously_for_testing = 14;
+
+ // When this boolean is true AND the ftrace_events contains "kmem/rss_stat",
+ // this option causes traced_probes to enable the "kmem/rss_stat_throttled"
+ // event instad if present, and fall back to "kmem/rss_stat" if not present.
+ // The historical context for this is the following:
+ // - Up to Android S (12), the rss_stat was internally throttled in its
+ // kernel implementation.
+ // - A change introduced in the kernels after S has introduced a new
+ // "rss_stat_throttled" making the original "rss_stat" event unthrottled
+ // (hence very spammy).
+ // - Not all Android T/13 devices will receive a new kernel though, hence we
+ // need to deal with both cases.
+ // For more context: go/rss-stat-throttled.
+ // TODO(kaleshsingh): implement the logic behind this. Right now this flag
+ // does nothing.
+ optional bool throttle_rss_stat = 15;
+
+ // If true, avoid enabling events that aren't statically known by
+ // traced_probes. Otherwise, the default is to emit such events as
+ // GenericFtraceEvent protos.
+ // Prefer to keep this flag at its default. This was added for Android
+ // tracing, where atrace categories and/or atrace HAL requested events can
+ // expand to events that aren't of interest to the tracing user.
+ // Introduced in: Android T.
+ optional bool disable_generic_events = 16;
}
diff --git a/protos/perfetto/config/perfetto_config.proto b/protos/perfetto/config/perfetto_config.proto
index 756c8a6c8..5c354e8e9 100644
--- a/protos/perfetto/config/perfetto_config.proto
+++ b/protos/perfetto/config/perfetto_config.proto
@@ -11,6 +11,24 @@ syntax = "proto2";
package perfetto.protos;
+option go_package = "github.com/google/perfetto/perfetto_proto";
+
+// Begin of protos/perfetto/common/ftrace_descriptor.proto
+
+message FtraceDescriptor {
+ message AtraceCategory {
+ optional string name = 1;
+ optional string description = 2;
+ }
+
+ // Report the available atrace categories.
+ //
+ // Used by Traceur via `perfetto --query`.
+ repeated AtraceCategory atrace_categories = 1;
+}
+
+// End of protos/perfetto/common/ftrace_descriptor.proto
+
// Begin of protos/perfetto/common/gpu_counter_descriptor.proto
// Description of GPU counters.
@@ -158,6 +176,13 @@ message DataSourceDescriptor {
// e.g., "linux.ftrace", "chromium.tracing"
optional string name = 1;
+ // When non-zero, this is a unique ID within the scope of the Producer for
+ // this data source (it is NOT globally unique). This is useful to
+ // differentiate between data sources with matching names when calling
+ // UpdateDataSource(). This field has been introduced in November 2021
+ // (v22, Android T) and is not supported on older versions.
+ optional uint64 id = 7;
+
// When true the data source is expected to ack the stop request through the
// NotifyDataSourceStopped() IPC. This field has been introduced after
// Android P in Jul 2018 and is not supported on older versions.
@@ -177,6 +202,8 @@ message DataSourceDescriptor {
optional GpuCounterDescriptor gpu_counter_descriptor = 5 [lazy = true];
optional TrackEventDescriptor track_event_descriptor = 6 [lazy = true];
+
+ optional FtraceDescriptor ftrace_descriptor = 8 [lazy = true];
}
// End of protos/perfetto/common/data_source_descriptor.proto
@@ -195,6 +222,10 @@ message TracingServiceState {
// Typically matches the process name.
optional string name = 2;
+ // Unix pid of the remote process. Supported only on Linux-based systems.
+ // Introduced in v24 / Android T.
+ optional int32 pid = 5;
+
// Unix uid of the remote process.
optional int32 uid = 3;
@@ -215,12 +246,53 @@ message TracingServiceState {
optional int32 producer_id = 2;
}
+ message TracingSession {
+ // The TracingSessionID.
+ optional uint64 id = 1;
+
+ // The Unix uid of the consumer that started the session.
+ // This is meaningful only if the caller is root. In all other cases only
+ // tracing sessions that match the caller UID will be displayed.
+ optional int32 consumer_uid = 2;
+
+ // Internal state of the tracing session.
+ // These strings are FYI only and subjected to change.
+ optional string state = 3;
+
+ // The unique_session_name as set in the trace config (might be empty).
+ optional string unique_session_name = 4;
+
+ // The number and size of each buffer.
+ repeated uint32 buffer_size_kb = 5;
+
+ // Duration, as specified in the TraceConfig.duration_ms.
+ optional uint32 duration_ms = 6;
+
+ // Number of data sources involved in the session.
+ optional uint32 num_data_sources = 7;
+
+ // Time when the session was started, in the CLOCK_REALTIME domain.
+ // Available only on Linux-based systems.
+ optional int64 start_realtime_ns = 8;
+ }
+
// Lists all the producers connected.
repeated Producer producers = 1;
// Lists the data sources available.
repeated DataSource data_sources = 2;
+ // Lists the tracing sessions active AND owned by a consumer that has the same
+ // UID of the caller (or all of them if the caller is root).
+ // Introduced in v24 / Android T.
+ repeated TracingSession tracing_sessions = 6;
+
+ // This is always set to true from v24 and beyond. This flag is only used to
+ // tell the difference between: (1) talking to a recent service which happens
+ // to have no tracing session active; (2) talking to an older version of the
+ // service which will never report any tracing session.
+ optional bool supports_tracing_sessions = 7;
+
// Total number of tracing sessions.
optional int32 num_sessions = 3;
@@ -249,6 +321,10 @@ enum BuiltinClock {
BUILTIN_CLOCK_MAX_ID = 63;
reserved 7, 8;
+
+ // An internal CL (ag/16521245) has taken this for BUILTIN_CLOCK_TSC.
+ // That might get upstreamed later on. Avoid diverging on this ID in future.
+ reserved 9;
}
// End of protos/perfetto/common/builtin_clock.proto
@@ -392,6 +468,31 @@ message FtraceConfig {
// initialized synchronously on the data source start and hence avoiding
// timing races in tests.
optional bool initialize_ksyms_synchronously_for_testing = 14;
+
+ // When this boolean is true AND the ftrace_events contains "kmem/rss_stat",
+ // this option causes traced_probes to enable the "kmem/rss_stat_throttled"
+ // event instad if present, and fall back to "kmem/rss_stat" if not present.
+ // The historical context for this is the following:
+ // - Up to Android S (12), the rss_stat was internally throttled in its
+ // kernel implementation.
+ // - A change introduced in the kernels after S has introduced a new
+ // "rss_stat_throttled" making the original "rss_stat" event unthrottled
+ // (hence very spammy).
+ // - Not all Android T/13 devices will receive a new kernel though, hence we
+ // need to deal with both cases.
+ // For more context: go/rss-stat-throttled.
+ // TODO(kaleshsingh): implement the logic behind this. Right now this flag
+ // does nothing.
+ optional bool throttle_rss_stat = 15;
+
+ // If true, avoid enabling events that aren't statically known by
+ // traced_probes. Otherwise, the default is to emit such events as
+ // GenericFtraceEvent protos.
+ // Prefer to keep this flag at its default. This was added for Android
+ // tracing, where atrace categories and/or atrace HAL requested events can
+ // expand to events that aren't of interest to the tracing user.
+ // Introduced in: Android T.
+ optional bool disable_generic_events = 16;
}
// End of protos/perfetto/config/ftrace/ftrace_config.proto
@@ -597,6 +698,10 @@ message HeapprofdConfig {
//
// BUGS
// Before Android 12, setting this to 0 would crash the target process.
+ //
+ // N.B. This must be explicitly set to a non-zero value for all heaps (with
+ // this field or with heap_sampling_intervals), otherwise the producer will
+ // not start.
optional uint64 sampling_interval_bytes = 1;
// If less than the given numbers of bytes are left free in the shared
@@ -651,6 +756,8 @@ message HeapprofdConfig {
// crash the target process before Android 12.
//
// Introduced in Android 12.
+ //
+ // All values must be non-zero or the producer will not start.
repeated uint64 heap_sampling_intervals = 22;
// Sample all heaps registered by target process. Introduced in Android 12.
@@ -751,7 +858,7 @@ message HeapprofdConfig {
// Begin of protos/perfetto/config/profiling/java_hprof_config.proto
-// Configuration for go/heapprofd.
+// Configuration for managed app heap graph snapshots.
message JavaHprofConfig {
// If dump_interval_ms != 0, the following configuration is used.
message ContinuousDumpConfig {
@@ -760,14 +867,36 @@ message JavaHprofConfig {
optional uint32 dump_phase_ms = 1;
// ms to wait between following dumps.
optional uint32 dump_interval_ms = 2;
+ // If true, scans all the processes to find `process_cmdline` and filter by
+ // `min_anonymous_memory_kb` only at data source start. Default on Android
+ // S-.
+ //
+ // If false, rescans all the processes to find on every dump. Default on
+ // Android T+.
+ optional bool scan_pids_only_on_start = 3;
}
- // This input is normalized in the following way: if it contains slashes,
- // everything up to the last slash is discarded. If it contains "@",
- // everything after the first @ is discared.
- // E.g. /system/bin/surfaceflinger@1.0 normalizes to surfaceflinger.
- // This transformation is also applied to the processes' command lines when
- // matching.
+ // Command line allowlist, matched against the /proc/<pid>/cmdline (not the
+ // comm string). The semantics of this field were changed since its original
+ // introduction.
+ //
+ // On Android T+ (13+), this field can specify a single wildcard (*), and
+ // the profiler will attempt to match it in two possible ways:
+ // * if the pattern starts with a '/', then it is matched against the first
+ // segment of the cmdline (i.e. argv0). For example "/bin/e*" would match
+ // "/bin/echo".
+ // * otherwise the pattern is matched against the part of argv0
+ // corresponding to the binary name (this is unrelated to /proc/pid/exe).
+ // For example "echo" would match "/bin/echo".
+ //
+ // On Android S (12) and below, both this pattern and /proc/pid/cmdline get
+ // normalized prior to an exact string comparison. Normalization is as
+ // follows: (1) trim everything beyond the first null or "@" byte; (2) if
+ // the string contains forward slashes, trim everything up to and including
+ // the last one.
+ //
+ // Implementation note: in either case, at most 511 characters of cmdline
+ // are considered.
repeated string process_cmdline = 1;
// For watermark based triggering or local debugging.
@@ -804,6 +933,7 @@ message JavaHprofConfig {
// Begin of protos/perfetto/common/perf_events.proto
+// Next id: 12
message PerfEvents {
// What event to sample on, and how often. Commented from the perspective of
// its use in |PerfEventConfig|.
@@ -833,17 +963,72 @@ message PerfEvents {
oneof event {
Counter counter = 4;
Tracepoint tracepoint = 3;
+ RawEvent raw_event = 5;
}
+
+ // If set, samples will be timestamped with the given clock.
+ // If unset, the clock is chosen by the implementation.
+ // For software events, prefer PERF_CLOCK_BOOTTIME. However it cannot be
+ // used for hardware events (due to interrupt safety), for which the
+ // recommendation is to use one of the monotonic clocks.
+ optional PerfClock timestamp_clock = 11;
+
+ // Optional arbitrary name for the event, to identify it in the parsed
+ // trace. Does *not* affect the profiling itself. If unset, the trace
+ // parser will choose a suitable name.
+ optional string name = 10;
}
+ // Builtin counter names from the uapi header. Commented with their perf tool
+ // aliases.
+ // TODO(rsavitski): consider generating enums for cache events (should be
+ // finite), and generally make this list as extensive as possible. Excluding
+ // things like dynamic PMUs since those don't fit into a static enum.
+ // Next id: 21
enum Counter {
UNKNOWN_COUNTER = 0;
- // software:
+
+ // cpu-clock
SW_CPU_CLOCK = 1;
+ // page-faults, faults
SW_PAGE_FAULTS = 2;
- // hardware:
+ // task-clock
+ SW_TASK_CLOCK = 3;
+ // context-switches, cs
+ SW_CONTEXT_SWITCHES = 4;
+ // cpu-migrations, migrations
+ SW_CPU_MIGRATIONS = 5;
+ // minor-faults
+ SW_PAGE_FAULTS_MIN = 6;
+ // major-faults
+ SW_PAGE_FAULTS_MAJ = 7;
+ // alignment-faults
+ SW_ALIGNMENT_FAULTS = 8;
+ // emulation-faults
+ SW_EMULATION_FAULTS = 9;
+ // dummy
+ SW_DUMMY = 20;
+
+ // cpu-cycles, cycles
HW_CPU_CYCLES = 10;
+ // instructions
HW_INSTRUCTIONS = 11;
+ // cache-references
+ HW_CACHE_REFERENCES = 12;
+ // cache-misses
+ HW_CACHE_MISSES = 13;
+ // branch-instructions, branches
+ HW_BRANCH_INSTRUCTIONS = 14;
+ // branch-misses
+ HW_BRANCH_MISSES = 15;
+ // bus-cycles
+ HW_BUS_CYCLES = 16;
+ // stalled-cycles-frontend, idle-cycles-frontend
+ HW_STALLED_CYCLES_FRONTEND = 17;
+ // stalled-cycles-backend, idle-cycles-backend
+ HW_STALLED_CYCLES_BACKEND = 18;
+ // ref-cycles
+ HW_REF_CPU_CYCLES = 19;
}
message Tracepoint {
@@ -859,6 +1044,27 @@ message PerfEvents {
// https://www.kernel.org/doc/Documentation/trace/events.txt
optional string filter = 2;
}
+
+ // Syscall-level description of the event, propagated to the perf_event_attr
+ // struct. Primarily for local use-cases, since the event availability and
+ // encoding is hardware-specific.
+ message RawEvent {
+ optional uint32 type = 1;
+ optional uint64 config = 2;
+ optional uint64 config1 = 3;
+ optional uint64 config2 = 4;
+ }
+
+ // Subset of clocks that is supported by perf timestamping.
+ // CLOCK_TAI is excluded since it's not expected to be used in practice, but
+ // would require additions to the trace clock synchronisation logic.
+ enum PerfClock {
+ UNKNOWN_PERF_CLOCK = 0;
+ PERF_CLOCK_REALTIME = 1;
+ PERF_CLOCK_MONOTONIC = 2;
+ PERF_CLOCK_MONOTONIC_RAW = 3;
+ PERF_CLOCK_BOOTTIME = 4;
+ }
}
// End of protos/perfetto/common/perf_events.proto
@@ -939,6 +1145,14 @@ message PerfEventConfig {
// If unset, the cached state will not be cleared.
optional uint32 unwind_state_clear_period_ms = 10;
+ // If set, only profile target if it was installed by a package with one of
+ // these names. Special values:
+ // * "@system": installed on the system partition
+ // * "@product": installed on the product partition
+ // * "@null": sideloaded
+ // Supported on Android 12+.
+ repeated string target_installed_by = 18;
+
//
// Deprecated (superseded by options above):
//
@@ -952,14 +1166,6 @@ message PerfEventConfig {
optional bool kernel_frames = 12;
repeated int32 target_pid = 4;
repeated string target_cmdline = 5;
-
- // Only profile target if it was installed by one of the packages given.
- // Special values are:
- // * @system: installed on the system partition
- // * @product: installed on the product partition
- // * @null: sideloaded
- // Supported on Android 12+.
- repeated string target_installed_by = 18;
repeated int32 exclude_pid = 6;
repeated string exclude_cmdline = 7;
optional uint32 additional_cmdline_count = 11;
@@ -993,18 +1199,34 @@ message PerfEventConfig {
// process.
repeated int32 target_pid = 1;
- // Command line allowlist, matched against the
- // /proc/<pid>/cmdline (not the comm string), with both sides being
- // "normalized". Normalization is as follows: (1) trim everything beyond the
- // first null or "@" byte; (2) if the string contains forward slashes, trim
- // everything up to and including the last one.
+ // Command line allowlist, matched against the /proc/<pid>/cmdline (not the
+ // comm string). The semantics of this field were changed since its original
+ // introduction.
+ //
+ // On Android T+ (13+), this field can specify a single wildcard (*), and
+ // the profiler will attempt to match it in two possible ways:
+ // * if the pattern starts with a '/', then it is matched against the first
+ // segment of the cmdline (i.e. argv0). For example "/bin/e*" would match
+ // "/bin/echo".
+ // * otherwise the pattern is matched against the part of argv0
+ // corresponding to the binary name (this is unrelated to /proc/pid/exe).
+ // For example "echo" would match "/bin/echo".
+ //
+ // On Android S (12) and below, both this pattern and /proc/pid/cmdline get
+ // normalized prior to an exact string comparison. Normalization is as
+ // follows: (1) trim everything beyond the first null or "@" byte; (2) if
+ // the string contains forward slashes, trim everything up to and including
+ // the last one.
+ //
+ // Implementation note: in either case, at most 511 characters of cmdline
+ // are considered.
repeated string target_cmdline = 2;
// List of excluded pids.
repeated int32 exclude_pid = 3;
- // List of excluded cmdlines. Normalized in the same way as
- // |target_cmdline|.
+ // List of excluded cmdlines. See description of |target_cmdline| for how
+ // this is handled.
repeated string exclude_cmdline = 4;
// Number of additional command lines to sample. Only those which are
@@ -1238,6 +1460,10 @@ message SysStatsConfig {
// This option can be used to record unchanging values.
// Updates from frequency changes can come from ftrace/set_clock_rate.
optional uint32 devfreq_period_ms = 7;
+
+ // Polls /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_cur_freq every X ms.
+ // This is required to be > 10ms to avoid excessive CPU usage.
+ optional uint32 cpufreq_period_ms = 8;
}
// End of protos/perfetto/config/sys_stats/sys_stats_config.proto
@@ -1333,11 +1559,28 @@ message TrackEventConfig {
// Default: []
repeated string enabled_categories = 2;
- // Default: [“slowâ€, “debugâ€]
+ // Default: ["slow", "debug"]
repeated string disabled_tags = 3;
// Default: []
repeated string enabled_tags = 4;
+
+ // Default: false (i.e. enabled by default)
+ optional bool disable_incremental_timestamps = 5;
+
+ // Allows to specify a custom unit different than the default (ns).
+ // A multiplier of 1000 means that a timestamp = 3 should be interpreted as
+ // 3000 ns = 3 us.
+ // Default: 1 (if unset, it should be read as 1).
+ // For now, this multiplier only affects incremental timestamps.
+ // Note: This isn't supported in the SDK yet. It will be supported soon.
+ optional uint64 timestamp_unit_multipler = 6;
+
+ // Default: false (i.e. debug_annotations is NOT filtered out by default)
+ // When true, any debug annotations provided as arguments to the
+ // TRACE_EVENT macros are not written into the trace. Typed arguments will
+ // still be emitted even if set to true.
+ optional bool filter_debug_annotations = 7;
}
// End of protos/perfetto/config/track_event/track_event_config.proto
@@ -1474,7 +1717,7 @@ message DataSourceConfig {
// It contains the general config for the logging buffer(s) and the configs for
// all the data source being enabled.
//
-// Next id: 33.
+// Next id: 35.
message TraceConfig {
message BufferConfig {
optional uint32 size_kb = 1;
@@ -1874,10 +2117,77 @@ message TraceConfig {
// provided. The filter is applied at ReadBuffers() time and works both in the
// case of IPC readback and write_into_file. This filter can be generated
// using `tools/proto_filter -s schema.proto -F filter_out.bytes` or
- // `-T filter_out.escaped_string` (for .pbtx).
- // Introduced in Android S. See go/trace-filtering for design.
- message TraceFilter { optional bytes bytecode = 1; }
- optional TraceFilter trace_filter = 32;
+ // `-T filter_out.escaped_string` (for .pbtx). See go/trace-filtering for
+ // design.
+ //
+ // Introduced in Android S, but it was broken (b/195065199). Reintroduced in
+ // Android T with a different field number.
+ message TraceFilter {
+ optional bytes bytecode = 1;
+ }
+ // old field number for trace_filter
+ reserved 32;
+ optional TraceFilter trace_filter = 33;
+
+ // Android-only. Not for general use. If set, reports the trace to the
+ // Android framework. This field is read by perfetto_cmd, rather than the
+ // tracing service. This field must be set when passing the --upload flag to
+ // perfetto_cmd.
+ message AndroidReportConfig {
+ // In this message, either:
+ // * |reporter_service_package| and |reporter_service_class| must be set.
+ // * |skip_reporting| must be explicitly set to true.
+
+ optional string reporter_service_package = 1;
+ optional string reporter_service_class = 2;
+
+ // If true, then skips reporting the trace to Android framework.
+ //
+ // This flag is useful in testing (e.g. Perfetto-statsd integration tests)
+ // or when we explicitly don't want to report traces to the framework even
+ // when they usually would (e.g. configs deployed using statsd but only
+ // used for inclusion in bugreports using |bugreport_score|).
+ //
+ // The motivation for having this flag, instead of just not setting
+ // |framework_report_config|, is prevent accidents where
+ // |framework_report_config| is omitted by mistake.
+ optional bool skip_report = 3;
+
+ // If true, will direct the Android framework to read the data in trace
+ // file and pass it to the reporter class over a pipe instead of passing
+ // the file descriptor directly.
+ //
+ // This flag is needed because the Android test framework does not
+ // currently support priv-app helper apps (in terms of SELinux) and we
+ // really don't want to add an allow rule for untrusted_app to receive
+ // trace fds.
+ //
+ // Because of this, we instead will direct the framework to create a new
+ // pipe and pass this to the reporter process instead. As the pipe is
+ // created by the framework, we won't have any problems with SELinux
+ // (system_server is already allowed to pass pipe fds, even
+ // to untrusted apps).
+ //
+ // As the name suggests this option *MUST* only be used for testing.
+ // Note that the framework will reject (and drop) files which are too
+ // large both for simplicity and to be minimize the amount of data we
+ // pass to a non-priv app (note that the framework will still check
+ // manifest permissions even though SELinux permissions are worked around).
+ optional bool use_pipe_in_framework_for_testing = 4;
+ }
+ optional AndroidReportConfig android_report_config = 34;
+
+ // If set, delays the start of tracing by a random duration. The duration is
+ // chosen from a uniform distribution between the specified minimum and
+ // maximum.
+ // Note: this delay is implemented by perfetto_cmd *not* by traced so will
+ // not work if you communicate with traced directly over the consumer API.
+ // Introduced in Android T.
+ message CmdTraceStartDelay {
+ optional uint32 min_delay_ms = 1;
+ optional uint32 max_delay_ms = 2;
+ }
+ optional CmdTraceStartDelay cmd_trace_start_delay = 35;
}
// End of protos/perfetto/config/trace_config.proto
diff --git a/protos/perfetto/config/profiling/heapprofd_config.proto b/protos/perfetto/config/profiling/heapprofd_config.proto
index 00dd6929c..2636e06dd 100644
--- a/protos/perfetto/config/profiling/heapprofd_config.proto
+++ b/protos/perfetto/config/profiling/heapprofd_config.proto
@@ -45,6 +45,10 @@ message HeapprofdConfig {
//
// BUGS
// Before Android 12, setting this to 0 would crash the target process.
+ //
+ // N.B. This must be explicitly set to a non-zero value for all heaps (with
+ // this field or with heap_sampling_intervals), otherwise the producer will
+ // not start.
optional uint64 sampling_interval_bytes = 1;
// If less than the given numbers of bytes are left free in the shared
@@ -99,6 +103,8 @@ message HeapprofdConfig {
// crash the target process before Android 12.
//
// Introduced in Android 12.
+ //
+ // All values must be non-zero or the producer will not start.
repeated uint64 heap_sampling_intervals = 22;
// Sample all heaps registered by target process. Introduced in Android 12.
diff --git a/protos/perfetto/config/profiling/java_hprof_config.proto b/protos/perfetto/config/profiling/java_hprof_config.proto
index d5046782e..c1613963f 100644
--- a/protos/perfetto/config/profiling/java_hprof_config.proto
+++ b/protos/perfetto/config/profiling/java_hprof_config.proto
@@ -18,7 +18,7 @@ syntax = "proto2";
package perfetto.protos;
-// Configuration for go/heapprofd.
+// Configuration for managed app heap graph snapshots.
message JavaHprofConfig {
// If dump_interval_ms != 0, the following configuration is used.
message ContinuousDumpConfig {
@@ -27,14 +27,36 @@ message JavaHprofConfig {
optional uint32 dump_phase_ms = 1;
// ms to wait between following dumps.
optional uint32 dump_interval_ms = 2;
+ // If true, scans all the processes to find `process_cmdline` and filter by
+ // `min_anonymous_memory_kb` only at data source start. Default on Android
+ // S-.
+ //
+ // If false, rescans all the processes to find on every dump. Default on
+ // Android T+.
+ optional bool scan_pids_only_on_start = 3;
}
- // This input is normalized in the following way: if it contains slashes,
- // everything up to the last slash is discarded. If it contains "@",
- // everything after the first @ is discared.
- // E.g. /system/bin/surfaceflinger@1.0 normalizes to surfaceflinger.
- // This transformation is also applied to the processes' command lines when
- // matching.
+ // Command line allowlist, matched against the /proc/<pid>/cmdline (not the
+ // comm string). The semantics of this field were changed since its original
+ // introduction.
+ //
+ // On Android T+ (13+), this field can specify a single wildcard (*), and
+ // the profiler will attempt to match it in two possible ways:
+ // * if the pattern starts with a '/', then it is matched against the first
+ // segment of the cmdline (i.e. argv0). For example "/bin/e*" would match
+ // "/bin/echo".
+ // * otherwise the pattern is matched against the part of argv0
+ // corresponding to the binary name (this is unrelated to /proc/pid/exe).
+ // For example "echo" would match "/bin/echo".
+ //
+ // On Android S (12) and below, both this pattern and /proc/pid/cmdline get
+ // normalized prior to an exact string comparison. Normalization is as
+ // follows: (1) trim everything beyond the first null or "@" byte; (2) if
+ // the string contains forward slashes, trim everything up to and including
+ // the last one.
+ //
+ // Implementation note: in either case, at most 511 characters of cmdline
+ // are considered.
repeated string process_cmdline = 1;
// For watermark based triggering or local debugging.
diff --git a/protos/perfetto/config/profiling/perf_event_config.proto b/protos/perfetto/config/profiling/perf_event_config.proto
index 754d948df..a440464c2 100644
--- a/protos/perfetto/config/profiling/perf_event_config.proto
+++ b/protos/perfetto/config/profiling/perf_event_config.proto
@@ -94,6 +94,14 @@ message PerfEventConfig {
// If unset, the cached state will not be cleared.
optional uint32 unwind_state_clear_period_ms = 10;
+ // If set, only profile target if it was installed by a package with one of
+ // these names. Special values:
+ // * "@system": installed on the system partition
+ // * "@product": installed on the product partition
+ // * "@null": sideloaded
+ // Supported on Android 12+.
+ repeated string target_installed_by = 18;
+
//
// Deprecated (superseded by options above):
//
@@ -107,14 +115,6 @@ message PerfEventConfig {
optional bool kernel_frames = 12;
repeated int32 target_pid = 4;
repeated string target_cmdline = 5;
-
- // Only profile target if it was installed by one of the packages given.
- // Special values are:
- // * @system: installed on the system partition
- // * @product: installed on the product partition
- // * @null: sideloaded
- // Supported on Android 12+.
- repeated string target_installed_by = 18;
repeated int32 exclude_pid = 6;
repeated string exclude_cmdline = 7;
optional uint32 additional_cmdline_count = 11;
@@ -148,18 +148,34 @@ message PerfEventConfig {
// process.
repeated int32 target_pid = 1;
- // Command line allowlist, matched against the
- // /proc/<pid>/cmdline (not the comm string), with both sides being
- // "normalized". Normalization is as follows: (1) trim everything beyond the
- // first null or "@" byte; (2) if the string contains forward slashes, trim
- // everything up to and including the last one.
+ // Command line allowlist, matched against the /proc/<pid>/cmdline (not the
+ // comm string). The semantics of this field were changed since its original
+ // introduction.
+ //
+ // On Android T+ (13+), this field can specify a single wildcard (*), and
+ // the profiler will attempt to match it in two possible ways:
+ // * if the pattern starts with a '/', then it is matched against the first
+ // segment of the cmdline (i.e. argv0). For example "/bin/e*" would match
+ // "/bin/echo".
+ // * otherwise the pattern is matched against the part of argv0
+ // corresponding to the binary name (this is unrelated to /proc/pid/exe).
+ // For example "echo" would match "/bin/echo".
+ //
+ // On Android S (12) and below, both this pattern and /proc/pid/cmdline get
+ // normalized prior to an exact string comparison. Normalization is as
+ // follows: (1) trim everything beyond the first null or "@" byte; (2) if
+ // the string contains forward slashes, trim everything up to and including
+ // the last one.
+ //
+ // Implementation note: in either case, at most 511 characters of cmdline
+ // are considered.
repeated string target_cmdline = 2;
// List of excluded pids.
repeated int32 exclude_pid = 3;
- // List of excluded cmdlines. Normalized in the same way as
- // |target_cmdline|.
+ // List of excluded cmdlines. See description of |target_cmdline| for how
+ // this is handled.
repeated string exclude_cmdline = 4;
// Number of additional command lines to sample. Only those which are
diff --git a/protos/perfetto/config/sys_stats/sys_stats_config.proto b/protos/perfetto/config/sys_stats/sys_stats_config.proto
index 0986924ce..09d34eadc 100644
--- a/protos/perfetto/config/sys_stats/sys_stats_config.proto
+++ b/protos/perfetto/config/sys_stats/sys_stats_config.proto
@@ -63,4 +63,8 @@ message SysStatsConfig {
// This option can be used to record unchanging values.
// Updates from frequency changes can come from ftrace/set_clock_rate.
optional uint32 devfreq_period_ms = 7;
+
+ // Polls /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_cur_freq every X ms.
+ // This is required to be > 10ms to avoid excessive CPU usage.
+ optional uint32 cpufreq_period_ms = 8;
}
diff --git a/protos/perfetto/config/trace_config.proto b/protos/perfetto/config/trace_config.proto
index dbc1babda..be1ba8237 100644
--- a/protos/perfetto/config/trace_config.proto
+++ b/protos/perfetto/config/trace_config.proto
@@ -16,17 +16,17 @@
syntax = "proto2";
-import "protos/perfetto/config/data_source_config.proto";
-import "protos/perfetto/common/builtin_clock.proto";
-
package perfetto.protos;
+import "protos/perfetto/common/builtin_clock.proto";
+import "protos/perfetto/config/data_source_config.proto";
+
// The overall config that is used when starting a new tracing session through
// ProducerPort::StartTracing().
// It contains the general config for the logging buffer(s) and the configs for
// all the data source being enabled.
//
-// Next id: 33.
+// Next id: 35.
message TraceConfig {
message BufferConfig {
optional uint32 size_kb = 1;
@@ -426,8 +426,75 @@ message TraceConfig {
// provided. The filter is applied at ReadBuffers() time and works both in the
// case of IPC readback and write_into_file. This filter can be generated
// using `tools/proto_filter -s schema.proto -F filter_out.bytes` or
- // `-T filter_out.escaped_string` (for .pbtx).
- // Introduced in Android S. See go/trace-filtering for design.
- message TraceFilter { optional bytes bytecode = 1; }
- optional TraceFilter trace_filter = 32;
+ // `-T filter_out.escaped_string` (for .pbtx). See go/trace-filtering for
+ // design.
+ //
+ // Introduced in Android S, but it was broken (b/195065199). Reintroduced in
+ // Android T with a different field number.
+ message TraceFilter {
+ optional bytes bytecode = 1;
+ }
+ // old field number for trace_filter
+ reserved 32;
+ optional TraceFilter trace_filter = 33;
+
+ // Android-only. Not for general use. If set, reports the trace to the
+ // Android framework. This field is read by perfetto_cmd, rather than the
+ // tracing service. This field must be set when passing the --upload flag to
+ // perfetto_cmd.
+ message AndroidReportConfig {
+ // In this message, either:
+ // * |reporter_service_package| and |reporter_service_class| must be set.
+ // * |skip_reporting| must be explicitly set to true.
+
+ optional string reporter_service_package = 1;
+ optional string reporter_service_class = 2;
+
+ // If true, then skips reporting the trace to Android framework.
+ //
+ // This flag is useful in testing (e.g. Perfetto-statsd integration tests)
+ // or when we explicitly don't want to report traces to the framework even
+ // when they usually would (e.g. configs deployed using statsd but only
+ // used for inclusion in bugreports using |bugreport_score|).
+ //
+ // The motivation for having this flag, instead of just not setting
+ // |framework_report_config|, is prevent accidents where
+ // |framework_report_config| is omitted by mistake.
+ optional bool skip_report = 3;
+
+ // If true, will direct the Android framework to read the data in trace
+ // file and pass it to the reporter class over a pipe instead of passing
+ // the file descriptor directly.
+ //
+ // This flag is needed because the Android test framework does not
+ // currently support priv-app helper apps (in terms of SELinux) and we
+ // really don't want to add an allow rule for untrusted_app to receive
+ // trace fds.
+ //
+ // Because of this, we instead will direct the framework to create a new
+ // pipe and pass this to the reporter process instead. As the pipe is
+ // created by the framework, we won't have any problems with SELinux
+ // (system_server is already allowed to pass pipe fds, even
+ // to untrusted apps).
+ //
+ // As the name suggests this option *MUST* only be used for testing.
+ // Note that the framework will reject (and drop) files which are too
+ // large both for simplicity and to be minimize the amount of data we
+ // pass to a non-priv app (note that the framework will still check
+ // manifest permissions even though SELinux permissions are worked around).
+ optional bool use_pipe_in_framework_for_testing = 4;
+ }
+ optional AndroidReportConfig android_report_config = 34;
+
+ // If set, delays the start of tracing by a random duration. The duration is
+ // chosen from a uniform distribution between the specified minimum and
+ // maximum.
+ // Note: this delay is implemented by perfetto_cmd *not* by traced so will
+ // not work if you communicate with traced directly over the consumer API.
+ // Introduced in Android T.
+ message CmdTraceStartDelay {
+ optional uint32 min_delay_ms = 1;
+ optional uint32 max_delay_ms = 2;
+ }
+ optional CmdTraceStartDelay cmd_trace_start_delay = 35;
}
diff --git a/protos/perfetto/config/track_event/track_event_config.proto b/protos/perfetto/config/track_event/track_event_config.proto
index 5f4160e75..3725cd1e8 100644
--- a/protos/perfetto/config/track_event/track_event_config.proto
+++ b/protos/perfetto/config/track_event/track_event_config.proto
@@ -59,9 +59,26 @@ message TrackEventConfig {
// Default: []
repeated string enabled_categories = 2;
- // Default: [“slowâ€, “debugâ€]
+ // Default: ["slow", "debug"]
repeated string disabled_tags = 3;
// Default: []
repeated string enabled_tags = 4;
+
+ // Default: false (i.e. enabled by default)
+ optional bool disable_incremental_timestamps = 5;
+
+ // Allows to specify a custom unit different than the default (ns).
+ // A multiplier of 1000 means that a timestamp = 3 should be interpreted as
+ // 3000 ns = 3 us.
+ // Default: 1 (if unset, it should be read as 1).
+ // For now, this multiplier only affects incremental timestamps.
+ // Note: This isn't supported in the SDK yet. It will be supported soon.
+ optional uint64 timestamp_unit_multipler = 6;
+
+ // Default: false (i.e. debug_annotations is NOT filtered out by default)
+ // When true, any debug annotations provided as arguments to the
+ // TRACE_EVENT macros are not written into the trace. Typed arguments will
+ // still be emitted even if set to true.
+ optional bool filter_debug_annotations = 7;
}
diff --git a/protos/perfetto/ipc/BUILD.gn b/protos/perfetto/ipc/BUILD.gn
index 49c077e79..fb9bfcfd2 100644
--- a/protos/perfetto/ipc/BUILD.gn
+++ b/protos/perfetto/ipc/BUILD.gn
@@ -21,6 +21,7 @@ perfetto_proto_library("@TYPE@") {
proto_generators = [
"ipc",
"cpp",
+ "source_set",
]
sources = [
"consumer_port.proto",
@@ -39,6 +40,7 @@ perfetto_proto_library("wire_protocol_@TYPE@") {
proto_generators = [
"zero",
"cpp",
+ "source_set",
]
sources = [ "wire_protocol.proto" ]
}
diff --git a/protos/perfetto/ipc/OWNERS b/protos/perfetto/ipc/OWNERS
new file mode 100644
index 000000000..a10c8b820
--- /dev/null
+++ b/protos/perfetto/ipc/OWNERS
@@ -0,0 +1,9 @@
+# Changes to the Tracing Protocol ABI are extremely subtle because they need to
+# be forward/backward compatible with various combinations of producer and
+# service versions. Adding >1 OWNER is encouraged here.
+
+set noparent
+eseckler@google.com
+hjd@google.com
+primiano@google.com
+skyostil@google.com
diff --git a/protos/perfetto/ipc/producer_port.proto b/protos/perfetto/ipc/producer_port.proto
index 50b90e7a2..d63f5bb69 100644
--- a/protos/perfetto/ipc/producer_port.proto
+++ b/protos/perfetto/ipc/producer_port.proto
@@ -29,7 +29,7 @@ service ProducerPort {
rpc InitializeConnection(InitializeConnectionRequest)
returns (InitializeConnectionResponse) {}
- // Advertises a data source.
+ // Advertises a new data source.
rpc RegisterDataSource(RegisterDataSourceRequest)
returns (RegisterDataSourceResponse) {}
@@ -92,6 +92,17 @@ service ProducerPort {
// When the Sync() response is received, the producer is guaranteed that the
// service has seen both data source registrations.
rpc Sync(SyncRequest) returns (SyncResponse) {}
+
+ // ----------------------------------------------------
+ // All methods below have been introduced in Android T.
+ // ----------------------------------------------------
+
+ // Updates the data source descriptor for an already-registered data source.
+ // This can be used to update the list of features supported.
+ // Only the data source with a matching data_source_descriptor.id is updated.
+ // The data_source_descriptor.name cannot be changed.
+ rpc UpdateDataSource(UpdateDataSourceRequest)
+ returns (UpdateDataSourceResponse) {}
}
// Arguments for rpc InitializeConnection().
@@ -128,16 +139,11 @@ message InitializeConnectionRequest {
// If provided, overrides the service's SMB scraping setting for the producer.
optional ProducerSMBScrapingMode smb_scraping_mode = 4;
- enum ProducerBuildFlags {
- BUILD_FLAGS_UNSPECIFIED = 0;
- BUILD_FLAGS_DCHECKS_ON = 1;
- BUILD_FLAGS_DCHECKS_OFF = 2;
- }
-
- // If provided, reports the build flags of the producer. It's used merely for
- // error reporting, to print a log message when a producer connects to a
- // service that has mismatching build flags.
- optional ProducerBuildFlags build_flags = 5;
+ // Was build_flags = BUILD_FLAGS_DCHECKS_ON|OFF. It was used to emit an error
+ // when DCHECKs level didn't match between service and producer (in turn that
+ // would crash the service when applying patches).
+ // Removed in v20 as part of b/197340286.
+ reserved 5;
// ---------------------------------------------------
// All fields below have been introduced in Android R.
@@ -162,6 +168,11 @@ message InitializeConnectionRequest {
// the build system that is used to build the code and the repo (standalone
// vs AOSP). This is intended for human debugging only.
optional string sdk_version = 8;
+
+ // On Windows, when producer_provided_shmem = true, the client creates a named
+ // SHM region and passes the name (an unguessable token) back to the service.
+ // Introduced in v13.
+ optional string shm_key_windows = 7;
}
message InitializeConnectionResponse {
@@ -187,6 +198,16 @@ message RegisterDataSourceResponse {
optional string error = 1;
};
+// Arguments for rpc UpdateDataSource().
+
+message UpdateDataSourceRequest {
+ // The new data_source_descriptor.{id, name} must match {id, name} of a
+ // data source previously registered via RegisterDataSource().
+ optional protos.DataSourceDescriptor data_source_descriptor = 1;
+}
+
+message UpdateDataSourceResponse {};
+
// Arguments for rpc UnregisterDataSource().
message UnregisterDataSourceRequest {
@@ -276,6 +297,11 @@ message GetAsyncCommandResponse {
// the shared memory buffer (not a proto field).
message SetupTracing {
optional uint32 shared_buffer_page_size_kb = 1;
+
+ // On Windows, instead, we pass the name (an unguessable token) of a shared
+ // memory region that can be attached by the other process by name.
+ // Introduced in v13.
+ optional string shm_key_windows = 2;
}
message Flush {
diff --git a/protos/perfetto/metrics/BUILD.gn b/protos/perfetto/metrics/BUILD.gn
index a0aec35e8..751ed949b 100644
--- a/protos/perfetto/metrics/BUILD.gn
+++ b/protos/perfetto/metrics/BUILD.gn
@@ -33,6 +33,6 @@ perfetto_proto_library("custom_options_@TYPE@") {
perfetto_proto_library("descriptor") {
proto_generators = [ "descriptor" ]
generate_descriptor = "metrics.descriptor"
- deps = [ "android:source_set" ]
+ deps = [ ":source_set" ]
sources = [ "metrics.proto" ]
}
diff --git a/protos/perfetto/metrics/android/BUILD.gn b/protos/perfetto/metrics/android/BUILD.gn
index 5e45f9cd2..c32d09317 100644
--- a/protos/perfetto/metrics/android/BUILD.gn
+++ b/protos/perfetto/metrics/android/BUILD.gn
@@ -20,16 +20,21 @@ perfetto_proto_library("@TYPE@") {
"source_set",
]
sources = [
+ "android_trusty_workqueues.proto",
"batt_metric.proto",
+ "camera_metric.proto",
+ "camera_unagg_metric.proto",
"cpu_metric.proto",
"display_metrics.proto",
"dma_heap_metric.proto",
+ "dvfs_metric.proto",
"fastrpc_metric.proto",
"g2d_metric.proto",
"gpu_metric.proto",
"hwcomposer.proto",
"hwui_metric.proto",
"ion_metric.proto",
+ "irq_runtime_metric.proto",
"jank_metric.proto",
"java_heap_histogram.proto",
"java_heap_stats.proto",
@@ -37,14 +42,21 @@ perfetto_proto_library("@TYPE@") {
"lmk_reason_metric.proto",
"mem_metric.proto",
"mem_unagg_metric.proto",
+ "multiuser_metric.proto",
+ "network_metric.proto",
+ "other_traces.proto",
"package_list.proto",
"powrails_metric.proto",
"process_metadata.proto",
+ "profiler_smaps.proto",
+ "rt_runtime_metric.proto",
+ "simpleperf.proto",
"startup_metric.proto",
"surfaceflinger.proto",
"sysui_cuj_metrics.proto",
"task_names.proto",
"thread_time_in_state_metric.proto",
+ "trace_quality.proto",
"unsymbolized_frames.proto",
]
}
diff --git a/protos/perfetto/metrics/android/android_trusty_workqueues.proto b/protos/perfetto/metrics/android/android_trusty_workqueues.proto
new file mode 100644
index 000000000..b7a1d5a3d
--- /dev/null
+++ b/protos/perfetto/metrics/android/android_trusty_workqueues.proto
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+// Metric used to generate a simplified view of the Trusty kworker events.
+message AndroidTrustyWorkqueues {}
diff --git a/protos/perfetto/metrics/android/camera_metric.proto b/protos/perfetto/metrics/android/camera_metric.proto
new file mode 100644
index 000000000..932cd7e93
--- /dev/null
+++ b/protos/perfetto/metrics/android/camera_metric.proto
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+message AndroidCameraMetric {
+ message Counter {
+ optional double min = 1;
+ optional double max = 2;
+ optional double avg = 3;
+ }
+
+ // Counter for the sum of DMA and RSS across GCA, cameraserver
+ // and HAL. This provides a single number for the memory
+ // pressure using the camera is putting on the rest of the
+ // system.
+ //
+ // Note: this number assumes that all DMA pressure is coming
+ // from the camera as this is usually a pretty good
+ // approximation. Being more accurate here would increase the
+ // complexity of the metric significantly.
+ //
+ // Note: if there are multiple GCA/cameraserver/HAL processes
+ // in the trace, this metric will simply take the latest
+ // one in the trace and ignore the others.
+ optional Counter gc_rss_and_dma = 1;
+}
diff --git a/protos/perfetto/metrics/android/camera_unagg_metric.proto b/protos/perfetto/metrics/android/camera_unagg_metric.proto
new file mode 100644
index 000000000..fc6a5dd02
--- /dev/null
+++ b/protos/perfetto/metrics/android/camera_unagg_metric.proto
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+message AndroidCameraUnaggregatedMetric {
+ message Value {
+ optional int64 ts = 1;
+ optional double value = 2;
+ }
+
+ // Timeseries for the sum of DMA and RSS across GCA, cameraserver
+ // and HAL. This provides a single number for the memory
+ // pressure using the camera is putting on the rest of the
+ // system.
+ //
+ // Note: this number assumes that all DMA pressure is coming
+ // from the camera as this is usually a pretty good
+ // approximation. Being more accurate here would increase the
+ // complexity of the metric significantly.
+ //
+ // Note: if there are multiple GCA/cameraserver/HAL processes
+ // in the trace, this metric will simply take the latest
+ // one in the trace and ignore the others.
+ repeated Value gc_rss_and_dma = 1;
+}
diff --git a/protos/perfetto/metrics/android/dvfs_metric.proto b/protos/perfetto/metrics/android/dvfs_metric.proto
new file mode 100644
index 000000000..e7bb625ba
--- /dev/null
+++ b/protos/perfetto/metrics/android/dvfs_metric.proto
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+message AndroidDvfsMetric {
+
+ message BandStat {
+ // Operating frequency
+ optional int32 freq_value = 1;
+
+ // Percentage of duration in this operating frequency compared to all frequencies
+ optional double percentage = 2;
+
+ // Total duration in ns when the state was in this operating frequency
+ optional int64 duration_ns = 3;
+ }
+
+ message FrequencyResidency {
+ // Frequency representative name
+ optional string freq_name = 1;
+ // Each band statistics meta
+ repeated BandStat band_stat = 2;
+ }
+
+ // Frequency residency metrics from clock_set_rate ftrace event.
+ repeated FrequencyResidency freq_residencies = 1;
+}
diff --git a/protos/perfetto/metrics/android/g2d_metric.proto b/protos/perfetto/metrics/android/g2d_metric.proto
index e7a2d6a34..29b3888c6 100644
--- a/protos/perfetto/metrics/android/g2d_metric.proto
+++ b/protos/perfetto/metrics/android/g2d_metric.proto
@@ -23,25 +23,32 @@ message G2dMetrics {
// G2d name.
optional string name = 1;
- optional int64 max_dur_ns = 2;
- optional int64 min_dur_ns = 3;
- optional int64 avg_dur_ns = 4;
optional uint32 frame_count = 5;
optional uint32 error_count = 6;
+
+ optional double max_dur_ms = 7;
+ optional double min_dur_ms = 8;
+ optional double avg_dur_ms = 9;
+
+ // Removed: was int64 versions of max_dur_ns, min_dur_ns and avg_dur_ns.
+ reserved 2 to 4;
}
message G2dMetric {
// G2D Metric for each G2D Instance.
repeated G2dInstance instances = 1;
- // max/min/avg G2d frame durations for all instances.
- optional int64 max_dur_ns = 2;
- optional int64 min_dur_ns = 3;
- optional int64 avg_dur_ns = 4;
-
// the number of frames processed by G2D
optional uint32 frame_count = 5;
// the number of error events
optional uint32 error_count = 6;
+
+ // max/min/avg G2d frame durations for all instances.
+ optional double max_dur_ms = 7;
+ optional double min_dur_ms = 8;
+ optional double avg_dur_ms = 9;
+
+ // Removed: was int64 versions of max_dur_ns, min_dur_ns and avg_dur_ns.
+ reserved 2 to 4;
}
optional G2dMetric g2d_hw = 1;
diff --git a/protos/perfetto/metrics/android/gpu_metric.proto b/protos/perfetto/metrics/android/gpu_metric.proto
index 23658559f..2aaaeafa5 100644
--- a/protos/perfetto/metrics/android/gpu_metric.proto
+++ b/protos/perfetto/metrics/android/gpu_metric.proto
@@ -36,4 +36,33 @@ message AndroidGpuMetric {
optional int64 mem_max = 2;
optional int64 mem_min = 3;
optional int64 mem_avg = 4;
+
+ message FrequencyMetric {
+ // Identifier for GPU in a multi-gpu device.
+ optional uint32 gpu_id = 1;
+
+ // max/min/avg GPU frequency for this gpu_id
+ // the calculation of avg is weighted by the duration of each frequency
+ optional int64 freq_max = 2;
+ optional int64 freq_min = 3;
+ optional double freq_avg = 4;
+
+ message MetricsPerFrequency {
+ // Used frequency
+ optional int64 freq = 1;
+
+ // Total duration in ms when the state of GPU was in this frequency
+ optional double dur_ms = 2;
+
+ // Percentage of duration in this frequency compared to all frequencies
+ // in this gpu_id
+ optional double percentage = 3;
+ }
+
+ // Metrics for each used GPU frequency
+ repeated MetricsPerFrequency used_freqs = 5;
+ }
+
+ // GPU frequency metric for each gpu_id
+ repeated FrequencyMetric freq_metrics = 5;
}
diff --git a/protos/perfetto/metrics/android/hwcomposer.proto b/protos/perfetto/metrics/android/hwcomposer.proto
index 72edc6d13..d9812a8bb 100644
--- a/protos/perfetto/metrics/android/hwcomposer.proto
+++ b/protos/perfetto/metrics/android/hwcomposer.proto
@@ -59,4 +59,24 @@ message AndroidHwcomposerMetrics {
// the average of hwcomposer execution time for separated validation cases.
optional double avg_separated_execution_time_ms = 13;
+
+ message DpuVoteMetrics {
+ // the thread ID that handles this track
+ optional uint32 tid = 1;
+
+ // the weighted average of DPU Vote Clock
+ optional double avg_dpu_vote_clock = 2;
+
+ // the weighted average of DPU Vote Avg Bandwidth
+ optional double avg_dpu_vote_avg_bw = 3;
+
+ // the weighted average of DPU Vote Peak Bandwidth
+ optional double avg_dpu_vote_peak_bw = 4;
+
+ // the weighted average of DPU Vote RT (Real Time) Bandwidth
+ optional double avg_dpu_vote_rt_bw = 5;
+ }
+
+ // DPU Vote Metrics for each thread track
+ repeated DpuVoteMetrics dpu_vote_metrics = 14;
}
diff --git a/protos/perfetto/metrics/android/irq_runtime_metric.proto b/protos/perfetto/metrics/android/irq_runtime_metric.proto
new file mode 100644
index 000000000..dd2ed513d
--- /dev/null
+++ b/protos/perfetto/metrics/android/irq_runtime_metric.proto
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+// measure max IRQ runtime and IRQ tasks running over threshold.
+message AndroidIrqRuntimeMetric {
+ message IrqSlice {
+ // IRQ name
+ optional string irq_name = 1;
+ // timestamp
+ optional int64 ts = 2;
+ // runtime of IRQ task
+ optional int64 dur = 3;
+ }
+ message ThresholdMetric {
+ // Threshold value
+ optional string threshold = 1;
+ // over threshold count
+ optional int64 over_threshold_count = 2;
+ // anomaly ratio (over threshold count / total count)
+ optional double anomaly_ratio= 3;
+ }
+ message IrqRuntimeMetric {
+ // max runtime of IRQ tasks
+ optional int64 max_runtime = 1;
+ // total IRQ tasks
+ optional int64 total_count = 2;
+ // over threshold metric
+ optional ThresholdMetric threshold_metric = 3;
+ // information for top 10 IRQ tasks
+ repeated IrqSlice longest_irq_slices = 4;
+ }
+
+ // metrics for hardirq and softirq
+ optional IrqRuntimeMetric hw_irq = 1;
+ optional IrqRuntimeMetric sw_irq = 2;
+}
+
diff --git a/protos/perfetto/metrics/android/java_heap_histogram.proto b/protos/perfetto/metrics/android/java_heap_histogram.proto
index ce23669d1..7fa86ef06 100644
--- a/protos/perfetto/metrics/android/java_heap_histogram.proto
+++ b/protos/perfetto/metrics/android/java_heap_histogram.proto
@@ -19,13 +19,18 @@ package perfetto.protos;
import "protos/perfetto/metrics/android/process_metadata.proto";
message JavaHeapHistogram {
- // Next id: 5
+ // Next id: 9
message TypeCount {
optional string type_name = 1;
optional string category = 4;
optional uint32 obj_count = 2;
optional uint32 reachable_obj_count = 3;
+
+ optional uint32 size_kb = 5;
+ optional uint32 reachable_size_kb = 6;
+ optional uint32 native_size_kb = 7;
+ optional uint32 reachable_native_size_kb = 8;
}
message Sample {
diff --git a/protos/perfetto/metrics/android/java_heap_stats.proto b/protos/perfetto/metrics/android/java_heap_stats.proto
index 3f269c090..2579888ee 100644
--- a/protos/perfetto/metrics/android/java_heap_stats.proto
+++ b/protos/perfetto/metrics/android/java_heap_stats.proto
@@ -26,14 +26,19 @@ message JavaHeapStats {
optional int64 obj_count = 3;
}
- // Next id: 7
+ // Next id: 10
message Sample {
optional int64 ts = 1;
// Size of the Java heap in bytes
optional int64 heap_size = 2;
+ // Native size of all the objects (not included in heap_size)
+ optional int64 heap_native_size = 8;
optional int64 obj_count = 4;
// Size of the reachable objects in bytes.
optional int64 reachable_heap_size = 3;
+ // Native size of all the reachable objects (not included in
+ // reachable_heap_size)
+ optional int64 reachable_heap_native_size = 9;
optional int64 reachable_obj_count = 5;
// Sum of anonymous RSS + swap pages in bytes.
optional int64 anon_rss_and_swap_size = 6;
diff --git a/protos/perfetto/metrics/android/mem_metric.proto b/protos/perfetto/metrics/android/mem_metric.proto
index 5fb5c9f3f..6dee65864 100644
--- a/protos/perfetto/metrics/android/mem_metric.proto
+++ b/protos/perfetto/metrics/android/mem_metric.proto
@@ -45,6 +45,10 @@ message AndroidMemoryMetric {
optional double min = 1;
optional double max = 2;
optional double avg = 3;
+
+ // Memory growth observed in the counter sequence. In case of multiple
+ // processes with the same name, break ties using max.
+ optional double delta = 4;
}
// Process metrics, grouped by process name
diff --git a/protos/perfetto/metrics/android/multiuser_metric.proto b/protos/perfetto/metrics/android/multiuser_metric.proto
new file mode 100644
index 000000000..c29ea6e43
--- /dev/null
+++ b/protos/perfetto/metrics/android/multiuser_metric.proto
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+// Metrics for Multiuser events, such as switching users.
+message AndroidMultiuserMetric {
+
+ // Holds the data for a Multiuser event.
+ message EventData {
+ // Duration of the event (in milliseconds).
+ optional int32 duration_ms = 1;
+
+ // CPU usage of each process during the event.
+ message CpuUsage {
+ // The userId of the process (e.g. 0 or 10).
+ optional int32 user_id = 1;
+ // The name of the process.
+ optional string process_name = 2;
+ // The number of CPU cycles (in megacycles) spent by that process during the event.
+ optional int32 cpu_mcycles = 3;
+ // The ratio of this process's cycles to the total for all processes, expressed as a percentage.
+ optional float cpu_percentage = 4;
+ // General identifier for this usage source: determined from the process name, user, etc.
+ // Should be stable across multiple runs (i.e. does not print the user_id directly).
+ optional string identifier = 5;
+ }
+ repeated CpuUsage cpu_usage = 2;
+ }
+
+ // Metrics for a user switch.
+ optional EventData user_switch = 1;
+} \ No newline at end of file
diff --git a/protos/perfetto/metrics/android/network_metric.proto b/protos/perfetto/metrics/android/network_metric.proto
new file mode 100644
index 000000000..e09c57185
--- /dev/null
+++ b/protos/perfetto/metrics/android/network_metric.proto
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+message AndroidNetworkMetric {
+ message PacketStatistic {
+ // Packet count.
+ optional int64 packets = 1;
+
+ // Packet Bytes.
+ optional int64 bytes = 2;
+
+ // Timestamp when first packet received or transmitted.
+ optional int64 first_packet_timestamp_ns = 3;
+
+ // Timestamp when last packet received or transmitted.
+ optional int64 last_packet_timestamp_ns = 4;
+
+ // Interval between first & last packet. The minimum interval is 10ms.
+ optional int64 interval_ns = 5;
+
+ // Data Speed.
+ optional double data_rate_kbps = 6;
+ }
+
+ message CorePacketStatistic {
+ optional uint32 id = 1;
+ optional PacketStatistic packet_statistic = 2;
+ }
+
+ message Rx {
+ // Total packets statistic.
+ optional PacketStatistic total = 1;
+
+ // Per core packets statistic.
+ repeated CorePacketStatistic core = 2;
+
+ // GRO aggregation ratio.
+ optional string gro_aggregation_ratio = 3;
+ }
+
+ message Tx {
+ // Total packets statistic.
+ optional PacketStatistic total = 1;
+
+ // Per core packets statistic.
+ repeated CorePacketStatistic core = 2;
+ }
+
+ message NetDevice {
+ // Network device name.
+ optional string name = 1;
+
+ // Ingress traffic statistic.
+ optional Rx rx = 2;
+
+ // Egress traffic statistic
+ optional Tx tx = 3;
+ }
+
+ message NetRxActionStatistic {
+ // SoftIrq NET_RX action count.
+ optional int64 count = 1;
+
+ // SoftIrq NET_RX action was running in millisecond.
+ optional double runtime_ms = 2;
+
+ // SoftIrq NET_RX action average running time.
+ optional double avg_runtime_ms = 3;
+
+ // CPU megacycles (i.e. cycles divided by 1e6).
+ optional int64 mcycles = 4;
+
+ // Average weighted CPU frequency by the time the NET_RX Action
+ // running at each frequency.
+ optional int64 avg_freq_khz = 5;
+ }
+
+ message CoreNetRxActionStatistic {
+ optional uint32 id = 1;
+ optional NetRxActionStatistic net_rx_action_statistic = 2;
+ }
+
+ message NetRxAction {
+ // Total NET_RX action statistics.
+ optional NetRxActionStatistic total = 1;
+
+ // Per core NET_RX action statistics.
+ repeated CoreNetRxActionStatistic core = 2;
+
+ // The average packet time moves through the kernel stack.
+ optional double avg_interstack_latency_ms = 3;
+ }
+
+ // Network device metrics.
+ repeated NetDevice net_devices = 1;
+
+ // SoftIrq NET_RX action metrics.
+ optional NetRxAction net_rx_action = 2;
+
+ // Packet retransmission rate.
+ optional double retransmission_rate = 3;
+
+ // Kfree Skb rate (i.e. kfree_skb count divided by the packet count from all
+ // net devices).
+ optional double kfree_skb_rate = 4;
+}
diff --git a/protos/perfetto/metrics/android/other_traces.proto b/protos/perfetto/metrics/android/other_traces.proto
new file mode 100644
index 000000000..1795ee243
--- /dev/null
+++ b/protos/perfetto/metrics/android/other_traces.proto
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+message AndroidOtherTracesMetric {
+ // Uuids of other traces being finalized while the current trace was being
+ // recorded.
+ repeated string finalized_traces_uuid = 1;
+}
diff --git a/protos/perfetto/metrics/android/powrails_metric.proto b/protos/perfetto/metrics/android/powrails_metric.proto
index fcf0aa7ba..a17d47cdb 100644
--- a/protos/perfetto/metrics/android/powrails_metric.proto
+++ b/protos/perfetto/metrics/android/powrails_metric.proto
@@ -32,6 +32,9 @@ message AndroidPowerRails {
optional string name = 1;
// Energy data for given rail and for all samples in the trace.
repeated EnergyData energy_data = 2;
+ // The average used power between the first and the last sampled
+ // energy data in miliwatt (mw)
+ optional double avg_used_power_mw = 3;
}
// Energy data per Power Rail.
diff --git a/protos/perfetto/metrics/android/profiler_smaps.proto b/protos/perfetto/metrics/android/profiler_smaps.proto
new file mode 100644
index 000000000..bfb1416e7
--- /dev/null
+++ b/protos/perfetto/metrics/android/profiler_smaps.proto
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+package perfetto.protos;
+
+import "protos/perfetto/metrics/android/process_metadata.proto";
+
+message ProfilerSmaps {
+ message Mapping {
+ optional string path = 1;
+ optional int32 size_kb = 2;
+ optional int32 private_dirty_kb = 3;
+ optional int32 swap_kb = 4;
+ }
+
+ message Instance {
+ optional AndroidProcessMetadata process = 1;
+ repeated Mapping mappings = 2;
+ }
+
+ repeated Instance instance = 1;
+}
diff --git a/protos/perfetto/metrics/android/rt_runtime_metric.proto b/protos/perfetto/metrics/android/rt_runtime_metric.proto
new file mode 100644
index 000000000..edb66c54d
--- /dev/null
+++ b/protos/perfetto/metrics/android/rt_runtime_metric.proto
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+// measure max RT runtime and RT tasks running over 5ms.
+message AndroidRtRuntimeMetric {
+ message RtSlice {
+ // thread name
+ optional string tname = 1;
+ // timestamp
+ optional int64 ts = 2;
+ // runtime of RT task
+ optional int64 dur = 3;
+ }
+
+ // max runtime of RT tasks
+ optional int64 max_runtime = 1;
+ // how many RT tasks are over 5ms.
+ optional int64 over_5ms_count = 2;
+ // information for top 10 RT tasks
+ repeated RtSlice longest_rt_slices = 3;
+}
+
diff --git a/protos/perfetto/metrics/android/simpleperf.proto b/protos/perfetto/metrics/android/simpleperf.proto
new file mode 100644
index 000000000..7fcebe403
--- /dev/null
+++ b/protos/perfetto/metrics/android/simpleperf.proto
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+// Metric that stores information related to atrace events generated by
+// simpleperf tool
+message AndroidSimpleperfMetric {
+ optional double urgent_ratio = 1;
+}
diff --git a/protos/perfetto/metrics/android/startup_metric.proto b/protos/perfetto/metrics/android/startup_metric.proto
index 54bf1d74a..aef7c10d4 100644
--- a/protos/perfetto/metrics/android/startup_metric.proto
+++ b/protos/perfetto/metrics/android/startup_metric.proto
@@ -131,6 +131,17 @@ message AndroidStartupMetric {
message BinderTransaction {
optional Slice duration = 1;
optional string thread = 2;
+ optional string destination_thread = 3;
+ optional string destination_process = 4;
+ // From
+ // https://cs.android.com/android/platform/superproject/+/master:external/perfetto/protos/perfetto/trace/ftrace/binder.proto;l=15;drc=7b6a788162a30802f4c9d8d7a30a54e25edd30f1
+ optional string flags = 5;
+ // From
+ // https://cs.android.com/android/platform/superproject/+/master:external/perfetto/protos/perfetto/trace/ftrace/binder.proto;l=14;drc=7b6a788162a30802f4c9d8d7a30a54e25edd30f1
+ optional string code = 6;
+ // From
+ // https://cs.android.com/android/platform/superproject/+/master:external/perfetto/protos/perfetto/trace/ftrace/binder.proto;l=37;drc=7b6a788162a30802f4c9d8d7a30a54e25edd30f1
+ optional int64 data_size = 7;
}
// Metrics with information about the status of odex files and the outcome
diff --git a/protos/perfetto/metrics/android/surfaceflinger.proto b/protos/perfetto/metrics/android/surfaceflinger.proto
index 76fb493fa..3cc2c9e08 100644
--- a/protos/perfetto/metrics/android/surfaceflinger.proto
+++ b/protos/perfetto/metrics/android/surfaceflinger.proto
@@ -39,4 +39,19 @@ message AndroidSurfaceflingerMetric {
// Calculate the number of missed GPU frames divided by
// total GPU frames
optional double missed_gpu_frame_rate = 6;
+
+ // Count the number of times SurfaceFlinger needs to invoke GPU
+ // for rendering some layers
+ optional uint32 gpu_invocations = 7;
+
+ // Calculate the average duration of GPU request by SurfaceFlinger
+ // since it enters the FenceMonitor's queue until it gets completed
+ optional double avg_gpu_waiting_dur_ms = 8;
+
+ // Calculate the total duration when there is at least one GPU request
+ // by SurfaceFlinger that is still waiting for GPU to complete the
+ // request.
+ // This also equals to the total duration of
+ // "waiting for GPU completion <fence_num>" in SurfaceFlinger.
+ optional double total_non_empty_gpu_waiting_dur_ms = 9;
}
diff --git a/protos/perfetto/metrics/android/trace_quality.proto b/protos/perfetto/metrics/android/trace_quality.proto
new file mode 100644
index 000000000..9d3844464
--- /dev/null
+++ b/protos/perfetto/metrics/android/trace_quality.proto
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+// Metric which checks the data in the trace processor tables is "reasonble"
+// (i.e. we would expect to see it from a real device).
+//
+// This is useful to reject traces which may be valid (so no stat would be
+// recorded) but a human would find the trace nonsensical.
+message AndroidTraceQualityMetric {
+ message Failure {
+ // The name of the failed check.
+ optional string name = 1;
+ }
+ repeated Failure failures = 1;
+} \ No newline at end of file
diff --git a/protos/perfetto/metrics/android/unsymbolized_frames.proto b/protos/perfetto/metrics/android/unsymbolized_frames.proto
index da75511cb..afd942174 100644
--- a/protos/perfetto/metrics/android/unsymbolized_frames.proto
+++ b/protos/perfetto/metrics/android/unsymbolized_frames.proto
@@ -23,6 +23,13 @@ message UnsymbolizedFrames {
optional string module = 1;
optional string build_id = 2;
optional int64 address = 3;
+
+ // In some cases (Chrome/Webview) the ID that should be used to query
+ // symbols in Google's internal tera-scale symbolization service is !=
+ // `build_id` and requires some mangling.
+ // This field is == 'build_id` for non-chromium cases, and is the breakpad
+ // module ID (with lowercase hex digics) for chromium cases.
+ optional string google_lookup_id = 4;
}
repeated Frame frames = 1;
diff --git a/protos/perfetto/metrics/chrome/BUILD.gn b/protos/perfetto/metrics/chrome/BUILD.gn
index 078913804..e88997faf 100644
--- a/protos/perfetto/metrics/chrome/BUILD.gn
+++ b/protos/perfetto/metrics/chrome/BUILD.gn
@@ -23,11 +23,18 @@ perfetto_proto_library("@TYPE@") {
sources = [
"all_chrome_metrics.proto",
"blink_gc_metric.proto",
+ "dropped_frames.proto",
"frame_times.proto",
+ "histogram_hashes.proto",
+ "long_latency.proto",
"media_metric.proto",
+ "performance_mark_hashes.proto",
"reported_by_page.proto",
"scroll_jank.proto",
+ "slice_names.proto",
"test_chrome_metric.proto",
+ "touch_jank.proto",
+ "user_event_hashes.proto",
]
}
diff --git a/protos/perfetto/metrics/chrome/all_chrome_metrics.proto b/protos/perfetto/metrics/chrome/all_chrome_metrics.proto
index eb5209991..a0b87634f 100644
--- a/protos/perfetto/metrics/chrome/all_chrome_metrics.proto
+++ b/protos/perfetto/metrics/chrome/all_chrome_metrics.proto
@@ -20,12 +20,20 @@ package perfetto.protos;
import "protos/perfetto/metrics/metrics.proto";
import "protos/perfetto/metrics/chrome/blink_gc_metric.proto";
+import "protos/perfetto/metrics/chrome/dropped_frames.proto";
import "protos/perfetto/metrics/chrome/frame_times.proto";
+import "protos/perfetto/metrics/chrome/histogram_hashes.proto";
+import "protos/perfetto/metrics/chrome/long_latency.proto";
import "protos/perfetto/metrics/chrome/media_metric.proto";
+import "protos/perfetto/metrics/chrome/performance_mark_hashes.proto";
+import "protos/perfetto/metrics/chrome/reported_by_page.proto";
+import "protos/perfetto/metrics/chrome/slice_names.proto";
import "protos/perfetto/metrics/chrome/scroll_jank.proto";
import "protos/perfetto/metrics/chrome/test_chrome_metric.proto";
-import "protos/perfetto/metrics/chrome/reported_by_page.proto";
+import "protos/perfetto/metrics/chrome/touch_jank.proto";
+import "protos/perfetto/metrics/chrome/user_event_hashes.proto";
+// TODO(lalitm): rename metrics below to include a "chrome_" prefix.
extend TraceMetrics {
optional TestChromeMetric test_chrome_metric = 1001;
optional FrameTimes frame_times = 1002;
@@ -33,4 +41,11 @@ extend TraceMetrics {
optional ScrollJank scroll_jank = 1004;
optional BlinkGcMetric blink_gc_metric = 1005;
optional MediaMetric media_metric = 1006;
+ optional TouchJank touch_jank = 1007;
+ optional ChromeDroppedFrames chrome_dropped_frames = 1008;
+ optional ChromeLongLatency chrome_long_latency = 1009;
+ optional ChromeHistogramHashes chrome_histogram_hashes = 1010;
+ optional ChromeUserEventHashes chrome_user_event_hashes = 1011;
+ optional ChromePerformanceMarkHashes chrome_performance_mark_hashes = 1012;
+ optional ChromeSliceNames chrome_slice_names = 1013;
}
diff --git a/protos/perfetto/metrics/chrome/dropped_frames.proto b/protos/perfetto/metrics/chrome/dropped_frames.proto
new file mode 100644
index 000000000..cb416cb2c
--- /dev/null
+++ b/protos/perfetto/metrics/chrome/dropped_frames.proto
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+message ChromeDroppedFrames {
+ message DroppedFrame {
+ optional int64 ts = 1;
+ optional string process_name = 2;
+ optional int64 pid = 3;
+ }
+
+ repeated DroppedFrame dropped_frame = 1;
+} \ No newline at end of file
diff --git a/protos/perfetto/metrics/chrome/histogram_hashes.proto b/protos/perfetto/metrics/chrome/histogram_hashes.proto
new file mode 100644
index 000000000..8f7323e5f
--- /dev/null
+++ b/protos/perfetto/metrics/chrome/histogram_hashes.proto
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+// The list of Chrome Histogram hashes in trace track events.
+// Use cases include translating histogram hashes to histogram
+// names by getting this list, and prepending a translation table to the trace.
+message ChromeHistogramHashes {
+ repeated int64 hash = 1;
+}
diff --git a/protos/perfetto/metrics/chrome/long_latency.proto b/protos/perfetto/metrics/chrome/long_latency.proto
new file mode 100644
index 000000000..2c5fbaffe
--- /dev/null
+++ b/protos/perfetto/metrics/chrome/long_latency.proto
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+// Information of a frame associated with long latency input events.
+// The latency info is extracted from EventLatency slices.
+message ChromeLongLatency {
+ message LongLatency {
+ // The ending timestamp of the input event, i.e. the presentation time of
+ // the frame that contains updates triggered by the input event.
+ optional int64 ts = 1;
+
+ // The type of the input event as reported in the EventLatency slice,
+ // e.g. 'GestureScrollUpdate'.
+ optional string event_type = 2;
+
+ // The name and pid of the process where the EventLatency slice
+ // originates from.
+ optional string process_name = 3;
+ optional int64 pid = 4;
+ }
+
+ repeated LongLatency long_latency = 1;
+} \ No newline at end of file
diff --git a/protos/perfetto/metrics/chrome/performance_mark_hashes.proto b/protos/perfetto/metrics/chrome/performance_mark_hashes.proto
new file mode 100644
index 000000000..d3ae5dcaa
--- /dev/null
+++ b/protos/perfetto/metrics/chrome/performance_mark_hashes.proto
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+// The list of Chrome performance mark hashes in trace track events.
+// Use cases include translating performance mark hashes to site and mark
+// names by getting this list, and prepending a translation table to the trace.
+message ChromePerformanceMarkHashes {
+ repeated int64 site_hash = 1;
+ repeated int64 mark_hash = 2;
+}
diff --git a/protos/perfetto/metrics/chrome/scroll_jank.proto b/protos/perfetto/metrics/chrome/scroll_jank.proto
index 6fea1d8c5..3fe397d5a 100644
--- a/protos/perfetto/metrics/chrome/scroll_jank.proto
+++ b/protos/perfetto/metrics/chrome/scroll_jank.proto
@@ -30,4 +30,5 @@ message ScrollJank {
optional int64 num_scroll_update_count = 5 [(unit) = "count_biggerIsBetter"];
optional int64 num_scroll_update_jank_count = 6
[(unit) = "count_smallerIsBetter"];
+ optional double scroll_jank_budget_ms = 7 [(unit) = "ms_smallerIsBetter"];
}
diff --git a/protos/perfetto/metrics/chrome/slice_names.proto b/protos/perfetto/metrics/chrome/slice_names.proto
new file mode 100644
index 000000000..c0a166556
--- /dev/null
+++ b/protos/perfetto/metrics/chrome/slice_names.proto
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+// The list of slice names in a trace.
+// Use cases include deobfuscating slice names by getting this list,
+// generating, and prepending a translation table to the trace.
+message ChromeSliceNames {
+ repeated int64 chrome_version_code = 1;
+ repeated string slice_name = 2;
+}
diff --git a/protos/perfetto/metrics/chrome/touch_jank.proto b/protos/perfetto/metrics/chrome/touch_jank.proto
new file mode 100644
index 000000000..20318b8c8
--- /dev/null
+++ b/protos/perfetto/metrics/chrome/touch_jank.proto
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+import "protos/perfetto/metrics/custom_options.proto";
+
+message TouchJank {
+ // The percentage of time we consider janky of the total time spent performing
+ // touch gestures during the trace. I.E. approximately equal to
+ // |touch_jank_ms|/|touch_ms|.
+ optional double touch_jank_percentage = 1 [(unit) = "n%_smallerIsBetter"];
+ optional double touch_ms = 2 [(unit) = "ms_biggerIsBetter"];
+ optional double touch_processing_ms = 3 [(unit) = "ms_biggerIsBetter"];
+ optional double touch_jank_processing_ms = 4 [(unit) = "ms_smallerIsBetter"];
+ optional int64 num_touch_update_count = 5 [(unit) = "count_biggerIsBetter"];
+ optional int64 num_touch_update_jank_count = 6
+ [(unit) = "count_smallerIsBetter"];
+ optional double touch_jank_budget_ms = 7 [(unit) = "ms_smallerIsBetter"];
+}
diff --git a/protos/perfetto/metrics/chrome/user_event_hashes.proto b/protos/perfetto/metrics/chrome/user_event_hashes.proto
new file mode 100644
index 000000000..e50e6bd3d
--- /dev/null
+++ b/protos/perfetto/metrics/chrome/user_event_hashes.proto
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+// The list of Chrome user event hashes in trace track events.
+// Use cases include translating user event hashes to action
+// names by getting this list, and prepending a translation table to the trace.
+message ChromeUserEventHashes {
+ repeated int64 action_hash = 1;
+}
diff --git a/protos/perfetto/metrics/metrics.proto b/protos/perfetto/metrics/metrics.proto
index 164377fa4..b872ab9da 100644
--- a/protos/perfetto/metrics/metrics.proto
+++ b/protos/perfetto/metrics/metrics.proto
@@ -20,14 +20,18 @@ package perfetto.protos;
import "protos/perfetto/metrics/android/batt_metric.proto";
import "protos/perfetto/metrics/android/cpu_metric.proto";
+import "protos/perfetto/metrics/android/camera_metric.proto";
+import "protos/perfetto/metrics/android/camera_unagg_metric.proto";
import "protos/perfetto/metrics/android/display_metrics.proto";
import "protos/perfetto/metrics/android/dma_heap_metric.proto";
+import "protos/perfetto/metrics/android/dvfs_metric.proto";
import "protos/perfetto/metrics/android/fastrpc_metric.proto";
import "protos/perfetto/metrics/android/g2d_metric.proto";
import "protos/perfetto/metrics/android/gpu_metric.proto";
import "protos/perfetto/metrics/android/hwcomposer.proto";
import "protos/perfetto/metrics/android/hwui_metric.proto";
import "protos/perfetto/metrics/android/ion_metric.proto";
+import "protos/perfetto/metrics/android/irq_runtime_metric.proto";
import "protos/perfetto/metrics/android/jank_metric.proto";
import "protos/perfetto/metrics/android/java_heap_histogram.proto";
import "protos/perfetto/metrics/android/java_heap_stats.proto";
@@ -35,13 +39,21 @@ import "protos/perfetto/metrics/android/lmk_metric.proto";
import "protos/perfetto/metrics/android/lmk_reason_metric.proto";
import "protos/perfetto/metrics/android/mem_metric.proto";
import "protos/perfetto/metrics/android/mem_unagg_metric.proto";
+import "protos/perfetto/metrics/android/multiuser_metric.proto";
+import "protos/perfetto/metrics/android/network_metric.proto";
+import "protos/perfetto/metrics/android/other_traces.proto";
import "protos/perfetto/metrics/android/package_list.proto";
import "protos/perfetto/metrics/android/powrails_metric.proto";
+import "protos/perfetto/metrics/android/profiler_smaps.proto";
+import "protos/perfetto/metrics/android/rt_runtime_metric.proto";
+import "protos/perfetto/metrics/android/simpleperf.proto";
import "protos/perfetto/metrics/android/startup_metric.proto";
import "protos/perfetto/metrics/android/surfaceflinger.proto";
import "protos/perfetto/metrics/android/sysui_cuj_metrics.proto";
import "protos/perfetto/metrics/android/task_names.proto";
import "protos/perfetto/metrics/android/thread_time_in_state_metric.proto";
+import "protos/perfetto/metrics/android/trace_quality.proto";
+import "protos/perfetto/metrics/android/android_trusty_workqueues.proto";
import "protos/perfetto/metrics/android/unsymbolized_frames.proto";
// Trace processor metadata
@@ -88,7 +100,7 @@ message TraceAnalysisStats {
// Root message for all Perfetto-based metrics.
//
-// Next id: 34
+// Next id: 46
message TraceMetrics {
reserved 4, 10, 13, 14, 16, 19;
@@ -172,6 +184,44 @@ message TraceMetrics {
// Dmabuf heap metrics.
optional AndroidDmaHeapMetric android_dma_heap = 32;
+ // Metric to verify the quality of the trace.
+ optional AndroidTraceQualityMetric android_trace_quality = 34;
+
+ // Profiler smaps
+ optional ProfilerSmaps profiler_smaps = 35;
+
+ // Multiuser - metrics for switching users.
+ optional AndroidMultiuserMetric android_multiuser = 36;
+
+ // Metrics related to simpleperf tool
+ optional AndroidSimpleperfMetric android_simpleperf = 37;
+
+ // Metrics for the Camera team.
+ optional AndroidCameraMetric android_camera = 38;
+
+ // Metrics for dynamic voltage and frequency scaling.
+ optional AndroidDvfsMetric android_dvfs = 39;
+
+ // Metrics for network performance.
+ optional AndroidNetworkMetric android_netperf = 40;
+
+ // Metrics for the Camera team.
+ // Note: this generates a lot of data so should not be requested unless it
+ // is clear that this data is necessary.
+ optional AndroidCameraUnaggregatedMetric android_camera_unagg = 41;
+
+ // Metrics for RT runtime.
+ optional AndroidRtRuntimeMetric android_rt_runtime = 42;
+
+ // Metrics for IRQ runtime.
+ optional AndroidIrqRuntimeMetric android_irq_runtime = 43;
+
+ // Metrics for the Trusty team.
+ optional AndroidTrustyWorkqueues android_trusty_workqueues = 44;
+
+ // Summary of other concurrent trace recording.
+ optional AndroidOtherTracesMetric android_other_traces = 45;
+
// Demo extensions.
extensions 450 to 499;
diff --git a/protos/perfetto/metrics/perfetto_merged_metrics.proto b/protos/perfetto/metrics/perfetto_merged_metrics.proto
index dc2196e4a..97ee857c3 100644
--- a/protos/perfetto/metrics/perfetto_merged_metrics.proto
+++ b/protos/perfetto/metrics/perfetto_merged_metrics.proto
@@ -11,6 +11,15 @@ syntax = "proto2";
package perfetto.protos;
+option go_package = "github.com/google/perfetto/perfetto_proto";
+
+// Begin of protos/perfetto/metrics/android/android_trusty_workqueues.proto
+
+// Metric used to generate a simplified view of the Trusty kworker events.
+message AndroidTrustyWorkqueues {}
+
+// End of protos/perfetto/metrics/android/android_trusty_workqueues.proto
+
// Begin of protos/perfetto/metrics/android/batt_metric.proto
message AndroidBatteryMetric {
@@ -56,6 +65,59 @@ message AndroidBatteryMetric {
// End of protos/perfetto/metrics/android/batt_metric.proto
+// Begin of protos/perfetto/metrics/android/camera_metric.proto
+
+message AndroidCameraMetric {
+ message Counter {
+ optional double min = 1;
+ optional double max = 2;
+ optional double avg = 3;
+ }
+
+ // Counter for the sum of DMA and RSS across GCA, cameraserver
+ // and HAL. This provides a single number for the memory
+ // pressure using the camera is putting on the rest of the
+ // system.
+ //
+ // Note: this number assumes that all DMA pressure is coming
+ // from the camera as this is usually a pretty good
+ // approximation. Being more accurate here would increase the
+ // complexity of the metric significantly.
+ //
+ // Note: if there are multiple GCA/cameraserver/HAL processes
+ // in the trace, this metric will simply take the latest
+ // one in the trace and ignore the others.
+ optional Counter gc_rss_and_dma = 1;
+}
+
+// End of protos/perfetto/metrics/android/camera_metric.proto
+
+// Begin of protos/perfetto/metrics/android/camera_unagg_metric.proto
+
+message AndroidCameraUnaggregatedMetric {
+ message Value {
+ optional int64 ts = 1;
+ optional double value = 2;
+ }
+
+ // Timeseries for the sum of DMA and RSS across GCA, cameraserver
+ // and HAL. This provides a single number for the memory
+ // pressure using the camera is putting on the rest of the
+ // system.
+ //
+ // Note: this number assumes that all DMA pressure is coming
+ // from the camera as this is usually a pretty good
+ // approximation. Being more accurate here would increase the
+ // complexity of the metric significantly.
+ //
+ // Note: if there are multiple GCA/cameraserver/HAL processes
+ // in the trace, this metric will simply take the latest
+ // one in the trace and ignore the others.
+ repeated Value gc_rss_and_dma = 1;
+}
+
+// End of protos/perfetto/metrics/android/camera_unagg_metric.proto
+
// Begin of protos/perfetto/metrics/android/cpu_metric.proto
message AndroidCpuMetric {
@@ -173,6 +235,34 @@ message AndroidDmaHeapMetric {
// End of protos/perfetto/metrics/android/dma_heap_metric.proto
+// Begin of protos/perfetto/metrics/android/dvfs_metric.proto
+
+message AndroidDvfsMetric {
+
+ message BandStat {
+ // Operating frequency
+ optional int32 freq_value = 1;
+
+ // Percentage of duration in this operating frequency compared to all frequencies
+ optional double percentage = 2;
+
+ // Total duration in ns when the state was in this operating frequency
+ optional int64 duration_ns = 3;
+ }
+
+ message FrequencyResidency {
+ // Frequency representative name
+ optional string freq_name = 1;
+ // Each band statistics meta
+ repeated BandStat band_stat = 2;
+ }
+
+ // Frequency residency metrics from clock_set_rate ftrace event.
+ repeated FrequencyResidency freq_residencies = 1;
+}
+
+// End of protos/perfetto/metrics/android/dvfs_metric.proto
+
// Begin of protos/perfetto/metrics/android/fastrpc_metric.proto
// fastrpc memory stats on Android.
@@ -200,25 +290,32 @@ message G2dMetrics {
// G2d name.
optional string name = 1;
- optional int64 max_dur_ns = 2;
- optional int64 min_dur_ns = 3;
- optional int64 avg_dur_ns = 4;
optional uint32 frame_count = 5;
optional uint32 error_count = 6;
+
+ optional double max_dur_ms = 7;
+ optional double min_dur_ms = 8;
+ optional double avg_dur_ms = 9;
+
+ // Removed: was int64 versions of max_dur_ns, min_dur_ns and avg_dur_ns.
+ reserved 2 to 4;
}
message G2dMetric {
// G2D Metric for each G2D Instance.
repeated G2dInstance instances = 1;
- // max/min/avg G2d frame durations for all instances.
- optional int64 max_dur_ns = 2;
- optional int64 min_dur_ns = 3;
- optional int64 avg_dur_ns = 4;
-
// the number of frames processed by G2D
optional uint32 frame_count = 5;
// the number of error events
optional uint32 error_count = 6;
+
+ // max/min/avg G2d frame durations for all instances.
+ optional double max_dur_ms = 7;
+ optional double min_dur_ms = 8;
+ optional double avg_dur_ms = 9;
+
+ // Removed: was int64 versions of max_dur_ns, min_dur_ns and avg_dur_ns.
+ reserved 2 to 4;
}
optional G2dMetric g2d_hw = 1;
@@ -247,6 +344,35 @@ message AndroidGpuMetric {
optional int64 mem_max = 2;
optional int64 mem_min = 3;
optional int64 mem_avg = 4;
+
+ message FrequencyMetric {
+ // Identifier for GPU in a multi-gpu device.
+ optional uint32 gpu_id = 1;
+
+ // max/min/avg GPU frequency for this gpu_id
+ // the calculation of avg is weighted by the duration of each frequency
+ optional int64 freq_max = 2;
+ optional int64 freq_min = 3;
+ optional double freq_avg = 4;
+
+ message MetricsPerFrequency {
+ // Used frequency
+ optional int64 freq = 1;
+
+ // Total duration in ms when the state of GPU was in this frequency
+ optional double dur_ms = 2;
+
+ // Percentage of duration in this frequency compared to all frequencies
+ // in this gpu_id
+ optional double percentage = 3;
+ }
+
+ // Metrics for each used GPU frequency
+ repeated MetricsPerFrequency used_freqs = 5;
+ }
+
+ // GPU frequency metric for each gpu_id
+ repeated FrequencyMetric freq_metrics = 5;
}
// End of protos/perfetto/metrics/android/gpu_metric.proto
@@ -294,6 +420,26 @@ message AndroidHwcomposerMetrics {
// the average of hwcomposer execution time for separated validation cases.
optional double avg_separated_execution_time_ms = 13;
+
+ message DpuVoteMetrics {
+ // the thread ID that handles this track
+ optional uint32 tid = 1;
+
+ // the weighted average of DPU Vote Clock
+ optional double avg_dpu_vote_clock = 2;
+
+ // the weighted average of DPU Vote Avg Bandwidth
+ optional double avg_dpu_vote_avg_bw = 3;
+
+ // the weighted average of DPU Vote Peak Bandwidth
+ optional double avg_dpu_vote_peak_bw = 4;
+
+ // the weighted average of DPU Vote RT (Real Time) Bandwidth
+ optional double avg_dpu_vote_rt_bw = 5;
+ }
+
+ // DPU Vote Metrics for each thread track
+ repeated DpuVoteMetrics dpu_vote_metrics = 14;
}
// End of protos/perfetto/metrics/android/hwcomposer.proto
@@ -406,6 +552,45 @@ message AndroidIonMetric {
// End of protos/perfetto/metrics/android/ion_metric.proto
+// Begin of protos/perfetto/metrics/android/irq_runtime_metric.proto
+
+// measure max IRQ runtime and IRQ tasks running over threshold.
+message AndroidIrqRuntimeMetric {
+ message IrqSlice {
+ // IRQ name
+ optional string irq_name = 1;
+ // timestamp
+ optional int64 ts = 2;
+ // runtime of IRQ task
+ optional int64 dur = 3;
+ }
+ message ThresholdMetric {
+ // Threshold value
+ optional string threshold = 1;
+ // over threshold count
+ optional int64 over_threshold_count = 2;
+ // anomaly ratio (over threshold count / total count)
+ optional double anomaly_ratio= 3;
+ }
+ message IrqRuntimeMetric {
+ // max runtime of IRQ tasks
+ optional int64 max_runtime = 1;
+ // total IRQ tasks
+ optional int64 total_count = 2;
+ // over threshold metric
+ optional ThresholdMetric threshold_metric = 3;
+ // information for top 10 IRQ tasks
+ repeated IrqSlice longest_irq_slices = 4;
+ }
+
+ // metrics for hardirq and softirq
+ optional IrqRuntimeMetric hw_irq = 1;
+ optional IrqRuntimeMetric sw_irq = 2;
+}
+
+
+// End of protos/perfetto/metrics/android/irq_runtime_metric.proto
+
// Begin of protos/perfetto/metrics/android/jank_metric.proto
message AndroidJankMetrics {
@@ -458,13 +643,18 @@ message AndroidProcessMetadata {
// Begin of protos/perfetto/metrics/android/java_heap_histogram.proto
message JavaHeapHistogram {
- // Next id: 5
+ // Next id: 9
message TypeCount {
optional string type_name = 1;
optional string category = 4;
optional uint32 obj_count = 2;
optional uint32 reachable_obj_count = 3;
+
+ optional uint32 size_kb = 5;
+ optional uint32 reachable_size_kb = 6;
+ optional uint32 native_size_kb = 7;
+ optional uint32 reachable_native_size_kb = 8;
}
message Sample {
@@ -494,14 +684,19 @@ message JavaHeapStats {
optional int64 obj_count = 3;
}
- // Next id: 7
+ // Next id: 10
message Sample {
optional int64 ts = 1;
// Size of the Java heap in bytes
optional int64 heap_size = 2;
+ // Native size of all the objects (not included in heap_size)
+ optional int64 heap_native_size = 8;
optional int64 obj_count = 4;
// Size of the reachable objects in bytes.
optional int64 reachable_heap_size = 3;
+ // Native size of all the reachable objects (not included in
+ // reachable_heap_size)
+ optional int64 reachable_heap_native_size = 9;
optional int64 reachable_obj_count = 5;
// Sum of anonymous RSS + swap pages in bytes.
optional int64 anon_rss_and_swap_size = 6;
@@ -610,6 +805,10 @@ message AndroidMemoryMetric {
optional double min = 1;
optional double max = 2;
optional double avg = 3;
+
+ // Memory growth observed in the counter sequence. In case of multiple
+ // processes with the same name, break ties using max.
+ optional double delta = 4;
}
// Process metrics, grouped by process name
@@ -646,6 +845,156 @@ message AndroidMemoryUnaggregatedMetric {
// End of protos/perfetto/metrics/android/mem_unagg_metric.proto
+// Begin of protos/perfetto/metrics/android/multiuser_metric.proto
+
+// Metrics for Multiuser events, such as switching users.
+message AndroidMultiuserMetric {
+
+ // Holds the data for a Multiuser event.
+ message EventData {
+ // Duration of the event (in milliseconds).
+ optional int32 duration_ms = 1;
+
+ // CPU usage of each process during the event.
+ message CpuUsage {
+ // The userId of the process (e.g. 0 or 10).
+ optional int32 user_id = 1;
+ // The name of the process.
+ optional string process_name = 2;
+ // The number of CPU cycles (in megacycles) spent by that process during the event.
+ optional int32 cpu_mcycles = 3;
+ // The ratio of this process's cycles to the total for all processes, expressed as a percentage.
+ optional float cpu_percentage = 4;
+ // General identifier for this usage source: determined from the process name, user, etc.
+ // Should be stable across multiple runs (i.e. does not print the user_id directly).
+ optional string identifier = 5;
+ }
+ repeated CpuUsage cpu_usage = 2;
+ }
+
+ // Metrics for a user switch.
+ optional EventData user_switch = 1;
+}
+// End of protos/perfetto/metrics/android/multiuser_metric.proto
+
+// Begin of protos/perfetto/metrics/android/network_metric.proto
+
+message AndroidNetworkMetric {
+ message PacketStatistic {
+ // Packet count.
+ optional int64 packets = 1;
+
+ // Packet Bytes.
+ optional int64 bytes = 2;
+
+ // Timestamp when first packet received or transmitted.
+ optional int64 first_packet_timestamp_ns = 3;
+
+ // Timestamp when last packet received or transmitted.
+ optional int64 last_packet_timestamp_ns = 4;
+
+ // Interval between first & last packet. The minimum interval is 10ms.
+ optional int64 interval_ns = 5;
+
+ // Data Speed.
+ optional double data_rate_kbps = 6;
+ }
+
+ message CorePacketStatistic {
+ optional uint32 id = 1;
+ optional PacketStatistic packet_statistic = 2;
+ }
+
+ message Rx {
+ // Total packets statistic.
+ optional PacketStatistic total = 1;
+
+ // Per core packets statistic.
+ repeated CorePacketStatistic core = 2;
+
+ // GRO aggregation ratio.
+ optional string gro_aggregation_ratio = 3;
+ }
+
+ message Tx {
+ // Total packets statistic.
+ optional PacketStatistic total = 1;
+
+ // Per core packets statistic.
+ repeated CorePacketStatistic core = 2;
+ }
+
+ message NetDevice {
+ // Network device name.
+ optional string name = 1;
+
+ // Ingress traffic statistic.
+ optional Rx rx = 2;
+
+ // Egress traffic statistic
+ optional Tx tx = 3;
+ }
+
+ message NetRxActionStatistic {
+ // SoftIrq NET_RX action count.
+ optional int64 count = 1;
+
+ // SoftIrq NET_RX action was running in millisecond.
+ optional double runtime_ms = 2;
+
+ // SoftIrq NET_RX action average running time.
+ optional double avg_runtime_ms = 3;
+
+ // CPU megacycles (i.e. cycles divided by 1e6).
+ optional int64 mcycles = 4;
+
+ // Average weighted CPU frequency by the time the NET_RX Action
+ // running at each frequency.
+ optional int64 avg_freq_khz = 5;
+ }
+
+ message CoreNetRxActionStatistic {
+ optional uint32 id = 1;
+ optional NetRxActionStatistic net_rx_action_statistic = 2;
+ }
+
+ message NetRxAction {
+ // Total NET_RX action statistics.
+ optional NetRxActionStatistic total = 1;
+
+ // Per core NET_RX action statistics.
+ repeated CoreNetRxActionStatistic core = 2;
+
+ // The average packet time moves through the kernel stack.
+ optional double avg_interstack_latency_ms = 3;
+ }
+
+ // Network device metrics.
+ repeated NetDevice net_devices = 1;
+
+ // SoftIrq NET_RX action metrics.
+ optional NetRxAction net_rx_action = 2;
+
+ // Packet retransmission rate.
+ optional double retransmission_rate = 3;
+
+ // Kfree Skb rate (i.e. kfree_skb count divided by the packet count from all
+ // net devices).
+ optional double kfree_skb_rate = 4;
+}
+
+// End of protos/perfetto/metrics/android/network_metric.proto
+
+// Begin of protos/perfetto/metrics/android/other_traces.proto
+
+message AndroidOtherTracesMetric {
+ // Uuids of other traces being finalized while the current trace was being
+ // recorded.
+ repeated string finalized_traces_uuid = 1;
+}
+
+// End of protos/perfetto/metrics/android/other_traces.proto
+
// Begin of protos/perfetto/metrics/android/package_list.proto
message AndroidPackageList {
@@ -676,6 +1025,9 @@ message AndroidPowerRails {
optional string name = 1;
// Energy data for given rail and for all samples in the trace.
repeated EnergyData energy_data = 2;
+ // The average used power between the first and the last sampled
+ // energy data in miliwatt (mw)
+ optional double avg_used_power_mw = 3;
}
// Energy data per Power Rail.
@@ -683,6 +1035,60 @@ message AndroidPowerRails {
}
// End of protos/perfetto/metrics/android/powrails_metric.proto
+// Begin of protos/perfetto/metrics/android/profiler_smaps.proto
+
+message ProfilerSmaps {
+ message Mapping {
+ optional string path = 1;
+ optional int32 size_kb = 2;
+ optional int32 private_dirty_kb = 3;
+ optional int32 swap_kb = 4;
+ }
+
+ message Instance {
+ optional AndroidProcessMetadata process = 1;
+ repeated Mapping mappings = 2;
+ }
+
+ repeated Instance instance = 1;
+}
+
+// End of protos/perfetto/metrics/android/profiler_smaps.proto
+
+// Begin of protos/perfetto/metrics/android/rt_runtime_metric.proto
+
+// measure max RT runtime and RT tasks running over 5ms.
+message AndroidRtRuntimeMetric {
+ message RtSlice {
+ // thread name
+ optional string tname = 1;
+ // timestamp
+ optional int64 ts = 2;
+ // runtime of RT task
+ optional int64 dur = 3;
+ }
+
+ // max runtime of RT tasks
+ optional int64 max_runtime = 1;
+ // how many RT tasks are over 5ms.
+ optional int64 over_5ms_count = 2;
+ // information for top 10 RT tasks
+ repeated RtSlice longest_rt_slices = 3;
+}
+
+
+// End of protos/perfetto/metrics/android/rt_runtime_metric.proto
+
+// Begin of protos/perfetto/metrics/android/simpleperf.proto
+
+// Metric that stores information related to atrace events generated by
+// simpleperf tool
+message AndroidSimpleperfMetric {
+ optional double urgent_ratio = 1;
+}
+
+// End of protos/perfetto/metrics/android/simpleperf.proto
+
// Begin of protos/perfetto/metrics/android/startup_metric.proto
// Android app startup metrics.
@@ -796,6 +1202,17 @@ message AndroidStartupMetric {
message BinderTransaction {
optional Slice duration = 1;
optional string thread = 2;
+ optional string destination_thread = 3;
+ optional string destination_process = 4;
+ // From
+ // https://cs.android.com/android/platform/superproject/+/master:external/perfetto/protos/perfetto/trace/ftrace/binder.proto;l=15;drc=7b6a788162a30802f4c9d8d7a30a54e25edd30f1
+ optional string flags = 5;
+ // From
+ // https://cs.android.com/android/platform/superproject/+/master:external/perfetto/protos/perfetto/trace/ftrace/binder.proto;l=14;drc=7b6a788162a30802f4c9d8d7a30a54e25edd30f1
+ optional string code = 6;
+ // From
+ // https://cs.android.com/android/platform/superproject/+/master:external/perfetto/protos/perfetto/trace/ftrace/binder.proto;l=37;drc=7b6a788162a30802f4c9d8d7a30a54e25edd30f1
+ optional int64 data_size = 7;
}
// Metrics with information about the status of odex files and the outcome
@@ -898,6 +1315,21 @@ message AndroidSurfaceflingerMetric {
// Calculate the number of missed GPU frames divided by
// total GPU frames
optional double missed_gpu_frame_rate = 6;
+
+ // Count the number of times SurfaceFlinger needs to invoke GPU
+ // for rendering some layers
+ optional uint32 gpu_invocations = 7;
+
+ // Calculate the average duration of GPU request by SurfaceFlinger
+ // since it enters the FenceMonitor's queue until it gets completed
+ optional double avg_gpu_waiting_dur_ms = 8;
+
+ // Calculate the total duration when there is at least one GPU request
+ // by SurfaceFlinger that is still waiting for GPU to complete the
+ // request.
+ // This also equals to the total duration of
+ // "waiting for GPU completion <fence_num>" in SurfaceFlinger.
+ optional double total_non_empty_gpu_waiting_dur_ms = 9;
}
// End of protos/perfetto/metrics/android/surfaceflinger.proto
@@ -987,6 +1419,22 @@ message AndroidThreadTimeInStateMetric {
// End of protos/perfetto/metrics/android/thread_time_in_state_metric.proto
+// Begin of protos/perfetto/metrics/android/trace_quality.proto
+
+// Metric which checks the data in the trace processor tables is "reasonble"
+// (i.e. we would expect to see it from a real device).
+//
+// This is useful to reject traces which may be valid (so no stat would be
+// recorded) but a human would find the trace nonsensical.
+message AndroidTraceQualityMetric {
+ message Failure {
+ // The name of the failed check.
+ optional string name = 1;
+ }
+ repeated Failure failures = 1;
+}
+// End of protos/perfetto/metrics/android/trace_quality.proto
+
// Begin of protos/perfetto/metrics/android/unsymbolized_frames.proto
message UnsymbolizedFrames {
@@ -994,6 +1442,13 @@ message UnsymbolizedFrames {
optional string module = 1;
optional string build_id = 2;
optional int64 address = 3;
+
+ // In some cases (Chrome/Webview) the ID that should be used to query
+ // symbols in Google's internal tera-scale symbolization service is !=
+ // `build_id` and requires some mangling.
+ // This field is == 'build_id` for non-chromium cases, and is the breakpad
+ // module ID (with lowercase hex digics) for chromium cases.
+ optional string google_lookup_id = 4;
}
repeated Frame frames = 1;
@@ -1047,7 +1502,7 @@ message TraceAnalysisStats {
// Root message for all Perfetto-based metrics.
//
-// Next id: 34
+// Next id: 46
message TraceMetrics {
reserved 4, 10, 13, 14, 16, 19;
@@ -1131,6 +1586,44 @@ message TraceMetrics {
// Dmabuf heap metrics.
optional AndroidDmaHeapMetric android_dma_heap = 32;
+ // Metric to verify the quality of the trace.
+ optional AndroidTraceQualityMetric android_trace_quality = 34;
+
+ // Profiler smaps
+ optional ProfilerSmaps profiler_smaps = 35;
+
+ // Multiuser - metrics for switching users.
+ optional AndroidMultiuserMetric android_multiuser = 36;
+
+ // Metrics related to simpleperf tool
+ optional AndroidSimpleperfMetric android_simpleperf = 37;
+
+ // Metrics for the Camera team.
+ optional AndroidCameraMetric android_camera = 38;
+
+ // Metrics for dynamic voltage and frequency scaling.
+ optional AndroidDvfsMetric android_dvfs = 39;
+
+ // Metrics for network performance.
+ optional AndroidNetworkMetric android_netperf = 40;
+
+ // Metrics for the Camera team.
+ // Note: this generates a lot of data so should not be requested unless it
+ // is clear that this data is necessary.
+ optional AndroidCameraUnaggregatedMetric android_camera_unagg = 41;
+
+ // Metrics for RT runtime.
+ optional AndroidRtRuntimeMetric android_rt_runtime = 42;
+
+ // Metrics for IRQ runtime.
+ optional AndroidIrqRuntimeMetric android_irq_runtime = 43;
+
+ // Metrics for the Trusty team.
+ optional AndroidTrustyWorkqueues android_trusty_workqueues = 44;
+
+ // Summary of other concurrent trace recording.
+ optional AndroidOtherTracesMetric android_other_traces = 45;
+
// Demo extensions.
extensions 450 to 499;
diff --git a/protos/perfetto/trace/BUILD.gn b/protos/perfetto/trace/BUILD.gn
index ed7b6aedb..2a9032f80 100644
--- a/protos/perfetto/trace/BUILD.gn
+++ b/protos/perfetto/trace/BUILD.gn
@@ -71,11 +71,21 @@ group("cpp") {
]
}
+# This is only for Bazel build generation.
+group("source_set") {
+ testonly = true
+ public_deps = [
+ ":minimal_source_set",
+ ":non_minimal_source_set",
+ ]
+}
+
perfetto_proto_library("non_minimal_@TYPE@") {
proto_generators = [
"cpp",
"lite",
"zero",
+ "source_set",
]
deps = [
":minimal_@TYPE@",
@@ -93,8 +103,10 @@ perfetto_proto_library("non_minimal_@TYPE@") {
"sys_stats:@TYPE@",
"system_info:@TYPE@",
"track_event:@TYPE@",
+ "translation:@TYPE@",
]
sources = proto_sources_non_minimal
+ public_deps = [ "track_event:@TYPE@" ]
}
perfetto_proto_library("minimal_@TYPE@") {
@@ -102,19 +114,11 @@ perfetto_proto_library("minimal_@TYPE@") {
sources = proto_sources_minimal
}
-# This target is not used in the tree and is built only to guarantee that the
-# autogenerated merged proto has a valid syntax.
-perfetto_proto_library("merged_trace") {
- proto_generators = [ "lite" ]
- sources = [ "perfetto_trace.proto" ]
-}
-
-if (perfetto_build_standalone) {
- perfetto_proto_library("descriptor") {
- proto_generators = [ "descriptor" ]
- generate_descriptor = "trace.descriptor"
- sources = [ "trace.proto" ]
- }
+perfetto_proto_library("descriptor") {
+ proto_generators = [ "descriptor" ]
+ generate_descriptor = "trace.descriptor"
+ sources = [ "trace.proto" ]
+ deps = [ ":non_minimal_source_set" ]
}
# This target exports perfetto trace protos allowing both host and device
@@ -130,3 +134,10 @@ perfetto_proto_library("test_extensions_descriptor") {
sources = [ "test_extensions.proto" ]
deps = [ "track_event:source_set" ]
}
+
+# This target are not used in the tree and is built only to guarantee that the
+# autogenerated merged proto has a valid syntax.
+perfetto_proto_library("merged_trace_@TYPE@") {
+ proto_generators = [ "lite" ]
+ sources = [ "perfetto_trace.proto" ]
+}
diff --git a/protos/perfetto/trace/android/BUILD.gn b/protos/perfetto/trace/android/BUILD.gn
index c957f647c..364342755 100644
--- a/protos/perfetto/trace/android/BUILD.gn
+++ b/protos/perfetto/trace/android/BUILD.gn
@@ -19,6 +19,7 @@ perfetto_proto_library("@TYPE@") {
sources = [
"android_log.proto",
+ "camera_event.proto",
"frame_timeline_event.proto",
"gpu_mem_event.proto",
"graphics_frame_event.proto",
diff --git a/protos/perfetto/trace/android/camera_event.proto b/protos/perfetto/trace/android/camera_event.proto
new file mode 100644
index 000000000..1e0b88768
--- /dev/null
+++ b/protos/perfetto/trace/android/camera_event.proto
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+package perfetto.protos;
+
+// A profiling event corresponding to a single camera frame. This message
+// collects important details and timestamps involved in producing a single
+// camera frame.
+// Next ID: 17
+message AndroidCameraFrameEvent {
+ // Identifier for the CameraCaptureSession this frame originates from. See:
+ // https://developer.android.com/reference/android/hardware/camera2/CameraCaptureSession
+ optional uint64 session_id = 1;
+ // Identifier for the camera sensor that is the source of this frame. This may
+ // be either a physical or logical camera (up to vendor interpretation).
+ optional uint32 camera_id = 2;
+ // The frame number identifying this frame on this camera.
+ optional int64 frame_number = 3;
+ // Identifier for the CaptureRequest. See:
+ // https://developer.android.com/reference/android/hardware/camera2/CaptureRequest
+ //
+ // If multiple cameras are streaming simultaneously, the request_id may be
+ // used to identify which frames were captured in service of the same request.
+ optional int64 request_id = 4;
+
+ // The CLOCK_BOOTTIME timestamp at which the camera framework request is
+ // received by the camera HAL pipeline. Note that this request may wait for
+ // some time before processing actually begins. See also
+ // request_processing_started_ns.
+ optional int64 request_received_ns = 5;
+ // The CLOCK_BOOTTIME timestamp at which the framework request is accepted for
+ // processing by the camera HAL pipeline. This is the time at which the
+ // pipeline actually begins to work on the request.
+ optional int64 request_processing_started_ns = 6;
+
+ // The CLOCK_BOOTTIME timestamp at which the sensor begins its exposure.
+ optional int64 start_of_exposure_ns = 7;
+ // The CLOCK_BOOTTIME timestamp corresponding to the sensor start of frame
+ // event.
+ optional int64 start_of_frame_ns = 8;
+ // The CLOCK_BOOTTIME timestamp at which the camera HAL has sent all responses
+ // for the frame.
+ optional int64 responses_all_sent_ns = 9;
+
+ // The error status, if any, reported to the camera framework. Any status
+ // other than STATUS_OK indicates a dropped frame.
+ // Next Enum: 6
+ enum CaptureResultStatus {
+ STATUS_UNSPECIFIED = 0;
+ STATUS_OK = 1;
+ // Early metadata was returned to the camera framework with an error.
+ STATUS_EARLY_METADATA_ERROR = 2;
+ // Final metadata was returned to the camera framework with an error.
+ STATUS_FINAL_METADATA_ERROR = 3;
+ // One or more buffers were returned to the camera framework with an error.
+ STATUS_BUFFER_ERROR = 4;
+ // The frame was dropped as a result of a flush operation.
+ STATUS_FLUSH_ERROR = 5;
+ }
+ optional CaptureResultStatus capture_result_status = 10;
+
+ // The number of sensor frames that were skipped between this frame and the
+ // previous frame. Under normal operation, this should be zero. Any number
+ // greater than zero indicates dropped sensor frames.
+ optional int32 skipped_sensor_frames = 11;
+
+ // The value of CONTROL_CAPTURE_INTENT. See:
+ // https://developer.android.com/reference/android/hardware/camera2/CaptureRequest#CONTROL_CAPTURE_INTENT
+ optional int32 capture_intent = 12;
+ // The number of streams in the capture request.
+ optional int32 num_streams = 13;
+
+ // A profiling event corresponding to a single node processing within the camera
+ // pipeline. Intuitively this corresponds to a single stage of processing to
+ // produce a camera frame.
+ // Next ID: 6
+ message CameraNodeProcessingDetails {
+ optional int64 node_id = 1;
+ // The timestamp at which node processing begins to run.
+ optional int64 start_processing_ns = 2;
+ // The timestamp at which node processing finishes running.
+ optional int64 end_processing_ns = 3;
+ // The delay between inputs becoming ready and the node actually beginning to
+ // run.
+ optional int64 scheduling_latency_ns = 4;
+ }
+ repeated CameraNodeProcessingDetails node_processing_details = 14;
+
+ // These fields capture vendor-specific additions to this proto message. In
+ // practice `vendor_data` typically contains a serialized message of the
+ // vendor's design, and `vendor_data_version` is incremented each time there
+ // is a backwards incompatible change made to the message.
+ optional int32 vendor_data_version = 15;
+ optional bytes vendor_data = 16;
+}
+
+// A profiling event that may be emitted periodically (i.e., at a slower rate
+// than `AndroidCameraFrameEvent`s) to record fixed and aggregated camera
+// session-specific values.
+message AndroidCameraSessionStats {
+ // Identifier for the CameraCaptureSession this frame originates from. See:
+ // https://developer.android.com/reference/android/hardware/camera2/CameraCaptureSession
+ optional uint64 session_id = 1;
+
+ // Although vendor implementations may vary, camera pipeline processing is
+ // typically arranged into a directed graph-like structure. This message is
+ // used to record that graph.
+ message CameraGraph {
+ message CameraNode {
+ optional int64 node_id = 1;
+ // A list of inputs consumed by this node.
+ repeated int64 input_ids = 2;
+ // A list of outputs produced by this node.
+ repeated int64 output_ids = 3;
+
+ // These fields capture vendor-specific additions to this proto message. In
+ // practice `vendor_data` typically contains a serialized message of the
+ // vendor's design, and `vendor_data_version` is incremented each time there
+ // is a backwards incompatible change made to the message.
+ optional int32 vendor_data_version = 4;
+ optional bytes vendor_data = 5;
+ }
+ repeated CameraNode nodes = 1;
+
+ // An adjacency list describing connections between CameraNodes, mapping
+ // nodes and their outputs to other nodes that consume them as inputs.
+ message CameraEdge {
+ // The pair of IDs identifying the node and output connected by this edge.
+ optional int64 output_node_id = 1;
+ optional int64 output_id = 2;
+
+ // The pair of IDs identifying the node and input connected by this edge.
+ optional int64 input_node_id = 3;
+ optional int64 input_id = 4;
+
+ // These fields capture vendor-specific additions to this proto message. In
+ // practice `vendor_data` typically contains a serialized message of the
+ // vendor's design, and `vendor_data_version` is incremented each time there
+ // is a backwards incompatible change made to the message.
+ optional int32 vendor_data_version = 5;
+ optional bytes vendor_data = 6;
+ }
+ repeated CameraEdge edges = 2;
+ }
+ optional CameraGraph graph = 2;
+}
diff --git a/protos/perfetto/trace/chrome/BUILD.gn b/protos/perfetto/trace/chrome/BUILD.gn
index dc4ecb2d9..2cad8301b 100644
--- a/protos/perfetto/trace/chrome/BUILD.gn
+++ b/protos/perfetto/trace/chrome/BUILD.gn
@@ -22,7 +22,7 @@ perfetto_proto_library("@TYPE@") {
]
}
-perfetto_proto_library("minimal_complete_lite") {
+perfetto_proto_library("minimal_complete_@TYPE@") {
proto_generators = [ "lite" ]
deps = [
":@TYPE@",
diff --git a/protos/perfetto/trace/ftrace/BUILD.gn b/protos/perfetto/trace/ftrace/BUILD.gn
index 568445013..2b6182db6 100644
--- a/protos/perfetto/trace/ftrace/BUILD.gn
+++ b/protos/perfetto/trace/ftrace/BUILD.gn
@@ -17,11 +17,6 @@ import("../../../../gn/proto_library.gni")
import("all_protos.gni")
perfetto_proto_library("@TYPE@") {
- proto_generators = [
- "cpp",
- "zero",
- "lite",
- ]
sources = ftrace_proto_names
}
diff --git a/protos/perfetto/trace/ftrace/all_protos.gni b/protos/perfetto/trace/ftrace/all_protos.gni
index 891085371..35802909f 100644
--- a/protos/perfetto/trace/ftrace/all_protos.gni
+++ b/protos/perfetto/trace/ftrace/all_protos.gni
@@ -26,8 +26,11 @@ ftrace_proto_names = [
"clk.proto",
"compaction.proto",
"cpuhp.proto",
+ "cros_ec.proto",
+ "dma_fence.proto",
"dmabuf_heap.proto",
"dpu.proto",
+ "drm.proto",
"ext4.proto",
"f2fs.proto",
"fastrpc.proto",
@@ -36,27 +39,36 @@ ftrace_proto_names = [
"ftrace.proto",
"g2d.proto",
"gpu_mem.proto",
+ "gpu_scheduler.proto",
"i2c.proto",
"ion.proto",
"ipi.proto",
"irq.proto",
"kmem.proto",
+ "kvm.proto",
"lowmemorykiller.proto",
"mali.proto",
"mdss.proto",
"mm_event.proto",
+ "net.proto",
"oom.proto",
"power.proto",
+ "printk.proto",
"raw_syscalls.proto",
"regulator.proto",
"sched.proto",
"scm.proto",
"sde.proto",
"signal.proto",
+ "skb.proto",
+ "sock.proto",
"sync.proto",
+ "synthetic.proto",
"systrace.proto",
"task.proto",
+ "tcp.proto",
"thermal.proto",
+ "ufs.proto",
"vmscan.proto",
"workqueue.proto",
]
diff --git a/protos/perfetto/trace/ftrace/binder.proto b/protos/perfetto/trace/ftrace/binder.proto
index ecec4a1e9..89d74aa96 100644
--- a/protos/perfetto/trace/ftrace/binder.proto
+++ b/protos/perfetto/trace/ftrace/binder.proto
@@ -37,4 +37,5 @@ message BinderTransactionAllocBufFtraceEvent {
optional uint64 data_size = 1;
optional int32 debug_id = 2;
optional uint64 offsets_size = 3;
+ optional uint64 extra_buffers_size = 4;
}
diff --git a/protos/perfetto/trace/ftrace/block.proto b/protos/perfetto/trace/ftrace/block.proto
index c39a7a2ad..5549f6b28 100644
--- a/protos/perfetto/trace/ftrace/block.proto
+++ b/protos/perfetto/trace/ftrace/block.proto
@@ -87,6 +87,7 @@ message BlockRqCompleteFtraceEvent {
optional int32 errors = 4;
optional string rwbs = 5;
optional string cmd = 6;
+ optional int32 error = 7;
}
message BlockRqInsertFtraceEvent {
optional uint64 dev = 1;
diff --git a/protos/perfetto/trace/ftrace/cgroup.proto b/protos/perfetto/trace/ftrace/cgroup.proto
index b8a7d1e2c..3f8288ed5 100644
--- a/protos/perfetto/trace/ftrace/cgroup.proto
+++ b/protos/perfetto/trace/ftrace/cgroup.proto
@@ -11,11 +11,15 @@ message CgroupAttachTaskFtraceEvent {
optional int32 pid = 3;
optional string comm = 4;
optional string cname = 5;
+ optional int32 dst_level = 6;
+ optional string dst_path = 7;
}
message CgroupMkdirFtraceEvent {
optional int32 root = 1;
optional int32 id = 2;
optional string cname = 3;
+ optional int32 level = 4;
+ optional string path = 5;
}
message CgroupRemountFtraceEvent {
optional int32 root = 1;
@@ -26,6 +30,8 @@ message CgroupRmdirFtraceEvent {
optional int32 root = 1;
optional int32 id = 2;
optional string cname = 3;
+ optional int32 level = 4;
+ optional string path = 5;
}
message CgroupTransferTasksFtraceEvent {
optional int32 dst_root = 1;
@@ -33,6 +39,8 @@ message CgroupTransferTasksFtraceEvent {
optional int32 pid = 3;
optional string comm = 4;
optional string cname = 5;
+ optional int32 dst_level = 6;
+ optional string dst_path = 7;
}
message CgroupDestroyRootFtraceEvent {
optional int32 root = 1;
@@ -43,11 +51,15 @@ message CgroupReleaseFtraceEvent {
optional int32 root = 1;
optional int32 id = 2;
optional string cname = 3;
+ optional int32 level = 4;
+ optional string path = 5;
}
message CgroupRenameFtraceEvent {
optional int32 root = 1;
optional int32 id = 2;
optional string cname = 3;
+ optional int32 level = 4;
+ optional string path = 5;
}
message CgroupSetupRootFtraceEvent {
optional int32 root = 1;
diff --git a/protos/perfetto/trace/ftrace/compaction.proto b/protos/perfetto/trace/ftrace/compaction.proto
index cb5726239..ee6c6ff60 100644
--- a/protos/perfetto/trace/ftrace/compaction.proto
+++ b/protos/perfetto/trace/ftrace/compaction.proto
@@ -69,6 +69,7 @@ message MmCompactionKcompactdWakeFtraceEvent {
optional int32 nid = 1;
optional int32 order = 2;
optional uint32 classzone_idx = 3;
+ optional uint32 highest_zoneidx = 4;
}
message MmCompactionMigratepagesFtraceEvent {
optional uint64 nr_migrated = 1;
@@ -84,9 +85,11 @@ message MmCompactionTryToCompactPagesFtraceEvent {
optional int32 order = 1;
optional uint32 gfp_mask = 2;
optional uint32 mode = 3;
+ optional int32 prio = 4;
}
message MmCompactionWakeupKcompactdFtraceEvent {
optional int32 nid = 1;
optional int32 order = 2;
optional uint32 classzone_idx = 3;
+ optional uint32 highest_zoneidx = 4;
}
diff --git a/protos/perfetto/trace/ftrace/cros_ec.proto b/protos/perfetto/trace/ftrace/cros_ec.proto
new file mode 100644
index 000000000..b3ba4fbcc
--- /dev/null
+++ b/protos/perfetto/trace/ftrace/cros_ec.proto
@@ -0,0 +1,15 @@
+// Autogenerated by:
+// ../../tools/ftrace_proto_gen/ftrace_proto_gen.cc
+// Do not edit.
+
+syntax = "proto2";
+package perfetto.protos;
+
+message CrosEcSensorhubDataFtraceEvent {
+ optional int64 current_time = 1;
+ optional int64 current_timestamp = 2;
+ optional int64 delta = 3;
+ optional uint32 ec_fifo_timestamp = 4;
+ optional uint32 ec_sensor_num = 5;
+ optional int64 fifo_timestamp = 6;
+}
diff --git a/protos/perfetto/trace/ftrace/dma_fence.proto b/protos/perfetto/trace/ftrace/dma_fence.proto
new file mode 100644
index 000000000..70ff767e9
--- /dev/null
+++ b/protos/perfetto/trace/ftrace/dma_fence.proto
@@ -0,0 +1,37 @@
+// Autogenerated by:
+// ../../tools/ftrace_proto_gen/ftrace_proto_gen.cc
+// Do not edit.
+
+syntax = "proto2";
+package perfetto.protos;
+
+message DmaFenceInitFtraceEvent {
+ optional uint32 context = 1;
+ optional string driver = 2;
+ optional uint32 seqno = 3;
+ optional string timeline = 4;
+}
+message DmaFenceEmitFtraceEvent {
+ optional uint32 context = 1;
+ optional string driver = 2;
+ optional uint32 seqno = 3;
+ optional string timeline = 4;
+}
+message DmaFenceSignaledFtraceEvent {
+ optional uint32 context = 1;
+ optional string driver = 2;
+ optional uint32 seqno = 3;
+ optional string timeline = 4;
+}
+message DmaFenceWaitStartFtraceEvent {
+ optional uint32 context = 1;
+ optional string driver = 2;
+ optional uint32 seqno = 3;
+ optional string timeline = 4;
+}
+message DmaFenceWaitEndFtraceEvent {
+ optional uint32 context = 1;
+ optional string driver = 2;
+ optional uint32 seqno = 3;
+ optional string timeline = 4;
+}
diff --git a/protos/perfetto/trace/ftrace/drm.proto b/protos/perfetto/trace/ftrace/drm.proto
new file mode 100644
index 000000000..3095a5d36
--- /dev/null
+++ b/protos/perfetto/trace/ftrace/drm.proto
@@ -0,0 +1,18 @@
+// Autogenerated by:
+// ../../tools/ftrace_proto_gen/ftrace_proto_gen.cc
+// Do not edit.
+
+syntax = "proto2";
+package perfetto.protos;
+
+message DrmVblankEventFtraceEvent {
+ optional int32 crtc = 1;
+ optional uint32 high_prec = 2;
+ optional uint32 seq = 3;
+ optional int64 time = 4;
+}
+message DrmVblankEventDeliveredFtraceEvent {
+ optional int32 crtc = 1;
+ optional uint64 file = 2;
+ optional uint32 seq = 3;
+}
diff --git a/protos/perfetto/trace/ftrace/ext4.proto b/protos/perfetto/trace/ftrace/ext4.proto
index 90d032257..1bbe72c32 100644
--- a/protos/perfetto/trace/ftrace/ext4.proto
+++ b/protos/perfetto/trace/ftrace/ext4.proto
@@ -138,6 +138,8 @@ message Ext4DiscardBlocksFtraceEvent {
message Ext4DiscardPreallocationsFtraceEvent {
optional uint64 dev = 1;
optional uint64 ino = 2;
+ optional uint32 len = 3;
+ optional uint32 needed = 4;
}
message Ext4DropInodeFtraceEvent {
optional uint64 dev = 1;
@@ -302,6 +304,9 @@ message Ext4ExtRemoveSpaceDoneFtraceEvent {
optional int32 depth = 5;
optional int64 partial = 6;
optional uint32 eh_entries = 7;
+ optional uint32 pc_lblk = 8;
+ optional uint64 pc_pclu = 9;
+ optional int32 pc_state = 10;
}
message Ext4ExtRmIdxFtraceEvent {
optional uint64 dev = 1;
@@ -316,6 +321,9 @@ message Ext4ExtRmLeafFtraceEvent {
optional uint32 ee_lblk = 5;
optional uint64 ee_pblk = 6;
optional int32 ee_len = 7;
+ optional uint32 pc_lblk = 8;
+ optional uint64 pc_pclu = 9;
+ optional int32 pc_state = 10;
}
message Ext4ExtShowExtentFtraceEvent {
optional uint64 dev = 1;
@@ -421,6 +429,7 @@ message Ext4JournalStartFtraceEvent {
optional int32 blocks = 3;
optional int32 rsv_blocks = 4;
optional int32 nblocks = 5;
+ optional int32 revoke_creds = 6;
}
message Ext4JournalStartReservedFtraceEvent {
optional uint64 dev = 1;
@@ -557,6 +566,7 @@ message Ext4PunchHoleFtraceEvent {
message Ext4ReadBlockBitmapLoadFtraceEvent {
optional uint64 dev = 1;
optional uint32 group = 2;
+ optional uint32 prefetch = 3;
}
message Ext4ReadpageFtraceEvent {
optional uint64 dev = 1;
@@ -577,6 +587,9 @@ message Ext4RemoveBlocksFtraceEvent {
optional uint64 ee_pblk = 6;
optional uint32 ee_lblk = 7;
optional uint32 ee_len = 8;
+ optional uint32 pc_lblk = 9;
+ optional uint64 pc_pclu = 10;
+ optional int32 pc_state = 11;
}
message Ext4RequestBlocksFtraceEvent {
optional uint64 dev = 1;
diff --git a/protos/perfetto/trace/ftrace/f2fs.proto b/protos/perfetto/trace/ftrace/f2fs.proto
index 556c964aa..3a69da3fd 100644
--- a/protos/perfetto/trace/ftrace/f2fs.proto
+++ b/protos/perfetto/trace/ftrace/f2fs.proto
@@ -51,6 +51,7 @@ message F2fsGetVictimFtraceEvent {
optional uint32 pre_victim = 8;
optional uint32 prefree = 9;
optional uint32 free = 10;
+ optional uint32 cost = 11;
}
message F2fsIgetFtraceEvent {
optional uint64 dev = 1;
@@ -78,6 +79,9 @@ message F2fsReadpageFtraceEvent {
optional uint64 index = 3;
optional uint64 blkaddr = 4;
optional int32 type = 5;
+ optional int32 dir = 6;
+ optional int32 dirty = 7;
+ optional int32 uptodate = 8;
}
message F2fsReserveNewBlockFtraceEvent {
optional uint64 dev = 1;
@@ -91,6 +95,7 @@ message F2fsSetPageDirtyFtraceEvent {
optional int32 dir = 4;
optional uint64 index = 5;
optional int32 dirty = 6;
+ optional int32 uptodate = 7;
}
message F2fsSubmitWritePageFtraceEvent {
optional uint64 dev = 1;
@@ -115,6 +120,7 @@ message F2fsSyncFileExitFtraceEvent {
optional uint32 need_cp = 3;
optional int32 datasync = 4;
optional int32 ret = 5;
+ optional int32 cp_reason = 6;
}
message F2fsSyncFsFtraceEvent {
optional uint64 dev = 1;
@@ -205,6 +211,7 @@ message F2fsVmPageMkwriteFtraceEvent {
optional int32 dir = 4;
optional uint64 index = 5;
optional int32 dirty = 6;
+ optional int32 uptodate = 7;
}
message F2fsWriteBeginFtraceEvent {
optional uint64 dev = 1;
@@ -217,6 +224,7 @@ message F2fsWriteCheckpointFtraceEvent {
optional uint64 dev = 1;
optional uint32 is_umount = 2;
optional string msg = 3;
+ optional int32 reason = 4;
}
message F2fsWriteEndFtraceEvent {
optional uint64 dev = 1;
diff --git a/protos/perfetto/trace/ftrace/ftrace_event.proto b/protos/perfetto/trace/ftrace/ftrace_event.proto
index 31e5b9287..85ff78853 100644
--- a/protos/perfetto/trace/ftrace/ftrace_event.proto
+++ b/protos/perfetto/trace/ftrace/ftrace_event.proto
@@ -26,8 +26,11 @@ import "protos/perfetto/trace/ftrace/cgroup.proto";
import "protos/perfetto/trace/ftrace/clk.proto";
import "protos/perfetto/trace/ftrace/compaction.proto";
import "protos/perfetto/trace/ftrace/cpuhp.proto";
+import "protos/perfetto/trace/ftrace/cros_ec.proto";
+import "protos/perfetto/trace/ftrace/dma_fence.proto";
import "protos/perfetto/trace/ftrace/dmabuf_heap.proto";
import "protos/perfetto/trace/ftrace/dpu.proto";
+import "protos/perfetto/trace/ftrace/drm.proto";
import "protos/perfetto/trace/ftrace/ext4.proto";
import "protos/perfetto/trace/ftrace/f2fs.proto";
import "protos/perfetto/trace/ftrace/fastrpc.proto";
@@ -36,27 +39,36 @@ import "protos/perfetto/trace/ftrace/filemap.proto";
import "protos/perfetto/trace/ftrace/ftrace.proto";
import "protos/perfetto/trace/ftrace/g2d.proto";
import "protos/perfetto/trace/ftrace/gpu_mem.proto";
+import "protos/perfetto/trace/ftrace/gpu_scheduler.proto";
import "protos/perfetto/trace/ftrace/i2c.proto";
import "protos/perfetto/trace/ftrace/ion.proto";
import "protos/perfetto/trace/ftrace/ipi.proto";
import "protos/perfetto/trace/ftrace/irq.proto";
import "protos/perfetto/trace/ftrace/kmem.proto";
+import "protos/perfetto/trace/ftrace/kvm.proto";
import "protos/perfetto/trace/ftrace/lowmemorykiller.proto";
import "protos/perfetto/trace/ftrace/mali.proto";
import "protos/perfetto/trace/ftrace/mdss.proto";
import "protos/perfetto/trace/ftrace/mm_event.proto";
+import "protos/perfetto/trace/ftrace/net.proto";
import "protos/perfetto/trace/ftrace/oom.proto";
import "protos/perfetto/trace/ftrace/power.proto";
+import "protos/perfetto/trace/ftrace/printk.proto";
import "protos/perfetto/trace/ftrace/raw_syscalls.proto";
import "protos/perfetto/trace/ftrace/regulator.proto";
import "protos/perfetto/trace/ftrace/sched.proto";
import "protos/perfetto/trace/ftrace/scm.proto";
import "protos/perfetto/trace/ftrace/sde.proto";
import "protos/perfetto/trace/ftrace/signal.proto";
+import "protos/perfetto/trace/ftrace/skb.proto";
+import "protos/perfetto/trace/ftrace/sock.proto";
import "protos/perfetto/trace/ftrace/sync.proto";
+import "protos/perfetto/trace/ftrace/synthetic.proto";
import "protos/perfetto/trace/ftrace/systrace.proto";
import "protos/perfetto/trace/ftrace/task.proto";
+import "protos/perfetto/trace/ftrace/tcp.proto";
import "protos/perfetto/trace/ftrace/thermal.proto";
+import "protos/perfetto/trace/ftrace/ufs.proto";
import "protos/perfetto/trace/ftrace/vmscan.proto";
import "protos/perfetto/trace/ftrace/workqueue.proto";
import "protos/perfetto/trace/ftrace/generic.proto";
@@ -447,5 +459,65 @@ message FtraceEvent {
SdeSdePerfCrtcUpdateFtraceEvent sde_sde_perf_crtc_update = 356;
SdeSdePerfSetQosLutsFtraceEvent sde_sde_perf_set_qos_luts = 357;
SdeSdePerfUpdateBusFtraceEvent sde_sde_perf_update_bus = 358;
+ RssStatThrottledFtraceEvent rss_stat_throttled = 359;
+ NetifReceiveSkbFtraceEvent netif_receive_skb = 360;
+ NetDevXmitFtraceEvent net_dev_xmit = 361;
+ InetSockSetStateFtraceEvent inet_sock_set_state = 362;
+ TcpRetransmitSkbFtraceEvent tcp_retransmit_skb = 363;
+ CrosEcSensorhubDataFtraceEvent cros_ec_sensorhub_data = 364;
+ NapiGroReceiveEntryFtraceEvent napi_gro_receive_entry = 365;
+ NapiGroReceiveExitFtraceEvent napi_gro_receive_exit = 366;
+ KfreeSkbFtraceEvent kfree_skb = 367;
+ KvmAccessFaultFtraceEvent kvm_access_fault = 368;
+ KvmAckIrqFtraceEvent kvm_ack_irq = 369;
+ KvmAgeHvaFtraceEvent kvm_age_hva = 370;
+ KvmAgePageFtraceEvent kvm_age_page = 371;
+ KvmArmClearDebugFtraceEvent kvm_arm_clear_debug = 372;
+ KvmArmSetDreg32FtraceEvent kvm_arm_set_dreg32 = 373;
+ KvmArmSetRegsetFtraceEvent kvm_arm_set_regset = 374;
+ KvmArmSetupDebugFtraceEvent kvm_arm_setup_debug = 375;
+ KvmEntryFtraceEvent kvm_entry = 376;
+ KvmExitFtraceEvent kvm_exit = 377;
+ KvmFpuFtraceEvent kvm_fpu = 378;
+ KvmGetTimerMapFtraceEvent kvm_get_timer_map = 379;
+ KvmGuestFaultFtraceEvent kvm_guest_fault = 380;
+ KvmHandleSysRegFtraceEvent kvm_handle_sys_reg = 381;
+ KvmHvcArm64FtraceEvent kvm_hvc_arm64 = 382;
+ KvmIrqLineFtraceEvent kvm_irq_line = 383;
+ KvmMmioFtraceEvent kvm_mmio = 384;
+ KvmMmioEmulateFtraceEvent kvm_mmio_emulate = 385;
+ KvmSetGuestDebugFtraceEvent kvm_set_guest_debug = 386;
+ KvmSetIrqFtraceEvent kvm_set_irq = 387;
+ KvmSetSpteHvaFtraceEvent kvm_set_spte_hva = 388;
+ KvmSetWayFlushFtraceEvent kvm_set_way_flush = 389;
+ KvmSysAccessFtraceEvent kvm_sys_access = 390;
+ KvmTestAgeHvaFtraceEvent kvm_test_age_hva = 391;
+ KvmTimerEmulateFtraceEvent kvm_timer_emulate = 392;
+ KvmTimerHrtimerExpireFtraceEvent kvm_timer_hrtimer_expire = 393;
+ KvmTimerRestoreStateFtraceEvent kvm_timer_restore_state = 394;
+ KvmTimerSaveStateFtraceEvent kvm_timer_save_state = 395;
+ KvmTimerUpdateIrqFtraceEvent kvm_timer_update_irq = 396;
+ KvmToggleCacheFtraceEvent kvm_toggle_cache = 397;
+ KvmUnmapHvaRangeFtraceEvent kvm_unmap_hva_range = 398;
+ KvmUserspaceExitFtraceEvent kvm_userspace_exit = 399;
+ KvmVcpuWakeupFtraceEvent kvm_vcpu_wakeup = 400;
+ KvmWfxArm64FtraceEvent kvm_wfx_arm64 = 401;
+ TrapRegFtraceEvent trap_reg = 402;
+ VgicUpdateIrqPendingFtraceEvent vgic_update_irq_pending = 403;
+ WakeupSourceActivateFtraceEvent wakeup_source_activate = 404;
+ WakeupSourceDeactivateFtraceEvent wakeup_source_deactivate = 405;
+ UfshcdCommandFtraceEvent ufshcd_command = 406;
+ UfshcdClkGatingFtraceEvent ufshcd_clk_gating = 407;
+ ConsoleFtraceEvent console = 408;
+ DrmVblankEventFtraceEvent drm_vblank_event = 409;
+ DrmVblankEventDeliveredFtraceEvent drm_vblank_event_delivered = 410;
+ DrmSchedJobFtraceEvent drm_sched_job = 411;
+ DrmRunJobFtraceEvent drm_run_job = 412;
+ DrmSchedProcessJobFtraceEvent drm_sched_process_job = 413;
+ DmaFenceInitFtraceEvent dma_fence_init = 414;
+ DmaFenceEmitFtraceEvent dma_fence_emit = 415;
+ DmaFenceSignaledFtraceEvent dma_fence_signaled = 416;
+ DmaFenceWaitStartFtraceEvent dma_fence_wait_start = 417;
+ DmaFenceWaitEndFtraceEvent dma_fence_wait_end = 418;
}
}
diff --git a/protos/perfetto/trace/ftrace/ftrace_event_bundle.proto b/protos/perfetto/trace/ftrace/ftrace_event_bundle.proto
index 69aedaa53..5e531f617 100644
--- a/protos/perfetto/trace/ftrace/ftrace_event_bundle.proto
+++ b/protos/perfetto/trace/ftrace/ftrace_event_bundle.proto
@@ -26,6 +26,7 @@ package perfetto.protos;
message FtraceEventBundle {
optional uint32 cpu = 1;
repeated FtraceEvent event = 2;
+
// Set to true if there was data loss between the last time we've read from
// the corresponding per-cpu kernel buffer, and the earliest event recorded
// in this bundle.
@@ -62,4 +63,45 @@ message FtraceEventBundle {
repeated uint32 waking_comm_index = 11 [packed = true];
}
optional CompactSched compact_sched = 4;
+
+ // traced_probes always sets the ftrace_clock to "boot". That is not available
+ // in older kernels (v3.x). In that case we fallback on "global" or "local".
+ // When we do that, we report the fallback clock in each bundle so we can do
+ // proper clock syncing at parsing time in TraceProcessor. We cannot use the
+ // TracePacket timestamp_clock_id because: (1) there is no per-packet
+ // timestamp for ftrace bundles; (2) "global" does not match CLOCK_MONOTONIC.
+ // Having a dedicated and explicit flag allows us to correct further misakes
+ // in future by looking at the kernel version.
+ // This field has been introduced in perfetto v19 / Android T (13).
+ // This field is omitted when the ftrace clock is just "boot", as that is the
+ // default assumption (and for consistency with the past).
+ optional FtraceClock ftrace_clock = 5;
+
+ // The timestamp according to the ftrace clock, taken at the same instant
+ // as |boot_timestamp|. This is used to sync ftrace events when a non-boot
+ // clock is used as the ftrace clock. We don't use the ClockSnapshot packet
+ // because the ftrace global/local clocks don't match any of the clock_gettime
+ // domains and can be only read by traced_probes.
+ //
+ // Only set when |ftrace_clock| != FTRACE_CLOCK_UNSPECIFIED.
+ //
+ // Implementation note: Populated by reading the 'now ts:' field in
+ // tracefs/per_cpu/cpuX/stat.
+ optional int64 ftrace_timestamp = 6;
+
+ // The timestamp according to CLOCK_BOOTTIME, taken at the same instant as
+ // |ftrace_timestamp|. See documentation of |ftrace_timestamp| for
+ // more info.
+ //
+ // Only set when |ftrace_clock| != FTRACE_CLOCK_UNSPECIFIED.
+ optional int64 boot_timestamp = 7;
+}
+
+enum FtraceClock {
+ // There is no FTRACE_CLOCK_BOOT entry as that's the default assumption. When
+ // the ftrace clock is "boot", it's just omitted (so UNSPECIFIED == BOOT).
+ FTRACE_CLOCK_UNSPECIFIED = 0;
+ FTRACE_CLOCK_UNKNOWN = 1;
+ FTRACE_CLOCK_GLOBAL = 2;
+ FTRACE_CLOCK_LOCAL = 3;
}
diff --git a/protos/perfetto/trace/ftrace/ftrace_stats.proto b/protos/perfetto/trace/ftrace/ftrace_stats.proto
index 1f65456a0..9f26fa3f2 100644
--- a/protos/perfetto/trace/ftrace/ftrace_stats.proto
+++ b/protos/perfetto/trace/ftrace/ftrace_stats.proto
@@ -80,4 +80,16 @@ message FtraceStats {
// The memory used by the kernel symbolizer (KernelSymbolMap.size_bytes()).
optional uint32 kernel_symbols_mem_kb = 4;
+
+ // Atrace errors (even non-fatal ones) are reported here. A typical example is
+ // one or more atrace categories not available on the device.
+ optional string atrace_errors = 5;
+
+ // Ftrace events requested by the config but not present on device.
+ repeated string unknown_ftrace_events = 6;
+
+ // Ftrace events requested by the config and present on device, but which we
+ // failed to enable due to permissions, or due to a conflicting option
+ // (currently FtraceConfig.disable_generic_events).
+ repeated string failed_ftrace_events = 7;
}
diff --git a/protos/perfetto/trace/ftrace/gpu_scheduler.proto b/protos/perfetto/trace/ftrace/gpu_scheduler.proto
new file mode 100644
index 000000000..a70329db7
--- /dev/null
+++ b/protos/perfetto/trace/ftrace/gpu_scheduler.proto
@@ -0,0 +1,26 @@
+// Autogenerated by:
+// ../../tools/ftrace_proto_gen/ftrace_proto_gen.cc
+// Do not edit.
+
+syntax = "proto2";
+package perfetto.protos;
+
+message DrmSchedJobFtraceEvent {
+ optional uint64 entity = 1;
+ optional uint64 fence = 2;
+ optional int32 hw_job_count = 3;
+ optional uint64 id = 4;
+ optional uint32 job_count = 5;
+ optional string name = 6;
+}
+message DrmRunJobFtraceEvent {
+ optional uint64 entity = 1;
+ optional uint64 fence = 2;
+ optional int32 hw_job_count = 3;
+ optional uint64 id = 4;
+ optional uint32 job_count = 5;
+ optional string name = 6;
+}
+message DrmSchedProcessJobFtraceEvent {
+ optional uint64 fence = 1;
+}
diff --git a/protos/perfetto/trace/ftrace/kvm.proto b/protos/perfetto/trace/ftrace/kvm.proto
new file mode 100644
index 000000000..e1797901d
--- /dev/null
+++ b/protos/perfetto/trace/ftrace/kvm.proto
@@ -0,0 +1,170 @@
+// Autogenerated by:
+// ../../tools/ftrace_proto_gen/ftrace_proto_gen.cc
+// Do not edit.
+
+syntax = "proto2";
+package perfetto.protos;
+
+message KvmAccessFaultFtraceEvent {
+ optional uint64 ipa = 1;
+}
+message KvmAckIrqFtraceEvent {
+ optional uint32 irqchip = 1;
+ optional uint32 pin = 2;
+}
+message KvmAgeHvaFtraceEvent {
+ optional uint64 end = 1;
+ optional uint64 start = 2;
+}
+message KvmAgePageFtraceEvent {
+ optional uint64 gfn = 1;
+ optional uint64 hva = 2;
+ optional uint32 level = 3;
+ optional uint32 referenced = 4;
+}
+message KvmArmClearDebugFtraceEvent {
+ optional uint32 guest_debug = 1;
+}
+message KvmArmSetDreg32FtraceEvent {
+ optional string name = 1;
+ optional uint32 value = 2;
+}
+message KvmArmSetRegsetFtraceEvent {
+ optional int32 len = 1;
+ optional string name = 2;
+}
+message KvmArmSetupDebugFtraceEvent {
+ optional uint32 guest_debug = 1;
+ optional uint64 vcpu = 2;
+}
+message KvmEntryFtraceEvent {
+ optional uint64 vcpu_pc = 1;
+}
+message KvmExitFtraceEvent {
+ optional uint32 esr_ec = 1;
+ optional int32 ret = 2;
+ optional uint64 vcpu_pc = 3;
+}
+message KvmFpuFtraceEvent {
+ optional uint32 load = 1;
+}
+message KvmGetTimerMapFtraceEvent {
+ optional int32 direct_ptimer = 1;
+ optional int32 direct_vtimer = 2;
+ optional int32 emul_ptimer = 3;
+ optional uint64 vcpu_id = 4;
+}
+message KvmGuestFaultFtraceEvent {
+ optional uint64 hsr = 1;
+ optional uint64 hxfar = 2;
+ optional uint64 ipa = 3;
+ optional uint64 vcpu_pc = 4;
+}
+message KvmHandleSysRegFtraceEvent {
+ optional uint64 hsr = 1;
+}
+message KvmHvcArm64FtraceEvent {
+ optional uint64 imm = 1;
+ optional uint64 r0 = 2;
+ optional uint64 vcpu_pc = 3;
+}
+message KvmIrqLineFtraceEvent {
+ optional int32 irq_num = 1;
+ optional int32 level = 2;
+ optional uint32 type = 3;
+ optional int32 vcpu_idx = 4;
+}
+message KvmMmioFtraceEvent {
+ optional uint64 gpa = 1;
+ optional uint32 len = 2;
+ optional uint32 type = 3;
+ optional uint64 val = 4;
+}
+message KvmMmioEmulateFtraceEvent {
+ optional uint64 cpsr = 1;
+ optional uint64 instr = 2;
+ optional uint64 vcpu_pc = 3;
+}
+message KvmSetGuestDebugFtraceEvent {
+ optional uint32 guest_debug = 1;
+ optional uint64 vcpu = 2;
+}
+message KvmSetIrqFtraceEvent {
+ optional uint32 gsi = 1;
+ optional int32 irq_source_id = 2;
+ optional int32 level = 3;
+}
+message KvmSetSpteHvaFtraceEvent {
+ optional uint64 hva = 1;
+}
+message KvmSetWayFlushFtraceEvent {
+ optional uint32 cache = 1;
+ optional uint64 vcpu_pc = 2;
+}
+message KvmSysAccessFtraceEvent {
+ optional uint32 CRm = 1;
+ optional uint32 CRn = 2;
+ optional uint32 Op0 = 3;
+ optional uint32 Op1 = 4;
+ optional uint32 Op2 = 5;
+ optional uint32 is_write = 6;
+ optional string name = 7;
+ optional uint64 vcpu_pc = 8;
+}
+message KvmTestAgeHvaFtraceEvent {
+ optional uint64 hva = 1;
+}
+message KvmTimerEmulateFtraceEvent {
+ optional uint32 should_fire = 1;
+ optional int32 timer_idx = 2;
+}
+message KvmTimerHrtimerExpireFtraceEvent {
+ optional int32 timer_idx = 1;
+}
+message KvmTimerRestoreStateFtraceEvent {
+ optional uint64 ctl = 1;
+ optional uint64 cval = 2;
+ optional int32 timer_idx = 3;
+}
+message KvmTimerSaveStateFtraceEvent {
+ optional uint64 ctl = 1;
+ optional uint64 cval = 2;
+ optional int32 timer_idx = 3;
+}
+message KvmTimerUpdateIrqFtraceEvent {
+ optional uint32 irq = 1;
+ optional int32 level = 2;
+ optional uint64 vcpu_id = 3;
+}
+message KvmToggleCacheFtraceEvent {
+ optional uint32 now = 1;
+ optional uint64 vcpu_pc = 2;
+ optional uint32 was = 3;
+}
+message KvmUnmapHvaRangeFtraceEvent {
+ optional uint64 end = 1;
+ optional uint64 start = 2;
+}
+message KvmUserspaceExitFtraceEvent {
+ optional uint32 reason = 1;
+}
+message KvmVcpuWakeupFtraceEvent {
+ optional uint64 ns = 1;
+ optional uint32 valid = 2;
+ optional uint32 waited = 3;
+}
+message KvmWfxArm64FtraceEvent {
+ optional uint32 is_wfe = 1;
+ optional uint64 vcpu_pc = 2;
+}
+message TrapRegFtraceEvent {
+ optional string fn = 1;
+ optional uint32 is_write = 2;
+ optional int32 reg = 3;
+ optional uint64 write_value = 4;
+}
+message VgicUpdateIrqPendingFtraceEvent {
+ optional uint32 irq = 1;
+ optional uint32 level = 2;
+ optional uint64 vcpu_id = 3;
+}
diff --git a/protos/perfetto/trace/ftrace/net.proto b/protos/perfetto/trace/ftrace/net.proto
new file mode 100644
index 000000000..866a5995e
--- /dev/null
+++ b/protos/perfetto/trace/ftrace/net.proto
@@ -0,0 +1,42 @@
+// Autogenerated by:
+// ../../tools/ftrace_proto_gen/ftrace_proto_gen.cc
+// Do not edit.
+
+syntax = "proto2";
+package perfetto.protos;
+
+message NetifReceiveSkbFtraceEvent {
+ optional uint32 len = 1;
+ optional string name = 2;
+ optional uint64 skbaddr = 3;
+}
+message NetDevXmitFtraceEvent {
+ optional uint32 len = 1;
+ optional string name = 2;
+ optional int32 rc = 3;
+ optional uint64 skbaddr = 4;
+}
+message NapiGroReceiveEntryFtraceEvent {
+ optional uint32 data_len = 1;
+ optional uint32 gso_size = 2;
+ optional uint32 gso_type = 3;
+ optional uint32 hash = 4;
+ optional uint32 ip_summed = 5;
+ optional uint32 l4_hash = 6;
+ optional uint32 len = 7;
+ optional int32 mac_header = 8;
+ optional uint32 mac_header_valid = 9;
+ optional string name = 10;
+ optional uint32 napi_id = 11;
+ optional uint32 nr_frags = 12;
+ optional uint32 protocol = 13;
+ optional uint32 queue_mapping = 14;
+ optional uint64 skbaddr = 15;
+ optional uint32 truesize = 16;
+ optional uint32 vlan_proto = 17;
+ optional uint32 vlan_tagged = 18;
+ optional uint32 vlan_tci = 19;
+}
+message NapiGroReceiveExitFtraceEvent {
+ optional int32 ret = 1;
+}
diff --git a/protos/perfetto/trace/ftrace/power.proto b/protos/perfetto/trace/ftrace/power.proto
index f38015a81..7279e244e 100644
--- a/protos/perfetto/trace/ftrace/power.proto
+++ b/protos/perfetto/trace/ftrace/power.proto
@@ -42,3 +42,11 @@ message GpuFrequencyFtraceEvent {
optional uint32 gpu_id = 1;
optional uint32 state = 2;
}
+message WakeupSourceActivateFtraceEvent {
+ optional string name = 1;
+ optional uint64 state = 2;
+}
+message WakeupSourceDeactivateFtraceEvent {
+ optional string name = 1;
+ optional uint64 state = 2;
+}
diff --git a/protos/perfetto/trace/ftrace/printk.proto b/protos/perfetto/trace/ftrace/printk.proto
new file mode 100644
index 000000000..45261e6a0
--- /dev/null
+++ b/protos/perfetto/trace/ftrace/printk.proto
@@ -0,0 +1,10 @@
+// Autogenerated by:
+// ../../tools/ftrace_proto_gen/ftrace_proto_gen.cc
+// Do not edit.
+
+syntax = "proto2";
+package perfetto.protos;
+
+message ConsoleFtraceEvent {
+ optional string msg = 1;
+}
diff --git a/protos/perfetto/trace/ftrace/scm.proto b/protos/perfetto/trace/ftrace/scm.proto
index 22a80a51f..616a39d93 100644
--- a/protos/perfetto/trace/ftrace/scm.proto
+++ b/protos/perfetto/trace/ftrace/scm.proto
@@ -10,4 +10,5 @@ message ScmCallStartFtraceEvent {
optional uint64 x0 = 2;
optional uint64 x5 = 3;
}
-message ScmCallEndFtraceEvent {}
+message ScmCallEndFtraceEvent {
+}
diff --git a/protos/perfetto/trace/ftrace/skb.proto b/protos/perfetto/trace/ftrace/skb.proto
new file mode 100644
index 000000000..b77f87118
--- /dev/null
+++ b/protos/perfetto/trace/ftrace/skb.proto
@@ -0,0 +1,12 @@
+// Autogenerated by:
+// ../../tools/ftrace_proto_gen/ftrace_proto_gen.cc
+// Do not edit.
+
+syntax = "proto2";
+package perfetto.protos;
+
+message KfreeSkbFtraceEvent {
+ optional uint64 location = 1;
+ optional uint32 protocol = 2;
+ optional uint64 skbaddr = 3;
+}
diff --git a/protos/perfetto/trace/ftrace/sock.proto b/protos/perfetto/trace/ftrace/sock.proto
new file mode 100644
index 000000000..960711767
--- /dev/null
+++ b/protos/perfetto/trace/ftrace/sock.proto
@@ -0,0 +1,18 @@
+// Autogenerated by:
+// ../../tools/ftrace_proto_gen/ftrace_proto_gen.cc
+// Do not edit.
+
+syntax = "proto2";
+package perfetto.protos;
+
+message InetSockSetStateFtraceEvent {
+ optional uint32 daddr = 1;
+ optional uint32 dport = 2;
+ optional uint32 family = 3;
+ optional int32 newstate = 4;
+ optional int32 oldstate = 5;
+ optional uint32 protocol = 6;
+ optional uint32 saddr = 7;
+ optional uint64 skaddr = 8;
+ optional uint32 sport = 9;
+}
diff --git a/protos/perfetto/trace/ftrace/synthetic.proto b/protos/perfetto/trace/ftrace/synthetic.proto
new file mode 100644
index 000000000..32ea40304
--- /dev/null
+++ b/protos/perfetto/trace/ftrace/synthetic.proto
@@ -0,0 +1,13 @@
+// Autogenerated by:
+// ../../tools/ftrace_proto_gen/ftrace_proto_gen.cc
+// Do not edit.
+
+syntax = "proto2";
+package perfetto.protos;
+
+message RssStatThrottledFtraceEvent {
+ optional uint32 curr = 1;
+ optional int32 member = 2;
+ optional uint32 mm_id = 3;
+ optional int64 size = 4;
+}
diff --git a/protos/perfetto/trace/ftrace/tcp.proto b/protos/perfetto/trace/ftrace/tcp.proto
new file mode 100644
index 000000000..fb854c3a7
--- /dev/null
+++ b/protos/perfetto/trace/ftrace/tcp.proto
@@ -0,0 +1,16 @@
+// Autogenerated by:
+// ../../tools/ftrace_proto_gen/ftrace_proto_gen.cc
+// Do not edit.
+
+syntax = "proto2";
+package perfetto.protos;
+
+message TcpRetransmitSkbFtraceEvent {
+ optional uint32 daddr = 1;
+ optional uint32 dport = 2;
+ optional uint32 saddr = 3;
+ optional uint64 skaddr = 4;
+ optional uint64 skbaddr = 5;
+ optional uint32 sport = 6;
+ optional int32 state = 7;
+}
diff --git a/protos/perfetto/trace/ftrace/ufs.proto b/protos/perfetto/trace/ftrace/ufs.proto
new file mode 100644
index 000000000..1e2d94973
--- /dev/null
+++ b/protos/perfetto/trace/ftrace/ufs.proto
@@ -0,0 +1,23 @@
+// Autogenerated by:
+// ../../tools/ftrace_proto_gen/ftrace_proto_gen.cc
+// Do not edit.
+
+syntax = "proto2";
+package perfetto.protos;
+
+message UfshcdCommandFtraceEvent {
+ optional string dev_name = 1;
+ optional uint32 doorbell = 2;
+ optional uint32 intr = 3;
+ optional uint64 lba = 4;
+ optional uint32 opcode = 5;
+ optional string str = 6;
+ optional uint32 tag = 7;
+ optional int32 transfer_len = 8;
+ optional uint32 group_id = 9;
+ optional uint32 str_t = 10;
+}
+message UfshcdClkGatingFtraceEvent {
+ optional string dev_name = 1;
+ optional int32 state = 2;
+}
diff --git a/protos/perfetto/trace/ftrace/vmscan.proto b/protos/perfetto/trace/ftrace/vmscan.proto
index f5c5f669b..084b22143 100644
--- a/protos/perfetto/trace/ftrace/vmscan.proto
+++ b/protos/perfetto/trace/ftrace/vmscan.proto
@@ -16,6 +16,7 @@ message MmVmscanDirectReclaimEndFtraceEvent {
message MmVmscanKswapdWakeFtraceEvent {
optional int32 nid = 1;
optional int32 order = 2;
+ optional int32 zid = 3;
}
message MmVmscanKswapdSleepFtraceEvent {
optional int32 nid = 1;
diff --git a/protos/perfetto/trace/ftrace/workqueue.proto b/protos/perfetto/trace/ftrace/workqueue.proto
index dd683611a..cf6d8a747 100644
--- a/protos/perfetto/trace/ftrace/workqueue.proto
+++ b/protos/perfetto/trace/ftrace/workqueue.proto
@@ -10,6 +10,7 @@ message WorkqueueActivateWorkFtraceEvent {
}
message WorkqueueExecuteEndFtraceEvent {
optional uint64 work = 1;
+ optional uint64 function = 2;
}
message WorkqueueExecuteStartFtraceEvent {
optional uint64 work = 1;
diff --git a/protos/perfetto/trace/interned_data/interned_data.proto b/protos/perfetto/trace/interned_data/interned_data.proto
index cc9c9e33a..86b8a9f36 100644
--- a/protos/perfetto/trace/interned_data/interned_data.proto
+++ b/protos/perfetto/trace/interned_data/interned_data.proto
@@ -53,7 +53,7 @@ package perfetto.protos;
// emitted proactively in advance of referring to them in later packets.
//
// Next reserved id: 8 (up to 15).
-// Next id: 27.
+// Next id: 28.
message InternedData {
// TODO(eseckler): Replace iid fields inside interned messages with
// map<iid, message> type fields in InternedData.
@@ -68,6 +68,7 @@ message InternedData {
repeated EventCategory event_categories = 1;
repeated EventName event_names = 2;
repeated DebugAnnotationName debug_annotation_names = 3;
+ repeated DebugAnnotationValueTypeName debug_annotation_value_type_names = 27;
repeated SourceLocation source_locations = 4;
repeated LogMessageBody log_message_body = 20;
repeated HistogramName histogram_names = 25;
diff --git a/protos/perfetto/trace/perfetto/perfetto_metatrace.proto b/protos/perfetto/trace/perfetto/perfetto_metatrace.proto
index a7b966c0d..df33b13e3 100644
--- a/protos/perfetto/trace/perfetto/perfetto_metatrace.proto
+++ b/protos/perfetto/trace/perfetto/perfetto_metatrace.proto
@@ -35,7 +35,7 @@ message PerfettoMetatrace {
}
// Only when using |event_id|.
- optional uint32 event_duration_ns = 3;
+ optional uint64 event_duration_ns = 3;
// Only when using |counter_id|.
optional int32 counter_value = 4;
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index bbb16997a..63b058f13 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -11,6 +11,24 @@ syntax = "proto2";
package perfetto.protos;
+option go_package = "github.com/google/perfetto/perfetto_proto";
+
+// Begin of protos/perfetto/common/ftrace_descriptor.proto
+
+message FtraceDescriptor {
+ message AtraceCategory {
+ optional string name = 1;
+ optional string description = 2;
+ }
+
+ // Report the available atrace categories.
+ //
+ // Used by Traceur via `perfetto --query`.
+ repeated AtraceCategory atrace_categories = 1;
+}
+
+// End of protos/perfetto/common/ftrace_descriptor.proto
+
// Begin of protos/perfetto/common/gpu_counter_descriptor.proto
// Description of GPU counters.
@@ -158,6 +176,13 @@ message DataSourceDescriptor {
// e.g., "linux.ftrace", "chromium.tracing"
optional string name = 1;
+ // When non-zero, this is a unique ID within the scope of the Producer for
+ // this data source (it is NOT globally unique). This is useful to
+ // differentiate between data sources with matching names when calling
+ // UpdateDataSource(). This field has been introduced in November 2021
+ // (v22, Android T) and is not supported on older versions.
+ optional uint64 id = 7;
+
// When true the data source is expected to ack the stop request through the
// NotifyDataSourceStopped() IPC. This field has been introduced after
// Android P in Jul 2018 and is not supported on older versions.
@@ -177,6 +202,8 @@ message DataSourceDescriptor {
optional GpuCounterDescriptor gpu_counter_descriptor = 5 [lazy = true];
optional TrackEventDescriptor track_event_descriptor = 6 [lazy = true];
+
+ optional FtraceDescriptor ftrace_descriptor = 8 [lazy = true];
}
// End of protos/perfetto/common/data_source_descriptor.proto
@@ -195,6 +222,10 @@ message TracingServiceState {
// Typically matches the process name.
optional string name = 2;
+ // Unix pid of the remote process. Supported only on Linux-based systems.
+ // Introduced in v24 / Android T.
+ optional int32 pid = 5;
+
// Unix uid of the remote process.
optional int32 uid = 3;
@@ -215,12 +246,53 @@ message TracingServiceState {
optional int32 producer_id = 2;
}
+ message TracingSession {
+ // The TracingSessionID.
+ optional uint64 id = 1;
+
+ // The Unix uid of the consumer that started the session.
+ // This is meaningful only if the caller is root. In all other cases only
+ // tracing sessions that match the caller UID will be displayed.
+ optional int32 consumer_uid = 2;
+
+ // Internal state of the tracing session.
+ // These strings are FYI only and subjected to change.
+ optional string state = 3;
+
+ // The unique_session_name as set in the trace config (might be empty).
+ optional string unique_session_name = 4;
+
+ // The number and size of each buffer.
+ repeated uint32 buffer_size_kb = 5;
+
+ // Duration, as specified in the TraceConfig.duration_ms.
+ optional uint32 duration_ms = 6;
+
+ // Number of data sources involved in the session.
+ optional uint32 num_data_sources = 7;
+
+ // Time when the session was started, in the CLOCK_REALTIME domain.
+ // Available only on Linux-based systems.
+ optional int64 start_realtime_ns = 8;
+ }
+
// Lists all the producers connected.
repeated Producer producers = 1;
// Lists the data sources available.
repeated DataSource data_sources = 2;
+ // Lists the tracing sessions active AND owned by a consumer that has the same
+ // UID of the caller (or all of them if the caller is root).
+ // Introduced in v24 / Android T.
+ repeated TracingSession tracing_sessions = 6;
+
+ // This is always set to true from v24 and beyond. This flag is only used to
+ // tell the difference between: (1) talking to a recent service which happens
+ // to have no tracing session active; (2) talking to an older version of the
+ // service which will never report any tracing session.
+ optional bool supports_tracing_sessions = 7;
+
// Total number of tracing sessions.
optional int32 num_sessions = 3;
@@ -249,6 +321,10 @@ enum BuiltinClock {
BUILTIN_CLOCK_MAX_ID = 63;
reserved 7, 8;
+
+ // An internal CL (ag/16521245) has taken this for BUILTIN_CLOCK_TSC.
+ // That might get upstreamed later on. Avoid diverging on this ID in future.
+ reserved 9;
}
// End of protos/perfetto/common/builtin_clock.proto
@@ -392,6 +468,31 @@ message FtraceConfig {
// initialized synchronously on the data source start and hence avoiding
// timing races in tests.
optional bool initialize_ksyms_synchronously_for_testing = 14;
+
+ // When this boolean is true AND the ftrace_events contains "kmem/rss_stat",
+ // this option causes traced_probes to enable the "kmem/rss_stat_throttled"
+ // event instad if present, and fall back to "kmem/rss_stat" if not present.
+ // The historical context for this is the following:
+ // - Up to Android S (12), the rss_stat was internally throttled in its
+ // kernel implementation.
+ // - A change introduced in the kernels after S has introduced a new
+ // "rss_stat_throttled" making the original "rss_stat" event unthrottled
+ // (hence very spammy).
+ // - Not all Android T/13 devices will receive a new kernel though, hence we
+ // need to deal with both cases.
+ // For more context: go/rss-stat-throttled.
+ // TODO(kaleshsingh): implement the logic behind this. Right now this flag
+ // does nothing.
+ optional bool throttle_rss_stat = 15;
+
+ // If true, avoid enabling events that aren't statically known by
+ // traced_probes. Otherwise, the default is to emit such events as
+ // GenericFtraceEvent protos.
+ // Prefer to keep this flag at its default. This was added for Android
+ // tracing, where atrace categories and/or atrace HAL requested events can
+ // expand to events that aren't of interest to the tracing user.
+ // Introduced in: Android T.
+ optional bool disable_generic_events = 16;
}
// End of protos/perfetto/config/ftrace/ftrace_config.proto
@@ -597,6 +698,10 @@ message HeapprofdConfig {
//
// BUGS
// Before Android 12, setting this to 0 would crash the target process.
+ //
+ // N.B. This must be explicitly set to a non-zero value for all heaps (with
+ // this field or with heap_sampling_intervals), otherwise the producer will
+ // not start.
optional uint64 sampling_interval_bytes = 1;
// If less than the given numbers of bytes are left free in the shared
@@ -651,6 +756,8 @@ message HeapprofdConfig {
// crash the target process before Android 12.
//
// Introduced in Android 12.
+ //
+ // All values must be non-zero or the producer will not start.
repeated uint64 heap_sampling_intervals = 22;
// Sample all heaps registered by target process. Introduced in Android 12.
@@ -751,7 +858,7 @@ message HeapprofdConfig {
// Begin of protos/perfetto/config/profiling/java_hprof_config.proto
-// Configuration for go/heapprofd.
+// Configuration for managed app heap graph snapshots.
message JavaHprofConfig {
// If dump_interval_ms != 0, the following configuration is used.
message ContinuousDumpConfig {
@@ -760,14 +867,36 @@ message JavaHprofConfig {
optional uint32 dump_phase_ms = 1;
// ms to wait between following dumps.
optional uint32 dump_interval_ms = 2;
+ // If true, scans all the processes to find `process_cmdline` and filter by
+ // `min_anonymous_memory_kb` only at data source start. Default on Android
+ // S-.
+ //
+ // If false, rescans all the processes to find on every dump. Default on
+ // Android T+.
+ optional bool scan_pids_only_on_start = 3;
}
- // This input is normalized in the following way: if it contains slashes,
- // everything up to the last slash is discarded. If it contains "@",
- // everything after the first @ is discared.
- // E.g. /system/bin/surfaceflinger@1.0 normalizes to surfaceflinger.
- // This transformation is also applied to the processes' command lines when
- // matching.
+ // Command line allowlist, matched against the /proc/<pid>/cmdline (not the
+ // comm string). The semantics of this field were changed since its original
+ // introduction.
+ //
+ // On Android T+ (13+), this field can specify a single wildcard (*), and
+ // the profiler will attempt to match it in two possible ways:
+ // * if the pattern starts with a '/', then it is matched against the first
+ // segment of the cmdline (i.e. argv0). For example "/bin/e*" would match
+ // "/bin/echo".
+ // * otherwise the pattern is matched against the part of argv0
+ // corresponding to the binary name (this is unrelated to /proc/pid/exe).
+ // For example "echo" would match "/bin/echo".
+ //
+ // On Android S (12) and below, both this pattern and /proc/pid/cmdline get
+ // normalized prior to an exact string comparison. Normalization is as
+ // follows: (1) trim everything beyond the first null or "@" byte; (2) if
+ // the string contains forward slashes, trim everything up to and including
+ // the last one.
+ //
+ // Implementation note: in either case, at most 511 characters of cmdline
+ // are considered.
repeated string process_cmdline = 1;
// For watermark based triggering or local debugging.
@@ -804,6 +933,7 @@ message JavaHprofConfig {
// Begin of protos/perfetto/common/perf_events.proto
+// Next id: 12
message PerfEvents {
// What event to sample on, and how often. Commented from the perspective of
// its use in |PerfEventConfig|.
@@ -833,17 +963,72 @@ message PerfEvents {
oneof event {
Counter counter = 4;
Tracepoint tracepoint = 3;
+ RawEvent raw_event = 5;
}
+
+ // If set, samples will be timestamped with the given clock.
+ // If unset, the clock is chosen by the implementation.
+ // For software events, prefer PERF_CLOCK_BOOTTIME. However it cannot be
+ // used for hardware events (due to interrupt safety), for which the
+ // recommendation is to use one of the monotonic clocks.
+ optional PerfClock timestamp_clock = 11;
+
+ // Optional arbitrary name for the event, to identify it in the parsed
+ // trace. Does *not* affect the profiling itself. If unset, the trace
+ // parser will choose a suitable name.
+ optional string name = 10;
}
+ // Builtin counter names from the uapi header. Commented with their perf tool
+ // aliases.
+ // TODO(rsavitski): consider generating enums for cache events (should be
+ // finite), and generally make this list as extensive as possible. Excluding
+ // things like dynamic PMUs since those don't fit into a static enum.
+ // Next id: 21
enum Counter {
UNKNOWN_COUNTER = 0;
- // software:
+
+ // cpu-clock
SW_CPU_CLOCK = 1;
+ // page-faults, faults
SW_PAGE_FAULTS = 2;
- // hardware:
+ // task-clock
+ SW_TASK_CLOCK = 3;
+ // context-switches, cs
+ SW_CONTEXT_SWITCHES = 4;
+ // cpu-migrations, migrations
+ SW_CPU_MIGRATIONS = 5;
+ // minor-faults
+ SW_PAGE_FAULTS_MIN = 6;
+ // major-faults
+ SW_PAGE_FAULTS_MAJ = 7;
+ // alignment-faults
+ SW_ALIGNMENT_FAULTS = 8;
+ // emulation-faults
+ SW_EMULATION_FAULTS = 9;
+ // dummy
+ SW_DUMMY = 20;
+
+ // cpu-cycles, cycles
HW_CPU_CYCLES = 10;
+ // instructions
HW_INSTRUCTIONS = 11;
+ // cache-references
+ HW_CACHE_REFERENCES = 12;
+ // cache-misses
+ HW_CACHE_MISSES = 13;
+ // branch-instructions, branches
+ HW_BRANCH_INSTRUCTIONS = 14;
+ // branch-misses
+ HW_BRANCH_MISSES = 15;
+ // bus-cycles
+ HW_BUS_CYCLES = 16;
+ // stalled-cycles-frontend, idle-cycles-frontend
+ HW_STALLED_CYCLES_FRONTEND = 17;
+ // stalled-cycles-backend, idle-cycles-backend
+ HW_STALLED_CYCLES_BACKEND = 18;
+ // ref-cycles
+ HW_REF_CPU_CYCLES = 19;
}
message Tracepoint {
@@ -859,6 +1044,27 @@ message PerfEvents {
// https://www.kernel.org/doc/Documentation/trace/events.txt
optional string filter = 2;
}
+
+ // Syscall-level description of the event, propagated to the perf_event_attr
+ // struct. Primarily for local use-cases, since the event availability and
+ // encoding is hardware-specific.
+ message RawEvent {
+ optional uint32 type = 1;
+ optional uint64 config = 2;
+ optional uint64 config1 = 3;
+ optional uint64 config2 = 4;
+ }
+
+ // Subset of clocks that is supported by perf timestamping.
+ // CLOCK_TAI is excluded since it's not expected to be used in practice, but
+ // would require additions to the trace clock synchronisation logic.
+ enum PerfClock {
+ UNKNOWN_PERF_CLOCK = 0;
+ PERF_CLOCK_REALTIME = 1;
+ PERF_CLOCK_MONOTONIC = 2;
+ PERF_CLOCK_MONOTONIC_RAW = 3;
+ PERF_CLOCK_BOOTTIME = 4;
+ }
}
// End of protos/perfetto/common/perf_events.proto
@@ -939,6 +1145,14 @@ message PerfEventConfig {
// If unset, the cached state will not be cleared.
optional uint32 unwind_state_clear_period_ms = 10;
+ // If set, only profile target if it was installed by a package with one of
+ // these names. Special values:
+ // * "@system": installed on the system partition
+ // * "@product": installed on the product partition
+ // * "@null": sideloaded
+ // Supported on Android 12+.
+ repeated string target_installed_by = 18;
+
//
// Deprecated (superseded by options above):
//
@@ -952,14 +1166,6 @@ message PerfEventConfig {
optional bool kernel_frames = 12;
repeated int32 target_pid = 4;
repeated string target_cmdline = 5;
-
- // Only profile target if it was installed by one of the packages given.
- // Special values are:
- // * @system: installed on the system partition
- // * @product: installed on the product partition
- // * @null: sideloaded
- // Supported on Android 12+.
- repeated string target_installed_by = 18;
repeated int32 exclude_pid = 6;
repeated string exclude_cmdline = 7;
optional uint32 additional_cmdline_count = 11;
@@ -993,18 +1199,34 @@ message PerfEventConfig {
// process.
repeated int32 target_pid = 1;
- // Command line allowlist, matched against the
- // /proc/<pid>/cmdline (not the comm string), with both sides being
- // "normalized". Normalization is as follows: (1) trim everything beyond the
- // first null or "@" byte; (2) if the string contains forward slashes, trim
- // everything up to and including the last one.
+ // Command line allowlist, matched against the /proc/<pid>/cmdline (not the
+ // comm string). The semantics of this field were changed since its original
+ // introduction.
+ //
+ // On Android T+ (13+), this field can specify a single wildcard (*), and
+ // the profiler will attempt to match it in two possible ways:
+ // * if the pattern starts with a '/', then it is matched against the first
+ // segment of the cmdline (i.e. argv0). For example "/bin/e*" would match
+ // "/bin/echo".
+ // * otherwise the pattern is matched against the part of argv0
+ // corresponding to the binary name (this is unrelated to /proc/pid/exe).
+ // For example "echo" would match "/bin/echo".
+ //
+ // On Android S (12) and below, both this pattern and /proc/pid/cmdline get
+ // normalized prior to an exact string comparison. Normalization is as
+ // follows: (1) trim everything beyond the first null or "@" byte; (2) if
+ // the string contains forward slashes, trim everything up to and including
+ // the last one.
+ //
+ // Implementation note: in either case, at most 511 characters of cmdline
+ // are considered.
repeated string target_cmdline = 2;
// List of excluded pids.
repeated int32 exclude_pid = 3;
- // List of excluded cmdlines. Normalized in the same way as
- // |target_cmdline|.
+ // List of excluded cmdlines. See description of |target_cmdline| for how
+ // this is handled.
repeated string exclude_cmdline = 4;
// Number of additional command lines to sample. Only those which are
@@ -1238,6 +1460,10 @@ message SysStatsConfig {
// This option can be used to record unchanging values.
// Updates from frequency changes can come from ftrace/set_clock_rate.
optional uint32 devfreq_period_ms = 7;
+
+ // Polls /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_cur_freq every X ms.
+ // This is required to be > 10ms to avoid excessive CPU usage.
+ optional uint32 cpufreq_period_ms = 8;
}
// End of protos/perfetto/config/sys_stats/sys_stats_config.proto
@@ -1333,11 +1559,28 @@ message TrackEventConfig {
// Default: []
repeated string enabled_categories = 2;
- // Default: [“slowâ€, “debugâ€]
+ // Default: ["slow", "debug"]
repeated string disabled_tags = 3;
// Default: []
repeated string enabled_tags = 4;
+
+ // Default: false (i.e. enabled by default)
+ optional bool disable_incremental_timestamps = 5;
+
+ // Allows to specify a custom unit different than the default (ns).
+ // A multiplier of 1000 means that a timestamp = 3 should be interpreted as
+ // 3000 ns = 3 us.
+ // Default: 1 (if unset, it should be read as 1).
+ // For now, this multiplier only affects incremental timestamps.
+ // Note: This isn't supported in the SDK yet. It will be supported soon.
+ optional uint64 timestamp_unit_multipler = 6;
+
+ // Default: false (i.e. debug_annotations is NOT filtered out by default)
+ // When true, any debug annotations provided as arguments to the
+ // TRACE_EVENT macros are not written into the trace. Typed arguments will
+ // still be emitted even if set to true.
+ optional bool filter_debug_annotations = 7;
}
// End of protos/perfetto/config/track_event/track_event_config.proto
@@ -1474,7 +1717,7 @@ message DataSourceConfig {
// It contains the general config for the logging buffer(s) and the configs for
// all the data source being enabled.
//
-// Next id: 33.
+// Next id: 35.
message TraceConfig {
message BufferConfig {
optional uint32 size_kb = 1;
@@ -1874,10 +2117,77 @@ message TraceConfig {
// provided. The filter is applied at ReadBuffers() time and works both in the
// case of IPC readback and write_into_file. This filter can be generated
// using `tools/proto_filter -s schema.proto -F filter_out.bytes` or
- // `-T filter_out.escaped_string` (for .pbtx).
- // Introduced in Android S. See go/trace-filtering for design.
- message TraceFilter { optional bytes bytecode = 1; }
- optional TraceFilter trace_filter = 32;
+ // `-T filter_out.escaped_string` (for .pbtx). See go/trace-filtering for
+ // design.
+ //
+ // Introduced in Android S, but it was broken (b/195065199). Reintroduced in
+ // Android T with a different field number.
+ message TraceFilter {
+ optional bytes bytecode = 1;
+ }
+ // old field number for trace_filter
+ reserved 32;
+ optional TraceFilter trace_filter = 33;
+
+ // Android-only. Not for general use. If set, reports the trace to the
+ // Android framework. This field is read by perfetto_cmd, rather than the
+ // tracing service. This field must be set when passing the --upload flag to
+ // perfetto_cmd.
+ message AndroidReportConfig {
+ // In this message, either:
+ // * |reporter_service_package| and |reporter_service_class| must be set.
+ // * |skip_reporting| must be explicitly set to true.
+
+ optional string reporter_service_package = 1;
+ optional string reporter_service_class = 2;
+
+ // If true, then skips reporting the trace to Android framework.
+ //
+ // This flag is useful in testing (e.g. Perfetto-statsd integration tests)
+ // or when we explicitly don't want to report traces to the framework even
+ // when they usually would (e.g. configs deployed using statsd but only
+ // used for inclusion in bugreports using |bugreport_score|).
+ //
+ // The motivation for having this flag, instead of just not setting
+ // |framework_report_config|, is prevent accidents where
+ // |framework_report_config| is omitted by mistake.
+ optional bool skip_report = 3;
+
+ // If true, will direct the Android framework to read the data in trace
+ // file and pass it to the reporter class over a pipe instead of passing
+ // the file descriptor directly.
+ //
+ // This flag is needed because the Android test framework does not
+ // currently support priv-app helper apps (in terms of SELinux) and we
+ // really don't want to add an allow rule for untrusted_app to receive
+ // trace fds.
+ //
+ // Because of this, we instead will direct the framework to create a new
+ // pipe and pass this to the reporter process instead. As the pipe is
+ // created by the framework, we won't have any problems with SELinux
+ // (system_server is already allowed to pass pipe fds, even
+ // to untrusted apps).
+ //
+ // As the name suggests this option *MUST* only be used for testing.
+ // Note that the framework will reject (and drop) files which are too
+ // large both for simplicity and to be minimize the amount of data we
+ // pass to a non-priv app (note that the framework will still check
+ // manifest permissions even though SELinux permissions are worked around).
+ optional bool use_pipe_in_framework_for_testing = 4;
+ }
+ optional AndroidReportConfig android_report_config = 34;
+
+ // If set, delays the start of tracing by a random duration. The duration is
+ // chosen from a uniform distribution between the specified minimum and
+ // maximum.
+ // Note: this delay is implemented by perfetto_cmd *not* by traced so will
+ // not work if you communicate with traced directly over the consumer API.
+ // Introduced in Android T.
+ message CmdTraceStartDelay {
+ optional uint32 min_delay_ms = 1;
+ optional uint32 max_delay_ms = 2;
+ }
+ optional CmdTraceStartDelay cmd_trace_start_delay = 35;
}
// End of protos/perfetto/config/trace_config.proto
@@ -1886,7 +2196,7 @@ message TraceConfig {
// Statistics for the internals of the tracing service.
//
-// Next id: 11.
+// Next id: 16.
message TraceStats {
// From TraceBuffer::Stats.
//
@@ -2033,6 +2343,25 @@ message TraceStats {
optional uint64 errors = 4;
}
optional FilterStats filter_stats = 11;
+
+ // Count of Flush() requests (either from the Consumer, or self-induced
+ // periodic flushes). The final Flush() is also included in the count.
+ optional uint64 flushes_requested = 12;
+
+ // The count of the Flush() requests that were completed successfully.
+ // In a well behaving trace this should always be == `flush_requests`.
+ optional uint64 flushes_succeeded = 13;
+
+ // The count of the Flush() requests that failed (in most timed out).
+ // In a well behaving trace this should always be == 0.
+ optional uint64 flushes_failed = 14;
+
+ enum FinalFlushOutcome {
+ FINAL_FLUSH_UNSPECIFIED = 0;
+ FINAL_FLUSH_SUCCEEDED = 1;
+ FINAL_FLUSH_FAILED = 2;
+ }
+ optional FinalFlushOutcome final_flush_outcome = 15;
}
// End of protos/perfetto/common/trace_stats.proto
@@ -2098,6 +2427,152 @@ message AndroidLogPacket {
// End of protos/perfetto/trace/android/android_log.proto
+// Begin of protos/perfetto/trace/android/camera_event.proto
+
+// A profiling event corresponding to a single camera frame. This message
+// collects important details and timestamps involved in producing a single
+// camera frame.
+// Next ID: 17
+message AndroidCameraFrameEvent {
+ // Identifier for the CameraCaptureSession this frame originates from. See:
+ // https://developer.android.com/reference/android/hardware/camera2/CameraCaptureSession
+ optional uint64 session_id = 1;
+ // Identifier for the camera sensor that is the source of this frame. This may
+ // be either a physical or logical camera (up to vendor interpretation).
+ optional uint32 camera_id = 2;
+ // The frame number identifying this frame on this camera.
+ optional int64 frame_number = 3;
+ // Identifier for the CaptureRequest. See:
+ // https://developer.android.com/reference/android/hardware/camera2/CaptureRequest
+ //
+ // If multiple cameras are streaming simultaneously, the request_id may be
+ // used to identify which frames were captured in service of the same request.
+ optional int64 request_id = 4;
+
+ // The CLOCK_BOOTTIME timestamp at which the camera framework request is
+ // received by the camera HAL pipeline. Note that this request may wait for
+ // some time before processing actually begins. See also
+ // request_processing_started_ns.
+ optional int64 request_received_ns = 5;
+ // The CLOCK_BOOTTIME timestamp at which the framework request is accepted for
+ // processing by the camera HAL pipeline. This is the time at which the
+ // pipeline actually begins to work on the request.
+ optional int64 request_processing_started_ns = 6;
+
+ // The CLOCK_BOOTTIME timestamp at which the sensor begins its exposure.
+ optional int64 start_of_exposure_ns = 7;
+ // The CLOCK_BOOTTIME timestamp corresponding to the sensor start of frame
+ // event.
+ optional int64 start_of_frame_ns = 8;
+ // The CLOCK_BOOTTIME timestamp at which the camera HAL has sent all responses
+ // for the frame.
+ optional int64 responses_all_sent_ns = 9;
+
+ // The error status, if any, reported to the camera framework. Any status
+ // other than STATUS_OK indicates a dropped frame.
+ // Next Enum: 6
+ enum CaptureResultStatus {
+ STATUS_UNSPECIFIED = 0;
+ STATUS_OK = 1;
+ // Early metadata was returned to the camera framework with an error.
+ STATUS_EARLY_METADATA_ERROR = 2;
+ // Final metadata was returned to the camera framework with an error.
+ STATUS_FINAL_METADATA_ERROR = 3;
+ // One or more buffers were returned to the camera framework with an error.
+ STATUS_BUFFER_ERROR = 4;
+ // The frame was dropped as a result of a flush operation.
+ STATUS_FLUSH_ERROR = 5;
+ }
+ optional CaptureResultStatus capture_result_status = 10;
+
+ // The number of sensor frames that were skipped between this frame and the
+ // previous frame. Under normal operation, this should be zero. Any number
+ // greater than zero indicates dropped sensor frames.
+ optional int32 skipped_sensor_frames = 11;
+
+ // The value of CONTROL_CAPTURE_INTENT. See:
+ // https://developer.android.com/reference/android/hardware/camera2/CaptureRequest#CONTROL_CAPTURE_INTENT
+ optional int32 capture_intent = 12;
+ // The number of streams in the capture request.
+ optional int32 num_streams = 13;
+
+ // A profiling event corresponding to a single node processing within the camera
+ // pipeline. Intuitively this corresponds to a single stage of processing to
+ // produce a camera frame.
+ // Next ID: 6
+ message CameraNodeProcessingDetails {
+ optional int64 node_id = 1;
+ // The timestamp at which node processing begins to run.
+ optional int64 start_processing_ns = 2;
+ // The timestamp at which node processing finishes running.
+ optional int64 end_processing_ns = 3;
+ // The delay between inputs becoming ready and the node actually beginning to
+ // run.
+ optional int64 scheduling_latency_ns = 4;
+ }
+ repeated CameraNodeProcessingDetails node_processing_details = 14;
+
+ // These fields capture vendor-specific additions to this proto message. In
+ // practice `vendor_data` typically contains a serialized message of the
+ // vendor's design, and `vendor_data_version` is incremented each time there
+ // is a backwards incompatible change made to the message.
+ optional int32 vendor_data_version = 15;
+ optional bytes vendor_data = 16;
+}
+
+// A profiling event that may be emitted periodically (i.e., at a slower rate
+// than `AndroidCameraFrameEvent`s) to record fixed and aggregated camera
+// session-specific values.
+message AndroidCameraSessionStats {
+ // Identifier for the CameraCaptureSession this frame originates from. See:
+ // https://developer.android.com/reference/android/hardware/camera2/CameraCaptureSession
+ optional uint64 session_id = 1;
+
+ // Although vendor implementations may vary, camera pipeline processing is
+ // typically arranged into a directed graph-like structure. This message is
+ // used to record that graph.
+ message CameraGraph {
+ message CameraNode {
+ optional int64 node_id = 1;
+ // A list of inputs consumed by this node.
+ repeated int64 input_ids = 2;
+ // A list of outputs produced by this node.
+ repeated int64 output_ids = 3;
+
+ // These fields capture vendor-specific additions to this proto message. In
+ // practice `vendor_data` typically contains a serialized message of the
+ // vendor's design, and `vendor_data_version` is incremented each time there
+ // is a backwards incompatible change made to the message.
+ optional int32 vendor_data_version = 4;
+ optional bytes vendor_data = 5;
+ }
+ repeated CameraNode nodes = 1;
+
+ // An adjacency list describing connections between CameraNodes, mapping
+ // nodes and their outputs to other nodes that consume them as inputs.
+ message CameraEdge {
+ // The pair of IDs identifying the node and output connected by this edge.
+ optional int64 output_node_id = 1;
+ optional int64 output_id = 2;
+
+ // The pair of IDs identifying the node and input connected by this edge.
+ optional int64 input_node_id = 3;
+ optional int64 input_id = 4;
+
+ // These fields capture vendor-specific additions to this proto message. In
+ // practice `vendor_data` typically contains a serialized message of the
+ // vendor's design, and `vendor_data_version` is incremented each time there
+ // is a backwards incompatible change made to the message.
+ optional int32 vendor_data_version = 5;
+ optional bytes vendor_data = 6;
+ }
+ repeated CameraEdge edges = 2;
+ }
+ optional CameraGraph graph = 2;
+}
+
+// End of protos/perfetto/trace/android/camera_event.proto
+
// Begin of protos/perfetto/trace/android/frame_timeline_event.proto
// Generated by SurfaceFlinger's FrameTimeline (go/adaptive-scheduling-fr).
@@ -2889,6 +3364,7 @@ message BinderTransactionAllocBufFtraceEvent {
optional uint64 data_size = 1;
optional int32 debug_id = 2;
optional uint64 offsets_size = 3;
+ optional uint64 extra_buffers_size = 4;
}
// End of protos/perfetto/trace/ftrace/binder.proto
@@ -2977,6 +3453,7 @@ message BlockRqCompleteFtraceEvent {
optional int32 errors = 4;
optional string rwbs = 5;
optional string cmd = 6;
+ optional int32 error = 7;
}
message BlockRqInsertFtraceEvent {
optional uint64 dev = 1;
@@ -3038,11 +3515,15 @@ message CgroupAttachTaskFtraceEvent {
optional int32 pid = 3;
optional string comm = 4;
optional string cname = 5;
+ optional int32 dst_level = 6;
+ optional string dst_path = 7;
}
message CgroupMkdirFtraceEvent {
optional int32 root = 1;
optional int32 id = 2;
optional string cname = 3;
+ optional int32 level = 4;
+ optional string path = 5;
}
message CgroupRemountFtraceEvent {
optional int32 root = 1;
@@ -3053,6 +3534,8 @@ message CgroupRmdirFtraceEvent {
optional int32 root = 1;
optional int32 id = 2;
optional string cname = 3;
+ optional int32 level = 4;
+ optional string path = 5;
}
message CgroupTransferTasksFtraceEvent {
optional int32 dst_root = 1;
@@ -3060,6 +3543,8 @@ message CgroupTransferTasksFtraceEvent {
optional int32 pid = 3;
optional string comm = 4;
optional string cname = 5;
+ optional int32 dst_level = 6;
+ optional string dst_path = 7;
}
message CgroupDestroyRootFtraceEvent {
optional int32 root = 1;
@@ -3070,11 +3555,15 @@ message CgroupReleaseFtraceEvent {
optional int32 root = 1;
optional int32 id = 2;
optional string cname = 3;
+ optional int32 level = 4;
+ optional string path = 5;
}
message CgroupRenameFtraceEvent {
optional int32 root = 1;
optional int32 id = 2;
optional string cname = 3;
+ optional int32 level = 4;
+ optional string path = 5;
}
message CgroupSetupRootFtraceEvent {
optional int32 root = 1;
@@ -3165,6 +3654,7 @@ message MmCompactionKcompactdWakeFtraceEvent {
optional int32 nid = 1;
optional int32 order = 2;
optional uint32 classzone_idx = 3;
+ optional uint32 highest_zoneidx = 4;
}
message MmCompactionMigratepagesFtraceEvent {
optional uint64 nr_migrated = 1;
@@ -3180,11 +3670,13 @@ message MmCompactionTryToCompactPagesFtraceEvent {
optional int32 order = 1;
optional uint32 gfp_mask = 2;
optional uint32 mode = 3;
+ optional int32 prio = 4;
}
message MmCompactionWakeupKcompactdFtraceEvent {
optional int32 nid = 1;
optional int32 order = 2;
optional uint32 classzone_idx = 3;
+ optional uint32 highest_zoneidx = 4;
}
// End of protos/perfetto/trace/ftrace/compaction.proto
@@ -3224,6 +3716,54 @@ message CpuhpPauseFtraceEvent {
// End of protos/perfetto/trace/ftrace/cpuhp.proto
+// Begin of protos/perfetto/trace/ftrace/cros_ec.proto
+
+message CrosEcSensorhubDataFtraceEvent {
+ optional int64 current_time = 1;
+ optional int64 current_timestamp = 2;
+ optional int64 delta = 3;
+ optional uint32 ec_fifo_timestamp = 4;
+ optional uint32 ec_sensor_num = 5;
+ optional int64 fifo_timestamp = 6;
+}
+
+// End of protos/perfetto/trace/ftrace/cros_ec.proto
+
+// Begin of protos/perfetto/trace/ftrace/dma_fence.proto
+
+message DmaFenceInitFtraceEvent {
+ optional uint32 context = 1;
+ optional string driver = 2;
+ optional uint32 seqno = 3;
+ optional string timeline = 4;
+}
+message DmaFenceEmitFtraceEvent {
+ optional uint32 context = 1;
+ optional string driver = 2;
+ optional uint32 seqno = 3;
+ optional string timeline = 4;
+}
+message DmaFenceSignaledFtraceEvent {
+ optional uint32 context = 1;
+ optional string driver = 2;
+ optional uint32 seqno = 3;
+ optional string timeline = 4;
+}
+message DmaFenceWaitStartFtraceEvent {
+ optional uint32 context = 1;
+ optional string driver = 2;
+ optional uint32 seqno = 3;
+ optional string timeline = 4;
+}
+message DmaFenceWaitEndFtraceEvent {
+ optional uint32 context = 1;
+ optional string driver = 2;
+ optional uint32 seqno = 3;
+ optional string timeline = 4;
+}
+
+// End of protos/perfetto/trace/ftrace/dma_fence.proto
+
// Begin of protos/perfetto/trace/ftrace/dmabuf_heap.proto
message DmaHeapStatFtraceEvent {
@@ -3247,6 +3787,22 @@ message DpuTracingMarkWriteFtraceEvent {
// End of protos/perfetto/trace/ftrace/dpu.proto
+// Begin of protos/perfetto/trace/ftrace/drm.proto
+
+message DrmVblankEventFtraceEvent {
+ optional int32 crtc = 1;
+ optional uint32 high_prec = 2;
+ optional uint32 seq = 3;
+ optional int64 time = 4;
+}
+message DrmVblankEventDeliveredFtraceEvent {
+ optional int32 crtc = 1;
+ optional uint64 file = 2;
+ optional uint32 seq = 3;
+}
+
+// End of protos/perfetto/trace/ftrace/drm.proto
+
// Begin of protos/perfetto/trace/ftrace/ext4.proto
message Ext4DaWriteBeginFtraceEvent {
@@ -3382,6 +3938,8 @@ message Ext4DiscardBlocksFtraceEvent {
message Ext4DiscardPreallocationsFtraceEvent {
optional uint64 dev = 1;
optional uint64 ino = 2;
+ optional uint32 len = 3;
+ optional uint32 needed = 4;
}
message Ext4DropInodeFtraceEvent {
optional uint64 dev = 1;
@@ -3546,6 +4104,9 @@ message Ext4ExtRemoveSpaceDoneFtraceEvent {
optional int32 depth = 5;
optional int64 partial = 6;
optional uint32 eh_entries = 7;
+ optional uint32 pc_lblk = 8;
+ optional uint64 pc_pclu = 9;
+ optional int32 pc_state = 10;
}
message Ext4ExtRmIdxFtraceEvent {
optional uint64 dev = 1;
@@ -3560,6 +4121,9 @@ message Ext4ExtRmLeafFtraceEvent {
optional uint32 ee_lblk = 5;
optional uint64 ee_pblk = 6;
optional int32 ee_len = 7;
+ optional uint32 pc_lblk = 8;
+ optional uint64 pc_pclu = 9;
+ optional int32 pc_state = 10;
}
message Ext4ExtShowExtentFtraceEvent {
optional uint64 dev = 1;
@@ -3665,6 +4229,7 @@ message Ext4JournalStartFtraceEvent {
optional int32 blocks = 3;
optional int32 rsv_blocks = 4;
optional int32 nblocks = 5;
+ optional int32 revoke_creds = 6;
}
message Ext4JournalStartReservedFtraceEvent {
optional uint64 dev = 1;
@@ -3801,6 +4366,7 @@ message Ext4PunchHoleFtraceEvent {
message Ext4ReadBlockBitmapLoadFtraceEvent {
optional uint64 dev = 1;
optional uint32 group = 2;
+ optional uint32 prefetch = 3;
}
message Ext4ReadpageFtraceEvent {
optional uint64 dev = 1;
@@ -3821,6 +4387,9 @@ message Ext4RemoveBlocksFtraceEvent {
optional uint64 ee_pblk = 6;
optional uint32 ee_lblk = 7;
optional uint32 ee_len = 8;
+ optional uint32 pc_lblk = 9;
+ optional uint64 pc_pclu = 10;
+ optional int32 pc_state = 11;
}
message Ext4RequestBlocksFtraceEvent {
optional uint64 dev = 1;
@@ -3976,6 +4545,7 @@ message F2fsGetVictimFtraceEvent {
optional uint32 pre_victim = 8;
optional uint32 prefree = 9;
optional uint32 free = 10;
+ optional uint32 cost = 11;
}
message F2fsIgetFtraceEvent {
optional uint64 dev = 1;
@@ -4003,6 +4573,9 @@ message F2fsReadpageFtraceEvent {
optional uint64 index = 3;
optional uint64 blkaddr = 4;
optional int32 type = 5;
+ optional int32 dir = 6;
+ optional int32 dirty = 7;
+ optional int32 uptodate = 8;
}
message F2fsReserveNewBlockFtraceEvent {
optional uint64 dev = 1;
@@ -4016,6 +4589,7 @@ message F2fsSetPageDirtyFtraceEvent {
optional int32 dir = 4;
optional uint64 index = 5;
optional int32 dirty = 6;
+ optional int32 uptodate = 7;
}
message F2fsSubmitWritePageFtraceEvent {
optional uint64 dev = 1;
@@ -4040,6 +4614,7 @@ message F2fsSyncFileExitFtraceEvent {
optional uint32 need_cp = 3;
optional int32 datasync = 4;
optional int32 ret = 5;
+ optional int32 cp_reason = 6;
}
message F2fsSyncFsFtraceEvent {
optional uint64 dev = 1;
@@ -4130,6 +4705,7 @@ message F2fsVmPageMkwriteFtraceEvent {
optional int32 dir = 4;
optional uint64 index = 5;
optional int32 dirty = 6;
+ optional int32 uptodate = 7;
}
message F2fsWriteBeginFtraceEvent {
optional uint64 dev = 1;
@@ -4142,6 +4718,7 @@ message F2fsWriteCheckpointFtraceEvent {
optional uint64 dev = 1;
optional uint32 is_umount = 2;
optional string msg = 3;
+ optional int32 reason = 4;
}
message F2fsWriteEndFtraceEvent {
optional uint64 dev = 1;
@@ -4261,6 +4838,30 @@ message GpuMemTotalFtraceEvent {
// End of protos/perfetto/trace/ftrace/gpu_mem.proto
+// Begin of protos/perfetto/trace/ftrace/gpu_scheduler.proto
+
+message DrmSchedJobFtraceEvent {
+ optional uint64 entity = 1;
+ optional uint64 fence = 2;
+ optional int32 hw_job_count = 3;
+ optional uint64 id = 4;
+ optional uint32 job_count = 5;
+ optional string name = 6;
+}
+message DrmRunJobFtraceEvent {
+ optional uint64 entity = 1;
+ optional uint64 fence = 2;
+ optional int32 hw_job_count = 3;
+ optional uint64 id = 4;
+ optional uint32 job_count = 5;
+ optional string name = 6;
+}
+message DrmSchedProcessJobFtraceEvent {
+ optional uint64 fence = 1;
+}
+
+// End of protos/perfetto/trace/ftrace/gpu_scheduler.proto
+
// Begin of protos/perfetto/trace/ftrace/i2c.proto
message I2cReadFtraceEvent {
@@ -4613,6 +5214,174 @@ message IonBufferDestroyFtraceEvent {
// End of protos/perfetto/trace/ftrace/kmem.proto
+// Begin of protos/perfetto/trace/ftrace/kvm.proto
+
+message KvmAccessFaultFtraceEvent {
+ optional uint64 ipa = 1;
+}
+message KvmAckIrqFtraceEvent {
+ optional uint32 irqchip = 1;
+ optional uint32 pin = 2;
+}
+message KvmAgeHvaFtraceEvent {
+ optional uint64 end = 1;
+ optional uint64 start = 2;
+}
+message KvmAgePageFtraceEvent {
+ optional uint64 gfn = 1;
+ optional uint64 hva = 2;
+ optional uint32 level = 3;
+ optional uint32 referenced = 4;
+}
+message KvmArmClearDebugFtraceEvent {
+ optional uint32 guest_debug = 1;
+}
+message KvmArmSetDreg32FtraceEvent {
+ optional string name = 1;
+ optional uint32 value = 2;
+}
+message KvmArmSetRegsetFtraceEvent {
+ optional int32 len = 1;
+ optional string name = 2;
+}
+message KvmArmSetupDebugFtraceEvent {
+ optional uint32 guest_debug = 1;
+ optional uint64 vcpu = 2;
+}
+message KvmEntryFtraceEvent {
+ optional uint64 vcpu_pc = 1;
+}
+message KvmExitFtraceEvent {
+ optional uint32 esr_ec = 1;
+ optional int32 ret = 2;
+ optional uint64 vcpu_pc = 3;
+}
+message KvmFpuFtraceEvent {
+ optional uint32 load = 1;
+}
+message KvmGetTimerMapFtraceEvent {
+ optional int32 direct_ptimer = 1;
+ optional int32 direct_vtimer = 2;
+ optional int32 emul_ptimer = 3;
+ optional uint64 vcpu_id = 4;
+}
+message KvmGuestFaultFtraceEvent {
+ optional uint64 hsr = 1;
+ optional uint64 hxfar = 2;
+ optional uint64 ipa = 3;
+ optional uint64 vcpu_pc = 4;
+}
+message KvmHandleSysRegFtraceEvent {
+ optional uint64 hsr = 1;
+}
+message KvmHvcArm64FtraceEvent {
+ optional uint64 imm = 1;
+ optional uint64 r0 = 2;
+ optional uint64 vcpu_pc = 3;
+}
+message KvmIrqLineFtraceEvent {
+ optional int32 irq_num = 1;
+ optional int32 level = 2;
+ optional uint32 type = 3;
+ optional int32 vcpu_idx = 4;
+}
+message KvmMmioFtraceEvent {
+ optional uint64 gpa = 1;
+ optional uint32 len = 2;
+ optional uint32 type = 3;
+ optional uint64 val = 4;
+}
+message KvmMmioEmulateFtraceEvent {
+ optional uint64 cpsr = 1;
+ optional uint64 instr = 2;
+ optional uint64 vcpu_pc = 3;
+}
+message KvmSetGuestDebugFtraceEvent {
+ optional uint32 guest_debug = 1;
+ optional uint64 vcpu = 2;
+}
+message KvmSetIrqFtraceEvent {
+ optional uint32 gsi = 1;
+ optional int32 irq_source_id = 2;
+ optional int32 level = 3;
+}
+message KvmSetSpteHvaFtraceEvent {
+ optional uint64 hva = 1;
+}
+message KvmSetWayFlushFtraceEvent {
+ optional uint32 cache = 1;
+ optional uint64 vcpu_pc = 2;
+}
+message KvmSysAccessFtraceEvent {
+ optional uint32 CRm = 1;
+ optional uint32 CRn = 2;
+ optional uint32 Op0 = 3;
+ optional uint32 Op1 = 4;
+ optional uint32 Op2 = 5;
+ optional uint32 is_write = 6;
+ optional string name = 7;
+ optional uint64 vcpu_pc = 8;
+}
+message KvmTestAgeHvaFtraceEvent {
+ optional uint64 hva = 1;
+}
+message KvmTimerEmulateFtraceEvent {
+ optional uint32 should_fire = 1;
+ optional int32 timer_idx = 2;
+}
+message KvmTimerHrtimerExpireFtraceEvent {
+ optional int32 timer_idx = 1;
+}
+message KvmTimerRestoreStateFtraceEvent {
+ optional uint64 ctl = 1;
+ optional uint64 cval = 2;
+ optional int32 timer_idx = 3;
+}
+message KvmTimerSaveStateFtraceEvent {
+ optional uint64 ctl = 1;
+ optional uint64 cval = 2;
+ optional int32 timer_idx = 3;
+}
+message KvmTimerUpdateIrqFtraceEvent {
+ optional uint32 irq = 1;
+ optional int32 level = 2;
+ optional uint64 vcpu_id = 3;
+}
+message KvmToggleCacheFtraceEvent {
+ optional uint32 now = 1;
+ optional uint64 vcpu_pc = 2;
+ optional uint32 was = 3;
+}
+message KvmUnmapHvaRangeFtraceEvent {
+ optional uint64 end = 1;
+ optional uint64 start = 2;
+}
+message KvmUserspaceExitFtraceEvent {
+ optional uint32 reason = 1;
+}
+message KvmVcpuWakeupFtraceEvent {
+ optional uint64 ns = 1;
+ optional uint32 valid = 2;
+ optional uint32 waited = 3;
+}
+message KvmWfxArm64FtraceEvent {
+ optional uint32 is_wfe = 1;
+ optional uint64 vcpu_pc = 2;
+}
+message TrapRegFtraceEvent {
+ optional string fn = 1;
+ optional uint32 is_write = 2;
+ optional int32 reg = 3;
+ optional uint64 write_value = 4;
+}
+message VgicUpdateIrqPendingFtraceEvent {
+ optional uint32 irq = 1;
+ optional uint32 level = 2;
+ optional uint64 vcpu_id = 3;
+}
+
+// End of protos/perfetto/trace/ftrace/kvm.proto
+
// Begin of protos/perfetto/trace/ftrace/lowmemorykiller.proto
message LowmemoryKillFtraceEvent {
@@ -4799,6 +5568,46 @@ message MmEventRecordFtraceEvent {
// End of protos/perfetto/trace/ftrace/mm_event.proto
+// Begin of protos/perfetto/trace/ftrace/net.proto
+
+message NetifReceiveSkbFtraceEvent {
+ optional uint32 len = 1;
+ optional string name = 2;
+ optional uint64 skbaddr = 3;
+}
+message NetDevXmitFtraceEvent {
+ optional uint32 len = 1;
+ optional string name = 2;
+ optional int32 rc = 3;
+ optional uint64 skbaddr = 4;
+}
+message NapiGroReceiveEntryFtraceEvent {
+ optional uint32 data_len = 1;
+ optional uint32 gso_size = 2;
+ optional uint32 gso_type = 3;
+ optional uint32 hash = 4;
+ optional uint32 ip_summed = 5;
+ optional uint32 l4_hash = 6;
+ optional uint32 len = 7;
+ optional int32 mac_header = 8;
+ optional uint32 mac_header_valid = 9;
+ optional string name = 10;
+ optional uint32 napi_id = 11;
+ optional uint32 nr_frags = 12;
+ optional uint32 protocol = 13;
+ optional uint32 queue_mapping = 14;
+ optional uint64 skbaddr = 15;
+ optional uint32 truesize = 16;
+ optional uint32 vlan_proto = 17;
+ optional uint32 vlan_tagged = 18;
+ optional uint32 vlan_tci = 19;
+}
+message NapiGroReceiveExitFtraceEvent {
+ optional int32 ret = 1;
+}
+
+// End of protos/perfetto/trace/ftrace/net.proto
+
// Begin of protos/perfetto/trace/ftrace/oom.proto
message OomScoreAdjUpdateFtraceEvent {
@@ -4851,9 +5660,25 @@ message GpuFrequencyFtraceEvent {
optional uint32 gpu_id = 1;
optional uint32 state = 2;
}
+message WakeupSourceActivateFtraceEvent {
+ optional string name = 1;
+ optional uint64 state = 2;
+}
+message WakeupSourceDeactivateFtraceEvent {
+ optional string name = 1;
+ optional uint64 state = 2;
+}
// End of protos/perfetto/trace/ftrace/power.proto
+// Begin of protos/perfetto/trace/ftrace/printk.proto
+
+message ConsoleFtraceEvent {
+ optional string msg = 1;
+}
+
+// End of protos/perfetto/trace/ftrace/printk.proto
+
// Begin of protos/perfetto/trace/ftrace/raw_syscalls.proto
message SysEnterFtraceEvent {
@@ -4984,7 +5809,8 @@ message ScmCallStartFtraceEvent {
optional uint64 x0 = 2;
optional uint64 x5 = 3;
}
-message ScmCallEndFtraceEvent {}
+message ScmCallEndFtraceEvent {
+}
// End of protos/perfetto/trace/ftrace/scm.proto
@@ -5061,6 +5887,32 @@ message SignalGenerateFtraceEvent {
// End of protos/perfetto/trace/ftrace/signal.proto
+// Begin of protos/perfetto/trace/ftrace/skb.proto
+
+message KfreeSkbFtraceEvent {
+ optional uint64 location = 1;
+ optional uint32 protocol = 2;
+ optional uint64 skbaddr = 3;
+}
+
+// End of protos/perfetto/trace/ftrace/skb.proto
+
+// Begin of protos/perfetto/trace/ftrace/sock.proto
+
+message InetSockSetStateFtraceEvent {
+ optional uint32 daddr = 1;
+ optional uint32 dport = 2;
+ optional uint32 family = 3;
+ optional int32 newstate = 4;
+ optional int32 oldstate = 5;
+ optional uint32 protocol = 6;
+ optional uint32 saddr = 7;
+ optional uint64 skaddr = 8;
+ optional uint32 sport = 9;
+}
+
+// End of protos/perfetto/trace/ftrace/sock.proto
+
// Begin of protos/perfetto/trace/ftrace/sync.proto
message SyncPtFtraceEvent {
@@ -5079,6 +5931,17 @@ message SyncWaitFtraceEvent {
// End of protos/perfetto/trace/ftrace/sync.proto
+// Begin of protos/perfetto/trace/ftrace/synthetic.proto
+
+message RssStatThrottledFtraceEvent {
+ optional uint32 curr = 1;
+ optional int32 member = 2;
+ optional uint32 mm_id = 3;
+ optional int64 size = 4;
+}
+
+// End of protos/perfetto/trace/ftrace/synthetic.proto
+
// Begin of protos/perfetto/trace/ftrace/systrace.proto
message ZeroFtraceEvent {
@@ -5107,6 +5970,20 @@ message TaskRenameFtraceEvent {
// End of protos/perfetto/trace/ftrace/task.proto
+// Begin of protos/perfetto/trace/ftrace/tcp.proto
+
+message TcpRetransmitSkbFtraceEvent {
+ optional uint32 daddr = 1;
+ optional uint32 dport = 2;
+ optional uint32 saddr = 3;
+ optional uint64 skaddr = 4;
+ optional uint64 skbaddr = 5;
+ optional uint32 sport = 6;
+ optional int32 state = 7;
+}
+
+// End of protos/perfetto/trace/ftrace/tcp.proto
+
// Begin of protos/perfetto/trace/ftrace/thermal.proto
message ThermalTemperatureFtraceEvent {
@@ -5122,6 +5999,27 @@ message CdevUpdateFtraceEvent {
// End of protos/perfetto/trace/ftrace/thermal.proto
+// Begin of protos/perfetto/trace/ftrace/ufs.proto
+
+message UfshcdCommandFtraceEvent {
+ optional string dev_name = 1;
+ optional uint32 doorbell = 2;
+ optional uint32 intr = 3;
+ optional uint64 lba = 4;
+ optional uint32 opcode = 5;
+ optional string str = 6;
+ optional uint32 tag = 7;
+ optional int32 transfer_len = 8;
+ optional uint32 group_id = 9;
+ optional uint32 str_t = 10;
+}
+message UfshcdClkGatingFtraceEvent {
+ optional string dev_name = 1;
+ optional int32 state = 2;
+}
+
+// End of protos/perfetto/trace/ftrace/ufs.proto
+
// Begin of protos/perfetto/trace/ftrace/vmscan.proto
message MmVmscanDirectReclaimBeginFtraceEvent {
@@ -5135,6 +6033,7 @@ message MmVmscanDirectReclaimEndFtraceEvent {
message MmVmscanKswapdWakeFtraceEvent {
optional int32 nid = 1;
optional int32 order = 2;
+ optional int32 zid = 3;
}
message MmVmscanKswapdSleepFtraceEvent {
optional int32 nid = 1;
@@ -5149,6 +6048,7 @@ message WorkqueueActivateWorkFtraceEvent {
}
message WorkqueueExecuteEndFtraceEvent {
optional uint64 work = 1;
+ optional uint64 function = 2;
}
message WorkqueueExecuteStartFtraceEvent {
optional uint64 work = 1;
@@ -5550,6 +6450,66 @@ message FtraceEvent {
SdeSdePerfCrtcUpdateFtraceEvent sde_sde_perf_crtc_update = 356;
SdeSdePerfSetQosLutsFtraceEvent sde_sde_perf_set_qos_luts = 357;
SdeSdePerfUpdateBusFtraceEvent sde_sde_perf_update_bus = 358;
+ RssStatThrottledFtraceEvent rss_stat_throttled = 359;
+ NetifReceiveSkbFtraceEvent netif_receive_skb = 360;
+ NetDevXmitFtraceEvent net_dev_xmit = 361;
+ InetSockSetStateFtraceEvent inet_sock_set_state = 362;
+ TcpRetransmitSkbFtraceEvent tcp_retransmit_skb = 363;
+ CrosEcSensorhubDataFtraceEvent cros_ec_sensorhub_data = 364;
+ NapiGroReceiveEntryFtraceEvent napi_gro_receive_entry = 365;
+ NapiGroReceiveExitFtraceEvent napi_gro_receive_exit = 366;
+ KfreeSkbFtraceEvent kfree_skb = 367;
+ KvmAccessFaultFtraceEvent kvm_access_fault = 368;
+ KvmAckIrqFtraceEvent kvm_ack_irq = 369;
+ KvmAgeHvaFtraceEvent kvm_age_hva = 370;
+ KvmAgePageFtraceEvent kvm_age_page = 371;
+ KvmArmClearDebugFtraceEvent kvm_arm_clear_debug = 372;
+ KvmArmSetDreg32FtraceEvent kvm_arm_set_dreg32 = 373;
+ KvmArmSetRegsetFtraceEvent kvm_arm_set_regset = 374;
+ KvmArmSetupDebugFtraceEvent kvm_arm_setup_debug = 375;
+ KvmEntryFtraceEvent kvm_entry = 376;
+ KvmExitFtraceEvent kvm_exit = 377;
+ KvmFpuFtraceEvent kvm_fpu = 378;
+ KvmGetTimerMapFtraceEvent kvm_get_timer_map = 379;
+ KvmGuestFaultFtraceEvent kvm_guest_fault = 380;
+ KvmHandleSysRegFtraceEvent kvm_handle_sys_reg = 381;
+ KvmHvcArm64FtraceEvent kvm_hvc_arm64 = 382;
+ KvmIrqLineFtraceEvent kvm_irq_line = 383;
+ KvmMmioFtraceEvent kvm_mmio = 384;
+ KvmMmioEmulateFtraceEvent kvm_mmio_emulate = 385;
+ KvmSetGuestDebugFtraceEvent kvm_set_guest_debug = 386;
+ KvmSetIrqFtraceEvent kvm_set_irq = 387;
+ KvmSetSpteHvaFtraceEvent kvm_set_spte_hva = 388;
+ KvmSetWayFlushFtraceEvent kvm_set_way_flush = 389;
+ KvmSysAccessFtraceEvent kvm_sys_access = 390;
+ KvmTestAgeHvaFtraceEvent kvm_test_age_hva = 391;
+ KvmTimerEmulateFtraceEvent kvm_timer_emulate = 392;
+ KvmTimerHrtimerExpireFtraceEvent kvm_timer_hrtimer_expire = 393;
+ KvmTimerRestoreStateFtraceEvent kvm_timer_restore_state = 394;
+ KvmTimerSaveStateFtraceEvent kvm_timer_save_state = 395;
+ KvmTimerUpdateIrqFtraceEvent kvm_timer_update_irq = 396;
+ KvmToggleCacheFtraceEvent kvm_toggle_cache = 397;
+ KvmUnmapHvaRangeFtraceEvent kvm_unmap_hva_range = 398;
+ KvmUserspaceExitFtraceEvent kvm_userspace_exit = 399;
+ KvmVcpuWakeupFtraceEvent kvm_vcpu_wakeup = 400;
+ KvmWfxArm64FtraceEvent kvm_wfx_arm64 = 401;
+ TrapRegFtraceEvent trap_reg = 402;
+ VgicUpdateIrqPendingFtraceEvent vgic_update_irq_pending = 403;
+ WakeupSourceActivateFtraceEvent wakeup_source_activate = 404;
+ WakeupSourceDeactivateFtraceEvent wakeup_source_deactivate = 405;
+ UfshcdCommandFtraceEvent ufshcd_command = 406;
+ UfshcdClkGatingFtraceEvent ufshcd_clk_gating = 407;
+ ConsoleFtraceEvent console = 408;
+ DrmVblankEventFtraceEvent drm_vblank_event = 409;
+ DrmVblankEventDeliveredFtraceEvent drm_vblank_event_delivered = 410;
+ DrmSchedJobFtraceEvent drm_sched_job = 411;
+ DrmRunJobFtraceEvent drm_run_job = 412;
+ DrmSchedProcessJobFtraceEvent drm_sched_process_job = 413;
+ DmaFenceInitFtraceEvent dma_fence_init = 414;
+ DmaFenceEmitFtraceEvent dma_fence_emit = 415;
+ DmaFenceSignaledFtraceEvent dma_fence_signaled = 416;
+ DmaFenceWaitStartFtraceEvent dma_fence_wait_start = 417;
+ DmaFenceWaitEndFtraceEvent dma_fence_wait_end = 418;
}
}
@@ -5563,6 +6523,7 @@ message FtraceEvent {
message FtraceEventBundle {
optional uint32 cpu = 1;
repeated FtraceEvent event = 2;
+
// Set to true if there was data loss between the last time we've read from
// the corresponding per-cpu kernel buffer, and the earliest event recorded
// in this bundle.
@@ -5599,6 +6560,47 @@ message FtraceEventBundle {
repeated uint32 waking_comm_index = 11 [packed = true];
}
optional CompactSched compact_sched = 4;
+
+ // traced_probes always sets the ftrace_clock to "boot". That is not available
+ // in older kernels (v3.x). In that case we fallback on "global" or "local".
+ // When we do that, we report the fallback clock in each bundle so we can do
+ // proper clock syncing at parsing time in TraceProcessor. We cannot use the
+ // TracePacket timestamp_clock_id because: (1) there is no per-packet
+ // timestamp for ftrace bundles; (2) "global" does not match CLOCK_MONOTONIC.
+ // Having a dedicated and explicit flag allows us to correct further misakes
+ // in future by looking at the kernel version.
+ // This field has been introduced in perfetto v19 / Android T (13).
+ // This field is omitted when the ftrace clock is just "boot", as that is the
+ // default assumption (and for consistency with the past).
+ optional FtraceClock ftrace_clock = 5;
+
+ // The timestamp according to the ftrace clock, taken at the same instant
+ // as |boot_timestamp|. This is used to sync ftrace events when a non-boot
+ // clock is used as the ftrace clock. We don't use the ClockSnapshot packet
+ // because the ftrace global/local clocks don't match any of the clock_gettime
+ // domains and can be only read by traced_probes.
+ //
+ // Only set when |ftrace_clock| != FTRACE_CLOCK_UNSPECIFIED.
+ //
+ // Implementation note: Populated by reading the 'now ts:' field in
+ // tracefs/per_cpu/cpuX/stat.
+ optional int64 ftrace_timestamp = 6;
+
+ // The timestamp according to CLOCK_BOOTTIME, taken at the same instant as
+ // |ftrace_timestamp|. See documentation of |ftrace_timestamp| for
+ // more info.
+ //
+ // Only set when |ftrace_clock| != FTRACE_CLOCK_UNSPECIFIED.
+ optional int64 boot_timestamp = 7;
+}
+
+enum FtraceClock {
+ // There is no FTRACE_CLOCK_BOOT entry as that's the default assumption. When
+ // the ftrace clock is "boot", it's just omitted (so UNSPECIFIED == BOOT).
+ FTRACE_CLOCK_UNSPECIFIED = 0;
+ FTRACE_CLOCK_UNKNOWN = 1;
+ FTRACE_CLOCK_GLOBAL = 2;
+ FTRACE_CLOCK_LOCAL = 3;
}
// End of protos/perfetto/trace/ftrace/ftrace_event_bundle.proto
@@ -5667,6 +6669,18 @@ message FtraceStats {
// The memory used by the kernel symbolizer (KernelSymbolMap.size_bytes()).
optional uint32 kernel_symbols_mem_kb = 4;
+
+ // Atrace errors (even non-fatal ones) are reported here. A typical example is
+ // one or more atrace categories not available on the device.
+ optional string atrace_errors = 5;
+
+ // Ftrace events requested by the config but not present on device.
+ repeated string unknown_ftrace_events = 6;
+
+ // Ftrace events requested by the config and present on device, but which we
+ // failed to enable due to permissions, or due to a conflicting option
+ // (currently FtraceConfig.disable_generic_events).
+ repeated string failed_ftrace_events = 7;
}
// End of protos/perfetto/trace/ftrace/ftrace_stats.proto
@@ -6169,7 +7183,8 @@ message ChromeHistogramSample {
// }
// }
//
-// Next ID: 13.
+// Next ID: 17.
+// Reserved ID: 15
message DebugAnnotation {
// Name fields are set only for dictionary entries.
oneof name_field {
@@ -6197,6 +7212,18 @@ message DebugAnnotation {
string legacy_json_value = 9;
}
+ // Used to embed arbitrary proto messages (which are also typically used to
+ // represent typed TrackEvent arguments). |proto_type_name| or
+ // |proto_type_name_iid| are storing the full name of the proto messages (e.g.
+ // .perfetto.protos.DebugAnnotation) and |proto_value| contains the serialised
+ // proto messages. See |TracedValue::WriteProto| for more details.
+ oneof proto_type_descriptor {
+ string proto_type_name = 16;
+ // interned DebugAnnotationValueTypeName.
+ uint64 proto_type_name_iid = 13;
+ }
+ optional bytes proto_value = 14;
+
repeated DebugAnnotation dict_entries = 11;
repeated DebugAnnotation array_values = 12;
@@ -6231,6 +7258,12 @@ message DebugAnnotationName {
optional string name = 2;
}
+// See the |proto_type_descriptor| comment.
+message DebugAnnotationValueTypeName {
+ optional uint64 iid = 1;
+ optional string name = 2;
+}
+
// End of protos/perfetto/trace/track_event/debug_annotation.proto
// Begin of protos/perfetto/trace/track_event/log_message.proto
@@ -6301,7 +7334,8 @@ message ChromeApplicationStateInfo {
// The original format was generated in JSON by the code at
// https://cs.chromium.org/chromium/src/cc/scheduler/scheduler.cc?l=870&rcl=5e15eabc9c0eec8daf94fdf78e93f13b6e3b63dd
//
-// TODO(nuskos): Update link once we've switched to writing this proto.
+// And is now generated as protozero:
+// https://cs.chromium.org/chromium/src/cc/scheduler/scheduler.cc?q=Scheduler::AsPro
//
// All non-delta-timestamps are absolute CLOCK_MONOTONIC timestamps.
@@ -6337,7 +7371,6 @@ message ChromeCompositorSchedulerState {
optional bool begin_impl_frame_deadline_task = 3;
optional bool pending_begin_frame_task = 4;
optional bool skipped_last_frame_missed_exceeded_deadline = 5;
- optional bool skipped_last_frame_to_reduce_latency = 6;
optional ChromeCompositorSchedulerAction inside_action = 7;
optional BeginImplFrameDeadlineMode deadline_mode = 8;
optional int64 deadline_us = 9;
@@ -6349,6 +7382,8 @@ message ChromeCompositorSchedulerState {
optional BeginFrameObserverState begin_frame_observer_state = 15;
optional BeginFrameSourceState begin_frame_source_state = 16;
optional CompositorTimingHistory compositor_timing_history = 17;
+
+ reserved 6;
}
// Describes the current values stored in the Chrome Compositor state machine.
@@ -6438,7 +7473,6 @@ message ChromeCompositorStateMachine {
optional ScrollHandlerState scroll_handler_state = 32;
optional bool critical_begin_main_frame_to_activate_is_fast = 33;
optional bool main_thread_missed_last_deadline = 34;
- optional bool skip_next_begin_main_frame_to_reduce_latency = 35;
optional bool video_needs_begin_frames = 36;
optional bool defer_begin_main_frame = 37;
optional bool last_commit_had_no_updates = 38;
@@ -6450,11 +7484,13 @@ message ChromeCompositorStateMachine {
optional bool processing_animation_worklets_for_active_tree = 44;
optional bool processing_animation_worklets_for_pending_tree = 45;
optional bool processing_paint_worklets_for_pending_tree = 46;
+
+ reserved 35;
}
optional MinorState minor_state = 2;
}
-// Next id: 12
+// Next id: 13
message BeginFrameArgs {
// JSON format has a "type" field that was always just "BeginFrameArgs" we
// drop this in the proto representation, and instead make the JSON format
@@ -6483,6 +7519,7 @@ message BeginFrameArgs {
// remove this |source_location|.
SourceLocation source_location = 10;
}
+ optional int64 frames_throttled_since_last = 12;
}
// Next id: 7
@@ -6606,11 +7643,11 @@ message ChromeFrameReporter {
SCROLL_MAIN_THREAD = 1;
SCROLL_COMPOSITOR_THREAD = 2;
- // Used when it can't be determined wheter a scroll is in progress or not.
+ // Used when it can't be determined whether a scroll is in progress or not.
SCROLL_UNKNOWN = 3;
}
- // The type of active scroll
+ // The type of active scroll.
optional ScrollState scroll_state = 6;
// If any main thread animation is active during this frame.
@@ -6709,6 +7746,7 @@ message ChromeLatencyInfo {
repeated ComponentInfo component_info = 4;
optional bool is_coalesced = 5;
optional int64 gesture_scroll_id = 6;
+ optional int64 touch_id = 7;
}
// End of protos/perfetto/trace/track_event/chrome_latency_info.proto
@@ -6822,6 +7860,9 @@ enum ChromeRAILMode {
// Next id: 2
message ChromeRendererSchedulerState {
optional ChromeRAILMode rail_mode = 1;
+
+ optional bool is_backgrounded = 2;
+ optional bool is_hidden = 3;
}
// End of protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto
@@ -7274,7 +8315,7 @@ message EventName {
// emitted proactively in advance of referring to them in later packets.
//
// Next reserved id: 8 (up to 15).
-// Next id: 27.
+// Next id: 28.
message InternedData {
// TODO(eseckler): Replace iid fields inside interned messages with
// map<iid, message> type fields in InternedData.
@@ -7289,6 +8330,7 @@ message InternedData {
repeated EventCategory event_categories = 1;
repeated EventName event_names = 2;
repeated DebugAnnotationName debug_annotation_names = 3;
+ repeated DebugAnnotationValueTypeName debug_annotation_value_type_names = 27;
repeated SourceLocation source_locations = 4;
repeated LogMessageBody log_message_body = 20;
repeated HistogramName histogram_names = 25;
@@ -7461,7 +8503,7 @@ message PerfettoMetatrace {
}
// Only when using |event_id|.
- optional uint32 event_duration_ns = 3;
+ optional uint64 event_duration_ns = 3;
// Only when using |counter_id|.
optional int32 counter_value = 4;
@@ -7747,8 +8789,11 @@ message HeapGraphObject {
// Bytes occupied by this objects.
optional uint64 self_size = 3;
- // Add this to all non-zero values in reference_field_id. This is used to
+ // Add this to all non-zero values in reference_object_id. This is used to
// get more compact varint encoding.
+ //
+ // The name is confusing, but this has always been used as a base for
+ // reference_object_id. The field should be named reference_object_id_base.
optional uint64 reference_field_id_base = 6;
// Indices for InternedData.field_names for the name of the field referring
@@ -7759,6 +8804,12 @@ message HeapGraphObject {
// Ids of the Object that is referred to.
repeated uint64 reference_object_id = 5 [packed = true];
+
+ // If this object is an instance of `libcore.util.NativeAllocationRegistry`,
+ // the value of the `size` field.
+ //
+ // N.B. This is not the native size of this object.
+ optional int64 native_allocation_registry_size_field = 8;
}
message HeapGraph {
@@ -7796,6 +8847,58 @@ message HeapGraph {
// Begin of protos/perfetto/trace/profiling/profile_packet.proto
+// This file contains a mixture of messages emitted by various sampling
+// profilers:
+//
+// Memory allocator profiling
+// ----------------
+// ProfilePacket:
+// The packet emitted by heapprofd, which started off as a native heap
+// (malloc/free) profiler, but now supports custom allocators as well. Each
+// packet contains a preaggregated state of the heap at snapshot time, which
+// report the total allocated/free bytes per callstack (plus other info such
+// as the number of samples).
+// StreamingAllocation/StreamingFree:
+// Emitted by heapprofd when configured in streaming mode (i.e. when
+// stream_allocations = true). This is only for local testing, and doesn't
+// report callstacks (only address time and size of each alloc/free). It can
+// lead to enormous traces, as it contains the stream of each alloc/free call.
+//
+// Callstack sampling
+// ------------------
+// StreamingProfilePacket:
+// The packet emitted by the chromium in-process sampling profiler, which is
+// based on periodically sending a signal to itself, and unwinding the stack
+// in the signal handler. Each packet contains a series of individual stack
+// samples for a Chromium thread.
+//
+// Callstack and performance counter sampling
+// ---------------------
+// PerfSample:
+// The packet emitted by traced_perf sampling performance profiler based on
+// the perf_event_open syscall. Each packet represents an individual sample
+// of a performance counter (which might be a timer), and optionally a
+// callstack of the process that was scheduled at the time of the sample.
+//
+
+// The packet emitted by heapprofd for each heap snapshot. A snapshot can
+// involve more than one ProfilePacket if the snapshot is big (when |continued|
+// is true). The cardinality and grouping is as follows:
+// A ProfilePacket contains:
+// - 1+ per-process heap snapshots (ProcessHeapSamples). Normally there is only
+// one heap per process (the main malloc/free heap), but there can be more if
+// the process is using the heapprofd API to profile custom allocators.
+// - Globally interned strings, mappings and frames (to allow de-duplicating
+// frames/mapping in common between different processes).
+// A ProcessHeapSamples contains:
+// - The process and heap identifier.
+// - A number of HeapSample, one for each callsite that had some alloc/frees.
+// - Statistics about heapprofd internals (e.g., sampling/unwinding timings).
+// A HeapSample contains statistics about callsites:
+// - Total number of bytes allocated and freed from that callsite.
+// - Total number of alloc/free calls sampled.
+// - Stats at the local maximum when dump_at_max = true.
+// See https://perfetto.dev/docs/data-sources/native-heap-profiler for more.
message ProfilePacket {
// The following interning tables are only used in Android version Q.
// In newer versions, these tables are in InternedData
@@ -7934,6 +9037,8 @@ message ProfilePacket {
optional uint64 index = 7;
}
+// Packet emitted by heapprofd when stream_allocations = true. Only for local
+// testing. Doesn't report the callsite.
message StreamingAllocation {
// TODO(fmayer): Add callstack.
repeated uint64 address = 1;
@@ -7944,6 +9049,8 @@ message StreamingAllocation {
repeated uint64 sequence_number = 6;
};
+// Packet emitted by heapprofd when stream_allocations = true. Only for local
+// testing. Doesn't report the callsite.
message StreamingFree {
// TODO(fmayer): Add callstack.
repeated uint64 address = 1;
@@ -7951,8 +9058,9 @@ message StreamingFree {
repeated uint64 sequence_number = 3;
};
-// Message used to represent individual stack samples sampled at discrete
-// points in time, rather than aggregated over an interval.
+// Packet emitted by the chromium in-process signal-based callstack sampler.
+// Represents a series of individual stack samples (sampled at discrete points
+// in time), rather than aggregated over an interval.
message StreamingProfilePacket {
// Index into InternedData.callstacks
repeated uint64 callstack_iid = 1;
@@ -7989,21 +9097,26 @@ message Profiling {
UNWIND_ERROR_SYSTEM_CALL = 9;
UNWIND_ERROR_THREAD_TIMEOUT = 10;
UNWIND_ERROR_THREAD_DOES_NOT_EXIST = 11;
+ UNWIND_ERROR_BAD_ARCH = 12;
+ UNWIND_ERROR_MAPS_PARSE = 13;
+ UNWIND_ERROR_INVALID_PARAMETER = 14;
}
}
-// Individual performance sampling packet payload. Typically corresponds to a
-// stack sample on a configration-dependent counter overflow.
+// Packet emitted by the traced_perf sampling performance profiler, which
+// gathers data via the perf_event_open syscall. Each packet contains an
+// individual sample with a counter value, and optionally a
+// callstack.
//
-// Timestamps are within the root packet. This used to use the CLOCK_BOOTTIME
-// domain, but now the default is CLOCK_MONOTONIC_RAW which is compatible with
-// more event types.
+// Timestamps are within the root packet. The config can specify the clock, or
+// the implementation will default to CLOCK_MONOTONIC_RAW. Within the Android R
+// timeframe, the default was CLOCK_BOOTTIME.
//
// There are several distinct views of this message:
-// * completely processed sample (callstack_iid set)
// * indication of kernel buffer data loss (kernel_records_lost set)
// * indication of skipped samples (sample_skipped_reason set)
// * notable event in the sampling implementation (producer_event set)
+// * normal sample (timebase_count set, typically also callstack_iid)
message PerfSample {
optional uint32 cpu = 1;
optional uint32 pid = 2;
@@ -8068,6 +9181,7 @@ message PerfSampleDefaults {
// the implementation decided to default/override some parameters.
optional PerfEvents.Timebase timebase = 1;
}
+
// End of protos/perfetto/trace/profiling/profile_packet.proto
// Begin of protos/perfetto/trace/profiling/smaps.proto
@@ -8184,7 +9298,7 @@ message ProcessStats {
message ProcessTree {
// Representation of a thread.
message Thread {
- // The thread id (as per gettid())
+ // The thread ID (as per gettid()) in the root PID namespace.
optional int32 tid = 1;
// Thread group id (i.e. the PID of the process, == TID of the main thread)
@@ -8192,11 +9306,17 @@ message ProcessTree {
// The name of the thread.
optional string name = 2;
+
+ // The non-root-level thread IDs if the thread runs in a PID namespace. Read
+ // from the NSpid entry of /proc/<tid>/status, with the first element (root-
+ // level thread ID) omitted.
+ repeated int32 nstid = 4;
}
// Representation of a process.
message Process {
- // The UNIX process ID, aka thread group ID (as per getpid()).
+ // The UNIX process ID, aka thread group ID (as per getpid()) in the root
+ // PID namespace.
optional int32 pid = 1;
// The parent process ID, as per getppid().
@@ -8213,6 +9333,11 @@ message ProcessTree {
// The uid for the process, as per /proc/pid/status.
optional int32 uid = 5;
+
+ // The non-root-level process IDs if the process runs in a PID namespace.
+ // Read from the NSpid entry of /proc/<pid>/status, with the first element (
+ // root-level process ID) omitted.
+ repeated int32 nspid = 6;
}
// List of processes and threads in the client. These lists are incremental
@@ -8319,6 +9444,11 @@ message SysStats {
// One entry per device.
repeated DevfreqValue devfreq = 10;
+
+ // Cpu current frequency from
+ // /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_cur_freq in kHz.
+ // One entry per cpu. Report 0 for offline cpu
+ repeated uint32 cpufreq_khz = 11;
}
// End of protos/perfetto/trace/sys_stats/sys_stats.proto
@@ -8344,6 +9474,10 @@ message SystemInfo {
// the build system and the repo (standalone vs AOSP).
// This is intended for human debugging only.
optional string tracing_service_version = 4;
+
+ // The Android SDK vesion (e.g. 21 for L, 31 for S etc).
+ // Introduced in Android T.
+ optional uint64 android_sdk_version = 5;
}
// End of protos/perfetto/trace/system_info.proto
@@ -8397,6 +9531,8 @@ message TestEvent {
// When 0 this is the bottom-most nested message.
optional uint32 remaining_nesting_depth = 3;
+
+ repeated DebugAnnotation debug_annotations = 7;
}
optional TestPayload payload = 5;
}
@@ -8428,7 +9564,7 @@ message TracePacketDefaults {
// Describes a process's attributes. Emitted as part of a TrackDescriptor,
// usually by the process's main thread.
//
-// Next id: 8.
+// Next id: 9.
message ProcessDescriptor {
optional int32 pid = 1;
repeated string cmdline = 2;
@@ -8460,6 +9596,11 @@ message ProcessDescriptor {
// To support old UI. New UI should determine default sorting by process_type.
optional int32 legacy_sort_index = 3;
+
+ // Labels can be used to further describe properties of the work performed by
+ // the process. For example, these can be used by Chrome renderer process to
+ // provide titles of frames being rendered.
+ repeated string process_labels = 8;
}
// End of protos/perfetto/trace/track_event/process_descriptor.proto
@@ -8573,6 +9714,7 @@ message ChromeProcessDescriptor {
PROCESS_SERVICE_IME = 37;
PROCESS_SERVICE_RECORDING = 38;
PROCESS_SERVICE_SHAPEDETECTION = 39;
+ PROCESS_RENDERER_EXTENSION = 40;
}
optional ProcessType process_type = 1;
optional int32 process_priority = 2;
@@ -8657,6 +9799,7 @@ message ChromeThreadDescriptor {
THREAD_DEVTOOLSADB = 38;
THREAD_NETWORKCONFIGWATCHER = 39;
THREAD_WASAPI_RENDER = 40;
+ THREAD_LOADER_LOCK_SAMPLER = 41;
THREAD_MEMORY_INFRA = 50;
THREAD_SAMPLING_PROFILER = 51;
@@ -8816,6 +9959,42 @@ message TrackDescriptor {
// End of protos/perfetto/trace/track_event/track_descriptor.proto
+// Begin of protos/perfetto/trace/translation/translation_table.proto
+
+// Translation rules for the trace processor.
+// See the comments for each rule type for specific meaning.
+message TranslationTable {
+ oneof table {
+ ChromeHistorgramTranslationTable chrome_histogram = 1;
+ ChromeUserEventTranslationTable chrome_user_event = 2;
+ ChromePerformanceMarkTranslationTable chrome_performance_mark = 3;
+ SliceNameTranslationTable slice_name = 4;
+ }
+}
+
+// Chrome histogram sample hash -> name translation rules.
+message ChromeHistorgramTranslationTable {
+ map<uint64, string> hash_to_name = 1;
+}
+
+// Chrome user event action hash -> name translation rules.
+message ChromeUserEventTranslationTable {
+ map<uint64, string> action_hash_to_name = 1;
+}
+
+// Chrome performance mark translation rules.
+message ChromePerformanceMarkTranslationTable {
+ map<uint32, string> site_hash_to_name = 1;
+ map<uint32, string> mark_hash_to_name = 2;
+};
+
+// Raw -> deobfuscated slice name translation rules.
+message SliceNameTranslationTable {
+ map<string, string> raw_to_deobfuscated_name = 1;
+};
+
+// End of protos/perfetto/trace/translation/translation_table.proto
+
// Begin of protos/perfetto/trace/trigger.proto
// When a TracingSession receives a trigger it records the boot time nanoseconds
@@ -8894,7 +10073,7 @@ message UiState {
// See the [Buffers and Dataflow](/docs/concepts/buffers.md) doc for details.
//
// Next reserved id: 14 (up to 15).
-// Next id: 79.
+// Next id: 83.
message TracePacket {
// The timestamp of the TracePacket.
// By default this timestamps refers to the trace clock (CLOCK_BOOTTIME on
@@ -8956,6 +10135,9 @@ message TracePacket {
FrameTimelineEvent frame_timeline_event = 76;
AndroidEnergyEstimationBreakdown android_energy_estimation_breakdown = 77;
UiState ui_state = 78;
+ AndroidCameraFrameEvent android_camera_frame_event = 80;
+ AndroidCameraSessionStats android_camera_session_stats = 81;
+ TranslationTable translation_table = 82;
// Only used in profile packets.
ProfiledFrameSymbols profiled_frame_symbols = 55;
@@ -9016,6 +10198,10 @@ message TracePacket {
uint32 trusted_packet_sequence_id = 10;
}
+ // Trusted process id of the producer which generated this packet, written by
+ // the service.
+ optional int32 trusted_pid = 79;
+
// Incrementally emitted interned data, valid only on the packet's sequence
// (packets with the same |trusted_packet_sequence_id|). The writer will
// usually emit new interned data in the same TracePacket that first refers to
diff --git a/protos/perfetto/trace/profiling/heap_graph.proto b/protos/perfetto/trace/profiling/heap_graph.proto
index 2b7a44b9e..d57568fcb 100644
--- a/protos/perfetto/trace/profiling/heap_graph.proto
+++ b/protos/perfetto/trace/profiling/heap_graph.proto
@@ -95,8 +95,11 @@ message HeapGraphObject {
// Bytes occupied by this objects.
optional uint64 self_size = 3;
- // Add this to all non-zero values in reference_field_id. This is used to
+ // Add this to all non-zero values in reference_object_id. This is used to
// get more compact varint encoding.
+ //
+ // The name is confusing, but this has always been used as a base for
+ // reference_object_id. The field should be named reference_object_id_base.
optional uint64 reference_field_id_base = 6;
// Indices for InternedData.field_names for the name of the field referring
@@ -107,6 +110,12 @@ message HeapGraphObject {
// Ids of the Object that is referred to.
repeated uint64 reference_object_id = 5 [packed = true];
+
+ // If this object is an instance of `libcore.util.NativeAllocationRegistry`,
+ // the value of the `size` field.
+ //
+ // N.B. This is not the native size of this object.
+ optional int64 native_allocation_registry_size_field = 8;
}
message HeapGraph {
diff --git a/protos/perfetto/trace/profiling/profile_packet.proto b/protos/perfetto/trace/profiling/profile_packet.proto
index 8548a4ec1..d58e6e72d 100644
--- a/protos/perfetto/trace/profiling/profile_packet.proto
+++ b/protos/perfetto/trace/profiling/profile_packet.proto
@@ -21,6 +21,58 @@ import "protos/perfetto/trace/profiling/profile_common.proto";
package perfetto.protos;
+// This file contains a mixture of messages emitted by various sampling
+// profilers:
+//
+// Memory allocator profiling
+// ----------------
+// ProfilePacket:
+// The packet emitted by heapprofd, which started off as a native heap
+// (malloc/free) profiler, but now supports custom allocators as well. Each
+// packet contains a preaggregated state of the heap at snapshot time, which
+// report the total allocated/free bytes per callstack (plus other info such
+// as the number of samples).
+// StreamingAllocation/StreamingFree:
+// Emitted by heapprofd when configured in streaming mode (i.e. when
+// stream_allocations = true). This is only for local testing, and doesn't
+// report callstacks (only address time and size of each alloc/free). It can
+// lead to enormous traces, as it contains the stream of each alloc/free call.
+//
+// Callstack sampling
+// ------------------
+// StreamingProfilePacket:
+// The packet emitted by the chromium in-process sampling profiler, which is
+// based on periodically sending a signal to itself, and unwinding the stack
+// in the signal handler. Each packet contains a series of individual stack
+// samples for a Chromium thread.
+//
+// Callstack and performance counter sampling
+// ---------------------
+// PerfSample:
+// The packet emitted by traced_perf sampling performance profiler based on
+// the perf_event_open syscall. Each packet represents an individual sample
+// of a performance counter (which might be a timer), and optionally a
+// callstack of the process that was scheduled at the time of the sample.
+//
+
+// The packet emitted by heapprofd for each heap snapshot. A snapshot can
+// involve more than one ProfilePacket if the snapshot is big (when |continued|
+// is true). The cardinality and grouping is as follows:
+// A ProfilePacket contains:
+// - 1+ per-process heap snapshots (ProcessHeapSamples). Normally there is only
+// one heap per process (the main malloc/free heap), but there can be more if
+// the process is using the heapprofd API to profile custom allocators.
+// - Globally interned strings, mappings and frames (to allow de-duplicating
+// frames/mapping in common between different processes).
+// A ProcessHeapSamples contains:
+// - The process and heap identifier.
+// - A number of HeapSample, one for each callsite that had some alloc/frees.
+// - Statistics about heapprofd internals (e.g., sampling/unwinding timings).
+// A HeapSample contains statistics about callsites:
+// - Total number of bytes allocated and freed from that callsite.
+// - Total number of alloc/free calls sampled.
+// - Stats at the local maximum when dump_at_max = true.
+// See https://perfetto.dev/docs/data-sources/native-heap-profiler for more.
message ProfilePacket {
// The following interning tables are only used in Android version Q.
// In newer versions, these tables are in InternedData
@@ -159,6 +211,8 @@ message ProfilePacket {
optional uint64 index = 7;
}
+// Packet emitted by heapprofd when stream_allocations = true. Only for local
+// testing. Doesn't report the callsite.
message StreamingAllocation {
// TODO(fmayer): Add callstack.
repeated uint64 address = 1;
@@ -169,6 +223,8 @@ message StreamingAllocation {
repeated uint64 sequence_number = 6;
};
+// Packet emitted by heapprofd when stream_allocations = true. Only for local
+// testing. Doesn't report the callsite.
message StreamingFree {
// TODO(fmayer): Add callstack.
repeated uint64 address = 1;
@@ -176,8 +232,9 @@ message StreamingFree {
repeated uint64 sequence_number = 3;
};
-// Message used to represent individual stack samples sampled at discrete
-// points in time, rather than aggregated over an interval.
+// Packet emitted by the chromium in-process signal-based callstack sampler.
+// Represents a series of individual stack samples (sampled at discrete points
+// in time), rather than aggregated over an interval.
message StreamingProfilePacket {
// Index into InternedData.callstacks
repeated uint64 callstack_iid = 1;
@@ -214,21 +271,26 @@ message Profiling {
UNWIND_ERROR_SYSTEM_CALL = 9;
UNWIND_ERROR_THREAD_TIMEOUT = 10;
UNWIND_ERROR_THREAD_DOES_NOT_EXIST = 11;
+ UNWIND_ERROR_BAD_ARCH = 12;
+ UNWIND_ERROR_MAPS_PARSE = 13;
+ UNWIND_ERROR_INVALID_PARAMETER = 14;
}
}
-// Individual performance sampling packet payload. Typically corresponds to a
-// stack sample on a configration-dependent counter overflow.
+// Packet emitted by the traced_perf sampling performance profiler, which
+// gathers data via the perf_event_open syscall. Each packet contains an
+// individual sample with a counter value, and optionally a
+// callstack.
//
-// Timestamps are within the root packet. This used to use the CLOCK_BOOTTIME
-// domain, but now the default is CLOCK_MONOTONIC_RAW which is compatible with
-// more event types.
+// Timestamps are within the root packet. The config can specify the clock, or
+// the implementation will default to CLOCK_MONOTONIC_RAW. Within the Android R
+// timeframe, the default was CLOCK_BOOTTIME.
//
// There are several distinct views of this message:
-// * completely processed sample (callstack_iid set)
// * indication of kernel buffer data loss (kernel_records_lost set)
// * indication of skipped samples (sample_skipped_reason set)
// * notable event in the sampling implementation (producer_event set)
+// * normal sample (timebase_count set, typically also callstack_iid)
message PerfSample {
optional uint32 cpu = 1;
optional uint32 pid = 2;
@@ -292,4 +354,4 @@ message PerfSampleDefaults {
// The sampling timebase. Might not be identical to the data source config if
// the implementation decided to default/override some parameters.
optional PerfEvents.Timebase timebase = 1;
-} \ No newline at end of file
+}
diff --git a/protos/perfetto/trace/ps/process_tree.proto b/protos/perfetto/trace/ps/process_tree.proto
index 67556a3ec..078492303 100644
--- a/protos/perfetto/trace/ps/process_tree.proto
+++ b/protos/perfetto/trace/ps/process_tree.proto
@@ -25,7 +25,7 @@ package perfetto.protos;
message ProcessTree {
// Representation of a thread.
message Thread {
- // The thread id (as per gettid())
+ // The thread ID (as per gettid()) in the root PID namespace.
optional int32 tid = 1;
// Thread group id (i.e. the PID of the process, == TID of the main thread)
@@ -33,11 +33,17 @@ message ProcessTree {
// The name of the thread.
optional string name = 2;
+
+ // The non-root-level thread IDs if the thread runs in a PID namespace. Read
+ // from the NSpid entry of /proc/<tid>/status, with the first element (root-
+ // level thread ID) omitted.
+ repeated int32 nstid = 4;
}
// Representation of a process.
message Process {
- // The UNIX process ID, aka thread group ID (as per getpid()).
+ // The UNIX process ID, aka thread group ID (as per getpid()) in the root
+ // PID namespace.
optional int32 pid = 1;
// The parent process ID, as per getppid().
@@ -54,6 +60,11 @@ message ProcessTree {
// The uid for the process, as per /proc/pid/status.
optional int32 uid = 5;
+
+ // The non-root-level process IDs if the process runs in a PID namespace.
+ // Read from the NSpid entry of /proc/<pid>/status, with the first element (
+ // root-level process ID) omitted.
+ repeated int32 nspid = 6;
}
// List of processes and threads in the client. These lists are incremental
diff --git a/protos/perfetto/trace/sys_stats/sys_stats.proto b/protos/perfetto/trace/sys_stats/sys_stats.proto
index 30edac03f..5bd421fe8 100644
--- a/protos/perfetto/trace/sys_stats/sys_stats.proto
+++ b/protos/perfetto/trace/sys_stats/sys_stats.proto
@@ -103,4 +103,9 @@ message SysStats {
// One entry per device.
repeated DevfreqValue devfreq = 10;
+
+ // Cpu current frequency from
+ // /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_cur_freq in kHz.
+ // One entry per cpu. Report 0 for offline cpu
+ repeated uint32 cpufreq_khz = 11;
}
diff --git a/protos/perfetto/trace/system_info.proto b/protos/perfetto/trace/system_info.proto
index ddce4ca7a..2f8d64235 100644
--- a/protos/perfetto/trace/system_info.proto
+++ b/protos/perfetto/trace/system_info.proto
@@ -37,4 +37,8 @@ message SystemInfo {
// the build system and the repo (standalone vs AOSP).
// This is intended for human debugging only.
optional string tracing_service_version = 4;
+
+ // The Android SDK vesion (e.g. 21 for L, 31 for S etc).
+ // Introduced in Android T.
+ optional uint64 android_sdk_version = 5;
}
diff --git a/protos/perfetto/trace/test_event.proto b/protos/perfetto/trace/test_event.proto
index 67a8f60f7..023343e19 100644
--- a/protos/perfetto/trace/test_event.proto
+++ b/protos/perfetto/trace/test_event.proto
@@ -16,6 +16,8 @@
syntax = "proto2";
+import "protos/perfetto/trace/track_event/debug_annotation.proto";
+
package perfetto.protos;
// Event used by testing code.
@@ -43,6 +45,8 @@ message TestEvent {
// When 0 this is the bottom-most nested message.
optional uint32 remaining_nesting_depth = 3;
+
+ repeated DebugAnnotation debug_annotations = 7;
}
optional TestPayload payload = 5;
}
diff --git a/protos/perfetto/trace/test_extensions.proto b/protos/perfetto/trace/test_extensions.proto
index 94118dce4..dca2db627 100644
--- a/protos/perfetto/trace/test_extensions.proto
+++ b/protos/perfetto/trace/test_extensions.proto
@@ -17,6 +17,7 @@
syntax = "proto2";
import public "protos/perfetto/trace/track_event/track_event.proto";
+import "protos/perfetto/trace/track_event/debug_annotation.proto";
package perfetto.protos;
@@ -35,4 +36,6 @@ message TestExtension {
message TestExtensionChild {
optional string child_field_for_testing = 1;
+
+ repeated DebugAnnotation debug_annotations = 99;
}
diff --git a/protos/perfetto/trace/trace_packet.proto b/protos/perfetto/trace/trace_packet.proto
index 24284271c..b08ec4e7e 100644
--- a/protos/perfetto/trace/trace_packet.proto
+++ b/protos/perfetto/trace/trace_packet.proto
@@ -20,6 +20,7 @@ import "protos/perfetto/common/trace_stats.proto";
import "protos/perfetto/config/trace_config.proto";
import "protos/perfetto/trace/extension_descriptor.proto";
import "protos/perfetto/trace/android/android_log.proto";
+import "protos/perfetto/trace/android/camera_event.proto";
import "protos/perfetto/trace/android/frame_timeline_event.proto";
import "protos/perfetto/trace/android/gpu_mem_event.proto";
import "protos/perfetto/trace/android/graphics_frame_event.proto";
@@ -59,6 +60,7 @@ import "protos/perfetto/trace/track_event/process_descriptor.proto";
import "protos/perfetto/trace/track_event/thread_descriptor.proto";
import "protos/perfetto/trace/track_event/track_descriptor.proto";
import "protos/perfetto/trace/track_event/track_event.proto";
+import "protos/perfetto/trace/translation/translation_table.proto";
import "protos/perfetto/trace/trigger.proto";
import "protos/perfetto/trace/test_event.proto";
import "protos/perfetto/trace/ui_state.proto";
@@ -85,7 +87,7 @@ package perfetto.protos;
// See the [Buffers and Dataflow](/docs/concepts/buffers.md) doc for details.
//
// Next reserved id: 14 (up to 15).
-// Next id: 79.
+// Next id: 83.
message TracePacket {
// The timestamp of the TracePacket.
// By default this timestamps refers to the trace clock (CLOCK_BOOTTIME on
@@ -147,6 +149,9 @@ message TracePacket {
FrameTimelineEvent frame_timeline_event = 76;
AndroidEnergyEstimationBreakdown android_energy_estimation_breakdown = 77;
UiState ui_state = 78;
+ AndroidCameraFrameEvent android_camera_frame_event = 80;
+ AndroidCameraSessionStats android_camera_session_stats = 81;
+ TranslationTable translation_table = 82;
// Only used in profile packets.
ProfiledFrameSymbols profiled_frame_symbols = 55;
@@ -207,6 +212,10 @@ message TracePacket {
uint32 trusted_packet_sequence_id = 10;
}
+ // Trusted process id of the producer which generated this packet, written by
+ // the service.
+ optional int32 trusted_pid = 79;
+
// Incrementally emitted interned data, valid only on the packet's sequence
// (packets with the same |trusted_packet_sequence_id|). The writer will
// usually emit new interned data in the same TracePacket that first refers to
diff --git a/protos/perfetto/trace/track_event/BUILD.gn b/protos/perfetto/trace/track_event/BUILD.gn
index d1a81779c..ab9d27352 100644
--- a/protos/perfetto/trace/track_event/BUILD.gn
+++ b/protos/perfetto/trace/track_event/BUILD.gn
@@ -43,7 +43,7 @@ perfetto_proto_library("@TYPE@") {
]
}
-perfetto_proto_library("track_event_@TYPE@") {
+perfetto_proto_library("@TYPE@") {
proto_generators = [ "descriptor" ]
generate_descriptor = "track_event.descriptor"
sources = [ "track_event.proto" ]
diff --git a/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto b/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto
index 109180abf..476ed3887 100644
--- a/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto
+++ b/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto
@@ -31,7 +31,8 @@ package perfetto.protos;
// The original format was generated in JSON by the code at
// https://cs.chromium.org/chromium/src/cc/scheduler/scheduler.cc?l=870&rcl=5e15eabc9c0eec8daf94fdf78e93f13b6e3b63dd
//
-// TODO(nuskos): Update link once we've switched to writing this proto.
+// And is now generated as protozero:
+// https://cs.chromium.org/chromium/src/cc/scheduler/scheduler.cc?q=Scheduler::AsPro
//
// All non-delta-timestamps are absolute CLOCK_MONOTONIC timestamps.
@@ -67,7 +68,6 @@ message ChromeCompositorSchedulerState {
optional bool begin_impl_frame_deadline_task = 3;
optional bool pending_begin_frame_task = 4;
optional bool skipped_last_frame_missed_exceeded_deadline = 5;
- optional bool skipped_last_frame_to_reduce_latency = 6;
optional ChromeCompositorSchedulerAction inside_action = 7;
optional BeginImplFrameDeadlineMode deadline_mode = 8;
optional int64 deadline_us = 9;
@@ -79,6 +79,8 @@ message ChromeCompositorSchedulerState {
optional BeginFrameObserverState begin_frame_observer_state = 15;
optional BeginFrameSourceState begin_frame_source_state = 16;
optional CompositorTimingHistory compositor_timing_history = 17;
+
+ reserved 6;
}
// Describes the current values stored in the Chrome Compositor state machine.
@@ -168,7 +170,6 @@ message ChromeCompositorStateMachine {
optional ScrollHandlerState scroll_handler_state = 32;
optional bool critical_begin_main_frame_to_activate_is_fast = 33;
optional bool main_thread_missed_last_deadline = 34;
- optional bool skip_next_begin_main_frame_to_reduce_latency = 35;
optional bool video_needs_begin_frames = 36;
optional bool defer_begin_main_frame = 37;
optional bool last_commit_had_no_updates = 38;
@@ -180,11 +181,13 @@ message ChromeCompositorStateMachine {
optional bool processing_animation_worklets_for_active_tree = 44;
optional bool processing_animation_worklets_for_pending_tree = 45;
optional bool processing_paint_worklets_for_pending_tree = 46;
+
+ reserved 35;
}
optional MinorState minor_state = 2;
}
-// Next id: 12
+// Next id: 13
message BeginFrameArgs {
// JSON format has a "type" field that was always just "BeginFrameArgs" we
// drop this in the proto representation, and instead make the JSON format
@@ -213,6 +216,7 @@ message BeginFrameArgs {
// remove this |source_location|.
SourceLocation source_location = 10;
}
+ optional int64 frames_throttled_since_last = 12;
}
// Next id: 7
diff --git a/protos/perfetto/trace/track_event/chrome_frame_reporter.proto b/protos/perfetto/trace/track_event/chrome_frame_reporter.proto
index 00930c7f6..f1165a89b 100644
--- a/protos/perfetto/trace/track_event/chrome_frame_reporter.proto
+++ b/protos/perfetto/trace/track_event/chrome_frame_reporter.proto
@@ -74,11 +74,11 @@ message ChromeFrameReporter {
SCROLL_MAIN_THREAD = 1;
SCROLL_COMPOSITOR_THREAD = 2;
- // Used when it can't be determined wheter a scroll is in progress or not.
+ // Used when it can't be determined whether a scroll is in progress or not.
SCROLL_UNKNOWN = 3;
}
- // The type of active scroll
+ // The type of active scroll.
optional ScrollState scroll_state = 6;
// If any main thread animation is active during this frame.
diff --git a/protos/perfetto/trace/track_event/chrome_latency_info.proto b/protos/perfetto/trace/track_event/chrome_latency_info.proto
index 5412b400b..75113ea33 100644
--- a/protos/perfetto/trace/track_event/chrome_latency_info.proto
+++ b/protos/perfetto/trace/track_event/chrome_latency_info.proto
@@ -84,4 +84,5 @@ message ChromeLatencyInfo {
repeated ComponentInfo component_info = 4;
optional bool is_coalesced = 5;
optional int64 gesture_scroll_id = 6;
+ optional int64 touch_id = 7;
}
diff --git a/protos/perfetto/trace/track_event/chrome_process_descriptor.proto b/protos/perfetto/trace/track_event/chrome_process_descriptor.proto
index ee6e1964e..ca7d6fe45 100644
--- a/protos/perfetto/trace/track_event/chrome_process_descriptor.proto
+++ b/protos/perfetto/trace/track_event/chrome_process_descriptor.proto
@@ -65,6 +65,7 @@ message ChromeProcessDescriptor {
PROCESS_SERVICE_IME = 37;
PROCESS_SERVICE_RECORDING = 38;
PROCESS_SERVICE_SHAPEDETECTION = 39;
+ PROCESS_RENDERER_EXTENSION = 40;
}
optional ProcessType process_type = 1;
optional int32 process_priority = 2;
diff --git a/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto b/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto
index ade789774..436cc79b8 100644
--- a/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto
+++ b/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.proto
@@ -34,4 +34,7 @@ enum ChromeRAILMode {
// Next id: 2
message ChromeRendererSchedulerState {
optional ChromeRAILMode rail_mode = 1;
+
+ optional bool is_backgrounded = 2;
+ optional bool is_hidden = 3;
}
diff --git a/protos/perfetto/trace/track_event/chrome_thread_descriptor.proto b/protos/perfetto/trace/track_event/chrome_thread_descriptor.proto
index f142e49d6..bd82b5a9d 100644
--- a/protos/perfetto/trace/track_event/chrome_thread_descriptor.proto
+++ b/protos/perfetto/trace/track_event/chrome_thread_descriptor.proto
@@ -73,6 +73,7 @@ message ChromeThreadDescriptor {
THREAD_DEVTOOLSADB = 38;
THREAD_NETWORKCONFIGWATCHER = 39;
THREAD_WASAPI_RENDER = 40;
+ THREAD_LOADER_LOCK_SAMPLER = 41;
THREAD_MEMORY_INFRA = 50;
THREAD_SAMPLING_PROFILER = 51;
diff --git a/protos/perfetto/trace/track_event/debug_annotation.proto b/protos/perfetto/trace/track_event/debug_annotation.proto
index d6766cb31..35a041d6b 100644
--- a/protos/perfetto/trace/track_event/debug_annotation.proto
+++ b/protos/perfetto/trace/track_event/debug_annotation.proto
@@ -57,7 +57,8 @@ package perfetto.protos;
// }
// }
//
-// Next ID: 13.
+// Next ID: 17.
+// Reserved ID: 15
message DebugAnnotation {
// Name fields are set only for dictionary entries.
oneof name_field {
@@ -85,6 +86,18 @@ message DebugAnnotation {
string legacy_json_value = 9;
}
+ // Used to embed arbitrary proto messages (which are also typically used to
+ // represent typed TrackEvent arguments). |proto_type_name| or
+ // |proto_type_name_iid| are storing the full name of the proto messages (e.g.
+ // .perfetto.protos.DebugAnnotation) and |proto_value| contains the serialised
+ // proto messages. See |TracedValue::WriteProto| for more details.
+ oneof proto_type_descriptor {
+ string proto_type_name = 16;
+ // interned DebugAnnotationValueTypeName.
+ uint64 proto_type_name_iid = 13;
+ }
+ optional bytes proto_value = 14;
+
repeated DebugAnnotation dict_entries = 11;
repeated DebugAnnotation array_values = 12;
@@ -118,3 +131,9 @@ message DebugAnnotationName {
optional uint64 iid = 1;
optional string name = 2;
}
+
+// See the |proto_type_descriptor| comment.
+message DebugAnnotationValueTypeName {
+ optional uint64 iid = 1;
+ optional string name = 2;
+}
diff --git a/protos/perfetto/trace/track_event/process_descriptor.proto b/protos/perfetto/trace/track_event/process_descriptor.proto
index 1a6388dc2..cacc6357f 100644
--- a/protos/perfetto/trace/track_event/process_descriptor.proto
+++ b/protos/perfetto/trace/track_event/process_descriptor.proto
@@ -21,7 +21,7 @@ package perfetto.protos;
// Describes a process's attributes. Emitted as part of a TrackDescriptor,
// usually by the process's main thread.
//
-// Next id: 8.
+// Next id: 9.
message ProcessDescriptor {
optional int32 pid = 1;
repeated string cmdline = 2;
@@ -53,4 +53,9 @@ message ProcessDescriptor {
// To support old UI. New UI should determine default sorting by process_type.
optional int32 legacy_sort_index = 3;
+
+ // Labels can be used to further describe properties of the work performed by
+ // the process. For example, these can be used by Chrome renderer process to
+ // provide titles of frames being rendered.
+ repeated string process_labels = 8;
}
diff --git a/protos/perfetto/trace/translation/BUILD.gn b/protos/perfetto/trace/translation/BUILD.gn
new file mode 100644
index 000000000..4e344ba5f
--- /dev/null
+++ b/protos/perfetto/trace/translation/BUILD.gn
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("../../../../gn/proto_library.gni")
+
+perfetto_proto_library("@TYPE@") {
+ sources = [ "translation_table.proto" ]
+}
diff --git a/protos/perfetto/trace/translation/translation_table.proto b/protos/perfetto/trace/translation/translation_table.proto
new file mode 100644
index 000000000..06cef3128
--- /dev/null
+++ b/protos/perfetto/trace/translation/translation_table.proto
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+// Translation rules for the trace processor.
+// See the comments for each rule type for specific meaning.
+message TranslationTable {
+ oneof table {
+ ChromeHistorgramTranslationTable chrome_histogram = 1;
+ ChromeUserEventTranslationTable chrome_user_event = 2;
+ ChromePerformanceMarkTranslationTable chrome_performance_mark = 3;
+ SliceNameTranslationTable slice_name = 4;
+ }
+}
+
+// Chrome histogram sample hash -> name translation rules.
+message ChromeHistorgramTranslationTable {
+ map<uint64, string> hash_to_name = 1;
+}
+
+// Chrome user event action hash -> name translation rules.
+message ChromeUserEventTranslationTable {
+ map<uint64, string> action_hash_to_name = 1;
+}
+
+// Chrome performance mark translation rules.
+message ChromePerformanceMarkTranslationTable {
+ map<uint32, string> site_hash_to_name = 1;
+ map<uint32, string> mark_hash_to_name = 2;
+};
+
+// Raw -> deobfuscated slice name translation rules.
+message SliceNameTranslationTable {
+ map<string, string> raw_to_deobfuscated_name = 1;
+};
diff --git a/protos/perfetto/trace_processor/BUILD.gn b/protos/perfetto/trace_processor/BUILD.gn
index ee1c79533..c8671b18f 100644
--- a/protos/perfetto/trace_processor/BUILD.gn
+++ b/protos/perfetto/trace_processor/BUILD.gn
@@ -16,7 +16,10 @@ import("../../../gn/proto_library.gni")
import("proto_files.gni")
perfetto_proto_library("@TYPE@") {
- proto_generators = [ "zero" ]
+ proto_generators = [
+ "zero",
+ "source_set",
+ ]
deps = [ "../common:zero" ] # ../common:zero needed for descriptor.proto.
sources = []
foreach(source, trace_processor_protos) {
@@ -24,7 +27,10 @@ perfetto_proto_library("@TYPE@") {
}
}
-perfetto_proto_library("metrics_impl_zero") {
- proto_generators = [ "zero" ]
+perfetto_proto_library("metrics_impl_@TYPE@") {
+ proto_generators = [
+ "zero",
+ "source_set",
+ ]
sources = [ "metrics_impl.proto" ]
}
diff --git a/protos/perfetto/trace_processor/trace_processor.proto b/protos/perfetto/trace_processor/trace_processor.proto
index f32745bd8..2d19871da 100644
--- a/protos/perfetto/trace_processor/trace_processor.proto
+++ b/protos/perfetto/trace_processor/trace_processor.proto
@@ -35,12 +35,117 @@ import "protos/perfetto/common/descriptor.proto";
// In this case these messages are used to {,un}marshall HTTP requests and
// response made through src/trace_processor/rpc/httpd.cc .
+enum TraceProcessorApiVersion {
+ // This variable has been introduced in v15 and is used to deal with API
+ // mismatches between UI and trace_processor_shell --httpd. Increment this
+ // every time a new feature that the UI depends on is being introduced (e.g.
+ // new tables, new SQL operators, metrics that are required by the UI).
+ // See also TraceProcessorVersion (below).
+ TRACE_PROCESSOR_CURRENT_API_VERSION = 3;
+}
+
+// At lowest level, the wire-format of the RPC procol is a linear sequence of
+// TraceProcessorRpc messages on each side of the byte pipe
+// Each message is prefixed by a tag (field = 1, type = length delimited) and a
+// varint encoding its size (this is so the whole stream can also be read /
+// written as if it was a repeated field of TraceProcessorRpcStream).
+
+message TraceProcessorRpcStream {
+ repeated TraceProcessorRpc msg = 1;
+}
+
+message TraceProcessorRpc {
+ // A monotonic counter used only for debugging purposes, to detect if the
+ // underlying stream is missing or duping data. The counter starts at 0 on
+ // each side of the pipe and is incremented on each message.
+ // Do NOT expect that a response has the same |seq| of its corresponding
+ // request: some requests (e.g., a query returning many rows) can yield more
+ // than one response message, bringing the tx and rq seq our of sync.
+ optional int64 seq = 1;
+
+ // This is returned when some unrecoverable error has been detected by the
+ // peer. The typical case is TraceProcessor detecting that the |seq| sequence
+ // is broken (e.g. when having two tabs open with the same --httpd instance).
+ optional string fatal_error = 5;
+
+ enum TraceProcessorMethod {
+ TPM_UNSPECIFIED = 0;
+ TPM_APPEND_TRACE_DATA = 1;
+ TPM_FINALIZE_TRACE_DATA = 2;
+ TPM_QUERY_STREAMING = 3;
+ TPM_QUERY_RAW_DEPRECATED = 4;
+ TPM_COMPUTE_METRIC = 5;
+ TPM_GET_METRIC_DESCRIPTORS = 6;
+ TPM_RESTORE_INITIAL_TABLES = 7;
+ TPM_ENABLE_METATRACE = 8;
+ TPM_DISABLE_AND_READ_METATRACE = 9;
+ TPM_GET_STATUS = 10;
+ }
+
+ oneof type {
+ // Client -> TraceProcessor requests.
+ TraceProcessorMethod request = 2;
+
+ // TraceProcessor -> Client responses.
+ TraceProcessorMethod response = 3;
+
+ // This is sent back instead of filling |response| when the client sends a
+ // |request| which is not known by the TraceProcessor service. This can
+ // happen when the client is newer than the service.
+ TraceProcessorMethod invalid_request = 4;
+ }
+
+ // Request/Response arguments.
+ // Not all requests / responses require an argument.
+
+ oneof args {
+ // TraceProcessorMethod request args.
+
+ // For TPM_APPEND_TRACE_DATA.
+ bytes append_trace_data = 101;
+ // For TPM_QUERY_STREAMING.
+ QueryArgs query_args = 103;
+ // For TPM_QUERY_RAW_DEPRECATED.
+ RawQueryArgs raw_query_args = 104;
+ // For TPM_COMPUTE_METRIC.
+ ComputeMetricArgs compute_metric_args = 105;
+
+ // TraceProcessorMethod response args.
+ // For TPM_APPEND_TRACE_DATA.
+ AppendTraceDataResult append_result = 201;
+ // For TPM_QUERY_STREAMING.
+ QueryResult query_result = 203;
+ // For TPM_QUERY_RAW_DEPRECATED.
+ RawQueryResult raw_query_result = 204;
+ // For TPM_COMPUTE_METRIC.
+ ComputeMetricResult metric_result = 205;
+ // For TPM_GET_METRIC_DESCRIPTORS.
+ DescriptorSet metric_descriptors = 206;
+ // For TPM_DISABLE_AND_READ_METATRACE.
+ DisableAndReadMetatraceResult metatrace = 209;
+ // For TPM_GET_STATUS.
+ StatusResult status = 210;
+ }
+}
+
+message AppendTraceDataResult {
+ optional int64 total_bytes_parsed = 1;
+ optional string error = 2;
+}
+
+message QueryArgs {
+ optional string sql_query = 1;
+
+ // Was time_queued_ns
+ reserved 2;
+}
+
// Input for the /raw_query endpoint.
message RawQueryArgs {
optional string sql_query = 1;
- // Wall time when the query was queued. Used only for query stats.
- optional uint64 time_queued_ns = 2;
+ // Was time_queued_ns
+ reserved 2;
}
// Output for the /raw_query endpoint.
@@ -117,7 +222,6 @@ message QueryResult {
// NUL-terminated. This is because JS incurs into a non-negligible overhead
// when decoding strings and one decode + split('\0') is measurably faster
// than decoding N strings. See goto.google.com/postmessage-benchmark .
- // \0-concatenated.
optional string string_cells = 5;
// If true this is the last batch for the query result.
@@ -127,6 +231,12 @@ message QueryResult {
reserved 7;
}
repeated CellsBatch batch = 3;
+
+ // The number of statements in the provided SQL.
+ optional uint32 statement_count = 4;
+
+ // The number of statements which produced output rows in the provided SQL.
+ optional uint32 statement_with_output_count = 5;
}
// Input for the /status endpoint.
@@ -138,6 +248,15 @@ message StatusResult {
// when using the HTTP+RPC mode nad passing a trace file to the shell, via
// trace_processor_shell -D trace_file.pftrace .
optional string loaded_trace_name = 1;
+
+ // Typically something like "v11.0.123", but could be just "v11" or "unknown",
+ // for binaries built from Bazel or other build configurations. This is for
+ // human presentation only, don't attempt to parse and reason on it.
+ optional string human_readable_version = 2;
+
+ // The API version is incremented every time a change that the UI depends
+ // on is introduced (e.g. adding a new table that the UI queries).
+ optional int32 api_version = 3;
}
// Input for the /compute_metric endpoint.
@@ -189,11 +308,3 @@ message DisableAndReadMetatraceResult {
message DescriptorSet {
repeated DescriptorProto descriptors = 1;
}
-
-// Input for the /get_metric_descriptors endpoint.
-message GetMetricDescriptorsArgs {}
-
-// Output for the /get_metric_descriptors endpoint.
-message GetMetricDescriptorsResult {
- optional DescriptorSet descriptor_set = 1;
-}
diff --git a/protos/third_party/chromium/BUILD.gn b/protos/third_party/chromium/BUILD.gn
index cff5b38d0..b0f4f779c 100644
--- a/protos/third_party/chromium/BUILD.gn
+++ b/protos/third_party/chromium/BUILD.gn
@@ -2,11 +2,16 @@ import("../../../gn/perfetto.gni")
import("../../../gn/proto_library.gni")
import("sources.gni")
-perfetto_proto_library("chrome_track_event_@TYPE@") {
+perfetto_proto_library("@TYPE@") {
+ sources = chrome_track_event_sources
+ public_deps = [ "../../perfetto/trace/track_event:@TYPE@" ]
+}
+
+perfetto_proto_library("@TYPE@") {
proto_generators = [ "descriptor" ]
sources = chrome_track_event_sources
generate_descriptor = "chrome_track_event.descriptor"
- deps = [ "../../perfetto/trace/track_event:source_set" ]
+ deps = [ ":source_set" ]
# When rolled into Chrome, extension descriptor is going to be linked into
# binary, therefore increasing its size. Including imports means that the
diff --git a/protos/third_party/chromium/chrome_track_event.proto b/protos/third_party/chromium/chrome_track_event.proto
index 813b17430..debe2a7a1 100644
--- a/protos/third_party/chromium/chrome_track_event.proto
+++ b/protos/third_party/chromium/chrome_track_event.proto
@@ -5,6 +5,7 @@
syntax = "proto2";
import public "protos/perfetto/trace/track_event/track_event.proto";
+import public "protos/perfetto/trace/track_event/debug_annotation.proto";
package perfetto.protos;
@@ -28,10 +29,14 @@ message ChromeMemoryPressureNotification {
message ChromeTaskAnnotator {
optional uint32 ipc_hash = 1;
+ // The delay in microseconds that was specified, if any, when this task was
+ // posted. This is only valid for delayed tasks.
+ optional uint64 task_delay_us = 2;
}
message ChromeBrowserContext {
- optional fixed64 ptr = 1;
+ reserved 1;
+ optional string id = 2;
}
message ChromeProfileDestroyer {
@@ -92,8 +97,10 @@ message RenderFrameImplDeletion {
optional uint64 frame_tree_node_id = 4;
}
+// Matches content::ShouldSwapBrowsingInstance.
enum ShouldSwapBrowsingInstance {
- // No BrowsingInstance swap.
+ // Was used for all "no BrowsingInstance swap" scenarios, now broken down in
+ // separate reasons.
SHOULD_SWAP_BROWSING_INSTANCE_NO = 0;
// Forced BrowsingInstance swap.
@@ -104,6 +111,27 @@ enum ShouldSwapBrowsingInstance {
// Proactive BrowsingInstance swap for same-site navigation.
SHOULD_SWAP_BROWSING_INSTANCE_YES_SAME_SITE_PROACTIVE_SWAP = 3;
+
+ SHOULD_SWAP_BROWSING_INSTANCE_NO_PROACTIVE_SWAP_DISABLED = 4;
+ SHOULD_SWAP_BROWSING_INSTANCE_NO_NOT_MAIN_FRAME = 5;
+ SHOULD_SWAP_BROWSING_INSTANCE_NO_HAS_RELATED_ACTIVE_CONTENTS = 6;
+ SHOULD_SWAP_BROWSING_INSTANCE_NO_DOES_NOT_HAVE_SITE = 7;
+ SHOULD_SWAP_BROWSING_INSTANCE_NO_SOURCE_URL_SCHEME_NOT_HTTP_OR_HTTPS = 8;
+ SHOULD_SWAP_BROWSING_INSTANCE_NO_DESTINATION_URL_SCHEME_NOT_HTTP_OR_HTTPS = 9;
+ SHOULD_SWAP_BROWSING_INSTANCE_NO_SAME_SITE_NAVIGATION = 10;
+ SHOULD_SWAP_BROWSING_INSTANCE_NO_RELOADING_ERROR_PAGE = 11;
+ SHOULD_SWAP_BROWSING_INSTANCE_NO_ALREADY_HAS_MATCHING_BROWSING_INSTANCE = 12;
+ SHOULD_SWAP_BROWSING_INSTANCE_NO_RENDERER_DEBUG_URL = 13;
+ SHOULD_SWAP_BROWSING_INSTANCE_NO_NOT_NEEDED_FOR_BACK_FORWARD_CACHE = 14;
+ SHOULD_SWAP_BROWSING_INSTANCE_NO_SAME_DOCUMENT_NAVIGATION = 15;
+ SHOULD_SWAP_BROWSING_INSTANCE_NO_SAME_URL_NAVIGATION = 16;
+ SHOULD_SWAP_BROWSING_INSTANCE_NO_WILL_REPLACE_ENTRY = 17;
+ SHOULD_SWAP_BROWSING_INSTANCE_NO_RELOAD = 18;
+ SHOULD_SWAP_BROWSING_INSTANCE_NO_GUEST = 19;
+ SHOULD_SWAP_BROWSING_INSTANCE_NO_HAS_NOT_COMMITTED_ANY_NAVIGATION = 20;
+ SHOULD_SWAP_BROWSING_INSTANCE_NO_UNLOAD_HANDLER_EXISTS_ON_SAME_SITE_NAVIGATION =
+ 21;
+ SHOULD_SWAP_BROWSING_INSTANCE_NO_NOT_PRIMARY_MAIN_FRAME = 22;
}
message ShouldSwapBrowsingInstancesResult {
@@ -123,6 +151,13 @@ message FrameTreeNodeInfo {
// Whether there's a speculative RenderFrameHost or not.
optional bool has_speculative_render_frame_host = 3;
+
+ optional RenderFrameHost current_frame_host = 4;
+ optional RenderFrameHost speculative_frame_host = 5;
+
+ // Additional untyped debug information associated with this
+ // FrameTreeNode, populated via TracedProto::AddDebugAnnotations API.
+ repeated DebugAnnotation debug_annotations = 99;
}
message ChromeHashedPerformanceMark {
@@ -130,11 +165,615 @@ message ChromeHashedPerformanceMark {
optional string site = 2;
optional uint32 mark_hash = 3;
optional string mark = 4;
+
+ // A randomly generated unique identifier for a given ExecutionContext
+ // (document, worker, etc). Used to be able to correlate events in a process
+ // where there are multiple execution contexts from the same site.
+ optional uint32 execution_context_id = 5;
+
+ // Indicates the sequence number of this particular mark being emitted from
+ // a particular site in the scope of a single ExecutionContext. Typical
+ // sites emit batches of events that are correlated in time (a thing started,
+ // a thing reached a given milestone, a thing completed). When these events
+ // are intermixed it is useful to know which ones are semantically related.
+ // The value is generated by the content itself, but shifted by a fixed
+ // random offset at runtime so as to limit usage as a side channel.
+ optional uint32 sequence_number = 6;
+}
+
+message ChromeWebAppBadNavigate {
+ optional bool is_kiosk = 1;
+ optional bool has_hosted_app_controller = 2;
+ optional string app_name = 3;
+ optional uint32 system_app_type = 4;
+ optional bool web_app_provider_registry_ready = 5;
+ optional bool system_web_app_manager_synchronized = 6;
+}
+
+// These IDs are generated at compile time and differ for each chrome version.
+// IDs are stable on for a given chrome version but are changing when resources
+// are added or removed to chrome.
+message ResourceBundle {
+ optional uint32 resource_id = 1;
+}
+
+// Information about RenderProcessHost.
+message RenderProcessHost {
+ // Unique Id to identify the RenderProcessHost. This is the browser-side,
+ // persistent id for this RenderProcessHost that stays constant even across OS
+ // layer processes managed by this RenderProcessHost.
+ optional uint32 id = 1;
+ // See ProcessLock::ToString().
+ optional string process_lock = 2;
+ // The PID of the child process.
+ optional int32 child_process_id = 3;
+
+ // Details about the associated browser context.
+ optional ChromeBrowserContext browser_context = 4;
+
+ // Additional untyped debug information associated with this
+ // RenderProcessHost, populated via TracedProto::AddDebugAnnotations API.
+ repeated DebugAnnotation debug_annotations = 99;
+}
+
+message RenderProcessHostListener {
+ // Routing ID of the listener to the RenderProcessHost, recorded when a new ID
+ // is added or when an ID is removed.
+ optional uint32 routing_id = 1;
+}
+
+message RenderProcessHostCleanup {
+ // Number of IPC listeners registered to the host when Cleanup() was called.
+ optional uint32 listener_count = 1;
+ // Number of "keep alive" references active in the RenderProcessHost, recorded
+ // when Cleanup() was called.
+ optional uint32 keep_alive_ref_count = 2;
+ // Number of "shutdown delay" references active in the RenderProcessHost,
+ // recorded when Cleanup() was called.
+ optional uint32 shutdown_delay_ref_count = 3;
+ // Number of "worker delay" references active in the RenderProcessHost,
+ // recorded when Cleanup() was called.
+ optional uint32 worker_ref_count = 4;
+}
+
+message ChildProcessLauncherPriority {
+ // True if the new priority set to background.
+ optional bool is_backgrounded = 1;
+ // True if the renderer proecss has pending views.
+ optional bool has_pending_views = 2;
+
+ // Importance of the child process in Android.
+ enum Importance {
+ IMPORTANCE_NORMAL = 1;
+ IMPORTANCE_MODERATE = 2;
+ IMPORTANCE_IMPORTANT = 3;
+ }
+ optional Importance importance = 3;
+}
+
+// Information that identifies a Chrome Extension.
+message ChromeExtensionId {
+ // Unique id that identifies a Chrome Extension.
+ optional string extension_id = 1;
+
+ // Pseudonymized `extension_id` field (see also
+ // content::PseudonymizationUtil::PseudonymizeString method).
+ optional uint32 pseudonymized_extension_id = 2;
+}
+
+message SiteInstance {
+ // The ID of the SiteInstance.
+ optional int32 site_instance_id = 1;
+
+ // The ID of the BrowsingInstance that the SiteInstance belongs to.
+ optional int32 browsing_instance_id = 2;
+
+ // Whether the SiteInstance is the "default SiteInstance" or not. Non-isolated
+ // sites on Android are not assigned to their own specific per-site process,
+ // and shares SiteInstances with each other (the default SiteInstance).
+ optional bool is_default = 3;
+
+ // Whether this SiteInstance has a running process associated with it.
+ optional bool has_process = 4;
+
+ // Returns the total active WebContents count for this SiteInstance and all
+ // related SiteInstances in the same BrowsingInstance.
+ optional int32 related_active_contents_count = 5;
+
+ // The number of active RenderFrameHosts this SiteInstance's SiteInstanceGroup
+ // has.
+ optional int32 active_rfh_count = 6;
+
+ // The SiteInstanceGroup this SiteInstance belongs to.
+ optional SiteInstanceGroup site_instance_group = 7;
+
+ // Additional untyped debug information associated with this
+ // SiteInstance, populated via TracedProto::AddDebugAnnotations API.
+ repeated DebugAnnotation debug_annotations = 99;
+}
+
+message SiteInstanceGroup {
+ // The ID of the SiteInstanceGroup.
+ optional int32 site_instance_group_id = 1;
+
+ // The number of active frames in this SiteInstanceGroup.
+ optional int32 active_frame_count = 2;
+
+ // The process ID of the SiteInstanceGroup.
+ optional RenderProcessHost process = 3;
+
+ // Additional untyped debug information associated with this
+ // SiteInstanceGroup, populated via TracedProto::AddDebugAnnotations API.
+ repeated DebugAnnotation debug_annotations = 99;
+}
+
+// Next ID: 7
+message RenderViewHost {
+ // The RenderViewHostMapId for the RenderViewHost.
+ optional int32 rvh_map_id = 1;
+
+ // The routing ID for the RenderViewHost.
+ optional int32 routing_id = 2;
+
+ // The process ID of the RenderViewHost. Deprecated in favour of |process|.
+ optional int32 process_id = 3;
+
+ // Process this RenderViewHost is associated with.
+ optional RenderProcessHost process = 6;
+
+ // Whether the RenderViewHost is in back/forward cache or not.
+ optional bool is_in_back_forward_cache = 4;
+
+ // Whether the renderer-side RenderView is created.
+ optional bool renderer_view_created = 5;
+
+ // Additional untyped debug information associated with this
+ // RenderViewHost, populated via TracedProto::AddDebugAnnotations API.
+ repeated DebugAnnotation debug_annotations = 99;
+}
+
+message RenderFrameProxyHost {
+ // The routing ID for the RenderFrameProxyHost.
+ optional int32 routing_id = 1;
+
+ // The process ID of the RenderFrameProxyHost.
+ optional int32 process_id = 2;
+
+ // The RenderViewHostMapId of the RenderViewHost associated with the
+ // RenderFrameProxyHost.
+ optional int32 rvh_map_id = 3;
+
+ // The SiteInstanceId of the SiteInstance associated with the
+ // RenderFrameProxyHost.
+ optional int32 site_instance_id = 4;
+
+ // Whether the renderer-side RenderFrameProxy is live or not.
+ optional bool is_render_frame_proxy_live = 5;
+
+ // The SiteInstanceGroupId of the SiteInstanceGroup associated with the
+ // RenderFrameProxyHost.
+ optional int32 site_instance_group_id = 6;
+
+ // Additional untyped debug information associated with this
+ // RenderFrameProxyHost, populated via TracedProto::AddDebugAnnotations API.
+ repeated DebugAnnotation debug_annotations = 99;
+}
+
+message AndroidView {
+ optional int32 id = 1;
+ optional int32 parent_id = 2;
+ optional bool is_shown = 3;
+ optional bool is_dirty = 4;
+ optional string class_name = 5;
+ optional string resource_name = 6;
+}
+
+message AndroidActivity {
+ optional string name = 1;
+ repeated AndroidView view = 2;
+}
+
+message AndroidViewDump {
+ repeated AndroidActivity activity = 1;
+}
+
+message ParkableStringCompressInBackground {
+ // The size of the string that is being compressed, in bytes.
+ optional int32 size_bytes = 1;
+}
+
+message ParkableStringUnpark {
+ // The size of the string that is being unparked, in bytes.
+ optional int32 size_bytes = 1;
+
+ // The elapsed time since the string was written to disk (in seconds), or -1
+ // if it hadn't yet been written to disk.
+ optional int32 time_since_last_disk_write_sec = 2;
+}
+
+message ChromeSamplingProfilerSampleCollected {
+ optional int32 frame_count = 1;
+
+ enum WriteStatus {
+ WRITE_STATUS_NONE = 0;
+ WRITE_STATUS_BUFFERING_SAMPLE = 1;
+ WRITE_STATUS_WRITING_BUFFERED = 2;
+ WRITE_STATUS_WRITING_TO_TRACE = 3;
+ }
+ optional WriteStatus write_status = 2;
+
+ optional int32 sampled_thread_id = 3;
+}
+
+// Reports the latency caused by each breakdown in the
+// SendBeginMainFrameToCommit stage of the PipelineReporter.
+message SendBeginMainFrameToCommitBreakdown {
+ // Handle input events breakdown
+ optional uint64 handle_input_events_us = 1;
+
+ // Animate breakdown
+ optional uint64 animate_us = 2;
+
+ // Style update breakdown
+ optional uint64 style_update_us = 3;
+
+ // Layout update breakdown
+ optional uint64 layout_update_us = 4;
+
+ // Prepaint breakdown
+ optional uint64 prepaint_us = 5;
+
+ // Compositing inputs breakdown
+ optional uint64 compositing_inputs_us = 6;
+
+ // Compositing assignments breakdown
+ optional uint64 compositing_assignments_us = 7;
+
+ // Paint breakdown
+ optional uint64 paint_us = 8;
+
+ // Composite commit breakdown
+ optional uint64 composite_commit_us = 9;
+
+ // Update layers breakdown
+ optional uint64 update_layers_us = 10;
+
+ // Beginmainsenttostarted breakdown
+ optional uint64 begin_main_sent_to_started_us = 11;
+}
+
+message GlobalRenderFrameHostId {
+ optional int32 routing_id = 1;
+ optional int32 process_id = 2;
+}
+
+message BrowsingContextState {
+ // The ID of the BrowsingInstance that the BrowsingContextState belongs to.
+ optional int32 browsing_instance_id = 1;
+
+ // Additional untyped debug information associated with this
+ // FrameTreeNode, populated via TracedProto::AddDebugAnnotations API.
+ repeated DebugAnnotation debug_annotations = 99;
+}
+
+message RenderFrameHost {
+ optional RenderProcessHost process = 1;
+ optional GlobalRenderFrameHostId render_frame_host_id = 2;
+
+ // NOTE: this proto must be kept consistent with
+ // RenderFrameHostImpl::LifecycleStateImpl.
+ enum LifecycleState {
+ UNSPECIFIED = 0;
+ SPECULATIVE = 1;
+ PENDING_COMMIT = 2;
+ PRERENDERING = 3;
+ ACTIVE = 4;
+ IN_BACK_FORWARD_CACHE = 5;
+ RUNNING_UNLOAD_HANDLERS = 6;
+ READY_TO_BE_DELETED = 7;
+ }
+
+ optional LifecycleState lifecycle_state = 3;
+ optional string origin = 4;
+ optional string url = 5;
+ optional uint64 frame_tree_node_id = 6;
+ optional SiteInstance site_instance = 7;
+ optional RenderFrameHost parent = 8;
+ optional RenderFrameHost outer_document = 9;
+ optional RenderFrameHost embedder = 10;
+ optional BrowsingContextState browsing_context_state = 11;
+
+ // Additional untyped debug information associated with this
+ // RenderViewHost, populated via TracedProto::AddDebugAnnotations API.
+ repeated DebugAnnotation debug_annotations = 99;
+}
+
+message ChromeThreadPoolTask {
+ enum Priority {
+ PRIORITY_UNSPECIFIED = 0;
+ PRIORITY_BEST_EFFORT = 1;
+ PRIORITY_USER_VISIBLE = 2;
+ PRIORITY_USER_BLOCKING = 3;
+ }
+
+ enum ExecutionMode {
+ EXECTUION_MODE_UNSPECIFIED = 0;
+ EXECUTION_MODE_PARALLEL = 1;
+ EXECUTION_MODE_SEQUENCED = 2;
+ EXECUTION_MODE_SINGLE_THREAD = 3;
+ EXECUTION_MODE_JOB = 4;
+ }
+
+ enum ShutdownBehavior {
+ SHUTDOWN_BEHAVIOR_UNSPECIFIED = 0;
+ SHUTDOWN_BEHAVIOR_CONTINUE_ON_SHUTDOWN = 1;
+ SHUTDOWN_BEHAVIOR_SKIP_ON_SHUTDOWN = 2;
+ SHUTDOWN_BEHAVIOR_BLOCK_SHUTDOWN = 3;
+ }
+
+ optional Priority task_priority = 1;
+ optional ExecutionMode execution_mode = 2;
+ optional int64 sequence_token = 3;
+ optional ShutdownBehavior shutdown_behavior = 4;
+}
+
+// TODO(crbug.com/1258495): Add more information.
+message BackForwardCacheCanStoreDocumentResult {
+ enum BackForwardCacheNotRestoredReason {
+ NOT_MAIN_FRAME = 1;
+ // BackForwardCache is disabled due to low memory device, base::Feature or
+ // command line. Note that the more specific NotRestoredReasons
+ // BACK_FORWARD_CACHE_DISABLED_BY_LOW_MEMORY and
+ // BACK_FORWARD_CACHE_DISABLED_BY_COMMAND_LINE will also be set as other
+ // reasons along with this when appropriate.
+ BACK_FORWARD_CACHE_DISABLED = 2;
+ RELATED_ACTIVE_CONTENTS_EXIST = 3;
+ HTTP_STATUS_NOT_OK = 4;
+ SCHEME_NOT_HTTP_OR_HTTPS = 5;
+ LOADING = 6;
+ WAS_GRANTED_MEDIA_ACCESS = 7;
+ BLOCKLISTED_FEATURES = 8;
+ DISABLE_FOR_RENDER_FRAME_HOST_CALLED = 9;
+ DOMAIN_NOT_ALLOWED = 10;
+ HTTP_METHOD_NOT_GET = 11;
+ SUBFRAME_IS_NAVIGATING = 12;
+ TIMEOUT = 13;
+ CACHE_LIMIT = 14;
+ JAVASCRIPT_EXECUTION = 15;
+ RENDERER_PROCESS_KILLED = 16;
+ RENDERER_PROCESS_CRASHED = 17;
+ GRANTED_MEDIA_STREAM_ACCESS = 19;
+ SCHEDULER_TRACKED_FEATURE_USED = 20;
+ CONFLICTING_BROWSING_INSTANCE = 21;
+ CACHE_FLUSHED = 22;
+ SERVICE_WORKER_VERSION_ACTIVATION = 23;
+ SESSION_RESTORED = 24;
+ UNKNOWN = 25;
+ SERVICE_WORKER_POST_MESSAGE = 26;
+ ENTERED_BACK_FORWARD_CACHE_BEFORE_SERVICE_WORKER_HOST_ADDED = 27;
+ NOT_MOST_RECENT_NAVIGATION_ENTRY = 28;
+ SERVICE_WORKER_CLAIM = 29;
+ IGNORE_EVENT_AND_EVICT = 30;
+ HAVE_INNER_CONTENTS = 31;
+ TIMEOUT_PUTTING_IN_CACHE = 32;
+ // BackForwardCache is disabled due to low memory device.
+ BACK_FORWARD_CACHE_DISABLED_BY_LOW_MEMORY = 33;
+ // BackForwardCache is disabled due to command-line switch (may include
+ // cases where the embedder disabled it due to, e.g., enterprise policy).
+ BACK_FORWARD_CACHE_DISABLED_BY_COMMAND_LINE = 34;
+ NETWORK_REQUEST_REDIRECTED = 35;
+ NETWORK_REQUEST_TIMEOUT = 36;
+ NETWORK_EXCEEDS_BUFFER_LIMIT = 37;
+ NAVIGATION_CANCELLED_WHILE_RESTORING = 38;
+ BACK_FORWARD_CACHE_DISABLED_FOR_PRERENDER = 39;
+ USER_AGENT_OVERRIDE_DIFFERS = 40;
+ NETWORK_REQUEST_DATAPIPE_DRAINED_AS_BYTES_CONSUMER = 41;
+ FOREGROUND_CACHE_LIMIT = 42;
+ BROWSING_INSTANCE_NOT_SWAPPED = 43;
+ BACK_FORWARD_CACHE_DISABLED_FOR_DELEGATE = 44;
+ OPT_IN_UNLOAD_HEADER_NOT_PRESENT = 45;
+ UNLOAD_HANDLER_EXISTS_IN_MAIN_FRAME = 46;
+ UNLOAD_HANDLER_EXISTS_IN_SUBFRAME = 47;
+ SERVICE_WORKER_UNREGISTRATION = 48;
+ CACHE_CONTROL_NO_STORE = 49;
+ CACHE_CONTROL_NO_STORE_COOKIE_MODIFIED = 50;
+ CACHE_CONTROL_NO_STORE_HTTP_ONLY_COOKIE_MODIFIED = 51;
+ NO_RESPONSE_HEAD = 52;
+ ACTIVATION_NAVIGATION_DISALLOWED_FOR_BUG_1234857 = 53;
+ ERROR_DOCUMENT = 54;
+ FENCED_FRAMES_EMBEDDER = 55;
+ }
+
+ optional BackForwardCacheNotRestoredReason
+ back_forward_cache_not_restored_reason = 1;
+}
+
+message RendererMainThreadTaskExecution {
+ enum TaskType {
+ TASK_TYPE_UNKNOWN = 0;
+ TASK_TYPE_DOM_MANIPULATION = 1;
+ TASK_TYPE_USER_INTERACTION = 2;
+ TASK_TYPE_NETWORKING = 3;
+ TASK_TYPE_NETWORKING_CONTROL = 4;
+ TASK_TYPE_HISTORY_TRAVERSAL = 5;
+ TASK_TYPE_EMBED = 6;
+ TASK_TYPE_MEDIA_ELEMENT_EVENT = 7;
+ TASK_TYPE_CANVAS_BLOB_SERIALIZATION = 8;
+ TASK_TYPE_MICROTASK = 9;
+ TASK_TYPE_JAVASCRIPT_TIMER_DELAYED_HIGH_NESTING = 10;
+ TASK_TYPE_REMOTE_EVENT = 11;
+ TASK_TYPE_WEB_SOCKET = 12;
+ TASK_TYPE_POSTED_MESSAGE = 13;
+ TASK_TYPE_UNSHIPPED_PORT_MESSAGE = 14;
+ TASK_TYPE_FILE_READING = 15;
+ TASK_TYPE_DATABASE_ACCESS = 16;
+ TASK_TYPE_PRESENTATION = 17;
+ TASK_TYPE_SENSOR = 18;
+ TASK_TYPE_PERFORMANCE_TIMELINE = 19;
+ TASK_TYPE_WEB_GL = 20;
+ TASK_TYPE_IDLE_TASK = 21;
+ TASK_TYPE_MISC_PLATFORM_API = 22;
+ TASK_TYPE_INTERNAL_DEFAULT = 23;
+ TASK_TYPE_INTERNAL_LOADING = 24;
+
+ TASK_TYPE_INTERNAL_TEST = 26;
+ TASK_TYPE_INTERNAL_WEB_CRYPTO = 27;
+
+ TASK_TYPE_INTERNAL_MEDIA = 29;
+ TASK_TYPE_INTERNAL_MEDIA_REALTIME = 30;
+
+ TASK_TYPE_INTERNAL_USER_INTERACTION = 32;
+ TASK_TYPE_INTERNAL_INSPECTOR = 33;
+
+ TASK_TYPE_MAIN_THREAD_TASK_QUEUE_V8 = 37;
+ TASK_TYPE_MAIN_THREAD_TASK_QUEUE_COMPOSITOR = 38;
+ TASK_TYPE_MAIN_THREAD_TASK_QUEUE_DEFAULT = 39;
+ TASK_TYPE_MAIN_THREAD_TASK_QUEUE_INPUT = 40;
+ TASK_TYPE_MAIN_THREAD_TASK_QUEUE_IDLE = 41;
+
+ TASK_TYPE_MAIN_THREAD_TASK_QUEUE_CONTROL = 43;
+ TASK_TYPE_INTERNAL_INTERSECTION_OBSERVER = 44;
+ TASK_TYPE_COMPOSITOR_THREAD_TASK_QUEUE_DEFAULT = 45;
+ TASK_TYPE_WORKER_THREAD_TASK_QUEUE_DEFAULT = 46;
+ TASK_TYPE_WORKER_THREAD_TASK_QUEUE_V8 = 47;
+ TASK_TYPE_WORKER_THREAD_TASK_QUEUE_COMPOSITOR = 48;
+ TASK_TYPE_COMPOSITOR_THREAD_TASK_QUEUE_INPUT = 49;
+ TASK_TYPE_NETWORKING_WITH_URL_LOADER_ANNOTATION = 50;
+ TASK_TYPE_WORKER_ANIMATION = 51;
+
+ TASK_TYPE_INTERNAL_TRANSLATION = 55;
+ TASK_TYPE_FONT_LOADING = 56;
+ TASK_TYPE_APPLICATION_LIFECYCLE = 57;
+ TASK_TYPE_BACKGROUND_FETCH = 58;
+ TASK_TYPE_PERMISSION = 59;
+ TASK_TYPE_SERVICE_WORKER_CLIENT_MESSAGE = 60;
+ TASK_TYPE_INTERNAL_CONTENT_CAPTURE = 61;
+ TASK_TYPE_MAIN_THREAD_TASK_QUEUE_MEMORY_PURGE = 62;
+ TASK_TYPE_INTERNAL_NAVIGATION_ASSOCIATED = 63;
+ TASK_TYPE_INTERNAL_NAVIGATION_ASSOCIATED_UNFREEZABLE = 64;
+ TASK_TYPE_INTERNAL_CONTINUE_SCRIPT_LOADING = 65;
+ TASK_TYPE_WEB_LOCKS = 66;
+ TASK_TYPE_WEB_SCHEDULING_POSTED_TASK = 67;
+ TASK_TYPE_INTERNAL_FRAME_LIFE_CYCLE_CONTROL = 68;
+ TASK_TYPE_MAIN_THREAD_TASK_QUEUE_NON_WAKING = 69;
+ TASK_TYPE_INTERNAL_FIND_IN_PAGE = 70;
+ TASK_TYPE_INTERNAL_HIGH_PRIORITY_LOCAL_FRAME = 71;
+ TASK_TYPE_JAVASCRIPT_TIMER_IMMEDIATE = 72;
+ TASK_TYPE_JAVASCRIPT_TIMER_DELAYED_LOW_NESTING = 73;
+ TASK_TYPE_MAIN_THREAD_TASK_QUEUE_IPC_TRACKING = 74;
+ TASK_TYPE_NETWORKING_UNFREEZABLE = 75;
+ TASK_TYPE_WAKE_LOCK = 76;
+ TASK_TYPE_INTERNAL_INPUT_BLOCKING = 77;
+ TASK_TYPE_WEB_GPU = 78;
+ TASK_TYPE_INTERNAL_POST_MESSAGE_FORWARDING = 79;
+ }
+
+ enum FrameType {
+ FRAME_TYPE_UNSPECIFIED = 0;
+ FRAME_TYPE_MAIN_FRAME = 1;
+ FRAME_TYPE_SAME_ORIGIN_SUBFRAME = 2;
+ FRAME_TYPE_CROSS_ORIGIN_SUBFRAME = 3;
+ }
+
+ optional TaskType task_type = 1;
+
+ // FrameScheduler related data
+ optional bool frame_visible = 2;
+ optional bool page_visible = 3;
+ optional FrameType frame_type = 4;
+}
+
+message EventLatency {
+ enum EventType {
+ EVENT_TYPE_UNSPECIFIED = 0;
+ MOUSE_PRESSED = 1;
+ MOUSE_RELEASED = 2;
+ MOUSE_WHEEL = 3;
+ KEY_PRESSED = 4;
+ KEY_RELEASED = 5;
+ TOUCH_PRESSED = 6;
+ TOUCH_RELEASED = 7;
+ TOUCH_MOVED = 8;
+ GESTURE_SCROLL_BEGIN = 9;
+ GESTURE_SCROLL_UPDATE = 10;
+ GESTURE_SCROLL_END = 11;
+ GESTURE_DOUBLE_TAP = 12;
+ GESTURE_LONG_PRESS = 13;
+ GESTURE_LONG_TAP = 14;
+ GESTURE_SHOW_PRESS = 15;
+ GESTURE_TAP = 16;
+ GESTURE_TAP_CANCEL = 17;
+ GESTURE_TAP_DOWN = 18;
+ GESTURE_TAP_UNCONFIRMED = 19;
+ GESTURE_TWO_FINGER_TAP = 20;
+ FIRST_GESTURE_SCROLL_UPDATE = 21;
+ MOUSE_DRAGGED = 22;
+ GESTURE_PINCH_BEGIN = 23;
+ GESTURE_PINCH_END = 24;
+ GESTURE_PINCH_UPDATE = 25;
+ INERTIAL_GESTURE_SCROLL_UPDATE = 26;
+ }
+
+ optional EventType event_type = 1;
+}
+
+message ProcessSingleton {
+ enum RemoteProcessInteractionResult {
+ INTERACTION_RESULT_UNSPECIFIED = 0;
+ TERMINATE_FAILED = 1;
+ REMOTE_PROCESS_NOT_FOUND = 2;
+ TERMINATE_WAIT_TIMEOUT = 3;
+ RUNNING_PROCESS_NOTIFY_ERROR = 4;
+ TERMINATE_NOT_ENOUGH_PERMISSIONS = 5;
+ REMOTE_PROCESS_SHUTTING_DOWN = 6;
+ PROFILE_UNLOCKED = 7;
+ PROFILE_UNLOCKED_BEFORE_KILL = 8;
+ SAME_BROWSER_INSTANCE = 9;
+ SAME_BROWSER_INSTANCE_BEFORE_KILL = 10;
+ FAILED_TO_EXTRACT_PID = 11;
+ INVALID_LOCK_FILE = 12;
+ ORPHANED_LOCK_FILE = 13;
+ USER_REFUSED_TERMINATION = 14;
+ TERMINATE_SUCCEEDED = 100;
+ }
+
+ enum RemoteHungProcessTerminateReason {
+ TERMINATE_REASON_UNSPECIFIED = 0;
+ USER_ACCEPTED_TERMINATION = 1;
+ NO_VISIBLE_WINDOW_FOUND = 2;
+ NOTIFY_ATTEMPTS_EXCEEDED = 3;
+ SOCKET_WRITE_FAILED = 4;
+ SOCKET_READ_FAILED = 5;
+ }
+
+ optional RemoteProcessInteractionResult remote_process_interaction_result = 1;
+ optional RemoteHungProcessTerminateReason remote_process_terminate_reason = 2;
+}
+
+message NavigationHandle {
+ optional int64 navigation_id = 1;
+ optional bool has_committed = 2;
+ optional bool is_error_page = 3;
+ optional FrameTreeNodeInfo frame_tree_node = 4;
+ optional RenderFrameHost render_frame_host = 5;
+
+ // Additional untyped debug information associated with this
+ // NavigationHandle/Request, populated via TracedProto::AddDebugAnnotations
+ // API.
+ repeated DebugAnnotation debug_annotations = 99;
+}
+
+enum DeviceThermalState {
+ DEVICE_THERMAL_STATE_UNKNOWN = 0;
+ DEVICE_THERMAL_STATE_NOMINAL = 1;
+ DEVICE_THERMAL_STATE_FAIR = 2;
+ DEVICE_THERMAL_STATE_SERIOUS = 3;
+ DEVICE_THERMAL_STATE_CRITICAL = 4;
}
message ChromeTrackEvent {
// Extension range for Chrome: 1000-1999
- // Next ID: 1012
+ // Next ID: 1037
extend TrackEvent {
optional ChromeAppState chrome_app_state = 1000;
@@ -162,5 +801,59 @@ message ChromeTrackEvent {
optional FrameTreeNodeInfo frame_tree_node_info = 1010;
optional ChromeHashedPerformanceMark chrome_hashed_performance_mark = 1011;
+
+ optional RenderProcessHost render_process_host = 1012;
+ optional RenderProcessHostCleanup render_process_host_cleanup = 1013;
+ optional RenderProcessHostListener render_process_host_listener_changed =
+ 1014;
+ optional ChildProcessLauncherPriority child_process_launcher_priority =
+ 1015;
+
+ optional ResourceBundle resource_bundle = 1016;
+
+ optional ChromeWebAppBadNavigate chrome_web_app_bad_navigate = 1017;
+
+ optional ChromeExtensionId chrome_extension_id = 1018;
+
+ optional SiteInstance site_instance = 1019;
+
+ optional RenderViewHost render_view_host = 1020;
+
+ optional RenderFrameProxyHost render_frame_proxy_host = 1021;
+
+ optional AndroidViewDump android_view_dump = 1022;
+
+ optional ParkableStringCompressInBackground
+ parkable_string_compress_in_background = 1023;
+ optional ParkableStringUnpark parkable_string_unpark = 1024;
+
+ optional ChromeSamplingProfilerSampleCollected
+ chrome_sampling_profiler_sample_completed = 1025;
+ optional SendBeginMainFrameToCommitBreakdown
+ send_begin_mainframe_to_commit_breakdown = 1026;
+
+ optional GlobalRenderFrameHostId global_render_frame_host_id = 1027;
+
+ optional RenderFrameHost render_frame_host = 1028;
+
+ optional ChromeThreadPoolTask thread_pool_task = 1029;
+
+ optional BackForwardCacheCanStoreDocumentResult
+ back_forward_cache_can_store_document_result = 1030;
+
+ optional RendererMainThreadTaskExecution
+ renderer_main_thread_task_execution = 1031;
+
+ optional EventLatency event_latency = 1032;
+
+ optional ProcessSingleton process_singleton = 1033;
+
+ optional SiteInstanceGroup site_instance_group = 1034;
+
+ optional BrowsingContextState browsing_context_state = 1035;
+
+ optional DeviceThermalState device_thermal_state = 1036;
+
+ optional NavigationHandle navigation = 1037;
}
}
diff --git a/protos/third_party/pprof/BUILD.gn b/protos/third_party/pprof/BUILD.gn
index 553d0acab..adbdf95a2 100644
--- a/protos/third_party/pprof/BUILD.gn
+++ b/protos/third_party/pprof/BUILD.gn
@@ -15,6 +15,9 @@
import("../../../gn/proto_library.gni")
perfetto_proto_library("@TYPE@") {
- proto_generators = [ "zero" ]
+ proto_generators = [
+ "zero",
+ "source_set",
+ ]
sources = [ "profile.proto" ]
}
diff --git a/python/BUILD b/python/BUILD
new file mode 100644
index 000000000..6f9830198
--- /dev/null
+++ b/python/BUILD
@@ -0,0 +1,107 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+load("@perfetto_cfg//:perfetto_cfg.bzl", "PERFETTO_CONFIG")
+load(
+ "@perfetto//bazel:rules.bzl",
+ "perfetto_py_binary",
+ "perfetto_py_library",
+)
+
+licenses(["notice"])
+
+package(default_visibility = ["//visibility:private"])
+
+perfetto_py_binary(
+ name = "trace_processor_py_example",
+ srcs = ["example.py"],
+ deps = [":trace_processor_py"] + PERFETTO_CONFIG.deps.pandas_py,
+ main = "example.py",
+ python_version = "PY3",
+)
+
+perfetto_py_library(
+ name = "trace_processor_py",
+ srcs = glob(["perfetto/trace_processor/*.py"]),
+ data = [
+ ":trace_uri_resolver",
+ "perfetto/trace_processor/trace_processor.descriptor",
+ "perfetto/trace_processor/metrics.descriptor",
+ PERFETTO_CONFIG.root + ":trace_processor_shell",
+ ],
+ deps = PERFETTO_CONFIG.deps.tp_vendor_py +
+ PERFETTO_CONFIG.deps.protobuf_py +
+ PERFETTO_CONFIG.deps.pandas_py,
+ imports = [
+ ".",
+ ],
+ visibility = PERFETTO_CONFIG.public_visibility,
+)
+
+perfetto_py_library(
+ name = "trace_uri_resolver",
+ srcs = glob(["perfetto/trace_uri_resolver/*.py"]),
+ imports = [
+ ".",
+ ],
+)
+
+perfetto_py_library(
+ name = "experimental_slice_breakdown_lib",
+ srcs = glob(["perfetto/experimental/slice_breakdown/*.py"]),
+ deps = [
+ ":trace_processor_py",
+ ],
+ imports = [
+ "tools/slice_breakdown",
+ ],
+)
+
+perfetto_py_binary(
+ name = "experimental_slice_breakdown_bin",
+ srcs = ["tools/slice_breakdown.py"],
+ main = "tools/slice_breakdown.py",
+ deps = [
+ ":experimental_slice_breakdown_lib",
+ ":trace_processor_py",
+ ] + PERFETTO_CONFIG.deps.pandas_py,
+ python_version = "PY3",
+ legacy_create_init = 0,
+)
+
+perfetto_py_library(
+ name = "batch_trace_processor",
+ srcs = glob([
+ "perfetto/batch_trace_processor/*.py"
+ ]),
+ deps = [
+ ":trace_processor_py",
+ ] + PERFETTO_CONFIG.deps.pandas_py +
+ PERFETTO_CONFIG.deps.tp_vendor_py,
+ imports = [
+ ".",
+ ],
+)
+
+perfetto_py_binary(
+ name = "batch_trace_processor_shell",
+ srcs = ["tools/batch_trace_processor_shell.py"],
+ main = "tools/batch_trace_processor_shell.py",
+ deps = [
+ ":trace_processor_py",
+ ":batch_trace_processor",
+ ] + PERFETTO_CONFIG.deps.pandas_py,
+ python_version = "PY3",
+ legacy_create_init = 0,
+)
diff --git a/src/trace_processor/python/LICENSE b/python/LICENSE
index ab4c4a21b..ab4c4a21b 100644
--- a/src/trace_processor/python/LICENSE
+++ b/python/LICENSE
diff --git a/src/trace_processor/python/README.md b/python/README.md
index 3ef343078..3ef343078 100644
--- a/src/trace_processor/python/README.md
+++ b/python/README.md
diff --git a/python/example.py b/python/example.py
new file mode 100644
index 000000000..ffdd9ace4
--- /dev/null
+++ b/python/example.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python3
+# Copyright (C) 2020 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import argparse
+
+from perfetto.trace_processor import TraceProcessor, TraceProcessorConfig
+
+
+def main():
+ # Parse arguments passed from command line
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ "-a",
+ "--address",
+ help="Address at which trace_processor is being run, e.g. localhost:9001",
+ type=str)
+ parser.add_argument(
+ "-b",
+ "--binary",
+ help="Absolute path to a trace processor binary",
+ type=str)
+ parser.add_argument("-f", "--file", help="Absolute path to trace", type=str)
+ args = parser.parse_args()
+
+ config = TraceProcessorConfig(bin_path=args.binary)
+
+ # Pass arguments into api to construct the trace processor and load the trace
+ if args.address is None and args.file is None:
+ raise Exception("You must specify an address or a file path to trace")
+ elif args.address is None:
+ tp = TraceProcessor(trace=args.file, config=config)
+ elif args.file is None:
+ tp = TraceProcessor(addr=args.address, config=config)
+ else:
+ tp = TraceProcessor(trace=args.file, addr=args.address, config=config)
+
+ # Iterate through QueryResultIterator
+ res_it = tp.query('select * from slice limit 10')
+ for row in res_it:
+ print(row.name)
+
+ # Convert QueryResultIterator into a pandas dataframe + iterate. This yields
+ # the same results as the function above.
+ try:
+ res_df = tp.query('select * from slice limit 10').as_pandas_dataframe()
+ for index, row in res_df.iterrows():
+ print(row['name'])
+ except Exception:
+ pass
+
+ # Call another function on the loaded trace
+ am_metrics = tp.metric(['android_mem'])
+ tp.close()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/trace_processor/python/perfetto/__init__.py b/python/perfetto/__init__.py
index c56906938..c56906938 100644
--- a/src/trace_processor/python/perfetto/__init__.py
+++ b/python/perfetto/__init__.py
diff --git a/python/perfetto/batch_trace_processor/__init__.py b/python/perfetto/batch_trace_processor/__init__.py
new file mode 100644
index 000000000..3ecbffc17
--- /dev/null
+++ b/python/perfetto/batch_trace_processor/__init__.py
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from perfetto.batch_trace_processor.api import TraceListReference
+from perfetto.batch_trace_processor.api import BatchTraceProcessorConfig
+from perfetto.batch_trace_processor.api import BatchTraceProcessor
diff --git a/python/perfetto/batch_trace_processor/api.py b/python/perfetto/batch_trace_processor/api.py
new file mode 100644
index 000000000..c26a8e653
--- /dev/null
+++ b/python/perfetto/batch_trace_processor/api.py
@@ -0,0 +1,368 @@
+#!/usr/bin/env python3
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Contains classes for BatchTraceProcessor API."""
+
+import concurrent.futures as cf
+import dataclasses as dc
+from enum import Enum
+import multiprocessing
+from typing import Any, Callable, Dict, Tuple, List, Optional
+
+import pandas as pd
+
+from perfetto.batch_trace_processor.platform import PlatformDelegate
+from perfetto.trace_processor.api import PLATFORM_DELEGATE as TP_PLATFORM_DELEGATE
+from perfetto.trace_processor.api import TraceProcessor
+from perfetto.trace_processor.api import TraceProcessorException
+from perfetto.trace_processor.api import TraceProcessorConfig
+from perfetto.trace_uri_resolver import registry
+from perfetto.trace_uri_resolver.registry import ResolverRegistry
+
+# Defining this field as a module variable means this can be changed by
+# implementations at startup and used for all BatchTraceProcessor objects
+# without having to specify on each one.
+# In Google3, this field is rewritten using Copybara to a implementation
+# which can integrates with internal infra.
+PLATFORM_DELEGATE = PlatformDelegate
+
+TraceListReference = registry.TraceListReference
+Metadata = Dict[str, str]
+
+
+# Enum encoding how errors while loading/querying traces in BatchTraceProcessor
+# should be handled.
+class FailureHandling(Enum):
+ # If any trace fails to load or be queried, raises an exception causing the
+ # entire batch trace processor to fail.
+ # This is the default behaviour and the method which should be preferred for
+ # any interactive use of BatchTraceProcessor.
+ RAISE_EXCEPTION = 0
+
+ # If a trace fails to load or be queried, the trace processor for that trace
+ # is dropped but loading of other traces is unaffected. A failure integer is
+ # incremented in the Stats class for the batch trace processor instance.
+ INCREMENT_STAT = 1
+
+
+@dc.dataclass
+class BatchTraceProcessorConfig:
+ tp_config: TraceProcessorConfig
+ load_failure_handling: FailureHandling
+ query_failure_handling: FailureHandling
+
+ def __init__(
+ self,
+ tp_config: TraceProcessorConfig = TraceProcessorConfig(),
+ load_failure_handling: FailureHandling = FailureHandling.RAISE_EXCEPTION,
+ execute_failure_handling: FailureHandling = FailureHandling
+ .RAISE_EXCEPTION,
+ ):
+ self.tp_config = tp_config
+ self.load_failure_handling = load_failure_handling
+ self.execute_failure_handling = execute_failure_handling
+
+
+# Contains stats about the events which happened during the use of
+# BatchTraceProcessor.
+@dc.dataclass
+class Stats:
+ # The number of traces which failed to load; only non-zero if
+ # FailureHanding.INCREMENT_STAT is chosen as the load failure handling type.
+ load_failures: int = 0
+
+ # The number of traces which failed while executing (query, metric or
+ # arbitary function); only non-zero if FailureHanding.INCREMENT_STAT is
+ # chosen as the execute failure handling type.
+ execute_failures: int = 0
+
+
+class BatchTraceProcessor:
+ """Run ad-hoc SQL queries across many Perfetto traces.
+
+ Usage:
+ with BatchTraceProcessor(traces) as btp:
+ dfs = btp.query('select * from slice')
+ for df in dfs:
+ print(df)
+ """
+
+ def __init__(self,
+ traces: TraceListReference,
+ config: BatchTraceProcessorConfig = BatchTraceProcessorConfig()):
+ """Creates a batch trace processor instance.
+
+ BatchTraceProcessor is the blessed way of running ad-hoc queries in
+ Python across many traces.
+
+ Args:
+ traces: A list of traces, a trace URI resolver or a URI which
+ can be resolved to a list of traces.
+
+ If a list, each of items must be one of the following types:
+ 1) path to a trace file to open and read
+ 2) a file like object (file, io.BytesIO or similar) to read
+ 3) a generator yielding bytes
+ 4) an URI which resolves to a trace
+
+ A trace URI resolver is a subclass of resolver.TraceUriResolver
+ which generates a list of trace references when the |resolve|
+ method is called on it.
+
+ A URI is similar to a connection string (e.g. for a web
+ address or SQL database) which specifies where to lookup traces
+ and which traces to pick from this data source. The format of a
+ string should be as follows:
+ resolver_name:key_1=list,of,values;key_2=value
+
+ Custom resolvers can be provided to handle URIs via
+ |config.resolver_registry|.
+ config: configuration options which customize functionality of batch
+ trace processor and underlying trace processors.
+ """
+
+ self.tps_and_metadata = None
+ self.closed = False
+ self._stats = Stats()
+
+ self.platform_delegate = PLATFORM_DELEGATE()
+ self.tp_platform_delegate = TP_PLATFORM_DELEGATE()
+ self.config = config
+
+ # Make sure the descendent trace processors are using the same resolver
+ # registry (even though they won't actually use it as we will resolve
+ # everything fully in this class).
+ self.resolver_registry = config.tp_config.resolver_registry or \
+ self.tp_platform_delegate.default_resolver_registry()
+ self.config.tp_config.resolver_registry = self.resolver_registry
+
+ # Resolve all the traces to their final form.
+ resolved = self.resolver_registry.resolve(traces)
+
+ # As trace processor is completely CPU bound, it makes sense to just
+ # max out the CPUs available.
+ query_executor = self.platform_delegate.create_query_executor(
+ len(resolved)) or cf.ThreadPoolExecutor(
+ max_workers=multiprocessing.cpu_count())
+ load_exectuor = self.platform_delegate.create_load_executor(
+ len(resolved)) or query_executor
+
+ self.query_executor = query_executor
+ self.tps_and_metadata = [
+ x for x in load_exectuor.map(self._create_tp, resolved) if x is not None
+ ]
+
+ def metric(self, metrics: List[str]):
+ """Computes the provided metrics.
+
+ The computation happens in parallel across all the traces.
+
+ Args:
+ metrics: A list of valid metrics as defined in TraceMetrics
+
+ Returns:
+ A list of TraceMetric protos (one for each trace).
+ """
+ return self.execute(lambda tp: tp.metric(metrics))
+
+ def query(self, sql: str):
+ """Executes the provided SQL statement (returning a single row).
+
+ The execution happens in parallel across all the traces.
+
+ Args:
+ sql: The SQL statement to execute.
+
+ Returns:
+ A list of Pandas dataframes with the result of executing the query (one
+ per trace).
+
+ Raises:
+ TraceProcessorException: An error occurred running the query.
+ """
+ return self.execute(lambda tp: tp.query(sql).as_pandas_dataframe())
+
+ def query_and_flatten(self, sql: str):
+ """Executes the provided SQL statement and flattens the result.
+
+ The execution happens in parallel across all the traces and the
+ resulting Pandas dataframes are flattened into a single dataframe.
+
+ Args:
+ sql: The SQL statement to execute.
+
+ Returns:
+ A concatenated Pandas dataframe containing the result of executing the
+ query across all the traces.
+
+ If an URI or a trace resolver was passed to the constructor, the
+ contents of the |metadata| dictionary emitted by the resolver will also
+ be emitted as extra columns (key being column name, value being the
+ value in the dataframe).
+
+ For example:
+ class CustomResolver(TraceResolver):
+ def resolve(self):
+ return [TraceResolver.Result(trace='/tmp/path',
+ metadata={
+ 'path': '/tmp/path'
+ 'foo': 'bar'
+ })]
+
+ with BatchTraceProcessor(CustomResolver()) as btp:
+ df = btp.query_and_flatten('select count(1) as cnt from slice')
+
+ Then df will look like this:
+ cnt path foo
+ 100 /tmp/path bar
+
+ Raises:
+ TraceProcessorException: An error occurred running the query.
+ """
+ return self.execute_and_flatten(lambda tp: tp.query(sql).
+ as_pandas_dataframe())
+
+ def query_single_result(self, sql: str):
+ """Executes the provided SQL statement (returning a single row).
+
+ The execution happens in parallel across all the traces.
+
+ Args:
+ sql: The SQL statement to execute. This statement should return exactly
+ one row on any trace.
+
+ Returns:
+ A list of values with the result of executing the query (one per trace).
+
+ Raises:
+ TraceProcessorException: An error occurred running the query or more than
+ one result was returned.
+ """
+
+ def query_single_result_inner(tp):
+ df = tp.query(sql).as_pandas_dataframe()
+ if len(df.index) != 1:
+ raise TraceProcessorException("Query should only return a single row")
+
+ if len(df.columns) != 1:
+ raise TraceProcessorException(
+ "Query should only return a single column")
+
+ return df.iloc[0, 0]
+
+ return self.execute(query_single_result_inner)
+
+ def execute(self, fn: Callable[[TraceProcessor], Any]) -> List[Any]:
+ """Executes the provided function.
+
+ The execution happens in parallel across all the trace processor instances
+ owned by this object.
+
+ Args:
+ fn: The function to execute.
+
+ Returns:
+ A list of values with the result of executing the fucntion (one per
+ trace).
+ """
+
+ def wrapped(pair: Tuple[TraceProcessor, Metadata]):
+ (tp, metadata) = pair
+ return self._execute_handling_failure(fn, tp, metadata)
+
+ return list(self.query_executor.map(wrapped, self.tps_and_metadata))
+
+ def execute_and_flatten(self, fn: Callable[[TraceProcessor], pd.DataFrame]
+ ) -> pd.DataFrame:
+ """Executes the provided function and flattens the result.
+
+ The execution happens in parallel across all the trace processor
+ instances owned by this object and the returned Pandas dataframes are
+ flattened into a single dataframe.
+
+ Args:
+ fn: The function to execute which returns a Pandas dataframe.
+
+ Returns:
+ A Pandas dataframe containing the result of executing the query across all
+ the traces. Extra columns containing the file path and args will
+ be added to the dataframe (see |query_and_flatten| for details).
+ """
+
+ def wrapped(pair: Tuple[TraceProcessor, Metadata]):
+ (tp, metadata) = pair
+ df = self._execute_handling_failure(fn, tp, metadata)
+ for key, value in metadata.items():
+ df[key] = value
+ return df
+
+ df = pd.concat(
+ list(self.query_executor.map(wrapped, self.tps_and_metadata)))
+ return df.reset_index(drop=True)
+
+ def close(self):
+ """Closes this batch trace processor instance.
+
+ This closes all spawned trace processor instances, releasing all the memory
+ and resources those instances take.
+
+ No further calls to other methods in this class should be made after
+ calling this method.
+ """
+ if self.closed:
+ return
+ self.closed = True
+
+ if self.tps_and_metadata:
+ for tp, _ in self.tps_and_metadata:
+ tp.close()
+
+ def stats(self):
+ """Statistics about the operation of this batch trace processor instance.
+
+ See |Stats| class definition for the list of the statistics available."""
+ return self._stats
+
+ def _create_tp(self, trace: ResolverRegistry.Result
+ ) -> Optional[Tuple[TraceProcessor, Metadata]]:
+ try:
+ return TraceProcessor(
+ trace=trace.generator, config=self.config.tp_config), trace.metadata
+ except TraceProcessorException as ex:
+ if self.config.load_failure_handling == FailureHandling.RAISE_EXCEPTION:
+ raise ex
+ self._stats.load_failures += 1
+ return None
+
+ def _execute_handling_failure(self, fn: Callable[[TraceProcessor], Any],
+ tp: TraceProcessor, metadata: Metadata):
+ try:
+ return fn(tp)
+ except TraceProcessorException as ex:
+ if self.config.execute_failure_handling == \
+ FailureHandling.RAISE_EXCEPTION:
+ raise TraceProcessorException(f'{metadata} {ex}') from None
+ self._stats.execute_failures += 1
+ return pd.DataFrame()
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, a, b, c):
+ del a, b, c # Unused.
+ self.close()
+ return False
+
+ def __del__(self):
+ self.close()
diff --git a/python/perfetto/batch_trace_processor/platform.py b/python/perfetto/batch_trace_processor/platform.py
new file mode 100644
index 000000000..677c8a52b
--- /dev/null
+++ b/python/perfetto/batch_trace_processor/platform.py
@@ -0,0 +1,28 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import concurrent.futures as cf
+from typing import Optional
+
+
+class PlatformDelegate:
+ """Abstracts operations which can vary based on platform."""
+
+ def create_query_executor(self, trace_count: int
+ ) -> Optional[cf.ThreadPoolExecutor]:
+ return None
+
+ def create_load_executor(self,
+ trace_count: int) -> Optional[cf.ThreadPoolExecutor]:
+ return None
diff --git a/python/perfetto/experimental/slice_breakdown/__init__.py b/python/perfetto/experimental/slice_breakdown/__init__.py
new file mode 100644
index 000000000..53d1e85d3
--- /dev/null
+++ b/python/perfetto/experimental/slice_breakdown/__init__.py
@@ -0,0 +1,16 @@
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from perfetto.experimental.slice_breakdown.breakdown import compute_breakdown
+from perfetto.experimental.slice_breakdown.breakdown import compute_breakdown_for_startup \ No newline at end of file
diff --git a/python/perfetto/experimental/slice_breakdown/breakdown.py b/python/perfetto/experimental/slice_breakdown/breakdown.py
new file mode 100644
index 000000000..9eb99defe
--- /dev/null
+++ b/python/perfetto/experimental/slice_breakdown/breakdown.py
@@ -0,0 +1,194 @@
+#!/usr/bin/env python3
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from perfetto.trace_processor.api import TraceProcessor
+from perfetto.trace_processor.api import TraceProcessorException
+
+
+def compute_breakdown(tp: TraceProcessor,
+ start_ts=None,
+ end_ts=None,
+ process_name=None):
+ """For each userspace slice in the trace processor instance |tp|, computes
+ the self-time of that slice grouping by process name, thread name
+ and thread state.
+
+ Args:
+ tp: the trace processor instance to query.
+ start_ts: optional bound to only consider slices after this ts
+ end_ts: optional bound to only consider slices until this ts
+ process_name: optional process name to filter for slices; specifying
+ this argument can make computing the breakdown a lot faster.
+
+ Returns:
+ A Pandas dataframe containing the total self time taken by a slice stack
+ broken down by process name, thread name and thread state.
+ """
+ bounds = tp.query('SELECT * FROM trace_bounds').as_pandas_dataframe()
+ start_ts = start_ts if start_ts else bounds['start_ts'][0]
+ end_ts = end_ts if end_ts else bounds['end_ts'][0]
+
+ tp.query("""
+ DROP VIEW IF EXISTS modded_names
+ """)
+
+ tp.query("""
+ CREATE VIEW modded_names AS
+ SELECT
+ slice.id,
+ slice.depth,
+ slice.stack_id,
+ CASE
+ WHEN slice.name LIKE 'Choreographer#doFrame%'
+ THEN 'Choreographer#doFrame'
+ WHEN slice.name LIKE 'DrawFrames%'
+ THEN 'DrawFrames'
+ WHEN slice.name LIKE '/data/app%.apk'
+ THEN 'APK load'
+ WHEN slice.name LIKE 'OpenDexFilesFromOat%'
+ THEN 'OpenDexFilesFromOat'
+ WHEN slice.name LIKE 'Open oat file%'
+ THEN 'Open oat file'
+ ELSE slice.name
+ END AS modded_name
+ FROM slice
+ """)
+
+ tp.query("""
+ DROP VIEW IF EXISTS thread_slice_stack
+ """)
+
+ tp.query("""
+ CREATE VIEW thread_slice_stack AS
+ SELECT
+ efs.ts,
+ efs.dur,
+ IFNULL(n.stack_id, -1) AS stack_id,
+ t.utid,
+ IIF(efs.source_id IS NULL, '[No slice]', IFNULL(
+ (
+ SELECT GROUP_CONCAT(modded_name, ' > ')
+ FROM (
+ SELECT p.modded_name
+ FROM ancestor_slice(efs.source_id) a
+ JOIN modded_names p ON a.id = p.id
+ ORDER BY p.depth
+ )
+ ) || ' > ' || n.modded_name,
+ n.modded_name
+ )) AS stack_name
+ FROM experimental_flat_slice({}, {}) efs
+ LEFT JOIN modded_names n ON efs.source_id = n.id
+ JOIN thread_track t ON t.id = efs.track_id
+ """.format(start_ts, end_ts))
+
+ tp.query("""
+ DROP TABLE IF EXISTS thread_slice_stack_with_state
+ """)
+
+ tp.query("""
+ CREATE VIRTUAL TABLE thread_slice_stack_with_state
+ USING SPAN_JOIN(
+ thread_slice_stack PARTITIONED utid,
+ thread_state PARTITIONED utid
+ )
+ """)
+
+ if process_name:
+ where_process = "AND process.name = '{}'".format(process_name)
+ else:
+ where_process = ''
+
+ breakdown = tp.query("""
+ SELECT
+ process.name AS process_name,
+ thread.name AS thread_name,
+ CASE
+ WHEN slice.state = 'D' and slice.io_wait
+ THEN 'Uninterruptible sleep (IO)'
+ WHEN slice.state = 'DK' and slice.io_wait
+ THEN 'Uninterruptible sleep + Wake-kill (IO)'
+ WHEN slice.state = 'D' and not slice.io_wait
+ THEN 'Uninterruptible sleep (non-IO)'
+ WHEN slice.state = 'DK' and not slice.io_wait
+ THEN 'Uninterruptible sleep + Wake-kill (non-IO)'
+ WHEN slice.state = 'D'
+ THEN 'Uninterruptible sleep'
+ WHEN slice.state = 'DK'
+ THEN 'Uninterruptible sleep + Wake-kill'
+ WHEN slice.state = 'S' THEN 'Interruptible sleep'
+ WHEN slice.state = 'R' THEN 'Runnable'
+ WHEN slice.state = 'R+' THEN 'Runnable (Preempted)'
+ ELSE slice.state
+ END AS state,
+ slice.stack_name,
+ SUM(slice.dur)/1e6 AS dur_sum,
+ MIN(slice.dur/1e6) AS dur_min,
+ MAX(slice.dur/1e6) AS dur_max,
+ AVG(slice.dur/1e6) AS dur_mean,
+ PERCENTILE(slice.dur/1e6, 50) AS dur_median,
+ PERCENTILE(slice.dur/1e6, 25) AS dur_25_percentile,
+ PERCENTILE(slice.dur/1e6, 75) AS dur_75_percentile,
+ PERCENTILE(slice.dur/1e6, 95) AS dur_95_percentile,
+ PERCENTILE(slice.dur/1e6, 99) AS dur_99_percentile,
+ COUNT(1) as count
+ FROM process
+ JOIN thread USING (upid)
+ JOIN thread_slice_stack_with_state slice USING (utid)
+ WHERE dur != -1 {}
+ GROUP BY thread.name, stack_id, state
+ ORDER BY dur_sum DESC
+ """.format(where_process)).as_pandas_dataframe()
+
+ return breakdown
+
+
+def compute_breakdown_for_startup(tp: TraceProcessor,
+ package_name=None,
+ process_name=None):
+ """Computes the slice breakdown (like |compute_breakdown|) but only
+ considering slices which happened during an app startup
+
+ Args:
+ tp: the trace processor instance to query.
+ package_name: optional package name to filter for startups. Only a single
+ startup matching this package name should be present. If not specified,
+ only a single startup of any app should be in the trace.
+ process_name: optional process name to filter for slices; specifying
+ this argument can make computing the breakdown a lot faster.
+
+ Returns:
+ The same as |compute_breakdown| but only containing slices which happened
+ during app startup.
+ """
+ tp.metric(['android_startup'])
+
+ # Verify there was only one startup in the trace matching the package
+ # name.
+ filter = "WHERE package = '{}'".format(package_name) if package_name else ''
+ launches = tp.query('''
+ SELECT ts, ts_end, dur
+ FROM launches
+ {}
+ '''.format(filter)).as_pandas_dataframe()
+ if len(launches) == 0:
+ raise TraceProcessorException("Didn't find startup in trace")
+ if len(launches) > 1:
+ raise TraceProcessorException("Found multiple startups in trace")
+
+ start = launches['ts'][0]
+ end = launches['ts_end'][0]
+
+ return compute_breakdown(tp, start, end, process_name)
diff --git a/python/perfetto/trace_processor/__init__.py b/python/perfetto/trace_processor/__init__.py
new file mode 100644
index 000000000..fc396ce0a
--- /dev/null
+++ b/python/perfetto/trace_processor/__init__.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python3
+# Copyright (C) 2020 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from perfetto.trace_processor.api import TraceProcessor
+from perfetto.trace_processor.api import TraceProcessorConfig
+from perfetto.trace_processor.api import TraceProcessorException
+from perfetto.trace_processor.http import TraceProcessorHttp
+from perfetto.trace_processor.api import TraceReference
diff --git a/python/perfetto/trace_processor/api.py b/python/perfetto/trace_processor/api.py
new file mode 100644
index 000000000..a5efbcde2
--- /dev/null
+++ b/python/perfetto/trace_processor/api.py
@@ -0,0 +1,359 @@
+# Copyright (C) 2020 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import dataclasses as dc
+from urllib.parse import urlparse
+from typing import List, Optional
+
+from perfetto.trace_processor.http import TraceProcessorHttp
+from perfetto.trace_processor.platform import PlatformDelegate
+from perfetto.trace_processor.protos import ProtoFactory
+from perfetto.trace_processor.shell import load_shell
+from perfetto.trace_uri_resolver import registry
+from perfetto.trace_uri_resolver.registry import ResolverRegistry
+
+# Defining this field as a module variable means this can be changed by
+# implementations at startup and used for all TraceProcessor objects
+# without having to specify on each one.
+# In Google3, this field is rewritten using Copybara to a implementation
+# which can integrates with internal infra.
+PLATFORM_DELEGATE = PlatformDelegate
+
+TraceReference = registry.TraceReference
+
+# Custom exception raised if any trace_processor functions return a
+# response with an error defined
+class TraceProcessorException(Exception):
+
+ def __init__(self, message):
+ super().__init__(message)
+
+
+@dc.dataclass
+class TraceProcessorConfig:
+ bin_path: Optional[str]
+ unique_port: bool
+ verbose: bool
+ ingest_ftrace_in_raw: bool
+ resolver_registry: Optional[ResolverRegistry]
+
+ def __init__(self,
+ bin_path: Optional[str] = None,
+ unique_port: bool = True,
+ verbose: bool = False,
+ ingest_ftrace_in_raw: bool = False,
+ resolver_registry: Optional[ResolverRegistry] = None):
+ self.bin_path = bin_path
+ self.unique_port = unique_port
+ self.verbose = verbose
+ self.ingest_ftrace_in_raw = ingest_ftrace_in_raw
+ self.resolver_registry = resolver_registry
+
+
+class TraceProcessor:
+
+ # Values of these constants correspond to the QueryResponse message at
+ # protos/perfetto/trace_processor/trace_processor.proto
+ QUERY_CELL_INVALID_FIELD_ID = 0
+ QUERY_CELL_NULL_FIELD_ID = 1
+ QUERY_CELL_VARINT_FIELD_ID = 2
+ QUERY_CELL_FLOAT64_FIELD_ID = 3
+ QUERY_CELL_STRING_FIELD_ID = 4
+ QUERY_CELL_BLOB_FIELD_ID = 5
+
+ # This is the class returned to the user and contains one row of the
+ # resultant query. Each column name is stored as an attribute of this
+ # class, with the value corresponding to the column name and row in
+ # the query results table.
+ class Row(object):
+
+ def __str__(self):
+ return str(self.__dict__)
+
+ def __repr__(self):
+ return self.__dict__
+
+ class QueryResultIterator:
+
+ def __init__(self, column_names, batches):
+ self.__column_names = column_names
+ self.__column_count = 0
+ self.__count = 0
+ self.__cells = []
+ self.__data_lists = [[], [], [], [], [], []]
+ self.__data_lists_index = [0, 0, 0, 0, 0, 0]
+ self.__current_index = 0
+
+ # Iterate over all the batches and collect their
+ # contents into lists based on the type of the batch
+ batch_index = 0
+ while True:
+ # It's possible on some occasions that there are non UTF-8 characters
+ # in the string_cells field. If this is the case, string_cells is
+ # a bytestring which needs to be decoded (but passing ignore so that
+ # we don't fail in decoding).
+ strings_batch_str = batches[batch_index].string_cells
+ try:
+ strings_batch_str = strings_batch_str.decode('utf-8', 'ignore')
+ except AttributeError:
+ # AttributeError can occur when |strings_batch_str| is an str which
+ # happens when everything in it is UTF-8 (protobuf automatically
+ # does the conversion if it can).
+ pass
+
+ # Null-terminated strings in a batch are concatenated
+ # into a single large byte array, so we split on the
+ # null-terminator to get the individual strings
+ strings_batch = strings_batch_str.split('\0')[:-1]
+ self.__data_lists[TraceProcessor.QUERY_CELL_STRING_FIELD_ID].extend(
+ strings_batch)
+ self.__data_lists[TraceProcessor.QUERY_CELL_VARINT_FIELD_ID].extend(
+ batches[batch_index].varint_cells)
+ self.__data_lists[TraceProcessor.QUERY_CELL_FLOAT64_FIELD_ID].extend(
+ batches[batch_index].float64_cells)
+ self.__data_lists[TraceProcessor.QUERY_CELL_BLOB_FIELD_ID].extend(
+ batches[batch_index].blob_cells)
+ self.__cells.extend(batches[batch_index].cells)
+
+ if batches[batch_index].is_last_batch:
+ break
+ batch_index += 1
+
+ # If there are no rows in the query result, don't bother updating the
+ # counts to avoid dealing with / 0 errors.
+ if len(self.__cells) == 0:
+ return
+
+ # The count we collected so far was a count of all individual columns
+ # in the query result, so we divide by the number of columns in a row
+ # to get the number of rows
+ self.__column_count = len(self.__column_names)
+ self.__count = int(len(self.__cells) / self.__column_count)
+
+ # Data integrity check - see that we have the expected amount of cells
+ # for the number of rows that we need to return
+ if len(self.__cells) % self.__column_count != 0:
+ raise TraceProcessorException("Cell count " + str(len(self.__cells)) +
+ " is not a multiple of column count " +
+ str(len(self.__column_names)))
+
+ # To use the query result as a populated Pandas dataframe, this
+ # function must be called directly after calling query inside
+ # TraceProcesor.
+ def as_pandas_dataframe(self):
+ try:
+ import pandas as pd
+
+ # Populate the dataframe with the query results
+ rows = []
+ for i in range(0, self.__count):
+ row = []
+ base_cell_index = i * self.__column_count
+ for num in range(len(self.__column_names)):
+ col_type = self.__cells[base_cell_index + num]
+ if col_type == TraceProcessor.QUERY_CELL_INVALID_FIELD_ID:
+ raise TraceProcessorException('Invalid cell type')
+
+ if col_type == TraceProcessor.QUERY_CELL_NULL_FIELD_ID:
+ row.append(None)
+ else:
+ col_index = self.__data_lists_index[col_type]
+ self.__data_lists_index[col_type] += 1
+ row.append(self.__data_lists[col_type][col_index])
+ rows.append(row)
+
+ df = pd.DataFrame(rows, columns=self.__column_names)
+ return df.astype(object).where(df.notnull(),
+ None).reset_index(drop=True)
+
+ except ModuleNotFoundError:
+ raise TraceProcessorException(
+ 'Python dependencies missing. Please pip3 install pandas numpy')
+
+ def __len__(self):
+ return self.__count
+
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ if self.__current_index == self.__count:
+ raise StopIteration
+ result = TraceProcessor.Row()
+ base_cell_index = self.__current_index * self.__column_count
+ for num, column_name in enumerate(self.__column_names):
+ col_type = self.__cells[base_cell_index + num]
+ if col_type == TraceProcessor.QUERY_CELL_INVALID_FIELD_ID:
+ raise TraceProcessorException('Invalid cell type')
+ if col_type != TraceProcessor.QUERY_CELL_NULL_FIELD_ID:
+ col_index = self.__data_lists_index[col_type]
+ self.__data_lists_index[col_type] += 1
+ setattr(result, column_name, self.__data_lists[col_type][col_index])
+ else:
+ setattr(result, column_name, None)
+
+ self.__current_index += 1
+ return result
+
+ def __init__(self,
+ trace: Optional[TraceReference] = None,
+ addr: Optional[str] = None,
+ config: TraceProcessorConfig = TraceProcessorConfig(),
+ file_path: Optional[str] = None):
+ """Create a trace processor instance.
+
+ Args:
+ trace: reference to a trace to be loaded into the trace
+ processor instance.
+
+ One of several types is supported:
+ 1) path to a trace file to open and read
+ 2) a file like object (file, io.BytesIO or similar) to read
+ 3) a generator yielding bytes
+ 4) a trace URI which resolves to one of the above types
+ 5) a trace URI resolver; this is a subclass of
+ resolver.TraceUriResolver which generates a reference to a
+ trace when the |resolve| method is called on it.
+
+ An URI is similar to a connection string (e.g. for a web
+ address or SQL database) which specifies where to lookup traces
+ and which traces to pick from this data source. The format of a
+ string should be as follows:
+ resolver_name:key_1=list,of,values;key_2=value
+
+ Custom resolvers can be provided to handle URIs via
+ |config.resolver_registry|.
+ addr: address of a running trace processor instance. Useful to query an
+ already loaded trace.
+ config: configuration options which customize functionality of trace
+ processor and the Python binding.
+ file_path (deprecated): path to a trace file to load. Use
+ |trace| instead of this field: specifying both will cause
+ an exception to be thrown.
+ """
+
+ if trace and file_path:
+ raise TraceProcessorException(
+ "trace and file_path cannot both be specified.")
+
+ self.config = config
+ self.platform_delegate = PLATFORM_DELEGATE()
+ self.protos = ProtoFactory(self.platform_delegate)
+ self.resolver_registry = config.resolver_registry or \
+ self.platform_delegate.default_resolver_registry()
+ self.http = self._create_tp_http(addr)
+
+ if trace or file_path:
+ self._parse_trace(trace if trace else file_path)
+
+ def query(self, sql: str):
+ """Executes passed in SQL query using class defined HTTP API, and returns
+ the response as a QueryResultIterator. Raises TraceProcessorException if
+ the response returns with an error.
+
+ Args:
+ sql: SQL query written as a String
+
+ Returns:
+ A class which can iterate through each row of the results table. This
+ can also be converted to a pandas dataframe by calling the
+ as_pandas_dataframe() function after calling query.
+ """
+ response = self.http.execute_query(sql)
+ if response.error:
+ raise TraceProcessorException(response.error)
+
+ return TraceProcessor.QueryResultIterator(response.column_names,
+ response.batch)
+
+ def metric(self, metrics: List[str]):
+ """Returns the metrics data corresponding to the passed in trace metric.
+ Raises TraceProcessorException if the response returns with an error.
+
+ Args:
+ metrics: A list of valid metrics as defined in TraceMetrics
+
+ Returns:
+ The metrics data as a proto message
+ """
+ response = self.http.compute_metric(metrics)
+ if response.error:
+ raise TraceProcessorException(response.error)
+
+ metrics = self.protos.TraceMetrics()
+ metrics.ParseFromString(response.metrics)
+ return metrics
+
+ def enable_metatrace(self):
+ """Enable metatrace for the currently running trace_processor.
+ """
+ return self.http.enable_metatrace()
+
+ def disable_and_read_metatrace(self):
+ """Disable and return the metatrace formed from the currently running
+ trace_processor. This must be enabled before attempting to disable. This
+ returns the serialized bytes of the metatrace data directly. Raises
+ TraceProcessorException if the response returns with an error.
+ """
+ response = self.http.disable_and_read_metatrace()
+ if response.error:
+ raise TraceProcessorException(response.error)
+
+ return response.metatrace
+
+ def _create_tp_http(self, addr: str) -> TraceProcessorHttp:
+ if addr:
+ p = urlparse(addr)
+ parsed = p.netloc if p.netloc else p.path
+ return TraceProcessorHttp(parsed, protos=self.protos)
+
+ url, self.subprocess = load_shell(self.config.bin_path,
+ self.config.unique_port,
+ self.config.verbose,
+ self.config.ingest_ftrace_in_raw,
+ self.platform_delegate)
+ return TraceProcessorHttp(url, protos=self.protos)
+
+ def _parse_trace(self, trace: TraceReference):
+ resolved_lst = self.resolver_registry.resolve(trace)
+ if not resolved_lst:
+ raise TraceProcessorException(
+ 'trace argument did not resolve to a trace.')
+
+ if len(resolved_lst) > 1:
+ raise TraceProcessorException(
+ 'trace argument resolved to more than one trace. Trace processor '
+ 'only supports loading a single trace; please use '
+ 'BatchTraceProcessor to operate on multiple traces.')
+
+ resolved = resolved_lst[0]
+ for chunk in resolved.generator:
+ result = self.http.parse(chunk)
+ if result.error:
+ raise TraceProcessorException(
+ f'Failed while parsing trace. Error message: {result.error}')
+ self.http.notify_eof()
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, a, b, c):
+ del a, b, c # Unused.
+ self.close()
+ return False
+
+ def close(self):
+ if hasattr(self, 'subprocess'):
+ self.subprocess.kill()
+ self.http.conn.close()
diff --git a/python/perfetto/trace_processor/http.py b/python/perfetto/trace_processor/http.py
new file mode 100644
index 000000000..9c6c780d8
--- /dev/null
+++ b/python/perfetto/trace_processor/http.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python3
+# Copyright (C) 2020 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import http.client
+from typing import List
+
+from perfetto.trace_processor.protos import ProtoFactory
+
+
+class TraceProcessorHttp:
+
+ def __init__(self, url: str, protos: ProtoFactory):
+ self.protos = protos
+ self.conn = http.client.HTTPConnection(url)
+
+ def execute_query(self, query: str):
+ args = self.protos.RawQueryArgs()
+ args.sql_query = query
+ byte_data = args.SerializeToString()
+ self.conn.request('POST', '/query', body=byte_data)
+ with self.conn.getresponse() as f:
+ result = self.protos.QueryResult()
+ result.ParseFromString(f.read())
+ return result
+
+ def compute_metric(self, metrics: List[str]):
+ args = self.protos.ComputeMetricArgs()
+ args.metric_names.extend(metrics)
+ byte_data = args.SerializeToString()
+ self.conn.request('POST', '/compute_metric', body=byte_data)
+ with self.conn.getresponse() as f:
+ result = self.protos.ComputeMetricResult()
+ result.ParseFromString(f.read())
+ return result
+
+ def parse(self, chunk: bytes):
+ self.conn.request('POST', '/parse', body=chunk)
+ with self.conn.getresponse() as f:
+ result = self.protos.AppendTraceDataResult()
+ result.ParseFromString(f.read())
+ return result
+
+ def notify_eof(self):
+ self.conn.request('GET', '/notify_eof')
+ with self.conn.getresponse() as f:
+ return f.read()
+
+ def status(self):
+ self.conn.request('GET', '/status')
+ with self.conn.getresponse() as f:
+ result = self.protos.StatusResult()
+ result.ParseFromString(f.read())
+ return result
+
+ def enable_metatrace(self):
+ self.conn.request('GET', '/enable_metatrace')
+ with self.conn.getresponse() as f:
+ return f.read()
+
+ def disable_and_read_metatrace(self):
+ self.conn.request('GET', '/disable_and_read_metatrace')
+ with self.conn.getresponse() as f:
+ result = self.protos.DisableAndReadMetatraceResult()
+ result.ParseFromString(f.read())
+ return result
diff --git a/python/perfetto/trace_processor/metrics.descriptor b/python/perfetto/trace_processor/metrics.descriptor
new file mode 100644
index 000000000..a91d7a95f
--- /dev/null
+++ b/python/perfetto/trace_processor/metrics.descriptor
@@ -0,0 +1,775 @@
+
+¤
+1protos/perfetto/metrics/android/batt_metric.protoperfetto.protos"Ý
+AndroidBatteryMetric`
+battery_counters ( 25.perfetto.protos.AndroidBatteryMetric.BatteryCountersRbatteryCountersf
+battery_aggregates ( 27.perfetto.protos.AndroidBatteryMetric.BatteryAggregatesRbatteryAggregatesZ
+suspend_period ( 23.perfetto.protos.AndroidBatteryMetric.SuspendPeriodR suspendPeriodÒ
+BatteryCounters!
+ timestamp_ns (R timestampNs,
+charge_counter_uah (RchargeCounterUah)
+capacity_percent (RcapacityPercent
+
+current_ua (R currentUa$
+current_avg_ua (R currentAvgUaô
+BatteryAggregates-
+total_screen_off_ns (RtotalScreenOffNs+
+total_screen_on_ns (RtotalScreenOnNs/
+total_screen_doze_ns (RtotalScreenDozeNs*
+total_wakelock_ns (RtotalWakelockNs
+sleep_ns (RsleepNs-
+sleep_screen_off_ns (RsleepScreenOffNs+
+sleep_screen_on_ns (RsleepScreenOnNs/
+sleep_screen_doze_ns (RsleepScreenDozeNsS
+ SuspendPeriod!
+ timestamp_ns (R timestampNs
+ duration_ns (R
+durationNs
+Ô
+0protos/perfetto/metrics/android/cpu_metric.protoperfetto.protos"Ž
+AndroidCpuMetricL
+ process_info ( 2).perfetto.protos.AndroidCpuMetric.ProcessR processInfo¨
+Metrics
+mcycles (Rmcycles
+
+runtime_ns (R runtimeNs
+ min_freq_khz (R
+minFreqKhz
+ max_freq_khz (R
+maxFreqKhz
+ avg_freq_khz (R
+avgFreqKhze
+CoreData
+id ( RidC
+metrics ( 2).perfetto.protos.AndroidCpuMetric.MetricsRmetricsJg
+ CoreTypeData
+type ( RtypeC
+metrics ( 2).perfetto.protos.AndroidCpuMetric.MetricsRmetricsô
+Thread
+name ( RnameC
+metrics ( 2).perfetto.protos.AndroidCpuMetric.MetricsRmetrics>
+core ( 2*.perfetto.protos.AndroidCpuMetric.CoreDataRcoreK
+ core_type ( 2..perfetto.protos.AndroidCpuMetric.CoreTypeDataRcoreTypeJ¹
+Process
+name ( RnameC
+metrics ( 2).perfetto.protos.AndroidCpuMetric.MetricsRmetricsB
+threads ( 2(.perfetto.protos.AndroidCpuMetric.ThreadRthreads>
+core ( 2*.perfetto.protos.AndroidCpuMetric.CoreDataRcoreK
+ core_type ( 2..perfetto.protos.AndroidCpuMetric.CoreTypeDataRcoreTypeJ
+ò
+3protos/perfetto/metrics/android/camera_metric.protoperfetto.protos"©
+AndroidCameraMetricQ
+gc_rss_and_dma ( 2,.perfetto.protos.AndroidCameraMetric.CounterR gcRssAndDma?
+Counter
+min (Rmin
+max (Rmax
+avg (Ravg
+ü
+9protos/perfetto/metrics/android/camera_unagg_metric.protoperfetto.protos"­
+AndroidCameraUnaggregatedMetric[
+gc_rss_and_dma ( 26.perfetto.protos.AndroidCameraUnaggregatedMetric.ValueR gcRssAndDma-
+Value
+ts (Rts
+value (Rvalue
+·
+5protos/perfetto/metrics/android/display_metrics.protoperfetto.protos"ì
+AndroidDisplayMetrics4
+total_duplicate_frames ( RtotalDuplicateFrames6
+duplicate_frames_logged ( RduplicateFramesLogged7
+total_dpu_underrun_count ( RtotalDpuUnderrunCount2
+refresh_rate_switches ( RrefreshRateSwitchesd
+refresh_rate_stats ( 26.perfetto.protos.AndroidDisplayMetrics.RefreshRateStatRrefreshRateStats‘
+RefreshRateStat(
+refresh_rate_fps ( RrefreshRateFps
+count ( Rcount
+ total_dur_ms (R
+totalDurMs
+
+avg_dur_ms (RavgDurMs
+ˆ
+5protos/perfetto/metrics/android/dma_heap_metric.protoperfetto.protos"½
+AndroidDmaHeapMetric$
+avg_size_bytes (R avgSizeBytes$
+min_size_bytes (R minSizeBytes$
+max_size_bytes (R maxSizeBytes3
+total_alloc_size_bytes (RtotalAllocSizeBytes
+¥
+1protos/perfetto/metrics/android/dvfs_metric.protoperfetto.protos"Þ
+AndroidDvfsMetric`
+freq_residencies ( 25.perfetto.protos.AndroidDvfsMetric.FrequencyResidencyRfreqResidenciesj
+BandStat
+
+freq_value (R freqValue
+
+percentage (R
+percentage
+ duration_ns (R
+durationNs{
+FrequencyResidency
+ freq_name ( RfreqNameH
+ band_stat ( 2+.perfetto.protos.AndroidDvfsMetric.BandStatRbandStat
+ø
+4protos/perfetto/metrics/android/fastrpc_metric.protoperfetto.protos"®
+AndroidFastrpcMetricM
+ subsystem ( 2/.perfetto.protos.AndroidFastrpcMetric.SubsystemR subsystemÆ
+ Subsystem
+name ( Rname$
+avg_size_bytes (R avgSizeBytes$
+min_size_bytes (R minSizeBytes$
+max_size_bytes (R maxSizeBytes3
+total_alloc_size_bytes (RtotalAllocSizeBytes
+‹
+0protos/perfetto/metrics/android/g2d_metric.protoperfetto.protos"Å
+
+G2dMetrics<
+g2d_hw ( 2%.perfetto.protos.G2dMetrics.G2dMetricRg2dHw<
+g2d_sw ( 2%.perfetto.protos.G2dMetrics.G2dMetricRg2dSwÃ
+ G2dInstance
+name ( Rname
+ frame_count ( R
+frameCount
+ error_count ( R
+errorCount
+
+max_dur_ms (RmaxDurMs
+
+min_dur_ms (RminDurMs
+
+avg_dur_ms (RavgDurMsJô
+ G2dMetricE
+ instances ( 2'.perfetto.protos.G2dMetrics.G2dInstanceR instances
+ frame_count ( R
+frameCount
+ error_count ( R
+errorCount
+
+max_dur_ms (RmaxDurMs
+
+min_dur_ms (RminDurMs
+
+avg_dur_ms (RavgDurMsJ
+ð
+0protos/perfetto/metrics/android/gpu_metric.protoperfetto.protos"ª
+AndroidGpuMetricG
+ processes ( 2).perfetto.protos.AndroidGpuMetric.ProcessR processes
+mem_max (RmemMax
+mem_min (RmemMin
+mem_avg (RmemAvgT
+ freq_metrics ( 21.perfetto.protos.AndroidGpuMetric.FrequencyMetricR freqMetricsh
+Process
+name ( Rname
+mem_max (RmemMax
+mem_min (RmemMin
+mem_avg (RmemAvgÁ
+FrequencyMetric
+gpu_id ( RgpuId
+freq_max (RfreqMax
+freq_min (RfreqMin
+freq_avg (RfreqAvgd
+
+used_freqs ( 2E.perfetto.protos.AndroidGpuMetric.FrequencyMetric.MetricsPerFrequencyR usedFreqs`
+MetricsPerFrequency
+freq (Rfreq
+dur_ms (RdurMs
+
+percentage (R
+percentage
+0protos/perfetto/metrics/android/hwcomposer.protoperfetto.protos"ü
+AndroidHwcomposerMetrics8
+composition_total_layers (RcompositionTotalLayers4
+composition_dpu_layers (RcompositionDpuLayers4
+composition_gpu_layers (RcompositionGpuLayersA
+composition_dpu_cached_layers (RcompositionDpuCachedLayers?
+composition_sf_cached_layers (RcompositionSfCachedLayers8
+skipped_validation_count (RskippedValidationCount<
+unskipped_validation_count (RunskippedValidationCount<
+separated_validation_count (RseparatedValidationCount8
+unknown_validation_count (RunknownValidationCount8
+avg_all_execution_time_ms
+ (RavgAllExecutionTimeMs@
+avg_skipped_execution_time_ms (RavgSkippedExecutionTimeMsD
+avg_unskipped_execution_time_ms (RavgUnskippedExecutionTimeMsD
+avg_separated_execution_time_ms (RavgSeparatedExecutionTimeMsb
+dpu_vote_metrics ( 28.perfetto.protos.AndroidHwcomposerMetrics.DpuVoteMetricsRdpuVoteMetricsÙ
+DpuVoteMetrics
+tid ( Rtid+
+avg_dpu_vote_clock (RavgDpuVoteClock,
+avg_dpu_vote_avg_bw (RavgDpuVoteAvgBw.
+avg_dpu_vote_peak_bw (RavgDpuVotePeakBw*
+avg_dpu_vote_rt_bw (RavgDpuVoteRtBw
+†
+1protos/perfetto/metrics/android/hwui_metric.protoperfetto.protos"ã
+ProcessRenderInfo!
+ process_name ( R processName#
+rt_cpu_time_ms (R rtCpuTimeMs(
+draw_frame_count ( RdrawFrameCount$
+draw_frame_max (R drawFrameMax$
+draw_frame_min (R drawFrameMin$
+draw_frame_avg (R drawFrameAvg
+ flush_count ( R
+flushCount
+ flush_max (RflushMax
+ flush_min (RflushMin
+ flush_avg
+ (RflushAvg,
+prepare_tree_count ( RprepareTreeCount(
+prepare_tree_max (RprepareTreeMax(
+prepare_tree_min (RprepareTreeMin(
+prepare_tree_avg (RprepareTreeAvg0
+gpu_completion_count ( RgpuCompletionCount,
+gpu_completion_max (RgpuCompletionMax,
+gpu_completion_min (RgpuCompletionMin,
+gpu_completion_avg (RgpuCompletionAvg&
+ui_record_count ( R uiRecordCount"
+ ui_record_max (R uiRecordMax"
+ ui_record_min (R uiRecordMin"
+ ui_record_avg (R uiRecordAvg0
+shader_compile_count ( RshaderCompileCount.
+shader_compile_time (RshaderCompileTime,
+shader_compile_avg (RshaderCompileAvg&
+cache_hit_count ( R cacheHitCount$
+cache_hit_time (R cacheHitTime"
+ cache_hit_avg (R cacheHitAvg(
+cache_miss_count ( RcacheMissCount&
+cache_miss_time (R cacheMissTime$
+cache_miss_avg (R cacheMissAvg/
+graphics_cpu_mem_max (RgraphicsCpuMemMax/
+graphics_cpu_mem_min! (RgraphicsCpuMemMin/
+graphics_cpu_mem_avg" (RgraphicsCpuMemAvg/
+graphics_gpu_mem_max# (RgraphicsGpuMemMax/
+graphics_gpu_mem_min$ (RgraphicsGpuMemMin/
+graphics_gpu_mem_avg% (RgraphicsGpuMemAvg&
+texture_mem_max& (R textureMemMax&
+texture_mem_min' (R textureMemMin&
+texture_mem_avg( (R textureMemAvg
+ all_mem_max) (R allMemMax
+ all_mem_min* (R allMemMin
+ all_mem_avg+ (R allMemAvg"Z
+AndroidHwuiMetricE
+ process_info ( 2".perfetto.protos.ProcessRenderInfoR processInfo
+à
+0protos/perfetto/metrics/android/ion_metric.protoperfetto.protos"š
+AndroidIonMetric@
+buffer ( 2(.perfetto.protos.AndroidIonMetric.BufferRbufferÃ
+Buffer
+name ( Rname$
+avg_size_bytes (R avgSizeBytes$
+min_size_bytes (R minSizeBytes$
+max_size_bytes (R maxSizeBytes3
+total_alloc_size_bytes (RtotalAllocSizeBytes
+ú
+8protos/perfetto/metrics/android/irq_runtime_metric.protoperfetto.protos"¬
+AndroidIrqRuntimeMetricP
+hw_irq ( 29.perfetto.protos.AndroidIrqRuntimeMetric.IrqRuntimeMetricRhwIrqP
+sw_irq ( 29.perfetto.protos.AndroidIrqRuntimeMetric.IrqRuntimeMetricRswIrqG
+IrqSlice
+irq_name ( RirqName
+ts (Rts
+dur (Rdur†
+ThresholdMetric
+ threshold ( R threshold0
+over_threshold_count (RoverThresholdCount#
+ anomaly_ratio (R anomalyRatioš
+IrqRuntimeMetric
+ max_runtime (R
+maxRuntime
+ total_count (R
+totalCountc
+threshold_metric ( 28.perfetto.protos.AndroidIrqRuntimeMetric.ThresholdMetricRthresholdMetric_
+longest_irq_slices ( 21.perfetto.protos.AndroidIrqRuntimeMetric.IrqSliceRlongestIrqSlices
+—
+1protos/perfetto/metrics/android/jank_metric.protoperfetto.protos"Ð
+AndroidJankMetricsG
+warnings ( 2+.perfetto.protos.AndroidJankMetrics.WarningRwarningsq
+Warning
+ts (Rts
+dur (Rdur!
+ process_name ( R processName!
+ warning_text ( R warningText
+À
+6protos/perfetto/metrics/android/process_metadata.protoperfetto.protos"ô
+AndroidProcessMetadata
+name ( Rname
+uid (RuidI
+package ( 2/.perfetto.protos.AndroidProcessMetadata.PackageRpackageY
+packages_for_uid ( 2/.perfetto.protos.AndroidProcessMetadata.PackageRpackagesForUidv
+Package!
+ package_name ( R packageName(
+apk_version_code (RapkVersionCode
+
+debuggable (R
+debuggableJJJJ
+À
+9protos/perfetto/metrics/android/java_heap_histogram.protoperfetto.protos6protos/perfetto/metrics/android/process_metadata.proto"¹
+JavaHeapHistogramW
+instance_stats ( 20.perfetto.protos.JavaHeapHistogram.InstanceStatsR instanceStatsµ
+ TypeCount
+ type_name ( RtypeName
+category ( Rcategory
+ obj_count ( RobjCount.
+reachable_obj_count ( RreachableObjCount
+size_kb ( RsizeKb*
+reachable_size_kb ( RreachableSizeKb$
+native_size_kb ( R nativeSizeKb7
+reachable_native_size_kb ( RreachableNativeSizeKbe
+Sample
+ts (RtsK
+
+type_count ( 2,.perfetto.protos.JavaHeapHistogram.TypeCountR typeCount«
+ InstanceStats
+upid ( RupidA
+process ( 2'.perfetto.protos.AndroidProcessMetadataRprocessC
+samples ( 2).perfetto.protos.JavaHeapHistogram.SampleRsamples
+…
+5protos/perfetto/metrics/android/java_heap_stats.protoperfetto.protos6protos/perfetto/metrics/android/process_metadata.proto"‚
+ JavaHeapStatsS
+instance_stats ( 2,.perfetto.protos.JavaHeapStats.InstanceStatsR instanceStatsb
+ HeapRoots
+ root_type ( RrootType
+ type_name ( RtypeName
+ obj_count (RobjCount
+Sample
+ts (Rts
+ heap_size (RheapSize(
+heap_native_size (RheapNativeSize
+ obj_count (RobjCount.
+reachable_heap_size (RreachableHeapSize;
+reachable_heap_native_size (RreachableHeapNativeSize.
+reachable_obj_count (RreachableObjCount2
+anon_rss_and_swap_size (RanonRssAndSwapSize>
+roots ( 2(.perfetto.protos.JavaHeapStats.HeapRootsRroots§
+ InstanceStats
+upid ( RupidA
+process ( 2'.perfetto.protos.AndroidProcessMetadataRprocess?
+samples ( 2%.perfetto.protos.JavaHeapStats.SampleRsamples
+»
+0protos/perfetto/metrics/android/lmk_metric.protoperfetto.protos"õ
+AndroidLmkMetric
+ total_count (R
+totalCountN
+ by_oom_score ( 2,.perfetto.protos.AndroidLmkMetric.ByOomScoreR
+byOomScore(
+oom_victim_count (RoomVictimCountF
+
+ByOomScore"
+ oom_score_adj (R oomScoreAdj
+count (Rcount
+Ì
+7protos/perfetto/metrics/android/lmk_reason_metric.protoperfetto.protos6protos/perfetto/metrics/android/process_metadata.proto"Ç
+AndroidLmkReasonMetric?
+lmks ( 2+.perfetto.protos.AndroidLmkReasonMetric.LmkRlmks—
+ProcessA
+process ( 2'.perfetto.protos.AndroidProcessMetadataRprocess"
+ oom_score_adj (R oomScoreAdj
+size (Rsize$
+file_rss_bytes (R fileRssBytes$
+anon_rss_bytes (R anonRssBytes&
+shmem_rss_bytes (R shmemRssBytes
+
+swap_bytes (R swapBytesÑ
+Lmk"
+ oom_score_adj (R oomScoreAdj&
+ion_heaps_bytes (R ionHeapsBytes/
+system_ion_heap_size (RsystemIonHeapSizeM
+ processes ( 2/.perfetto.protos.AndroidLmkReasonMetric.ProcessR processes
+¥
+0protos/perfetto/metrics/android/mem_metric.protoperfetto.protos"ß
+AndroidMemoryMetric\
+process_metrics ( 23.perfetto.protos.AndroidMemoryMetric.ProcessMetricsRprocessMetricsý
+ProcessMetrics!
+ process_name ( R processNamea
+total_counters ( 2:.perfetto.protos.AndroidMemoryMetric.ProcessMemoryCountersR totalCounterse
+priority_breakdown ( 26.perfetto.protos.AndroidMemoryMetric.PriorityBreakdownRpriorityBreakdown‡
+PriorityBreakdown
+priority ( RpriorityV
+counters ( 2:.perfetto.protos.AndroidMemoryMetric.ProcessMemoryCountersRcountersˆ
+ProcessMemoryCountersG
+anon_rss ( 2,.perfetto.protos.AndroidMemoryMetric.CounterRanonRssG
+file_rss ( 2,.perfetto.protos.AndroidMemoryMetric.CounterRfileRss@
+swap ( 2,.perfetto.protos.AndroidMemoryMetric.CounterRswapP
+ anon_and_swap ( 2,.perfetto.protos.AndroidMemoryMetric.CounterR anonAndSwapI
+ java_heap ( 2,.perfetto.protos.AndroidMemoryMetric.CounterRjavaHeapU
+Counter
+min (Rmin
+max (Rmax
+avg (Ravg
+delta (Rdelta
+ 
+6protos/perfetto/metrics/android/mem_unagg_metric.protoperfetto.protos"Ô
+AndroidMemoryUnaggregatedMetrice
+process_values ( 2>.perfetto.protos.AndroidMemoryUnaggregatedMetric.ProcessValuesR processValues—
+ ProcessValues!
+ process_name ( R processNamec
+
+mem_values ( 2D.perfetto.protos.AndroidMemoryUnaggregatedMetric.ProcessMemoryValuesR memValuesã
+ProcessMemoryValuesQ
+anon_rss ( 26.perfetto.protos.AndroidMemoryUnaggregatedMetric.ValueRanonRssQ
+file_rss ( 26.perfetto.protos.AndroidMemoryUnaggregatedMetric.ValueRfileRssJ
+swap ( 26.perfetto.protos.AndroidMemoryUnaggregatedMetric.ValueRswapZ
+ anon_and_swap ( 26.perfetto.protos.AndroidMemoryUnaggregatedMetric.ValueR anonAndSwapJ
+Value
+ts (Rts
+ oom_score (RoomScore
+value (Rvalue
+ñ
+6protos/perfetto/metrics/android/multiuser_metric.protoperfetto.protos"¥
+AndroidMultiuserMetricR
+ user_switch ( 21.perfetto.protos.AndroidMultiuserMetric.EventDataR
+userSwitch¶
+ EventData
+ duration_ms (R
+durationMsW
+ cpu_usage ( 2:.perfetto.protos.AndroidMultiuserMetric.EventData.CpuUsageRcpuUsage®
+CpuUsage
+user_id (RuserId!
+ process_name ( R processName
+ cpu_mcycles (R
+cpuMcycles%
+cpu_percentage (R cpuPercentage
+
+identifier ( R
+identifier
+º
+4protos/perfetto/metrics/android/network_metric.protoperfetto.protos"ð
+AndroidNetworkMetricP
+ net_devices ( 2/.perfetto.protos.AndroidNetworkMetric.NetDeviceR
+netDevicesU
+ net_rx_action ( 21.perfetto.protos.AndroidNetworkMetric.NetRxActionR netRxAction/
+retransmission_rate (RretransmissionRate$
+kfree_skb_rate (R kfreeSkbRateü
+PacketStatistic
+packets (Rpackets
+bytes (Rbytes9
+first_packet_timestamp_ns (RfirstPacketTimestampNs7
+last_packet_timestamp_ns (RlastPacketTimestampNs
+ interval_ns (R
+intervalNs$
+data_rate_kbps (R dataRateKbps‡
+CorePacketStatistic
+id ( Rid`
+packet_statistic ( 25.perfetto.protos.AndroidNetworkMetric.PacketStatisticRpacketStatisticÔ
+RxK
+total ( 25.perfetto.protos.AndroidNetworkMetric.PacketStatisticRtotalM
+core ( 29.perfetto.protos.AndroidNetworkMetric.CorePacketStatisticRcore2
+gro_aggregation_ratio ( RgroAggregationRatio 
+TxK
+total ( 25.perfetto.protos.AndroidNetworkMetric.PacketStatisticRtotalM
+core ( 29.perfetto.protos.AndroidNetworkMetric.CorePacketStatisticRcore“
+ NetDevice
+name ( Rname8
+rx ( 2(.perfetto.protos.AndroidNetworkMetric.RxRrx8
+tx ( 2(.perfetto.protos.AndroidNetworkMetric.TxRtx­
+NetRxActionStatistic
+count (Rcount
+
+runtime_ms (R runtimeMs$
+avg_runtime_ms (R avgRuntimeMs
+mcycles (Rmcycles
+ avg_freq_khz (R
+avgFreqKhz
+CoreNetRxActionStatistic
+id ( Ridq
+net_rx_action_statistic ( 2:.perfetto.protos.AndroidNetworkMetric.NetRxActionStatisticRnetRxActionStatisticî
+ NetRxActionP
+total ( 2:.perfetto.protos.AndroidNetworkMetric.NetRxActionStatisticRtotalR
+core ( 2>.perfetto.protos.AndroidNetworkMetric.CoreNetRxActionStatisticRcore9
+avg_interstack_latency_ms (RavgInterstackLatencyMs
+•
+2protos/perfetto/metrics/android/other_traces.protoperfetto.protos"N
+AndroidOtherTracesMetric2
+finalized_traces_uuid ( RfinalizedTracesUuid
+ˆ
+2protos/perfetto/metrics/android/package_list.protoperfetto.protos"À
+AndroidPackageListG
+packages ( 2+.perfetto.protos.AndroidPackageList.PackageRpackagesa
+Package!
+ package_name ( R packageName
+uid (Ruid!
+ version_code (R versionCode
+œ
+5protos/perfetto/metrics/android/powrails_metric.protoperfetto.protos"Ñ
+AndroidPowerRailsN
+ power_rails ( 2-.perfetto.protos.AndroidPowerRails.PowerRailsR
+powerRailsN
+
+EnergyData!
+ timestamp_ms (R timestampMs
+
+energy_uws (R energyUws›
+
+PowerRails
+name ( RnameN
+ energy_data ( 2-.perfetto.protos.AndroidPowerRails.EnergyDataR
+energyData)
+avg_used_power_mw (RavgUsedPowerMw
+å
+4protos/perfetto/metrics/android/profiler_smaps.protoperfetto.protos6protos/perfetto/metrics/android/process_metadata.proto"ã
+ ProfilerSmapsC
+instance ( 2'.perfetto.protos.ProfilerSmaps.InstanceRinstancey
+Mapping
+path ( Rpath
+size_kb (RsizeKb(
+private_dirty_kb (RprivateDirtyKb
+swap_kb (RswapKb‘
+InstanceA
+process ( 2'.perfetto.protos.AndroidProcessMetadataRprocessB
+mappings ( 2&.perfetto.protos.ProfilerSmaps.MappingRmappings
+Ì
+7protos/perfetto/metrics/android/rt_runtime_metric.protoperfetto.protos"ÿ
+AndroidRtRuntimeMetric
+ max_runtime (R
+maxRuntime$
+over_5ms_count (R over5msCount[
+longest_rt_slices ( 2/.perfetto.protos.AndroidRtRuntimeMetric.RtSliceRlongestRtSlicesA
+RtSlice
+tname ( Rtname
+ts (Rts
+dur (Rdur
+
+0protos/perfetto/metrics/android/simpleperf.protoperfetto.protos"<
+AndroidSimpleperfMetric!
+ urgent_ratio (R urgentRatio
+õ#
+4protos/perfetto/metrics/android/startup_metric.protoperfetto.protos6protos/perfetto/metrics/android/process_metadata.proto"ó"
+AndroidStartupMetricG
+startup ( 2-.perfetto.protos.AndroidStartupMetric.StartupRstartupà
+TaskStateBreakdown$
+running_dur_ns (R runningDurNs&
+runnable_dur_ns (R runnableDurNs?
+uninterruptible_sleep_dur_ns (RuninterruptibleSleepDurNs;
+interruptible_sleep_dur_ns (RinterruptibleSleepDurNso
+McyclesByCoreType
+little (Rlittle
+big (Rbig
+bigger (Rbigger
+unknown (Runknown5
+Slice
+dur_ns (RdurNs
+dur_ms (RdurMsß
+ ToFirstFrame
+dur_ns (RdurNs
+dur_ms (RdurMsr
+main_thread_by_task_state ( 28.perfetto.protos.AndroidStartupMetric.TaskStateBreakdownRmainThreadByTaskStateh
+mcycles_by_core_type ( 27.perfetto.protos.AndroidStartupMetric.McyclesByCoreTypeRmcyclesByCoreTypeA
+other_processes_spawned_count ( RotherProcessesSpawnedCount_
+time_activity_manager ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeActivityManagerf
+time_activity_thread_main ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeActivityThreadMain_
+time_bind_application ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeBindApplication[
+time_activity_start ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeActivityStart]
+time_activity_resume ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeActivityResume_
+time_activity_restart ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeActivityRestartZ
+time_choreographer ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeChoreographerN
+ time_inflate ( 2+.perfetto.protos.AndroidStartupMetric.SliceR timeInflateY
+time_get_resources ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeGetResourcesf
+time_before_start_process
+ ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeBeforeStartProcessf
+time_during_start_process ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeDuringStartProcessM
+ to_post_fork ( 2+.perfetto.protos.AndroidStartupMetric.SliceR
+toPostForkb
+to_activity_thread_main ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtoActivityThreadMain[
+to_bind_application ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtoBindApplicationQ
+time_post_fork ( 2+.perfetto.protos.AndroidStartupMetric.SliceR timePostForkO
+ time_dex_open ( 2+.perfetto.protos.AndroidStartupMetric.SliceR timeDexOpenW
+time_verify_class ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeVerifyClass0
+jit_compiled_methods ( RjitCompiledMethodsh
+time_jit_thread_pool_on_cpu ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeJitThreadPoolOnCpuO
+ time_gc_total ( 2+.perfetto.protos.AndroidStartupMetric.SliceR timeGcTotalP
+time_gc_on_cpu ( 2+.perfetto.protos.AndroidStartupMetric.SliceR timeGcOnCpuJ  J JJ\
+
+HscMetricsN
+ full_startup ( 2+.perfetto.protos.AndroidStartupMetric.SliceR fullStartupd
+Activity
+name ( Rname
+method ( Rmethod&
+ts_method_start (R tsMethodStartJ›
+BinderTransactionG
+duration ( 2+.perfetto.protos.AndroidStartupMetric.SliceRduration
+thread ( Rthread-
+destination_thread ( RdestinationThread/
+destination_process ( RdestinationProcess
+flags ( Rflags
+code ( Rcode
+ data_size (RdataSize¯
+OptimizationStatus
+ odex_status ( R
+odexStatus-
+compilation_filter ( RcompilationFilter-
+compilation_reason ( RcompilationReason
+location ( Rlocation[
+EventTimestamps'
+intent_received (RintentReceived
+ first_frame (R
+firstFrame³
+Startup
+
+startup_id ( R startupId!
+ package_name ( R packageName!
+ process_name ( R processNameN
+
+activities ( 2..perfetto.protos.AndroidStartupMetric.ActivityR
+activitiesq
+long_binder_transactions ( 27.perfetto.protos.AndroidStartupMetric.BinderTransactionRlongBinderTransactions,
+zygote_new_process (RzygoteNewProcessC
+activity_hosting_process_count ( RactivityHostingProcessCount`
+event_timestamps ( 25.perfetto.protos.AndroidStartupMetric.EventTimestampsReventTimestampsX
+to_first_frame ( 22.perfetto.protos.AndroidStartupMetric.ToFirstFrameR toFirstFrameA
+process ( 2'.perfetto.protos.AndroidProcessMetadataRprocessB
+hsc ( 20.perfetto.protos.AndroidStartupMetric.HscMetricsRhscY
+report_fully_drawn ( 2+.perfetto.protos.AndroidStartupMetric.SliceRreportFullyDrawni
+optimization_status ( 28.perfetto.protos.AndroidStartupMetric.OptimizationStatusRoptimizationStatusJ
+
+
+4protos/perfetto/metrics/android/surfaceflinger.protoperfetto.protos"Ó
+AndroidSurfaceflingerMetric#
+ missed_frames ( R missedFrames*
+missed_hwc_frames ( RmissedHwcFrames*
+missed_gpu_frames ( RmissedGpuFrames*
+missed_frame_rate (RmissedFrameRate1
+missed_hwc_frame_rate (RmissedHwcFrameRate1
+missed_gpu_frame_rate (RmissedGpuFrameRate'
+gpu_invocations ( RgpuInvocations2
+avg_gpu_waiting_dur_ms (RavgGpuWaitingDurMsH
+"total_non_empty_gpu_waiting_dur_ms (RtotalNonEmptyGpuWaitingDurMs
+ð
+7protos/perfetto/metrics/android/sysui_cuj_metrics.protoperfetto.protos6protos/perfetto/metrics/android/process_metadata.proto"ë
+AndroidSysUiCujMetricsE
+frames ( 2-.perfetto.protos.AndroidSysUiCujMetrics.FrameRframes
+cuj_name ( RcujName
+ cuj_start (RcujStart
+cuj_dur (RcujDurA
+process ( 2'.perfetto.protos.AndroidProcessMetadataRprocessv
+Frame
+number (Rnumber
+vsync (Rvsync
+ts (Rts
+dur (Rdur
+
+jank_cause ( R jankCause
+»
+0protos/perfetto/metrics/android/task_names.protoperfetto.protos"õ
+AndroidTaskNamesC
+process ( 2).perfetto.protos.AndroidTaskNames.ProcessRprocess›
+Process
+pid (Rpid!
+ process_name ( R processName
+ thread_name ( R
+threadName
+uid (Ruid(
+uid_package_name ( RuidPackageName
+”
+Aprotos/perfetto/metrics/android/thread_time_in_state_metric.protoperfetto.protos6protos/perfetto/metrics/android/process_metadata.proto"…
+AndroidThreadTimeInStateMetricU
+ processes ( 27.perfetto.protos.AndroidThreadTimeInStateMetric.ProcessR processesÀ
+MetricsByCoreType)
+time_in_state_cpu (RtimeInStateCpu
+ core_type ( RcoreType
+
+runtime_ms (R runtimeMs
+mcycles (Rmcycles*
+power_profile_mah (RpowerProfileMah±
+Thread
+name ( Rname
+ main_thread (R
+mainThreadr
+metrics_by_core_type ( 2A.perfetto.protos.AndroidThreadTimeInStateMetric.MetricsByCoreTypeRmetricsByCoreType”
+ProcessC
+metadata ( 2'.perfetto.protos.AndroidProcessMetadataRmetadatar
+metrics_by_core_type ( 2A.perfetto.protos.AndroidThreadTimeInStateMetric.MetricsByCoreTypeRmetricsByCoreTypeP
+threads ( 26.perfetto.protos.AndroidThreadTimeInStateMetric.ThreadRthreads
+Ó
+3protos/perfetto/metrics/android/trace_quality.protoperfetto.protos"Š
+AndroidTraceQualityMetricN
+failures ( 22.perfetto.protos.AndroidTraceQualityMetric.FailureRfailures
+Failure
+name ( Rname
+m
+?protos/perfetto/metrics/android/android_trusty_workqueues.protoperfetto.protos"
+AndroidTrustyWorkqueues
+¦
+9protos/perfetto/metrics/android/unsymbolized_frames.protoperfetto.protos"×
+UnsymbolizedFramesA
+frames ( 2).perfetto.protos.UnsymbolizedFrames.FrameRframes~
+Frame
+module ( Rmodule
+build_id ( RbuildId
+address (Raddress(
+google_lookup_id ( RgoogleLookupId
+Ú0
+%protos/perfetto/metrics/metrics.protoperfetto.protos1protos/perfetto/metrics/android/batt_metric.proto0protos/perfetto/metrics/android/cpu_metric.proto3protos/perfetto/metrics/android/camera_metric.proto9protos/perfetto/metrics/android/camera_unagg_metric.proto5protos/perfetto/metrics/android/display_metrics.proto5protos/perfetto/metrics/android/dma_heap_metric.proto1protos/perfetto/metrics/android/dvfs_metric.proto4protos/perfetto/metrics/android/fastrpc_metric.proto0protos/perfetto/metrics/android/g2d_metric.proto0protos/perfetto/metrics/android/gpu_metric.proto0protos/perfetto/metrics/android/hwcomposer.proto1protos/perfetto/metrics/android/hwui_metric.proto0protos/perfetto/metrics/android/ion_metric.proto8protos/perfetto/metrics/android/irq_runtime_metric.proto1protos/perfetto/metrics/android/jank_metric.proto9protos/perfetto/metrics/android/java_heap_histogram.proto5protos/perfetto/metrics/android/java_heap_stats.proto0protos/perfetto/metrics/android/lmk_metric.proto7protos/perfetto/metrics/android/lmk_reason_metric.proto0protos/perfetto/metrics/android/mem_metric.proto6protos/perfetto/metrics/android/mem_unagg_metric.proto6protos/perfetto/metrics/android/multiuser_metric.proto4protos/perfetto/metrics/android/network_metric.proto2protos/perfetto/metrics/android/other_traces.proto2protos/perfetto/metrics/android/package_list.proto5protos/perfetto/metrics/android/powrails_metric.proto4protos/perfetto/metrics/android/profiler_smaps.proto7protos/perfetto/metrics/android/rt_runtime_metric.proto0protos/perfetto/metrics/android/simpleperf.proto4protos/perfetto/metrics/android/startup_metric.proto4protos/perfetto/metrics/android/surfaceflinger.proto7protos/perfetto/metrics/android/sysui_cuj_metrics.proto0protos/perfetto/metrics/android/task_names.protoAprotos/perfetto/metrics/android/thread_time_in_state_metric.proto3protos/perfetto/metrics/android/trace_quality.proto?protos/perfetto/metrics/android/android_trusty_workqueues.proto9protos/perfetto/metrics/android/unsymbolized_frames.proto"À
+ TraceMetadata*
+trace_duration_ns (RtraceDurationNs
+
+trace_uuid ( R traceUuid:
+android_build_fingerprint ( RandroidBuildFingerprintI
+!statsd_triggering_subscription_id (RstatsdTriggeringSubscriptionId(
+trace_size_bytes (RtraceSizeBytes#
+ trace_trigger ( R traceTrigger.
+unique_session_name ( RuniqueSessionName,
+trace_config_pbtxt ( RtraceConfigPbtxt*
+sched_duration_ns
+ (RschedDurationNsJ"Ë
+TraceAnalysisStats<
+stat ( 2(.perfetto.protos.TraceAnalysisStats.StatRstatÐ
+Stat
+name ( Rname
+idx ( RidxH
+severity (2,.perfetto.protos.TraceAnalysisStats.SeverityRseverityB
+source (2*.perfetto.protos.TraceAnalysisStats.SourceRsource
+count (Rcount"_
+Severity
+SEVERITY_UNKNOWN
+ SEVERITY_INFO
+SEVERITY_DATA_LOSS
+SEVERITY_ERROR"C
+Source
+SOURCE_UNKNOWN
+ SOURCE_TRACE
+SOURCE_ANALYSIS"º
+ TraceMetricsH
+ android_batt ( 2%.perfetto.protos.AndroidBatteryMetricR androidBattB
+ android_cpu ( 2!.perfetto.protos.AndroidCpuMetricR
+androidCpuE
+ android_mem ( 2$.perfetto.protos.AndroidMemoryMetricR
+androidMem\
+android_mem_unagg ( 20.perfetto.protos.AndroidMemoryUnaggregatedMetricRandroidMemUnaggU
+android_package_list ( 2#.perfetto.protos.AndroidPackageListRandroidPackageListB
+ android_ion ( 2!.perfetto.protos.AndroidIonMetricR
+androidIonN
+android_fastrpc ( 2%.perfetto.protos.AndroidFastrpcMetricRandroidFastrpcB
+ android_lmk ( 2!.perfetto.protos.AndroidLmkMetricR
+androidLmkM
+android_powrails ( 2".perfetto.protos.AndroidPowerRailsRandroidPowrailsN
+android_startup ( 2%.perfetto.protos.AndroidStartupMetricRandroidStartupE
+trace_metadata ( 2.perfetto.protos.TraceMetadataR traceMetadataD
+ trace_stats! ( 2#.perfetto.protos.TraceAnalysisStatsR
+traceStatsT
+unsymbolized_frames ( 2#.perfetto.protos.UnsymbolizedFramesRunsymbolizedFramesF
+java_heap_stats ( 2.perfetto.protos.JavaHeapStatsR javaHeapStatsR
+java_heap_histogram ( 2".perfetto.protos.JavaHeapHistogramRjavaHeapHistogramU
+android_lmk_reason ( 2'.perfetto.protos.AndroidLmkReasonMetricRandroidLmkReasonR
+android_hwui_metric ( 2".perfetto.protos.AndroidHwuiMetricRandroidHwuiMetricO
+display_metrics ( 2&.perfetto.protos.AndroidDisplayMetricsRdisplayMetricsO
+android_task_names ( 2!.perfetto.protos.AndroidTaskNamesRandroidTaskNameso
+android_thread_time_in_state ( 2/.perfetto.protos.AndroidThreadTimeInStateMetricRandroidThreadTimeInStatec
+android_surfaceflinger ( 2,.perfetto.protos.AndroidSurfaceflingerMetricRandroidSurfaceflingerB
+ android_gpu ( 2!.perfetto.protos.AndroidGpuMetricR
+androidGpuS
+android_sysui_cuj ( 2'.perfetto.protos.AndroidSysUiCujMetricsRandroidSysuiCujX
+android_hwcomposer ( 2).perfetto.protos.AndroidHwcomposerMetricsRandroidHwcomposerF
+ android_jank ( 2#.perfetto.protos.AndroidJankMetricsR androidJank-
+g2d ( 2.perfetto.protos.G2dMetricsRg2dO
+android_dma_heap ( 2%.perfetto.protos.AndroidDmaHeapMetricRandroidDmaHeap^
+android_trace_quality" ( 2*.perfetto.protos.AndroidTraceQualityMetricRandroidTraceQualityE
+profiler_smaps# ( 2.perfetto.protos.ProfilerSmapsR profilerSmapsT
+android_multiuser$ ( 2'.perfetto.protos.AndroidMultiuserMetricRandroidMultiuserW
+android_simpleperf% ( 2(.perfetto.protos.AndroidSimpleperfMetricRandroidSimpleperfK
+android_camera& ( 2$.perfetto.protos.AndroidCameraMetricR androidCameraE
+ android_dvfs' ( 2".perfetto.protos.AndroidDvfsMetricR androidDvfsN
+android_netperf( ( 2%.perfetto.protos.AndroidNetworkMetricRandroidNetperfb
+android_camera_unagg) ( 20.perfetto.protos.AndroidCameraUnaggregatedMetricRandroidCameraUnaggU
+android_rt_runtime* ( 2'.perfetto.protos.AndroidRtRuntimeMetricRandroidRtRuntimeX
+android_irq_runtime+ ( 2(.perfetto.protos.AndroidIrqRuntimeMetricRandroidIrqRuntimed
+android_trusty_workqueues, ( 2(.perfetto.protos.AndroidTrustyWorkqueuesRandroidTrustyWorkqueues[
+android_other_traces- ( 2).perfetto.protos.AndroidOtherTracesMetricRandroidOtherTraces*Âô*ôé*éÑJJ
+ J JJJ \ No newline at end of file
diff --git a/python/perfetto/trace_processor/metrics.descriptor.sha1 b/python/perfetto/trace_processor/metrics.descriptor.sha1
new file mode 100644
index 000000000..4704b1e2b
--- /dev/null
+++ b/python/perfetto/trace_processor/metrics.descriptor.sha1
@@ -0,0 +1,6 @@
+
+// SHA1(tools/gen_binary_descriptors)
+// c4a38769074f8a8c2ffbf514b267919b5f2d47df
+// SHA1(protos/perfetto/metrics/metrics.proto)
+// 05ee0e06abfeb9a93681abeaa5983cb25d663125
+ \ No newline at end of file
diff --git a/python/perfetto/trace_processor/platform.py b/python/perfetto/trace_processor/platform.py
new file mode 100644
index 000000000..650805845
--- /dev/null
+++ b/python/perfetto/trace_processor/platform.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import socket
+import subprocess
+import tempfile
+from typing import Tuple
+from urllib import request
+
+from perfetto.trace_uri_resolver.path import PathUriResolver
+from perfetto.trace_uri_resolver.registry import ResolverRegistry
+
+
+# URL to download script to run trace_processor
+SHELL_URL = 'http://get.perfetto.dev/trace_processor'
+
+
+class PlatformDelegate:
+ """Abstracts operations which can vary based on platform."""
+
+ def get_resource(self, file: str) -> bytes:
+ ws = os.path.dirname(__file__)
+ with open(os.path.join(ws, file), 'rb') as x:
+ return x.read()
+
+ def get_shell_path(self, bin_path: str) -> str:
+ if bin_path is not None:
+ if not os.path.isfile(bin_path):
+ raise Exception('Path to binary is not valid')
+ return bin_path
+
+ with tempfile.NamedTemporaryFile(delete=False) as file:
+ req = request.Request(SHELL_URL)
+ with request.urlopen(req) as req:
+ file.write(req.read())
+ if os.name != 'nt':
+ subprocess.check_output(['chmod', '+x', file.name])
+ return file.name
+
+ def get_bind_addr(self, port: int) -> Tuple[str, int]:
+ if port:
+ return 'localhost', port
+
+ free_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ free_socket.bind(('', 0))
+ free_socket.listen(5)
+ port = free_socket.getsockname()[1]
+ free_socket.close()
+ return 'localhost', port
+
+ def default_resolver_registry(self) -> ResolverRegistry:
+ return ResolverRegistry(resolvers=[PathUriResolver])
diff --git a/python/perfetto/trace_processor/protos.py b/python/perfetto/trace_processor/protos.py
new file mode 100644
index 000000000..2eb0af341
--- /dev/null
+++ b/python/perfetto/trace_processor/protos.py
@@ -0,0 +1,63 @@
+# Copyright (C) 2020 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from google.protobuf import descriptor_pb2
+from google.protobuf import message_factory
+from google.protobuf.descriptor_pool import DescriptorPool
+
+from perfetto.trace_processor.platform import PlatformDelegate
+
+
+class ProtoFactory:
+
+ def __init__(self, platform_delegate: PlatformDelegate):
+ # Declare descriptor pool
+ self.descriptor_pool = DescriptorPool()
+
+ # Load trace processor descriptor and add to descriptor pool
+ tp_desc = platform_delegate.get_resource('trace_processor.descriptor')
+ tp_file_desc_set_pb2 = descriptor_pb2.FileDescriptorSet()
+ tp_file_desc_set_pb2.MergeFromString(tp_desc)
+
+ for f_desc_pb2 in tp_file_desc_set_pb2.file:
+ self.descriptor_pool.Add(f_desc_pb2)
+
+ # Load metrics descriptor and add to descriptor pool
+ metrics_desc = platform_delegate.get_resource('metrics.descriptor')
+ metrics_file_desc_set_pb2 = descriptor_pb2.FileDescriptorSet()
+ metrics_file_desc_set_pb2.MergeFromString(metrics_desc)
+
+ for f_desc_pb2 in metrics_file_desc_set_pb2.file:
+ self.descriptor_pool.Add(f_desc_pb2)
+
+ def create_message_factory(message_type):
+ message_desc = self.descriptor_pool.FindMessageTypeByName(message_type)
+ return message_factory.MessageFactory().GetPrototype(message_desc)
+
+ # Create proto messages to correctly communicate with the RPC API by sending
+ # and receiving data as protos
+ self.AppendTraceDataResult = create_message_factory(
+ 'perfetto.protos.AppendTraceDataResult')
+ self.StatusResult = create_message_factory('perfetto.protos.StatusResult')
+ self.ComputeMetricArgs = create_message_factory(
+ 'perfetto.protos.ComputeMetricArgs')
+ self.ComputeMetricResult = create_message_factory(
+ 'perfetto.protos.ComputeMetricResult')
+ self.RawQueryArgs = create_message_factory('perfetto.protos.RawQueryArgs')
+ self.QueryResult = create_message_factory('perfetto.protos.QueryResult')
+ self.TraceMetrics = create_message_factory('perfetto.protos.TraceMetrics')
+ self.DisableAndReadMetatraceResult = create_message_factory(
+ 'perfetto.protos.DisableAndReadMetatraceResult')
+ self.CellsBatch = create_message_factory(
+ 'perfetto.protos.QueryResult.CellsBatch')
diff --git a/python/perfetto/trace_processor/shell.py b/python/perfetto/trace_processor/shell.py
new file mode 100644
index 000000000..93f8bd083
--- /dev/null
+++ b/python/perfetto/trace_processor/shell.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+# Copyright (C) 2020 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import subprocess
+import sys
+import time
+from urllib import request, error
+
+from perfetto.trace_processor.platform import PlatformDelegate
+
+# Default port that trace_processor_shell runs on
+TP_PORT = 9001
+
+
+def load_shell(bin_path: str, unique_port: bool, verbose: bool,
+ ingest_ftrace_in_raw: bool, platform_delegate: PlatformDelegate):
+ addr, port = platform_delegate.get_bind_addr(
+ port=0 if unique_port else TP_PORT)
+ url = f'{addr}:{str(port)}'
+
+ shell_path = platform_delegate.get_shell_path(bin_path=bin_path)
+ if os.name == 'nt' and not shell_path.endswith('.exe'):
+ tp_exec = [sys.executable, shell_path]
+ else:
+ tp_exec = [shell_path]
+
+ args = ['-D', '--http-port', str(port)]
+ if not ingest_ftrace_in_raw:
+ args.append('--no-ftrace-raw')
+
+ p = subprocess.Popen(
+ tp_exec + args,
+ stdout=subprocess.DEVNULL,
+ stderr=None if verbose else subprocess.DEVNULL)
+
+ while True:
+ try:
+ if p.poll() != None:
+ if unique_port:
+ raise Exception(
+ "Random port allocation failed, please file a bug at https://goto.google.com/perfetto-bug"
+ )
+ raise Exception(
+ "Trace processor failed to start, please file a bug at https://goto.google.com/perfetto-bug"
+ )
+ _ = request.urlretrieve(f'http://{url}/status')
+ time.sleep(1)
+ break
+ except error.URLError:
+ pass
+
+ return url, p
diff --git a/python/perfetto/trace_processor/trace_processor.descriptor b/python/perfetto/trace_processor/trace_processor.descriptor
new file mode 100644
index 000000000..d8fe39e0d
--- /dev/null
+++ b/python/perfetto/trace_processor/trace_processor.descriptor
Binary files differ
diff --git a/python/perfetto/trace_processor/trace_processor.descriptor.sha1 b/python/perfetto/trace_processor/trace_processor.descriptor.sha1
new file mode 100644
index 000000000..3d9e07544
--- /dev/null
+++ b/python/perfetto/trace_processor/trace_processor.descriptor.sha1
@@ -0,0 +1,6 @@
+
+// SHA1(tools/gen_binary_descriptors)
+// c4a38769074f8a8c2ffbf514b267919b5f2d47df
+// SHA1(protos/perfetto/trace_processor/trace_processor.proto)
+// ea89764637957b3b71978972257aba2f0fddbfc9
+ \ No newline at end of file
diff --git a/src/trace_processor/metrics/experimental/OWNERS b/python/perfetto/trace_uri_resolver/__init__.py
index e69de29bb..e69de29bb 100644
--- a/src/trace_processor/metrics/experimental/OWNERS
+++ b/python/perfetto/trace_uri_resolver/__init__.py
diff --git a/python/perfetto/trace_uri_resolver/path.py b/python/perfetto/trace_uri_resolver/path.py
new file mode 100644
index 000000000..ca5893af0
--- /dev/null
+++ b/python/perfetto/trace_uri_resolver/path.py
@@ -0,0 +1,36 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from typing import Type
+
+from perfetto.trace_uri_resolver import util
+from perfetto.trace_uri_resolver.resolver import TraceUriResolver
+
+
+class PathUriResolver(TraceUriResolver):
+ PREFIX: str = None
+
+ def __init__(self, path: str):
+ self.path = path
+
+ def resolve(self) -> TraceUriResolver.Result:
+ return [
+ TraceUriResolver.Result(
+ trace=util.file_generator(self.path), metadata=dict())
+ ]
+
+ @classmethod
+ def from_trace_uri(cls: Type['PathUriResolver'],
+ args_str: str) -> 'PathUriResolver':
+ return PathUriResolver(args_str)
diff --git a/python/perfetto/trace_uri_resolver/registry.py b/python/perfetto/trace_uri_resolver/registry.py
new file mode 100644
index 000000000..7a57bb024
--- /dev/null
+++ b/python/perfetto/trace_uri_resolver/registry.py
@@ -0,0 +1,81 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import dataclasses as dc
+from typing import Dict, List, Type, Union
+
+from perfetto.trace_uri_resolver import util
+from perfetto.trace_uri_resolver.resolver import TraceContent
+from perfetto.trace_uri_resolver.resolver import TraceGenerator
+from perfetto.trace_uri_resolver.resolver import TraceUri
+from perfetto.trace_uri_resolver.resolver import TraceUriResolver
+
+TraceReference = Union[TraceUriResolver, TraceUri, TraceContent]
+TraceListReference = Union[TraceReference, List[TraceReference]]
+
+
+class ResolverRegistry:
+
+ @dc.dataclass
+ class Result:
+ generator: TraceGenerator
+ metadata: Dict[str, str]
+
+ def __init__(self, resolvers: List[Type[TraceUriResolver]] = []):
+ self.registry: Dict[str, Type[TraceUriResolver]] = dict()
+
+ for resolver in resolvers:
+ self.register(resolver)
+
+ def register(self, provider: Type[TraceUriResolver]):
+ self.registry[provider.PREFIX] = provider
+
+ def resolve(self, ref: TraceListReference) -> List['ResolverRegistry.Result']:
+ if isinstance(ref, list):
+ return [inner for outer in ref for inner in self._resolve_ref(outer)]
+ return self._resolve_ref(ref)
+
+ def _resolve_ref(self,
+ ref: TraceReference) -> List['ResolverRegistry.Result']:
+ if isinstance(ref, TraceUriResolver):
+ return [
+ _merge_metadata(outer, inner)
+ for outer in ref.resolve()
+ for inner in self.resolve(outer.trace)
+ ]
+
+ if isinstance(ref, TraceUri):
+ return [
+ _merge_metadata(outer, inner)
+ for outer in self._resolver_from_uri(ref).resolve()
+ for inner in self.resolve(outer.trace)
+ ]
+
+ if hasattr(ref, 'read'):
+ return [ResolverRegistry.Result(util.read_generator(ref), {})]
+
+ return [ResolverRegistry.Result(ref, {})]
+
+ def _resolver_from_uri(self, uri: TraceUri) -> TraceUriResolver:
+ resolver_name, _ = util.parse_trace_uri(uri)
+ resolver_cls = self.registry[resolver_name]
+ return resolver_cls.from_trace_uri(uri)
+
+
+def _merge_metadata(resolver_res: TraceUriResolver.Result,
+ registry_res: ResolverRegistry.Result
+ ) -> List[ResolverRegistry.Result]:
+ return ResolverRegistry.Result(
+ generator=registry_res.generator,
+ metadata=util.merge_dicts(resolver_res.metadata, registry_res.metadata))
diff --git a/python/perfetto/trace_uri_resolver/resolver.py b/python/perfetto/trace_uri_resolver/resolver.py
new file mode 100644
index 000000000..13ec58f08
--- /dev/null
+++ b/python/perfetto/trace_uri_resolver/resolver.py
@@ -0,0 +1,134 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import dataclasses as dc
+from typing import BinaryIO, Dict, Generator, List, Type, Union
+
+from perfetto.trace_uri_resolver import util
+
+TraceUri = str
+TraceGenerator = Generator[bytes, None, None]
+TraceContent = Union[BinaryIO, TraceGenerator]
+
+
+class TraceUriResolver:
+ """"Resolves a trace URI (e.g. 'ants:trace_id=1234') into a list of traces.
+
+ This class can be subclassed to provide a pluggable mechanism for looking
+ up traces using URI strings.
+
+ For example:
+ class CustomTraceResolver(TraceResolver):
+ PREFIX = 'custom'
+
+ def __init__(self, build_branch: List[str] = None, id: str = None):
+ self.build_branch = build_branch
+ self.id = id
+ self.db = init_db()
+
+ def resolve(self):
+ traces = self.db.lookup(
+ id=self.id, build_branch=self.build_branch)['path']
+ return [
+ TraceResolver.Result(
+ trace=t['path'],
+ args={'iteration': t['iteration'], 'device': t['device']}
+ )
+ for t in traces
+ ]
+
+ Trace resolvers can be passed to trace processor directly:
+ with TraceProcessor(CustomTraceResolver(id='abcdefg')) as tp:
+ tp.query('select * from slice')
+
+ Alternatively, a trace addesses can be passed:
+ config = TraceProcessorConfig(
+ resolver_registry=ResolverRegistry(resolvers=[CustomTraceResolver])
+ )
+ with TraceProcessor('custom:id=abcdefg', config=config) as tp:
+ tp.query('select * from slice')
+ """
+
+ # Subclasses should set PREFIX to match the trace address prefix they
+ # want to handle.
+ PREFIX: str = None
+
+ @dc.dataclass
+ class Result:
+ # TraceUri is present here because it allows recursive lookups (i.e.
+ # a resolver which returns a path to a trace).
+ trace: Union[TraceUri, TraceContent]
+
+ # metadata allows additional key-value pairs to be provided which are
+ # associated for trace. For example, test names and iteration numbers
+ # could be provivded for traces originating from lab tests.
+ metadata: Dict[str, str]
+
+ def __init__(self,
+ trace: Union[TraceUri, TraceContent],
+ metadata: Dict[str, str] = dict()):
+ self.trace = trace
+ self.metadata = metadata
+
+ def resolve(self) -> List['TraceUriResolver.Result']:
+ """Resolves a list of traces.
+
+ Subclasses should implement this method and resolve the parameters
+ specified in the constructor to a list of traces."""
+ raise Exception("resolve is unimplemented for this resolver")
+
+ @classmethod
+ def from_trace_uri(cls: Type['TraceUriResolver'],
+ uri: TraceUri) -> 'TraceUriResolver':
+ """Creates a resolver from a URI.
+
+ URIs have the form:
+ android_ci:day=2021-01-01;devices=blueline,crosshatch
+
+ This is converted to a dictionary of the form:
+ {'day': '2021-01-01', 'id': ['blueline', 'crosshatch']}
+
+ and passed as kwargs to the constructor of the trace resolver (see class
+ documentation for info).
+
+ Generally, sublcasses should not override this method as the standard
+ trace address format should work for most usecases. Instead, simply
+ define your constructor with the parameters you expect to see in the
+ trace address."""
+ return cls(**_args_dict_from_uri(uri))
+
+
+def _args_dict_from_uri(uri: str) -> Dict[str, str]:
+ """Creates an the args dictionary from a trace URI.
+
+ URIs have the form:
+ android_ci:day=2021-01-01;devices=blueline,crosshatch
+
+ This is converted to a dictionary of the form:
+ {'day': '2021-01-01', 'id': ['blueline', 'crosshatch']}
+ """
+ _, args_str = util.parse_trace_uri(uri)
+ if not args_str:
+ return {}
+
+ args_lst = args_str.split(';')
+ args_dict = dict()
+ for arg in args_lst:
+ (key, value) = arg.split('=')
+ lst = value.split(',')
+ if len(lst) > 1:
+ args_dict[key] = lst
+ else:
+ args_dict[key] = value
+ return args_dict
diff --git a/python/perfetto/trace_uri_resolver/util.py b/python/perfetto/trace_uri_resolver/util.py
new file mode 100644
index 000000000..116be38d4
--- /dev/null
+++ b/python/perfetto/trace_uri_resolver/util.py
@@ -0,0 +1,57 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+from typing import BinaryIO, Dict, Optional, Tuple
+
+# Limit parsing file to 1MB to maintain parity with the UI
+MAX_BYTES_LOADED = 1 * 1024 * 1024
+
+
+def file_generator(path: str):
+ with open(path, 'rb') as f:
+ yield from read_generator(f)
+
+
+def read_generator(trace: BinaryIO):
+ while True:
+ chunk = trace.read(MAX_BYTES_LOADED)
+ if not chunk:
+ break
+ yield chunk
+
+
+def merge_dicts(a: Dict[str, str], b: Dict[str, str]):
+ return {**a, **b}
+
+
+def parse_trace_uri(uri: str) -> Tuple[Optional[str], str]:
+ # This is definitely a path and not a URI
+ if uri.startswith('/') or uri.startswith('.'):
+ return None, uri
+
+ # If there's no colon, it cannot be a URI
+ idx = uri.find(':')
+ if idx == -1:
+ return None, uri
+
+ # If there is only a single character before the colon
+ # this is likely a Windows path; throw an error on other platforms
+ # to prevent single character names causing issues on Windows.
+ if idx == 1:
+ if os.name != 'nt':
+ raise Exception('Single character resolvers are not allowed')
+ return None, uri
+
+ return (uri[:idx], uri[idx + 1:])
diff --git a/python/run_tests.py b/python/run_tests.py
new file mode 100755
index 000000000..9c1dbf996
--- /dev/null
+++ b/python/run_tests.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python3
+# Copyright (C) 2020 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import argparse
+import os
+import sys
+import unittest
+
+from test import api_unittest
+from test import api_integrationtest
+from test import resolver_unittest
+
+ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+
+def main():
+ try:
+ import numpy
+ import pandas
+ except ModuleNotFoundError:
+ print('Cannot proceed. Please `pip3 install pandas numpy`', file=sys.stderr)
+ return 1
+
+ # Set paths to trace_processor_shell and root directory as environment
+ # variables
+ parser = argparse.ArgumentParser()
+ parser.add_argument("shell", type=str)
+ os.environ["SHELL_PATH"] = parser.parse_args().shell
+ os.environ["ROOT_DIR"] = ROOT_DIR
+
+ loader = unittest.TestLoader()
+ suite = unittest.TestSuite()
+
+ # Add all relevant tests to test suite
+ suite.addTests(loader.loadTestsFromModule(api_unittest))
+ suite.addTests(loader.loadTestsFromModule(resolver_unittest))
+ suite.addTests(loader.loadTestsFromModule(api_integrationtest))
+
+ # Initialise runner to run all tests in suite
+ runner = unittest.TextTestRunner(verbosity=3)
+ result = runner.run(suite)
+
+ return 0 if result.wasSuccessful() else 1
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/python/setup.py b/python/setup.py
new file mode 100644
index 000000000..15ccfd1af
--- /dev/null
+++ b/python/setup.py
@@ -0,0 +1,32 @@
+from distutils.core import setup
+
+setup(
+ name='perfetto',
+ packages=[
+ 'perfetto', 'perfetto.batch_trace_processor',
+ 'perfetto.trace_processor', 'perfetto.trace_uri_resolver'
+ ],
+ package_data={'perfetto.trace_processor': ['*.descriptor']},
+ include_package_data=True,
+ version='0.5.0',
+ license='apache-2.0',
+ description='Python API for Perfetto\'s Trace Processor',
+ author='Perfetto',
+ author_email='perfetto-pypi@google.com',
+ url='https://perfetto.dev/',
+ download_url='https://github.com/google/perfetto/archive/refs/tags/v20.1.tar.gz',
+ keywords=['trace processor', 'tracing', 'perfetto'],
+ install_requires=[
+ 'protobuf',
+ ],
+ classifiers=[
+ 'Development Status :: 3 - Alpha',
+ 'License :: OSI Approved :: Apache Software License',
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3.5",
+ "Programming Language :: Python :: 3.6",
+ "Programming Language :: Python :: 3.7",
+ "Programming Language :: Python :: 3.8",
+ "Programming Language :: Python :: 3.9",
+ ],
+)
diff --git a/python/test/__init__.py b/python/test/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/python/test/__init__.py
diff --git a/python/test/api_integrationtest.py b/python/test/api_integrationtest.py
new file mode 100644
index 000000000..090c4642c
--- /dev/null
+++ b/python/test/api_integrationtest.py
@@ -0,0 +1,261 @@
+#!/usr/bin/env python3
+# Copyright (C) 2020 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import io
+import os
+import unittest
+
+import pandas as pd
+
+from perfetto.batch_trace_processor.api import BatchTraceProcessor
+from perfetto.batch_trace_processor.api import BatchTraceProcessorConfig
+from perfetto.batch_trace_processor.api import FailureHandling
+from perfetto.batch_trace_processor.api import TraceListReference
+from perfetto.trace_processor.api import PLATFORM_DELEGATE
+from perfetto.trace_processor.api import TraceProcessor
+from perfetto.trace_processor.api import TraceProcessorException
+from perfetto.trace_processor.api import TraceProcessorConfig
+from perfetto.trace_processor.api import TraceReference
+from perfetto.trace_uri_resolver.resolver import TraceUriResolver
+from perfetto.trace_uri_resolver.path import PathUriResolver
+
+
+class SimpleResolver(TraceUriResolver):
+ PREFIX = 'simple'
+
+ def __init__(self, path, skip_resolve_file=False):
+ self.path = path
+ self.file = open(example_android_trace_path(), 'rb')
+ self.skip_resolve_file = skip_resolve_file
+
+ def file_gen(self):
+ with open(example_android_trace_path(), 'rb') as f:
+ yield f.read()
+
+ def resolve(self):
+ res = [
+ TraceUriResolver.Result(
+ self.file_gen(), metadata={'source': 'generator'}),
+ TraceUriResolver.Result(
+ example_android_trace_path(), metadata={'source': 'path'}),
+ ]
+ if not self.skip_resolve_file:
+ res.extend([
+ TraceUriResolver.Result(
+ PathUriResolver(example_android_trace_path()),
+ metadata={'source': 'path_resolver'}),
+ TraceUriResolver.Result(self.file, metadata={'source': 'file'}),
+ ])
+ return res
+
+
+class RecursiveResolver(SimpleResolver):
+ PREFIX = 'recursive'
+
+ def __init__(self, path, skip_resolve_file):
+ super().__init__(path=path, skip_resolve_file=skip_resolve_file)
+
+ def resolve(self):
+ srf = self.skip_resolve_file
+ return [
+ TraceUriResolver.Result(
+ self.file_gen(), metadata={'source': 'recursive_gen'}),
+ TraceUriResolver.Result(
+ f'simple:path={self.path};skip_resolve_file={srf}',
+ metadata={
+ 'source': 'recursive_path',
+ 'root_source': 'recursive_path'
+ }),
+ TraceUriResolver.Result(
+ SimpleResolver(
+ path=self.path, skip_resolve_file=self.skip_resolve_file),
+ metadata={
+ 'source': 'recursive_obj',
+ 'root_source': 'recursive_obj'
+ }),
+ ]
+
+
+def create_batch_tp(
+ traces: TraceListReference,
+ load_failure_handling: FailureHandling = FailureHandling.RAISE_EXCEPTION,
+ execute_failure_handling: FailureHandling = FailureHandling.RAISE_EXCEPTION,
+):
+ registry = PLATFORM_DELEGATE().default_resolver_registry()
+ registry.register(SimpleResolver)
+ registry.register(RecursiveResolver)
+ config = BatchTraceProcessorConfig(
+ load_failure_handling=load_failure_handling,
+ execute_failure_handling=execute_failure_handling,
+ tp_config=TraceProcessorConfig(
+ bin_path=os.environ["SHELL_PATH"], resolver_registry=registry))
+ return BatchTraceProcessor(traces=traces, config=config)
+
+
+def create_tp(trace: TraceReference):
+ return TraceProcessor(
+ trace=trace,
+ config=TraceProcessorConfig(bin_path=os.environ["SHELL_PATH"]))
+
+
+def example_android_trace_path():
+ return os.path.join(os.environ["ROOT_DIR"], 'test', 'data',
+ 'example_android_trace_30s.pb')
+
+
+class TestApi(unittest.TestCase):
+
+ def test_invalid_trace(self):
+ f = io.BytesIO(b'<foo></foo>')
+ with self.assertRaises(TraceProcessorException):
+ _ = create_tp(trace=f)
+
+ def test_trace_path(self):
+ # Get path to trace_processor_shell and construct TraceProcessor
+ tp = create_tp(trace=example_android_trace_path())
+ qr_iterator = tp.query('select * from slice limit 10')
+ dur_result = [
+ 178646, 119740, 58073, 155000, 173177, 20209377, 3589167, 90104, 275312,
+ 65313
+ ]
+
+ for num, row in enumerate(qr_iterator):
+ self.assertEqual(row.type, 'internal_slice')
+ self.assertEqual(row.dur, dur_result[num])
+
+ # Test the batching logic by issuing a large query and ensuring we receive
+ # all rows, not just a truncated subset.
+ qr_iterator = tp.query('select count(*) as cnt from slice')
+ expected_count = next(qr_iterator).cnt
+ self.assertGreater(expected_count, 0)
+
+ qr_iterator = tp.query('select * from slice')
+ count = sum(1 for _ in qr_iterator)
+ self.assertEqual(count, expected_count)
+
+ tp.close()
+
+ def test_trace_byteio(self):
+ f = io.BytesIO(
+ b'\n(\n&\x08\x00\x12\x12\x08\x01\x10\xc8\x01\x1a\x0b\x12\t'
+ b'B|200|foo\x12\x0e\x08\x02\x10\xc8\x01\x1a\x07\x12\x05E|200')
+ with create_tp(trace=f) as tp:
+ qr_iterator = tp.query('select * from slice limit 10')
+ res = list(qr_iterator)
+
+ self.assertEqual(len(res), 1)
+
+ row = res[0]
+ self.assertEqual(row.ts, 1)
+ self.assertEqual(row.dur, 1)
+ self.assertEqual(row.name, 'foo')
+
+ def test_trace_file(self):
+ with open(example_android_trace_path(), 'rb') as file:
+ with create_tp(trace=file) as tp:
+ qr_iterator = tp.query('select * from slice limit 10')
+ dur_result = [
+ 178646, 119740, 58073, 155000, 173177, 20209377, 3589167, 90104,
+ 275312, 65313
+ ]
+
+ for num, row in enumerate(qr_iterator):
+ self.assertEqual(row.dur, dur_result[num])
+
+ def test_trace_generator(self):
+
+ def reader_generator():
+ with open(example_android_trace_path(), 'rb') as file:
+ yield file.read(1024)
+
+ with create_tp(trace=reader_generator()) as tp:
+ qr_iterator = tp.query('select * from slice limit 10')
+ dur_result = [
+ 178646, 119740, 58073, 155000, 173177, 20209377, 3589167, 90104,
+ 275312, 65313
+ ]
+
+ for num, row in enumerate(qr_iterator):
+ self.assertEqual(row.dur, dur_result[num])
+
+ def test_simple_resolver(self):
+ dur = [178646, 178646, 178646, 178646]
+ source = ['generator', 'path', 'path_resolver', 'file']
+ expected = pd.DataFrame(list(zip(dur, source)), columns=['dur', 'source'])
+
+ with create_batch_tp(
+ traces='simple:path={}'.format(example_android_trace_path())) as btp:
+ df = btp.query_and_flatten('select dur from slice limit 1')
+ pd.testing.assert_frame_equal(df, expected, check_dtype=False)
+
+ with create_batch_tp(
+ traces=SimpleResolver(path=example_android_trace_path())) as btp:
+ df = btp.query_and_flatten('select dur from slice limit 1')
+ pd.testing.assert_frame_equal(df, expected, check_dtype=False)
+
+ def test_recursive_resolver(self):
+ dur = [
+ 178646, 178646, 178646, 178646, 178646, 178646, 178646, 178646, 178646
+ ]
+ source = ['recursive_gen', 'generator', 'path', 'generator', 'path']
+ root_source = [
+ None, 'recursive_path', 'recursive_path', 'recursive_obj',
+ 'recursive_obj'
+ ]
+ expected = pd.DataFrame(
+ list(zip(dur, source, root_source)),
+ columns=['dur', 'source', 'root_source'])
+
+ uri = 'recursive:path={};skip_resolve_file=true'.format(
+ example_android_trace_path())
+ with create_batch_tp(traces=uri) as btp:
+ df = btp.query_and_flatten('select dur from slice limit 1')
+ pd.testing.assert_frame_equal(df, expected, check_dtype=False)
+
+ with create_batch_tp(
+ traces=RecursiveResolver(
+ path=example_android_trace_path(), skip_resolve_file=True)) as btp:
+ df = btp.query_and_flatten('select dur from slice limit 1')
+ pd.testing.assert_frame_equal(df, expected, check_dtype=False)
+
+ def test_btp_load_failure(self):
+ f = io.BytesIO(b'<foo></foo>')
+ with self.assertRaises(TraceProcessorException):
+ _ = create_batch_tp(traces=f)
+
+ def test_btp_load_failure_increment_stat(self):
+ f = io.BytesIO(b'<foo></foo>')
+ btp = create_batch_tp(
+ traces=f, load_failure_handling=FailureHandling.INCREMENT_STAT)
+ self.assertEqual(btp.stats().load_failures, 1)
+
+ def test_btp_query_failure(self):
+ btp = create_batch_tp(traces=example_android_trace_path())
+ with self.assertRaises(TraceProcessorException):
+ _ = btp.query('select * from sl')
+
+ def test_btp_query_failure_increment_stat(self):
+ btp = create_batch_tp(
+ traces=example_android_trace_path(),
+ execute_failure_handling=FailureHandling.INCREMENT_STAT)
+ _ = btp.query('select * from sl')
+ self.assertEqual(btp.stats().execute_failures, 1)
+
+ def test_btp_query_failure_message(self):
+ btp = create_batch_tp(
+ traces='simple:path={}'.format(example_android_trace_path()))
+ with self.assertRaisesRegex(
+ TraceProcessorException, expected_regex='.*source.*generator.*'):
+ _ = btp.query('select * from sl')
diff --git a/python/test/api_unittest.py b/python/test/api_unittest.py
new file mode 100755
index 000000000..23e4a233a
--- /dev/null
+++ b/python/test/api_unittest.py
@@ -0,0 +1,348 @@
+# Copyright (C) 2020 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import unittest
+
+from perfetto.trace_processor.api import TraceProcessor
+from perfetto.trace_processor.api import TraceProcessorException
+from perfetto.trace_processor.api import PLATFORM_DELEGATE
+from perfetto.trace_processor.protos import ProtoFactory
+
+PROTO_FACTORY = ProtoFactory(PLATFORM_DELEGATE())
+
+
+class TestQueryResultIterator(unittest.TestCase):
+ # The numbers input into cells correspond the CellType enum values
+ # defined under trace_processor.proto
+ CELL_VARINT = PROTO_FACTORY.CellsBatch().CELL_VARINT
+ CELL_STRING = PROTO_FACTORY.CellsBatch().CELL_STRING
+ CELL_INVALID = PROTO_FACTORY.CellsBatch().CELL_INVALID
+ CELL_NULL = PROTO_FACTORY.CellsBatch().CELL_NULL
+
+ def test_one_batch(self):
+ int_values = [100, 200]
+ str_values = ['bar1', 'bar2']
+
+ batch = PROTO_FACTORY.CellsBatch()
+ batch.cells.extend([
+ TestQueryResultIterator.CELL_STRING,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_NULL,
+ TestQueryResultIterator.CELL_STRING,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_NULL,
+ ])
+ batch.varint_cells.extend(int_values)
+ batch.string_cells = "\0".join(str_values) + "\0"
+ batch.is_last_batch = True
+
+ qr_iterator = TraceProcessor.QueryResultIterator(
+ ['foo_id', 'foo_num', 'foo_null'], [batch])
+
+ for num, row in enumerate(qr_iterator):
+ self.assertEqual(row.foo_id, str_values[num])
+ self.assertEqual(row.foo_num, int_values[num])
+ self.assertEqual(row.foo_null, None)
+
+ def test_many_batches(self):
+ int_values = [100, 200, 300, 400]
+ str_values = ['bar1', 'bar2', 'bar3', 'bar4']
+
+ batch_1 = PROTO_FACTORY.CellsBatch()
+ batch_1.cells.extend([
+ TestQueryResultIterator.CELL_STRING,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_NULL,
+ TestQueryResultIterator.CELL_STRING,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_NULL,
+ ])
+ batch_1.varint_cells.extend(int_values[:2])
+ batch_1.string_cells = "\0".join(str_values[:2]) + "\0"
+ batch_1.is_last_batch = False
+
+ batch_2 = PROTO_FACTORY.CellsBatch()
+ batch_2.cells.extend([
+ TestQueryResultIterator.CELL_STRING,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_NULL,
+ TestQueryResultIterator.CELL_STRING,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_NULL,
+ ])
+ batch_2.varint_cells.extend(int_values[2:])
+ batch_2.string_cells = "\0".join(str_values[2:]) + "\0"
+ batch_2.is_last_batch = True
+
+ qr_iterator = TraceProcessor.QueryResultIterator(
+ ['foo_id', 'foo_num', 'foo_null'], [batch_1, batch_2])
+
+ for num, row in enumerate(qr_iterator):
+ self.assertEqual(row.foo_id, str_values[num])
+ self.assertEqual(row.foo_num, int_values[num])
+ self.assertEqual(row.foo_null, None)
+
+ def test_empty_batch(self):
+ batch = PROTO_FACTORY.CellsBatch()
+ batch.is_last_batch = True
+
+ qr_iterator = TraceProcessor.QueryResultIterator([], [batch])
+
+ for num, row in enumerate(qr_iterator):
+ self.assertIsNone(row.foo_id)
+ self.assertIsNone(row.foo_num)
+
+ def test_invalid_batch(self):
+ batch = PROTO_FACTORY.CellsBatch()
+
+ # Since the batch isn't defined as the last batch, the QueryResultsIterator
+ # expects another batch and thus raises IndexError as no next batch exists.
+ with self.assertRaises(IndexError):
+ qr_iterator = TraceProcessor.QueryResultIterator([], [batch])
+
+ def test_null_cells(self):
+ int_values = [100, 200, 300, 500, 600]
+ str_values = ['bar1', 'bar2', 'bar3']
+
+ batch = PROTO_FACTORY.CellsBatch()
+ batch.cells.extend([
+ TestQueryResultIterator.CELL_STRING,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_STRING,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_NULL,
+ TestQueryResultIterator.CELL_STRING,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_VARINT,
+ ])
+ batch.varint_cells.extend(int_values)
+ batch.string_cells = "\0".join(str_values) + "\0"
+ batch.is_last_batch = True
+
+ qr_iterator = TraceProcessor.QueryResultIterator(
+ ['foo_id', 'foo_num', 'foo_num_2'], [batch])
+
+ # Any cell (and thus column in a row) can be set to null
+ # In this query result, foo_num_2 of row 2 was set to null
+ # Test to see that all the rows are still returned correctly
+ int_values_check = [100, 200, 300, None, 500, 600]
+ for num, row in enumerate(qr_iterator):
+ self.assertEqual(row.foo_id, str_values[num])
+ self.assertEqual(row.foo_num, int_values_check[num * 2])
+ self.assertEqual(row.foo_num_2, int_values_check[num * 2 + 1])
+
+ def test_incorrect_cells_batch(self):
+ str_values = ['bar1', 'bar2']
+
+ batch = PROTO_FACTORY.CellsBatch()
+ batch.cells.extend([
+ TestQueryResultIterator.CELL_STRING,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_STRING, TestQueryResultIterator.CELL_VARINT
+ ])
+ batch.string_cells = "\0".join(str_values) + "\0"
+ batch.is_last_batch = True
+
+ qr_iterator = TraceProcessor.QueryResultIterator(['foo_id', 'foo_num'],
+ [batch])
+
+ # The batch specifies there ought to be 2 cells of type VARINT and 2 cells
+ # of type STRING, but there are no string cells defined in the batch. Thus
+ # an IndexError occurs as it tries to access the empty string cells list.
+ with self.assertRaises(IndexError):
+ for row in qr_iterator:
+ pass
+
+ def test_incorrect_columns_batch(self):
+ batch = PROTO_FACTORY.CellsBatch()
+ batch.cells.extend([
+ TestQueryResultIterator.CELL_VARINT, TestQueryResultIterator.CELL_VARINT
+ ])
+ batch.varint_cells.extend([100, 200])
+ batch.is_last_batch = True
+
+ # It's always the case that the number of cells is a multiple of the number
+ # of columns. However, here this is clearly not the case, so raise a
+ # TraceProcessorException during the data integrity check in the constructor
+ with self.assertRaises(TraceProcessorException):
+ qr_iterator = TraceProcessor.QueryResultIterator(
+ ['foo_id', 'foo_num', 'foo_dur', 'foo_ms'], [batch])
+
+ def test_invalid_cell_type(self):
+ batch = PROTO_FACTORY.CellsBatch()
+ batch.cells.extend([
+ TestQueryResultIterator.CELL_INVALID,
+ TestQueryResultIterator.CELL_VARINT
+ ])
+ batch.varint_cells.extend([100, 200])
+ batch.is_last_batch = True
+
+ qr_iterator = TraceProcessor.QueryResultIterator(['foo_id', 'foo_num'],
+ [batch])
+
+ # In this batch we declare the columns types to be CELL_INVALID,
+ # CELL_VARINT but that doesn't match the data which are both ints*
+ # so we should raise a TraceProcessorException.
+ with self.assertRaises(TraceProcessorException):
+ for row in qr_iterator:
+ pass
+
+ def test_one_batch_as_pandas(self):
+ int_values = [100, 200]
+ str_values = ['bar1', 'bar2']
+
+ batch = PROTO_FACTORY.CellsBatch()
+ batch.cells.extend([
+ TestQueryResultIterator.CELL_STRING,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_NULL,
+ TestQueryResultIterator.CELL_STRING,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_NULL,
+ ])
+ batch.varint_cells.extend(int_values)
+ batch.string_cells = "\0".join(str_values) + "\0"
+ batch.is_last_batch = True
+
+ qr_iterator = TraceProcessor.QueryResultIterator(
+ ['foo_id', 'foo_num', 'foo_null'], [batch])
+
+ qr_df = qr_iterator.as_pandas_dataframe()
+ for num, row in qr_df.iterrows():
+ self.assertEqual(row['foo_id'], str_values[num])
+ self.assertEqual(row['foo_num'], int_values[num])
+ self.assertEqual(row['foo_null'], None)
+
+ def test_many_batches_as_pandas(self):
+ int_values = [100, 200, 300, 400]
+ str_values = ['bar1', 'bar2', 'bar3', 'bar4']
+
+ batch_1 = PROTO_FACTORY.CellsBatch()
+ batch_1.cells.extend([
+ TestQueryResultIterator.CELL_STRING,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_NULL,
+ TestQueryResultIterator.CELL_STRING,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_NULL,
+ ])
+ batch_1.varint_cells.extend(int_values[:2])
+ batch_1.string_cells = "\0".join(str_values[:2]) + "\0"
+ batch_1.is_last_batch = False
+
+ batch_2 = PROTO_FACTORY.CellsBatch()
+ batch_2.cells.extend([
+ TestQueryResultIterator.CELL_STRING,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_NULL,
+ TestQueryResultIterator.CELL_STRING,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_NULL,
+ ])
+ batch_2.varint_cells.extend(int_values[2:])
+ batch_2.string_cells = "\0".join(str_values[2:]) + "\0"
+ batch_2.is_last_batch = True
+
+ qr_iterator = TraceProcessor.QueryResultIterator(
+ ['foo_id', 'foo_num', 'foo_null'], [batch_1, batch_2])
+
+ qr_df = qr_iterator.as_pandas_dataframe()
+ for num, row in qr_df.iterrows():
+ self.assertEqual(row['foo_id'], str_values[num])
+ self.assertEqual(row['foo_num'], int_values[num])
+ self.assertEqual(row['foo_null'], None)
+
+ def test_empty_batch_as_pandas(self):
+ batch = PROTO_FACTORY.CellsBatch()
+ batch.is_last_batch = True
+
+ qr_iterator = TraceProcessor.QueryResultIterator([], [batch])
+
+ qr_df = qr_iterator.as_pandas_dataframe()
+ for num, row in qr_df.iterrows():
+ self.assertEqual(row['foo_id'], str_values[num])
+ self.assertEqual(row['foo_num'], int_values[num])
+
+ def test_null_cells_as_pandas(self):
+ int_values = [100, 200, 300, 500, 600]
+ str_values = ['bar1', 'bar2', 'bar3']
+
+ batch = PROTO_FACTORY.CellsBatch()
+ batch.cells.extend([
+ TestQueryResultIterator.CELL_STRING,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_STRING,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_NULL,
+ TestQueryResultIterator.CELL_STRING,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_VARINT,
+ ])
+ batch.varint_cells.extend(int_values)
+ batch.string_cells = "\0".join(str_values) + "\0"
+ batch.is_last_batch = True
+
+ qr_iterator = TraceProcessor.QueryResultIterator(
+ ['foo_id', 'foo_num', 'foo_num_2'], [batch])
+ qr_df = qr_iterator.as_pandas_dataframe()
+
+ # Any cell (and thus column in a row) can be set to null
+ # In this query result, foo_num_2 of row 2 was set to null
+ # Test to see that all the rows are still returned correctly
+ int_values_check = [100, 200, 300, None, 500, 600]
+ for num, row in qr_df.iterrows():
+ self.assertEqual(row['foo_id'], str_values[num])
+ self.assertEqual(row['foo_num'], int_values_check[num * 2])
+ self.assertEqual(row['foo_num_2'], int_values_check[num * 2 + 1])
+
+ def test_incorrect_cells_batch_as_pandas(self):
+ str_values = ['bar1', 'bar2']
+
+ batch = PROTO_FACTORY.CellsBatch()
+ batch.cells.extend([
+ TestQueryResultIterator.CELL_STRING,
+ TestQueryResultIterator.CELL_VARINT,
+ TestQueryResultIterator.CELL_STRING, TestQueryResultIterator.CELL_VARINT
+ ])
+ batch.string_cells = "\0".join(str_values) + "\0"
+ batch.is_last_batch = True
+
+ qr_iterator = TraceProcessor.QueryResultIterator(['foo_id', 'foo_num'],
+ [batch])
+
+ # The batch specifies there ought to be 2 cells of type VARINT and 2 cells
+ # of type STRING, but there are no string cells defined in the batch. Thus
+ # an IndexError occurs as it tries to access the empty string cells list.
+ with self.assertRaises(IndexError):
+ _ = qr_iterator.as_pandas_dataframe()
+
+ def test_invalid_cell_type_as_pandas(self):
+ batch = PROTO_FACTORY.CellsBatch()
+ batch.cells.extend([
+ TestQueryResultIterator.CELL_INVALID,
+ TestQueryResultIterator.CELL_VARINT
+ ])
+ batch.varint_cells.extend([100, 200])
+ batch.is_last_batch = True
+
+ qr_iterator = TraceProcessor.QueryResultIterator(['foo_id', 'foo_num'],
+ [batch])
+
+ # In this batch we declare the columns types to be CELL_INVALID,
+ # CELL_VARINT but that doesn't match the data which are both ints*
+ # so we should raise a TraceProcessorException.
+ with self.assertRaises(TraceProcessorException):
+ _ = qr_iterator.as_pandas_dataframe()
diff --git a/python/test/resolver_unittest.py b/python/test/resolver_unittest.py
new file mode 100644
index 000000000..4c3c32d63
--- /dev/null
+++ b/python/test/resolver_unittest.py
@@ -0,0 +1,155 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import unittest
+
+from perfetto.trace_uri_resolver.util import parse_trace_uri
+from perfetto.trace_uri_resolver.resolver import _args_dict_from_uri
+from perfetto.trace_uri_resolver.resolver import TraceUriResolver
+from perfetto.trace_uri_resolver.registry import ResolverRegistry
+
+
+class SimpleResolver(TraceUriResolver):
+ PREFIX = 'simple'
+
+ def __init__(self, foo=None, bar=None):
+ self.foo = foo
+ self.bar = bar
+
+ def foo_gen(self):
+ yield self.foo.encode() if self.foo else b''
+
+ def bar_gen(self):
+ yield self.bar.encode() if self.bar else b''
+
+ def resolve(self):
+ return [
+ TraceUriResolver.Result(self.foo_gen()),
+ TraceUriResolver.Result(
+ self.bar_gen(), metadata={
+ 'foo': self.foo,
+ 'bar': self.bar
+ })
+ ]
+
+
+class RecursiveResolver(SimpleResolver):
+ PREFIX = 'recursive'
+
+ def __init__(self, foo=None, bar=None):
+ super().__init__(foo=foo, bar=bar)
+
+ def resolve(self):
+ return [
+ TraceUriResolver.Result(self.foo_gen()),
+ TraceUriResolver.Result(
+ self.bar_gen(), metadata={
+ 'foo': 'foo',
+ 'bar': 'bar'
+ }),
+ TraceUriResolver.Result(f'simple:foo={self.foo};bar={self.bar}'),
+ TraceUriResolver.Result(SimpleResolver(foo=self.foo, bar=self.bar)),
+ ]
+
+
+class TestResolver(unittest.TestCase):
+
+ def test_simple_resolve(self):
+ registry = ResolverRegistry([SimpleResolver])
+
+ res = registry.resolve('simple:foo=x;bar=y')
+ self.assertEqual(len(res), 2)
+
+ (foo_res, bar_res) = res
+ self._check_resolver_result(foo_res, bar_res)
+
+ (foo_res, bar_res) = registry.resolve(['simple:foo=x;bar=y'])
+ self._check_resolver_result(foo_res, bar_res)
+
+ resolver = SimpleResolver(foo='x', bar='y')
+
+ (foo_res, bar_res) = registry.resolve(resolver)
+ self._check_resolver_result(foo_res, bar_res)
+
+ (foo_res, bar_res) = registry.resolve([resolver])
+ self._check_resolver_result(foo_res, bar_res)
+
+ (foo_a, bar_b, foo_x,
+ bar_y) = registry.resolve(['simple:foo=a;bar=b', resolver])
+ self._check_resolver_result(foo_a, bar_b, foo='a', bar='b')
+ self._check_resolver_result(foo_x, bar_y)
+
+ def test_simple_resolve_missing_arg(self):
+ registry = ResolverRegistry([SimpleResolver])
+
+ (foo_res, bar_res) = registry.resolve('simple:foo=x')
+ self._check_resolver_result(foo_res, bar_res, bar=None)
+
+ (foo_res, bar_res) = registry.resolve('simple:bar=y')
+ self._check_resolver_result(foo_res, bar_res, foo=None)
+
+ (foo_res, bar_res) = registry.resolve('simple:')
+ self._check_resolver_result(foo_res, bar_res, foo=None, bar=None)
+
+ def test_recursive_resolve(self):
+ registry = ResolverRegistry([SimpleResolver])
+ registry.register(RecursiveResolver)
+
+ res = registry.resolve('recursive:foo=x;bar=y')
+ self.assertEqual(len(res), 6)
+
+ (non_rec_foo, non_rec_bar, rec_foo_str, rec_bar_str, rec_foo_obj,
+ rec_bar_obj) = res
+
+ self._check_resolver_result(
+ non_rec_foo, non_rec_bar, foo_metadata='foo', bar_metadata='bar')
+ self._check_resolver_result(rec_foo_str, rec_bar_str)
+ self._check_resolver_result(rec_foo_obj, rec_bar_obj)
+
+ def test_parse_trace_uri(self):
+ self.assertEqual(parse_trace_uri('/foo/bar'), (None, '/foo/bar'))
+ self.assertEqual(parse_trace_uri('foo/bar'), (None, 'foo/bar'))
+ self.assertEqual(parse_trace_uri('/foo/b:ar'), (None, '/foo/b:ar'))
+ self.assertEqual(parse_trace_uri('./foo/b:ar'), (None, './foo/b:ar'))
+ self.assertEqual(parse_trace_uri('foo/b:ar'), ('foo/b', 'ar'))
+
+ def test_args_dict_from_uri(self):
+ self.assertEqual(_args_dict_from_uri('foo:'), {})
+ self.assertEqual(_args_dict_from_uri('foo:bar=baz'), {
+ 'bar': 'baz',
+ })
+ self.assertEqual(
+ _args_dict_from_uri('foo:key=v1,v2'), {'key': ['v1', 'v2']})
+ self.assertEqual(
+ _args_dict_from_uri('foo:bar=baz;key=v1,v2'), {
+ 'bar': 'baz',
+ 'key': ['v1', 'v2']
+ })
+
+ def _check_resolver_result(self,
+ foo_res,
+ bar_res,
+ foo='x',
+ bar='y',
+ foo_metadata=None,
+ bar_metadata=None):
+ self.assertEqual(
+ tuple(foo_res.generator), (foo.encode() if foo else ''.encode(),))
+ self.assertEqual(
+ tuple(bar_res.generator), (bar.encode() if bar else ''.encode(),))
+ self.assertEqual(
+ bar_res.metadata, {
+ 'foo': foo_metadata if foo_metadata else foo,
+ 'bar': bar_metadata if bar_metadata else bar
+ }) \ No newline at end of file
diff --git a/python/tools/batch_trace_processor_shell.py b/python/tools/batch_trace_processor_shell.py
new file mode 100644
index 000000000..651247d0b
--- /dev/null
+++ b/python/tools/batch_trace_processor_shell.py
@@ -0,0 +1,140 @@
+#!/usr/bin/env python3
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+""" Given a trace file, gives the self-time of userspace slices broken
+down by process, thread and thread state.
+"""
+
+import argparse
+import cmd
+import logging
+import numpy as np
+import pandas as pd
+import plotille
+
+from perfetto.batch_trace_processor.api import BatchTraceProcessor, BatchTraceProcessorConfig
+from perfetto.trace_processor import TraceProcessorException, TraceProcessorConfig
+from typing import List
+
+
+class TpBatchShell(cmd.Cmd):
+
+ def __init__(self, files: List[str], batch_tp: BatchTraceProcessor):
+ super().__init__()
+ self.files = files
+ self.batch_tp = batch_tp
+
+ def do_table(self, arg: str):
+ try:
+ data = self.batch_tp.query_and_flatten(arg)
+ print(data)
+ except TraceProcessorException as ex:
+ logging.error("Query failed: {}".format(ex))
+
+ def do_histogram(self, arg: str):
+ try:
+ data = self.batch_tp.query_single_result(arg)
+ print(plotille.histogram(data))
+ self.print_percentiles(data)
+ except TraceProcessorException as ex:
+ logging.error("Query failed: {}".format(ex))
+
+ def do_vhistogram(self, arg: str):
+ try:
+ data = self.batch_tp.query_single_result(arg)
+ print(plotille.hist(data))
+ self.print_percentiles(data)
+ except TraceProcessorException as ex:
+ logging.error("Query failed: {}".format(ex))
+
+ def do_count(self, arg: str):
+ try:
+ data = self.batch_tp.query_single_result(arg)
+ counts = dict()
+ for i in data:
+ counts[i] = counts.get(i, 0) + 1
+ print(counts)
+ except TraceProcessorException as ex:
+ logging.error("Query failed: {}".format(ex))
+
+ def do_close(self, _):
+ return True
+
+ def do_quit(self, _):
+ return True
+
+ def do_EOF(self, _):
+ print("")
+ return True
+
+ def print_percentiles(self, data):
+ percentiles = [25, 50, 75, 95, 99, 99.9]
+ nearest = np.percentile(data, percentiles, interpolation='nearest')
+ logging.info("Representative traces for percentiles")
+ for i, near in enumerate(nearest):
+ print("{}%: {}".format(percentiles[i], self.files[data.index(near)]))
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--shell-path', default=None)
+ parser.add_argument('--verbose', action='store_true', default=False)
+ parser.add_argument('--file-list', default=None)
+ parser.add_argument('--query-file', default=None)
+ parser.add_argument('--interactive', default=None)
+ parser.add_argument('files', nargs='*')
+ args = parser.parse_args()
+
+ logging.basicConfig(level=logging.DEBUG)
+
+ files = args.files
+ if args.file_list:
+ with open(args.file_list, 'r') as f:
+ files += f.read().splitlines()
+
+ if not files:
+ logging.info("At least one file must be specified in files or file list")
+
+ logging.info('Loading traces...')
+ config = BatchTraceProcessorConfig(
+ tp_config=TraceProcessorConfig(
+ bin_path=args.shell_path,
+ verbose=args.verbose,
+ ))
+
+ with BatchTraceProcessor(files, config) as batch_tp:
+ if args.query_file:
+ logging.info('Running query file...')
+
+ with open(args.query_file, 'r') as f:
+ queries_str = f.read()
+
+ queries = [q.strip() for q in queries_str.split(";\n")]
+ for q in queries[:-1]:
+ batch_tp.query(q)
+
+ res = batch_tp.query_and_flatten(queries[-1])
+ print(res.to_csv(index=False))
+
+ if args.interactive or not args.query_file:
+ try:
+ TpBatchShell(files, batch_tp).cmdloop()
+ except KeyboardInterrupt:
+ pass
+
+ logging.info("Closing; please wait...")
+
+
+if __name__ == '__main__':
+ exit(main())
diff --git a/python/tools/slice_breakdown.py b/python/tools/slice_breakdown.py
new file mode 100644
index 000000000..9c481ba65
--- /dev/null
+++ b/python/tools/slice_breakdown.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python3
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+""" Given a trace file, gives the self-time of userspace slices broken
+down by process, thread and thread state.
+"""
+
+import argparse
+import sys
+
+from perfetto.experimental.slice_breakdown import compute_breakdown
+from perfetto.experimental.slice_breakdown import compute_breakdown_for_startup
+from perfetto.trace_processor import TraceProcessor
+from perfetto.trace_processor import TraceProcessorConfig
+
+
+def compute_breakdown_wrapper(args):
+ config = TraceProcessorConfig(bin_path=args.shell_path, verbose=args.verbose)
+ with TraceProcessor(trace=args.file, config=config) as tp:
+ if args.startup_bounds:
+ breakdown = compute_breakdown_for_startup(tp, args.startup_package,
+ args.process_name)
+ else:
+ breakdown = compute_breakdown(tp, args.start_ts, args.end_ts,
+ args.process_name)
+ return breakdown
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--file', required=True)
+ parser.add_argument('--shell-path', default=None)
+ parser.add_argument('--start-ts', default=None)
+ parser.add_argument('--end-ts', default=None)
+ parser.add_argument('--startup-bounds', action='store_true', default=False)
+ parser.add_argument('--startup-package', default=None)
+ parser.add_argument('--process-name', default=None)
+ parser.add_argument('--verbose', action='store_true', default=False)
+ parser.add_argument('--out-csv', required=True)
+ args = parser.parse_args()
+
+ if (args.start_ts or args.end_ts) and args.startup_bounds:
+ print("Cannot specify --start-ts or --end-ts and --startup-bounds")
+ return 1
+
+ if args.startup_package and not args.startup_bounds:
+ print("Must specify --startup-bounds if --startup-package is specified")
+ return 1
+
+ breakdown = compute_breakdown_wrapper(args)
+
+ if args.out_csv:
+ diff_csv = breakdown.to_csv(index=False)
+ if args.out_csv == '-':
+ sys.stdout.write(diff_csv)
+ else:
+ with open(args.out_csv, 'w') as out:
+ out.write(diff_csv)
+
+ return 0
+
+
+if __name__ == '__main__':
+ exit(main())
diff --git a/src/android_internal/BUILD.gn b/src/android_internal/BUILD.gn
index 02d07fbf5..ed0112164 100644
--- a/src/android_internal/BUILD.gn
+++ b/src/android_internal/BUILD.gn
@@ -37,6 +37,7 @@ if (perfetto_build_with_android) {
]
libs = [
"android.hardware.health@2.0",
+ "android.hardware.health-V1-ndk",
"android.hardware.power.stats@1.0",
"android.hardware.power.stats-V1-cpp",
"android.hardware.atrace@1.0",
@@ -45,6 +46,7 @@ if (perfetto_build_with_android) {
"cutils",
"base",
"binder",
+ "binder_ndk",
"log",
"hidlbase",
"incident",
diff --git a/src/android_internal/atrace_hal.cc b/src/android_internal/atrace_hal.cc
index 486a44aa9..4a19d8360 100644
--- a/src/android_internal/atrace_hal.cc
+++ b/src/android_internal/atrace_hal.cc
@@ -19,6 +19,8 @@
#include <android/hardware/atrace/1.0/IAtraceDevice.h>
#include <iostream>
+#include <string.h>
+
namespace perfetto {
namespace android_internal {
@@ -53,11 +55,9 @@ bool ListCategories(TracingVendorCategory* categories, size_t* size_of_arr) {
for (int i = 0; i < *size_of_arr; ++i) {
const TracingCategory& cat = r[i];
TracingVendorCategory& result = categories[i];
- strncpy(result.name, cat.name.c_str(), sizeof(result.name));
- strncpy(result.description, cat.description.c_str(),
+ strlcpy(result.name, cat.name.c_str(), sizeof(result.name));
+ strlcpy(result.description, cat.description.c_str(),
sizeof(result.description));
- result.name[sizeof(result.name) - 1] = '\0';
- result.description[sizeof(result.description) - 1] = '\0';
}
};
diff --git a/src/android_internal/health_hal.cc b/src/android_internal/health_hal.cc
index 0d8ad05fb..f21af800e 100644
--- a/src/android_internal/health_hal.cc
+++ b/src/android_internal/health_hal.cc
@@ -16,67 +16,78 @@
#include "src/android_internal/health_hal.h"
+#include <aidl/android/hardware/health/IHealth.h>
+#include <android/binder_manager.h>
#include <android/hardware/health/2.0/IHealth.h>
#include <healthhalutils/HealthHalUtils.h>
namespace perfetto {
namespace android_internal {
-using ::android::hardware::health::V2_0::IHealth;
+using HidlHealth = ::android::hardware::health::V2_0::IHealth;
+using ::aidl::android::hardware::health::IHealth;
+using ::android::hardware::Return;
using ::android::hardware::health::V2_0::Result;
namespace {
-android::sp<IHealth> g_svc;
+struct HealthService {
+ android::sp<HidlHealth> hidl;
+ std::shared_ptr<IHealth> aidl;
+};
+
+HealthService g_svc;
void ResetService() {
- g_svc = ::android::hardware::health::V2_0::get_health_service();
+ auto aidl_name = std::string(IHealth::descriptor) + "/default";
+ if (AServiceManager_isDeclared(aidl_name.c_str())) {
+ ndk::SpAIBinder binder(AServiceManager_waitForService(aidl_name.c_str()));
+ g_svc.aidl = IHealth::fromBinder(binder);
+ if (g_svc.aidl != nullptr) {
+ return;
+ }
+ }
+ g_svc.hidl = ::android::hardware::health::V2_0::get_health_service();
}
-} // namespace
-
-bool GetBatteryCounter(BatteryCounter counter, int64_t* value) {
- *value = 0;
- if (!g_svc)
- ResetService();
-
- if (!g_svc)
- return false;
-
- // The Android VNDK documentation states that for blocking services, the
+bool GetBatteryCounterHidl(BatteryCounter counter, int64_t* value) {
+ // The Android HIDL documentation states that for blocking services, the
// caller blocks until the reply is received and the callback is called inline
// in the same thread.
// See https://source.android.com/devices/architecture/hidl/threading .
- Result res;
+ Return<void> ret;
+ Result res = Result::UNKNOWN;
switch (counter) {
case BatteryCounter::kUnspecified:
- res = Result::NOT_FOUND;
break;
case BatteryCounter::kCharge:
- g_svc->getChargeCounter([&res, value](Result hal_res, int32_t hal_value) {
- res = hal_res;
- *value = hal_value;
- });
+ ret = g_svc.hidl->getChargeCounter(
+ [&res, value](Result hal_res, int32_t hal_value) {
+ res = hal_res;
+ *value = hal_value;
+ });
break;
case BatteryCounter::kCapacityPercent:
- g_svc->getCapacity([&res, value](Result hal_res, int64_t hal_value) {
- res = hal_res;
- *value = hal_value;
- });
+ ret = g_svc.hidl->getCapacity(
+ [&res, value](Result hal_res, int32_t hal_value) {
+ res = hal_res;
+ *value = hal_value;
+ });
break;
case BatteryCounter::kCurrent:
- g_svc->getCurrentNow([&res, value](Result hal_res, int32_t hal_value) {
- res = hal_res;
- *value = hal_value;
- });
+ ret = g_svc.hidl->getCurrentNow(
+ [&res, value](Result hal_res, int32_t hal_value) {
+ res = hal_res;
+ *value = hal_value;
+ });
break;
case BatteryCounter::kCurrentAvg:
- g_svc->getCurrentAverage(
+ ret = g_svc.hidl->getCurrentAverage(
[&res, value](Result hal_res, int32_t hal_value) {
res = hal_res;
*value = hal_value;
@@ -84,10 +95,62 @@ bool GetBatteryCounter(BatteryCounter counter, int64_t* value) {
break;
} // switch(counter)
- if (res == Result::CALLBACK_DIED)
- g_svc.clear();
+ if (ret.isDeadObject())
+ g_svc.hidl.clear();
+
+ return ret.isOk() && res == Result::SUCCESS;
+}
+
+bool GetBatteryCounterAidl(BatteryCounter counter, int64_t* value) {
+ ndk::ScopedAStatus status;
+ int32_t value32;
+
+ switch (counter) {
+ case BatteryCounter::kUnspecified:
+ return false;
+
+ case BatteryCounter::kCharge:
+ status = g_svc.aidl->getChargeCounterUah(&value32);
+ break;
+
+ case BatteryCounter::kCapacityPercent:
+ status = g_svc.aidl->getCapacity(&value32);
+ break;
+
+ case BatteryCounter::kCurrent:
+ status = g_svc.aidl->getCurrentNowMicroamps(&value32);
+ break;
+
+ case BatteryCounter::kCurrentAvg:
+ status = g_svc.aidl->getCurrentAverageMicroamps(&value32);
+ break;
+ } // switch(counter)
+
+ if (status.isOk()) {
+ *value = value32;
+ return true;
+ }
+
+ if (status.getStatus() == STATUS_DEAD_OBJECT)
+ g_svc.aidl.reset();
+
+ return false;
+}
+
+} // namespace
+
+bool GetBatteryCounter(BatteryCounter counter, int64_t* value) {
+ *value = 0;
+ if (!g_svc.aidl && !g_svc.hidl)
+ ResetService();
+
+ if (!g_svc.aidl && !g_svc.hidl)
+ return false;
+
+ if (g_svc.aidl)
+ return GetBatteryCounterAidl(counter, value);
- return res == Result::SUCCESS;
+ return GetBatteryCounterHidl(counter, value);
}
} // namespace android_internal
diff --git a/src/android_internal/power_stats.cc b/src/android_internal/power_stats.cc
index 34da342d1..f7badf66f 100644
--- a/src/android_internal/power_stats.cc
+++ b/src/android_internal/power_stats.cc
@@ -164,12 +164,10 @@ bool PowerStatsHalDataProvider::GetAvailableRails(
descriptor.index = rail_info.index;
descriptor.sampling_rate = rail_info.samplingRate;
- strncpy(descriptor.rail_name, rail_info.railName.c_str(),
+ strlcpy(descriptor.rail_name, rail_info.railName.c_str(),
sizeof(descriptor.rail_name));
- strncpy(descriptor.subsys_name, rail_info.subsysName.c_str(),
+ strlcpy(descriptor.subsys_name, rail_info.subsysName.c_str(),
sizeof(descriptor.subsys_name));
- descriptor.rail_name[sizeof(descriptor.rail_name) - 1] = '\0';
- descriptor.subsys_name[sizeof(descriptor.subsys_name) - 1] = '\0';
}
}
};
@@ -263,10 +261,8 @@ bool PowerStatsAidlDataProvider::GetAvailableRails(RailDescriptor* descriptor,
auto& cur = descriptor[(*size_of_arr)++];
cur.index = result.id;
cur.sampling_rate = 0;
- strncpy(cur.rail_name, result.name.c_str(), sizeof(cur.rail_name));
- strncpy(cur.subsys_name, result.subsystem.c_str(), sizeof(cur.subsys_name));
- cur.rail_name[sizeof(cur.rail_name) - 1] = '\0';
- cur.subsys_name[sizeof(cur.subsys_name) - 1] = '\0';
+ strlcpy(cur.rail_name, result.name.c_str(), sizeof(cur.rail_name));
+ strlcpy(cur.subsys_name, result.subsystem.c_str(), sizeof(cur.subsys_name));
}
return true;
}
@@ -333,10 +329,8 @@ bool PowerStatsAidlDataProvider::GetEnergyConsumerInfo(
auto& cur = consumers[(*size_of_arr)++];
cur.energy_consumer_id = result.id;
cur.ordinal = result.ordinal;
- strncpy(cur.type, aidl::toString(result.type).c_str(), sizeof(cur.type));
- cur.type[sizeof(cur.type) - 1] = '\0';
- strncpy(cur.name, result.name.c_str(), sizeof(cur.name));
- cur.name[sizeof(cur.name) - 1] = '\0';
+ strlcpy(cur.type, aidl::toString(result.type).c_str(), sizeof(cur.type));
+ strlcpy(cur.name, result.name.c_str(), sizeof(cur.name));
}
return true;
}
diff --git a/src/android_internal/tracing_service_proxy.cc b/src/android_internal/tracing_service_proxy.cc
index e297b75f8..a88668983 100644
--- a/src/android_internal/tracing_service_proxy.cc
+++ b/src/android_internal/tracing_service_proxy.cc
@@ -17,21 +17,29 @@
#include "src/android_internal/tracing_service_proxy.h"
#include <android/tracing/ITracingServiceProxy.h>
+#include <android/tracing/TraceReportParams.h>
#include <binder/IBinder.h>
#include <binder/IServiceManager.h>
+#include <binder/ParcelFileDescriptor.h>
#include <binder/Status.h>
+#include <utils/String16.h>
namespace perfetto {
namespace android_internal {
using android::sp;
using android::binder::Status;
+using android::os::ParcelFileDescriptor;
using android::tracing::ITracingServiceProxy;
+using android::tracing::TraceReportParams;
-bool NotifyTraceSessionEnded(bool session_stolen) {
- sp<ITracingServiceProxy> service = android::interface_cast<ITracingServiceProxy>(
- android::defaultServiceManager()->getService(android::String16("tracing.proxy")));
+namespace {
+static constexpr char kServiceName[] = "tracing.proxy";
+}
+bool NotifyTraceSessionEnded(bool session_stolen) {
+ auto service = android::waitForService<ITracingServiceProxy>(
+ android::String16(kServiceName));
if (service == nullptr) {
return false;
}
@@ -40,5 +48,38 @@ bool NotifyTraceSessionEnded(bool session_stolen) {
return s.isOk();
}
-} // namespace android_internal
-} // namespace perfetto
+bool ReportTrace(const char* reporter_package_name,
+ const char* reporter_class_name,
+ int owned_trace_fd,
+ int64_t uuid_lsb,
+ int64_t uuid_msb,
+ bool use_pipe_in_framework_for_testing) {
+ // Keep this first so we recapture the raw fd in a RAII type as soon as
+ // possible.
+ android::base::unique_fd fd(owned_trace_fd);
+
+ auto service = android::waitForService<ITracingServiceProxy>(
+ android::String16(kServiceName));
+ if (service == nullptr) {
+ return false;
+ }
+
+ TraceReportParams params{};
+ params.reporterPackageName = android::String16(reporter_package_name);
+ params.reporterClassName = android::String16(reporter_class_name);
+ params.fd = ParcelFileDescriptor(std::move(fd));
+ params.uuidLsb = uuid_lsb;
+ params.uuidMsb = uuid_msb;
+ params.usePipeForTesting = use_pipe_in_framework_for_testing;
+
+ Status s = service->reportTrace(std::move(params));
+ if (!s.isOk()) {
+ __android_log_print(ANDROID_LOG_ERROR, "perfetto", "reportTrace failed: %s",
+ s.toString8().c_str());
+ }
+
+ return s.isOk();
+}
+
+} // namespace android_internal
+} // namespace perfetto
diff --git a/src/android_internal/tracing_service_proxy.h b/src/android_internal/tracing_service_proxy.h
index 0b045e238..5c459348a 100644
--- a/src/android_internal/tracing_service_proxy.h
+++ b/src/android_internal/tracing_service_proxy.h
@@ -17,6 +17,8 @@
#ifndef SRC_ANDROID_INTERNAL_TRACING_SERVICE_PROXY_H_
#define SRC_ANDROID_INTERNAL_TRACING_SERVICE_PROXY_H_
+#include <stdint.h>
+
namespace perfetto {
namespace android_internal {
@@ -25,6 +27,14 @@ extern "C" {
bool __attribute__((visibility("default")))
NotifyTraceSessionEnded(bool session_stolen);
+bool __attribute__((visibility("default")))
+ReportTrace(const char* reporter_package_name,
+ const char* reporter_class_name,
+ int owned_trace_fd,
+ int64_t uuid_lsb,
+ int64_t uuid_msb,
+ bool use_pipe_in_framework_for_testing);
+
} // extern "C"
} // namespace android_internal
diff --git a/src/android_stats/perfetto_atoms.h b/src/android_stats/perfetto_atoms.h
index 3731c2e76..75cbbd837 100644
--- a/src/android_stats/perfetto_atoms.h
+++ b/src/android_stats/perfetto_atoms.h
@@ -69,31 +69,37 @@ enum class PerfettoStatsdAtom {
kTracedEnableTracingUnknown = 35,
kTracedStartTracingInvalidSessionState = 36,
kTracedEnableTracingInvalidFilter = 47,
+ kTracedEnableTracingOobTargetBuffer = 48,
// Checkpoints inside perfetto_cmd after tracing has finished.
kOnTracingDisabled = 4,
- kUploadIncidentBegin = 8,
kFinalizeTraceAndExit = 11,
+ kCmdFwReportBegin = 49,
+ // Will be removed once incidentd is no longer used.
+ kUploadIncidentBegin = 8,
kNotUploadingEmptyTrace = 17,
// Guardrails inside perfetto_cmd after tracing has finished.
+ kCmdFwReportEmptyTrace = 50,
+ // Will be removed once incidentd is no longer used.
kUploadIncidentFailure = 10,
+ // "Successful" terminal states inside perfetto_cmd.
+ kCmdFwReportHandoff = 51,
+
// Deprecated as "success" is misleading; it simply means we were
// able to communicate with incidentd. Will be removed once
- // incidentd is properly instrumented.
+ // incidentd is no longer used.
kUploadIncidentSuccess = 9,
- // Deprecated as has the potential to be too spammy. Will be
- // replaced with a whole new atom proto which uses a count metric
- // instead of the event metric used for this proto.
- kTriggerBegin = 12,
- kTriggerSuccess = 13,
- kTriggerFailure = 14,
+ // Contained trigger begin/success/failure. Replaced by
+ // |PerfettoTriggerAtom| to allow aggregation using a count metric
+ // and reduce spam.
+ // reserved 12, 13, 14;
- // Deprecated as too coarse grained to be useful. Will be replaced
- // with better broken down atoms as we do with traced.
- kHitGuardrails = 15,
+ // Contained that a guardrail in perfetto_cmd was hit. Replaced with
+ // kCmd* guardrails.
+ // reserved 15;
// Contained status of Dropbox uploads. Removed as Perfetto no
// longer supports uploading traces using Dropbox.
diff --git a/src/base/BUILD.gn b/src/base/BUILD.gn
index f761a5348..47748464b 100644
--- a/src/base/BUILD.gn
+++ b/src/base/BUILD.gn
@@ -31,10 +31,14 @@ perfetto_component("base") {
"../../include/perfetto/ext/base",
]
sources = [
+ "android_utils.cc",
+ "base64.cc",
+ "crash_keys.cc",
"ctrl_c_handler.cc",
"event_fd.cc",
"file_utils.cc",
"getopt_compat.cc",
+ "log_ring_buffer.h",
"logging.cc",
"metatrace.cc",
"paged_memory.cc",
@@ -128,6 +132,8 @@ source_set("test_support") {
"../../gn:default_deps",
]
sources = [
+ "test/tmp_dir_tree.cc",
+ "test/tmp_dir_tree.h",
"test/utils.cc",
"test/utils.h",
"test/vm_test_utils.cc",
@@ -153,8 +159,14 @@ perfetto_unittest_source_set("unittests") {
"../../gn:gtest_and_gmock",
]
+ if (enable_perfetto_ipc) {
+ deps += [ "http:unittests" ]
+ }
+
sources = [
+ "base64_unittest.cc",
"circular_queue_unittest.cc",
+ "flat_hash_map_unittest.cc",
"flat_set_unittest.cc",
"getopt_compat_unittest.cc",
"logging_unittest.cc",
@@ -163,6 +175,7 @@ perfetto_unittest_source_set("unittests") {
"paged_memory_unittest.cc",
"periodic_task_unittest.cc",
"scoped_file_unittest.cc",
+ "small_vector_unittest.cc",
"string_splitter_unittest.cc",
"string_utils_unittest.cc",
"string_view_unittest.cc",
@@ -189,6 +202,9 @@ perfetto_unittest_source_set("unittests") {
"watchdog_posix_unittest.cc",
]
}
+ if (is_fuchsia) {
+ deps += [ "//third_party/fuchsia-sdk/sdk/pkg/fdio" ]
+ }
if (perfetto_build_standalone || perfetto_build_with_android) {
# This causes some problems on the chromium waterfall.
if (is_linux || is_android) {
@@ -200,13 +216,33 @@ perfetto_unittest_source_set("unittests") {
}
if (enable_perfetto_benchmarks) {
+ declare_args() {
+ perfetto_benchmark_3p_libs_prefix = ""
+ }
source_set("benchmarks") {
+ # If you intend to reproduce the comparison with {Absl, Folly, Tessil}
+ # you need to manually install those libraries and then set the GN arg
+ # perfetto_benchmark_3p_libs_prefix = "/usr/local"
testonly = true
deps = [
":base",
"../../gn:benchmark",
"../../gn:default_deps",
]
- sources = [ "flat_set_benchmark.cc" ]
+ if (perfetto_benchmark_3p_libs_prefix != "") {
+ configs -= [ "//gn/standalone:c++11" ]
+ configs += [ "//gn/standalone:c++17" ]
+ defines = [ "PERFETTO_HASH_MAP_COMPARE_THIRD_PARTY_LIBS" ]
+ cflags = [ "-isystem${perfetto_benchmark_3p_libs_prefix}/include" ]
+ libs = [
+ "${perfetto_benchmark_3p_libs_prefix}/lib/libfolly.a",
+ "${perfetto_benchmark_3p_libs_prefix}/lib/libabsl_raw_hash_set.a",
+ "${perfetto_benchmark_3p_libs_prefix}/lib/libabsl_hash.a",
+ ]
+ }
+ sources = [
+ "flat_hash_map_benchmark.cc",
+ "flat_set_benchmark.cc",
+ ]
}
}
diff --git a/src/base/android_utils.cc b/src/base/android_utils.cc
new file mode 100644
index 000000000..623a96a34
--- /dev/null
+++ b/src/base/android_utils.cc
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/ext/base/android_utils.h"
+
+#include "perfetto/base/build_config.h"
+
+#include <string>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <sys/system_properties.h>
+#endif
+
+#include "perfetto/base/compiler.h"
+#include "perfetto/base/logging.h"
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+std::string GetAndroidProp(const char* name) {
+ std::string ret;
+#if __ANDROID_API__ >= 26
+ const prop_info* pi = __system_property_find(name);
+ if (!pi) {
+ return ret;
+ }
+ __system_property_read_callback(
+ pi,
+ [](void* dst_void, const char*, const char* value, uint32_t) {
+ std::string& dst = *static_cast<std::string*>(dst_void);
+ dst = value;
+ },
+ &ret);
+#else // __ANDROID_API__ < 26
+ char value_buf[PROP_VALUE_MAX];
+ int len = __system_property_get(name, value_buf);
+ if (len > 0 && static_cast<size_t>(len) < sizeof(value_buf)) {
+ ret = std::string(value_buf, static_cast<size_t>(len));
+ }
+#endif
+ return ret;
+}
+
+#endif // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+} // namespace base
+} // namespace perfetto
diff --git a/src/base/base64.cc b/src/base/base64.cc
new file mode 100644
index 000000000..bb2e3c485
--- /dev/null
+++ b/src/base/base64.cc
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/ext/base/base64.h"
+
+namespace perfetto {
+namespace base {
+
+namespace {
+
+constexpr char kPadding = '=';
+
+constexpr char kEncTable[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static_assert(sizeof(kEncTable) == (1u << 6) + sizeof('\0'), "Bad table size");
+
+// Maps an ASCII character to its 6-bit value. It only contains translations
+// from '+' to 'z'. Supports the standard (+/) and URL-safe (-_) alphabets.
+constexpr uint8_t kX = 0xff; // Value used for invalid characters
+constexpr uint8_t kDecTable[] = {
+ 62, kX, 62, kX, 63, 52, 53, 54, 55, 56, // 00 - 09
+ 57, 58, 59, 60, 61, kX, kX, kX, 0, kX, // 10 - 19
+ kX, kX, 0, 1, 2, 3, 4, 5, 6, 7, // 20 - 29
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, // 30 - 39
+ 18, 19, 20, 21, 22, 23, 24, 25, kX, kX, // 40 - 49
+ kX, kX, 63, kX, 26, 27, 28, 29, 30, 31, // 50 - 59
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, // 60 - 69
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 70 - 79
+};
+constexpr char kMinDecChar = '+';
+constexpr char kMaxDecChar = 'z';
+static_assert(kMaxDecChar - kMinDecChar <= sizeof(kDecTable), "Bad table size");
+
+inline uint8_t DecodeChar(char c) {
+ if (c < kMinDecChar || c > kMaxDecChar)
+ return kX;
+ return kDecTable[c - kMinDecChar];
+}
+
+} // namespace
+
+ssize_t Base64Encode(const void* src,
+ size_t src_size,
+ char* dst,
+ size_t dst_size) {
+ const size_t padded_dst_size = Base64EncSize(src_size);
+ if (dst_size < padded_dst_size)
+ return -1; // Not enough space in output.
+
+ const uint8_t* rd = static_cast<const uint8_t*>(src);
+ const uint8_t* const end = rd + src_size;
+ size_t wr_size = 0;
+ while (rd < end) {
+ uint8_t s[3]{};
+ s[0] = *(rd++);
+ dst[wr_size++] = kEncTable[s[0] >> 2];
+
+ uint8_t carry0 = static_cast<uint8_t>((s[0] & 0x03) << 4);
+ if (PERFETTO_LIKELY(rd < end)) {
+ s[1] = *(rd++);
+ dst[wr_size++] = kEncTable[carry0 | (s[1] >> 4)];
+ } else {
+ dst[wr_size++] = kEncTable[carry0];
+ dst[wr_size++] = kPadding;
+ dst[wr_size++] = kPadding;
+ break;
+ }
+
+ uint8_t carry1 = static_cast<uint8_t>((s[1] & 0x0f) << 2);
+ if (PERFETTO_LIKELY(rd < end)) {
+ s[2] = *(rd++);
+ dst[wr_size++] = kEncTable[carry1 | (s[2] >> 6)];
+ } else {
+ dst[wr_size++] = kEncTable[carry1];
+ dst[wr_size++] = kPadding;
+ break;
+ }
+
+ dst[wr_size++] = kEncTable[s[2] & 0x3f];
+ }
+ PERFETTO_DCHECK(wr_size == padded_dst_size);
+ return static_cast<ssize_t>(padded_dst_size);
+}
+
+std::string Base64Encode(const void* src, size_t src_size) {
+ std::string dst;
+ dst.resize(Base64EncSize(src_size));
+ auto res = Base64Encode(src, src_size, &dst[0], dst.size());
+ PERFETTO_CHECK(res == static_cast<ssize_t>(dst.size()));
+ return dst;
+}
+
+ssize_t Base64Decode(const char* src,
+ size_t src_size,
+ uint8_t* dst,
+ size_t dst_size) {
+ const size_t min_dst_size = Base64DecSize(src_size);
+ if (dst_size < min_dst_size)
+ return -1;
+
+ const char* rd = src;
+ const char* const end = src + src_size;
+ size_t wr_size = 0;
+
+ char s[4]{};
+ while (rd < end) {
+ uint8_t d[4];
+ for (uint32_t j = 0; j < 4; j++) {
+ // Padding is only feasible for the last 2 chars of each group of 4.
+ s[j] = rd < end ? *(rd++) : (j < 2 ? '\0' : kPadding);
+ d[j] = DecodeChar(s[j]);
+ if (d[j] == kX)
+ return -1; // Invalid input char.
+ }
+ dst[wr_size] = static_cast<uint8_t>((d[0] << 2) | (d[1] >> 4));
+ dst[wr_size + 1] = static_cast<uint8_t>((d[1] << 4) | (d[2] >> 2));
+ dst[wr_size + 2] = static_cast<uint8_t>((d[2] << 6) | (d[3]));
+ wr_size += 3;
+ }
+
+ PERFETTO_CHECK(wr_size <= dst_size);
+ wr_size -= (s[3] == kPadding ? 1 : 0) + (s[2] == kPadding ? 1 : 0);
+ return static_cast<ssize_t>(wr_size);
+}
+
+Optional<std::string> Base64Decode(const char* src, size_t src_size) {
+ std::string dst;
+ dst.resize(Base64DecSize(src_size));
+ auto res = Base64Decode(src, src_size, reinterpret_cast<uint8_t*>(&dst[0]),
+ dst.size());
+ if (res < 0)
+ return nullopt; // Decoding error.
+
+ PERFETTO_CHECK(res <= static_cast<ssize_t>(dst.size()));
+ dst.resize(static_cast<size_t>(res));
+ return base::make_optional(dst);
+}
+
+} // namespace base
+} // namespace perfetto
diff --git a/src/base/base64_unittest.cc b/src/base/base64_unittest.cc
new file mode 100644
index 000000000..fb131d904
--- /dev/null
+++ b/src/base/base64_unittest.cc
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/ext/base/base64.h"
+
+#include "perfetto/ext/base/string_view.h"
+#include "perfetto/ext/base/utils.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace base {
+namespace {
+
+struct TestPattern {
+ size_t decoded_len;
+ const char* decoded;
+ const char* encoded;
+};
+
+TestPattern kPatterns[] = {
+
+ // Basic bit patterns;
+ // values obtained with "echo -n '...' | uuencode -m test"
+
+ {1, "\000", "AA=="},
+ {1, "\001", "AQ=="},
+ {1, "\002", "Ag=="},
+ {1, "\004", "BA=="},
+ {1, "\010", "CA=="},
+ {1, "\020", "EA=="},
+ {1, "\040", "IA=="},
+ {1, "\100", "QA=="},
+ {1, "\200", "gA=="},
+
+ {1, "\377", "/w=="},
+ {1, "\376", "/g=="},
+ {1, "\375", "/Q=="},
+ {1, "\373", "+w=="},
+ {1, "\367", "9w=="},
+ {1, "\357", "7w=="},
+ {1, "\337", "3w=="},
+ {1, "\277", "vw=="},
+ {1, "\177", "fw=="},
+ {2, "\000\000", "AAA="},
+ {2, "\000\001", "AAE="},
+ {2, "\000\002", "AAI="},
+ {2, "\000\004", "AAQ="},
+ {2, "\000\010", "AAg="},
+ {2, "\000\020", "ABA="},
+ {2, "\000\040", "ACA="},
+ {2, "\000\100", "AEA="},
+ {2, "\000\200", "AIA="},
+ {2, "\001\000", "AQA="},
+ {2, "\002\000", "AgA="},
+ {2, "\004\000", "BAA="},
+ {2, "\010\000", "CAA="},
+ {2, "\020\000", "EAA="},
+ {2, "\040\000", "IAA="},
+ {2, "\100\000", "QAA="},
+ {2, "\200\000", "gAA="},
+
+ {2, "\377\377", "//8="},
+ {2, "\377\376", "//4="},
+ {2, "\377\375", "//0="},
+ {2, "\377\373", "//s="},
+ {2, "\377\367", "//c="},
+ {2, "\377\357", "/+8="},
+ {2, "\377\337", "/98="},
+ {2, "\377\277", "/78="},
+ {2, "\377\177", "/38="},
+ {2, "\376\377", "/v8="},
+ {2, "\375\377", "/f8="},
+ {2, "\373\377", "+/8="},
+ {2, "\367\377", "9/8="},
+ {2, "\357\377", "7/8="},
+ {2, "\337\377", "3/8="},
+ {2, "\277\377", "v/8="},
+ {2, "\177\377", "f/8="},
+
+ {3, "\000\000\000", "AAAA"},
+ {3, "\000\000\001", "AAAB"},
+ {3, "\000\000\002", "AAAC"},
+ {3, "\000\000\004", "AAAE"},
+ {3, "\000\000\010", "AAAI"},
+ {3, "\000\000\020", "AAAQ"},
+ {3, "\000\000\040", "AAAg"},
+ {3, "\000\000\100", "AABA"},
+ {3, "\000\000\200", "AACA"},
+ {3, "\000\001\000", "AAEA"},
+ {3, "\000\002\000", "AAIA"},
+ {3, "\000\004\000", "AAQA"},
+ {3, "\000\010\000", "AAgA"},
+ {3, "\000\020\000", "ABAA"},
+ {3, "\000\040\000", "ACAA"},
+ {3, "\000\100\000", "AEAA"},
+ {3, "\000\200\000", "AIAA"},
+ {3, "\001\000\000", "AQAA"},
+ {3, "\002\000\000", "AgAA"},
+ {3, "\004\000\000", "BAAA"},
+ {3, "\010\000\000", "CAAA"},
+ {3, "\020\000\000", "EAAA"},
+ {3, "\040\000\000", "IAAA"},
+ {3, "\100\000\000", "QAAA"},
+ {3, "\200\000\000", "gAAA"},
+
+ {3, "\377\377\377", "////"},
+ {3, "\377\377\376", "///+"},
+ {3, "\377\377\375", "///9"},
+ {3, "\377\377\373", "///7"},
+ {3, "\377\377\367", "///3"},
+ {3, "\377\377\357", "///v"},
+ {3, "\377\377\337", "///f"},
+ {3, "\377\377\277", "//+/"},
+ {3, "\377\377\177", "//9/"},
+ {3, "\377\376\377", "//7/"},
+ {3, "\377\375\377", "//3/"},
+ {3, "\377\373\377", "//v/"},
+ {3, "\377\367\377", "//f/"},
+ {3, "\377\357\377", "/+//"},
+ {3, "\377\337\377", "/9//"},
+ {3, "\377\277\377", "/7//"},
+ {3, "\377\177\377", "/3//"},
+ {3, "\376\377\377", "/v//"},
+ {3, "\375\377\377", "/f//"},
+ {3, "\373\377\377", "+///"},
+ {3, "\367\377\377", "9///"},
+ {3, "\357\377\377", "7///"},
+ {3, "\337\377\377", "3///"},
+ {3, "\277\377\377", "v///"},
+ {3, "\177\377\377", "f///"},
+
+ // Random numbers: values obtained with
+ //
+ // #! /bin/bash
+ // dd bs=$1 count=1 if=/dev/random of=/tmp/bar.random
+ // od -N $1 -t o1 /tmp/bar.random
+ // uuencode -m test < /tmp/bar.random
+ //
+ // where $1 is the number of bytes (2, 3)
+
+ {2, "\243\361", "o/E="},
+ {2, "\024\167", "FHc="},
+ {2, "\313\252", "y6o="},
+ {2, "\046\041", "JiE="},
+ {2, "\145\236", "ZZ4="},
+ {2, "\254\325", "rNU="},
+ {2, "\061\330", "Mdg="},
+ {2, "\245\032", "pRo="},
+ {2, "\006\000", "BgA="},
+ {2, "\375\131", "/Vk="},
+ {2, "\303\210", "w4g="},
+ {2, "\040\037", "IB8="},
+ {2, "\261\372", "sfo="},
+ {2, "\335\014", "3Qw="},
+ {2, "\233\217", "m48="},
+ {2, "\373\056", "+y4="},
+ {2, "\247\232", "p5o="},
+ {2, "\107\053", "Rys="},
+ {2, "\204\077", "hD8="},
+ {2, "\276\211", "vok="},
+ {2, "\313\110", "y0g="},
+ {2, "\363\376", "8/4="},
+ {2, "\251\234", "qZw="},
+ {2, "\103\262", "Q7I="},
+ {2, "\142\312", "Yso="},
+ {2, "\067\211", "N4k="},
+ {2, "\220\001", "kAE="},
+ {2, "\152\240", "aqA="},
+ {2, "\367\061", "9zE="},
+ {2, "\133\255", "W60="},
+ {2, "\176\035", "fh0="},
+ {2, "\032\231", "Gpk="},
+
+ {3, "\013\007\144", "Cwdk"},
+ {3, "\030\112\106", "GEpG"},
+ {3, "\047\325\046", "J9Um"},
+ {3, "\310\160\022", "yHAS"},
+ {3, "\131\100\237", "WUCf"},
+ {3, "\064\342\134", "NOJc"},
+ {3, "\010\177\004", "CH8E"},
+ {3, "\345\147\205", "5WeF"},
+ {3, "\300\343\360", "wOPw"},
+ {3, "\061\240\201", "MaCB"},
+ {3, "\225\333\044", "ldsk"},
+ {3, "\215\137\352", "jV/q"},
+ {3, "\371\147\160", "+Wdw"},
+ {3, "\030\320\051", "GNAp"},
+ {3, "\044\174\241", "JHyh"},
+ {3, "\260\127\037", "sFcf"},
+ {3, "\111\045\033", "SSUb"},
+ {3, "\202\114\107", "gkxH"},
+ {3, "\057\371\042", "L/ki"},
+ {3, "\223\247\244", "k6ek"},
+ {3, "\047\216\144", "J45k"},
+ {3, "\203\070\327", "gzjX"},
+ {3, "\247\140\072", "p2A6"},
+ {3, "\124\115\116", "VE1O"},
+ {3, "\157\162\050", "b3Io"},
+ {3, "\357\223\004", "75ME"},
+ {3, "\052\117\156", "Kk9u"},
+ {3, "\347\154\000", "52wA"},
+ {3, "\303\012\142", "wwpi"},
+ {3, "\060\035\362", "MB3y"},
+ {3, "\130\226\361", "WJbx"},
+ {3, "\173\013\071", "ews5"},
+ {3, "\336\004\027", "3gQX"},
+ {3, "\357\366\234", "7/ac"},
+ {3, "\353\304\111", "68RJ"},
+ {3, "\024\264\131", "FLRZ"},
+ {3, "\075\114\251", "PUyp"},
+ {3, "\315\031\225", "zRmV"},
+ {3, "\154\201\276", "bIG+"},
+ {3, "\200\066\072", "gDY6"},
+ {3, "\142\350\267", "Yui3"},
+ {3, "\033\000\166", "GwB2"},
+ {3, "\210\055\077", "iC0/"},
+ {3, "\341\037\124", "4R9U"},
+ {3, "\161\103\152", "cUNq"},
+ {3, "\270\142\131", "uGJZ"},
+ {3, "\337\076\074", "3z48"},
+ {3, "\375\106\362", "/Uby"},
+ {3, "\227\301\127", "l8FX"},
+ {3, "\340\002\234", "4AKc"},
+ {3, "\121\064\033", "UTQb"},
+ {3, "\157\134\143", "b1xj"},
+ {3, "\247\055\327", "py3X"},
+ {3, "\340\142\005", "4GIF"},
+ {3, "\060\260\143", "MLBj"},
+ {3, "\075\203\170", "PYN4"},
+ {3, "\143\160\016", "Y3AO"},
+ {3, "\313\013\063", "ywsz"},
+ {3, "\174\236\135", "fJ5d"},
+ {3, "\103\047\026", "QycW"},
+ {3, "\365\005\343", "9QXj"},
+ {3, "\271\160\223", "uXCT"},
+ {3, "\362\255\172", "8q16"},
+ {3, "\113\012\015", "SwoN"},
+
+ // various lengths, generated by this python script:
+ //
+ // from string import lowercase as lc
+ // for i in range(27):
+ // print '{ %2d, "%s",%s "%s" },' % (i, lc[:i], ' ' * (26-i),
+ // lc[:i].encode('base64').strip())
+
+ {0, "abcdefghijklmnopqrstuvwxyz", ""},
+ {1, "abcdefghijklmnopqrstuvwxyz", "YQ=="},
+ {2, "abcdefghijklmnopqrstuvwxyz", "YWI="},
+ {3, "abcdefghijklmnopqrstuvwxyz", "YWJj"},
+ {4, "abcdefghijklmnopqrstuvwxyz", "YWJjZA=="},
+ {5, "abcdefghijklmnopqrstuvwxyz", "YWJjZGU="},
+ {6, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVm"},
+ {7, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZw=="},
+ {8, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2g="},
+ {9, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hp"},
+ {10, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpag=="},
+ {11, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpams="},
+ {12, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamts"},
+ {13, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbQ=="},
+ {14, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW4="},
+ {15, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5v"},
+ {16, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcA=="},
+ {17, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHE="},
+ {18, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFy"},
+ {19, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFycw=="},
+ {20, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3Q="},
+ {21, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1"},
+ {22, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dg=="},
+ {23, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnc="},
+ {24, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4"},
+ {25, "abcdefghijklmnopqrstuvwxy", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eQ=="},
+ {26, "abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo="},
+};
+
+TEST(Base64Test, Encode) {
+ EXPECT_EQ(Base64Encode(""), "");
+ EXPECT_EQ(Base64Encode("f"), "Zg==");
+ EXPECT_EQ(Base64Encode("fo"), "Zm8=");
+ EXPECT_EQ(Base64Encode("foo"), "Zm9v");
+ EXPECT_EQ(Base64Encode("foob"), "Zm9vYg==");
+ EXPECT_EQ(Base64Encode("fooba"), "Zm9vYmE=");
+ EXPECT_EQ(Base64Encode("foobar"), "Zm9vYmFy");
+ EXPECT_EQ(Base64Encode("\xff"), "/w==");
+ EXPECT_EQ(Base64Encode("\xff\xfe"), "//4=");
+ EXPECT_EQ(Base64Encode("\xff\xfe\xfd"), "//79");
+ EXPECT_EQ(Base64Encode("\xff\xfe\xfd\xfc"), "//79/A==");
+
+ for (size_t i = 0; i < ArraySize(kPatterns); ++i) {
+ const auto& p = kPatterns[i];
+ std::string res = Base64Encode(StringView(p.decoded, p.decoded_len));
+ EXPECT_EQ(p.encoded, res);
+ }
+
+ // Error cases
+ char buf[4];
+ EXPECT_EQ(0, Base64Encode("", 0, buf, 0));
+ EXPECT_EQ(0, Base64Encode("", 0, buf, 1));
+ EXPECT_EQ(-1, Base64Encode("a", 1, buf, 0));
+ EXPECT_EQ(-1, Base64Encode("abc", 3, buf, 0));
+ EXPECT_EQ(-1, Base64Encode("abc", 3, buf, 1));
+ EXPECT_EQ(-1, Base64Encode("abc", 3, buf, 3));
+ EXPECT_EQ(4, Base64Encode("abc", 3, buf, 4));
+}
+
+TEST(Base64Test, Decode) {
+ EXPECT_EQ(Base64Decode(""), "");
+ EXPECT_EQ(Base64Decode("Zg=="), "f");
+ EXPECT_EQ(Base64Decode("Zg="), "f");
+ EXPECT_EQ(Base64Decode("Zg"), "f");
+ EXPECT_EQ(Base64Decode("Zm8="), "fo");
+ EXPECT_EQ(Base64Decode("Zm8"), "fo");
+ EXPECT_EQ(Base64Decode("Zm9v"), "foo");
+ EXPECT_EQ(Base64Decode("Zm9vYg=="), "foob");
+ EXPECT_EQ(Base64Decode("Zm9vYg="), "foob");
+ EXPECT_EQ(Base64Decode("Zm9vYg"), "foob");
+ EXPECT_EQ(Base64Decode("Zm9vYmE="), "fooba");
+ EXPECT_EQ(Base64Decode("Zm9vYmE"), "fooba");
+ EXPECT_EQ(Base64Decode("Zm9vYmFy"), "foobar");
+ EXPECT_EQ(Base64Decode("/w=="), "\xff");
+ EXPECT_EQ(Base64Decode("/w="), "\xff");
+ EXPECT_EQ(Base64Decode("/w"), "\xff");
+ EXPECT_EQ(Base64Decode("//4="), "\xff\xfe");
+ EXPECT_EQ(Base64Decode("//4"), "\xff\xfe");
+ EXPECT_EQ(Base64Decode("//79"), "\xff\xfe\xfd");
+ EXPECT_EQ(Base64Decode("//79/A=="), "\xff\xfe\xfd\xfc");
+ EXPECT_EQ(Base64Decode("//79/A="), "\xff\xfe\xfd\xfc");
+ EXPECT_EQ(Base64Decode("//79/A"), "\xff\xfe\xfd\xfc");
+
+ for (size_t i = 0; i < ArraySize(kPatterns); ++i) {
+ const auto& p = kPatterns[i];
+ Optional<std::string> dec = Base64Decode(StringView(p.encoded));
+ EXPECT_TRUE(dec.has_value());
+ EXPECT_EQ(dec.value(), StringView(p.decoded, p.decoded_len).ToStdString());
+ }
+
+ // Error cases:
+ EXPECT_EQ(Base64Decode("Z"), nullopt);
+ EXPECT_EQ(Base64Decode("Zm9vY"), nullopt);
+
+ uint8_t buf[4];
+ EXPECT_EQ(Base64Decode("", 0, buf, 2), 0); // Valid, 0 len.
+ EXPECT_EQ(Base64Decode("Z", 1, buf, 1), -1); // Invalid input.
+ EXPECT_EQ(Base64Decode("Zg==", 4, buf, 1), -1); // Not enough dst space.
+}
+
+} // namespace
+} // namespace base
+} // namespace perfetto
diff --git a/src/base/crash_keys.cc b/src/base/crash_keys.cc
new file mode 100644
index 000000000..13e1c51ac
--- /dev/null
+++ b/src/base/crash_keys.cc
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/ext/base/crash_keys.h"
+
+#include <string.h>
+
+#include <atomic>
+#include <cinttypes>
+
+#include "perfetto/ext/base/string_utils.h"
+
+namespace perfetto {
+namespace base {
+
+namespace {
+
+constexpr size_t kMaxKeys = 32;
+
+std::atomic<CrashKey*> g_keys[kMaxKeys]{};
+std::atomic<uint32_t> g_num_keys{};
+} // namespace
+
+void CrashKey::Register() {
+ // If doesn't matter if we fail below. If there are no slots left, don't
+ // keep trying re-registering on every Set(), the outcome won't change.
+
+ // If two threads raced on the Register(), avoid registering the key twice.
+ if (registered_.exchange(true))
+ return;
+
+ uint32_t slot = g_num_keys.fetch_add(1);
+ if (slot >= kMaxKeys) {
+ PERFETTO_LOG("Too many crash keys registered");
+ return;
+ }
+ g_keys[slot].store(this);
+}
+
+// Returns the number of chars written, without counting the \0.
+size_t CrashKey::ToString(char* dst, size_t len) {
+ if (len > 0)
+ *dst = '\0';
+ switch (type_.load(std::memory_order_relaxed)) {
+ case Type::kUnset:
+ break;
+ case Type::kInt:
+ return SprintfTrunc(dst, len, "%s: %" PRId64 "\n", name_,
+ int_value_.load(std::memory_order_relaxed));
+ case Type::kStr:
+ char buf[sizeof(str_value_)];
+ for (size_t i = 0; i < sizeof(str_value_); i++)
+ buf[i] = str_value_[i].load(std::memory_order_relaxed);
+
+ // Don't assume |str_value_| is properly null-terminated.
+ return SprintfTrunc(dst, len, "%s: %.*s\n", name_, int(sizeof(buf)), buf);
+ }
+ return 0;
+}
+
+void UnregisterAllCrashKeysForTesting() {
+ g_num_keys.store(0);
+ for (auto& key : g_keys)
+ key.store(nullptr);
+}
+
+size_t SerializeCrashKeys(char* dst, size_t len) {
+ size_t written = 0;
+ uint32_t num_keys = g_num_keys.load();
+ if (len > 0)
+ *dst = '\0';
+ for (uint32_t i = 0; i < num_keys && written < len; i++) {
+ CrashKey* key = g_keys[i].load();
+ if (!key)
+ continue; // Can happen if we hit this between the add and the store.
+ written += key->ToString(dst + written, len - written);
+ }
+ PERFETTO_DCHECK(written <= len);
+ PERFETTO_DCHECK(len == 0 || dst[written] == '\0');
+ return written;
+}
+
+} // namespace base
+} // namespace perfetto
diff --git a/src/base/debug_crash_stack_trace.cc b/src/base/debug_crash_stack_trace.cc
index 4da0fba7f..4a16f2915 100644
--- a/src/base/debug_crash_stack_trace.cc
+++ b/src/base/debug_crash_stack_trace.cc
@@ -107,6 +107,7 @@ _Unwind_Reason_Code TraceStackFrame(_Unwind_Context* context, void* arg) {
}
void RestoreSignalHandlers() {
+ g_sighandler_registered = false;
for (size_t i = 0; i < sizeof(g_signals) / sizeof(g_signals[0]); i++)
sigaction(g_signals[i].sig_num, &g_signals[i].old_handler, nullptr);
}
@@ -167,7 +168,7 @@ void SignalHandler(int sig_num, siginfo_t* info, void* /*ucontext*/) {
const char* function) -> int {
SymbolInfo* psym = reinterpret_cast<SymbolInfo*>(data);
if (function)
- strncpy(psym->sym_name, function, sizeof(psym->sym_name));
+ snprintf(psym->sym_name, sizeof(psym->sym_name), "%s", function);
if (filename) {
snprintf(psym->file_name, sizeof(psym->file_name), "%s:%d", filename,
lineno);
@@ -179,7 +180,7 @@ void SignalHandler(int sig_num, siginfo_t* info, void* /*ucontext*/) {
Dl_info dl_info = {};
int res = dladdr(reinterpret_cast<void*>(frames[i]), &dl_info);
if (res && dl_info.dli_sname)
- strncpy(sym.sym_name, dl_info.dli_sname, sizeof(sym.sym_name));
+ snprintf(sym.sym_name, sizeof(sym.sym_name), "%s", dl_info.dli_sname);
#endif
Print("\n#");
@@ -192,7 +193,7 @@ void SignalHandler(int sig_num, siginfo_t* info, void* /*ucontext*/) {
char* demangled =
abi::__cxa_demangle(sym.sym_name, g_demangled_name, &len, &ignored);
if (demangled) {
- strncpy(sym.sym_name, demangled, sizeof(sym.sym_name));
+ snprintf(sym.sym_name, sizeof(sym.sym_name), "%s", demangled);
// In the exceptional case of demangling something > kDemangledNameLen,
// __cxa_demangle will realloc(). In that case the malloc()-ed pointer
// might be moved.
@@ -233,10 +234,12 @@ void SignalHandler(int sig_num, siginfo_t* info, void* /*ucontext*/) {
}
}
-// __attribute__((constructor)) causes a static initializer that automagically
-// early runs this function before the main().
-void __attribute__((constructor)) EnableStacktraceOnCrashForDebug();
+} // namespace
+
+namespace perfetto {
+namespace base {
+// The prototype for this function is in logging.h.
void EnableStacktraceOnCrashForDebug() {
if (g_sighandler_registered)
return;
@@ -259,7 +262,7 @@ void EnableStacktraceOnCrashForDebug() {
// (ii) the output of death test is not visible.
pthread_atfork(nullptr, nullptr, &RestoreSignalHandlers);
}
-
-} // namespace
+} // namespace base
+} // namespace perfetto
#pragma GCC diagnostic pop
diff --git a/src/base/event_fd.cc b/src/base/event_fd.cc
index 085681823..135a59b93 100644
--- a/src/base/event_fd.cc
+++ b/src/base/event_fd.cc
@@ -74,7 +74,8 @@ void EventFd::Notify() {
void EventFd::Clear() {
uint64_t value;
- ssize_t ret = read(event_handle_.get(), &value, sizeof(value));
+ ssize_t ret =
+ PERFETTO_EINTR(read(event_handle_.get(), &value, sizeof(value)));
if (ret <= 0 && errno != EAGAIN)
PERFETTO_DFATAL("EventFd::Clear()");
}
@@ -100,7 +101,8 @@ void EventFd::Clear() {
// Drain the byte(s) written to the wake-up pipe. We can potentially read
// more than one byte if several wake-ups have been scheduled.
char buffer[16];
- ssize_t ret = read(event_handle_.get(), &buffer[0], sizeof(buffer));
+ ssize_t ret =
+ PERFETTO_EINTR(read(event_handle_.get(), &buffer[0], sizeof(buffer)));
if (ret <= 0 && errno != EAGAIN)
PERFETTO_DFATAL("EventFd::Clear()");
}
diff --git a/src/base/file_utils.cc b/src/base/file_utils.cc
index 9b92af284..09782fee7 100644
--- a/src/base/file_utils.cc
+++ b/src/base/file_utils.cc
@@ -20,10 +20,14 @@
#include <sys/types.h>
#include <algorithm>
+#include <deque>
+#include <string>
+#include <vector>
#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
#include "perfetto/base/platform_handle.h"
+#include "perfetto/base/status.h"
#include "perfetto/ext/base/scoped_file.h"
#include "perfetto/ext/base/utils.h"
@@ -40,7 +44,15 @@ namespace perfetto {
namespace base {
namespace {
constexpr size_t kBufSize = 2048;
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// Wrap FindClose to: (1) make the return unix-style; (2) deal with stdcall.
+int CloseFindHandle(HANDLE h) {
+ return FindClose(h) ? 0 : -1;
}
+#endif
+
+} // namespace
ssize_t Read(int fd, void* dst, size_t dst_size) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
@@ -208,5 +220,112 @@ int ClosePlatformHandle(PlatformHandle handle) {
#endif
}
+base::Status ListFilesRecursive(const std::string& dir_path,
+ std::vector<std::string>& output) {
+ std::string root_dir_path = dir_path;
+ if (root_dir_path.back() == '\\') {
+ root_dir_path.back() = '/';
+ } else if (root_dir_path.back() != '/') {
+ root_dir_path.push_back('/');
+ }
+
+ // dir_queue contains full paths to the directories. The paths include the
+ // root_dir_path at the beginning and the trailing slash at the end.
+ std::deque<std::string> dir_queue;
+ dir_queue.push_back(root_dir_path);
+
+ while (!dir_queue.empty()) {
+ const std::string cur_dir = std::move(dir_queue.front());
+ dir_queue.pop_front();
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+ return base::ErrStatus("ListFilesRecursive not supported yet");
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ std::string glob_path = cur_dir + "*";
+ // + 1 because we also have to count the NULL terminator.
+ if (glob_path.length() + 1 > MAX_PATH)
+ return base::ErrStatus("Directory path %s is too long", dir_path.c_str());
+ WIN32_FIND_DATAA ffd;
+
+ base::ScopedResource<HANDLE, CloseFindHandle, nullptr, false,
+ base::PlatformHandleChecker>
+ hFind(FindFirstFileA(glob_path.c_str(), &ffd));
+ if (!hFind) {
+ // For empty directories, there should be at least one entry '.'.
+ // If FindFirstFileA returns INVALID_HANDLE_VALUE, this means directory
+ // couldn't be accessed.
+ return base::ErrStatus("Failed to open directory %s", cur_dir.c_str());
+ }
+ do {
+ if (strcmp(ffd.cFileName, ".") == 0 || strcmp(ffd.cFileName, "..") == 0)
+ continue;
+ if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ std::string subdir_path = cur_dir + ffd.cFileName + '/';
+ dir_queue.push_back(subdir_path);
+ } else {
+ const std::string full_path = cur_dir + ffd.cFileName;
+ PERFETTO_CHECK(full_path.length() > root_dir_path.length());
+ output.push_back(full_path.substr(root_dir_path.length()));
+ }
+ } while (FindNextFileA(*hFind, &ffd));
+#else
+ ScopedDir dir = ScopedDir(opendir(cur_dir.c_str()));
+ if (!dir) {
+ return base::ErrStatus("Failed to open directory %s", cur_dir.c_str());
+ }
+ for (auto* dirent = readdir(dir.get()); dirent != nullptr;
+ dirent = readdir(dir.get())) {
+ if (strcmp(dirent->d_name, ".") == 0 ||
+ strcmp(dirent->d_name, "..") == 0) {
+ continue;
+ }
+ if (dirent->d_type == DT_DIR) {
+ dir_queue.push_back(cur_dir + dirent->d_name + '/');
+ } else if (dirent->d_type == DT_REG) {
+ const std::string full_path = cur_dir + dirent->d_name;
+ PERFETTO_CHECK(full_path.length() > root_dir_path.length());
+ output.push_back(full_path.substr(root_dir_path.length()));
+ }
+ }
+#endif
+ }
+ return base::OkStatus();
+}
+
+std::string GetFileExtension(const std::string& filename) {
+ auto ext_idx = filename.rfind('.');
+ if (ext_idx == std::string::npos)
+ return std::string();
+ return filename.substr(ext_idx);
+}
+
+base::Optional<size_t> GetFileSize(const std::string& file_path) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ HANDLE file =
+ CreateFileA(file_path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
+ if (file == INVALID_HANDLE_VALUE) {
+ return nullopt;
+ }
+ LARGE_INTEGER file_size;
+ file_size.QuadPart = 0;
+ BOOL ok = GetFileSizeEx(file, &file_size);
+ CloseHandle(file);
+ if (!ok) {
+ return nullopt;
+ }
+ return static_cast<size_t>(file_size.QuadPart);
+#else
+ base::ScopedFile fd(base::OpenFile(file_path, O_RDONLY | O_CLOEXEC));
+ if (!fd) {
+ return nullopt;
+ }
+ struct stat buf{};
+ if (fstat(*fd, &buf) == -1) {
+ return nullopt;
+ }
+ return static_cast<size_t>(buf.st_size);
+#endif
+}
+
} // namespace base
} // namespace perfetto
diff --git a/src/base/flat_hash_map_benchmark.cc b/src/base/flat_hash_map_benchmark.cc
new file mode 100644
index 000000000..33da6690e
--- /dev/null
+++ b/src/base/flat_hash_map_benchmark.cc
@@ -0,0 +1,378 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <functional>
+#include <random>
+#include <unordered_map>
+
+#include <benchmark/benchmark.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/flat_hash_map.h"
+#include "perfetto/ext/base/hash.h"
+#include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/string_view.h"
+
+// This benchmark allows to compare our FlatHashMap implementation against
+// reference implementations from Absl (Google), Folly F14 (FB), and Tssil's
+// reference RobinHood hashmap.
+// Those libraries are not checked in into the repo. If you want to reproduce
+// the benchmark you need to:
+// - Manually install the three libraries using following the instructions in
+// their readme (they all use cmake).
+// - When running cmake, remember to pass
+// -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS='-DNDEBUG -O3 -msse4.2 -mavx'.
+// That sets cflags for a more fair comparison.
+// - Set is_debug=false in the GN args.
+// - Set the GN var perfetto_benchmark_3p_libs_prefix="/usr/local" (or whatever
+// other directory you set as DESTDIR when running make install).
+// The presence of the perfetto_benchmark_3p_libs_prefix GN variable will
+// automatically define PERFETTO_HASH_MAP_COMPARE_THIRD_PARTY_LIBS.
+
+#if defined(PERFETTO_HASH_MAP_COMPARE_THIRD_PARTY_LIBS)
+
+// Last tested: https://github.com/abseil/abseil-cpp @ f2dbd918d.
+#include <absl/container/flat_hash_map.h>
+
+// Last tested: https://github.com/facebook/folly @ 028a9abae3.
+#include <folly/container/F14Map.h>
+
+// Last tested: https://github.com/Tessil/robin-map @ a603419b9.
+#include <tsl/robin_map.h>
+#endif
+
+namespace {
+
+using namespace perfetto;
+using benchmark::Counter;
+using perfetto::base::AlreadyHashed;
+using perfetto::base::LinearProbe;
+using perfetto::base::QuadraticHalfProbe;
+using perfetto::base::QuadraticProbe;
+
+// Our FlatHashMap doesn't have a STL-like interface, mainly because we use
+// columnar-oriented storage, not array-of-tuples, so we can't easily map into
+// that interface. This wrapper makes our FlatHashMap compatible with STL (just
+// for what it takes to build this translation unit), at the cost of some small
+// performance penalty (around 1-2%).
+template <typename Key, typename Value, typename Hasher, typename Probe>
+class Ours : public base::FlatHashMap<Key, Value, Hasher, Probe> {
+ public:
+ struct Iterator {
+ using value_type = std::pair<const Key&, Value&>;
+ Iterator(const Key& k, Value& v) : pair_{k, v} {}
+ value_type* operator->() { return &pair_; }
+ value_type& operator*() { return pair_; }
+ bool operator==(const Iterator& other) const {
+ return &pair_.first == &other.pair_.first;
+ }
+ bool operator!=(const Iterator& other) const { return !operator==(other); }
+ value_type pair_;
+ };
+
+ void insert(std::pair<Key, Value>&& pair) {
+ this->Insert(std::move(pair.first), std::move(pair.second));
+ }
+
+ Iterator find(const Key& key) {
+ const size_t idx = this->FindInternal(key);
+ return Iterator(this->keys_[idx], this->values_[idx]);
+ }
+
+ Iterator end() {
+ return Iterator(this->keys_[this->kNotFound],
+ this->values_[this->kNotFound]);
+ }
+};
+
+std::vector<uint64_t> LoadTraceStrings(benchmark::State& state) {
+ std::vector<uint64_t> str_hashes;
+ // This requires that the user has downloaded the file
+ // go/perfetto-benchmark-trace-strings into /tmp/trace_strings. The file is
+ // too big (2.3 GB after uncompression) and it's not worth adding it to the
+ // //test/data. Also it contains data from a team member's phone and cannot
+ // be public.
+ base::ScopedFstream f(fopen("/tmp/trace_strings", "re"));
+ if (!f) {
+ state.SkipWithError(
+ "Test strings missing. Googlers: download "
+ "go/perfetto-benchmark-trace-strings and save into /tmp/trace_strings");
+ return str_hashes;
+ }
+ char line[4096];
+ while (fgets(line, sizeof(line), *f)) {
+ base::Hash hasher;
+ hasher.Update(line, strlen(line));
+ str_hashes.emplace_back(hasher.digest());
+ }
+ return str_hashes;
+}
+
+bool IsBenchmarkFunctionalOnly() {
+ return getenv("BENCHMARK_FUNCTIONAL_TEST_ONLY") != nullptr;
+}
+
+size_t num_samples() {
+ return IsBenchmarkFunctionalOnly() ? size_t(100) : size_t(10 * 1000 * 1000);
+}
+
+// Uses directly the base::FlatHashMap with no STL wrapper. Configures the map
+// in append-only mode.
+void BM_HashMap_InsertTraceStrings_AppendOnly(benchmark::State& state) {
+ std::vector<uint64_t> hashes = LoadTraceStrings(state);
+ for (auto _ : state) {
+ base::FlatHashMap<uint64_t, uint64_t, AlreadyHashed<uint64_t>, LinearProbe,
+ /*AppendOnly=*/true>
+ mapz;
+ for (uint64_t hash : hashes)
+ mapz.Insert(hash, 42);
+
+ benchmark::ClobberMemory();
+ state.counters["uniq"] = Counter(static_cast<double>(mapz.size()));
+ }
+ state.counters["tot"] = Counter(static_cast<double>(hashes.size()),
+ Counter::kIsIterationInvariant);
+ state.counters["rate"] = Counter(static_cast<double>(hashes.size()),
+ Counter::kIsIterationInvariantRate);
+}
+
+template <typename MapType>
+void BM_HashMap_InsertTraceStrings(benchmark::State& state) {
+ std::vector<uint64_t> hashes = LoadTraceStrings(state);
+ for (auto _ : state) {
+ MapType mapz;
+ for (uint64_t hash : hashes)
+ mapz.insert({hash, 42});
+
+ benchmark::ClobberMemory();
+ state.counters["uniq"] = Counter(static_cast<double>(mapz.size()));
+ }
+ state.counters["tot"] = Counter(static_cast<double>(hashes.size()),
+ Counter::kIsIterationInvariant);
+ state.counters["rate"] = Counter(static_cast<double>(hashes.size()),
+ Counter::kIsIterationInvariantRate);
+}
+
+template <typename MapType>
+void BM_HashMap_TraceTids(benchmark::State& state) {
+ std::vector<std::pair<char, int>> ops_and_tids;
+ {
+ base::ScopedFstream f(fopen("/tmp/tids", "re"));
+ if (!f) {
+ // This test requires a large (800MB) test file. It's not checked into the
+ // repository's //test/data because it would slow down all developers for
+ // a marginal benefit.
+ state.SkipWithError(
+ "Please run `curl -Lo /tmp/tids "
+ "https://storage.googleapis.com/perfetto/test_datalong_trace_tids.txt"
+ "` and try again.");
+ return;
+ }
+ char op;
+ int tid;
+ while (fscanf(*f, "%c %d\n", &op, &tid) == 2)
+ ops_and_tids.emplace_back(op, tid);
+ }
+
+ for (auto _ : state) {
+ MapType mapz;
+ for (const auto& ops_and_tid : ops_and_tids) {
+ if (ops_and_tid.first == '[') {
+ mapz[ops_and_tid.second]++;
+ } else {
+ mapz.insert({ops_and_tid.second, 0});
+ }
+ }
+
+ benchmark::ClobberMemory();
+ state.counters["uniq"] = Counter(static_cast<double>(mapz.size()));
+ }
+ state.counters["rate"] = Counter(static_cast<double>(ops_and_tids.size()),
+ Counter::kIsIterationInvariantRate);
+}
+
+template <typename MapType>
+void BM_HashMap_InsertRandInts(benchmark::State& state) {
+ std::minstd_rand0 rng(0);
+ std::vector<size_t> keys(static_cast<size_t>(num_samples()));
+ std::shuffle(keys.begin(), keys.end(), rng);
+ for (auto _ : state) {
+ MapType mapz;
+ for (const auto key : keys)
+ mapz.insert({key, key});
+ benchmark::DoNotOptimize(mapz);
+ benchmark::ClobberMemory();
+ }
+ state.counters["insertions"] = Counter(static_cast<double>(keys.size()),
+ Counter::kIsIterationInvariantRate);
+}
+
+// This test is performs insertions on integers that are designed to create
+// lot of clustering on the same small set of buckets.
+// This covers the unlucky case of using a map with a poor hashing function.
+template <typename MapType>
+void BM_HashMap_InsertCollidingInts(benchmark::State& state) {
+ std::vector<size_t> keys;
+ const size_t kNumSamples = num_samples();
+
+ // Generates numbers that are all distinct from each other, but that are
+ // designed to collide on the same buckets.
+ constexpr size_t kShift = 8; // Collide on the same 2^8 = 256 buckets.
+ for (size_t i = 0; i < kNumSamples; i++) {
+ size_t bucket = i & ((1 << kShift) - 1); // [0, 256].
+ size_t multiplier = i >> kShift; // 0,0,0... 1,1,1..., 2,2,2...
+ size_t key = 8192 * multiplier + bucket;
+ keys.push_back(key);
+ }
+ for (auto _ : state) {
+ MapType mapz;
+ for (const size_t key : keys)
+ mapz.insert({key, key});
+ benchmark::DoNotOptimize(mapz);
+ benchmark::ClobberMemory();
+ }
+ state.counters["insertions"] = Counter(static_cast<double>(keys.size()),
+ Counter::kIsIterationInvariantRate);
+}
+
+// Unlike the previous benchmark, here integers don't just collide on the same
+// buckets, they have a large number of duplicates with the same values.
+// Most of those insertions are no-ops. This tests the ability of the hashmap
+// to deal with cases where the hash function is good but the insertions contain
+// lot of dupes (e.g. dealing with pids).
+template <typename MapType>
+void BM_HashMap_InsertDupeInts(benchmark::State& state) {
+ std::vector<size_t> keys;
+ const size_t kNumSamples = num_samples();
+
+ for (size_t i = 0; i < kNumSamples; i++)
+ keys.push_back(i % 16384);
+
+ for (auto _ : state) {
+ MapType mapz;
+ for (const size_t key : keys)
+ mapz.insert({key, key});
+ benchmark::DoNotOptimize(mapz);
+ benchmark::ClobberMemory();
+ }
+ state.counters["insertions"] = Counter(static_cast<double>(keys.size()),
+ Counter::kIsIterationInvariantRate);
+}
+
+template <typename MapType>
+void BM_HashMap_LookupRandInts(benchmark::State& state) {
+ std::minstd_rand0 rng(0);
+ std::vector<size_t> keys(static_cast<size_t>(num_samples()));
+ std::shuffle(keys.begin(), keys.end(), rng);
+
+ MapType mapz;
+ for (const size_t key : keys)
+ mapz.insert({key, key});
+
+ for (auto _ : state) {
+ int64_t total = 0;
+ for (const size_t key : keys) {
+ auto it = mapz.find(static_cast<uint64_t>(key));
+ PERFETTO_CHECK(it != mapz.end());
+ total += it->second;
+ }
+ benchmark::DoNotOptimize(total);
+ benchmark::ClobberMemory();
+ state.counters["sum"] = Counter(static_cast<double>(total));
+ }
+ state.counters["lookups"] = Counter(static_cast<double>(keys.size()),
+ Counter::kIsIterationInvariantRate);
+}
+
+} // namespace
+
+using Ours_LinearProbing =
+ Ours<uint64_t, uint64_t, AlreadyHashed<uint64_t>, LinearProbe>;
+using Ours_QuadProbing =
+ Ours<uint64_t, uint64_t, AlreadyHashed<uint64_t>, QuadraticProbe>;
+using Ours_QuadCompProbing =
+ Ours<uint64_t, uint64_t, AlreadyHashed<uint64_t>, QuadraticHalfProbe>;
+using StdUnorderedMap =
+ std::unordered_map<uint64_t, uint64_t, AlreadyHashed<uint64_t>>;
+
+#if defined(PERFETTO_HASH_MAP_COMPARE_THIRD_PARTY_LIBS)
+using RobinMap = tsl::robin_map<uint64_t, uint64_t, AlreadyHashed<uint64_t>>;
+using AbslFlatHashMap =
+ absl::flat_hash_map<uint64_t, uint64_t, AlreadyHashed<uint64_t>>;
+using FollyF14FastMap =
+ folly::F14FastMap<uint64_t, uint64_t, AlreadyHashed<uint64_t>>;
+#endif
+
+BENCHMARK(BM_HashMap_InsertTraceStrings_AppendOnly);
+BENCHMARK_TEMPLATE(BM_HashMap_InsertTraceStrings, Ours_LinearProbing);
+BENCHMARK_TEMPLATE(BM_HashMap_InsertTraceStrings, Ours_QuadProbing);
+BENCHMARK_TEMPLATE(BM_HashMap_InsertTraceStrings, StdUnorderedMap);
+#if defined(PERFETTO_HASH_MAP_COMPARE_THIRD_PARTY_LIBS)
+BENCHMARK_TEMPLATE(BM_HashMap_InsertTraceStrings, RobinMap);
+BENCHMARK_TEMPLATE(BM_HashMap_InsertTraceStrings, AbslFlatHashMap);
+BENCHMARK_TEMPLATE(BM_HashMap_InsertTraceStrings, FollyF14FastMap);
+#endif
+
+#define TID_ARGS int, uint64_t, std::hash<int>
+BENCHMARK_TEMPLATE(BM_HashMap_TraceTids, Ours<TID_ARGS, LinearProbe>);
+BENCHMARK_TEMPLATE(BM_HashMap_TraceTids, Ours<TID_ARGS, QuadraticProbe>);
+BENCHMARK_TEMPLATE(BM_HashMap_TraceTids, Ours<TID_ARGS, QuadraticHalfProbe>);
+BENCHMARK_TEMPLATE(BM_HashMap_TraceTids, std::unordered_map<TID_ARGS>);
+#if defined(PERFETTO_HASH_MAP_COMPARE_THIRD_PARTY_LIBS)
+BENCHMARK_TEMPLATE(BM_HashMap_TraceTids, tsl::robin_map<TID_ARGS>);
+BENCHMARK_TEMPLATE(BM_HashMap_TraceTids, absl::flat_hash_map<TID_ARGS>);
+BENCHMARK_TEMPLATE(BM_HashMap_TraceTids, folly::F14FastMap<TID_ARGS>);
+#endif
+
+BENCHMARK_TEMPLATE(BM_HashMap_InsertRandInts, Ours_LinearProbing);
+BENCHMARK_TEMPLATE(BM_HashMap_InsertRandInts, Ours_QuadProbing);
+BENCHMARK_TEMPLATE(BM_HashMap_InsertRandInts, StdUnorderedMap);
+#if defined(PERFETTO_HASH_MAP_COMPARE_THIRD_PARTY_LIBS)
+BENCHMARK_TEMPLATE(BM_HashMap_InsertRandInts, RobinMap);
+BENCHMARK_TEMPLATE(BM_HashMap_InsertRandInts, AbslFlatHashMap);
+BENCHMARK_TEMPLATE(BM_HashMap_InsertRandInts, FollyF14FastMap);
+#endif
+
+BENCHMARK_TEMPLATE(BM_HashMap_InsertCollidingInts, Ours_LinearProbing);
+BENCHMARK_TEMPLATE(BM_HashMap_InsertCollidingInts, Ours_QuadProbing);
+BENCHMARK_TEMPLATE(BM_HashMap_InsertCollidingInts, Ours_QuadCompProbing);
+BENCHMARK_TEMPLATE(BM_HashMap_InsertCollidingInts, StdUnorderedMap);
+#if defined(PERFETTO_HASH_MAP_COMPARE_THIRD_PARTY_LIBS)
+BENCHMARK_TEMPLATE(BM_HashMap_InsertCollidingInts, RobinMap);
+BENCHMARK_TEMPLATE(BM_HashMap_InsertCollidingInts, AbslFlatHashMap);
+BENCHMARK_TEMPLATE(BM_HashMap_InsertCollidingInts, FollyF14FastMap);
+#endif
+
+BENCHMARK_TEMPLATE(BM_HashMap_InsertDupeInts, Ours_LinearProbing);
+BENCHMARK_TEMPLATE(BM_HashMap_InsertDupeInts, Ours_QuadProbing);
+BENCHMARK_TEMPLATE(BM_HashMap_InsertDupeInts, Ours_QuadCompProbing);
+BENCHMARK_TEMPLATE(BM_HashMap_InsertDupeInts, StdUnorderedMap);
+#if defined(PERFETTO_HASH_MAP_COMPARE_THIRD_PARTY_LIBS)
+BENCHMARK_TEMPLATE(BM_HashMap_InsertDupeInts, RobinMap);
+BENCHMARK_TEMPLATE(BM_HashMap_InsertDupeInts, AbslFlatHashMap);
+BENCHMARK_TEMPLATE(BM_HashMap_InsertDupeInts, FollyF14FastMap);
+#endif
+
+BENCHMARK_TEMPLATE(BM_HashMap_LookupRandInts, Ours_LinearProbing);
+BENCHMARK_TEMPLATE(BM_HashMap_LookupRandInts, Ours_QuadProbing);
+BENCHMARK_TEMPLATE(BM_HashMap_LookupRandInts, StdUnorderedMap);
+#if defined(PERFETTO_HASH_MAP_COMPARE_THIRD_PARTY_LIBS)
+BENCHMARK_TEMPLATE(BM_HashMap_LookupRandInts, RobinMap);
+BENCHMARK_TEMPLATE(BM_HashMap_LookupRandInts, AbslFlatHashMap);
+BENCHMARK_TEMPLATE(BM_HashMap_LookupRandInts, FollyF14FastMap);
+#endif
diff --git a/src/base/flat_hash_map_unittest.cc b/src/base/flat_hash_map_unittest.cc
new file mode 100644
index 000000000..7d3d62757
--- /dev/null
+++ b/src/base/flat_hash_map_unittest.cc
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/ext/base/flat_hash_map.h"
+
+#include <array>
+#include <functional>
+#include <random>
+#include <set>
+#include <unordered_map>
+
+#include "perfetto/ext/base/hash.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace base {
+namespace {
+
+using ::testing::Types;
+
+struct CollidingHasher {
+ size_t operator()(int n) const { return static_cast<size_t>(n % 1000); }
+};
+
+template <typename T>
+class FlatHashMapTest : public testing::Test {
+ public:
+ using Probe = T;
+};
+
+using ProbeTypes = Types<LinearProbe, QuadraticHalfProbe, QuadraticProbe>;
+TYPED_TEST_SUITE(FlatHashMapTest, ProbeTypes, /* trailing ',' for GCC*/);
+
+struct Key {
+ static int instances;
+
+ explicit Key(int v) : val(v) {}
+ ~Key() { instances--; }
+ Key(Key&& other) noexcept {
+ val = other.val;
+ other.val = -1;
+ }
+ bool operator==(const Key& other) { return val == other.val; }
+ int val = 0;
+ int id = instances++;
+};
+
+struct Value {
+ static int instances;
+
+ explicit Value(int v = 0) : val(v) {}
+ ~Value() { instances--; }
+ Value(Value&& other) noexcept {
+ val = other.val;
+ other.val = -1;
+ }
+ Value(const Value&) = delete;
+ int val = 0;
+ int id = instances++;
+};
+
+struct Hasher {
+ size_t operator()(const Key& k) const { return static_cast<size_t>(k.val); }
+};
+
+int Key::instances = 0;
+int Value::instances = 0;
+
+TYPED_TEST(FlatHashMapTest, NonTrivialKeyValues) {
+ FlatHashMap<Key, Value, Hasher, typename TestFixture::Probe> fmap;
+
+ for (int iteration = 0; iteration < 3; iteration++) {
+ const int kNum = 10;
+ for (int i = 0; i < kNum; i++) {
+ ASSERT_TRUE(fmap.Insert(Key(i), Value(i * 2)).second);
+ Value* value = fmap.Find(Key(i));
+ ASSERT_NE(value, nullptr);
+ ASSERT_EQ(value->val, i * 2);
+ ASSERT_EQ(Key::instances, i + 1);
+ ASSERT_EQ(Value::instances, i + 1);
+ }
+
+ ASSERT_TRUE(fmap.Erase(Key(1)));
+ ASSERT_TRUE(fmap.Erase(Key(5)));
+ ASSERT_TRUE(fmap.Erase(Key(9)));
+
+ ASSERT_EQ(Key::instances, kNum - 3);
+ ASSERT_EQ(Value::instances, kNum - 3);
+
+ FlatHashMap<Key, Value, Hasher, typename TestFixture::Probe> fmap2(
+ std::move(fmap));
+ ASSERT_EQ(fmap.size(), 0u);
+ ASSERT_EQ(fmap2.size(), static_cast<size_t>(kNum - 3));
+
+ ASSERT_EQ(Key::instances, kNum - 3);
+ ASSERT_EQ(Value::instances, kNum - 3);
+
+ // Ensure the moved-from map is usable.
+ fmap.Insert(Key(1), Value(-1));
+ fmap.Insert(Key(5), Value(-5));
+ fmap.Insert(Key(9), Value(-9));
+ ASSERT_EQ(Key::instances, (kNum - 3) + 3);
+ ASSERT_EQ(Value::instances, (kNum - 3) + 3);
+
+ fmap2.Clear();
+ ASSERT_EQ(fmap2.size(), 0u);
+ ASSERT_EQ(fmap.size(), 3u);
+ ASSERT_EQ(Key::instances, 3);
+ ASSERT_EQ(Value::instances, 3);
+ ASSERT_EQ(fmap.Find(Key(1))->val, -1);
+ ASSERT_EQ(fmap.Find(Key(5))->val, -5);
+ ASSERT_EQ(fmap.Find(Key(9))->val, -9);
+
+ fmap = std::move(fmap2);
+ ASSERT_EQ(Key::instances, 0);
+ ASSERT_EQ(Value::instances, 0);
+ ASSERT_EQ(fmap.size(), 0u);
+ }
+
+ // Test that operator[] behaves rationally.
+ fmap = decltype(fmap)(); // Re-assign with a copy constructor.
+ fmap[Key{2}].val = 102;
+ fmap[Key{1}].val = 101;
+ ASSERT_EQ(fmap.Find(Key{2})->val, 102);
+ ASSERT_EQ(fmap.Find(Key{1})->val, 101);
+ fmap[Key{2}].val = 122;
+ ASSERT_EQ(fmap.Find(Key{2})->val, 122);
+ ASSERT_EQ(fmap[Key{1}].val, 101);
+ auto fmap2(std::move(fmap));
+ ASSERT_EQ(fmap[Key{1}].val, 0);
+ ASSERT_EQ(fmap.size(), 1u);
+}
+
+TYPED_TEST(FlatHashMapTest, AllTagsAreValid) {
+ FlatHashMap<size_t, size_t, base::AlreadyHashed<size_t>,
+ typename TestFixture::Probe>
+ fmap;
+ auto make_key = [](size_t tag) {
+ return tag << ((sizeof(size_t) - 1) * size_t(8));
+ };
+ for (size_t i = 0; i < 256; i++) {
+ size_t key = make_key(i);
+ fmap.Insert(key, i);
+ ASSERT_EQ(fmap.size(), i + 1);
+ }
+ for (size_t i = 0; i < 256; i++) {
+ size_t key = make_key(i);
+ ASSERT_NE(fmap.Find(key), nullptr);
+ ASSERT_EQ(*fmap.Find(key), i);
+ }
+ for (size_t i = 0; i < 256; i++) {
+ size_t key = make_key(i);
+ fmap.Erase(key);
+ ASSERT_EQ(fmap.size(), 255 - i);
+ ASSERT_EQ(fmap.Find(key), nullptr);
+ }
+}
+
+TYPED_TEST(FlatHashMapTest, FillWithTombstones) {
+ FlatHashMap<Key, Value, Hasher, typename TestFixture::Probe> fmap(
+ /*initial_capacity=*/0, /*load_limit_pct=*/100);
+
+ for (int rep = 0; rep < 3; rep++) {
+ for (int i = 0; i < 1024; i++)
+ ASSERT_TRUE(fmap.Insert(Key(i), Value(i)).second);
+
+ ASSERT_EQ(fmap.size(), 1024u);
+ ASSERT_EQ(Key::instances, 1024);
+ ASSERT_EQ(Value::instances, 1024);
+
+ // Erase all entries.
+ for (int i = 0; i < 1024; i++)
+ ASSERT_TRUE(fmap.Erase(Key(i)));
+
+ ASSERT_EQ(fmap.size(), 0u);
+ ASSERT_EQ(Key::instances, 0);
+ ASSERT_EQ(Value::instances, 0);
+ }
+}
+
+TYPED_TEST(FlatHashMapTest, Collisions) {
+ FlatHashMap<int, int, CollidingHasher, typename TestFixture::Probe> fmap(
+ /*initial_capacity=*/0, /*load_limit_pct=*/100);
+
+ for (int rep = 0; rep < 3; rep++) {
+ // Insert four values which collide on the same bucket.
+ ASSERT_TRUE(fmap.Insert(1001, 1001).second);
+ ASSERT_TRUE(fmap.Insert(2001, 2001).second);
+ ASSERT_TRUE(fmap.Insert(3001, 3001).second);
+ ASSERT_TRUE(fmap.Insert(4001, 4001).second);
+
+ // Erase the 2nd one, it will create a tombstone.
+ ASSERT_TRUE(fmap.Erase(2001));
+ ASSERT_EQ(fmap.size(), 3u);
+
+ // Insert an entry that exists already, but happens to be located after the
+ // tombstone. Should still fail.
+ ASSERT_FALSE(fmap.Insert(3001, 3001).second);
+ ASSERT_EQ(fmap.size(), 3u);
+
+ ASSERT_TRUE(fmap.Erase(3001));
+ ASSERT_FALSE(fmap.Erase(2001));
+ ASSERT_TRUE(fmap.Erase(4001));
+
+ // The only element left is 101.
+ ASSERT_EQ(fmap.size(), 1u);
+
+ ASSERT_TRUE(fmap.Erase(1001));
+ ASSERT_EQ(fmap.size(), 0u);
+ }
+}
+
+TYPED_TEST(FlatHashMapTest, ProbeVisitsAllSlots) {
+ const int kIterations = 1024;
+ FlatHashMap<int, int, CollidingHasher, typename TestFixture::Probe> fmap(
+ /*initial_capacity=*/kIterations, /*load_limit_pct=*/100);
+ for (int i = 0; i < kIterations; i++) {
+ ASSERT_TRUE(fmap.Insert(i, i).second);
+ }
+ // If the hashmap hits an expansion the tests doesn't make sense. This test
+ // makes sense only if we actually saturate all buckets.
+ EXPECT_EQ(fmap.capacity(), static_cast<size_t>(kIterations));
+}
+
+TYPED_TEST(FlatHashMapTest, Iterator) {
+ FlatHashMap<int, int, base::AlreadyHashed<int>, typename TestFixture::Probe>
+ fmap;
+
+ auto it = fmap.GetIterator();
+ ASSERT_FALSE(it);
+
+ // Insert 3 values and iterate.
+ ASSERT_TRUE(fmap.Insert(1, 1001).second);
+ ASSERT_TRUE(fmap.Insert(2, 2001).second);
+ ASSERT_TRUE(fmap.Insert(3, 3001).second);
+ it = fmap.GetIterator();
+ for (int i = 1; i <= 3; i++) {
+ ASSERT_TRUE(it);
+ ASSERT_EQ(it.key(), i);
+ ASSERT_EQ(it.value(), i * 1000 + 1);
+ ++it;
+ }
+ ASSERT_FALSE(it);
+
+ // Erase the middle one and iterate.
+ fmap.Erase(2);
+ it = fmap.GetIterator();
+ ASSERT_TRUE(it);
+ ASSERT_EQ(it.key(), 1);
+ ++it;
+ ASSERT_TRUE(it);
+ ASSERT_EQ(it.key(), 3);
+ ++it;
+ ASSERT_FALSE(it);
+
+ // Erase everything and iterate.
+ fmap.Clear();
+ it = fmap.GetIterator();
+ ASSERT_FALSE(it);
+}
+
+// Test that Insert() and operator[] don't invalidate pointers if the key exists
+// already, regardless of the load factor.
+TYPED_TEST(FlatHashMapTest, DontRehashIfKeyAlreadyExists) {
+ static constexpr size_t kInitialCapacity = 128;
+ static std::array<size_t, 3> kLimitPct{25, 50, 100};
+
+ for (size_t limit_pct : kLimitPct) {
+ FlatHashMap<size_t, size_t, AlreadyHashed<size_t>,
+ typename TestFixture::Probe>
+ fmap(kInitialCapacity, static_cast<int>(limit_pct));
+
+ const size_t limit = kInitialCapacity * limit_pct / 100u;
+ ASSERT_EQ(fmap.capacity(), kInitialCapacity);
+ std::vector<size_t*> key_ptrs;
+ for (size_t i = 0; i < limit; i++) {
+ auto it_and_ins = fmap.Insert(i, i);
+ ASSERT_TRUE(it_and_ins.second);
+ ASSERT_EQ(fmap.capacity(), kInitialCapacity);
+ key_ptrs.push_back(it_and_ins.first);
+ }
+
+ // Re-insert existing items. It should not cause rehashing.
+ for (size_t i = 0; i < limit; i++) {
+ auto it_and_ins = fmap.Insert(i, i);
+ ASSERT_FALSE(it_and_ins.second);
+ ASSERT_EQ(it_and_ins.first, key_ptrs[i]);
+
+ size_t* key_ptr = &fmap[i];
+ ASSERT_EQ(key_ptr, key_ptrs[i]);
+ ASSERT_EQ(fmap.capacity(), kInitialCapacity);
+ }
+ }
+}
+
+TYPED_TEST(FlatHashMapTest, VsUnorderedMap) {
+ std::unordered_map<int, int, CollidingHasher> umap;
+ FlatHashMap<int, int, CollidingHasher, typename TestFixture::Probe> fmap;
+ std::minstd_rand0 rng(0);
+
+ for (int rep = 0; rep < 2; rep++) {
+ std::set<int> keys_copy;
+ const int kRange = 1024;
+
+ // Insert some random elements.
+ for (int i = 0; i < kRange; i++) {
+ int key = static_cast<int>(rng()) / 2;
+ int value = key * 2;
+ keys_copy.insert(key);
+ auto it_and_inserted_u = umap.insert({key, value});
+ auto it_and_inserted_f = fmap.Insert(key, value);
+ ASSERT_EQ(it_and_inserted_u.second, it_and_inserted_f.second);
+ ASSERT_EQ(*it_and_inserted_f.first, value);
+ ASSERT_EQ(umap.size(), fmap.size());
+ int* res = fmap.Find(key);
+ ASSERT_NE(res, nullptr);
+ ASSERT_EQ(*res, value);
+ ASSERT_EQ(fmap[key], value); // Test that operator[] behaves like Find().
+ }
+ // Look them up.
+ for (int key : keys_copy) {
+ int* res = fmap.Find(key);
+ ASSERT_NE(res, nullptr);
+ ASSERT_EQ(*res, key * 2);
+ ASSERT_EQ(umap.size(), fmap.size());
+ }
+
+ // Some further deletions / insertions / reinsertions.
+ for (int key : keys_copy) {
+ auto op = rng() % 4;
+
+ if (op < 2) {
+ // With a 50% chance, erase the key.
+ bool erased_u = umap.erase(key) > 0;
+ bool erased_f = fmap.Erase(key);
+ ASSERT_EQ(erased_u, erased_f);
+ } else if (op == 3) {
+ // With a 25% chance, re-insert the same key (should fail).
+ umap.insert({key, 0});
+ ASSERT_FALSE(fmap.Insert(key, 0).second);
+ } else {
+ // With a 25% chance, insert a new key.
+ umap.insert({key + kRange, (key + kRange) * 2});
+ ASSERT_TRUE(fmap.Insert(key + kRange, (key + kRange) * 2).second);
+ }
+
+ ASSERT_EQ(umap.size(), fmap.size());
+ }
+
+ // Re-look up keys. Note some of them might be deleted by the loop above.
+ for (int k : keys_copy) {
+ for (int i = 0; i < 2; i++) {
+ const int key = k + kRange * i;
+ int* res = fmap.Find(key);
+ if (umap.count(key)) {
+ ASSERT_NE(res, nullptr);
+ ASSERT_EQ(*res, key * 2);
+ } else {
+ ASSERT_EQ(res, nullptr);
+ }
+ }
+ }
+
+ fmap.Clear();
+ umap.clear();
+ ASSERT_EQ(fmap.size(), 0u);
+
+ for (int key : keys_copy)
+ ASSERT_EQ(fmap.Find(key), nullptr);
+ }
+}
+
+} // namespace
+} // namespace base
+} // namespace perfetto
diff --git a/src/base/getopt_compat.cc b/src/base/getopt_compat.cc
index 19c8adc46..0c80dc6de 100644
--- a/src/base/getopt_compat.cc
+++ b/src/base/getopt_compat.cc
@@ -30,6 +30,8 @@ namespace getopt_compat {
char* optarg = nullptr;
int optind = 0;
+int optopt = 0;
+int opterr = 1;
namespace {
@@ -47,7 +49,7 @@ const option* LookupLongOpt(const std::vector<option>& opts,
const option* LookupShortOpt(const std::vector<option>& opts, char c) {
for (const option& opt : opts) {
- if (opt.name == nullptr && opt.val == c)
+ if (!*opt.name && opt.val == c)
return &opt;
}
return nullptr;
@@ -78,6 +80,7 @@ bool ParseOpts(const char* shortopts,
}
res->emplace_back();
option& opt = res->back();
+ opt.name = "";
opt.val = c;
opt.has_arg = no_argument;
if (*sopt == ':') {
@@ -108,6 +111,7 @@ int getopt_long(int argc,
return '?';
char* arg = argv[optind];
+ optopt = 0;
if (!nextchar) {
// If |nextchar| is null we are NOT in the middle of a short option and we
@@ -120,11 +124,14 @@ int getopt_long(int argc,
size_t len = sep ? static_cast<size_t>(sep - arg) : strlen(arg);
const option* opt = LookupLongOpt(opts, arg, len);
+
if (!opt) {
- fprintf(stderr, "unrecognized option '--%s'\n", arg);
+ if (opterr)
+ fprintf(stderr, "unrecognized option '--%s'\n", arg);
return '?';
}
+ optopt = opt->val;
if (opt->has_arg == no_argument) {
if (sep) {
fprintf(stderr, "option '--%s' doesn't allow an argument\n", arg);
@@ -137,7 +144,8 @@ int getopt_long(int argc,
optarg = sep + 1;
return opt->val;
} else if (optind >= argc) {
- fprintf(stderr, "option '--%s' requires an argument\n", arg);
+ if (opterr)
+ fprintf(stderr, "option '--%s' requires an argument\n", arg);
return '?';
} else {
optarg = argv[optind++];
@@ -173,8 +181,10 @@ int getopt_long(int argc,
}
const option* opt = LookupShortOpt(opts, cur_char);
+ optopt = cur_char;
if (!opt) {
- fprintf(stderr, "invalid option -- '%c'\n", cur_char);
+ if (opterr)
+ fprintf(stderr, "invalid option -- '%c'\n", cur_char);
return '?';
}
if (opt->has_arg == no_argument) {
@@ -189,7 +199,8 @@ int getopt_long(int argc,
if (!nextchar) {
// Case 1.
if (optind >= argc) {
- fprintf(stderr, "option requires an argument -- '%c'\n", cur_char);
+ if (opterr)
+ fprintf(stderr, "option requires an argument -- '%c'\n", cur_char);
return '?';
} else {
optarg = argv[optind++];
diff --git a/src/base/getopt_compat_unittest.cc b/src/base/getopt_compat_unittest.cc
index a7d4db342..0ae372109 100644
--- a/src/base/getopt_compat_unittest.cc
+++ b/src/base/getopt_compat_unittest.cc
@@ -47,6 +47,8 @@ struct OurGetopt {
GetoptFn getopt = &getopt_compat::getopt;
GetoptLongFn getopt_long = &getopt_compat::getopt_long;
int& optind = getopt_compat::optind;
+ int& optopt = getopt_compat::optopt;
+ int& opterr = getopt_compat::opterr;
char*& optarg = getopt_compat::optarg;
};
@@ -58,6 +60,8 @@ struct SystemGetopt {
GetoptFn getopt = &::getopt;
GetoptLongFn getopt_long = &::getopt_long;
int& optind = ::optind;
+ int& optopt = ::optopt;
+ int& opterr = ::opterr;
char*& optarg = ::optarg;
};
#endif
@@ -109,7 +113,6 @@ TYPED_TEST(GetoptCompatTest, ShortOptions) {
sops = "h";
this->SetCmdline({"argv0", "-h"});
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), 'h');
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 2);
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), -1);
EXPECT_EQ(t.optind, 2);
@@ -133,7 +136,6 @@ TYPED_TEST(GetoptCompatTest, ShortOptions) {
sops = "abc";
this->SetCmdline({"argv0", "-c", "-a", "-b"});
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), 'c');
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 2);
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), 'a');
EXPECT_EQ(t.optind, 3);
@@ -145,25 +147,19 @@ TYPED_TEST(GetoptCompatTest, ShortOptions) {
sops = "abc";
this->SetCmdline({"argv0", "-c", "-a", "--", "nonopt"});
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), 'c');
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 2);
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), 'a');
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 3);
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), -1);
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 4);
sops = "abc";
this->SetCmdline({"argv0", "-cb"});
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), 'c');
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 1);
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), 'b');
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 2);
EXPECT_EQ(t.getopt(this->argc, this->argv, sops), -1);
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 2);
sops = "abc";
@@ -228,7 +224,6 @@ TYPED_TEST(GetoptCompatTest, LongOptions) {
const char* sops = "";
this->SetCmdline({"argv0"});
EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), -1);
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 1);
}
@@ -239,7 +234,6 @@ TYPED_TEST(GetoptCompatTest, LongOptions) {
const char* sops = "";
this->SetCmdline({"argv0", "--unknown"});
EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), '?');
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 2);
}
@@ -252,13 +246,10 @@ TYPED_TEST(GetoptCompatTest, LongOptions) {
const char* sops = "";
this->SetCmdline({"argv0", "--two", "--one"});
EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), 2);
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 2);
EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), 1);
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 3);
EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), -1);
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 3);
}
@@ -271,13 +262,10 @@ TYPED_TEST(GetoptCompatTest, LongOptions) {
const char* sops = "";
this->SetCmdline({"argv0", "--two", "--one", "--not-an-opt"});
EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), 2);
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 2);
EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), 1);
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 3);
EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), '?');
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 4);
}
@@ -351,7 +339,6 @@ TYPED_TEST(GetoptCompatTest, ShortAndLongOptions) {
this->SetCmdline({"argv0"});
EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), -1);
- EXPECT_EQ(t.optarg, nullptr);
EXPECT_EQ(t.optind, 1);
this->SetCmdline({"argv0", "-13", "--two", "--three", "--", "--one"});
@@ -382,6 +369,32 @@ TYPED_TEST(GetoptCompatTest, ShortAndLongOptions) {
}
}
+TYPED_TEST(GetoptCompatTest, OpterrHandling) {
+ auto& t = this->impl;
+ t.opterr = 0; // Make errors silent.
+
+ const char* sops = "ab:";
+ this->SetCmdline({"argv0", "-a", "-c", "-b"});
+ EXPECT_EQ(t.getopt(this->argc, this->argv, sops), 'a');
+ EXPECT_EQ(t.getopt(this->argc, this->argv, sops), '?');
+ EXPECT_EQ(t.optopt, 'c');
+ EXPECT_EQ(t.getopt(this->argc, this->argv, sops), '?');
+ EXPECT_EQ(t.optopt, 'b');
+ EXPECT_EQ(t.getopt(this->argc, this->argv, sops), -1);
+
+ using LongOptionType = typename decltype(this->impl)::LongOptionType;
+ LongOptionType lopts[]{
+ {"requires_arg", 1 /*required_argument*/, nullptr, 42},
+ {nullptr, 0, nullptr, 0},
+ };
+ this->SetCmdline({"argv0", "-a", "--unkonwn", "--requires_arg"});
+ EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), 'a');
+ EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), '?');
+ EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), '?');
+ EXPECT_EQ(t.optopt, 42);
+ EXPECT_EQ(t.getopt_long(this->argc, this->argv, sops, lopts, nullptr), -1);
+}
+
} // namespace
} // namespace base
} // namespace perfetto
diff --git a/src/base/http/BUILD.gn b/src/base/http/BUILD.gn
new file mode 100644
index 000000000..e0861347c
--- /dev/null
+++ b/src/base/http/BUILD.gn
@@ -0,0 +1,47 @@
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("../../../gn/perfetto.gni")
+import("../../../gn/perfetto_component.gni")
+import("../../../gn/test.gni")
+
+perfetto_component("http") {
+ deps = [
+ "..:base",
+ "..:unix_socket",
+ "../../../gn:default_deps",
+ ]
+ public_deps = [
+ "../../../include/perfetto/base",
+ "../../../include/perfetto/ext/base/http",
+ ]
+ sources = [
+ "http_server.cc",
+ "sha1.cc",
+ ]
+}
+
+perfetto_unittest_source_set("unittests") {
+ testonly = true
+ deps = [
+ ":http",
+ "..:test_support",
+ "../../../gn:default_deps",
+ "../../../gn:gtest_and_gmock",
+ ]
+ sources = [
+ "http_server_unittest.cc",
+ "sha1_unittest.cc",
+ ]
+}
diff --git a/src/base/http/http_server.cc b/src/base/http/http_server.cc
new file mode 100644
index 000000000..0b098e16b
--- /dev/null
+++ b/src/base/http/http_server.cc
@@ -0,0 +1,580 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "perfetto/ext/base/http/http_server.h"
+
+#include <cinttypes>
+
+#include <vector>
+
+#include "perfetto/ext/base/base64.h"
+#include "perfetto/ext/base/endian.h"
+#include "perfetto/ext/base/http/sha1.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/string_view.h"
+
+namespace perfetto {
+namespace base {
+
+namespace {
+constexpr size_t kMaxPayloadSize = 64 * 1024 * 1024;
+constexpr size_t kMaxRequestSize = kMaxPayloadSize + 4096;
+
+enum WebsocketOpcode : uint8_t {
+ kOpcodeContinuation = 0x0,
+ kOpcodeText = 0x1,
+ kOpcodeBinary = 0x2,
+ kOpcodeDataUnused = 0x3,
+ kOpcodeClose = 0x8,
+ kOpcodePing = 0x9,
+ kOpcodePong = 0xA,
+ kOpcodeControlUnused = 0xB,
+};
+
+// From https://datatracker.ietf.org/doc/html/rfc6455#section-1.3.
+constexpr char kWebsocketGuid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+
+} // namespace
+
+HttpServer::HttpServer(TaskRunner* task_runner, HttpRequestHandler* req_handler)
+ : task_runner_(task_runner), req_handler_(req_handler) {}
+HttpServer::~HttpServer() = default;
+
+void HttpServer::Start(int port) {
+ std::string ipv4_addr = "127.0.0.1:" + std::to_string(port);
+ std::string ipv6_addr = "[::1]:" + std::to_string(port);
+
+ sock4_ = UnixSocket::Listen(ipv4_addr, this, task_runner_, SockFamily::kInet,
+ SockType::kStream);
+ bool ipv4_listening = sock4_ && sock4_->is_listening();
+ if (!ipv4_listening) {
+ PERFETTO_PLOG("Failed to listen on IPv4 socket");
+ sock4_.reset();
+ }
+
+ sock6_ = UnixSocket::Listen(ipv6_addr, this, task_runner_, SockFamily::kInet6,
+ SockType::kStream);
+ bool ipv6_listening = sock6_ && sock6_->is_listening();
+ if (!ipv6_listening) {
+ PERFETTO_PLOG("Failed to listen on IPv6 socket");
+ sock6_.reset();
+ }
+}
+
+void HttpServer::AddAllowedOrigin(const std::string& origin) {
+ allowed_origins_.emplace_back(origin);
+}
+
+void HttpServer::OnNewIncomingConnection(
+ UnixSocket*, // The listening socket, irrelevant here.
+ std::unique_ptr<UnixSocket> sock) {
+ PERFETTO_LOG("[HTTP] New connection");
+ clients_.emplace_back(std::move(sock));
+}
+
+void HttpServer::OnConnect(UnixSocket*, bool) {}
+
+void HttpServer::OnDisconnect(UnixSocket* sock) {
+ PERFETTO_LOG("[HTTP] Client disconnected");
+ for (auto it = clients_.begin(); it != clients_.end(); ++it) {
+ if (it->sock.get() == sock) {
+ req_handler_->OnHttpConnectionClosed(&*it);
+ clients_.erase(it);
+ return;
+ }
+ }
+ PERFETTO_DFATAL("[HTTP] Untracked client in OnDisconnect()");
+}
+
+void HttpServer::OnDataAvailable(UnixSocket* sock) {
+ HttpServerConnection* conn = nullptr;
+ for (auto it = clients_.begin(); it != clients_.end() && !conn; ++it)
+ conn = (it->sock.get() == sock) ? &*it : nullptr;
+ PERFETTO_CHECK(conn);
+
+ char* rxbuf = reinterpret_cast<char*>(conn->rxbuf.Get());
+ for (;;) {
+ size_t avail = conn->rxbuf_avail();
+ PERFETTO_CHECK(avail <= kMaxRequestSize);
+ if (avail == 0) {
+ conn->SendResponseAndClose("413 Payload Too Large");
+ return;
+ }
+ size_t rsize = sock->Receive(&rxbuf[conn->rxbuf_used], avail);
+ conn->rxbuf_used += rsize;
+ if (rsize == 0 || conn->rxbuf_avail() == 0)
+ break;
+ }
+
+ // At this point |rxbuf| can contain a partial HTTP request, a full one or
+ // more (in case of HTTP Keepalive pipelining).
+ for (;;) {
+ size_t bytes_consumed;
+
+ if (conn->is_websocket()) {
+ bytes_consumed = ParseOneWebsocketFrame(conn);
+ } else {
+ bytes_consumed = ParseOneHttpRequest(conn);
+ }
+
+ if (bytes_consumed == 0)
+ break;
+ memmove(rxbuf, &rxbuf[bytes_consumed], conn->rxbuf_used - bytes_consumed);
+ conn->rxbuf_used -= bytes_consumed;
+ }
+}
+
+// Parses the HTTP request and invokes HandleRequest(). It returns the size of
+// the HTTP header + body that has been processed or 0 if there isn't enough
+// data for a full HTTP request in the buffer.
+size_t HttpServer::ParseOneHttpRequest(HttpServerConnection* conn) {
+ auto* rxbuf = reinterpret_cast<char*>(conn->rxbuf.Get());
+ StringView buf_view(rxbuf, conn->rxbuf_used);
+ bool has_parsed_first_line = false;
+ bool all_headers_received = false;
+ HttpRequest http_req(conn);
+ size_t body_size = 0;
+
+ // This loop parses the HTTP request headers and sets the |body_offset|.
+ while (!buf_view.empty()) {
+ size_t next = buf_view.find('\n');
+ if (next == StringView::npos)
+ break;
+ StringView line = buf_view.substr(0, next);
+ buf_view = buf_view.substr(next + 1); // Eat the current line.
+ while (!line.empty() && (line.at(line.size() - 1) == '\r' ||
+ line.at(line.size() - 1) == '\n')) {
+ line = line.substr(0, line.size() - 1);
+ }
+
+ if (!has_parsed_first_line) {
+ // Parse the "GET /xxx HTTP/1.1" line.
+ has_parsed_first_line = true;
+ size_t space = line.find(' ');
+ if (space == std::string::npos || space + 2 >= line.size()) {
+ conn->SendResponseAndClose("400 Bad Request");
+ return 0;
+ }
+ http_req.method = line.substr(0, space);
+ size_t uri_size = line.find(' ', space + 1) - (space + 1);
+ http_req.uri = line.substr(space + 1, uri_size);
+ } else if (line.empty()) {
+ all_headers_received = true;
+ // The CR-LF marker that separates headers from body.
+ break;
+ } else {
+ // Parse HTTP headers, e.g. "Content-Length: 1234".
+ size_t col = line.find(':');
+ if (col == StringView::npos) {
+ PERFETTO_DLOG("[HTTP] Malformed HTTP header: \"%s\"",
+ line.ToStdString().c_str());
+ conn->SendResponseAndClose("400 Bad Request", {}, "Bad HTTP header");
+ return 0;
+ }
+ auto hdr_name = line.substr(0, col);
+ auto hdr_value = line.substr(col + 2);
+ if (http_req.num_headers < http_req.headers.size()) {
+ http_req.headers[http_req.num_headers++] = {hdr_name, hdr_value};
+ } else {
+ conn->SendResponseAndClose("400 Bad Request", {},
+ "Too many HTTP headers");
+ }
+
+ if (hdr_name.CaseInsensitiveEq("content-length")) {
+ body_size = static_cast<size_t>(atoi(hdr_value.ToStdString().c_str()));
+ } else if (hdr_name.CaseInsensitiveEq("origin")) {
+ http_req.origin = hdr_value;
+ if (IsOriginAllowed(hdr_value))
+ conn->origin_allowed_ = hdr_value.ToStdString();
+ } else if (hdr_name.CaseInsensitiveEq("connection")) {
+ conn->keepalive_ = hdr_value.CaseInsensitiveEq("keep-alive");
+ http_req.is_websocket_handshake =
+ hdr_value.CaseInsensitiveEq("upgrade");
+ }
+ }
+ }
+
+ // At this point |buf_view| has been stripped of the header and contains the
+ // request body. We don't know yet if we have all the bytes for it or not.
+ PERFETTO_CHECK(buf_view.size() <= conn->rxbuf_used);
+ const size_t headers_size = conn->rxbuf_used - buf_view.size();
+
+ if (body_size + headers_size >= kMaxRequestSize ||
+ body_size > kMaxPayloadSize) {
+ conn->SendResponseAndClose("413 Payload Too Large");
+ return 0;
+ }
+
+ // If we can't read the full request return and try again next time with more
+ // data.
+ if (!all_headers_received || buf_view.size() < body_size)
+ return 0;
+
+ http_req.body = buf_view.substr(0, body_size);
+
+ PERFETTO_LOG("[HTTP] %.*s %.*s [body=%zuB, origin=\"%.*s\"]",
+ static_cast<int>(http_req.method.size()), http_req.method.data(),
+ static_cast<int>(http_req.uri.size()), http_req.uri.data(),
+ http_req.body.size(), static_cast<int>(http_req.origin.size()),
+ http_req.origin.data());
+
+ if (http_req.method == "OPTIONS") {
+ HandleCorsPreflightRequest(http_req);
+ } else {
+ // Let the HttpHandler handle the request.
+ req_handler_->OnHttpRequest(http_req);
+ }
+
+ // The handler is expected to send a response. If not, bail with a HTTP 500.
+ if (!conn->headers_sent_)
+ conn->SendResponseAndClose("500 Internal Server Error");
+
+ // Allow chaining multiple responses in the same HTTP-Keepalive connection.
+ conn->headers_sent_ = false;
+
+ return headers_size + body_size;
+}
+
+void HttpServer::HandleCorsPreflightRequest(const HttpRequest& req) {
+ req.conn->SendResponseAndClose(
+ "204 No Content",
+ {
+ "Access-Control-Allow-Methods: POST, GET, OPTIONS", //
+ "Access-Control-Allow-Headers: *", //
+ "Access-Control-Max-Age: 86400", //
+ });
+}
+
+bool HttpServer::IsOriginAllowed(StringView origin) {
+ for (const std::string& allowed_origin : allowed_origins_) {
+ if (origin.CaseInsensitiveEq(StringView(allowed_origin))) {
+ return true;
+ }
+ }
+ if (!origin_error_logged_ && !origin.empty()) {
+ origin_error_logged_ = true;
+ PERFETTO_ELOG(
+ "[HTTP] The origin \"%.*s\" is not allowed, Access-Control-Allow-Origin"
+ " won't be emitted. If this request comes from a browser it will fail.",
+ static_cast<int>(origin.size()), origin.data());
+ }
+ return false;
+}
+
+void HttpServerConnection::UpgradeToWebsocket(const HttpRequest& req) {
+ PERFETTO_CHECK(req.is_websocket_handshake);
+
+ // |origin_allowed_| is set to the req.origin only if it's in the allowlist.
+ if (origin_allowed_.empty())
+ return SendResponseAndClose("403 Forbidden", {}, "Origin not allowed");
+
+ auto ws_ver = req.GetHeader("sec-webSocket-version").value_or(StringView());
+ auto ws_key = req.GetHeader("sec-webSocket-key").value_or(StringView());
+
+ if (!ws_ver.CaseInsensitiveEq("13"))
+ return SendResponseAndClose("505 HTTP Version Not Supported", {});
+
+ if (ws_key.size() != 24) {
+ // The nonce must be a base64 encoded 16 bytes value (24 after base64).
+ return SendResponseAndClose("400 Bad Request", {});
+ }
+
+ // From https://datatracker.ietf.org/doc/html/rfc6455#section-1.3 :
+ // For this header field, the server has to take the value (as present
+ // in the header field, e.g., the base64-encoded [RFC4648] version minus
+ // any leading and trailing whitespace) and concatenate this with the
+ // Globally Unique Identifier (GUID, [RFC4122]) "258EAFA5-E914-47DA-
+ // 95CA-C5AB0DC85B11" in string form, which is unlikely to be used by
+ // network endpoints that do not understand the WebSocket Protocol. A
+ // SHA-1 hash (160 bits) [FIPS.180-3], base64-encoded (see Section 4 of
+ // [RFC4648]), of this concatenation is then returned in the server's
+ // handshake.
+ StackString<128> signed_nonce("%.*s%s", static_cast<int>(ws_key.size()),
+ ws_key.data(), kWebsocketGuid);
+ auto digest = SHA1Hash(signed_nonce.c_str(), signed_nonce.len());
+ std::string digest_b64 = Base64Encode(digest.data(), digest.size());
+
+ StackString<128> accept_hdr("Sec-WebSocket-Accept: %s", digest_b64.c_str());
+
+ std::initializer_list<const char*> headers = {
+ "Upgrade: websocket", //
+ "Connection: Upgrade", //
+ accept_hdr.c_str(), //
+ };
+ PERFETTO_DLOG("[HTTP] Handshaking WebSocket for %.*s",
+ static_cast<int>(req.uri.size()), req.uri.data());
+ for (const char* hdr : headers)
+ PERFETTO_DLOG("> %s", hdr);
+
+ SendResponseHeaders("101 Switching Protocols", headers,
+ HttpServerConnection::kOmitContentLength);
+
+ is_websocket_ = true;
+}
+
+size_t HttpServer::ParseOneWebsocketFrame(HttpServerConnection* conn) {
+ auto* rxbuf = reinterpret_cast<uint8_t*>(conn->rxbuf.Get());
+ const size_t frame_size = conn->rxbuf_used;
+ uint8_t* rd = rxbuf;
+ uint8_t* const end = rxbuf + frame_size;
+
+ auto avail = [&] {
+ PERFETTO_CHECK(rd <= end);
+ return static_cast<size_t>(end - rd);
+ };
+
+ // From https://datatracker.ietf.org/doc/html/rfc6455#section-5.2 :
+ // 0 1 2 3
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ // +-+-+-+-+-------+-+-------------+-------------------------------+
+ // |F|R|R|R| opcode|M| Payload len | Extended payload length |
+ // |I|S|S|S| (4) |A| (7) | (16/64) |
+ // |N|V|V|V| |S| | (if payload len==126/127) |
+ // | |1|2|3| |K| | |
+ // +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
+ // | Extended payload length continued, if payload len == 127 |
+ // + - - - - - - - - - - - - - - - +-------------------------------+
+ // | |Masking-key, if MASK set to 1 |
+ // +-------------------------------+-------------------------------+
+ // | Masking-key (continued) | Payload Data |
+ // +-------------------------------- - - - - - - - - - - - - - - - +
+ // : Payload Data continued ... :
+ // + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
+ // | Payload Data continued ... |
+ // +---------------------------------------------------------------+
+
+ if (avail() < 2)
+ return 0; // Can't even decode the frame header. Wait for more data.
+
+ uint8_t h0 = *(rd++);
+ uint8_t h1 = *(rd++);
+ const bool fin = !!(h0 & 0x80); // This bit is set if this frame is the last
+ // data to complete this message.
+ const uint8_t opcode = h0 & 0x0F;
+
+ const bool has_mask = !!(h1 & 0x80);
+ uint64_t payload_len_u64 = (h1 & 0x7F);
+ uint8_t extended_payload_size = 0;
+ if (payload_len_u64 == 126) {
+ extended_payload_size = 2;
+ } else if (payload_len_u64 == 127) {
+ extended_payload_size = 8;
+ }
+
+ if (extended_payload_size > 0) {
+ if (avail() < extended_payload_size)
+ return 0; // Not enough data to read the extended header.
+ payload_len_u64 = 0;
+ for (uint8_t i = 0; i < extended_payload_size; ++i) {
+ payload_len_u64 <<= 8;
+ payload_len_u64 |= *(rd++);
+ }
+ }
+
+ if (payload_len_u64 >= kMaxPayloadSize) {
+ PERFETTO_ELOG("[HTTP] Websocket payload too big (%" PRIu64 " > %zu)",
+ payload_len_u64, kMaxPayloadSize);
+ conn->Close();
+ return 0;
+ }
+ const size_t payload_len = static_cast<size_t>(payload_len_u64);
+
+ if (!has_mask) {
+ // https://datatracker.ietf.org/doc/html/rfc6455#section-5.1
+ // The server MUST close the connection upon receiving a frame that is
+ // not masked.
+ PERFETTO_ELOG("[HTTP] Websocket inbound frames must be masked");
+ conn->Close();
+ return 0;
+ }
+
+ uint8_t mask[4];
+ if (avail() < sizeof(mask))
+ return 0; // Not enough data to read the masking key.
+ memcpy(mask, rd, sizeof(mask));
+ rd += sizeof(mask);
+
+ PERFETTO_DLOG(
+ "[HTTP] Websocket fin=%d opcode=%u, payload_len=%zu (avail=%zu), "
+ "mask=%02x%02x%02x%02x",
+ fin, opcode, payload_len, avail(), mask[0], mask[1], mask[2], mask[3]);
+
+ if (avail() < payload_len)
+ return 0; // Not enouh data to read the payload.
+ uint8_t* const payload_start = rd;
+
+ // Unmask the payload.
+ for (uint32_t i = 0; i < payload_len; ++i)
+ payload_start[i] ^= mask[i % sizeof(mask)];
+
+ if (opcode == kOpcodePing) {
+ PERFETTO_DLOG("[HTTP] Websocket PING");
+ conn->SendWebsocketFrame(kOpcodePong, payload_start, payload_len);
+ } else if (opcode == kOpcodeBinary || opcode == kOpcodeText ||
+ opcode == kOpcodeContinuation) {
+ // We do NOT handle fragmentation. We propagate all fragments as individual
+ // messages, breaking the message-oriented nature of websockets. We do this
+ // because in all our use cases we need only a byte stream without caring
+ // about message boundaries.
+ // If we wanted to support fragmentation, we'd have to stash
+ // kOpcodeContinuation messages in a buffer, until we FIN bit is set.
+ // When loading traces with trace processor, the messages can be up to
+ // 32MB big (SLICE_SIZE in trace_stream.ts). The double-buffering would
+ // slow down significantly trace loading with no benefits.
+ WebsocketMessage msg(conn);
+ msg.data =
+ StringView(reinterpret_cast<const char*>(payload_start), payload_len);
+ msg.is_text = opcode == kOpcodeText;
+ req_handler_->OnWebsocketMessage(msg);
+ } else if (opcode == kOpcodeClose) {
+ conn->Close();
+ } else {
+ PERFETTO_LOG("Unsupported WebSocket opcode: %d", opcode);
+ }
+ return static_cast<size_t>(rd - rxbuf) + payload_len;
+}
+
+void HttpServerConnection::SendResponseHeaders(
+ const char* http_code,
+ std::initializer_list<const char*> headers,
+ size_t content_length) {
+ PERFETTO_CHECK(!headers_sent_);
+ PERFETTO_CHECK(!is_websocket_);
+ headers_sent_ = true;
+ std::vector<char> resp_hdr;
+ resp_hdr.reserve(512);
+ bool has_connection_header = false;
+
+ auto append = [&resp_hdr](const char* str) {
+ resp_hdr.insert(resp_hdr.end(), str, str + strlen(str));
+ };
+
+ append("HTTP/1.1 ");
+ append(http_code);
+ append("\r\n");
+ for (const char* hdr_cstr : headers) {
+ StringView hdr = (hdr_cstr);
+ if (hdr.empty())
+ continue;
+ has_connection_header |= hdr.substr(0, 11).CaseInsensitiveEq("connection:");
+ append(hdr_cstr);
+ append("\r\n");
+ }
+ content_len_actual_ = 0;
+ content_len_headers_ = content_length;
+ if (content_length != kOmitContentLength) {
+ append("Content-Length: ");
+ append(std::to_string(content_length).c_str());
+ append("\r\n");
+ }
+ if (!has_connection_header) {
+ // Various clients (e.g., python's http.client) assume that a HTTP
+ // connection is keep-alive if the server says nothing, even when they do
+ // NOT ask for it. Hence we must be explicit. If we are about to close the
+ // connection, we must say so.
+ append(keepalive_ ? "Connection: keep-alive\r\n" : "Connection: close\r\n");
+ }
+ if (!origin_allowed_.empty()) {
+ append("Access-Control-Allow-Origin: ");
+ append(origin_allowed_.c_str());
+ append("\r\n");
+ append("Vary: Origin\r\n");
+ }
+ append("\r\n"); // End-of-headers marker.
+ sock->Send(resp_hdr.data(),
+ resp_hdr.size()); // Send response headers.
+}
+
+void HttpServerConnection::SendResponseBody(const void* data, size_t len) {
+ PERFETTO_CHECK(!is_websocket_);
+ if (data == nullptr) {
+ PERFETTO_DCHECK(len == 0);
+ return;
+ }
+ content_len_actual_ += len;
+ PERFETTO_CHECK(content_len_actual_ <= content_len_headers_ ||
+ content_len_headers_ == kOmitContentLength);
+ sock->Send(data, len);
+}
+
+void HttpServerConnection::Close() {
+ sock->Shutdown(/*notify=*/true);
+}
+
+void HttpServerConnection::SendResponse(
+ const char* http_code,
+ std::initializer_list<const char*> headers,
+ StringView content,
+ bool force_close) {
+ if (force_close)
+ keepalive_ = false;
+ SendResponseHeaders(http_code, headers, content.size());
+ SendResponseBody(content.data(), content.size());
+ if (!keepalive_)
+ Close();
+}
+
+void HttpServerConnection::SendWebsocketMessage(const void* data, size_t len) {
+ SendWebsocketFrame(kOpcodeBinary, data, len);
+}
+
+void HttpServerConnection::SendWebsocketFrame(uint8_t opcode,
+ const void* payload,
+ size_t payload_len) {
+ PERFETTO_CHECK(is_websocket_);
+
+ uint8_t hdr[10]{};
+ uint32_t hdr_len = 0;
+
+ hdr[0] = opcode | 0x80 /* FIN=1, no fragmentation */;
+ if (payload_len < 126) {
+ hdr_len = 2;
+ hdr[1] = static_cast<uint8_t>(payload_len);
+ } else if (payload_len < 0xffff) {
+ hdr_len = 4;
+ hdr[1] = 126; // Special value: Header extends for 2 bytes.
+ uint16_t len_be = HostToBE16(static_cast<uint16_t>(payload_len));
+ memcpy(&hdr[2], &len_be, sizeof(len_be));
+ } else {
+ hdr_len = 10;
+ hdr[1] = 127; // Special value: Header extends for 4 bytes.
+ uint64_t len_be = HostToBE64(payload_len);
+ memcpy(&hdr[2], &len_be, sizeof(len_be));
+ }
+
+ sock->Send(hdr, hdr_len);
+ if (payload && payload_len > 0)
+ sock->Send(payload, payload_len);
+}
+
+HttpServerConnection::HttpServerConnection(std::unique_ptr<UnixSocket> s)
+ : sock(std::move(s)), rxbuf(PagedMemory::Allocate(kMaxRequestSize)) {}
+
+HttpServerConnection::~HttpServerConnection() = default;
+
+Optional<StringView> HttpRequest::GetHeader(StringView name) const {
+ for (size_t i = 0; i < num_headers; i++) {
+ if (headers[i].name.CaseInsensitiveEq(name))
+ return headers[i].value;
+ }
+ return nullopt;
+}
+
+HttpRequestHandler::~HttpRequestHandler() = default;
+void HttpRequestHandler::OnWebsocketMessage(const WebsocketMessage&) {}
+void HttpRequestHandler::OnHttpConnectionClosed(HttpServerConnection*) {}
+
+} // namespace base
+} // namespace perfetto
diff --git a/src/base/http/http_server_unittest.cc b/src/base/http/http_server_unittest.cc
new file mode 100644
index 000000000..be651989d
--- /dev/null
+++ b/src/base/http/http_server_unittest.cc
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/ext/base/http/http_server.h"
+
+#include <initializer_list>
+#include <string>
+
+#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/unix_socket.h"
+#include "src/base/test/test_task_runner.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace base {
+namespace {
+
+using testing::_;
+using testing::Invoke;
+using testing::InvokeWithoutArgs;
+using testing::NiceMock;
+
+constexpr int kTestPort = 5127; // Chosen with a fair dice roll.
+
+class MockHttpHandler : public HttpRequestHandler {
+ public:
+ MOCK_METHOD1(OnHttpRequest, void(const HttpRequest&));
+ MOCK_METHOD1(OnHttpConnectionClosed, void(HttpServerConnection*));
+ MOCK_METHOD1(OnWebsocketMessage, void(const WebsocketMessage&));
+};
+
+class HttpCli {
+ public:
+ explicit HttpCli(TestTaskRunner* ttr) : task_runner_(ttr) {
+ sock = UnixSocketRaw::CreateMayFail(SockFamily::kInet, SockType::kStream);
+ sock.SetBlocking(true);
+ sock.Connect("127.0.0.1:" + std::to_string(kTestPort));
+ }
+
+ void SendHttpReq(std::initializer_list<std::string> headers,
+ const std::string& body = "") {
+ for (auto& header : headers)
+ sock.SendStr(header + "\r\n");
+ if (!body.empty())
+ sock.SendStr("Content-Length: " + std::to_string(body.size()) + "\r\n");
+ sock.SendStr("\r\n");
+ sock.SendStr(body);
+ }
+
+ std::string Recv(size_t min_bytes) {
+ static int n = 0;
+ auto checkpoint_name = "rx_" + std::to_string(n++);
+ auto checkpoint = task_runner_->CreateCheckpoint(checkpoint_name);
+ std::string rxbuf;
+ sock.SetBlocking(false);
+ task_runner_->AddFileDescriptorWatch(sock.watch_handle(), [&] {
+ char buf[1024]{};
+ auto rsize = PERFETTO_EINTR(sock.Receive(buf, sizeof(buf)));
+ if (rsize < 0)
+ return;
+ rxbuf.append(buf, static_cast<size_t>(rsize));
+ if (rsize == 0 || (min_bytes && rxbuf.length() >= min_bytes))
+ checkpoint();
+ });
+ task_runner_->RunUntilCheckpoint(checkpoint_name);
+ task_runner_->RemoveFileDescriptorWatch(sock.watch_handle());
+ return rxbuf;
+ }
+
+ std::string RecvAndWaitConnClose() { return Recv(0); }
+
+ TestTaskRunner* task_runner_;
+ UnixSocketRaw sock;
+};
+
+class HttpServerTest : public ::testing::Test {
+ public:
+ HttpServerTest() : srv_(&task_runner_, &handler_) { srv_.Start(kTestPort); }
+
+ TestTaskRunner task_runner_;
+ MockHttpHandler handler_;
+ HttpServer srv_;
+};
+
+TEST_F(HttpServerTest, GET) {
+ const int kIterations = 3;
+ EXPECT_CALL(handler_, OnHttpRequest(_))
+ .Times(kIterations)
+ .WillRepeatedly(Invoke([](const HttpRequest& req) {
+ EXPECT_EQ(req.uri.ToStdString(), "/foo/bar");
+ EXPECT_EQ(req.method.ToStdString(), "GET");
+ EXPECT_EQ(req.origin.ToStdString(), "https://example.com");
+ EXPECT_EQ("42",
+ req.GetHeader("X-header").value_or("N/A").ToStdString());
+ EXPECT_EQ("foo",
+ req.GetHeader("X-header2").value_or("N/A").ToStdString());
+ EXPECT_FALSE(req.is_websocket_handshake);
+ req.conn->SendResponseAndClose("200 OK", {}, "<html>");
+ }));
+ EXPECT_CALL(handler_, OnHttpConnectionClosed(_)).Times(kIterations);
+
+ for (int i = 0; i < 3; i++) {
+ HttpCli cli(&task_runner_);
+ cli.SendHttpReq(
+ {
+ "GET /foo/bar HTTP/1.1", //
+ "Origin: https://example.com", //
+ "X-header: 42", //
+ "X-header2: foo", //
+ },
+ "");
+ EXPECT_EQ(cli.RecvAndWaitConnClose(),
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 6\r\n"
+ "Connection: close\r\n"
+ "\r\n<html>");
+ }
+}
+
+TEST_F(HttpServerTest, GET_404) {
+ HttpCli cli(&task_runner_);
+ EXPECT_CALL(handler_, OnHttpRequest(_))
+ .WillOnce(Invoke([&](const HttpRequest& req) {
+ EXPECT_EQ(req.uri.ToStdString(), "/404");
+ EXPECT_EQ(req.method.ToStdString(), "GET");
+ req.conn->SendResponseAndClose("404 Not Found");
+ }));
+ cli.SendHttpReq({"GET /404 HTTP/1.1"}, "");
+ EXPECT_CALL(handler_, OnHttpConnectionClosed(_));
+ EXPECT_EQ(cli.RecvAndWaitConnClose(),
+ "HTTP/1.1 404 Not Found\r\n"
+ "Content-Length: 0\r\n"
+ "Connection: close\r\n"
+ "\r\n");
+}
+
+TEST_F(HttpServerTest, POST) {
+ HttpCli cli(&task_runner_);
+
+ EXPECT_CALL(handler_, OnHttpRequest(_))
+ .WillOnce(Invoke([&](const HttpRequest& req) {
+ EXPECT_EQ(req.uri.ToStdString(), "/rpc");
+ EXPECT_EQ(req.method.ToStdString(), "POST");
+ EXPECT_EQ(req.origin.ToStdString(), "https://example.com");
+ EXPECT_EQ("foo", req.GetHeader("X-1").value_or("N/A").ToStdString());
+ EXPECT_EQ(req.body.ToStdString(), "the\r\npost\nbody\r\n\r\n");
+ req.conn->SendResponseAndClose("200 OK");
+ }));
+
+ cli.SendHttpReq(
+ {"POST /rpc HTTP/1.1", "Origin: https://example.com", "X-1: foo"},
+ "the\r\npost\nbody\r\n\r\n");
+ EXPECT_CALL(handler_, OnHttpConnectionClosed(_));
+ EXPECT_EQ(cli.RecvAndWaitConnClose(),
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 0\r\n"
+ "Connection: close\r\n"
+ "\r\n");
+}
+
+// An unhandled request should cause a HTTP 500.
+TEST_F(HttpServerTest, Unhadled_500) {
+ HttpCli cli(&task_runner_);
+ EXPECT_CALL(handler_, OnHttpRequest(_));
+ cli.SendHttpReq({"GET /unhandled HTTP/1.1"});
+ EXPECT_CALL(handler_, OnHttpConnectionClosed(_));
+ EXPECT_EQ(cli.RecvAndWaitConnClose(),
+ "HTTP/1.1 500 Internal Server Error\r\n"
+ "Content-Length: 0\r\n"
+ "Connection: close\r\n"
+ "\r\n");
+}
+
+// Send three requests within the same keepalive connection.
+TEST_F(HttpServerTest, POST_Keepalive) {
+ HttpCli cli(&task_runner_);
+ static const int kNumRequests = 3;
+ int req_num = 0;
+ EXPECT_CALL(handler_, OnHttpConnectionClosed(_)).Times(1);
+ EXPECT_CALL(handler_, OnHttpRequest(_))
+ .Times(3)
+ .WillRepeatedly(Invoke([&](const HttpRequest& req) {
+ EXPECT_EQ(req.uri.ToStdString(), "/" + std::to_string(req_num));
+ EXPECT_EQ(req.method.ToStdString(), "POST");
+ EXPECT_EQ(req.body.ToStdString(), "body" + std::to_string(req_num));
+ req.conn->SendResponseHeaders("200 OK");
+ if (++req_num == kNumRequests)
+ req.conn->Close();
+ }));
+
+ for (int i = 0; i < kNumRequests; i++) {
+ auto i_str = std::to_string(i);
+ cli.SendHttpReq({"POST /" + i_str + " HTTP/1.1", "Connection: keep-alive"},
+ "body" + i_str);
+ }
+
+ std::string expected_response;
+ for (int i = 0; i < kNumRequests; i++) {
+ expected_response +=
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 0\r\n"
+ "Connection: keep-alive\r\n"
+ "\r\n";
+ }
+ EXPECT_EQ(cli.RecvAndWaitConnClose(), expected_response);
+}
+
+TEST_F(HttpServerTest, Websocket) {
+ srv_.AddAllowedOrigin("http://foo.com");
+ srv_.AddAllowedOrigin("http://websocket.com");
+ for (int rep = 0; rep < 3; rep++) {
+ HttpCli cli(&task_runner_);
+ EXPECT_CALL(handler_, OnHttpRequest(_))
+ .WillOnce(Invoke([&](const HttpRequest& req) {
+ EXPECT_EQ(req.uri.ToStdString(), "/websocket");
+ EXPECT_EQ(req.method.ToStdString(), "GET");
+ EXPECT_EQ(req.origin.ToStdString(), "http://websocket.com");
+ EXPECT_TRUE(req.is_websocket_handshake);
+ req.conn->UpgradeToWebsocket(req);
+ }));
+
+ cli.SendHttpReq({
+ "GET /websocket HTTP/1.1", //
+ "Origin: http://websocket.com", //
+ "Connection: upgrade", //
+ "Upgrade: websocket", //
+ "Sec-WebSocket-Version: 13", //
+ "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==", //
+ });
+ std::string expected_resp =
+ "HTTP/1.1 101 Switching Protocols\r\n"
+ "Upgrade: websocket\r\n"
+ "Connection: Upgrade\r\n"
+ "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
+ "Access-Control-Allow-Origin: http://websocket.com\r\n"
+ "Vary: Origin\r\n"
+ "\r\n";
+ EXPECT_EQ(cli.Recv(expected_resp.size()), expected_resp);
+
+ for (int i = 0; i < 3; i++) {
+ EXPECT_CALL(handler_, OnWebsocketMessage(_))
+ .WillOnce(Invoke([i](const WebsocketMessage& msg) {
+ EXPECT_EQ(msg.data.ToStdString(), "test message");
+ StackString<6> resp("PONG%d", i);
+ msg.conn->SendWebsocketMessage(resp.c_str(), resp.len());
+ }));
+
+ // A frame from a real tcpdump capture:
+ // 1... .... = Fin: True
+ // .000 .... = Reserved: 0x0
+ // .... 0001 = Opcode: Text (1)
+ // 1... .... = Mask: True
+ // .000 1100 = Payload length: 12
+ // Masking-Key: e17e8eb9
+ // Masked payload: "test message"
+ cli.sock.SendStr(
+ "\x81\x8c\xe1\x7e\x8e\xb9\x95\x1b\xfd\xcd\xc1\x13\xeb\xca\x92\x1f\xe9"
+ "\xdc");
+ EXPECT_EQ(cli.Recv(2 + 5), "\x82\x05PONG" + std::to_string(i));
+ }
+
+ cli.sock.Shutdown();
+ auto checkpoint_name = "ws_close_" + std::to_string(rep);
+ auto ws_close = task_runner_.CreateCheckpoint(checkpoint_name);
+ EXPECT_CALL(handler_, OnHttpConnectionClosed(_))
+ .WillOnce(InvokeWithoutArgs(ws_close));
+ task_runner_.RunUntilCheckpoint(checkpoint_name);
+ }
+}
+
+TEST_F(HttpServerTest, Websocket_OriginNotAllowed) {
+ srv_.AddAllowedOrigin("http://websocket.com");
+ srv_.AddAllowedOrigin("http://notallowed.commando");
+ srv_.AddAllowedOrigin("http://iamnotallowed.com");
+ srv_.AddAllowedOrigin("iamnotallowed.com");
+ // The origin must match in full, including scheme. This won't match.
+ srv_.AddAllowedOrigin("notallowed.com");
+
+ HttpCli cli(&task_runner_);
+ auto close_checkpoint = task_runner_.CreateCheckpoint("close");
+ EXPECT_CALL(handler_, OnHttpConnectionClosed(_))
+ .WillOnce(InvokeWithoutArgs(close_checkpoint));
+ EXPECT_CALL(handler_, OnHttpRequest(_))
+ .WillOnce(Invoke([&](const HttpRequest& req) {
+ EXPECT_EQ(req.origin.ToStdString(), "http://notallowed.com");
+ EXPECT_TRUE(req.is_websocket_handshake);
+ req.conn->UpgradeToWebsocket(req);
+ }));
+
+ cli.SendHttpReq({
+ "GET /websocket HTTP/1.1", //
+ "Origin: http://notallowed.com", //
+ "Connection: upgrade", //
+ "Upgrade: websocket", //
+ "Sec-WebSocket-Version: 13", //
+ "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==", //
+ });
+ std::string expected_resp =
+ "HTTP/1.1 403 Forbidden\r\n"
+ "Content-Length: 18\r\n"
+ "Connection: close\r\n"
+ "\r\n"
+ "Origin not allowed";
+
+ EXPECT_EQ(cli.Recv(expected_resp.size()), expected_resp);
+ cli.sock.Shutdown();
+ task_runner_.RunUntilCheckpoint("close");
+}
+
+} // namespace
+} // namespace base
+} // namespace perfetto
diff --git a/src/base/http/sha1.cc b/src/base/http/sha1.cc
new file mode 100644
index 000000000..f3e1e5d54
--- /dev/null
+++ b/src/base/http/sha1.cc
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "perfetto/ext/base/http/sha1.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+// From chrome_elf/sha1/sha1.cc.
+
+namespace perfetto {
+namespace base {
+
+namespace {
+
+inline uint32_t BSwap32(uint32_t x) {
+#if defined(__GNUC__)
+ return __builtin_bswap32(x);
+#elif defined(_MSC_VER)
+ return _byteswap_ulong(x);
+#else
+ return (((x & 0xff000000u) >> 24) | ((x & 0x00ff0000u) >> 8) |
+ ((x & 0x0000ff00u) << 8) | ((x & 0x000000ffu) << 24));
+#endif
+}
+
+// Usage example:
+//
+// SecureHashAlgorithm sha;
+// while(there is data to hash)
+// sha.Update(moredata, size of data);
+// sha.Final();
+// memcpy(somewhere, sha.Digest(), 20);
+//
+// to reuse the instance of sha, call sha.Init();
+class SecureHashAlgorithm {
+ public:
+ SecureHashAlgorithm() { Init(); }
+
+ void Init();
+ void Update(const void* data, size_t nbytes);
+ void Final();
+
+ // 20 bytes of message digest.
+ const unsigned char* Digest() const {
+ return reinterpret_cast<const unsigned char*>(H);
+ }
+
+ private:
+ void Pad();
+ void Process();
+
+ uint32_t A, B, C, D, E;
+
+ uint32_t H[5];
+
+ union {
+ uint32_t W[80];
+ uint8_t M[64];
+ };
+
+ uint32_t cursor;
+ uint64_t l;
+};
+
+//------------------------------------------------------------------------------
+// Private functions
+//------------------------------------------------------------------------------
+
+// Identifier names follow notation in FIPS PUB 180-3, where you'll
+// also find a description of the algorithm:
+// http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf
+
+inline uint32_t f(uint32_t t, uint32_t B, uint32_t C, uint32_t D) {
+ if (t < 20) {
+ return (B & C) | ((~B) & D);
+ } else if (t < 40) {
+ return B ^ C ^ D;
+ } else if (t < 60) {
+ return (B & C) | (B & D) | (C & D);
+ } else {
+ return B ^ C ^ D;
+ }
+}
+
+inline uint32_t S(uint32_t n, uint32_t X) {
+ return (X << n) | (X >> (32 - n));
+}
+
+inline uint32_t K(uint32_t t) {
+ if (t < 20) {
+ return 0x5a827999;
+ } else if (t < 40) {
+ return 0x6ed9eba1;
+ } else if (t < 60) {
+ return 0x8f1bbcdc;
+ } else {
+ return 0xca62c1d6;
+ }
+}
+
+void SecureHashAlgorithm::Init() {
+ A = 0;
+ B = 0;
+ C = 0;
+ D = 0;
+ E = 0;
+ cursor = 0;
+ l = 0;
+ H[0] = 0x67452301;
+ H[1] = 0xefcdab89;
+ H[2] = 0x98badcfe;
+ H[3] = 0x10325476;
+ H[4] = 0xc3d2e1f0;
+}
+
+void SecureHashAlgorithm::Update(const void* data, size_t nbytes) {
+ const uint8_t* d = reinterpret_cast<const uint8_t*>(data);
+ while (nbytes--) {
+ M[cursor++] = *d++;
+ if (cursor >= 64)
+ Process();
+ l += 8;
+ }
+}
+
+void SecureHashAlgorithm::Final() {
+ Pad();
+ Process();
+
+ for (size_t t = 0; t < 5; ++t)
+ H[t] = BSwap32(H[t]);
+}
+
+void SecureHashAlgorithm::Process() {
+ uint32_t t;
+
+ // Each a...e corresponds to a section in the FIPS 180-3 algorithm.
+
+ // a.
+ //
+ // W and M are in a union, so no need to memcpy.
+ // memcpy(W, M, sizeof(M));
+ for (t = 0; t < 16; ++t)
+ W[t] = BSwap32(W[t]);
+
+ // b.
+ for (t = 16; t < 80; ++t)
+ W[t] = S(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]);
+
+ // c.
+ A = H[0];
+ B = H[1];
+ C = H[2];
+ D = H[3];
+ E = H[4];
+
+ // d.
+ for (t = 0; t < 80; ++t) {
+ uint32_t TEMP = S(5, A) + f(t, B, C, D) + E + W[t] + K(t);
+ E = D;
+ D = C;
+ C = S(30, B);
+ B = A;
+ A = TEMP;
+ }
+
+ // e.
+ H[0] += A;
+ H[1] += B;
+ H[2] += C;
+ H[3] += D;
+ H[4] += E;
+
+ cursor = 0;
+}
+
+void SecureHashAlgorithm::Pad() {
+ M[cursor++] = 0x80;
+
+ if (cursor > 64 - 8) {
+ // pad out to next block
+ while (cursor < 64)
+ M[cursor++] = 0;
+
+ Process();
+ }
+
+ while (cursor < 64 - 8)
+ M[cursor++] = 0;
+
+ M[cursor++] = (l >> 56) & 0xff;
+ M[cursor++] = (l >> 48) & 0xff;
+ M[cursor++] = (l >> 40) & 0xff;
+ M[cursor++] = (l >> 32) & 0xff;
+ M[cursor++] = (l >> 24) & 0xff;
+ M[cursor++] = (l >> 16) & 0xff;
+ M[cursor++] = (l >> 8) & 0xff;
+ M[cursor++] = l & 0xff;
+}
+
+// Computes the SHA-1 hash of the |len| bytes in |data| and puts the hash
+// in |hash|. |hash| must be kSHA1Length bytes long.
+void SHA1HashBytes(const unsigned char* data, size_t len, unsigned char* hash) {
+ SecureHashAlgorithm sha;
+ sha.Update(data, len);
+ sha.Final();
+
+ ::memcpy(hash, sha.Digest(), kSHA1Length);
+}
+
+} // namespace
+
+//------------------------------------------------------------------------------
+// Public functions
+//------------------------------------------------------------------------------
+SHA1Digest SHA1Hash(const void* data, size_t size) {
+ SHA1Digest digest;
+ SHA1HashBytes(static_cast<const unsigned char*>(data), size,
+ reinterpret_cast<unsigned char*>(&digest[0]));
+ return digest;
+}
+
+SHA1Digest SHA1Hash(const std::string& str) {
+ return SHA1Hash(str.data(), str.size());
+}
+
+} // namespace base
+} // namespace perfetto
diff --git a/src/base/http/sha1_unittest.cc b/src/base/http/sha1_unittest.cc
new file mode 100644
index 000000000..269afc1ee
--- /dev/null
+++ b/src/base/http/sha1_unittest.cc
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/ext/base/http/sha1.h"
+
+#include <string>
+
+#include "perfetto/ext/base/string_view.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace base {
+namespace {
+
+using testing::ElementsAreArray;
+
+TEST(SHA1Test, Hash) {
+ EXPECT_THAT(SHA1Hash(""), ElementsAreArray<uint8_t>(
+ {0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b,
+ 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60,
+ 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09}));
+
+ EXPECT_THAT(SHA1Hash("abc"), ElementsAreArray<uint8_t>(
+ {0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81,
+ 0x6a, 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50,
+ 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d}));
+
+ EXPECT_THAT(
+ SHA1Hash("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"),
+ ElementsAreArray<uint8_t>({0x84, 0x98, 0x3e, 0x44, 0x1c, 0x3b, 0xd2,
+ 0x6e, 0xba, 0xae, 0x4a, 0xa1, 0xf9, 0x51,
+ 0x29, 0xe5, 0xe5, 0x46, 0x70, 0xf1}));
+
+ EXPECT_THAT(
+ SHA1Hash(std::string(1000000, 'a')),
+ ElementsAreArray<uint8_t>({0x34, 0xaa, 0x97, 0x3c, 0xd4, 0xc4, 0xda,
+ 0xa4, 0xf6, 0x1e, 0xeb, 0x2b, 0xdb, 0xad,
+ 0x27, 0x31, 0x65, 0x34, 0x01, 0x6f}));
+}
+
+} // namespace
+} // namespace base
+} // namespace perfetto
diff --git a/src/base/log_ring_buffer.h b/src/base/log_ring_buffer.h
new file mode 100644
index 000000000..43a06ab15
--- /dev/null
+++ b/src/base/log_ring_buffer.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_BASE_LOG_RING_BUFFER_H_
+#define SRC_BASE_LOG_RING_BUFFER_H_
+
+#include <stddef.h>
+#include <stdio.h>
+
+#include <array>
+#include <atomic>
+
+#include "perfetto/ext/base/string_view.h"
+#include "perfetto/ext/base/thread_annotations.h"
+
+namespace perfetto {
+namespace base {
+
+// Defined out of line because a static constexpr requires static storage if
+// ODR-used, not worth adding a .cc file just for tests.
+constexpr size_t kLogRingBufEntries = 8;
+constexpr size_t kLogRingBufMsgLen = 256;
+
+// A static non-allocating ring-buffer to hold the most recent log events.
+// This class is really an implementation detail of logging.cc. The only reason
+// why is fully defined in a dedicated header is for allowing unittesting,
+// without leaking extra headers into logging.h (which is a high-fanout header).
+// This is used to report the last logs in a crash report when a CHECK/FATAL
+// is encountered.
+// This class has just an Append() method to insert events into the buffer and
+// a Read() to read the events in FIFO order. Read() is non-destructive.
+//
+// Thread safety considerations:
+// - The Append() method can be called concurrently by several threads, unless
+// there are > kLogRingBufEntries concurrent threads. Even if that happens,
+// case some events will contain a mix of strings but the behavior of
+// futher Append() and Read() is still defined.
+// - The Read() method is not thread safe but it's fine in practice. Even if
+// it's called concurrently with other Append(), it only causes some partial
+// events to be emitted in output.
+// In both cases, we never rely purely on \0, all operations are size-bound.
+//
+// See logging_unittest.cc for tests.
+class LogRingBuffer {
+ public:
+ LogRingBuffer() = default;
+ LogRingBuffer(const LogRingBuffer&) = delete;
+ LogRingBuffer& operator=(const LogRingBuffer&) = delete;
+ LogRingBuffer(LogRingBuffer&&) = delete;
+ LogRingBuffer& operator=(LogRingBuffer&&) = delete;
+
+ // This takes three arguments because it fits its only caller (logging.cc).
+ // The args are just concatenated together (plus one space before the msg).
+ void Append(StringView tstamp, StringView source, StringView log_msg) {
+ // Reserve atomically a slot in the ring buffer, so any concurrent Append()
+ // won't overlap (unless too many concurrent Append() happen together).
+ // There is no strict synchronization here, |event_slot_| is atomic only for
+ // the sake of avoiding colliding on the same slot but does NOT guarantee
+ // full consistency and integrity of the log messages written in each slot.
+ // A release-store (or acq+rel) won't be enough for full consistency. Two
+ // threads that race on Append() and take the N+1 and N+2 slots could finish
+ // the write in reverse order. So Read() would need to synchronize with
+ // something else (either a per-slot atomic flag or with a second atomic
+ // counter which is incremented after the snprintf). Both options increase
+ // the cost of Append() with no huge benefits (90% of the perfetto services
+ // where we use it is single thread, and the log ring buffer is disabled
+ // on non-standalone builds like the SDK).
+ uint32_t slot = event_slot_.fetch_add(1, std::memory_order_relaxed);
+ slot = slot % kLogRingBufEntries;
+
+ char* const msg = events_[slot];
+ PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(msg, kLogRingBufMsgLen,
+ "see comments in log_ring_buffer.h")
+ snprintf(msg, kLogRingBufMsgLen, "%.*s%.*s %.*s",
+ static_cast<int>(tstamp.size()), tstamp.data(),
+ static_cast<int>(source.size()), source.data(),
+ static_cast<int>(log_msg.size()), log_msg.data());
+ }
+
+ // Reads back the buffer in FIFO order, up to |len - 1| characters at most
+ // (the -1 is because a NUL terminator is always appended, unless |len| == 0).
+ // The string written in |dst| is guaranteed to be NUL-terminated, even if
+ // |len| < buffer contents length.
+ // Returns the number of bytes written in output, excluding the \0 terminator.
+ size_t Read(char* dst, size_t len) {
+ if (len == 0)
+ return 0;
+ // This is a relaxed-load because we don't need to fully synchronize on the
+ // writing path for the reasons described in the fetch_add() above.
+ const uint32_t event_slot = event_slot_.load(std::memory_order_relaxed);
+ size_t dst_written = 0;
+ for (uint32_t pos = 0; pos < kLogRingBufEntries; ++pos) {
+ const uint32_t slot = (event_slot + pos) % kLogRingBufEntries;
+ const char* src = events_[slot];
+ if (*src == '\0')
+ continue; // Empty slot. Skip.
+ char* const wptr = dst + dst_written;
+ // |src| might not be null terminated. This can happen if some
+ // thread-race happened. Limit the copy length.
+ const size_t limit = std::min(len - dst_written, kLogRingBufMsgLen);
+ for (size_t i = 0; i < limit; ++i) {
+ const char c = src[i];
+ ++dst_written;
+ if (c == '\0' || i == limit - 1) {
+ wptr[i] = '\n';
+ break;
+ }
+ // Skip non-printable ASCII characters to avoid confusing crash reports.
+ // Note that this deliberately mangles \n. Log messages should not have
+ // a \n in the middle and are NOT \n terminated. The trailing \n between
+ // each line is appended by the if () branch above.
+ const bool is_printable = c >= ' ' && c <= '~';
+ wptr[i] = is_printable ? c : '?';
+ }
+ }
+ // Ensure that the output string is null-terminated.
+ PERFETTO_DCHECK(dst_written <= len);
+ if (dst_written == len) {
+ // In case of truncation we replace the last char with \0. But the return
+ // value is the number of chars without \0, hence the --.
+ dst[--dst_written] = '\0';
+ } else {
+ dst[dst_written] = '\0';
+ }
+ return dst_written;
+ }
+
+ private:
+ using EventBuf = char[kLogRingBufMsgLen];
+ EventBuf events_[kLogRingBufEntries]{};
+
+ static_assert((kLogRingBufEntries & (kLogRingBufEntries - 1)) == 0,
+ "kLogRingBufEntries must be a power of two");
+
+ // A monotonically increasing counter incremented on each event written.
+ // It determines which of the kLogRingBufEntries indexes in |events_| should
+ // be used next.
+ // It grows >> kLogRingBufEntries, it's supposed to be always used
+ // mod(kLogRingBufEntries). A static_assert in the .cc file ensures that
+ // kLogRingBufEntries is a power of two so wraps are aligned.
+ std::atomic<uint32_t> event_slot_{};
+};
+
+} // namespace base
+} // namespace perfetto
+
+#endif // SRC_BASE_LOG_RING_BUFFER_H_
diff --git a/src/base/logging.cc b/src/base/logging.cc
index 5b251d63a..7f5460585 100644
--- a/src/base/logging.cc
+++ b/src/base/logging.cc
@@ -26,7 +26,16 @@
#include <atomic>
#include <memory>
+#include "perfetto/base/build_config.h"
#include "perfetto/base/time.h"
+#include "perfetto/ext/base/crash_keys.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/string_view.h"
+#include "src/base/log_ring_buffer.h"
+
+#if PERFETTO_ENABLE_LOG_RING_BUFFER() && PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <android/set_abort_message.h>
+#endif
namespace perfetto {
namespace base {
@@ -41,6 +50,28 @@ const char kLightGray[] = "\x1b[90m";
std::atomic<LogMessageCallback> g_log_callback{};
+#if PERFETTO_BUILDFLAG(PERFETTO_STDERR_CRASH_DUMP)
+// __attribute__((constructor)) causes a static initializer that automagically
+// early runs this function before the main().
+void PERFETTO_EXPORT __attribute__((constructor)) InitDebugCrashReporter() {
+ // This function is defined in debug_crash_stack_trace.cc.
+ // The dynamic initializer is in logging.cc because logging.cc is included
+ // in virtually any target that depends on base. Having it in
+ // debug_crash_stack_trace.cc would require figuring out -Wl,whole-archive
+ // which is not worth it.
+ EnableStacktraceOnCrashForDebug();
+}
+#endif
+
+#if PERFETTO_ENABLE_LOG_RING_BUFFER()
+LogRingBuffer g_log_ring_buffer{};
+
+// This is global to avoid allocating memory or growing too much the stack
+// in MaybeSerializeLastLogsForCrashReporting(), which is called from
+// arbitrary code paths hitting PERFETTO_CHECK()/FATAL().
+char g_crash_buf[kLogRingBufEntries * kLogRingBufMsgLen];
+#endif
+
} // namespace
void SetLogMessageCallback(LogMessageCallback callback) {
@@ -55,6 +86,7 @@ void LogMessage(LogLev level,
char stack_buf[512];
std::unique_ptr<char[]> large_buf;
char* log_msg = &stack_buf[0];
+ size_t log_msg_len = 0;
// By default use a stack allocated buffer because most log messages are quite
// short. In rare cases they can be larger (e.g. --help). In those cases we
@@ -69,14 +101,18 @@ void LogMessage(LogLev level,
// it. The code below will attach the filename and line, which is still
// useful.
if (res < 0) {
- strncpy(log_msg, "[printf format error]", max_len);
+ snprintf(log_msg, max_len, "%s", "[printf format error]");
break;
}
// if res == max_len, vsnprintf saturated the input buffer. Retry with a
// larger buffer in that case (within reasonable limits).
- if (res < static_cast<int>(max_len) || max_len >= 128 * 1024)
+ if (res < static_cast<int>(max_len) || max_len >= 128 * 1024) {
+ // In case of truncation vsnprintf returns the len that "would have been
+ // written if the string was longer", not the actual chars written.
+ log_msg_len = std::min(static_cast<size_t>(res), max_len - 1);
break;
+ }
max_len *= 4;
large_buf.reset(new char[max_len]);
log_msg = &large_buf[0];
@@ -104,8 +140,9 @@ void LogMessage(LogLev level,
break;
}
-#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
- !PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
+ !PERFETTO_BUILDFLAG(PERFETTO_OS_WASM) && \
+ !PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
static const bool use_colors = isatty(STDERR_FILENO);
#else
static const bool use_colors = false;
@@ -113,44 +150,85 @@ void LogMessage(LogLev level,
// Formats file.cc:line as a space-padded fixed width string. If the file name
// |fname| is too long, truncate it on the left-hand side.
- char line_str[10];
- size_t line_len =
- static_cast<size_t>(snprintf(line_str, sizeof(line_str), "%d", line));
+ StackString<10> line_str("%d", line);
// 24 will be the width of the file.cc:line column in the log event.
- char file_and_line[24];
+ static constexpr size_t kMaxNameAndLine = 24;
size_t fname_len = strlen(fname);
- size_t fname_max = sizeof(file_and_line) - line_len - 2; // 2 = ':' + '\0'.
+ size_t fname_max = kMaxNameAndLine - line_str.len() - 2; // 2 = ':' + '\0'.
size_t fname_offset = fname_len <= fname_max ? 0 : fname_len - fname_max;
- int len = snprintf(file_and_line, sizeof(file_and_line), "%s:%s",
- fname + fname_offset, line_str);
- memset(&file_and_line[len], ' ', sizeof(file_and_line) - size_t(len));
- file_and_line[sizeof(file_and_line) - 1] = '\0';
+ StackString<kMaxNameAndLine> file_and_line(
+ "%*s:%s", static_cast<int>(fname_max), &fname[fname_offset],
+ line_str.c_str());
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
// Logcat has already timestamping, don't re-emit it.
__android_log_print(ANDROID_LOG_DEBUG + level, "perfetto", "%s %s",
- file_and_line, log_msg);
+ file_and_line.c_str(), log_msg);
#endif
// When printing on stderr, print also the timestamp. We don't really care
// about the actual time. We just need some reference clock that can be used
// to correlated events across differrent processses (e.g. traced and
// traced_probes). The wall time % 1000 is good enough.
- char timestamp[32];
uint32_t t_ms = static_cast<uint32_t>(GetWallTimeMs().count());
uint32_t t_sec = t_ms / 1000;
t_ms -= t_sec * 1000;
t_sec = t_sec % 1000;
- snprintf(timestamp, sizeof(timestamp), "[%03u.%03u] ", t_sec, t_ms);
+ StackString<32> timestamp("[%03u.%03u] ", t_sec, t_ms);
if (use_colors) {
- fprintf(stderr, "%s%s%s%s %s%s%s\n", kLightGray, timestamp, file_and_line,
- kReset, color, log_msg, kReset);
+ fprintf(stderr, "%s%s%s%s %s%s%s\n", kLightGray, timestamp.c_str(),
+ file_and_line.c_str(), kReset, color, log_msg, kReset);
} else {
- fprintf(stderr, "%s%s %s\n", timestamp, file_and_line, log_msg);
+ fprintf(stderr, "%s%s %s\n", timestamp.c_str(), file_and_line.c_str(),
+ log_msg);
}
+
+#if PERFETTO_ENABLE_LOG_RING_BUFFER()
+ // Append the message to the ring buffer for crash reporting postmortems.
+ StringView timestamp_sv = timestamp.string_view();
+ StringView file_and_line_sv = file_and_line.string_view();
+ StringView log_msg_sv(log_msg, static_cast<size_t>(log_msg_len));
+ g_log_ring_buffer.Append(timestamp_sv, file_and_line_sv, log_msg_sv);
+#else
+ ignore_result(log_msg_len);
+#endif
+}
+
+#if PERFETTO_ENABLE_LOG_RING_BUFFER()
+void MaybeSerializeLastLogsForCrashReporting() {
+ // Keep this function minimal. This is called from the watchdog thread, often
+ // when the system is thrashing.
+
+ // This is racy because two threads could hit a CHECK/FATAL at the same time.
+ // But if that happens we have bigger problems, not worth designing around it.
+ // The behaviour is still defined in the race case (the string attached to
+ // the crash report will contain a mixture of log strings).
+ size_t wr = 0;
+ wr += SerializeCrashKeys(&g_crash_buf[wr], sizeof(g_crash_buf) - wr);
+ wr += g_log_ring_buffer.Read(&g_crash_buf[wr], sizeof(g_crash_buf) - wr);
+
+ // Read() null-terminates the string properly. This is just to avoid UB when
+ // two threads race on each other (T1 writes a shorter string, T2
+ // overwrites the \0 writing a longer string. T1 continues here before T2
+ // finishes writing the longer string with the \0 -> boom.
+ g_crash_buf[sizeof(g_crash_buf) - 1] = '\0';
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+ // android_set_abort_message() will cause debuggerd to report the message
+ // in the tombstone and in the crash log in logcat.
+ // NOTE: android_set_abort_message() can be called only once. This should
+ // be called only when we are sure we are about to crash.
+ android_set_abort_message(g_crash_buf);
+#else
+ // Print out the message on stderr on Linux/Mac/Win.
+ fputs("\n-----BEGIN PERFETTO PRE-CRASH LOG-----\n", stderr);
+ fputs(g_crash_buf, stderr);
+ fputs("\n-----END PERFETTO PRE-CRASH LOG-----\n", stderr);
+#endif
}
+#endif // PERFETTO_ENABLE_LOG_RING_BUFFER
} // namespace base
} // namespace perfetto
diff --git a/src/base/logging_unittest.cc b/src/base/logging_unittest.cc
index 534929026..83358955a 100644
--- a/src/base/logging_unittest.cc
+++ b/src/base/logging_unittest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,14 @@
#include <stdint.h>
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <vector>
+
+#include "perfetto/ext/base/crash_keys.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "src/base/log_ring_buffer.h"
#include "test/gtest_and_gmock.h"
namespace perfetto {
@@ -45,6 +53,205 @@ TEST(LoggingTest, Basic) {
ASSERT_STREQ(g_last_line, "");
}
+TEST(LogRingBufferTest, SimpleCases) {
+ char buf[4096];
+ memset(buf, 'x', sizeof(buf)); // Deliberately not 0-initialized.
+
+ LogRingBuffer lrb;
+ EXPECT_EQ(0u, lrb.Read(buf, sizeof(buf)));
+ EXPECT_STREQ(buf, "");
+
+ // Append one entry and read back.
+ lrb.Append("tstamp1,", "src1.cc", "message1");
+ EXPECT_EQ(25u, lrb.Read(buf, sizeof(buf)));
+ EXPECT_STREQ(buf, "tstamp1,src1.cc message1\n");
+
+ lrb.Append("tstamp2,", "src2.cc", "message2");
+ EXPECT_EQ(50u, lrb.Read(buf, sizeof(buf)));
+ EXPECT_STREQ(buf, "tstamp1,src1.cc message1\ntstamp2,src2.cc message2\n");
+}
+
+TEST(LogRingBufferTest, Truncation) {
+ // Append a long entry that overflows the event slot.
+ std::string long_msg;
+ long_msg.resize(kLogRingBufMsgLen * 2);
+ for (size_t i = 0; i < long_msg.size(); i++)
+ long_msg[i] = static_cast<char>('a' + (i % 27));
+ LogRingBuffer lrb;
+ lrb.Append("A", "B", StringView(long_msg));
+
+ // Check that it gets truncated with no side effects.
+ char buf[4096];
+ memset(buf, 'x', sizeof(buf)); // Deliberately not 0-initialized.
+ auto expected = "AB " + long_msg.substr(0, kLogRingBufMsgLen - 4) + "\n";
+ EXPECT_EQ(expected.size(), lrb.Read(buf, sizeof(buf)));
+ EXPECT_EQ(buf, expected);
+
+ // Append a short message and check everything still works.
+ lrb.Append("X", "Y", "foo");
+ EXPECT_EQ(expected.size() + 7, lrb.Read(buf, sizeof(buf)));
+ EXPECT_EQ(buf, expected + "XY foo\n");
+}
+
+TEST(LogRingBufferTest, Wrapping) {
+ LogRingBuffer lrb;
+
+ std::vector<std::string> expected_logs;
+ for (uint32_t i = 0; i < 128; i++) {
+ std::string id = std::to_string(i);
+ std::string tstamp = "tstamp" + id + ",";
+ std::string src = "src";
+ std::string msg;
+ msg.resize(1 + (i % 16));
+ for (size_t c = 0; c < msg.size(); c++)
+ msg[c] = static_cast<char>('a' + c);
+ lrb.Append(StringView(tstamp), StringView(src), StringView(msg));
+ auto expected_log =
+ (tstamp + src + " " + msg).substr(0, kLogRingBufMsgLen) + "\n";
+ expected_logs.emplace_back(expected_log);
+ }
+
+ std::string expected;
+ for (size_t i = expected_logs.size() - kLogRingBufEntries;
+ i < expected_logs.size(); i++) {
+ expected += expected_logs[i];
+ }
+
+ char buf[kLogRingBufMsgLen * kLogRingBufEntries];
+ memset(buf, 'x', sizeof(buf)); // Deliberately not 0-initialized.
+ lrb.Read(buf, sizeof(buf));
+ EXPECT_EQ(buf, expected);
+
+ // Do a partial readback which will cause output truncation.
+ lrb.Read(buf, 127);
+ EXPECT_EQ(buf, expected.substr(0, 127 - 1)); // - 1 for the NUL terminator.
+}
+
+// Writes concurrently into the ring buffer and check that all the events are
+// seen in some order.
+TEST(LogRingBufferTest, MultiThreadedWrites) {
+ LogRingBuffer lrb;
+
+ std::vector<std::thread> threads;
+ const size_t kNumThreads = 8;
+
+ std::mutex mutex;
+ std::condition_variable cond;
+ bool sync_start = false;
+
+ auto thread_main = [&](size_t thread_idx) {
+ std::unique_lock<std::mutex> lock(mutex);
+ cond.wait(lock, [&] { return sync_start; });
+
+ std::string tstamp = "ts" + std::to_string(thread_idx) + ",";
+ std::string src = "src";
+ std::string msg(thread_idx + 1, '.'); // A variable number of dots.
+ lrb.Append(StringView(tstamp), StringView(src), StringView(msg));
+ };
+
+ std::vector<std::string> expected_events;
+ for (size_t i = 0; i < kNumThreads; i++) {
+ threads.emplace_back(thread_main, i);
+ std::string id = std::to_string(i);
+ expected_events.emplace_back("ts" + id + ",src " + std::string(i + 1, '.'));
+ }
+
+ // Unlock all the threads as close as possible to maximize races.
+ {
+ std::unique_lock<std::mutex> lock(mutex);
+ sync_start = true;
+ cond.notify_all();
+ }
+
+ for (auto& thread : threads)
+ thread.join();
+
+ char buf[kLogRingBufEntries * 40];
+ memset(buf, 'x', sizeof(buf)); // Deliberately not 0-initialized.
+ lrb.Read(buf, sizeof(buf));
+
+ std::vector<std::string> actual_events = SplitString(buf, "\n");
+ EXPECT_THAT(actual_events,
+ testing::UnorderedElementsAreArray(expected_events));
+}
+
+TEST(CrashKeysTest, SetClearAndLongKeys) {
+ UnregisterAllCrashKeysForTesting();
+
+ char buf[1024];
+ memset(buf, 'x', sizeof(buf));
+ EXPECT_EQ(0u, SerializeCrashKeys(buf, sizeof(buf)));
+ EXPECT_STREQ(buf, "");
+
+ CrashKey k1("key1");
+ CrashKey k2("key2");
+ CrashKey k3("key3");
+ CrashKey k4("key4");
+
+ k1.Set(0);
+ k1.Clear();
+
+ k2.Set(42);
+
+ k3.Set("xx");
+ k3.Clear();
+
+ k4.Set("value");
+
+ EXPECT_EQ(21u, SerializeCrashKeys(buf, sizeof(buf)));
+ EXPECT_STREQ(buf, "key2: 42\nkey4: value\n");
+
+ EXPECT_EQ(0u, SerializeCrashKeys(buf, 0));
+
+ EXPECT_EQ(0u, SerializeCrashKeys(buf, 1));
+ EXPECT_STREQ(buf, "");
+
+ // Test truncated output.
+ EXPECT_EQ(5u, SerializeCrashKeys(buf, 5 + 1));
+ EXPECT_STREQ(buf, "key2:");
+
+ k2.Clear();
+
+ std::string long_str(1024, 'x');
+ k4.Set(StringView(long_str));
+
+ EXPECT_EQ(6 + kCrashKeyMaxStrSize, SerializeCrashKeys(buf, sizeof(buf)));
+ std::string expected =
+ "key4: " + long_str.substr(0, kCrashKeyMaxStrSize - 1) + "\n";
+ EXPECT_EQ(buf, expected);
+
+ UnregisterAllCrashKeysForTesting();
+}
+
+TEST(CrashKeysTest, ScopedSet) {
+ UnregisterAllCrashKeysForTesting();
+
+ char buf[1024];
+ memset(buf, 'x', sizeof(buf));
+
+ CrashKey k1("key1");
+ CrashKey k2("key2");
+
+ auto scoped_key = k1.SetScoped(42);
+ EXPECT_GT(SerializeCrashKeys(buf, sizeof(buf)), 0u);
+ EXPECT_STREQ(buf, "key1: 42\n");
+
+ {
+ auto scoped_key2 = k2.SetScoped("foo");
+ EXPECT_GT(SerializeCrashKeys(buf, sizeof(buf)), 0u);
+ EXPECT_STREQ(buf, "key1: 42\nkey2: foo\n");
+ }
+
+ EXPECT_GT(SerializeCrashKeys(buf, sizeof(buf)), 0u);
+ EXPECT_STREQ(buf, "key1: 42\n");
+
+ k1.Clear();
+ EXPECT_EQ(0u, SerializeCrashKeys(buf, sizeof(buf)));
+ EXPECT_STREQ(buf, "");
+
+ UnregisterAllCrashKeysForTesting();
+}
+
} // namespace
} // namespace base
} // namespace perfetto
diff --git a/src/base/paged_memory_unittest.cc b/src/base/paged_memory_unittest.cc
index fd2790da7..7e3508bfe 100644
--- a/src/base/paged_memory_unittest.cc
+++ b/src/base/paged_memory_unittest.cc
@@ -36,12 +36,16 @@ namespace {
TEST(PagedMemoryTest, Basic) {
const size_t kNumPages = 10;
const size_t kSize = 4096 * kNumPages;
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
void* ptr_raw = nullptr;
+#endif
{
PagedMemory mem = PagedMemory::Allocate(kSize);
ASSERT_TRUE(mem.IsValid());
ASSERT_EQ(0u, reinterpret_cast<uintptr_t>(mem.Get()) % 4096);
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
ptr_raw = mem.Get();
+#endif
for (size_t i = 0; i < kSize / sizeof(uint64_t); i++)
ASSERT_EQ(0u, *(reinterpret_cast<uint64_t*>(mem.Get()) + i));
@@ -93,11 +97,15 @@ TEST(PagedMemoryTest, SubPageGranularity) {
TEST(PagedMemoryTest, Uncommitted) {
constexpr size_t kNumPages = 4096;
constexpr size_t kSize = 4096 * kNumPages;
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
char* ptr_raw = nullptr;
+#endif
{
PagedMemory mem = PagedMemory::Allocate(kSize, PagedMemory::kDontCommit);
ASSERT_TRUE(mem.IsValid());
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
ptr_raw = reinterpret_cast<char*>(mem.Get());
+#endif
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
// Windows only commits the first 1024 pages.
diff --git a/src/base/scoped_file_unittest.cc b/src/base/scoped_file_unittest.cc
index 759095523..d3d1e7d84 100644
--- a/src/base/scoped_file_unittest.cc
+++ b/src/base/scoped_file_unittest.cc
@@ -22,6 +22,8 @@
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <io.h>
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+#include <lib/fdio/fdio.h>
#else
#include <unistd.h>
// Double closing of file handles on Windows leads to invocation of the invalid
@@ -36,16 +38,46 @@ namespace perfetto {
namespace base {
namespace {
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
-const char kNullFilename[] = "NUL";
-const char kZeroFilename[] = "NUL";
+int OpenDevNull() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+ return fdio_fd_create_null();
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ return open("NUL", O_RDONLY);
+#else
+ return open("/dev/null", O_RDONLY);
+#endif
+}
+
+FILE* OpenDevNullStream() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+ return fdopen(fdio_fd_create_null(), "r");
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ return fopen("NUL", "r");
#else
-const char kNullFilename[] = "/dev/null";
-const char kZeroFilename[] = "/dev/zero";
+ return fopen("/dev/null", "r");
#endif
+}
+
+// Returns a file descriptor to some file. On Fuchsia: returns a descriptor of a
+// file in /tmp. On other platforms: returns a descriptor of /dev/zero.
+int MakeSecondFileDescriptor() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+ // Create a random file in /tmp and unlink it straight away since its name
+ // never need be known or uttered.
+ char path[] = "/tmp/sfuXXXXXX";
+ const int fd = mkstemp(&path[0]);
+ if (fd >= 0)
+ unlink(path);
+ return fd;
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ return open("NUL", O_RDONLY);
+#else
+ return open("/dev/zero", O_RDONLY);
+#endif
+}
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
- TEST(ScopedDirTest, CloseOutOfScope) {
+TEST(ScopedDirTest, CloseOutOfScope) {
DIR* dir_handle = opendir(".");
ASSERT_NE(nullptr, dir_handle);
int dir_handle_fd = dirfd(dir_handle);
@@ -60,7 +92,7 @@ const char kZeroFilename[] = "/dev/zero";
#endif
TEST(ScopedFileTest, CloseOutOfScope) {
- int raw_fd = open(kNullFilename, O_RDONLY);
+ int raw_fd = OpenDevNull();
ASSERT_GE(raw_fd, 0);
{
ScopedFile scoped_file(raw_fd);
@@ -74,7 +106,7 @@ TEST(ScopedFileTest, CloseOutOfScope) {
}
TEST(ScopedFstreamTest, CloseOutOfScope) {
- FILE* raw_stream = fopen(kNullFilename, "r");
+ FILE* raw_stream = OpenDevNullStream();
ASSERT_NE(nullptr, raw_stream);
{
ScopedFstream scoped_stream(raw_stream);
@@ -86,8 +118,8 @@ TEST(ScopedFstreamTest, CloseOutOfScope) {
}
TEST(ScopedFileTest, Reset) {
- int raw_fd1 = open(kNullFilename, O_RDONLY);
- int raw_fd2 = open(kZeroFilename, O_RDONLY);
+ int raw_fd1 = OpenDevNull();
+ int raw_fd2 = MakeSecondFileDescriptor();
ASSERT_GE(raw_fd1, 0);
ASSERT_GE(raw_fd2, 0);
{
@@ -102,13 +134,13 @@ TEST(ScopedFileTest, Reset) {
#ifdef TEST_INVALID_CLOSE
ASSERT_NE(0, close(raw_fd2));
#endif
- scoped_file.reset(open(kNullFilename, O_RDONLY));
+ scoped_file.reset(OpenDevNull());
ASSERT_GE(scoped_file.get(), 0);
}
}
TEST(ScopedFileTest, Release) {
- int raw_fd = open(kNullFilename, O_RDONLY);
+ int raw_fd = OpenDevNull();
ASSERT_GE(raw_fd, 0);
{
ScopedFile scoped_file(raw_fd);
@@ -119,8 +151,8 @@ TEST(ScopedFileTest, Release) {
}
TEST(ScopedFileTest, MoveCtor) {
- int raw_fd1 = open(kNullFilename, O_RDONLY);
- int raw_fd2 = open(kZeroFilename, O_RDONLY);
+ int raw_fd1 = OpenDevNull();
+ int raw_fd2 = MakeSecondFileDescriptor();
ASSERT_GE(raw_fd1, 0);
ASSERT_GE(raw_fd2, 0);
{
@@ -141,8 +173,8 @@ TEST(ScopedFileTest, MoveCtor) {
}
TEST(ScopedFileTest, MoveAssignment) {
- int raw_fd1 = open(kNullFilename, O_RDONLY);
- int raw_fd2 = open(kZeroFilename, O_RDONLY);
+ int raw_fd1 = OpenDevNull();
+ int raw_fd2 = MakeSecondFileDescriptor();
ASSERT_GE(raw_fd1, 0);
ASSERT_GE(raw_fd2, 0);
{
@@ -170,7 +202,7 @@ TEST(ScopedFileTest, MoveAssignment) {
// might have leaked a capability.
#ifdef TEST_INVALID_CLOSE
TEST(ScopedFileTest, CloseFailureIsFatal) {
- int raw_fd = open(kNullFilename, O_RDONLY);
+ int raw_fd = OpenDevNull();
ASSERT_DEATH_IF_SUPPORTED(
{
ScopedFile scoped_file(raw_fd);
diff --git a/src/base/small_vector_unittest.cc b/src/base/small_vector_unittest.cc
new file mode 100644
index 000000000..e99d84ae3
--- /dev/null
+++ b/src/base/small_vector_unittest.cc
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/ext/base/small_vector.h"
+
+#include <tuple>
+#include <utility>
+
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace base {
+namespace {
+
+int g_instances = 0;
+
+struct Obj {
+ explicit Obj(size_t v = 0) : value(v) {
+ EXPECT_FALSE(constructed);
+ constructed = true;
+ g_instances++;
+ }
+
+ ~Obj() {
+ EXPECT_TRUE(constructed);
+ g_instances--;
+ }
+
+ // Move operators.
+ Obj(Obj&& other) noexcept {
+ g_instances++;
+ constructed = true;
+ moved_into = true;
+ value = other.value;
+ other.moved_from = true;
+ other.value = 0xffffffff - value;
+ }
+
+ Obj& operator=(Obj&& other) noexcept {
+ this->~Obj();
+ new (this) Obj(std::move(other));
+ return *this;
+ }
+
+ // Copy operators.
+ Obj(const Obj& other) {
+ other.copied_from = true;
+ g_instances++;
+ constructed = true;
+ copied_into = true;
+ value = other.value;
+ }
+
+ Obj& operator=(const Obj& other) {
+ this->~Obj();
+ new (this) Obj(other);
+ return *this;
+ }
+
+ uintptr_t addr = reinterpret_cast<uintptr_t>(this);
+ bool constructed = false;
+ size_t value = 0;
+ bool moved_from = false;
+ mutable bool copied_from = false;
+ bool moved_into = false;
+ bool copied_into = false;
+};
+
+TEST(SmallVectorTest, StaySmall) {
+ SmallVector<Obj, 8> v;
+ EXPECT_EQ(g_instances, 0);
+ EXPECT_EQ(v.size(), 0u);
+ EXPECT_TRUE(v.empty());
+ EXPECT_EQ(v.begin(), v.end());
+
+ for (size_t i = 1; i <= 8; i++) {
+ v.emplace_back(i);
+ EXPECT_EQ(g_instances, static_cast<int>(i));
+ EXPECT_FALSE(v.empty());
+ EXPECT_EQ(v.end(), v.begin() + i);
+ EXPECT_EQ(v.back().value, i);
+ EXPECT_EQ(v[static_cast<size_t>(i - 1)].value, i);
+ EXPECT_EQ(v[static_cast<size_t>(i - 1)].value, i);
+ }
+
+ for (size_t i = 1; i <= 3; i++) {
+ v.pop_back();
+ EXPECT_EQ(g_instances, 8 - static_cast<int>(i));
+ }
+
+ v.clear();
+ EXPECT_EQ(g_instances, 0);
+}
+
+TEST(SmallVectorTest, GrowOnHeap) {
+ SmallVector<Obj, 4> v;
+ for (size_t i = 0; i < 10; i++) {
+ v.emplace_back(i);
+ EXPECT_EQ(g_instances, static_cast<int>(i + 1));
+ EXPECT_FALSE(v.empty());
+ EXPECT_EQ(v.end(), v.begin() + i + 1);
+ EXPECT_EQ(v[i].value, i);
+ }
+
+ // Do a second pass and check that the initial elements aren't corrupt.
+ for (size_t i = 0; i < 10; i++) {
+ EXPECT_EQ(v[i].value, i);
+ EXPECT_TRUE(v[i].constructed);
+ }
+
+ // The first 4 elements must have been moved into because of the heap growth.
+ for (size_t i = 0; i < 4; i++)
+ EXPECT_TRUE(v[i].moved_into);
+ EXPECT_FALSE(v.back().moved_into);
+}
+
+class SmallVectorTestP : public testing::TestWithParam<size_t> {};
+
+TEST_P(SmallVectorTestP, MoveOperators) {
+ size_t num_elements = GetParam();
+ static constexpr size_t kInlineCapacity = 4;
+ SmallVector<Obj, kInlineCapacity> v1;
+ for (size_t i = 0; i < num_elements; i++)
+ v1.emplace_back(i);
+
+ SmallVector<Obj, kInlineCapacity> v2(std::move(v1));
+ EXPECT_TRUE(v1.empty());
+ EXPECT_EQ(v2.size(), num_elements);
+
+ // Check that v2 (the moved into vector) is consistent.
+ for (size_t i = 0; i < num_elements; i++) {
+ EXPECT_EQ(v2[i].value, i);
+ EXPECT_TRUE(v2[i].constructed);
+ if (num_elements <= kInlineCapacity) {
+ EXPECT_TRUE(v2[i].moved_into);
+ }
+ }
+
+ // Check that v1 (the moved-from object) is still usable.
+ EXPECT_EQ(v1.size(), 0u);
+
+ for (size_t i = 0; i < num_elements; i++) {
+ v1.emplace_back(1000 + i);
+ EXPECT_EQ(v1.size(), i + 1);
+ }
+
+ EXPECT_NE(v1.data(), v2.data());
+
+ for (size_t i = 0; i < num_elements; i++) {
+ EXPECT_EQ(v1[i].value, 1000 + i);
+ EXPECT_EQ(v2[i].value, i);
+ EXPECT_TRUE(v1[i].constructed);
+ EXPECT_FALSE(v1[i].moved_from);
+ }
+
+ // Now swap again using the move-assignment.
+
+ v1 = std::move(v2);
+ EXPECT_EQ(v1.size(), num_elements);
+ EXPECT_TRUE(v2.empty());
+ for (size_t i = 0; i < num_elements; i++) {
+ EXPECT_EQ(v1[i].value, i);
+ EXPECT_TRUE(v1[i].constructed);
+ }
+
+ { auto destroy = std::move(v1); }
+
+ EXPECT_EQ(g_instances, 0);
+}
+
+TEST_P(SmallVectorTestP, CopyOperators) {
+ size_t num_elements = GetParam();
+ static constexpr size_t kInlineCapacity = 4;
+ SmallVector<Obj, kInlineCapacity> v1;
+ for (size_t i = 0; i < num_elements; i++)
+ v1.emplace_back(i);
+
+ SmallVector<Obj, kInlineCapacity> v2(v1);
+ EXPECT_EQ(v1.size(), num_elements);
+ EXPECT_EQ(v2.size(), num_elements);
+ EXPECT_EQ(g_instances, static_cast<int>(num_elements * 2));
+
+ for (size_t i = 0; i < num_elements; i++) {
+ EXPECT_EQ(v1[i].value, i);
+ EXPECT_TRUE(v1[i].copied_from);
+ EXPECT_EQ(v2[i].value, i);
+ EXPECT_TRUE(v2[i].copied_into);
+ }
+
+ // Now edit v2.
+ for (size_t i = 0; i < num_elements; i++)
+ v2[i].value = i + 100;
+ EXPECT_EQ(g_instances, static_cast<int>(num_elements * 2));
+
+ // Append some extra elements.
+ for (size_t i = 0; i < num_elements; i++)
+ v2.emplace_back(i + 200);
+ EXPECT_EQ(g_instances, static_cast<int>(num_elements * 3));
+
+ for (size_t i = 0; i < num_elements * 2; i++) {
+ if (i < num_elements) {
+ EXPECT_EQ(v1[i].value, i);
+ EXPECT_EQ(v2[i].value, 100 + i);
+ } else {
+ EXPECT_EQ(v2[i].value, 200 + i - num_elements);
+ }
+ }
+
+ v2.clear();
+ EXPECT_EQ(g_instances, static_cast<int>(num_elements));
+}
+
+INSTANTIATE_TEST_SUITE_P(SmallVectorTest,
+ SmallVectorTestP,
+ testing::Values(2, 4, 7, 512));
+
+} // namespace
+} // namespace base
+} // namespace perfetto
diff --git a/src/base/string_utils.cc b/src/base/string_utils.cc
index c0b078057..7e98ecdf2 100644
--- a/src/base/string_utils.cc
+++ b/src/base/string_utils.cc
@@ -16,25 +16,23 @@
#include "perfetto/ext/base/string_utils.h"
-#include <inttypes.h>
#include <locale.h>
+#include <stdarg.h>
#include <string.h>
+#include <algorithm>
+
#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
#include <xlocale.h>
#endif
-#include <algorithm>
+#include <cinttypes>
+#include "perfetto/base/compiler.h"
#include "perfetto/base/logging.h"
namespace perfetto {
namespace base {
-namespace {
-constexpr char kBase64Table[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz0123456789+/";
-}
// Locale-independant as possible version of strtod.
double StrToD(const char* nptr, char** endptr) {
@@ -48,46 +46,17 @@ double StrToD(const char* nptr, char** endptr) {
#endif
}
-std::string QuoteAndEscapeControlCodes(const std::string& raw) {
- std::string ret;
- for (auto it = raw.cbegin(); it != raw.cend(); it++) {
- switch (*it) {
- case '\\':
- ret += "\\\\";
- break;
- case '"':
- ret += "\\\"";
- break;
- case '/':
- ret += "\\/";
- break;
- case '\b':
- ret += "\\b";
- break;
- case '\f':
- ret += "\\f";
- break;
- case '\n':
- ret += "\\n";
- break;
- case '\r':
- ret += "\\r";
- break;
- case '\t':
- ret += "\\t";
- break;
- default:
- ret += *it;
- break;
- }
- }
- return '"' + ret + '"';
-}
-
bool StartsWith(const std::string& str, const std::string& prefix) {
return str.compare(0, prefix.length(), prefix) == 0;
}
+bool StartsWithAny(const std::string& str,
+ const std::vector<std::string>& prefixes) {
+ return std::any_of(
+ prefixes.begin(), prefixes.end(),
+ [&str](const std::string& prefix) { return StartsWith(str, prefix); });
+}
+
bool EndsWith(const std::string& str, const std::string& suffix) {
if (suffix.size() > str.size())
return false;
@@ -195,9 +164,8 @@ std::string IntToHexString(uint32_t number) {
size_t max_size = 11; // Max uint32 is 0xFFFFFFFF + 1 for null byte.
std::string buf;
buf.resize(max_size);
- auto final_size = snprintf(&buf[0], max_size, "0x%02x", number);
- PERFETTO_DCHECK(final_size >= 0);
- buf.resize(static_cast<size_t>(final_size)); // Cuts off the final null byte.
+ size_t final_len = SprintfTrunc(&buf[0], max_size, "0x%02x", number);
+ buf.resize(static_cast<size_t>(final_len)); // Cuts off the final null byte.
return buf;
}
@@ -209,9 +177,8 @@ std::string Uint64ToHexStringNoPrefix(uint64_t number) {
size_t max_size = 17; // Max uint64 is FFFFFFFFFFFFFFFF + 1 for null byte.
std::string buf;
buf.resize(max_size);
- auto final_size = snprintf(&buf[0], max_size, "%" PRIx64 "", number);
- PERFETTO_DCHECK(final_size >= 0);
- buf.resize(static_cast<size_t>(final_size)); // Cuts off the final null byte.
+ size_t final_len = SprintfTrunc(&buf[0], max_size, "%" PRIx64 "", number);
+ buf.resize(static_cast<size_t>(final_len)); // Cuts off the final null byte.
return buf;
}
@@ -238,47 +205,32 @@ std::string ReplaceAll(std::string str,
return str;
}
-std::string TrimLeading(const std::string& str) {
- size_t idx = str.find_first_not_of(' ');
- return idx == std::string::npos ? str : str.substr(idx);
-}
+size_t SprintfTrunc(char* dst, size_t dst_size, const char* fmt, ...) {
+ if (PERFETTO_UNLIKELY(dst_size) == 0)
+ return 0;
-std::string Base64Encode(const void* raw, size_t size) {
- // The following three cases are based on the tables in the example
- // section in https://en.wikipedia.org/wiki/Base64. We process three
- // input bytes at a time, emitting 4 output bytes at a time.
- const uint8_t* ptr = static_cast<const uint8_t*>(raw);
- size_t ii = 0;
-
- std::string out;
- out.reserve((size + 2) * 4 / 3);
-
- // While possible, process three input bytes.
- for (; ii + 3 <= size; ii += 3) {
- uint32_t twentyfour_bits =
- (uint32_t(ptr[ii]) << 16) | (uint32_t(ptr[ii + 1]) << 8) | ptr[ii + 2];
- out.push_back(kBase64Table[(twentyfour_bits >> 18)]);
- out.push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
- out.push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]);
- out.push_back(kBase64Table[twentyfour_bits & 0x3f]);
- }
- if (ii + 2 <= size) { // Process two input bytes.
- uint32_t twentyfour_bits =
- (uint32_t(ptr[ii]) << 16) | (uint32_t(ptr[ii + 1]) << 8);
- out.push_back(kBase64Table[(twentyfour_bits >> 18)]);
- out.push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
- out.push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]);
- out.push_back('='); // Emit padding.
- return out;
+ va_list args;
+ va_start(args, fmt);
+ int src_size = vsnprintf(dst, dst_size, fmt, args);
+ va_end(args);
+
+ if (PERFETTO_UNLIKELY(src_size) <= 0) {
+ dst[0] = '\0';
+ return 0;
}
- if (ii + 1 <= size) { // Process a single input byte.
- uint32_t twentyfour_bits = (uint32_t(ptr[ii]) << 16);
- out.push_back(kBase64Table[(twentyfour_bits >> 18)]);
- out.push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
- out.push_back('='); // Emit padding.
- out.push_back('='); // Emit padding.
+
+ size_t res;
+ if (PERFETTO_LIKELY(src_size < static_cast<int>(dst_size))) {
+ // Most common case.
+ res = static_cast<size_t>(src_size);
+ } else {
+ // Truncation case.
+ res = dst_size - 1;
}
- return out;
+
+ PERFETTO_DCHECK(res < dst_size);
+ PERFETTO_DCHECK(dst[res] == '\0');
+ return res;
}
} // namespace base
diff --git a/src/base/string_utils_unittest.cc b/src/base/string_utils_unittest.cc
index 5c41f16de..9a885d159 100644
--- a/src/base/string_utils_unittest.cc
+++ b/src/base/string_utils_unittest.cc
@@ -24,6 +24,13 @@ namespace perfetto {
namespace base {
namespace {
+template <size_t N>
+struct UninitializedBuf {
+ UninitializedBuf() { memset(data, '?', sizeof(data)); }
+ operator char*() { return data; }
+ char data[N];
+};
+
using testing::ElementsAre;
TEST(StringUtilsTest, Lowercase) {
@@ -156,6 +163,14 @@ TEST(StringUtilsTest, StartsWith) {
EXPECT_FALSE(StartsWith("", "ab"));
}
+TEST(StringUtilsTest, StartsWithAny) {
+ EXPECT_FALSE(StartsWithAny("", {"a", "b"}));
+ EXPECT_FALSE(StartsWithAny("abcd", {}));
+ EXPECT_FALSE(StartsWithAny("", {}));
+ EXPECT_TRUE(StartsWithAny("abcd", {"ac", "ab"}));
+ EXPECT_FALSE(StartsWithAny("abcd", {"bc", "ac"}));
+}
+
TEST(StringUtilsTest, EndsWith) {
EXPECT_TRUE(EndsWith("", ""));
EXPECT_TRUE(EndsWith("abc", ""));
@@ -281,34 +296,124 @@ TEST(StringUtilsTest, ReplaceAll) {
EXPECT_EQ(ReplaceAll("abc", "c", "bbb"), "abbbb");
}
-TEST(StringUtilsTest, TrimLeading) {
- EXPECT_EQ(TrimLeading(""), "");
- EXPECT_EQ(TrimLeading("a"), "a");
- EXPECT_EQ(TrimLeading(" aaaa"), "aaaa");
- EXPECT_EQ(TrimLeading(" aaaaa "), "aaaaa ");
+TEST(StringUtilsTest, StringCopy) {
+ // Nothing should be written when |dst_size| = 0.
+ {
+ char dst[2] = {42, 43};
+ StringCopy(dst, "12345", 0);
+ EXPECT_EQ(42, dst[0]);
+ EXPECT_EQ(43, dst[1]);
+ }
+
+ // Nominal case, len(src) < sizeof(dst).
+ {
+ UninitializedBuf<10> dst;
+ StringCopy(dst, "1234567", sizeof(dst));
+ EXPECT_STREQ(dst, "1234567");
+ }
+
+ // Edge case where we perfectly fit including the \0.
+ {
+ UninitializedBuf<8> dst;
+ StringCopy(dst, "1234567", sizeof(dst));
+ EXPECT_STREQ(dst, "1234567");
+ }
+
+ // Edge case where |dst| is smaller by one char.
+ {
+ UninitializedBuf<8> dst;
+ StringCopy(dst, "12345678", sizeof(dst));
+ EXPECT_STREQ(dst, "1234567");
+ }
+
+ // Case when |dst| is smaller than |src|.
+ {
+ UninitializedBuf<3> dst;
+ StringCopy(dst, "12345678", sizeof(dst));
+ EXPECT_STREQ(dst, "12");
+ }
}
-TEST(StringUtilsTest, Base64Encode) {
- auto base64_encode = [](const std::string& str) {
- return Base64Encode(str.c_str(), str.size());
- };
-
- EXPECT_EQ(base64_encode(""), "");
- EXPECT_EQ(base64_encode("f"), "Zg==");
- EXPECT_EQ(base64_encode("fo"), "Zm8=");
- EXPECT_EQ(base64_encode("foo"), "Zm9v");
- EXPECT_EQ(base64_encode("foob"), "Zm9vYg==");
- EXPECT_EQ(base64_encode("fooba"), "Zm9vYmE=");
- EXPECT_EQ(base64_encode("foobar"), "Zm9vYmFy");
-
- EXPECT_EQ(Base64Encode("foo\0bar", 7), "Zm9vAGJhcg==");
-
- std::vector<uint8_t> buffer = {0x04, 0x53, 0x42, 0x35,
- 0x32, 0xFF, 0x00, 0xFE};
- EXPECT_EQ(Base64Encode(buffer.data(), buffer.size()), "BFNCNTL/AP4=");
+TEST(StringUtilsTest, SprintfTrunc) {
+ {
+ UninitializedBuf<3> dst;
+ ASSERT_EQ(0u, SprintfTrunc(dst, sizeof(dst), "%s", ""));
+ EXPECT_STREQ(dst, "");
+ }
+
+ {
+ char dst[3]{'O', 'K', '\0'};
+ ASSERT_EQ(0u, SprintfTrunc(dst, 0, "whatever"));
+ EXPECT_STREQ(dst, "OK"); // dst_size == 0 shouldn't touch the buffer.
+ }
+
+ {
+ UninitializedBuf<1> dst;
+ ASSERT_EQ(0u, SprintfTrunc(dst, sizeof(dst), "whatever"));
+ EXPECT_STREQ(dst, "");
+ }
+
+ {
+ UninitializedBuf<3> dst;
+ ASSERT_EQ(1u, SprintfTrunc(dst, sizeof(dst), "1"));
+ EXPECT_STREQ(dst, "1");
+ }
+
+ {
+ UninitializedBuf<3> dst;
+ ASSERT_EQ(2u, SprintfTrunc(dst, sizeof(dst), "12"));
+ EXPECT_STREQ(dst, "12");
+ }
+
+ {
+ UninitializedBuf<3> dst;
+ ASSERT_EQ(2u, SprintfTrunc(dst, sizeof(dst), "123"));
+ EXPECT_STREQ(dst, "12");
+ }
+
+ {
+ UninitializedBuf<3> dst;
+ ASSERT_EQ(2u, SprintfTrunc(dst, sizeof(dst), "1234"));
+ EXPECT_STREQ(dst, "12");
+ }
+
+ {
+ UninitializedBuf<11> dst;
+ ASSERT_EQ(10u, SprintfTrunc(dst, sizeof(dst), "a %d b %s", 42, "foo"));
+ EXPECT_STREQ(dst, "a 42 b foo");
+ }
+}
- buffer = {0xfb, 0xf0, 0x3e, 0x07, 0xfc};
- EXPECT_EQ(Base64Encode(buffer.data(), buffer.size()), "+/A+B/w=");
+TEST(StringUtilsTest, StackString) {
+ {
+ StackString<1> s("123");
+ EXPECT_EQ(0u, s.len());
+ EXPECT_STREQ("", s.c_str());
+ }
+
+ {
+ StackString<4> s("123");
+ EXPECT_EQ(3u, s.len());
+ EXPECT_STREQ("123", s.c_str());
+ EXPECT_EQ(s.ToStdString(), std::string(s.c_str()));
+ EXPECT_EQ(s.string_view().ToStdString(), s.ToStdString());
+ }
+
+ {
+ StackString<3> s("123");
+ EXPECT_EQ(2u, s.len());
+ EXPECT_STREQ("12", s.c_str());
+ EXPECT_EQ(s.ToStdString(), std::string(s.c_str()));
+ EXPECT_EQ(s.string_view().ToStdString(), s.ToStdString());
+ }
+
+ {
+ StackString<11> s("foo %d %s", 42, "bar!!!OVERFLOW");
+ EXPECT_EQ(10u, s.len());
+ EXPECT_STREQ("foo 42 bar", s.c_str());
+ EXPECT_EQ(s.ToStdString(), std::string(s.c_str()));
+ EXPECT_EQ(s.string_view().ToStdString(), s.ToStdString());
+ }
}
} // namespace
diff --git a/src/base/string_view_unittest.cc b/src/base/string_view_unittest.cc
index bb00035c6..848e51d42 100644
--- a/src/base/string_view_unittest.cc
+++ b/src/base/string_view_unittest.cc
@@ -34,6 +34,8 @@ TEST(StringViewTest, BasicCases) {
EXPECT_EQ(StringView("ax", 1), StringView("ay", 1));
EXPECT_EQ(StringView("ax", 1), StringView("a"));
EXPECT_EQ(StringView("ax", 1), "a");
+ EXPECT_EQ(StringView(reinterpret_cast<const char*>(0x100), 0).ToStdString(),
+ std::string(""));
EXPECT_EQ(StringView("foo|", 3).ToStdString(), std::string("foo"));
EXPECT_TRUE(StringView("x") != StringView(""));
EXPECT_TRUE(StringView("") != StringView("y"));
@@ -153,6 +155,20 @@ TEST(StringViewTest, BasicCases) {
EXPECT_FALSE(StringView("foo") >= StringView("fooo"));
EXPECT_TRUE(StringView("fooo") >= StringView("foo"));
EXPECT_FALSE(StringView("bar") >= StringView("foo"));
+
+ // Test StartsWith.
+ EXPECT_TRUE(StringView().StartsWith(StringView()));
+ EXPECT_TRUE(StringView().StartsWith(StringView("")));
+ EXPECT_TRUE(StringView("").StartsWith(StringView("")));
+ EXPECT_TRUE(StringView("").StartsWith(StringView()));
+ EXPECT_TRUE(StringView("foo").StartsWith(StringView()));
+ EXPECT_TRUE(StringView("foo").StartsWith(StringView("")));
+ EXPECT_FALSE(StringView().StartsWith("foo"));
+ EXPECT_FALSE(StringView("").StartsWith("foo"));
+ EXPECT_TRUE(StringView("foo").StartsWith("foo"));
+ EXPECT_TRUE(StringView("foorbar").StartsWith("foo"));
+ EXPECT_FALSE(StringView("foorbar").StartsWith("bar"));
+ EXPECT_FALSE(StringView("foo").StartsWith("fooo"));
}
TEST(StringViewTest, HashCollisions) {
diff --git a/src/base/subprocess_posix.cc b/src/base/subprocess_posix.cc
index 85df3398a..fd32bb98e 100644
--- a/src/base/subprocess_posix.cc
+++ b/src/base/subprocess_posix.cc
@@ -82,6 +82,12 @@ void __attribute__((noreturn)) ChildProcess(ChildProcessArgs* args) {
_exit(128);
};
+ if (args->create_args->posix_proc_group_id.has_value()) {
+ if (setpgid(0 /*self*/, args->create_args->posix_proc_group_id.value())) {
+ die("setpgid() failed");
+ }
+ }
+
auto set_fd_close_on_exec = [&die](int fd, bool close_on_exec) {
int flags = fcntl(fd, F_GETFD, 0);
if (flags < 0)
@@ -94,41 +100,49 @@ void __attribute__((noreturn)) ChildProcess(ChildProcessArgs* args) {
if (getppid() == 1)
die("terminating because parent process died");
- if (dup2(args->stdin_pipe_rd, STDIN_FILENO) == -1)
- die("Failed to dup2(STDIN)");
- close(args->stdin_pipe_rd);
+ switch (args->create_args->stdin_mode) {
+ case Subprocess::InputMode::kBuffer:
+ if (dup2(args->stdin_pipe_rd, STDIN_FILENO) == -1)
+ die("Failed to dup2(STDIN)");
+ close(args->stdin_pipe_rd);
+ break;
+ case Subprocess::InputMode::kDevNull:
+ if (dup2(open("/dev/null", O_RDONLY), STDIN_FILENO) == -1)
+ die("Failed to dup2(STDOUT)");
+ break;
+ }
switch (args->create_args->stdout_mode) {
- case Subprocess::kInherit:
+ case Subprocess::OutputMode::kInherit:
break;
- case Subprocess::kDevNull: {
+ case Subprocess::OutputMode::kDevNull: {
if (dup2(open("/dev/null", O_RDWR), STDOUT_FILENO) == -1)
die("Failed to dup2(STDOUT)");
break;
}
- case Subprocess::kBuffer:
+ case Subprocess::OutputMode::kBuffer:
if (dup2(args->stdouterr_pipe_wr, STDOUT_FILENO) == -1)
die("Failed to dup2(STDOUT)");
break;
- case Subprocess::kFd:
+ case Subprocess::OutputMode::kFd:
if (dup2(*args->create_args->out_fd, STDOUT_FILENO) == -1)
die("Failed to dup2(STDOUT)");
break;
}
switch (args->create_args->stderr_mode) {
- case Subprocess::kInherit:
+ case Subprocess::OutputMode::kInherit:
break;
- case Subprocess::kDevNull: {
+ case Subprocess::OutputMode::kDevNull: {
if (dup2(open("/dev/null", O_RDWR), STDERR_FILENO) == -1)
die("Failed to dup2(STDERR)");
break;
}
- case Subprocess::kBuffer:
+ case Subprocess::OutputMode::kBuffer:
if (dup2(args->stdouterr_pipe_wr, STDERR_FILENO) == -1)
die("Failed to dup2(STDERR)");
break;
- case Subprocess::kFd:
+ case Subprocess::OutputMode::kFd:
if (dup2(*args->create_args->out_fd, STDERR_FILENO) == -1)
die("Failed to dup2(STDERR)");
break;
@@ -150,12 +164,15 @@ void __attribute__((noreturn)) ChildProcess(ChildProcessArgs* args) {
}
}
- // Clears O_CLOEXEC from stdin/out/err. These are the only FDs that we want
- // to be preserved after the exec().
+ // Clears O_CLOEXEC from stdin/out/err and the |preserve_fds| list. These are
+ // the only FDs that we want to be preserved after the exec().
set_fd_close_on_exec(STDIN_FILENO, false);
set_fd_close_on_exec(STDOUT_FILENO, false);
set_fd_close_on_exec(STDERR_FILENO, false);
+ for (auto fd : preserve_fds)
+ set_fd_close_on_exec(fd, false);
+
// If the caller specified a std::function entrypoint, run that first.
if (args->create_args->posix_entrypoint_for_testing)
args->create_args->posix_entrypoint_for_testing();
@@ -211,8 +228,10 @@ void Subprocess::Start() {
}
// Setup the pipes for stdin/err redirection.
- s_->stdin_pipe = base::Pipe::Create(base::Pipe::kWrNonBlock);
- proc_args.stdin_pipe_rd = *s_->stdin_pipe.rd;
+ if (args.stdin_mode == InputMode::kBuffer) {
+ s_->stdin_pipe = base::Pipe::Create(base::Pipe::kWrNonBlock);
+ proc_args.stdin_pipe_rd = *s_->stdin_pipe.rd;
+ }
s_->stdouterr_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
proc_args.stdouterr_pipe_wr = *s_->stdouterr_pipe.wr;
diff --git a/src/base/subprocess_unittest.cc b/src/base/subprocess_unittest.cc
index b52c80484..6cebd1b04 100644
--- a/src/base/subprocess_unittest.cc
+++ b/src/base/subprocess_unittest.cc
@@ -74,8 +74,8 @@ TEST(SubprocessTest, StdoutOnly) {
#else
Subprocess p({"sh", "-c", "(echo skip_err >&2); echo out_only"});
#endif
- p.args.stdout_mode = Subprocess::kBuffer;
- p.args.stderr_mode = Subprocess::kDevNull;
+ p.args.stdout_mode = Subprocess::OutputMode::kBuffer;
+ p.args.stderr_mode = Subprocess::OutputMode::kDevNull;
EXPECT_TRUE(p.Call());
EXPECT_EQ(p.status(), Subprocess::kTerminated);
@@ -88,8 +88,8 @@ TEST(SubprocessTest, StderrOnly) {
#else
Subprocess p({"sh", "-c", "(echo err_only >&2); echo skip_out"});
#endif
- p.args.stdout_mode = Subprocess::kDevNull;
- p.args.stderr_mode = Subprocess::kBuffer;
+ p.args.stdout_mode = Subprocess::OutputMode::kDevNull;
+ p.args.stderr_mode = Subprocess::OutputMode::kBuffer;
EXPECT_TRUE(p.Call());
EXPECT_EQ(GetOutput(p), "err_only\n");
}
@@ -100,12 +100,54 @@ TEST(SubprocessTest, BothStdoutAndStderr) {
#else
Subprocess p({"sh", "-c", "echo out; (echo err >&2); echo out2"});
#endif
- p.args.stdout_mode = Subprocess::kBuffer;
- p.args.stderr_mode = Subprocess::kBuffer;
+ p.args.stdout_mode = Subprocess::OutputMode::kBuffer;
+ p.args.stderr_mode = Subprocess::OutputMode::kBuffer;
EXPECT_TRUE(p.Call());
EXPECT_EQ(GetOutput(p), "out\nerr\nout2\n");
}
+TEST(SubprocessTest, CatInputModeDevNull) {
+ std::string ignored_input = "ignored input";
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ Subprocess p({"cmd", "/C", "findstr . || exit 0"});
+#else
+ Subprocess p({"cat", "-"});
+#endif
+ p.args.stdout_mode = Subprocess::OutputMode::kBuffer;
+ p.args.input = ignored_input;
+ p.args.stdin_mode = Subprocess::InputMode::kDevNull;
+ EXPECT_TRUE(p.Call());
+ EXPECT_EQ(p.status(), Subprocess::kTerminated);
+ EXPECT_EQ(GetOutput(p), "");
+}
+
+TEST(SubprocessTest, BothStdoutAndStderrInputModeDevNull) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ Subprocess p({"cmd", "/c", "echo out&&(echo err>&2)&&echo out2"});
+#else
+ Subprocess p({"sh", "-c", "echo out; (echo err >&2); echo out2"});
+#endif
+ p.args.stdout_mode = Subprocess::OutputMode::kBuffer;
+ p.args.stderr_mode = Subprocess::OutputMode::kBuffer;
+ p.args.stdin_mode = Subprocess::InputMode::kDevNull;
+ EXPECT_TRUE(p.Call());
+ EXPECT_EQ(GetOutput(p), "out\nerr\nout2\n");
+}
+
+TEST(SubprocessTest, AllDevNull) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ Subprocess p({"cmd", "/c", "(exit 1)"});
+#else
+ Subprocess p({"false"});
+#endif
+ p.args.stdout_mode = Subprocess::OutputMode::kDevNull;
+ p.args.stderr_mode = Subprocess::OutputMode::kDevNull;
+ p.args.stdin_mode = Subprocess::InputMode::kDevNull;
+ EXPECT_FALSE(p.Call());
+ EXPECT_EQ(p.status(), Subprocess::kTerminated);
+ EXPECT_EQ(p.returncode(), 1);
+}
+
TEST(SubprocessTest, BinTrue) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
Subprocess p({"cmd", "/c", "(exit 0)"});
@@ -134,7 +176,7 @@ TEST(SubprocessTest, Echo) {
#else
Subprocess p({"echo", "-n", "foobar"});
#endif
- p.args.stdout_mode = Subprocess::kBuffer;
+ p.args.stdout_mode = Subprocess::OutputMode::kBuffer;
EXPECT_TRUE(p.Call());
EXPECT_EQ(p.status(), Subprocess::kTerminated);
EXPECT_EQ(p.returncode(), 0);
@@ -148,7 +190,7 @@ TEST(SubprocessTest, FeedbackLongInput) {
#else
Subprocess p({"cat", "-"});
#endif
- p.args.stdout_mode = Subprocess::kBuffer;
+ p.args.stdout_mode = Subprocess::OutputMode::kBuffer;
p.args.input = contents;
EXPECT_TRUE(p.Call());
EXPECT_EQ(p.status(), Subprocess::kTerminated);
@@ -166,7 +208,7 @@ TEST(SubprocessTest, CatLargeFile) {
#else
Subprocess p({"cat", tf.path().c_str()});
#endif
- p.args.stdout_mode = Subprocess::kBuffer;
+ p.args.stdout_mode = Subprocess::OutputMode::kBuffer;
EXPECT_TRUE(p.Call());
EXPECT_EQ(GetOutput(p), contents);
}
@@ -174,7 +216,7 @@ TEST(SubprocessTest, CatLargeFile) {
TEST(SubprocessTest, Timeout) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
Subprocess p({"ping", "127.0.0.1", "-n", "60"});
- p.args.stdout_mode = Subprocess::kDevNull;
+ p.args.stdout_mode = Subprocess::OutputMode::kDevNull;
#else
Subprocess p({"sleep", "60"});
#endif
@@ -187,7 +229,7 @@ TEST(SubprocessTest, Timeout) {
TEST(SubprocessTest, TimeoutNotHit) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
Subprocess p({"ping", "127.0.0.1", "-n", "1"});
- p.args.stdout_mode = Subprocess::kDevNull;
+ p.args.stdout_mode = Subprocess::OutputMode::kDevNull;
#else
Subprocess p({"sleep", "0.01"});
#endif
@@ -201,7 +243,7 @@ TEST(SubprocessTest, TimeoutStopOutput) {
#else
Subprocess p({"sh", "-c", "while true; do echo stuff; done"});
#endif
- p.args.stdout_mode = Subprocess::kDevNull;
+ p.args.stdout_mode = Subprocess::OutputMode::kDevNull;
EXPECT_FALSE(p.Call(/*timeout_ms=*/10));
EXPECT_EQ(p.status(), Subprocess::kTerminated);
EXPECT_TRUE(p.timed_out());
@@ -214,8 +256,8 @@ TEST(SubprocessTest, ExitBeforeReadingStdin) {
// 'sh -c' is to avoid closing stdin (sleep closes it before sleeping).
Subprocess p({"sh", "-c", "sleep 0.01"});
#endif
- p.args.stdout_mode = Subprocess::kDevNull;
- p.args.stderr_mode = Subprocess::kDevNull;
+ p.args.stdout_mode = Subprocess::OutputMode::kDevNull;
+ p.args.stderr_mode = Subprocess::OutputMode::kDevNull;
p.args.input = GenLargeString();
EXPECT_TRUE(p.Call());
EXPECT_EQ(p.status(), Subprocess::kTerminated);
@@ -232,8 +274,8 @@ TEST(SubprocessTest, StdinWriteStall) {
// still handle the timeout properly.
Subprocess p({"sh", "-c", "sleep 10"});
#endif
- p.args.stdout_mode = Subprocess::kDevNull;
- p.args.stderr_mode = Subprocess::kDevNull;
+ p.args.stdout_mode = Subprocess::OutputMode::kDevNull;
+ p.args.stderr_mode = Subprocess::OutputMode::kDevNull;
p.args.input = GenLargeString();
EXPECT_FALSE(p.Call(/*timeout_ms=*/10));
EXPECT_EQ(p.status(), Subprocess::kTerminated);
@@ -246,7 +288,7 @@ TEST(SubprocessTest, StartAndWait) {
#else
Subprocess p({"sleep", "1000"});
#endif
- p.args.stdout_mode = Subprocess::kDevNull;
+ p.args.stdout_mode = Subprocess::OutputMode::kDevNull;
p.Start();
EXPECT_EQ(p.Poll(), Subprocess::kRunning);
p.KillAndWaitForTermination();
@@ -267,7 +309,7 @@ TEST(SubprocessTest, PollBehavesProperly) {
#else
Subprocess p({"true"});
#endif
- p.args.stdout_mode = Subprocess::kFd;
+ p.args.stdout_mode = Subprocess::OutputMode::kFd;
p.args.out_fd = std::move(pipe.wr);
p.Start();
@@ -296,7 +338,7 @@ TEST(SubprocessTest, Wait) {
#else
Subprocess p({"sh", "-c", "echo exec_done; while true; do true; done"});
#endif
- p.args.stdout_mode = Subprocess::kBuffer;
+ p.args.stdout_mode = Subprocess::OutputMode::kBuffer;
p.Start();
// Wait for the fork()+exec() to complete.
@@ -365,7 +407,7 @@ TEST(SubprocessTest, MoveOperators) {
#else
Subprocess initial = Subprocess({"sleep", "10000"});
#endif
- initial.args.stdout_mode = Subprocess::kDevNull;
+ initial.args.stdout_mode = Subprocess::OutputMode::kDevNull;
initial.Start();
Subprocess moved(std::move(initial));
EXPECT_EQ(moved.Poll(), Subprocess::kRunning);
@@ -379,7 +421,7 @@ TEST(SubprocessTest, MoveOperators) {
#endif
initial.args.stdout_mode = Subprocess::OutputMode::kBuffer;
initial.Start();
- initial.Wait(/*timeout=*/5000);
+ initial.Wait(/*timeout_ms=*/5000);
EXPECT_EQ(initial.status(), Subprocess::kTerminated);
EXPECT_EQ(initial.returncode(), 0);
EXPECT_EQ(initial.output(), "hello");
@@ -406,7 +448,7 @@ TEST(SubprocessTest, MoveOperators) {
TEST(SubprocessTest, Entrypoint) {
Subprocess p;
p.args.input = "ping\n";
- p.args.stdout_mode = Subprocess::kBuffer;
+ p.args.stdout_mode = Subprocess::OutputMode::kBuffer;
p.args.posix_entrypoint_for_testing = [] {
char buf[32]{};
PERFETTO_CHECK(fgets(buf, sizeof(buf), stdin));
@@ -428,7 +470,7 @@ TEST(SubprocessTest, EntrypointAndExec) {
int pipe2_wr = *pipe2.wr;
Subprocess p({"echo", "123"});
- p.args.stdout_mode = Subprocess::kBuffer;
+ p.args.stdout_mode = Subprocess::OutputMode::kBuffer;
p.args.preserve_fds.push_back(pipe2_wr);
p.args.posix_entrypoint_for_testing = [pipe1_wr, pipe2_wr] {
base::ignore_result(write(pipe1_wr, "fail", 4));
diff --git a/src/base/subprocess_windows.cc b/src/base/subprocess_windows.cc
index d58d7bd24..12646550e 100644
--- a/src/base/subprocess_windows.cc
+++ b/src/base/subprocess_windows.cc
@@ -61,22 +61,26 @@ void Subprocess::Start() {
if (!cmd.empty())
cmd.resize(cmd.size() - 1);
- s_->stdin_pipe = Pipe::Create();
- // Allow the child process to inherit the other end of the pipe.
- PERFETTO_CHECK(
- ::SetHandleInformation(*s_->stdin_pipe.rd, HANDLE_FLAG_INHERIT, 1));
+ if (args.stdin_mode == InputMode::kBuffer) {
+ s_->stdin_pipe = Pipe::Create();
+ // Allow the child process to inherit the other end of the pipe.
+ PERFETTO_CHECK(
+ ::SetHandleInformation(*s_->stdin_pipe.rd, HANDLE_FLAG_INHERIT, 1));
+ }
- if (args.stderr_mode == kBuffer || args.stdout_mode == kBuffer) {
+ if (args.stderr_mode == OutputMode::kBuffer ||
+ args.stdout_mode == OutputMode::kBuffer) {
s_->stdouterr_pipe = Pipe::Create();
PERFETTO_CHECK(
::SetHandleInformation(*s_->stdouterr_pipe.wr, HANDLE_FLAG_INHERIT, 1));
}
ScopedPlatformHandle nul_handle;
- if (args.stderr_mode == kDevNull || args.stdout_mode == kDevNull) {
- nul_handle.reset(::CreateFileA("NUL", GENERIC_WRITE, FILE_SHARE_WRITE,
- nullptr, OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL, nullptr));
+ if (args.stderr_mode == OutputMode::kDevNull ||
+ args.stdout_mode == OutputMode::kDevNull) {
+ nul_handle.reset(::CreateFileA(
+ "NUL", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr));
PERFETTO_CHECK(::SetHandleInformation(*nul_handle, HANDLE_FLAG_INHERIT, 1));
}
@@ -84,13 +88,13 @@ void Subprocess::Start() {
STARTUPINFOA start_info{};
start_info.cb = sizeof(STARTUPINFOA);
- if (args.stderr_mode == kInherit) {
+ if (args.stderr_mode == OutputMode::kInherit) {
start_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
- } else if (args.stderr_mode == kBuffer) {
+ } else if (args.stderr_mode == OutputMode::kBuffer) {
start_info.hStdError = *s_->stdouterr_pipe.wr;
- } else if (args.stderr_mode == kDevNull) {
+ } else if (args.stderr_mode == OutputMode::kDevNull) {
start_info.hStdError = *nul_handle;
- } else if (args.stderr_mode == kFd) {
+ } else if (args.stderr_mode == OutputMode::kFd) {
PERFETTO_CHECK(
::SetHandleInformation(*args.out_fd, HANDLE_FLAG_INHERIT, 1));
start_info.hStdError = *args.out_fd;
@@ -98,13 +102,13 @@ void Subprocess::Start() {
PERFETTO_CHECK(false);
}
- if (args.stdout_mode == kInherit) {
+ if (args.stdout_mode == OutputMode::kInherit) {
start_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
- } else if (args.stdout_mode == kBuffer) {
+ } else if (args.stdout_mode == OutputMode::kBuffer) {
start_info.hStdOutput = *s_->stdouterr_pipe.wr;
- } else if (args.stdout_mode == kDevNull) {
+ } else if (args.stdout_mode == OutputMode::kDevNull) {
start_info.hStdOutput = *nul_handle;
- } else if (args.stdout_mode == kFd) {
+ } else if (args.stdout_mode == OutputMode::kFd) {
PERFETTO_CHECK(
::SetHandleInformation(*args.out_fd, HANDLE_FLAG_INHERIT, 1));
start_info.hStdOutput = *args.out_fd;
@@ -112,7 +116,12 @@ void Subprocess::Start() {
PERFETTO_CHECK(false);
}
- start_info.hStdInput = *s_->stdin_pipe.rd;
+ if (args.stdin_mode == InputMode::kBuffer) {
+ start_info.hStdInput = *s_->stdin_pipe.rd;
+ } else if (args.stdin_mode == InputMode::kDevNull) {
+ start_info.hStdInput = *nul_handle;
+ }
+
start_info.dwFlags |= STARTF_USESTDHANDLES;
// Create the child process.
@@ -149,9 +158,12 @@ void Subprocess::Start() {
s_->status = kRunning;
MovableState* s = s_.get();
- s_->stdin_thread = std::thread(&Subprocess::StdinThread, s, args.input);
+ if (args.stdin_mode == InputMode::kBuffer) {
+ s_->stdin_thread = std::thread(&Subprocess::StdinThread, s, args.input);
+ }
- if (args.stderr_mode == kBuffer || args.stdout_mode == kBuffer) {
+ if (args.stderr_mode == OutputMode::kBuffer ||
+ args.stdout_mode == OutputMode::kBuffer) {
PERFETTO_DCHECK(s_->stdouterr_pipe.rd);
s_->stdouterr_thread = std::thread(&Subprocess::StdoutErrThread, s);
}
@@ -222,14 +234,14 @@ bool Subprocess::Wait(int timeout_ms) {
const int64_t wait_start_ms = base::GetWallTimeMs().count();
// Break out of the loop only after both conditions are satisfied:
- // - All stdout/stderr data has been read (if kBuffer).
+ // - All stdout/stderr data has been read (if OutputMode::kBuffer).
// - The process exited.
// Note that the two events can happen arbitrary order. After the process
// exits, there might be still data in the pipe buffer, which we want to
// read fully.
// Note also that stdout/err might be "complete" before starting, if neither
- // is operating in kBuffer mode. In that case we just want to wait for the
- // process termination.
+ // is operating in OutputMode::kBuffer mode. In that case we just want to wait
+ // for the process termination.
//
// Instead, don't wait on the stdin to be fully written. The child process
// might exit prematurely (or crash). If that happens, we can end up in a
diff --git a/src/base/test/tmp_dir_tree.cc b/src/base/test/tmp_dir_tree.cc
new file mode 100644
index 000000000..9ed785f88
--- /dev/null
+++ b/src/base/test/tmp_dir_tree.cc
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/base/test/tmp_dir_tree.h"
+
+#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/scoped_file.h"
+
+namespace perfetto {
+namespace base {
+
+TmpDirTree::TmpDirTree() : tmp_dir_(base::TempDir::Create()) {}
+
+TmpDirTree::~TmpDirTree() {
+ for (; !files_to_remove_.empty(); files_to_remove_.pop()) {
+ PERFETTO_CHECK(remove(AbsolutePath(files_to_remove_.top()).c_str()) == 0);
+ }
+ for (; !dirs_to_remove_.empty(); dirs_to_remove_.pop()) {
+ base::Rmdir(AbsolutePath(dirs_to_remove_.top()));
+ }
+}
+
+std::string TmpDirTree::AbsolutePath(const std::string& relative_path) const {
+ return path() + "/" + relative_path;
+}
+
+void TmpDirTree::AddDir(const std::string& relative_path) {
+ dirs_to_remove_.push(relative_path);
+ PERFETTO_CHECK(base::Mkdir(AbsolutePath(relative_path)));
+}
+
+void TmpDirTree::AddFile(const std::string& relative_path,
+ const std::string& content) {
+ files_to_remove_.push(relative_path);
+ base::ScopedFile fd(base::OpenFile(AbsolutePath(relative_path),
+ O_WRONLY | O_CREAT | O_TRUNC, 0600));
+ PERFETTO_CHECK(base::WriteAll(fd.get(), content.c_str(), content.size()) ==
+ static_cast<ssize_t>(content.size()));
+}
+
+} // namespace base
+} // namespace perfetto
diff --git a/src/base/test/tmp_dir_tree.h b/src/base/test/tmp_dir_tree.h
new file mode 100644
index 000000000..6bb730c97
--- /dev/null
+++ b/src/base/test/tmp_dir_tree.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_BASE_TEST_TMP_DIR_TREE_H_
+#define SRC_BASE_TEST_TMP_DIR_TREE_H_
+
+#include <stack>
+#include <string>
+
+#include "perfetto/ext/base/temp_file.h"
+
+namespace perfetto {
+namespace base {
+
+// Helper to construct and automatically destroy temporary file hierarchies in
+// tests.
+class TmpDirTree {
+ public:
+ TmpDirTree();
+ virtual ~TmpDirTree();
+
+ // Returns the absolute path where the temporary hierarchy is located.
+ const std::string& path() const { return tmp_dir_.path(); }
+
+ // Prepends `path()` to `relative_path` (making it an absolute path).
+ std::string AbsolutePath(const std::string& relative_path) const;
+
+ // Creates a directory at `relative_path`. All the parent directories should
+ // have been created. PERFETTO_CHECK()s that the operation succeeds.
+ void AddDir(const std::string& relative_path);
+
+ // Creates a file at `relative_path` which contains `content`. All the parent
+ // directories should have been created. PERFETTO_CHECK()s that the operation
+ // succeeds.
+ void AddFile(const std::string& relative_path, const std::string& content);
+
+ private:
+ TmpDirTree(const TmpDirTree&) = delete;
+ TmpDirTree& operator=(const TmpDirTree&) = delete;
+
+ base::TempDir tmp_dir_;
+ std::stack<std::string> dirs_to_remove_;
+ std::stack<std::string> files_to_remove_;
+};
+
+} // namespace base
+} // namespace perfetto
+
+#endif // SRC_BASE_TEST_TMP_DIR_TREE_H_
diff --git a/src/base/test/utils.cc b/src/base/test/utils.cc
index 0a5661162..56e51a805 100644
--- a/src/base/test/utils.cc
+++ b/src/base/test/utils.cc
@@ -23,55 +23,11 @@
#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/file_utils.h"
-
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
- PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
- PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) || \
- PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
-#include <limits.h>
-#include <unistd.h>
-#endif
-
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
-#include <Windows.h>
-#include <io.h>
-#endif
-
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
-#include <mach-o/dyld.h>
-#endif
+#include "perfetto/ext/base/utils.h"
namespace perfetto {
namespace base {
-std::string GetCurExecutableDir() {
- std::string self_path;
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
- PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
- PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
- char buf[PATH_MAX];
- ssize_t size = readlink("/proc/self/exe", buf, sizeof(buf));
- PERFETTO_CHECK(size != -1);
- // readlink does not null terminate.
- self_path = std::string(buf, static_cast<size_t>(size));
-#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
- uint32_t size = 0;
- PERFETTO_CHECK(_NSGetExecutablePath(nullptr, &size));
- self_path.resize(size);
- PERFETTO_CHECK(_NSGetExecutablePath(&self_path[0], &size) == 0);
-#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
- char buf[MAX_PATH];
- auto len = ::GetModuleFileNameA(nullptr /*current*/, buf, sizeof(buf));
- self_path = std::string(buf, len);
- self_path = self_path.substr(0, self_path.find_last_of("\\"));
-#else
- PERFETTO_FATAL(
- "GetCurExecutableDir() not implemented on the current platform");
-#endif
- // Cut binary name.
- return self_path.substr(0, self_path.find_last_of("/"));
-}
-
std::string GetTestDataPath(const std::string& path) {
std::string self_path = GetCurExecutableDir();
std::string full_path = self_path + "/../../" + path;
@@ -84,28 +40,5 @@ std::string GetTestDataPath(const std::string& path) {
return path;
}
-std::string HexDump(const void* data_void, size_t len, size_t bytes_per_line) {
- const char* data = reinterpret_cast<const char*>(data_void);
- std::string res;
- static const size_t kPadding = bytes_per_line * 3 + 12;
- std::unique_ptr<char[]> line(new char[bytes_per_line * 4 + 128]);
- for (size_t i = 0; i < len; i += bytes_per_line) {
- char* wptr = line.get();
- wptr += sprintf(wptr, "%08zX: ", i);
- for (size_t j = i; j < i + bytes_per_line && j < len; j++)
- wptr += sprintf(wptr, "%02X ", static_cast<unsigned>(data[j]) & 0xFF);
- for (size_t j = static_cast<size_t>(wptr - line.get()); j < kPadding; ++j)
- *(wptr++) = ' ';
- for (size_t j = i; j < i + bytes_per_line && j < len; j++) {
- char c = data[j];
- *(wptr++) = (c >= 32 && c < 127) ? c : '.';
- }
- *(wptr++) = '\n';
- *(wptr++) = '\0';
- res.append(line.get());
- }
- return res;
-}
-
} // namespace base
} // namespace perfetto
diff --git a/src/base/test/utils.h b/src/base/test/utils.h
index e53b7863d..4dfc28132 100644
--- a/src/base/test/utils.h
+++ b/src/base/test/utils.h
@@ -50,16 +50,8 @@
namespace perfetto {
namespace base {
-std::string GetCurExecutableDir();
std::string GetTestDataPath(const std::string& path);
-// Returns a xxd-style hex dump (hex + ascii chars) of the input data.
-std::string HexDump(const void* data, size_t len, size_t bytes_per_line = 16);
-inline std::string HexDump(const std::string& data,
- size_t bytes_per_line = 16) {
- return HexDump(data.data(), data.size(), bytes_per_line);
-}
-
} // namespace base
} // namespace perfetto
diff --git a/src/base/unix_socket.cc b/src/base/unix_socket.cc
index 598691767..3088399e8 100644
--- a/src/base/unix_socket.cc
+++ b/src/base/unix_socket.cc
@@ -36,6 +36,7 @@
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
+#include <poll.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
@@ -51,6 +52,7 @@
#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
#include "perfetto/base/task_runner.h"
+#include "perfetto/base/time.h"
#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/utils.h"
@@ -66,16 +68,6 @@ namespace base {
namespace {
-// MSG_NOSIGNAL is not supported on Mac OS X, but in that case the socket is
-// created with SO_NOSIGPIPE (See InitializeSocket()).
-// On Windows this does't apply as signals don't exist.
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
-#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
-constexpr int kNoSigPipe = 0;
-#else
-constexpr int kNoSigPipe = MSG_NOSIGNAL;
-#endif
-
// Android takes an int instead of socklen_t for the control buffer size.
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
using CBufLenType = size_t;
@@ -431,19 +423,60 @@ ssize_t UnixSocketRaw::SendMsgAllPosix(struct msghdr* msg) {
// This does not make sense on non-blocking sockets.
PERFETTO_DCHECK(fd_);
+ const bool is_blocking_with_timeout =
+ tx_timeout_ms_ > 0 && ((fcntl(*fd_, F_GETFL, 0) & O_NONBLOCK) == 0);
+ const int64_t start_ms = GetWallTimeMs().count();
+
+ // Waits until some space is available in the tx buffer.
+ // Returns true if some buffer space is available, false if times out.
+ auto poll_or_timeout = [&] {
+ PERFETTO_DCHECK(is_blocking_with_timeout);
+ const int64_t deadline = start_ms + tx_timeout_ms_;
+ const int64_t now_ms = GetWallTimeMs().count();
+ if (now_ms >= deadline)
+ return false; // Timed out
+ const int timeout_ms = static_cast<int>(deadline - now_ms);
+ pollfd pfd{*fd_, POLLOUT, 0};
+ return PERFETTO_EINTR(poll(&pfd, 1, timeout_ms)) > 0;
+ };
+
+// We implement blocking sends that require a timeout as non-blocking + poll.
+// This is because SO_SNDTIMEO doesn't work as expected (b/193234818). On linux
+// we can just pass MSG_DONTWAIT to force the send to be non-blocking. On Mac,
+// instead we need to flip the O_NONBLOCK flag back and forth.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+ // MSG_NOSIGNAL is not supported on Mac OS X, but in that case the socket is
+ // created with SO_NOSIGPIPE (See InitializeSocket()).
+ int send_flags = 0;
+
+ if (is_blocking_with_timeout)
+ SetBlocking(false);
+
+ auto reset_nonblock_on_exit = OnScopeExit([&] {
+ if (is_blocking_with_timeout)
+ SetBlocking(true);
+ });
+#else
+ int send_flags = MSG_NOSIGNAL | (is_blocking_with_timeout ? MSG_DONTWAIT : 0);
+#endif
+
ssize_t total_sent = 0;
while (msg->msg_iov) {
- ssize_t sent = PERFETTO_EINTR(sendmsg(*fd_, msg, kNoSigPipe));
- if (sent <= 0) {
- if (sent == -1 && IsAgain(errno))
- return total_sent;
- return sent;
+ ssize_t send_res = PERFETTO_EINTR(sendmsg(*fd_, msg, send_flags));
+ if (send_res == -1 && IsAgain(errno)) {
+ if (is_blocking_with_timeout && poll_or_timeout()) {
+ continue; // Tx buffer unblocked, repeat the loop.
+ }
+ return total_sent;
+ } else if (send_res <= 0) {
+ return send_res; // An error occurred.
+ } else {
+ total_sent += send_res;
+ ShiftMsgHdrPosix(static_cast<size_t>(send_res), msg);
+ // Only send the ancillary data with the first sendmsg call.
+ msg->msg_control = nullptr;
+ msg->msg_controllen = 0;
}
- total_sent += sent;
- ShiftMsgHdrPosix(static_cast<size_t>(sent), msg);
- // Only send the ancillary data with the first sendmsg call.
- msg->msg_control = nullptr;
- msg->msg_controllen = 0;
}
return total_sent;
}
@@ -541,8 +574,14 @@ ssize_t UnixSocketRaw::Receive(void* msg,
bool UnixSocketRaw::SetTxTimeout(uint32_t timeout_ms) {
PERFETTO_DCHECK(fd_);
+ // On Unix-based systems, SO_SNDTIMEO isn't used for Send() because it's
+ // unreliable (b/193234818). Instead we use non-blocking sendmsg() + poll().
+ // See SendMsgAllPosix(). We still make the setsockopt call because
+ // SO_SNDTIMEO also affects connect().
+ tx_timeout_ms_ = timeout_ms;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
DWORD timeout = timeout_ms;
+ ignore_result(tx_timeout_ms_);
#else
struct timeval timeout {};
uint32_t timeout_sec = timeout_ms / 1000;
diff --git a/src/base/unix_socket_unittest.cc b/src/base/unix_socket_unittest.cc
index 9ef69c961..45c09d53e 100644
--- a/src/base/unix_socket_unittest.cc
+++ b/src/base/unix_socket_unittest.cc
@@ -30,6 +30,7 @@
#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/periodic_task.h"
#include "perfetto/ext/base/pipe.h"
#include "perfetto/ext/base/temp_file.h"
#include "perfetto/ext/base/utils.h"
@@ -131,8 +132,8 @@ TEST_F(UnixSocketTest, ConnectionImmediatelyDroppedByServer) {
// On Windows the first send immediately after the disconnection succeeds, the
// kernel will detect the disconnection only later.
- cli->Send(".");
- EXPECT_FALSE(cli->Send("should_fail_both_on_win_and_unix"));
+ cli->SendStr(".");
+ EXPECT_FALSE(cli->SendStr("should_fail_both_on_win_and_unix"));
task_runner_.RunUntilCheckpoint("cli_disconnected");
}
@@ -177,8 +178,8 @@ TEST_F(UnixSocketTest, ClientAndServerExchangeData) {
ASSERT_EQ("cli>srv", s->ReceiveString());
srv_did_recv();
}));
- ASSERT_TRUE(cli->Send("cli>srv"));
- ASSERT_TRUE(srv_conn->Send("srv>cli"));
+ ASSERT_TRUE(cli->SendStr("cli>srv"));
+ ASSERT_TRUE(srv_conn->SendStr("srv>cli"));
task_runner_.RunUntilCheckpoint("cli_did_recv");
task_runner_.RunUntilCheckpoint("srv_did_recv");
@@ -192,8 +193,8 @@ TEST_F(UnixSocketTest, ClientAndServerExchangeData) {
ASSERT_EQ("", cli->ReceiveString());
ASSERT_EQ(0u, srv_conn->Receive(&msg, sizeof(msg)));
ASSERT_EQ("", srv_conn->ReceiveString());
- ASSERT_FALSE(cli->Send("foo"));
- ASSERT_FALSE(srv_conn->Send("bar"));
+ ASSERT_FALSE(cli->SendStr("foo"));
+ ASSERT_FALSE(srv_conn->SendStr("bar"));
srv->Shutdown(true);
task_runner_.RunUntilCheckpoint("cli_disconnected");
task_runner_.RunUntilCheckpoint("srv_disconnected");
@@ -250,7 +251,7 @@ TEST_F(UnixSocketTest, SeveralClients) {
EXPECT_CALL(event_listener_, OnDataAvailable(s))
.WillOnce(Invoke([](UnixSocket* t) {
ASSERT_EQ("PING", t->ReceiveString());
- ASSERT_TRUE(t->Send("PONG"));
+ ASSERT_TRUE(t->SendStr("PONG"));
}));
}));
@@ -261,7 +262,7 @@ TEST_F(UnixSocketTest, SeveralClients) {
EXPECT_CALL(event_listener_, OnConnect(cli[i].get(), true))
.WillOnce(Invoke([](UnixSocket* s, bool success) {
ASSERT_TRUE(success);
- ASSERT_TRUE(s->Send("PING"));
+ ASSERT_TRUE(s->SendStr("PING"));
}));
auto checkpoint = task_runner_.CreateCheckpoint(std::to_string(i));
@@ -318,10 +319,10 @@ TEST_F(UnixSocketTest, BlockingSend) {
tx_task_runner.RunUntilCheckpoint("cli_connected");
auto all_sent = tx_task_runner.CreateCheckpoint("all_sent");
- char buf[1024 * 32] = {};
+ std::string buf(1024 * 32, '\0');
tx_task_runner.PostTask([&cli, &buf, all_sent] {
- for (size_t i = 0; i < kTotalBytes / sizeof(buf); i++)
- cli->Send(buf, sizeof(buf));
+ for (size_t i = 0; i < kTotalBytes / buf.size(); i++)
+ cli->Send(buf.data(), buf.size());
all_sent();
});
tx_task_runner.RunUntilCheckpoint("all_sent", kTimeoutMs);
@@ -405,7 +406,7 @@ TEST_F(UnixSocketTest, ReleaseSocket) {
task_runner_.RunUntilCheckpoint("cli_connected");
srv->Shutdown(true);
- cli->Send("test");
+ cli->SendStr("test");
ASSERT_NE(peer, nullptr);
auto raw_sock = peer->ReleaseSocket();
@@ -413,10 +414,10 @@ TEST_F(UnixSocketTest, ReleaseSocket) {
EXPECT_CALL(event_listener_, OnDataAvailable(_)).Times(0);
task_runner_.RunUntilIdle();
- char buf[sizeof("test")];
+ char buf[5];
ASSERT_TRUE(raw_sock);
- ASSERT_EQ(raw_sock.Receive(buf, sizeof(buf)),
- static_cast<ssize_t>(sizeof(buf)));
+ ASSERT_EQ(raw_sock.Receive(buf, sizeof(buf)), 4);
+ buf[sizeof(buf) - 1] = '\0';
ASSERT_STREQ(buf, "test");
}
@@ -445,7 +446,7 @@ TEST_F(UnixSocketTest, TcpStream) {
.WillRepeatedly(Invoke([](UnixSocket* cli_sock) {
cli_sock->ReceiveString(); // Read connection EOF;
}));
- ASSERT_TRUE(s->Send("welcome"));
+ ASSERT_TRUE(s->SendStr("welcome"));
}));
for (size_t i = 0; i < kNumClients; i++) {
@@ -717,7 +718,7 @@ TEST_F(UnixSocketTest, SharedMemory) {
// Now change the shared memory and ping the other process.
memcpy(mem, "rock more", 10);
- ASSERT_TRUE(s->Send("change notify"));
+ ASSERT_TRUE(s->SendStr("change notify"));
checkpoint();
}));
task_runner_.RunUntilCheckpoint("change_seen_by_client");
@@ -834,11 +835,11 @@ TEST_F(UnixSocketTest, PartialSendMsgAll) {
// Send something larger than send + recv kernel buffers combined to make
// sendmsg block.
- char send_buf[8192];
+ std::string send_buf(8192, '\0');
// Make MSAN happy.
- for (size_t i = 0; i < sizeof(send_buf); ++i)
+ for (size_t i = 0; i < send_buf.size(); ++i)
send_buf[i] = static_cast<char>(i % 256);
- char recv_buf[sizeof(send_buf)];
+ std::string recv_buf(send_buf.size(), '\0');
// Need to install signal handler to cause the interrupt to happen.
// man 3 pthread_kill:
@@ -855,15 +856,15 @@ TEST_F(UnixSocketTest, PartialSendMsgAll) {
auto blocked_thread = pthread_self();
std::thread th([blocked_thread, &recv_sock, &recv_buf] {
- ssize_t rd = PERFETTO_EINTR(read(recv_sock.fd(), recv_buf, 1));
+ ssize_t rd = PERFETTO_EINTR(read(recv_sock.fd(), &recv_buf[0], 1));
ASSERT_EQ(rd, 1);
// We are now sure the other thread is in sendmsg, interrupt send.
ASSERT_EQ(pthread_kill(blocked_thread, SIGWINCH), 0);
// Drain the socket to allow SendMsgAllPosix to succeed.
size_t offset = 1;
- while (offset < sizeof(recv_buf)) {
+ while (offset < recv_buf.size()) {
rd = PERFETTO_EINTR(
- read(recv_sock.fd(), recv_buf + offset, sizeof(recv_buf) - offset));
+ read(recv_sock.fd(), &recv_buf[offset], recv_buf.size() - offset));
ASSERT_GE(rd, 0);
offset += static_cast<size_t>(rd);
}
@@ -873,23 +874,70 @@ TEST_F(UnixSocketTest, PartialSendMsgAll) {
// more complicated code-paths of SendMsgAllPosix.
struct msghdr hdr = {};
struct iovec iov[4];
- static_assert(sizeof(send_buf) % base::ArraySize(iov) == 0,
- "Cannot split buffer into even pieces.");
- constexpr size_t kChunkSize = sizeof(send_buf) / base::ArraySize(iov);
+ ASSERT_EQ(send_buf.size() % base::ArraySize(iov), 0u)
+ << "Cannot split buffer into even pieces.";
+ const size_t kChunkSize = send_buf.size() / base::ArraySize(iov);
for (size_t i = 0; i < base::ArraySize(iov); ++i) {
- iov[i].iov_base = send_buf + i * kChunkSize;
+ iov[i].iov_base = &send_buf[i * kChunkSize];
iov[i].iov_len = kChunkSize;
}
hdr.msg_iov = iov;
hdr.msg_iovlen = base::ArraySize(iov);
ASSERT_EQ(send_sock.SendMsgAllPosix(&hdr),
- static_cast<ssize_t>(sizeof(send_buf)));
+ static_cast<ssize_t>(send_buf.size()));
send_sock.Shutdown();
th.join();
// Make sure the re-entry logic was actually triggered.
ASSERT_EQ(hdr.msg_iov, nullptr);
- ASSERT_EQ(memcmp(send_buf, recv_buf, sizeof(send_buf)), 0);
+ ASSERT_EQ(memcmp(&send_buf[0], &recv_buf[0], send_buf.size()), 0);
+}
+
+// Regression test for b/193234818. SO_SNDTIMEO is unreliable on most systems.
+// It doesn't guarantee that the whole send() call blocks for at most X, as the
+// kernel rearms the timeout if the send buffers frees up and allows a partial
+// send. This test reproduces the issue 100% on Mac. Unfortunately on Linux the
+// repro seem to happen only when a suspend happens in the middle.
+TEST_F(UnixSocketTest, BlockingSendTimeout) {
+ TestTaskRunner ttr;
+ UnixSocketRaw send_sock;
+ UnixSocketRaw recv_sock;
+ std::tie(send_sock, recv_sock) =
+ UnixSocketRaw::CreatePairPosix(kTestSocket.family(), SockType::kStream);
+
+ auto blocking_send_done = ttr.CreateCheckpoint("blocking_send_done");
+
+ std::thread tx_thread([&] {
+ // Fill the tx buffer in non-blocking mode.
+ send_sock.SetBlocking(false);
+ char buf[1024 * 16]{};
+ while (send_sock.Send(buf, sizeof(buf)) > 0) {
+ }
+
+ // Then do a blocking send. It should return a partial value within the tx
+ // timeout.
+ send_sock.SetBlocking(true);
+ send_sock.SetTxTimeout(10);
+ ASSERT_LT(send_sock.Send(buf, sizeof(buf)),
+ static_cast<ssize_t>(sizeof(buf)));
+ ttr.PostTask(blocking_send_done);
+ });
+
+ // This task needs to be slow enough so that doesn't unblock the send, but
+ // fast enough so that within a blocking cycle, the send re-attempts and
+ // re-arms the timeout.
+ PeriodicTask read_slowly_task(&ttr);
+ PeriodicTask::Args args;
+ args.period_ms = 1; // Read 1 byte every ms (1 KiB/s).
+ args.task = [&] {
+ char rxbuf[1]{};
+ recv_sock.Receive(rxbuf, sizeof(rxbuf));
+ };
+ read_slowly_task.Start(args);
+
+ ttr.RunUntilCheckpoint("blocking_send_done");
+ read_slowly_task.Reset();
+ tx_thread.join();
}
#endif // !OS_WIN
diff --git a/src/base/utils.cc b/src/base/utils.cc
index d5bd5a0d7..b4da80cb1 100644
--- a/src/base/utils.cc
+++ b/src/base/utils.cc
@@ -14,22 +14,34 @@
* limitations under the License.
*/
-#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/utils.h"
+#include <string>
+
#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/file_utils.h"
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
- PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+ PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) || \
+ PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+#include <limits.h>
+#include <stdlib.h> // For _exit()
#include <unistd.h> // For getpagesize() and geteuid() & fork()
#endif
#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#include <mach-o/dyld.h>
#include <mach/vm_page_size.h>
#endif
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#include <io.h>
+#include <malloc.h> // For _aligned_malloc().
+#endif
+
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
#include <dlfcn.h>
#include <malloc.h>
@@ -39,7 +51,7 @@
#else
// Only available in in-tree builds and on newer SDKs.
#define PERFETTO_M_PURGE -101
-#endif
+#endif // M_PURGE
namespace {
extern "C" {
@@ -48,6 +60,57 @@ using MalloptType = void (*)(int, int);
} // namespace
#endif // OS_ANDROID
+namespace {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_X64_CPU_OPT)
+
+// Preserve the %rbx register via %rdi to work around a clang bug
+// https://bugs.llvm.org/show_bug.cgi?id=17907 (%rbx in an output constraint
+// is not considered a clobbered register).
+#define PERFETTO_GETCPUID(a, b, c, d, a_inp, c_inp) \
+ asm("mov %%rbx, %%rdi\n" \
+ "cpuid\n" \
+ "xchg %%rdi, %%rbx\n" \
+ : "=a"(a), "=D"(b), "=c"(c), "=d"(d) \
+ : "a"(a_inp), "2"(c_inp))
+
+uint32_t GetXCR0EAX() {
+ uint32_t eax = 0, edx = 0;
+ asm("xgetbv" : "=a"(eax), "=d"(edx) : "c"(0));
+ return eax;
+}
+
+// If we are building with -msse4 check that the CPU actually supports it.
+// This file must be kept in sync with gn/standalone/BUILD.gn.
+void PERFETTO_EXPORT __attribute__((constructor)) CheckCpuOptimizations() {
+ uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
+ PERFETTO_GETCPUID(eax, ebx, ecx, edx, 1, 0);
+
+ static constexpr uint64_t xcr0_xmm_mask = 0x2;
+ static constexpr uint64_t xcr0_ymm_mask = 0x4;
+ static constexpr uint64_t xcr0_avx_mask = xcr0_xmm_mask | xcr0_ymm_mask;
+
+ const bool have_popcnt = ecx & (1u << 23);
+ const bool have_sse4_2 = ecx & (1u << 20);
+ const bool have_avx =
+ // Does the OS save/restore XMM and YMM state?
+ (ecx & (1u << 27)) && // OS support XGETBV.
+ (ecx & (1u << 28)) && // AVX supported in hardware
+ ((GetXCR0EAX() & xcr0_avx_mask) == xcr0_avx_mask);
+
+ if (!have_sse4_2 || !have_popcnt || !have_avx) {
+ fprintf(
+ stderr,
+ "This executable requires a cpu that supports SSE4.2 and AVX2.\n"
+ "Rebuild with enable_perfetto_x64_cpu_opt=false (ebx=%x, ecx=%x).\n",
+ ebx, ecx);
+ _exit(126);
+ }
+}
+#endif
+
+} // namespace
+
namespace perfetto {
namespace base {
@@ -109,36 +172,121 @@ void SetEnv(const std::string& key, const std::string& value) {
#endif
}
-void Daemonize() {
- #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
- PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
- PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
- pid_t pid;
- switch (pid = fork()) {
- case -1:
- PERFETTO_FATAL("fork");
- case 0: {
- PERFETTO_CHECK(setsid() != -1);
- base::ignore_result(chdir("/"));
- base::ScopedFile null = base::OpenFile("/dev/null", O_RDONLY);
- PERFETTO_CHECK(null);
- PERFETTO_CHECK(dup2(*null, STDIN_FILENO) != -1);
- PERFETTO_CHECK(dup2(*null, STDOUT_FILENO) != -1);
- PERFETTO_CHECK(dup2(*null, STDERR_FILENO) != -1);
- // Do not accidentally close stdin/stdout/stderr.
- if (*null <= 2)
- null.release();
- break;
- }
- default:
- printf("%d\n", pid);
- exit(0);
- }
- #else
- // Avoid -Wunreachable warnings.
- if (reinterpret_cast<intptr_t>(&Daemonize) != 16)
- PERFETTO_FATAL("--background is only supported on Linux/Android/Mac");
- #endif // OS_WIN
+void Daemonize(std::function<int()> parent_cb) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+ PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+ PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+ pid_t pid;
+ switch (pid = fork()) {
+ case -1:
+ PERFETTO_FATAL("fork");
+ case 0: {
+ PERFETTO_CHECK(setsid() != -1);
+ base::ignore_result(chdir("/"));
+ base::ScopedFile null = base::OpenFile("/dev/null", O_RDONLY);
+ PERFETTO_CHECK(null);
+ PERFETTO_CHECK(dup2(*null, STDIN_FILENO) != -1);
+ PERFETTO_CHECK(dup2(*null, STDOUT_FILENO) != -1);
+ PERFETTO_CHECK(dup2(*null, STDERR_FILENO) != -1);
+ // Do not accidentally close stdin/stdout/stderr.
+ if (*null <= 2)
+ null.release();
+ break;
+ }
+ default:
+ printf("%d\n", pid);
+ int err = parent_cb();
+ exit(err);
+ }
+#else
+ // Avoid -Wunreachable warnings.
+ if (reinterpret_cast<intptr_t>(&Daemonize) != 16)
+ PERFETTO_FATAL("--background is only supported on Linux/Android/Mac");
+ ignore_result(parent_cb);
+#endif // OS_WIN
+}
+
+std::string GetCurExecutablePath() {
+ std::string self_path;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+ PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+ PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+ char buf[PATH_MAX];
+ ssize_t size = readlink("/proc/self/exe", buf, sizeof(buf));
+ PERFETTO_CHECK(size != -1);
+ // readlink does not null terminate.
+ self_path = std::string(buf, static_cast<size_t>(size));
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+ uint32_t size = 0;
+ PERFETTO_CHECK(_NSGetExecutablePath(nullptr, &size));
+ self_path.resize(size);
+ PERFETTO_CHECK(_NSGetExecutablePath(&self_path[0], &size) == 0);
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ char buf[MAX_PATH];
+ auto len = ::GetModuleFileNameA(nullptr /*current*/, buf, sizeof(buf));
+ self_path = std::string(buf, len);
+#else
+ PERFETTO_FATAL(
+ "GetCurExecutableDir() not implemented on the current platform");
+#endif
+ return self_path;
+}
+
+std::string GetCurExecutableDir() {
+ auto path = GetCurExecutablePath();
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ // Paths in Windows can have both kinds of slashes (mingw vs msvc).
+ path = path.substr(0, path.find_last_of('\\'));
+#endif
+ path = path.substr(0, path.find_last_of('/'));
+ return path;
+}
+
+void* AlignedAlloc(size_t alignment, size_t size) {
+ void* res = nullptr;
+ alignment = AlignUp<sizeof(void*)>(alignment); // At least pointer size.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ // Window's _aligned_malloc() has a nearly identically signature to Unix's
+ // aligned_alloc() but its arguments are obviously swapped.
+ res = _aligned_malloc(size, alignment);
+#else
+ // aligned_alloc() has been introduced in Android only in API 28.
+ // Also NaCl and Fuchsia seems to have only posix_memalign().
+ ignore_result(posix_memalign(&res, alignment, size));
+#endif
+ PERFETTO_CHECK(res);
+ return res;
+}
+
+void AlignedFree(void* ptr) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ _aligned_free(ptr); // MSDN says it is fine to pass nullptr.
+#else
+ free(ptr);
+#endif
+}
+
+std::string HexDump(const void* data_void, size_t len, size_t bytes_per_line) {
+ const char* data = reinterpret_cast<const char*>(data_void);
+ std::string res;
+ static const size_t kPadding = bytes_per_line * 3 + 12;
+ std::unique_ptr<char[]> line(new char[bytes_per_line * 4 + 128]);
+ for (size_t i = 0; i < len; i += bytes_per_line) {
+ char* wptr = line.get();
+ wptr += sprintf(wptr, "%08zX: ", i);
+ for (size_t j = i; j < i + bytes_per_line && j < len; j++)
+ wptr += sprintf(wptr, "%02X ", static_cast<unsigned>(data[j]) & 0xFF);
+ for (size_t j = static_cast<size_t>(wptr - line.get()); j < kPadding; ++j)
+ *(wptr++) = ' ';
+ for (size_t j = i; j < i + bytes_per_line && j < len; j++) {
+ char c = data[j];
+ *(wptr++) = (c >= 32 && c < 127) ? c : '.';
+ }
+ *(wptr++) = '\n';
+ *(wptr++) = '\0';
+ res.append(line.get());
+ }
+ return res;
}
} // namespace base
diff --git a/src/base/utils_unittest.cc b/src/base/utils_unittest.cc
index ef6e65767..b75ec05e6 100644
--- a/src/base/utils_unittest.cc
+++ b/src/base/utils_unittest.cc
@@ -202,6 +202,19 @@ TEST(UtilsTest, Align) {
EXPECT_EQ(0xffffff00u, AlignUp<16>(0xffffff00 - 1));
}
+TEST(UtilsTest, HexDump) {
+ char input[] = {0x00, 0x00, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'};
+
+ std::string output = HexDump(input, sizeof(input));
+
+ EXPECT_EQ(
+ output,
+ R"(00000000: 00 00 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E ..abcdefghijklmn
+00000010: 6F 70 op
+)");
+}
+
} // namespace
} // namespace base
} // namespace perfetto
diff --git a/src/base/watchdog_posix.cc b/src/base/watchdog_posix.cc
index fea7cd9d1..b92e9cec1 100644
--- a/src/base/watchdog_posix.cc
+++ b/src/base/watchdog_posix.cc
@@ -19,16 +19,24 @@
#if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
#include <fcntl.h>
-#include <inttypes.h>
+#include <poll.h>
#include <signal.h>
#include <stdint.h>
+#include <stdlib.h>
+#include <sys/syscall.h>
+#include <sys/timerfd.h>
+#include <unistd.h>
+#include <algorithm>
+#include <cinttypes>
#include <fstream>
#include <thread>
#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
#include "perfetto/base/thread_utils.h"
+#include "perfetto/base/time.h"
+#include "perfetto/ext/base/crash_keys.h"
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/scoped_file.h"
#include "perfetto/ext/base/utils.h"
@@ -40,6 +48,8 @@ namespace {
constexpr uint32_t kDefaultPollingInterval = 30 * 1000;
+base::CrashKey g_crash_key_reason("wdog_reason");
+
bool IsMultipleOf(uint32_t number, uint32_t divisor) {
return number >= divisor && number % divisor == 0;
}
@@ -50,7 +60,6 @@ double MeanForArray(const uint64_t array[], size_t size) {
total += array[i];
}
return static_cast<double>(total / size);
-
}
} // namespace
@@ -91,7 +100,16 @@ Watchdog::~Watchdog() {
}
PERFETTO_DCHECK(enabled_);
enabled_ = false;
- exit_signal_.notify_one();
+
+ // Rearm the timer to 1ns from now. This will cause the watchdog thread to
+ // wakeup from the poll() and see |enabled_| == false.
+ // This code path is used only in tests. In production code the watchdog is
+ // a singleton and is never destroyed.
+ struct itimerspec ts {};
+ ts.it_value.tv_sec = 0;
+ ts.it_value.tv_nsec = 1;
+ timerfd_settime(*timer_fd_, /*flags=*/0, &ts, nullptr);
+
thread_.join();
}
@@ -100,11 +118,49 @@ Watchdog* Watchdog::GetInstance() {
return watchdog;
}
-Watchdog::Timer Watchdog::CreateFatalTimer(uint32_t ms) {
+// Can be called from any thread.
+Watchdog::Timer Watchdog::CreateFatalTimer(uint32_t ms,
+ WatchdogCrashReason crash_reason) {
if (!enabled_.load(std::memory_order_relaxed))
- return Watchdog::Timer(0);
+ return Watchdog::Timer(this, 0, crash_reason);
+
+ return Watchdog::Timer(this, ms, crash_reason);
+}
+
+// Can be called from any thread.
+void Watchdog::AddFatalTimer(TimerData timer) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ timers_.emplace_back(std::move(timer));
+ RearmTimerFd_Locked();
+}
+
+// Can be called from any thread.
+void Watchdog::RemoveFatalTimer(TimerData timer) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ for (auto it = timers_.begin(); it != timers_.end(); it++) {
+ if (*it == timer) {
+ timers_.erase(it);
+ break; // Remove only one. Doesn't matter which one.
+ }
+ }
+ RearmTimerFd_Locked();
+}
- return Watchdog::Timer(ms);
+void Watchdog::RearmTimerFd_Locked() {
+ if (!enabled_)
+ return;
+ auto it = std::min_element(timers_.begin(), timers_.end());
+
+ // We use one timerfd to handle all the oustanding |timers_|. Keep it armed
+ // to the task expiring soonest.
+ struct itimerspec ts {};
+ if (it != timers_.end()) {
+ ts.it_value = ToPosixTimespec(it->deadline);
+ }
+ // If |timers_| is empty (it == end()) |ts.it_value| will remain
+ // zero-initialized and that will disarm the timer in the call below.
+ int res = timerfd_settime(*timer_fd_, TFD_TIMER_ABSTIME, &ts, nullptr);
+ PERFETTO_DCHECK(res == 0);
}
void Watchdog::Start() {
@@ -117,7 +173,15 @@ void Watchdog::Start() {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
// Kick the thread to start running but only on Android or Linux.
+ timer_fd_.reset(
+ timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK));
+ if (!timer_fd_) {
+ PERFETTO_PLOG(
+ "timerfd_create failed, the Perfetto watchdog is not available");
+ return;
+ }
enabled_ = true;
+ RearmTimerFd_Locked(); // Deal with timers created before Start().
thread_ = std::thread(&Watchdog::ThreadMain, this);
#endif
}
@@ -147,55 +211,143 @@ void Watchdog::SetCpuLimit(uint32_t percentage, uint32_t window_ms) {
}
void Watchdog::ThreadMain() {
+ // Register crash keys explicitly to avoid running out of slots at crash time.
+ g_crash_key_reason.Register();
+
base::ScopedFile stat_fd(base::OpenFile("/proc/self/stat", O_RDONLY));
if (!stat_fd) {
PERFETTO_ELOG("Failed to open stat file to enforce resource limits.");
return;
}
- std::unique_lock<std::mutex> guard(mutex_);
+ PERFETTO_DCHECK(timer_fd_);
+
+ constexpr uint8_t kFdCount = 1;
+ struct pollfd fds[kFdCount]{};
+ fds[0].fd = *timer_fd_;
+ fds[0].events = POLLIN;
+
for (;;) {
- exit_signal_.wait_for(guard,
- std::chrono::milliseconds(polling_interval_ms_));
+ // We use the poll() timeout to drive the periodic ticks for the cpu/memory
+ // checks. The only other case when the poll() unblocks is when we crash
+ // (or have to quit via enabled_ == false, but that happens only in tests).
+ auto ret = poll(fds, kFdCount, static_cast<int>(polling_interval_ms_));
if (!enabled_)
return;
+ if (ret < 0) {
+ if (errno == ENOMEM || errno == EINTR) {
+ // Should happen extremely rarely.
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ continue;
+ }
+ PERFETTO_FATAL("watchdog poll() failed");
+ }
- lseek(stat_fd.get(), 0, SEEK_SET);
-
- ProcStat stat;
- if (!ReadProcStat(stat_fd.get(), &stat)) {
- return;
+ // If we get here either:
+ // 1. poll() timed out, in which case we should process cpu/mem guardrails.
+ // 2. A timer expired, in which case we shall crash.
+
+ uint64_t expired = 0; // Must be exactly 8 bytes.
+ auto res = PERFETTO_EINTR(read(*timer_fd_, &expired, sizeof(expired)));
+ PERFETTO_DCHECK((res < 0 && (errno == EAGAIN)) ||
+ (res == sizeof(expired) && expired > 0));
+ const auto now = GetWallTimeMs();
+
+ // Check if any of the timers expired.
+ int tid_to_kill = 0;
+ WatchdogCrashReason crash_reason{};
+ std::unique_lock<std::mutex> guard(mutex_);
+ for (const auto& timer : timers_) {
+ if (now >= timer.deadline) {
+ tid_to_kill = timer.thread_id;
+ crash_reason = timer.crash_reason;
+ break;
+ }
}
+ guard.unlock();
+
+ if (tid_to_kill)
+ SerializeLogsAndKillThread(tid_to_kill, crash_reason);
+ // Check CPU and memory guardrails (if enabled).
+ lseek(stat_fd.get(), 0, SEEK_SET);
+ ProcStat stat;
+ if (!ReadProcStat(stat_fd.get(), &stat))
+ continue;
uint64_t cpu_time = stat.utime + stat.stime;
uint64_t rss_bytes =
static_cast<uint64_t>(stat.rss_pages) * base::GetSysPageSize();
- CheckMemory(rss_bytes);
- CheckCpu(cpu_time);
+ bool threshold_exceeded = false;
+ guard.lock();
+ if (CheckMemory_Locked(rss_bytes)) {
+ threshold_exceeded = true;
+ crash_reason = WatchdogCrashReason::kMemGuardrail;
+ } else if (CheckCpu_Locked(cpu_time)) {
+ threshold_exceeded = true;
+ crash_reason = WatchdogCrashReason::kCpuGuardrail;
+ }
+ guard.unlock();
+
+ if (threshold_exceeded)
+ SerializeLogsAndKillThread(getpid(), crash_reason);
}
}
-void Watchdog::CheckMemory(uint64_t rss_bytes) {
- if (memory_limit_bytes_ == 0)
+void Watchdog::SerializeLogsAndKillThread(int tid,
+ WatchdogCrashReason crash_reason) {
+ g_crash_key_reason.Set(static_cast<int>(crash_reason));
+
+ // We are about to die. Serialize the logs into the crash buffer so the
+ // debuggerd crash handler picks them up and attaches to the bugreport.
+ // In the case of a PERFETTO_CHECK/PERFETTO_FATAL this is done in logging.h.
+ // But in the watchdog case, we don't hit that codepath and must do ourselves.
+ MaybeSerializeLastLogsForCrashReporting();
+
+ // Send a SIGABRT to the thread that armed the timer. This is to see the
+ // callstack of the thread that is stuck in a long task rather than the
+ // watchdog thread.
+ if (syscall(__NR_tgkill, getpid(), tid, SIGABRT) < 0) {
+ // At this point the process must die. If for any reason the tgkill doesn't
+ // work (e.g. the thread has disappeared), force a crash from here.
+ abort();
+ }
+
+ if (disable_kill_failsafe_for_testing_)
return;
+ // The tgkill() above will take some milliseconds to cause a crash, as it
+ // involves the kernel to queue the SIGABRT on the target thread (often the
+ // main thread, which is != watchdog thread) and do a scheduling round.
+ // If something goes wrong though (the target thread has signals masked or
+ // is stuck in an uninterruptible+wakekill syscall) force quit from this
+ // thread.
+ std::this_thread::sleep_for(std::chrono::seconds(10));
+ abort();
+}
+
+bool Watchdog::CheckMemory_Locked(uint64_t rss_bytes) {
+ if (memory_limit_bytes_ == 0)
+ return false;
+
// Add the current stat value to the ring buffer and check that the mean
// remains under our threshold.
if (memory_window_bytes_.Push(rss_bytes)) {
- if (memory_window_bytes_.Mean() > static_cast<double>(memory_limit_bytes_)) {
+ if (memory_window_bytes_.Mean() >
+ static_cast<double>(memory_limit_bytes_)) {
PERFETTO_ELOG(
"Memory watchdog trigger. Memory window of %f bytes is above the "
"%" PRIu64 " bytes limit.",
memory_window_bytes_.Mean(), memory_limit_bytes_);
- kill(getpid(), SIGABRT);
+ return true;
}
}
+ return false;
}
-void Watchdog::CheckCpu(uint64_t cpu_time) {
+bool Watchdog::CheckCpu_Locked(uint64_t cpu_time) {
if (cpu_limit_percentage_ == 0)
- return;
+ return false;
// Add the cpu time to the ring buffer.
if (cpu_window_time_ticks_.Push(cpu_time)) {
@@ -213,9 +365,10 @@ void Watchdog::CheckCpu(uint64_t cpu_time) {
PERFETTO_ELOG("CPU watchdog trigger. %f%% CPU use is above the %" PRIu32
"%% CPU limit.",
percentage, cpu_limit_percentage_);
- kill(getpid(), SIGABRT);
+ return true;
}
}
+ return false;
}
uint32_t Watchdog::WindowTimeForRingBuffer(const WindowedInterval& window) {
@@ -249,32 +402,29 @@ void Watchdog::WindowedInterval::Reset(size_t new_size) {
buffer_.reset(new_size == 0 ? nullptr : new uint64_t[new_size]());
}
-Watchdog::Timer::Timer(uint32_t ms) {
+Watchdog::Timer::Timer(Watchdog* watchdog,
+ uint32_t ms,
+ WatchdogCrashReason crash_reason)
+ : watchdog_(watchdog) {
if (!ms)
return; // No-op timer created when the watchdog is disabled.
-
- struct sigevent sev = {};
- timer_t timerid;
- sev.sigev_notify = SIGEV_THREAD_ID;
- sev._sigev_un._tid = base::GetThreadId();
- sev.sigev_signo = SIGABRT;
- PERFETTO_CHECK(timer_create(CLOCK_MONOTONIC, &sev, &timerid) != -1);
- timerid_ = base::make_optional(timerid);
- struct itimerspec its = {};
- its.it_value.tv_sec = ms / 1000;
- its.it_value.tv_nsec = 1000000L * (ms % 1000);
- PERFETTO_CHECK(timer_settime(timerid_.value(), 0, &its, nullptr) != -1);
+ timer_data_.deadline = GetWallTimeMs() + std::chrono::milliseconds(ms);
+ timer_data_.thread_id = GetThreadId();
+ timer_data_.crash_reason = crash_reason;
+ PERFETTO_DCHECK(watchdog_);
+ watchdog_->AddFatalTimer(timer_data_);
}
Watchdog::Timer::~Timer() {
- if (timerid_) {
- timer_delete(timerid_.value());
- }
+ if (timer_data_.deadline.count())
+ watchdog_->RemoveFatalTimer(timer_data_);
}
Watchdog::Timer::Timer(Timer&& other) noexcept {
- timerid_ = std::move(other.timerid_);
- other.timerid_ = base::nullopt;
+ watchdog_ = std::move(other.watchdog_);
+ other.watchdog_ = nullptr;
+ timer_data_ = std::move(other.timer_data_);
+ other.timer_data_ = TimerData();
}
} // namespace base
diff --git a/src/base/watchdog_unittest.cc b/src/base/watchdog_unittest.cc
index 81d0ac6fb..ae2006f6f 100644
--- a/src/base/watchdog_unittest.cc
+++ b/src/base/watchdog_unittest.cc
@@ -36,17 +36,21 @@ namespace perfetto {
namespace base {
namespace {
+static auto kCrashReasonIgnored = WatchdogCrashReason::kUnspecified;
+
class TestWatchdog : public Watchdog {
public:
explicit TestWatchdog(uint32_t polling_interval_ms)
- : Watchdog(polling_interval_ms) {}
+ : Watchdog(polling_interval_ms) {
+ disable_kill_failsafe_for_testing_ = true;
+ }
~TestWatchdog() override {}
};
TEST(WatchdogTest, NoTimerCrashIfNotEnabled) {
// CreateFatalTimer should be a noop if the watchdog is not enabled.
TestWatchdog watchdog(100);
- auto handle = watchdog.CreateFatalTimer(1);
+ auto handle = watchdog.CreateFatalTimer(1, kCrashReasonIgnored);
usleep(100 * 1000);
}
@@ -56,7 +60,7 @@ TEST(WatchdogTest, TimerCrash) {
{
TestWatchdog watchdog(100);
watchdog.Start();
- auto handle = watchdog.CreateFatalTimer(20);
+ auto handle = watchdog.CreateFatalTimer(20, kCrashReasonIgnored);
usleep(200 * 1000);
},
"");
@@ -68,7 +72,7 @@ TEST(WatchdogTest, CrashEvenWhenMove) {
{
TestWatchdog watchdog(100);
watchdog.Start();
- timers.emplace(0, watchdog.CreateFatalTimer(20));
+ timers.emplace(0, watchdog.CreateFatalTimer(20, kCrashReasonIgnored));
usleep(200 * 1000);
},
"");
@@ -145,7 +149,7 @@ TEST(WatchdogTest, TimerCrashDeliveredToCallerThread) {
expected_tid = GetThreadId();
TestWatchdog watchdog(100);
watchdog.Start();
- auto handle = watchdog.CreateFatalTimer(2);
+ auto handle = watchdog.CreateFatalTimer(2, kCrashReasonIgnored);
usleep(200 * 1000); // This will be interrupted by the fatal timer.
std::unique_lock<std::mutex> lock(mutex);
quit = true;
@@ -157,6 +161,7 @@ TEST(WatchdogTest, TimerCrashDeliveredToCallerThread) {
};
std::vector<std::thread> threads;
+
for (size_t i = 0; i < 8; i++)
threads.emplace_back(thread_fn, i);
diff --git a/src/ipc/buffered_frame_deserializer.cc b/src/ipc/buffered_frame_deserializer.cc
index d893dfb5c..16d3c8630 100644
--- a/src/ipc/buffered_frame_deserializer.cc
+++ b/src/ipc/buffered_frame_deserializer.cc
@@ -16,9 +16,8 @@
#include "src/ipc/buffered_frame_deserializer.h"
-#include <inttypes.h>
-
#include <algorithm>
+#include <cinttypes>
#include <type_traits>
#include <utility>
diff --git a/src/ipc/client_impl.cc b/src/ipc/client_impl.cc
index 540656f0b..46cf9af2e 100644
--- a/src/ipc/client_impl.cc
+++ b/src/ipc/client_impl.cc
@@ -17,8 +17,8 @@
#include "src/ipc/client_impl.h"
#include <fcntl.h>
-#include <inttypes.h>
+#include <cinttypes>
#include <utility>
#include "perfetto/base/task_runner.h"
diff --git a/src/ipc/host_impl.cc b/src/ipc/host_impl.cc
index d0f370cf1..c182cd17e 100644
--- a/src/ipc/host_impl.cc
+++ b/src/ipc/host_impl.cc
@@ -16,12 +16,14 @@
#include "src/ipc/host_impl.h"
-#include <inttypes.h>
-
#include <algorithm>
+#include <cinttypes>
#include <utility>
+#include "perfetto/base/build_config.h"
#include "perfetto/base/task_runner.h"
+#include "perfetto/base/time.h"
+#include "perfetto/ext/base/crash_keys.h"
#include "perfetto/ext/base/utils.h"
#include "perfetto/ext/ipc/service.h"
#include "perfetto/ext/ipc/service_descriptor.h"
@@ -38,6 +40,8 @@ namespace {
constexpr base::SockFamily kHostSockFamily =
kUseTCPSocket ? base::SockFamily::kInet : base::SockFamily::kUnix;
+base::CrashKey g_crash_key_uid("ipc_uid");
+
uid_t GetPosixPeerUid(base::UnixSocket* sock) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
base::ignore_result(sock);
@@ -48,6 +52,16 @@ uid_t GetPosixPeerUid(base::UnixSocket* sock) {
#endif
}
+pid_t GetLinuxPeerPid(base::UnixSocket* sock) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+ PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+ return sock->peer_pid_linux();
+#else
+ base::ignore_result(sock);
+ return base::kInvalidPid; // Unsupported.
+#endif
+}
+
} // namespace
// static
@@ -124,6 +138,9 @@ void HostImpl::OnDataAvailable(base::UnixSocket* sock) {
ClientConnection* client = it->second;
BufferedFrameDeserializer& frame_deserializer = client->frame_deserializer;
+ auto peer_uid = GetPosixPeerUid(client->sock.get());
+ auto scoped_key = g_crash_key_uid.SetScoped(static_cast<int64_t>(peer_uid));
+
size_t rsize;
do {
auto buf = frame_deserializer.BeginReceive();
@@ -218,8 +235,10 @@ void HostImpl::OnInvokeMethod(ClientConnection* client,
});
}
+ auto peer_uid = GetPosixPeerUid(client->sock.get());
+ auto scoped_key = g_crash_key_uid.SetScoped(static_cast<int64_t>(peer_uid));
service->client_info_ =
- ClientInfo(client->id, GetPosixPeerUid(client->sock.get()));
+ ClientInfo(client->id, peer_uid, GetLinuxPeerPid(client->sock.get()));
service->received_fd_ = &client->received_fd;
method.invoker(service, *decoded_req_args, std::move(deferred_reply));
service->received_fd_ = nullptr;
@@ -252,6 +271,9 @@ void HostImpl::ReplyToMethodInvocation(ClientID client_id,
// static
void HostImpl::SendFrame(ClientConnection* client, const Frame& frame, int fd) {
+ auto peer_uid = GetPosixPeerUid(client->sock.get());
+ auto scoped_key = g_crash_key_uid.SetScoped(static_cast<int64_t>(peer_uid));
+
std::string buf = BufferedFrameDeserializer::Serialize(frame);
// When a new Client connects in OnNewClientConnection we set a timeout on
@@ -272,7 +294,8 @@ void HostImpl::OnDisconnect(base::UnixSocket* sock) {
return;
ClientID client_id = it->second->id;
- ClientInfo client_info(client_id, GetPosixPeerUid(sock));
+ ClientInfo client_info(client_id, GetPosixPeerUid(sock),
+ GetLinuxPeerPid(sock));
clients_by_socket_.erase(it);
PERFETTO_DCHECK(clients_.count(client_id));
clients_.erase(client_id);
diff --git a/src/ipc/host_impl_unittest.cc b/src/ipc/host_impl_unittest.cc
index a04ff2237..e1bbee720 100644
--- a/src/ipc/host_impl_unittest.cc
+++ b/src/ipc/host_impl_unittest.cc
@@ -478,6 +478,39 @@ TEST_F(HostImplTest, MoveReplyObjectAndReplyAsynchronously) {
task_runner_->RunUntilCheckpoint("on_reply_received");
}
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+ PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+// Check ClientInfo of the service.
+TEST_F(HostImplTest, ServiceClientInfo) {
+ FakeService* fake_service = new FakeService("FakeService");
+ ASSERT_TRUE(host_->ExposeService(std::unique_ptr<Service>(fake_service)));
+ auto on_bind = task_runner_->CreateCheckpoint("on_bind");
+ cli_->BindService("FakeService");
+ EXPECT_CALL(*cli_, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
+ task_runner_->RunUntilCheckpoint("on_bind");
+
+ RequestProto req_args;
+ req_args.set_data("foo");
+ cli_->InvokeMethod(cli_->last_bound_service_id_, 1, req_args);
+ EXPECT_CALL(*fake_service, OnFakeMethod1(_, _))
+ .WillOnce(
+ Invoke([fake_service](const RequestProto& req, DeferredBase* reply) {
+ ASSERT_EQ("foo", req.data());
+ std::unique_ptr<ReplyProto> reply_args(new ReplyProto());
+ reply_args->set_data("bar");
+ reply->Resolve(AsyncResult<ProtoMessage>(
+ std::unique_ptr<ProtoMessage>(reply_args.release())));
+ // Verifies the pid() and uid() values in ClientInfo.
+ const auto& client_info = fake_service->client_info();
+ ASSERT_EQ(client_info.uid(), getuid());
+ ASSERT_EQ(client_info.pid(), getpid());
+ }));
+
+ EXPECT_CALL(*cli_, OnInvokeMethodReply(_)).WillOnce(Return());
+ task_runner_->RunUntilIdle();
+}
+#endif // OS_WIN
+
// TODO(primiano): add the tests below in next CLs.
// TEST(HostImplTest, ManyClients) {}
// TEST(HostImplTest, OverlappingRequstsOutOfOrder) {}
diff --git a/src/ipc/test/test_socket.h b/src/ipc/test/test_socket.h
index e55a8dfcc..eaafd73d7 100644
--- a/src/ipc/test/test_socket.h
+++ b/src/ipc/test/test_socket.h
@@ -17,10 +17,11 @@
#ifndef SRC_IPC_TEST_TEST_SOCKET_H_
#define SRC_IPC_TEST_TEST_SOCKET_H_
-#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
+#include <cinttypes>
+
#include "perfetto/base/build_config.h"
#include "perfetto/ext/base/unix_socket.h"
diff --git a/src/kallsyms/kernel_symbol_map.cc b/src/kallsyms/kernel_symbol_map.cc
index 920c89735..ae8fff740 100644
--- a/src/kallsyms/kernel_symbol_map.cc
+++ b/src/kallsyms/kernel_symbol_map.cc
@@ -26,12 +26,13 @@
#include "perfetto/ext/base/utils.h"
#include "perfetto/protozero/proto_utils.h"
-#include <inttypes.h>
#include <stdio.h>
#include <algorithm>
+#include <cinttypes>
#include <functional>
#include <map>
+#include <unordered_map>
#include <utility>
namespace perfetto {
@@ -202,7 +203,7 @@ TokenId KernelSymbolMap::TokenTable::Add(const std::string& token) {
*(tok_wptr++) = token.at(i) & 0x7f;
}
*(tok_wptr++) = static_cast<char>(token.at(token_size - 1) | 0x80);
- PERFETTO_DCHECK(tok_wptr == &buf_[buf_.size()]);
+ PERFETTO_DCHECK(tok_wptr == buf_.data() + buf_.size());
return id;
}
@@ -243,8 +244,9 @@ size_t KernelSymbolMap::Parse(const std::string& kallsyms_path) {
TokenId id = 0;
};
- // Note if changing the container: the code below relies on stable iterators.
- using TokenMap = std::map<std::string, TokenInfo>;
+ // Note if changing the container: the code below doesn't rely on stable
+ // iterators, but relies on stable pointers.
+ using TokenMap = std::unordered_map<std::string, TokenInfo>;
using TokenMapPtr = TokenMap::value_type*;
TokenMap tokens;
@@ -394,7 +396,7 @@ std::string KernelSymbolMap::Lookup(uint64_t sym_addr) {
uint32_t addr = it->first;
uint32_t off = it->second;
const uint8_t* rdptr = &buf_[off];
- const uint8_t* const buf_end = &buf_[buf_.size()];
+ const uint8_t* const buf_end = buf_.data() + buf_.size();
bool parsing_addr = true;
const uint8_t* next_rdptr = nullptr;
uint64_t sym_start_addr = 0;
diff --git a/src/kallsyms/kernel_symbol_map_benchmark.cc b/src/kallsyms/kernel_symbol_map_benchmark.cc
index 7c3e9a909..704fa8215 100644
--- a/src/kallsyms/kernel_symbol_map_benchmark.cc
+++ b/src/kallsyms/kernel_symbol_map_benchmark.cc
@@ -19,6 +19,7 @@
#include <benchmark/benchmark.h>
#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/utils.h"
#include "src/base/test/utils.h"
#include "src/kallsyms/kernel_symbol_map.h"
@@ -89,7 +90,7 @@ ExpectedSym kExpectedSyms[] = {
} // namespace
-static void BM_KallSyms(benchmark::State& state) {
+static void BM_KallSymsFind(benchmark::State& state) {
perfetto::KernelSymbolMap::kTokenIndexSampling =
static_cast<size_t>(state.range(0));
perfetto::KernelSymbolMap::kSymIndexSampling =
@@ -113,4 +114,31 @@ static void BM_KallSyms(benchmark::State& state) {
state.counters["mem"] = static_cast<double>(kallsyms.size_bytes());
}
-BENCHMARK(BM_KallSyms)->Apply(BenchmarkArgs);
+BENCHMARK(BM_KallSymsFind)->Apply(BenchmarkArgs);
+
+static void BM_KallSymsLoad(benchmark::State& state) {
+ perfetto::KernelSymbolMap::kTokenIndexSampling =
+ static_cast<size_t>(state.range(0));
+ perfetto::KernelSymbolMap::kSymIndexSampling =
+ static_cast<size_t>(state.range(1));
+
+ // Don't run the benchmark on the CI as it requires pushing all test data,
+ // which slows down significantly the CI.
+ const bool skip = IsBenchmarkFunctionalOnly();
+
+ const std::string kallsyms_path = perfetto::base::GetTestDataPath("test/data/kallsyms.txt");
+ if (!skip) {
+ std::string tmp;
+ // Read the whole file once, so that it's cached.
+ PERFETTO_CHECK(perfetto::base::ReadFile(kallsyms_path, &tmp));
+ }
+
+ for (auto _ : state) {
+ perfetto::KernelSymbolMap kallsyms;
+ if (!skip) {
+ kallsyms.Parse(kallsyms_path);
+ }
+ }
+}
+
+BENCHMARK(BM_KallSymsLoad)->Apply(BenchmarkArgs);
diff --git a/src/kallsyms/kernel_symbol_map_unittest.cc b/src/kallsyms/kernel_symbol_map_unittest.cc
index deba34a02..9cecddabb 100644
--- a/src/kallsyms/kernel_symbol_map_unittest.cc
+++ b/src/kallsyms/kernel_symbol_map_unittest.cc
@@ -16,8 +16,7 @@
#include "src/kallsyms/kernel_symbol_map.h"
-#include <inttypes.h>
-
+#include <cinttypes>
#include <random>
#include <unordered_map>
diff --git a/src/kallsyms/lazy_kernel_symbolizer_unittest.cc b/src/kallsyms/lazy_kernel_symbolizer_unittest.cc
index c219dda96..ca463ba60 100644
--- a/src/kallsyms/lazy_kernel_symbolizer_unittest.cc
+++ b/src/kallsyms/lazy_kernel_symbolizer_unittest.cc
@@ -16,7 +16,7 @@
#include "src/kallsyms/lazy_kernel_symbolizer.h"
-#include <inttypes.h>
+#include <cinttypes>
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/temp_file.h"
diff --git a/src/perfetto_cmd/BUILD.gn b/src/perfetto_cmd/BUILD.gn
index 637436ff2..74ca8fbad 100644
--- a/src/perfetto_cmd/BUILD.gn
+++ b/src/perfetto_cmd/BUILD.gn
@@ -45,7 +45,7 @@ executable("trigger_perfetto") {
# is shared both by the executable and tests.
source_set("perfetto_cmd") {
public_deps = [
- ":protos",
+ ":protos_cpp",
"../../include/perfetto/ext/traced",
]
deps = [
@@ -82,13 +82,13 @@ source_set("perfetto_cmd") {
}
perfetto_cc_proto_descriptor("gen_cc_config_descriptor") {
- descriptor_name = "perfetto_config.descriptor"
- descriptor_target = "../../protos/perfetto/config:perfetto_config_descriptor"
+ descriptor_name = "config.descriptor"
+ descriptor_target = "../../protos/perfetto/config:descriptor"
}
source_set("trigger_perfetto_cmd") {
public_deps = [
- ":protos",
+ ":protos_cpp",
"../../include/perfetto/ext/traced",
]
deps = [
@@ -113,8 +113,11 @@ source_set("trigger_producer") {
]
}
-perfetto_proto_library("protos") {
- proto_generators = [ "cpp" ]
+perfetto_proto_library("protos_@TYPE@") {
+ proto_generators = [
+ "cpp",
+ "source_set",
+ ]
sources = [ "perfetto_cmd_state.proto" ]
proto_path = perfetto_root_path
}
diff --git a/src/perfetto_cmd/config.cc b/src/perfetto_cmd/config.cc
index f2b40d445..502220397 100644
--- a/src/perfetto_cmd/config.cc
+++ b/src/perfetto_cmd/config.cc
@@ -147,6 +147,7 @@ bool CreateConfigFromOptions(const ConfigOptions& options,
ftrace_cfg.add_atrace_categories(cat);
for (const auto& app : atrace_apps)
ftrace_cfg.add_atrace_apps(app);
+ ftrace_cfg.set_symbolize_ksyms(true);
ds_config->set_ftrace_config_raw(ftrace_cfg.SerializeAsString());
auto* ps_config = config->add_data_sources()->mutable_config();
diff --git a/src/perfetto_cmd/config_unittest.cc b/src/perfetto_cmd/config_unittest.cc
index cc1db346b..5435c8a60 100644
--- a/src/perfetto_cmd/config_unittest.cc
+++ b/src/perfetto_cmd/config_unittest.cc
@@ -147,6 +147,7 @@ TEST_F(CreateConfigFromOptionsTest, FullConfig) {
ASSERT_TRUE(ftrace.ParseFromString(
config.data_sources()[0].config().ftrace_config_raw()));
EXPECT_THAT(ftrace.ftrace_events(), Contains("sched/sched_switch"));
+ EXPECT_TRUE(ftrace.symbolize_ksyms());
EXPECT_THAT(ftrace.atrace_categories(), Contains("sw"));
EXPECT_THAT(ftrace.atrace_apps(), Contains("com.android.chrome"));
}
diff --git a/src/perfetto_cmd/pbtxt_to_pb.cc b/src/perfetto_cmd/pbtxt_to_pb.cc
index b78d93829..2c7b67a21 100644
--- a/src/perfetto_cmd/pbtxt_to_pb.cc
+++ b/src/perfetto_cmd/pbtxt_to_pb.cc
@@ -16,6 +16,7 @@
#include <ctype.h>
+#include <limits>
#include <map>
#include <set>
#include <stack>
@@ -32,7 +33,7 @@
#include "perfetto/protozero/message.h"
#include "perfetto/protozero/message_handle.h"
#include "perfetto/protozero/scattered_heap_buffer.h"
-#include "src/perfetto_cmd/perfetto_config.descriptor.h"
+#include "src/perfetto_cmd/config.descriptor.h"
#include "protos/perfetto/common/descriptor.gen.h"
@@ -706,8 +707,7 @@ std::vector<uint8_t> PbtxtToPb(const std::string& input,
{
file_descriptor_set.ParseFromArray(
- kPerfettoConfigDescriptor.data(),
- static_cast<int>(kPerfettoConfigDescriptor.size()));
+ kConfigDescriptor.data(), static_cast<int>(kConfigDescriptor.size()));
for (const auto& file_descriptor : file_descriptor_set.file()) {
for (const auto& enum_descriptor : file_descriptor.enum_type()) {
const std::string name =
diff --git a/src/perfetto_cmd/perfetto_cmd.cc b/src/perfetto_cmd/perfetto_cmd.cc
index 67ea3ea24..3ed31406f 100644
--- a/src/perfetto_cmd/perfetto_cmd.cc
+++ b/src/perfetto_cmd/perfetto_cmd.cc
@@ -17,6 +17,8 @@
#include "src/perfetto_cmd/perfetto_cmd.h"
#include "perfetto/base/build_config.h"
+#include "perfetto/base/proc_utils.h"
+#include "perfetto/ext/base/scoped_file.h"
#include <fcntl.h>
#include <stdio.h>
@@ -24,10 +26,6 @@
#include <sys/types.h>
#include <time.h>
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-#include <sys/system_properties.h>
-#endif // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-
// For dup().
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <io.h>
@@ -35,17 +33,22 @@
#include <unistd.h>
#endif
+#include <chrono>
#include <fstream>
#include <iostream>
#include <iterator>
+#include <random>
#include <sstream>
+#include <thread>
#include "perfetto/base/compiler.h"
#include "perfetto/base/logging.h"
#include "perfetto/base/time.h"
+#include "perfetto/ext/base/android_utils.h"
#include "perfetto/ext/base/ctrl_c_handler.h"
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/getopt.h"
+#include "perfetto/ext/base/pipe.h"
#include "perfetto/ext/base/string_view.h"
#include "perfetto/ext/base/thread_utils.h"
#include "perfetto/ext/base/utils.h"
@@ -65,12 +68,14 @@
#include "src/perfetto_cmd/pbtxt_to_pb.h"
#include "src/perfetto_cmd/trigger_producer.h"
+#include "protos/perfetto/common/ftrace_descriptor.gen.h"
#include "protos/perfetto/common/tracing_service_state.gen.h"
+#include "protos/perfetto/common/track_event_descriptor.gen.h"
namespace perfetto {
namespace {
-perfetto::PerfettoCmd* g_consumer_cmd;
+perfetto::PerfettoCmd* g_perfetto_cmd;
uint32_t kOnTraceDataTimeoutMs = 3000;
@@ -134,12 +139,12 @@ bool ParseTraceConfigPbtxt(const std::string& file_name,
bool IsUserBuild() {
#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
- char value[PROP_VALUE_MAX];
- if (!__system_property_get("ro.build.type", value)) {
+ std::string build_type = base::GetAndroidProp("ro.build.type");
+ if (build_type.empty()) {
PERFETTO_ELOG("Unable to read ro.build.type: assuming user build");
return true;
}
- return strcmp(value, "user") == 0;
+ return build_type == "user";
#else
return false;
#endif // PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
@@ -162,59 +167,101 @@ base::Optional<PerfettoStatsdAtom> ConvertRateLimiterResponseToAtom(
PERFETTO_FATAL("For GCC");
}
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+// Reports trace with `uuid` being finalized to the trace marker.
+//
+// This reimplements parts of android libcutils, because:
+// * libcutils is not exposed to the NDK and cannot be used from standalone
+// perfetto
+// * libcutils atrace uses properties to enable tags, which are not required in
+// this case.
+void ReportFinalizeTraceUuidToAtrace(const base::Uuid& uuid) {
+ base::ScopedFile file =
+ base::OpenFile("/sys/kernel/tracing/trace_marker", O_WRONLY);
+ if (!file) {
+ file = base::OpenFile("/sys/kernel/debug/tracing/trace_marker", O_WRONLY);
+ if (!file) {
+ return;
+ }
+ }
+ base::StackString<100> uuid_slice("N|%d|OtherTraces|finalize-uuid-%s",
+ base::GetProcessId(),
+ uuid.ToPrettyString().c_str());
+ PERFETTO_EINTR(write(file.get(), uuid_slice.c_str(), uuid_slice.len()));
+}
+#endif // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
} // namespace
const char* kStateDir = "/data/misc/perfetto-traces";
-int PerfettoCmd::PrintUsage(const char* argv0) {
- PERFETTO_ELOG(R"(
+PerfettoCmd::PerfettoCmd() {
+ PERFETTO_DCHECK(!g_perfetto_cmd);
+ g_perfetto_cmd = this;
+}
+
+PerfettoCmd::~PerfettoCmd() {
+ PERFETTO_DCHECK(g_perfetto_cmd == this);
+ g_perfetto_cmd = nullptr;
+}
+
+void PerfettoCmd::PrintUsage(const char* argv0) {
+ fprintf(stderr, R"(
Usage: %s
- --background -d : Exits immediately and continues tracing in
- background
+ --background -d : Exits immediately and continues in the background.
+ Prints the PID of the bg process. The printed PID
+ can used to gracefully terminate the tracing
+ session by issuing a `kill -TERM $PRINTED_PID`.
+ --background-wait -D : Like --background, but waits (up to 30s) for all
+ data sources to be started before exiting. Exit
+ code is zero if a successful acknowledgement is
+ received, non-zero otherwise (error or timeout).
--config -c : /path/to/trace/config/file or - for stdin
--out -o : /path/to/out/trace/file or - for stdout
- --upload : Upload field trace (Android only)
- --dropbox TAG : DEPRECATED: Use --upload instead
- TAG should always be set to 'perfetto'
- --no-guardrails : Ignore guardrails triggered when using --upload
- (for testing).
--txt : Parse config as pbtxt. Not for production use.
Not a stable API.
- --reset-guardrails : Resets the state of the guardails and exits
- (for testing).
--query : Queries the service state and prints it as
human-readable text.
--query-raw : Like --query, but prints raw proto-encoded bytes
of tracing_service_state.proto.
- --save-for-bugreport : If a trace with bugreport_score > 0 is running, it
- saves it into a file. Outputs the path when done.
--help -h
-
-light configuration flags: (only when NOT using -c/--config)
+Light configuration flags: (only when NOT using -c/--config)
--time -t : Trace duration N[s,m,h] (default: 10s)
--buffer -b : Ring buffer size N[mb,gb] (default: 32mb)
- --size -s : Max file size N[mb,gb] (default: in-memory ring-buffer only)
+ --size -s : Max file size N[mb,gb]
+ (default: in-memory ring-buffer only)
--app -a : Android (atrace) app name
- ATRACE_CAT : Record ATRACE_CAT (e.g. wm)
FTRACE_GROUP/FTRACE_NAME : Record ftrace event (e.g. sched/sched_switch)
+ ATRACE_CAT : Record ATRACE_CAT (e.g. wm) (Android only)
-statsd-specific flags:
+Statsd-specific and other Android-only flags:
--alert-id : ID of the alert that triggered this trace.
--config-id : ID of the triggering config.
--config-uid : UID of app which registered the config.
--subscription-id : ID of the subscription that triggered this trace.
-
-Detach mode. DISCOURAGED, read https://perfetto.dev/docs/concepts/detached-mode :
+ --upload : Upload trace.
+ --dropbox TAG : DEPRECATED: Use --upload instead
+ TAG should always be set to 'perfetto'.
+ --save-for-bugreport : If a trace with bugreport_score > 0 is running, it
+ saves it into a file. Outputs the path when done.
+ --no-guardrails : Ignore guardrails triggered when using --upload
+ (testing only).
+ --reset-guardrails : Resets the state of the guardails and exits
+ (testing only).
+
+Detach mode. DISCOURAGED, read https://perfetto.dev/docs/concepts/detached-mode
--detach=key : Detach from the tracing session with the given key.
- --attach=key [--stop] : Re-attach to the session (optionally stop tracing once reattached).
- --is_detached=key : Check if the session can be re-attached (0:Yes, 2:No, 1:Error).
+ --attach=key [--stop] : Re-attach to the session (optionally stop tracing
+ once reattached).
+ --is_detached=key : Check if the session can be re-attached.
+ Exit code: 0:Yes, 2:No, 1:Error.
)", /* this comment fixes syntax highlighting in some editors */
- argv0);
- return 1;
+ argv0);
}
-int PerfettoCmd::Main(int argc, char** argv) {
+base::Optional<int> PerfettoCmd::ParseCmdlineAndMaybeDaemonize(int argc,
+ char** argv) {
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
umask(0000); // make sure that file creation is not affected by umask.
#endif
@@ -242,6 +289,7 @@ int PerfettoCmd::Main(int argc, char** argv) {
{"config", required_argument, nullptr, 'c'},
{"out", required_argument, nullptr, 'o'},
{"background", no_argument, nullptr, 'd'},
+ {"background-wait", no_argument, nullptr, 'D'},
{"time", required_argument, nullptr, 't'},
{"buffer", required_argument, nullptr, 'b'},
{"size", required_argument, nullptr, 's'},
@@ -267,19 +315,21 @@ int PerfettoCmd::Main(int argc, char** argv) {
std::string config_file_name;
std::string trace_config_raw;
- bool background = false;
- bool ignore_guardrails = false;
bool parse_as_pbtxt = false;
- bool upload_flag = false;
TraceConfig::StatsdMetadata statsd_metadata;
- RateLimiter limiter;
+ limiter_.reset(new RateLimiter());
ConfigOptions config_options;
bool has_config_options = false;
+ if (argc <= 1) {
+ PrintUsage(argv[0]);
+ return 1;
+ }
+
for (;;) {
int option =
- getopt_long(argc, argv, "hc:o:dt:b:s:a:", long_options, nullptr);
+ getopt_long(argc, argv, "hc:o:dDt:b:s:a:", long_options, nullptr);
if (option == -1)
break; // EOF.
@@ -314,9 +364,16 @@ int PerfettoCmd::Main(int argc, char** argv) {
}
if (option == 'd') {
- background = true;
+ background_ = true;
continue;
}
+
+ if (option == 'D') {
+ background_ = true;
+ background_wait_ = true;
+ continue;
+ }
+
if (option == 't') {
has_config_options = true;
config_options.time = std::string(optarg);
@@ -343,7 +400,7 @@ int PerfettoCmd::Main(int argc, char** argv) {
if (option == OPT_UPLOAD) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
- upload_flag = true;
+ upload_flag_ = true;
continue;
#else
PERFETTO_ELOG("--upload is only supported on Android");
@@ -354,7 +411,7 @@ int PerfettoCmd::Main(int argc, char** argv) {
if (option == OPT_DROPBOX) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
PERFETTO_CHECK(optarg);
- upload_flag = true;
+ upload_flag_ = true;
continue;
#else
PERFETTO_ELOG("--dropbox is only supported on Android");
@@ -368,12 +425,12 @@ int PerfettoCmd::Main(int argc, char** argv) {
}
if (option == OPT_IGNORE_GUARDRAILS) {
- ignore_guardrails = true;
+ ignore_guardrails_ = true;
continue;
}
if (option == OPT_RESET_GUARDRAILS) {
- PERFETTO_CHECK(limiter.ClearState());
+ PERFETTO_CHECK(limiter_->ClearState());
PERFETTO_ILOG("Guardrail state cleared");
return 0;
}
@@ -443,7 +500,8 @@ int PerfettoCmd::Main(int argc, char** argv) {
continue;
}
- return PrintUsage(argv[0]);
+ PrintUsage(argv[0]);
+ return 1;
}
for (ssize_t i = optind; i < argc; i++) {
@@ -451,7 +509,7 @@ int PerfettoCmd::Main(int argc, char** argv) {
config_options.categories.push_back(argv[i]);
}
- if (query_service_ && (is_detach() || is_attach() || background)) {
+ if (query_service_ && (is_detach() || is_attach() || background_)) {
PERFETTO_ELOG("--query cannot be combined with any other argument");
return 1;
}
@@ -461,7 +519,7 @@ int PerfettoCmd::Main(int argc, char** argv) {
return 1;
}
- if (is_detach() && background) {
+ if (is_detach() && background_) {
PERFETTO_ELOG("--detach and --background are mutually exclusive");
return 1;
}
@@ -471,8 +529,8 @@ int PerfettoCmd::Main(int argc, char** argv) {
return 1;
}
- if (bugreport_ &&
- (is_attach() | is_detach() || query_service_ || has_config_options)) {
+ if (bugreport_ && (is_attach() || is_detach() || query_service_ ||
+ has_config_options || background_wait_)) {
PERFETTO_ELOG("--save-for-bugreport cannot take any other argument");
return 1;
}
@@ -485,10 +543,10 @@ int PerfettoCmd::Main(int argc, char** argv) {
// For this we are just acting on already existing sessions.
trace_config_.reset(new TraceConfig());
- std::vector<std::string> triggers_to_activate;
bool parsed = false;
- const bool will_trace = !is_attach() && !query_service_ && !bugreport_;
- if (!will_trace) {
+ const bool will_trace_or_trigger =
+ !is_attach() && !query_service_ && !bugreport_;
+ if (!will_trace_or_trigger) {
if ((!trace_config_raw.empty() || has_config_options)) {
PERFETTO_ELOG("Cannot specify a trace config with this option");
return 1;
@@ -518,7 +576,7 @@ int PerfettoCmd::Main(int argc, char** argv) {
if (parsed) {
*trace_config_->mutable_statsd_metadata() = std::move(statsd_metadata);
trace_config_raw.clear();
- } else if (will_trace) {
+ } else if (will_trace_or_trigger) {
PERFETTO_ELOG("The trace config is invalid, bailing out.");
return 1;
}
@@ -539,27 +597,72 @@ int PerfettoCmd::Main(int argc, char** argv) {
uuid_ = uuid.ToString();
}
- if (!trace_config_->incident_report_config().destination_package().empty() &&
- !upload_flag) {
+ const auto& delay = trace_config_->cmd_trace_start_delay();
+ if (delay.has_max_delay_ms() != delay.has_min_delay_ms()) {
+ PERFETTO_ELOG("cmd_trace_start_delay field is only partially specified.");
+ return 1;
+ }
+
+ bool has_incidentd_package =
+ !trace_config_->incident_report_config().destination_package().empty();
+ if (has_incidentd_package && !upload_flag_) {
PERFETTO_ELOG(
"Unexpected IncidentReportConfig without --dropbox / --upload.");
return 1;
}
- if (trace_config_->activate_triggers().empty() &&
- trace_config_->incident_report_config().destination_package().empty() &&
- !trace_config_->incident_report_config().skip_incidentd() &&
- upload_flag) {
+ bool has_android_reporter_package = !trace_config_->android_report_config()
+ .reporter_service_package()
+ .empty();
+ if (has_android_reporter_package && !upload_flag_) {
+ PERFETTO_ELOG(
+ "Unexpected AndroidReportConfig without --dropbox / --upload.");
+ return 1;
+ }
+
+ if (has_incidentd_package && has_android_reporter_package) {
PERFETTO_ELOG(
- "Missing IncidentReportConfig.destination_package with --dropbox / "
- "--upload.");
+ "Only one of IncidentReportConfig and AndroidReportConfig "
+ "allowed in the same config.");
return 1;
}
- // Only save to incidentd if both --upload is set and |skip_incidentd| is
- // absent or false.
+ // If the upload flag is set, we can only be doing one of three things:
+ // 1. Reporting to either incidentd or Android framework.
+ // 2. Skipping incidentd/Android report because it was explicitly
+ // specified in the config.
+ // 3. Activating triggers.
+ bool incidentd_valid =
+ has_incidentd_package ||
+ trace_config_->incident_report_config().skip_incidentd();
+ bool android_report_valid =
+ has_android_reporter_package ||
+ trace_config_->android_report_config().skip_report();
+ bool has_triggers = !trace_config_->activate_triggers().empty();
+ if (upload_flag_ && !incidentd_valid && !android_report_valid &&
+ !has_triggers) {
+ PERFETTO_ELOG(
+ "One of IncidentReportConfig, AndroidReportConfig or activate_triggers "
+ "must be specified with --dropbox / --upload.");
+ return 1;
+ }
+
+ // Only save to incidentd if:
+ // 1) |destination_package| is set
+ // 2) |skip_incidentd| is absent or false.
+ // 3) we are not simply activating triggers.
save_to_incidentd_ =
- upload_flag && !trace_config_->incident_report_config().skip_incidentd();
+ has_incidentd_package &&
+ !trace_config_->incident_report_config().skip_incidentd() &&
+ !has_triggers;
+
+ // Only report to the Andorid framework if:
+ // 1) |reporter_service_package| is set
+ // 2) |skip_report| is absent or false.
+ // 3) we are not simply activating triggers.
+ report_to_android_framework_ =
+ has_android_reporter_package &&
+ !trace_config_->android_report_config().skip_report() && !has_triggers;
// Respect the wishes of the config with respect to statsd logging or fall
// back on the presence of the --upload flag if not set.
@@ -571,7 +674,7 @@ int PerfettoCmd::Main(int argc, char** argv) {
statsd_logging_ = false;
break;
case TraceConfig::STATSD_LOGGING_UNSPECIFIED:
- statsd_logging_ = upload_flag;
+ statsd_logging_ = upload_flag_;
break;
}
trace_config_->set_statsd_logging(statsd_logging_
@@ -581,7 +684,7 @@ int PerfettoCmd::Main(int argc, char** argv) {
// Set up the output file. Either --out or --upload are expected, with the
// only exception of --attach. In this case the output file is passed when
// detaching.
- if (!trace_out_path_.empty() && upload_flag) {
+ if (!trace_out_path_.empty() && upload_flag_) {
PERFETTO_ELOG(
"Can't log to a file (--out) and incidentd (--upload) at the same "
"time");
@@ -589,7 +692,7 @@ int PerfettoCmd::Main(int argc, char** argv) {
}
if (!trace_config_->output_path().empty()) {
- if (!trace_out_path_.empty() || upload_flag) {
+ if (!trace_out_path_.empty() || upload_flag_) {
PERFETTO_ELOG(
"Can't pass --out or --upload if output_path is set in the "
"trace config");
@@ -609,25 +712,25 @@ int PerfettoCmd::Main(int argc, char** argv) {
// In this case we don't intend to send any trace config to the service,
// rather use that as a signal to the cmdline client to connect as a producer
// and activate triggers.
- if (!trace_config_->activate_triggers().empty()) {
+ if (has_triggers) {
for (const auto& trigger : trace_config_->activate_triggers()) {
- triggers_to_activate.push_back(trigger);
+ triggers_to_activate_.push_back(trigger);
}
trace_config_.reset(new TraceConfig());
}
bool open_out_file = true;
- if (!will_trace) {
+ if (!will_trace_or_trigger) {
open_out_file = false;
- if (!trace_out_path_.empty() || upload_flag) {
+ if (!trace_out_path_.empty() || upload_flag_) {
PERFETTO_ELOG("Can't pass an --out file (or --upload) with this option");
return 1;
}
- } else if (!triggers_to_activate.empty() ||
+ } else if (!triggers_to_activate_.empty() ||
(trace_config_->write_into_file() &&
!trace_config_->output_path().empty())) {
open_out_file = false;
- } else if (trace_out_path_.empty() && !upload_flag) {
+ } else if (trace_out_path_.empty() && !upload_flag_) {
PERFETTO_ELOG("Either --out or --upload is required");
return 1;
} else if (is_detach() && !trace_config_->write_into_file()) {
@@ -654,16 +757,116 @@ int PerfettoCmd::Main(int argc, char** argv) {
packet_writer_ = CreateFilePacketWriter(trace_out_stream_.get());
}
- if (background) {
- base::Daemonize();
+ if (trace_config_->compression_type() ==
+ TraceConfig::COMPRESSION_TYPE_DEFLATE) {
+ if (packet_writer_) {
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
+ packet_writer_ = CreateZipPacketWriter(std::move(packet_writer_));
+#else
+ PERFETTO_ELOG("Cannot compress. Zlib not enabled in the build config");
+#endif
+ } else {
+ PERFETTO_ELOG("Cannot compress when tracing directly to file.");
+ }
+ }
+
+ bool will_trace_indefinitely =
+ trace_config_->duration_ms() == 0 &&
+ trace_config_->trigger_config().trigger_timeout_ms() == 0;
+ if (will_trace_indefinitely && save_to_incidentd_ && !ignore_guardrails_) {
+ PERFETTO_ELOG("Can't trace indefinitely when tracing to Incidentd.");
+ return 1;
+ }
+
+ if (will_trace_indefinitely && report_to_android_framework_ &&
+ !ignore_guardrails_) {
+ PERFETTO_ELOG(
+ "Can't trace indefinitely when reporting to Android framework.");
+ return 1;
+ }
+
+ if (background_) {
+ if (background_wait_) {
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ background_wait_pipe_ = base::Pipe::Create(base::Pipe::kRdNonBlock);
+#endif
+ }
+
+ base::Daemonize([this]() -> int {
+ background_wait_pipe_.wr.reset();
+
+ if (background_wait_) {
+ return WaitOnBgProcessPipe();
+ }
+
+ return 0;
+ });
+ background_wait_pipe_.rd.reset();
+ }
+
+ return base::nullopt; // Continues in ConnectToServiceRunAndMaybeNotify()
+ // below.
+}
+
+void PerfettoCmd::NotifyBgProcessPipe(BgProcessStatus status) {
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ if (!background_wait_pipe_.wr) {
+ return;
+ }
+ static_assert(sizeof status == 1, "Enum bigger than one byte");
+ PERFETTO_EINTR(write(background_wait_pipe_.wr.get(), &status, 1));
+ background_wait_pipe_.wr.reset();
+#else // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ base::ignore_result(status);
+#endif //! PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+}
+
+PerfettoCmd::BgProcessStatus PerfettoCmd::WaitOnBgProcessPipe() {
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ base::ScopedPlatformHandle fd = std::move(background_wait_pipe_.rd);
+ PERFETTO_CHECK(fd);
+
+ BgProcessStatus msg;
+ static_assert(sizeof msg == 1, "Enum bigger than one byte");
+ std::array<pollfd, 1> pollfds = {pollfd{fd.get(), POLLIN, 0}};
+
+ int ret = PERFETTO_EINTR(poll(&pollfds[0], pollfds.size(), 30000 /*ms*/));
+ PERFETTO_CHECK(ret >= 0);
+ if (ret == 0) {
+ fprintf(stderr, "Timeout waiting for all data sources to start\n");
+ return kBackgroundTimeout;
}
+ ssize_t read_ret = PERFETTO_EINTR(read(fd.get(), &msg, 1));
+ PERFETTO_CHECK(read_ret >= 0);
+ if (read_ret == 0) {
+ fprintf(stderr, "Background process didn't report anything\n");
+ return kBackgroundOtherError;
+ }
+
+ if (msg != kBackgroundOk) {
+ fprintf(stderr, "Background process failed, BgProcessStatus=%d\n",
+ static_cast<int>(msg));
+ return msg;
+ }
+#endif //! PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+ return kBackgroundOk;
+}
+
+int PerfettoCmd::ConnectToServiceRunAndMaybeNotify() {
+ int exit_code = ConnectToServiceAndRun();
+
+ NotifyBgProcessPipe(exit_code == 0 ? kBackgroundOk : kBackgroundOtherError);
+
+ return exit_code;
+}
+int PerfettoCmd::ConnectToServiceAndRun() {
// If we are just activating triggers then we don't need to rate limit,
// connect as a consumer or run the trace. So bail out after processing all
// the options.
- if (!triggers_to_activate.empty()) {
- LogUploadEvent(PerfettoStatsdAtom::kTriggerBegin);
- LogTriggerEvents(PerfettoTriggerAtom::kCmdTrigger, triggers_to_activate);
+ if (!triggers_to_activate_.empty()) {
+ LogTriggerEvents(PerfettoTriggerAtom::kCmdTrigger, triggers_to_activate_);
bool finished_with_success = false;
TriggerProducer producer(
@@ -672,43 +875,27 @@ int PerfettoCmd::Main(int argc, char** argv) {
finished_with_success = success;
task_runner_.Quit();
},
- &triggers_to_activate);
+ &triggers_to_activate_);
task_runner_.Run();
- if (finished_with_success) {
- LogUploadEvent(PerfettoStatsdAtom::kTriggerSuccess);
- } else {
- LogUploadEvent(PerfettoStatsdAtom::kTriggerFailure);
+ if (!finished_with_success) {
LogTriggerEvents(PerfettoTriggerAtom::kCmdTriggerFail,
- triggers_to_activate);
+ triggers_to_activate_);
}
return finished_with_success ? 0 : 1;
- }
+ } // if (triggers_to_activate_)
if (query_service_ || bugreport_) {
consumer_endpoint_ =
ConsumerIPCClient::Connect(GetConsumerSocket(), this, &task_runner_);
task_runner_.Run();
return 1; // We can legitimately get here if the service disconnects.
- }
-
- if (trace_config_->compression_type() ==
- TraceConfig::COMPRESSION_TYPE_DEFLATE) {
- if (packet_writer_) {
-#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
- packet_writer_ = CreateZipPacketWriter(std::move(packet_writer_));
-#else
- PERFETTO_ELOG("Cannot compress. Zlib not enabled in the build config");
-#endif
- } else {
- PERFETTO_ELOG("Cannot compress when tracing directly to file.");
- }
- }
+ } // if (query_service || bugreport_)
RateLimiter::Args args{};
args.is_user_build = IsUserBuild();
- args.is_uploading = save_to_incidentd_;
+ args.is_uploading = save_to_incidentd_ || report_to_android_framework_;
args.current_time = base::GetWallTimeS();
- args.ignore_guardrails = ignore_guardrails;
+ args.ignore_guardrails = ignore_guardrails_;
args.allow_user_build_tracing = trace_config_->allow_user_build_tracing();
args.unique_session_name = trace_config_->unique_session_name();
args.max_upload_bytes_override =
@@ -717,13 +904,6 @@ int PerfettoCmd::Main(int argc, char** argv) {
if (!args.unique_session_name.empty())
base::MaybeSetThreadName("p-" + args.unique_session_name);
- if (args.is_uploading && !args.ignore_guardrails &&
- (trace_config_->duration_ms() == 0 &&
- trace_config_->trigger_config().trigger_timeout_ms() == 0)) {
- PERFETTO_ELOG("Can't trace indefinitely when tracing to Dropbox.");
- return 1;
- }
-
expected_duration_ms_ = trace_config_->duration_ms();
if (!expected_duration_ms_) {
uint32_t timeout_ms = trace_config_->trigger_config().trigger_timeout_ms();
@@ -734,31 +914,58 @@ int PerfettoCmd::Main(int argc, char** argv) {
expected_duration_ms_ = timeout_ms + max_stop_delay_ms;
}
+ const auto& delay = trace_config_->cmd_trace_start_delay();
+ if (delay.has_min_delay_ms()) {
+ PERFETTO_DCHECK(delay.has_max_delay_ms());
+ std::random_device r;
+ std::minstd_rand minstd(r());
+ std::uniform_int_distribution<uint32_t> dist(delay.min_delay_ms(),
+ delay.max_delay_ms());
+ std::this_thread::sleep_for(std::chrono::milliseconds(dist(minstd)));
+ }
+
if (trace_config_->trigger_config().trigger_timeout_ms() == 0) {
LogUploadEvent(PerfettoStatsdAtom::kTraceBegin);
} else {
LogUploadEvent(PerfettoStatsdAtom::kBackgroundTraceBegin);
}
- auto err_atom = ConvertRateLimiterResponseToAtom(limiter.ShouldTrace(args));
+ auto err_atom = ConvertRateLimiterResponseToAtom(limiter_->ShouldTrace(args));
if (err_atom) {
- // TODO(lalitm): remove this once we're ready on server side.
- LogUploadEvent(PerfettoStatsdAtom::kHitGuardrails);
LogUploadEvent(err_atom.value());
return 1;
}
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+ if (!background_ && !is_detach() && !upload_flag_ &&
+ triggers_to_activate_.empty() && !isatty(STDIN_FILENO) &&
+ !isatty(STDERR_FILENO)) {
+ fprintf(stderr,
+ "Warning: No PTY. CTRL+C won't gracefully stop the trace. If you "
+ "are running perfetto via adb shell, use the -tt arg (adb shell "
+ "-t perfetto ...) or consider using the helper script "
+ "tools/record_android_trace from the Perfetto repository.\n\n");
+ }
+#endif
+
consumer_endpoint_ =
ConsumerIPCClient::Connect(GetConsumerSocket(), this, &task_runner_);
SetupCtrlCSignalHandler();
task_runner_.Run();
- return limiter.OnTraceDone(args, update_guardrail_state_, bytes_written_) ? 0
- : 1;
+ return limiter_->OnTraceDone(args, update_guardrail_state_, bytes_written_)
+ ? 0
+ : 1;
}
void PerfettoCmd::OnConnect() {
LogUploadEvent(PerfettoStatsdAtom::kOnConnect);
+
+ if (background_wait_) {
+ consumer_endpoint_->ObserveEvents(
+ perfetto::ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED);
+ }
+
if (query_service_) {
consumer_endpoint_->QueryServiceState(
[this](bool success, const TracingServiceState& svc_state) {
@@ -904,7 +1111,11 @@ void PerfettoCmd::FinalizeTraceAndExit() {
if (save_to_incidentd_) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
- SaveTraceIntoDropboxAndIncidentOrCrash();
+ SaveTraceIntoIncidentOrCrash();
+#endif
+ } else if (report_to_android_framework_) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+ ReportTraceToAndroidFrameworkOrCrash();
#endif
} else {
trace_out_stream_.reset();
@@ -917,6 +1128,12 @@ void PerfettoCmd::FinalizeTraceAndExit() {
}
}
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+ // When multiple traces are being recorded at the same time, this is used to
+ // correlate one trace with another.
+ ReportFinalizeTraceUuidToAtrace(base::Uuid(uuid_));
+#endif
+
update_guardrail_state_ = true;
task_runner_.Quit();
}
@@ -946,7 +1163,7 @@ bool PerfettoCmd::OpenOutputFile() {
}
void PerfettoCmd::SetupCtrlCSignalHandler() {
- base::InstallCtrCHandler([] { g_consumer_cmd->SignalCtrlC(); });
+ base::InstallCtrCHandler([] { g_perfetto_cmd->SignalCtrlC(); });
task_runner_.AddFileDescriptorWatch(ctrl_c_evt_.fd(), [this] {
PERFETTO_LOG("SIGINT/SIGTERM received: disabling tracing.");
ctrl_c_evt_.Clear();
@@ -1014,33 +1231,111 @@ void PerfettoCmd::PrintServiceState(bool success,
return;
}
- printf("Not meant for machine consumption. Use --query-raw for scripts.\n");
+ printf(
+ "\x1b[31mNot meant for machine consumption. Use --query-raw for "
+ "scripts.\x1b[0m\n\n");
+ printf(
+ "Service: %s\n"
+ "Tracing sessions: %d (started: %d)\n",
+ svc_state.tracing_service_version().c_str(), svc_state.num_sessions(),
+ svc_state.num_sessions_started());
+ printf(R"(
+
+PRODUCER PROCESSES CONNECTED:
+
+ID PID UID NAME SDK
+== === === ==== ===
+)");
for (const auto& producer : svc_state.producers()) {
- printf("producers: {\n");
- printf(" id: %d\n", producer.id());
- printf(" name: \"%s\" \n", producer.name().c_str());
- printf(" uid: %d \n", producer.uid());
- printf(" sdk_version: \"%s\" \n", producer.sdk_version().c_str());
- printf("}\n");
+ printf("%-10d %-10d %-10d %-32s %s\n", producer.id(), producer.pid(),
+ producer.uid(), producer.name().c_str(),
+ producer.sdk_version().c_str());
}
+ printf(R"(
+
+DATA SOURCES REGISTERED:
+
+NAME PRODUCER DETAILS
+=== ======== ========
+)");
for (const auto& ds : svc_state.data_sources()) {
- printf("data_sources: {\n");
- printf(" producer_id: %d\n", ds.producer_id());
- printf(" descriptor: {\n");
- printf(" name: \"%s\"\n", ds.ds_descriptor().name().c_str());
- printf(" }\n");
- printf("}\n");
- }
- printf("tracing_service_version: \"%s\"\n",
- svc_state.tracing_service_version().c_str());
- printf("num_sessions: %d\n", svc_state.num_sessions());
- printf("num_sessions_started: %d\n", svc_state.num_sessions_started());
+ char producer_id_and_name[128]{};
+ const int ds_producer_id = ds.producer_id();
+ for (const auto& producer : svc_state.producers()) {
+ if (producer.id() == ds_producer_id) {
+ base::SprintfTrunc(producer_id_and_name, sizeof(producer_id_and_name),
+ "%s (%d)", producer.name().c_str(), ds_producer_id);
+ break;
+ }
+ }
+
+ printf("%-40s %-40s ", ds.ds_descriptor().name().c_str(),
+ producer_id_and_name);
+ // Print the category names for clients using the track event SDK.
+ if (!ds.ds_descriptor().track_event_descriptor_raw().empty()) {
+ const std::string& raw = ds.ds_descriptor().track_event_descriptor_raw();
+ protos::gen::TrackEventDescriptor desc;
+ if (desc.ParseFromArray(raw.data(), raw.size())) {
+ for (const auto& cat : desc.available_categories()) {
+ printf("%s,", cat.name().c_str());
+ }
+ }
+ } else if (!ds.ds_descriptor().ftrace_descriptor_raw().empty()) {
+ const std::string& raw = ds.ds_descriptor().ftrace_descriptor_raw();
+ protos::gen::FtraceDescriptor desc;
+ if (desc.ParseFromArray(raw.data(), raw.size())) {
+ for (const auto& cat : desc.atrace_categories()) {
+ printf("%s,", cat.name().c_str());
+ }
+ }
+ }
+ printf("\n");
+ } // for data_sources()
+
+ if (svc_state.supports_tracing_sessions()) {
+ printf(R"(
+
+TRACING SESSIONS:
+
+ID UID STATE BUF (#) KB DUR (s) #DS STARTED NAME
+=== === ===== ========== ======= === ======= ====
+)");
+ for (const auto& sess : svc_state.tracing_sessions()) {
+ uint32_t buf_tot_kb = 0;
+ for (uint32_t kb : sess.buffer_size_kb())
+ buf_tot_kb += kb;
+ int sec =
+ static_cast<int>((sess.start_realtime_ns() / 1000000000) % 86400);
+ int h = sec / 3600;
+ int m = (sec - (h * 3600)) / 60;
+ int s = (sec - h * 3600 - m * 60);
+ printf("%-7" PRIu64 " %-7d %-10s (%d) %-8u %-9u %-4u %02d:%02d:%02d %s\n",
+ sess.id(), sess.consumer_uid(), sess.state().c_str(),
+ sess.buffer_size_kb_size(), buf_tot_kb, sess.duration_ms() / 1000,
+ sess.num_data_sources(), h, m, s,
+ sess.unique_session_name().c_str());
+ } // for tracing_sessions()
+
+ int sessions_listed = static_cast<int>(svc_state.tracing_sessions().size());
+ if (sessions_listed != svc_state.num_sessions() &&
+ base::GetCurrentUserId() != 0) {
+ printf(
+ "\n"
+ "NOTE: Some tracing sessions are not reported in the list above.\n"
+ "This is likely because they are owned by a different UID.\n"
+ "If you want to list all session, run again this command as root.\n");
+ }
+ } // if (supports_tracing_sessions)
}
void PerfettoCmd::OnObservableEvents(
- const ObservableEvents& /*observable_events*/) {}
+ const ObservableEvents& observable_events) {
+ if (observable_events.all_data_sources_started()) {
+ NotifyBgProcessPipe(kBackgroundOk);
+ }
+}
void PerfettoCmd::LogUploadEvent(PerfettoStatsdAtom atom) {
if (!statsd_logging_)
@@ -1058,8 +1353,11 @@ void PerfettoCmd::LogTriggerEvents(
}
int PERFETTO_EXPORT_ENTRYPOINT PerfettoCmdMain(int argc, char** argv) {
- g_consumer_cmd = new perfetto::PerfettoCmd();
- return g_consumer_cmd->Main(argc, argv);
+ perfetto::PerfettoCmd cmd;
+ auto opt_res = cmd.ParseCmdlineAndMaybeDaemonize(argc, argv);
+ if (opt_res.has_value())
+ return *opt_res;
+ return cmd.ConnectToServiceRunAndMaybeNotify();
}
} // namespace perfetto
diff --git a/src/perfetto_cmd/perfetto_cmd.h b/src/perfetto_cmd/perfetto_cmd.h
index 215c3beeb..28c7733cc 100644
--- a/src/perfetto_cmd/perfetto_cmd.h
+++ b/src/perfetto_cmd/perfetto_cmd.h
@@ -26,6 +26,7 @@
#include "perfetto/base/build_config.h"
#include "perfetto/ext/base/event_fd.h"
#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/pipe.h"
#include "perfetto/ext/base/scoped_file.h"
#include "perfetto/ext/base/unix_task_runner.h"
#include "perfetto/ext/tracing/core/consumer.h"
@@ -36,6 +37,7 @@
namespace perfetto {
class PacketWriter;
+class RateLimiter;
// Directory for local state and temporary files. This is automatically
// created by the system by setting setprop persist.traced.enable=1.
@@ -43,7 +45,18 @@ extern const char* kStateDir;
class PerfettoCmd : public Consumer {
public:
- int Main(int argc, char** argv);
+ PerfettoCmd();
+ ~PerfettoCmd() override;
+
+ // The main() is split in two stages: cmdline parsing and actual interaction
+ // with traced. This is to allow tools like tracebox to avoid spawning the
+ // service for no reason if the cmdline parsing fails.
+ // Return value:
+ // nullopt: no error, the caller should call
+ // ConnectToServiceRunAndMaybeNotify.
+ // 0-N: the caller should exit() with the given exit code.
+ base::Optional<int> ParseCmdlineAndMaybeDaemonize(int argc, char** argv);
+ int ConnectToServiceRunAndMaybeNotify();
// perfetto::Consumer implementation.
void OnConnect() override;
@@ -61,7 +74,7 @@ class PerfettoCmd : public Consumer {
bool OpenOutputFile();
void SetupCtrlCSignalHandler();
void FinalizeTraceAndExit();
- int PrintUsage(const char* argv0);
+ void PrintUsage(const char* argv0);
void PrintServiceState(bool success, const TracingServiceState&);
void OnTimeout();
bool is_detach() const { return !detach_key_.empty(); }
@@ -75,10 +88,36 @@ class PerfettoCmd : public Consumer {
// within OnTraceDataTimeoutMs of when we expected to.
void CheckTraceDataTimeout();
+ int ConnectToServiceAndRun();
+
+ enum BgProcessStatus : char {
+ kBackgroundOk = 0,
+ kBackgroundOtherError = 1,
+ kBackgroundTimeout = 2,
+ };
+
+ // Used to implement the --background-wait flag.
+ //
+ // Waits (up to 30s) for the child process to signal (success or an error).
+ //
+ // Returns the status received from the child process or kTimeout, in case of
+ // timeout.
+ BgProcessStatus WaitOnBgProcessPipe();
+
+ // Used to implement the --background-wait flag.
+ //
+ // Signals the parent process (if there is one) that it can exit (successfully
+ // or with an error).
+ //
+ // Only the first time this function is called is significant. Further calls
+ // will have no effect.
+ void NotifyBgProcessPipe(BgProcessStatus status);
+
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
static base::ScopedFile CreateUnlinkedTmpFile();
- void SaveTraceIntoDropboxAndIncidentOrCrash();
+ void SaveTraceIntoIncidentOrCrash();
void SaveOutputToIncidentTraceOrCrash();
+ void ReportTraceToAndroidFrameworkOrCrash();
#endif
void LogUploadEvent(PerfettoStatsdAtom atom);
void LogTriggerEvents(PerfettoTriggerAtom atom,
@@ -86,16 +125,18 @@ class PerfettoCmd : public Consumer {
base::UnixTaskRunner task_runner_;
+ std::unique_ptr<RateLimiter> limiter_;
std::unique_ptr<perfetto::TracingService::ConsumerEndpoint>
consumer_endpoint_;
std::unique_ptr<TraceConfig> trace_config_;
-
std::unique_ptr<PacketWriter> packet_writer_;
base::ScopedFstream trace_out_stream_;
-
+ std::vector<std::string> triggers_to_activate_;
std::string trace_out_path_;
base::EventFd ctrl_c_evt_;
+ base::Pipe background_wait_pipe_;
bool save_to_incidentd_ = false;
+ bool report_to_android_framework_ = false;
bool statsd_logging_ = false;
bool update_guardrail_state_ = false;
uint64_t bytes_written_ = 0;
@@ -106,6 +147,10 @@ class PerfettoCmd : public Consumer {
bool query_service_ = false;
bool query_service_output_raw_ = false;
bool bugreport_ = false;
+ bool background_ = false;
+ bool background_wait_ = false;
+ bool ignore_guardrails_ = false;
+ bool upload_flag_ = false;
std::string uuid_;
// How long we expect to trace for or 0 if the trace is indefinite.
diff --git a/src/perfetto_cmd/perfetto_cmd_android.cc b/src/perfetto_cmd/perfetto_cmd_android.cc
index d64fe85cb..c1fa07bd9 100644
--- a/src/perfetto_cmd/perfetto_cmd_android.cc
+++ b/src/perfetto_cmd/perfetto_cmd_android.cc
@@ -16,16 +16,19 @@
#include "src/perfetto_cmd/perfetto_cmd.h"
-#include <inttypes.h>
#include <sys/sendfile.h>
+#include <cinttypes>
+
#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/uuid.h"
#include "perfetto/tracing/core/trace_config.h"
#include "src/android_internal/incident_service.h"
#include "src/android_internal/lazy_library_loader.h"
+#include "src/android_internal/tracing_service_proxy.h"
namespace perfetto {
namespace {
@@ -34,10 +37,12 @@ constexpr int64_t kSendfileTimeoutNs = 10UL * 1000 * 1000 * 1000; // 10s
} // namespace
-void PerfettoCmd::SaveTraceIntoDropboxAndIncidentOrCrash() {
+void PerfettoCmd::SaveTraceIntoIncidentOrCrash() {
PERFETTO_CHECK(save_to_incidentd_);
- PERFETTO_CHECK(
- !trace_config_->incident_report_config().destination_package().empty());
+
+ const auto& cfg = trace_config_->incident_report_config();
+ PERFETTO_CHECK(!cfg.destination_package().empty());
+ PERFETTO_CHECK(!cfg.skip_incidentd());
if (bytes_written_ == 0) {
LogUploadEvent(PerfettoStatsdAtom::kNotUploadingEmptyTrace);
@@ -48,21 +53,64 @@ void PerfettoCmd::SaveTraceIntoDropboxAndIncidentOrCrash() {
// Save the trace as an incident.
SaveOutputToIncidentTraceOrCrash();
- if (!uuid_.empty()) {
+ // Skip the trace-uuid link for traces that are too small. Realistically those
+ // traces contain only a marker (e.g. seized_for_bugreport, or the trace
+ // expired without triggers). Those are useless and introduce only noise.
+ if (bytes_written_ > 4096) {
base::Uuid uuid(uuid_);
- PERFETTO_LOG("go/trace-uuid/%s (%" PRIu64 " bytes)",
- uuid.ToPrettyString().c_str(), bytes_written_);
+ PERFETTO_LOG("go/trace-uuid/%s name=\"%s\" size=%" PRIu64,
+ uuid.ToPrettyString().c_str(),
+ trace_config_->unique_session_name().c_str(), bytes_written_);
}
// Ask incidentd to create a report, which will read the file we just
// wrote.
- const auto& cfg = trace_config_->incident_report_config();
PERFETTO_LAZY_LOAD(android_internal::StartIncidentReport, incident_fn);
PERFETTO_CHECK(incident_fn(cfg.destination_package().c_str(),
cfg.destination_class().c_str(),
cfg.privacy_level()));
}
+void PerfettoCmd::ReportTraceToAndroidFrameworkOrCrash() {
+ PERFETTO_CHECK(report_to_android_framework_);
+ PERFETTO_CHECK(trace_out_stream_);
+
+ const auto& cfg = trace_config_->android_report_config();
+ PERFETTO_CHECK(!cfg.reporter_service_package().empty());
+ PERFETTO_CHECK(!cfg.skip_report());
+
+ if (bytes_written_ == 0) {
+ LogUploadEvent(PerfettoStatsdAtom::kCmdFwReportEmptyTrace);
+ PERFETTO_LOG("Skipping reporting trace to Android. Empty trace.");
+ return;
+ }
+
+ LogUploadEvent(PerfettoStatsdAtom::kCmdFwReportBegin);
+ base::StackString<128> self_fd("/proc/self/fd/%d",
+ fileno(*trace_out_stream_));
+ base::ScopedFile fd(base::OpenFile(self_fd.c_str(), O_RDONLY | O_CLOEXEC));
+ if (!fd) {
+ PERFETTO_FATAL("Failed to dup fd when reporting to Android");
+ }
+
+ base::Uuid uuid(uuid_);
+ PERFETTO_LAZY_LOAD(android_internal::ReportTrace, report_fn);
+ PERFETTO_CHECK(report_fn(cfg.reporter_service_package().c_str(),
+ cfg.reporter_service_class().c_str(), fd.release(),
+ uuid.lsb(), uuid.msb(),
+ cfg.use_pipe_in_framework_for_testing()));
+
+ // Skip the trace-uuid link for traces that are too small. Realistically those
+ // traces contain only a marker (e.g. seized_for_bugreport, or the trace
+ // expired without triggers). Those are useless and introduce only noise.
+ if (bytes_written_ > 4096) {
+ PERFETTO_LOG("go/trace-uuid/%s name=\"%s\" size=%" PRIu64,
+ uuid.ToPrettyString().c_str(),
+ trace_config_->unique_session_name().c_str(), bytes_written_);
+ }
+ LogUploadEvent(PerfettoStatsdAtom::kCmdFwReportHandoff);
+}
+
// Open a staging file (unlinking the previous instance), copy the trace
// contents over, then rename to a final hardcoded path (known to incidentd).
// Such tracing sessions should not normally overlap. We do not use unique
diff --git a/src/perfetto_cmd/rate_limiter.cc b/src/perfetto_cmd/rate_limiter.cc
index 65e26e3f1..75e36cb4d 100644
--- a/src/perfetto_cmd/rate_limiter.cc
+++ b/src/perfetto_cmd/rate_limiter.cc
@@ -17,11 +17,11 @@
#include "src/perfetto_cmd/rate_limiter.h"
#include <fcntl.h>
-#include <inttypes.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <algorithm>
+#include <cinttypes>
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/file_utils.h"
diff --git a/src/profiling/OWNERS b/src/profiling/OWNERS
new file mode 100644
index 000000000..cbe914be5
--- /dev/null
+++ b/src/profiling/OWNERS
@@ -0,0 +1,2 @@
+ddiproietto@google.com
+rsavitski@google.com
diff --git a/src/profiling/common/BUILD.gn b/src/profiling/common/BUILD.gn
index 583edc65a..1fcc6fb96 100644
--- a/src/profiling/common/BUILD.gn
+++ b/src/profiling/common/BUILD.gn
@@ -66,8 +66,8 @@ source_set("interning_output") {
source_set("proc_utils") {
deps = [
+ ":proc_cmdline",
"../../../gn:default_deps",
- "../../../include/perfetto/profiling:normalize",
"../../base",
]
sources = [
@@ -76,6 +76,17 @@ source_set("proc_utils") {
]
}
+source_set("proc_cmdline") {
+ deps = [
+ "../../../gn:default_deps",
+ "../../base",
+ ]
+ sources = [
+ "proc_cmdline.cc",
+ "proc_cmdline.h",
+ ]
+}
+
source_set("producer_support") {
deps = [
"../../../gn:default_deps",
@@ -106,18 +117,19 @@ perfetto_unittest_source_set("unittests") {
testonly = true
deps = [
":interner",
+ ":proc_cmdline",
":proc_utils",
":producer_support",
":profiler_guardrails",
"../../../gn:default_deps",
"../../../gn:gtest_and_gmock",
- "../../../include/perfetto/profiling:normalize",
"../../base",
"../../base:test_support",
"../../tracing/core",
]
sources = [
"interner_unittest.cc",
+ "proc_cmdline_unittest.cc",
"proc_utils_unittest.cc",
"producer_support_unittest.cc",
"profiler_guardrails_unittest.cc",
diff --git a/src/profiling/common/callstack_trie.cc b/src/profiling/common/callstack_trie.cc
index 81d00635f..7cfd0833d 100644
--- a/src/profiling/common/callstack_trie.cc
+++ b/src/profiling/common/callstack_trie.cc
@@ -100,14 +100,16 @@ Interned<Frame> GlobalCallstackTrie::InternCodeLocation(
const unwindstack::FrameData& loc,
const std::string& build_id) {
Mapping map(string_interner_.Intern(build_id));
- map.exact_offset = loc.map_exact_offset;
- map.start_offset = loc.map_elf_start_offset;
- map.start = loc.map_start;
- map.end = loc.map_end;
- map.load_bias = loc.map_load_bias;
- base::StringSplitter sp(loc.map_name, '/');
- while (sp.Next())
- map.path_components.emplace_back(string_interner_.Intern(sp.cur_token()));
+ if (loc.map_info != nullptr) {
+ map.exact_offset = loc.map_info->offset();
+ map.start_offset = loc.map_info->elf_start_offset();
+ map.start = loc.map_info->start();
+ map.end = loc.map_info->end();
+ map.load_bias = loc.map_info->GetLoadBias();
+ base::StringSplitter sp(loc.map_info->GetFullName(), '/');
+ while (sp.Next())
+ map.path_components.emplace_back(string_interner_.Intern(sp.cur_token()));
+ }
Frame frame(mapping_interner_.Intern(std::move(map)),
string_interner_.Intern(loc.function_name), loc.rel_pc);
diff --git a/src/profiling/common/callstack_trie.h b/src/profiling/common/callstack_trie.h
index f8ca30450..f5d2378cd 100644
--- a/src/profiling/common/callstack_trie.h
+++ b/src/profiling/common/callstack_trie.h
@@ -184,6 +184,8 @@ class GlobalCallstackTrie {
uint64_t next_callstack_id_ = 0;
+ // Note: profile_module in trace processor relies on the value of this root
+ // callsite being exactly "1". See the perf_sample parsing code.
Node root_{MakeRootFrame(), ++next_callstack_id_};
};
diff --git a/src/profiling/common/proc_cmdline.cc b/src/profiling/common/proc_cmdline.cc
new file mode 100644
index 000000000..a6f7d93c0
--- /dev/null
+++ b/src/profiling/common/proc_cmdline.cc
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/profiling/common/proc_cmdline.h"
+
+#include <fcntl.h>
+#include <fnmatch.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "perfetto/ext/base/file_utils.h"
+
+namespace perfetto {
+namespace profiling {
+namespace glob_aware {
+
+// Edge cases: the raw cmdline as read out of the kernel can have several
+// shapes, the process can rewrite the contents to be arbitrary, and overly long
+// cmdlines can be truncated as we use a 511 byte limit. Some examples to
+// consider for the implementation:
+// * "echo\0hello\0"
+// * "/bin/top\0\0\0\0\0\0\0"
+// * "arbitrary string as rewritten by the process\0"
+// * "some_bugged_kernels_forget_final_nul_terminator"
+//
+// The approach when performing the read->derive->match is to minimize early
+// return codepaths for the caller. So even if we read a non-conforming cmdline
+// (e.g. just a single nul byte), it can still be fed through FindBinaryName and
+// MatchGlobPattern. It'll just make the intermediate strings be empty (so
+// starting with a nul byte, but never nullptr).
+//
+// NB: bionic/libc/bionic/malloc_heapprofd will require a parallel
+// implementation of these functions (to avoid a bionic->perfetto dependency).
+// Keep them as STL-free as possible to allow for both implementations to be
+// close to verbatim copies.
+
+// TODO(rsavitski): consider changing to Optional<> return type.
+bool ReadProcCmdlineForPID(pid_t pid, std::string* cmdline_out) {
+ std::string filename = "/proc/" + std::to_string(pid) + "/cmdline";
+ base::ScopedFile fd(base::OpenFile(filename, O_RDONLY));
+ if (!fd) {
+ PERFETTO_DPLOG("Failed to open %s", filename.c_str());
+ return false;
+ }
+
+ // buf is 511 bytes to match an implementation that adds a null terminator to
+ // the back of a 512 byte buffer.
+ char buf[511];
+ ssize_t rd = PERFETTO_EINTR(read(*fd, buf, sizeof(buf)));
+ if (rd < 0) {
+ PERFETTO_DPLOG("Failed to read %s", filename.c_str());
+ return false;
+ }
+
+ cmdline_out->assign(buf, static_cast<size_t>(rd));
+ return true;
+}
+
+// Returns a pointer into |cmdline| corresponding to the argv0 without any
+// leading directories if the binary path is absolute. |cmdline_len| corresponds
+// to the length of the cmdline string as read out of procfs as a C string -
+// length doesn't include the final nul terminator, but it must be present at
+// cmdline[cmdline_len]. Note that normally the string itself will contain nul
+// bytes, as that's what the kernel uses to separate arguments.
+//
+// Function output examples:
+// * /system/bin/adb\0--flag -> adb
+// * adb -> adb
+// * com.example.app -> com.example.app
+const char* FindBinaryName(const char* cmdline, size_t cmdline_len) {
+ // Find the first nul byte that signifies the end of argv0. We might not find
+ // one if the process rewrote its cmdline without nul separators, and/or the
+ // cmdline didn't fully fit into our read buffer. In such cases, proceed with
+ // the full string to do best-effort matching.
+ const char* argv0_end =
+ static_cast<const char*>(memchr(cmdline, '\0', cmdline_len));
+ if (argv0_end == nullptr) {
+ argv0_end = cmdline + cmdline_len; // set to final nul terminator
+ }
+ // Find the last path separator of argv0, if it exists.
+ const char* name_start = static_cast<const char*>(
+ memrchr(cmdline, '/', static_cast<size_t>(argv0_end - cmdline)));
+ if (name_start == nullptr) {
+ name_start = cmdline;
+ } else {
+ name_start++; // skip the separator
+ }
+ return name_start;
+}
+
+// All inputs must be non-nullptr, but can start with a nul byte.
+bool MatchGlobPattern(const char* pattern,
+ const char* cmdline,
+ const char* binname) {
+ if (pattern[0] == '/') {
+ return fnmatch(pattern, cmdline, FNM_NOESCAPE) == 0;
+ }
+ return fnmatch(pattern, binname, FNM_NOESCAPE) == 0;
+}
+
+} // namespace glob_aware
+} // namespace profiling
+} // namespace perfetto
diff --git a/src/profiling/common/proc_cmdline.h b/src/profiling/common/proc_cmdline.h
new file mode 100644
index 000000000..1d01f931e
--- /dev/null
+++ b/src/profiling/common/proc_cmdline.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_PROFILING_COMMON_PROC_CMDLINE_H_
+#define SRC_PROFILING_COMMON_PROC_CMDLINE_H_
+
+#include <sys/types.h>
+
+#include <string>
+
+namespace perfetto {
+namespace profiling {
+
+// TODO(rsavitski): these functions are a reimplementation of those found in
+// proc_utils, but with a change in semantics that we intend for all profilers.
+// Eventually this should become the single canonical file dealing with proc
+// cmdlines. The transition will start with traced_perf and perfetto_hprof, and
+// heapprofd will follow later.
+namespace glob_aware {
+
+// These functions let the profilers read a /proc/pid/cmdline, find the
+// substrings corresponding to the argv0 as well as the binary name (e.g.
+// "/bin/echo" and "echo" respectively), and then match it against a set of glob
+// patterns.
+//
+// Example usage:
+// std::string cmdline;
+// bool success = ReadProcCmdlineForPID(42, &cmdline);
+// if (!success) return false;
+// const char* binname = FindBinaryName(cmdline.c_str(), cmdline.size());
+// return MatchGlobPattern("test*", cmdline.c_str(), binname);
+
+bool ReadProcCmdlineForPID(pid_t pid, std::string* cmdline_out);
+const char* FindBinaryName(const char* cmdline, size_t cmdline_len);
+bool MatchGlobPattern(const char* pattern,
+ const char* cmdline,
+ const char* binname);
+
+} // namespace glob_aware
+} // namespace profiling
+} // namespace perfetto
+
+#endif // SRC_PROFILING_COMMON_PROC_CMDLINE_H_
diff --git a/src/profiling/common/proc_cmdline_unittest.cc b/src/profiling/common/proc_cmdline_unittest.cc
new file mode 100644
index 000000000..dc23594dc
--- /dev/null
+++ b/src/profiling/common/proc_cmdline_unittest.cc
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/profiling/common/proc_cmdline.h"
+
+#include <string>
+
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace profiling {
+namespace glob_aware {
+namespace {
+
+TEST(ProcCmdlineTest, FindBinaryNameBinNameOnly) {
+ char cmdline[] = "surfaceflinger";
+ EXPECT_EQ(cmdline, FindBinaryName(cmdline, sizeof(cmdline) - 1));
+}
+
+TEST(ProcCmdlineTest, FindBinaryNameWithArg) {
+ char cmdline[] = "surfaceflinger\0--flag";
+ EXPECT_EQ(cmdline, FindBinaryName(cmdline, sizeof(cmdline) - 1));
+}
+
+TEST(ProcCmdlineTest, FindBinaryNameFullPathAndArgs) {
+ char cmdline[] = "/system/bin/surfaceflinger\0--flag\0--flag2";
+ EXPECT_STREQ("surfaceflinger", FindBinaryName(cmdline, sizeof(cmdline) - 1));
+}
+
+TEST(ProcCmdlineTest, FindBinaryNameSpecialCharsInName) {
+ {
+ char cmdline[] = "android.hardware.graphics.composer@2.2-service";
+ EXPECT_EQ(cmdline, FindBinaryName(cmdline, sizeof(cmdline) - 1));
+ }
+ {
+ char cmdline[] = "com.google.android.googlequicksearchbox:search";
+ EXPECT_EQ(cmdline, FindBinaryName(cmdline, sizeof(cmdline) - 1));
+ }
+ {
+ // chrome rewrites cmdline with spaces instead of nul bytes, parsing will
+ // therefore treat everything as argv0.
+ char cmdline[] =
+ "/opt/google/chrome/chrome --type=renderer --enable-crashpad";
+ EXPECT_STREQ("chrome --type=renderer --enable-crashpad",
+ FindBinaryName(cmdline, sizeof(cmdline) - 1));
+ }
+}
+
+TEST(ProcCmdlineTest, FindBinaryNameEdgeCases) {
+ {
+ char cmdline[] = "";
+ EXPECT_STREQ("", FindBinaryName(cmdline, sizeof(cmdline) - 1));
+ }
+ {
+ char cmdline[] = "\0foo";
+ EXPECT_STREQ("", FindBinaryName(cmdline, sizeof(cmdline) - 1));
+ }
+ {
+ char cmdline[] = "/foo/";
+ EXPECT_STREQ("", FindBinaryName(cmdline, sizeof(cmdline) - 1));
+ }
+ {
+ char cmdline[] = "/";
+ EXPECT_STREQ("", FindBinaryName(cmdline, sizeof(cmdline) - 1));
+ }
+ {
+ char cmdline[] = "foo/\0";
+ EXPECT_STREQ("", FindBinaryName(cmdline, sizeof(cmdline) - 1));
+ }
+}
+
+TEST(ProcCmdlineTest, FindAndMatchAbsolutePath) {
+ char cmdline[] = "/system/bin/surfaceflinger\0--flag\0--flag2";
+ const char* binname = FindBinaryName(cmdline, sizeof(cmdline) - 1);
+ ASSERT_TRUE(binname != nullptr);
+
+ EXPECT_TRUE(MatchGlobPattern("/system/bin/surfaceflinger", cmdline, binname));
+ EXPECT_TRUE(MatchGlobPattern("/*/surfaceflinger", cmdline, binname));
+ EXPECT_TRUE(MatchGlobPattern("surfaceflinger", cmdline, binname));
+ EXPECT_TRUE(MatchGlobPattern("???faceflinger", cmdline, binname));
+ EXPECT_TRUE(MatchGlobPattern("*", cmdline, binname));
+
+ EXPECT_FALSE(MatchGlobPattern("/system", cmdline, binname));
+ EXPECT_FALSE(MatchGlobPattern("bin/surfaceflinger", cmdline, binname));
+ EXPECT_FALSE(
+ MatchGlobPattern("?system/bin/surfaceflinger", cmdline, binname));
+ EXPECT_FALSE(MatchGlobPattern("*/surfaceflinger", cmdline, binname));
+}
+
+TEST(ProcCmdlineTest, FindAndMatchRelativePath) {
+ char cmdline[] = "./top";
+ const char* binname = FindBinaryName(cmdline, sizeof(cmdline) - 1);
+ ASSERT_TRUE(binname != nullptr);
+
+ EXPECT_TRUE(MatchGlobPattern("top", cmdline, binname));
+ EXPECT_TRUE(MatchGlobPattern("*", cmdline, binname));
+
+ EXPECT_FALSE(MatchGlobPattern("./top", cmdline, binname));
+}
+
+} // namespace
+} // namespace glob_aware
+} // namespace profiling
+} // namespace perfetto
diff --git a/src/profiling/common/proc_utils.cc b/src/profiling/common/proc_utils.cc
index c2d1e5569..4188b2aba 100644
--- a/src/profiling/common/proc_utils.cc
+++ b/src/profiling/common/proc_utils.cc
@@ -16,30 +16,20 @@
#include "src/profiling/common/proc_utils.h"
-#include <inttypes.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <cinttypes>
+
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/optional.h"
-#include "perfetto/profiling/normalize.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "src/profiling/common/proc_cmdline.h"
namespace perfetto {
namespace profiling {
namespace {
-bool GetProcFile(pid_t pid, const char* file, char* filename_buf, size_t size) {
- ssize_t written = snprintf(filename_buf, size, "/proc/%d/%s", pid, file);
- if (written < 0 || static_cast<size_t>(written) >= size) {
- if (written < 0)
- PERFETTO_ELOG("Failed to concatenate cmdline file.");
- else
- PERFETTO_ELOG("Overflow when concatenating cmdline file.");
- return false;
- }
- return true;
-}
-
base::Optional<uint32_t> ParseProcStatusSize(const std::string& status,
const std::string& key) {
auto entry_idx = status.find(key);
@@ -57,6 +47,105 @@ base::Optional<uint32_t> ParseProcStatusSize(const std::string& status,
}
} // namespace
+base::Optional<std::string> ReadStatus(pid_t pid) {
+ std::string path = "/proc/" + std::to_string(pid) + "/status";
+ std::string status;
+ bool read_proc = base::ReadFile(path, &status);
+ if (!read_proc) {
+ PERFETTO_ELOG("Failed to read %s", path.c_str());
+ return base::nullopt;
+ }
+ return base::Optional<std::string>(status);
+}
+
+base::Optional<uint32_t> GetRssAnonAndSwap(const std::string& status) {
+ auto anon_rss = ParseProcStatusSize(status, "RssAnon:");
+ auto swap = ParseProcStatusSize(status, "VmSwap:");
+ if (anon_rss.has_value() && swap.has_value()) {
+ return *anon_rss + *swap;
+ }
+ return base::nullopt;
+}
+
+void RemoveUnderAnonThreshold(uint32_t min_size_kb, std::set<pid_t>* pids) {
+ for (auto it = pids->begin(); it != pids->end();) {
+ const pid_t pid = *it;
+
+ base::Optional<std::string> status = ReadStatus(pid);
+ base::Optional<uint32_t> rss_and_swap;
+ if (status)
+ rss_and_swap = GetRssAnonAndSwap(*status);
+
+ if (rss_and_swap && rss_and_swap < min_size_kb) {
+ PERFETTO_LOG("Removing pid %d from profiled set (anon: %d kB < %" PRIu32
+ ")",
+ pid, *rss_and_swap, min_size_kb);
+ it = pids->erase(it);
+ } else {
+ ++it;
+ }
+ }
+}
+
+base::Optional<Uids> GetUids(const std::string& status) {
+ auto entry_idx = status.find("Uid:");
+ if (entry_idx == std::string::npos)
+ return base::nullopt;
+
+ Uids uids;
+ const char* str = &status[entry_idx + 4];
+ char* endptr;
+
+ uids.real = strtoull(str, &endptr, 10);
+ if (*endptr != ' ' && *endptr != '\t')
+ return base::nullopt;
+
+ str = endptr;
+ uids.effective = strtoull(str, &endptr, 10);
+ if (*endptr != ' ' && *endptr != '\t')
+ return base::nullopt;
+
+ str = endptr;
+ uids.saved_set = strtoull(str, &endptr, 10);
+ if (*endptr != ' ' && *endptr != '\t')
+ return base::nullopt;
+
+ str = endptr;
+ uids.filesystem = strtoull(str, &endptr, 10);
+ if (*endptr != '\n' && *endptr != '\0')
+ return base::nullopt;
+ return uids;
+}
+
+// Normalize cmdline in place. Stores new beginning of string in *cmdline_ptr.
+// Returns new size of string (from new beginning).
+// Modifies string in *cmdline_ptr.
+ssize_t NormalizeCmdLine(char** cmdline_ptr, size_t size) {
+ char* cmdline = *cmdline_ptr;
+ char* first_arg = static_cast<char*>(memchr(cmdline, '\0', size));
+ if (first_arg == nullptr) {
+ errno = EOVERFLOW;
+ return -1;
+ }
+ // For consistency with what we do with Java app cmdlines, trim everything
+ // after the @ sign of the first arg.
+ char* first_at = static_cast<char*>(memchr(cmdline, '@', size));
+ if (first_at != nullptr && first_at < first_arg) {
+ *first_at = '\0';
+ first_arg = first_at;
+ }
+ char* start = static_cast<char*>(
+ memrchr(cmdline, '/', static_cast<size_t>(first_arg - cmdline)));
+ if (start == nullptr) {
+ start = cmdline;
+ } else {
+ // Skip the /.
+ start++;
+ }
+ *cmdline_ptr = start;
+ return first_arg - start;
+}
+
base::Optional<std::vector<std::string>> NormalizeCmdlines(
const std::vector<std::string>& cmdlines) {
std::vector<std::string> normalized_cmdlines;
@@ -129,8 +218,7 @@ void FindAllProfilablePids(std::set<pid_t>* pids) {
return;
char filename_buf[128];
- if (!GetProcFile(pid, "cmdline", filename_buf, sizeof(filename_buf)))
- return;
+ snprintf(filename_buf, sizeof(filename_buf), "/proc/%d/%s", pid, "cmdline");
struct stat statbuf;
// Check if we have permission to the process.
if (stat(filename_buf, &statbuf) == 0)
@@ -153,75 +241,27 @@ void FindPidsForCmdlines(const std::vector<std::string>& cmdlines,
});
}
-base::Optional<std::string> ReadStatus(pid_t pid) {
- std::string path = "/proc/" + std::to_string(pid) + "/status";
- std::string status;
- bool read_proc = base::ReadFile(path, &status);
- if (!read_proc) {
- PERFETTO_ELOG("Failed to read %s", path.c_str());
- return base::nullopt;
- }
- return base::Optional<std::string>(status);
-}
-
-base::Optional<uint32_t> GetRssAnonAndSwap(const std::string& status) {
- auto anon_rss = ParseProcStatusSize(status, "RssAnon:");
- auto swap = ParseProcStatusSize(status, "VmSwap:");
- if (anon_rss.has_value() && swap.has_value()) {
- return *anon_rss + *swap;
- }
- return base::nullopt;
-}
-
-void RemoveUnderAnonThreshold(uint32_t min_size_kb, std::set<pid_t>* pids) {
- for (auto it = pids->begin(); it != pids->end();) {
- const pid_t pid = *it;
-
- base::Optional<std::string> status = ReadStatus(pid);
- base::Optional<uint32_t> rss_and_swap;
- if (status)
- rss_and_swap = GetRssAnonAndSwap(*status);
+namespace glob_aware {
+void FindPidsForCmdlinePatterns(const std::vector<std::string>& patterns,
+ std::set<pid_t>* pids) {
+ ForEachPid([&patterns, pids](pid_t pid) {
+ if (pid == getpid())
+ return;
+ std::string cmdline;
+ if (!glob_aware::ReadProcCmdlineForPID(pid, &cmdline))
+ return;
+ const char* binname =
+ glob_aware::FindBinaryName(cmdline.c_str(), cmdline.size());
- if (rss_and_swap && rss_and_swap < min_size_kb) {
- PERFETTO_LOG("Removing pid %d from profiled set (anon: %d kB < %" PRIu32
- ")",
- pid, *rss_and_swap, min_size_kb);
- it = pids->erase(it);
- } else {
- ++it;
+ for (const std::string& pattern : patterns) {
+ if (glob_aware::MatchGlobPattern(pattern.c_str(), cmdline.c_str(),
+ binname)) {
+ pids->insert(pid);
+ }
}
- }
-}
-
-base::Optional<Uids> GetUids(const std::string& status) {
- auto entry_idx = status.find("Uid:");
- if (entry_idx == std::string::npos)
- return base::nullopt;
-
- Uids uids;
- const char* str = &status[entry_idx + 4];
- char* endptr;
-
- uids.real = strtoull(str, &endptr, 10);
- if (*endptr != ' ' && *endptr != '\t')
- return base::nullopt;
-
- str = endptr;
- uids.effective = strtoull(str, &endptr, 10);
- if (*endptr != ' ' && *endptr != '\t')
- return base::nullopt;
-
- str = endptr;
- uids.saved_set = strtoull(str, &endptr, 10);
- if (*endptr != ' ' && *endptr != '\t')
- return base::nullopt;
-
- str = endptr;
- uids.filesystem = strtoull(str, &endptr, 10);
- if (*endptr != '\n' && *endptr != '\0')
- return base::nullopt;
- return uids;
+ });
}
+} // namespace glob_aware
} // namespace profiling
} // namespace perfetto
diff --git a/src/profiling/common/proc_utils.h b/src/profiling/common/proc_utils.h
index facd10ef1..ccbf6335b 100644
--- a/src/profiling/common/proc_utils.h
+++ b/src/profiling/common/proc_utils.h
@@ -17,9 +17,9 @@
#ifndef SRC_PROFILING_COMMON_PROC_UTILS_H_
#define SRC_PROFILING_COMMON_PROC_UTILS_H_
-#include <inttypes.h>
#include <sys/types.h>
+#include <cinttypes>
#include <set>
#include <vector>
@@ -53,14 +53,6 @@ void ForEachPid(Fn callback) {
}
}
-base::Optional<std::vector<std::string>> NormalizeCmdlines(
- const std::vector<std::string>& cmdlines);
-
-void FindAllProfilablePids(std::set<pid_t>* pids);
-void FindPidsForCmdlines(const std::vector<std::string>& cmdlines,
- std::set<pid_t>* pids);
-bool GetCmdlineForPID(pid_t pid, std::string* name);
-
base::Optional<std::string> ReadStatus(pid_t pid);
base::Optional<uint32_t> GetRssAnonAndSwap(const std::string&);
// Filters the list of pids (in-place), keeping only the
@@ -69,6 +61,24 @@ void RemoveUnderAnonThreshold(uint32_t min_size_kb, std::set<pid_t>* pids);
base::Optional<Uids> GetUids(const std::string&);
+void FindAllProfilablePids(std::set<pid_t>* pids);
+
+// TODO(rsavitski): we're changing how the profilers treat proc cmdlines, the
+// newer semantics are implemented in proc_cmdline.h. Wrappers around those
+// implementations are placed in the "glob_aware" namespace here, until we
+// migrate to one implementation for all profilers.
+ssize_t NormalizeCmdLine(char** cmdline_ptr, size_t size);
+base::Optional<std::vector<std::string>> NormalizeCmdlines(
+ const std::vector<std::string>& cmdlines);
+void FindPidsForCmdlines(const std::vector<std::string>& cmdlines,
+ std::set<pid_t>* pids);
+bool GetCmdlineForPID(pid_t pid, std::string* name);
+
+namespace glob_aware {
+void FindPidsForCmdlinePatterns(const std::vector<std::string>& cmdlines,
+ std::set<pid_t>* pids);
+} // namespace glob_aware
+
} // namespace profiling
} // namespace perfetto
diff --git a/src/profiling/common/proc_utils_unittest.cc b/src/profiling/common/proc_utils_unittest.cc
index cec73d88d..36a7720db 100644
--- a/src/profiling/common/proc_utils_unittest.cc
+++ b/src/profiling/common/proc_utils_unittest.cc
@@ -16,7 +16,6 @@
#include "src/profiling/common/proc_utils.h"
#include "perfetto/ext/base/optional.h"
-#include "perfetto/profiling/normalize.h"
#include "perfetto/ext/base/utils.h"
#include "test/gtest_and_gmock.h"
diff --git a/src/profiling/common/producer_support.cc b/src/profiling/common/producer_support.cc
index 2347edda6..544d3c5a2 100644
--- a/src/profiling/common/producer_support.cc
+++ b/src/profiling/common/producer_support.cc
@@ -16,20 +16,61 @@
#include "src/profiling/common/producer_support.h"
+#include "perfetto/ext/base/android_utils.h"
#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/string_splitter.h"
#include "perfetto/tracing/core/data_source_config.h"
-
-#include "perfetto/tracing/core/forward_decls.h"
#include "src/traced/probes/packages_list/packages_list_parser.h"
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-#include <sys/system_properties.h>
-#endif
-
namespace perfetto {
namespace profiling {
+namespace {
+base::Optional<Package> FindInPackagesList(
+ uint64_t lookup_uid,
+ const std::string& packages_list_path) {
+ std::string content;
+ if (!base::ReadFile(packages_list_path, &content)) {
+ PERFETTO_ELOG("Failed to read %s", packages_list_path.c_str());
+ return base::nullopt;
+ }
+ for (base::StringSplitter ss(std::move(content), '\n'); ss.Next();) {
+ Package pkg;
+ if (!ReadPackagesListLine(ss.cur_token(), &pkg)) {
+ PERFETTO_ELOG("Failed to parse packages.list");
+ return base::nullopt;
+ }
+
+ if (pkg.uid == lookup_uid) {
+ return std::move(pkg); // -Wreturn-std-move-in-c++11
+ }
+ }
+ return base::nullopt;
+}
+
+bool AllPackagesProfileableByTrustedInitiator(
+ const std::string& packages_list_path) {
+ std::string content;
+ if (!base::ReadFile(packages_list_path, &content)) {
+ PERFETTO_ELOG("Failed to read %s", packages_list_path.c_str());
+ return false;
+ }
+ bool ret = true;
+ for (base::StringSplitter ss(std::move(content), '\n'); ss.Next();) {
+ Package pkg;
+ if (!ReadPackagesListLine(ss.cur_token(), &pkg)) {
+ PERFETTO_ELOG("Failed to parse packages.list");
+ return false;
+ }
+
+ ret = ret && (pkg.profileable || pkg.debuggable);
+ }
+ return ret;
+}
+
+} // namespace
+
bool CanProfile(const DataSourceConfig& ds_config,
uint64_t uid,
const std::vector<std::string>& installed_by) {
@@ -44,10 +85,8 @@ bool CanProfile(const DataSourceConfig& ds_config,
base::ignore_result(installed_by);
return true;
#else
- char buf[PROP_VALUE_MAX + 1] = {};
- int ret = __system_property_get("ro.build.type", buf);
- PERFETTO_CHECK(ret >= 0);
- return CanProfileAndroid(ds_config, uid, installed_by, std::string(buf),
+ std::string build_type = base::GetAndroidProp("ro.build.type");
+ return CanProfileAndroid(ds_config, uid, installed_by, build_type,
"/data/system/packages.list");
#endif
}
@@ -57,54 +96,85 @@ bool CanProfileAndroid(const DataSourceConfig& ds_config,
const std::vector<std::string>& installed_by,
const std::string& build_type,
const std::string& packages_list_path) {
- // These are replicated constants from libcutils android_filesystem_config.h
- constexpr auto kAidAppStart = 10000; // AID_APP_START
- constexpr auto kAidAppEnd = 19999; // AID_APP_END
- constexpr auto kAidUserOffset = 100000; // AID_USER_OFFSET
+ // These constants are replicated from libcutils android_filesystem_config.h,
+ // to allow for building and testing the profilers outside the android tree.
+ constexpr auto kAidSystem = 1000; // AID_SYSTEM
+ constexpr auto kAidUserOffset = 100000; // AID_USER_OFFSET
+ constexpr auto kAidAppStart = 10000; // AID_APP_START
+ constexpr auto kAidAppEnd = 19999; // AID_APP_END
+ constexpr auto kAidSdkSandboxStart = 20000; // AID_SDK_SANDBOX_PROCESS_START
+ constexpr auto kAidSdkSandboxEnd = 29999; // AID_SDK_SANDBOX_PROCESS_END
+ constexpr auto kAidIsolatedStart = 90000; // AID_ISOLATED_START
+ constexpr auto kAidIsolatedEnd = 99999; // AID_ISOLATED_END
- if (build_type != "user") {
+ if (!build_type.empty() && build_type != "user") {
return true;
}
- uint64_t uid_without_profile = uid % kAidUserOffset;
- if (uid_without_profile < kAidAppStart || kAidAppEnd < uid_without_profile) {
- // TODO(fmayer): relax this.
- return false; // no native services on user.
+ // TODO(b/217368496): remove this.
+ if (uid == kAidSystem) {
+ return ds_config.session_initiator() ==
+ DataSourceConfig::SESSION_INITIATOR_TRUSTED_SYSTEM;
}
- std::string content;
- if (!base::ReadFile(packages_list_path, &content)) {
- PERFETTO_ELOG("Failed to read %s.", packages_list_path.c_str());
+ uint64_t uid_without_profile = uid % kAidUserOffset;
+ uint64_t uid_for_lookup = 0;
+ if (uid_without_profile >= kAidAppStart &&
+ uid_without_profile <= kAidAppEnd) {
+ // normal app
+ uid_for_lookup = uid_without_profile;
+
+ } else if (uid_without_profile >= kAidSdkSandboxStart &&
+ uid_without_profile <= kAidSdkSandboxEnd) {
+ // sdk sandbox process, has deterministic mapping to corresponding app
+ uint64_t sdk_sandbox_offset = kAidSdkSandboxStart - kAidAppStart;
+ uid_for_lookup = uid_without_profile - sdk_sandbox_offset;
+
+ } else if (uid_without_profile >= kAidIsolatedStart &&
+ uid_without_profile <= kAidIsolatedEnd) {
+ // Isolated process. Such processes run under random UIDs and have no
+ // straightforward link to the original app's UID without consulting
+ // system_server. So we have to perform a very conservative check - if *all*
+ // packages are profileable, then any isolated process must be profileable
+ // as well, regardless of which package it's running for (which might not
+ // even be the package in which the service was defined).
+ // TODO(rsavitski): find a way for the platform to tell native services
+ // about isolated<->app relations.
+ bool trusted_initiator = ds_config.session_initiator() ==
+ DataSourceConfig::SESSION_INITIATOR_TRUSTED_SYSTEM;
+ return trusted_initiator &&
+ AllPackagesProfileableByTrustedInitiator(packages_list_path);
+
+ } else {
+ // disallow everything else on release builds
return false;
}
- for (base::StringSplitter ss(std::move(content), '\n'); ss.Next();) {
- Package pkg;
- if (!ReadPackagesListLine(ss.cur_token(), &pkg)) {
- PERFETTO_ELOG("Failed to parse packages.list.");
+
+ base::Optional<Package> pkg =
+ FindInPackagesList(uid_for_lookup, packages_list_path);
+
+ if (!pkg)
+ return false;
+
+ // check installer constraint if given
+ if (!installed_by.empty()) {
+ if (pkg->installed_by.empty()) {
+ PERFETTO_ELOG("Cannot parse installer from packages.list");
return false;
}
- if (pkg.uid != uid_without_profile)
- continue;
- if (!installed_by.empty()) {
- if (pkg.installed_by.empty()) {
- PERFETTO_ELOG(
- "installed_by given in TraceConfig, but cannot parse "
- "installer from packages.list.");
- return false;
- }
- if (std::find(installed_by.cbegin(), installed_by.cend(),
- pkg.installed_by) == installed_by.cend()) {
- return false;
- }
- }
- switch (ds_config.session_initiator()) {
- case DataSourceConfig::SESSION_INITIATOR_UNSPECIFIED:
- return pkg.profileable_from_shell || pkg.debuggable;
- case DataSourceConfig::SESSION_INITIATOR_TRUSTED_SYSTEM:
- return pkg.profileable || pkg.debuggable;
+ if (std::find(installed_by.cbegin(), installed_by.cend(),
+ pkg->installed_by) == installed_by.cend()) {
+ // not installed by one of the requested origins
+ return false;
}
}
- // Did not find package.
+
+ switch (ds_config.session_initiator()) {
+ case DataSourceConfig::SESSION_INITIATOR_UNSPECIFIED:
+ return pkg->profileable_from_shell || pkg->debuggable;
+ case DataSourceConfig::SESSION_INITIATOR_TRUSTED_SYSTEM:
+ return pkg->profileable || pkg->debuggable;
+ }
return false;
}
diff --git a/src/profiling/common/producer_support.h b/src/profiling/common/producer_support.h
index 4e6b856b2..6f5404537 100644
--- a/src/profiling/common/producer_support.h
+++ b/src/profiling/common/producer_support.h
@@ -17,7 +17,7 @@
#ifndef SRC_PROFILING_COMMON_PRODUCER_SUPPORT_H_
#define SRC_PROFILING_COMMON_PRODUCER_SUPPORT_H_
-#include <inttypes.h>
+#include <cinttypes>
#include <string>
#include "perfetto/tracing/core/forward_decls.h"
diff --git a/src/profiling/common/producer_support_unittest.cc b/src/profiling/common/producer_support_unittest.cc
index 33fdf2800..469a0a42e 100644
--- a/src/profiling/common/producer_support_unittest.cc
+++ b/src/profiling/common/producer_support_unittest.cc
@@ -16,7 +16,10 @@
#include "src/profiling/common/producer_support.h"
+#include <stdio.h>
+
#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/temp_file.h"
#include "perfetto/ext/base/utils.h"
#include "perfetto/tracing/core/data_source_config.h"
@@ -26,147 +29,268 @@ namespace perfetto {
namespace profiling {
namespace {
-TEST(CanProfileAndroidTest, NonUserSystemExtraGuardrails) {
+DataSourceConfig ShellInitiator() {
DataSourceConfig ds_config;
- ds_config.set_enable_extra_guardrails(true);
- EXPECT_TRUE(CanProfileAndroid(ds_config, 1, {}, "userdebug", "/dev/null"));
+ ds_config.set_session_initiator(
+ DataSourceConfig::SESSION_INITIATOR_UNSPECIFIED);
+ return ds_config;
}
-TEST(CanProfileAndroidTest, NonUserNonProfileableApp) {
+DataSourceConfig TrustedInitiator() {
DataSourceConfig ds_config;
- ds_config.set_enable_extra_guardrails(false);
- auto tmp = base::TempFile::Create();
- constexpr char content[] =
- "invalid.example.profileable 10001 0 "
- "/data/user/0/invalid.example.profileable default:targetSdkVersion=10000 "
- "none 0 1\n";
- base::WriteAll(tmp.fd(), content, sizeof(content));
- EXPECT_TRUE(CanProfileAndroid(ds_config, 10001, {}, "userdebug", tmp.path()));
+ ds_config.set_session_initiator(
+ DataSourceConfig::SESSION_INITIATOR_TRUSTED_SYSTEM);
+ return ds_config;
}
-TEST(CanProfileAndroidTest, NonUserNonProfileableAppExtraGuardrails) {
- DataSourceConfig ds_config;
- ds_config.set_enable_extra_guardrails(true);
- auto tmp = base::TempFile::Create();
- constexpr char content[] =
- "invalid.example.profileable 10001 0 "
- "/data/user/0/invalid.example.profileable default:targetSdkVersion=10000 "
- "none 0 1\n";
- base::WriteAll(tmp.fd(), content, sizeof(content));
- EXPECT_TRUE(CanProfileAndroid(ds_config, 10001, {}, "userdebug", tmp.path()));
+// pkgName - package name
+// userId - application-specific user id
+// debugFlag - 0 or 1 if the package is debuggable.
+// dataPath - path to package's data path
+// seinfo - seinfo label for the app (assigned at install time)
+// gids - supplementary gids this app launches with
+// profileableFromShellFlag - 0 or 1 if the package is profileable from shell.
+// longVersionCode - integer version of the package.
+// profileable - 0 or 1 if the package is profileable by the platform.
+// packageInstaller - the package that installed this app, or @system, @product
+// or @null.
+std::string PackageListLine(unsigned long uid,
+ bool debuggable,
+ bool profileable_from_shell,
+ bool profileable,
+ const char* installer) {
+ base::StackString<256> ss(
+ "com.package.name %lu %d /data/user/0/com.package.name "
+ "platform:privapp:targetSdkVersion=29 1065,3003 %d 500 %d %s\n",
+ uid, debuggable, profileable_from_shell, profileable, installer);
+ return ss.ToStdString();
}
-TEST(CanProfileAndroidTest, UserProfileableApp) {
- DataSourceConfig ds_config;
- ds_config.set_enable_extra_guardrails(false);
+TEST(CanProfileAndroidTest, DebuggableBuild) {
+ unsigned pkg_uid = 10001;
+ std::string content = PackageListLine(
+ pkg_uid, /*debuggable=*/false, /*profileable_from_shell=*/false,
+ /*profileable=*/false, /*installer=*/"@system");
auto tmp = base::TempFile::Create();
- constexpr char content[] =
- "invalid.example.profileable 10001 0 "
- "/data/user/0/invalid.example.profileable default:targetSdkVersion=10000 "
- "none 1 1\n";
- base::WriteAll(tmp.fd(), content, sizeof(content));
- EXPECT_TRUE(CanProfileAndroid(ds_config, 10001, {}, "user", tmp.path()));
-}
+ base::WriteAll(tmp.fd(), content.c_str(), content.size());
-TEST(CanProfileAndroidTest, UserProfileableAppMultiuser) {
- DataSourceConfig ds_config;
- ds_config.set_enable_extra_guardrails(false);
- auto tmp = base::TempFile::Create();
- constexpr char content[] =
- "invalid.example.profileable 10001 0 "
- "/data/user/0/invalid.example.profileable default:targetSdkVersion=10000 "
- "none 1 1\n";
- base::WriteAll(tmp.fd(), content, sizeof(content));
- EXPECT_TRUE(CanProfileAndroid(ds_config, 210001, {}, "user", tmp.path()));
+ // non-app UIDs can be profiled
+ EXPECT_TRUE(CanProfileAndroid(ShellInitiator(), /*uid=*/200,
+ /*installed_by=*/{}, "userdebug", tmp.path()));
+ EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), /*uid=*/200,
+ /*installed_by=*/{}, "userdebug", tmp.path()));
+
+ // app UIDs can be profiled, regardless of manifest
+ EXPECT_TRUE(CanProfileAndroid(ShellInitiator(), pkg_uid, /*installed_by=*/{},
+ "userdebug", tmp.path()));
+ EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), pkg_uid,
+ /*installed_by=*/{}, "userdebug", tmp.path()));
}
-TEST(CanProfileAndroidTest, UserNonProfileableApp) {
- DataSourceConfig ds_config;
- ds_config.set_enable_extra_guardrails(false);
+TEST(CanProfileAndroidTest, DebuggableApp) {
+ unsigned uid = 10001;
+ std::string content = PackageListLine(
+ uid, /*debuggable=*/true, /*profileable_from_shell=*/false,
+ /*profileable=*/false, /*installer=*/"@system");
auto tmp = base::TempFile::Create();
- constexpr char content[] =
- "invalid.example.profileable 10001 0 "
- "/data/user/0/invalid.example.profileable default:targetSdkVersion=10000 "
- "none 0 1\n";
- base::WriteAll(tmp.fd(), content, sizeof(content));
- EXPECT_FALSE(CanProfileAndroid(ds_config, 10001, {}, "user", tmp.path()));
+ base::WriteAll(tmp.fd(), content.c_str(), content.size());
+
+ // Debuggable apps can always be profiled (without installer constraint)
+ EXPECT_TRUE(CanProfileAndroid(ShellInitiator(), uid, /*installed_by=*/{},
+ "user", tmp.path()));
+ EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), uid, /*installed_by=*/{},
+ "user", tmp.path()));
}
-TEST(CanProfileAndroidTest, UserDebuggableApp) {
- DataSourceConfig ds_config;
- ds_config.set_enable_extra_guardrails(false);
+TEST(CanProfileAndroidTest, NonProfileableApp) {
+ unsigned uid = 10002;
+ std::string content = PackageListLine(
+ uid, /*debuggable=*/false, /*profileable_from_shell=*/false,
+ /*profileable=*/false, /*installer=*/"@system");
auto tmp = base::TempFile::Create();
- constexpr char content[] =
- "invalid.example.profileable 10001 1 "
- "/data/user/0/invalid.example.profileable default:targetSdkVersion=10000 "
- "none 0 1\n";
- base::WriteAll(tmp.fd(), content, sizeof(content));
- EXPECT_TRUE(CanProfileAndroid(ds_config, 10001, {}, "user", tmp.path()));
+ base::WriteAll(tmp.fd(), content.c_str(), content.size());
+
+ // Opted out packages cannot be profiled
+ EXPECT_FALSE(CanProfileAndroid(ShellInitiator(), uid, /*installed_by=*/{},
+ "user", tmp.path()));
+ EXPECT_FALSE(CanProfileAndroid(TrustedInitiator(), uid, /*installed_by=*/{},
+ "user", tmp.path()));
}
-TEST(CanProfileAndroidTest, UserProfileableMatchingInstallerStatsd) {
- DataSourceConfig ds_config;
- ds_config.set_session_initiator(
- DataSourceConfig::SESSION_INITIATOR_TRUSTED_SYSTEM);
+TEST(CanProfileAndroidTest, ProfileableApp) {
+ unsigned uid = 10004;
+ std::string content = PackageListLine(
+ uid, /*debuggable=*/false, /*profileable_from_shell=*/false,
+ /*profileable=*/true, /*installer=*/"@system");
auto tmp = base::TempFile::Create();
- constexpr char content[] =
- "invalid.example 10001 0 /data/user/0/invalid.example "
- "default:targetSdkVersion=29 3002,3003 0 13030407 1 invalid.store";
- base::WriteAll(tmp.fd(), content, sizeof(content));
- EXPECT_TRUE(CanProfileAndroid(ds_config, 10001, {"invalid.store"}, "user",
- tmp.path()));
+ base::WriteAll(tmp.fd(), content.c_str(), content.size());
+
+ // Only profileable by the platform
+ EXPECT_FALSE(CanProfileAndroid(ShellInitiator(), uid, /*installed_by=*/{},
+ "user", tmp.path()));
+ EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), uid, /*installed_by=*/{},
+ "user", tmp.path()));
}
-TEST(CanProfileAndroidTest, UserProfileableMatchingInstallerShell) {
- DataSourceConfig ds_config;
- ds_config.set_session_initiator(
- DataSourceConfig::SESSION_INITIATOR_UNSPECIFIED);
+TEST(CanProfileAndroidTest, ProfileableFromShellApp) {
+ unsigned uid = 10001;
+ std::string content = PackageListLine(
+ uid, /*debuggable=*/false, /*profileable_from_shell=*/true,
+ /*profileable=*/true, /*installer=*/"@system");
auto tmp = base::TempFile::Create();
- constexpr char content[] =
- "invalid.example 10001 0 /data/user/0/invalid.example "
- "default:targetSdkVersion=29 3002,3003 0 13030407 1 invalid.store";
- base::WriteAll(tmp.fd(), content, sizeof(content));
- EXPECT_FALSE(CanProfileAndroid(ds_config, 10001, {"invalid.store"}, "user",
- tmp.path()));
+ base::WriteAll(tmp.fd(), content.c_str(), content.size());
+
+ EXPECT_TRUE(CanProfileAndroid(ShellInitiator(), uid, /*installed_by=*/{},
+ "user", tmp.path()));
+ EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), uid, /*installed_by=*/{},
+ "user", tmp.path()));
}
-TEST(CanProfileAndroidTest, UserProfileableNonMatchingInstallerStatsd) {
- DataSourceConfig ds_config;
- ds_config.set_session_initiator(
- DataSourceConfig::SESSION_INITIATOR_TRUSTED_SYSTEM);
+// As ProfileableApp, but with a user profile offset
+TEST(CanProfileAndroidTest, UserProfileUidOffset) {
+ unsigned u0_uid = 10199;
+ std::string content = PackageListLine(
+ u0_uid, /*debuggable=*/false, /*profileable_from_shell=*/false,
+ /*profileable=*/true, /*installer=*/"@system");
auto tmp = base::TempFile::Create();
- constexpr char content[] =
- "invalid.example 10001 0 /data/user/0/invalid.example "
- "default:targetSdkVersion=29 3002,3003 0 13030407 1 invalid.store";
- base::WriteAll(tmp.fd(), content, sizeof(content));
- EXPECT_FALSE(CanProfileAndroid(ds_config, 10001, {"invalid.otherstore"},
+ base::WriteAll(tmp.fd(), content.c_str(), content.size());
+
+ // Only profileable by the platform
+ EXPECT_FALSE(CanProfileAndroid(ShellInitiator(), u0_uid, /*installed_by=*/{},
+ "user", tmp.path()));
+ EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), u0_uid, /*installed_by=*/{},
+ "user", tmp.path()));
+ unsigned u10_uid = 1010199;
+ EXPECT_FALSE(CanProfileAndroid(ShellInitiator(), u10_uid, /*installed_by=*/{},
"user", tmp.path()));
+ EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), u10_uid,
+ /*installed_by=*/{}, "user", tmp.path()));
}
-TEST(CanProfileAndroidTest, UserProfileableNonMatchingInstallerShell) {
- DataSourceConfig ds_config;
- ds_config.set_session_initiator(
- DataSourceConfig::SESSION_INITIATOR_UNSPECIFIED);
+// As ProfileableFromShellApp, but with installer constraints
+TEST(CanProfileAndroidTest, InstallerPackageConstraint) {
+ unsigned uid_installed_by_system = 10001;
+ unsigned uid_installed_by_store = 10003;
+ std::string content =
+ PackageListLine(uid_installed_by_system, /*debuggable=*/false,
+ /*profileable_from_shell=*/true,
+ /*profileable=*/true, /*installer=*/"@system");
+ content += PackageListLine( //
+ uid_installed_by_store, /*debuggable=*/false,
+ /*profileable_from_shell=*/true,
+ /*profileable=*/true, /*installer=*/"com.installer.package");
auto tmp = base::TempFile::Create();
- constexpr char content[] =
- "invalid.example 10001 0 /data/user/0/invalid.example "
- "default:targetSdkVersion=29 3002,3003 0 13030407 1 invalid.store";
- base::WriteAll(tmp.fd(), content, sizeof(content));
- EXPECT_FALSE(CanProfileAndroid(ds_config, 10001, {"invalid.otherstore"},
- "user", tmp.path()));
+ base::WriteAll(tmp.fd(), content.c_str(), content.size());
+
+ // Can profile if installer in the list (and other checks pass)
+ // @system installer:
+ EXPECT_TRUE(CanProfileAndroid(ShellInitiator(), uid_installed_by_system,
+ /*installed_by=*/{"@product", "@system"},
+ "user", tmp.path()));
+ EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), uid_installed_by_system,
+ /*installed_by=*/{"@product", "@system"},
+ "user", tmp.path()));
+ EXPECT_FALSE(CanProfileAndroid(ShellInitiator(), uid_installed_by_system,
+ /*installed_by=*/{"@product"}, "user",
+ tmp.path()));
+ EXPECT_FALSE(CanProfileAndroid(TrustedInitiator(), uid_installed_by_system,
+ /*installed_by=*/{"@product"}, "user",
+ tmp.path()));
+
+ // com.installer.package installer:
+ EXPECT_TRUE(CanProfileAndroid(ShellInitiator(), uid_installed_by_store,
+ /*installed_by=*/{"com.installer.package"},
+ "user", tmp.path()));
+ EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), uid_installed_by_store,
+ /*installed_by=*/{"com.installer.package"},
+ "user", tmp.path()));
+ EXPECT_FALSE(CanProfileAndroid(ShellInitiator(), uid_installed_by_store,
+ /*installed_by=*/{"@product"}, "user",
+ tmp.path()));
+ EXPECT_FALSE(CanProfileAndroid(TrustedInitiator(), uid_installed_by_store,
+ /*installed_by=*/{"@product"}, "user",
+ tmp.path()));
}
-TEST(CanProfileAndroidTest, UserProfileableFromShellWithInstallerOldPackages) {
- DataSourceConfig ds_config;
- ds_config.set_session_initiator(
- DataSourceConfig::SESSION_INITIATOR_UNSPECIFIED);
+TEST(CanProfileAndroidTest, AppSandboxProcess) {
+ unsigned uid_profileable_app = 10004;
+ unsigned uid_nonprofileable_app = 10007;
+ std::string content =
+ PackageListLine(uid_profileable_app, /*debuggable=*/false,
+ /*profileable_from_shell=*/true,
+ /*profileable=*/true, /*installer=*/"@system");
+ content += //
+ PackageListLine(uid_nonprofileable_app, /*debuggable=*/false,
+ /*profileable_from_shell=*/false,
+ /*profileable=*/false, /*installer=*/"@system");
auto tmp = base::TempFile::Create();
- constexpr char content[] =
- "invalid.example 10001 0 /data/user/0/invalid.example "
- "default:targetSdkVersion=29 3002,3003 1 13030407";
- base::WriteAll(tmp.fd(), content, sizeof(content));
- EXPECT_FALSE(CanProfileAndroid(ds_config, 10001, {"invalid.otherstore"},
- "user", tmp.path()));
+ base::WriteAll(tmp.fd(), content.c_str(), content.size());
+
+ // Sandbox profileable if the app is profileable
+ unsigned uid_profileable_sandbox = 20004;
+ EXPECT_TRUE(CanProfileAndroid(ShellInitiator(), uid_profileable_sandbox,
+ /*installed_by=*/{}, "user", tmp.path()));
+ EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), uid_profileable_sandbox,
+ /*installed_by=*/{}, "user", tmp.path()));
+
+ unsigned uid_nonprofileable_sandbox = 20007;
+ EXPECT_FALSE(CanProfileAndroid(ShellInitiator(), uid_nonprofileable_sandbox,
+ /*installed_by=*/{}, "user", tmp.path()));
+ EXPECT_FALSE(CanProfileAndroid(TrustedInitiator(), uid_nonprofileable_sandbox,
+ /*installed_by=*/{}, "user", tmp.path()));
+}
+
+TEST(CanProfileAndroidTest, IsolatedProcess) {
+ {
+ // Packages list with only profileable packages
+ unsigned uid_app = 10199;
+ std::string content =
+ PackageListLine(10003, /*debuggable=*/false,
+ /*profileable_from_shell=*/true,
+ /*profileable=*/true, /*installer=*/"@system");
+ content += //
+ PackageListLine(uid_app, /*debuggable=*/false,
+ /*profileable_from_shell=*/false,
+ /*profileable=*/true, /*installer=*/"@system");
+ content += //
+ PackageListLine(10008, /*debuggable=*/true,
+ /*profileable_from_shell=*/true,
+ /*profileable=*/true, /*installer=*/"@system");
+ auto tmp = base::TempFile::Create();
+ base::WriteAll(tmp.fd(), content.c_str(), content.size());
+
+ // Any isolated process is thus profileable by trusted initiators
+ unsigned uid_isolated = 90100;
+ EXPECT_FALSE(CanProfileAndroid(ShellInitiator(), uid_isolated,
+ /*installed_by=*/{}, "user", tmp.path()));
+ EXPECT_TRUE(CanProfileAndroid(TrustedInitiator(), uid_isolated,
+ /*installed_by=*/{}, "user", tmp.path()));
+ }
+ {
+ // Packages list with an opted out package
+ unsigned uid_app = 10199;
+ std::string content =
+ PackageListLine(10003, /*debuggable=*/false,
+ /*profileable_from_shell=*/true,
+ /*profileable=*/true, /*installer=*/"@system");
+ content += //
+ PackageListLine(uid_app, /*debuggable=*/false,
+ /*profileable_from_shell=*/false,
+ /*profileable=*/true, /*installer=*/"@system");
+ content += //
+ PackageListLine(10008, /*debuggable=*/false,
+ /*profileable_from_shell=*/false,
+ /*profileable=*/false, /*installer=*/"@system");
+ auto tmp = base::TempFile::Create();
+ base::WriteAll(tmp.fd(), content.c_str(), content.size());
+
+ // Conservatively conclude that an isolated process is not profileable
+ unsigned uid_isolated = 90100;
+ EXPECT_FALSE(CanProfileAndroid(ShellInitiator(), uid_isolated,
+ /*installed_by=*/{}, "user", tmp.path()));
+ EXPECT_FALSE(CanProfileAndroid(TrustedInitiator(), uid_isolated,
+ /*installed_by=*/{}, "user", tmp.path()));
+ }
}
} // namespace
diff --git a/src/profiling/common/profiler_guardrails.h b/src/profiling/common/profiler_guardrails.h
index f89c0c225..e9e9d47fc 100644
--- a/src/profiling/common/profiler_guardrails.h
+++ b/src/profiling/common/profiler_guardrails.h
@@ -18,9 +18,10 @@
#define SRC_PROFILING_COMMON_PROFILER_GUARDRAILS_H_
#include <fcntl.h>
-#include <inttypes.h>
#include <unistd.h>
+#include <cinttypes>
+
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/scoped_file.h"
diff --git a/src/profiling/common/profiler_guardrails_unittest.cc b/src/profiling/common/profiler_guardrails_unittest.cc
index ef8a450ae..ca9d1b232 100644
--- a/src/profiling/common/profiler_guardrails_unittest.cc
+++ b/src/profiling/common/profiler_guardrails_unittest.cc
@@ -16,9 +16,9 @@
#include "src/profiling/common/profiler_guardrails.h"
-#include <inttypes.h>
#include <unistd.h>
+#include <cinttypes>
#include <map>
#include "perfetto/ext/base/file_utils.h"
diff --git a/src/profiling/common/unwind_support.cc b/src/profiling/common/unwind_support.cc
index 5302015b6..a070ee20e 100644
--- a/src/profiling/common/unwind_support.cc
+++ b/src/profiling/common/unwind_support.cc
@@ -16,7 +16,7 @@
#include "src/profiling/common/unwind_support.h"
-#include <inttypes.h>
+#include <cinttypes>
#include <procinfo/process_map.h>
#include <unwindstack/Maps.h>
@@ -68,8 +68,7 @@ bool FDMaps::Parse() {
return false;
unwindstack::SharedString name("");
- unwindstack::MapInfo* prev_map = nullptr;
- unwindstack::MapInfo* prev_real_map = nullptr;
+ std::shared_ptr<unwindstack::MapInfo> prev_map;
return android::procinfo::ReadMapFileContent(
&content[0], [&](const android::procinfo::MapInfo& mapinfo) {
// Mark a device map in /dev/ and not in /dev/ashmem/ specially.
@@ -82,13 +81,10 @@ bool FDMaps::Parse() {
if (name != mapinfo.name) {
name = unwindstack::SharedString(mapinfo.name);
}
- maps_.emplace_back(new unwindstack::MapInfo(
- prev_map, prev_real_map, mapinfo.start, mapinfo.end, mapinfo.pgoff,
+ maps_.emplace_back(unwindstack::MapInfo::Create(
+ prev_map, mapinfo.start, mapinfo.end, mapinfo.pgoff,
flags, name));
- prev_map = maps_.back().get();
- if (!prev_map->IsBlank()) {
- prev_real_map = prev_map;
- }
+ prev_map = maps_.back();
});
}
@@ -134,10 +130,8 @@ unwindstack::DexFiles* UnwindingMetadata::GetDexFiles(unwindstack::ArchEnum arch
const std::string& UnwindingMetadata::GetBuildId(
const unwindstack::FrameData& frame) {
- if (!frame.map_name.empty()) {
- unwindstack::MapInfo* map_info = fd_maps.Find(frame.pc);
- if (map_info)
- return map_info->GetBuildID();
+ if (frame.map_info != nullptr && !frame.map_info->name().empty()) {
+ return frame.map_info->GetBuildID();
}
return empty_string_;
@@ -167,6 +161,12 @@ std::string StringifyLibUnwindstackError(unwindstack::ErrorCode e) {
return "THREAD_DOES_NOT_EXIST";
case unwindstack::ERROR_THREAD_TIMEOUT:
return "THREAD_TIMEOUT";
+ case unwindstack::ERROR_BAD_ARCH:
+ return "BAD_ARCH";
+ case unwindstack::ERROR_MAPS_PARSE:
+ return "MAPS_PARSE";
+ case unwindstack::ERROR_INVALID_PARAMETER:
+ return "INVALID_PARAMETER";
}
}
diff --git a/src/profiling/deobfuscator.cc b/src/profiling/deobfuscator.cc
index ba58dfa15..378677e52 100644
--- a/src/profiling/deobfuscator.cc
+++ b/src/profiling/deobfuscator.cc
@@ -159,8 +159,10 @@ std::string FlattenClasses(
// See https://www.guardsquare.com/en/products/proguard/manual/retrace for the
// file format we are parsing.
base::Status ProguardParser::AddLine(std::string line) {
- if (line.length() == 0 || line[0] == '#')
+ auto first_ch_pos = line.find_first_not_of(" \t");
+ if (first_ch_pos == std::string::npos || line[first_ch_pos] == '#')
return base::Status();
+
bool is_member = line[0] == ' ';
if (is_member && !current_class_) {
return base::Status(
diff --git a/src/profiling/deobfuscator_unittest.cc b/src/profiling/deobfuscator_unittest.cc
index 02a0e8d4f..11b267c29 100644
--- a/src/profiling/deobfuscator_unittest.cc
+++ b/src/profiling/deobfuscator_unittest.cc
@@ -71,12 +71,11 @@ TEST(ProguardParserTest, Member) {
ASSERT_TRUE(
p.AddLine(" android.arch.core.executor.TaskExecutor mDelegate -> b")
.ok());
- std::map<std::string, std::string> deobfuscated_fields{{"b", "mDelegate"}};
- ASSERT_THAT(
+ EXPECT_THAT(
p.ConsumeMapping(),
ElementsAre(std::pair<std::string, ObfuscatedClass>(
"android.arch.a.a.a", {"android.arch.core.executor.ArchTaskExecutor",
- std::move(deobfuscated_fields),
+ {{"b", "mDelegate"}},
{}})));
}
@@ -224,6 +223,25 @@ TEST(ProguardParserTest, DuplicateFieldSame) {
.ok());
}
+TEST(ProguardParserTest, EmptyLinesAndComments) {
+ ProguardParser p;
+ const char input[] = R"(
+# comment
+
+Example$$Class -> C:
+
+ int first -> q
+ # indented comment
+ long second -> o
+)";
+
+ ASSERT_TRUE(p.AddLines(std::string(input)));
+ EXPECT_THAT(
+ p.ConsumeMapping(),
+ ElementsAre(std::pair<std::string, ObfuscatedClass>(
+ "C", {"Example$$Class", {{"q", "first"}, {"o", "second"}}, {}})));
+}
+
} // namespace
} // namespace profiling
} // namespace perfetto
diff --git a/src/profiling/memory/BUILD.gn b/src/profiling/memory/BUILD.gn
index f0e350f11..a4c77773f 100644
--- a/src/profiling/memory/BUILD.gn
+++ b/src/profiling/memory/BUILD.gn
@@ -21,6 +21,14 @@ assert(enable_perfetto_heapprofd)
# The Android heap profiling daemon.
executable("heapprofd") {
deps = [
+ ":heapprofd_main",
+ "../../../gn:default_deps",
+ ]
+ sources = [ "main.cc" ]
+}
+
+source_set("heapprofd_main") {
+ deps = [
"../../../gn:default_deps",
"../../../protos/perfetto/trace:zero",
"../../../src/base",
@@ -29,7 +37,10 @@ executable("heapprofd") {
"../../../src/profiling/memory:wire_protocol",
"../../../src/tracing/ipc/producer",
]
- sources = [ "main.cc" ]
+ sources = [
+ "heapprofd.cc",
+ "heapprofd.h",
+ ]
}
# This library gets loaded into (and executes in) arbitrary android processes.
@@ -170,7 +181,6 @@ source_set("client_api") {
":wire_protocol",
"../../../gn:default_deps",
"../../base",
- "../common:proc_utils",
]
sources = [ "client_api.cc" ]
}
@@ -246,6 +256,7 @@ source_set("daemon") {
"../common:callstack_trie",
"../common:interner",
"../common:interning_output",
+ "../common:proc_cmdline",
"../common:proc_utils",
"../common:producer_support",
"../common:profiler_guardrails",
@@ -285,7 +296,6 @@ source_set("client") {
"../../../gn:default_deps",
"../../base",
"../../base:unix_socket",
- "../common:proc_utils",
]
public_deps = [ "../../../gn:libunwindstack" ]
sources = [
@@ -354,9 +364,6 @@ source_set("end_to_end_tests") {
} else {
deps += [ ":heapprofd_standalone_client" ]
}
- if (start_daemons_for_testing) {
- defines = [ "PERFETTO_START_DAEMONS_FOR_TESTING" ]
- }
}
perfetto_fuzzer_test("unwinding_fuzzer") {
diff --git a/src/profiling/memory/bookkeeping.cc b/src/profiling/memory/bookkeeping.cc
index 3439db43b..828280d7d 100644
--- a/src/profiling/memory/bookkeeping.cc
+++ b/src/profiling/memory/bookkeeping.cc
@@ -17,10 +17,11 @@
#include "src/profiling/memory/bookkeeping.h"
#include <fcntl.h>
-#include <inttypes.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <cinttypes>
+
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/scoped_file.h"
diff --git a/src/profiling/memory/bookkeeping.h b/src/profiling/memory/bookkeeping.h
index 6aa908665..77a131978 100644
--- a/src/profiling/memory/bookkeeping.h
+++ b/src/profiling/memory/bookkeeping.h
@@ -193,8 +193,9 @@ class HeapTracker {
void ClearFrameCache() { frame_cache_.clear(); }
- uint64_t committed_timestamp() { return committed_timestamp_; }
- uint64_t max_timestamp() { return max_timestamp_; }
+ uint64_t dump_timestamp() {
+ return dump_at_max_mode_ ? max_timestamp_ : committed_timestamp_;
+ }
uint64_t GetSizeForTesting(const std::vector<unwindstack::FrameData>& stack,
std::vector<std::string> build_ids);
diff --git a/src/profiling/memory/bookkeeping_dump.h b/src/profiling/memory/bookkeeping_dump.h
index 9c376767a..115653abf 100644
--- a/src/profiling/memory/bookkeeping_dump.h
+++ b/src/profiling/memory/bookkeeping_dump.h
@@ -17,22 +17,20 @@
#ifndef SRC_PROFILING_MEMORY_BOOKKEEPING_DUMP_H_
#define SRC_PROFILING_MEMORY_BOOKKEEPING_DUMP_H_
+#include <cinttypes>
#include <functional>
#include <set>
-#include <inttypes.h>
+#include "perfetto/ext/tracing/core/trace_writer.h"
+#include "src/profiling/common/interner.h"
+#include "src/profiling/common/interning_output.h"
+#include "src/profiling/memory/bookkeeping.h"
#include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
#include "protos/perfetto/trace/profiling/profile_common.pbzero.h"
#include "protos/perfetto/trace/profiling/profile_packet.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
-#include "perfetto/ext/tracing/core/trace_writer.h"
-
-#include "src/profiling/common/interner.h"
-#include "src/profiling/common/interning_output.h"
-#include "src/profiling/memory/bookkeeping.h"
-
namespace perfetto {
namespace profiling {
diff --git a/src/profiling/memory/bookkeeping_unittest.cc b/src/profiling/memory/bookkeeping_unittest.cc
index 79e018325..9027a8a0a 100644
--- a/src/profiling/memory/bookkeeping_unittest.cc
+++ b/src/profiling/memory/bookkeeping_unittest.cc
@@ -30,12 +30,10 @@ std::vector<unwindstack::FrameData> stack() {
unwindstack::FrameData data{};
data.function_name = "fun1";
- data.map_name = "map1";
data.pc = 1;
res.emplace_back(std::move(data));
data = {};
data.function_name = "fun2";
- data.map_name = "map2";
data.pc = 2;
res.emplace_back(std::move(data));
return res;
@@ -45,12 +43,10 @@ std::vector<unwindstack::FrameData> stack2() {
std::vector<unwindstack::FrameData> res;
unwindstack::FrameData data{};
data.function_name = "fun1";
- data.map_name = "map1";
data.pc = 1;
res.emplace_back(std::move(data));
data = {};
data.function_name = "fun3";
- data.map_name = "map3";
data.pc = 3;
res.emplace_back(std::move(data));
return res;
@@ -60,12 +56,10 @@ std::vector<unwindstack::FrameData> stack3() {
std::vector<unwindstack::FrameData> res;
unwindstack::FrameData data{};
data.function_name = "fun1";
- data.map_name = "map1";
data.pc = 1;
res.emplace_back(std::move(data));
data = {};
data.function_name = "fun4";
- data.map_name = "map4";
data.pc = 4;
res.emplace_back(std::move(data));
return res;
@@ -145,7 +139,7 @@ TEST(BookkeepingTest, Max) {
sequence_number++;
hd.RecordMalloc(stack2(), DummyBuildIds(stack2().size()), 0x2, 1, 2,
sequence_number, 100 * sequence_number);
- ASSERT_EQ(hd.max_timestamp(), 200u);
+ ASSERT_EQ(hd.dump_timestamp(), 200u);
ASSERT_EQ(hd.GetMaxForTesting(stack(), DummyBuildIds(stack().size())), 5u);
ASSERT_EQ(hd.GetMaxForTesting(stack2(), DummyBuildIds(stack2().size())), 2u);
ASSERT_EQ(hd.GetMaxCountForTesting(stack(), DummyBuildIds(stack().size())),
@@ -171,7 +165,7 @@ TEST(BookkeepingTest, Max2) {
sequence_number, 100 * sequence_number);
sequence_number++;
hd.RecordFree(0x2, sequence_number, 100 * sequence_number);
- EXPECT_EQ(hd.max_timestamp(), 400u);
+ EXPECT_EQ(hd.dump_timestamp(), 400u);
EXPECT_EQ(hd.GetMaxForTesting(stack(), DummyBuildIds(stack().size())), 0u);
EXPECT_EQ(hd.GetMaxForTesting(stack2(), DummyBuildIds(stack2().size())), 15u);
EXPECT_EQ(hd.GetMaxForTesting(stack3(), DummyBuildIds(stack3().size())), 15u);
diff --git a/src/profiling/memory/client.cc b/src/profiling/memory/client.cc
index 4a84a2020..79e1a770e 100644
--- a/src/profiling/memory/client.cc
+++ b/src/profiling/memory/client.cc
@@ -16,13 +16,17 @@
#include "src/profiling/memory/client.h"
-#include <inttypes.h>
#include <signal.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
+#include <algorithm>
+#include <atomic>
+#include <cinttypes>
+#include <new>
+
#include <unwindstack/MachineArm.h>
#include <unwindstack/MachineArm64.h>
#include <unwindstack/MachineMips.h>
@@ -32,16 +36,13 @@
#include <unwindstack/Regs.h>
#include <unwindstack/RegsGetLocal.h>
-#include <algorithm>
-#include <atomic>
-#include <new>
-
#include "perfetto/base/compiler.h"
#include "perfetto/base/logging.h"
#include "perfetto/base/thread_utils.h"
#include "perfetto/base/time.h"
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/unix_socket.h"
#include "perfetto/ext/base/utils.h"
#include "src/profiling/memory/sampler.h"
@@ -463,8 +464,7 @@ bool Client::RecordHeapInfo(uint32_t heap_id,
HeapName hnr;
hnr.heap_id = heap_id;
- strncpy(&hnr.heap_name[0], heap_name, sizeof(hnr.heap_name));
- hnr.heap_name[sizeof(hnr.heap_name) - 1] = '\0';
+ base::StringCopy(&hnr.heap_name[0], heap_name, sizeof(hnr.heap_name));
hnr.sample_interval = interval;
WireMessage msg = {};
diff --git a/src/profiling/memory/client_api.cc b/src/profiling/memory/client_api.cc
index bdede0d57..0d46ac22b 100644
--- a/src/profiling/memory/client_api.cc
+++ b/src/profiling/memory/client_api.cc
@@ -17,7 +17,6 @@
#include "perfetto/heap_profile.h"
#include "src/profiling/memory/heap_profile_internal.h"
-#include <inttypes.h>
#include <malloc.h>
#include <stddef.h>
#include <stdio.h>
@@ -27,17 +26,16 @@
#include <unistd.h>
#include <atomic>
+#include <cinttypes>
#include <memory>
-#include <tuple>
#include <type_traits>
#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
-#include "perfetto/ext/base/no_destructor.h"
+#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/unix_socket.h"
#include "perfetto/ext/base/utils.h"
-#include "src/profiling/common/proc_utils.h"
#include "src/profiling/memory/client.h"
#include "src/profiling/memory/client_api_factory.h"
#include "src/profiling/memory/scoped_spinlock.h"
@@ -113,8 +111,9 @@ std::shared_ptr<perfetto::profiling::Client>* GetClientLocked() {
}
constexpr auto kMinHeapId = 1;
+constexpr auto kMaxNumHeaps = 256;
-AHeapInfo g_heaps[256];
+AHeapInfo g_heaps[kMaxNumHeaps];
AHeapInfo& GetHeap(uint32_t id) {
return g_heaps[id];
@@ -133,32 +132,49 @@ perfetto::profiling::Spinlock g_client_lock{};
std::atomic<uint32_t> g_next_heap_id{kMinHeapId};
+// This can get called while holding the spinlock (in normal operation), or
+// without holding the spinlock (from OnSpinlockTimeout).
void DisableAllHeaps() {
- for (uint32_t i = kMinHeapId; i < g_next_heap_id.load(); ++i) {
+ bool disabled[kMaxNumHeaps] = {};
+ uint32_t max_heap = g_next_heap_id.load();
+ // This has to be done in two passes, in case the disabled_callback for one
+ // enabled heap uses another. In that case, the callbacks for the other heap
+ // would time out trying to acquire the spinlock, which we hold here.
+ for (uint32_t i = kMinHeapId; i < max_heap; ++i) {
AHeapInfo& info = GetHeap(i);
if (!info.ready.load(std::memory_order_acquire))
continue;
- if (info.enabled.load(std::memory_order_acquire)) {
- info.enabled.store(false, std::memory_order_release);
- if (info.disabled_callback) {
- AHeapProfileDisableCallbackInfo disable_info;
- info.disabled_callback(info.disabled_callback_data, &disable_info);
- }
+ disabled[i] = info.enabled.exchange(false, std::memory_order_acq_rel);
+ }
+ for (uint32_t i = kMinHeapId; i < max_heap; ++i) {
+ if (!disabled[i]) {
+ continue;
+ }
+ AHeapInfo& info = GetHeap(i);
+ if (info.disabled_callback) {
+ AHeapProfileDisableCallbackInfo disable_info;
+ info.disabled_callback(info.disabled_callback_data, &disable_info);
}
}
}
+#pragma GCC diagnostic push
+#if PERFETTO_DCHECK_IS_ON()
+#pragma GCC diagnostic ignored "-Wmissing-noreturn"
+#endif
+
void OnSpinlockTimeout() {
// Give up on profiling the process but leave it running.
// The process enters into a poisoned state and will reject all
// subsequent profiling requests. The current session is kept
// running but no samples are reported to it.
- PERFETTO_ELOG(
+ PERFETTO_DFATAL_OR_ELOG(
"Timed out on the spinlock - something is horribly wrong. "
"Leaking heapprofd client.");
DisableAllHeaps();
perfetto::profiling::PoisonSpinlock(&g_client_lock);
}
+#pragma GCC diagnostic pop
// Note: g_client can be reset by AHeapProfile_initSession without calling this
// function.
@@ -280,7 +296,7 @@ __attribute__((visibility("default"))) AHeapInfo* AHeapInfo_create(
}
uint32_t next_id = g_next_heap_id.fetch_add(1);
- if (next_id >= perfetto::base::ArraySize(g_heaps)) {
+ if (next_id >= kMaxNumHeaps) {
return nullptr;
}
@@ -288,7 +304,7 @@ __attribute__((visibility("default"))) AHeapInfo* AHeapInfo_create(
perfetto::profiling::StartHeapprofdIfStatic();
AHeapInfo& info = GetHeap(next_id);
- strncpy(info.heap_name, heap_name, sizeof(info.heap_name));
+ perfetto::base::StringCopy(info.heap_name, heap_name, sizeof(info.heap_name));
return &info;
}
@@ -522,11 +538,8 @@ __attribute__((visibility("default"))) bool AHeapProfile_initSession(
return false;
}
- uint64_t heap_intervals[perfetto::base::ArraySize(g_heaps)] = {};
uint32_t max_heap = g_next_heap_id.load();
- for (uint32_t i = kMinHeapId; i < max_heap; ++i) {
- heap_intervals[i] = MaybeToggleHeap(i, client.get());
- }
+ bool heaps_enabled[kMaxNumHeaps] = {};
PERFETTO_LOG("%s: heapprofd_client initialized.", getprogname());
{
@@ -540,15 +553,36 @@ __attribute__((visibility("default"))) bool AHeapProfile_initSession(
// random engine.
for (uint32_t i = kMinHeapId; i < max_heap; ++i) {
AHeapInfo& heap = GetHeap(i);
- if (heap_intervals[i]) {
- heap.sampler.SetSamplingInterval(heap_intervals[i]);
+ if (!heap.ready.load(std::memory_order_acquire)) {
+ continue;
+ }
+ const uint64_t interval =
+ GetHeapSamplingInterval(client->client_config(), heap.heap_name);
+ if (interval) {
+ heaps_enabled[i] = true;
+ heap.sampler.SetSamplingInterval(interval);
}
}
// This cannot have been set in the meantime. There are never two concurrent
// calls to this function, as Bionic uses atomics to guard against that.
PERFETTO_DCHECK(*GetClientLocked() == nullptr);
- *GetClientLocked() = std::move(client);
+ *GetClientLocked() = client;
+ }
+
+ // We want to run MaybeToggleHeap last to make sure we never enable a heap
+ // but subsequently return `false` from this function, which indicates to the
+ // caller that we did not enable anything.
+ //
+ // For startup profiles, `false` is used by Bionic to signal it can unload
+ // the library again.
+ for (uint32_t i = kMinHeapId; i < max_heap; ++i) {
+ if (!heaps_enabled[i]) {
+ continue;
+ }
+ auto interval = MaybeToggleHeap(i, client.get());
+ PERFETTO_DCHECK(interval > 0);
}
+
return true;
}
diff --git a/src/profiling/memory/client_api_factory_android.cc b/src/profiling/memory/client_api_factory_android.cc
index 370dd60da..16c3a25e5 100644
--- a/src/profiling/memory/client_api_factory_android.cc
+++ b/src/profiling/memory/client_api_factory_android.cc
@@ -27,7 +27,6 @@
#include "perfetto/base/build_config.h"
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/unix_socket.h"
-#include "src/profiling/common/proc_utils.h"
#include "src/profiling/memory/client.h"
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
diff --git a/src/profiling/memory/client_api_factory_standalone.cc b/src/profiling/memory/client_api_factory_standalone.cc
index f21ce0d1b..55a77bb22 100644
--- a/src/profiling/memory/client_api_factory_standalone.cc
+++ b/src/profiling/memory/client_api_factory_standalone.cc
@@ -16,6 +16,7 @@
#include "src/profiling/memory/client_api_factory.h"
+#include "perfetto/base/logging.h"
#include "perfetto/ext/base/scoped_file.h"
#include "perfetto/ext/base/unix_socket.h"
#include "perfetto/ext/base/unix_task_runner.h"
@@ -50,19 +51,27 @@ namespace {
base::UnixSocketRaw* g_client_sock;
+bool MonitorFdOnce() {
+ char buf[1];
+ ssize_t r = g_client_sock->Receive(buf, sizeof(buf));
+ if (r == 0) {
+ PERFETTO_ELOG("Server disconneced.");
+ return false;
+ }
+ if (r < 0) {
+ PERFETTO_PLOG("Receive failed.");
+ return true;
+ }
+ AHeapProfile_initSession(malloc, free);
+ return true;
+}
+
void MonitorFd() {
g_client_sock->DcheckIsBlocking(true);
for (;;) {
- char buf[1];
- ssize_t r = g_client_sock->Receive(buf, sizeof(buf));
- if (r >= 1) {
- AHeapProfile_initSession(malloc, free);
- } else if (r == 0) {
- PERFETTO_ELOG("Server disconneced.");
+ bool cont = MonitorFdOnce();
+ if (!cont)
break;
- } else {
- PERFETTO_PLOG("Receive failed.");
- }
}
}
@@ -100,6 +109,13 @@ void StartHeapprofdIfStatic() {
PERFETTO_PLOG("waitpid");
*g_client_sock = std::move(cli_sock);
+
+ const char* w = getenv("PERFETTO_HEAPPROFD_BLOCKING_INIT");
+ if (w && w[0] == '1') {
+ g_client_sock->DcheckIsBlocking(true);
+ MonitorFdOnce();
+ }
+
std::thread th(MonitorFd);
th.detach();
return;
@@ -107,6 +123,11 @@ void StartHeapprofdIfStatic() {
daemon(/* nochdir= */ 0, /* noclose= */ 1);
+ // On debug builds, we want to turn on crash reporting for heapprofd.
+#if PERFETTO_BUILDFLAG(PERFETTO_STDERR_CRASH_DUMP)
+ base::EnableStacktraceOnCrashForDebug();
+#endif
+
cli_sock.ReleaseFd();
// Leave stderr open for logging.
@@ -149,6 +170,9 @@ void StartHeapprofdIfStatic() {
}
});
task_runner.Run();
+ // We currently do not Quit the task_runner, but if we ever do it will be
+ // very hard to debug if we don't exit here.
+ exit(0);
}
// This is called by AHeapProfile_initSession (client_api.cc) to construct a
diff --git a/src/profiling/memory/client_api_noop.cc b/src/profiling/memory/client_api_noop.cc
index 0f3732fcf..228766126 100644
--- a/src/profiling/memory/client_api_noop.cc
+++ b/src/profiling/memory/client_api_noop.cc
@@ -17,7 +17,7 @@
#include "perfetto/heap_profile.h"
#include "src/profiling/memory/heap_profile_internal.h"
-#include <inttypes.h>
+#include <cinttypes>
__attribute__((visibility("default"))) uint64_t
AHeapProfileEnableCallbackInfo_getSamplingInterval(
diff --git a/src/profiling/memory/heap_profile_internal.h b/src/profiling/memory/heap_profile_internal.h
index 8e9a9801c..05420143d 100644
--- a/src/profiling/memory/heap_profile_internal.h
+++ b/src/profiling/memory/heap_profile_internal.h
@@ -17,9 +17,10 @@
#ifndef SRC_PROFILING_MEMORY_HEAP_PROFILE_INTERNAL_H_
#define SRC_PROFILING_MEMORY_HEAP_PROFILE_INTERNAL_H_
-#include <inttypes.h>
#include <stdlib.h>
+#include <cinttypes>
+
#pragma GCC diagnostic push
#if defined(__clang__)
diff --git a/src/profiling/memory/heapprofd.cc b/src/profiling/memory/heapprofd.cc
new file mode 100644
index 000000000..d3a8caea2
--- /dev/null
+++ b/src/profiling/memory/heapprofd.cc
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/profiling/memory/heapprofd.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <array>
+#include <memory>
+#include <vector>
+
+#include <signal.h>
+
+#include "perfetto/ext/base/event_fd.h"
+#include "perfetto/ext/base/getopt.h"
+#include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/unix_socket.h"
+#include "perfetto/ext/base/watchdog.h"
+#include "perfetto/ext/tracing/ipc/default_socket.h"
+#include "src/profiling/memory/heapprofd_producer.h"
+#include "src/profiling/memory/java_hprof_producer.h"
+#include "src/profiling/memory/wire_protocol.h"
+
+#include "perfetto/ext/base/unix_task_runner.h"
+
+// TODO(rsavitski): the task runner watchdog spawns a thread (normally for
+// tracking cpu/mem usage) that we don't strictly need.
+
+namespace perfetto {
+namespace profiling {
+namespace {
+
+int StartCentralHeapprofd();
+
+int GetListeningSocket() {
+ const char* sock_fd = getenv(kHeapprofdSocketEnvVar);
+ if (sock_fd == nullptr)
+ PERFETTO_FATAL("Did not inherit socket from init.");
+ char* end;
+ int raw_fd = static_cast<int>(strtol(sock_fd, &end, 10));
+ if (*end != '\0')
+ PERFETTO_FATAL("Invalid %s. Expected decimal integer.",
+ kHeapprofdSocketEnvVar);
+ return raw_fd;
+}
+
+base::EventFd* g_dump_evt = nullptr;
+
+int StartCentralHeapprofd() {
+ // We set this up before launching any threads, so we do not have to use a
+ // std::atomic for g_dump_evt.
+ g_dump_evt = new base::EventFd();
+
+ base::UnixTaskRunner task_runner;
+ base::Watchdog::GetInstance()->Start(); // crash on exceedingly long tasks
+ HeapprofdProducer producer(HeapprofdMode::kCentral, &task_runner,
+ /* exit_when_done= */ false);
+
+ int listening_raw_socket = GetListeningSocket();
+ auto listening_socket = base::UnixSocket::Listen(
+ base::ScopedFile(listening_raw_socket), &producer.socket_delegate(),
+ &task_runner, base::SockFamily::kUnix, base::SockType::kStream);
+
+ struct sigaction action = {};
+ action.sa_handler = [](int) { g_dump_evt->Notify(); };
+ // Allow to trigger a full dump by sending SIGUSR1 to heapprofd.
+ // This will allow manually deciding when to dump on userdebug.
+ PERFETTO_CHECK(sigaction(SIGUSR1, &action, nullptr) == 0);
+ task_runner.AddFileDescriptorWatch(g_dump_evt->fd(), [&producer] {
+ g_dump_evt->Clear();
+ producer.DumpAll();
+ });
+ producer.ConnectWithRetries(GetProducerSocket());
+ // TODO(fmayer): Create one producer that manages both heapprofd and Java
+ // producers, so we do not have two connections to traced.
+ JavaHprofProducer java_producer(&task_runner);
+ java_producer.ConnectWithRetries(GetProducerSocket());
+ task_runner.Run();
+ return 0;
+}
+
+} // namespace
+
+int HeapprofdMain(int argc, char** argv) {
+ bool cleanup_crash = false;
+
+ enum { kCleanupCrash = 256, kTargetPid, kTargetCmd, kInheritFd };
+ static option long_options[] = {
+ {"cleanup-after-crash", no_argument, nullptr, kCleanupCrash},
+ {nullptr, 0, nullptr, 0}};
+ int c;
+ while ((c = getopt_long(argc, argv, "", long_options, nullptr)) != -1) {
+ switch (c) {
+ case kCleanupCrash:
+ cleanup_crash = true;
+ break;
+ }
+ }
+
+ if (cleanup_crash) {
+ PERFETTO_LOG(
+ "Recovering from crash: unsetting heapprofd system properties. "
+ "Expect SELinux denials for unrelated properties.");
+ SystemProperties::ResetHeapprofdProperties();
+ PERFETTO_LOG(
+ "Finished unsetting heapprofd system properties. "
+ "SELinux denials about properties are unexpected after "
+ "this point.");
+ return 0;
+ }
+
+ // start as a central daemon.
+ return StartCentralHeapprofd();
+}
+
+} // namespace profiling
+} // namespace perfetto
diff --git a/src/profiling/memory/heapprofd.h b/src/profiling/memory/heapprofd.h
new file mode 100644
index 000000000..e40558561
--- /dev/null
+++ b/src/profiling/memory/heapprofd.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_PROFILING_MEMORY_HEAPPROFD_H_
+#define SRC_PROFILING_MEMORY_HEAPPROFD_H_
+
+namespace perfetto {
+namespace profiling {
+
+int HeapprofdMain(int argc, char** argv);
+
+} // namespace profiling
+} // namespace perfetto
+
+#endif // SRC_PROFILING_MEMORY_HEAPPROFD_H_
diff --git a/src/profiling/memory/heapprofd_end_to_end_test.cc b/src/profiling/memory/heapprofd_end_to_end_test.cc
index 97c9876dc..df08bd96e 100644
--- a/src/profiling/memory/heapprofd_end_to_end_test.cc
+++ b/src/profiling/memory/heapprofd_end_to_end_test.cc
@@ -19,6 +19,7 @@
#include <vector>
#include <fcntl.h>
+#include <stdint.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -311,6 +312,9 @@ void __attribute__((constructor(1024))) RunAccurateMalloc() {
// Wait around so we can verify it did't crash.
for (;;) {
+ // Call sleep, otherwise an empty busy loop is undefined behavior:
+ // http://en.cppreference.com/w/cpp/language/memory_model#Progress_guarantee
+ sleep(1);
}
}
@@ -350,6 +354,9 @@ void __attribute__((noreturn)) RunAccurateMallocWithVforkCommon() {
// Wait around so we can verify it did't crash.
for (;;) {
+ // Call sleep, otherwise an empty busy loop is undefined behavior:
+ // http://en.cppreference.com/w/cpp/language/memory_model#Progress_guarantee
+ sleep(1);
}
}
@@ -386,6 +393,9 @@ void __attribute__((constructor(1024))) RunAccurateSample() {
// Wait around so we can verify it did't crash.
for (;;) {
+ // Call sleep, otherwise an empty busy loop is undefined behavior:
+ // http://en.cppreference.com/w/cpp/language/memory_model#Progress_guarantee
+ sleep(1);
}
}
@@ -454,6 +464,7 @@ void __attribute__((constructor(1024))) RunCustomLifetime() {
static std::atomic<bool> disabled{false};
static std::atomic<uint64_t> sampling_interval;
+ static uint32_t other_heap_id = 0;
auto enabled_callback = [](void*,
const AHeapProfileEnableCallbackInfo* info) {
sampling_interval =
@@ -461,6 +472,8 @@ void __attribute__((constructor(1024))) RunCustomLifetime() {
initialized = true;
};
auto disabled_callback = [](void*, const AHeapProfileDisableCallbackInfo*) {
+ PERFETTO_CHECK(other_heap_id);
+ AHeapProfile_reportFree(other_heap_id, 0);
disabled = true;
};
static uint32_t heap_id =
@@ -469,6 +482,7 @@ void __attribute__((constructor(1024))) RunCustomLifetime() {
enabled_callback, nullptr),
disabled_callback, nullptr));
+ other_heap_id = AHeapProfile_registerHeap(AHeapInfo_create("othertest"));
ChildFinishHandshake();
// heapprofd_client needs malloc to see the signal.
@@ -488,6 +502,9 @@ void __attribute__((constructor(1024))) RunCustomLifetime() {
// Wait around so we can verify it didn't crash.
for (;;) {
+ // Call sleep, otherwise an empty busy loop is undefined behavior:
+ // http://en.cppreference.com/w/cpp/language/memory_model#Progress_guarantee
+ sleep(1);
}
}
@@ -1136,6 +1153,7 @@ TEST_P(HeapprofdEndToEnd, CustomLifetime) {
cfg->set_sampling_interval_bytes(1000000);
cfg->add_pid(pid);
cfg->add_heaps("test");
+ cfg->add_heaps("othertest");
});
auto helper = Trace(trace_config);
@@ -1744,6 +1762,10 @@ TEST_P(HeapprofdEndToEnd, NativeProfilingActiveAtProcessExit) {
EXPECT_GT(total_allocated, 0u);
}
+// Disable these tests when running with sanitizers. They (double) fork and that
+// seems to cause flaky crashes with sanitizers.
+#if !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER) && \
+ !defined(MEMORY_SANITIZER) && !defined(LEAK_SANITIZER)
// On in-tree Android, we use the system heapprofd in fork or central mode.
// For Linux and out-of-tree Android, we statically include a copy of
// heapprofd and use that. This one does not support intercepting malloc.
@@ -1752,7 +1774,7 @@ TEST_P(HeapprofdEndToEnd, NativeProfilingActiveAtProcessExit) {
#error "Need to start daemons for Linux test."
#endif
-INSTANTIATE_TEST_CASE_P(DISABLED_Run,
+INSTANTIATE_TEST_CASE_P(Run,
HeapprofdEndToEnd,
Values(std::make_tuple(TestMode::kStatic,
AllocatorMode::kCustom)),
@@ -1765,6 +1787,8 @@ INSTANTIATE_TEST_CASE_P(
std::make_tuple(TestMode::kCentral, AllocatorMode::kCustom)),
TestSuffix);
#endif
+#endif
+
} // namespace
} // namespace profiling
diff --git a/src/profiling/memory/heapprofd_producer.cc b/src/profiling/memory/heapprofd_producer.cc
index dfc69222c..eede46145 100644
--- a/src/profiling/memory/heapprofd_producer.cc
+++ b/src/profiling/memory/heapprofd_producer.cc
@@ -16,16 +16,16 @@
#include "src/profiling/memory/heapprofd_producer.h"
-#include <algorithm>
-#include <functional>
-#include <string>
-
-#include <inttypes.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
+#include <algorithm>
+#include <cinttypes>
+#include <functional>
+#include <string>
+
#include "perfetto/base/compiler.h"
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/file_utils.h"
@@ -63,8 +63,6 @@ constexpr uint32_t kInitialConnectionBackoffMs = 100;
constexpr uint32_t kMaxConnectionBackoffMs = 30 * 1000;
constexpr uint32_t kGuardrailIntervalMs = 30 * 1000;
-constexpr uint32_t kChildModeWatchdogPeriodMs = 10 * 1000;
-
constexpr uint64_t kDefaultShmemSize = 8 * 1048576; // ~8 MB
constexpr uint64_t kMaxShmemSize = 500 * 1048576; // ~500 MB
@@ -101,7 +99,6 @@ bool ConfigTargetsProcess(const HeapprofdConfig& cfg,
return false;
}
-
bool IsFile(int fd, const char* fn) {
struct stat fdstat;
struct stat fnstat;
@@ -149,7 +146,8 @@ bool HeapprofdConfigToClientConfiguration(
cli_config->adaptive_sampling_max_sampling_interval_bytes =
heapprofd_config.adaptive_sampling_max_sampling_interval_bytes();
size_t n = 0;
- const std::vector<std::string>& exclude_heaps = heapprofd_config.exclude_heaps();
+ const std::vector<std::string>& exclude_heaps =
+ heapprofd_config.exclude_heaps();
// heaps[i] and heaps_interval[i] represent that the heap named in heaps[i]
// should be sampled with sampling interval of heap_interval[i].
std::vector<std::string> heaps = heapprofd_config.heaps();
@@ -194,9 +192,8 @@ bool HeapprofdConfigToClientConfiguration(
HEAPPROFD_HEAP_NAME_SZ - 1);
continue;
}
- strncpy(&cli_config->heaps[n].name[0], heap.c_str(),
- sizeof(cli_config->heaps[0].name));
- cli_config->heaps[n].name[sizeof(cli_config->heaps[0].name) - 1] = '\0';
+ base::StringCopy(&cli_config->heaps[n].name[0], heap.c_str(),
+ sizeof(cli_config->heaps[n].name));
cli_config->heaps[n].interval = interval;
n++;
}
@@ -335,29 +332,6 @@ void HeapprofdProducer::Restart() {
ConnectWithRetries(socket_name);
}
-void HeapprofdProducer::ActiveDataSourceWatchdogCheck() {
- PERFETTO_DCHECK(mode_ == HeapprofdMode::kChild);
-
- // Fork mode heapprofd should be working on exactly one data source matching
- // its target process.
- if (data_sources_.empty()) {
- PERFETTO_LOG(
- "Child heapprofd exiting as it never received a data source for the "
- "target process, or somehow lost/finished the task without exiting.");
- TerminateProcess(/*exit_status=*/1);
- } else {
- // reschedule check.
- auto weak_producer = weak_factory_.GetWeakPtr();
- task_runner_->PostDelayedTask(
- [weak_producer]() {
- if (!weak_producer)
- return;
- weak_producer->ActiveDataSourceWatchdogCheck();
- },
- kChildModeWatchdogPeriodMs);
- }
-}
-
// TODO(rsavitski): would be cleaner to shut down the event loop instead
// (letting main exit). One test-friendly approach is to supply a shutdown
// callback in the constructor.
@@ -598,7 +572,7 @@ void HeapprofdProducer::StopDataSource(DataSourceInstanceID id) {
return;
}
- PERFETTO_DLOG("Stopping data source %" PRIu64, id);
+ PERFETTO_LOG("Stopping data source %" PRIu64, id);
DataSource& data_source = it->second;
data_source.was_stopped = true;
@@ -699,39 +673,26 @@ void HeapprofdProducer::DumpProcessState(DataSource* data_source,
bool from_startup = data_source->signaled_pids.find(pid) ==
data_source->signaled_pids.cend();
- uint64_t dump_timestamp;
- if (data_source->config.dump_at_max())
- dump_timestamp = heap_info.heap_tracker.max_timestamp();
- else
- dump_timestamp = heap_info.heap_tracker.committed_timestamp();
-
- const char* heap_name = nullptr;
- if (!heap_info.heap_name.empty())
- heap_name = heap_info.heap_name.c_str();
- uint64_t sampling_interval = heap_info.sampling_interval;
- uint64_t orig_sampling_interval = heap_info.orig_sampling_interval;
-
- auto new_heapsamples =
- [pid, from_startup, dump_timestamp, process_state, data_source,
- heap_name, sampling_interval,
- orig_sampling_interval](ProfilePacket::ProcessHeapSamples* proto) {
- proto->set_pid(static_cast<uint64_t>(pid));
- proto->set_timestamp(dump_timestamp);
- proto->set_from_startup(from_startup);
- proto->set_disconnected(process_state->disconnected);
- proto->set_buffer_overran(process_state->error_state ==
- SharedRingBuffer::kHitTimeout);
- proto->set_client_error(
- ErrorStateToProto(process_state->error_state));
- proto->set_buffer_corrupted(process_state->buffer_corrupted);
- proto->set_hit_guardrail(data_source->hit_guardrail);
- if (heap_name)
- proto->set_heap_name(heap_name);
- proto->set_sampling_interval_bytes(sampling_interval);
- proto->set_orig_sampling_interval_bytes(orig_sampling_interval);
- auto* stats = proto->set_stats();
- SetStats(stats, *process_state);
- };
+
+ auto new_heapsamples = [pid, from_startup, process_state, data_source,
+ &heap_info](
+ ProfilePacket::ProcessHeapSamples* proto) {
+ proto->set_pid(static_cast<uint64_t>(pid));
+ proto->set_timestamp(heap_info.heap_tracker.dump_timestamp());
+ proto->set_from_startup(from_startup);
+ proto->set_disconnected(process_state->disconnected);
+ proto->set_buffer_overran(process_state->error_state ==
+ SharedRingBuffer::kHitTimeout);
+ proto->set_client_error(ErrorStateToProto(process_state->error_state));
+ proto->set_buffer_corrupted(process_state->buffer_corrupted);
+ proto->set_hit_guardrail(data_source->hit_guardrail);
+ if (!heap_info.heap_name.empty())
+ proto->set_heap_name(heap_info.heap_name.c_str());
+ proto->set_sampling_interval_bytes(heap_info.sampling_interval);
+ proto->set_orig_sampling_interval_bytes(heap_info.orig_sampling_interval);
+ auto* stats = proto->set_stats();
+ SetStats(stats, *process_state);
+ };
DumpState dump_state(data_source->trace_writer.get(),
std::move(new_heapsamples),
@@ -1066,7 +1027,10 @@ void HeapprofdProducer::HandleAllocRecord(AllocRecord* alloc_rec) {
const auto& prefixes = ds.config.skip_symbol_prefix();
if (!prefixes.empty()) {
for (unwindstack::FrameData& frame_data : alloc_rec->frames) {
- const std::string& map = frame_data.map_name;
+ if (frame_data.map_info == nullptr) {
+ continue;
+ }
+ const std::string& map = frame_data.map_info->name();
if (std::find_if(prefixes.cbegin(), prefixes.cend(),
[&map](const std::string& prefix) {
return base::StartsWith(map, prefix);
@@ -1249,6 +1213,8 @@ void HeapprofdProducer::CheckDataSourceCpuTask() {
DataSource& ds = p.second;
if (gr.IsOverCpuThreshold(ds.guardrail_config)) {
ds.hit_guardrail = true;
+ PERFETTO_LOG("Data source %" PRIu64 " hit CPU guardrail. Shutting down.",
+ ds.id);
ShutdownDataSource(&ds);
}
}
@@ -1268,6 +1234,9 @@ void HeapprofdProducer::CheckDataSourceMemoryTask() {
DataSource& ds = p.second;
if (gr.IsOverMemoryThreshold(ds.guardrail_config)) {
ds.hit_guardrail = true;
+ PERFETTO_LOG("Data source %" PRIu64
+ " hit memory guardrail. Shutting down.",
+ ds.id);
ShutdownDataSource(&ds);
}
}
diff --git a/src/profiling/memory/heapprofd_producer.h b/src/profiling/memory/heapprofd_producer.h
index b8e9c53af..4c57a5d78 100644
--- a/src/profiling/memory/heapprofd_producer.h
+++ b/src/profiling/memory/heapprofd_producer.h
@@ -18,23 +18,20 @@
#define SRC_PROFILING_MEMORY_HEAPPROFD_PRODUCER_H_
#include <array>
+#include <cinttypes>
#include <functional>
#include <map>
#include <vector>
-#include <inttypes.h>
-
#include "perfetto/base/task_runner.h"
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/unix_socket.h"
#include "perfetto/ext/base/unix_task_runner.h"
-
#include "perfetto/ext/tracing/core/basic_types.h"
#include "perfetto/ext/tracing/core/producer.h"
#include "perfetto/ext/tracing/core/trace_writer.h"
#include "perfetto/ext/tracing/core/tracing_service.h"
#include "perfetto/tracing/core/data_source_config.h"
-
#include "perfetto/tracing/core/forward_decls.h"
#include "src/profiling/common/interning_output.h"
#include "src/profiling/common/proc_utils.h"
@@ -277,8 +274,6 @@ class HeapprofdProducer : public Producer, public UnwindingWorker::Delegate {
// Specific to mode_ == kChild
void TerminateProcess(int exit_status);
- // Specific to mode_ == kChild
- void ActiveDataSourceWatchdogCheck();
void ShutdownDataSource(DataSource* ds);
bool MaybeFinishDataSource(DataSource* ds);
diff --git a/src/profiling/memory/heapprofd_producer_unittest.cc b/src/profiling/memory/heapprofd_producer_unittest.cc
index fa08e95f9..78ed9ea83 100644
--- a/src/profiling/memory/heapprofd_producer_unittest.cc
+++ b/src/profiling/memory/heapprofd_producer_unittest.cc
@@ -48,6 +48,7 @@ class MockProducerEndpoint : public TracingService::ProducerEndpoint {
MOCK_METHOD1(ActivateTriggers, void(const std::vector<std::string>&));
MOCK_METHOD1(RegisterDataSource, void(const DataSourceDescriptor&));
+ MOCK_METHOD1(UpdateDataSource, void(const DataSourceDescriptor&));
MOCK_METHOD2(CommitData, void(const CommitDataRequest&, CommitDataCallback));
MOCK_METHOD2(RegisterTraceWriter, void(uint32_t, uint32_t));
MOCK_METHOD1(UnregisterTraceWriter, void(uint32_t));
diff --git a/src/profiling/memory/include/perfetto/heap_profile.h b/src/profiling/memory/include/perfetto/heap_profile.h
index 8f03a63c2..b4e0e62ab 100644
--- a/src/profiling/memory/include/perfetto/heap_profile.h
+++ b/src/profiling/memory/include/perfetto/heap_profile.h
@@ -59,9 +59,10 @@
#ifndef SRC_PROFILING_MEMORY_INCLUDE_PERFETTO_HEAP_PROFILE_H_
#define SRC_PROFILING_MEMORY_INCLUDE_PERFETTO_HEAP_PROFILE_H_
-#include <inttypes.h>
#include <stdlib.h>
+#include <cinttypes>
+
#pragma GCC diagnostic push
#if defined(__clang__)
@@ -82,6 +83,14 @@ typedef struct AHeapInfo AHeapInfo;
typedef struct AHeapProfileEnableCallbackInfo AHeapProfileEnableCallbackInfo;
typedef struct AHeapProfileDisableCallbackInfo AHeapProfileDisableCallbackInfo;
+typedef void (*_Nonnull AHeapInfo_EnableCallback)(
+ void* _Nullable data,
+ const AHeapProfileEnableCallbackInfo* _Nonnull session_info);
+
+typedef void (*_Nonnull AHeapInfo_DisableCallback)(
+ void* _Nullable data,
+ const AHeapProfileDisableCallbackInfo* _Nonnull session_info);
+
// Get sampling interval (in bytes) of the profiling session that was started.
uint64_t AHeapProfileEnableCallbackInfo_getSamplingInterval(
const AHeapProfileEnableCallbackInfo* _Nonnull session_info);
@@ -109,9 +118,7 @@ AHeapInfo* _Nullable AHeapInfo_create(const char* _Nonnull heap_name);
// this callback is called when profiling of the heap is requested.
AHeapInfo* _Nullable AHeapInfo_setEnabledCallback(
AHeapInfo* _Nullable info,
- void (*_Nonnull callback)(
- void* _Nullable,
- const AHeapProfileEnableCallbackInfo* _Nonnull session_info),
+ AHeapInfo_EnableCallback callback,
void* _Nullable data);
// Set disabled callback in AHeapInfo.
@@ -122,9 +129,7 @@ AHeapInfo* _Nullable AHeapInfo_setEnabledCallback(
// this callback is called when profiling of the heap ends.
AHeapInfo* _Nullable AHeapInfo_setDisabledCallback(
AHeapInfo* _Nullable info,
- void (*_Nonnull callback)(
- void* _Nullable,
- const AHeapProfileDisableCallbackInfo* _Nonnull session_info),
+ AHeapInfo_DisableCallback callback,
void* _Nullable data);
// Register heap described in AHeapInfo.
diff --git a/src/profiling/memory/java_hprof_producer.cc b/src/profiling/memory/java_hprof_producer.cc
index aef9b5bc2..81a9c2772 100644
--- a/src/profiling/memory/java_hprof_producer.cc
+++ b/src/profiling/memory/java_hprof_producer.cc
@@ -21,6 +21,7 @@
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/tracing/core/trace_writer.h"
+#include "src/profiling/common/proc_cmdline.h"
#include "src/profiling/common/proc_utils.h"
#include "src/profiling/common/producer_support.h"
@@ -40,8 +41,11 @@ void JavaHprofProducer::DoContinuousDump(DataSourceInstanceID id,
auto it = data_sources_.find(id);
if (it == data_sources_.end())
return;
- const DataSource& ds = it->second;
- SignalDataSource(ds);
+ DataSource& ds = it->second;
+ if (!ds.config().continuous_dump_config().scan_pids_only_on_start()) {
+ ds.CollectPids();
+ }
+ ds.SendSignal();
auto weak_producer = weak_factory_.GetWeakPtr();
task_runner_->PostDelayedTask(
[weak_producer, id, dump_interval] {
@@ -52,10 +56,16 @@ void JavaHprofProducer::DoContinuousDump(DataSourceInstanceID id,
dump_interval);
}
-// static
-void JavaHprofProducer::SignalDataSource(const DataSource& ds) {
- const std::set<pid_t>& pids = ds.pids;
- for (pid_t pid : pids) {
+JavaHprofProducer::DataSource::DataSource(
+ DataSourceConfig ds_config,
+ JavaHprofConfig config,
+ std::vector<std::string> target_cmdlines)
+ : ds_config_(std::move(ds_config)),
+ config_(std::move(config)),
+ target_cmdlines_(std::move(target_cmdlines)) {}
+
+void JavaHprofProducer::DataSource::SendSignal() const {
+ for (pid_t pid : pids_) {
auto opt_status = ReadStatus(pid);
if (!opt_status) {
PERFETTO_PLOG("Failed to read /proc/%d/status. Not signalling.", pid);
@@ -69,23 +79,32 @@ void JavaHprofProducer::SignalDataSource(const DataSource& ds) {
pid);
continue;
}
- if (!CanProfile(ds.ds_config, uids->effective,
- ds.config.target_installed_by())) {
+ if (!CanProfile(ds_config_, uids->effective,
+ config_.target_installed_by())) {
PERFETTO_ELOG("%d (UID %" PRIu64 ") not profileable.", pid,
uids->effective);
continue;
}
PERFETTO_DLOG("Sending %d to %d", kJavaHeapprofdSignal, pid);
union sigval signal_value;
- signal_value.sival_int =
- static_cast<int32_t>(ds.ds_config.tracing_session_id() %
- std::numeric_limits<int32_t>::max());
+ signal_value.sival_int = static_cast<int32_t>(
+ ds_config_.tracing_session_id() % std::numeric_limits<int32_t>::max());
if (sigqueue(pid, kJavaHeapprofdSignal, signal_value) != 0) {
PERFETTO_DPLOG("sigqueue");
}
}
}
+void JavaHprofProducer::DataSource::CollectPids() {
+ pids_.clear();
+ for (uint64_t pid : config_.pid()) {
+ pids_.insert(static_cast<pid_t>(pid));
+ }
+ glob_aware::FindPidsForCmdlinePatterns(target_cmdlines_, &pids_);
+ if (config_.min_anonymous_memory_kb() > 0)
+ RemoveUnderAnonThreshold(config_.min_anonymous_memory_kb(), &pids_);
+}
+
void JavaHprofProducer::IncreaseConnectionBackoff() {
connection_backoff_ms_ *= 2;
if (connection_backoff_ms_ > kMaxConnectionBackoffMs)
@@ -104,23 +123,10 @@ void JavaHprofProducer::SetupDataSource(DataSourceInstanceID id,
}
JavaHprofConfig config;
config.ParseFromString(ds_config.java_hprof_config_raw());
- DataSource ds;
- ds.id = id;
- for (uint64_t pid : config.pid())
- ds.pids.emplace(static_cast<pid_t>(pid));
- base::Optional<std::vector<std::string>> normalized_cmdlines =
- NormalizeCmdlines(config.process_cmdline());
- if (!normalized_cmdlines.has_value()) {
- PERFETTO_ELOG("Rejecting data source due to invalid cmdline in config.");
- return;
- }
- FindPidsForCmdlines(normalized_cmdlines.value(), &ds.pids);
- if (config.min_anonymous_memory_kb() > 0)
- RemoveUnderAnonThreshold(config.min_anonymous_memory_kb(), &ds.pids);
-
- ds.config = std::move(config);
- ds.ds_config = std::move(ds_config);
- data_sources_.emplace(id, std::move(ds));
+ std::vector<std::string> cmdline_patterns = config.process_cmdline();
+ DataSource ds(ds_config, std::move(config), std::move(cmdline_patterns));
+ ds.CollectPids();
+ data_sources_.emplace(id, ds);
}
void JavaHprofProducer::StartDataSource(DataSourceInstanceID id,
@@ -131,7 +137,7 @@ void JavaHprofProducer::StartDataSource(DataSourceInstanceID id,
return;
}
const DataSource& ds = it->second;
- const auto continuous_dump_config = ds.config.continuous_dump_config();
+ const auto& continuous_dump_config = ds.config().continuous_dump_config();
uint32_t dump_interval = continuous_dump_config.dump_interval_ms();
if (dump_interval) {
auto weak_producer = weak_factory_.GetWeakPtr();
@@ -143,7 +149,7 @@ void JavaHprofProducer::StartDataSource(DataSourceInstanceID id,
},
continuous_dump_config.dump_phase_ms());
}
- SignalDataSource(ds);
+ ds.SendSignal();
}
void JavaHprofProducer::StopDataSource(DataSourceInstanceID id) {
diff --git a/src/profiling/memory/java_hprof_producer.h b/src/profiling/memory/java_hprof_producer.h
index 97ac07d23..4355d9686 100644
--- a/src/profiling/memory/java_hprof_producer.h
+++ b/src/profiling/memory/java_hprof_producer.h
@@ -69,11 +69,23 @@ class JavaHprofProducer : public Producer {
kConnected,
};
- struct DataSource {
- DataSourceInstanceID id;
- std::set<pid_t> pids;
- JavaHprofConfig config;
- DataSourceConfig ds_config;
+ class DataSource {
+ public:
+ DataSource(DataSourceConfig ds_config,
+ JavaHprofConfig config,
+ std::vector<std::string> target_cmdlines);
+ void CollectPids();
+ void SendSignal() const;
+
+ const JavaHprofConfig& config() const { return config_; }
+ const DataSourceConfig& ds_config() const { return ds_config_; }
+
+ private:
+ DataSourceConfig ds_config_;
+ JavaHprofConfig config_;
+ std::vector<std::string> target_cmdlines_;
+
+ std::set<pid_t> pids_;
};
void ConnectService();
@@ -82,7 +94,6 @@ class JavaHprofProducer : public Producer {
void IncreaseConnectionBackoff();
void DoContinuousDump(DataSourceInstanceID id, uint32_t dump_interval);
- static void SignalDataSource(const DataSource& ds);
// State of connection to the tracing service.
State state_ = kNotStarted;
diff --git a/src/profiling/memory/log_histogram.cc b/src/profiling/memory/log_histogram.cc
index 3db734fc0..3e7e32892 100644
--- a/src/profiling/memory/log_histogram.cc
+++ b/src/profiling/memory/log_histogram.cc
@@ -16,9 +16,9 @@
#include "src/profiling/memory/log_histogram.h"
-#include <inttypes.h>
#include <stddef.h>
+#include <cinttypes>
#include <utility>
#include <vector>
diff --git a/src/profiling/memory/log_histogram.h b/src/profiling/memory/log_histogram.h
index 9b16b8681..e016173bc 100644
--- a/src/profiling/memory/log_histogram.h
+++ b/src/profiling/memory/log_histogram.h
@@ -17,10 +17,10 @@
#ifndef SRC_PROFILING_MEMORY_LOG_HISTOGRAM_H_
#define SRC_PROFILING_MEMORY_LOG_HISTOGRAM_H_
-#include <inttypes.h>
#include <stddef.h>
#include <array>
+#include <cinttypes>
#include <utility>
#include <vector>
diff --git a/src/profiling/memory/main.cc b/src/profiling/memory/main.cc
index f0bb47b39..078ca860b 100644
--- a/src/profiling/memory/main.cc
+++ b/src/profiling/memory/main.cc
@@ -14,117 +14,7 @@
* limitations under the License.
*/
-#include <stdlib.h>
-#include <unistd.h>
-#include <array>
-#include <memory>
-#include <vector>
-
-#include <signal.h>
-
-#include "perfetto/ext/base/event_fd.h"
-#include "perfetto/ext/base/getopt.h"
-#include "perfetto/ext/base/scoped_file.h"
-#include "perfetto/ext/base/unix_socket.h"
-#include "perfetto/ext/base/watchdog.h"
-#include "perfetto/ext/tracing/ipc/default_socket.h"
-#include "src/profiling/memory/heapprofd_producer.h"
-#include "src/profiling/memory/java_hprof_producer.h"
-#include "src/profiling/memory/wire_protocol.h"
-
-#include "perfetto/ext/base/unix_task_runner.h"
-
-// TODO(rsavitski): the task runner watchdog spawns a thread (normally for
-// tracking cpu/mem usage) that we don't strictly need.
-
-namespace perfetto {
-namespace profiling {
-namespace {
-
-int StartCentralHeapprofd();
-
-int GetListeningSocket() {
- const char* sock_fd = getenv(kHeapprofdSocketEnvVar);
- if (sock_fd == nullptr)
- PERFETTO_FATAL("Did not inherit socket from init.");
- char* end;
- int raw_fd = static_cast<int>(strtol(sock_fd, &end, 10));
- if (*end != '\0')
- PERFETTO_FATAL("Invalid %s. Expected decimal integer.",
- kHeapprofdSocketEnvVar);
- return raw_fd;
-}
-
-base::EventFd* g_dump_evt = nullptr;
-
-int HeapprofdMain(int argc, char** argv) {
- bool cleanup_crash = false;
-
- enum { kCleanupCrash = 256, kTargetPid, kTargetCmd, kInheritFd };
- static option long_options[] = {
- {"cleanup-after-crash", no_argument, nullptr, kCleanupCrash},
- {nullptr, 0, nullptr, 0}};
- int c;
- while ((c = getopt_long(argc, argv, "", long_options, nullptr)) != -1) {
- switch (c) {
- case kCleanupCrash:
- cleanup_crash = true;
- break;
- }
- }
-
- if (cleanup_crash) {
- PERFETTO_LOG(
- "Recovering from crash: unsetting heapprofd system properties. "
- "Expect SELinux denials for unrelated properties.");
- SystemProperties::ResetHeapprofdProperties();
- PERFETTO_LOG(
- "Finished unsetting heapprofd system properties. "
- "SELinux denials about properties are unexpected after "
- "this point.");
- return 0;
- }
-
- // start as a central daemon.
- return StartCentralHeapprofd();
-}
-
-int StartCentralHeapprofd() {
- // We set this up before launching any threads, so we do not have to use a
- // std::atomic for g_dump_evt.
- g_dump_evt = new base::EventFd();
-
- base::UnixTaskRunner task_runner;
- base::Watchdog::GetInstance()->Start(); // crash on exceedingly long tasks
- HeapprofdProducer producer(HeapprofdMode::kCentral, &task_runner,
- /* exit_when_done= */ false);
-
- int listening_raw_socket = GetListeningSocket();
- auto listening_socket = base::UnixSocket::Listen(
- base::ScopedFile(listening_raw_socket), &producer.socket_delegate(),
- &task_runner, base::SockFamily::kUnix, base::SockType::kStream);
-
- struct sigaction action = {};
- action.sa_handler = [](int) { g_dump_evt->Notify(); };
- // Allow to trigger a full dump by sending SIGUSR1 to heapprofd.
- // This will allow manually deciding when to dump on userdebug.
- PERFETTO_CHECK(sigaction(SIGUSR1, &action, nullptr) == 0);
- task_runner.AddFileDescriptorWatch(g_dump_evt->fd(), [&producer] {
- g_dump_evt->Clear();
- producer.DumpAll();
- });
- producer.ConnectWithRetries(GetProducerSocket());
- // TODO(fmayer): Create one producer that manages both heapprofd and Java
- // producers, so we do not have two connections to traced.
- JavaHprofProducer java_producer(&task_runner);
- java_producer.ConnectWithRetries(GetProducerSocket());
- task_runner.Run();
- return 0;
-}
-
-} // namespace
-} // namespace profiling
-} // namespace perfetto
+#include "src/profiling/memory/heapprofd.h"
int main(int argc, char** argv) {
return perfetto::profiling::HeapprofdMain(argc, argv);
diff --git a/src/profiling/memory/malloc_interceptor_bionic_hooks.cc b/src/profiling/memory/malloc_interceptor_bionic_hooks.cc
index 2e63f23f1..0d5a92eae 100644
--- a/src/profiling/memory/malloc_interceptor_bionic_hooks.cc
+++ b/src/profiling/memory/malloc_interceptor_bionic_hooks.cc
@@ -15,11 +15,11 @@
*/
#include <bionic/malloc.h>
-#include <inttypes.h>
#include <malloc.h>
#include <private/bionic_malloc_dispatch.h>
#include <atomic>
+#include <cinttypes>
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/utils.h"
diff --git a/src/profiling/memory/parse_smaps_unittest.cc b/src/profiling/memory/parse_smaps_unittest.cc
index 5708a2ce6..d59d9dfb9 100644
--- a/src/profiling/memory/parse_smaps_unittest.cc
+++ b/src/profiling/memory/parse_smaps_unittest.cc
@@ -16,12 +16,12 @@
#include "perfetto/profiling/parse_smaps.h"
+#include <cinttypes>
+
#include "perfetto/ext/base/scoped_file.h"
#include "src/base/test/utils.h"
#include "test/gtest_and_gmock.h"
-#include <inttypes.h>
-
namespace perfetto {
namespace profiling {
diff --git a/src/profiling/memory/sampler.cc b/src/profiling/memory/sampler.cc
index a5e59db7a..9a05fc359 100644
--- a/src/profiling/memory/sampler.cc
+++ b/src/profiling/memory/sampler.cc
@@ -19,33 +19,10 @@
namespace perfetto {
namespace profiling {
-namespace {
-
-// If the probability of getting less than one sample is less than this,
-// sidestep the sampler and treat the allocation as a sample.
-constexpr double kPassthroughError = 0.01;
-
-} // namespace
-
-uint64_t GetPassthroughThreshold(uint64_t interval) {
- if (interval <= 1)
- return interval;
- // (1 - 1 / interval)^x = kPassthroughError
- // x = log_(1 - 1/interval)(kPassthroughError)
- return 1 + uint64_t(log(kPassthroughError) / log(1.0 - 1 / double(interval)));
-}
-
std::default_random_engine& GetGlobalRandomEngineLocked() {
static std::default_random_engine engine;
return engine;
}
-void Sampler::SetSamplingInterval(uint64_t sampling_interval) {
- sampling_interval_ = sampling_interval;
- passthrough_threshold_ = GetPassthroughThreshold(sampling_interval_);
- sampling_rate_ = 1.0 / static_cast<double>(sampling_interval_);
- interval_to_next_sample_ = NextSampleInterval();
-}
-
} // namespace profiling
} // namespace perfetto
diff --git a/src/profiling/memory/sampler.h b/src/profiling/memory/sampler.h
index d462190e5..40e429ffc 100644
--- a/src/profiling/memory/sampler.h
+++ b/src/profiling/memory/sampler.h
@@ -29,8 +29,6 @@ namespace profiling {
constexpr uint64_t kSamplerSeed = 1;
-uint64_t GetPassthroughThreshold(uint64_t interval);
-
std::default_random_engine& GetGlobalRandomEngineLocked();
// Poisson sampler for memory allocations. We apply sampling individually to
@@ -44,7 +42,11 @@ std::default_random_engine& GetGlobalRandomEngineLocked();
// NB: not thread-safe, requires external synchronization.
class Sampler {
public:
- void SetSamplingInterval(uint64_t sampling_interval);
+ void SetSamplingInterval(uint64_t sampling_interval) {
+ sampling_interval_ = sampling_interval;
+ sampling_rate_ = 1.0 / static_cast<double>(sampling_interval_);
+ interval_to_next_sample_ = NextSampleInterval();
+ }
// Returns number of bytes that should be be attributed to the sample.
// If returned size is 0, the allocation should not be sampled.
@@ -52,7 +54,7 @@ class Sampler {
// Due to how the poission sampling works, some samples should be accounted
// multiple times.
size_t SampleSize(size_t alloc_sz) {
- if (PERFETTO_UNLIKELY(alloc_sz >= passthrough_threshold_))
+ if (PERFETTO_UNLIKELY(alloc_sz >= sampling_interval_))
return alloc_sz;
return static_cast<size_t>(sampling_interval_ * NumberOfSamples(alloc_sz));
}
@@ -83,7 +85,6 @@ class Sampler {
}
uint64_t sampling_interval_;
- uint64_t passthrough_threshold_;
double sampling_rate_;
int64_t interval_to_next_sample_;
};
diff --git a/src/profiling/memory/sampler_unittest.cc b/src/profiling/memory/sampler_unittest.cc
index b3eca7bbc..409fa4cbc 100644
--- a/src/profiling/memory/sampler_unittest.cc
+++ b/src/profiling/memory/sampler_unittest.cc
@@ -27,8 +27,8 @@ namespace {
TEST(SamplerTest, TestLarge) {
GetGlobalRandomEngineLocked().seed(1);
Sampler sampler;
- sampler.SetSamplingInterval(32768);
- EXPECT_EQ(sampler.SampleSize(160000u), 160000u);
+ sampler.SetSamplingInterval(512);
+ EXPECT_EQ(sampler.SampleSize(1024), 1024u);
}
TEST(SamplerTest, TestSmall) {
@@ -47,12 +47,6 @@ TEST(SamplerTest, TestSequence) {
EXPECT_EQ(sampler.SampleSize(5), 5u);
}
-TEST(SamplerTest, TestGetPassthroughThreshold) {
- EXPECT_EQ(GetPassthroughThreshold(32768u), 150900u);
- EXPECT_EQ(GetPassthroughThreshold(1u), 1u);
- EXPECT_EQ(GetPassthroughThreshold(2u), 7u);
-}
-
} // namespace
} // namespace profiling
} // namespace perfetto
diff --git a/src/profiling/memory/shared_ring_buffer.cc b/src/profiling/memory/shared_ring_buffer.cc
index bc563278b..1120c7a6d 100644
--- a/src/profiling/memory/shared_ring_buffer.cc
+++ b/src/profiling/memory/shared_ring_buffer.cc
@@ -16,16 +16,16 @@
#include "src/profiling/memory/shared_ring_buffer.h"
-#include <atomic>
-#include <type_traits>
-
#include <errno.h>
#include <fcntl.h>
-#include <inttypes.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <atomic>
+#include <cinttypes>
+#include <type_traits>
+
#include "perfetto/base/build_config.h"
#include "perfetto/ext/base/scoped_file.h"
#include "perfetto/ext/base/temp_file.h"
diff --git a/src/profiling/memory/shared_ring_buffer_write_fuzzer.cc b/src/profiling/memory/shared_ring_buffer_write_fuzzer.cc
index 486033ee5..62b82eb77 100644
--- a/src/profiling/memory/shared_ring_buffer_write_fuzzer.cc
+++ b/src/profiling/memory/shared_ring_buffer_write_fuzzer.cc
@@ -70,6 +70,7 @@ int FuzzRingBufferWrite(const uint8_t* data, size_t size) {
memcpy(&header, data, sizeof(header));
SharedRingBuffer::MetadataPage& metadata_page = header.metadata_page;
metadata_page.spinlock.locked = false;
+ metadata_page.spinlock.poisoned = false;
PERFETTO_CHECK(ftruncate(*fd, static_cast<off_t>(total_size_pages *
base::kPageSize)) == 0);
diff --git a/src/profiling/memory/unwinding.cc b/src/profiling/memory/unwinding.cc
index 5021949cd..d500e0b9c 100644
--- a/src/profiling/memory/unwinding.cc
+++ b/src/profiling/memory/unwinding.cc
@@ -129,7 +129,6 @@ bool DoUnwind(WireMessage* msg, UnwindingMetadata* metadata, AllocRecord* out) {
PERFETTO_DLOG("Unable to construct unwindstack::Regs");
unwindstack::FrameData frame_data{};
frame_data.function_name = "ERROR READING REGISTERS";
- frame_data.map_name = "ERROR";
out->frames.clear();
out->build_ids.clear();
@@ -191,7 +190,6 @@ bool DoUnwind(WireMessage* msg, UnwindingMetadata* metadata, AllocRecord* out) {
unwindstack::FrameData frame_data{};
frame_data.function_name =
"ERROR " + StringifyLibUnwindstackError(error_code);
- frame_data.map_name = "ERROR";
out->frames.emplace_back(std::move(frame_data));
out->build_ids.emplace_back("");
@@ -228,14 +226,14 @@ void UnwindingWorker::OnDisconnect(base::UnixSocket* self) {
DataSourceInstanceID ds_id = client_data.data_source_instance_id;
client_data_.erase(it);
+ // The erase invalidates the self pointer.
+ self = nullptr;
if (client_data_.empty()) {
// We got rid of the last client. Flush and destruct AllocRecords in
// arena. Disable the arena (will not accept returning borrowed records)
// in case there are pending AllocRecords on the main thread.
alloc_record_arena_.Disable();
}
- // The erase invalidates the self pointer.
- self = nullptr;
delegate_->PostSocketDisconnected(this, ds_id, peer_pid, stats);
}
diff --git a/src/profiling/memory/unwinding_unittest.cc b/src/profiling/memory/unwinding_unittest.cc
index 40cfc0892..5a238e91b 100644
--- a/src/profiling/memory/unwinding_unittest.cc
+++ b/src/profiling/memory/unwinding_unittest.cc
@@ -65,7 +65,7 @@ TEST(UnwindingTest, FDMapsParse) {
FDMaps maps(std::move(proc_maps));
ASSERT_TRUE(maps.Parse());
unwindstack::MapInfo* map_info =
- maps.Find(reinterpret_cast<uint64_t>(&proc_maps));
+ maps.Find(reinterpret_cast<uint64_t>(&proc_maps)).get();
ASSERT_NE(map_info, nullptr);
ASSERT_EQ(map_info->name(), "[stack]");
}
diff --git a/src/profiling/memory/wire_protocol.cc b/src/profiling/memory/wire_protocol.cc
index 29ea0423b..9d30bebb5 100644
--- a/src/profiling/memory/wire_protocol.cc
+++ b/src/profiling/memory/wire_protocol.cc
@@ -58,6 +58,10 @@ void UnsafeMemcpy(char* dest, const char* src, size_t n)
template <typename F>
int64_t WithBuffer(SharedRingBuffer* shmem, size_t total_size, F fn) {
+ if (total_size > shmem->size()) {
+ errno = EMSGSIZE;
+ return -1;
+ }
SharedRingBuffer::Buffer buf;
{
ScopedSpinlock lock = shmem->AcquireLock(ScopedSpinlock::Mode::Try);
diff --git a/src/profiling/memory/wire_protocol.h b/src/profiling/memory/wire_protocol.h
index f1989b727..164358f4f 100644
--- a/src/profiling/memory/wire_protocol.h
+++ b/src/profiling/memory/wire_protocol.h
@@ -20,7 +20,8 @@
#ifndef SRC_PROFILING_MEMORY_WIRE_PROTOCOL_H_
#define SRC_PROFILING_MEMORY_WIRE_PROTOCOL_H_
-#include <inttypes.h>
+#include <cinttypes>
+
#include <unwindstack/Elf.h>
#include <unwindstack/MachineArm.h>
#include <unwindstack/MachineArm64.h>
diff --git a/src/profiling/memory/wire_protocol_unittest.cc b/src/profiling/memory/wire_protocol_unittest.cc
index 3f7e494dd..873d97761 100644
--- a/src/profiling/memory/wire_protocol_unittest.cc
+++ b/src/profiling/memory/wire_protocol_unittest.cc
@@ -95,12 +95,13 @@ TEST(WireProtocolTest, AllocMessage) {
WireMessage recv_msg;
ASSERT_TRUE(ReceiveWireMessage(reinterpret_cast<char*>(buf.data), buf.size,
&recv_msg));
- shmem_server->EndRead(std::move(buf));
ASSERT_EQ(recv_msg.record_type, msg.record_type);
ASSERT_EQ(*recv_msg.alloc_header, *msg.alloc_header);
ASSERT_EQ(recv_msg.payload_size, msg.payload_size);
ASSERT_STREQ(recv_msg.payload, msg.payload);
+
+ shmem_server->EndRead(std::move(buf));
}
TEST(WireProtocolTest, FreeMessage) {
@@ -123,11 +124,12 @@ TEST(WireProtocolTest, FreeMessage) {
WireMessage recv_msg;
ASSERT_TRUE(ReceiveWireMessage(reinterpret_cast<char*>(buf.data), buf.size,
&recv_msg));
- shmem_server->EndRead(std::move(buf));
ASSERT_EQ(recv_msg.record_type, msg.record_type);
ASSERT_EQ(*recv_msg.free_header, *msg.free_header);
ASSERT_EQ(recv_msg.payload_size, msg.payload_size);
+
+ shmem_server->EndRead(std::move(buf));
}
TEST(GetHeapSamplingInterval, Default) {
diff --git a/src/profiling/memory/wrap_allocators.cc b/src/profiling/memory/wrap_allocators.cc
index 696337a9c..e73c15147 100644
--- a/src/profiling/memory/wrap_allocators.cc
+++ b/src/profiling/memory/wrap_allocators.cc
@@ -14,9 +14,10 @@
* limitations under the License.
*/
-#include <inttypes.h>
#include <stdlib.h>
+#include <cinttypes>
+
#include "perfetto/ext/base/utils.h"
#include "perfetto/heap_profile.h"
#include "src/profiling/memory/wrap_allocators.h"
diff --git a/src/profiling/memory/wrap_allocators.h b/src/profiling/memory/wrap_allocators.h
index ce9fb3e20..0d5a982c4 100644
--- a/src/profiling/memory/wrap_allocators.h
+++ b/src/profiling/memory/wrap_allocators.h
@@ -17,9 +17,10 @@
#ifndef SRC_PROFILING_MEMORY_WRAP_ALLOCATORS_H_
#define SRC_PROFILING_MEMORY_WRAP_ALLOCATORS_H_
-#include <inttypes.h>
#include <stdlib.h>
+#include <cinttypes>
+
namespace perfetto {
namespace profiling {
diff --git a/src/profiling/perf/BUILD.gn b/src/profiling/perf/BUILD.gn
index 899e09c77..341bd3a1b 100644
--- a/src/profiling/perf/BUILD.gn
+++ b/src/profiling/perf/BUILD.gn
@@ -51,7 +51,6 @@ source_set("producer") {
deps = [
":proc_descriptors",
"../../../gn:default_deps",
- "../../../include/perfetto/profiling:normalize",
"../../../protos/perfetto/common:cpp",
"../../../protos/perfetto/common:zero",
"../../../protos/perfetto/config:cpp",
@@ -65,7 +64,7 @@ source_set("producer") {
"../common:callstack_trie",
"../common:interner",
"../common:interning_output",
- "../common:proc_utils",
+ "../common:proc_cmdline",
"../common:producer_support",
"../common:profiler_guardrails",
]
diff --git a/src/profiling/perf/event_config.cc b/src/profiling/perf/event_config.cc
index a7b6533f0..8506a1c55 100644
--- a/src/profiling/perf/event_config.cc
+++ b/src/profiling/perf/event_config.cc
@@ -25,7 +25,6 @@
#include "perfetto/base/flat_set.h"
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/utils.h"
-#include "perfetto/profiling/normalize.h"
#include "src/profiling/perf/regs_parsing.h"
#include "protos/perfetto/common/perf_events.gen.h"
@@ -40,23 +39,6 @@ constexpr uint32_t kDefaultDataPagesPerRingBuffer = 256; // 1 MB: 256x 4k pages
constexpr uint32_t kDefaultReadTickPeriodMs = 100;
constexpr uint32_t kDefaultRemoteDescriptorTimeoutMs = 100;
-base::Optional<std::string> Normalize(const std::string& src) {
- // Construct a null-terminated string that will be mutated by the normalizer.
- std::vector<char> base(src.size() + 1);
- memcpy(base.data(), src.data(), src.size());
- base[src.size()] = '\0';
-
- char* new_start = base.data();
- ssize_t new_sz = NormalizeCmdLine(&new_start, base.size());
- if (new_sz < 0) {
- PERFETTO_ELOG("Failed to normalize config cmdline [%s], aborting",
- base.data());
- return base::nullopt;
- }
- return base::make_optional<std::string>(new_start,
- static_cast<size_t>(new_sz));
-}
-
// Acceptable forms: "sched/sched_switch" or "sched:sched_switch".
std::pair<std::string, std::string> SplitTracepointString(
const std::string& input) {
@@ -100,40 +82,29 @@ base::Optional<uint32_t> ParseTracepointAndResolveId(
return base::make_optional(tracepoint_id);
}
-// Returns |base::nullopt| if any of the input cmdlines couldn't be normalized.
// |T| is either gen::PerfEventConfig or gen::PerfEventConfig::Scope.
+// Note: the semantics of target_cmdline and exclude_cmdline were changed since
+// their original introduction. They used to be put through a canonicalization
+// function that simplified them to the binary name alone. We no longer do this,
+// regardless of whether we're parsing an old-style config. The overall outcome
+// shouldn't change for almost all existing uses.
template <typename T>
-base::Optional<TargetFilter> ParseTargetFilter(const T& cfg) {
+TargetFilter ParseTargetFilter(const T& cfg) {
TargetFilter filter;
for (const auto& str : cfg.target_cmdline()) {
- base::Optional<std::string> opt = Normalize(str);
- if (!opt.has_value()) {
- PERFETTO_ELOG("Failure normalizing cmdline: [%s]", str.c_str());
- return base::nullopt;
- }
- filter.cmdlines.insert(std::move(opt.value()));
+ filter.cmdlines.push_back(str);
}
-
for (const auto& str : cfg.exclude_cmdline()) {
- base::Optional<std::string> opt = Normalize(str);
- if (!opt.has_value()) {
- PERFETTO_ELOG("Failure normalizing cmdline: [%s]", str.c_str());
- return base::nullopt;
- }
- filter.exclude_cmdlines.insert(std::move(opt.value()));
+ filter.exclude_cmdlines.push_back(str);
}
-
for (const int32_t pid : cfg.target_pid()) {
filter.pids.insert(pid);
}
-
for (const int32_t pid : cfg.exclude_pid()) {
filter.exclude_pids.insert(pid);
}
-
filter.additional_cmdline_count = cfg.additional_cmdline_count();
-
- return base::make_optional(std::move(filter));
+ return filter;
}
constexpr bool IsPowerOfTwo(size_t v) {
@@ -156,23 +127,91 @@ base::Optional<uint32_t> ChooseActualRingBufferPages(uint32_t config_value) {
}
base::Optional<PerfCounter> ToPerfCounter(
+ std::string name,
protos::gen::PerfEvents::Counter pb_enum) {
using protos::gen::PerfEvents;
switch (static_cast<int>(pb_enum)) { // cast to pacify -Wswitch-enum
case PerfEvents::SW_CPU_CLOCK:
- return PerfCounter::Counter(PerfEvents::SW_CPU_CLOCK, PERF_TYPE_SOFTWARE,
- PERF_COUNT_SW_CPU_CLOCK);
+ return PerfCounter::BuiltinCounter(name, PerfEvents::SW_CPU_CLOCK,
+ PERF_TYPE_SOFTWARE,
+ PERF_COUNT_SW_CPU_CLOCK);
case PerfEvents::SW_PAGE_FAULTS:
- return PerfCounter::Counter(PerfEvents::SW_PAGE_FAULTS,
- PERF_TYPE_SOFTWARE,
- PERF_COUNT_SW_PAGE_FAULTS);
+ return PerfCounter::BuiltinCounter(name, PerfEvents::SW_PAGE_FAULTS,
+ PERF_TYPE_SOFTWARE,
+ PERF_COUNT_SW_PAGE_FAULTS);
+ case PerfEvents::SW_TASK_CLOCK:
+ return PerfCounter::BuiltinCounter(name, PerfEvents::SW_TASK_CLOCK,
+ PERF_TYPE_SOFTWARE,
+ PERF_COUNT_SW_TASK_CLOCK);
+ case PerfEvents::SW_CONTEXT_SWITCHES:
+ return PerfCounter::BuiltinCounter(name, PerfEvents::SW_CONTEXT_SWITCHES,
+ PERF_TYPE_SOFTWARE,
+ PERF_COUNT_SW_CONTEXT_SWITCHES);
+ case PerfEvents::SW_CPU_MIGRATIONS:
+ return PerfCounter::BuiltinCounter(name, PerfEvents::SW_CPU_MIGRATIONS,
+ PERF_TYPE_SOFTWARE,
+ PERF_COUNT_SW_CPU_MIGRATIONS);
+ case PerfEvents::SW_PAGE_FAULTS_MIN:
+ return PerfCounter::BuiltinCounter(name, PerfEvents::SW_PAGE_FAULTS_MIN,
+ PERF_TYPE_SOFTWARE,
+ PERF_COUNT_SW_PAGE_FAULTS_MIN);
+ case PerfEvents::SW_PAGE_FAULTS_MAJ:
+ return PerfCounter::BuiltinCounter(name, PerfEvents::SW_PAGE_FAULTS_MAJ,
+ PERF_TYPE_SOFTWARE,
+ PERF_COUNT_SW_PAGE_FAULTS_MAJ);
+ case PerfEvents::SW_ALIGNMENT_FAULTS:
+ return PerfCounter::BuiltinCounter(name, PerfEvents::SW_ALIGNMENT_FAULTS,
+ PERF_TYPE_SOFTWARE,
+ PERF_COUNT_SW_ALIGNMENT_FAULTS);
+ case PerfEvents::SW_EMULATION_FAULTS:
+ return PerfCounter::BuiltinCounter(name, PerfEvents::SW_EMULATION_FAULTS,
+ PERF_TYPE_SOFTWARE,
+ PERF_COUNT_SW_EMULATION_FAULTS);
+ case PerfEvents::SW_DUMMY:
+ return PerfCounter::BuiltinCounter(
+ name, PerfEvents::SW_DUMMY, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY);
+
case PerfEvents::HW_CPU_CYCLES:
- return PerfCounter::Counter(PerfEvents::HW_CPU_CYCLES, PERF_TYPE_HARDWARE,
- PERF_COUNT_HW_CPU_CYCLES);
+ return PerfCounter::BuiltinCounter(name, PerfEvents::HW_CPU_CYCLES,
+ PERF_TYPE_HARDWARE,
+ PERF_COUNT_HW_CPU_CYCLES);
case PerfEvents::HW_INSTRUCTIONS:
- return PerfCounter::Counter(PerfEvents::HW_INSTRUCTIONS,
- PERF_TYPE_HARDWARE,
- PERF_COUNT_HW_INSTRUCTIONS);
+ return PerfCounter::BuiltinCounter(name, PerfEvents::HW_INSTRUCTIONS,
+ PERF_TYPE_HARDWARE,
+ PERF_COUNT_HW_INSTRUCTIONS);
+ case PerfEvents::HW_CACHE_REFERENCES:
+ return PerfCounter::BuiltinCounter(name, PerfEvents::HW_CACHE_REFERENCES,
+ PERF_TYPE_HARDWARE,
+ PERF_COUNT_HW_CACHE_REFERENCES);
+ case PerfEvents::HW_CACHE_MISSES:
+ return PerfCounter::BuiltinCounter(name, PerfEvents::HW_CACHE_MISSES,
+ PERF_TYPE_HARDWARE,
+ PERF_COUNT_HW_CACHE_MISSES);
+ case PerfEvents::HW_BRANCH_INSTRUCTIONS:
+ return PerfCounter::BuiltinCounter(
+ name, PerfEvents::HW_BRANCH_INSTRUCTIONS, PERF_TYPE_HARDWARE,
+ PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
+ case PerfEvents::HW_BRANCH_MISSES:
+ return PerfCounter::BuiltinCounter(name, PerfEvents::HW_BRANCH_MISSES,
+ PERF_TYPE_HARDWARE,
+ PERF_COUNT_HW_BRANCH_MISSES);
+ case PerfEvents::HW_BUS_CYCLES:
+ return PerfCounter::BuiltinCounter(name, PerfEvents::HW_BUS_CYCLES,
+ PERF_TYPE_HARDWARE,
+ PERF_COUNT_HW_BUS_CYCLES);
+ case PerfEvents::HW_STALLED_CYCLES_FRONTEND:
+ return PerfCounter::BuiltinCounter(
+ name, PerfEvents::HW_STALLED_CYCLES_FRONTEND, PERF_TYPE_HARDWARE,
+ PERF_COUNT_HW_STALLED_CYCLES_FRONTEND);
+ case PerfEvents::HW_STALLED_CYCLES_BACKEND:
+ return PerfCounter::BuiltinCounter(
+ name, PerfEvents::HW_STALLED_CYCLES_BACKEND, PERF_TYPE_HARDWARE,
+ PERF_COUNT_HW_STALLED_CYCLES_BACKEND);
+ case PerfEvents::HW_REF_CPU_CYCLES:
+ return PerfCounter::BuiltinCounter(name, PerfEvents::HW_REF_CPU_CYCLES,
+ PERF_TYPE_HARDWARE,
+ PERF_COUNT_HW_REF_CPU_CYCLES);
+
default:
PERFETTO_ELOG("Unrecognised PerfEvents::Counter enum value: %zu",
static_cast<size_t>(pb_enum));
@@ -180,27 +219,74 @@ base::Optional<PerfCounter> ToPerfCounter(
}
}
+int32_t ToClockId(protos::gen::PerfEvents::PerfClock pb_enum) {
+ using protos::gen::PerfEvents;
+ switch (static_cast<int>(pb_enum)) { // cast to pacify -Wswitch-enum
+ case PerfEvents::PERF_CLOCK_REALTIME:
+ return CLOCK_REALTIME;
+ case PerfEvents::PERF_CLOCK_MONOTONIC:
+ return CLOCK_MONOTONIC;
+ case PerfEvents::PERF_CLOCK_MONOTONIC_RAW:
+ return CLOCK_MONOTONIC_RAW;
+ case PerfEvents::PERF_CLOCK_BOOTTIME:
+ return CLOCK_BOOTTIME;
+ // Default to a monotonic clock since it should be compatible with all types
+ // of events. Whereas boottime cannot be used with hardware events due to
+ // potential access within non-maskable interrupts.
+ default:
+ return CLOCK_MONOTONIC_RAW;
+ }
+}
+
} // namespace
// static
-PerfCounter PerfCounter::Counter(protos::gen::PerfEvents::Counter counter,
- uint32_t type,
- uint32_t config) {
+PerfCounter PerfCounter::BuiltinCounter(
+ std::string name,
+ protos::gen::PerfEvents::Counter counter,
+ uint32_t type,
+ uint64_t config) {
PerfCounter ret;
+ ret.type = PerfCounter::Type::kBuiltinCounter;
ret.counter = counter;
- ret.type = type;
- ret.config = config;
+ ret.name = std::move(name);
+
+ ret.attr_type = type;
+ ret.attr_config = config;
+ // none of the builtin counters require config1 and config2 at the moment
+ return ret;
+}
+
+// static
+PerfCounter PerfCounter::Tracepoint(std::string name,
+ std::string tracepoint_name,
+ std::string tracepoint_filter,
+ uint64_t id) {
+ PerfCounter ret;
+ ret.type = PerfCounter::Type::kTracepoint;
+ ret.tracepoint_name = std::move(tracepoint_name);
+ ret.tracepoint_filter = std::move(tracepoint_filter);
+ ret.name = std::move(name);
+
+ ret.attr_type = PERF_TYPE_TRACEPOINT;
+ ret.attr_config = id;
return ret;
}
// static
-PerfCounter PerfCounter::Tracepoint(
- protos::gen::PerfEvents::Tracepoint tracepoint,
- uint32_t id) {
+PerfCounter PerfCounter::RawEvent(std::string name,
+ uint32_t type,
+ uint64_t config,
+ uint64_t config1,
+ uint64_t config2) {
PerfCounter ret;
- ret.tracepoint = std::move(tracepoint);
- ret.type = PERF_TYPE_TRACEPOINT;
- ret.config = id;
+ ret.type = PerfCounter::Type::kRawEvent;
+ ret.name = std::move(name);
+
+ ret.attr_type = type;
+ ret.attr_config = config;
+ ret.attr_config1 = config1;
+ ret.attr_config2 = config2;
return ret;
}
@@ -237,8 +323,10 @@ base::Optional<EventConfig> EventConfig::Create(
// Timebase event. Default: CPU timer.
PerfCounter timebase_event;
+ std::string timebase_name = pb_config.timebase().name();
if (pb_config.timebase().has_counter()) {
- auto maybe_counter = ToPerfCounter(pb_config.timebase().counter());
+ auto maybe_counter =
+ ToPerfCounter(timebase_name, pb_config.timebase().counter());
if (!maybe_counter)
return base::nullopt;
timebase_event = *maybe_counter;
@@ -249,12 +337,18 @@ base::Optional<EventConfig> EventConfig::Create(
ParseTracepointAndResolveId(tracepoint_pb, tracepoint_id_lookup);
if (!maybe_id)
return base::nullopt;
- timebase_event = PerfCounter::Tracepoint(tracepoint_pb, *maybe_id);
+ timebase_event = PerfCounter::Tracepoint(
+ timebase_name, tracepoint_pb.name(), tracepoint_pb.filter(), *maybe_id);
+
+ } else if (pb_config.timebase().has_raw_event()) {
+ const auto& raw = pb_config.timebase().raw_event();
+ timebase_event = PerfCounter::RawEvent(
+ timebase_name, raw.type(), raw.config(), raw.config1(), raw.config2());
} else {
- timebase_event =
- PerfCounter::Counter(protos::gen::PerfEvents::PerfEvents::SW_CPU_CLOCK,
- PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK);
+ timebase_event = PerfCounter::BuiltinCounter(
+ timebase_name, protos::gen::PerfEvents::PerfEvents::SW_CPU_CLOCK,
+ PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK);
}
// Callstack sampling.
@@ -266,14 +360,10 @@ base::Optional<EventConfig> EventConfig::Create(
sample_callstacks = true;
// Process scoping.
- auto maybe_filter =
+ target_filter =
pb_config.callstack_sampling().has_scope()
? ParseTargetFilter(pb_config.callstack_sampling().scope())
: ParseTargetFilter(pb_config); // backwards compatibility
- if (!maybe_filter.has_value())
- return base::nullopt;
-
- target_filter = std::move(maybe_filter.value());
// Inclusion of kernel callchains.
kernel_frames = pb_config.callstack_sampling().kernel_frames() ||
@@ -298,7 +388,7 @@ base::Optional<EventConfig> EventConfig::Create(
// expected = rate * period, with a conversion of period from ms to s:
uint64_t expected_samples_per_tick =
1 + (sampling_frequency * read_tick_period_ms) / 1000;
- // Double the the limit to account of actual sample rate uncertainties, as
+ // Double the limit to account of actual sample rate uncertainties, as
// well as any other factors:
samples_per_tick_limit = 2 * expected_samples_per_tick;
} else { // sampling_period
@@ -332,8 +422,10 @@ base::Optional<EventConfig> EventConfig::Create(
pe.disabled = 1; // will be activated via ioctl
// Sampling timebase.
- pe.type = timebase_event.type;
- pe.config = timebase_event.config;
+ pe.type = timebase_event.attr_type;
+ pe.config = timebase_event.attr_config;
+ pe.config1 = timebase_event.attr_config1;
+ pe.config2 = timebase_event.attr_config2;
if (sampling_frequency) {
pe.freq = true;
pe.sample_freq = sampling_frequency;
@@ -344,9 +436,7 @@ base::Optional<EventConfig> EventConfig::Create(
// What the samples will contain.
pe.sample_type = PERF_SAMPLE_TID | PERF_SAMPLE_TIME | PERF_SAMPLE_READ;
// PERF_SAMPLE_TIME:
- // We used to use CLOCK_BOOTTIME, but that is not nmi-safe, and therefore
- // works only for software events.
- pe.clockid = CLOCK_MONOTONIC_RAW;
+ pe.clockid = ToClockId(pb_config.timebase().timestamp_clock());
pe.use_clockid = true;
if (sample_callstacks) {
diff --git a/src/profiling/perf/event_config.h b/src/profiling/perf/event_config.h
index d75c7c8ca..cb841687b 100644
--- a/src/profiling/perf/event_config.h
+++ b/src/profiling/perf/event_config.h
@@ -17,11 +17,11 @@
#ifndef SRC_PROFILING_PERF_EVENT_CONFIG_H_
#define SRC_PROFILING_PERF_EVENT_CONFIG_H_
+#include <cinttypes>
#include <functional>
#include <string>
#include <vector>
-#include <inttypes.h>
#include <linux/perf_event.h>
#include <stdint.h>
#include <sys/types.h>
@@ -44,34 +44,61 @@ namespace profiling {
// Parsed allow/deny-list for filtering samples.
// An empty filter set means that all targets are allowed.
struct TargetFilter {
- base::FlatSet<std::string> cmdlines;
- base::FlatSet<std::string> exclude_cmdlines;
+ std::vector<std::string> cmdlines;
+ std::vector<std::string> exclude_cmdlines;
base::FlatSet<pid_t> pids;
base::FlatSet<pid_t> exclude_pids;
uint32_t additional_cmdline_count = 0;
};
+// Describes a perf event for two purposes:
+// * encoding the event in the perf_event_open syscall
+// * echoing the counter's config in the trace packet defaults, so that the
+// parser can tell which datastream belongs to which counter.
+// Note: It's slightly odd to decode & pass around values we don't use outside
+// of reencoding back into a defaults proto. One option would be to carry the
+// Timebase proto, but this won't fit with the eventual support of multiple
+// counters, as at the proto level it'll be a distinct message from Timebase.
struct PerfCounter {
- // Either a predefined counter, or a tracepoint:
- protos::gen::PerfEvents::Counter counter =
- protos::gen::PerfEvents::PerfEvents::UNKNOWN_COUNTER;
- protos::gen::PerfEvents::Tracepoint tracepoint;
-
- // sycall-level description of the event:
- uint32_t type = 0; // perf_event_attr.type
- uint32_t config = 0; // perf_event_attr.config
+ enum class Type { kBuiltinCounter, kTracepoint, kRawEvent };
- bool is_counter() const {
- return counter != protos::gen::PerfEvents::PerfEvents::UNKNOWN_COUNTER;
- }
- bool is_tracepoint() const { return type == PERF_TYPE_TRACEPOINT; }
+ Type type = Type::kBuiltinCounter;
- static PerfCounter Counter(protos::gen::PerfEvents::Counter counter,
- uint32_t type,
- uint32_t config);
+ // Optional config-supplied name for the counter, to identify it during
+ // trace parsing, does not affect the syscall.
+ std::string name;
- static PerfCounter Tracepoint(protos::gen::PerfEvents::Tracepoint tracepoint,
- uint32_t id);
+ // valid if kBuiltinCounter
+ protos::gen::PerfEvents::Counter counter =
+ protos::gen::PerfEvents::PerfEvents::UNKNOWN_COUNTER;
+ // valid if kTracepoint. Example: "sched:sched_switch".
+ std::string tracepoint_name;
+ // valid if kTracepoint
+ std::string tracepoint_filter;
+
+ // sycall-level description of the event (perf_event_attr):
+ uint32_t attr_type = 0;
+ uint64_t attr_config = 0;
+ uint64_t attr_config1 = 0; // optional extension
+ uint64_t attr_config2 = 0; // optional extension
+
+ Type event_type() const { return type; }
+
+ static PerfCounter BuiltinCounter(std::string name,
+ protos::gen::PerfEvents::Counter counter,
+ uint32_t type,
+ uint64_t config);
+
+ static PerfCounter Tracepoint(std::string name,
+ std::string tracepoint_name,
+ std::string tracepoint_filter,
+ uint64_t id);
+
+ static PerfCounter RawEvent(std::string name,
+ uint32_t type,
+ uint64_t config,
+ uint64_t config1,
+ uint64_t config2);
};
// Describes a single profiling configuration. Bridges the gap between the data
@@ -171,9 +198,9 @@ class EventConfig {
// Only profile target if it was installed by one of the packages given.
// Special values are:
- // * @system: installed on the system partition
- // * @product: installed on the product partition
- // * @null: sideloaded
+ // * "@system": installed on the system partition
+ // * "@product": installed on the product partition
+ // * "@null": sideloaded
const std::vector<std::string> target_installed_by_;
// The raw data source config, as a pbzero-generated C++ class.
diff --git a/src/profiling/perf/event_config_unittest.cc b/src/profiling/perf/event_config_unittest.cc
index c69d45d0e..801d8ea6b 100644
--- a/src/profiling/perf/event_config_unittest.cc
+++ b/src/profiling/perf/event_config_unittest.cc
@@ -18,6 +18,7 @@
#include <linux/perf_event.h>
#include <stdint.h>
+#include <time.h>
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/optional.h"
@@ -318,15 +319,50 @@ TEST(EventConfigTest, CallstackSamplingModeDetection) {
EventConfig::Create(AsDataSourceConfig(cfg));
ASSERT_TRUE(event_config.has_value());
- EXPECT_EQ(event_config->perf_attr()->sample_type &
- (PERF_SAMPLE_STACK_USER | PERF_SAMPLE_REGS_USER),
- PERF_SAMPLE_STACK_USER | PERF_SAMPLE_REGS_USER);
+ EXPECT_EQ(
+ event_config->perf_attr()->sample_type &
+ (PERF_SAMPLE_STACK_USER | PERF_SAMPLE_REGS_USER),
+ static_cast<uint64_t>(PERF_SAMPLE_STACK_USER | PERF_SAMPLE_REGS_USER));
EXPECT_NE(event_config->perf_attr()->sample_regs_user, 0u);
EXPECT_NE(event_config->perf_attr()->sample_stack_user, 0u);
}
}
+TEST(EventConfigTest, TimestampClockId) {
+ { // if unset, a default is used
+ protos::gen::PerfEventConfig cfg;
+ base::Optional<EventConfig> event_config =
+ EventConfig::Create(AsDataSourceConfig(cfg));
+
+ ASSERT_TRUE(event_config.has_value());
+ EXPECT_TRUE(event_config->perf_attr()->use_clockid);
+ EXPECT_EQ(event_config->perf_attr()->clockid, CLOCK_MONOTONIC_RAW);
+ }
+ { // explicit boottime
+ protos::gen::PerfEventConfig cfg;
+ cfg.mutable_timebase()->set_timestamp_clock(
+ protos::gen::PerfEvents::PERF_CLOCK_BOOTTIME);
+ base::Optional<EventConfig> event_config =
+ EventConfig::Create(AsDataSourceConfig(cfg));
+
+ ASSERT_TRUE(event_config.has_value());
+ EXPECT_TRUE(event_config->perf_attr()->use_clockid);
+ EXPECT_EQ(event_config->perf_attr()->clockid, CLOCK_BOOTTIME);
+ }
+ { // explicit monotonic
+ protos::gen::PerfEventConfig cfg;
+ cfg.mutable_timebase()->set_timestamp_clock(
+ protos::gen::PerfEvents::PERF_CLOCK_MONOTONIC);
+ base::Optional<EventConfig> event_config =
+ EventConfig::Create(AsDataSourceConfig(cfg));
+
+ ASSERT_TRUE(event_config.has_value());
+ EXPECT_TRUE(event_config->perf_attr()->use_clockid);
+ EXPECT_EQ(event_config->perf_attr()->clockid, CLOCK_MONOTONIC);
+ }
+}
+
} // namespace
} // namespace profiling
} // namespace perfetto
diff --git a/src/profiling/perf/event_reader.cc b/src/profiling/perf/event_reader.cc
index 039afa38d..3c6271a8e 100644
--- a/src/profiling/perf/event_reader.cc
+++ b/src/profiling/perf/event_reader.cc
@@ -68,13 +68,15 @@ base::ScopedFile PerfEventOpen(uint32_t cpu,
// If counting tracepoints, set an event filter if requested.
bool MaybeApplyTracepointFilter(int fd, const PerfCounter& event) {
- if (event.type == PERF_TYPE_TRACEPOINT &&
- !event.tracepoint.filter().empty()) {
- if (ioctl(fd, PERF_EVENT_IOC_SET_FILTER,
- event.tracepoint.filter().c_str()) != 0) {
- PERFETTO_PLOG("Failed ioctl to set event filter");
- return false;
- }
+ if (event.type != PerfCounter::Type::kTracepoint ||
+ event.tracepoint_filter.empty()) {
+ return true;
+ }
+ PERFETTO_DCHECK(event.attr_type == PERF_TYPE_TRACEPOINT);
+
+ if (ioctl(fd, PERF_EVENT_IOC_SET_FILTER, event.tracepoint_filter.c_str())) {
+ PERFETTO_PLOG("Failed ioctl to set event filter");
+ return false;
}
return true;
}
@@ -133,7 +135,9 @@ base::Optional<PerfRingBuffer> PerfRingBuffer::Allocate(
ret.metadata_page_ = reinterpret_cast<perf_event_mmap_page*>(mmap_addr);
ret.data_buf_ = reinterpret_cast<char*>(mmap_addr) + base::kPageSize;
PERFETTO_CHECK(ret.metadata_page_->data_offset == base::kPageSize);
- PERFETTO_CHECK(ret.metadata_page_->data_size = ret.data_buf_sz_);
+ PERFETTO_CHECK(ret.metadata_page_->data_size == ret.data_buf_sz_);
+
+ PERFETTO_DCHECK(IsPowerOfTwo(ret.data_buf_sz_));
return base::make_optional(std::move(ret));
}
@@ -176,8 +180,6 @@ char* PerfRingBuffer::ReadRecordNonconsuming() {
// event wrapped - reconstruct it, and return a pointer to the buffer
if (read_pos + evt_size > data_buf_sz_) {
- PERFETTO_DCHECK(read_pos + evt_size !=
- ((read_pos + evt_size) & (data_buf_sz_ - 1)));
PERFETTO_DLOG("PerfRingBuffer: returning reconstructed event");
size_t prefix_sz = data_buf_sz_ - read_pos;
@@ -187,9 +189,6 @@ char* PerfRingBuffer::ReadRecordNonconsuming() {
return &reconstructed_record_[0];
} else {
// usual case - contiguous sample
- PERFETTO_DCHECK(read_pos + evt_size ==
- ((read_pos + evt_size) & (data_buf_sz_ - 1)));
-
return data_buf_ + read_pos;
}
}
diff --git a/src/profiling/perf/perf_producer.cc b/src/profiling/perf/perf_producer.cc
index b1c7e1f27..858288507 100644
--- a/src/profiling/perf/perf_producer.cc
+++ b/src/profiling/perf/perf_producer.cc
@@ -36,7 +36,7 @@
#include "perfetto/tracing/core/data_source_config.h"
#include "perfetto/tracing/core/data_source_descriptor.h"
#include "src/profiling/common/callstack_trie.h"
-#include "src/profiling/common/proc_utils.h"
+#include "src/profiling/common/proc_cmdline.h"
#include "src/profiling/common/producer_support.h"
#include "src/profiling/common/profiler_guardrails.h"
#include "src/profiling/common/unwind_support.h"
@@ -68,7 +68,7 @@ namespace {
// The proper fix is in the platform, see bug for progress.
constexpr uint32_t kProcDescriptorsAndroidDelayMs = 50;
-constexpr uint32_t kMemoryLimitCheckPeriodMs = 5 * 1000;
+constexpr uint32_t kMemoryLimitCheckPeriodMs = 1000;
constexpr uint32_t kInitialConnectionBackoffMs = 100;
constexpr uint32_t kMaxConnectionBackoffMs = 30 * 1000;
@@ -80,6 +80,23 @@ size_t NumberOfCpus() {
return static_cast<size_t>(sysconf(_SC_NPROCESSORS_CONF));
}
+int32_t ToBuiltinClock(int32_t clockid) {
+ switch (clockid) {
+ case CLOCK_REALTIME:
+ return protos::pbzero::BUILTIN_CLOCK_REALTIME;
+ case CLOCK_MONOTONIC:
+ return protos::pbzero::BUILTIN_CLOCK_MONOTONIC;
+ case CLOCK_MONOTONIC_RAW:
+ return protos::pbzero::BUILTIN_CLOCK_MONOTONIC_RAW;
+ case CLOCK_BOOTTIME:
+ return protos::pbzero::BUILTIN_CLOCK_BOOTTIME;
+ // Should never get invalid input here as otherwise the syscall itself
+ // would've failed earlier.
+ default:
+ return protos::pbzero::BUILTIN_CLOCK_UNKNOWN;
+ }
+}
+
TraceWriter::TracePacketHandle StartTracePacket(TraceWriter* trace_writer) {
auto packet = trace_writer->NewTracePacket();
packet->set_sequence_flags(
@@ -97,16 +114,16 @@ void WritePerfEventDefaultsPacket(const EventConfig& event_config,
packet->set_sequence_flags(
protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED);
- // default packet timestamp clockid:
+ // default packet timestamp clock for the samples:
+ perf_event_attr* perf_attr = event_config.perf_attr();
auto* defaults = packet->set_trace_packet_defaults();
- defaults->set_timestamp_clock_id(protos::pbzero::BUILTIN_CLOCK_MONOTONIC_RAW);
- PERFETTO_DCHECK(event_config.perf_attr()->clockid == CLOCK_MONOTONIC_RAW);
+ int32_t builtin_clock = ToBuiltinClock(perf_attr->clockid);
+ defaults->set_timestamp_clock_id(static_cast<uint32_t>(builtin_clock));
auto* perf_defaults = defaults->set_perf_sample_defaults();
auto* timebase_pb = perf_defaults->set_timebase();
// frequency/period:
- perf_event_attr* perf_attr = event_config.perf_attr();
if (perf_attr->freq) {
timebase_pb->set_frequency(perf_attr->sample_freq);
} else {
@@ -115,17 +132,35 @@ void WritePerfEventDefaultsPacket(const EventConfig& event_config,
// event:
const PerfCounter& timebase = event_config.timebase_event();
- if (timebase.is_counter()) {
- timebase_pb->set_counter(
- static_cast<protos::pbzero::PerfEvents::Counter>(timebase.counter));
- } else {
- PERFETTO_DCHECK(timebase.is_tracepoint());
- // TODO(rsavitski): reconsider using a struct with two strings instead
- // of the ::gen::Tracepoint class in the C++ code.
- auto* tracepoint_pb = timebase_pb->set_tracepoint();
- tracepoint_pb->set_name(timebase.tracepoint.name());
- tracepoint_pb->set_filter(timebase.tracepoint.filter());
+ switch (timebase.event_type()) {
+ case PerfCounter::Type::kBuiltinCounter: {
+ timebase_pb->set_counter(
+ static_cast<protos::pbzero::PerfEvents::Counter>(timebase.counter));
+ break;
+ }
+ case PerfCounter::Type::kTracepoint: {
+ auto* tracepoint_pb = timebase_pb->set_tracepoint();
+ tracepoint_pb->set_name(timebase.tracepoint_name);
+ tracepoint_pb->set_filter(timebase.tracepoint_filter);
+ break;
+ }
+ case PerfCounter::Type::kRawEvent: {
+ auto* raw_pb = timebase_pb->set_raw_event();
+ raw_pb->set_type(timebase.attr_type);
+ raw_pb->set_config(timebase.attr_config);
+ raw_pb->set_config1(timebase.attr_config1);
+ raw_pb->set_config2(timebase.attr_config2);
+ break;
+ }
}
+
+ // optional name to identify the counter during parsing:
+ if (!timebase.name.empty()) {
+ timebase_pb->set_name(timebase.name);
+ }
+
+ // Not setting timebase.timestamp_clock since the field that matters during
+ // parsing is the root timestamp_clock_id set above.
}
uint32_t TimeToNextReadTickMs(DataSourceInstanceID ds_id, uint32_t period_ms) {
@@ -145,14 +180,27 @@ bool ShouldRejectDueToFilter(pid_t pid,
base::FlatSet<std::string>* additional_cmdlines,
const TargetFilter& filter) {
PERFETTO_CHECK(additional_cmdlines);
+
std::string cmdline;
- bool have_cmdline = GetCmdlineForPID(pid, &cmdline); // normalized form
- if (!have_cmdline) {
- PERFETTO_DLOG("Failed to look up cmdline for pid [%d]",
- static_cast<int>(pid));
+ bool have_cmdline = glob_aware::ReadProcCmdlineForPID(pid, &cmdline);
+
+ const char* binname = "";
+ if (have_cmdline) {
+ binname = glob_aware::FindBinaryName(cmdline.c_str(), cmdline.size());
}
- if (have_cmdline && filter.exclude_cmdlines.count(cmdline)) {
+ auto has_matching_pattern = [](const std::vector<std::string>& patterns,
+ const char* cmd, const char* name) {
+ for (const std::string& pattern : patterns) {
+ if (glob_aware::MatchGlobPattern(pattern.c_str(), cmd, name)) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+ if (have_cmdline &&
+ has_matching_pattern(filter.exclude_cmdlines, cmdline.c_str(), binname)) {
PERFETTO_DLOG("Explicitly rejecting samples for pid [%d] due to cmdline",
static_cast<int>(pid));
return true;
@@ -163,20 +211,21 @@ bool ShouldRejectDueToFilter(pid_t pid,
return true;
}
- if (have_cmdline && filter.cmdlines.count(cmdline)) {
+ if (have_cmdline &&
+ has_matching_pattern(filter.cmdlines, cmdline.c_str(), binname)) {
return false;
}
if (filter.pids.count(pid)) {
return false;
}
+
+ // Empty allow filter means keep everything that isn't explicitly excluded.
if (filter.cmdlines.empty() && filter.pids.empty() &&
!filter.additional_cmdline_count) {
- // If no filters are set allow everything.
return false;
}
- // If we didn't read the command line that's a good prediction we will not be
- // able to profile either.
+ // Config option that allows to profile just the N first seen cmdlines.
if (have_cmdline) {
if (additional_cmdlines->count(cmdline)) {
return false;
@@ -235,6 +284,12 @@ protos::pbzero::Profiling::StackUnwindError ToProtoEnum(
return Profiling::UNWIND_ERROR_THREAD_TIMEOUT;
case unwindstack::ERROR_THREAD_DOES_NOT_EXIST:
return Profiling::UNWIND_ERROR_THREAD_DOES_NOT_EXIST;
+ case unwindstack::ERROR_BAD_ARCH:
+ return Profiling::UNWIND_ERROR_BAD_ARCH;
+ case unwindstack::ERROR_MAPS_PARSE:
+ return Profiling::UNWIND_ERROR_MAPS_PARSE;
+ case unwindstack::ERROR_INVALID_PARAMETER:
+ return Profiling::UNWIND_ERROR_INVALID_PARAMETER;
}
return Profiling::UNWIND_ERROR_UNKNOWN;
}
diff --git a/src/profiling/perf/proc_descriptors.cc b/src/profiling/perf/proc_descriptors.cc
index b03d5d04c..066cf18f4 100644
--- a/src/profiling/perf/proc_descriptors.cc
+++ b/src/profiling/perf/proc_descriptors.cc
@@ -21,6 +21,8 @@
#include <sys/stat.h>
#include <unistd.h>
+#include "perfetto/ext/base/string_utils.h"
+
namespace perfetto {
ProcDescriptorDelegate::~ProcDescriptorDelegate() {}
@@ -36,20 +38,19 @@ void DirectDescriptorGetter::SetDelegate(ProcDescriptorDelegate* delegate) {
}
void DirectDescriptorGetter::GetDescriptorsForPid(pid_t pid) {
- char dir_buf[128] = {};
- snprintf(dir_buf, sizeof(dir_buf), "/proc/%d", pid);
- auto dir_fd =
- base::ScopedFile(open(dir_buf, O_DIRECTORY | O_RDONLY | O_CLOEXEC));
+ base::StackString<128> dir_buf("/proc/%d", pid);
+ auto dir_fd = base::ScopedFile(
+ open(dir_buf.c_str(), O_DIRECTORY | O_RDONLY | O_CLOEXEC));
if (!dir_fd) {
if (errno != ENOENT) // not surprising if the process has quit
- PERFETTO_PLOG("Failed to open [%s]", dir_buf);
+ PERFETTO_PLOG("Failed to open [%s]", dir_buf.c_str());
return;
}
struct stat stat_buf;
if (fstat(dir_fd.get(), &stat_buf) == -1) {
- PERFETTO_PLOG("Failed to stat [%s]", dir_buf);
+ PERFETTO_PLOG("Failed to stat [%s]", dir_buf.c_str());
return;
}
@@ -57,7 +58,7 @@ void DirectDescriptorGetter::GetDescriptorsForPid(pid_t pid) {
base::ScopedFile{openat(dir_fd.get(), "maps", O_RDONLY | O_CLOEXEC)};
if (!maps_fd) {
if (errno != ENOENT) // not surprising if the process has quit
- PERFETTO_PLOG("Failed to open %s/maps", dir_buf);
+ PERFETTO_PLOG("Failed to open %s/maps", dir_buf.c_str());
return;
}
@@ -66,7 +67,7 @@ void DirectDescriptorGetter::GetDescriptorsForPid(pid_t pid) {
base::ScopedFile{openat(dir_fd.get(), "mem", O_RDONLY | O_CLOEXEC)};
if (!mem_fd) {
if (errno != ENOENT) // not surprising if the process has quit
- PERFETTO_PLOG("Failed to open %s/mem", dir_buf);
+ PERFETTO_PLOG("Failed to open %s/mem", dir_buf.c_str());
return;
}
diff --git a/src/profiling/perf/regs_parsing.cc b/src/profiling/perf/regs_parsing.cc
index 75c1a75db..99bed4237 100644
--- a/src/profiling/perf/regs_parsing.cc
+++ b/src/profiling/perf/regs_parsing.cc
@@ -16,10 +16,11 @@
#include "src/profiling/perf/regs_parsing.h"
-#include <inttypes.h>
#include <linux/perf_event.h>
#include <stdint.h>
#include <unistd.h>
+
+#include <cinttypes>
#include <memory>
#include <unwindstack/Elf.h>
diff --git a/src/profiling/perf/unwinding.cc b/src/profiling/perf/unwinding.cc
index 46dfc6bdb..65678ffc6 100644
--- a/src/profiling/perf/unwinding.cc
+++ b/src/profiling/perf/unwinding.cc
@@ -16,13 +16,13 @@
#include "src/profiling/perf/unwinding.h"
+#include <cinttypes>
#include <mutex>
-#include <inttypes.h>
-
#include <unwindstack/Unwinder.h>
#include "perfetto/ext/base/metatrace.h"
+#include "perfetto/ext/base/no_destructor.h"
#include "perfetto/ext/base/thread_utils.h"
#include "perfetto/ext/base/utils.h"
@@ -406,7 +406,6 @@ CompletedSample Unwinder::UnwindSample(const ParsedSample& sample,
unwindstack::FrameData frame_data{};
frame_data.function_name =
"ERROR " + StringifyLibUnwindstackError(unwind.error_code);
- frame_data.map_name = "ERROR";
ret.frames.emplace_back(std::move(frame_data));
ret.build_ids.emplace_back("");
ret.unwind_error = unwind.error_code;
@@ -417,6 +416,8 @@ CompletedSample Unwinder::UnwindSample(const ParsedSample& sample,
std::vector<unwindstack::FrameData> Unwinder::SymbolizeKernelCallchain(
const ParsedSample& sample) {
+ static base::NoDestructor<std::shared_ptr<unwindstack::MapInfo>> kernel_map_info(
+ unwindstack::MapInfo::Create(0, 0, 0, 0, "kernel"));
std::vector<unwindstack::FrameData> ret;
if (sample.kernel_ips.empty())
return ret;
@@ -439,10 +440,10 @@ std::vector<unwindstack::FrameData> Unwinder::SymbolizeKernelCallchain(
// Synthesise a partially-valid libunwindstack frame struct for the kernel
// frame. We reuse the type for convenience. The kernel frames are marked by
- // a magical "kernel" string as their containing mapping.
+ // a magical "kernel" MapInfo object as their containing mapping.
unwindstack::FrameData frame{};
frame.function_name = std::move(function_name);
- frame.map_name = "kernel";
+ frame.map_info = kernel_map_info.ref();
ret.emplace_back(std::move(frame));
}
return ret;
diff --git a/src/profiling/symbolizer/BUILD.gn b/src/profiling/symbolizer/BUILD.gn
index 6989d0ab3..70dc0917a 100644
--- a/src/profiling/symbolizer/BUILD.gn
+++ b/src/profiling/symbolizer/BUILD.gn
@@ -19,9 +19,11 @@ source_set("symbolizer") {
public_deps = [ "../../../include/perfetto/ext/base" ]
deps = [ "../../../gn:default_deps" ]
sources = [
- "filesystem.h",
- "filesystem_posix.cc",
- "filesystem_windows.cc",
+ "breakpad_parser.cc",
+ "breakpad_parser.h",
+ "breakpad_symbolizer.cc",
+ "breakpad_symbolizer.h",
+ "elf.h",
"local_symbolizer.cc",
"local_symbolizer.h",
"scoped_read_mmap.h",
@@ -61,5 +63,9 @@ perfetto_unittest_source_set("unittests") {
"../../../gn:gtest_and_gmock",
"../../base:test_support",
]
- sources = [ "local_symbolizer_unittest.cc" ]
+ sources = [
+ "breakpad_parser_unittest.cc",
+ "breakpad_symbolizer_unittest.cc",
+ "local_symbolizer_unittest.cc",
+ ]
}
diff --git a/src/profiling/symbolizer/breakpad_parser.cc b/src/profiling/symbolizer/breakpad_parser.cc
new file mode 100644
index 000000000..5c3c5c067
--- /dev/null
+++ b/src/profiling/symbolizer/breakpad_parser.cc
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <memory>
+
+#include "src/profiling/symbolizer/breakpad_parser.h"
+
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/string_splitter.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/string_writer.h"
+
+namespace perfetto {
+namespace profiling {
+
+namespace {
+
+bool SymbolComparator(const uint64_t i, const BreakpadParser::Symbol& sym) {
+ return i < sym.start_address;
+}
+
+base::Optional<std::string> GetFileContents(const std::string& file_path) {
+ std::string file_contents;
+ base::ScopedFile fd = base::OpenFile(file_path, O_RDONLY);
+ // Read the contents of the file into |file_contents|.
+ if (!fd) {
+ return base::nullopt;
+ }
+ if (!base::ReadFileDescriptor(fd.get(), &file_contents)) {
+ return base::nullopt;
+ }
+
+ return base::make_optional(std::move(file_contents));
+}
+
+// Parses the given string and determines if it begins with the label
+// 'MODULE'. Returns an ok status if it does begin with this label and a fail
+// status otherwise.
+base::Status ParseIfModuleRecord(base::StringView first_line) {
+ // Split the given line by spaces.
+ const char kModuleLabel[] = "MODULE";
+ // Check to see if the line starts with 'MODULE'.
+ if (!base::StartsWith(first_line.ToStdString(), kModuleLabel)) {
+ return base::Status("Breakpad file not formatted correctly.");
+ }
+ return base::OkStatus();
+}
+
+} // namespace
+
+BreakpadParser::BreakpadParser(const std::string& file_path)
+ : file_path_(file_path) {}
+
+bool BreakpadParser::ParseFile() {
+ base::Optional<std::string> file_contents = GetFileContents(file_path_);
+ if (!file_contents) {
+ PERFETTO_ELOG("Could not get file contents of %s.", file_path_.c_str());
+ return false;
+ }
+
+ // TODO(uwemwilson): Extract a build id and store it in the Symbol object.
+
+ if (!ParseFromString(*file_contents)) {
+ PERFETTO_ELOG("Could not parse file contents.");
+ return false;
+ }
+
+ return true;
+}
+
+bool BreakpadParser::ParseFromString(const std::string& file_contents) {
+ // Create StringSplitter objects for each line so that specific lines can be
+ // used to create StringSplitter objects for words on that line.
+ base::StringSplitter lines(file_contents, '\n');
+ if (!lines.Next()) {
+ // File must be empty, so just return true and continue.
+ return true;
+ }
+
+ // TODO(crbug/1239750): Extract a build id and store it in the Symbol object.
+ base::StringView first_line(lines.cur_token(), lines.cur_token_size());
+ base::Status parse_record_status = ParseIfModuleRecord(first_line);
+ if (!parse_record_status.ok()) {
+ PERFETTO_ELOG("%s Breakpad files should begin with a MODULE record",
+ parse_record_status.message().c_str());
+ return false;
+ }
+
+ // Parse each line.
+ while (lines.Next()) {
+ parse_record_status = ParseIfFuncRecord(lines.cur_token());
+ if (!parse_record_status.ok()) {
+ PERFETTO_ELOG("%s", parse_record_status.message().c_str());
+ return false;
+ }
+ }
+
+ return true;
+}
+
+base::Optional<std::string> BreakpadParser::GetSymbol(uint64_t address) const {
+ // Returns an iterator pointing to the first element where the symbol's start
+ // address is greater than |address|.
+ auto it = std::upper_bound(symbols_.begin(), symbols_.end(), address,
+ &SymbolComparator);
+ // If the first symbol's address is greater than |address| then |address| is
+ // too low to appear in |symbols_|.
+ if (it == symbols_.begin()) {
+ return base::nullopt;
+ }
+ // upper_bound() returns the first symbol who's start address is greater than
+ // |address|. Therefore to find the symbol with a range of addresses that
+ // |address| falls into, we check the previous symbol.
+ it--;
+ // Check to see if the address is in the function's range.
+ if (address >= it->start_address &&
+ address < it->start_address + it->function_size) {
+ return it->symbol_name;
+ }
+ return base::nullopt;
+}
+
+base::Status BreakpadParser::ParseIfFuncRecord(base::StringView current_line) {
+ // Parses a FUNC record from a file. Structure of a FUNC record:
+ // FUNC [m] address size parameter_size name
+ // m: The m field is optional. If present it indicates that multiple symbols
+ // reference this function's instructions. (In which case, only one symbol
+ // name is mentioned within the breakpad file.)
+ // address: The start address of the function relative to the module's load
+ // address.
+ // size: The length in bytes of function's instructions.
+ // parameter_size: A hexadecimal number indicating the size, in bytes, of the
+ // arguments pushed on the stack for this function.
+ // name: The function name. This field may contain spaces.
+ // More info at
+ // https://chromium.googlesource.com/breakpad/breakpad/+/HEAD/docs/symbol_files.md
+
+ const char kFuncLabel[] = "FUNC";
+ base::StringSplitter words(current_line.ToStdString(), ' ');
+ // Check to see if the first word indicates a FUNC record. If it is, create a
+ // Symbol struct and add tokens from words. If it isn't the function can just
+ // return true and resume parsing file.
+ if (!words.Next() || strcmp(words.cur_token(), kFuncLabel) != 0) {
+ return base::OkStatus();
+ }
+
+ Symbol new_symbol;
+ // There can be either 4 or 5 FUNC record tokens. The second token, 'm' is
+ // optional.
+ const char kOptionalArg[] = "m";
+ // Get the first argument on the line.
+ words.Next();
+
+ // If the optional argument is present, skip to the next token.
+ if (strcmp(words.cur_token(), kOptionalArg) == 0) {
+ words.Next();
+ }
+
+ // Get the start address.
+ base::Optional<uint64_t> optional_address =
+ base::CStringToUInt64(words.cur_token(), 16);
+ if (!optional_address) {
+ return base::Status("Address should be hexadecimal.");
+ }
+ new_symbol.start_address = *optional_address;
+
+ // Get the function size.
+ words.Next();
+ base::Optional<size_t> optional_func_size =
+ base::CStringToUInt32(words.cur_token(), 16);
+ if (!optional_func_size) {
+ return base::Status("Function size should be hexadecimal.");
+ }
+ new_symbol.function_size = *optional_func_size;
+
+ // Skip the parameter size.
+ words.Next();
+
+ // Get the function name. Function names can have spaces, so any token is now
+ // considered a part of the function name and will be appended to the buffer
+ // in |func_name_writer|.
+ std::unique_ptr<char[]> joined_string(new char[current_line.size()]);
+ base::StringWriter func_name_writer(joined_string.get(), current_line.size());
+ bool first_token = true;
+ while (words.Next()) {
+ if (!first_token) {
+ func_name_writer.AppendChar(' ');
+ } else {
+ first_token = false;
+ }
+ func_name_writer.AppendString(words.cur_token(), strlen(words.cur_token()));
+ }
+
+ new_symbol.symbol_name = func_name_writer.GetStringView().ToStdString();
+
+ symbols_.push_back(std::move(new_symbol));
+
+ return base::OkStatus();
+}
+
+} // namespace profiling
+} // namespace perfetto
diff --git a/src/profiling/symbolizer/breakpad_parser.h b/src/profiling/symbolizer/breakpad_parser.h
new file mode 100644
index 000000000..03773535d
--- /dev/null
+++ b/src/profiling/symbolizer/breakpad_parser.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_PROFILING_SYMBOLIZER_BREAKPAD_PARSER_H_
+#define SRC_PROFILING_SYMBOLIZER_BREAKPAD_PARSER_H_
+
+#include <string>
+#include <vector>
+
+#include "perfetto/base/status.h"
+#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/string_view.h"
+
+namespace perfetto {
+namespace profiling {
+
+// The BreakpadParser class is used to parse a breakpad file and store data on
+// symbols so that a given address can be used to query a symbol. The class is
+// instantiated with the |file_path| of the file to be parsed. Breakpad file
+// format:
+// https://chromium.googlesource.com/breakpad/breakpad/+/master/docs/symbol_files.md
+// Usage:
+//
+// BreakpadParser parser("file.breakpad");
+// parser.ParseFile();
+// std::string symbol = parser.GetSymbol(addr);
+class BreakpadParser {
+ public:
+ struct Symbol {
+ // The address where a function starts.
+ uint64_t start_address = 0;
+ // The length in bytes of the function's instructions.
+ size_t function_size = 0;
+ // The human-readable name for the function signature.
+ std::string symbol_name;
+ };
+
+ explicit BreakpadParser(const std::string& file_path);
+
+ BreakpadParser(const BreakpadParser& other) = delete;
+ BreakpadParser& operator=(const BreakpadParser& other) = delete;
+
+ // Fills in |symbols_| by parsing the breakpad file given.
+ // Returns true if it is able to parse the entire file specified by
+ // |file_path_|. Returns false if the parsing fails.
+ bool ParseFile();
+
+ // Parses from a string instead of a file.
+ bool ParseFromString(const std::string& file_contents);
+
+ // Returns the function name corresponding to |address| as a string. The
+ // search is log(N) on the number of functions in the binary. |address| is the
+ // relative offset from the start of the binary.
+ base::Optional<std::string> GetSymbol(uint64_t address) const;
+
+ const std::vector<Symbol>& symbols_for_testing() const { return symbols_; }
+
+ private:
+ // Parses the given string and creates a new Symbol object if it is a FUNC
+ // record. Returns an ok status if it was successfully able to add to the
+ // |symbols_| or if the string is not a FUNC record. Return a fail status on
+ // parsing errors on FUNC record.
+ base::Status ParseIfFuncRecord(base::StringView current_line);
+
+ std::vector<Symbol> symbols_;
+ const std::string file_path_;
+};
+
+} // namespace profiling
+} // namespace perfetto
+
+#endif // SRC_PROFILING_SYMBOLIZER_BREAKPAD_PARSER_H_
diff --git a/src/profiling/symbolizer/breakpad_parser_unittest.cc b/src/profiling/symbolizer/breakpad_parser_unittest.cc
new file mode 100644
index 000000000..d42b6daf3
--- /dev/null
+++ b/src/profiling/symbolizer/breakpad_parser_unittest.cc
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "test/gtest_and_gmock.h"
+
+#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/temp_file.h"
+#include "src/profiling/symbolizer/breakpad_parser.h"
+
+namespace perfetto {
+namespace profiling {
+
+namespace {
+
+// Used to initialize parser objects.
+constexpr char kFakeFilePath[] = "bad/file/path";
+
+TEST(BreakpadParserTest, FileIsEmpty) {
+ base::TempFile file = base::TempFile::Create();
+ BreakpadParser parser(file.path());
+ ASSERT_TRUE(parser.ParseFile());
+ EXPECT_TRUE(parser.symbols_for_testing().empty());
+}
+
+TEST(BreakpadParserTest, FileNotOpened) {
+ BreakpadParser parser(kFakeFilePath);
+ ASSERT_FALSE(parser.ParseFile());
+ EXPECT_TRUE(parser.symbols_for_testing().empty());
+}
+
+TEST(BreakpadParserTest, ContainsNoFuncRecord) {
+ BreakpadParser parser(kFakeFilePath);
+ constexpr char kTestFileContents[] =
+ "MODULE mac x86_64 E3A0F28FBCB43C15986D8608AF1DD2380 exif.so\n"
+ "FILE 0 /Applications/../MacOSX10.10.sdk/usr/include/ctype.h\n"
+ "1031 2 39 4\n"
+ "PUBLIC 313c0 0 items\n"
+ "STACK CFI 1014 .cfa: $rbp 16 +\n";
+ ASSERT_TRUE(parser.ParseFromString(kTestFileContents));
+ EXPECT_TRUE(parser.symbols_for_testing().empty());
+}
+
+TEST(BreakpadParserTest, ContainsOneFuncRecord) {
+ BreakpadParser parser(kFakeFilePath);
+ constexpr char kTestFileContents[] =
+ "MODULE mac x86_64 E3A0F28FBCB43C15986D8608AF1DD2380 exif.so\n"
+ "FUNC 1010 23 0 foo::bar()\n"
+ "1031 2 39 4\n"
+ "PUBLIC 2e7c0 0 items\n";
+ ASSERT_TRUE(parser.ParseFromString(kTestFileContents));
+ ASSERT_EQ(parser.symbols_for_testing().size(), 1u);
+ EXPECT_STREQ(parser.symbols_for_testing()[0].symbol_name.c_str(),
+ "foo::bar()");
+ EXPECT_EQ(parser.symbols_for_testing()[0].start_address,
+ static_cast<uint64_t>(0x1010));
+}
+
+TEST(BreakpadParserTest, ContainsManyFuncRecords) {
+ BreakpadParser parser(kFakeFilePath);
+ constexpr char kTestFileContents[] =
+ "MODULE mac x86_64 E3A0F28FBCB43C15986D8608AF1DD2380 exif.so\n"
+ "FUNC 1010 23 0 foo_foo\n"
+ "1031 2 39 4\n"
+ "FUNC 1040 84 0 bar_1\n"
+ "1040 4 44 5\n"
+ "FUNC 10d0 6b 0 baz_baz()\n";
+ ASSERT_TRUE(parser.ParseFromString(kTestFileContents));
+ ASSERT_EQ(parser.symbols_for_testing().size(), 3u);
+ EXPECT_STREQ(parser.symbols_for_testing()[0].symbol_name.c_str(), "foo_foo");
+ EXPECT_EQ(parser.symbols_for_testing()[0].start_address,
+ static_cast<uint64_t>(0x1010));
+ EXPECT_EQ(parser.symbols_for_testing()[0].function_size, 35u);
+ EXPECT_STREQ(parser.symbols_for_testing()[1].symbol_name.c_str(), "bar_1");
+ EXPECT_EQ(parser.symbols_for_testing()[1].start_address,
+ static_cast<uint64_t>(0x1040));
+ EXPECT_EQ(parser.symbols_for_testing()[1].function_size, 132u);
+ EXPECT_STREQ(parser.symbols_for_testing()[2].symbol_name.c_str(),
+ "baz_baz()");
+ EXPECT_EQ(parser.symbols_for_testing()[2].start_address,
+ static_cast<uint64_t>(0x10d0));
+ EXPECT_EQ(parser.symbols_for_testing()[2].function_size, 107u);
+}
+
+TEST(BreakpadParserTest, OptionalArgument) {
+ BreakpadParser parser(kFakeFilePath);
+ constexpr char kTestFileContents[] =
+ "MODULE mac x86_64 E3A0F28FBCB43C15986D8608AF1DD2380 exif.so\n"
+ "FUNC m 1010 23 0 foo_foo()\n"
+ "1031 2 39 4\n"
+ "FUNC m 1040 84 0 bar_1\n";
+ ASSERT_TRUE(parser.ParseFromString(kTestFileContents));
+ ASSERT_EQ(parser.symbols_for_testing().size(), 2u);
+ EXPECT_STREQ(parser.symbols_for_testing()[0].symbol_name.c_str(),
+ "foo_foo()");
+ EXPECT_EQ(parser.symbols_for_testing()[0].start_address,
+ static_cast<uint64_t>(0x1010));
+ EXPECT_STREQ(parser.symbols_for_testing()[1].symbol_name.c_str(), "bar_1");
+ EXPECT_EQ(parser.symbols_for_testing()[1].start_address,
+ static_cast<uint64_t>(0x1040));
+}
+
+TEST(BreakpadParserTest, FuncNameWithSpaces) {
+ BreakpadParser parser(kFakeFilePath);
+ constexpr char kTestFileContents[] =
+ "MODULE mac x86_64 E3A0F28FBCB43C15986D8608AF1DD2380 exif.so\n"
+ "FUNC 1010 23 0 foo foo foo\n"
+ "1031 2 39 4\n"
+ "FUNC 1040 84 0 bar\n"
+ "1040 4 44 5\n"
+ "FUNC 10d0 6b 0 baz\n";
+ ASSERT_TRUE(parser.ParseFromString(kTestFileContents));
+ ASSERT_EQ(parser.symbols_for_testing().size(), 3u);
+ EXPECT_STREQ(parser.symbols_for_testing()[0].symbol_name.c_str(),
+ "foo foo foo");
+ EXPECT_EQ(parser.symbols_for_testing()[0].start_address,
+ static_cast<uint64_t>(0x1010));
+ EXPECT_STREQ(parser.symbols_for_testing()[2].symbol_name.c_str(), "baz");
+ EXPECT_EQ(parser.symbols_for_testing()[2].start_address,
+ static_cast<uint64_t>(0x10d0));
+}
+
+TEST(BreakpadParserTest, NonHexAddress) {
+ BreakpadParser parser(kFakeFilePath);
+ constexpr char kTestFileContents[] =
+ "MODULE mac x86_64 E3A0F28FBCB43C15986D8608AF1DD2380 exif.so\n"
+ "FUNC foo 23 0 foo\n"
+ "1031 2 39 4\n"
+ "FUNC 1040 84 0 bar\n"
+ "1040 4 44 5\n"
+ "FUNC 10d0 6b 0 baz\n";
+ ASSERT_FALSE(parser.ParseFromString(kTestFileContents));
+ EXPECT_TRUE(parser.symbols_for_testing().empty());
+}
+
+TEST(BreakpadParserTest, NoModuleRecord) {
+ BreakpadParser parser(kFakeFilePath);
+ constexpr char kTestFileContents[] =
+ "FUNC foo 23 0 foo()\n"
+ "1031 2 39 4\n"
+ "FUNC 1040 84 0 bar\n"
+ "1040 4 44 5\n"
+ "FUNC 10d0 6b 0 baz\n";
+ ASSERT_FALSE(parser.ParseFromString(kTestFileContents));
+ EXPECT_TRUE(parser.symbols_for_testing().empty());
+}
+
+// To make it easy to read, each FUNC record is followed by two LINE records:
+// one showing the start address of the ending instruction and one showing the
+// address where the function ends.
+constexpr char kGetSymbolTestContents[] =
+ "MODULE mac x86_64 E3A0F28FBCB43C15986D8608AF1DD2380 exif.so\n"
+ "FUNC 1010 23 0 foo\n"
+ "1031 2 39 4\n"
+ "1033 0 0 0\n"
+ "FUNC 1040 84 0 bar\n"
+ "10b6 e 44 5\n"
+ "10c4 0 0 0\n"
+ "FUNC 10d0 6b 0 baz\n"
+ "1136 5 44 5\n"
+ "113b 0 0 0\n";
+
+TEST(BreakpadParserTest, GivenStartAddr) {
+ BreakpadParser parser(kFakeFilePath);
+ ASSERT_TRUE(parser.ParseFromString(kGetSymbolTestContents));
+ ASSERT_EQ(parser.symbols_for_testing().size(), 3u);
+ EXPECT_EQ(*parser.GetSymbol(0x1010U), "foo");
+ EXPECT_EQ(*parser.GetSymbol(0x10d0U), "baz");
+}
+
+TEST(BreakpadParserTest, GivenAddrInRange) {
+ BreakpadParser parser(kFakeFilePath);
+ ASSERT_TRUE(parser.ParseFromString(kGetSymbolTestContents));
+ ASSERT_EQ(parser.symbols_for_testing().size(), 3u);
+ EXPECT_EQ(*parser.GetSymbol(0x1030U), "foo");
+ EXPECT_EQ(*parser.GetSymbol(0x10c0U), "bar");
+}
+
+TEST(BreakpadParserTest, AddrTooLow) {
+ BreakpadParser parser(kFakeFilePath);
+ ASSERT_TRUE(parser.ParseFromString(kGetSymbolTestContents));
+ ASSERT_EQ(parser.symbols_for_testing().size(), 3u);
+ EXPECT_FALSE(parser.GetSymbol(0x1000U));
+}
+
+TEST(BreakpadParserTest, AddrTooHigh) {
+ BreakpadParser parser(kFakeFilePath);
+ ASSERT_TRUE(parser.ParseFromString(kGetSymbolTestContents));
+ ASSERT_EQ(parser.symbols_for_testing().size(), 3u);
+ EXPECT_FALSE(parser.GetSymbol(0x3000U));
+}
+
+TEST(BreakpadParserTest, AddrBetweenFunctions) {
+ BreakpadParser parser(kFakeFilePath);
+ ASSERT_TRUE(parser.ParseFromString(kGetSymbolTestContents));
+ ASSERT_EQ(parser.symbols_for_testing().size(), 3u);
+ EXPECT_FALSE(parser.GetSymbol(0x1036U));
+}
+
+} // namespace
+} // namespace profiling
+} // namespace perfetto
diff --git a/src/profiling/symbolizer/breakpad_symbolizer.cc b/src/profiling/symbolizer/breakpad_symbolizer.cc
new file mode 100644
index 000000000..c7558c7c1
--- /dev/null
+++ b/src/profiling/symbolizer/breakpad_symbolizer.cc
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/profiling/symbolizer/breakpad_symbolizer.h"
+
+#include "perfetto/base/build_config.h"
+#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/string_view.h"
+#include "perfetto/ext/base/string_writer.h"
+#include "src/profiling/symbolizer/breakpad_parser.h"
+
+namespace perfetto {
+namespace profiling {
+
+namespace {
+
+// Returns the file path for a breakpad symbol file with the given |build_id|.
+std::string MakeFilePath(const std::string& build_id,
+ const std::string& symbol_dir_path) {
+ // The directory of the symbol file is stored in an environment variable.
+ constexpr char kBreakpadSuffix[] = ".breakpad";
+ std::string file_path;
+ // Append file name to symbol directory path using |build_id| and
+ // |kBreakpadSuffix|.
+ file_path.append(symbol_dir_path);
+// TODO: Add a path utility for perfetto to use here.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ file_path.append("\\");
+#else
+ file_path.append("/");
+#endif
+ file_path.append(build_id);
+ file_path.append(kBreakpadSuffix);
+
+ return file_path;
+}
+
+} // namespace
+
+BreakpadSymbolizer::BreakpadSymbolizer(const std::string& symbol_dir_path)
+ : symbol_dir_path_(symbol_dir_path) {}
+
+std::vector<std::vector<SymbolizedFrame>> BreakpadSymbolizer::Symbolize(
+ const std::string&,
+ const std::string& build_id,
+ uint64_t,
+ const std::vector<uint64_t>& address) {
+ std::vector<std::vector<SymbolizedFrame>> result;
+ size_t num_symbolized_frames = 0;
+ result.reserve(address.size());
+ std::string file_path;
+
+ // Check to see if the |file_path_for_testing_| member is populated. If it is,
+ // this file must be used.
+ if (file_path_for_testing_.empty()) {
+ file_path = MakeFilePath(build_id, symbol_dir_path_).c_str();
+ } else {
+ file_path = file_path_for_testing_;
+ }
+
+ BreakpadParser parser(file_path);
+ if (!parser.ParseFile()) {
+ PERFETTO_ELOG("Failed to parse file %s.", file_path.c_str());
+ PERFETTO_PLOG("Symbolized %zu of %zu frames.", num_symbolized_frames,
+ address.size());
+ return result;
+ }
+
+ // Add each address's function name to the |result| vector in the same order.
+ for (uint64_t addr : address) {
+ SymbolizedFrame frame;
+ base::Optional<std::string> opt_func_name = parser.GetSymbol(addr);
+ if (opt_func_name) {
+ frame.function_name = *opt_func_name;
+ num_symbolized_frames++;
+ }
+ result.push_back({std::move(frame)});
+ }
+ PERFETTO_PLOG("Symbolized %zu of %zu frames.", num_symbolized_frames,
+ address.size());
+ return result;
+}
+
+} // namespace profiling
+} // namespace perfetto
diff --git a/src/profiling/symbolizer/breakpad_symbolizer.h b/src/profiling/symbolizer/breakpad_symbolizer.h
new file mode 100644
index 000000000..89c5ec59c
--- /dev/null
+++ b/src/profiling/symbolizer/breakpad_symbolizer.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_PROFILING_SYMBOLIZER_BREAKPAD_SYMBOLIZER_H_
+#define SRC_PROFILING_SYMBOLIZER_BREAKPAD_SYMBOLIZER_H_
+
+#include "perfetto/ext/base/string_view.h"
+#include "src/profiling/symbolizer/symbolizer.h"
+
+namespace perfetto {
+namespace profiling {
+
+// A subclass of Symbolizer that overrides the Symbolize method to make the
+// symbolization process work for breakpad files.
+class BreakpadSymbolizer : public Symbolizer {
+ public:
+ // Takes the path to a folder containing breakpad symbol files as an argument.
+ // The files in this folder will be used to symbolize a given trace. Each
+ // breakpad symbol file should use the upper case hex representation of the
+ // module ID, contained in the first line of the file, as the name of the
+ // file, with a ".breakpad" suffix. eg: <module_id>.breakpad.
+ explicit BreakpadSymbolizer(const std::string& symbol_dir_path);
+
+ BreakpadSymbolizer(BreakpadSymbolizer&& other) = default;
+ BreakpadSymbolizer& operator=(BreakpadSymbolizer&& other) = default;
+
+ std::vector<std::vector<SymbolizedFrame>> Symbolize(
+ const std::string&,
+ const std::string& build_id,
+ uint64_t,
+ const std::vector<uint64_t>& address) override;
+
+ void SetBreakpadFileForTesting(const std::string& path) {
+ file_path_for_testing_ = path;
+ }
+
+ bool BuildIdNeedsHexConversion() override { return false; }
+
+ private:
+ std::string symbol_dir_path_;
+ std::string file_path_for_testing_;
+};
+
+} // namespace profiling
+} // namespace perfetto
+
+#endif // SRC_PROFILING_SYMBOLIZER_BREAKPAD_SYMBOLIZER_H_
diff --git a/src/profiling/symbolizer/breakpad_symbolizer_unittest.cc b/src/profiling/symbolizer/breakpad_symbolizer_unittest.cc
new file mode 100644
index 000000000..ed68f8810
--- /dev/null
+++ b/src/profiling/symbolizer/breakpad_symbolizer_unittest.cc
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+
+#include "test/gtest_and_gmock.h"
+
+#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/string_view.h"
+#include "perfetto/ext/base/temp_file.h"
+#include "src/profiling/symbolizer/breakpad_symbolizer.h"
+
+namespace perfetto {
+namespace profiling {
+
+namespace {
+
+TEST(BreakpadSymbolizerTest, NonExistantFile) {
+ const std::string kBadFilePath = "/bad/file/path";
+ constexpr char kTestDir[] = "Unused";
+ BreakpadSymbolizer symbolizer(kTestDir);
+ symbolizer.SetBreakpadFileForTesting(kBadFilePath);
+ std::vector<uint64_t> addresses = {0x1010u, 0x1040u, 0x10d0u, 0x1140u};
+ std::vector<std::vector<SymbolizedFrame>> frames =
+ symbolizer.Symbolize("mapping", "build", 0, addresses);
+ EXPECT_TRUE(frames.empty());
+}
+
+// To make it easy to read, each FUNC record is followed by two LINE records:
+// one showing the start address of the ending instruction and one showing the
+// address where the function ends.
+constexpr char kTestFileContents[] =
+ "MODULE mac x86_64 A68BC89F12C foo.so\n"
+ "FUNC 1010 23 0 foo_foo()\n"
+ "1031 2 39 4\n"
+ "1033 0 0 0\n"
+ "FUNC 1040 84 0 bar_bar_bar()\n"
+ "10b6 e 44 5\n"
+ "10c4 0 0 0\n"
+ "FUNC 10d0 6b 0 foo::bar()\n"
+ "1136 5 44 5\n"
+ "113b 0 0 0\n"
+ "FUNC 1140 6b 0 baz()\n"
+ "114a 2 82 5\n"
+ "114c 0 0 0\n";
+constexpr ssize_t kTestFileLength = base::ArraySize(kTestFileContents);
+
+TEST(BreakpadSymbolizerTest, SymbolFrames) {
+ base::TempFile test_file = base::TempFile::Create();
+ ASSERT_TRUE(*test_file);
+ ssize_t written =
+ base::WriteAll(test_file.fd(), kTestFileContents, kTestFileLength);
+ ASSERT_EQ(written, kTestFileLength);
+ constexpr char kTestDir[] = "Unused";
+ BreakpadSymbolizer symbolizer(kTestDir);
+ symbolizer.SetBreakpadFileForTesting(test_file.path());
+ // The first 4 addresses are valid, while the last four, cannot be mapped to a
+ // function because they are either too low, too large, or not mapped in any
+ // function's range.
+ std::vector<uint64_t> addresses = {0x1010u, 0x1040u, 0x10d0u, 0x1140u,
+ 0xeu, 0x1036u, 0x30d0u, 0x113eu};
+ std::vector<std::vector<SymbolizedFrame>> frames =
+ symbolizer.Symbolize("mapping", "build", 0, addresses);
+ ASSERT_EQ(frames.size(), 8u);
+ EXPECT_EQ(frames[0][0].function_name, "foo_foo()");
+ EXPECT_EQ(frames[1][0].function_name, "bar_bar_bar()");
+ EXPECT_EQ(frames[2][0].function_name, "foo::bar()");
+ EXPECT_EQ(frames[3][0].function_name, "baz()");
+ EXPECT_TRUE(frames[4][0].function_name.empty());
+ EXPECT_TRUE(frames[5][0].function_name.empty());
+ EXPECT_TRUE(frames[6][0].function_name.empty());
+ EXPECT_TRUE(frames[7][0].function_name.empty());
+}
+
+} // namespace
+} // namespace profiling
+} // namespace perfetto
diff --git a/src/profiling/symbolizer/elf.h b/src/profiling/symbolizer/elf.h
new file mode 100644
index 000000000..de036121e
--- /dev/null
+++ b/src/profiling/symbolizer/elf.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_PROFILING_SYMBOLIZER_ELF_H_
+#define SRC_PROFILING_SYMBOLIZER_ELF_H_
+
+#include <stddef.h>
+#include <cinttypes>
+
+#include "perfetto/base/build_config.h"
+
+// We cannot just include elf.h, as that only exists on Linux, and we want to
+// allow symbolization on other platforms as well. As we only need a small
+// subset, it is easiest to define the constants and structs ourselves.
+
+namespace perfetto {
+namespace profiling {
+
+constexpr auto PT_LOAD = 1;
+constexpr auto PF_X = 1;
+constexpr auto SHT_NOTE = 7;
+constexpr auto NT_GNU_BUILD_ID = 3;
+constexpr auto ELFCLASS32 = 1;
+constexpr auto ELFCLASS64 = 2;
+constexpr auto ELFMAG0 = 0x7f;
+constexpr auto ELFMAG1 = 'E';
+constexpr auto ELFMAG2 = 'L';
+constexpr auto ELFMAG3 = 'F';
+constexpr auto ELFDATA2LSB = 1;
+constexpr auto EV_CURRENT = 1;
+constexpr auto EI_MAG0 = 0;
+constexpr auto EI_MAG1 = 1;
+constexpr auto EI_MAG2 = 2;
+constexpr auto EI_MAG3 = 3;
+constexpr auto EI_CLASS = 4;
+constexpr auto EI_DATA = 5;
+constexpr auto EI_VERSION = 6;
+
+struct Elf32 {
+ using Addr = uint32_t;
+ using Half = uint16_t;
+ using Off = uint32_t;
+ using Sword = int32_t;
+ using Word = uint32_t;
+ struct Ehdr {
+ unsigned char e_ident[16];
+ Half e_type;
+ Half e_machine;
+ Word e_version;
+ Addr e_entry;
+ Off e_phoff;
+ Off e_shoff;
+ Word e_flags;
+ Half e_ehsize;
+ Half e_phentsize;
+ Half e_phnum;
+ Half e_shentsize;
+ Half e_shnum;
+ Half e_shstrndx;
+ };
+ struct Shdr {
+ Word sh_name;
+ Word sh_type;
+ Word sh_flags;
+ Addr sh_addr;
+ Off sh_offset;
+ Word sh_size;
+ Word sh_link;
+ Word sh_info;
+ Word sh_addralign;
+ Word sh_entsize;
+ };
+ struct Nhdr {
+ Word n_namesz;
+ Word n_descsz;
+ Word n_type;
+ };
+ struct Phdr {
+ uint32_t p_type;
+ Off p_offset;
+ Addr p_vaddr;
+ Addr p_paddr;
+ uint32_t p_filesz;
+ uint32_t p_memsz;
+ uint32_t p_flags;
+ uint32_t p_align;
+ };
+};
+
+struct Elf64 {
+ using Addr = uint64_t;
+ using Half = uint16_t;
+ using SHalf = int16_t;
+ using Off = uint64_t;
+ using Sword = int32_t;
+ using Word = uint32_t;
+ using Xword = uint64_t;
+ using Sxword = int64_t;
+ struct Ehdr {
+ unsigned char e_ident[16];
+ Half e_type;
+ Half e_machine;
+ Word e_version;
+ Addr e_entry;
+ Off e_phoff;
+ Off e_shoff;
+ Word e_flags;
+ Half e_ehsize;
+ Half e_phentsize;
+ Half e_phnum;
+ Half e_shentsize;
+ Half e_shnum;
+ Half e_shstrndx;
+ };
+ struct Shdr {
+ Word sh_name;
+ Word sh_type;
+ Xword sh_flags;
+ Addr sh_addr;
+ Off sh_offset;
+ Xword sh_size;
+ Word sh_link;
+ Word sh_info;
+ Xword sh_addralign;
+ Xword sh_entsize;
+ };
+ struct Nhdr {
+ Word n_namesz;
+ Word n_descsz;
+ Word n_type;
+ };
+ struct Phdr {
+ uint32_t p_type;
+ uint32_t p_flags;
+ Off p_offset;
+ Addr p_vaddr;
+ Addr p_paddr;
+ uint64_t p_filesz;
+ uint64_t p_memsz;
+ uint64_t p_align;
+ };
+};
+
+template <typename E>
+typename E::Shdr* GetShdr(void* mem, const typename E::Ehdr* ehdr, size_t i) {
+ return reinterpret_cast<typename E::Shdr*>(
+ static_cast<char*>(mem) + ehdr->e_shoff + i * sizeof(typename E::Shdr));
+}
+
+template <typename E>
+typename E::Phdr* GetPhdr(void* mem, const typename E::Ehdr* ehdr, size_t i) {
+ return reinterpret_cast<typename E::Phdr*>(
+ static_cast<char*>(mem) + ehdr->e_phoff + i * sizeof(typename E::Phdr));
+}
+
+} // namespace profiling
+} // namespace perfetto
+
+#endif // SRC_PROFILING_SYMBOLIZER_ELF_H_
diff --git a/src/profiling/symbolizer/filesystem.h b/src/profiling/symbolizer/filesystem.h
deleted file mode 100644
index d9cf87c5a..000000000
--- a/src/profiling/symbolizer/filesystem.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SRC_PROFILING_SYMBOLIZER_FILESYSTEM_H_
-#define SRC_PROFILING_SYMBOLIZER_FILESYSTEM_H_
-
-#include "src/profiling/symbolizer/local_symbolizer.h"
-
-namespace perfetto {
-namespace profiling {
-
-using FileCallback = std::function<void(const char*, size_t)>;
-size_t GetFileSize(const std::string& file_path);
-bool WalkDirectories(std::vector<std::string> dirs, FileCallback fn);
-
-} // namespace profiling
-} // namespace perfetto
-
-#endif // SRC_PROFILING_SYMBOLIZER_FILESYSTEM_H_
diff --git a/src/profiling/symbolizer/filesystem_posix.cc b/src/profiling/symbolizer/filesystem_posix.cc
deleted file mode 100644
index cc983e264..000000000
--- a/src/profiling/symbolizer/filesystem_posix.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/profiling/symbolizer/filesystem.h"
-
-#include "perfetto/base/build_config.h"
-
-#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
-#if PERFETTO_BUILDFLAG(PERFETTO_LOCAL_SYMBOLIZER)
-#include <fts.h>
-#include <sys/stat.h>
-#endif
-
-#include <string>
-
-#include "perfetto/ext/base/file_utils.h"
-
-namespace perfetto {
-namespace profiling {
-#if PERFETTO_BUILDFLAG(PERFETTO_LOCAL_SYMBOLIZER)
-bool WalkDirectories(std::vector<std::string> dirs, FileCallback fn) {
- std::vector<char*> dir_cstrs;
- dir_cstrs.reserve(dirs.size());
- for (std::string& dir : dirs)
- dir_cstrs.emplace_back(&dir[0]);
- dir_cstrs.push_back(nullptr);
- base::ScopedResource<FTS*, fts_close, nullptr> fts(
- fts_open(&dir_cstrs[0], FTS_LOGICAL | FTS_NOCHDIR, nullptr));
- if (!fts) {
- PERFETTO_PLOG("fts_open");
- return false;
- }
- FTSENT* ent;
- while ((ent = fts_read(*fts))) {
- if (ent->fts_info & FTS_F)
- fn(ent->fts_path, static_cast<size_t>(ent->fts_statp->st_size));
- }
- return true;
-}
-
-size_t GetFileSize(const std::string& file_path) {
- base::ScopedFile fd(base::OpenFile(file_path, O_RDONLY | O_CLOEXEC));
- if (!fd) {
- PERFETTO_PLOG("Failed to get file size %s", file_path.c_str());
- return 0;
- }
- struct stat buf;
- if (fstat(*fd, &buf) == -1) {
- return 0;
- }
- return static_cast<size_t>(buf.st_size);
-}
-#else
-bool WalkDirectories(std::vector<std::string>, FileCallback) {
- return false;
-}
-size_t GetFileSize(const std::string&) {
- return 0;
-}
-#endif
-
-} // namespace profiling
-} // namespace perfetto
-
-#endif // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
diff --git a/src/profiling/symbolizer/filesystem_windows.cc b/src/profiling/symbolizer/filesystem_windows.cc
deleted file mode 100644
index bb2652c93..000000000
--- a/src/profiling/symbolizer/filesystem_windows.cc
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/profiling/symbolizer/filesystem.h"
-
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
-
-#include <Windows.h>
-
-namespace perfetto {
-namespace profiling {
-
-bool WalkDirectories(std::vector<std::string> dirs, FileCallback fn) {
- std::vector<std::string> sub_dirs;
- for (const std::string& dir : dirs) {
- WIN32_FIND_DATAA file;
- HANDLE fh = FindFirstFileA((dir + "\\*").c_str(), &file);
- if (fh != INVALID_HANDLE_VALUE) {
- do {
- std::string file_path = dir + "\\" + file.cFileName;
- if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- if (strcmp(file.cFileName, ".") != 0 &&
- strcmp(file.cFileName, "..") != 0) {
- sub_dirs.push_back(file_path);
- }
- } else {
- ULARGE_INTEGER size;
- size.HighPart = file.nFileSizeHigh;
- size.LowPart = file.nFileSizeLow;
- fn(file_path.c_str(), size.QuadPart);
- }
- } while (FindNextFileA(fh, &file));
- }
- CloseHandle(fh);
- }
- if (!sub_dirs.empty()) {
- WalkDirectories(sub_dirs, fn);
- }
- return true;
-}
-
-size_t GetFileSize(const std::string& file_path) {
- HANDLE file =
- CreateFileA(file_path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
- if (file == INVALID_HANDLE_VALUE) {
- PERFETTO_PLOG("Failed to get file size %s", file_path.c_str());
- return 0;
- }
- LARGE_INTEGER file_size;
- file_size.QuadPart = 0;
- if (!GetFileSizeEx(file, &file_size)) {
- PERFETTO_PLOG("Failed to get file size %s", file_path.c_str());
- }
- CloseHandle(file);
- return static_cast<size_t>(file_size.QuadPart);
-}
-
-} // namespace profiling
-} // namespace perfetto
-
-#endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
diff --git a/src/profiling/symbolizer/local_symbolizer.cc b/src/profiling/symbolizer/local_symbolizer.cc
index fa4e449ec..1fe4dbdeb 100644
--- a/src/profiling/symbolizer/local_symbolizer.cc
+++ b/src/profiling/symbolizer/local_symbolizer.cc
@@ -18,6 +18,7 @@
#include <fcntl.h>
+#include <cinttypes>
#include <memory>
#include <sstream>
#include <string>
@@ -30,7 +31,7 @@
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/scoped_file.h"
#include "perfetto/ext/base/string_utils.h"
-#include "src/profiling/symbolizer/filesystem.h"
+#include "src/profiling/symbolizer/elf.h"
#include "src/profiling/symbolizer/scoped_read_mmap.h"
namespace perfetto {
@@ -69,7 +70,6 @@ std::unique_ptr<Symbolizer> LocalSymbolizerOrDie(
#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/utils.h"
-#include <inttypes.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -116,142 +116,6 @@ std::vector<std::string> GetLines(
}
namespace {
-// We cannot just include elf.h, as that only exists on Linux, and we want to
-// allow symbolization on other platforms as well. As we only need a small
-// subset, it is easiest to define the constants and structs ourselves.
-constexpr auto PT_LOAD = 1;
-constexpr auto PF_X = 1;
-constexpr auto SHT_NOTE = 7;
-constexpr auto NT_GNU_BUILD_ID = 3;
-constexpr auto ELFCLASS32 = 1;
-constexpr auto ELFCLASS64 = 2;
-constexpr auto ELFMAG0 = 0x7f;
-constexpr auto ELFMAG1 = 'E';
-constexpr auto ELFMAG2 = 'L';
-constexpr auto ELFMAG3 = 'F';
-constexpr auto EI_MAG0 = 0;
-constexpr auto EI_MAG1 = 1;
-constexpr auto EI_MAG2 = 2;
-constexpr auto EI_MAG3 = 3;
-constexpr auto EI_CLASS = 4;
-
-struct Elf32 {
- using Addr = uint32_t;
- using Half = uint16_t;
- using Off = uint32_t;
- using Sword = int32_t;
- using Word = uint32_t;
- struct Ehdr {
- unsigned char e_ident[16];
- Half e_type;
- Half e_machine;
- Word e_version;
- Addr e_entry;
- Off e_phoff;
- Off e_shoff;
- Word e_flags;
- Half e_ehsize;
- Half e_phentsize;
- Half e_phnum;
- Half e_shentsize;
- Half e_shnum;
- Half e_shstrndx;
- };
- struct Shdr {
- Word sh_name;
- Word sh_type;
- Word sh_flags;
- Addr sh_addr;
- Off sh_offset;
- Word sh_size;
- Word sh_link;
- Word sh_info;
- Word sh_addralign;
- Word sh_entsize;
- };
- struct Nhdr {
- Word n_namesz;
- Word n_descsz;
- Word n_type;
- };
- struct Phdr {
- uint32_t p_type;
- Off p_offset;
- Addr p_vaddr;
- Addr p_paddr;
- uint32_t p_filesz;
- uint32_t p_memsz;
- uint32_t p_flags;
- uint32_t p_align;
- };
-};
-
-struct Elf64 {
- using Addr = uint64_t;
- using Half = uint16_t;
- using SHalf = int16_t;
- using Off = uint64_t;
- using Sword = int32_t;
- using Word = uint32_t;
- using Xword = uint64_t;
- using Sxword = int64_t;
- struct Ehdr {
- unsigned char e_ident[16];
- Half e_type;
- Half e_machine;
- Word e_version;
- Addr e_entry;
- Off e_phoff;
- Off e_shoff;
- Word e_flags;
- Half e_ehsize;
- Half e_phentsize;
- Half e_phnum;
- Half e_shentsize;
- Half e_shnum;
- Half e_shstrndx;
- };
- struct Shdr {
- Word sh_name;
- Word sh_type;
- Xword sh_flags;
- Addr sh_addr;
- Off sh_offset;
- Xword sh_size;
- Word sh_link;
- Word sh_info;
- Xword sh_addralign;
- Xword sh_entsize;
- };
- struct Nhdr {
- Word n_namesz;
- Word n_descsz;
- Word n_type;
- };
- struct Phdr {
- uint32_t p_type;
- uint32_t p_flags;
- Off p_offset;
- Addr p_vaddr;
- Addr p_paddr;
- uint64_t p_filesz;
- uint64_t p_memsz;
- uint64_t p_align;
- };
-};
-
-template <typename E>
-typename E::Shdr* GetShdr(void* mem, const typename E::Ehdr* ehdr, size_t i) {
- return reinterpret_cast<typename E::Shdr*>(
- static_cast<char*>(mem) + ehdr->e_shoff + i * sizeof(typename E::Shdr));
-}
-
-template <typename E>
-typename E::Phdr* GetPhdr(void* mem, const typename E::Ehdr* ehdr, size_t i) {
- return reinterpret_cast<typename E::Phdr*>(
- static_cast<char*>(mem) + ehdr->e_phoff + i * sizeof(typename E::Phdr));
-}
-
bool InRange(const void* base,
size_t total_size,
const void* ptr,
@@ -352,31 +216,36 @@ struct BuildIdAndLoadBias {
uint64_t load_bias;
};
-base::Optional<BuildIdAndLoadBias> GetBuildIdAndLoadBias(const char* fname,
- size_t size) {
+base::Optional<BuildIdAndLoadBias> GetBuildIdAndLoadBias(
+ const std::string& fname) {
+ base::Optional<size_t> size = base::GetFileSize(fname);
+ if (!size.has_value()) {
+ PERFETTO_PLOG("Failed to get file size %s", fname.c_str());
+ return base::nullopt;
+ }
static_assert(EI_CLASS > EI_MAG3, "mem[EI_MAG?] accesses are in range.");
- if (size <= EI_CLASS)
+ if (*size <= EI_CLASS)
return base::nullopt;
- ScopedReadMmap map(fname, size);
+ ScopedReadMmap map(fname.c_str(), *size);
if (!map.IsValid()) {
PERFETTO_PLOG("mmap");
return base::nullopt;
}
char* mem = static_cast<char*>(*map);
- if (!IsElf(mem, size))
+ if (!IsElf(mem, *size))
return base::nullopt;
base::Optional<std::string> build_id;
base::Optional<uint64_t> load_bias;
switch (mem[EI_CLASS]) {
case ELFCLASS32:
- build_id = GetBuildId<Elf32>(mem, size);
- load_bias = GetLoadBias<Elf32>(mem, size);
+ build_id = GetBuildId<Elf32>(mem, *size);
+ load_bias = GetLoadBias<Elf32>(mem, *size);
break;
case ELFCLASS64:
- build_id = GetBuildId<Elf64>(mem, size);
- load_bias = GetLoadBias<Elf64>(mem, size);
+ build_id = GetBuildId<Elf64>(mem, *size);
+ load_bias = GetLoadBias<Elf64>(mem, *size);
break;
default:
return base::nullopt;
@@ -387,35 +256,48 @@ base::Optional<BuildIdAndLoadBias> GetBuildIdAndLoadBias(const char* fname,
return base::nullopt;
}
+bool StartsWithElfMagic(const std::string& fname) {
+ base::ScopedFile fd(base::OpenFile(fname, O_RDONLY));
+ char magic[EI_MAG3 + 1];
+ if (!fd) {
+ PERFETTO_PLOG("Failed to open %s", fname.c_str());
+ return false;
+ }
+ ssize_t rd = base::Read(*fd, &magic, sizeof(magic));
+ if (rd != sizeof(magic)) {
+ PERFETTO_PLOG("Failed to read %s", fname.c_str());
+ return false;
+ }
+ if (!IsElf(magic, static_cast<size_t>(rd))) {
+ PERFETTO_DLOG("%s not an ELF.", fname.c_str());
+ return false;
+ }
+ return true;
+}
+
std::map<std::string, FoundBinary> BuildIdIndex(std::vector<std::string> dirs) {
std::map<std::string, FoundBinary> result;
- WalkDirectories(std::move(dirs), [&result](const char* fname, size_t size) {
- char magic[EI_MAG3 + 1];
- // Scope file access. On windows OpenFile opens an exclusive lock.
- // This lock needs to be released before mapping the file.
- {
- base::ScopedFile fd(base::OpenFile(fname, O_RDONLY));
- if (!fd) {
- PERFETTO_PLOG("Failed to open %s", fname);
- return;
- }
- ssize_t rd = base::Read(*fd, &magic, sizeof(magic));
- if (rd != sizeof(magic)) {
- PERFETTO_PLOG("Failed to read %s", fname);
- return;
+ for (const std::string& dir : dirs) {
+ std::vector<std::string> files;
+ base::Status status = base::ListFilesRecursive(dir, files);
+ if (!status.ok()) {
+ PERFETTO_PLOG("Failed to list directory %s", dir.c_str());
+ continue;
+ }
+ for (const std::string& basename : files) {
+ std::string fname = dir + "/" + basename;
+ if (!StartsWithElfMagic(fname)) {
+ continue;
}
- if (!IsElf(magic, static_cast<size_t>(rd))) {
- PERFETTO_DLOG("%s not an ELF.", fname);
- return;
+ base::Optional<BuildIdAndLoadBias> build_id_and_load_bias =
+ GetBuildIdAndLoadBias(fname);
+ if (build_id_and_load_bias) {
+ result.emplace(build_id_and_load_bias->build_id,
+ FoundBinary{fname, build_id_and_load_bias->load_bias});
}
}
- base::Optional<BuildIdAndLoadBias> build_id_and_load_bias =
- GetBuildIdAndLoadBias(fname, size);
- if (build_id_and_load_bias) {
- result.emplace(build_id_and_load_bias->build_id,
- FoundBinary{fname, build_id_and_load_bias->load_bias});
- }
- });
+ }
+
return result;
}
@@ -486,15 +368,8 @@ base::Optional<FoundBinary> LocalBinaryFinder::IsCorrectFile(
if (!base::FileExists(symbol_file)) {
return base::nullopt;
}
- // Openfile opens the file with an exclusive lock on windows.
- size_t size = GetFileSize(symbol_file);
-
- if (size == 0) {
- return base::nullopt;
- }
-
base::Optional<BuildIdAndLoadBias> build_id_and_load_bias =
- GetBuildIdAndLoadBias(symbol_file.c_str(), size);
+ GetBuildIdAndLoadBias(symbol_file);
if (!build_id_and_load_bias)
return base::nullopt;
if (build_id_and_load_bias->build_id != build_id) {
@@ -548,8 +423,8 @@ base::Optional<FoundBinary> LocalBinaryFinder::FindBinaryInRoot(
}
if (base::StartsWith(filename, kApkPrefix)) {
- symbol_file =
- root_str + "/" + dirname + "/" + filename.substr(sizeof(kApkPrefix));
+ symbol_file = root_str + "/" + dirname + "/" +
+ filename.substr(sizeof(kApkPrefix) - 1);
result = IsCorrectFile(symbol_file, build_id);
if (result) {
return result;
@@ -563,7 +438,7 @@ base::Optional<FoundBinary> LocalBinaryFinder::FindBinaryInRoot(
}
if (base::StartsWith(filename, kApkPrefix)) {
- symbol_file = root_str + "/" + filename.substr(sizeof(kApkPrefix));
+ symbol_file = root_str + "/" + filename.substr(sizeof(kApkPrefix) - 1);
result = IsCorrectFile(symbol_file, build_id);
if (result) {
return result;
diff --git a/src/profiling/symbolizer/local_symbolizer.h b/src/profiling/symbolizer/local_symbolizer.h
index 01d1fe4d3..bb8b0c261 100644
--- a/src/profiling/symbolizer/local_symbolizer.h
+++ b/src/profiling/symbolizer/local_symbolizer.h
@@ -107,6 +107,8 @@ class LocalSymbolizer : public Symbolizer {
uint64_t load_bias,
const std::vector<uint64_t>& address) override;
+ bool BuildIdNeedsHexConversion() override { return true; }
+
~LocalSymbolizer() override;
private:
diff --git a/src/profiling/symbolizer/local_symbolizer_unittest.cc b/src/profiling/symbolizer/local_symbolizer_unittest.cc
index b96d318ae..cb0c11d72 100644
--- a/src/profiling/symbolizer/local_symbolizer_unittest.cc
+++ b/src/profiling/symbolizer/local_symbolizer_unittest.cc
@@ -20,7 +20,11 @@
// This translation unit is built only on Linux and MacOS. See //gn/BUILD.gn.
#if PERFETTO_BUILDFLAG(PERFETTO_LOCAL_SYMBOLIZER)
+#include <cstddef>
+
+#include "src/base/test/tmp_dir_tree.h"
#include "src/base/test/utils.h"
+#include "src/profiling/symbolizer/elf.h"
#include "src/profiling/symbolizer/local_symbolizer.h"
#include "src/profiling/symbolizer/subprocess.h"
@@ -95,6 +99,142 @@ TEST(LocalSymbolizerTest, ParseLinesSingleCharRead) {
}
}
+// Creates a very simple ELF file content with the first 20 bytes of `build_id`
+// as build id (if build id is shorter the remainin bytes are zero).
+std::string CreateElfWithBuildId(const std::string& build_id) {
+ struct SimpleElf {
+ Elf64::Ehdr ehdr;
+ Elf64::Shdr shdr;
+ Elf64::Nhdr nhdr;
+ char note_name[4];
+ char note_desc[20];
+ } e;
+ memset(&e, 0, sizeof e);
+
+ e.ehdr.e_ident[EI_MAG0] = ELFMAG0;
+ e.ehdr.e_ident[EI_MAG1] = ELFMAG1;
+ e.ehdr.e_ident[EI_MAG2] = ELFMAG2;
+ e.ehdr.e_ident[EI_MAG3] = ELFMAG3;
+ e.ehdr.e_ident[EI_CLASS] = ELFCLASS64;
+ e.ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
+ e.ehdr.e_ident[EI_VERSION] = EV_CURRENT;
+ e.ehdr.e_version = EV_CURRENT;
+ e.ehdr.e_shentsize = sizeof(Elf64::Shdr);
+ e.ehdr.e_shnum = 1;
+ e.ehdr.e_ehsize = sizeof e.ehdr;
+ e.ehdr.e_shoff = offsetof(SimpleElf, shdr);
+
+ e.shdr.sh_type = SHT_NOTE;
+ e.shdr.sh_offset = offsetof(SimpleElf, nhdr);
+
+ e.nhdr.n_type = NT_GNU_BUILD_ID;
+ e.nhdr.n_namesz = sizeof e.note_name;
+ e.nhdr.n_descsz = sizeof e.note_desc;
+ strcpy(e.note_name, "GNU");
+ memcpy(e.note_desc, build_id.c_str(),
+ std::min(build_id.size(), sizeof(e.note_desc)));
+
+ e.shdr.sh_size = offsetof(SimpleElf, note_desc) + sizeof(e.note_desc) -
+ offsetof(SimpleElf, nhdr);
+
+ return std::string(reinterpret_cast<const char*>(&e), sizeof e);
+}
+
+TEST(LocalBinaryIndexerTest, SimpleTree) {
+ base::TmpDirTree tmp;
+ tmp.AddDir("dir1");
+ tmp.AddFile("dir1/elf1", CreateElfWithBuildId("AAAAAAAAAAAAAAAAAAAA"));
+ tmp.AddFile("dir1/nonelf1", "OTHERDATA");
+ tmp.AddDir("dir2");
+ tmp.AddFile("dir2/elf1", CreateElfWithBuildId("BBBBBBBBBBBBBBBBBBBB"));
+ tmp.AddFile("dir2/nonelf1", "other text");
+
+ LocalBinaryIndexer indexer({tmp.path() + "/dir1", tmp.path() + "/dir2"});
+
+ base::Optional<FoundBinary> bin1 =
+ indexer.FindBinary("", "AAAAAAAAAAAAAAAAAAAA");
+ ASSERT_TRUE(bin1.has_value());
+ EXPECT_EQ(bin1.value().file_name, tmp.path() + "/dir1/elf1");
+
+ base::Optional<FoundBinary> bin2 =
+ indexer.FindBinary("", "BBBBBBBBBBBBBBBBBBBB");
+ ASSERT_TRUE(bin2.has_value());
+ EXPECT_EQ(bin2.value().file_name, tmp.path() + "/dir2/elf1");
+}
+
+TEST(LocalBinaryFinderTest, AbsolutePath) {
+ base::TmpDirTree tmp;
+ tmp.AddDir("root");
+ tmp.AddDir("root/dir");
+ tmp.AddFile("root/dir/elf1.so", CreateElfWithBuildId("AAAAAAAAAAAAAAAAAAAA"));
+
+ LocalBinaryFinder finder({tmp.path() + "/root"});
+
+ base::Optional<FoundBinary> bin1 =
+ finder.FindBinary("/dir/elf1.so", "AAAAAAAAAAAAAAAAAAAA");
+ ASSERT_TRUE(bin1.has_value());
+ EXPECT_EQ(bin1.value().file_name, tmp.path() + "/root/dir/elf1.so");
+}
+
+TEST(LocalBinaryFinderTest, AbsolutePathWithoutBaseApk) {
+ base::TmpDirTree tmp;
+ tmp.AddDir("root");
+ tmp.AddDir("root/dir");
+ tmp.AddFile("root/dir/elf1.so", CreateElfWithBuildId("AAAAAAAAAAAAAAAAAAAA"));
+
+ LocalBinaryFinder finder({tmp.path() + "/root"});
+
+ base::Optional<FoundBinary> bin1 =
+ finder.FindBinary("/dir/base.apk!elf1.so", "AAAAAAAAAAAAAAAAAAAA");
+ ASSERT_TRUE(bin1.has_value());
+ EXPECT_EQ(bin1.value().file_name, tmp.path() + "/root/dir/elf1.so");
+}
+
+TEST(LocalBinaryFinderTest, OnlyFilename) {
+ base::TmpDirTree tmp;
+ tmp.AddDir("root");
+ tmp.AddFile("root/elf1.so", CreateElfWithBuildId("AAAAAAAAAAAAAAAAAAAA"));
+
+ LocalBinaryFinder finder({tmp.path() + "/root"});
+
+ base::Optional<FoundBinary> bin1 =
+ finder.FindBinary("/ignored_dir/elf1.so", "AAAAAAAAAAAAAAAAAAAA");
+ ASSERT_TRUE(bin1.has_value());
+ EXPECT_EQ(bin1.value().file_name, tmp.path() + "/root/elf1.so");
+}
+
+TEST(LocalBinaryFinderTest, OnlyFilenameWithoutBaseApk) {
+ base::TmpDirTree tmp;
+ tmp.AddDir("root");
+ tmp.AddFile("root/elf1.so", CreateElfWithBuildId("AAAAAAAAAAAAAAAAAAAA"));
+
+ LocalBinaryFinder finder({tmp.path() + "/root"});
+
+ base::Optional<FoundBinary> bin1 = finder.FindBinary(
+ "/ignored_dir/base.apk!elf1.so", "AAAAAAAAAAAAAAAAAAAA");
+ ASSERT_TRUE(bin1.has_value());
+ EXPECT_EQ(bin1.value().file_name, tmp.path() + "/root/elf1.so");
+}
+
+TEST(LocalBinaryFinderTest, BuildIdSubdir) {
+ base::TmpDirTree tmp;
+ tmp.AddDir("root");
+ tmp.AddDir("root/.build-id");
+ tmp.AddDir("root/.build-id/41");
+ tmp.AddFile("root/.build-id/41/41414141414141414141414141414141414141.debug",
+ CreateElfWithBuildId("AAAAAAAAAAAAAAAAAAAA"));
+
+ LocalBinaryFinder finder({tmp.path() + "/root"});
+
+ base::Optional<FoundBinary> bin1 =
+ finder.FindBinary("/ignored_dir/ignored_name.so", "AAAAAAAAAAAAAAAAAAAA");
+ ASSERT_TRUE(bin1.has_value());
+ EXPECT_EQ(
+ bin1.value().file_name,
+ tmp.path() +
+ "/root/.build-id/41/41414141414141414141414141414141414141.debug");
+}
+
} // namespace
} // namespace profiling
} // namespace perfetto
diff --git a/src/profiling/symbolizer/symbolize_database.cc b/src/profiling/symbolizer/symbolize_database.cc
index a002aea25..c6fca904e 100644
--- a/src/profiling/symbolizer/symbolize_database.cc
+++ b/src/profiling/symbolizer/symbolize_database.cc
@@ -81,14 +81,20 @@ std::string FromHex(const std::string& str) {
}
std::map<UnsymbolizedMapping, std::vector<uint64_t>> GetUnsymbolizedFrames(
- trace_processor::TraceProcessor* tp) {
+ trace_processor::TraceProcessor* tp,
+ bool convert_build_id_to_bytes) {
std::map<UnsymbolizedMapping, std::vector<uint64_t>> res;
Iterator it = tp->ExecuteQuery(kQueryUnsymbolized);
while (it.Next()) {
int64_t load_bias = it.Get(3).AsLong();
PERFETTO_CHECK(load_bias >= 0);
- UnsymbolizedMapping unsymbolized_mapping{it.Get(0).AsString(),
- FromHex(it.Get(1).AsString()),
+ std::string build_id;
+ if (convert_build_id_to_bytes) {
+ build_id = FromHex(it.Get(1).AsString());
+ } else {
+ build_id = it.Get(1).AsString();
+ }
+ UnsymbolizedMapping unsymbolized_mapping{it.Get(0).AsString(), build_id,
static_cast<uint64_t>(load_bias)};
int64_t rel_pc = it.Get(2).AsLong();
res[unsymbolized_mapping].emplace_back(rel_pc);
@@ -106,7 +112,8 @@ void SymbolizeDatabase(trace_processor::TraceProcessor* tp,
Symbolizer* symbolizer,
std::function<void(const std::string&)> callback) {
PERFETTO_CHECK(symbolizer);
- auto unsymbolized = GetUnsymbolizedFrames(tp);
+ auto unsymbolized =
+ GetUnsymbolizedFrames(tp, symbolizer->BuildIdNeedsHexConversion());
for (auto it = unsymbolized.cbegin(); it != unsymbolized.cend(); ++it) {
const auto& unsymbolized_mapping = it->first;
const std::vector<uint64_t>& rel_pcs = it->second;
diff --git a/src/profiling/symbolizer/symbolizer.h b/src/profiling/symbolizer/symbolizer.h
index 3e96142ab..85c3f917c 100644
--- a/src/profiling/symbolizer/symbolizer.h
+++ b/src/profiling/symbolizer/symbolizer.h
@@ -27,7 +27,7 @@ namespace profiling {
struct SymbolizedFrame {
std::string function_name;
std::string file_name;
- uint32_t line;
+ uint32_t line = 0;
};
class Symbolizer {
@@ -43,6 +43,12 @@ class Symbolizer {
uint64_t load_bias,
const std::vector<uint64_t>& address) = 0;
virtual ~Symbolizer();
+
+ // LocalSymbolizer uses a specific conversion of a symbol file's |build_id| to
+ // bytes, but BreakpadSymbolizer requires the |build_id| as given. Return true
+ // if the |build_id| passed to Symbolize() requires the conversion to bytes
+ // and false otherwise.
+ virtual bool BuildIdNeedsHexConversion() = 0;
};
} // namespace profiling
diff --git a/src/protozero/BUILD.gn b/src/protozero/BUILD.gn
index 69d911a8a..b11a56944 100644
--- a/src/protozero/BUILD.gn
+++ b/src/protozero/BUILD.gn
@@ -44,9 +44,22 @@ perfetto_component("protozero") {
]
}
+source_set("proto_ring_buffer") {
+ deps = [
+ ":protozero",
+ "../../gn:default_deps",
+ "../base",
+ ]
+ sources = [
+ "proto_ring_buffer.cc",
+ "proto_ring_buffer.h",
+ ]
+}
+
perfetto_unittest_source_set("unittests") {
testonly = true
deps = [
+ ":proto_ring_buffer",
":protozero",
":testing_messages_cpp",
":testing_messages_lite",
@@ -62,6 +75,7 @@ perfetto_unittest_source_set("unittests") {
"message_handle_unittest.cc",
"message_unittest.cc",
"proto_decoder_unittest.cc",
+ "proto_ring_buffer_unittest.cc",
"proto_utils_unittest.cc",
"scattered_stream_writer_unittest.cc",
"test/cppgen_conformance_unittest.cc",
diff --git a/src/protozero/filtering/BUILD.gn b/src/protozero/filtering/BUILD.gn
index b438929b4..ffd1c8cc1 100644
--- a/src/protozero/filtering/BUILD.gn
+++ b/src/protozero/filtering/BUILD.gn
@@ -83,7 +83,6 @@ perfetto_unittest_source_set("unittests") {
":bytecode_common",
":bytecode_generator",
":bytecode_parser",
- ":filter_util",
":message_filter",
"..:protozero",
"../../../gn:default_deps",
@@ -95,10 +94,19 @@ perfetto_unittest_source_set("unittests") {
sources = [
"filter_bytecode_generator_unittest.cc",
"filter_bytecode_parser_unittest.cc",
- "filter_util_unittest.cc",
- "message_filter_unittest.cc",
"message_tokenizer_unittest.cc",
]
+
+ # On chromium component build we cannot have a test target depening boh on
+ # protobuf-full and protobuf-lite. Just skip those targets there.
+ # See also https://crug.com/1210223 .
+ if (perfetto_build_standalone || perfetto_build_with_android) {
+ deps += [ ":filter_util" ]
+ sources += [
+ "filter_util_unittest.cc",
+ "message_filter_unittest.cc",
+ ]
+ }
}
if (enable_perfetto_benchmarks) {
diff --git a/src/protozero/filtering/filter_bytecode_parser.h b/src/protozero/filtering/filter_bytecode_parser.h
index b2378caca..6ecbdfb18 100644
--- a/src/protozero/filtering/filter_bytecode_parser.h
+++ b/src/protozero/filtering/filter_bytecode_parser.h
@@ -111,7 +111,7 @@ class FilterBytecodeParser {
std::vector<uint32_t> words_;
// One entry for each message index stored in the filter plus a sentinel at
- // the end. Maps each message index to the offset in |words_| where the the
+ // the end. Maps each message index to the offset in |words_| where the
// Nth message start.
// message_offset_.size() - 2 == the max message id that can be parsed.
std::vector<uint32_t> message_offset_;
diff --git a/src/protozero/filtering/filter_util.h b/src/protozero/filtering/filter_util.h
index 3cc7655c8..14d01dcb4 100644
--- a/src/protozero/filtering/filter_util.h
+++ b/src/protozero/filtering/filter_util.h
@@ -23,11 +23,9 @@
#include <map>
#include <string>
-namespace google {
-namespace protobuf {
-class Descriptor;
-}
-} // namespace google
+// We include this intentionally instead of forward declaring to allow
+// for an easy find/replace transformation when moving to Google3.
+#include <google/protobuf/descriptor.h>
namespace protozero {
diff --git a/src/protozero/filtering/message_filter.h b/src/protozero/filtering/message_filter.h
index 37dc9b520..80ddd0ea0 100644
--- a/src/protozero/filtering/message_filter.h
+++ b/src/protozero/filtering/message_filter.h
@@ -130,7 +130,7 @@ class MessageFilter {
// Gets into an error state which swallows all the input and emits no output.
void SetUnrecoverableErrorState();
- // We keep track of the the nest of messages in a stack. Each StackState
+ // We keep track of the nest of messages in a stack. Each StackState
// object corresponds to a level of nesting in the proto message structure.
// Every time a new field of type len-delimited that has a corresponding
// sub-message in the bytecode is encountered, a new StackState is pushed in
diff --git a/src/protozero/proto_decoder.cc b/src/protozero/proto_decoder.cc
index f83c91fe9..a766a287a 100644
--- a/src/protozero/proto_decoder.cc
+++ b/src/protozero/proto_decoder.cc
@@ -17,7 +17,10 @@
#include "perfetto/protozero/proto_decoder.h"
#include <string.h>
+
+#include <cinttypes>
#include <limits>
+#include <memory>
#include "perfetto/base/compiler.h"
#include "perfetto/base/logging.h"
@@ -186,17 +189,26 @@ void TypedProtoDecoderBase::ParseAllFields() {
res = ParseOneField(cur, end_);
PERFETTO_DCHECK(res.parse_res != ParseFieldResult::kOk || res.next != cur);
cur = res.next;
- if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kSkip)) {
+ if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kSkip))
continue;
- } else if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kAbort)) {
+ if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kAbort))
break;
- }
+
PERFETTO_DCHECK(res.parse_res == ParseFieldResult::kOk);
PERFETTO_DCHECK(res.field.valid());
auto field_id = res.field.id();
if (PERFETTO_UNLIKELY(field_id >= num_fields_))
continue;
+ // There are two reasons why we might want to expand the heap capacity:
+ // 1. We are writing a non-repeated field, which has an id >
+ // INITIAL_STACK_CAPACITY. In this case ExpandHeapStorage() ensures to
+ // allocate at least (num_fields_ + 1) slots.
+ // 2. We are writing a repeated field but ran out of capacity.
+ if (PERFETTO_UNLIKELY(field_id >= size_ || size_ >= capacity_))
+ ExpandHeapStorage();
+
+ PERFETTO_DCHECK(field_id < size_);
Field* fld = &fields_[field_id];
if (PERFETTO_LIKELY(!fld->valid())) {
// This is the first time we see this field.
@@ -211,12 +223,7 @@ void TypedProtoDecoderBase::ParseAllFields() {
// supposed to return the last value of X, not the first one.
// This is so that the RepeatedFieldIterator will iterate in the right
// order, see comments on RepeatedFieldIterator.
- if (PERFETTO_UNLIKELY(size_ >= capacity_)) {
- ExpandHeapStorage();
- // ExpandHeapStorage moves fields_ so we need to update the ptr to fld:
- fld = &fields_[field_id];
- PERFETTO_DCHECK(size_ < capacity_);
- }
+ PERFETTO_DCHECK(size_ < capacity_);
fields_[size_++] = *fld;
*fld = std::move(res.field);
}
@@ -225,17 +232,34 @@ void TypedProtoDecoderBase::ParseAllFields() {
}
void TypedProtoDecoderBase::ExpandHeapStorage() {
- uint32_t new_capacity = capacity_ * 2;
- PERFETTO_CHECK(new_capacity > size_);
+ // When we expand the heap we must ensure that we have at very last capacity
+ // to deal with all known fields plus at least one repeated field. We go +2048
+ // here based on observations on a large 4GB android trace. This is to avoid
+ // trivial re-allocations when dealing with repeated fields of a message that
+ // has > INITIAL_STACK_CAPACITY fields.
+ const uint32_t min_capacity = num_fields_ + 2048; // Any num >= +1 will do.
+ const uint32_t new_capacity = std::max(capacity_ * 2, min_capacity);
+ PERFETTO_CHECK(new_capacity > size_ && new_capacity > num_fields_);
std::unique_ptr<Field[]> new_storage(new Field[new_capacity]);
+ static_assert(std::is_trivially_constructible<Field>::value,
+ "Field must be trivially constructible");
static_assert(std::is_trivially_copyable<Field>::value,
"Field must be trivially copyable");
+
+ // Zero-initialize the slots for known field IDs slots, as they can be
+ // randomly accessed. Instead, there is no need to initialize the repeated
+ // slots, because they are written linearly with no gaps and are always
+ // initialized before incrementing |size_|.
+ const uint32_t new_size = std::max(size_, num_fields_);
+ memset(&new_storage[size_], 0, sizeof(Field) * (new_size - size_));
+
memcpy(&new_storage[0], fields_, sizeof(Field) * size_);
heap_storage_ = std::move(new_storage);
fields_ = &heap_storage_[0];
capacity_ = new_capacity;
+ size_ = new_size;
}
} // namespace protozero
diff --git a/src/protozero/proto_decoder_unittest.cc b/src/protozero/proto_decoder_unittest.cc
index 5f40a8918..0991f887b 100644
--- a/src/protozero/proto_decoder_unittest.cc
+++ b/src/protozero/proto_decoder_unittest.cc
@@ -72,9 +72,10 @@ TEST(ProtoDecoderTest, SkipVeryLargeFields) {
wptr = WriteVarInt(MakeTagLengthDelimited(2), wptr);
wptr = WriteVarInt(kPayloadSize, wptr);
message->AppendRawProtoBytes(raw, static_cast<size_t>(wptr - raw));
- const uint8_t padding[1024 * 128]{};
- for (size_t i = 0; i < kPayloadSize / sizeof(padding); i++)
- message->AppendRawProtoBytes(padding, sizeof(padding));
+ const size_t kPaddingSize = 1024 * 128;
+ std::unique_ptr<uint8_t[]> padding(new uint8_t[kPaddingSize]());
+ for (size_t i = 0; i < kPayloadSize / kPaddingSize; i++)
+ message->AppendRawProtoBytes(padding.get(), kPaddingSize);
// Append another valid field.
message->AppendVarInt(/*field_id=*/3, 13);
diff --git a/src/protozero/proto_ring_buffer.cc b/src/protozero/proto_ring_buffer.cc
new file mode 100644
index 000000000..631d355af
--- /dev/null
+++ b/src/protozero/proto_ring_buffer.cc
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/protozero/proto_ring_buffer.h"
+
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/paged_memory.h"
+#include "perfetto/protozero/proto_utils.h"
+
+namespace protozero {
+
+namespace {
+constexpr size_t kGrowBytes = 128 * 1024;
+
+inline ProtoRingBuffer::Message FramingError() {
+ ProtoRingBuffer::Message msg{};
+ msg.fatal_framing_error = true;
+ return msg;
+}
+
+// Tries to decode a length-delimited proto field from |start|.
+// Returns a valid boundary if the preamble is valid and the length is within
+// |end|, or an invalid message otherwise.
+ProtoRingBuffer::Message TryReadMessage(const uint8_t* start,
+ const uint8_t* end) {
+ namespace proto_utils = protozero::proto_utils;
+ uint64_t field_tag = 0;
+ auto* start_of_len = proto_utils::ParseVarInt(start, end, &field_tag);
+ if (start_of_len == start)
+ return ProtoRingBuffer::Message{}; // Not enough data.
+
+ const uint32_t tag = field_tag & 0x07;
+ if (tag !=
+ static_cast<uint32_t>(proto_utils::ProtoWireType::kLengthDelimited)) {
+ PERFETTO_ELOG("RPC framing error, unexpected msg tag 0x%xu", tag);
+ return FramingError();
+ }
+
+ uint64_t msg_len = 0;
+ auto* start_of_msg = proto_utils::ParseVarInt(start_of_len, end, &msg_len);
+ if (start_of_msg == start_of_len)
+ return ProtoRingBuffer::Message{}; // Not enough data.
+
+ if (msg_len > ProtoRingBuffer::kMaxMsgSize) {
+ PERFETTO_ELOG("RPC framing error, message too large (%" PRIu64 " > %zu)",
+ msg_len, ProtoRingBuffer::kMaxMsgSize);
+ return FramingError();
+ }
+
+ if (start_of_msg + msg_len > end)
+ return ProtoRingBuffer::Message{}; // Not enough data.
+
+ ProtoRingBuffer::Message msg{};
+ msg.start = start_of_msg;
+ msg.len = static_cast<uint32_t>(msg_len);
+ msg.field_id = static_cast<uint32_t>(field_tag >> 3);
+ return msg;
+}
+
+} // namespace
+
+ProtoRingBuffer::ProtoRingBuffer()
+ : buf_(perfetto::base::PagedMemory::Allocate(kGrowBytes)) {}
+ProtoRingBuffer::~ProtoRingBuffer() = default;
+
+void ProtoRingBuffer::Append(const void* data_void, size_t data_len) {
+ if (failed_)
+ return;
+ const uint8_t* data = static_cast<const uint8_t*>(data_void);
+ PERFETTO_DCHECK(wr_ <= buf_.size());
+ PERFETTO_DCHECK(wr_ >= rd_);
+
+ // If the last call to ReadMessage() consumed all the data in the buffer and
+ // there are no incomplete messages pending, restart from the beginning rather
+ // than keep ringing. This is the most common case.
+ if (rd_ == wr_)
+ rd_ = wr_ = 0;
+
+ // The caller is expected to always issue a ReadMessage() after each Append().
+ PERFETTO_CHECK(!fastpath_.valid());
+ if (rd_ == wr_) {
+ auto msg = TryReadMessage(data, data + data_len);
+ if (msg.valid() && msg.end() == (data + data_len)) {
+ // Fastpath: in many cases, the underlying stream will effectively
+ // preserve the atomicity of messages for most small messages.
+ // In this case we can avoid the extra buf_ roundtrip and just pass a
+ // pointer to |data| + (proto preamble len).
+ // The next call to ReadMessage)= will return |fastpath_|.
+ fastpath_ = std::move(msg);
+ return;
+ }
+ }
+
+ size_t avail = buf_.size() - wr_;
+ if (data_len > avail) {
+ // This whole section should be hit extremely rarely.
+
+ // Try first just recompacting the buffer by moving everything to the left.
+ // This can happen if we received "a message and a bit" on each Append call
+ // so we ended pup in a situation like:
+ // buf_: [unused space] [msg1 incomplete]
+ // ^rd_ ^wr_
+ //
+ // After recompaction:
+ // buf_: [msg1 incomplete]
+ // ^rd_ ^wr_
+ uint8_t* buf = static_cast<uint8_t*>(buf_.Get());
+ memmove(&buf[0], &buf[rd_], wr_ - rd_);
+ avail += rd_;
+ wr_ -= rd_;
+ rd_ = 0;
+ if (data_len > avail) {
+ // The compaction didn't free up enough space and we need to expand the
+ // ring buffer. Yes, we could have detected this earlier and split the
+ // code paths, rather than first compacting and then realizing it wasn't
+ // sufficient. However, that would make the code harder to reason about,
+ // creating code paths that are nearly never hit, hence making it more
+ // likely to accumulate bugs in future. All this is very rare.
+ size_t new_size = buf_.size();
+ while (data_len > new_size - wr_)
+ new_size += kGrowBytes;
+ if (new_size > kMaxMsgSize * 2) {
+ failed_ = true;
+ return;
+ }
+ auto new_buf = perfetto::base::PagedMemory::Allocate(new_size);
+ memcpy(new_buf.Get(), buf_.Get(), buf_.size());
+ buf_ = std::move(new_buf);
+ avail = new_size - wr_;
+ // No need to touch rd_ / wr_ cursors.
+ }
+ }
+
+ // Append the received data at the end of the ring buffer.
+ uint8_t* buf = static_cast<uint8_t*>(buf_.Get());
+ memcpy(&buf[wr_], data, data_len);
+ wr_ += data_len;
+}
+
+ProtoRingBuffer::Message ProtoRingBuffer::ReadMessage() {
+ if (failed_)
+ return FramingError();
+
+ if (fastpath_.valid()) {
+ // The fastpath can only be hit when the buffer is empty.
+ PERFETTO_CHECK(rd_ == wr_);
+ auto msg = std::move(fastpath_);
+ fastpath_ = Message{};
+ return msg;
+ }
+
+ uint8_t* buf = static_cast<uint8_t*>(buf_.Get());
+
+ PERFETTO_DCHECK(rd_ <= wr_);
+ if (rd_ >= wr_)
+ return Message{}; // Completely empty.
+
+ auto msg = TryReadMessage(&buf[rd_], &buf[wr_]);
+ if (!msg.valid()) {
+ failed_ = failed_ || msg.fatal_framing_error;
+ return msg; // Return |msg| because it could be a framing error.
+ }
+
+ // Note: msg.start is > buf[rd_], because it skips the proto preamble.
+ PERFETTO_DCHECK(msg.start > &buf[rd_]);
+ const uint8_t* msg_end = msg.start + msg.len;
+ PERFETTO_CHECK(msg_end > &buf[rd_] && msg_end <= &buf[wr_]);
+ auto msg_outer_len = static_cast<size_t>(msg_end - &buf[rd_]);
+ rd_ += msg_outer_len;
+ return msg;
+}
+
+} // namespace protozero
diff --git a/src/protozero/proto_ring_buffer.h b/src/protozero/proto_ring_buffer.h
new file mode 100644
index 000000000..d71a231c9
--- /dev/null
+++ b/src/protozero/proto_ring_buffer.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_PROTOZERO_PROTO_RING_BUFFER_H_
+#define SRC_PROTOZERO_PROTO_RING_BUFFER_H_
+
+#include <stdint.h>
+
+#include "perfetto/ext/base/paged_memory.h"
+
+namespace protozero {
+
+// This class buffers and tokenizes proto messages.
+//
+// From a logical level, it works with a sequence of protos like this.
+// [ header 1 ] [ payload 1 ]
+// [ header 2 ] [ payload 2 ]
+// [ header 3 ] [ payload 3 ]
+// Where [ header ] is a variable-length sequence of:
+// [ Field ID = 1, type = length-delimited] [ length (varint) ].
+//
+// The input to this class is byte-oriented, not message-oriented (like a TCP
+// stream or a pipe). The caller is not required to respect the boundaries of
+// each message; only guarantee that data is not lost or duplicated. The
+// following sequence of inbound events is possible:
+// 1. [ hdr 1 (incomplete) ... ]
+// 2. [ ... hdr 1 ] [ payload 1 ] [ hdr 2 ] [ payoad 2 ] [ hdr 3 ] [ pay... ]
+// 3. [ ...load 3 ]
+//
+// This class maintains inbound requests in a ring buffer.
+// The expected usage is:
+// ring_buf.Append(data, len);
+// for (;;) {
+// auto msg = ring_buf.ReadMessage();
+// if (!msg.valid())
+// break;
+// Decode(msg);
+// }
+//
+// After each call to Append, the caller is expected to call ReadMessage() until
+// it returns an invalid message (signalling no more messages could be decoded).
+// Note that a single Append can "unblock" > 1 messages, which is why the caller
+// needs to keep calling ReadMessage in a loop.
+//
+// Internal architecture
+// ---------------------
+// Internally this is similar to a ring-buffer, with the caveat that it never
+// wraps, it only expands. Expansions are rare. The deal is that in most cases
+// the read cursor follows very closely the write cursor. For instance, if the
+// underlying transport behaves as a dgram socket, after each Append, the read
+// cursor will chase completely the write cursor. Even if the underlying stream
+// is not always atomic, the expectation is that the read cursor will eventually
+// reach the write one within few messages.
+// A visual example, imagine we have four messages: 2it 4will 2be 4fine
+// Visually:
+//
+// Append("2it4wi"): A message and a bit:
+// [ 2it 4wi ]
+// ^R ^W
+//
+// After the ReadMessage(), the 1st message will be read, but not the 2nd.
+// [ 2it 4wi ]
+// ^R ^W
+//
+// Append("ll2be4f")
+// [ 2it 4will 2be 4f ]
+// ^R ^W
+//
+// After the ReadMessage() loop:
+// [ 2it 4will 2be 4f ]
+// ^R ^W
+// Append("ine")
+// [ 2it 4will 2be 4fine ]
+// ^R ^W
+//
+// In the next ReadMessage() the R cursor will chase the W cursor. When this
+// happens (very frequent) we can just reset both cursors to 0 and restart.
+// If we are unlucky and get to the end of the buffer, two things happen:
+// 1. We try first to recompact the buffer, moving everything left by R.
+// 2. If still there isn't enough space, we expand the buffer.
+// Given that each message is expected to be at most kMaxMsgSize (64 MB), the
+// expansion is bound at 2 * kMaxMsgSize.
+class ProtoRingBuffer {
+ public:
+ static constexpr size_t kMaxMsgSize = 64 * 1024 * 1024;
+ struct Message {
+ const uint8_t* start = nullptr;
+ uint32_t len = 0;
+ uint32_t field_id = 0;
+ bool fatal_framing_error = false;
+ const uint8_t* end() const { return start + len; }
+ inline bool valid() const { return !!start; }
+ };
+
+ ProtoRingBuffer();
+ ~ProtoRingBuffer();
+ ProtoRingBuffer(const ProtoRingBuffer&) = delete;
+ ProtoRingBuffer& operator=(const ProtoRingBuffer&) = delete;
+
+ // Appends data into the ring buffer, recompacting or resizing it if needed.
+ // Will invaildate the pointers previously handed out.
+ void Append(const void* data, size_t len);
+
+ // If a protobuf message can be read, it returns the boundaries of the message
+ // (without including the preamble) and advances the read cursor.
+ // If no message is avaiable, returns a null range.
+ // The returned pointer is only valid until the next call to Append(), as
+ // that can recompact or resize the underlying buffer.
+ Message ReadMessage();
+
+ // Exposed for testing.
+ size_t capacity() const { return buf_.size(); }
+ size_t avail() const { return buf_.size() - (wr_ - rd_); }
+
+ private:
+ perfetto::base::PagedMemory buf_;
+ Message fastpath_{};
+ bool failed_ = false; // Set in case of an unrecoverable framing faiulre.
+ size_t rd_ = 0; // Offset of the read cursor in |buf_|.
+ size_t wr_ = 0; // Offset of the write cursor in |buf_|.
+};
+
+} // namespace protozero
+
+#endif // SRC_PROTOZERO_PROTO_RING_BUFFER_H_
diff --git a/src/protozero/proto_ring_buffer_unittest.cc b/src/protozero/proto_ring_buffer_unittest.cc
new file mode 100644
index 000000000..263baf342
--- /dev/null
+++ b/src/protozero/proto_ring_buffer_unittest.cc
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/protozero/proto_ring_buffer.h"
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <list>
+#include <ostream>
+#include <random>
+#include <vector>
+
+#include "perfetto/ext/base/utils.h"
+#include "perfetto/protozero/proto_utils.h"
+#include "test/gtest_and_gmock.h"
+
+using testing::ElementsAre;
+
+namespace protozero {
+
+// For ASSERT_EQ()
+inline bool operator==(const ProtoRingBuffer::Message& a,
+ const ProtoRingBuffer::Message& b) {
+ if (a.field_id != b.field_id || a.len != b.len || a.valid() != b.valid())
+ return false;
+ if (!a.valid())
+ return true;
+ return memcmp(a.start, b.start, a.len) == 0;
+}
+
+inline std::ostream& operator<<(std::ostream& stream,
+ const ProtoRingBuffer::Message& msg) {
+ stream << "Message{field_id:" << msg.field_id << ", len:" << msg.len;
+ stream << ", payload: \"";
+ static constexpr uint32_t kTruncLen = 16;
+ for (uint32_t i = 0; i < std::min(msg.len, kTruncLen); i++)
+ stream << static_cast<char>(msg.start[i]);
+ if (msg.len > kTruncLen)
+ stream << "...";
+ stream << "\"}";
+ return stream;
+}
+
+namespace {
+
+using ::perfetto::base::ArraySize;
+
+constexpr uint32_t kMaxMsgSize = ProtoRingBuffer::kMaxMsgSize;
+
+class ProtoRingBufferTest : public ::testing::Test {
+ public:
+ ProtoRingBuffer::Message MakeProtoMessage(uint32_t field_id,
+ uint32_t len,
+ bool append = false) {
+ ProtoRingBuffer::Message msg{};
+ namespace proto_utils = protozero::proto_utils;
+ const uint8_t* initial_ptr = last_msg_.data();
+ if (!append)
+ last_msg_.clear();
+ size_t initial_size = last_msg_.size();
+
+ // 20 is an over-estimation of the preamble (fixed by the 2nd resize below).
+ last_msg_.resize(initial_size + len + 20);
+ uint8_t* wptr = &last_msg_[initial_size];
+ auto tag = proto_utils::MakeTagLengthDelimited(field_id);
+ wptr = proto_utils::WriteVarInt(tag, wptr);
+ wptr = proto_utils::WriteVarInt(len, wptr);
+ msg.start = wptr;
+ msg.len = len;
+ msg.field_id = field_id;
+ for (uint32_t i = 0; i < len; i++)
+ *(wptr++) = '0' + ((len + i) % 73); // 73 prime for more unique patterns.
+
+ PERFETTO_CHECK(wptr <= &last_msg_.back());
+ last_msg_.resize(static_cast<size_t>(wptr - &last_msg_[0]));
+
+ // Vector must not expand, because the returned Mesdage relies on pointer
+ // stability. The TEST_F must reserve enough capacity.
+ if (append)
+ PERFETTO_CHECK(last_msg_.data() == initial_ptr);
+ return msg;
+ }
+
+ std::vector<uint8_t> last_msg_;
+};
+
+// Test that when appending buffers that contain whole messages the ring buffer
+// is skipped.
+TEST_F(ProtoRingBufferTest, Fastpath) {
+ ProtoRingBuffer buf;
+ for (uint32_t i = 0; i < 10; i++) {
+ // Write a whole message that hits the fastpath.
+ auto expected = MakeProtoMessage(/*field_id=*/i + 1, /*len=*/i * 7);
+ buf.Append(last_msg_.data(), last_msg_.size());
+ // Shouln't take any space the buffer because it hits the fastpath.
+ EXPECT_EQ(buf.avail(), buf.capacity());
+ auto actual = buf.ReadMessage();
+ ASSERT_TRUE(actual.valid());
+ EXPECT_EQ(actual.start, expected.start); // Should point to the same buf.
+ EXPECT_EQ(actual, expected);
+
+ // Now write a message in two fragments. It won't hit the fastpath
+ expected = MakeProtoMessage(/*field_id*/ 1, /*len=*/32);
+ buf.Append(last_msg_.data(), 13);
+ EXPECT_LT(buf.avail(), buf.capacity());
+ EXPECT_FALSE(buf.ReadMessage().valid());
+
+ // Append 2nd fragment.
+ buf.Append(last_msg_.data() + 13, last_msg_.size() - 13);
+ actual = buf.ReadMessage();
+ ASSERT_TRUE(actual.valid());
+ EXPECT_EQ(actual, expected);
+ }
+}
+
+TEST_F(ProtoRingBufferTest, CoalescingStream) {
+ ProtoRingBuffer buf;
+ last_msg_.reserve(1024);
+ std::list<ProtoRingBuffer::Message> expected;
+
+ // Build 6 messages of 100 bytes each (100 does not include preambles).
+ for (uint32_t i = 1; i <= 6; i++)
+ expected.emplace_back(MakeProtoMessage(i, 100, /*append=*/true));
+
+ uint32_t frag_lens[] = {120, 20, 471, 1};
+ uint32_t frag_sum = 0;
+ for (uint32_t i = 0; i < ArraySize(frag_lens); i++)
+ frag_sum += frag_lens[i];
+ ASSERT_EQ(frag_sum, last_msg_.size());
+
+ // Append the messages in such a way that each appen either passes a portion
+ // of a message (the 20 ones) or more than a message.
+ uint32_t written = 0;
+ for (uint32_t i = 0; i < ArraySize(frag_lens); i++) {
+ buf.Append(&last_msg_[written], frag_lens[i]);
+ written += frag_lens[i];
+ for (;;) {
+ auto msg = buf.ReadMessage();
+ if (!msg.valid())
+ break;
+ ASSERT_FALSE(expected.empty());
+ ASSERT_EQ(expected.front(), msg);
+ expected.pop_front();
+ }
+ }
+ EXPECT_TRUE(expected.empty());
+}
+
+TEST_F(ProtoRingBufferTest, RandomSizes) {
+ ProtoRingBuffer buf;
+ std::minstd_rand0 rnd(0);
+
+ last_msg_.reserve(1024 * 1024 * 64);
+ std::list<ProtoRingBuffer::Message> expected;
+
+ const uint32_t kNumMsg = 100;
+ for (uint32_t i = 0; i < kNumMsg; i++) {
+ uint32_t field_id = static_cast<uint32_t>(1 + (rnd() % 1024u));
+ uint32_t rndval = static_cast<uint32_t>(rnd());
+ uint32_t len = 1 + (rndval % 1024);
+ if ((rndval % 100) < 2) {
+ len *= 10 * 1024; // 2% of messages will get close to kMaxMsgSize
+ } else if ((rndval % 100) < 20) {
+ len *= 512; // 18% will be around 500K;
+ }
+ len = std::max(std::min(len, kMaxMsgSize), 1u);
+ expected.push_back(MakeProtoMessage(field_id, len, /*append=*/true));
+ }
+
+ uint32_t total = static_cast<uint32_t>(last_msg_.size());
+ for (uint32_t frag_sum = 0; frag_sum < total;) {
+ uint32_t frag_len = static_cast<uint32_t>(1 + (rnd() % 32768));
+ frag_len = std::min(frag_len, total - frag_sum);
+ buf.Append(&last_msg_[frag_sum], frag_len);
+ frag_sum += frag_len;
+ for (;;) {
+ auto msg = buf.ReadMessage();
+ if (!msg.valid())
+ break;
+ ASSERT_FALSE(expected.empty());
+ ASSERT_EQ(expected.front(), msg);
+ expected.pop_front();
+ }
+ }
+ EXPECT_TRUE(expected.empty());
+}
+
+TEST_F(ProtoRingBufferTest, HandleProtoErrorsGracefully) {
+ ProtoRingBuffer buf;
+
+ // Apppend a partial valid 32 byte message, followed by some invalild
+ // data.
+ auto expected = MakeProtoMessage(1, 32);
+ buf.Append(last_msg_.data(), last_msg_.size() - 1);
+ auto msg = buf.ReadMessage();
+ EXPECT_FALSE(msg.valid());
+ EXPECT_FALSE(msg.fatal_framing_error);
+
+ uint8_t invalid[] = {0x7f, 0x7f, 0x7f, 0x7f};
+ invalid[0] = last_msg_.back();
+ buf.Append(invalid, sizeof(invalid));
+
+ // The first message shoudl be valild
+ msg = buf.ReadMessage();
+ EXPECT_EQ(msg, expected);
+
+ // All the rest should be a framing error.
+ for (int i = 0; i < 3; i++) {
+ msg = buf.ReadMessage();
+ EXPECT_FALSE(msg.valid());
+ EXPECT_TRUE(msg.fatal_framing_error);
+
+ buf.Append(invalid, sizeof(invalid));
+ }
+}
+
+} // namespace
+} // namespace protozero
diff --git a/src/protozero/protoc_plugin/protozero_plugin.cc b/src/protozero/protoc_plugin/protozero_plugin.cc
index 311672ab6..feabdf1b0 100644
--- a/src/protozero/protoc_plugin/protozero_plugin.cc
+++ b/src/protozero/protoc_plugin/protozero_plugin.cc
@@ -779,6 +779,10 @@ class GeneratorJob {
GenerateConstantsForMessageFields(message);
+ stub_h_->Print(
+ "static constexpr const char* GetName() { return \".$name$\"; }\n\n",
+ "name", message->full_name());
+
// Using statements for nested messages.
for (int i = 0; i < message->nested_type_count(); ++i) {
const Descriptor* nested_message = message->nested_type(i);
@@ -848,7 +852,7 @@ using $field_metadata_type$ =
// It is declared as a function to keep protozero bindings header-only as
// inline constexpr variables are not available until C++17 (while inline
// functions are).
-// TODO(altimin): Use inline variable instead after adopting C++17.
+// TODO(altimin): Use inline variable instead after adopting C++17.
static constexpr $field_metadata_type$ $field_metadata_var$() { return {}; }
)";
diff --git a/src/protozero/scattered_stream_writer.cc b/src/protozero/scattered_stream_writer.cc
index 16dd895c9..3487fb03f 100644
--- a/src/protozero/scattered_stream_writer.cc
+++ b/src/protozero/scattered_stream_writer.cc
@@ -67,6 +67,15 @@ uint8_t* ScatteredStreamWriter::ReserveBytes(size_t size) {
uint8_t* begin = write_ptr_;
write_ptr_ += size;
#if PERFETTO_DCHECK_IS_ON()
+ // In the past, the service had a matching DCHECK in
+ // TraceBuffer::TryPatchChunkContents, which was assuming that service and all
+ // producers are built with matching DCHECK levels. This turned out to be a
+ // source of problems and was removed in b/197340286. This memset is useless
+ // these days and is here only to maintain ABI compatibility between producers
+ // that use a v20+ SDK and older versions of the service that were built in
+ // debug mode. At some point around 2023 it should be safe to remove it.
+ // (running a debug version of traced in production seems a bad idea
+ // regardless).
memset(begin, 0, size);
#endif
return begin;
diff --git a/src/protozero/test/example_proto/test_messages.proto b/src/protozero/test/example_proto/test_messages.proto
index 8e710b44f..ba3e5d39c 100644
--- a/src/protozero/test/example_proto/test_messages.proto
+++ b/src/protozero/test/example_proto/test_messages.proto
@@ -101,8 +101,26 @@ message CamelCaseFields {
message PackedRepeatedFields {
repeated int32 field_int32 = 1 [packed = true];
+ repeated int64 field_int64 = 4 [packed = true];
+ repeated uint32 field_uint32 = 5 [packed = true];
+ repeated uint64 field_uint64 = 6 [packed = true];
+ // Repeated packed Zig-zag fields are currently unsupported by our protoc
+ // plugin.
+ // repeated sint32 field_sint32 = 7 [packed = true];
+ // repeated sint64 field_sint64 = 8 [packed = true];
repeated fixed32 field_fixed32 = 2 [packed = true];
+ repeated fixed64 field_fixed64 = 9 [packed = true];
+ repeated sfixed32 field_sfixed32 = 10 [packed = true];
repeated sfixed64 field_sfixed64 = 3 [packed = true];
+ repeated float field_float = 11 [packed = true];
+ repeated double field_double = 12 [packed = true];
+ // Repeated (even non-packed) bool fields are currently unsupported by our
+ // protoc plugin.
+ // repeated bool field_bool = 13 [packed = true];
+ // Repeated packed enum fields are currently unsupported by our protoc plugin.
+ // repeated SmallEnum small_enum = 51 [packed = true];
+ // repeated SignedEnum signed_enum = 52 [packed = true];
+ // repeated BigEnum big_enum = 53 [packed = true];
}
// The following two messages are for testing that unknown fields being
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index 8384f5187..ec49f719b 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -54,6 +54,30 @@ source_set("metatrace") {
]
}
+# In Bazel builds the ":demangle" target (below) should be a static_library so
+# it gets mapped to an actual target (rather than being squashed as a filegroup)
+# and can be replaced in Google internal builds via perfetto_cfg.bzl.
+# Unfortunately, however, static_library targets seem to break Wasm builds on
+# Mac. For this reason we just make it a source_set for all other build types.
+if (is_perfetto_build_generator) {
+ _demangle_target_type = "static_library"
+} else {
+ _demangle_target_type = "source_set"
+}
+
+target(_demangle_target_type, "demangle") {
+ sources = [ "demangle.cc" ]
+ deps = [
+ "../../gn:default_deps",
+ "../../include/perfetto/base",
+ "../../include/perfetto/ext/base",
+ ]
+ public_deps = [ "../../include/perfetto/ext/trace_processor:demangle" ]
+ if (enable_perfetto_llvm_demangle) {
+ deps += [ "../../gn:llvm_demangle" ]
+ }
+}
+
source_set("ftrace_descriptors") {
sources = [
"importers/ftrace/ftrace_descriptors.cc",
@@ -76,12 +100,12 @@ source_set("storage_minimal") {
"importers/ftrace/ftrace_module.h",
"importers/fuchsia/fuchsia_record.h",
"importers/fuchsia/fuchsia_trace_utils.h",
- "importers/gzip/gzip_utils.cc",
- "importers/gzip/gzip_utils.h",
"importers/json/json_utils.cc",
"importers/json/json_utils.h",
"importers/ninja/ninja_log_parser.cc",
"importers/ninja/ninja_log_parser.h",
+ "importers/proto/android_camera_event_module.cc",
+ "importers/proto/android_camera_event_module.h",
"importers/proto/async_track_set_tracker.cc",
"importers/proto/async_track_set_tracker.h",
"importers/proto/chrome_string_lookup.cc",
@@ -90,6 +114,8 @@ source_set("storage_minimal") {
"importers/proto/chrome_system_probes_module.h",
"importers/proto/chrome_system_probes_parser.cc",
"importers/proto/chrome_system_probes_parser.h",
+ "importers/proto/flamegraph_construction_algorithms.cc",
+ "importers/proto/flamegraph_construction_algorithms.h",
"importers/proto/heap_profile_tracker.cc",
"importers/proto/heap_profile_tracker.h",
"importers/proto/memory_tracker_snapshot_module.cc",
@@ -129,9 +155,12 @@ source_set("storage_minimal") {
"importers/proto/track_event_tokenizer.h",
"importers/proto/track_event_tracker.cc",
"importers/proto/track_event_tracker.h",
+ "importers/proto/translation_table_module.cc",
+ "importers/proto/translation_table_module.h",
"importers/syscalls/syscall_tracker.h",
"importers/systrace/systrace_line.h",
"timestamped_trace_piece.h",
+ "trace_blob.cc",
"trace_processor_context.cc",
"trace_processor_storage.cc",
"trace_processor_storage_impl.cc",
@@ -154,6 +183,8 @@ source_set("storage_minimal") {
"types",
"util",
"util:descriptors",
+ "util:gzip",
+ "util:interned_message_view",
"util:proto_to_args_parser",
]
public_deps = [
@@ -172,17 +203,13 @@ source_set("storage_minimal") {
"../../protos/perfetto/trace/sys_stats:zero",
"../../protos/perfetto/trace/system_info:zero",
"../../protos/perfetto/trace/track_event:zero",
+ "../../protos/perfetto/trace/translation:zero",
]
# json_utils optionally depends on jsoncpp.
if (enable_perfetto_trace_processor_json) {
deps += [ "../../gn:jsoncpp" ]
}
-
- # gzip_utils optionally depends on zlib.
- if (enable_perfetto_zlib) {
- deps += [ "../../gn:zlib" ]
- }
}
source_set("storage_full") {
@@ -213,8 +240,6 @@ source_set("storage_full") {
"importers/json/json_trace_parser.h",
"importers/json/json_trace_tokenizer.cc",
"importers/json/json_trace_tokenizer.h",
- "importers/json/json_tracker.cc",
- "importers/json/json_tracker.h",
"importers/proto/android_probes_module.cc",
"importers/proto/android_probes_module.h",
"importers/proto/android_probes_parser.cc",
@@ -270,6 +295,7 @@ source_set("storage_full") {
"tables",
"types",
"util",
+ "util:gzip",
]
if (enable_perfetto_trace_processor_json) {
deps += [ "../../gn:jsoncpp" ]
@@ -301,8 +327,8 @@ if (enable_perfetto_trace_processor_sqlite) {
"dynamic/ancestor_generator.h",
"dynamic/connected_flow_generator.cc",
"dynamic/connected_flow_generator.h",
- "dynamic/descendant_slice_generator.cc",
- "dynamic/descendant_slice_generator.h",
+ "dynamic/descendant_generator.cc",
+ "dynamic/descendant_generator.h",
"dynamic/describe_slice_generator.cc",
"dynamic/describe_slice_generator.h",
"dynamic/experimental_annotated_stack_generator.cc",
@@ -311,6 +337,8 @@ if (enable_perfetto_trace_processor_sqlite) {
"dynamic/experimental_counter_dur_generator.h",
"dynamic/experimental_flamegraph_generator.cc",
"dynamic/experimental_flamegraph_generator.h",
+ "dynamic/experimental_flat_slice_generator.cc",
+ "dynamic/experimental_flat_slice_generator.h",
"dynamic/experimental_sched_upid_generator.cc",
"dynamic/experimental_sched_upid_generator.h",
"dynamic/experimental_slice_layout_generator.cc",
@@ -326,6 +354,7 @@ if (enable_perfetto_trace_processor_sqlite) {
]
deps = [
+ ":demangle",
":export_json",
":metatrace",
":storage_full",
@@ -336,12 +365,13 @@ if (enable_perfetto_trace_processor_sqlite) {
"analysis",
"db",
"importers/common",
- "metrics:lib",
+ "metrics",
"sqlite",
"storage",
"tables",
"types",
"util",
+ "util:gzip",
"util:protozero_to_text",
]
public_deps = [
@@ -358,11 +388,12 @@ if (enable_perfetto_trace_processor_sqlite) {
":lib",
"../../gn:default_deps",
"../../gn:protobuf_full",
+ "../../protos/perfetto/trace_processor:zero",
"../../src/profiling:deobfuscator",
"../../src/profiling/symbolizer",
"../../src/profiling/symbolizer:symbolize_database",
"../base",
- "metrics:lib",
+ "metrics",
"util",
]
if (enable_perfetto_trace_processor_linenoise) {
@@ -391,6 +422,7 @@ perfetto_unittest_source_set("unittests") {
testonly = true
sources = [
"forwarding_trace_parser_unittest.cc",
+ "importers/ftrace/binder_tracker_unittest.cc",
"importers/ftrace/sched_event_tracker_unittest.cc",
"importers/fuchsia/fuchsia_trace_utils_unittest.cc",
"importers/memory_tracker/graph_processor_unittest.cc",
@@ -403,6 +435,7 @@ perfetto_unittest_source_set("unittests") {
"importers/proto/proto_trace_parser_unittest.cc",
"importers/syscalls/syscall_tracker_unittest.cc",
"importers/systrace/systrace_parser_unittest.cc",
+ "ref_counted_unittest.cc",
"trace_sorter_unittest.cc",
]
deps = [
@@ -427,6 +460,7 @@ perfetto_unittest_source_set("unittests") {
"../base",
"../protozero",
"../protozero:testing_messages_zero",
+ "containers",
"containers:unittests",
"db:unittests",
"importers/common",
@@ -444,6 +478,7 @@ perfetto_unittest_source_set("unittests") {
if (enable_perfetto_trace_processor_sqlite) {
sources += [
"dynamic/experimental_counter_dur_generator_unittest.cc",
+ "dynamic/experimental_flat_slice_generator_unittest.cc",
"dynamic/experimental_slice_layout_generator_unittest.cc",
"dynamic/thread_state_generator_unittest.cc",
]
@@ -457,7 +492,6 @@ perfetto_unittest_source_set("unittests") {
if (enable_perfetto_trace_processor_json) {
sources += [
"importers/json/json_trace_tokenizer_unittest.cc",
- "importers/json/json_tracker_unittest.cc",
"importers/json/json_utils_unittest.cc",
]
deps += [ "../../gn:jsoncpp" ]
diff --git a/src/trace_processor/OWNERS b/src/trace_processor/OWNERS
new file mode 100644
index 000000000..c360c7889
--- /dev/null
+++ b/src/trace_processor/OWNERS
@@ -0,0 +1,5 @@
+# For core Trace Processor changes.
+lalitm@google.com
+
+# For most Android-related metrics.
+ilkos@google.com
diff --git a/src/trace_processor/containers/bit_vector.h b/src/trace_processor/containers/bit_vector.h
index 20773dda9..5f9c27a08 100644
--- a/src/trace_processor/containers/bit_vector.h
+++ b/src/trace_processor/containers/bit_vector.h
@@ -491,7 +491,7 @@ class BitVector {
// mask: 00000000001111111
uint64_t mask = MaskAllBitsSetUntil(idx);
- // Finish up by anding the the atom with the computed msk.
+ // Finish up by and'ing the atom with the computed mask.
return word_ & mask;
}
diff --git a/src/trace_processor/containers/nullable_vector.h b/src/trace_processor/containers/nullable_vector.h
index 2a623c66e..2fed43019 100644
--- a/src/trace_processor/containers/nullable_vector.h
+++ b/src/trace_processor/containers/nullable_vector.h
@@ -86,15 +86,15 @@ class NullableVector : public NullableVectorBase {
base::Optional<T> Get(uint32_t idx) const {
if (mode_ == Mode::kDense) {
bool contains = valid_.Contains(idx);
- return contains ? base::Optional<T>(data_[idx]) : base::nullopt;
+ return contains ? base::make_optional(data_[idx]) : base::nullopt;
} else {
- auto opt_idx = valid_.IndexOf(idx);
- return opt_idx ? base::Optional<T>(data_[*opt_idx]) : base::nullopt;
+ auto opt_row = valid_.RowOf(idx);
+ return opt_row ? base::make_optional(data_[*opt_row]) : base::nullopt;
}
}
- // Returns the non-null value at |ordinal| where |ordinal| gives the index
- // of the entry in-terms of non-null entries only.
+ // Returns the non-null value at |non_null_idx| where |non_null_idx| gives the
+ // index of the entry in-terms of non-null entries only.
//
// For example:
// this = [0, null, 2, null, 4]
@@ -103,12 +103,12 @@ class NullableVector : public NullableVectorBase {
// GetNonNull(1) = 2
// GetNonNull(2) = 4
// ...
- T GetNonNull(uint32_t ordinal) const {
+ T GetNonNull(uint32_t non_null_idx) const {
if (mode_ == Mode::kDense) {
- return data_[valid_.Get(ordinal)];
+ return data_[valid_.Get(non_null_idx)];
} else {
- PERFETTO_DCHECK(ordinal < data_.size());
- return data_[ordinal];
+ PERFETTO_DCHECK(non_null_idx < data_.size());
+ return data_[non_null_idx];
}
}
@@ -143,18 +143,18 @@ class NullableVector : public NullableVectorBase {
}
data_[idx] = val;
} else {
- auto opt_idx = valid_.IndexOf(idx);
+ auto opt_row = valid_.RowOf(idx);
// Generally, we will be setting a null row to non-null so optimize for
// that path.
- if (PERFETTO_UNLIKELY(opt_idx)) {
- data_[*opt_idx] = val;
+ if (PERFETTO_UNLIKELY(opt_row)) {
+ data_[*opt_row] = val;
} else {
valid_.Insert(idx);
- opt_idx = valid_.IndexOf(idx);
- PERFETTO_DCHECK(opt_idx);
- data_.insert(data_.begin() + static_cast<ptrdiff_t>(*opt_idx), val);
+ opt_row = valid_.RowOf(idx);
+ PERFETTO_DCHECK(opt_row);
+ data_.insert(data_.begin() + static_cast<ptrdiff_t>(*opt_row), val);
}
}
}
@@ -166,7 +166,7 @@ class NullableVector : public NullableVectorBase {
bool IsDense() const { return mode_ == Mode::kDense; }
private:
- NullableVector(Mode mode) : mode_(mode) {}
+ explicit NullableVector(Mode mode) : mode_(mode) {}
Mode mode_ = Mode::kSparse;
diff --git a/src/trace_processor/containers/row_map.cc b/src/trace_processor/containers/row_map.cc
index 297a0ef44..ceacf9580 100644
--- a/src/trace_processor/containers/row_map.cc
+++ b/src/trace_processor/containers/row_map.cc
@@ -146,8 +146,8 @@ RowMap::RowMap() : RowMap(0, 0) {}
RowMap::RowMap(uint32_t start, uint32_t end, OptimizeFor optimize_for)
: mode_(Mode::kRange),
- start_idx_(start),
- end_idx_(end),
+ start_index_(start),
+ end_index_(end),
optimize_for_(optimize_for) {}
RowMap::RowMap(BitVector bit_vector)
@@ -159,7 +159,7 @@ RowMap::RowMap(std::vector<uint32_t> vec)
RowMap RowMap::Copy() const {
switch (mode_) {
case Mode::kRange:
- return RowMap(start_idx_, end_idx_);
+ return RowMap(start_index_, end_index_);
case Mode::kBitVector:
return RowMap(bit_vector_.Copy());
case Mode::kIndexVector:
@@ -176,20 +176,22 @@ RowMap RowMap::SelectRowsSlow(const RowMap& selector) const {
case Mode::kRange:
switch (mode_) {
case Mode::kRange:
- return SelectRangeWithRange(start_idx_, end_idx_, selector.start_idx_,
- selector.end_idx_);
+ return SelectRangeWithRange(start_index_, end_index_,
+ selector.start_index_,
+ selector.end_index_);
case Mode::kBitVector:
- return SelectBvWithRange(bit_vector_, selector.start_idx_,
- selector.end_idx_);
+ return SelectBvWithRange(bit_vector_, selector.start_index_,
+ selector.end_index_);
case Mode::kIndexVector:
- return SelectIvWithRange(index_vector_, selector.start_idx_,
- selector.end_idx_);
+ return SelectIvWithRange(index_vector_, selector.start_index_,
+ selector.end_index_);
}
break;
case Mode::kBitVector:
switch (mode_) {
case Mode::kRange:
- return SelectRangeWithBv(start_idx_, end_idx_, selector.bit_vector_);
+ return SelectRangeWithBv(start_index_, end_index_,
+ selector.bit_vector_);
case Mode::kBitVector:
return SelectBvWithBv(bit_vector_, selector.bit_vector_);
case Mode::kIndexVector:
@@ -199,7 +201,7 @@ RowMap RowMap::SelectRowsSlow(const RowMap& selector) const {
case Mode::kIndexVector:
switch (mode_) {
case Mode::kRange:
- return SelectRangeWithIv(start_idx_, end_idx_,
+ return SelectRangeWithIv(start_index_, end_index_,
selector.index_vector_);
case Mode::kBitVector:
return SelectBvWithIv(bit_vector_, selector.index_vector_);
diff --git a/src/trace_processor/containers/row_map.h b/src/trace_processor/containers/row_map.h
index cb39ac1b1..5ca3c9c04 100644
--- a/src/trace_processor/containers/row_map.h
+++ b/src/trace_processor/containers/row_map.h
@@ -34,6 +34,20 @@ namespace trace_processor {
// columns can refer to the same RowMap. The RowMap defines the access pattern
// to iterate on rows.
//
+// Naming convention:
+//
+// As both the input and output of RowMap is a uint32_t, it can be quite
+// confusing to reason about what parameters/return values of the functions
+// of RowMap actually means. To help with this, we define a strict convention
+// of naming.
+//
+// row: input - that is, rows are what are passed into operator[]; named as
+// such because a "row" number in a table is converted to an index to
+// lookup in the backing vectors.
+// index: output - that is, indices are what are returned from operator[];
+// named as such because an "index" is what's used to lookup data
+// from the backing vectors.
+//
// Implementation details:
//
// Behind the scenes, this class is impelemented using one of three backing
@@ -69,15 +83,15 @@ class RowMap {
// BitVector::SetBitsIterator.
class RangeIterator {
public:
- RangeIterator(const RowMap* rm) : rm_(rm), index_(rm->start_idx_) {}
+ RangeIterator(const RowMap* rm) : rm_(rm), index_(rm->start_index_) {}
void Next() { ++index_; }
- operator bool() const { return index_ < rm_->end_idx_; }
+ operator bool() const { return index_ < rm_->end_index_; }
uint32_t index() const { return index_; }
- uint32_t ordinal() const { return index_ - rm_->start_idx_; }
+ uint32_t ordinal() const { return index_ - rm_->start_index_; }
private:
const RowMap* rm_ = nullptr;
@@ -105,6 +119,10 @@ class RowMap {
};
public:
+ // Input type.
+ using InputRow = uint32_t;
+ using OutputIndex = uint32_t;
+
// Allows efficient iteration over the rows of a RowMap.
//
// Note: you should usually prefer to use the methods on RowMap directly (if
@@ -158,12 +176,8 @@ class RowMap {
PERFETTO_FATAL("For GCC");
}
- // Returns the row pointed to by this iterator.
- uint32_t row() const {
- // RowMap uses the row/index nomenclature for referring to the mapping
- // from index to a row (as the name suggests). However, the data
- // structures used by RowMap use the index/ordinal naming (because they
- // don't have the concept of a "row"). Switch the naming here.
+ // Returns the index pointed to by this iterator.
+ OutputIndex index() const {
switch (rm_->mode_) {
case Mode::kRange:
return range_it_->index();
@@ -175,12 +189,8 @@ class RowMap {
PERFETTO_FATAL("For GCC");
}
- // Returns the index of the row the iterator points to.
- uint32_t index() const {
- // RowMap uses the row/index nomenclature for referring to the mapping
- // from index to a row (as the name suggests). However, the data
- // structures used by RowMap use the index/ordinal naming (because they
- // don't have the concept of a "row"). Switch the naming here.
+ // Returns the row of the index the iterator points to.
+ InputRow row() const {
switch (rm_->mode_) {
case Mode::kRange:
return range_it_->ordinal();
@@ -216,21 +226,23 @@ class RowMap {
// By default this will be implemented using a range.
RowMap();
- // Creates a RowMap containing the range of rows between |start| and |end|
- // i.e. all rows between |start| (inclusive) and |end| (exclusive).
- explicit RowMap(uint32_t start,
- uint32_t end,
+ // Creates a RowMap containing the range of indices between |start| and |end|
+ // i.e. all indices between |start| (inclusive) and |end| (exclusive).
+ explicit RowMap(OutputIndex start,
+ OutputIndex end,
OptimizeFor optimize_for = OptimizeFor::kMemory);
// Creates a RowMap backed by a BitVector.
explicit RowMap(BitVector bit_vector);
// Creates a RowMap backed by an std::vector<uint32_t>.
- explicit RowMap(std::vector<uint32_t> vec);
+ explicit RowMap(std::vector<OutputIndex> vec);
- // Creates a RowMap containing just |row|.
+ // Creates a RowMap containing just |index|.
// By default this will be implemented using a range.
- static RowMap SingleRow(uint32_t row) { return RowMap(row, row + 1); }
+ static RowMap SingleRow(OutputIndex index) {
+ return RowMap(index, index + 1);
+ }
// Creates a copy of the RowMap.
// We have an explicit copy function because RowMap can hold onto large chunks
@@ -238,11 +250,12 @@ class RowMap {
// accidental leaks and copies.
RowMap Copy() const;
- // Returns the size of the RowMap; that is the number of rows in the RowMap.
+ // Returns the size of the RowMap; that is the number of indices in the
+ // RowMap.
uint32_t size() const {
switch (mode_) {
case Mode::kRange:
- return end_idx_ - start_idx_;
+ return end_index_ - start_index_;
case Mode::kBitVector:
return bit_vector_.GetNumBitsSet();
case Mode::kIndexVector:
@@ -254,54 +267,54 @@ class RowMap {
// Returns whether this rowmap is empty.
bool empty() const { return size() == 0; }
- // Returns the row at index |row|.
- uint32_t Get(uint32_t idx) const {
- PERFETTO_DCHECK(idx < size());
+ // Returns the index at the given |row|.
+ OutputIndex Get(InputRow row) const {
+ PERFETTO_DCHECK(row < size());
switch (mode_) {
case Mode::kRange:
- return GetRange(idx);
+ return GetRange(row);
case Mode::kBitVector:
- return GetBitVector(idx);
+ return GetBitVector(row);
case Mode::kIndexVector:
- return GetIndexVector(idx);
+ return GetIndexVector(row);
}
PERFETTO_FATAL("For GCC");
}
- // Returns whether the RowMap contains the given row.
- bool Contains(uint32_t row) const {
+ // Returns whether the RowMap contains the given index.
+ bool Contains(OutputIndex index) const {
switch (mode_) {
case Mode::kRange: {
- return row >= start_idx_ && row < end_idx_;
+ return index >= start_index_ && index < end_index_;
}
case Mode::kBitVector: {
- return row < bit_vector_.size() && bit_vector_.IsSet(row);
+ return index < bit_vector_.size() && bit_vector_.IsSet(index);
}
case Mode::kIndexVector: {
- auto it = std::find(index_vector_.begin(), index_vector_.end(), row);
+ auto it = std::find(index_vector_.begin(), index_vector_.end(), index);
return it != index_vector_.end();
}
}
PERFETTO_FATAL("For GCC");
}
- // Returns the first index of the given |row| in the RowMap.
- base::Optional<uint32_t> IndexOf(uint32_t row) const {
+ // Returns the first row of the given |index| in the RowMap.
+ base::Optional<InputRow> RowOf(OutputIndex index) const {
switch (mode_) {
case Mode::kRange: {
- if (row < start_idx_ || row >= end_idx_)
+ if (index < start_index_ || index >= end_index_)
return base::nullopt;
- return row - start_idx_;
+ return index - start_index_;
}
case Mode::kBitVector: {
- return row < bit_vector_.size() && bit_vector_.IsSet(row)
- ? base::make_optional(bit_vector_.GetNumBitsSet(row))
+ return index < bit_vector_.size() && bit_vector_.IsSet(index)
+ ? base::make_optional(bit_vector_.GetNumBitsSet(index))
: base::nullopt;
}
case Mode::kIndexVector: {
- auto it = std::find(index_vector_.begin(), index_vector_.end(), row);
+ auto it = std::find(index_vector_.begin(), index_vector_.end(), index);
return it != index_vector_.end()
- ? base::make_optional(static_cast<uint32_t>(
+ ? base::make_optional(static_cast<InputRow>(
std::distance(index_vector_.begin(), it)))
: base::nullopt;
}
@@ -309,8 +322,8 @@ class RowMap {
PERFETTO_FATAL("For GCC");
}
- // Performs an ordered insert the row into the current RowMap (precondition:
- // this RowMap is ordered based on the rows it contains).
+ // Performs an ordered insert of the index into the current RowMap
+ // (precondition: this RowMap is ordered based on the indices it contains).
//
// Example:
// this = [1, 5, 10, 11, 20]
@@ -320,41 +333,41 @@ class RowMap {
// Insert(2) // this = [1, 2, 5, 10, 11, 12, 20, 21]
//
// Speecifically, this means that it is only valid to call Insert on a RowMap
- // which is sorted by the rows it contains; this is automatically true when
+ // which is sorted by the indices it contains; this is automatically true when
// the RowMap is in range or BitVector mode but is a required condition for
// IndexVector mode.
- void Insert(uint32_t row) {
+ void Insert(OutputIndex index) {
switch (mode_) {
case Mode::kRange:
- if (row == end_idx_) {
+ if (index == end_index_) {
// Fast path: if we're just appending to the end of the range, we can
// stay in range mode and just bump the end index.
- end_idx_++;
+ end_index_++;
} else {
// Slow path: the insert is somewhere else other than the end. This
// means we need to switch to using a BitVector instead.
- bit_vector_.Resize(start_idx_, false);
- bit_vector_.Resize(end_idx_, true);
+ bit_vector_.Resize(start_index_, false);
+ bit_vector_.Resize(end_index_, true);
*this = RowMap(std::move(bit_vector_));
- InsertIntoBitVector(row);
+ InsertIntoBitVector(index);
}
break;
case Mode::kBitVector:
- InsertIntoBitVector(row);
+ InsertIntoBitVector(index);
break;
case Mode::kIndexVector: {
PERFETTO_DCHECK(
std::is_sorted(index_vector_.begin(), index_vector_.end()));
auto it =
- std::upper_bound(index_vector_.begin(), index_vector_.end(), row);
- index_vector_.insert(it, row);
+ std::upper_bound(index_vector_.begin(), index_vector_.end(), index);
+ index_vector_.insert(it, index);
break;
}
}
}
- // Updates this RowMap by 'picking' the rows at indicies given by |picker|.
+ // Updates this RowMap by 'picking' the indices given by |picker|.
// This is easiest to explain with an example; suppose we have the following
// RowMaps:
// this : [0, 1, 4, 10, 11]
@@ -365,8 +378,8 @@ class RowMap {
//
// Conceptually, we are performing the following algorithm:
// RowMap rm = Copy()
- // for (idx : picker)
- // rm[i++] = this[idx]
+ // for (p : picker)
+ // rm[i++] = this[p]
// return rm;
RowMap SelectRows(const RowMap& selector) const {
uint32_t size = selector.size();
@@ -385,8 +398,8 @@ class RowMap {
}
// Intersects |other| with |this| writing the result into |this|.
- // By "intersect", we mean to keep only the rows present in both RowMaps. The
- // order of the preserved rows will be the same as |this|.
+ // By "intersect", we mean to keep only the indices present in both RowMaps.
+ // The order of the preserved indices will be the same as |this|.
//
// Conceptually, we are performing the following algorithm:
// for (idx : this)
@@ -398,8 +411,9 @@ class RowMap {
// of them as the new RowMap.
// We have this as an explicit fast path as this is very common for
// constraints on id and sorted columns to satisfy this condition.
- start_idx_ = std::max(start_idx_, other.start_idx_);
- end_idx_ = std::max(start_idx_, std::min(end_idx_, other.end_idx_));
+ start_index_ = std::max(start_index_, other.start_index_);
+ end_index_ =
+ std::max(start_index_, std::min(end_index_, other.end_index_));
return;
}
@@ -410,7 +424,7 @@ class RowMap {
// Filters the current RowMap into the RowMap given by |out| based on the
// return value of |p(idx)|.
//
- // Precondition: |out| should be sorted by the rows inside it (this is
+ // Precondition: |out| should be sorted by the indices inside it (this is
// required to keep this method efficient). This is automatically true if the
// mode is out is Range or BitVector but needs to be enforced if the mode is
// IndexVector.
@@ -450,13 +464,13 @@ class RowMap {
// cases where |out| has only a few entries so we can scan |out| instead of
// scanning |this|.
- // Ideally, we'd always just scan the rows in |out| and keep those which
+ // Ideally, we'd always just scan |out| and keep the indices in |this| which
// meet |p|. However, if |this| is a BitVector, we end up needing expensive
- // |IndexOfNthSet| calls (as we need to lookup the row before passing it to
- // |p|).
+ // |IndexOfNthSet| calls (as we need to convert the row to an index before
+ // passing it to |p|).
switch (mode_) {
case Mode::kRange: {
- auto ip = [this, p](uint32_t idx) { return p(GetRange(idx)); };
+ auto ip = [this, p](uint32_t row) { return p(GetRange(row)); };
out->Filter(ip);
break;
}
@@ -542,12 +556,12 @@ class RowMap {
case Mode::kRange: {
// TODO(lalitm): investigate whether we can reuse the data inside
// out->bit_vector_ at some point.
- BitVector bv(out->end_idx_, false);
+ BitVector bv(out->end_index_, false);
for (auto out_it = bv.IterateAllBits(); it; it.Next(), out_it.Next()) {
uint32_t ordinal = it.ordinal();
- if (ordinal < out->start_idx_)
+ if (ordinal < out->start_index_)
continue;
- if (ordinal >= out->end_idx_)
+ if (ordinal >= out->end_index_)
break;
if (p(it.index())) {
@@ -587,16 +601,16 @@ class RowMap {
template <typename Predicate>
void FilterRange(Predicate p) {
- uint32_t count = end_idx_ - start_idx_;
+ uint32_t count = end_index_ - start_index_;
- // Optimization: if we are only going to scan a few rows, it's not
+ // Optimization: if we are only going to scan a few indices, it's not
// worth the haslle of working with a BitVector.
constexpr uint32_t kSmallRangeLimit = 2048;
bool is_small_range = count < kSmallRangeLimit;
// Optimization: weif the cost of a BitVector is more than the highest
// possible cost an index vector could have, use the index vector.
- uint32_t bit_vector_cost = BitVector::ApproxBytesCost(end_idx_);
+ uint32_t bit_vector_cost = BitVector::ApproxBytesCost(end_index_);
uint32_t index_vector_cost_ub = sizeof(uint32_t) * count;
// If either of the conditions hold which make it better to use an
@@ -608,21 +622,21 @@ class RowMap {
// big and good performance.
std::vector<uint32_t> iv(std::min(kSmallRangeLimit, count));
- uint32_t out_idx = 0;
+ uint32_t out_i = 0;
for (uint32_t i = 0; i < count; ++i) {
// If we reach the capacity add another small set of indices.
- if (PERFETTO_UNLIKELY(out_idx == iv.size()))
+ if (PERFETTO_UNLIKELY(out_i == iv.size()))
iv.resize(iv.size() + kSmallRangeLimit);
// We keep this branch free by always writing the index but only
// incrementing the out index if the return value is true.
- bool value = p(i + start_idx_);
- iv[out_idx] = i + start_idx_;
- out_idx += value;
+ bool value = p(i + start_index_);
+ iv[out_i] = i + start_index_;
+ out_i += value;
}
// Make the vector the correct size and as small as possible.
- iv.resize(out_idx);
+ iv.resize(out_i);
iv.shrink_to_fit();
*this = RowMap(std::move(iv));
@@ -631,7 +645,7 @@ class RowMap {
// Otherwise, create a bitvector which spans the full range using
// |p| as the filler for the bits between start and end.
- *this = RowMap(BitVector::Range(start_idx_, end_idx_, p));
+ *this = RowMap(BitVector::Range(start_index_, end_index_, p));
}
void InsertIntoBitVector(uint32_t row) {
@@ -642,17 +656,17 @@ class RowMap {
bit_vector_.Set(row);
}
- PERFETTO_ALWAYS_INLINE uint32_t GetRange(uint32_t idx) const {
+ PERFETTO_ALWAYS_INLINE OutputIndex GetRange(InputRow row) const {
PERFETTO_DCHECK(mode_ == Mode::kRange);
- return start_idx_ + idx;
+ return start_index_ + row;
}
- PERFETTO_ALWAYS_INLINE uint32_t GetBitVector(uint32_t idx) const {
+ PERFETTO_ALWAYS_INLINE OutputIndex GetBitVector(uint32_t row) const {
PERFETTO_DCHECK(mode_ == Mode::kBitVector);
- return bit_vector_.IndexOfNthSet(idx);
+ return bit_vector_.IndexOfNthSet(row);
}
- PERFETTO_ALWAYS_INLINE uint32_t GetIndexVector(uint32_t idx) const {
+ PERFETTO_ALWAYS_INLINE OutputIndex GetIndexVector(uint32_t row) const {
PERFETTO_DCHECK(mode_ == Mode::kIndexVector);
- return index_vector_[idx];
+ return index_vector_[row];
}
RowMap SelectRowsSlow(const RowMap& selector) const;
@@ -660,14 +674,14 @@ class RowMap {
Mode mode_ = Mode::kRange;
// Only valid when |mode_| == Mode::kRange.
- uint32_t start_idx_ = 0; // This is an inclusive index.
- uint32_t end_idx_ = 0; // This is an exclusive index.
+ OutputIndex start_index_ = 0; // This is an inclusive index.
+ OutputIndex end_index_ = 0; // This is an exclusive index.
// Only valid when |mode_| == Mode::kBitVector.
BitVector bit_vector_;
// Only valid when |mode_| == Mode::kIndexVector.
- std::vector<uint32_t> index_vector_;
+ std::vector<OutputIndex> index_vector_;
OptimizeFor optimize_for_ = OptimizeFor::kMemory;
};
diff --git a/src/trace_processor/containers/row_map_unittest.cc b/src/trace_processor/containers/row_map_unittest.cc
index ac54cb12f..16022b2ef 100644
--- a/src/trace_processor/containers/row_map_unittest.cc
+++ b/src/trace_processor/containers/row_map_unittest.cc
@@ -34,11 +34,11 @@ TEST(RowMapUnittest, SmokeRange) {
ASSERT_EQ(rm.Get(1), 31u);
ASSERT_EQ(rm.Get(16), 46u);
- ASSERT_EQ(rm.IndexOf(29), base::nullopt);
- ASSERT_EQ(rm.IndexOf(30), 0u);
- ASSERT_EQ(rm.IndexOf(37), 7u);
- ASSERT_EQ(rm.IndexOf(46), 16u);
- ASSERT_EQ(rm.IndexOf(47), base::nullopt);
+ ASSERT_EQ(rm.RowOf(29), base::nullopt);
+ ASSERT_EQ(rm.RowOf(30), 0u);
+ ASSERT_EQ(rm.RowOf(37), 7u);
+ ASSERT_EQ(rm.RowOf(46), 16u);
+ ASSERT_EQ(rm.RowOf(47), base::nullopt);
}
TEST(RowMapUnittest, SmokeBitVector) {
@@ -50,12 +50,12 @@ TEST(RowMapUnittest, SmokeBitVector) {
ASSERT_EQ(rm.Get(1u), 4u);
ASSERT_EQ(rm.Get(2u), 5u);
- ASSERT_EQ(rm.IndexOf(0u), 0u);
- ASSERT_EQ(rm.IndexOf(4u), 1u);
- ASSERT_EQ(rm.IndexOf(5u), 2u);
+ ASSERT_EQ(rm.RowOf(0u), 0u);
+ ASSERT_EQ(rm.RowOf(4u), 1u);
+ ASSERT_EQ(rm.RowOf(5u), 2u);
- ASSERT_EQ(rm.IndexOf(1u), base::nullopt);
- ASSERT_EQ(rm.IndexOf(100u), base::nullopt);
+ ASSERT_EQ(rm.RowOf(1u), base::nullopt);
+ ASSERT_EQ(rm.RowOf(100u), base::nullopt);
}
TEST(RowMapUnittest, SmokeIndexVector) {
@@ -70,12 +70,12 @@ TEST(RowMapUnittest, SmokeIndexVector) {
ASSERT_EQ(rm.Get(4u), 100u);
ASSERT_EQ(rm.Get(5u), 1u);
- ASSERT_EQ(rm.IndexOf(32u), 0u);
- ASSERT_EQ(rm.IndexOf(56u), 1u);
- ASSERT_EQ(rm.IndexOf(24u), 2u);
- ASSERT_EQ(rm.IndexOf(0u), 3u);
- ASSERT_EQ(rm.IndexOf(100u), 4u);
- ASSERT_EQ(rm.IndexOf(1u), 5u);
+ ASSERT_EQ(rm.RowOf(32u), 0u);
+ ASSERT_EQ(rm.RowOf(56u), 1u);
+ ASSERT_EQ(rm.RowOf(24u), 2u);
+ ASSERT_EQ(rm.RowOf(0u), 3u);
+ ASSERT_EQ(rm.RowOf(100u), 4u);
+ ASSERT_EQ(rm.RowOf(1u), 5u);
}
TEST(RowMapUnittest, InsertToRangeAfter) {
@@ -84,7 +84,7 @@ TEST(RowMapUnittest, InsertToRangeAfter) {
ASSERT_EQ(rm.size(), 5u);
ASSERT_EQ(rm.Get(4u), 10u);
- ASSERT_EQ(rm.IndexOf(10u), 4u);
+ ASSERT_EQ(rm.RowOf(10u), 4u);
}
TEST(RowMapUnittest, InsertToBitVectorBefore) {
@@ -105,7 +105,7 @@ TEST(RowMapUnittest, InsertToBitVectorAfter) {
ASSERT_EQ(rm.size(), 5u);
ASSERT_EQ(rm.Get(4u), 10u);
- ASSERT_EQ(rm.IndexOf(10u), 4u);
+ ASSERT_EQ(rm.RowOf(10u), 4u);
}
TEST(RowMapUnittest, InsertToIndexVectorAfter) {
@@ -114,7 +114,7 @@ TEST(RowMapUnittest, InsertToIndexVectorAfter) {
ASSERT_EQ(rm.size(), 5u);
ASSERT_EQ(rm.Get(4u), 10u);
- ASSERT_EQ(rm.IndexOf(10u), 4u);
+ ASSERT_EQ(rm.RowOf(10u), 4u);
}
TEST(RowMapUnittest, ContainsRange) {
diff --git a/src/trace_processor/containers/string_pool.cc b/src/trace_processor/containers/string_pool.cc
index fd651958f..018905400 100644
--- a/src/trace_processor/containers/string_pool.cc
+++ b/src/trace_processor/containers/string_pool.cc
@@ -53,8 +53,8 @@ StringPool::StringPool() {
StringPool::~StringPool() = default;
-StringPool::StringPool(StringPool&&) = default;
-StringPool& StringPool::operator=(StringPool&&) = default;
+StringPool::StringPool(StringPool&&) noexcept = default;
+StringPool& StringPool::operator=(StringPool&&) noexcept = default;
StringPool::Id StringPool::InsertString(base::StringView str, uint64_t hash) {
// Try and find enough space in the current block for the string and the
@@ -70,9 +70,8 @@ StringPool::Id StringPool::InsertString(base::StringView str, uint64_t hash) {
// new block to store the string.
if (str.size() + kMaxMetadataSize >= kMinLargeStringSizeBytes) {
return InsertLargeString(str, hash);
- } else {
- blocks_.emplace_back(kBlockSizeBytes);
}
+ blocks_.emplace_back(kBlockSizeBytes);
// Try and reserve space again - this time we should definitely succeed.
std::tie(success, offset) = blocks_.back().TryInsert(str);
@@ -82,7 +81,11 @@ StringPool::Id StringPool::InsertString(base::StringView str, uint64_t hash) {
// Compute the id from the block index and offset and add a mapping from the
// hash to the id.
Id string_id = Id::BlockString(blocks_.size() - 1, offset);
- string_index_.emplace(hash, string_id);
+
+ // Deliberately not adding |string_id| to |string_index_|. The caller
+ // (InternString()) must take care of this.
+ PERFETTO_DCHECK(string_index_.Find(hash));
+
return string_id;
}
@@ -91,7 +94,11 @@ StringPool::Id StringPool::InsertLargeString(base::StringView str,
large_strings_.emplace_back(new std::string(str.begin(), str.size()));
// Compute id from the index and add a mapping from the hash to the id.
Id string_id = Id::LargeString(large_strings_.size() - 1);
- string_index_.emplace(hash, string_id);
+
+ // Deliberately not adding |string_id| to |string_index_|. The caller
+ // (InternString()) must take care of this.
+ PERFETTO_DCHECK(string_index_.Find(hash));
+
return string_id;
}
diff --git a/src/trace_processor/containers/string_pool.h b/src/trace_processor/containers/string_pool.h
index 241240c7e..8d5e22f38 100644
--- a/src/trace_processor/containers/string_pool.h
+++ b/src/trace_processor/containers/string_pool.h
@@ -21,9 +21,10 @@
#include <stdint.h>
#include <limits>
-#include <unordered_map>
#include <vector>
+#include "perfetto/ext/base/flat_hash_map.h"
+#include "perfetto/ext/base/hash.h"
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/paged_memory.h"
#include "perfetto/protozero/proto_utils.h"
@@ -106,8 +107,8 @@ class StringPool {
~StringPool();
// Allow std::move().
- StringPool(StringPool&&);
- StringPool& operator=(StringPool&&);
+ StringPool(StringPool&&) noexcept;
+ StringPool& operator=(StringPool&&) noexcept;
// Disable implicit copy.
StringPool(const StringPool&) = delete;
@@ -118,12 +119,17 @@ class StringPool {
return Id::Null();
auto hash = str.Hash();
- auto id_it = string_index_.find(hash);
- if (id_it != string_index_.end()) {
- PERFETTO_DCHECK(Get(id_it->second) == str);
- return id_it->second;
+
+ // Perform a hashtable insertion with a null ID just to check if the string
+ // is already inserted. If it's not, overwrite 0 with the actual Id.
+ auto it_and_inserted = string_index_.Insert(hash, Id());
+ Id* id = it_and_inserted.first;
+ if (!it_and_inserted.second) {
+ PERFETTO_DCHECK(Get(*id) == str);
+ return *id;
}
- return InsertString(str, hash);
+ *id = InsertString(str, hash);
+ return *id;
}
base::Optional<Id> GetId(base::StringView str) const {
@@ -131,10 +137,10 @@ class StringPool {
return Id::Null();
auto hash = str.Hash();
- auto id_it = string_index_.find(hash);
- if (id_it != string_index_.end()) {
- PERFETTO_DCHECK(Get(id_it->second) == str);
- return id_it->second;
+ Id* id = string_index_.Find(hash);
+ if (id) {
+ PERFETTO_DCHECK(Get(*id) == str);
+ return *id;
}
return base::nullopt;
}
@@ -286,9 +292,12 @@ class StringPool {
std::vector<std::unique_ptr<std::string>> large_strings_;
// Maps hashes of strings to the Id in the string pool.
- // TODO(lalitm): At some point we should benchmark just using a static
- // hashtable of 1M elements, we can afford paying a fixed 8MB here
- std::unordered_map<StringHash, Id> string_index_;
+ base::FlatHashMap<StringHash,
+ Id,
+ base::AlreadyHashed<StringHash>,
+ base::LinearProbe,
+ /*AppendOnly=*/true>
+ string_index_{/*initial_capacity=*/1024u * 1024u};
};
} // namespace trace_processor
diff --git a/src/trace_processor/db/column.cc b/src/trace_processor/db/column.cc
index 00496b335..3339c82a3 100644
--- a/src/trace_processor/db/column.cc
+++ b/src/trace_processor/db/column.cc
@@ -69,10 +69,19 @@ Column::Column(const char* name,
PERFETTO_CHECK(nullable_vector<StringPool::Id>().IsDense() == IsDense());
break;
case ColumnType::kId:
+ case ColumnType::kDummy:
break;
}
}
+Column Column::DummyColumn(const char* name,
+ Table* table,
+ uint32_t col_idx_in_table) {
+ return Column(name, ColumnType::kDummy, Flag::kNoFlag, table,
+ col_idx_in_table, std::numeric_limits<uint32_t>::max(), nullptr,
+ nullptr);
+}
+
Column Column::IdColumn(Table* table, uint32_t col_idx, uint32_t row_map_idx) {
return Column("id", ColumnType::kId, kIdFlags, table, col_idx, row_map_idx,
nullptr, nullptr);
@@ -128,6 +137,8 @@ void Column::FilterIntoSlow(FilterOp op, SqlValue value, RowMap* rm) const {
FilterIntoIdSlow(op, value, rm);
break;
}
+ case ColumnType::kDummy:
+ PERFETTO_FATAL("FilterIntoSlow not allowed on dummy column");
}
}
@@ -443,6 +454,9 @@ void Column::StableSort(std::vector<uint32_t>* out) const {
int res = compare::Numeric(a_idx, b_idx);
return desc ? res > 0 : res < 0;
});
+ break;
+ case ColumnType::kDummy:
+ PERFETTO_FATAL("StableSort not allowed on dummy column");
}
}
@@ -469,6 +483,7 @@ void Column::StableSortNumeric(std::vector<uint32_t>* out) const {
}
const RowMap& Column::row_map() const {
+ PERFETTO_DCHECK(type_ != ColumnType::kDummy);
return table_->row_maps_[row_map_idx_];
}
diff --git a/src/trace_processor/db/column.h b/src/trace_processor/db/column.h
index 9df9f70a6..ba0a981d6 100644
--- a/src/trace_processor/db/column.h
+++ b/src/trace_processor/db/column.h
@@ -69,11 +69,6 @@ struct Order {
bool desc;
};
-// Represents a column which is to be joined on.
-struct JoinKey {
- uint32_t col_idx;
-};
-
class Table;
// Represents a named, strongly typed list of data.
@@ -201,6 +196,11 @@ class Column {
row_map_idx, ptr, std::move(storage));
}
+ // Creates a Column which does not have any data backing it.
+ static Column DummyColumn(const char* name,
+ Table* table,
+ uint32_t col_idx_in_table);
+
// Creates a Column which returns the index as the value of the row.
static Column IdColumn(Table* table,
uint32_t col_idx_in_table,
@@ -229,8 +229,10 @@ class Column {
case ColumnType::kId: {
if (value.type != SqlValue::Type::kLong)
return base::nullopt;
- return row_map().IndexOf(static_cast<uint32_t>(value.long_value));
+ return row_map().RowOf(static_cast<uint32_t>(value.long_value));
}
+ case ColumnType::kDummy:
+ PERFETTO_FATAL("IndexOf not allowed on dummy column");
}
PERFETTO_FATAL("For GCC");
}
@@ -265,6 +267,8 @@ class Column {
case ColumnType::kId: {
PERFETTO_FATAL("Cannot set value on a id column");
}
+ case ColumnType::kDummy:
+ PERFETTO_FATAL("Set not allowed on dummy column");
}
}
@@ -330,6 +334,9 @@ class Column {
// Returns true if this column is considered an id column.
bool IsId() const { return type_ == ColumnType::kId; }
+ // Returns true if this column is a dummy column.
+ bool IsDummy() const { return type_ == ColumnType::kDummy; }
+
// Returns true if this column is a nullable column.
bool IsNullable() const { return (flags_ & Flag::kNonNull) == 0; }
@@ -389,9 +396,6 @@ class Column {
Order ascending() const { return Order{col_idx_in_table_, false}; }
Order descending() const { return Order{col_idx_in_table_, true}; }
- // Returns the JoinKey for this Column.
- JoinKey join_key() const { return JoinKey{col_idx_in_table_}; }
-
// Returns an iterator to the first entry in this column.
Iterator begin() const { return Iterator(this, 0); }
@@ -434,6 +438,9 @@ class Column {
// Types generated on the fly.
kId,
+
+ // Types which don't have any data backing them.
+ kDummy,
};
friend class Table;
@@ -476,6 +483,8 @@ class Column {
}
case ColumnType::kId:
return SqlValue::Long(idx);
+ case ColumnType::kDummy:
+ PERFETTO_FATAL("GetAtIdx not allowed on dummy column");
}
PERFETTO_FATAL("For GCC");
}
@@ -586,6 +595,8 @@ class Column {
return SqlValue::Type::kDouble;
case ColumnType::kString:
return SqlValue::Type::kString;
+ case ColumnType::kDummy:
+ PERFETTO_FATAL("ToSqlValueType not allowed on dummy column");
}
PERFETTO_FATAL("For GCC");
}
diff --git a/src/trace_processor/db/table.cc b/src/trace_processor/db/table.cc
index 940d8b10b..019df2020 100644
--- a/src/trace_processor/db/table.cc
+++ b/src/trace_processor/db/table.cc
@@ -144,57 +144,5 @@ Table Table::Sort(const std::vector<Order>& od) const {
return table;
}
-Table Table::LookupJoin(JoinKey left, const Table& other, JoinKey right) {
- // The join table will have the same size and RowMaps as the left (this)
- // table because the left column is indexing the right table.
- Table table(string_pool_, nullptr);
- table.row_count_ = row_count_;
- for (const RowMap& rm : row_maps_) {
- table.row_maps_.emplace_back(rm.Copy());
- }
-
- for (const Column& col : columns_) {
- // We skip id columns as they are misleading on join tables.
- if (col.IsId())
- continue;
- table.columns_.emplace_back(col, &table, table.columns_.size(),
- col.row_map_idx_);
- }
-
- const Column& left_col = columns_[left.col_idx];
- const Column& right_col = other.columns_[right.col_idx];
-
- // For each index in the left column, retrieve the index of the row inside
- // the RowMap of the right column. By getting the index of the row rather
- // than the row number itself, we can call |Apply| on the other RowMaps
- // in the right table.
- std::vector<uint32_t> indices(row_count_);
- for (uint32_t i = 0; i < row_count_; ++i) {
- SqlValue val = left_col.Get(i);
- PERFETTO_CHECK(val.type != SqlValue::Type::kNull);
- indices[i] = right_col.IndexOf(val).value();
- }
-
- // Apply the computed RowMap to each of the right RowMaps, adding it to the
- // join table as we go.
- RowMap rm(std::move(indices));
- for (const RowMap& ot : other.row_maps_) {
- table.row_maps_.emplace_back(ot.SelectRows(rm));
- }
-
- uint32_t left_row_maps_size = static_cast<uint32_t>(row_maps_.size());
- for (const Column& col : other.columns_) {
- // We skip id columns as they are misleading on join tables.
- if (col.IsId())
- continue;
-
- // Ensure that we offset the RowMap index by the number of RowMaps in the
- // left table.
- table.columns_.emplace_back(col, &table, table.columns_.size(),
- col.row_map_idx_ + left_row_maps_size);
- }
- return table;
-}
-
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/db/table.h b/src/trace_processor/db/table.h
index fb8b73b3d..cb54d53e2 100644
--- a/src/trace_processor/db/table.h
+++ b/src/trace_processor/db/table.h
@@ -38,7 +38,7 @@ class Table {
// Iterator over the rows of the table.
class Iterator {
public:
- Iterator(const Table* table) : table_(table) {
+ explicit Iterator(const Table* table) : table_(table) {
for (const auto& rm : table->row_maps()) {
its_.emplace_back(rm.IterateRows());
}
@@ -60,7 +60,7 @@ class Table {
// Returns the value at the current row for column |col_idx|.
SqlValue Get(uint32_t col_idx) const {
const auto& col = table_->columns_[col_idx];
- return col.GetAtIdx(its_[col.row_map_idx_].row());
+ return col.GetAtIdx(its_[col.row_map_idx_].index());
}
private:
@@ -134,22 +134,6 @@ class Table {
// Sorts the Table using the specified order by constraints.
Table Sort(const std::vector<Order>& od) const;
- // Joins |this| table with the |other| table using the values of column |left|
- // of |this| table to lookup the row in |right| column of the |other| table.
- //
- // Concretely, for each row in the returned table we lookup the value of
- // |left| in |right|. The found row is used as the values for |other|'s
- // columns in the returned table.
- //
- // This means we obtain the following invariants:
- // 1. this->size() == ret->size()
- // 2. this->Rows()[i].Get(j) == ret->Rows()[i].Get(j)
- //
- // It also means there are few restrictions on the data in |left| and |right|:
- // * |left| is not allowed to have any nulls.
- // * |left|'s values must exist in |right|
- Table LookupJoin(JoinKey left, const Table& other, JoinKey right);
-
// Extends the table with a new column called |name| with data |sv|.
template <typename T>
Table ExtendWithColumn(const char* name,
diff --git a/src/trace_processor/db/typed_column.h b/src/trace_processor/db/typed_column.h
index a8fc42450..d28683401 100644
--- a/src/trace_processor/db/typed_column.h
+++ b/src/trace_processor/db/typed_column.h
@@ -162,7 +162,7 @@ template <typename Id>
struct IdColumn : public Column {
Id operator[](uint32_t row) const { return Id(row_map().Get(row)); }
base::Optional<uint32_t> IndexOf(Id id) const {
- return row_map().IndexOf(id.value);
+ return row_map().RowOf(id.value);
}
// Reinterpret cast a Column to IdColumn or crash if that is likely to be
diff --git a/src/trace_processor/demangle.cc b/src/trace_processor/demangle.cc
new file mode 100644
index 000000000..c44f834c4
--- /dev/null
+++ b/src/trace_processor/demangle.cc
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/ext/trace_processor/demangle.h"
+
+#include <string.h>
+#include <string>
+
+#include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_LLVM_DEMANGLE)
+#include "llvm/Demangle/Demangle.h"
+#elif !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <cxxabi.h>
+#endif
+
+namespace perfetto {
+namespace trace_processor {
+namespace demangle {
+
+// Implementation depends on platform and build config. If llvm demangling
+// sources are available, use them. That is the most portable and handles more
+// than just Itanium mangling (e.g. Rust's _R scheme). Otherwise use the c++
+// standard library demangling if it implements the appropriate ABI. This
+// excludes Windows builds, where we therefore never demangle.
+// TODO(rsavitski): consider reimplementing llvm::demangle inline as it's
+// wrapping in std::strings a set of per-scheme demangling functions that
+// operate on C strings. Right now we're introducing yet another layer that
+// undoes that conversion.
+std::unique_ptr<char, base::FreeDeleter> Demangle(const char* mangled_name) {
+#if PERFETTO_BUILDFLAG(PERFETTO_LLVM_DEMANGLE)
+ std::string input(mangled_name);
+ std::string demangled = llvm::demangle(input);
+ if (demangled == input)
+ return nullptr; // demangling unsuccessful
+
+ std::unique_ptr<char, base::FreeDeleter> output(
+ static_cast<char*>(malloc(demangled.size() + 1)));
+ if (!output)
+ return nullptr;
+ memcpy(output.get(), demangled.c_str(), demangled.size() + 1);
+ return output;
+
+#elif !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ int ignored = 0;
+ return std::unique_ptr<char, base::FreeDeleter>(
+ abi::__cxa_demangle(mangled_name, nullptr, nullptr, &ignored));
+
+#else
+ return nullptr;
+#endif
+}
+
+} // namespace demangle
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/dynamic/ancestor_generator.cc b/src/trace_processor/dynamic/ancestor_generator.cc
index 3db6d3d51..1621a37a3 100644
--- a/src/trace_processor/dynamic/ancestor_generator.cc
+++ b/src/trace_processor/dynamic/ancestor_generator.cc
@@ -20,6 +20,7 @@
#include <set>
#include "src/trace_processor/types/trace_processor_context.h"
+#include "src/trace_processor/util/status_macros.h"
namespace perfetto {
namespace trace_processor {
@@ -31,23 +32,32 @@ uint32_t GetConstraintColumnIndex(AncestorGenerator::Ancestor type,
return context->storage->slice_table().GetColumnCount();
case AncestorGenerator::Ancestor::kStackProfileCallsite:
return context->storage->stack_profile_callsite_table().GetColumnCount();
+ case AncestorGenerator::Ancestor::kSliceByStack:
+ return context->storage->slice_table().GetColumnCount();
}
return 0;
}
template <typename T>
-base::Optional<RowMap> BuildAncestorsRowMap(const T& table,
- typename T::Id starting_id) {
- auto start_row = table.id().IndexOf(starting_id);
+Table ExtendTableWithStartId(const T& table, int64_t constraint_value) {
+ // Add a new column that includes the constraint.
+ std::unique_ptr<NullableVector<int64_t>> child_ids(
+ new NullableVector<int64_t>());
+ for (uint32_t i = 0; i < table.row_count(); ++i)
+ child_ids->Append(constraint_value);
+ return table.ExtendWithColumn(
+ "start_id", std::move(child_ids),
+ TypedColumn<uint32_t>::default_flags() | TypedColumn<uint32_t>::kHidden);
+}
+template <typename T>
+base::Status BuildAncestorsRowMap(const T& table,
+ typename T::Id starting_id,
+ RowMap& rowmap_return) {
+ auto start_row = table.id().IndexOf(starting_id);
if (!start_row) {
- // TODO(lalitm): Ideally this should result in an error, or be filtered out
- // during ValidateConstraints so we can just dereference |start_row|
- // directly. However ValidateConstraints doesn't know the value we're
- // filtering for so can't ensure it exists. For now we return a nullptr
- // which will cause the query to surface an error with the message "SQL
- // error: constraint failed".
- return base::nullopt;
+ return base::ErrStatus("no row with id %" PRIu32 "",
+ static_cast<uint32_t>(starting_id.value));
}
std::vector<uint32_t> parent_rows;
@@ -58,27 +68,25 @@ base::Optional<RowMap> BuildAncestorsRowMap(const T& table,
// Update the loop variable by looking up the next parent_id.
maybe_parent_id = table.parent_id()[parent_row];
}
- return RowMap(std::move(parent_rows));
+ rowmap_return = RowMap{parent_rows};
+ return base::OkStatus();
}
+// Constraint_value is used to construct the hidden column "start_id"
+// needed by SQL.
+// Starting_id refers to the id that is used to generate the ancestors.
template <typename T>
-std::unique_ptr<Table> BuildAncestorsTable(const T& table,
- typename T::Id starting_id) {
+base::Status BuildAncestorsTable(int64_t constraint_value,
+ const T& table,
+ typename T::Id starting_id,
+ std::unique_ptr<Table>& table_return) {
// Build up all the parents row ids.
- auto ancestors = BuildAncestorsRowMap(table, starting_id);
- if (!ancestors) {
- return nullptr;
- }
- // Add a new column that includes the constraint.
- std::unique_ptr<NullableVector<uint32_t>> child_ids(
- new NullableVector<uint32_t>());
- for (uint32_t i = 0; i < ancestors->size(); ++i)
- child_ids->Append(starting_id.value);
- return std::unique_ptr<Table>(
- new Table(table.Apply(std::move(*ancestors))
- .ExtendWithColumn("start_id", std::move(child_ids),
- TypedColumn<uint32_t>::default_flags() |
- TypedColumn<uint32_t>::kHidden)));
+ RowMap ancestors;
+ RETURN_IF_ERROR(BuildAncestorsRowMap(table, starting_id, ancestors));
+
+ table_return.reset(new Table(ExtendTableWithStartId(
+ table.Apply(std::move(ancestors)), constraint_value)));
+ return base::OkStatus();
}
} // namespace
@@ -86,7 +94,7 @@ AncestorGenerator::AncestorGenerator(Ancestor type,
TraceProcessorContext* context)
: type_(type), context_(context) {}
-util::Status AncestorGenerator::ValidateConstraints(
+base::Status AncestorGenerator::ValidateConstraints(
const QueryConstraints& qc) {
const auto& cs = qc.constraints();
@@ -95,30 +103,69 @@ util::Status AncestorGenerator::ValidateConstraints(
return c.column == column && c.op == SQLITE_INDEX_CONSTRAINT_EQ;
};
bool has_id_cs = std::find_if(cs.begin(), cs.end(), id_fn) != cs.end();
- return has_id_cs ? util::OkStatus()
- : util::ErrStatus("Failed to find required constraints");
+ return has_id_cs ? base::OkStatus()
+ : base::ErrStatus("Failed to find required constraints");
}
-std::unique_ptr<Table> AncestorGenerator::ComputeTable(
+base::Status AncestorGenerator::ComputeTable(
const std::vector<Constraint>& cs,
- const std::vector<Order>&) {
+ const std::vector<Order>&,
+ const BitVector&,
+ std::unique_ptr<Table>& table_return) {
uint32_t column = GetConstraintColumnIndex(type_, context_);
- auto it = std::find_if(cs.begin(), cs.end(), [column](const Constraint& c) {
- return c.col_idx == column && c.op == FilterOp::kEq;
- });
- PERFETTO_DCHECK(it != cs.end());
+ auto constraint_it =
+ std::find_if(cs.begin(), cs.end(), [column](const Constraint& c) {
+ return c.col_idx == column && c.op == FilterOp::kEq;
+ });
+ PERFETTO_DCHECK(constraint_it != cs.end());
+ if (constraint_it == cs.end() ||
+ constraint_it->value.type != SqlValue::Type::kLong) {
+ return base::ErrStatus("invalid start_id");
+ }
+ auto start_id = constraint_it->value.AsLong();
- auto start_id = static_cast<uint32_t>(it->value.AsLong());
switch (type_) {
- case Ancestor::kSlice:
- return BuildAncestorsTable(context_->storage->slice_table(),
- SliceId(start_id));
- case Ancestor::kStackProfileCallsite:
- return BuildAncestorsTable(
+ case Ancestor::kSlice: {
+ RETURN_IF_ERROR(BuildAncestorsTable(
+ /* constraint_id = */ start_id, context_->storage->slice_table(),
+ /* starting_id = */ SliceId(static_cast<uint32_t>(start_id)),
+ table_return));
+ return base::OkStatus();
+ }
+
+ case Ancestor::kStackProfileCallsite: {
+ RETURN_IF_ERROR(BuildAncestorsTable(
+ /* constraint_id = */ start_id,
context_->storage->stack_profile_callsite_table(),
- CallsiteId(start_id));
+ /* starting_id = */ CallsiteId(static_cast<uint32_t>(start_id)),
+ table_return));
+ return base::OkStatus();
+ }
+
+ case Ancestor::kSliceByStack: {
+ // Find the all slice ids that have the stack id and find all the
+ // ancestors of the slice ids.
+ const auto& slice_table = context_->storage->slice_table();
+
+ auto result = RowMap();
+ auto slice_ids =
+ slice_table.FilterToRowMap({slice_table.stack_id().eq(start_id)});
+
+ for (auto id_it = slice_ids.IterateRows(); id_it; id_it.Next()) {
+ auto slice_id = slice_table.id()[id_it.index()];
+
+ auto ancestors = GetAncestorSlices(slice_table, slice_id);
+ for (auto row_it = ancestors->IterateRows(); row_it; row_it.Next()) {
+ result.Insert(row_it.index());
+ }
+ }
+
+ table_return.reset(new Table(ExtendTableWithStartId(
+ slice_table.Apply(std::move(result)), start_id)));
+ return base::OkStatus();
+ }
}
- return nullptr;
+ return base::ErrStatus("unknown AncestorGenerator type");
}
Table::Schema AncestorGenerator::CreateSchema() {
@@ -130,6 +177,9 @@ Table::Schema AncestorGenerator::CreateSchema() {
case Ancestor::kStackProfileCallsite:
final_schema = tables::StackProfileCallsiteTable::Schema();
break;
+ case Ancestor::kSliceByStack:
+ final_schema = tables::SliceTable::Schema();
+ break;
}
final_schema.columns.push_back(Table::Schema::Column{
"start_id", SqlValue::Type::kLong, /* is_id = */ false,
@@ -143,6 +193,8 @@ std::string AncestorGenerator::TableName() {
return "ancestor_slice";
case Ancestor::kStackProfileCallsite:
return "experimental_ancestor_stack_profile_callsite";
+ case Ancestor::kSliceByStack:
+ return "ancestor_slice_by_stack";
}
return "ancestor_unknown";
}
@@ -155,7 +207,11 @@ uint32_t AncestorGenerator::EstimateRowCount() {
base::Optional<RowMap> AncestorGenerator::GetAncestorSlices(
const tables::SliceTable& slices,
SliceId slice_id) {
- return BuildAncestorsRowMap(slices, slice_id);
+ RowMap ret;
+ auto status = BuildAncestorsRowMap(slices, slice_id, ret);
+ if (!status.ok())
+ return base::nullopt;
+ return std::move(ret); // -Wreturn-std-move-in-c++11
}
} // namespace trace_processor
diff --git a/src/trace_processor/dynamic/ancestor_generator.h b/src/trace_processor/dynamic/ancestor_generator.h
index bf6324e9a..00679bea1 100644
--- a/src/trace_processor/dynamic/ancestor_generator.h
+++ b/src/trace_processor/dynamic/ancestor_generator.h
@@ -30,20 +30,27 @@ class TraceProcessorContext;
// Implements the following dynamic tables:
// * ancestor_slice
// * experimental_ancestor_stack_profile_callsite
+// * ancestor_slice_by_stack
//
// See docs/analysis/trace-processor for usage.
class AncestorGenerator : public DbSqliteTable::DynamicTableGenerator {
public:
- enum class Ancestor { kSlice = 1, kStackProfileCallsite = 2 };
+ enum class Ancestor {
+ kSlice = 1,
+ kStackProfileCallsite = 2,
+ kSliceByStack = 3
+ };
AncestorGenerator(Ancestor type, TraceProcessorContext* context);
Table::Schema CreateSchema() override;
std::string TableName() override;
uint32_t EstimateRowCount() override;
- util::Status ValidateConstraints(const QueryConstraints&) override;
- std::unique_ptr<Table> ComputeTable(const std::vector<Constraint>& cs,
- const std::vector<Order>& ob) override;
+ base::Status ValidateConstraints(const QueryConstraints&) override;
+ base::Status ComputeTable(const std::vector<Constraint>& cs,
+ const std::vector<Order>& ob,
+ const BitVector& cols_used,
+ std::unique_ptr<Table>& table_return) override;
// Returns a RowMap of slice IDs which are ancestors of |slice_id|. Returns
// NULL if an invalid |slice_id| is given. This is used by
diff --git a/src/trace_processor/dynamic/connected_flow_generator.cc b/src/trace_processor/dynamic/connected_flow_generator.cc
index c8fb57d24..8dbefa1e3 100644
--- a/src/trace_processor/dynamic/connected_flow_generator.cc
+++ b/src/trace_processor/dynamic/connected_flow_generator.cc
@@ -21,7 +21,7 @@
#include <set>
#include "src/trace_processor/dynamic/ancestor_generator.h"
-#include "src/trace_processor/dynamic/descendant_slice_generator.h"
+#include "src/trace_processor/dynamic/descendant_generator.h"
#include "src/trace_processor/importers/common/flow_tracker.h"
#include "src/trace_processor/types/trace_processor_context.h"
@@ -34,7 +34,7 @@ ConnectedFlowGenerator::ConnectedFlowGenerator(Mode mode,
ConnectedFlowGenerator::~ConnectedFlowGenerator() = default;
-util::Status ConnectedFlowGenerator::ValidateConstraints(
+base::Status ConnectedFlowGenerator::ValidateConstraints(
const QueryConstraints& qc) {
const auto& cs = qc.constraints();
@@ -47,8 +47,8 @@ util::Status ConnectedFlowGenerator::ValidateConstraints(
std::find_if(cs.begin(), cs.end(), flow_id_fn) != cs.end();
return has_flow_id_cs
- ? util::OkStatus()
- : util::ErrStatus("Failed to find required constraints");
+ ? base::OkStatus()
+ : base::ErrStatus("Failed to find required constraints");
}
namespace {
@@ -127,7 +127,7 @@ class BFS {
}
if (visit_relatives & VISIT_DESCENDANTS) {
base::Optional<RowMap> descendants =
- DescendantSliceGenerator::GetDescendantSlices(
+ DescendantGenerator::GetDescendantSlices(
context_->storage->slice_table(), slice_id);
GoToRelativesImpl(descendants->IterateRows());
}
@@ -162,8 +162,8 @@ class BFS {
auto rows = flow.FilterToRowMap({start_col.eq(slice_id.value)});
for (auto row_it = rows.IterateRows(); row_it; row_it.Next()) {
- flow_rows_.push_back(row_it.row());
- SliceId next_slice_id = end_col[row_it.row()];
+ flow_rows_.push_back(row_it.index());
+ SliceId next_slice_id = end_col[row_it.index()];
if (known_slices_.count(next_slice_id) != 0) {
continue;
}
@@ -179,7 +179,7 @@ class BFS {
void GoToRelativesImpl(RowMap::Iterator it) {
const auto& slice = context_->storage->slice_table();
for (; it; it.Next()) {
- auto relative_slice_id = slice.id()[it.row()];
+ auto relative_slice_id = slice.id()[it.index()];
if (known_slices_.count(relative_slice_id))
continue;
known_slices_.insert(relative_slice_id);
@@ -196,23 +196,27 @@ class BFS {
} // namespace
-std::unique_ptr<Table> ConnectedFlowGenerator::ComputeTable(
+base::Status ConnectedFlowGenerator::ComputeTable(
const std::vector<Constraint>& cs,
- const std::vector<Order>&) {
+ const std::vector<Order>&,
+ const BitVector&,
+ std::unique_ptr<Table>& table_return) {
const auto& flow = context_->storage->flow_table();
const auto& slice = context_->storage->slice_table();
auto it = std::find_if(cs.begin(), cs.end(), [&flow](const Constraint& c) {
return c.col_idx == flow.GetColumnCount() && c.op == FilterOp::kEq;
});
-
PERFETTO_DCHECK(it != cs.end());
+ if (it == cs.end() || it->value.type != SqlValue::Type::kLong) {
+ return base::ErrStatus("invalid start_id");
+ }
SliceId start_id{static_cast<uint32_t>(it->value.AsLong())};
if (!slice.id().IndexOf(start_id)) {
- PERFETTO_ELOG("Given slice id is invalid (ConnectedFlowGenerator)");
- return nullptr;
+ return base::ErrStatus("invalid slice id %" PRIu32 "",
+ static_cast<uint32_t>(start_id.value));
}
BFS bfs(context_);
@@ -240,11 +244,12 @@ std::unique_ptr<Table> ConnectedFlowGenerator::ComputeTable(
start_ids->Append(start_id.value);
}
- return std::unique_ptr<Table>(
+ table_return.reset(
new Table(flow.Apply(RowMap(std::move(result_rows)))
.ExtendWithColumn("start_id", std::move(start_ids),
TypedColumn<uint32_t>::default_flags() |
TypedColumn<uint32_t>::kHidden)));
+ return base::OkStatus();
}
Table::Schema ConnectedFlowGenerator::CreateSchema() {
diff --git a/src/trace_processor/dynamic/connected_flow_generator.h b/src/trace_processor/dynamic/connected_flow_generator.h
index e6d01b302..0b8661b73 100644
--- a/src/trace_processor/dynamic/connected_flow_generator.h
+++ b/src/trace_processor/dynamic/connected_flow_generator.h
@@ -53,9 +53,11 @@ class ConnectedFlowGenerator : public DbSqliteTable::DynamicTableGenerator {
Table::Schema CreateSchema() override;
std::string TableName() override;
uint32_t EstimateRowCount() override;
- util::Status ValidateConstraints(const QueryConstraints&) override;
- std::unique_ptr<Table> ComputeTable(const std::vector<Constraint>& cs,
- const std::vector<Order>& ob) override;
+ base::Status ValidateConstraints(const QueryConstraints&) override;
+ base::Status ComputeTable(const std::vector<Constraint>& cs,
+ const std::vector<Order>& ob,
+ const BitVector& cols_used,
+ std::unique_ptr<Table>& table_return) override;
private:
Mode mode_;
diff --git a/src/trace_processor/dynamic/descendant_generator.cc b/src/trace_processor/dynamic/descendant_generator.cc
new file mode 100644
index 000000000..c0df1cdf8
--- /dev/null
+++ b/src/trace_processor/dynamic/descendant_generator.cc
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/dynamic/descendant_generator.h"
+
+#include <memory>
+#include <set>
+
+#include "src/trace_processor/types/trace_processor_context.h"
+#include "src/trace_processor/util/status_macros.h"
+
+namespace perfetto {
+namespace trace_processor {
+namespace {
+uint32_t GetConstraintColumnIndex(TraceProcessorContext* context) {
+ return context->storage->slice_table().GetColumnCount();
+}
+
+template <typename T>
+Table ExtendTableWithStartId(const T& table, int64_t constraint_value) {
+ // Add a new column that includes the constraint.
+ std::unique_ptr<NullableVector<int64_t>> child_ids(
+ new NullableVector<int64_t>());
+ for (uint32_t i = 0; i < table.row_count(); ++i)
+ child_ids->Append(constraint_value);
+ return table.ExtendWithColumn(
+ "start_id", std::move(child_ids),
+ TypedColumn<uint32_t>::default_flags() | TypedColumn<uint32_t>::kHidden);
+}
+
+base::Status BuildDescendantsRowMap(const tables::SliceTable& slices,
+ SliceId starting_id,
+ RowMap& rowmap_return) {
+ auto start_row = slices.id().IndexOf(starting_id);
+ // The query gave an invalid ID that doesn't exist in the slice table.
+ if (!start_row) {
+ return base::ErrStatus("no row with id %" PRIu32 "",
+ static_cast<uint32_t>(starting_id.value));
+ }
+
+ // All nested descendents must be on the same track, with a ts between
+ // |start_id.ts| and |start_id.ts| + |start_id.dur|, and who's depth is larger
+ // then |start_row|'s. So we just use Filter to select all relevant slices.
+ rowmap_return = slices.FilterToRowMap(
+ {slices.ts().ge(slices.ts()[*start_row]),
+ slices.ts().le(slices.ts()[*start_row] + slices.dur()[*start_row]),
+ slices.track_id().eq(slices.track_id()[*start_row].value),
+ slices.depth().gt(slices.depth()[*start_row])});
+ return base::OkStatus();
+}
+
+base::Status BuildDescendantsTable(int64_t constraint_value,
+ const tables::SliceTable& slices,
+ SliceId starting_id,
+ std::unique_ptr<Table>& table_return) {
+ // Build up all the children row ids.
+ RowMap descendants;
+ RETURN_IF_ERROR(BuildDescendantsRowMap(slices, starting_id, descendants));
+
+ table_return.reset(new Table(ExtendTableWithStartId(
+ slices.Apply(std::move(descendants)), constraint_value)));
+ return base::OkStatus();
+}
+} // namespace
+
+DescendantGenerator::DescendantGenerator(Descendant type,
+ TraceProcessorContext* context)
+ : type_(type), context_(context) {}
+
+base::Status DescendantGenerator::ValidateConstraints(
+ const QueryConstraints& qc) {
+ const auto& cs = qc.constraints();
+
+ int column = static_cast<int>(GetConstraintColumnIndex(context_));
+ auto id_fn = [column](const QueryConstraints::Constraint& c) {
+ return c.column == column && c.op == SQLITE_INDEX_CONSTRAINT_EQ;
+ };
+ bool has_id_cs = std::find_if(cs.begin(), cs.end(), id_fn) != cs.end();
+ return has_id_cs ? base::OkStatus()
+ : base::ErrStatus("Failed to find required constraints");
+}
+
+base::Status DescendantGenerator::ComputeTable(
+ const std::vector<Constraint>& cs,
+ const std::vector<Order>&,
+ const BitVector&,
+ std::unique_ptr<Table>& table_return) {
+ const auto& slices = context_->storage->slice_table();
+
+ uint32_t column = GetConstraintColumnIndex(context_);
+ auto constraint_it =
+ std::find_if(cs.begin(), cs.end(), [column](const Constraint& c) {
+ return c.col_idx == column && c.op == FilterOp::kEq;
+ });
+ PERFETTO_DCHECK(constraint_it != cs.end());
+ if (constraint_it == cs.end() ||
+ constraint_it->value.type != SqlValue::Type::kLong) {
+ return base::ErrStatus("invalid start_id");
+ }
+ auto start_id = constraint_it->value.AsLong();
+
+ switch (type_) {
+ case Descendant::kSlice: {
+ RETURN_IF_ERROR(BuildDescendantsTable(
+ start_id, slices, SliceId(static_cast<uint32_t>(start_id)),
+ table_return));
+ return base::OkStatus();
+ }
+
+ case Descendant::kSliceByStack: {
+ auto result = RowMap();
+ auto slice_ids = slices.FilterToRowMap({slices.stack_id().eq(start_id)});
+
+ for (auto id_it = slice_ids.IterateRows(); id_it; id_it.Next()) {
+ auto slice_id = slices.id()[id_it.index()];
+
+ auto descendants = GetDescendantSlices(slices, slice_id);
+ for (auto row_it = descendants->IterateRows(); row_it; row_it.Next()) {
+ result.Insert(row_it.index());
+ }
+ }
+
+ table_return.reset(new Table(
+ ExtendTableWithStartId(slices.Apply(std::move(result)), start_id)));
+ return base::OkStatus();
+ }
+ }
+ return base::ErrStatus("unknown DescendantGenerator type");
+}
+
+Table::Schema DescendantGenerator::CreateSchema() {
+ auto schema = tables::SliceTable::Schema();
+ schema.columns.push_back(Table::Schema::Column{
+ "start_id", SqlValue::Type::kLong, /* is_id = */ false,
+ /* is_sorted = */ false, /* is_hidden = */ true});
+ return schema;
+}
+
+std::string DescendantGenerator::TableName() {
+ switch (type_) {
+ case Descendant::kSlice:
+ return "descendant_slice";
+ case Descendant::kSliceByStack:
+ return "descendant_slice_by_stack";
+ }
+ return "descendant_unknown";
+}
+
+uint32_t DescendantGenerator::EstimateRowCount() {
+ return 1;
+}
+
+// static
+base::Optional<RowMap> DescendantGenerator::GetDescendantSlices(
+ const tables::SliceTable& slices,
+ SliceId slice_id) {
+ RowMap ret;
+ auto status = BuildDescendantsRowMap(slices, slice_id, ret);
+ if (!status.ok())
+ return base::nullopt;
+ return std::move(ret); // -Wreturn-std-move-in-c++11
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/dynamic/descendant_generator.h b/src/trace_processor/dynamic/descendant_generator.h
new file mode 100644
index 000000000..318fe7d0b
--- /dev/null
+++ b/src/trace_processor/dynamic/descendant_generator.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_DYNAMIC_DESCENDANT_GENERATOR_H_
+#define SRC_TRACE_PROCESSOR_DYNAMIC_DESCENDANT_GENERATOR_H_
+
+#include "src/trace_processor/sqlite/db_sqlite_table.h"
+
+#include "perfetto/ext/base/optional.h"
+#include "src/trace_processor/storage/trace_storage.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class TraceProcessorContext;
+
+// Implements the following dynamic tables:
+// * descendant_slice
+// * descendant_slice_by_stack
+//
+// See docs/analysis/trace-processor for usage.
+class DescendantGenerator : public DbSqliteTable::DynamicTableGenerator {
+ public:
+ enum class Descendant { kSlice = 1, kSliceByStack = 2 };
+
+ DescendantGenerator(Descendant type, TraceProcessorContext* context);
+
+ Table::Schema CreateSchema() override;
+ std::string TableName() override;
+ uint32_t EstimateRowCount() override;
+ base::Status ValidateConstraints(const QueryConstraints&) override;
+ base::Status ComputeTable(const std::vector<Constraint>& cs,
+ const std::vector<Order>& ob,
+ const BitVector& cols_used,
+ std::unique_ptr<Table>& table_return) override;
+
+ // Returns a RowMap of slice IDs which are descendants of |slice_id|. Returns
+ // NULL if an invalid |slice_id| is given. This is used by
+ // ConnectedFlowGenerator to traverse flow indirectly connected flow events.
+ static base::Optional<RowMap> GetDescendantSlices(
+ const tables::SliceTable& slices,
+ SliceId slice_id);
+
+ private:
+ Descendant type_;
+ TraceProcessorContext* context_ = nullptr;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_DYNAMIC_DESCENDANT_GENERATOR_H_
diff --git a/src/trace_processor/dynamic/descendant_slice_generator.cc b/src/trace_processor/dynamic/descendant_slice_generator.cc
deleted file mode 100644
index d42a6a92a..000000000
--- a/src/trace_processor/dynamic/descendant_slice_generator.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/trace_processor/dynamic/descendant_slice_generator.h"
-
-#include <memory>
-#include <set>
-
-#include "src/trace_processor/types/trace_processor_context.h"
-
-namespace perfetto {
-namespace trace_processor {
-
-DescendantSliceGenerator::DescendantSliceGenerator(
- TraceProcessorContext* context)
- : context_(context) {}
-
-DescendantSliceGenerator::~DescendantSliceGenerator() = default;
-
-util::Status DescendantSliceGenerator::ValidateConstraints(
- const QueryConstraints& qc) {
- const auto& cs = qc.constraints();
-
- auto slice_id_fn = [this](const QueryConstraints::Constraint& c) {
- return c.column == static_cast<int>(
- context_->storage->slice_table().GetColumnCount()) &&
- c.op == SQLITE_INDEX_CONSTRAINT_EQ;
- };
- bool has_slice_id_cs =
- std::find_if(cs.begin(), cs.end(), slice_id_fn) != cs.end();
-
- return has_slice_id_cs
- ? util::OkStatus()
- : util::ErrStatus("Failed to find required constraints");
-}
-
-std::unique_ptr<Table> DescendantSliceGenerator::ComputeTable(
- const std::vector<Constraint>& cs,
- const std::vector<Order>&) {
- const auto& slice = context_->storage->slice_table();
-
- auto it = std::find_if(cs.begin(), cs.end(), [&slice](const Constraint& c) {
- return c.col_idx == slice.GetColumnCount() && c.op == FilterOp::kEq;
- });
- PERFETTO_DCHECK(it != cs.end());
-
- uint32_t start_id = static_cast<uint32_t>(it->value.AsLong());
- auto descendants = GetDescendantSlices(slice, SliceId(start_id));
- if (!descendants)
- return nullptr;
- Table reduced_slice = slice.Apply(std::move(*descendants));
-
- // For every row extend it to match the schema, and return it.
- std::unique_ptr<NullableVector<uint32_t>> start_ids(
- new NullableVector<uint32_t>());
- for (size_t i = 0; i < reduced_slice.row_count(); ++i) {
- start_ids->Append(start_id);
- }
- return std::unique_ptr<Table>(
- new Table(std::move(reduced_slice)
- .ExtendWithColumn("start_id", std::move(start_ids),
- TypedColumn<uint32_t>::default_flags() |
- TypedColumn<uint32_t>::kHidden)));
-}
-
-Table::Schema DescendantSliceGenerator::CreateSchema() {
- auto schema = tables::SliceTable::Schema();
- schema.columns.push_back(Table::Schema::Column{
- "start_id", SqlValue::Type::kLong, /* is_id = */ false,
- /* is_sorted = */ false, /* is_hidden = */ true});
- return schema;
-}
-
-std::string DescendantSliceGenerator::TableName() {
- return "descendant_slice";
-}
-
-uint32_t DescendantSliceGenerator::EstimateRowCount() {
- return 1;
-}
-
-// static
-base::Optional<RowMap> DescendantSliceGenerator::GetDescendantSlices(
- const tables::SliceTable& slice,
- SliceId start_id) {
- auto start_row = slice.id().IndexOf(start_id);
- // The query gave an invalid ID that doesn't exist in the slice table.
- if (!start_row) {
- // TODO(lalitm): Ideally this should result in an error, or be filtered out
- // during ValidateConstraints so we can just dereference |start_row|
- // directly. However ValidateConstraints doesn't know the value we're
- // filtering for so can't ensure it exists. For now we return a nullptr
- // which will cause the query to surface an error with the message "SQL
- // error: constraint failed".
- return base::nullopt;
- }
-
- // All nested descendents must be on the same track, with a ts between
- // |start_id.ts| and |start_id.ts| + |start_id.dur|, and who's depth is larger
- // then |start_row|'s. So we just use Filter to select all relevant slices.
- return slice.FilterToRowMap(
- {slice.ts().ge(slice.ts()[*start_row]),
- slice.ts().le(slice.ts()[*start_row] + slice.dur()[*start_row]),
- slice.track_id().eq(slice.track_id()[*start_row].value),
- slice.depth().gt(slice.depth()[*start_row])});
-}
-
-} // namespace trace_processor
-} // namespace perfetto
diff --git a/src/trace_processor/dynamic/descendant_slice_generator.h b/src/trace_processor/dynamic/descendant_slice_generator.h
deleted file mode 100644
index c152f7a61..000000000
--- a/src/trace_processor/dynamic/descendant_slice_generator.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SRC_TRACE_PROCESSOR_DYNAMIC_DESCENDANT_SLICE_GENERATOR_H_
-#define SRC_TRACE_PROCESSOR_DYNAMIC_DESCENDANT_SLICE_GENERATOR_H_
-
-#include "src/trace_processor/sqlite/db_sqlite_table.h"
-
-#include "perfetto/ext/base/optional.h"
-#include "src/trace_processor/storage/trace_storage.h"
-
-namespace perfetto {
-namespace trace_processor {
-
-class TraceProcessorContext;
-
-// Dynamic table for implementing the table.
-// See /docs/analysis.md for details about the functionality and usage of this
-// table.
-class DescendantSliceGenerator : public DbSqliteTable::DynamicTableGenerator {
- public:
- explicit DescendantSliceGenerator(TraceProcessorContext* context);
- ~DescendantSliceGenerator() override;
-
- Table::Schema CreateSchema() override;
- std::string TableName() override;
- uint32_t EstimateRowCount() override;
- util::Status ValidateConstraints(const QueryConstraints&) override;
- std::unique_ptr<Table> ComputeTable(const std::vector<Constraint>& cs,
- const std::vector<Order>& ob) override;
-
- // Returns a RowMap of slice IDs which are descendants of |slice_id|. Returns
- // NULL if an invalid |slice_id| is given. This is used by
- // ConnectedFlowGenerator to traverse flow indirectly connected flow events.
- static base::Optional<RowMap> GetDescendantSlices(
- const tables::SliceTable& slices,
- SliceId start_id);
-
- private:
- TraceProcessorContext* context_ = nullptr;
-};
-
-} // namespace trace_processor
-} // namespace perfetto
-
-#endif // SRC_TRACE_PROCESSOR_DYNAMIC_DESCENDANT_SLICE_GENERATOR_H_
diff --git a/src/trace_processor/dynamic/describe_slice_generator.cc b/src/trace_processor/dynamic/describe_slice_generator.cc
index edc610dda..ea8a70c77 100644
--- a/src/trace_processor/dynamic/describe_slice_generator.cc
+++ b/src/trace_processor/dynamic/describe_slice_generator.cc
@@ -18,6 +18,7 @@
#include "src/trace_processor/analysis/describe_slice.h"
#include "src/trace_processor/types/trace_processor_context.h"
+#include "src/trace_processor/util/status_macros.h"
namespace perfetto {
namespace trace_processor {
@@ -34,10 +35,9 @@ DescribeSliceGenerator::InputValues GetDescribeSliceInputValues(
};
auto slice_id_it = std::find_if(cs.begin(), cs.end(), slice_id_fn);
- // We should always have valid iterators here because BestIndex should only
- // allow the constraint set to be chosen when we have an equality constraint
- // on both ts and upid.
PERFETTO_CHECK(slice_id_it != cs.end());
+ // TODO(rsavitski): consider checking type of the SqlValue, as erroneous
+ // queries that pass a null here (or otherwise unexpected type) will crash.
uint32_t slice_id_value = static_cast<uint32_t>(slice_id_it->value.AsLong());
return DescribeSliceGenerator::InputValues{slice_id_value};
@@ -50,7 +50,7 @@ DescribeSliceGenerator::DescribeSliceGenerator(TraceProcessorContext* context)
DescribeSliceGenerator::~DescribeSliceGenerator() = default;
-util::Status DescribeSliceGenerator::ValidateConstraints(
+base::Status DescribeSliceGenerator::ValidateConstraints(
const QueryConstraints& qc) {
using T = tables::DescribeSliceTable;
@@ -64,20 +64,21 @@ util::Status DescribeSliceGenerator::ValidateConstraints(
std::find_if(cs.begin(), cs.end(), slice_id_fn) != cs.end();
return has_slice_id_cs
- ? util::OkStatus()
- : util::ErrStatus("Failed to find required constraints");
+ ? base::OkStatus()
+ : base::ErrStatus("Failed to find required constraints");
}
-std::unique_ptr<Table> DescribeSliceGenerator::ComputeTable(
+base::Status DescribeSliceGenerator::ComputeTable(
const std::vector<Constraint>& cs,
- const std::vector<Order>&) {
+ const std::vector<Order>&,
+ const BitVector&,
+ std::unique_ptr<Table>& table_return) {
auto input = GetDescribeSliceInputValues(cs);
const auto& slices = context_->storage->slice_table();
base::Optional<SliceDescription> opt_desc;
- auto status = DescribeSlice(slices, SliceId{input.slice_id_value}, &opt_desc);
- if (!status.ok())
- return nullptr;
+ RETURN_IF_ERROR(
+ DescribeSlice(slices, SliceId{input.slice_id_value}, &opt_desc));
auto* pool = context_->storage->mutable_string_pool();
std::unique_ptr<tables::DescribeSliceTable> table(
@@ -92,9 +93,8 @@ std::unique_ptr<Table> DescribeSliceGenerator::ComputeTable(
row.slice_id = input.slice_id_value;
table->Insert(row);
}
- // We need to explicitly std::move as clang complains about a bug in old
- // compilers otherwise (-Wreturn-std-move-in-c++11).
- return std::move(table);
+ table_return = std::move(table);
+ return base::OkStatus();
}
Table::Schema DescribeSliceGenerator::CreateSchema() {
diff --git a/src/trace_processor/dynamic/describe_slice_generator.h b/src/trace_processor/dynamic/describe_slice_generator.h
index af59529ae..fa8a87fbd 100644
--- a/src/trace_processor/dynamic/describe_slice_generator.h
+++ b/src/trace_processor/dynamic/describe_slice_generator.h
@@ -41,9 +41,11 @@ class DescribeSliceGenerator : public DbSqliteTable::DynamicTableGenerator {
Table::Schema CreateSchema() override;
std::string TableName() override;
uint32_t EstimateRowCount() override;
- util::Status ValidateConstraints(const QueryConstraints&) override;
- std::unique_ptr<Table> ComputeTable(const std::vector<Constraint>& cs,
- const std::vector<Order>& ob) override;
+ base::Status ValidateConstraints(const QueryConstraints&) override;
+ base::Status ComputeTable(const std::vector<Constraint>& cs,
+ const std::vector<Order>& ob,
+ const BitVector& cols_used,
+ std::unique_ptr<Table>& table_return) override;
private:
TraceProcessorContext* context_ = nullptr;
diff --git a/src/trace_processor/dynamic/experimental_annotated_stack_generator.cc b/src/trace_processor/dynamic/experimental_annotated_stack_generator.cc
index 1af5ad171..45cf5962b 100644
--- a/src/trace_processor/dynamic/experimental_annotated_stack_generator.cc
+++ b/src/trace_processor/dynamic/experimental_annotated_stack_generator.cc
@@ -104,7 +104,7 @@ Table::Schema ExperimentalAnnotatedStackGenerator::CreateSchema() {
return schema;
}
-util::Status ExperimentalAnnotatedStackGenerator::ValidateConstraints(
+base::Status ExperimentalAnnotatedStackGenerator::ValidateConstraints(
const QueryConstraints& qc) {
const auto& cs = qc.constraints();
int column = static_cast<int>(GetConstraintColumnIndex(context_));
@@ -113,13 +113,15 @@ util::Status ExperimentalAnnotatedStackGenerator::ValidateConstraints(
return c.column == column && c.op == SQLITE_INDEX_CONSTRAINT_EQ;
};
bool has_id_cs = std::find_if(cs.begin(), cs.end(), id_fn) != cs.end();
- return has_id_cs ? util::OkStatus()
- : util::ErrStatus("Failed to find required constraints");
+ return has_id_cs ? base::OkStatus()
+ : base::ErrStatus("Failed to find required constraints");
}
-std::unique_ptr<Table> ExperimentalAnnotatedStackGenerator::ComputeTable(
+base::Status ExperimentalAnnotatedStackGenerator::ComputeTable(
const std::vector<Constraint>& cs,
- const std::vector<Order>&) {
+ const std::vector<Order>&,
+ const BitVector&,
+ std::unique_ptr<Table>& table_return) {
const auto& cs_table = context_->storage->stack_profile_callsite_table();
const auto& f_table = context_->storage->stack_profile_frame_table();
const auto& m_table = context_->storage->stack_profile_mapping_table();
@@ -132,12 +134,17 @@ std::unique_ptr<Table> ExperimentalAnnotatedStackGenerator::ComputeTable(
return c.col_idx == constraint_col && c.op == FilterOp::kEq;
});
PERFETTO_DCHECK(constraint_it != cs.end());
+ if (constraint_it == cs.end() ||
+ constraint_it->value.type != SqlValue::Type::kLong) {
+ return base::ErrStatus("invalid input callsite id");
+ }
- auto start_id = static_cast<uint32_t>(constraint_it->value.AsLong());
+ uint32_t start_id = static_cast<uint32_t>(constraint_it->value.AsLong());
base::Optional<uint32_t> start_row =
cs_table.id().IndexOf(CallsiteId(start_id));
- if (!start_row)
- return nullptr;
+ if (!start_row) {
+ return base::ErrStatus("callsite with id %" PRIu32 " not found", start_id);
+ }
// Iteratively walk the parent_id chain to construct the list of callstack
// entries, each pointing at a frame.
@@ -263,13 +270,14 @@ std::unique_ptr<Table> ExperimentalAnnotatedStackGenerator::ComputeTable(
for (uint32_t i = 0; i < base_rowmap.size(); i++)
start_id_vals->Append(start_id);
- return std::unique_ptr<Table>(new Table(
+ table_return.reset(new Table(
cs_table.Apply(std::move(base_rowmap))
.ExtendWithColumn("annotation", std::move(annotation_vals),
TypedColumn<StringPool::Id>::default_flags())
.ExtendWithColumn("start_id", std::move(start_id_vals),
TypedColumn<uint32_t>::default_flags() |
TypedColumn<uint32_t>::kHidden)));
+ return base::OkStatus();
}
uint32_t ExperimentalAnnotatedStackGenerator::EstimateRowCount() {
diff --git a/src/trace_processor/dynamic/experimental_annotated_stack_generator.h b/src/trace_processor/dynamic/experimental_annotated_stack_generator.h
index 7e6a62d27..8b1353675 100644
--- a/src/trace_processor/dynamic/experimental_annotated_stack_generator.h
+++ b/src/trace_processor/dynamic/experimental_annotated_stack_generator.h
@@ -38,9 +38,11 @@ class ExperimentalAnnotatedStackGenerator
Table::Schema CreateSchema() override;
std::string TableName() override;
uint32_t EstimateRowCount() override;
- util::Status ValidateConstraints(const QueryConstraints&) override;
- std::unique_ptr<Table> ComputeTable(const std::vector<Constraint>& cs,
- const std::vector<Order>& ob) override;
+ base::Status ValidateConstraints(const QueryConstraints&) override;
+ base::Status ComputeTable(const std::vector<Constraint>& cs,
+ const std::vector<Order>& ob,
+ const BitVector& cols_used,
+ std::unique_ptr<Table>& table_return) override;
private:
TraceProcessorContext* context_ = nullptr;
diff --git a/src/trace_processor/dynamic/experimental_counter_dur_generator.cc b/src/trace_processor/dynamic/experimental_counter_dur_generator.cc
index 88d167f7c..ce60d47c7 100644
--- a/src/trace_processor/dynamic/experimental_counter_dur_generator.cc
+++ b/src/trace_processor/dynamic/experimental_counter_dur_generator.cc
@@ -43,14 +43,16 @@ uint32_t ExperimentalCounterDurGenerator::EstimateRowCount() {
return counter_table_->row_count();
}
-util::Status ExperimentalCounterDurGenerator::ValidateConstraints(
+base::Status ExperimentalCounterDurGenerator::ValidateConstraints(
const QueryConstraints&) {
- return util::OkStatus();
+ return base::OkStatus();
}
-std::unique_ptr<Table> ExperimentalCounterDurGenerator::ComputeTable(
+base::Status ExperimentalCounterDurGenerator::ComputeTable(
const std::vector<Constraint>&,
- const std::vector<Order>&) {
+ const std::vector<Order>&,
+ const BitVector&,
+ std::unique_ptr<Table>& table_return) {
if (!dur_column_) {
dur_column_.reset(
new NullableVector<int64_t>(ComputeDurColumn(*counter_table_)));
@@ -64,7 +66,8 @@ std::unique_ptr<Table> ExperimentalCounterDurGenerator::ComputeTable(
.ExtendWithColumn("delta", std::move(delta_column_.get()),
TypedColumn<int64_t>::default_flags());
- return std::unique_ptr<Table>(new Table(t.Copy()));
+ table_return.reset(new Table(t.Copy()));
+ return base::OkStatus();
}
// static
diff --git a/src/trace_processor/dynamic/experimental_counter_dur_generator.h b/src/trace_processor/dynamic/experimental_counter_dur_generator.h
index 38f9773e8..de7071e46 100644
--- a/src/trace_processor/dynamic/experimental_counter_dur_generator.h
+++ b/src/trace_processor/dynamic/experimental_counter_dur_generator.h
@@ -33,9 +33,11 @@ class ExperimentalCounterDurGenerator
Table::Schema CreateSchema() override;
std::string TableName() override;
uint32_t EstimateRowCount() override;
- util::Status ValidateConstraints(const QueryConstraints&) override;
- std::unique_ptr<Table> ComputeTable(const std::vector<Constraint>&,
- const std::vector<Order>&) override;
+ base::Status ValidateConstraints(const QueryConstraints&) override;
+ base::Status ComputeTable(const std::vector<Constraint>& cs,
+ const std::vector<Order>& ob,
+ const BitVector& cols_used,
+ std::unique_ptr<Table>& table_return) override;
// public + static for testing
static NullableVector<int64_t> ComputeDurColumn(const Table& table);
diff --git a/src/trace_processor/dynamic/experimental_flamegraph_generator.cc b/src/trace_processor/dynamic/experimental_flamegraph_generator.cc
index 90f52e99e..bcecec190 100644
--- a/src/trace_processor/dynamic/experimental_flamegraph_generator.cc
+++ b/src/trace_processor/dynamic/experimental_flamegraph_generator.cc
@@ -16,6 +16,9 @@
#include "src/trace_processor/dynamic/experimental_flamegraph_generator.h"
+#include <unordered_set>
+
+#include "perfetto/ext/base/string_splitter.h"
#include "perfetto/ext/base/string_utils.h"
#include "src/trace_processor/importers/proto/heap_graph_tracker.h"
@@ -27,18 +30,51 @@ namespace trace_processor {
namespace {
+ExperimentalFlamegraphGenerator::ProfileType extractProfileType(
+ std::string& profile_name) {
+ if (profile_name == "graph") {
+ return ExperimentalFlamegraphGenerator::ProfileType::kGraph;
+ }
+ if (profile_name == "native") {
+ return ExperimentalFlamegraphGenerator::ProfileType::kNative;
+ }
+ if (profile_name == "perf") {
+ return ExperimentalFlamegraphGenerator::ProfileType::kPerf;
+ }
+ PERFETTO_FATAL("Could not recognize profile type: %s.", profile_name.c_str());
+}
+
+bool IsValidTimestampOp(int op) {
+ return op == SQLITE_INDEX_CONSTRAINT_EQ || op == SQLITE_INDEX_CONSTRAINT_GT ||
+ op == SQLITE_INDEX_CONSTRAINT_LE || op == SQLITE_INDEX_CONSTRAINT_LT ||
+ op == SQLITE_INDEX_CONSTRAINT_GE;
+}
+
+bool IsValidFilterOp(FilterOp filterOp) {
+ return filterOp == FilterOp::kEq || filterOp == FilterOp::kGt ||
+ filterOp == FilterOp::kLe || filterOp == FilterOp::kLt ||
+ filterOp == FilterOp::kGe;
+}
+
+// For filtering, this method uses the same constraints as
+// ExperimentalFlamegraphGenerator::ValidateConstraints and should therefore
+// be kept in sync.
ExperimentalFlamegraphGenerator::InputValues GetFlamegraphInputValues(
const std::vector<Constraint>& cs) {
using T = tables::ExperimentalFlamegraphNodesTable;
auto ts_fn = [](const Constraint& c) {
return c.col_idx == static_cast<uint32_t>(T::ColumnIndex::ts) &&
- c.op == FilterOp::kEq;
+ IsValidFilterOp(c.op);
};
auto upid_fn = [](const Constraint& c) {
return c.col_idx == static_cast<uint32_t>(T::ColumnIndex::upid) &&
c.op == FilterOp::kEq;
};
+ auto upid_group_fn = [](const Constraint& c) {
+ return c.col_idx == static_cast<uint32_t>(T::ColumnIndex::upid_group) &&
+ c.op == FilterOp::kEq;
+ };
auto profile_type_fn = [](const Constraint& c) {
return c.col_idx == static_cast<uint32_t>(T::ColumnIndex::profile_type) &&
c.op == FilterOp::kEq;
@@ -50,23 +86,51 @@ ExperimentalFlamegraphGenerator::InputValues GetFlamegraphInputValues(
auto ts_it = std::find_if(cs.begin(), cs.end(), ts_fn);
auto upid_it = std::find_if(cs.begin(), cs.end(), upid_fn);
+ auto upid_group_it = std::find_if(cs.begin(), cs.end(), upid_group_fn);
auto profile_type_it = std::find_if(cs.begin(), cs.end(), profile_type_fn);
auto focus_str_it = std::find_if(cs.begin(), cs.end(), focus_str_fn);
// We should always have valid iterators here because BestIndex should only
// allow the constraint set to be chosen when we have an equality constraint
- // on both ts and upid.
+ // on upid and a constraint on ts.
PERFETTO_CHECK(ts_it != cs.end());
- PERFETTO_CHECK(upid_it != cs.end());
+ PERFETTO_CHECK(upid_it != cs.end() || upid_group_it != cs.end());
PERFETTO_CHECK(profile_type_it != cs.end());
- int64_t ts = ts_it->value.AsLong();
- UniquePid upid = static_cast<UniquePid>(upid_it->value.AsLong());
- std::string profile_type = profile_type_it->value.AsString();
+ std::string profile_name(profile_type_it->value.AsString());
+ ExperimentalFlamegraphGenerator::ProfileType profile_type =
+ extractProfileType(profile_name);
+ int64_t ts = -1;
+ std::vector<TimeConstraints> time_constraints = {};
+
+ for (; ts_it != cs.end(); ts_it++) {
+ if (ts_it->col_idx != static_cast<uint32_t>(T::ColumnIndex::ts)) {
+ continue;
+ }
+
+ if (profile_type == ExperimentalFlamegraphGenerator::ProfileType::kPerf) {
+ PERFETTO_CHECK(ts_it->op != FilterOp::kEq);
+ time_constraints.push_back(
+ TimeConstraints{ts_it->op, ts_it->value.AsLong()});
+ } else {
+ PERFETTO_CHECK(ts_it->op == FilterOp::kEq);
+ ts = ts_it->value.AsLong();
+ }
+ }
+
+ base::Optional<UniquePid> upid;
+ base::Optional<std::string> upid_group;
+ if (upid_it != cs.end()) {
+ upid = static_cast<UniquePid>(upid_it->value.AsLong());
+ } else {
+ upid_group = upid_group_it->value.AsString();
+ }
+
std::string focus_str =
focus_str_it != cs.end() ? focus_str_it->value.AsString() : "";
- return ExperimentalFlamegraphGenerator::InputValues{ts, upid, profile_type,
- focus_str};
+ return ExperimentalFlamegraphGenerator::InputValues{
+ profile_type, ts, std::move(time_constraints),
+ upid, upid_group, focus_str};
}
class Matcher {
@@ -218,7 +282,10 @@ ExperimentalFlamegraphGenerator::ExperimentalFlamegraphGenerator(
ExperimentalFlamegraphGenerator::~ExperimentalFlamegraphGenerator() = default;
-util::Status ExperimentalFlamegraphGenerator::ValidateConstraints(
+// For filtering, this method uses the same constraints as
+// ExperimentalFlamegraphGenerator::GetFlamegraphInputValues and should
+// therefore be kept in sync.
+base::Status ExperimentalFlamegraphGenerator::ValidateConstraints(
const QueryConstraints& qc) {
using T = tables::ExperimentalFlamegraphNodesTable;
@@ -226,7 +293,7 @@ util::Status ExperimentalFlamegraphGenerator::ValidateConstraints(
auto ts_fn = [](const QueryConstraints::Constraint& c) {
return c.column == static_cast<int>(T::ColumnIndex::ts) &&
- c.op == SQLITE_INDEX_CONSTRAINT_EQ;
+ IsValidTimestampOp(c.op);
};
bool has_ts_cs = std::find_if(cs.begin(), cs.end(), ts_fn) != cs.end();
@@ -236,6 +303,13 @@ util::Status ExperimentalFlamegraphGenerator::ValidateConstraints(
};
bool has_upid_cs = std::find_if(cs.begin(), cs.end(), upid_fn) != cs.end();
+ auto upid_group_fn = [](const QueryConstraints::Constraint& c) {
+ return c.column == static_cast<int>(T::ColumnIndex::upid_group) &&
+ c.op == SQLITE_INDEX_CONSTRAINT_EQ;
+ };
+ bool has_upid_group_cs =
+ std::find_if(cs.begin(), cs.end(), upid_group_fn) != cs.end();
+
auto profile_type_fn = [](const QueryConstraints::Constraint& c) {
return c.column == static_cast<int>(T::ColumnIndex::profile_type) &&
c.op == SQLITE_INDEX_CONSTRAINT_EQ;
@@ -243,25 +317,30 @@ util::Status ExperimentalFlamegraphGenerator::ValidateConstraints(
bool has_profile_type_cs =
std::find_if(cs.begin(), cs.end(), profile_type_fn) != cs.end();
- return has_ts_cs && has_upid_cs && has_profile_type_cs
- ? util::OkStatus()
- : util::ErrStatus("Failed to find required constraints");
+ return has_ts_cs && (has_upid_cs || has_upid_group_cs) && has_profile_type_cs
+ ? base::OkStatus()
+ : base::ErrStatus("Failed to find required constraints");
}
-std::unique_ptr<Table> ExperimentalFlamegraphGenerator::ComputeTable(
+base::Status ExperimentalFlamegraphGenerator::ComputeTable(
const std::vector<Constraint>& cs,
- const std::vector<Order>&) {
+ const std::vector<Order>&,
+ const BitVector&,
+ std::unique_ptr<Table>& table_return) {
// Get the input column values and compute the flamegraph using them.
auto values = GetFlamegraphInputValues(cs);
std::unique_ptr<tables::ExperimentalFlamegraphNodesTable> table;
- if (values.profile_type == "graph") {
+ if (values.profile_type == ProfileType::kGraph) {
auto* tracker = HeapGraphTracker::GetOrCreate(context_);
- table = tracker->BuildFlamegraph(values.ts, values.upid);
- }
- if (values.profile_type == "native") {
- table =
- BuildNativeFlamegraph(context_->storage.get(), values.upid, values.ts);
+ table = tracker->BuildFlamegraph(values.ts, *values.upid);
+ } else if (values.profile_type == ProfileType::kNative) {
+ table = BuildNativeHeapProfileFlamegraph(context_->storage.get(),
+ *values.upid, values.ts);
+ } else if (values.profile_type == ProfileType::kPerf) {
+ table = BuildNativeCallStackSamplingFlamegraph(
+ context_->storage.get(), values.upid, values.upid_group,
+ values.time_constraints);
}
if (!values.focus_str.empty()) {
table =
@@ -274,9 +353,8 @@ std::unique_ptr<Table> ExperimentalFlamegraphGenerator::ComputeTable(
table->mutable_focus_str()->Set(i, focus_id);
}
}
- // We need to explicitly std::move as clang complains about a bug in old
- // compilers otherwise (-Wreturn-std-move-in-c++11).
- return std::move(table);
+ table_return = std::move(table);
+ return base::OkStatus();
}
Table::Schema ExperimentalFlamegraphGenerator::CreateSchema() {
diff --git a/src/trace_processor/dynamic/experimental_flamegraph_generator.h b/src/trace_processor/dynamic/experimental_flamegraph_generator.h
index 7ca1f510e..4ec3cbc32 100644
--- a/src/trace_processor/dynamic/experimental_flamegraph_generator.h
+++ b/src/trace_processor/dynamic/experimental_flamegraph_generator.h
@@ -17,6 +17,7 @@
#ifndef SRC_TRACE_PROCESSOR_DYNAMIC_EXPERIMENTAL_FLAMEGRAPH_GENERATOR_H_
#define SRC_TRACE_PROCESSOR_DYNAMIC_EXPERIMENTAL_FLAMEGRAPH_GENERATOR_H_
+#include "src/trace_processor/importers/proto/flamegraph_construction_algorithms.h"
#include "src/trace_processor/sqlite/db_sqlite_table.h"
#include "src/trace_processor/storage/trace_storage.h"
@@ -29,10 +30,14 @@ class TraceProcessorContext;
class ExperimentalFlamegraphGenerator
: public DbSqliteTable::DynamicTableGenerator {
public:
+ enum class ProfileType { kGraph, kNative, kPerf };
+
struct InputValues {
+ ProfileType profile_type;
int64_t ts;
- UniquePid upid;
- std::string profile_type;
+ std::vector<TimeConstraints> time_constraints;
+ base::Optional<UniquePid> upid;
+ base::Optional<std::string> upid_group;
std::string focus_str;
};
@@ -42,9 +47,11 @@ class ExperimentalFlamegraphGenerator
Table::Schema CreateSchema() override;
std::string TableName() override;
uint32_t EstimateRowCount() override;
- util::Status ValidateConstraints(const QueryConstraints&) override;
- std::unique_ptr<Table> ComputeTable(const std::vector<Constraint>& cs,
- const std::vector<Order>& ob) override;
+ base::Status ValidateConstraints(const QueryConstraints&) override;
+ base::Status ComputeTable(const std::vector<Constraint>& cs,
+ const std::vector<Order>& ob,
+ const BitVector& cols_used,
+ std::unique_ptr<Table>& table_return) override;
private:
TraceProcessorContext* context_ = nullptr;
diff --git a/src/trace_processor/dynamic/experimental_flat_slice_generator.cc b/src/trace_processor/dynamic/experimental_flat_slice_generator.cc
new file mode 100644
index 000000000..48271b561
--- /dev/null
+++ b/src/trace_processor/dynamic/experimental_flat_slice_generator.cc
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/dynamic/experimental_flat_slice_generator.h"
+
+#include <memory>
+#include <set>
+
+#include "src/trace_processor/types/trace_processor_context.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+ExperimentalFlatSliceGenerator::ExperimentalFlatSliceGenerator(
+ TraceProcessorContext* context)
+ : context_(context) {}
+
+base::Status ExperimentalFlatSliceGenerator::ValidateConstraints(
+ const QueryConstraints& qc) {
+ using CI = tables::ExperimentalFlatSliceTable::ColumnIndex;
+ bool has_start_bound = false;
+ bool has_end_bound = false;
+ for (const auto& c : qc.constraints()) {
+ has_start_bound |= c.column == static_cast<int>(CI::start_bound) &&
+ c.op == SQLITE_INDEX_CONSTRAINT_EQ;
+ has_end_bound |= c.column == static_cast<int>(CI::end_bound) &&
+ c.op == SQLITE_INDEX_CONSTRAINT_EQ;
+ }
+ return has_start_bound && has_end_bound
+ ? base::OkStatus()
+ : base::ErrStatus("Failed to find required constraints");
+}
+
+base::Status ExperimentalFlatSliceGenerator::ComputeTable(
+ const std::vector<Constraint>& cs,
+ const std::vector<Order>&,
+ const BitVector&,
+ std::unique_ptr<Table>& table_return) {
+ using CI = tables::ExperimentalFlatSliceTable::ColumnIndex;
+ auto start_it = std::find_if(cs.begin(), cs.end(), [](const Constraint& c) {
+ return c.col_idx == static_cast<uint32_t>(CI::start_bound) &&
+ c.op == FilterOp::kEq;
+ });
+ auto end_it = std::find_if(cs.begin(), cs.end(), [](const Constraint& c) {
+ return c.col_idx == static_cast<uint32_t>(CI::end_bound) &&
+ c.op == FilterOp::kEq;
+ });
+ // TODO(rsavitski): consider checking the values' types (in case of erroneous
+ // queries passing e.g. null).
+ int64_t start_bound = start_it->value.AsLong();
+ int64_t end_bound = end_it->value.AsLong();
+ table_return = ComputeFlatSliceTable(context_->storage->slice_table(),
+ context_->storage->mutable_string_pool(),
+ start_bound, end_bound);
+ return base::OkStatus();
+}
+
+std::unique_ptr<tables::ExperimentalFlatSliceTable>
+ExperimentalFlatSliceGenerator::ComputeFlatSliceTable(
+ const tables::SliceTable& slice,
+ StringPool* pool,
+ int64_t start_bound,
+ int64_t end_bound) {
+ std::unique_ptr<tables::ExperimentalFlatSliceTable> out(
+ new tables::ExperimentalFlatSliceTable(pool, nullptr));
+
+ auto insert_slice = [&](uint32_t i, int64_t ts,
+ tables::TrackTable::Id track_id) {
+ tables::ExperimentalFlatSliceTable::Row row;
+ row.ts = ts;
+ row.dur = -1;
+ row.track_id = track_id;
+ row.category = slice.category()[i];
+ row.name = slice.name()[i];
+ row.arg_set_id = slice.arg_set_id()[i];
+ row.source_id = slice.id()[i];
+ row.start_bound = start_bound;
+ row.end_bound = end_bound;
+ return out->Insert(row).row;
+ };
+ auto insert_sentinel = [&](int64_t ts, TrackId track_id) {
+ tables::ExperimentalFlatSliceTable::Row row;
+ row.ts = ts;
+ row.dur = -1;
+ row.track_id = track_id;
+ row.category = kNullStringId;
+ row.name = kNullStringId;
+ row.arg_set_id = kInvalidArgSetId;
+ row.source_id = base::nullopt;
+ row.start_bound = start_bound;
+ row.end_bound = end_bound;
+ return out->Insert(row).row;
+ };
+
+ auto terminate_slice = [&](uint32_t out_row, int64_t end_ts) {
+ PERFETTO_DCHECK(out->dur()[out_row] == -1);
+ int64_t out_ts = out->ts()[out_row];
+ out->mutable_dur()->Set(out_row, end_ts - out_ts);
+ };
+
+ struct ActiveSlice {
+ base::Optional<uint32_t> source_row;
+ uint32_t out_row = std::numeric_limits<uint32_t>::max();
+
+ bool is_sentinel() const { return !source_row; }
+ };
+ struct Track {
+ std::vector<uint32_t> parents;
+ ActiveSlice active;
+ bool initialized = false;
+ };
+ std::unordered_map<TrackId, Track> tracks;
+
+ auto maybe_terminate_active_slice = [&](const Track& t, int64_t fin_ts) {
+ int64_t ts = slice.ts()[t.active.source_row.value()];
+ int64_t dur = slice.dur()[t.active.source_row.value()];
+ if (dur == -1 || ts + dur > fin_ts)
+ return false;
+
+ terminate_slice(t.active.out_row, ts + dur);
+ return true;
+ };
+
+ // Post-condition: |tracks[track_id].active| will always point to
+ // a slice which finishes after |fin_ts| and has a |dur| == -1 in
+ // |out|.
+ auto output_slices_before = [&](TrackId track_id, int64_t fin_ts) {
+ auto& t = tracks[track_id];
+
+ // A sentinel slice cannot have parents.
+ PERFETTO_DCHECK(!t.active.is_sentinel() || t.parents.empty());
+
+ // If we have a sentinel slice active, we have nothing to output.
+ if (t.active.is_sentinel())
+ return;
+
+ // Try and terminate the current slice (if it ends before |fin_ts|)
+ // If we cannot terminate it, then we leave it as pending for the caller
+ // to terminate.
+ if (!maybe_terminate_active_slice(t, fin_ts))
+ return;
+
+ // Next, add any parents as appropriate.
+ for (int64_t i = static_cast<int64_t>(t.parents.size()) - 1; i >= 0; --i) {
+ uint32_t source_row = t.parents[static_cast<size_t>(i)];
+ t.parents.pop_back();
+
+ int64_t active_ts = out->ts()[t.active.out_row];
+ int64_t active_dur = out->dur()[t.active.out_row];
+ PERFETTO_DCHECK(active_dur != -1);
+
+ t.active.source_row = source_row;
+ t.active.out_row =
+ insert_slice(source_row, active_ts + active_dur, track_id);
+
+ if (!maybe_terminate_active_slice(t, fin_ts))
+ break;
+ }
+
+ if (!t.parents.empty())
+ return;
+
+ // If the active slice is a sentinel, the check at the top of this function
+ // should have caught it; all code only adds slices from source.
+ PERFETTO_DCHECK(!t.active.is_sentinel());
+
+ int64_t ts = out->ts()[t.active.out_row];
+ int64_t dur = out->dur()[t.active.out_row];
+
+ // If the active slice is unfinshed, we return that for the caller to
+ // terminate.
+ if (dur == -1)
+ return;
+
+ // Otherwise, Add a sentinel slice after the end of the active slice.
+ t.active.source_row = base::nullopt;
+ t.active.out_row = insert_sentinel(ts + dur, track_id);
+ };
+
+ for (uint32_t i = 0; i < slice.row_count(); ++i) {
+ // TODO(lalitm): this can be optimized using a O(logn) lower bound/filter.
+ // Not adding for now as a premature optimization but may be needed down the
+ // line.
+ int64_t ts = slice.ts()[i];
+ if (ts < start_bound)
+ continue;
+
+ if (ts >= end_bound)
+ break;
+
+ // Ignore instants as they don't factor into flat slice at all.
+ if (slice.dur()[i] == 0)
+ continue;
+
+ TrackId track_id = slice.track_id()[i];
+ Track& track = tracks[track_id];
+
+ // Initalize the track (if needed) by adding a sentinel slice starting at
+ // start_bound.
+ bool is_root = slice.depth()[i] == 0;
+ if (!track.initialized) {
+ // If we are unintialized and our start box picks up slices mid way
+ // through startup, wait until we reach a root slice.
+ if (!is_root)
+ continue;
+
+ track.active.out_row = insert_sentinel(start_bound, track_id);
+ track.initialized = true;
+ }
+ output_slices_before(track_id, ts);
+ terminate_slice(track.active.out_row, ts);
+
+ // We should have sentinel slices iff the slice is a root.
+ PERFETTO_DCHECK(track.active.is_sentinel() == is_root);
+
+ // If our current slice has a parent, that must be the current active slice.
+ if (!is_root) {
+ track.parents.push_back(*track.active.source_row);
+ }
+
+ // The depth of our slice should also match the depth of the parent stack
+ // (after adding the previous slice).
+ PERFETTO_DCHECK(track.parents.size() == slice.depth()[i]);
+
+ track.active.source_row = i;
+ track.active.out_row = insert_slice(i, ts, track_id);
+ }
+
+ for (const auto& track : tracks) {
+ // If the track is not initialized, don't add anything.
+ if (!track.second.initialized)
+ continue;
+
+ // First, terminate any hanging slices.
+ output_slices_before(track.first, end_bound);
+
+ // Second, force terminate the final slice to the end bound.
+ terminate_slice(track.second.active.out_row, end_bound);
+ }
+
+ return out;
+}
+
+Table::Schema ExperimentalFlatSliceGenerator::CreateSchema() {
+ return tables::ExperimentalFlatSliceTable::Schema();
+}
+
+std::string ExperimentalFlatSliceGenerator::TableName() {
+ return "experimental_flat_slice";
+}
+
+uint32_t ExperimentalFlatSliceGenerator::EstimateRowCount() {
+ return context_->storage->slice_table().row_count();
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/dynamic/experimental_flat_slice_generator.h b/src/trace_processor/dynamic/experimental_flat_slice_generator.h
new file mode 100644
index 000000000..008345700
--- /dev/null
+++ b/src/trace_processor/dynamic/experimental_flat_slice_generator.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_DYNAMIC_EXPERIMENTAL_FLAT_SLICE_GENERATOR_H_
+#define SRC_TRACE_PROCESSOR_DYNAMIC_EXPERIMENTAL_FLAT_SLICE_GENERATOR_H_
+
+#include "perfetto/ext/base/optional.h"
+#include "src/trace_processor/sqlite/db_sqlite_table.h"
+#include "src/trace_processor/storage/trace_storage.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class TraceProcessorContext;
+
+// Dynamic table generator for "flat slice" table.
+//
+// The concept of a "flat slice" is to take the data in the slice table and
+// remove all notion of nesting; we do this by, at any point in time, taking the
+// most specific active slice (i.e. the slice at the bottom of the stack) and
+// representing that as the *only* slice that was running during that period.
+//
+// This concept becomes very useful when you try and linearise a trace and
+// compare it with other traces spanning the same user action; "self time" (i.e.
+// time spent in a slice but *not* any children) is easily computed and span
+// joins with thread state become possible without limiting to only depth zero
+// slices.
+//
+// This table also adds "gap slices" which fill in the gap between top level
+// slices with a sentinal values so that comparision of the gap between slices
+// is also possible.
+//
+// As input, this generator takes a start and end timestamp between
+// which slices should be picked; we do this rather than just using the trace
+// bounds so that the "gap slices" start and end at the appropriate place.
+//
+// Note that for the start bound we will *not* pick any slice which started
+// before the bound even if it finished after. This is dissimilar to span join
+// (which picks all slices with ts + dur >= bound) and is more akin to doing
+// a simple ts >= bound. However, slices *will* be truncated at the end
+// if they would spill past the provided end bound.
+class ExperimentalFlatSliceGenerator
+ : public DbSqliteTable::DynamicTableGenerator {
+ public:
+ ExperimentalFlatSliceGenerator(TraceProcessorContext* context);
+
+ Table::Schema CreateSchema() override;
+ std::string TableName() override;
+ uint32_t EstimateRowCount() override;
+ base::Status ValidateConstraints(const QueryConstraints&) override;
+ base::Status ComputeTable(const std::vector<Constraint>& cs,
+ const std::vector<Order>& ob,
+ const BitVector& cols_used,
+ std::unique_ptr<Table>& table_return) override;
+
+ // Visibile for testing.
+ static std::unique_ptr<tables::ExperimentalFlatSliceTable>
+ ComputeFlatSliceTable(const tables::SliceTable&,
+ StringPool*,
+ int64_t start_bound,
+ int64_t end_bound);
+
+ private:
+ TraceProcessorContext* context_ = nullptr;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_DYNAMIC_EXPERIMENTAL_FLAT_SLICE_GENERATOR_H_
diff --git a/src/trace_processor/dynamic/experimental_flat_slice_generator_unittest.cc b/src/trace_processor/dynamic/experimental_flat_slice_generator_unittest.cc
new file mode 100644
index 000000000..fd1bac793
--- /dev/null
+++ b/src/trace_processor/dynamic/experimental_flat_slice_generator_unittest.cc
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "src/trace_processor/dynamic/experimental_flat_slice_generator.h"
+
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace trace_processor {
+namespace {
+
+class TableInseter {
+ public:
+ void Insert(int64_t ts, int64_t dur, uint32_t depth, TrackId track_id) {
+ tables::SliceTable::Row row;
+ row.ts = ts;
+ row.dur = dur;
+ row.depth = depth;
+ row.track_id = track_id;
+ rows_.emplace_back(std::move(row));
+ }
+
+ void Populate(tables::SliceTable& table) {
+ using R = tables::SliceTable::Row;
+ std::sort(rows_.begin(), rows_.end(),
+ [](const R& a, const R& b) { return a.ts < b.ts; });
+ for (const auto& row : rows_) {
+ table.Insert(row);
+ }
+ rows_.clear();
+ }
+
+ private:
+ std::vector<tables::SliceTable::Row> rows_;
+};
+
+class TableAsserter {
+ public:
+ TableAsserter(Table table) : table_(std::move(table)) {}
+
+ void NextSlice(int64_t ts, int64_t dur) {
+ ++idx_;
+ ASSERT_LT(idx_, table_.row_count());
+ ASSERT_EQ(table_.GetTypedColumnByName<int64_t>("ts")[idx_], ts)
+ << "where idx_ = " << idx_;
+ ASSERT_EQ(table_.GetTypedColumnByName<int64_t>("dur")[idx_], dur)
+ << "where idx_ = " << idx_;
+ }
+
+ bool HasMoreSlices() { return idx_ + 1 < table_.row_count(); }
+
+ private:
+ Table table_;
+ uint32_t idx_ = std::numeric_limits<uint32_t>::max();
+};
+
+TEST(ExperimentalFlatSliceGenerator, Smoke) {
+ StringPool pool;
+ TableInseter inserter;
+ tables::SliceTable table(&pool, nullptr);
+
+ // A simple stack on track 1.
+ inserter.Insert(100, 10, 0, TrackId{1});
+ inserter.Insert(104, 6, 1, TrackId{1});
+ inserter.Insert(107, 1, 2, TrackId{1});
+
+ // Back to back slices with a gap on track 2.
+ inserter.Insert(200, 10, 0, TrackId{2});
+ inserter.Insert(210, 10, 0, TrackId{2});
+ inserter.Insert(230, 10, 0, TrackId{2});
+
+ // Deep nesting on track 3.
+ inserter.Insert(300, 100, 0, TrackId{3});
+ inserter.Insert(301, 98, 1, TrackId{3});
+ inserter.Insert(302, 96, 2, TrackId{3});
+ inserter.Insert(303, 94, 3, TrackId{3});
+ inserter.Insert(304, 92, 4, TrackId{3});
+ inserter.Insert(305, 90, 5, TrackId{3});
+
+ // Populate the table.
+ inserter.Populate(table);
+
+ auto out = ExperimentalFlatSliceGenerator::ComputeFlatSliceTable(table, &pool,
+ 0, 400);
+ auto sorted = out->Sort({out->track_id().ascending(), out->ts().ascending()});
+
+ TableAsserter asserter(std::move(sorted));
+
+ // Track 1's slices.
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(0, 100));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(100, 4));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(104, 3));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(107, 1));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(108, 2));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(110, 0));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(110, 290));
+
+ // Track 2's slices.
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(0, 200));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(200, 10));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(210, 0));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(210, 10));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(220, 10));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(230, 10));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(240, 160));
+
+ // Track 3's slices.
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(0, 300));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(300, 1));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(301, 1));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(302, 1));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(303, 1));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(304, 1));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(305, 90));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(395, 1));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(396, 1));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(397, 1));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(398, 1));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(399, 1));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(400, 0));
+
+ ASSERT_FALSE(asserter.HasMoreSlices());
+}
+
+TEST(ExperimentalFlatSliceGenerator, Bounds) {
+ StringPool pool;
+ TableInseter inserter;
+ tables::SliceTable table(&pool, nullptr);
+
+ /// Our timebounds is between 200 and 300.
+ int64_t start = 200;
+ int64_t end = 300;
+
+ // Track 1 has all events inside bounds.
+ inserter.Insert(200, 10, 0, TrackId{1});
+ inserter.Insert(210, 10, 0, TrackId{1});
+ inserter.Insert(230, 10, 0, TrackId{1});
+
+ // Track 2 has a two stacks, first partially inside at start, second partially
+ // inside at end.
+ // First stack.
+ inserter.Insert(190, 20, 0, TrackId{2});
+ inserter.Insert(200, 9, 1, TrackId{2});
+ inserter.Insert(201, 1, 2, TrackId{2});
+
+ // Second stack.
+ inserter.Insert(290, 20, 0, TrackId{2});
+ inserter.Insert(299, 2, 1, TrackId{2});
+ inserter.Insert(300, 1, 2, TrackId{2});
+
+ // Track 3 has two stacks but *only* outside bounds.
+ inserter.Insert(190, 9, 0, TrackId{3});
+ inserter.Insert(195, 2, 1, TrackId{3});
+
+ inserter.Insert(300, 9, 0, TrackId{3});
+ inserter.Insert(301, 2, 1, TrackId{3});
+
+ // Track 4 has one stack which is partially inside at start.
+ inserter.Insert(190, 20, 0, TrackId{4});
+ inserter.Insert(201, 2, 1, TrackId{4});
+
+ // Populate the table.
+ inserter.Populate(table);
+
+ auto out = ExperimentalFlatSliceGenerator::ComputeFlatSliceTable(table, &pool,
+ start, end);
+ auto sorted = out->Sort({out->track_id().ascending(), out->ts().ascending()});
+
+ TableAsserter asserter(std::move(sorted));
+
+ // Track 1's slices.
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(200, 0));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(200, 10));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(210, 0));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(210, 10));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(220, 10));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(230, 10));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(240, 60));
+
+ // Track 2's slices.
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(200, 90));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(290, 9));
+ ASSERT_NO_FATAL_FAILURE(asserter.NextSlice(299, 1));
+
+ ASSERT_FALSE(asserter.HasMoreSlices());
+}
+
+} // namespace
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/dynamic/experimental_sched_upid_generator.cc b/src/trace_processor/dynamic/experimental_sched_upid_generator.cc
index 190691895..f0cd06157 100644
--- a/src/trace_processor/dynamic/experimental_sched_upid_generator.cc
+++ b/src/trace_processor/dynamic/experimental_sched_upid_generator.cc
@@ -41,20 +41,24 @@ uint32_t ExperimentalSchedUpidGenerator::EstimateRowCount() {
return sched_slice_table_->row_count();
}
-util::Status ExperimentalSchedUpidGenerator::ValidateConstraints(
+base::Status ExperimentalSchedUpidGenerator::ValidateConstraints(
const QueryConstraints&) {
- return util::OkStatus();
+ return base::OkStatus();
}
-std::unique_ptr<Table> ExperimentalSchedUpidGenerator::ComputeTable(
+base::Status ExperimentalSchedUpidGenerator::ComputeTable(
const std::vector<Constraint>&,
- const std::vector<Order>&) {
+ const std::vector<Order>&,
+ const BitVector&,
+ std::unique_ptr<Table>& table_return) {
if (!upid_column_) {
upid_column_.reset(new NullableVector<uint32_t>(ComputeUpidColumn()));
}
- return std::unique_ptr<Table>(new Table(sched_slice_table_->ExtendWithColumn(
- "upid", upid_column_.get(),
- TypedColumn<base::Optional<uint32_t>>::default_flags())));
+ table_return =
+ std::unique_ptr<Table>(new Table(sched_slice_table_->ExtendWithColumn(
+ "upid", upid_column_.get(),
+ TypedColumn<base::Optional<uint32_t>>::default_flags())));
+ return base::OkStatus();
}
NullableVector<uint32_t> ExperimentalSchedUpidGenerator::ComputeUpidColumn() {
diff --git a/src/trace_processor/dynamic/experimental_sched_upid_generator.h b/src/trace_processor/dynamic/experimental_sched_upid_generator.h
index 09e0dfac8..569e21256 100644
--- a/src/trace_processor/dynamic/experimental_sched_upid_generator.h
+++ b/src/trace_processor/dynamic/experimental_sched_upid_generator.h
@@ -35,9 +35,11 @@ class ExperimentalSchedUpidGenerator
Table::Schema CreateSchema() override;
std::string TableName() override;
uint32_t EstimateRowCount() override;
- util::Status ValidateConstraints(const QueryConstraints&) override;
- std::unique_ptr<Table> ComputeTable(const std::vector<Constraint>&,
- const std::vector<Order>&) override;
+ base::Status ValidateConstraints(const QueryConstraints&) override;
+ base::Status ComputeTable(const std::vector<Constraint>& cs,
+ const std::vector<Order>& ob,
+ const BitVector& cols_used,
+ std::unique_ptr<Table>& table_return) override;
private:
NullableVector<uint32_t> ComputeUpidColumn();
diff --git a/src/trace_processor/dynamic/experimental_slice_layout_generator.cc b/src/trace_processor/dynamic/experimental_slice_layout_generator.cc
index 0c864a17a..c6153af9d 100644
--- a/src/trace_processor/dynamic/experimental_slice_layout_generator.cc
+++ b/src/trace_processor/dynamic/experimental_slice_layout_generator.cc
@@ -62,20 +62,22 @@ uint32_t ExperimentalSliceLayoutGenerator::EstimateRowCount() {
return slice_table_->row_count();
}
-util::Status ExperimentalSliceLayoutGenerator::ValidateConstraints(
+base::Status ExperimentalSliceLayoutGenerator::ValidateConstraints(
const QueryConstraints& cs) {
for (const auto& c : cs.constraints()) {
if (c.column == kFilterTrackIdsColumnIndex && sqlite_utils::IsOpEq(c.op)) {
- return util::OkStatus();
+ return base::OkStatus();
}
}
- return util::ErrStatus(
+ return base::ErrStatus(
"experimental_slice_layout must have filter_track_ids constraint");
}
-std::unique_ptr<Table> ExperimentalSliceLayoutGenerator::ComputeTable(
+base::Status ExperimentalSliceLayoutGenerator::ComputeTable(
const std::vector<Constraint>& cs,
- const std::vector<Order>&) {
+ const std::vector<Order>&,
+ const BitVector&,
+ std::unique_ptr<Table>& table_return) {
std::set<TrackId> selected_tracks;
std::string filter_string = "";
for (const auto& c : cs) {
@@ -99,7 +101,8 @@ std::unique_ptr<Table> ExperimentalSliceLayoutGenerator::ComputeTable(
// Try and find the table in the cache.
auto it = layout_table_cache_.find(filter_id);
if (it != layout_table_cache_.end()) {
- return std::unique_ptr<Table>(new Table(it->second.Copy()));
+ table_return.reset(new Table(it->second.Copy()));
+ return base::OkStatus();
}
// Find all the slices for the tracks we want to filter and create a RowMap
@@ -124,7 +127,9 @@ std::unique_ptr<Table> ExperimentalSliceLayoutGenerator::ComputeTable(
// Compute the table and add it to the cache for future use.
Table layout_table = ComputeLayoutTable(filtered_table, filter_id);
auto res = layout_table_cache_.emplace(filter_id, std::move(layout_table));
- return std::unique_ptr<Table>(new Table(res.first->second.Copy()));
+
+ table_return.reset(new Table(res.first->second.Copy()));
+ return base::OkStatus();
}
// Build up a table of slice id -> root slice id by observing each
@@ -235,7 +240,7 @@ Table ExperimentalSliceLayoutGenerator::ComputeLayoutTable(
{
auto it = still_open.begin();
while (it != still_open.end()) {
- if ((*it)->end < start) {
+ if ((*it)->end <= start) {
it = still_open.erase(it);
} else {
++it;
diff --git a/src/trace_processor/dynamic/experimental_slice_layout_generator.h b/src/trace_processor/dynamic/experimental_slice_layout_generator.h
index 4b033f75f..cc27bb227 100644
--- a/src/trace_processor/dynamic/experimental_slice_layout_generator.h
+++ b/src/trace_processor/dynamic/experimental_slice_layout_generator.h
@@ -38,9 +38,11 @@ class ExperimentalSliceLayoutGenerator
Table::Schema CreateSchema() override;
std::string TableName() override;
uint32_t EstimateRowCount() override;
- util::Status ValidateConstraints(const QueryConstraints&) override;
- std::unique_ptr<Table> ComputeTable(const std::vector<Constraint>&,
- const std::vector<Order>&) override;
+ base::Status ValidateConstraints(const QueryConstraints&) override;
+ base::Status ComputeTable(const std::vector<Constraint>& cs,
+ const std::vector<Order>& ob,
+ const BitVector& cols_used,
+ std::unique_ptr<Table>& table_return) override;
private:
Table ComputeLayoutTable(const Table& table, StringPool::Id filter_id);
diff --git a/src/trace_processor/dynamic/experimental_slice_layout_generator_unittest.cc b/src/trace_processor/dynamic/experimental_slice_layout_generator_unittest.cc
index 0f2945ab4..81fdb7d45 100644
--- a/src/trace_processor/dynamic/experimental_slice_layout_generator_unittest.cc
+++ b/src/trace_processor/dynamic/experimental_slice_layout_generator_unittest.cc
@@ -18,6 +18,7 @@
#include <algorithm>
+#include "src/trace_processor/containers/bit_vector.h"
#include "test/gtest_and_gmock.h"
namespace perfetto {
@@ -103,8 +104,11 @@ TEST(ExperimentalSliceLayoutGeneratorTest, SingleRow) {
ExperimentalSliceLayoutGenerator gen(&pool, &slice_table);
- std::unique_ptr<Table> table = gen.ComputeTable(
- {Constraint{kColumn, FilterOp::kEq, SqlValue::String("1")}}, {});
+ std::unique_ptr<Table> table;
+ auto status = gen.ComputeTable(
+ {Constraint{kColumn, FilterOp::kEq, SqlValue::String("1")}}, {},
+ BitVector(), table);
+ EXPECT_TRUE(status.ok());
ExpectOutput(*table, R"(
#####
)");
@@ -121,8 +125,11 @@ TEST(ExperimentalSliceLayoutGeneratorTest, DoubleRow) {
ExperimentalSliceLayoutGenerator gen(&pool, &slice_table);
- std::unique_ptr<Table> table = gen.ComputeTable(
- {Constraint{kColumn, FilterOp::kEq, SqlValue::String("1")}}, {});
+ std::unique_ptr<Table> table;
+ auto status = gen.ComputeTable(
+ {Constraint{kColumn, FilterOp::kEq, SqlValue::String("1")}}, {},
+ BitVector(), table);
+ EXPECT_TRUE(status.ok());
ExpectOutput(*table, R"(
#####
#####
@@ -144,8 +151,11 @@ TEST(ExperimentalSliceLayoutGeneratorTest, MultipleRows) {
ExperimentalSliceLayoutGenerator gen(&pool, &slice_table);
- std::unique_ptr<Table> table = gen.ComputeTable(
- {Constraint{kColumn, FilterOp::kEq, SqlValue::String("1")}}, {});
+ std::unique_ptr<Table> table;
+ auto status = gen.ComputeTable(
+ {Constraint{kColumn, FilterOp::kEq, SqlValue::String("1")}}, {},
+ BitVector(), table);
+ EXPECT_TRUE(status.ok());
ExpectOutput(*table, R"(
#####
####
@@ -174,8 +184,11 @@ TEST(ExperimentalSliceLayoutGeneratorTest, MultipleTracks) {
ExperimentalSliceLayoutGenerator gen(&pool, &slice_table);
- std::unique_ptr<Table> table = gen.ComputeTable(
- {Constraint{kColumn, FilterOp::kEq, SqlValue::String("1,2")}}, {});
+ std::unique_ptr<Table> table;
+ auto status = gen.ComputeTable(
+ {Constraint{kColumn, FilterOp::kEq, SqlValue::String("1,2")}}, {},
+ BitVector(), table);
+ EXPECT_TRUE(status.ok());
ExpectOutput(*table, R"(
####
##
@@ -209,8 +222,11 @@ TEST(ExperimentalSliceLayoutGeneratorTest, MultipleTracksWithGap) {
ExperimentalSliceLayoutGenerator gen(&pool, &slice_table);
- std::unique_ptr<Table> table = gen.ComputeTable(
- {Constraint{kColumn, FilterOp::kEq, SqlValue::String("1,2")}}, {});
+ std::unique_ptr<Table> table;
+ auto status = gen.ComputeTable(
+ {Constraint{kColumn, FilterOp::kEq, SqlValue::String("1,2")}}, {},
+ BitVector(), table);
+ EXPECT_TRUE(status.ok());
ExpectOutput(*table, R"(
#### ####
## ##
@@ -241,8 +257,11 @@ TEST(ExperimentalSliceLayoutGeneratorTest, FilterOutTracks) {
base::ignore_result(q);
ExperimentalSliceLayoutGenerator gen(&pool, &slice_table);
- std::unique_ptr<Table> table = gen.ComputeTable(
- {Constraint{kColumn, FilterOp::kEq, SqlValue::String("1,2")}}, {});
+ std::unique_ptr<Table> table;
+ auto status = gen.ComputeTable(
+ {Constraint{kColumn, FilterOp::kEq, SqlValue::String("1,2")}}, {},
+ BitVector(), table);
+ EXPECT_TRUE(status.ok());
ExpectOutput(*table, R"(
####
##
diff --git a/src/trace_processor/dynamic/thread_state_generator.cc b/src/trace_processor/dynamic/thread_state_generator.cc
index e2e7f89f5..7790a1f73 100644
--- a/src/trace_processor/dynamic/thread_state_generator.cc
+++ b/src/trace_processor/dynamic/thread_state_generator.cc
@@ -31,14 +31,16 @@ ThreadStateGenerator::ThreadStateGenerator(TraceProcessorContext* context)
ThreadStateGenerator::~ThreadStateGenerator() = default;
-util::Status ThreadStateGenerator::ValidateConstraints(
+base::Status ThreadStateGenerator::ValidateConstraints(
const QueryConstraints&) {
- return util::OkStatus();
+ return base::OkStatus();
}
-std::unique_ptr<Table> ThreadStateGenerator::ComputeTable(
+base::Status ThreadStateGenerator::ComputeTable(
const std::vector<Constraint>&,
- const std::vector<Order>&) {
+ const std::vector<Order>&,
+ const BitVector&,
+ std::unique_ptr<Table>& table_return) {
if (!unsorted_thread_state_table_) {
int64_t trace_end_ts =
context_->storage->GetTraceTimestampBoundsNs().second;
@@ -52,8 +54,11 @@ std::unique_ptr<Table> ThreadStateGenerator::ComputeTable(
sorted_thread_state_table_ = unsorted_thread_state_table_->Sort(
{unsorted_thread_state_table_->ts().ascending()});
}
+ // TODO(rsavitski): return base::ErrStatus instead?
PERFETTO_CHECK(sorted_thread_state_table_);
- return std::unique_ptr<Table>(new Table(sorted_thread_state_table_->Copy()));
+ table_return =
+ std::unique_ptr<Table>(new Table(sorted_thread_state_table_->Copy()));
+ return base::OkStatus();
}
std::unique_ptr<tables::ThreadStateTable>
@@ -65,19 +70,23 @@ ThreadStateGenerator::ComputeThreadStateTable(int64_t trace_end_ts) {
const auto& instants = context_->storage->instant_table();
// In both tables, exclude utid == 0 which represents the idle thread.
- Table sched = raw_sched.Filter({raw_sched.utid().ne(0)});
+ Table sched = raw_sched.Filter({raw_sched.utid().ne(0)},
+ RowMap::OptimizeFor::kLookupSpeed);
Table waking = instants.Filter(
- {instants.name().eq("sched_waking"), instants.ref().ne(0)});
+ {instants.name().eq("sched_waking"), instants.ref().ne(0)},
+ RowMap::OptimizeFor::kLookupSpeed);
// We prefer to use waking if at all possible and fall back to wakeup if not
// available.
if (waking.row_count() == 0) {
waking = instants.Filter(
- {instants.name().eq("sched_wakeup"), instants.ref().ne(0)});
+ {instants.name().eq("sched_wakeup"), instants.ref().ne(0)},
+ RowMap::OptimizeFor::kLookupSpeed);
}
Table sched_blocked_reason = instants.Filter(
- {instants.name().eq("sched_blocked_reason"), instants.ref().ne(0)});
+ {instants.name().eq("sched_blocked_reason"), instants.ref().ne(0)},
+ RowMap::OptimizeFor::kLookupSpeed);
const auto& sched_ts_col = sched.GetTypedColumnByName<int64_t>("ts");
const auto& waking_ts_col = waking.GetTypedColumnByName<int64_t>("ts");
@@ -87,7 +96,7 @@ ThreadStateGenerator::ComputeThreadStateTable(int64_t trace_end_ts) {
uint32_t sched_idx = 0;
uint32_t waking_idx = 0;
uint32_t blocked_idx = 0;
- std::unordered_map<UniqueTid, ThreadSchedInfo> state_map;
+ TidInfoMap state_map(/*initial_capacity=*/1024);
while (sched_idx < sched.row_count() || waking_idx < waking.row_count() ||
blocked_idx < sched_blocked_reason.row_count()) {
int64_t sched_ts = sched_idx < sched.row_count()
@@ -113,21 +122,21 @@ ThreadStateGenerator::ComputeThreadStateTable(int64_t trace_end_ts) {
}
// At the end, go through and flush any remaining pending events.
- for (const auto& utid_to_pending_info : state_map) {
- UniqueTid utid = utid_to_pending_info.first;
- const ThreadSchedInfo& pending_info = utid_to_pending_info.second;
+ for (auto it = state_map.GetIterator(); it; ++it) {
+ // for (const auto& utid_to_pending_info : state_map) {
+ UniqueTid utid = it.key();
+ const ThreadSchedInfo& pending_info = it.value();
FlushPendingEventsForThread(utid, pending_info, table.get(), base::nullopt);
}
return table;
}
-void ThreadStateGenerator::AddSchedEvent(
- const Table& sched,
- uint32_t sched_idx,
- std::unordered_map<UniqueTid, ThreadSchedInfo>& state_map,
- int64_t trace_end_ts,
- tables::ThreadStateTable* table) {
+void ThreadStateGenerator::AddSchedEvent(const Table& sched,
+ uint32_t sched_idx,
+ TidInfoMap& state_map,
+ int64_t trace_end_ts,
+ tables::ThreadStateTable* table) {
int64_t ts = sched.GetTypedColumnByName<int64_t>("ts")[sched_idx];
UniqueTid utid = sched.GetTypedColumnByName<uint32_t>("utid")[sched_idx];
ThreadSchedInfo* info = &state_map[utid];
@@ -197,10 +206,9 @@ void ThreadStateGenerator::AddSchedEvent(
info->scheduled_row = id_and_row.row;
}
-void ThreadStateGenerator::AddWakingEvent(
- const Table& waking,
- uint32_t waking_idx,
- std::unordered_map<UniqueTid, ThreadSchedInfo>& state_map) {
+void ThreadStateGenerator::AddWakingEvent(const Table& waking,
+ uint32_t waking_idx,
+ TidInfoMap& state_map) {
int64_t ts = waking.GetTypedColumnByName<int64_t>("ts")[waking_idx];
UniqueTid utid = static_cast<UniqueTid>(
waking.GetTypedColumnByName<int64_t>("ref")[waking_idx]);
@@ -295,10 +303,9 @@ void ThreadStateGenerator::FlushPendingEventsForThread(
}
}
-void ThreadStateGenerator::AddBlockedReasonEvent(
- const Table& blocked_reason,
- uint32_t blocked_idx,
- std::unordered_map<UniqueTid, ThreadSchedInfo>& state_map) {
+void ThreadStateGenerator::AddBlockedReasonEvent(const Table& blocked_reason,
+ uint32_t blocked_idx,
+ TidInfoMap& state_map) {
const auto& utid_col = blocked_reason.GetTypedColumnByName<int64_t>("ref");
const auto& arg_set_id_col =
blocked_reason.GetTypedColumnByName<uint32_t>("arg_set_id");
@@ -308,7 +315,7 @@ void ThreadStateGenerator::AddBlockedReasonEvent(
ThreadSchedInfo& info = state_map[utid];
base::Optional<Variadic> opt_value;
- util::Status status =
+ base::Status status =
context_->storage->ExtractArg(arg_set_id, "io_wait", &opt_value);
// We can't do anything better than ignoring any errors here.
diff --git a/src/trace_processor/dynamic/thread_state_generator.h b/src/trace_processor/dynamic/thread_state_generator.h
index 75895ba28..8e111de96 100644
--- a/src/trace_processor/dynamic/thread_state_generator.h
+++ b/src/trace_processor/dynamic/thread_state_generator.h
@@ -19,6 +19,7 @@
#include "src/trace_processor/sqlite/db_sqlite_table.h"
+#include "perfetto/ext/base/flat_hash_map.h"
#include "src/trace_processor/storage/trace_storage.h"
namespace perfetto {
@@ -37,9 +38,11 @@ class ThreadStateGenerator : public DbSqliteTable::DynamicTableGenerator {
Table::Schema CreateSchema() override;
std::string TableName() override;
uint32_t EstimateRowCount() override;
- util::Status ValidateConstraints(const QueryConstraints&) override;
- std::unique_ptr<Table> ComputeTable(const std::vector<Constraint>& cs,
- const std::vector<Order>& ob) override;
+ base::Status ValidateConstraints(const QueryConstraints&) override;
+ base::Status ComputeTable(const std::vector<Constraint>& cs,
+ const std::vector<Order>& ob,
+ const BitVector& cols_used,
+ std::unique_ptr<Table>& table_return) override;
// Visible for testing.
std::unique_ptr<tables::ThreadStateTable> ComputeThreadStateTable(
@@ -54,22 +57,25 @@ class ThreadStateGenerator : public DbSqliteTable::DynamicTableGenerator {
base::Optional<int64_t> runnable_ts;
base::Optional<StringId> blocked_function;
};
+ using TidInfoMap = base::FlatHashMap<UniqueTid,
+ ThreadSchedInfo,
+ base::AlreadyHashed<UniqueTid>,
+ base::QuadraticProbe,
+ /*AppendOnly=*/true>;
void AddSchedEvent(const Table& sched,
uint32_t sched_idx,
- std::unordered_map<UniqueTid, ThreadSchedInfo>& state_map,
+ TidInfoMap& state_map,
int64_t trace_end_ts,
tables::ThreadStateTable* table);
- void AddWakingEvent(
- const Table& wakeup,
- uint32_t wakeup_idx,
- std::unordered_map<UniqueTid, ThreadSchedInfo>& state_map);
+ void AddWakingEvent(const Table& wakeup,
+ uint32_t wakeup_idx,
+ TidInfoMap& state_map);
- void AddBlockedReasonEvent(
- const Table& blocked_reason,
- uint32_t blocked_idx,
- std::unordered_map<UniqueTid, ThreadSchedInfo>& state_map);
+ void AddBlockedReasonEvent(const Table& blocked_reason,
+ uint32_t blocked_idx,
+ TidInfoMap& state_map);
void FlushPendingEventsForThread(UniqueTid utid,
const ThreadSchedInfo&,
diff --git a/src/trace_processor/export_json.cc b/src/trace_processor/export_json.cc
index fe7381359..e05680ea0 100644
--- a/src/trace_processor/export_json.cc
+++ b/src/trace_processor/export_json.cc
@@ -17,11 +17,11 @@
#include "perfetto/ext/trace_processor/export_json.h"
#include "src/trace_processor/export_json.h"
-#include <inttypes.h>
#include <stdio.h>
#include <sstream>
#include <algorithm>
+#include <cinttypes>
#include <cmath>
#include <cstring>
#include <deque>
@@ -85,8 +85,11 @@ const char kLegacyEventLocalIdKey[] = "local_id";
const char kLegacyEventIdScopeKey[] = "id_scope";
const char kStrippedArgument[] = "__stripped__";
-const char* GetNonNullString(const TraceStorage* storage, StringId id) {
- return id == kNullStringId ? "" : storage->GetString(id).c_str();
+const char* GetNonNullString(const TraceStorage* storage,
+ base::Optional<StringId> id) {
+ return id == base::nullopt || *id == kNullStringId
+ ? ""
+ : storage->GetString(*id).c_str();
}
class JsonExporter {
@@ -561,6 +564,8 @@ class JsonExporter {
return base::Uint64ToHexString(variadic.pointer_value);
case Variadic::kBool:
return variadic.bool_value;
+ case Variadic::kNull:
+ return base::Uint64ToHexString(0);
case Variadic::kJson:
Json::CharReaderBuilder b;
auto reader = std::unique_ptr<Json::CharReader>(b.newCharReader());
@@ -704,7 +709,7 @@ class JsonExporter {
const auto& thread_table = storage_->thread_table();
for (UniqueTid utid = 0; utid < thread_table.row_count(); ++utid) {
auto opt_name = thread_table.name()[utid];
- if (!opt_name.is_null()) {
+ if (opt_name.has_value()) {
const char* thread_name = GetNonNullString(storage_, opt_name);
auto pid_and_tid = UtidToPidAndTid(utid);
writer_.WriteMetadataEvent("thread_name", "name", thread_name,
@@ -718,7 +723,7 @@ class JsonExporter {
const auto& process_table = storage_->process_table();
for (UniquePid upid = 0; upid < process_table.row_count(); ++upid) {
auto opt_name = process_table.name()[upid];
- if (!opt_name.is_null()) {
+ if (opt_name.has_value()) {
const char* process_name = GetNonNullString(storage_, opt_name);
writer_.WriteMetadataEvent("process_name", "name", process_name,
UpidToPid(upid), /*tid=*/0);
@@ -1111,8 +1116,10 @@ class JsonExporter {
} else {
auto opt_slice_out_idx = slice_table.id().IndexOf(slice_out);
PERFETTO_DCHECK(opt_slice_out_idx.has_value());
- StringId cat_id = slice_table.category()[opt_slice_out_idx.value()];
- StringId name_id = slice_table.name()[opt_slice_out_idx.value()];
+ base::Optional<StringId> cat_id =
+ slice_table.category()[opt_slice_out_idx.value()];
+ base::Optional<StringId> name_id =
+ slice_table.name()[opt_slice_out_idx.value()];
cat = GetNonNullString(storage_, cat_id);
name = GetNonNullString(storage_, name_id);
}
@@ -1409,17 +1416,17 @@ class JsonExporter {
storage_->symbol_table().name()[*opt_symbol_set_id]);
}
- char frame_entry[1024];
- snprintf(frame_entry, sizeof(frame_entry), "%s - %s [%s]\n",
- (symbol_name.empty()
- ? base::Uint64ToHexString(
- static_cast<uint64_t>(frames.rel_pc()[frame_row]))
- .c_str()
- : symbol_name.c_str()),
- GetNonNullString(storage_, mappings.name()[mapping_row]),
- GetNonNullString(storage_, mappings.build_id()[mapping_row]));
+ base::StackString<1024> frame_entry(
+ "%s - %s [%s]\n",
+ (symbol_name.empty()
+ ? base::Uint64ToHexString(
+ static_cast<uint64_t>(frames.rel_pc()[frame_row]))
+ .c_str()
+ : symbol_name.c_str()),
+ GetNonNullString(storage_, mappings.name()[mapping_row]),
+ GetNonNullString(storage_, mappings.build_id()[mapping_row]));
- callstack.emplace_back(frame_entry);
+ callstack.emplace_back(frame_entry.ToStdString());
opt_callsite_id = callsites.parent_id()[callsite_row];
}
@@ -1929,4 +1936,3 @@ util::Status ExportJson(const TraceStorage* storage, FILE* output) {
} // namespace json
} // namespace trace_processor
} // namespace perfetto
-
diff --git a/src/trace_processor/export_json_unittest.cc b/src/trace_processor/export_json_unittest.cc
index 9dadb4481..961ecfc90 100644
--- a/src/trace_processor/export_json_unittest.cc
+++ b/src/trace_processor/export_json_unittest.cc
@@ -32,6 +32,7 @@
#include "src/trace_processor/importers/common/track_tracker.h"
#include "src/trace_processor/importers/proto/metadata_tracker.h"
#include "src/trace_processor/importers/proto/track_event_tracker.h"
+#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/trace_processor_context.h"
#include "test/gtest_and_gmock.h"
@@ -230,8 +231,8 @@ TEST_F(ExportJsonTest, StorageWithThreadName) {
}
TEST_F(ExportJsonTest, SystemEventsIgnored) {
- TrackId track = context_.track_tracker->CreateAndroidAsyncTrack(
- /*name=*/kNullStringId, /*upid=*/0);
+ TrackId track = context_.track_tracker->CreateProcessAsyncTrack(
+ /*name=*/kNullStringId, /*upid=*/0, /*source=*/kNullStringId);
context_.args_tracker->Flush(); // Flush track args.
// System events have no category.
@@ -827,7 +828,8 @@ TEST_F(ExportJsonTest, InstantEventOnThread) {
TEST_F(ExportJsonTest, DuplicatePidAndTid) {
UniqueTid upid1 = context_.process_tracker->StartNewProcess(
- base::nullopt, base::nullopt, 1, kNullStringId);
+ base::nullopt, base::nullopt, 1, kNullStringId,
+ ThreadNamePriority::kTrackDescriptor);
UniqueTid utid1a = context_.process_tracker->UpdateThread(1, 1);
UniqueTid utid1b = context_.process_tracker->UpdateThread(2, 1);
UniqueTid utid1c = context_.process_tracker->StartNewThread(base::nullopt, 2);
@@ -835,7 +837,8 @@ TEST_F(ExportJsonTest, DuplicatePidAndTid) {
ASSERT_EQ(utid1c, context_.process_tracker->UpdateThread(2, 1));
UniqueTid upid2 = context_.process_tracker->StartNewProcess(
- base::nullopt, base::nullopt, 1, kNullStringId);
+ base::nullopt, base::nullopt, 1, kNullStringId,
+ ThreadNamePriority::kTrackDescriptor);
UniqueTid utid2a = context_.process_tracker->UpdateThread(1, 1);
UniqueTid utid2b = context_.process_tracker->UpdateThread(2, 1);
diff --git a/src/trace_processor/forwarding_trace_parser.cc b/src/trace_processor/forwarding_trace_parser.cc
index 4ba663e16..619a9e650 100644
--- a/src/trace_processor/forwarding_trace_parser.cc
+++ b/src/trace_processor/forwarding_trace_parser.cc
@@ -40,6 +40,17 @@ std::string RemoveWhitespace(std::string str) {
return str;
}
+TraceSorter::SortingMode ConvertSortingMode(SortingMode sorting_mode) {
+ switch (sorting_mode) {
+ case SortingMode::kDefaultHeuristics:
+ case SortingMode::kForceFlushPeriodWindowedSort:
+ return TraceSorter::SortingMode::kDefault;
+ case SortingMode::kForceFullSort:
+ return TraceSorter::SortingMode::kFullSort;
+ }
+ PERFETTO_FATAL("For GCC");
+}
+
// Fuchsia traces have a magic number as documented here:
// https://fuchsia.googlesource.com/fuchsia/+/HEAD/docs/development/tracing/trace-format/README.md#magic-number-record-trace-info-type-0
constexpr uint64_t kFuchsiaMagicNumber = 0x0016547846040010;
@@ -51,17 +62,15 @@ ForwardingTraceParser::ForwardingTraceParser(TraceProcessorContext* context)
ForwardingTraceParser::~ForwardingTraceParser() {}
-util::Status ForwardingTraceParser::Parse(std::unique_ptr<uint8_t[]> data,
- size_t size) {
+util::Status ForwardingTraceParser::Parse(TraceBlobView blob) {
// If this is the first Parse() call, guess the trace type and create the
// appropriate parser.
- static const int64_t kMaxWindowSize = std::numeric_limits<int64_t>::max();
if (!reader_) {
TraceType trace_type;
{
auto scoped_trace = context_->storage->TraceExecutionTimeIntoStats(
stats::guess_trace_type_duration_ns);
- trace_type = GuessTraceType(data.get(), size);
+ trace_type = GuessTraceType(blob.data(), blob.size());
}
switch (trace_type) {
case kJsonTraceType: {
@@ -70,8 +79,9 @@ util::Status ForwardingTraceParser::Parse(std::unique_ptr<uint8_t[]> data,
reader_ = std::move(context_->json_trace_tokenizer);
// JSON traces have no guarantees about the order of events in them.
- context_->sorter.reset(new TraceSorter(
- std::move(context_->json_trace_parser), kMaxWindowSize));
+ context_->sorter.reset(
+ new TraceSorter(context_, std::move(context_->json_trace_parser),
+ TraceSorter::SortingMode::kFullSort));
} else {
return util::ErrStatus("JSON support is disabled");
}
@@ -79,12 +89,12 @@ util::Status ForwardingTraceParser::Parse(std::unique_ptr<uint8_t[]> data,
}
case kProtoTraceType: {
PERFETTO_DLOG("Proto trace detected");
- // This will be reduced once we read the trace config and we see flush
- // period being set.
+ auto sorting_mode = ConvertSortingMode(context_->config.sorting_mode);
reader_.reset(new ProtoTraceReader(context_));
context_->sorter.reset(new TraceSorter(
+ context_,
std::unique_ptr<TraceParser>(new ProtoTraceParser(context_)),
- kMaxWindowSize));
+ sorting_mode));
context_->process_tracker->SetPidZeroIgnoredForIdleProcess();
break;
}
@@ -101,7 +111,8 @@ util::Status ForwardingTraceParser::Parse(std::unique_ptr<uint8_t[]> data,
// Fuschia traces can have massively out of order events.
context_->sorter.reset(new TraceSorter(
- std::move(context_->fuchsia_trace_parser), kMaxWindowSize));
+ context_, std::move(context_->fuchsia_trace_parser),
+ TraceSorter::SortingMode::kFullSort));
} else {
return util::ErrStatus("Fuchsia support is disabled");
}
@@ -136,7 +147,7 @@ util::Status ForwardingTraceParser::Parse(std::unique_ptr<uint8_t[]> data,
}
}
- return reader_->Parse(std::move(data), size);
+ return reader_->Parse(std::move(blob));
}
void ForwardingTraceParser::NotifyEndOfFile() {
@@ -147,7 +158,7 @@ TraceType GuessTraceType(const uint8_t* data, size_t size) {
if (size == 0)
return kUnknownTraceType;
std::string start(reinterpret_cast<const char*>(data),
- std::min<size_t>(size, 20));
+ std::min<size_t>(size, kGuessTraceMaxLookahead));
if (size >= 8) {
uint64_t first_word;
memcpy(&first_word, data, sizeof(first_word));
@@ -155,9 +166,9 @@ TraceType GuessTraceType(const uint8_t* data, size_t size) {
return kFuchsiaTraceType;
}
std::string start_minus_white_space = RemoveWhitespace(start);
- if (base::StartsWith(start_minus_white_space, "{"))
+ if (base::StartsWith(start_minus_white_space, "{\""))
return kJsonTraceType;
- if (base::StartsWith(start_minus_white_space, "[{"))
+ if (base::StartsWith(start_minus_white_space, "[{\""))
return kJsonTraceType;
// Systrace with header but no leading HTML.
@@ -169,10 +180,16 @@ TraceType GuessTraceType(const uint8_t* data, size_t size) {
base::StartsWith(start, "<html>"))
return kSystraceTraceType;
- // Ctrace is deflate'ed systrace.
- if (base::Contains(start, "TRACE:"))
+ // Traces obtained from atrace -z (compress).
+ // They all have the string "TRACE:" followed by 78 9C which is a zlib header
+ // for "deflate, default compression, window size=32K" (see b/208691037)
+ if (base::Contains(start, "TRACE:\n\x78\x9c"))
return kCtraceTraceType;
+ // Traces obtained from atrace without -z (no compression).
+ if (base::Contains(start, "TRACE:\n"))
+ return kSystraceTraceType;
+
// Ninja's buils log (.ninja_log).
if (base::StartsWith(start, "# ninja log"))
return kNinjaLogTraceType;
diff --git a/src/trace_processor/forwarding_trace_parser.h b/src/trace_processor/forwarding_trace_parser.h
index 0da568a89..566b3b8a5 100644
--- a/src/trace_processor/forwarding_trace_parser.h
+++ b/src/trace_processor/forwarding_trace_parser.h
@@ -24,6 +24,8 @@
namespace perfetto {
namespace trace_processor {
+constexpr size_t kGuessTraceMaxLookahead = 64;
+
enum TraceType {
kUnknownTraceType,
kProtoTraceType,
@@ -43,7 +45,7 @@ class ForwardingTraceParser : public ChunkedTraceReader {
~ForwardingTraceParser() override;
// ChunkedTraceReader implementation
- util::Status Parse(std::unique_ptr<uint8_t[]>, size_t) override;
+ util::Status Parse(TraceBlobView) override;
void NotifyEndOfFile() override;
private:
diff --git a/src/trace_processor/forwarding_trace_parser_unittest.cc b/src/trace_processor/forwarding_trace_parser_unittest.cc
index 048ab14bf..059caa064 100644
--- a/src/trace_processor/forwarding_trace_parser_unittest.cc
+++ b/src/trace_processor/forwarding_trace_parser_unittest.cc
@@ -44,7 +44,7 @@ TEST(TraceProcessorImplTest, GuessTraceType_JsonWithSpaces) {
// Some Android build traces do not contain the wrapper. See b/118826940
TEST(TraceProcessorImplTest, GuessTraceType_JsonMissingTraceEvents) {
- const uint8_t prefix[] = "[{";
+ const uint8_t prefix[] = "[{\"";
EXPECT_EQ(kJsonTraceType, GuessTraceType(prefix, sizeof(prefix)));
}
diff --git a/src/trace_processor/importers/BUILD.gn b/src/trace_processor/importers/BUILD.gn
index fceb53ffc..908ae8d4c 100644
--- a/src/trace_processor/importers/BUILD.gn
+++ b/src/trace_processor/importers/BUILD.gn
@@ -21,12 +21,10 @@ perfetto_cc_proto_descriptor("gen_cc_config_descriptor") {
perfetto_cc_proto_descriptor("gen_cc_chrome_track_event_descriptor") {
descriptor_name = "chrome_track_event.descriptor"
- descriptor_target =
- "../../../protos/third_party/chromium:chrome_track_event_descriptor"
+ descriptor_target = "../../../protos/third_party/chromium:descriptor"
}
perfetto_cc_proto_descriptor("gen_cc_track_event_descriptor") {
descriptor_name = "track_event.descriptor"
- descriptor_target =
- "../../../protos/perfetto/trace/track_event:track_event_descriptor"
+ descriptor_target = "../../../protos/perfetto/trace/track_event:descriptor"
}
diff --git a/src/trace_processor/importers/additional_modules.cc b/src/trace_processor/importers/additional_modules.cc
index 1627893d1..5368ed957 100644
--- a/src/trace_processor/importers/additional_modules.cc
+++ b/src/trace_processor/importers/additional_modules.cc
@@ -20,6 +20,7 @@
#include "src/trace_processor/importers/proto/graphics_event_module.h"
#include "src/trace_processor/importers/proto/heap_graph_module.h"
#include "src/trace_processor/importers/proto/system_probes_module.h"
+#include "src/trace_processor/importers/proto/translation_table_module.h"
namespace perfetto {
namespace trace_processor {
@@ -29,6 +30,7 @@ void RegisterAdditionalModules(TraceProcessorContext* context) {
context->modules.emplace_back(new GraphicsEventModule(context));
context->modules.emplace_back(new HeapGraphModule(context));
context->modules.emplace_back(new SystemProbesModule(context));
+ context->modules.emplace_back(new TranslationTableModule(context));
context->modules.emplace_back(new FtraceModuleImpl(context));
// Ftrace module is special, because it has one extra method for parsing
// ftrace packets. So we need to store a pointer to it separately.
diff --git a/src/trace_processor/importers/common/BUILD.gn b/src/trace_processor/importers/common/BUILD.gn
index e187260c7..5d1921869 100644
--- a/src/trace_processor/importers/common/BUILD.gn
+++ b/src/trace_processor/importers/common/BUILD.gn
@@ -18,6 +18,8 @@ source_set("common") {
sources = [
"args_tracker.cc",
"args_tracker.h",
+ "args_translation_table.cc",
+ "args_translation_table.h",
"chunked_trace_reader.h",
"clock_tracker.cc",
"clock_tracker.h",
@@ -31,19 +33,22 @@ source_set("common") {
"process_tracker.h",
"slice_tracker.cc",
"slice_tracker.h",
+ "slice_translation_table.cc",
+ "slice_translation_table.h",
"system_info_tracker.cc",
"system_info_tracker.h",
- "trace_blob_view.h",
"trace_parser.h",
"track_tracker.cc",
"track_tracker.h",
]
public_deps = [
"../:gen_cc_config_descriptor",
+ "../../util:proto_to_args_parser",
"../../util:protozero_to_text",
]
deps = [
"../../../../gn:default_deps",
+ "../../../../include/perfetto/trace_processor",
"../../../../include/perfetto/trace_processor:basic_types",
"../../../../protos/perfetto/common:zero",
"../../../../protos/perfetto/trace:zero",
@@ -56,11 +61,13 @@ source_set("common") {
source_set("unittests") {
sources = [
+ "args_translation_table_unittest.cc",
"clock_tracker_unittest.cc",
"event_tracker_unittest.cc",
"flow_tracker_unittest.cc",
"process_tracker_unittest.cc",
"slice_tracker_unittest.cc",
+ "slice_translation_table_unittest.cc",
]
testonly = true
deps = [
diff --git a/src/trace_processor/importers/common/args_tracker.cc b/src/trace_processor/importers/common/args_tracker.cc
index c7a5b9723..1b6e0e9da 100644
--- a/src/trace_processor/importers/common/args_tracker.cc
+++ b/src/trace_processor/importers/common/args_tracker.cc
@@ -79,7 +79,7 @@ void ArgsTracker::Flush() {
}
ArgSetId set_id =
- context_->global_args_tracker->AddArgSet(args_, i, next_rid_idx);
+ context_->global_args_tracker->AddArgSet(&args_[0], i, next_rid_idx);
column->Set(row, SqlValue::Long(set_id));
i = next_rid_idx;
@@ -96,9 +96,9 @@ ArgsTracker::BoundInserter::BoundInserter(ArgsTracker* args_tracker,
ArgsTracker::BoundInserter::~BoundInserter() {}
-ArgsTracker::BoundInserter::BoundInserter(BoundInserter&&) = default;
+ArgsTracker::BoundInserter::BoundInserter(BoundInserter&&) noexcept = default;
ArgsTracker::BoundInserter& ArgsTracker::BoundInserter::operator=(
- BoundInserter&&) = default;
+ BoundInserter&&) noexcept = default;
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/importers/common/args_tracker.h b/src/trace_processor/importers/common/args_tracker.h
index 4c2c94328..9452b9566 100644
--- a/src/trace_processor/importers/common/args_tracker.h
+++ b/src/trace_processor/importers/common/args_tracker.h
@@ -17,6 +17,7 @@
#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_ARGS_TRACKER_H_
#define SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_ARGS_TRACKER_H_
+#include "perfetto/ext/base/small_vector.h"
#include "src/trace_processor/importers/common/global_args_tracker.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/trace_processor_context.h"
@@ -38,8 +39,8 @@ class ArgsTracker {
public:
virtual ~BoundInserter();
- BoundInserter(BoundInserter&&);
- BoundInserter& operator=(BoundInserter&&);
+ BoundInserter(BoundInserter&&) noexcept;
+ BoundInserter& operator=(BoundInserter&&) noexcept;
BoundInserter(const BoundInserter&) = delete;
BoundInserter& operator=(const BoundInserter&) = delete;
@@ -64,18 +65,19 @@ class ArgsTracker {
// IncrementArrayEntryIndex() and GetNextArrayEntryIndex() provide a way to
// track the next array index for an array under a specific key.
- void IncrementArrayEntryIndex(StringId key) {
- // Zero-initializes |key| in the map if it doesn't exist yet.
- args_tracker_
- ->array_indexes_[std::make_tuple(arg_set_id_column_, row_, key)]++;
- }
-
size_t GetNextArrayEntryIndex(StringId key) {
// Zero-initializes |key| in the map if it doesn't exist yet.
return args_tracker_
->array_indexes_[std::make_tuple(arg_set_id_column_, row_, key)];
}
+ // Returns the next available array index after increment.
+ size_t IncrementArrayEntryIndex(StringId key) {
+ // Zero-initializes |key| in the map if it doesn't exist yet.
+ return ++args_tracker_->array_indexes_[std::make_tuple(arg_set_id_column_,
+ row_, key)];
+ }
+
protected:
BoundInserter(ArgsTracker* args_tracker,
Column* arg_set_id_column,
@@ -159,7 +161,7 @@ class ArgsTracker {
Variadic,
UpdatePolicy);
- std::vector<GlobalArgsTracker::Arg> args_;
+ base::SmallVector<GlobalArgsTracker::Arg, 16> args_;
TraceProcessorContext* const context_;
using ArrayKeyTuple =
diff --git a/src/trace_processor/importers/common/args_translation_table.cc b/src/trace_processor/importers/common/args_translation_table.cc
new file mode 100644
index 000000000..f7436e96e
--- /dev/null
+++ b/src/trace_processor/importers/common/args_translation_table.cc
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/importers/common/args_translation_table.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+constexpr char ArgsTranslationTable::kChromeHistogramHashKey[];
+constexpr char ArgsTranslationTable::kChromeHistogramNameKey[];
+
+constexpr char ArgsTranslationTable::kChromeUserEventHashKey[];
+constexpr char ArgsTranslationTable::kChromeUserEventActionKey[];
+
+constexpr char ArgsTranslationTable::kChromePerformanceMarkSiteHashKey[];
+constexpr char ArgsTranslationTable::kChromePerformanceMarkSiteKey[];
+
+constexpr char ArgsTranslationTable::kChromePerformanceMarkMarkHashKey[];
+constexpr char ArgsTranslationTable::kChromePerformanceMarkMarkKey[];
+
+ArgsTranslationTable::ArgsTranslationTable(TraceStorage* storage)
+ : storage_(storage),
+ interned_chrome_histogram_hash_key_(
+ storage->InternString(kChromeHistogramHashKey)),
+ interned_chrome_histogram_name_key_(
+ storage->InternString(kChromeHistogramNameKey)),
+ interned_chrome_user_event_hash_key_(
+ storage->InternString(kChromeUserEventHashKey)),
+ interned_chrome_user_event_action_key_(
+ storage->InternString(kChromeUserEventActionKey)),
+ interned_chrome_performance_mark_site_hash_key_(
+ storage->InternString(kChromePerformanceMarkSiteHashKey)),
+ interned_chrome_performance_mark_site_key_(
+ storage->InternString(kChromePerformanceMarkSiteKey)),
+ interned_chrome_performance_mark_mark_hash_key_(
+ storage->InternString(kChromePerformanceMarkMarkHashKey)),
+ interned_chrome_performance_mark_mark_key_(
+ storage->InternString(kChromePerformanceMarkMarkKey)) {}
+
+bool ArgsTranslationTable::TranslateUnsignedIntegerArg(
+ const Key& key,
+ uint64_t value,
+ ArgsTracker::BoundInserter& inserter) {
+ if (key.key == kChromeHistogramHashKey) {
+ inserter.AddArg(interned_chrome_histogram_hash_key_,
+ Variadic::UnsignedInteger(value));
+ const base::Optional<base::StringView> translated_value =
+ TranslateChromeHistogramHash(value);
+ if (translated_value) {
+ inserter.AddArg(
+ interned_chrome_histogram_name_key_,
+ Variadic::String(storage_->InternString(*translated_value)));
+ }
+ return true;
+ }
+ if (key.key == kChromeUserEventHashKey) {
+ inserter.AddArg(interned_chrome_user_event_hash_key_,
+ Variadic::UnsignedInteger(value));
+ const base::Optional<base::StringView> translated_value =
+ TranslateChromeUserEventHash(value);
+ if (translated_value) {
+ inserter.AddArg(
+ interned_chrome_user_event_action_key_,
+ Variadic::String(storage_->InternString(*translated_value)));
+ }
+ return true;
+ }
+ if (key.key == kChromePerformanceMarkSiteHashKey) {
+ inserter.AddArg(interned_chrome_performance_mark_site_hash_key_,
+ Variadic::UnsignedInteger(value));
+ const base::Optional<base::StringView> translated_value =
+ TranslateChromePerformanceMarkSiteHash(value);
+ if (translated_value) {
+ inserter.AddArg(
+ interned_chrome_performance_mark_site_key_,
+ Variadic::String(storage_->InternString(*translated_value)));
+ }
+ return true;
+ }
+ if (key.key == kChromePerformanceMarkMarkHashKey) {
+ inserter.AddArg(interned_chrome_performance_mark_mark_hash_key_,
+ Variadic::UnsignedInteger(value));
+ const base::Optional<base::StringView> translated_value =
+ TranslateChromePerformanceMarkMarkHash(value);
+ if (translated_value) {
+ inserter.AddArg(
+ interned_chrome_performance_mark_mark_key_,
+ Variadic::String(storage_->InternString(*translated_value)));
+ }
+ return true;
+ }
+ return false;
+}
+
+base::Optional<base::StringView>
+ArgsTranslationTable::TranslateChromeHistogramHash(uint64_t hash) const {
+ auto* value = chrome_histogram_hash_to_name_.Find(hash);
+ if (!value) {
+ return base::nullopt;
+ }
+ return base::StringView(*value);
+}
+
+base::Optional<base::StringView>
+ArgsTranslationTable::TranslateChromeUserEventHash(uint64_t hash) const {
+ auto* value = chrome_user_event_hash_to_action_.Find(hash);
+ if (!value) {
+ return base::nullopt;
+ }
+ return base::StringView(*value);
+}
+
+base::Optional<base::StringView>
+ArgsTranslationTable::TranslateChromePerformanceMarkSiteHash(
+ uint64_t hash) const {
+ auto* value = chrome_performance_mark_site_hash_to_name_.Find(hash);
+ if (!value) {
+ return base::nullopt;
+ }
+ return base::StringView(*value);
+}
+
+base::Optional<base::StringView>
+ArgsTranslationTable::TranslateChromePerformanceMarkMarkHash(
+ uint64_t hash) const {
+ auto* value = chrome_performance_mark_mark_hash_to_name_.Find(hash);
+ if (!value) {
+ return base::nullopt;
+ }
+ return base::StringView(*value);
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/common/args_translation_table.h b/src/trace_processor/importers/common/args_translation_table.h
new file mode 100644
index 000000000..79b848994
--- /dev/null
+++ b/src/trace_processor/importers/common/args_translation_table.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_ARGS_TRANSLATION_TABLE_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_ARGS_TRANSLATION_TABLE_H_
+
+#include <cstdint>
+
+#include "perfetto/ext/base/flat_hash_map.h"
+#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/string_view.h"
+#include "src/trace_processor/importers/common/args_tracker.h"
+#include "src/trace_processor/storage/trace_storage.h"
+#include "src/trace_processor/util/proto_to_args_parser.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+// Tracks and stores args translation rules. It allows Trace Processor
+// to map for example hashes to their names.
+class ArgsTranslationTable {
+ public:
+ using Key = util::ProtoToArgsParser::Key;
+
+ ArgsTranslationTable(TraceStorage* storage);
+
+ // Returns true if the translation table fully handles the arg, in which case
+ // the original arg doesn't need to be processed. This function has not added
+ // anything if returning false.
+ bool TranslateUnsignedIntegerArg(const Key& key,
+ uint64_t value,
+ ArgsTracker::BoundInserter& inserter);
+
+ void AddChromeHistogramTranslationRule(uint64_t hash, base::StringView name) {
+ chrome_histogram_hash_to_name_.Insert(hash, name.ToStdString());
+ }
+ void AddChromeUserEventTranslationRule(uint64_t hash,
+ base::StringView action) {
+ chrome_user_event_hash_to_action_.Insert(hash, action.ToStdString());
+ }
+ void AddChromePerformanceMarkSiteTranslationRule(uint64_t hash,
+ base::StringView name) {
+ chrome_performance_mark_site_hash_to_name_.Insert(hash, name.ToStdString());
+ }
+ void AddChromePerformanceMarkMarkTranslationRule(uint64_t hash,
+ base::StringView name) {
+ chrome_performance_mark_mark_hash_to_name_.Insert(hash, name.ToStdString());
+ }
+
+ base::Optional<base::StringView> TranslateChromeHistogramHashForTesting(
+ uint64_t hash) const {
+ return TranslateChromeHistogramHash(hash);
+ }
+ base::Optional<base::StringView> TranslateChromeUserEventHashForTesting(
+ uint64_t hash) const {
+ return TranslateChromeUserEventHash(hash);
+ }
+ base::Optional<base::StringView>
+ TranslateChromePerformanceMarkSiteHashForTesting(uint64_t hash) const {
+ return TranslateChromePerformanceMarkSiteHash(hash);
+ }
+ base::Optional<base::StringView>
+ TranslateChromePerformanceMarkMarkHashForTesting(uint64_t hash) const {
+ return TranslateChromePerformanceMarkMarkHash(hash);
+ }
+
+ private:
+ static constexpr char kChromeHistogramHashKey[] =
+ "chrome_histogram_sample.name_hash";
+ static constexpr char kChromeHistogramNameKey[] =
+ "chrome_histogram_sample.name";
+
+ static constexpr char kChromeUserEventHashKey[] =
+ "chrome_user_event.action_hash";
+ static constexpr char kChromeUserEventActionKey[] =
+ "chrome_user_event.action";
+
+ static constexpr char kChromePerformanceMarkSiteHashKey[] =
+ "chrome_hashed_performance_mark.site_hash";
+ static constexpr char kChromePerformanceMarkSiteKey[] =
+ "chrome_hashed_performance_mark.site";
+
+ static constexpr char kChromePerformanceMarkMarkHashKey[] =
+ "chrome_hashed_performance_mark.mark_hash";
+ static constexpr char kChromePerformanceMarkMarkKey[] =
+ "chrome_hashed_performance_mark.mark";
+
+ TraceStorage* storage_;
+ StringId interned_chrome_histogram_hash_key_;
+ StringId interned_chrome_histogram_name_key_;
+ StringId interned_chrome_user_event_hash_key_;
+ StringId interned_chrome_user_event_action_key_;
+ StringId interned_chrome_performance_mark_site_hash_key_;
+ StringId interned_chrome_performance_mark_site_key_;
+ StringId interned_chrome_performance_mark_mark_hash_key_;
+ StringId interned_chrome_performance_mark_mark_key_;
+ base::FlatHashMap<uint64_t, std::string> chrome_histogram_hash_to_name_;
+ base::FlatHashMap<uint64_t, std::string> chrome_user_event_hash_to_action_;
+ base::FlatHashMap<uint64_t, std::string>
+ chrome_performance_mark_site_hash_to_name_;
+ base::FlatHashMap<uint64_t, std::string>
+ chrome_performance_mark_mark_hash_to_name_;
+
+ base::Optional<base::StringView> TranslateChromeHistogramHash(
+ uint64_t hash) const;
+ base::Optional<base::StringView> TranslateChromeUserEventHash(
+ uint64_t hash) const;
+ base::Optional<base::StringView> TranslateChromePerformanceMarkSiteHash(
+ uint64_t hash) const;
+ base::Optional<base::StringView> TranslateChromePerformanceMarkMarkHash(
+ uint64_t hash) const;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_ARGS_TRANSLATION_TABLE_H_
diff --git a/src/trace_processor/importers/common/args_translation_table_unittest.cc b/src/trace_processor/importers/common/args_translation_table_unittest.cc
new file mode 100644
index 000000000..38ecd42b2
--- /dev/null
+++ b/src/trace_processor/importers/common/args_translation_table_unittest.cc
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/importers/common/args_translation_table.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace trace_processor {
+namespace {
+
+TEST(ArgsTranslationTable, EmptyTableByDefault) {
+ TraceStorage storage;
+ ArgsTranslationTable table(&storage);
+ EXPECT_EQ(table.TranslateChromeHistogramHashForTesting(1), base::nullopt);
+ EXPECT_EQ(table.TranslateChromeUserEventHashForTesting(1), base::nullopt);
+}
+
+TEST(ArgsTranslationTable, TranslatesHistogramHashes) {
+ TraceStorage storage;
+ ArgsTranslationTable table(&storage);
+ table.AddChromeHistogramTranslationRule(1, "hash1");
+ table.AddChromeHistogramTranslationRule(10, "hash2");
+ EXPECT_EQ(table.TranslateChromeHistogramHashForTesting(1),
+ base::Optional<base::StringView>("hash1"));
+ EXPECT_EQ(table.TranslateChromeHistogramHashForTesting(10),
+ base::Optional<base::StringView>("hash2"));
+ EXPECT_EQ(table.TranslateChromeHistogramHashForTesting(2), base::nullopt);
+}
+
+TEST(ArgsTranslationTable, TranslatesUserEventHashes) {
+ TraceStorage storage;
+ ArgsTranslationTable table(&storage);
+ table.AddChromeUserEventTranslationRule(1, "action1");
+ table.AddChromeUserEventTranslationRule(10, "action2");
+ EXPECT_EQ(table.TranslateChromeUserEventHashForTesting(1),
+ base::Optional<base::StringView>("action1"));
+ EXPECT_EQ(table.TranslateChromeUserEventHashForTesting(10),
+ base::Optional<base::StringView>("action2"));
+ EXPECT_EQ(table.TranslateChromeUserEventHashForTesting(2), base::nullopt);
+}
+
+TEST(ArgsTranslationTable, TranslatesPerformanceMarkSiteHashes) {
+ TraceStorage storage;
+ ArgsTranslationTable table(&storage);
+ table.AddChromePerformanceMarkSiteTranslationRule(1, "hash1");
+ table.AddChromePerformanceMarkSiteTranslationRule(10, "hash2");
+ EXPECT_EQ(table.TranslateChromePerformanceMarkSiteHashForTesting(1),
+ base::Optional<base::StringView>("hash1"));
+ EXPECT_EQ(table.TranslateChromePerformanceMarkSiteHashForTesting(10),
+ base::Optional<base::StringView>("hash2"));
+ EXPECT_EQ(table.TranslateChromePerformanceMarkSiteHashForTesting(2),
+ base::nullopt);
+}
+
+TEST(ArgsTranslationTable, TranslatesPerformanceMarkMarkHashes) {
+ TraceStorage storage;
+ ArgsTranslationTable table(&storage);
+ table.AddChromePerformanceMarkMarkTranslationRule(1, "hash1");
+ table.AddChromePerformanceMarkMarkTranslationRule(10, "hash2");
+ EXPECT_EQ(table.TranslateChromePerformanceMarkMarkHashForTesting(1),
+ base::Optional<base::StringView>("hash1"));
+ EXPECT_EQ(table.TranslateChromePerformanceMarkMarkHashForTesting(10),
+ base::Optional<base::StringView>("hash2"));
+ EXPECT_EQ(table.TranslateChromePerformanceMarkMarkHashForTesting(2),
+ base::nullopt);
+}
+
+} // namespace
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/common/chunked_trace_reader.h b/src/trace_processor/importers/common/chunked_trace_reader.h
index dc90344cd..a86ae138a 100644
--- a/src/trace_processor/importers/common/chunked_trace_reader.h
+++ b/src/trace_processor/importers/common/chunked_trace_reader.h
@@ -28,6 +28,8 @@
namespace perfetto {
namespace trace_processor {
+class TraceBlobView;
+
// Base interface for first stage of parsing pipeline
// (JsonTraceParser, ProtoTraceReader).
class ChunkedTraceReader {
@@ -38,7 +40,7 @@ class ChunkedTraceReader {
// caller to match line/protos boundaries. The parser class has to deal with
// intermediate buffering lines/protos that span across different chunks.
// The buffer size is guaranteed to be > 0.
- virtual util::Status Parse(std::unique_ptr<uint8_t[]>, size_t) = 0;
+ virtual util::Status Parse(TraceBlobView) = 0;
// Called after the last Parse() call.
virtual void NotifyEndOfFile() = 0;
diff --git a/src/trace_processor/importers/common/clock_tracker.cc b/src/trace_processor/importers/common/clock_tracker.cc
index 75518a263..61956c2bf 100644
--- a/src/trace_processor/importers/common/clock_tracker.cc
+++ b/src/trace_processor/importers/common/clock_tracker.cc
@@ -16,10 +16,9 @@
#include "src/trace_processor/importers/common/clock_tracker.h"
-#include <inttypes.h>
-
#include <algorithm>
#include <atomic>
+#include <cinttypes>
#include <queue>
#include "perfetto/base/logging.h"
diff --git a/src/trace_processor/importers/common/clock_tracker.h b/src/trace_processor/importers/common/clock_tracker.h
index 16b9d79ff..35b316e2d 100644
--- a/src/trace_processor/importers/common/clock_tracker.h
+++ b/src/trace_processor/importers/common/clock_tracker.h
@@ -17,10 +17,10 @@
#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_CLOCK_TRACKER_H_
#define SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_CLOCK_TRACKER_H_
-#include <inttypes.h>
#include <stdint.h>
#include <array>
+#include <cinttypes>
#include <map>
#include <random>
#include <set>
diff --git a/src/trace_processor/importers/common/flow_tracker.cc b/src/trace_processor/importers/common/flow_tracker.cc
index 9e6e2d87a..e9ba05b90 100644
--- a/src/trace_processor/importers/common/flow_tracker.cc
+++ b/src/trace_processor/importers/common/flow_tracker.cc
@@ -46,11 +46,15 @@ void FlowTracker::Begin(TrackId track_id, FlowId flow_id) {
context_->storage->IncrementStats(stats::flow_no_enclosing_slice);
return;
}
- if (flow_to_slice_map_.count(flow_id) != 0) {
+ Begin(open_slice_id.value(), flow_id);
+}
+
+void FlowTracker::Begin(SliceId slice_id, FlowId flow_id) {
+ auto it_and_ins = flow_to_slice_map_.Insert(flow_id, slice_id);
+ if (!it_and_ins.second) {
context_->storage->IncrementStats(stats::flow_duplicate_id);
return;
}
- flow_to_slice_map_[flow_id] = open_slice_id.value();
}
void FlowTracker::Step(TrackId track_id, FlowId flow_id) {
@@ -60,13 +64,18 @@ void FlowTracker::Step(TrackId track_id, FlowId flow_id) {
context_->storage->IncrementStats(stats::flow_no_enclosing_slice);
return;
}
- if (flow_to_slice_map_.count(flow_id) == 0) {
+ Step(open_slice_id.value(), flow_id);
+}
+
+void FlowTracker::Step(SliceId slice_id, FlowId flow_id) {
+ auto* it = flow_to_slice_map_.Find(flow_id);
+ if (!it) {
context_->storage->IncrementStats(stats::flow_step_without_start);
return;
}
- SliceId slice_out_id = flow_to_slice_map_[flow_id];
- InsertFlow(flow_id, slice_out_id, open_slice_id.value());
- flow_to_slice_map_[flow_id] = open_slice_id.value();
+ SliceId slice_out_id = *it;
+ InsertFlow(flow_id, slice_out_id, slice_id);
+ *it = slice_id;
}
void FlowTracker::End(TrackId track_id,
@@ -83,29 +92,32 @@ void FlowTracker::End(TrackId track_id,
context_->storage->IncrementStats(stats::flow_no_enclosing_slice);
return;
}
- if (flow_to_slice_map_.count(flow_id) == 0) {
+ End(open_slice_id.value(), flow_id, close_flow);
+}
+
+void FlowTracker::End(SliceId slice_id, FlowId flow_id, bool close_flow) {
+ auto* it = flow_to_slice_map_.Find(flow_id);
+ if (!it) {
context_->storage->IncrementStats(stats::flow_end_without_start);
return;
}
- SliceId slice_out_id = flow_to_slice_map_[flow_id];
- if (close_flow) {
- flow_to_slice_map_.erase(flow_to_slice_map_.find(flow_id));
- }
- InsertFlow(flow_id, slice_out_id, open_slice_id.value());
+ SliceId slice_out_id = *it;
+ if (close_flow)
+ flow_to_slice_map_.Erase(flow_id);
+ InsertFlow(flow_id, slice_out_id, slice_id);
}
bool FlowTracker::IsActive(FlowId flow_id) const {
- return flow_to_slice_map_.find(flow_id) != flow_to_slice_map_.end();
+ return flow_to_slice_map_.Find(flow_id) != nullptr;
}
FlowId FlowTracker::GetFlowIdForV1Event(uint64_t source_id,
StringId cat,
StringId name) {
V1FlowId v1_flow_id = {source_id, cat, name};
- auto iter = v1_flow_id_to_flow_id_map_.find(v1_flow_id);
- if (iter != v1_flow_id_to_flow_id_map_.end()) {
- return iter->second;
- }
+ auto* iter = v1_flow_id_to_flow_id_map_.Find(v1_flow_id);
+ if (iter)
+ return *iter;
FlowId new_id = v1_id_counter_++;
flow_id_to_v1_flow_id_map_[new_id] = v1_flow_id;
v1_flow_id_to_flow_id_map_[v1_flow_id] = new_id;
@@ -114,16 +126,16 @@ FlowId FlowTracker::GetFlowIdForV1Event(uint64_t source_id,
void FlowTracker::ClosePendingEventsOnTrack(TrackId track_id,
SliceId slice_id) {
- auto iter = pending_flow_ids_map_.find(track_id);
- if (iter == pending_flow_ids_map_.end())
+ auto* iter = pending_flow_ids_map_.Find(track_id);
+ if (!iter)
return;
- for (FlowId flow_id : iter->second) {
+ for (FlowId flow_id : *iter) {
SliceId slice_out_id = flow_to_slice_map_[flow_id];
InsertFlow(flow_id, slice_out_id, slice_id);
}
- pending_flow_ids_map_.erase(iter);
+ pending_flow_ids_map_.Erase(track_id);
}
void FlowTracker::InsertFlow(FlowId flow_id,
@@ -132,13 +144,13 @@ void FlowTracker::InsertFlow(FlowId flow_id,
tables::FlowTable::Row row(slice_out_id, slice_in_id, kInvalidArgSetId);
auto id = context_->storage->mutable_flow_table()->Insert(row).id;
- auto it = flow_id_to_v1_flow_id_map_.find(flow_id);
- if (it != flow_id_to_v1_flow_id_map_.end()) {
+ auto* it = flow_id_to_v1_flow_id_map_.Find(flow_id);
+ if (it) {
// TODO(b/168007725): Add any args from v1 flow events and also export them.
auto args_tracker = ArgsTracker(context_);
auto inserter = context_->args_tracker->AddArgsTo(id);
- inserter.AddArg(name_key_id_, Variadic::String(it->second.name));
- inserter.AddArg(cat_key_id_, Variadic::String(it->second.cat));
+ inserter.AddArg(name_key_id_, Variadic::String(it->name));
+ inserter.AddArg(cat_key_id_, Variadic::String(it->cat));
context_->args_tracker->Flush();
}
}
diff --git a/src/trace_processor/importers/common/flow_tracker.h b/src/trace_processor/importers/common/flow_tracker.h
index f05d854c1..2d749d182 100644
--- a/src/trace_processor/importers/common/flow_tracker.h
+++ b/src/trace_processor/importers/common/flow_tracker.h
@@ -19,6 +19,7 @@
#include <stdint.h>
+#include "perfetto/ext/base/flat_hash_map.h"
#include "src/trace_processor/importers/common/args_tracker.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/trace_processor_context.h"
@@ -31,14 +32,23 @@ using FlowId = uint64_t;
class FlowTracker {
public:
explicit FlowTracker(TraceProcessorContext*);
- virtual ~FlowTracker();
+ ~FlowTracker();
void InsertFlow(SliceId slice_out_id, SliceId slice_in_id);
- // These methods assume you have created a FlowId via GetFlowIdForV1Event.
- // If you don't have a v1 event you should use the InsertFlow method above.
- virtual void Begin(TrackId track_id, FlowId flow_id);
- virtual void Step(TrackId track_id, FlowId flow_id);
+ // These methods track flow ids associated with slices and create flows as
+ // needed.
+ // If you don't have flow ids associated with slices, you should use the
+ // InsertFlow method above.
+ void Begin(SliceId slice_id, FlowId flow_id);
+ void Step(SliceId slice_id, FlowId flow_id);
+ void End(SliceId track_id, FlowId flow_id, bool close_flow);
+
+ // These methods assume you have created a FlowId via GetFlowIdForV1Event and
+ // tie the flow id to the currently open slice on a given track. If you don't
+ // have a v1 event you should use the methods above.
+ void Begin(TrackId track_id, FlowId flow_id);
+ void Step(TrackId track_id, FlowId flow_id);
// When |bind_enclosing_slice| is true we will connect the flow to the
// currently open slice on the track, when false we will connect the flow to
@@ -46,10 +56,10 @@ class FlowTracker {
// When |close_flow| is true it will mark this as the singular end of the
// flow, however if there are multiple end points this should be set to
// false. Both parameters are only needed for v1 flow events support
- virtual void End(TrackId track_id,
- FlowId flow_id,
- bool bind_enclosing_slice,
- bool close_flow);
+ void End(TrackId track_id,
+ FlowId flow_id,
+ bool bind_enclosing_slice,
+ bool close_flow);
bool IsActive(FlowId flow_id) const;
@@ -70,19 +80,16 @@ class FlowTracker {
struct V1FlowIdHasher {
size_t operator()(const V1FlowId& c) const {
- base::Hash hasher;
- hasher.Update(c.source_id);
- hasher.Update(c.cat.raw_id());
- hasher.Update(c.name.raw_id());
- return std::hash<uint64_t>{}(hasher.digest());
+ return std::hash<uint64_t>{}(
+ base::Hash::Combine(c.source_id, c.cat.raw_id(), c.name.raw_id()));
}
};
- using FlowToSourceSliceMap = std::unordered_map<FlowId, SliceId>;
- using PendingFlowsMap = std::unordered_map<TrackId, std::vector<FlowId>>;
+ using FlowToSourceSliceMap = base::FlatHashMap<FlowId, SliceId>;
+ using PendingFlowsMap = base::FlatHashMap<TrackId, std::vector<FlowId>>;
using V1FlowIdToFlowIdMap =
- std::unordered_map<V1FlowId, FlowId, V1FlowIdHasher>;
- using FlowIdToV1FlowId = std::unordered_map<FlowId, V1FlowId>;
+ base::FlatHashMap<V1FlowId, FlowId, V1FlowIdHasher>;
+ using FlowIdToV1FlowId = base::FlatHashMap<FlowId, V1FlowId>;
void InsertFlow(FlowId flow_id,
SliceId outgoing_slice_id,
diff --git a/src/trace_processor/importers/common/flow_tracker_unittest.cc b/src/trace_processor/importers/common/flow_tracker_unittest.cc
index d8af423d8..3ac912f80 100644
--- a/src/trace_processor/importers/common/flow_tracker_unittest.cc
+++ b/src/trace_processor/importers/common/flow_tracker_unittest.cc
@@ -18,6 +18,7 @@
#include "src/trace_processor/importers/common/flow_tracker.h"
#include "src/trace_processor/importers/common/slice_tracker.h"
+#include "src/trace_processor/importers/common/slice_translation_table.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/trace_processor_context.h"
#include "test/gtest_and_gmock.h"
@@ -32,6 +33,8 @@ TEST(FlowTrackerTest, SingleFlowEventExplicitInSliceBinding) {
TraceProcessorContext context;
context.storage.reset(new TraceStorage());
context.slice_tracker.reset(new SliceTracker(&context));
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
auto& slice_tracker = context.slice_tracker;
FlowTracker tracker(&context);
slice_tracker->SetOnSliceBeginCallback(
@@ -64,6 +67,8 @@ TEST(FlowTrackerTest, SingleFlowEventWaitForNextSlice) {
TraceProcessorContext context;
context.storage.reset(new TraceStorage());
context.slice_tracker.reset(new SliceTracker(&context));
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
auto& slice_tracker = context.slice_tracker;
FlowTracker tracker(&context);
slice_tracker->SetOnSliceBeginCallback(
@@ -100,6 +105,8 @@ TEST(FlowTrackerTest, SingleFlowEventWaitForNextSliceScoped) {
TraceProcessorContext context;
context.storage.reset(new TraceStorage());
context.slice_tracker.reset(new SliceTracker(&context));
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
auto& slice_tracker = context.slice_tracker;
FlowTracker tracker(&context);
slice_tracker->SetOnSliceBeginCallback(
@@ -135,6 +142,8 @@ TEST(FlowTrackerTest, TwoFlowEventsWaitForNextSlice) {
TraceProcessorContext context;
context.storage.reset(new TraceStorage());
context.slice_tracker.reset(new SliceTracker(&context));
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
auto& slice_tracker = context.slice_tracker;
FlowTracker tracker(&context);
slice_tracker->SetOnSliceBeginCallback(
@@ -185,6 +194,8 @@ TEST(FlowTrackerTest, TwoFlowEventsSliceInSlice) {
TraceProcessorContext context;
context.storage.reset(new TraceStorage());
context.slice_tracker.reset(new SliceTracker(&context));
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
auto& slice_tracker = context.slice_tracker;
FlowTracker tracker(&context);
slice_tracker->SetOnSliceBeginCallback(
@@ -235,6 +246,8 @@ TEST(FlowTrackerTest, FlowEventsWithStep) {
TraceProcessorContext context;
context.storage.reset(new TraceStorage());
context.slice_tracker.reset(new SliceTracker(&context));
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
auto& slice_tracker = context.slice_tracker;
FlowTracker tracker(&context);
slice_tracker->SetOnSliceBeginCallback(
diff --git a/src/trace_processor/importers/common/global_args_tracker.h b/src/trace_processor/importers/common/global_args_tracker.h
index 94b960e0f..0d1c365ff 100644
--- a/src/trace_processor/importers/common/global_args_tracker.h
+++ b/src/trace_processor/importers/common/global_args_tracker.h
@@ -17,6 +17,9 @@
#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_GLOBAL_ARGS_TRACKER_H_
#define SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_GLOBAL_ARGS_TRACKER_H_
+#include "perfetto/ext/base/flat_hash_map.h"
+#include "perfetto/ext/base/hash.h"
+#include "perfetto/ext/base/small_vector.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/trace_processor_context.h"
#include "src/trace_processor/types/variadic.h"
@@ -73,19 +76,19 @@ class GlobalArgsTracker {
case Variadic::Type::kJson:
hash.Update(arg.value.json_value.raw_id());
break;
+ case Variadic::Type::kNull:
+ hash.Update(0);
+ break;
}
return hash.digest();
}
};
- GlobalArgsTracker(TraceProcessorContext* context);
+ explicit GlobalArgsTracker(TraceProcessorContext* context);
// Assumes that the interval [begin, end) of |args| is sorted by keys.
- ArgSetId AddArgSet(const std::vector<Arg>& args,
- uint32_t begin,
- uint32_t end) {
- std::vector<uint32_t> valid_indexes;
- valid_indexes.reserve(end - begin);
+ ArgSetId AddArgSet(const Arg* args, uint32_t begin, uint32_t end) {
+ base::SmallVector<uint32_t, 64> valid_indexes;
// TODO(eseckler): Also detect "invalid" key combinations in args sets (e.g.
// "foo" and "foo.bar" in the same arg set)?
@@ -103,7 +106,7 @@ class GlobalArgsTracker {
}
}
- valid_indexes.push_back(i);
+ valid_indexes.emplace_back(i);
}
base::Hash hash;
@@ -114,13 +117,16 @@ class GlobalArgsTracker {
auto* arg_table = context_->storage->mutable_arg_table();
ArgSetHash digest = hash.digest();
- auto it = arg_row_for_hash_.find(digest);
- if (it != arg_row_for_hash_.end())
- return arg_table->arg_set_id()[it->second];
+ auto it_and_inserted =
+ arg_row_for_hash_.Insert(digest, arg_table->row_count());
+ if (!it_and_inserted.second) {
+ // Already inserted.
+ return arg_table->arg_set_id()[*it_and_inserted.first];
+ }
- // The +1 ensures that nothing has an id == kInvalidArgSetId == 0.
- ArgSetId id = static_cast<uint32_t>(arg_row_for_hash_.size()) + 1;
- arg_row_for_hash_.emplace(digest, arg_table->row_count());
+ // Taking size() after the Insert() ensures that nothing has an id == 0
+ // (0 == kInvalidArgSetId).
+ ArgSetId id = static_cast<uint32_t>(arg_row_for_hash_.size());
for (uint32_t i : valid_indexes) {
const auto& arg = args[i];
@@ -150,6 +156,8 @@ class GlobalArgsTracker {
case Variadic::Type::kJson:
row.string_value = arg.value.json_value;
break;
+ case Variadic::Type::kNull:
+ break;
}
row.value_type = context_->storage->GetIdForVariadicType(arg.value.type);
arg_table->Insert(row);
@@ -157,10 +165,18 @@ class GlobalArgsTracker {
return id;
}
+ // Exposed for making tests easier to write.
+ ArgSetId AddArgSet(const std::vector<Arg>& args,
+ uint32_t begin,
+ uint32_t end) {
+ return AddArgSet(args.data(), begin, end);
+ }
+
private:
using ArgSetHash = uint64_t;
- std::unordered_map<ArgSetHash, uint32_t> arg_row_for_hash_;
+ base::FlatHashMap<ArgSetHash, uint32_t, base::AlreadyHashed<ArgSetHash>>
+ arg_row_for_hash_;
TraceProcessorContext* context_;
};
diff --git a/src/trace_processor/importers/common/process_tracker.cc b/src/trace_processor/importers/common/process_tracker.cc
index 173d47d43..2ef798d15 100644
--- a/src/trace_processor/importers/common/process_tracker.cc
+++ b/src/trace_processor/importers/common/process_tracker.cc
@@ -17,10 +17,9 @@
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/storage/stats.h"
+#include <cinttypes>
#include <utility>
-#include <inttypes.h>
-
namespace perfetto {
namespace trace_processor {
@@ -62,7 +61,19 @@ void ProcessTracker::EndThread(int64_t timestamp, uint32_t tid) {
auto* thread_table = context_->storage->mutable_thread_table();
auto* process_table = context_->storage->mutable_process_table();
- UniqueTid utid = GetOrCreateThread(tid);
+ // Don't bother creating a new thread if we're just going to
+ // end it straight away.
+ //
+ // This is useful in situations where we get a sched_process_free event for a
+ // worker thread in a process *after* the main thread finishes - in that case
+ // we would have already ended the process and we don't want to
+ // create a new thread here (see b/193520421 for an example of a trace
+ // where this happens in practice).
+ base::Optional<UniqueTid> opt_utid = GetThreadOrNull(tid);
+ if (!opt_utid)
+ return;
+
+ UniqueTid utid = *opt_utid;
thread_table->mutable_end_ts()->Set(utid, timestamp);
// Remove the thread from the list of threads being tracked as any event after
@@ -71,13 +82,14 @@ void ProcessTracker::EndThread(int64_t timestamp, uint32_t tid) {
vector.erase(std::remove(vector.begin(), vector.end(), utid));
auto opt_upid = thread_table->upid()[utid];
- if (opt_upid.has_value()) {
- // If the process pid and thread tid are equal, then this is the main thread
- // of the process.
- if (process_table->pid()[*opt_upid] == thread_table->tid()[utid]) {
- process_table->mutable_end_ts()->Set(*opt_upid, timestamp);
- }
- }
+ if (!opt_upid.has_value() || process_table->pid()[*opt_upid] != tid)
+ return;
+
+ // If the process pid and thread tid are equal then, as is the main thread
+ // of the process, we should also finish the process itself.
+ PERFETTO_DCHECK(thread_table->is_main_thread()[utid].value());
+ process_table->mutable_end_ts()->Set(*opt_upid, timestamp);
+ pids_.Erase(tid);
}
base::Optional<UniqueTid> ProcessTracker::GetThreadOrNull(uint32_t tid) {
@@ -144,8 +156,8 @@ bool ProcessTracker::IsThreadAlive(UniqueTid utid) {
// If the process has been replaced in |pids_|, this thread is dead.
uint32_t current_pid = processes->pid()[current_upid];
- auto pid_it = pids_.find(current_pid);
- if (pid_it != pids_.end() && pid_it->second != current_upid)
+ auto pid_it = pids_.Find(current_pid);
+ if (pid_it && *pid_it != current_upid)
return false;
return true;
@@ -157,13 +169,13 @@ base::Optional<UniqueTid> ProcessTracker::GetThreadOrNull(
auto* threads = context_->storage->mutable_thread_table();
auto* processes = context_->storage->mutable_process_table();
- auto vector_it = tids_.find(tid);
- if (vector_it == tids_.end())
+ auto vector_it = tids_.Find(tid);
+ if (!vector_it)
return base::nullopt;
// Iterate backwards through the threads so ones later in the trace are more
// likely to be picked.
- const auto& vector = vector_it->second;
+ const auto& vector = *vector_it;
for (auto it = vector.rbegin(); it != vector.rend(); it++) {
UniqueTid current_utid = *it;
@@ -208,11 +220,54 @@ UniqueTid ProcessTracker::UpdateThread(uint32_t tid, uint32_t pid) {
return utid;
}
+void ProcessTracker::UpdateTrustedPid(uint32_t trusted_pid, uint64_t uuid) {
+ trusted_pids_[uuid] = trusted_pid;
+}
+
+base::Optional<uint32_t> ProcessTracker::GetTrustedPid(uint64_t uuid) {
+ if (trusted_pids_.find(uuid) == trusted_pids_.end())
+ return base::nullopt;
+ return trusted_pids_[uuid];
+}
+
+base::Optional<uint32_t> ProcessTracker::ResolveNamespacedTid(
+ uint32_t root_level_pid,
+ uint32_t tid) {
+ if (root_level_pid <= 0) // Not a valid pid.
+ return base::nullopt;
+
+ // If the process doesn't run in a namespace (or traced_probes doesn't observe
+ // that), return base::nullopt as failure to resolve.
+ auto process_it = namespaced_processes_.find(root_level_pid);
+ if (process_it == namespaced_processes_.end())
+ return base::nullopt;
+
+ // Check if it's the main thread.
+ const auto& process = process_it->second;
+ auto ns_level = process.nspid.size() - 1;
+ auto pid_local = process.nspid.back();
+ if (pid_local == tid)
+ return root_level_pid;
+
+ // Check if any non-main thread has a matching ns-local thread ID.
+ for (const auto& root_level_tid : process.threads) {
+ const auto& thread = namespaced_threads_[root_level_tid];
+ PERFETTO_DCHECK(thread.nstid.size() > ns_level);
+ auto tid_ns_local = thread.nstid[ns_level];
+ if (tid_ns_local == tid)
+ return thread.tid;
+ }
+
+ // Failed to resolve or the thread isn't namespaced
+ return base::nullopt;
+}
+
UniquePid ProcessTracker::StartNewProcess(base::Optional<int64_t> timestamp,
base::Optional<uint32_t> parent_tid,
uint32_t pid,
- StringId main_thread_name) {
- pids_.erase(pid);
+ StringId main_thread_name,
+ ThreadNamePriority priority) {
+ pids_.Erase(pid);
// TODO(eseckler): Consider erasing all old entries in |tids_| that match the
// |pid| (those would be for an older process with the same pid). Right now,
// we keep them in |tids_| (if they weren't erased by EndThread()), but ignore
@@ -220,7 +275,8 @@ UniquePid ProcessTracker::StartNewProcess(base::Optional<int64_t> timestamp,
// Create a new UTID for the main thread, so we don't end up reusing an old
// entry in case of TID recycling.
- StartNewThread(timestamp, /*tid=*/pid);
+ UniqueTid utid = StartNewThread(timestamp, /*tid=*/pid);
+ UpdateThreadNameByUtid(utid, main_thread_name, priority);
// Note that we erased the pid above so this should always return a new
// process.
@@ -229,7 +285,7 @@ UniquePid ProcessTracker::StartNewProcess(base::Optional<int64_t> timestamp,
auto* process_table = context_->storage->mutable_process_table();
auto* thread_table = context_->storage->mutable_thread_table();
- PERFETTO_DCHECK(process_table->name()[upid].is_null());
+ PERFETTO_DCHECK(!process_table->name()[upid].has_value());
PERFETTO_DCHECK(!process_table->start_ts()[upid].has_value());
if (timestamp) {
@@ -253,20 +309,18 @@ UniquePid ProcessTracker::SetProcessMetadata(uint32_t pid,
base::Optional<uint32_t> ppid,
base::StringView name,
base::StringView cmdline) {
- auto proc_name_id = context_->storage->InternString(name);
-
base::Optional<UniquePid> pupid;
if (ppid.has_value()) {
pupid = GetOrCreateProcess(ppid.value());
}
UniquePid upid = GetOrCreateProcess(pid);
-
auto* process_table = context_->storage->mutable_process_table();
+
+ StringId proc_name_id = context_->storage->InternString(name);
process_table->mutable_name()->Set(upid, proc_name_id);
process_table->mutable_cmdline()->Set(
upid, context_->storage->InternString(cmdline));
-
if (pupid)
process_table->mutable_parent_upid()->Set(upid, *pupid);
@@ -285,7 +339,7 @@ void ProcessTracker::SetProcessUid(UniquePid upid, uint32_t uid) {
void ProcessTracker::SetProcessNameIfUnset(UniquePid upid,
StringId process_name_id) {
auto* process_table = context_->storage->mutable_process_table();
- if (process_table->name()[upid].is_null())
+ if (!process_table->name()[upid].has_value())
process_table->mutable_name()->Set(upid, process_name_id);
}
@@ -296,38 +350,43 @@ void ProcessTracker::SetStartTsIfUnset(UniquePid upid,
process_table->mutable_start_ts()->Set(upid, start_ts_nanoseconds);
}
-void ProcessTracker::UpdateProcessNameFromThreadName(uint32_t tid,
- StringId thread_name) {
+void ProcessTracker::UpdateThreadNameAndMaybeProcessName(
+ uint32_t tid,
+ StringId thread_name,
+ ThreadNamePriority priority) {
auto* thread_table = context_->storage->mutable_thread_table();
auto* process_table = context_->storage->mutable_process_table();
- auto utid = GetOrCreateThread(tid);
- auto opt_upid = thread_table->upid()[utid];
- if (opt_upid.has_value()) {
- if (process_table->pid()[*opt_upid] == tid) {
- process_table->mutable_name()->Set(*opt_upid, thread_name);
- }
+ UniqueTid utid = UpdateThreadName(tid, thread_name, priority);
+ base::Optional<UniquePid> opt_upid = thread_table->upid()[utid];
+ if (opt_upid.has_value() && process_table->pid()[*opt_upid] == tid) {
+ PERFETTO_DCHECK(thread_table->is_main_thread()[utid]);
+ process_table->mutable_name()->Set(*opt_upid, thread_name);
}
}
UniquePid ProcessTracker::GetOrCreateProcess(uint32_t pid) {
- UniquePid upid;
- auto it = pids_.find(pid);
- if (it != pids_.end()) {
- upid = it->second;
- } else {
- tables::ProcessTable::Row row;
- row.pid = pid;
- upid = context_->storage->mutable_process_table()->Insert(row).row;
-
- pids_.emplace(pid, upid);
-
- // Create an entry for the main thread.
- // We cannot call StartNewThread() here, because threads for this process
- // (including the main thread) might have been seen already prior to this
- // call. This call usually comes from the ProcessTree dump which is delayed.
- UpdateThread(/*tid=*/pid, pid);
+ auto* process_table = context_->storage->mutable_process_table();
+
+ // If the insertion succeeds, we'll fill the upid below.
+ auto it_and_ins = pids_.Insert(pid, UniquePid{0});
+ if (!it_and_ins.second) {
+ // Ensure that the process has not ended.
+ PERFETTO_DCHECK(!process_table->end_ts()[*it_and_ins.first].has_value());
+ return *it_and_ins.first;
}
+
+ tables::ProcessTable::Row row;
+ row.pid = pid;
+
+ UniquePid upid = process_table->Insert(row).row;
+ *it_and_ins.first = upid; // Update the newly inserted hashmap entry.
+
+ // Create an entry for the main thread.
+ // We cannot call StartNewThread() here, because threads for this process
+ // (including the main thread) might have been seen already prior to this
+ // call. This call usually comes from the ProcessTree dump which is delayed.
+ UpdateThread(/*tid=*/pid, pid);
return upid;
}
@@ -444,8 +503,8 @@ void ProcessTracker::AssociateThreadToProcess(UniqueTid utid, UniquePid upid) {
void ProcessTracker::SetPidZeroIgnoredForIdleProcess() {
// Create a mapping from (t|p)id 0 -> u(t|p)id 0 for the idle process.
- tids_.emplace(0, std::vector<UniqueTid>{0});
- pids_.emplace(0, 0);
+ tids_.Insert(0, std::vector<UniqueTid>{0});
+ pids_.Insert(0, 0);
auto swapper_id = context_->storage->InternString("swapper");
UpdateThreadName(0, swapper_id, ThreadNamePriority::kTraceProcessorConstant);
@@ -459,5 +518,21 @@ void ProcessTracker::NotifyEndOfFile() {
args_tracker_.Flush();
}
+void ProcessTracker::UpdateNamespacedProcess(uint32_t pid,
+ std::vector<uint32_t> nspid) {
+ namespaced_processes_[pid] = {pid, std::move(nspid), {}};
+}
+
+void ProcessTracker::UpdateNamespacedThread(uint32_t pid,
+ uint32_t tid,
+ std::vector<uint32_t> nstid) {
+ PERFETTO_DCHECK(namespaced_processes_.find(pid) !=
+ namespaced_processes_.end());
+ auto& process = namespaced_processes_[pid];
+ process.threads.emplace(tid);
+
+ namespaced_threads_[tid] = {pid, tid, std::move(nstid)};
+}
+
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/importers/common/process_tracker.h b/src/trace_processor/importers/common/process_tracker.h
index 3c46c38b2..2af44eba0 100644
--- a/src/trace_processor/importers/common/process_tracker.h
+++ b/src/trace_processor/importers/common/process_tracker.h
@@ -18,7 +18,9 @@
#define SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_PROCESS_TRACKER_H_
#include <tuple>
+#include <unordered_set>
+#include "perfetto/ext/base/flat_hash_map.h"
#include "perfetto/ext/base/string_view.h"
#include "src/trace_processor/importers/common/args_tracker.h"
#include "src/trace_processor/storage/trace_storage.h"
@@ -50,11 +52,6 @@ class ProcessTracker {
ProcessTracker& operator=(const ProcessTracker&) = delete;
virtual ~ProcessTracker();
- using UniqueProcessIterator =
- std::multimap<uint32_t, UniquePid>::const_iterator;
- using UniqueProcessBounds =
- std::pair<UniqueProcessIterator, UniqueProcessIterator>;
-
using UniqueThreadIterator = std::vector<UniqueTid>::const_iterator;
using UniqueThreadBounds =
std::pair<UniqueThreadIterator, UniqueThreadIterator>;
@@ -97,12 +94,29 @@ class ProcessTracker {
// Virtual for testing.
virtual UniqueTid UpdateThread(uint32_t tid, uint32_t tgid);
+ // Associates trusted_pid with track UUID.
+ void UpdateTrustedPid(uint32_t trusted_pid, uint64_t uuid);
+
+ // Returns the trusted_pid associated with the track UUID, or base::nullopt if
+ // not found.
+ base::Optional<uint32_t> GetTrustedPid(uint64_t uuid);
+
+ // Performs namespace-local to root-level resolution of thread or process id,
+ // given tid (can be root-level or namespace-local, but we don't know
+ // beforehand) and root-level pid/tgid that the thread belongs to.
+ // Returns the root-level thread id for tid on successful resolution;
+ // otherwise, returns base::nullopt on resolution failure, or the thread of
+ // tid isn't running in a pid namespace.
+ base::Optional<uint32_t> ResolveNamespacedTid(uint32_t root_level_pid,
+ uint32_t tid);
+
// Called when a task_newtask without the CLONE_THREAD flag is observed.
// This force the tracker to start both a new UTID and a new UPID.
UniquePid StartNewProcess(base::Optional<int64_t> timestamp,
base::Optional<uint32_t> parent_tid,
uint32_t pid,
- StringId main_thread_name);
+ StringId main_thread_name,
+ ThreadNamePriority priority);
// Called when a process is seen in a process tree. Retrieves the UniquePid
// for that pid or assigns a new one.
@@ -123,19 +137,21 @@ class ProcessTracker {
// have a timestamp yet.
void SetStartTsIfUnset(UniquePid upid, int64_t start_ts_nanoseconds);
- // Called on a task rename event to set the process name if the tid provided
- // is the main thread of the process.
- void UpdateProcessNameFromThreadName(uint32_t tid, StringId thread_name);
+ // Called on a task rename event to set the thread name and possibly process
+ // name (if the tid provided is the main thread of the process).
+ void UpdateThreadNameAndMaybeProcessName(uint32_t tid,
+ StringId thread_name,
+ ThreadNamePriority priority);
// Called when a process is seen in a process tree. Retrieves the UniquePid
// for that pid or assigns a new one.
// Virtual for testing.
virtual UniquePid GetOrCreateProcess(uint32_t pid);
- // Returns the bounds of a range that includes all UniquePids that have the
- // requested pid.
- UniqueProcessBounds UpidsForPidForTesting(uint32_t pid) {
- return pids_.equal_range(pid);
+ // Returns the upid for a given pid.
+ base::Optional<UniquePid> UpidForPidForTesting(uint32_t pid) {
+ auto it = pids_.Find(pid);
+ return it ? base::make_optional(*it) : base::nullopt;
}
// Returns the bounds of a range that includes all UniqueTids that have the
@@ -164,6 +180,15 @@ class ProcessTracker {
// Called when the trace was fully loaded.
void NotifyEndOfFile();
+ // Tracks the namespace-local pids for a process running in a pid namespace.
+ void UpdateNamespacedProcess(uint32_t pid, std::vector<uint32_t> nspid);
+
+ // Tracks the namespace-local thread ids for a thread running in a pid
+ // namespace.
+ void UpdateNamespacedThread(uint32_t pid,
+ uint32_t tid,
+ std::vector<uint32_t> nstid);
+
private:
// Returns the utid of a thread having |tid| and |pid| as the parent process.
// pid == base::nullopt matches all processes.
@@ -184,13 +209,16 @@ class ProcessTracker {
ArgsTracker args_tracker_;
- // Each tid can have multiple UniqueTid entries, a new UniqueTid is assigned
- // each time a thread is seen in the trace.
- std::map<uint32_t /* tid */, std::vector<UniqueTid>> tids_;
+ // Mapping for tid to the vector of possible UniqueTids.
+ // TODO(lalitm): this is a one-many mapping because this code was written
+ // before global sorting was a thing so multiple threads could be "active"
+ // simultaneously. This is no longer the case so this should be removed
+ // (though it seems like there are subtle things which break in Chrome if this
+ // changes).
+ base::FlatHashMap<uint32_t /* tid */, std::vector<UniqueTid>> tids_;
- // Each pid can have multiple UniquePid entries, a new UniquePid is assigned
- // each time a process is seen in the trace.
- std::map<uint32_t /* pid (aka tgid) */, UniquePid> pids_;
+ // Mapping of the most recently seen pid to the associated upid.
+ base::FlatHashMap<uint32_t /* pid (aka tgid) */, UniquePid> pids_;
// Pending thread associations. The meaning of a pair<ThreadA, ThreadB> in
// this vector is: we know that A and B belong to the same process, but we
@@ -205,6 +233,26 @@ class ProcessTracker {
// A mapping from utid to the priority of a thread name source.
std::vector<ThreadNamePriority> thread_name_priorities_;
+
+ // A mapping from track UUIDs to trusted pids.
+ std::unordered_map<uint64_t, uint32_t> trusted_pids_;
+
+ struct NamespacedThread {
+ uint32_t pid; // Root-level pid.
+ uint32_t tid; // Root-level tid.
+ std::vector<uint32_t> nstid; // Namespace-local tids.
+ };
+ // Keeps track of pid-namespaced threads, keyed by root-level thread ids.
+ std::unordered_map<uint32_t /* tid */, NamespacedThread> namespaced_threads_;
+
+ struct NamespacedProcess {
+ uint32_t pid; // Root-level pid.
+ std::vector<uint32_t> nspid; // Namespace-local pids.
+ std::unordered_set<uint32_t> threads; // Root-level thread IDs.
+ };
+ // Keeps track pid-namespaced processes, keyed by root-level pids.
+ std::unordered_map<uint32_t /* pid (aka tgid) */, NamespacedProcess>
+ namespaced_processes_;
};
} // namespace trace_processor
diff --git a/src/trace_processor/importers/common/process_tracker_unittest.cc b/src/trace_processor/importers/common/process_tracker_unittest.cc
index 3b1f9dd6c..d03713640 100644
--- a/src/trace_processor/importers/common/process_tracker_unittest.cc
+++ b/src/trace_processor/importers/common/process_tracker_unittest.cc
@@ -47,8 +47,8 @@ class ProcessTrackerTest : public ::testing::Test {
TEST_F(ProcessTrackerTest, PushProcess) {
context.process_tracker->SetProcessMetadata(1, base::nullopt, "test",
base::StringView());
- auto pair_it = context.process_tracker->UpidsForPidForTesting(1);
- ASSERT_EQ(pair_it.first->second, 1u);
+ auto opt_upid = context.process_tracker->UpidForPidForTesting(1);
+ ASSERT_EQ(opt_upid.value_or(-1), 1u);
}
TEST_F(ProcessTrackerTest, GetOrCreateNewProcess) {
@@ -57,8 +57,8 @@ TEST_F(ProcessTrackerTest, GetOrCreateNewProcess) {
}
TEST_F(ProcessTrackerTest, StartNewProcess) {
- auto upid =
- context.process_tracker->StartNewProcess(1000, 0u, 123, kNullStringId);
+ auto upid = context.process_tracker->StartNewProcess(
+ 1000, 0u, 123, kNullStringId, ThreadNamePriority::kFtrace);
ASSERT_EQ(context.process_tracker->GetOrCreateProcess(123), upid);
ASSERT_EQ(context.storage->process_table().start_ts()[upid], 1000);
}
@@ -68,9 +68,8 @@ TEST_F(ProcessTrackerTest, PushTwoProcessEntries_SamePidAndName) {
base::StringView());
context.process_tracker->SetProcessMetadata(1, base::nullopt, "test",
base::StringView());
- auto pair_it = context.process_tracker->UpidsForPidForTesting(1);
- ASSERT_EQ(pair_it.first->second, 1u);
- ASSERT_EQ(++pair_it.first, pair_it.second);
+ auto opt_upid = context.process_tracker->UpidForPidForTesting(1);
+ ASSERT_EQ(opt_upid.value_or(-1), 1u);
}
TEST_F(ProcessTrackerTest, PushTwoProcessEntries_DifferentPid) {
@@ -78,17 +77,17 @@ TEST_F(ProcessTrackerTest, PushTwoProcessEntries_DifferentPid) {
base::StringView());
context.process_tracker->SetProcessMetadata(3, base::nullopt, "test",
base::StringView());
- auto pair_it = context.process_tracker->UpidsForPidForTesting(1);
- ASSERT_EQ(pair_it.first->second, 1u);
- auto second_pair_it = context.process_tracker->UpidsForPidForTesting(3);
- ASSERT_EQ(second_pair_it.first->second, 2u);
+ auto opt_upid = context.process_tracker->UpidForPidForTesting(1);
+ ASSERT_EQ(opt_upid.value_or(-1), 1u);
+ opt_upid = context.process_tracker->UpidForPidForTesting(3);
+ ASSERT_EQ(opt_upid.value_or(-1), 2u);
}
TEST_F(ProcessTrackerTest, AddProcessEntry_CorrectName) {
context.process_tracker->SetProcessMetadata(1, base::nullopt, "test",
base::StringView());
- auto name =
- context.storage->GetString(context.storage->process_table().name()[1]);
+ auto name = context.storage->process_table().name().GetString(1);
+
ASSERT_EQ(name, "test");
}
@@ -101,18 +100,20 @@ TEST_F(ProcessTrackerTest, UpdateThreadCreate) {
auto tid_it = context.process_tracker->UtidsForTidForTesting(12);
ASSERT_NE(tid_it.first, tid_it.second);
ASSERT_EQ(context.storage->thread_table().upid()[1].value(), 1u);
- auto pid_it = context.process_tracker->UpidsForPidForTesting(2);
- ASSERT_NE(pid_it.first, pid_it.second);
+ auto opt_upid = context.process_tracker->UpidForPidForTesting(2);
+ ASSERT_TRUE(opt_upid.has_value());
ASSERT_EQ(context.storage->process_table().row_count(), 2u);
}
TEST_F(ProcessTrackerTest, PidReuseWithoutStartAndEndThread) {
UniquePid p1 = context.process_tracker->StartNewProcess(
- base::nullopt, base::nullopt, /*pid=*/1, kNullStringId);
+ base::nullopt, base::nullopt, /*pid=*/1, kNullStringId,
+ ThreadNamePriority::kFtrace);
UniqueTid t1 = context.process_tracker->UpdateThread(/*tid=*/2, /*pid=*/1);
UniquePid p2 = context.process_tracker->StartNewProcess(
- base::nullopt, base::nullopt, /*pid=*/1, kNullStringId);
+ base::nullopt, base::nullopt, /*pid=*/1, kNullStringId,
+ ThreadNamePriority::kFtrace);
UniqueTid t2 = context.process_tracker->UpdateThread(/*tid=*/2, /*pid=*/1);
ASSERT_NE(p1, p2);
@@ -156,7 +157,8 @@ TEST_F(ProcessTrackerTest, UpdateThreadName) {
TEST_F(ProcessTrackerTest, SetStartTsIfUnset) {
auto upid = context.process_tracker->StartNewProcess(
- /*timestamp=*/base::nullopt, 0u, 123, kNullStringId);
+ /*timestamp=*/base::nullopt, 0u, 123, kNullStringId,
+ ThreadNamePriority::kFtrace);
context.process_tracker->SetStartTsIfUnset(upid, 1000);
ASSERT_EQ(context.storage->process_table().start_ts()[upid], 1000);
@@ -164,6 +166,101 @@ TEST_F(ProcessTrackerTest, SetStartTsIfUnset) {
ASSERT_EQ(context.storage->process_table().start_ts()[upid], 1000);
}
+TEST_F(ProcessTrackerTest, PidReuseAfterExplicitEnd) {
+ UniquePid upid = context.process_tracker->GetOrCreateProcess(123);
+ context.process_tracker->EndThread(100, 123);
+
+ UniquePid reuse = context.process_tracker->GetOrCreateProcess(123);
+ ASSERT_NE(upid, reuse);
+}
+
+TEST_F(ProcessTrackerTest, TidReuseAfterExplicitEnd) {
+ UniqueTid utid = context.process_tracker->UpdateThread(123, 123);
+ context.process_tracker->EndThread(100, 123);
+
+ UniqueTid reuse = context.process_tracker->UpdateThread(123, 123);
+ ASSERT_NE(utid, reuse);
+
+ UniqueTid reuse_again = context.process_tracker->UpdateThread(123, 123);
+ ASSERT_EQ(reuse, reuse_again);
+}
+
+TEST_F(ProcessTrackerTest, EndThreadAfterProcessEnd) {
+ context.process_tracker->StartNewProcess(
+ 100, base::nullopt, 123, kNullStringId, ThreadNamePriority::kFtrace);
+ context.process_tracker->UpdateThread(124, 123);
+
+ context.process_tracker->EndThread(200, 123);
+ context.process_tracker->EndThread(201, 124);
+
+ // We expect two processes: the idle process and 123.
+ ASSERT_EQ(context.storage->process_table().row_count(), 2u);
+
+ // We expect three theads: the idle thread, 123 and 124.
+ ASSERT_EQ(context.storage->thread_table().row_count(), 3u);
+}
+
+TEST_F(ProcessTrackerTest, UpdateTrustedPid) {
+ context.process_tracker->UpdateTrustedPid(/*trusted_pid=*/123, /*uuid=*/1001);
+ context.process_tracker->UpdateTrustedPid(/*trusted_pid=*/456, /*uuid=*/1002);
+
+ ASSERT_EQ(context.process_tracker->GetTrustedPid(1001).value(), 123u);
+ ASSERT_EQ(context.process_tracker->GetTrustedPid(1002).value(), 456u);
+
+ // PID reuse. Multiple track UUIDs map to the same trusted_pid.
+ context.process_tracker->UpdateTrustedPid(/*trusted_pid=*/123, /*uuid=*/1003);
+ ASSERT_EQ(context.process_tracker->GetTrustedPid(1001).value(), 123u);
+ ASSERT_EQ(context.process_tracker->GetTrustedPid(1003).value(), 123u);
+}
+
+TEST_F(ProcessTrackerTest, NamespacedProcessesAndThreads) {
+ context.process_tracker->UpdateNamespacedProcess(/*pid=*/1001,
+ /*nspid=*/{1001, 190, 1});
+ context.process_tracker->UpdateNamespacedThread(/*pid=*/1001, /*tid=*/1002,
+ /*nstid=*/{1002, 192, 2});
+ context.process_tracker->UpdateNamespacedThread(1001, 1003, {1003, 193, 3});
+
+ context.process_tracker->UpdateNamespacedProcess(/*pid=*/1023,
+ /*nspid=*/{1023, 201, 21});
+ context.process_tracker->UpdateNamespacedThread(/*pid=*/1023, /*tid=*/1026,
+ {1026, 196, 26});
+ context.process_tracker->UpdateNamespacedThread(/*pid=*/1023, /*tid=*/1027,
+ {1027, 197, 27});
+
+ context.process_tracker->UpdateNamespacedProcess(/*pid=*/1024,
+ /*nspid=*/{1024, 202, 22});
+ context.process_tracker->UpdateNamespacedThread(/*pid=*/1024, /*tid=*/1028,
+ /*nstid=*/{1028, 198, 28});
+ context.process_tracker->UpdateNamespacedThread(/*pid=*/1024, /*tid=*/1029,
+ /*nstid=*/{1029, 198, 29});
+
+ // Don't resolve if the process/thread isn't namespaced.
+ ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(2001, 2002),
+ base::nullopt);
+
+ // Resolve from namespace-local PID to root-level PID.
+ ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(1001, 1).value(),
+ 1001u);
+ ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(1023, 21).value(),
+ 1023u);
+ ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(1024, 22).value(),
+ 1024u);
+
+ // Resolve from namespace-local TID to root-level TID.
+ ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(1001, 2).value(),
+ 1002u);
+ ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(1001, 3).value(),
+ 1003u);
+ ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(1023, 26).value(),
+ 1026u);
+ ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(1023, 27).value(),
+ 1027u);
+ ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(1024, 28).value(),
+ 1028u);
+ ASSERT_EQ(context.process_tracker->ResolveNamespacedTid(1024, 29).value(),
+ 1029u);
+}
+
} // namespace
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/importers/common/slice_tracker.cc b/src/trace_processor/importers/common/slice_tracker.cc
index 728f9c227..8bd2585a8 100644
--- a/src/trace_processor/importers/common/slice_tracker.cc
+++ b/src/trace_processor/importers/common/slice_tracker.cc
@@ -20,6 +20,7 @@
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/importers/common/slice_tracker.h"
+#include "src/trace_processor/importers/common/slice_translation_table.h"
#include "src/trace_processor/importers/common/track_tracker.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/trace_processor_context.h"
@@ -39,8 +40,10 @@ SliceTracker::~SliceTracker() = default;
base::Optional<SliceId> SliceTracker::Begin(int64_t timestamp,
TrackId track_id,
StringId category,
- StringId name,
+ StringId raw_name,
SetArgsCallback args_callback) {
+ const StringId name =
+ context_->slice_translation_table->TranslateName(raw_name);
tables::SliceTable::Row row(timestamp, kPendingDuration, track_id, category,
name);
return StartSlice(timestamp, track_id, args_callback, [this, &row]() {
@@ -50,6 +53,10 @@ base::Optional<SliceId> SliceTracker::Begin(int64_t timestamp,
void SliceTracker::BeginLegacyUnnestable(tables::SliceTable::Row row,
SetArgsCallback args_callback) {
+ if (row.name) {
+ row.name = context_->slice_translation_table->TranslateName(*row.name);
+ }
+
// Ensure that the duration is pending for this row.
// TODO(lalitm): change this to eventually use null instead of -1.
row.dur = kPendingDuration;
@@ -57,8 +64,8 @@ void SliceTracker::BeginLegacyUnnestable(tables::SliceTable::Row row,
// Double check that if we've seen this track in the past, it was also
// marked as unnestable then.
#if PERFETTO_DCHECK_IS_ON()
- auto it = stacks_.find(row.track_id);
- PERFETTO_DCHECK(it == stacks_.end() || it->second.is_legacy_unnestable);
+ auto* it = stacks_.Find(row.track_id);
+ PERFETTO_DCHECK(!it || it->is_legacy_unnestable);
#endif
// Ensure that StartSlice knows that this track is unnestable.
@@ -72,11 +79,13 @@ void SliceTracker::BeginLegacyUnnestable(tables::SliceTable::Row row,
base::Optional<SliceId> SliceTracker::Scoped(int64_t timestamp,
TrackId track_id,
StringId category,
- StringId name,
+ StringId raw_name,
int64_t duration,
SetArgsCallback args_callback) {
PERFETTO_DCHECK(duration >= 0);
+ const StringId name =
+ context_->slice_translation_table->TranslateName(raw_name);
tables::SliceTable::Row row(timestamp, duration, track_id, category, name);
return StartSlice(timestamp, track_id, args_callback, [this, &row]() {
return context_->storage->mutable_slice_table()->Insert(row).id;
@@ -86,8 +95,10 @@ base::Optional<SliceId> SliceTracker::Scoped(int64_t timestamp,
base::Optional<SliceId> SliceTracker::End(int64_t timestamp,
TrackId track_id,
StringId category,
- StringId name,
+ StringId raw_name,
SetArgsCallback args_callback) {
+ const StringId name =
+ context_->slice_translation_table->TranslateName(raw_name);
auto finder = [this, category, name](const SlicesStack& stack) {
return MatchingIncompleteSliceIndex(stack, name, category);
};
@@ -98,11 +109,11 @@ base::Optional<uint32_t> SliceTracker::AddArgs(TrackId track_id,
StringId category,
StringId name,
SetArgsCallback args_callback) {
- auto it = stacks_.find(track_id);
- if (it == stacks_.end())
+ auto* it = stacks_.Find(track_id);
+ if (!it)
return base::nullopt;
- auto& stack = it->second.slice_stack;
+ auto& stack = it->slice_stack;
if (stack.empty())
return base::nullopt;
@@ -152,10 +163,6 @@ base::Optional<SliceId> SliceTracker::StartSlice(
MaybeCloseStack(timestamp, stack, track_id);
const uint8_t depth = static_cast<uint8_t>(stack->size());
- if (depth >= std::numeric_limits<uint8_t>::max()) {
- PERFETTO_DFATAL("Slices with too large depth found.");
- return base::nullopt;
- }
int64_t parent_stack_id =
depth == 0 ? 0 : slices->stack_id()[stack->back().row];
base::Optional<tables::SliceTable::Id> parent_id =
@@ -164,6 +171,14 @@ base::Optional<SliceId> SliceTracker::StartSlice(
SliceId id = inserter();
uint32_t slice_idx = *slices->id().IndexOf(id);
+ if (depth >= std::numeric_limits<uint8_t>::max()) {
+ auto last_slice_name = slices->name().GetString(stack->back().row);
+ auto current_slice_name = slices->name().GetString(slice_idx);
+ PERFETTO_DLOG("Last slice: %s", last_slice_name.c_str());
+ PERFETTO_DLOG("Current slice: %s", current_slice_name.c_str());
+ PERFETTO_DFATAL("Slices with too large depth found.");
+ return base::nullopt;
+ }
StackPush(track_id, slice_idx);
// Post fill all the relevant columns. All the other columns should have
@@ -194,11 +209,11 @@ base::Optional<SliceId> SliceTracker::CompleteSlice(
}
prev_timestamp_ = timestamp;
- auto it = stacks_.find(track_id);
- if (it == stacks_.end())
+ auto it = stacks_.Find(track_id);
+ if (!it)
return base::nullopt;
- TrackInfo& track_info = it->second;
+ TrackInfo& track_info = *it;
SlicesStack& stack = track_info.slice_stack;
MaybeCloseStack(timestamp, &stack, track_id);
if (stack.empty())
@@ -252,13 +267,16 @@ base::Optional<uint32_t> SliceTracker::MatchingIncompleteSliceIndex(
uint32_t slice_idx = stack[static_cast<size_t>(i)].row;
if (slices->dur()[slice_idx] != kPendingDuration)
continue;
- const StringId& other_category = slices->category()[slice_idx];
- if (!category.is_null() &&
- (other_category.is_null() || category != other_category))
+ base::Optional<StringId> other_category = slices->category()[slice_idx];
+ if (!category.is_null() && (!other_category || other_category->is_null() ||
+ category != other_category)) {
continue;
- const StringId& other_name = slices->name()[slice_idx];
- if (!name.is_null() && !other_name.is_null() && name != other_name)
+ }
+ base::Optional<StringId> other_name = slices->name()[slice_idx];
+ if (!name.is_null() && other_name && !other_name->is_null() &&
+ name != other_name) {
continue;
+ }
return static_cast<uint32_t>(i);
}
return base::nullopt;
@@ -272,7 +290,7 @@ void SliceTracker::FlushPendingSlices() {
// TODO(eseckler): Reconsider whether we want to close pending slices by
// setting their duration to |trace_end - event_start|. Might still want some
// additional way of flagging these events as "incomplete" to the UI.
- stacks_.clear();
+ stacks_.Clear();
}
void SliceTracker::SetOnSliceBeginCallback(OnSliceBeginCallback callback) {
@@ -281,10 +299,10 @@ void SliceTracker::SetOnSliceBeginCallback(OnSliceBeginCallback callback) {
base::Optional<SliceId> SliceTracker::GetTopmostSliceOnTrack(
TrackId track_id) const {
- const auto iter = stacks_.find(track_id);
- if (iter == stacks_.end())
+ const auto* iter = stacks_.Find(track_id);
+ if (!iter)
return base::nullopt;
- const auto& stack = iter->second.slice_stack;
+ const auto& stack = iter->slice_stack;
if (stack.empty())
return base::nullopt;
uint32_t slice_idx = stack.back().row;
@@ -357,8 +375,8 @@ int64_t SliceTracker::GetStackHash(const SlicesStack& stack) {
base::Hash hash;
for (size_t i = 0; i < stack.size(); i++) {
uint32_t slice_idx = stack[i].row;
- hash.Update(slices.category()[slice_idx].raw_id());
- hash.Update(slices.name()[slice_idx].raw_id());
+ hash.Update(slices.category()[slice_idx].value_or(kNullStringId).raw_id());
+ hash.Update(slices.name()[slice_idx].value_or(kNullStringId).raw_id());
}
// For clients which don't have an integer type (i.e. Javascript), returning
diff --git a/src/trace_processor/importers/common/slice_tracker.h b/src/trace_processor/importers/common/slice_tracker.h
index f57416481..d6205b5f6 100644
--- a/src/trace_processor/importers/common/slice_tracker.h
+++ b/src/trace_processor/importers/common/slice_tracker.h
@@ -19,7 +19,9 @@
#include <stdint.h>
+#include "perfetto/ext/base/flat_hash_map.h"
#include "src/trace_processor/importers/common/args_tracker.h"
+#include "src/trace_processor/importers/common/slice_translation_table.h"
#include "src/trace_processor/storage/trace_storage.h"
namespace perfetto {
@@ -41,7 +43,7 @@ class SliceTracker {
int64_t timestamp,
TrackId track_id,
StringId category,
- StringId name,
+ StringId raw_name,
SetArgsCallback args_callback = SetArgsCallback());
// Unnestable slices are slices which do not have any concept of nesting so
@@ -60,6 +62,9 @@ class SliceTracker {
SetArgsCallback args_callback = SetArgsCallback()) {
// Ensure that the duration is pending for this row.
row.dur = kPendingDuration;
+ if (row.name) {
+ row.name = context_->slice_translation_table->TranslateName(*row.name);
+ }
return StartSlice(row.ts, row.track_id, args_callback,
[table, &row]() { return table->Insert(row).id; });
}
@@ -69,16 +74,19 @@ class SliceTracker {
int64_t timestamp,
TrackId track_id,
StringId category,
- StringId name,
+ StringId raw_name,
int64_t duration,
SetArgsCallback args_callback = SetArgsCallback());
template <typename Table>
base::Optional<SliceId> ScopedTyped(
Table* table,
- const typename Table::Row& row,
+ typename Table::Row row,
SetArgsCallback args_callback = SetArgsCallback()) {
PERFETTO_DCHECK(row.dur >= 0);
+ if (row.name) {
+ row.name = context_->slice_translation_table->TranslateName(*row.name);
+ }
return StartSlice(row.ts, row.track_id, args_callback,
[table, &row]() { return table->Insert(row).id; });
}
@@ -88,7 +96,7 @@ class SliceTracker {
int64_t timestamp,
TrackId track_id,
StringId opt_category = {},
- StringId opt_name = {},
+ StringId opt_raw_name = {},
SetArgsCallback args_callback = SetArgsCallback());
// Usually args should be added in the Begin or End args_callback but this
@@ -124,7 +132,7 @@ class SliceTracker {
uint32_t legacy_unnestable_begin_count = 0;
int64_t legacy_unnestable_last_begin_ts = 0;
};
- using StackMap = std::unordered_map<TrackId, TrackInfo>;
+ using StackMap = base::FlatHashMap<TrackId, TrackInfo>;
// virtual for testing.
virtual base::Optional<SliceId> StartSlice(int64_t timestamp,
diff --git a/src/trace_processor/importers/common/slice_tracker_unittest.cc b/src/trace_processor/importers/common/slice_tracker_unittest.cc
index 23e2bcf73..29e74899d 100644
--- a/src/trace_processor/importers/common/slice_tracker_unittest.cc
+++ b/src/trace_processor/importers/common/slice_tracker_unittest.cc
@@ -18,6 +18,7 @@
#include "src/trace_processor/importers/common/args_tracker.h"
#include "src/trace_processor/importers/common/slice_tracker.h"
+#include "src/trace_processor/importers/common/slice_translation_table.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/trace_processor_context.h"
#include "test/gtest_and_gmock.h"
@@ -53,6 +54,8 @@ std::vector<SliceInfo> ToSliceInfo(const tables::SliceTable& slices) {
TEST(SliceTrackerTest, OneSliceDetailed) {
TraceProcessorContext context;
context.storage.reset(new TraceStorage());
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
SliceTracker tracker(&context);
constexpr TrackId track{22u};
@@ -66,8 +69,36 @@ TEST(SliceTrackerTest, OneSliceDetailed) {
EXPECT_EQ(slices.ts()[0], 2);
EXPECT_EQ(slices.dur()[0], 8);
EXPECT_EQ(slices.track_id()[0], track);
- EXPECT_EQ(slices.category()[0].raw_id(), 0u);
- EXPECT_EQ(slices.name()[0].raw_id(), 1u);
+ EXPECT_EQ(slices.category()[0].value_or(kNullStringId).raw_id(), 0u);
+ EXPECT_EQ(slices.name()[0].value_or(kNullStringId).raw_id(), 1u);
+ EXPECT_EQ(slices.depth()[0], 0u);
+ EXPECT_EQ(slices.arg_set_id()[0], kInvalidArgSetId);
+}
+
+TEST(SliceTrackerTest, OneSliceDetailedWithTranslatedName) {
+ TraceProcessorContext context;
+ context.storage.reset(new TraceStorage());
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
+ SliceTracker tracker(&context);
+
+ const StringId raw_name = context.storage->InternString("raw_name");
+ const StringId mapped_name = context.storage->InternString("mapped_name");
+ context.slice_translation_table->AddNameTranslationRule("raw_name",
+ "mapped_name");
+
+ constexpr TrackId track{22u};
+ tracker.Begin(2 /*ts*/, track, kNullStringId /*cat*/, raw_name /*name*/);
+ tracker.End(10 /*ts*/, track, kNullStringId /*cat*/, raw_name /*name*/);
+
+ const auto& slices = context.storage->slice_table();
+ EXPECT_EQ(slices.row_count(), 1u);
+ EXPECT_EQ(slices.ts()[0], 2);
+ EXPECT_EQ(slices.dur()[0], 8);
+ EXPECT_EQ(slices.track_id()[0], track);
+ EXPECT_EQ(slices.category()[0].value_or(kNullStringId).raw_id(), 0u);
+ EXPECT_EQ(slices.name()[0].value_or(kNullStringId).raw_id(),
+ mapped_name.raw_id());
EXPECT_EQ(slices.depth()[0], 0u);
EXPECT_EQ(slices.arg_set_id()[0], kInvalidArgSetId);
}
@@ -75,6 +106,8 @@ TEST(SliceTrackerTest, OneSliceDetailed) {
TEST(SliceTrackerTest, NegativeTimestamps) {
TraceProcessorContext context;
context.storage.reset(new TraceStorage());
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
SliceTracker tracker(&context);
constexpr TrackId track{22u};
@@ -88,8 +121,8 @@ TEST(SliceTrackerTest, NegativeTimestamps) {
EXPECT_EQ(slices.ts()[0], -1000);
EXPECT_EQ(slices.dur()[0], 499);
EXPECT_EQ(slices.track_id()[0], track);
- EXPECT_EQ(slices.category()[0].raw_id(), 0u);
- EXPECT_EQ(slices.name()[0].raw_id(), 1u);
+ EXPECT_EQ(slices.category()[0].value_or(kNullStringId).raw_id(), 0u);
+ EXPECT_EQ(slices.name()[0].value_or(kNullStringId).raw_id(), 1u);
EXPECT_EQ(slices.depth()[0], 0u);
EXPECT_EQ(slices.arg_set_id()[0], kInvalidArgSetId);
}
@@ -98,6 +131,8 @@ TEST(SliceTrackerTest, OneSliceWithArgs) {
TraceProcessorContext context;
context.storage.reset(new TraceStorage());
context.global_args_tracker.reset(new GlobalArgsTracker(&context));
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
SliceTracker tracker(&context);
constexpr TrackId track{22u};
@@ -121,8 +156,57 @@ TEST(SliceTrackerTest, OneSliceWithArgs) {
EXPECT_EQ(slices.ts()[0], 2);
EXPECT_EQ(slices.dur()[0], 8);
EXPECT_EQ(slices.track_id()[0], track);
- EXPECT_EQ(slices.category()[0].raw_id(), 0u);
- EXPECT_EQ(slices.name()[0].raw_id(), 1u);
+ EXPECT_EQ(slices.category()[0].value_or(kNullStringId).raw_id(), 0u);
+ EXPECT_EQ(slices.name()[0].value_or(kNullStringId).raw_id(), 1u);
+ EXPECT_EQ(slices.depth()[0], 0u);
+ auto set_id = slices.arg_set_id()[0];
+
+ const auto& args = context.storage->arg_table();
+ EXPECT_EQ(args.arg_set_id()[0], set_id);
+ EXPECT_EQ(args.flat_key()[0].raw_id(), 1u);
+ EXPECT_EQ(args.key()[0].raw_id(), 2u);
+ EXPECT_EQ(args.int_value()[0], 10);
+ EXPECT_EQ(args.arg_set_id()[1], set_id);
+ EXPECT_EQ(args.flat_key()[1].raw_id(), 3u);
+ EXPECT_EQ(args.key()[1].raw_id(), 4u);
+ EXPECT_EQ(args.int_value()[1], 20);
+}
+
+TEST(SliceTrackerTest, OneSliceWithArgsWithTranslatedName) {
+ TraceProcessorContext context;
+ context.storage.reset(new TraceStorage());
+ context.global_args_tracker.reset(new GlobalArgsTracker(&context));
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
+ SliceTracker tracker(&context);
+
+ const StringId raw_name = context.storage->InternString("raw_name");
+ const StringId mapped_name = context.storage->InternString("mapped_name");
+ context.slice_translation_table->AddNameTranslationRule("raw_name",
+ "mapped_name");
+
+ constexpr TrackId track{22u};
+ tracker.Begin(2 /*ts*/, track, kNullStringId /*cat*/, raw_name /*name*/,
+ [](ArgsTracker::BoundInserter* inserter) {
+ inserter->AddArg(/*flat_key=*/StringId::Raw(1),
+ /*key=*/StringId::Raw(2),
+ /*value=*/Variadic::Integer(10));
+ });
+ tracker.End(10 /*ts*/, track, kNullStringId /*cat*/, raw_name /*name*/,
+ [](ArgsTracker::BoundInserter* inserter) {
+ inserter->AddArg(/*flat_key=*/StringId::Raw(3),
+ /*key=*/StringId::Raw(4),
+ /*value=*/Variadic::Integer(20));
+ });
+
+ const auto& slices = context.storage->slice_table();
+ EXPECT_EQ(slices.row_count(), 1u);
+ EXPECT_EQ(slices.ts()[0], 2);
+ EXPECT_EQ(slices.dur()[0], 8);
+ EXPECT_EQ(slices.track_id()[0], track);
+ EXPECT_EQ(slices.category()[0].value_or(kNullStringId).raw_id(), 0u);
+ EXPECT_EQ(slices.name()[0].value_or(kNullStringId).raw_id(),
+ mapped_name.raw_id());
EXPECT_EQ(slices.depth()[0], 0u);
auto set_id = slices.arg_set_id()[0];
@@ -140,6 +224,8 @@ TEST(SliceTrackerTest, OneSliceWithArgs) {
TEST(SliceTrackerTest, TwoSliceDetailed) {
TraceProcessorContext context;
context.storage.reset(new TraceStorage());
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
SliceTracker tracker(&context);
constexpr TrackId track{22u};
@@ -158,15 +244,15 @@ TEST(SliceTrackerTest, TwoSliceDetailed) {
EXPECT_EQ(slices.ts()[idx], 2);
EXPECT_EQ(slices.dur()[idx], 8);
EXPECT_EQ(slices.track_id()[idx], track);
- EXPECT_EQ(slices.category()[idx].raw_id(), 0u);
- EXPECT_EQ(slices.name()[idx].raw_id(), 1u);
+ EXPECT_EQ(slices.category()[idx].value_or(kNullStringId).raw_id(), 0u);
+ EXPECT_EQ(slices.name()[idx].value_or(kNullStringId).raw_id(), 1u);
EXPECT_EQ(slices.depth()[idx++], 0u);
EXPECT_EQ(slices.ts()[idx], 3);
EXPECT_EQ(slices.dur()[idx], 2);
EXPECT_EQ(slices.track_id()[idx], track);
- EXPECT_EQ(slices.category()[idx].raw_id(), 0u);
- EXPECT_EQ(slices.name()[idx].raw_id(), 2u);
+ EXPECT_EQ(slices.category()[idx].value_or(kNullStringId).raw_id(), 0u);
+ EXPECT_EQ(slices.name()[idx].value_or(kNullStringId).raw_id(), 2u);
EXPECT_EQ(slices.depth()[idx], 1u);
EXPECT_EQ(slices.parent_stack_id()[0], 0);
@@ -177,6 +263,8 @@ TEST(SliceTrackerTest, TwoSliceDetailed) {
TEST(SliceTrackerTest, Scoped) {
TraceProcessorContext context;
context.storage.reset(new TraceStorage());
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
SliceTracker tracker(&context);
constexpr TrackId track{22u};
@@ -191,9 +279,34 @@ TEST(SliceTrackerTest, Scoped) {
ElementsAre(SliceInfo{0, 10}, SliceInfo{1, 8}, SliceInfo{2, 6}));
}
+TEST(SliceTrackerTest, ScopedWithTranslatedName) {
+ TraceProcessorContext context;
+ context.storage.reset(new TraceStorage());
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
+ SliceTracker tracker(&context);
+
+ const StringId raw_name = context.storage->InternString("raw_name");
+ context.slice_translation_table->AddNameTranslationRule("raw_name",
+ "mapped_name");
+
+ constexpr TrackId track{22u};
+ tracker.Begin(0 /*ts*/, track, kNullStringId, raw_name);
+ tracker.Begin(1 /*ts*/, track, kNullStringId, raw_name);
+ tracker.Scoped(2 /*ts*/, track, kNullStringId, raw_name, 6);
+ tracker.End(9 /*ts*/, track);
+ tracker.End(10 /*ts*/, track);
+
+ auto slices = ToSliceInfo(context.storage->slice_table());
+ EXPECT_THAT(slices,
+ ElementsAre(SliceInfo{0, 10}, SliceInfo{1, 8}, SliceInfo{2, 6}));
+}
+
TEST(SliceTrackerTest, ParentId) {
TraceProcessorContext context;
context.storage.reset(new TraceStorage());
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
SliceTracker tracker(&context);
constexpr TrackId track{22u};
@@ -213,6 +326,8 @@ TEST(SliceTrackerTest, ParentId) {
TEST(SliceTrackerTest, IgnoreMismatchedEnds) {
TraceProcessorContext context;
context.storage.reset(new TraceStorage());
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
SliceTracker tracker(&context);
constexpr TrackId track{22u};
@@ -232,6 +347,8 @@ TEST(SliceTrackerTest, IgnoreMismatchedEnds) {
TEST(SliceTrackerTest, ZeroLengthScoped) {
TraceProcessorContext context;
context.storage.reset(new TraceStorage());
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
SliceTracker tracker(&context);
// Bug scenario: the second zero-length scoped slice prevents the first slice
@@ -255,6 +372,8 @@ TEST(SliceTrackerTest, ZeroLengthScoped) {
TEST(SliceTrackerTest, DifferentTracks) {
TraceProcessorContext context;
context.storage.reset(new TraceStorage());
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
SliceTracker tracker(&context);
constexpr TrackId track_a{22u};
@@ -280,6 +399,8 @@ TEST(SliceTrackerTest, DifferentTracks) {
TEST(SliceTrackerTest, EndEventOutOfOrder) {
TraceProcessorContext context;
context.storage.reset(new TraceStorage());
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
SliceTracker tracker(&context);
constexpr TrackId track{22u};
@@ -330,6 +451,8 @@ TEST(SliceTrackerTest, EndEventOutOfOrder) {
TEST(SliceTrackerTest, GetTopmostSliceOnTrack) {
TraceProcessorContext context;
context.storage.reset(new TraceStorage());
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
SliceTracker tracker(&context);
TrackId track{1u};
@@ -361,6 +484,8 @@ TEST(SliceTrackerTest, GetTopmostSliceOnTrack) {
TEST(SliceTrackerTest, OnSliceBeginCallback) {
TraceProcessorContext context;
context.storage.reset(new TraceStorage());
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
SliceTracker tracker(&context);
TrackId track1{1u};
diff --git a/src/trace_processor/importers/common/slice_translation_table.cc b/src/trace_processor/importers/common/slice_translation_table.cc
new file mode 100644
index 000000000..8c34dc7c3
--- /dev/null
+++ b/src/trace_processor/importers/common/slice_translation_table.cc
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/importers/common/slice_translation_table.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+SliceTranslationTable::SliceTranslationTable(TraceStorage* storage)
+ : storage_(storage) {}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/common/slice_translation_table.h b/src/trace_processor/importers/common/slice_translation_table.h
new file mode 100644
index 000000000..bcbad1606
--- /dev/null
+++ b/src/trace_processor/importers/common/slice_translation_table.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_SLICE_TRANSLATION_TABLE_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_SLICE_TRANSLATION_TABLE_H_
+
+#include <cstdint>
+
+#include "perfetto/ext/base/flat_hash_map.h"
+#include "perfetto/ext/base/string_view.h"
+#include "src/trace_processor/storage/trace_storage.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+// Tracks and stores slice translation rules. It allows Trace Processor
+// to for example deobfuscate slice names.
+class SliceTranslationTable {
+ public:
+ SliceTranslationTable(TraceStorage* storage);
+
+ // If the name is not mapped to anything, assumes that no translation is
+ // necessry, and returns the raw_name.
+ StringId TranslateName(StringId raw_name) const {
+ const auto* mapped_name = raw_to_deobfuscated_name_.Find(raw_name);
+ return mapped_name ? *mapped_name : raw_name;
+ }
+
+ void AddNameTranslationRule(base::StringView raw,
+ base::StringView deobfuscated) {
+ const StringId raw_id = storage_->InternString(raw);
+ const StringId deobfuscated_id = storage_->InternString(deobfuscated);
+ raw_to_deobfuscated_name_[raw_id] = deobfuscated_id;
+ }
+
+ private:
+ TraceStorage* storage_;
+ base::FlatHashMap<StringId, StringId> raw_to_deobfuscated_name_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_SLICE_TRANSLATION_TABLE_H_
diff --git a/src/trace_processor/importers/common/slice_translation_table_unittest.cc b/src/trace_processor/importers/common/slice_translation_table_unittest.cc
new file mode 100644
index 000000000..11bb5e3c5
--- /dev/null
+++ b/src/trace_processor/importers/common/slice_translation_table_unittest.cc
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/importers/common/slice_translation_table.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace trace_processor {
+namespace {
+
+TEST(SliceTranslationTable, UnknownName) {
+ TraceStorage storage;
+ SliceTranslationTable table(&storage);
+ const StringId raw_name = storage.InternString("name1");
+ EXPECT_EQ(raw_name, table.TranslateName(raw_name));
+}
+
+TEST(SliceTranslationTable, MappedName) {
+ TraceStorage storage;
+ SliceTranslationTable table(&storage);
+ table.AddNameTranslationRule("raw_name1", "mapped_name1");
+ const StringId raw_name = storage.InternString("raw_name1");
+ const StringId mapped_name = storage.InternString("mapped_name1");
+ EXPECT_EQ(mapped_name, table.TranslateName(raw_name));
+}
+
+} // namespace
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/common/trace_blob_view.h b/src/trace_processor/importers/common/trace_blob_view.h
deleted file mode 100644
index a94a994e4..000000000
--- a/src/trace_processor/importers/common/trace_blob_view.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_TRACE_BLOB_VIEW_H_
-#define SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_TRACE_BLOB_VIEW_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <limits>
-#include <memory>
-
-#include "perfetto/base/logging.h"
-
-namespace perfetto {
-namespace trace_processor {
-
-// This class is an equivalent of std::string_view for trace binary data.
-// The main difference is that this class has also shared ownership of a portion
-// of the raw trace.
-// The underlying buffer will be freed once all the TraceBlobViews that refer
-// to the same buffer have passed through the pipeline and been parsed.
-class TraceBlobView {
- public:
- TraceBlobView(std::unique_ptr<uint8_t[]> buffer, size_t offset, size_t length)
- : shbuf_(SharedBuf(std::move(buffer))),
- offset_(static_cast<uint32_t>(offset)),
- length_(static_cast<uint32_t>(length)) {
- PERFETTO_DCHECK(offset <= std::numeric_limits<uint32_t>::max());
- PERFETTO_DCHECK(length <= std::numeric_limits<uint32_t>::max());
- }
-
- // Allow std::move().
- TraceBlobView(TraceBlobView&&) noexcept = default;
- TraceBlobView& operator=(TraceBlobView&&) = default;
-
- // Disable implicit copy.
- TraceBlobView(const TraceBlobView&) = delete;
- TraceBlobView& operator=(const TraceBlobView&) = delete;
-
- TraceBlobView slice(size_t offset, size_t length) const {
- PERFETTO_DCHECK(offset + length <= offset_ + length_);
- return TraceBlobView(shbuf_, offset, length);
- }
-
- bool operator==(const TraceBlobView& rhs) const {
- return (shbuf_ == rhs.shbuf_) && (offset_ == rhs.offset_) &&
- (length_ == rhs.length_);
- }
- bool operator!=(const TraceBlobView& rhs) const { return !(*this == rhs); }
-
- inline const uint8_t* data() const { return start() + offset_; }
-
- size_t offset_of(const uint8_t* data) const {
- // When a field is size 0, data can be equal to start() + offset_ + length_.
- PERFETTO_DCHECK(data >= start() && data <= (start() + offset_ + length_));
- return static_cast<size_t>(data - start());
- }
-
- size_t length() const { return length_; }
- size_t offset() const { return offset_; }
-
- private:
- // An equivalent to std::shared_ptr<uint8_t>, with the differnce that:
- // - Supports array types, available for shared_ptr only in C++17.
- // - Is not thread safe, which is not needed for our purposes.
- class SharedBuf {
- public:
- explicit SharedBuf(std::unique_ptr<uint8_t[]> mem) {
- rcbuf_ = new RefCountedBuf(std::move(mem));
- }
-
- SharedBuf(const SharedBuf& copy) : rcbuf_(copy.rcbuf_) {
- PERFETTO_DCHECK(rcbuf_->refcount > 0);
- rcbuf_->refcount++;
- }
-
- ~SharedBuf() {
- if (!rcbuf_)
- return;
- PERFETTO_DCHECK(rcbuf_->refcount > 0);
- if (--rcbuf_->refcount == 0) {
- RefCountedBuf* rcbuf = rcbuf_;
- rcbuf_ = nullptr;
- delete rcbuf;
- }
- }
-
- SharedBuf(SharedBuf&& other) noexcept {
- rcbuf_ = other.rcbuf_;
- other.rcbuf_ = nullptr;
- }
-
- SharedBuf& operator=(SharedBuf&& other) {
- if (this != &other) {
- // A bit of a ugly but pragmatic pattern to implement move assignment.
- // First invoke the distructor and then invoke the move constructor
- // inline via placement-new.
- this->~SharedBuf();
- new (this) SharedBuf(std::move(other));
- }
- return *this;
- }
-
- bool operator==(const SharedBuf& x) const { return x.rcbuf_ == rcbuf_; }
- bool operator!=(const SharedBuf& x) const { return !(x == *this); }
- const uint8_t* data() const { return rcbuf_->mem.get(); }
-
- private:
- struct RefCountedBuf {
- explicit RefCountedBuf(std::unique_ptr<uint8_t[]> buf)
- : refcount(1), mem(std::move(buf)) {}
- int refcount;
- std::unique_ptr<uint8_t[]> mem;
- };
-
- RefCountedBuf* rcbuf_ = nullptr;
- };
-
- inline const uint8_t* start() const { return shbuf_.data(); }
-
- TraceBlobView(SharedBuf b, size_t o, size_t l)
- : shbuf_(b),
- offset_(static_cast<uint32_t>(o)),
- length_(static_cast<uint32_t>(l)) {}
-
- SharedBuf shbuf_;
- uint32_t offset_;
- uint32_t length_; // Measured from |offset_|, not from |data()|.
-};
-
-} // namespace trace_processor
-} // namespace perfetto
-
-#endif // SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_TRACE_BLOB_VIEW_H_
diff --git a/src/trace_processor/importers/common/track_tracker.cc b/src/trace_processor/importers/common/track_tracker.cc
index 73aef4ee4..36a282d27 100644
--- a/src/trace_processor/importers/common/track_tracker.cc
+++ b/src/trace_processor/importers/common/track_tracker.cc
@@ -31,7 +31,6 @@ TrackTracker::TrackTracker(TraceProcessorContext* context)
category_key_(context->storage->InternString("category")),
fuchsia_source_(context->storage->InternString("fuchsia")),
chrome_source_(context->storage->InternString("chrome")),
- android_source_(context->storage->InternString("android")),
context_(context) {}
TrackId TrackTracker::InternThreadTrack(UniqueTid utid) {
@@ -133,28 +132,29 @@ TrackId TrackTracker::InternLegacyChromeAsyncTrack(
return id;
}
-TrackId TrackTracker::CreateGlobalAsyncTrack(StringId name) {
+TrackId TrackTracker::CreateGlobalAsyncTrack(StringId name, StringId source) {
tables::TrackTable::Row row(name);
auto id = context_->storage->mutable_track_table()->Insert(row).id;
+ if (!source.is_null()) {
+ context_->args_tracker->AddArgsTo(id).AddArg(source_key_,
+ Variadic::String(source));
+ }
return id;
}
-TrackId TrackTracker::CreateAndroidAsyncTrack(StringId name, UniquePid upid) {
+TrackId TrackTracker::CreateProcessAsyncTrack(StringId name,
+ UniquePid upid,
+ StringId source) {
tables::ProcessTrackTable::Row row(name);
row.upid = upid;
auto id = context_->storage->mutable_process_track_table()->Insert(row).id;
- context_->args_tracker->AddArgsTo(id).AddArg(
- source_key_, Variadic::String(android_source_));
+ if (!source.is_null()) {
+ context_->args_tracker->AddArgsTo(id).AddArg(source_key_,
+ Variadic::String(source));
+ }
return id;
}
-TrackId TrackTracker::CreateFrameTimelineAsyncTrack(StringId name,
- UniquePid upid) {
- tables::ProcessTrackTable::Row row(name);
- row.upid = upid;
- return context_->storage->mutable_process_track_table()->Insert(row).id;
-}
-
TrackId TrackTracker::InternLegacyChromeProcessInstantTrack(UniquePid upid) {
auto it = chrome_process_instant_tracks_.find(upid);
if (it != chrome_process_instant_tracks_.end())
diff --git a/src/trace_processor/importers/common/track_tracker.h b/src/trace_processor/importers/common/track_tracker.h
index 6ed95b92d..d51d41a52 100644
--- a/src/trace_processor/importers/common/track_tracker.h
+++ b/src/trace_processor/importers/common/track_tracker.h
@@ -52,15 +52,6 @@ class TrackTracker {
bool source_id_is_process_scoped,
StringId source_scope);
- // Creates and inserts a global async track into the storage.
- TrackId CreateGlobalAsyncTrack(StringId name);
-
- // Creates and inserts a Android async track into the storage.
- TrackId CreateAndroidAsyncTrack(StringId name, UniquePid upid);
-
- // Creates and inserts a FrameTimeline async track into the storage.
- TrackId CreateFrameTimelineAsyncTrack(StringId name, UniquePid upid);
-
// Interns a track for legacy Chrome process-scoped instant events into the
// storage.
TrackId InternLegacyChromeProcessInstantTrack(UniquePid upid);
@@ -104,13 +95,24 @@ class TrackTracker {
StringId description = StringId::Null(),
StringId unit = StringId::Null());
- // Creaates a counter track for values within perf samples.
+ // Creates a counter track for values within perf samples.
// The tracks themselves are managed by PerfSampleTracker.
TrackId CreatePerfCounterTrack(StringId name,
uint32_t perf_session_id,
uint32_t cpu,
bool is_timebase);
+ // NOTE:
+ // The below method should only be called by AsyncTrackSetTracker
+
+ // Creates and inserts a global async track into the storage.
+ TrackId CreateGlobalAsyncTrack(StringId name, StringId source);
+
+ // Creates and inserts a Android async track into the storage.
+ TrackId CreateProcessAsyncTrack(StringId name,
+ UniquePid upid,
+ StringId source);
+
private:
struct GpuTrackTuple {
StringId track_name;
@@ -163,7 +165,6 @@ class TrackTracker {
const StringId fuchsia_source_ = kNullStringId;
const StringId chrome_source_ = kNullStringId;
- const StringId android_source_ = kNullStringId;
TraceProcessorContext* const context_;
};
diff --git a/src/trace_processor/importers/default_modules.cc b/src/trace_processor/importers/default_modules.cc
index 19345cf45..b14f35761 100644
--- a/src/trace_processor/importers/default_modules.cc
+++ b/src/trace_processor/importers/default_modules.cc
@@ -16,6 +16,7 @@
#include "src/trace_processor/importers/default_modules.h"
#include "src/trace_processor/importers/ftrace/ftrace_module.h"
+#include "src/trace_processor/importers/proto/android_camera_event_module.h"
#include "src/trace_processor/importers/proto/chrome_system_probes_module.h"
#include "src/trace_processor/importers/proto/memory_tracker_snapshot_module.h"
#include "src/trace_processor/importers/proto/metadata_module.h"
@@ -38,6 +39,7 @@ void RegisterDefaultModules(TraceProcessorContext* context) {
context->modules.emplace_back(new TrackEventModule(context));
context->modules.emplace_back(new ProfileModule(context));
context->modules.emplace_back(new MetadataModule(context));
+ context->modules.emplace_back(new AndroidCameraEventModule(context));
}
} // namespace trace_processor
diff --git a/src/trace_processor/importers/ftrace/binder_tracker.cc b/src/trace_processor/importers/ftrace/binder_tracker.cc
index d866c0a63..5e95579bb 100644
--- a/src/trace_processor/importers/ftrace/binder_tracker.cc
+++ b/src/trace_processor/importers/ftrace/binder_tracker.cc
@@ -15,14 +15,15 @@
*/
#include "src/trace_processor/importers/ftrace/binder_tracker.h"
+#include "perfetto/base/compiler.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "src/trace_processor/importers/common/flow_tracker.h"
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/importers/common/slice_tracker.h"
#include "src/trace_processor/importers/common/track_tracker.h"
+#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/trace_processor_context.h"
-#include "perfetto/base/compiler.h"
-#include "perfetto/ext/base/string_utils.h"
-
namespace perfetto {
namespace trace_processor {
@@ -75,7 +76,6 @@ BinderTracker::BinderTracker(TraceProcessorContext* context)
flags_(context->storage->InternString("flags")),
code_(context->storage->InternString("code")),
calling_tid_(context->storage->InternString("calling tid")),
- dest_slice_id_(context->storage->InternString("destination slice id")),
data_size_(context->storage->InternString("data size")),
offsets_size_(context->storage->InternString("offsets size")) {}
@@ -85,8 +85,8 @@ void BinderTracker::Transaction(int64_t ts,
uint32_t tid,
int32_t transaction_id,
int32_t dest_node,
- int32_t dest_tgid,
- int32_t dest_tid,
+ uint32_t dest_tgid,
+ uint32_t dest_tid,
bool is_reply,
uint32_t flags,
StringId code) {
@@ -106,94 +106,97 @@ void BinderTracker::Transaction(int64_t ts,
base::StringView(flag_str))));
inserter->AddArg(code_, Variadic::String(code));
inserter->AddArg(calling_tid_, Variadic::UnsignedInteger(tid));
- // TODO(hjd): The legacy UI included the calling pid in the args,
- // is this necessary? It's complicated in our case because process
- // association might not happen until after the binder transaction slices
- // have been parsed. We would need to backfill the arg.
};
- if (is_reply) {
- // Reply slices have accurate dest information, so we can add it.
- const auto& thread_table = context_->storage->thread_table();
- UniqueTid utid = context_->process_tracker->GetOrCreateThread(
- static_cast<uint32_t>(dest_tid));
- StringId dest_thread_name = thread_table.name()[utid];
- auto dest_args_inserter = [this, dest_tid, &dest_thread_name](
- ArgsTracker::BoundInserter* inserter) {
- inserter->AddArg(dest_thread_, Variadic::Integer(dest_tid));
- inserter->AddArg(dest_name_, Variadic::String(dest_thread_name));
- };
- context_->slice_tracker->AddArgs(track_id, binder_category_id_, reply_id_,
- dest_args_inserter);
- context_->slice_tracker->End(ts, track_id, kNullStringId, kNullStringId,
- args_inserter);
- awaiting_rcv_for_reply_.insert(transaction_id);
- return;
- }
-
- bool expects_reply = !is_reply && ((flags & kOneWay) == 0);
+ bool is_oneway = (flags & kOneWay) == kOneWay;
+ auto insert_slice = [&]() {
+ if (is_reply) {
+ UniqueTid utid = context_->process_tracker->GetOrCreateThread(
+ static_cast<uint32_t>(dest_tid));
+ auto dest_thread_name = context_->storage->thread_table().name()[utid];
+ auto dest_args_inserter = [this, dest_tid, &dest_thread_name](
+ ArgsTracker::BoundInserter* inserter) {
+ inserter->AddArg(dest_thread_, Variadic::Integer(dest_tid));
+ if (dest_thread_name.has_value()) {
+ inserter->AddArg(dest_name_, Variadic::String(*dest_thread_name));
+ }
+ };
+ context_->slice_tracker->AddArgs(track_id, binder_category_id_, reply_id_,
+ dest_args_inserter);
+ return context_->slice_tracker->End(ts, track_id, kNullStringId,
+ kNullStringId, args_inserter);
+ }
+ if (is_oneway) {
+ return context_->slice_tracker->Scoped(ts, track_id, binder_category_id_,
+ transaction_async_id_, 0,
+ args_inserter);
+ }
+ return context_->slice_tracker->Begin(ts, track_id, binder_category_id_,
+ transaction_slice_id_, args_inserter);
+ };
- if (expects_reply) {
- context_->slice_tracker->Begin(ts, track_id, binder_category_id_,
- transaction_slice_id_, args_inserter);
- transaction_await_rcv[transaction_id] = track_id;
- } else {
- context_->slice_tracker->Scoped(ts, track_id, binder_category_id_,
- transaction_async_id_, 0, args_inserter);
- awaiting_async_rcv_[transaction_id] = args_inserter;
- }
+ OutstandingTransaction transaction;
+ transaction.is_reply = is_reply;
+ transaction.is_oneway = is_oneway;
+ transaction.args_inserter = args_inserter;
+ transaction.send_track_id = track_id;
+ transaction.send_slice_id = insert_slice();
+ outstanding_transactions_.Insert(transaction_id, std::move(transaction));
}
void BinderTracker::TransactionReceived(int64_t ts,
uint32_t pid,
int32_t transaction_id) {
+ const OutstandingTransaction* opt_transaction =
+ outstanding_transactions_.Find(transaction_id);
+ if (!opt_transaction) {
+ // If we don't know what type of transaction it is, we don't know how to
+ // insert the slice.
+ // TODO(lalitm): maybe we should insert a dummy slice anyway - seems like
+ // a questionable idea to just ignore these completely.
+ return;
+ }
+
+ OutstandingTransaction transaction(std::move(*opt_transaction));
+ outstanding_transactions_.Erase(transaction_id);
+
UniqueTid utid = context_->process_tracker->GetOrCreateThread(pid);
- const auto& thread_table = context_->storage->thread_table();
- StringId thread_name = thread_table.name()[utid];
TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
- if (awaiting_rcv_for_reply_.count(transaction_id) > 0) {
+
+ if (transaction.is_reply) {
+ // Simply end the slice started back when the first |expects_reply|
+ // transaction was sent.
context_->slice_tracker->End(ts, track_id);
- awaiting_rcv_for_reply_.erase(transaction_id);
return;
}
- if (transaction_await_rcv.count(transaction_id) > 0) {
- // First begin the reply slice to get its slice id.
- auto reply_slice_id = context_->slice_tracker->Begin(
+ base::Optional<SliceId> recv_slice_id;
+ if (transaction.is_oneway) {
+ recv_slice_id = context_->slice_tracker->Scoped(
+ ts, track_id, binder_category_id_, async_rcv_id_, 0,
+ std::move(transaction.args_inserter));
+ } else {
+ if (transaction.send_track_id) {
+ auto args_inserter = [this, utid,
+ pid](ArgsTracker::BoundInserter* inserter) {
+ inserter->AddArg(dest_thread_, Variadic::UnsignedInteger(pid));
+ auto dest_thread_name = context_->storage->thread_table().name()[utid];
+ if (dest_thread_name.has_value()) {
+ inserter->AddArg(dest_name_, Variadic::String(*dest_thread_name));
+ }
+ };
+ context_->slice_tracker->AddArgs(*transaction.send_track_id,
+ binder_category_id_,
+ transaction_slice_id_, args_inserter);
+ }
+ recv_slice_id = context_->slice_tracker->Begin(
ts, track_id, binder_category_id_, reply_id_);
- // Add accurate dest info to the binder transaction slice.
- auto args_inserter = [this, pid, &thread_name, &reply_slice_id](
- ArgsTracker::BoundInserter* inserter) {
- inserter->AddArg(dest_thread_, Variadic::UnsignedInteger(pid));
- inserter->AddArg(dest_name_, Variadic::String(thread_name));
- if (reply_slice_id.has_value())
- inserter->AddArg(dest_slice_id_,
- Variadic::UnsignedInteger(reply_slice_id->value));
- };
- // Add the dest args to the current transaction slice and get the slice id.
- auto transaction_slice_id = context_->slice_tracker->AddArgs(
- transaction_await_rcv[transaction_id], binder_category_id_,
- transaction_slice_id_, args_inserter);
-
- // Add the dest slice id to the reply slice that has just begun.
- auto reply_dest_inserter =
- [this, &transaction_slice_id](ArgsTracker::BoundInserter* inserter) {
- if (transaction_slice_id.has_value())
- inserter->AddArg(dest_slice_id_, Variadic::UnsignedInteger(
- transaction_slice_id.value()));
- };
- context_->slice_tracker->AddArgs(track_id, binder_category_id_, reply_id_,
- reply_dest_inserter);
- transaction_await_rcv.erase(transaction_id);
- return;
}
- if (awaiting_async_rcv_.count(transaction_id) > 0) {
- auto args = awaiting_async_rcv_[transaction_id];
- context_->slice_tracker->Scoped(ts, track_id, binder_category_id_,
- async_rcv_id_, 0, args);
- awaiting_async_rcv_.erase(transaction_id);
- return;
+ // Create a flow between the sending slice and this slice.
+ if (transaction.send_slice_id && recv_slice_id) {
+ context_->flow_tracker->InsertFlow(*transaction.send_slice_id,
+ *recv_slice_id);
}
}
@@ -209,7 +212,7 @@ void BinderTracker::Lock(int64_t ts, uint32_t pid) {
void BinderTracker::Locked(int64_t ts, uint32_t pid) {
UniqueTid utid = context_->process_tracker->GetOrCreateThread(pid);
- if (attempt_lock_.count(pid) == 0)
+ if (!attempt_lock_.Find(pid))
return;
TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
@@ -218,19 +221,19 @@ void BinderTracker::Locked(int64_t ts, uint32_t pid) {
lock_held_id_);
lock_acquired_[pid] = ts;
- attempt_lock_.erase(pid);
+ attempt_lock_.Erase(pid);
}
void BinderTracker::Unlock(int64_t ts, uint32_t pid) {
UniqueTid utid = context_->process_tracker->GetOrCreateThread(pid);
- if (lock_acquired_.count(pid) == 0)
+ if (!lock_acquired_.Find(pid))
return;
TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
context_->slice_tracker->End(ts, track_id, binder_category_id_,
lock_held_id_);
- lock_acquired_.erase(pid);
+ lock_acquired_.Erase(pid);
}
void BinderTracker::TransactionAllocBuf(int64_t ts,
diff --git a/src/trace_processor/importers/ftrace/binder_tracker.h b/src/trace_processor/importers/ftrace/binder_tracker.h
index a96816d35..aa710e3ff 100644
--- a/src/trace_processor/importers/ftrace/binder_tracker.h
+++ b/src/trace_processor/importers/ftrace/binder_tracker.h
@@ -18,9 +18,10 @@
#define SRC_TRACE_PROCESSOR_IMPORTERS_FTRACE_BINDER_TRACKER_H_
#include <stdint.h>
-#include <unordered_map>
-#include <unordered_set>
+#include "perfetto/base/flat_set.h"
+#include "perfetto/ext/base/flat_hash_map.h"
+#include "perfetto/ext/base/optional.h"
#include "src/trace_processor/importers/common/args_tracker.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/destructible.h"
@@ -50,8 +51,8 @@ class BinderTracker : public Destructible {
uint32_t tid,
int32_t transaction_id,
int32_t dest_node,
- int32_t dest_tgid,
- int32_t dest_tid,
+ uint32_t dest_tgid,
+ uint32_t dest_tid,
bool is_reply,
uint32_t flags,
StringId code);
@@ -67,15 +68,20 @@ class BinderTracker : public Destructible {
uint64_t offsets_size);
private:
- TraceProcessorContext* const context_;
- std::unordered_set<int32_t> awaiting_rcv_for_reply_;
+ struct OutstandingTransaction {
+ bool is_reply = false;
+ bool is_oneway = false;
+ SetArgsCallback args_inserter;
+ base::Optional<TrackId> send_track_id;
+ base::Optional<SliceId> send_slice_id;
+ };
- std::unordered_map<int32_t, TrackId> transaction_await_rcv;
- std::unordered_map<int32_t, SetArgsCallback> awaiting_async_rcv_;
+ TraceProcessorContext* const context_;
- std::unordered_map<uint32_t, int64_t> attempt_lock_;
+ base::FlatHashMap<int32_t, OutstandingTransaction> outstanding_transactions_;
- std::unordered_map<uint32_t, int64_t> lock_acquired_;
+ base::FlatHashMap<uint32_t, int64_t> attempt_lock_;
+ base::FlatHashMap<uint32_t, int64_t> lock_acquired_;
const StringId binder_category_id_;
const StringId lock_waiting_id_;
@@ -93,7 +99,6 @@ class BinderTracker : public Destructible {
const StringId flags_;
const StringId code_;
const StringId calling_tid_;
- const StringId dest_slice_id_;
const StringId data_size_;
const StringId offsets_size_;
};
diff --git a/src/trace_processor/importers/ftrace/binder_tracker_unittest.cc b/src/trace_processor/importers/ftrace/binder_tracker_unittest.cc
new file mode 100644
index 000000000..cb025201e
--- /dev/null
+++ b/src/trace_processor/importers/ftrace/binder_tracker_unittest.cc
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/importers/ftrace/binder_tracker.h"
+
+#include "perfetto/base/logging.h"
+#include "src/trace_processor/importers/common/args_tracker.h"
+#include "src/trace_processor/importers/common/event_tracker.h"
+#include "src/trace_processor/importers/common/flow_tracker.h"
+#include "src/trace_processor/importers/common/process_tracker.h"
+#include "src/trace_processor/importers/common/slice_tracker.h"
+#include "src/trace_processor/importers/common/slice_translation_table.h"
+#include "src/trace_processor/importers/common/track_tracker.h"
+#include "src/trace_processor/storage/trace_storage.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace trace_processor {
+namespace {
+constexpr int kOneWay = 0x01;
+
+class BinderTrackerTest : public ::testing::Test {
+ public:
+ BinderTrackerTest() {
+ context.storage.reset(new TraceStorage());
+ context.global_args_tracker.reset(new GlobalArgsTracker(&context));
+ context.args_tracker.reset(new ArgsTracker(&context));
+ context.slice_tracker.reset(new SliceTracker(&context));
+ context.slice_translation_table.reset(
+ new SliceTranslationTable(context.storage.get()));
+ context.process_tracker.reset(new ProcessTracker(&context));
+ context.track_tracker.reset(new TrackTracker(&context));
+ context.flow_tracker.reset(new FlowTracker(&context));
+ binder_tracker = BinderTracker::GetOrCreate(&context);
+ }
+
+ protected:
+ TraceProcessorContext context;
+ BinderTracker* binder_tracker;
+};
+
+TEST_F(BinderTrackerTest, RequestReply) {
+ int64_t req_ts = 100;
+ int64_t req_recv_ts = 105;
+ int64_t rep_ts = 150;
+ int64_t rep_recv_ts = 155;
+
+ uint32_t req_tid = 5;
+ uint32_t rep_tid = 10;
+
+ int32_t req_transaction_id = 1234;
+ int32_t rep_transaction_id = 5678;
+
+ binder_tracker->Transaction(req_ts, req_tid, req_transaction_id, 9, rep_tid,
+ rep_tid, false, 0, kNullStringId);
+ binder_tracker->TransactionReceived(req_recv_ts, rep_tid, req_transaction_id);
+
+ binder_tracker->Transaction(rep_ts, rep_tid, rep_transaction_id, 99, req_tid,
+ req_tid, true, 0, kNullStringId);
+ binder_tracker->TransactionReceived(rep_recv_ts, req_tid, rep_transaction_id);
+
+ const auto& thread = context.storage->thread_table();
+ const auto& track = context.storage->thread_track_table();
+ const auto& slice = context.storage->slice_table();
+ const auto& flow = context.storage->flow_table();
+ ASSERT_EQ(slice.row_count(), 2u);
+
+ auto tid_for_slice = [&](uint32_t row) {
+ TrackId track_id = slice.track_id()[row];
+ UniqueTid utid = track.utid()[*track.id().IndexOf(track_id)];
+ return thread.tid()[utid];
+ };
+
+ ASSERT_EQ(slice.ts()[0], req_ts);
+ ASSERT_EQ(slice.dur()[0], rep_recv_ts - req_ts);
+ ASSERT_EQ(tid_for_slice(0), req_tid);
+
+ ASSERT_EQ(slice.ts()[1], req_recv_ts);
+ ASSERT_EQ(slice.dur()[1], rep_ts - req_recv_ts);
+ ASSERT_EQ(tid_for_slice(1), rep_tid);
+
+ ASSERT_EQ(flow.row_count(), 1u);
+ ASSERT_EQ(flow.slice_out()[0], slice.id()[0]);
+ ASSERT_EQ(flow.slice_in()[0], slice.id()[1]);
+}
+
+TEST_F(BinderTrackerTest, Oneway) {
+ int64_t sen_ts = 100;
+ int64_t rec_ts = 150;
+
+ uint32_t sen_tid = 5;
+ uint32_t rec_tid = 10;
+
+ int32_t transaction_id = 1234;
+
+ binder_tracker->Transaction(sen_ts, sen_tid, transaction_id, 9, rec_tid,
+ rec_tid, false, kOneWay, kNullStringId);
+ binder_tracker->TransactionReceived(rec_ts, rec_tid, transaction_id);
+
+ const auto& thread = context.storage->thread_table();
+ const auto& track = context.storage->thread_track_table();
+ const auto& slice = context.storage->slice_table();
+ const auto& flow = context.storage->flow_table();
+ ASSERT_EQ(slice.row_count(), 2u);
+
+ auto tid_for_slice = [&](uint32_t row) {
+ TrackId track_id = slice.track_id()[row];
+ UniqueTid utid = track.utid()[*track.id().IndexOf(track_id)];
+ return thread.tid()[utid];
+ };
+
+ ASSERT_EQ(slice.ts()[0], sen_ts);
+ ASSERT_EQ(slice.dur()[0], 0);
+ ASSERT_EQ(tid_for_slice(0), sen_tid);
+
+ ASSERT_EQ(slice.ts()[1], rec_ts);
+ ASSERT_EQ(slice.dur()[1], 0);
+ ASSERT_EQ(tid_for_slice(1), rec_tid);
+
+ ASSERT_EQ(flow.row_count(), 1u);
+ ASSERT_EQ(flow.slice_out()[0], slice.id()[0]);
+ ASSERT_EQ(flow.slice_in()[0], slice.id()[1]);
+}
+
+} // namespace
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/ftrace/ftrace_descriptors.cc b/src/trace_processor/importers/ftrace/ftrace_descriptors.cc
index cb0d50eea..46d1546fc 100644
--- a/src/trace_processor/importers/ftrace/ftrace_descriptors.cc
+++ b/src/trace_processor/importers/ftrace/ftrace_descriptors.cc
@@ -24,7 +24,7 @@ namespace perfetto {
namespace trace_processor {
namespace {
-std::array<MessageDescriptor, 359> descriptors{{
+std::array<MessageDescriptor, 419> descriptors{{
{nullptr, 0, {}},
{nullptr, 0, {}},
{nullptr, 0, {}},
@@ -446,11 +446,12 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"mm_vmscan_kswapd_wake",
- 2,
+ 3,
{
{},
{"nid", ProtoSchemaType::kInt32},
{"order", ProtoSchemaType::kInt32},
+ {"zid", ProtoSchemaType::kInt32},
},
},
{
@@ -529,10 +530,11 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"workqueue_execute_end",
- 1,
+ 2,
{
{},
{"work", ProtoSchemaType::kUint64},
+ {"function", ProtoSchemaType::kUint64},
},
},
{
@@ -617,7 +619,7 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"cgroup_attach_task",
- 5,
+ 7,
{
{},
{"dst_root", ProtoSchemaType::kInt32},
@@ -625,16 +627,20 @@ std::array<MessageDescriptor, 359> descriptors{{
{"pid", ProtoSchemaType::kInt32},
{"comm", ProtoSchemaType::kString},
{"cname", ProtoSchemaType::kString},
+ {"dst_level", ProtoSchemaType::kInt32},
+ {"dst_path", ProtoSchemaType::kString},
},
},
{
"cgroup_mkdir",
- 3,
+ 5,
{
{},
{"root", ProtoSchemaType::kInt32},
{"id", ProtoSchemaType::kInt32},
{"cname", ProtoSchemaType::kString},
+ {"level", ProtoSchemaType::kInt32},
+ {"path", ProtoSchemaType::kString},
},
},
{
@@ -649,17 +655,19 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"cgroup_rmdir",
- 3,
+ 5,
{
{},
{"root", ProtoSchemaType::kInt32},
{"id", ProtoSchemaType::kInt32},
{"cname", ProtoSchemaType::kString},
+ {"level", ProtoSchemaType::kInt32},
+ {"path", ProtoSchemaType::kString},
},
},
{
"cgroup_transfer_tasks",
- 5,
+ 7,
{
{},
{"dst_root", ProtoSchemaType::kInt32},
@@ -667,6 +675,8 @@ std::array<MessageDescriptor, 359> descriptors{{
{"pid", ProtoSchemaType::kInt32},
{"comm", ProtoSchemaType::kString},
{"cname", ProtoSchemaType::kString},
+ {"dst_level", ProtoSchemaType::kInt32},
+ {"dst_path", ProtoSchemaType::kString},
},
},
{
@@ -681,22 +691,26 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"cgroup_release",
- 3,
+ 5,
{
{},
{"root", ProtoSchemaType::kInt32},
{"id", ProtoSchemaType::kInt32},
{"cname", ProtoSchemaType::kString},
+ {"level", ProtoSchemaType::kInt32},
+ {"path", ProtoSchemaType::kString},
},
},
{
"cgroup_rename",
- 3,
+ 5,
{
{},
{"root", ProtoSchemaType::kInt32},
{"id", ProtoSchemaType::kInt32},
{"cname", ProtoSchemaType::kString},
+ {"level", ProtoSchemaType::kInt32},
+ {"path", ProtoSchemaType::kString},
},
},
{
@@ -1092,12 +1106,13 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"mm_compaction_kcompactd_wake",
- 3,
+ 4,
{
{},
{"nid", ProtoSchemaType::kInt32},
{"order", ProtoSchemaType::kInt32},
{"classzone_idx", ProtoSchemaType::kUint32},
+ {"highest_zoneidx", ProtoSchemaType::kUint32},
},
},
{
@@ -1122,22 +1137,24 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"mm_compaction_try_to_compact_pages",
- 3,
+ 4,
{
{},
{"order", ProtoSchemaType::kInt32},
{"gfp_mask", ProtoSchemaType::kUint32},
{"mode", ProtoSchemaType::kUint32},
+ {"prio", ProtoSchemaType::kInt32},
},
},
{
"mm_compaction_wakeup_kcompactd",
- 3,
+ 4,
{
{},
{"nid", ProtoSchemaType::kInt32},
{"order", ProtoSchemaType::kInt32},
{"classzone_idx", ProtoSchemaType::kUint32},
+ {"highest_zoneidx", ProtoSchemaType::kUint32},
},
},
{
@@ -1280,7 +1297,7 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"block_rq_complete",
- 6,
+ 7,
{
{},
{"dev", ProtoSchemaType::kUint64},
@@ -1289,6 +1306,7 @@ std::array<MessageDescriptor, 359> descriptors{{
{"errors", ProtoSchemaType::kInt32},
{"rwbs", ProtoSchemaType::kString},
{"cmd", ProtoSchemaType::kString},
+ {"error", ProtoSchemaType::kInt32},
},
},
{
@@ -1548,11 +1566,13 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"ext4_discard_preallocations",
- 2,
+ 4,
{
{},
{"dev", ProtoSchemaType::kUint64},
{"ino", ProtoSchemaType::kUint64},
+ {"len", ProtoSchemaType::kUint32},
+ {"needed", ProtoSchemaType::kUint32},
},
},
{
@@ -1822,7 +1842,7 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"ext4_ext_remove_space_done",
- 7,
+ 10,
{
{},
{"dev", ProtoSchemaType::kUint64},
@@ -1832,6 +1852,9 @@ std::array<MessageDescriptor, 359> descriptors{{
{"depth", ProtoSchemaType::kInt32},
{"partial", ProtoSchemaType::kInt64},
{"eh_entries", ProtoSchemaType::kUint32},
+ {"pc_lblk", ProtoSchemaType::kUint32},
+ {"pc_pclu", ProtoSchemaType::kUint64},
+ {"pc_state", ProtoSchemaType::kInt32},
},
},
{
@@ -1846,7 +1869,7 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"ext4_ext_rm_leaf",
- 7,
+ 10,
{
{},
{"dev", ProtoSchemaType::kUint64},
@@ -1856,6 +1879,9 @@ std::array<MessageDescriptor, 359> descriptors{{
{"ee_lblk", ProtoSchemaType::kUint32},
{"ee_pblk", ProtoSchemaType::kUint64},
{"ee_len", ProtoSchemaType::kInt32},
+ {"pc_lblk", ProtoSchemaType::kUint32},
+ {"pc_pclu", ProtoSchemaType::kUint64},
+ {"pc_state", ProtoSchemaType::kInt32},
},
},
{
@@ -2023,7 +2049,7 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"ext4_journal_start",
- 5,
+ 6,
{
{},
{"dev", ProtoSchemaType::kUint64},
@@ -2031,6 +2057,7 @@ std::array<MessageDescriptor, 359> descriptors{{
{"blocks", ProtoSchemaType::kInt32},
{"rsv_blocks", ProtoSchemaType::kInt32},
{"nblocks", ProtoSchemaType::kInt32},
+ {"revoke_creds", ProtoSchemaType::kInt32},
},
},
{
@@ -2262,11 +2289,12 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"ext4_read_block_bitmap_load",
- 2,
+ 3,
{
{},
{"dev", ProtoSchemaType::kUint64},
{"group", ProtoSchemaType::kUint32},
+ {"prefetch", ProtoSchemaType::kUint32},
},
},
{
@@ -2291,7 +2319,7 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"ext4_remove_blocks",
- 8,
+ 11,
{
{},
{"dev", ProtoSchemaType::kUint64},
@@ -2302,6 +2330,9 @@ std::array<MessageDescriptor, 359> descriptors{{
{"ee_pblk", ProtoSchemaType::kUint64},
{"ee_lblk", ProtoSchemaType::kUint32},
{"ee_len", ProtoSchemaType::kUint32},
+ {"pc_lblk", ProtoSchemaType::kUint32},
+ {"pc_pclu", ProtoSchemaType::kUint64},
+ {"pc_state", ProtoSchemaType::kInt32},
},
},
{
@@ -2632,7 +2663,7 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"f2fs_get_victim",
- 10,
+ 11,
{
{},
{"dev", ProtoSchemaType::kUint64},
@@ -2645,6 +2676,7 @@ std::array<MessageDescriptor, 359> descriptors{{
{"pre_victim", ProtoSchemaType::kUint32},
{"prefree", ProtoSchemaType::kUint32},
{"free", ProtoSchemaType::kUint32},
+ {"cost", ProtoSchemaType::kUint32},
},
},
{
@@ -2684,7 +2716,7 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"f2fs_readpage",
- 5,
+ 8,
{
{},
{"dev", ProtoSchemaType::kUint64},
@@ -2692,6 +2724,9 @@ std::array<MessageDescriptor, 359> descriptors{{
{"index", ProtoSchemaType::kUint64},
{"blkaddr", ProtoSchemaType::kUint64},
{"type", ProtoSchemaType::kInt32},
+ {"dir", ProtoSchemaType::kInt32},
+ {"dirty", ProtoSchemaType::kInt32},
+ {"uptodate", ProtoSchemaType::kInt32},
},
},
{
@@ -2706,7 +2741,7 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"f2fs_set_page_dirty",
- 6,
+ 7,
{
{},
{"dev", ProtoSchemaType::kUint64},
@@ -2715,6 +2750,7 @@ std::array<MessageDescriptor, 359> descriptors{{
{"dir", ProtoSchemaType::kInt32},
{"index", ProtoSchemaType::kUint64},
{"dirty", ProtoSchemaType::kInt32},
+ {"uptodate", ProtoSchemaType::kInt32},
},
},
{
@@ -2746,7 +2782,7 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"f2fs_sync_file_exit",
- 5,
+ 6,
{
{},
{"dev", ProtoSchemaType::kUint64},
@@ -2754,6 +2790,7 @@ std::array<MessageDescriptor, 359> descriptors{{
{"need_cp", ProtoSchemaType::kUint32},
{"datasync", ProtoSchemaType::kInt32},
{"ret", ProtoSchemaType::kInt32},
+ {"cp_reason", ProtoSchemaType::kInt32},
},
},
{
@@ -2905,7 +2942,7 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"f2fs_vm_page_mkwrite",
- 6,
+ 7,
{
{},
{"dev", ProtoSchemaType::kUint64},
@@ -2914,6 +2951,7 @@ std::array<MessageDescriptor, 359> descriptors{{
{"dir", ProtoSchemaType::kInt32},
{"index", ProtoSchemaType::kUint64},
{"dirty", ProtoSchemaType::kInt32},
+ {"uptodate", ProtoSchemaType::kInt32},
},
},
{
@@ -2930,12 +2968,13 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"f2fs_write_checkpoint",
- 3,
+ 4,
{
{},
{"dev", ProtoSchemaType::kUint64},
{"is_umount", ProtoSchemaType::kUint32},
{"msg", ProtoSchemaType::kString},
+ {"reason", ProtoSchemaType::kInt32},
},
},
{
@@ -3457,12 +3496,13 @@ std::array<MessageDescriptor, 359> descriptors{{
},
{
"binder_transaction_alloc_buf",
- 3,
+ 4,
{
{},
{"data_size", ProtoSchemaType::kUint64},
{"debug_id", ProtoSchemaType::kInt32},
{"offsets_size", ProtoSchemaType::kUint64},
+ {"extra_buffers_size", ProtoSchemaType::kUint64},
},
},
{
@@ -3841,6 +3881,630 @@ std::array<MessageDescriptor, 359> descriptors{{
{"ib_quota", ProtoSchemaType::kUint64},
},
},
+ {
+ "rss_stat_throttled",
+ 4,
+ {
+ {},
+ {"curr", ProtoSchemaType::kUint32},
+ {"member", ProtoSchemaType::kInt32},
+ {"mm_id", ProtoSchemaType::kUint32},
+ {"size", ProtoSchemaType::kInt64},
+ },
+ },
+ {
+ "netif_receive_skb",
+ 3,
+ {
+ {},
+ {"len", ProtoSchemaType::kUint32},
+ {"name", ProtoSchemaType::kString},
+ {"skbaddr", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "net_dev_xmit",
+ 4,
+ {
+ {},
+ {"len", ProtoSchemaType::kUint32},
+ {"name", ProtoSchemaType::kString},
+ {"rc", ProtoSchemaType::kInt32},
+ {"skbaddr", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "inet_sock_set_state",
+ 9,
+ {
+ {},
+ {"daddr", ProtoSchemaType::kUint32},
+ {"dport", ProtoSchemaType::kUint32},
+ {"family", ProtoSchemaType::kUint32},
+ {"newstate", ProtoSchemaType::kInt32},
+ {"oldstate", ProtoSchemaType::kInt32},
+ {"protocol", ProtoSchemaType::kUint32},
+ {"saddr", ProtoSchemaType::kUint32},
+ {"skaddr", ProtoSchemaType::kUint64},
+ {"sport", ProtoSchemaType::kUint32},
+ },
+ },
+ {
+ "tcp_retransmit_skb",
+ 7,
+ {
+ {},
+ {"daddr", ProtoSchemaType::kUint32},
+ {"dport", ProtoSchemaType::kUint32},
+ {"saddr", ProtoSchemaType::kUint32},
+ {"skaddr", ProtoSchemaType::kUint64},
+ {"skbaddr", ProtoSchemaType::kUint64},
+ {"sport", ProtoSchemaType::kUint32},
+ {"state", ProtoSchemaType::kInt32},
+ },
+ },
+ {
+ "cros_ec_sensorhub_data",
+ 6,
+ {
+ {},
+ {"current_time", ProtoSchemaType::kInt64},
+ {"current_timestamp", ProtoSchemaType::kInt64},
+ {"delta", ProtoSchemaType::kInt64},
+ {"ec_fifo_timestamp", ProtoSchemaType::kUint32},
+ {"ec_sensor_num", ProtoSchemaType::kUint32},
+ {"fifo_timestamp", ProtoSchemaType::kInt64},
+ },
+ },
+ {
+ "napi_gro_receive_entry",
+ 19,
+ {
+ {},
+ {"data_len", ProtoSchemaType::kUint32},
+ {"gso_size", ProtoSchemaType::kUint32},
+ {"gso_type", ProtoSchemaType::kUint32},
+ {"hash", ProtoSchemaType::kUint32},
+ {"ip_summed", ProtoSchemaType::kUint32},
+ {"l4_hash", ProtoSchemaType::kUint32},
+ {"len", ProtoSchemaType::kUint32},
+ {"mac_header", ProtoSchemaType::kInt32},
+ {"mac_header_valid", ProtoSchemaType::kUint32},
+ {"name", ProtoSchemaType::kString},
+ {"napi_id", ProtoSchemaType::kUint32},
+ {"nr_frags", ProtoSchemaType::kUint32},
+ {"protocol", ProtoSchemaType::kUint32},
+ {"queue_mapping", ProtoSchemaType::kUint32},
+ {"skbaddr", ProtoSchemaType::kUint64},
+ {"truesize", ProtoSchemaType::kUint32},
+ {"vlan_proto", ProtoSchemaType::kUint32},
+ {"vlan_tagged", ProtoSchemaType::kUint32},
+ {"vlan_tci", ProtoSchemaType::kUint32},
+ },
+ },
+ {
+ "napi_gro_receive_exit",
+ 1,
+ {
+ {},
+ {"ret", ProtoSchemaType::kInt32},
+ },
+ },
+ {
+ "kfree_skb",
+ 3,
+ {
+ {},
+ {"location", ProtoSchemaType::kUint64},
+ {"protocol", ProtoSchemaType::kUint32},
+ {"skbaddr", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "kvm_access_fault",
+ 1,
+ {
+ {},
+ {"ipa", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "kvm_ack_irq",
+ 2,
+ {
+ {},
+ {"irqchip", ProtoSchemaType::kUint32},
+ {"pin", ProtoSchemaType::kUint32},
+ },
+ },
+ {
+ "kvm_age_hva",
+ 2,
+ {
+ {},
+ {"end", ProtoSchemaType::kUint64},
+ {"start", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "kvm_age_page",
+ 4,
+ {
+ {},
+ {"gfn", ProtoSchemaType::kUint64},
+ {"hva", ProtoSchemaType::kUint64},
+ {"level", ProtoSchemaType::kUint32},
+ {"referenced", ProtoSchemaType::kUint32},
+ },
+ },
+ {
+ "kvm_arm_clear_debug",
+ 1,
+ {
+ {},
+ {"guest_debug", ProtoSchemaType::kUint32},
+ },
+ },
+ {
+ "kvm_arm_set_dreg32",
+ 2,
+ {
+ {},
+ {"name", ProtoSchemaType::kString},
+ {"value", ProtoSchemaType::kUint32},
+ },
+ },
+ {
+ "kvm_arm_set_regset",
+ 2,
+ {
+ {},
+ {"len", ProtoSchemaType::kInt32},
+ {"name", ProtoSchemaType::kString},
+ },
+ },
+ {
+ "kvm_arm_setup_debug",
+ 2,
+ {
+ {},
+ {"guest_debug", ProtoSchemaType::kUint32},
+ {"vcpu", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "kvm_entry",
+ 1,
+ {
+ {},
+ {"vcpu_pc", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "kvm_exit",
+ 3,
+ {
+ {},
+ {"esr_ec", ProtoSchemaType::kUint32},
+ {"ret", ProtoSchemaType::kInt32},
+ {"vcpu_pc", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "kvm_fpu",
+ 1,
+ {
+ {},
+ {"load", ProtoSchemaType::kUint32},
+ },
+ },
+ {
+ "kvm_get_timer_map",
+ 4,
+ {
+ {},
+ {"direct_ptimer", ProtoSchemaType::kInt32},
+ {"direct_vtimer", ProtoSchemaType::kInt32},
+ {"emul_ptimer", ProtoSchemaType::kInt32},
+ {"vcpu_id", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "kvm_guest_fault",
+ 4,
+ {
+ {},
+ {"hsr", ProtoSchemaType::kUint64},
+ {"hxfar", ProtoSchemaType::kUint64},
+ {"ipa", ProtoSchemaType::kUint64},
+ {"vcpu_pc", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "kvm_handle_sys_reg",
+ 1,
+ {
+ {},
+ {"hsr", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "kvm_hvc_arm64",
+ 3,
+ {
+ {},
+ {"imm", ProtoSchemaType::kUint64},
+ {"r0", ProtoSchemaType::kUint64},
+ {"vcpu_pc", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "kvm_irq_line",
+ 4,
+ {
+ {},
+ {"irq_num", ProtoSchemaType::kInt32},
+ {"level", ProtoSchemaType::kInt32},
+ {"type", ProtoSchemaType::kUint32},
+ {"vcpu_idx", ProtoSchemaType::kInt32},
+ },
+ },
+ {
+ "kvm_mmio",
+ 4,
+ {
+ {},
+ {"gpa", ProtoSchemaType::kUint64},
+ {"len", ProtoSchemaType::kUint32},
+ {"type", ProtoSchemaType::kUint32},
+ {"val", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "kvm_mmio_emulate",
+ 3,
+ {
+ {},
+ {"cpsr", ProtoSchemaType::kUint64},
+ {"instr", ProtoSchemaType::kUint64},
+ {"vcpu_pc", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "kvm_set_guest_debug",
+ 2,
+ {
+ {},
+ {"guest_debug", ProtoSchemaType::kUint32},
+ {"vcpu", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "kvm_set_irq",
+ 3,
+ {
+ {},
+ {"gsi", ProtoSchemaType::kUint32},
+ {"irq_source_id", ProtoSchemaType::kInt32},
+ {"level", ProtoSchemaType::kInt32},
+ },
+ },
+ {
+ "kvm_set_spte_hva",
+ 1,
+ {
+ {},
+ {"hva", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "kvm_set_way_flush",
+ 2,
+ {
+ {},
+ {"cache", ProtoSchemaType::kUint32},
+ {"vcpu_pc", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "kvm_sys_access",
+ 8,
+ {
+ {},
+ {"CRm", ProtoSchemaType::kUint32},
+ {"CRn", ProtoSchemaType::kUint32},
+ {"Op0", ProtoSchemaType::kUint32},
+ {"Op1", ProtoSchemaType::kUint32},
+ {"Op2", ProtoSchemaType::kUint32},
+ {"is_write", ProtoSchemaType::kUint32},
+ {"name", ProtoSchemaType::kString},
+ {"vcpu_pc", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "kvm_test_age_hva",
+ 1,
+ {
+ {},
+ {"hva", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "kvm_timer_emulate",
+ 2,
+ {
+ {},
+ {"should_fire", ProtoSchemaType::kUint32},
+ {"timer_idx", ProtoSchemaType::kInt32},
+ },
+ },
+ {
+ "kvm_timer_hrtimer_expire",
+ 1,
+ {
+ {},
+ {"timer_idx", ProtoSchemaType::kInt32},
+ },
+ },
+ {
+ "kvm_timer_restore_state",
+ 3,
+ {
+ {},
+ {"ctl", ProtoSchemaType::kUint64},
+ {"cval", ProtoSchemaType::kUint64},
+ {"timer_idx", ProtoSchemaType::kInt32},
+ },
+ },
+ {
+ "kvm_timer_save_state",
+ 3,
+ {
+ {},
+ {"ctl", ProtoSchemaType::kUint64},
+ {"cval", ProtoSchemaType::kUint64},
+ {"timer_idx", ProtoSchemaType::kInt32},
+ },
+ },
+ {
+ "kvm_timer_update_irq",
+ 3,
+ {
+ {},
+ {"irq", ProtoSchemaType::kUint32},
+ {"level", ProtoSchemaType::kInt32},
+ {"vcpu_id", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "kvm_toggle_cache",
+ 3,
+ {
+ {},
+ {"now", ProtoSchemaType::kUint32},
+ {"vcpu_pc", ProtoSchemaType::kUint64},
+ {"was", ProtoSchemaType::kUint32},
+ },
+ },
+ {
+ "kvm_unmap_hva_range",
+ 2,
+ {
+ {},
+ {"end", ProtoSchemaType::kUint64},
+ {"start", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "kvm_userspace_exit",
+ 1,
+ {
+ {},
+ {"reason", ProtoSchemaType::kUint32},
+ },
+ },
+ {
+ "kvm_vcpu_wakeup",
+ 3,
+ {
+ {},
+ {"ns", ProtoSchemaType::kUint64},
+ {"valid", ProtoSchemaType::kUint32},
+ {"waited", ProtoSchemaType::kUint32},
+ },
+ },
+ {
+ "kvm_wfx_arm64",
+ 2,
+ {
+ {},
+ {"is_wfe", ProtoSchemaType::kUint32},
+ {"vcpu_pc", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "trap_reg",
+ 4,
+ {
+ {},
+ {"fn", ProtoSchemaType::kString},
+ {"is_write", ProtoSchemaType::kUint32},
+ {"reg", ProtoSchemaType::kInt32},
+ {"write_value", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "vgic_update_irq_pending",
+ 3,
+ {
+ {},
+ {"irq", ProtoSchemaType::kUint32},
+ {"level", ProtoSchemaType::kUint32},
+ {"vcpu_id", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "wakeup_source_activate",
+ 2,
+ {
+ {},
+ {"name", ProtoSchemaType::kString},
+ {"state", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "wakeup_source_deactivate",
+ 2,
+ {
+ {},
+ {"name", ProtoSchemaType::kString},
+ {"state", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "ufshcd_command",
+ 10,
+ {
+ {},
+ {"dev_name", ProtoSchemaType::kString},
+ {"doorbell", ProtoSchemaType::kUint32},
+ {"intr", ProtoSchemaType::kUint32},
+ {"lba", ProtoSchemaType::kUint64},
+ {"opcode", ProtoSchemaType::kUint32},
+ {"str", ProtoSchemaType::kString},
+ {"tag", ProtoSchemaType::kUint32},
+ {"transfer_len", ProtoSchemaType::kInt32},
+ {"group_id", ProtoSchemaType::kUint32},
+ {"str_t", ProtoSchemaType::kUint32},
+ },
+ },
+ {
+ "ufshcd_clk_gating",
+ 2,
+ {
+ {},
+ {"dev_name", ProtoSchemaType::kString},
+ {"state", ProtoSchemaType::kInt32},
+ },
+ },
+ {
+ "console",
+ 1,
+ {
+ {},
+ {"msg", ProtoSchemaType::kString},
+ },
+ },
+ {
+ "drm_vblank_event",
+ 4,
+ {
+ {},
+ {"crtc", ProtoSchemaType::kInt32},
+ {"high_prec", ProtoSchemaType::kUint32},
+ {"seq", ProtoSchemaType::kUint32},
+ {"time", ProtoSchemaType::kInt64},
+ },
+ },
+ {
+ "drm_vblank_event_delivered",
+ 3,
+ {
+ {},
+ {"crtc", ProtoSchemaType::kInt32},
+ {"file", ProtoSchemaType::kUint64},
+ {"seq", ProtoSchemaType::kUint32},
+ },
+ },
+ {
+ "drm_sched_job",
+ 6,
+ {
+ {},
+ {"entity", ProtoSchemaType::kUint64},
+ {"fence", ProtoSchemaType::kUint64},
+ {"hw_job_count", ProtoSchemaType::kInt32},
+ {"id", ProtoSchemaType::kUint64},
+ {"job_count", ProtoSchemaType::kUint32},
+ {"name", ProtoSchemaType::kString},
+ },
+ },
+ {
+ "drm_run_job",
+ 6,
+ {
+ {},
+ {"entity", ProtoSchemaType::kUint64},
+ {"fence", ProtoSchemaType::kUint64},
+ {"hw_job_count", ProtoSchemaType::kInt32},
+ {"id", ProtoSchemaType::kUint64},
+ {"job_count", ProtoSchemaType::kUint32},
+ {"name", ProtoSchemaType::kString},
+ },
+ },
+ {
+ "drm_sched_process_job",
+ 1,
+ {
+ {},
+ {"fence", ProtoSchemaType::kUint64},
+ },
+ },
+ {
+ "dma_fence_init",
+ 4,
+ {
+ {},
+ {"context", ProtoSchemaType::kUint32},
+ {"driver", ProtoSchemaType::kString},
+ {"seqno", ProtoSchemaType::kUint32},
+ {"timeline", ProtoSchemaType::kString},
+ },
+ },
+ {
+ "dma_fence_emit",
+ 4,
+ {
+ {},
+ {"context", ProtoSchemaType::kUint32},
+ {"driver", ProtoSchemaType::kString},
+ {"seqno", ProtoSchemaType::kUint32},
+ {"timeline", ProtoSchemaType::kString},
+ },
+ },
+ {
+ "dma_fence_signaled",
+ 4,
+ {
+ {},
+ {"context", ProtoSchemaType::kUint32},
+ {"driver", ProtoSchemaType::kString},
+ {"seqno", ProtoSchemaType::kUint32},
+ {"timeline", ProtoSchemaType::kString},
+ },
+ },
+ {
+ "dma_fence_wait_start",
+ 4,
+ {
+ {},
+ {"context", ProtoSchemaType::kUint32},
+ {"driver", ProtoSchemaType::kString},
+ {"seqno", ProtoSchemaType::kUint32},
+ {"timeline", ProtoSchemaType::kString},
+ },
+ },
+ {
+ "dma_fence_wait_end",
+ 4,
+ {
+ {},
+ {"context", ProtoSchemaType::kUint32},
+ {"driver", ProtoSchemaType::kString},
+ {"seqno", ProtoSchemaType::kUint32},
+ {"timeline", ProtoSchemaType::kString},
+ },
+ },
}};
} // namespace
diff --git a/src/trace_processor/importers/ftrace/ftrace_module_impl.cc b/src/trace_processor/importers/ftrace/ftrace_module_impl.cc
index f86bdc5ee..d7579ece9 100644
--- a/src/trace_processor/importers/ftrace/ftrace_module_impl.cc
+++ b/src/trace_processor/importers/ftrace/ftrace_module_impl.cc
@@ -16,7 +16,7 @@
#include "src/trace_processor/importers/ftrace/ftrace_module_impl.h"
#include "perfetto/base/build_config.h"
-#include "src/trace_processor/importers/common/trace_blob_view.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
#include "src/trace_processor/importers/ftrace/ftrace_parser.h"
#include "src/trace_processor/importers/ftrace/ftrace_tokenizer.h"
#include "src/trace_processor/timestamped_trace_piece.h"
@@ -42,10 +42,9 @@ ModuleResult FtraceModuleImpl::TokenizePacket(
uint32_t field_id) {
if (field_id == TracePacket::kFtraceEventsFieldNumber) {
auto ftrace_field = decoder.ftrace_events();
- const size_t fld_off = packet->offset_of(ftrace_field.data);
- tokenizer_.TokenizeFtraceBundle(packet->slice(fld_off, ftrace_field.size),
- seq_state);
- return ModuleResult::Handled();
+ return tokenizer_.TokenizeFtraceBundle(
+ packet->slice(ftrace_field.data, ftrace_field.size), seq_state,
+ decoder.trusted_packet_sequence_id());
}
return ModuleResult::Ignored();
}
diff --git a/src/trace_processor/importers/ftrace/ftrace_module_impl.h b/src/trace_processor/importers/ftrace/ftrace_module_impl.h
index 2ba4d6ba2..da6ffd99e 100644
--- a/src/trace_processor/importers/ftrace/ftrace_module_impl.h
+++ b/src/trace_processor/importers/ftrace/ftrace_module_impl.h
@@ -18,7 +18,6 @@
#define SRC_TRACE_PROCESSOR_IMPORTERS_FTRACE_FTRACE_MODULE_IMPL_H_
#include "perfetto/base/build_config.h"
-#include "src/trace_processor/importers/common/trace_blob_view.h"
#include "src/trace_processor/importers/ftrace/ftrace_module.h"
#include "src/trace_processor/importers/ftrace/ftrace_parser.h"
#include "src/trace_processor/importers/ftrace/ftrace_tokenizer.h"
@@ -30,6 +29,8 @@
namespace perfetto {
namespace trace_processor {
+class TraceBlobView;
+
class FtraceModuleImpl : public FtraceModule {
public:
FtraceModuleImpl(TraceProcessorContext* context);
diff --git a/src/trace_processor/importers/ftrace/ftrace_parser.cc b/src/trace_processor/importers/ftrace/ftrace_parser.cc
index 654b332fd..40783197e 100644
--- a/src/trace_processor/importers/ftrace/ftrace_parser.cc
+++ b/src/trace_processor/importers/ftrace/ftrace_parser.cc
@@ -22,15 +22,18 @@
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/importers/ftrace/binder_tracker.h"
#include "src/trace_processor/importers/proto/async_track_set_tracker.h"
+#include "src/trace_processor/importers/proto/metadata_tracker.h"
#include "src/trace_processor/importers/syscalls/syscall_tracker.h"
#include "src/trace_processor/importers/systrace/systrace_parser.h"
#include "src/trace_processor/storage/stats.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/softirq_action.h"
+#include "src/trace_processor/types/tcp_state.h"
#include "protos/perfetto/common/gpu_counter_descriptor.pbzero.h"
#include "protos/perfetto/trace/ftrace/binder.pbzero.h"
#include "protos/perfetto/trace/ftrace/cpuhp.pbzero.h"
+#include "protos/perfetto/trace/ftrace/cros_ec.pbzero.h"
#include "protos/perfetto/trace/ftrace/dmabuf_heap.pbzero.h"
#include "protos/perfetto/trace/ftrace/dpu.pbzero.h"
#include "protos/perfetto/trace/ftrace/fastrpc.pbzero.h"
@@ -46,6 +49,7 @@
#include "protos/perfetto/trace/ftrace/lowmemorykiller.pbzero.h"
#include "protos/perfetto/trace/ftrace/mali.pbzero.h"
#include "protos/perfetto/trace/ftrace/mm_event.pbzero.h"
+#include "protos/perfetto/trace/ftrace/net.pbzero.h"
#include "protos/perfetto/trace/ftrace/oom.pbzero.h"
#include "protos/perfetto/trace/ftrace/power.pbzero.h"
#include "protos/perfetto/trace/ftrace/raw_syscalls.pbzero.h"
@@ -53,9 +57,14 @@
#include "protos/perfetto/trace/ftrace/scm.pbzero.h"
#include "protos/perfetto/trace/ftrace/sde.pbzero.h"
#include "protos/perfetto/trace/ftrace/signal.pbzero.h"
+#include "protos/perfetto/trace/ftrace/skb.pbzero.h"
+#include "protos/perfetto/trace/ftrace/sock.pbzero.h"
#include "protos/perfetto/trace/ftrace/systrace.pbzero.h"
#include "protos/perfetto/trace/ftrace/task.pbzero.h"
+#include "protos/perfetto/trace/ftrace/tcp.pbzero.h"
#include "protos/perfetto/trace/ftrace/thermal.pbzero.h"
+#include "protos/perfetto/trace/ftrace/ufs.pbzero.h"
+#include "protos/perfetto/trace/ftrace/vmscan.pbzero.h"
#include "protos/perfetto/trace/ftrace/workqueue.pbzero.h"
#include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
@@ -102,9 +111,13 @@ FtraceParser::FtraceParser(TraceProcessorContext* context)
rss_stat_tracker_(context),
sched_wakeup_name_id_(context->storage->InternString("sched_wakeup")),
sched_waking_name_id_(context->storage->InternString("sched_waking")),
+ cpu_id_(context->storage->InternString("cpu")),
cpu_freq_name_id_(context->storage->InternString("cpufreq")),
gpu_freq_name_id_(context->storage->InternString("gpufreq")),
cpu_idle_name_id_(context->storage->InternString("cpuidle")),
+ suspend_resume_name_id_(
+ context->storage->InternString("Suspend/Resume Latency")),
+ kfree_skb_name_id_(context->storage->InternString("Kfree Skb IP Prot")),
ion_total_id_(context->storage->InternString("mem.ion")),
ion_change_id_(context->storage->InternString("mem.ion_change")),
ion_buffer_id_(context->storage->InternString("mem.ion_buffer")),
@@ -124,7 +137,22 @@ FtraceParser::FtraceParser(TraceProcessorContext* context)
oom_kill_id_(context_->storage->InternString("mem.oom_kill")),
workqueue_id_(context_->storage->InternString("workqueue")),
irq_id_(context_->storage->InternString("irq")),
+ tcp_state_id_(context_->storage->InternString("tcp_state")),
+ tcp_event_id_(context_->storage->InternString("tcp_event")),
+ protocol_arg_id_(context_->storage->InternString("protocol")),
+ napi_gro_id_(context_->storage->InternString("napi_gro")),
+ tcp_retransmited_name_id_(
+ context_->storage->InternString("TCP Retransmit Skb")),
ret_arg_id_(context_->storage->InternString("ret")),
+ len_arg_id_(context->storage->InternString("len")),
+ direct_reclaim_nr_reclaimed_id_(
+ context->storage->InternString("direct_reclaim_nr_reclaimed")),
+ direct_reclaim_order_id_(
+ context->storage->InternString("direct_reclaim_order")),
+ direct_reclaim_may_writepage_id_(
+ context->storage->InternString("direct_reclaim_may_writepage")),
+ direct_reclaim_gfp_flags_id_(
+ context->storage->InternString("direct_reclaim_gfp_flags")),
vec_arg_id_(context->storage->InternString("vec")),
gpu_mem_total_name_id_(context->storage->InternString("GPU Memory")),
gpu_mem_total_unit_id_(context->storage->InternString(
@@ -136,7 +164,13 @@ FtraceParser::FtraceParser(TraceProcessorContext* context)
sched_blocked_reason_id_(
context->storage->InternString("sched_blocked_reason")),
io_wait_id_(context->storage->InternString("io_wait")),
- function_id_(context->storage->InternString("function")) {
+ function_id_(context->storage->InternString("function")),
+ waker_utid_id_(context->storage->InternString("waker_utid")),
+ cros_ec_arg_num_id_(context->storage->InternString("ec_num")),
+ cros_ec_arg_ec_id_(context->storage->InternString("ec_delta")),
+ cros_ec_arg_sample_ts_id_(context->storage->InternString("sample_ts")),
+ ufs_clkgating_id_(context->storage->InternString("UFS clkgating (OFF/REQ_OFF/REQ_ON/ON)")),
+ ufs_command_count_id_(context->storage->InternString("UFS Command Count")) {
// Build the lookup table for the strings inside ftrace events (e.g. the
// name of ftrace event fields and the names of their args).
for (size_t i = 0; i < GetDescriptorsSize(); i++) {
@@ -212,8 +246,14 @@ FtraceParser::FtraceParser(TraceProcessorContext* context)
void FtraceParser::ParseFtraceStats(ConstBytes blob) {
protos::pbzero::FtraceStats::Decoder evt(blob.data, blob.size);
- size_t phase =
- evt.phase() == protos::pbzero::FtraceStats_Phase_END_OF_TRACE ? 1 : 0;
+ bool is_start =
+ evt.phase() == protos::pbzero::FtraceStats_Phase_START_OF_TRACE;
+ bool is_end = evt.phase() == protos::pbzero::FtraceStats_Phase_END_OF_TRACE;
+ if (!is_start && !is_end) {
+ PERFETTO_ELOG("Ignoring unknown ftrace stats phase %d", evt.phase());
+ return;
+ }
+ size_t phase = is_end ? 1 : 0;
// This code relies on the fact that each ftrace_cpu_XXX_end event is
// just after the corresponding ftrace_cpu_XXX_begin event.
@@ -227,15 +267,81 @@ void FtraceParser::ParseFtraceStats(ConstBytes blob) {
for (auto it = evt.cpu_stats(); it; ++it) {
protos::pbzero::FtraceCpuStats::Decoder cpu_stats(*it);
int cpu = static_cast<int>(cpu_stats.cpu());
+
+ int64_t entries = static_cast<int64_t>(cpu_stats.entries());
+ int64_t overrun = static_cast<int64_t>(cpu_stats.overrun());
+ int64_t commit_overrun = static_cast<int64_t>(cpu_stats.commit_overrun());
+ int64_t bytes_read = static_cast<int64_t>(cpu_stats.bytes_read());
+ int64_t dropped_events = static_cast<int64_t>(cpu_stats.dropped_events());
+ int64_t read_events = static_cast<int64_t>(cpu_stats.read_events());
+ int64_t now_ts = static_cast<int64_t>(cpu_stats.now_ts() * 1e9);
+
storage->SetIndexedStats(stats::ftrace_cpu_entries_begin + phase, cpu,
- static_cast<int64_t>(cpu_stats.entries()));
+ entries);
storage->SetIndexedStats(stats::ftrace_cpu_overrun_begin + phase, cpu,
- static_cast<int64_t>(cpu_stats.overrun()));
+ overrun);
storage->SetIndexedStats(stats::ftrace_cpu_commit_overrun_begin + phase,
- cpu,
- static_cast<int64_t>(cpu_stats.commit_overrun()));
+ cpu, commit_overrun);
storage->SetIndexedStats(stats::ftrace_cpu_bytes_read_begin + phase, cpu,
- static_cast<int64_t>(cpu_stats.bytes_read()));
+ bytes_read);
+ storage->SetIndexedStats(stats::ftrace_cpu_dropped_events_begin + phase,
+ cpu, dropped_events);
+ storage->SetIndexedStats(stats::ftrace_cpu_read_events_begin + phase, cpu,
+ read_events);
+ storage->SetIndexedStats(stats::ftrace_cpu_now_ts_begin + phase, cpu,
+ now_ts);
+
+ if (is_end) {
+ auto opt_entries_begin =
+ storage->GetIndexedStats(stats::ftrace_cpu_entries_begin, cpu);
+ if (opt_entries_begin) {
+ int64_t delta_entries = entries - opt_entries_begin.value();
+ storage->SetIndexedStats(stats::ftrace_cpu_entries_delta, cpu,
+ delta_entries);
+ }
+
+ auto opt_overrun_begin =
+ storage->GetIndexedStats(stats::ftrace_cpu_overrun_begin, cpu);
+ if (opt_overrun_begin) {
+ int64_t delta_overrun = overrun - opt_overrun_begin.value();
+ storage->SetIndexedStats(stats::ftrace_cpu_overrun_delta, cpu,
+ delta_overrun);
+ }
+
+ auto opt_commit_overrun_begin =
+ storage->GetIndexedStats(stats::ftrace_cpu_commit_overrun_begin, cpu);
+ if (opt_commit_overrun_begin) {
+ int64_t delta_commit_overrun =
+ commit_overrun - opt_commit_overrun_begin.value();
+ storage->SetIndexedStats(stats::ftrace_cpu_commit_overrun_delta, cpu,
+ delta_commit_overrun);
+ }
+
+ auto opt_bytes_read_begin =
+ storage->GetIndexedStats(stats::ftrace_cpu_bytes_read_begin, cpu);
+ if (opt_bytes_read_begin) {
+ int64_t delta_bytes_read = bytes_read - opt_bytes_read_begin.value();
+ storage->SetIndexedStats(stats::ftrace_cpu_bytes_read_delta, cpu,
+ delta_bytes_read);
+ }
+
+ auto opt_dropped_events_begin =
+ storage->GetIndexedStats(stats::ftrace_cpu_dropped_events_begin, cpu);
+ if (opt_dropped_events_begin) {
+ int64_t delta_dropped_events =
+ dropped_events - opt_dropped_events_begin.value();
+ storage->SetIndexedStats(stats::ftrace_cpu_dropped_events_delta, cpu,
+ delta_dropped_events);
+ }
+
+ auto opt_read_events_begin =
+ storage->GetIndexedStats(stats::ftrace_cpu_read_events_begin, cpu);
+ if (opt_read_events_begin) {
+ int64_t delta_read_events = read_events - opt_read_events_begin.value();
+ storage->SetIndexedStats(stats::ftrace_cpu_read_events_delta, cpu,
+ delta_read_events);
+ }
+ }
// oldest_event_ts can often be set to very high values, possibly because
// of wrapping. Ensure that we are not overflowing to avoid ubsan
@@ -245,8 +351,8 @@ void FtraceParser::ParseFtraceStats(ConstBytes blob) {
// incorrect with >. std::numeric_limits<int64_t>::max() converted to
// a double is the next value representable as a double that is *larger*
// than std::numeric_limits<int64_t>::max(). All values that are
- // representable as doubles and < than that value are thus representable as
- // int64_t.
+ // representable as doubles and < than that value are thus representable
+ // as int64_t.
if (oldest_event_ts >=
static_cast<double>(std::numeric_limits<int64_t>::max())) {
storage->SetIndexedStats(stats::ftrace_cpu_oldest_event_ts_begin + phase,
@@ -255,14 +361,31 @@ void FtraceParser::ParseFtraceStats(ConstBytes blob) {
storage->SetIndexedStats(stats::ftrace_cpu_oldest_event_ts_begin + phase,
cpu, static_cast<int64_t>(oldest_event_ts));
}
+ }
- storage->SetIndexedStats(stats::ftrace_cpu_now_ts_begin + phase, cpu,
- static_cast<int64_t>(cpu_stats.now_ts() * 1e9));
- storage->SetIndexedStats(stats::ftrace_cpu_dropped_events_begin + phase,
- cpu,
- static_cast<int64_t>(cpu_stats.dropped_events()));
- storage->SetIndexedStats(stats::ftrace_cpu_read_events_begin + phase, cpu,
- static_cast<int64_t>(cpu_stats.read_events()));
+ // Compute atrace + ftrace setup errors. We do two things here:
+ // 1. We add up all the errors and put the counter in the stats table (which
+ // can hold only numerals). This will raise an orange flag in the UI.
+ // 2. We concatenate together all the errors in a string and put that in the
+ // medatata table.
+ // Both will be reported in the 'Info & stats' page in the UI.
+ if (is_start) {
+ std::string error_str;
+ for (auto it = evt.failed_ftrace_events(); it; ++it) {
+ storage->IncrementStats(stats::ftrace_setup_errors, 1);
+ error_str += "Ftrace event failed: " + it->as_std_string() + "\n";
+ }
+ for (auto it = evt.unknown_ftrace_events(); it; ++it) {
+ storage->IncrementStats(stats::ftrace_setup_errors, 1);
+ error_str += "Ftrace event unknown: " + it->as_std_string() + "\n";
+ }
+ if (evt.atrace_errors().size > 0) {
+ storage->IncrementStats(stats::ftrace_setup_errors, 1);
+ error_str += "Atrace failures: " + evt.atrace_errors().ToStdString();
+ }
+ auto error_str_id = storage->InternString(base::StringView(error_str));
+ context_->metadata_tracker->SetMetadata(metadata::ftrace_setup_errors,
+ Variadic::String(error_str_id));
}
}
@@ -359,11 +482,11 @@ util::Status FtraceParser::ParseFtraceEvent(uint32_t cpu,
break;
}
case FtraceEvent::kSchedWakeupFieldNumber: {
- ParseSchedWakeup(ts, data);
+ ParseSchedWakeup(ts, pid, data);
break;
}
case FtraceEvent::kSchedWakingFieldNumber: {
- ParseSchedWaking(ts, data);
+ ParseSchedWaking(ts, pid, data);
break;
}
case FtraceEvent::kSchedProcessFreeFieldNumber: {
@@ -390,8 +513,9 @@ util::Status FtraceParser::ParseFtraceEvent(uint32_t cpu,
ParseZero(ts, pid, data);
break;
}
+ case FtraceEvent::kRssStatThrottledFieldNumber:
case FtraceEvent::kRssStatFieldNumber: {
- rss_stat_tracker_.ParseRssStat(ts, pid, data);
+ rss_stat_tracker_.ParseRssStat(ts, fld.id(), pid, data);
break;
}
case FtraceEvent::kIonHeapGrowFieldNumber: {
@@ -498,8 +622,16 @@ util::Status FtraceParser::ParseFtraceEvent(uint32_t cpu,
ParseScmCallEnd(ts, pid, data);
break;
}
+ case FtraceEvent::kMmVmscanDirectReclaimBeginFieldNumber: {
+ ParseDirectReclaimBegin(ts, pid, data);
+ break;
+ }
+ case FtraceEvent::kMmVmscanDirectReclaimEndFieldNumber: {
+ ParseDirectReclaimEnd(ts, pid, data);
+ break;
+ }
case FtraceEvent::kWorkqueueExecuteStartFieldNumber: {
- ParseWorkqueueExecuteStart(ts, pid, data, seq_state);
+ ParseWorkqueueExecuteStart(cpu, ts, pid, data, seq_state);
break;
}
case FtraceEvent::kWorkqueueExecuteEndFieldNumber: {
@@ -558,6 +690,62 @@ util::Status FtraceParser::ParseFtraceEvent(uint32_t cpu,
ParseCpuhpPause(ts, pid, data);
break;
}
+ case FtraceEvent::kNetifReceiveSkbFieldNumber: {
+ ParseNetifReceiveSkb(cpu, ts, data);
+ break;
+ }
+ case FtraceEvent::kNetDevXmitFieldNumber: {
+ ParseNetDevXmit(cpu, ts, data);
+ break;
+ }
+ case FtraceEvent::kInetSockSetStateFieldNumber: {
+ ParseInetSockSetState(ts, pid, data);
+ break;
+ }
+ case FtraceEvent::kTcpRetransmitSkbFieldNumber: {
+ ParseTcpRetransmitSkb(ts, data);
+ break;
+ }
+ case FtraceEvent::kNapiGroReceiveEntryFieldNumber: {
+ ParseNapiGroReceiveEntry(cpu, ts, data);
+ break;
+ }
+ case FtraceEvent::kNapiGroReceiveExitFieldNumber: {
+ ParseNapiGroReceiveExit(cpu, ts, data);
+ break;
+ }
+ case FtraceEvent::kCpuFrequencyLimitsFieldNumber: {
+ ParseCpuFrequencyLimits(ts, data);
+ break;
+ }
+ case FtraceEvent::kKfreeSkbFieldNumber: {
+ ParseKfreeSkb(ts, data);
+ break;
+ }
+ case FtraceEvent::kCrosEcSensorhubDataFieldNumber: {
+ ParseCrosEcSensorhubData(ts, data);
+ break;
+ }
+ case FtraceEvent::kUfshcdCommandFieldNumber: {
+ ParseUfshcdCommand(ts, data);
+ break;
+ }
+ case FtraceEvent::kWakeupSourceActivateFieldNumber: {
+ ParseWakeSourceActivate(ts, data);
+ break;
+ }
+ case FtraceEvent::kWakeupSourceDeactivateFieldNumber: {
+ ParseWakeSourceDeactivate(ts, data);
+ break;
+ }
+ case FtraceEvent::kUfshcdClkGatingFieldNumber: {
+ ParseUfshcdClkGating(ts, data);
+ break;
+ }
+ case FtraceEvent::kSuspendResumeFieldNumber: {
+ ParseSuspendResume(ts, data);
+ break;
+ }
default:
break;
}
@@ -646,9 +834,9 @@ void FtraceParser::ParseTypedFtraceToRaw(
protos::pbzero::InternedData::kKernelSymbolsFieldNumber,
protos::pbzero::InternedString>(fld.as_uint64());
- // If we don't have the string for this field (can happen if symbolization
- // wasn't enabled, if reading the symbols errored out or on legacy traces)
- // then just add the field as a normal arg.
+ // If we don't have the string for this field (can happen if
+ // symbolization wasn't enabled, if reading the symbols errored out or
+ // on legacy traces) then just add the field as a normal arg.
if (interned_string) {
protozero::ConstBytes str = interned_string->str();
StringId str_id = context_->storage->InternString(base::StringView(
@@ -717,24 +905,36 @@ void FtraceParser::ParseSchedSwitch(uint32_t cpu,
next_pid, ss.next_comm(), ss.next_prio());
}
-void FtraceParser::ParseSchedWakeup(int64_t timestamp, ConstBytes blob) {
+void FtraceParser::ParseSchedWakeup(int64_t timestamp,
+ uint32_t pid,
+ ConstBytes blob) {
protos::pbzero::SchedWakeupFtraceEvent::Decoder sw(blob.data, blob.size);
uint32_t wakee_pid = static_cast<uint32_t>(sw.pid());
StringId name_id = context_->storage->InternString(sw.comm());
- auto utid = context_->process_tracker->UpdateThreadName(
+ auto wakee_utid = context_->process_tracker->UpdateThreadName(
wakee_pid, name_id, ThreadNamePriority::kFtrace);
- context_->event_tracker->PushInstant(timestamp, sched_wakeup_name_id_, utid,
- RefType::kRefUtid);
+ InstantId id = context_->event_tracker->PushInstant(
+ timestamp, sched_wakeup_name_id_, wakee_utid, RefType::kRefUtid);
+
+ UniqueTid utid = context_->process_tracker->GetOrCreateThread(pid);
+ context_->args_tracker->AddArgsTo(id).AddArg(waker_utid_id_,
+ Variadic::UnsignedInteger(utid));
}
-void FtraceParser::ParseSchedWaking(int64_t timestamp, ConstBytes blob) {
+void FtraceParser::ParseSchedWaking(int64_t timestamp,
+ uint32_t pid,
+ ConstBytes blob) {
protos::pbzero::SchedWakingFtraceEvent::Decoder sw(blob.data, blob.size);
uint32_t wakee_pid = static_cast<uint32_t>(sw.pid());
StringId name_id = context_->storage->InternString(sw.comm());
- auto utid = context_->process_tracker->UpdateThreadName(
+ auto wakee_utid = context_->process_tracker->UpdateThreadName(
wakee_pid, name_id, ThreadNamePriority::kFtrace);
- context_->event_tracker->PushInstant(timestamp, sched_waking_name_id_, utid,
- RefType::kRefUtid);
+ InstantId id = context_->event_tracker->PushInstant(
+ timestamp, sched_waking_name_id_, wakee_utid, RefType::kRefUtid);
+
+ UniqueTid utid = context_->process_tracker->GetOrCreateThread(pid);
+ context_->args_tracker->AddArgsTo(id).AddArg(waker_utid_id_,
+ Variadic::UnsignedInteger(utid));
}
void FtraceParser::ParseSchedProcessFree(int64_t timestamp, ConstBytes blob) {
@@ -812,6 +1012,13 @@ void FtraceParser::ParseDpuTracingMarkWrite(int64_t timestamp,
}
uint32_t tgid = static_cast<uint32_t>(evt.pid());
+ // For kernel counter events, they will become thread counter tracks.
+ // But, we want to use the pid field specified in the event as the thread ID
+ // of the thread_counter_track instead of using the thread ID that emitted
+ // the events. So here, we need to override pid = tgid.
+ if (static_cast<char>(evt.type()) == 'C') {
+ pid = tgid;
+ }
SystraceParser::GetOrCreate(context_)->ParseTracingMarkWrite(
timestamp, pid, static_cast<char>(evt.type()), false /*trace_begin*/,
evt.name(), tgid, evt.value());
@@ -828,6 +1035,13 @@ void FtraceParser::ParseG2dTracingMarkWrite(int64_t timestamp,
}
uint32_t tgid = static_cast<uint32_t>(evt.pid());
+ // For kernel counter events, they will become thread counter tracks.
+ // But, we want to use the pid field specified in the event as the thread ID
+ // of the thread_counter_track instead of using the thread ID that emitted
+ // the events. So here, we need to override pid = tgid.
+ if (static_cast<char>(evt.type()) == 'C') {
+ pid = tgid;
+ }
SystraceParser::GetOrCreate(context_)->ParseTracingMarkWrite(
timestamp, pid, static_cast<char>(evt.type()), false /*trace_begin*/,
evt.name(), tgid, evt.value());
@@ -863,14 +1077,14 @@ void FtraceParser::ParseIonHeapGrowOrShrink(int64_t timestamp,
StringId change_name_id = ion_change_unknown_id_;
if (ion.has_heap_name()) {
- char counter_name[255];
base::StringView heap_name = ion.heap_name();
- snprintf(counter_name, sizeof(counter_name), "mem.ion.%.*s",
- int(heap_name.size()), heap_name.data());
- global_name_id = context_->storage->InternString(counter_name);
- snprintf(counter_name, sizeof(counter_name), "mem.ion_change.%.*s",
- int(heap_name.size()), heap_name.data());
- change_name_id = context_->storage->InternString(counter_name);
+ base::StackString<255> ion_name("mem.ion.%.*s", int(heap_name.size()),
+ heap_name.data());
+ global_name_id = context_->storage->InternString(ion_name.string_view());
+
+ base::StackString<255> change_name("mem.ion_change.%.*s",
+ int(heap_name.size()), heap_name.data());
+ change_name_id = context_->storage->InternString(change_name.string_view());
}
// Push the global counter.
@@ -1013,8 +1227,9 @@ void FtraceParser::ParseLowmemoryKill(int64_t timestamp, ConstBytes blob) {
auto pid = static_cast<uint32_t>(lmk.pid());
auto opt_utid = context_->process_tracker->GetThreadOrNull(pid);
- // Don't add LMK events for threads we've never seen before. This works around
- // the case where we get an LMK event after a thread has already been killed.
+ // Don't add LMK events for threads we've never seen before. This works
+ // around the case where we get an LMK event after a thread has already been
+ // killed.
if (!opt_utid)
return;
@@ -1107,10 +1322,12 @@ void FtraceParser::ParseTaskNewTask(int64_t timestamp,
static const uint32_t kCloneThread = 0x00010000; // From kernel's sched.h.
// If the process is a fork, start a new process except if the source tid is
- // kthreadd in which case just make it a new thread associated with kthreadd.
+ // kthreadd in which case just make it a new thread associated with
+ // kthreadd.
if ((clone_flags & kCloneThread) == 0 && source_tid != kKthreaddPid) {
// This is a plain-old fork() or equivalent.
- proc_tracker->StartNewProcess(timestamp, source_tid, new_tid, new_comm);
+ proc_tracker->StartNewProcess(timestamp, source_tid, new_tid, new_comm,
+ ThreadNamePriority::kFtrace);
return;
}
@@ -1132,9 +1349,8 @@ void FtraceParser::ParseTaskRename(ConstBytes blob) {
protos::pbzero::TaskRenameFtraceEvent::Decoder evt(blob.data, blob.size);
uint32_t tid = static_cast<uint32_t>(evt.pid());
StringId comm = context_->storage->InternString(evt.newcomm());
- context_->process_tracker->UpdateThreadName(tid, comm,
- ThreadNamePriority::kFtrace);
- context_->process_tracker->UpdateProcessNameFromThreadName(tid, comm);
+ context_->process_tracker->UpdateThreadNameAndMaybeProcessName(
+ tid, comm, ThreadNamePriority::kFtrace);
}
void FtraceParser::ParseBinderTransaction(int64_t timestamp,
@@ -1143,8 +1359,8 @@ void FtraceParser::ParseBinderTransaction(int64_t timestamp,
protos::pbzero::BinderTransactionFtraceEvent::Decoder evt(blob.data,
blob.size);
int32_t dest_node = static_cast<int32_t>(evt.target_node());
- int32_t dest_tgid = static_cast<int32_t>(evt.to_proc());
- int32_t dest_tid = static_cast<int32_t>(evt.to_thread());
+ uint32_t dest_tgid = static_cast<uint32_t>(evt.to_proc());
+ uint32_t dest_tid = static_cast<uint32_t>(evt.to_thread());
int32_t transaction_id = static_cast<int32_t>(evt.debug_id());
bool is_reply = static_cast<int32_t>(evt.reply()) == 1;
uint32_t flags = static_cast<uint32_t>(evt.flags());
@@ -1220,11 +1436,10 @@ void FtraceParser::ClockRate(int64_t timestamp,
base::StringView clock_name,
base::StringView subtitle,
uint64_t rate) {
- char counter_name[255];
- snprintf(counter_name, sizeof(counter_name), "%.*s %.*s",
- int(clock_name.size()), clock_name.data(), int(subtitle.size()),
- subtitle.data());
- StringId name = context_->storage->InternString(counter_name);
+ base::StackString<255> counter_name("%.*s %.*s", int(clock_name.size()),
+ clock_name.data(), int(subtitle.size()),
+ subtitle.data());
+ StringId name = context_->storage->InternString(counter_name.c_str());
TrackId track = context_->track_tracker->InternGlobalCounterTrack(name);
context_->event_tracker->PushCounter(timestamp, static_cast<double>(rate),
track);
@@ -1252,7 +1467,52 @@ void FtraceParser::ParseScmCallEnd(int64_t timestamp,
context_->slice_tracker->End(timestamp, track_id);
}
+void FtraceParser::ParseDirectReclaimBegin(int64_t timestamp,
+ uint32_t pid,
+ ConstBytes blob) {
+ UniqueTid utid = context_->process_tracker->GetOrCreateThread(pid);
+ TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
+ protos::pbzero::MmVmscanDirectReclaimBeginFtraceEvent::Decoder
+ direct_reclaim_begin(blob.data, blob.size);
+
+ StringId name_id =
+ context_->storage->InternString("mm_vmscan_direct_reclaim");
+
+ auto args_inserter = [this, &direct_reclaim_begin](
+ ArgsTracker::BoundInserter* inserter) {
+ inserter->AddArg(direct_reclaim_order_id_,
+ Variadic::Integer(direct_reclaim_begin.order()));
+ inserter->AddArg(direct_reclaim_may_writepage_id_,
+ Variadic::Integer(direct_reclaim_begin.may_writepage()));
+ inserter->AddArg(
+ direct_reclaim_gfp_flags_id_,
+ Variadic::UnsignedInteger(direct_reclaim_begin.gfp_flags()));
+ };
+ context_->slice_tracker->Begin(timestamp, track_id, kNullStringId, name_id,
+ args_inserter);
+}
+
+void FtraceParser::ParseDirectReclaimEnd(int64_t timestamp,
+ uint32_t pid,
+ ConstBytes blob) {
+ protos::pbzero::ScmCallEndFtraceEvent::Decoder evt(blob.data, blob.size);
+ UniqueTid utid = context_->process_tracker->GetOrCreateThread(pid);
+ TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
+ protos::pbzero::MmVmscanDirectReclaimEndFtraceEvent::Decoder
+ direct_reclaim_end(blob.data, blob.size);
+
+ auto args_inserter =
+ [this, &direct_reclaim_end](ArgsTracker::BoundInserter* inserter) {
+ inserter->AddArg(
+ direct_reclaim_nr_reclaimed_id_,
+ Variadic::UnsignedInteger(direct_reclaim_end.nr_reclaimed()));
+ };
+ context_->slice_tracker->End(timestamp, track_id, kNullStringId,
+ kNullStringId, args_inserter);
+}
+
void FtraceParser::ParseWorkqueueExecuteStart(
+ uint32_t cpu,
int64_t timestamp,
uint32_t pid,
ConstBytes blob,
@@ -1269,15 +1529,18 @@ void FtraceParser::ParseWorkqueueExecuteStart(
name_id = context_->storage->InternString(
base::StringView(reinterpret_cast<const char*>(str.data), str.size));
} else {
- char slice_name[255];
- snprintf(slice_name, base::ArraySize(slice_name), "%#" PRIx64,
- evt.function());
- name_id = context_->storage->InternString(base::StringView(slice_name));
+ base::StackString<255> slice_name("%#" PRIx64, evt.function());
+ name_id = context_->storage->InternString(slice_name.string_view());
}
UniqueTid utid = context_->process_tracker->GetOrCreateThread(pid);
TrackId track = context_->track_tracker->InternThreadTrack(utid);
- context_->slice_tracker->Begin(timestamp, track, workqueue_id_, name_id);
+
+ auto args_inserter = [this, cpu](ArgsTracker::BoundInserter* inserter) {
+ inserter->AddArg(cpu_id_, Variadic::Integer(cpu));
+ };
+ context_->slice_tracker->Begin(timestamp, track, workqueue_id_, name_id,
+ args_inserter);
}
void FtraceParser::ParseWorkqueueExecuteEnd(int64_t timestamp,
@@ -1294,14 +1557,15 @@ void FtraceParser::ParseIrqHandlerEntry(uint32_t cpu,
int64_t timestamp,
protozero::ConstBytes blob) {
protos::pbzero::IrqHandlerEntryFtraceEvent::Decoder evt(blob.data, blob.size);
- char track_name[255];
- snprintf(track_name, sizeof(track_name), "Irq Cpu %d", cpu);
- StringId track_name_id = context_->storage->InternString(track_name);
- char slice_name[255];
+ base::StackString<255> track_name("Irq Cpu %d", cpu);
+ StringId track_name_id =
+ context_->storage->InternString(track_name.string_view());
+
base::StringView irq_name = evt.name();
- snprintf(slice_name, sizeof(slice_name), "IRQ (%.*s)", int(irq_name.size()),
- irq_name.data());
- StringId slice_name_id = context_->storage->InternString(slice_name);
+ base::StackString<255> slice_name("IRQ (%.*s)", int(irq_name.size()),
+ irq_name.data());
+ StringId slice_name_id =
+ context_->storage->InternString(slice_name.string_view());
TrackId track = context_->track_tracker->InternCpuTrack(track_name_id, cpu);
context_->slice_tracker->Begin(timestamp, track, irq_id_, slice_name_id);
}
@@ -1310,14 +1574,13 @@ void FtraceParser::ParseIrqHandlerExit(uint32_t cpu,
int64_t timestamp,
protozero::ConstBytes blob) {
protos::pbzero::IrqHandlerExitFtraceEvent::Decoder evt(blob.data, blob.size);
- char track_name[255];
- snprintf(track_name, sizeof(track_name), "Irq Cpu %d", cpu);
- StringId track_name_id = context_->storage->InternString(track_name);
+ base::StackString<255> track_name("Irq Cpu %d", cpu);
+ StringId track_name_id =
+ context_->storage->InternString(track_name.string_view());
TrackId track = context_->track_tracker->InternCpuTrack(track_name_id, cpu);
- char status[255];
- snprintf(status, sizeof(status), "%s",
- evt.ret() == 1 ? "handled" : "unhandled");
- StringId status_id = context_->storage->InternString(status);
+
+ base::StackString<255> status("%s", evt.ret() == 1 ? "handled" : "unhandled");
+ StringId status_id = context_->storage->InternString(status.string_view());
auto args_inserter = [this,
&status_id](ArgsTracker::BoundInserter* inserter) {
inserter->AddArg(ret_arg_id_, Variadic::String(status_id));
@@ -1329,9 +1592,9 @@ void FtraceParser::ParseSoftIrqEntry(uint32_t cpu,
int64_t timestamp,
protozero::ConstBytes blob) {
protos::pbzero::SoftirqEntryFtraceEvent::Decoder evt(blob.data, blob.size);
- char track_name[255];
- snprintf(track_name, sizeof(track_name), "SoftIrq Cpu %d", cpu);
- StringId track_name_id = context_->storage->InternString(track_name);
+ base::StackString<255> track_name("SoftIrq Cpu %d", cpu);
+ StringId track_name_id =
+ context_->storage->InternString(track_name.string_view());
auto num_actions = sizeof(kActionNames) / sizeof(*kActionNames);
if (evt.vec() >= num_actions) {
PERFETTO_DFATAL("No action name at index %d for softirq event.", evt.vec());
@@ -1347,9 +1610,9 @@ void FtraceParser::ParseSoftIrqExit(uint32_t cpu,
int64_t timestamp,
protozero::ConstBytes blob) {
protos::pbzero::SoftirqExitFtraceEvent::Decoder evt(blob.data, blob.size);
- char track_name[255];
- snprintf(track_name, sizeof(track_name), "SoftIrq Cpu %d", cpu);
- StringId track_name_id = context_->storage->InternString(track_name);
+ base::StackString<255> track_name("SoftIrq Cpu %d", cpu);
+ StringId track_name_id =
+ context_->storage->InternString(track_name.string_view());
TrackId track = context_->track_tracker->InternCpuTrack(track_name_id, cpu);
auto vec = evt.vec();
auto args_inserter = [this, vec](ArgsTracker::BoundInserter* inserter) {
@@ -1371,9 +1634,26 @@ void FtraceParser::ParseGpuMemTotal(int64_t timestamp,
gpu_mem_total_name_id_, gpu_mem_total_unit_id_,
gpu_mem_total_global_desc_id_);
} else {
- // Process emitting the packet can be different from the pid in the event.
- UniqueTid utid = context_->process_tracker->UpdateThread(pid, pid);
- UniquePid upid = context_->storage->thread_table().upid()[utid].value_or(0);
+ // It's possible for GpuMemTotal ftrace events to be emitted by kworker
+ // threads *after* process death. In this case, we simply want to discard
+ // the event as otherwise we would create fake processes which we
+ // definitely want to avoid.
+ // See b/192274404 for more info.
+ base::Optional<UniqueTid> opt_utid =
+ context_->process_tracker->GetThreadOrNull(pid);
+ if (!opt_utid)
+ return;
+
+ // If the thread does exist, the |pid| in gpu_mem_total events is always a
+ // true process id (and not a thread id) so ensure there is an association
+ // between the tid and pid.
+ UniqueTid updated_utid = context_->process_tracker->UpdateThread(pid, pid);
+ PERFETTO_DCHECK(updated_utid == *opt_utid);
+
+ // UpdateThread above should ensure this is always set.
+ UniquePid upid = *context_->storage->thread_table().upid()[*opt_utid];
+ PERFETTO_DCHECK(context_->storage->process_table().pid()[upid] == pid);
+
track = context_->track_tracker->InternProcessCounterTrack(
gpu_mem_total_name_id_, upid, gpu_mem_total_unit_id_,
gpu_mem_total_proc_desc_id_);
@@ -1386,11 +1666,10 @@ void FtraceParser::ParseThermalTemperature(int64_t timestamp,
protozero::ConstBytes blob) {
protos::pbzero::ThermalTemperatureFtraceEvent::Decoder evt(blob.data,
blob.size);
- char counter_name[255];
base::StringView thermal_zone = evt.thermal_zone();
- snprintf(counter_name, sizeof(counter_name), "%.*s Temperature",
- int(thermal_zone.size()), thermal_zone.data());
- StringId name = context_->storage->InternString(counter_name);
+ base::StackString<255> counter_name(
+ "%.*s Temperature", int(thermal_zone.size()), thermal_zone.data());
+ StringId name = context_->storage->InternString(counter_name.string_view());
TrackId track = context_->track_tracker->InternGlobalCounterTrack(name);
context_->event_tracker->PushCounter(timestamp, evt.temp(), track);
}
@@ -1398,11 +1677,10 @@ void FtraceParser::ParseThermalTemperature(int64_t timestamp,
void FtraceParser::ParseCdevUpdate(int64_t timestamp,
protozero::ConstBytes blob) {
protos::pbzero::CdevUpdateFtraceEvent::Decoder evt(blob.data, blob.size);
- char counter_name[255];
base::StringView type = evt.type();
- snprintf(counter_name, sizeof(counter_name), "%.*s Cooling Device",
- int(type.size()), type.data());
- StringId name = context_->storage->InternString(counter_name);
+ base::StackString<255> counter_name("%.*s Cooling Device", int(type.size()),
+ type.data());
+ StringId name = context_->storage->InternString(counter_name.string_view());
TrackId track = context_->track_tracker->InternGlobalCounterTrack(name);
context_->event_tracker->PushCounter(
timestamp, static_cast<double>(evt.target()), track);
@@ -1443,18 +1721,16 @@ void FtraceParser::ParseFastRpcDmaStat(int64_t timestamp,
if (0 <= evt.cid() && evt.cid() < static_cast<int32_t>(kFastRpcCounterSize)) {
name = fast_rpc_delta_names_[static_cast<size_t>(evt.cid())];
} else {
- char str[64];
- snprintf(str, sizeof(str), "mem.fastrpc[%" PRId32 "]", evt.cid());
- name = context_->storage->InternString(str);
+ base::StackString<64> str("mem.fastrpc[%" PRId32 "]", evt.cid());
+ name = context_->storage->InternString(str.string_view());
}
StringId total_name;
if (0 <= evt.cid() && evt.cid() < static_cast<int32_t>(kFastRpcCounterSize)) {
total_name = fast_rpc_total_names_[static_cast<size_t>(evt.cid())];
} else {
- char str[64];
- snprintf(str, sizeof(str), "mem.fastrpc[%" PRId32 "]", evt.cid());
- total_name = context_->storage->InternString(str);
+ base::StackString<64> str("mem.fastrpc[%" PRId32 "]", evt.cid());
+ total_name = context_->storage->InternString(str.string_view());
}
// Push the global counter.
@@ -1478,5 +1754,356 @@ void FtraceParser::ParseCpuhpPause(int64_t,
// TODO(b/183110813): Parse and visualize this event.
}
+void FtraceParser::ParseNetifReceiveSkb(uint32_t cpu,
+ int64_t timestamp,
+ protozero::ConstBytes blob) {
+ protos::pbzero::NetifReceiveSkbFtraceEvent::Decoder evt(blob.data, blob.size);
+ base::StringView net_device = evt.name();
+ base::StackString<255> counter_name("%.*s Received KB",
+ static_cast<int>(net_device.size()),
+ net_device.data());
+ StringId name = context_->storage->InternString(counter_name.string_view());
+
+ nic_received_bytes_[name] += evt.len();
+
+ uint64_t nic_received_kilobytes = nic_received_bytes_[name] / 1024;
+ TrackId track = context_->track_tracker->InternGlobalCounterTrack(name);
+ base::Optional<CounterId> id = context_->event_tracker->PushCounter(
+ timestamp, static_cast<double>(nic_received_kilobytes), track);
+ if (!id) {
+ return;
+ }
+ // Store cpu & len as args for metrics computation
+ StringId cpu_key = context_->storage->InternString("cpu");
+ StringId len_key = context_->storage->InternString("len");
+ context_->args_tracker->AddArgsTo(*id)
+ .AddArg(cpu_key, Variadic::UnsignedInteger(cpu))
+ .AddArg(len_key, Variadic::UnsignedInteger(evt.len()));
+}
+
+void FtraceParser::ParseNetDevXmit(uint32_t cpu,
+ int64_t timestamp,
+ protozero::ConstBytes blob) {
+ protos::pbzero::NetDevXmitFtraceEvent::Decoder evt(blob.data, blob.size);
+ base::StringView net_device = evt.name();
+ base::StackString<255> counter_name("%.*s Transmitted KB",
+ static_cast<int>(net_device.size()),
+ net_device.data());
+ StringId name = context_->storage->InternString(counter_name.string_view());
+
+ // Make sure driver took care of packet.
+ if (evt.rc() != 0) {
+ return;
+ }
+ nic_transmitted_bytes_[name] += evt.len();
+
+ uint64_t nic_transmitted_kilobytes = nic_transmitted_bytes_[name] / 1024;
+ TrackId track = context_->track_tracker->InternGlobalCounterTrack(name);
+ base::Optional<CounterId> id = context_->event_tracker->PushCounter(
+ timestamp, static_cast<double>(nic_transmitted_kilobytes), track);
+ if (!id) {
+ return;
+ }
+ // Store cpu & len as args for metrics computation.
+ context_->args_tracker->AddArgsTo(*id)
+ .AddArg(cpu_id_, Variadic::UnsignedInteger(cpu))
+ .AddArg(len_arg_id_, Variadic::UnsignedInteger(evt.len()));
+}
+
+void FtraceParser::ParseInetSockSetState(int64_t timestamp,
+ uint32_t pid,
+ protozero::ConstBytes blob) {
+ protos::pbzero::InetSockSetStateFtraceEvent::Decoder evt(blob.data,
+ blob.size);
+
+ // Skip non TCP protocol.
+ if (evt.protocol() != kIpprotoTcp) {
+ PERFETTO_ELOG("skip non tcp protocol");
+ return;
+ }
+
+ // Skip non IP protocol.
+ if (evt.family() != kAfNet && evt.family() != kAfNet6) {
+ PERFETTO_ELOG("skip non IP protocol");
+ return;
+ }
+
+ // Skip invalid TCP state.
+ if (evt.newstate() >= TCP_MAX_STATES || evt.oldstate() >= TCP_MAX_STATES) {
+ PERFETTO_ELOG("skip invalid tcp state");
+ return;
+ }
+
+ auto got = skaddr_to_stream_.find(evt.skaddr());
+ if (got == skaddr_to_stream_.end()) {
+ skaddr_to_stream_[evt.skaddr()] = ++num_of_tcp_stream_;
+ }
+ uint32_t stream = skaddr_to_stream_[evt.skaddr()];
+ char stream_str[64];
+ sprintf(stream_str, "TCP stream#%" PRIu32 "", stream);
+ StringId stream_id = context_->storage->InternString(stream_str);
+
+ StringId slice_name_id;
+ if (evt.newstate() == TCP_SYN_SENT) {
+ base::StackString<32> str("%s(pid=%" PRIu32 ")",
+ kTcpStateNames[evt.newstate()], pid);
+ slice_name_id = context_->storage->InternString(str.string_view());
+ } else if (evt.newstate() == TCP_ESTABLISHED) {
+ base::StackString<64> str("%s(sport=%" PRIu32 ",dport=%" PRIu32 ")",
+ kTcpStateNames[evt.newstate()], evt.sport(),
+ evt.dport());
+ slice_name_id = context_->storage->InternString(str.string_view());
+ } else {
+ base::StringView slice_name = kTcpStateNames[evt.newstate()];
+ slice_name_id = context_->storage->InternString(slice_name);
+ }
+
+ // Push to async task set tracker.
+ auto async_track =
+ context_->async_track_set_tracker->InternGlobalTrackSet(stream_id);
+ TrackId end_id = context_->async_track_set_tracker->End(
+ async_track, static_cast<int64_t>(evt.skaddr()));
+ context_->slice_tracker->End(timestamp, end_id);
+ TrackId start_id = context_->async_track_set_tracker->Begin(
+ async_track, static_cast<int64_t>(evt.skaddr()));
+ context_->slice_tracker->Begin(timestamp, start_id, tcp_state_id_,
+ slice_name_id);
+}
+
+void FtraceParser::ParseTcpRetransmitSkb(int64_t timestamp,
+ protozero::ConstBytes blob) {
+ protos::pbzero::TcpRetransmitSkbFtraceEvent::Decoder evt(blob.data,
+ blob.size);
+
+ // Push event as instant to async task set tracker.
+ auto async_track = context_->async_track_set_tracker->InternGlobalTrackSet(
+ tcp_retransmited_name_id_);
+ base::StackString<64> str("sport=%" PRIu32 ",dport=%" PRIu32 "", evt.sport(),
+ evt.dport());
+ StringId slice_name_id = context_->storage->InternString(str.string_view());
+ TrackId track_id =
+ context_->async_track_set_tracker->Scoped(async_track, timestamp, 0);
+ context_->slice_tracker->Scoped(timestamp, track_id, tcp_event_id_,
+ slice_name_id, 0);
+}
+
+void FtraceParser::ParseNapiGroReceiveEntry(uint32_t cpu,
+ int64_t timestamp,
+ protozero::ConstBytes blob) {
+ protos::pbzero::NapiGroReceiveEntryFtraceEvent::Decoder evt(blob.data,
+ blob.size);
+ base::StackString<255> track_name("Napi Gro Cpu %d", cpu);
+ StringId track_name_id =
+ context_->storage->InternString(track_name.string_view());
+ base::StringView net_device = evt.name();
+ StringId slice_name_id = context_->storage->InternString(net_device);
+ TrackId track = context_->track_tracker->InternCpuTrack(track_name_id, cpu);
+ auto len = evt.len();
+ auto args_inserter = [this, len](ArgsTracker::BoundInserter* inserter) {
+ inserter->AddArg(len_arg_id_, Variadic::Integer(len));
+ };
+ context_->slice_tracker->Begin(timestamp, track, napi_gro_id_, slice_name_id,
+ args_inserter);
+}
+
+void FtraceParser::ParseNapiGroReceiveExit(uint32_t cpu,
+ int64_t timestamp,
+ protozero::ConstBytes blob) {
+ protos::pbzero::NapiGroReceiveExitFtraceEvent::Decoder evt(blob.data,
+ blob.size);
+ base::StackString<255> track_name("Napi Gro Cpu %d", cpu);
+ StringId track_name_id =
+ context_->storage->InternString(track_name.string_view());
+ TrackId track = context_->track_tracker->InternCpuTrack(track_name_id, cpu);
+ auto ret = evt.ret();
+ auto args_inserter = [this, ret](ArgsTracker::BoundInserter* inserter) {
+ inserter->AddArg(ret_arg_id_, Variadic::Integer(ret));
+ };
+ context_->slice_tracker->End(timestamp, track, napi_gro_id_, {},
+ args_inserter);
+}
+
+void FtraceParser::ParseCpuFrequencyLimits(int64_t timestamp,
+ protozero::ConstBytes blob) {
+ protos::pbzero::CpuFrequencyLimitsFtraceEvent::Decoder evt(blob.data,
+ blob.size);
+ base::StackString<255> max_counter_name("Cpu %" PRIu32 " Max Freq Limit",
+ evt.cpu_id());
+ base::StackString<255> min_counter_name("Cpu %" PRIu32 " Min Freq Limit",
+ evt.cpu_id());
+ // Push max freq to global counter.
+ StringId max_name = context_->storage->InternString(max_counter_name.c_str());
+ TrackId max_track =
+ context_->track_tracker->InternGlobalCounterTrack(max_name);
+ context_->event_tracker->PushCounter(
+ timestamp, static_cast<double>(evt.max_freq()), max_track);
+
+ // Push min freq to global counter.
+ StringId min_name = context_->storage->InternString(min_counter_name.c_str());
+ TrackId min_track =
+ context_->track_tracker->InternGlobalCounterTrack(min_name);
+ context_->event_tracker->PushCounter(
+ timestamp, static_cast<double>(evt.min_freq()), min_track);
+}
+
+void FtraceParser::ParseKfreeSkb(int64_t timestamp,
+ protozero::ConstBytes blob) {
+ protos::pbzero::KfreeSkbFtraceEvent::Decoder evt(blob.data, blob.size);
+
+ // Skip non IP & IPV6 protocol.
+ if (evt.protocol() != kEthPIp && evt.protocol() != kEthPIp6) {
+ return;
+ }
+ num_of_kfree_skb_ip_prot += 1;
+
+ TrackId track =
+ context_->track_tracker->InternGlobalCounterTrack(kfree_skb_name_id_);
+ base::Optional<CounterId> id = context_->event_tracker->PushCounter(
+ timestamp, static_cast<double>(num_of_kfree_skb_ip_prot), track);
+ if (!id) {
+ return;
+ }
+ base::StackString<255> prot("%s", evt.protocol() == kEthPIp ? "IP" : "IPV6");
+ StringId prot_id = context_->storage->InternString(prot.string_view());
+ // Store protocol as args for metrics computation.
+ context_->args_tracker->AddArgsTo(*id).AddArg(
+ protocol_arg_id_, Variadic::String(prot_id));
+}
+
+void FtraceParser::ParseCrosEcSensorhubData(int64_t timestamp,
+ protozero::ConstBytes blob) {
+ protos::pbzero::CrosEcSensorhubDataFtraceEvent::Decoder evt(blob.data,
+ blob.size);
+
+ // Push the global counter.
+ TrackId track = context_->track_tracker->InternGlobalCounterTrack(
+ context_->storage->InternString(
+ base::StringView("cros_ec.cros_ec_sensorhub_data." +
+ std::to_string(evt.ec_sensor_num()))));
+
+ auto args_inserter = [this, &evt](ArgsTracker::BoundInserter* inserter) {
+ inserter->AddArg(cros_ec_arg_num_id_,
+ Variadic::Integer(evt.ec_sensor_num()));
+ inserter->AddArg(
+ cros_ec_arg_ec_id_,
+ Variadic::Integer(evt.fifo_timestamp() - evt.current_timestamp()));
+ inserter->AddArg(cros_ec_arg_sample_ts_id_,
+ Variadic::Integer(evt.current_timestamp()));
+ };
+
+ context_->event_tracker->PushCounter(
+ timestamp,
+ static_cast<double>(evt.current_time() - evt.current_timestamp()), track,
+ args_inserter);
+}
+
+void FtraceParser::ParseUfshcdClkGating(int64_t timestamp,
+ protozero::ConstBytes blob) {
+ protos::pbzero::UfshcdClkGatingFtraceEvent::Decoder evt(blob.data, blob.size);
+ int32_t clk_state = 0;
+
+ switch (evt.state()) {
+ case 1:
+ // Change ON state to 3
+ clk_state = 3;
+ break;
+ case 2:
+ // Change REQ_OFF state to 1
+ clk_state = 1;
+ break;
+ case 3:
+ // Change REQ_ON state to 2
+ clk_state = 2;
+ break;
+ }
+ TrackId track = context_->track_tracker->InternGlobalCounterTrack(
+ ufs_clkgating_id_);
+ context_->event_tracker->PushCounter(timestamp, static_cast<double>(clk_state),
+ track);
+}
+
+void FtraceParser::ParseUfshcdCommand(int64_t timestamp,
+ protozero::ConstBytes blob) {
+ protos::pbzero::UfshcdCommandFtraceEvent::Decoder evt(blob.data, blob.size);
+ uint32_t num = evt.doorbell() > 0 ?
+ static_cast<uint32_t>(PERFETTO_POPCOUNT(evt.doorbell())) :
+ (evt.str_t() == 1 ? 0 : 1);
+
+ TrackId track = context_->track_tracker->InternGlobalCounterTrack(
+ ufs_command_count_id_);
+ context_->event_tracker->PushCounter(timestamp, static_cast<double>(num),
+ track);
+}
+
+void FtraceParser::ParseWakeSourceActivate(int64_t timestamp,
+ protozero::ConstBytes blob) {
+ protos::pbzero::WakeupSourceActivateFtraceEvent::Decoder evt(blob.data,
+ blob.size);
+ std::string event_name = evt.name().ToStdString();
+
+ uint32_t count = active_wakelock_to_count_[event_name];
+
+ active_wakelock_to_count_[event_name] += 1;
+
+ // There is already an active track with this name, don't create another.
+ if (count > 0) {
+ return;
+ }
+
+ base::StackString<32> str("Wakelock(%s)", event_name.c_str());
+ StringId stream_id = context_->storage->InternString(str.string_view());
+
+ auto async_track =
+ context_->async_track_set_tracker->InternGlobalTrackSet(stream_id);
+
+ TrackId start_id = context_->async_track_set_tracker->Begin(async_track, 0);
+
+ context_->slice_tracker->Begin(timestamp, start_id, kNullStringId, stream_id);
+}
+
+void FtraceParser::ParseWakeSourceDeactivate(int64_t timestamp,
+ protozero::ConstBytes blob) {
+ protos::pbzero::WakeupSourceDeactivateFtraceEvent::Decoder evt(blob.data,
+ blob.size);
+
+ std::string event_name = evt.name().ToStdString();
+ uint32_t count = active_wakelock_to_count_[event_name];
+ active_wakelock_to_count_[event_name] = count > 0 ? count - 1 : 0;
+ if (count != 1) {
+ return;
+ }
+
+ base::StackString<32> str("Wakelock(%s)", event_name.c_str());
+ StringId stream_id = context_->storage->InternString(str.string_view());
+ auto async_track =
+ context_->async_track_set_tracker->InternGlobalTrackSet(stream_id);
+
+ TrackId end_id = context_->async_track_set_tracker->End(async_track, 0);
+ context_->slice_tracker->End(timestamp, end_id);
+}
+
+void FtraceParser::ParseSuspendResume(int64_t timestamp,
+ protozero::ConstBytes blob) {
+ protos::pbzero::SuspendResumeFtraceEvent::Decoder evt(blob.data, blob.size);
+
+ auto async_track = context_->async_track_set_tracker->InternGlobalTrackSet(
+ suspend_resume_name_id_);
+
+ base::StackString<64> str("%s(%" PRIu32 ")",
+ evt.action().ToStdString().c_str(), evt.val());
+ StringId slice_name_id = context_->storage->InternString(str.string_view());
+
+ if (evt.start()) {
+ TrackId start_id = context_->async_track_set_tracker->Begin(
+ async_track, static_cast<int64_t>(evt.val()));
+ context_->slice_tracker->Begin(timestamp, start_id, suspend_resume_name_id_,
+ slice_name_id);
+ } else {
+ TrackId end_id = context_->async_track_set_tracker->End(
+ async_track, static_cast<int64_t>(evt.val()));
+ context_->slice_tracker->End(timestamp, end_id);
+ }
+}
+
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/importers/ftrace/ftrace_parser.h b/src/trace_processor/importers/ftrace/ftrace_parser.h
index f0ef2b958..e4730c625 100644
--- a/src/trace_processor/importers/ftrace/ftrace_parser.h
+++ b/src/trace_processor/importers/ftrace/ftrace_parser.h
@@ -19,7 +19,6 @@
#include "perfetto/trace_processor/status.h"
#include "src/trace_processor/importers/common/event_tracker.h"
-#include "src/trace_processor/importers/common/trace_blob_view.h"
#include "src/trace_processor/importers/ftrace/ftrace_descriptors.h"
#include "src/trace_processor/importers/ftrace/rss_stat_tracker.h"
#include "src/trace_processor/importers/ftrace/sched_event_tracker.h"
@@ -49,8 +48,8 @@ class FtraceParser {
protozero::ConstBytes,
PacketSequenceStateGeneration*);
void ParseSchedSwitch(uint32_t cpu, int64_t timestamp, protozero::ConstBytes);
- void ParseSchedWakeup(int64_t timestamp, protozero::ConstBytes);
- void ParseSchedWaking(int64_t timestamp, protozero::ConstBytes);
+ void ParseSchedWakeup(int64_t timestamp, uint32_t pid, protozero::ConstBytes);
+ void ParseSchedWaking(int64_t timestamp, uint32_t pid, protozero::ConstBytes);
void ParseSchedProcessFree(int64_t timestamp, protozero::ConstBytes);
void ParseCpuFreq(int64_t timestamp, protozero::ConstBytes);
void ParseGpuFreq(int64_t timestamp, protozero::ConstBytes);
@@ -120,7 +119,14 @@ class FtraceParser {
uint32_t pid,
protozero::ConstBytes);
void ParseScmCallEnd(int64_t timestamp, uint32_t pid, protozero::ConstBytes);
- void ParseWorkqueueExecuteStart(int64_t timestamp,
+ void ParseDirectReclaimBegin(int64_t timestamp,
+ uint32_t pid,
+ protozero::ConstBytes);
+ void ParseDirectReclaimEnd(int64_t timestamp,
+ uint32_t pid,
+ protozero::ConstBytes);
+ void ParseWorkqueueExecuteStart(uint32_t cpu,
+ int64_t timestamp,
uint32_t pid,
protozero::ConstBytes,
PacketSequenceStateGeneration* seq_state);
@@ -147,15 +153,41 @@ class FtraceParser {
uint32_t pid,
protozero::ConstBytes);
void ParseCpuhpPause(int64_t, uint32_t, protozero::ConstBytes);
+ void ParseNetifReceiveSkb(uint32_t cpu,
+ int64_t timestamp,
+ protozero::ConstBytes);
+ void ParseNetDevXmit(uint32_t cpu, int64_t timestamp, protozero::ConstBytes);
+ void ParseInetSockSetState(int64_t timestamp,
+ uint32_t pid,
+ protozero::ConstBytes);
+ void ParseTcpRetransmitSkb(int64_t timestamp, protozero::ConstBytes);
+ void ParseNapiGroReceiveEntry(uint32_t cpu,
+ int64_t timestamp,
+ protozero::ConstBytes);
+ void ParseNapiGroReceiveExit(uint32_t cpu,
+ int64_t timestamp,
+ protozero::ConstBytes);
+ void ParseCpuFrequencyLimits(int64_t timestamp, protozero::ConstBytes);
+ void ParseKfreeSkb(int64_t timestamp, protozero::ConstBytes);
+ void ParseUfshcdCommand(int64_t timestamp, protozero::ConstBytes);
+ void ParseUfshcdClkGating(int64_t timestamp, protozero::ConstBytes);
+
+ void ParseCrosEcSensorhubData(int64_t timestamp, protozero::ConstBytes);
+ void ParseWakeSourceActivate(int64_t timestamp, protozero::ConstBytes);
+ void ParseWakeSourceDeactivate(int64_t timestamp, protozero::ConstBytes);
+ void ParseSuspendResume(int64_t timestamp, protozero::ConstBytes);
TraceProcessorContext* context_;
RssStatTracker rss_stat_tracker_;
const StringId sched_wakeup_name_id_;
const StringId sched_waking_name_id_;
+ const StringId cpu_id_;
const StringId cpu_freq_name_id_;
const StringId gpu_freq_name_id_;
const StringId cpu_idle_name_id_;
+ const StringId suspend_resume_name_id_;
+ const StringId kfree_skb_name_id_;
const StringId ion_total_id_;
const StringId ion_change_id_;
const StringId ion_buffer_id_;
@@ -173,7 +205,17 @@ class FtraceParser {
const StringId oom_kill_id_;
const StringId workqueue_id_;
const StringId irq_id_;
+ const StringId tcp_state_id_;
+ const StringId tcp_event_id_;
+ const StringId protocol_arg_id_;
+ const StringId napi_gro_id_;
+ const StringId tcp_retransmited_name_id_;
const StringId ret_arg_id_;
+ const StringId len_arg_id_;
+ const StringId direct_reclaim_nr_reclaimed_id_;
+ const StringId direct_reclaim_order_id_;
+ const StringId direct_reclaim_may_writepage_id_;
+ const StringId direct_reclaim_gfp_flags_id_;
const StringId vec_arg_id_;
const StringId gpu_mem_total_name_id_;
const StringId gpu_mem_total_unit_id_;
@@ -182,6 +224,12 @@ class FtraceParser {
const StringId sched_blocked_reason_id_;
const StringId io_wait_id_;
const StringId function_id_;
+ const StringId waker_utid_id_;
+ const StringId cros_ec_arg_num_id_;
+ const StringId cros_ec_arg_ec_id_;
+ const StringId cros_ec_arg_sample_ts_id_;
+ const StringId ufs_clkgating_id_;
+ const StringId ufs_command_count_id_;
struct FtraceMessageStrings {
// The string id of name of the event field (e.g. sched_switch's id).
@@ -208,6 +256,25 @@ class FtraceParser {
static constexpr size_t kMmEventCounterSize = 7;
std::array<MmEventCounterNames, kMmEventCounterSize> mm_event_counter_names_;
+ // Record number of received bytes from the network interface card.
+ std::unordered_map<StringId, uint64_t> nic_received_bytes_;
+
+ // Record number of transmitted bytes to the network interface card.
+ std::unordered_map<StringId, uint64_t> nic_transmitted_bytes_;
+
+ // Record number of kfree_skb with ip protocol.
+ uint64_t num_of_kfree_skb_ip_prot = 0;
+
+ // Keep sock to stream number mapping.
+ std::unordered_map<uint64_t, uint32_t> skaddr_to_stream_;
+
+ // Record number of tcp steams.
+ uint32_t num_of_tcp_stream_ = 0;
+
+ // A name collision is possible, always show if active wakelock exists
+ // with a give name
+ std::unordered_map<std::string, uint32_t> active_wakelock_to_count_;
+
bool has_seen_first_ftrace_packet_ = false;
// Stores information about the timestamp from the metadata table which is
diff --git a/src/trace_processor/importers/ftrace/ftrace_tokenizer.cc b/src/trace_processor/importers/ftrace/ftrace_tokenizer.cc
index e51545d78..3ca59f70e 100644
--- a/src/trace_processor/importers/ftrace/ftrace_tokenizer.cc
+++ b/src/trace_processor/importers/ftrace/ftrace_tokenizer.cc
@@ -23,6 +23,7 @@
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/trace_sorter.h"
+#include "protos/perfetto/common/builtin_clock.pbzero.h"
#include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
@@ -33,53 +34,92 @@ using protozero::ProtoDecoder;
using protozero::proto_utils::MakeTagVarInt;
using protozero::proto_utils::ParseVarInt;
+using protos::pbzero::BuiltinClock;
+using protos::pbzero::FtraceClock;
+using protos::pbzero::FtraceEventBundle;
+
+namespace {
+
+static constexpr uint32_t kFtraceGlobalClockIdForOldKernels = 64;
+
+PERFETTO_ALWAYS_INLINE base::Optional<int64_t> ResolveTraceTime(
+ TraceProcessorContext* context,
+ ClockTracker::ClockId clock_id,
+ int64_t ts) {
+ // On most traces (i.e. P+), the clock should be BOOTTIME.
+ if (PERFETTO_LIKELY(clock_id == BuiltinClock::BUILTIN_CLOCK_BOOTTIME))
+ return ts;
+ return context->clock_tracker->ToTraceTime(clock_id, ts);
+}
+
+} // namespace
+
PERFETTO_ALWAYS_INLINE
-void FtraceTokenizer::TokenizeFtraceBundle(TraceBlobView bundle,
- PacketSequenceState* state) {
+base::Status FtraceTokenizer::TokenizeFtraceBundle(
+ TraceBlobView bundle,
+ PacketSequenceState* state,
+ uint32_t packet_sequence_id) {
protos::pbzero::FtraceEventBundle::Decoder decoder(bundle.data(),
bundle.length());
if (PERFETTO_UNLIKELY(!decoder.has_cpu())) {
PERFETTO_ELOG("CPU field not found in FtraceEventBundle");
context_->storage->IncrementStats(stats::ftrace_bundle_tokenizer_errors);
- return;
+ return base::OkStatus();
}
uint32_t cpu = decoder.cpu();
- if (PERFETTO_UNLIKELY(cpu > kMaxCpus)) {
- PERFETTO_ELOG("CPU larger than kMaxCpus (%u > %zu)", cpu, kMaxCpus);
- return;
+ ClockTracker::ClockId clock_id;
+ switch (decoder.ftrace_clock()) {
+ case FtraceClock::FTRACE_CLOCK_UNSPECIFIED:
+ clock_id = BuiltinClock::BUILTIN_CLOCK_BOOTTIME;
+ break;
+ case FtraceClock::FTRACE_CLOCK_GLOBAL:
+ clock_id = ClockTracker::SeqScopedClockIdToGlobal(
+ packet_sequence_id, kFtraceGlobalClockIdForOldKernels);
+ break;
+ case FtraceClock::FTRACE_CLOCK_LOCAL:
+ return base::ErrStatus("Unable to parse ftrace packets with local clock");
+ default:
+ return base::ErrStatus(
+ "Unable to parse ftrace packets with unknown clock");
+ }
+
+ if (decoder.has_ftrace_timestamp()) {
+ PERFETTO_DCHECK(clock_id != BuiltinClock::BUILTIN_CLOCK_BOOTTIME);
+ HandleFtraceClockSnapshot(decoder.ftrace_timestamp(),
+ decoder.boot_timestamp(), packet_sequence_id);
}
if (decoder.has_compact_sched()) {
- TokenizeFtraceCompactSched(cpu, decoder.compact_sched().data,
- decoder.compact_sched().size);
+ TokenizeFtraceCompactSched(cpu, clock_id, decoder.compact_sched());
}
for (auto it = decoder.event(); it; ++it) {
- protozero::ConstBytes event = *it;
- size_t off = bundle.offset_of(event.data);
- TokenizeFtraceEvent(cpu, bundle.slice(off, event.size), state);
+ TokenizeFtraceEvent(cpu, clock_id, bundle.slice(it->data(), it->size()),
+ state);
}
- context_->sorter->FinalizeFtraceEventBatch(cpu);
+ return base::OkStatus();
}
PERFETTO_ALWAYS_INLINE
void FtraceTokenizer::TokenizeFtraceEvent(uint32_t cpu,
+ ClockTracker::ClockId clock_id,
TraceBlobView event,
PacketSequenceState* state) {
constexpr auto kTimestampFieldNumber =
protos::pbzero::FtraceEvent::kTimestampFieldNumber;
+ constexpr auto kTimestampFieldTag = MakeTagVarInt(kTimestampFieldNumber);
+
const uint8_t* data = event.data();
const size_t length = event.length();
ProtoDecoder decoder(data, length);
- uint64_t raw_timestamp = 0;
- bool timestamp_found = false;
// Speculate on the fact that the timestamp is often the 1st field of the
// event.
- constexpr auto timestampFieldTag = MakeTagVarInt(kTimestampFieldNumber);
- if (PERFETTO_LIKELY(length > 10 && data[0] == timestampFieldTag)) {
+ uint64_t raw_timestamp = 0;
+ bool timestamp_found = false;
+ if (PERFETTO_LIKELY(length > 10 && data[0] == kTimestampFieldTag)) {
// Fastpath.
const uint8_t* next = ParseVarInt(data + 1, data + 11, &raw_timestamp);
timestamp_found = next != data + 1;
@@ -98,18 +138,22 @@ void FtraceTokenizer::TokenizeFtraceEvent(uint32_t cpu,
return;
}
- // We don't need to parse this packet, just push it to be sorted with
- // the timestamp.
- int64_t timestamp = static_cast<int64_t>(raw_timestamp);
- context_->sorter->PushFtraceEvent(cpu, timestamp, std::move(event), state);
+ // ClockTracker will increment some error stats if it failed to convert the
+ // timestamp so just return.
+ int64_t int64_timestamp = static_cast<int64_t>(raw_timestamp);
+ base::Optional<int64_t> timestamp =
+ ResolveTraceTime(context_, clock_id, int64_timestamp);
+ if (!timestamp)
+ return;
+ context_->sorter->PushFtraceEvent(cpu, *timestamp, std::move(event), state);
}
PERFETTO_ALWAYS_INLINE
void FtraceTokenizer::TokenizeFtraceCompactSched(uint32_t cpu,
- const uint8_t* data,
- size_t size) {
- protos::pbzero::FtraceEventBundle::CompactSched::Decoder compact_sched(data,
- size);
+ ClockTracker::ClockId clock_id,
+ protozero::ConstBytes packet) {
+ FtraceEventBundle::CompactSched::Decoder compact_sched(packet);
+
// Build the interning table for comm fields.
std::vector<StringId> string_table;
string_table.reserve(512);
@@ -118,13 +162,14 @@ void FtraceTokenizer::TokenizeFtraceCompactSched(uint32_t cpu,
string_table.push_back(value);
}
- TokenizeFtraceCompactSchedSwitch(cpu, compact_sched, string_table);
- TokenizeFtraceCompactSchedWaking(cpu, compact_sched, string_table);
+ TokenizeFtraceCompactSchedSwitch(cpu, clock_id, compact_sched, string_table);
+ TokenizeFtraceCompactSchedWaking(cpu, clock_id, compact_sched, string_table);
}
void FtraceTokenizer::TokenizeFtraceCompactSchedSwitch(
uint32_t cpu,
- const protos::pbzero::FtraceEventBundle::CompactSched::Decoder& compact,
+ ClockTracker::ClockId clock_id,
+ const FtraceEventBundle::CompactSched::Decoder& compact,
const std::vector<StringId>& string_table) {
// Accumulator for timestamp deltas.
int64_t timestamp_acc = 0;
@@ -154,7 +199,11 @@ void FtraceTokenizer::TokenizeFtraceCompactSchedSwitch(
event.next_pid = *npid_it;
event.next_prio = *nprio_it;
- context_->sorter->PushInlineFtraceEvent(cpu, event_timestamp, event);
+ base::Optional<int64_t> timestamp =
+ ResolveTraceTime(context_, clock_id, event_timestamp);
+ if (!timestamp)
+ return;
+ context_->sorter->PushInlineFtraceEvent(cpu, *timestamp, event);
}
// Check that all packed buffers were decoded correctly, and fully.
@@ -166,7 +215,8 @@ void FtraceTokenizer::TokenizeFtraceCompactSchedSwitch(
void FtraceTokenizer::TokenizeFtraceCompactSchedWaking(
uint32_t cpu,
- const protos::pbzero::FtraceEventBundle::CompactSched::Decoder& compact,
+ ClockTracker::ClockId clock_id,
+ const FtraceEventBundle::CompactSched::Decoder& compact,
const std::vector<StringId>& string_table) {
// Accumulator for timestamp deltas.
int64_t timestamp_acc = 0;
@@ -197,7 +247,11 @@ void FtraceTokenizer::TokenizeFtraceCompactSchedWaking(
event.target_cpu = *tcpu_it;
event.prio = *prio_it;
- context_->sorter->PushInlineFtraceEvent(cpu, event_timestamp, event);
+ base::Optional<int64_t> timestamp =
+ ResolveTraceTime(context_, clock_id, event_timestamp);
+ if (!timestamp)
+ return;
+ context_->sorter->PushInlineFtraceEvent(cpu, *timestamp, event);
}
// Check that all packed buffers were decoded correctly, and fully.
@@ -207,5 +261,22 @@ void FtraceTokenizer::TokenizeFtraceCompactSchedWaking(
context_->storage->IncrementStats(stats::compact_sched_has_parse_errors);
}
+void FtraceTokenizer::HandleFtraceClockSnapshot(int64_t ftrace_ts,
+ int64_t boot_ts,
+ uint32_t packet_sequence_id) {
+ // If we've already seen a snapshot at this timestamp, don't unnecessarily
+ // add another entry to the clock tracker.
+ if (latest_ftrace_clock_snapshot_ts_ == ftrace_ts)
+ return;
+ latest_ftrace_clock_snapshot_ts_ = ftrace_ts;
+
+ ClockTracker::ClockId global_id = ClockTracker::SeqScopedClockIdToGlobal(
+ packet_sequence_id, kFtraceGlobalClockIdForOldKernels);
+ context_->clock_tracker->AddSnapshot(
+ {ClockTracker::ClockValue(global_id, ftrace_ts),
+ ClockTracker::ClockValue(BuiltinClock::BUILTIN_CLOCK_BOOTTIME,
+ boot_ts)});
+}
+
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/importers/ftrace/ftrace_tokenizer.h b/src/trace_processor/importers/ftrace/ftrace_tokenizer.h
index f4f541690..f92f55558 100644
--- a/src/trace_processor/importers/ftrace/ftrace_tokenizer.h
+++ b/src/trace_processor/importers/ftrace/ftrace_tokenizer.h
@@ -17,11 +17,13 @@
#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_FTRACE_FTRACE_TOKENIZER_H_
#define SRC_TRACE_PROCESSOR_IMPORTERS_FTRACE_FTRACE_TOKENIZER_H_
-#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
-#include "src/trace_processor/importers/common/trace_blob_view.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
+#include "src/trace_processor/importers/common/clock_tracker.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/trace_processor_context.h"
+#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
+
namespace perfetto {
namespace trace_processor {
@@ -32,24 +34,34 @@ class FtraceTokenizer {
explicit FtraceTokenizer(TraceProcessorContext* context)
: context_(context) {}
- void TokenizeFtraceBundle(TraceBlobView bundle, PacketSequenceState*);
+ base::Status TokenizeFtraceBundle(TraceBlobView bundle,
+ PacketSequenceState*,
+ uint32_t packet_sequence_id);
private:
void TokenizeFtraceEvent(uint32_t cpu,
+ ClockTracker::ClockId,
TraceBlobView event,
- PacketSequenceState*);
+ PacketSequenceState* state);
void TokenizeFtraceCompactSched(uint32_t cpu,
- const uint8_t* data,
- size_t size);
+ ClockTracker::ClockId,
+ protozero::ConstBytes);
void TokenizeFtraceCompactSchedSwitch(
uint32_t cpu,
+ ClockTracker::ClockId,
const protos::pbzero::FtraceEventBundle::CompactSched::Decoder& compact,
const std::vector<StringId>& string_table);
void TokenizeFtraceCompactSchedWaking(
uint32_t cpu,
+ ClockTracker::ClockId,
const protos::pbzero::FtraceEventBundle::CompactSched::Decoder& compact,
const std::vector<StringId>& string_table);
+ void HandleFtraceClockSnapshot(int64_t ftrace_ts,
+ int64_t boot_ts,
+ uint32_t packet_sequence_id);
+
+ int64_t latest_ftrace_clock_snapshot_ts_ = 0;
TraceProcessorContext* context_;
};
diff --git a/src/trace_processor/importers/ftrace/rss_stat_tracker.cc b/src/trace_processor/importers/ftrace/rss_stat_tracker.cc
index 214bd75b1..80ca10fc8 100644
--- a/src/trace_processor/importers/ftrace/rss_stat_tracker.cc
+++ b/src/trace_processor/importers/ftrace/rss_stat_tracker.cc
@@ -20,11 +20,15 @@
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/types/trace_processor_context.h"
+#include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
#include "protos/perfetto/trace/ftrace/kmem.pbzero.h"
+#include "protos/perfetto/trace/ftrace/synthetic.pbzero.h"
namespace perfetto {
namespace trace_processor {
+using FtraceEvent = protos::pbzero::FtraceEvent;
+
RssStatTracker::RssStatTracker(TraceProcessorContext* context)
: context_(context) {
rss_members_.emplace_back(context->storage->InternString("mem.rss.file"));
@@ -37,19 +41,41 @@ RssStatTracker::RssStatTracker(TraceProcessorContext* context)
context->storage->InternString("mem.unknown")); // Keep this last.
}
-void RssStatTracker::ParseRssStat(int64_t ts, uint32_t pid, ConstBytes blob) {
- protos::pbzero::RssStatFtraceEvent::Decoder rss(blob.data, blob.size);
- uint32_t member = static_cast<uint32_t>(rss.member());
- int64_t size = rss.size();
+void RssStatTracker::ParseRssStat(int64_t ts,
+ int32_t field_id,
+ uint32_t pid,
+ ConstBytes blob) {
+ uint32_t member;
+ int64_t size;
base::Optional<bool> curr;
base::Optional<int64_t> mm_id;
- if (rss.has_curr()) {
+
+ if (field_id == FtraceEvent::kRssStatFieldNumber) {
+ protos::pbzero::RssStatFtraceEvent::Decoder rss(blob.data, blob.size);
+
+ member = static_cast<uint32_t>(rss.member());
+ size = rss.size();
+ if (rss.has_curr()) {
+ curr = base::make_optional(static_cast<bool>(rss.curr()));
+ }
+ if (rss.has_mm_id()) {
+ mm_id = base::make_optional(rss.mm_id());
+ }
+
+ ParseRssStat(ts, pid, size, member, curr, mm_id);
+ } else if (field_id == FtraceEvent::kRssStatThrottledFieldNumber) {
+ protos::pbzero::RssStatThrottledFtraceEvent::Decoder rss(blob.data,
+ blob.size);
+
+ member = static_cast<uint32_t>(rss.member());
+ size = rss.size();
curr = base::make_optional(static_cast<bool>(rss.curr()));
- }
- if (rss.has_mm_id()) {
mm_id = base::make_optional(rss.mm_id());
+
+ ParseRssStat(ts, pid, size, member, curr, mm_id);
+ } else {
+ PERFETTO_DFATAL("Unexpected field id");
}
- ParseRssStat(ts, pid, size, member, curr, mm_id);
}
void RssStatTracker::ParseRssStat(int64_t ts,
@@ -97,32 +123,33 @@ base::Optional<UniqueTid> RssStatTracker::FindUtidForMmId(int64_t mm_id,
// If curr is false, try and lookup the utid we previously saw for this
// mm id.
- auto it = mm_id_to_utid_.find(mm_id);
- if (it == mm_id_to_utid_.end())
+ auto* it = mm_id_to_utid_.Find(mm_id);
+ if (!it)
return base::nullopt;
// If the utid in the map is the same as our current utid but curr is false,
// that means we are in the middle of a process changing mm structs (i.e. in
// the middle of a vfork + exec). Therefore, we should discard the association
// of this vm struct with this thread.
- UniqueTid utid = context_->process_tracker->GetOrCreateThread(pid);
- if (it->second == utid) {
- mm_id_to_utid_.erase(it);
+ const UniqueTid mm_utid = *it;
+ const UniqueTid utid = context_->process_tracker->GetOrCreateThread(pid);
+ if (mm_utid == utid) {
+ mm_id_to_utid_.Erase(mm_id);
return base::nullopt;
}
// Verify that the utid in the map is still alive. This can happen if an mm
// struct we saw in the past is about to be reused after thread but we don't
// know the new process that struct will be associated with.
- if (!context_->process_tracker->IsThreadAlive(it->second)) {
- mm_id_to_utid_.erase(it);
+ if (!context_->process_tracker->IsThreadAlive(mm_utid)) {
+ mm_id_to_utid_.Erase(mm_id);
return base::nullopt;
}
// This case happens when a process is changing the VM of another process and
// we know that the utid corresponding to the target process. Just return that
// utid.
- return it->second;
+ return mm_utid;
}
} // namespace trace_processor
diff --git a/src/trace_processor/importers/ftrace/rss_stat_tracker.h b/src/trace_processor/importers/ftrace/rss_stat_tracker.h
index fff203c59..b3ba29a53 100644
--- a/src/trace_processor/importers/ftrace/rss_stat_tracker.h
+++ b/src/trace_processor/importers/ftrace/rss_stat_tracker.h
@@ -17,8 +17,7 @@
#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_FTRACE_RSS_STAT_TRACKER_H_
#define SRC_TRACE_PROCESSOR_IMPORTERS_FTRACE_RSS_STAT_TRACKER_H_
-#include <unordered_map>
-
+#include "perfetto/ext/base/flat_hash_map.h"
#include "perfetto/protozero/field.h"
#include "src/trace_processor/storage/trace_storage.h"
@@ -33,7 +32,10 @@ class RssStatTracker {
explicit RssStatTracker(TraceProcessorContext*);
- void ParseRssStat(int64_t ts, uint32_t pid, ConstBytes blob);
+ void ParseRssStat(int64_t ts,
+ int32_t field_id,
+ uint32_t pid,
+ ConstBytes blob);
void ParseRssStat(int64_t ts,
uint32_t pid,
int64_t size,
@@ -46,7 +48,7 @@ class RssStatTracker {
bool is_curr,
uint32_t pid);
- std::unordered_map<int64_t, UniqueTid> mm_id_to_utid_;
+ base::FlatHashMap<int64_t, UniqueTid> mm_id_to_utid_;
std::vector<StringId> rss_members_;
TraceProcessorContext* const context_;
};
diff --git a/src/trace_processor/importers/ftrace/sched_event_tracker.cc b/src/trace_processor/importers/ftrace/sched_event_tracker.cc
index 247c08ee2..66a78b302 100644
--- a/src/trace_processor/importers/ftrace/sched_event_tracker.cc
+++ b/src/trace_processor/importers/ftrace/sched_event_tracker.cc
@@ -36,7 +36,8 @@ namespace perfetto {
namespace trace_processor {
SchedEventTracker::SchedEventTracker(TraceProcessorContext* context)
- : context_(context) {
+ : waker_utid_id_(context->storage->InternString("waker_utid")),
+ context_(context) {
// pre-parse sched_switch
auto* switch_descriptor = GetMessageDescriptorForId(
protos::pbzero::FtraceEvent::kSchedSwitchFieldNumber);
@@ -58,6 +59,10 @@ SchedEventTracker::SchedEventTracker(TraceProcessorContext* context)
context->storage->InternString(waking_descriptor->fields[i].name);
}
sched_waking_id_ = context->storage->InternString(waking_descriptor->name);
+
+ // Pre-allocate space for 128 CPUs, which should be enough for most hosts.
+ // It's OK if this number is too small, the vector will be grown on-demand.
+ pending_sched_per_cpu_.reserve(128);
}
SchedEventTracker::~SchedEventTracker() = default;
@@ -81,7 +86,6 @@ void SchedEventTracker::PushSchedSwitch(uint32_t cpu,
return;
}
context_->event_tracker->UpdateMaxTimestamp(ts);
- PERFETTO_DCHECK(cpu < kMaxCpus);
StringId next_comm_id = context_->storage->InternString(next_comm);
UniqueTid next_utid = context_->process_tracker->UpdateThreadName(
@@ -89,7 +93,7 @@ void SchedEventTracker::PushSchedSwitch(uint32_t cpu,
// First use this data to close the previous slice.
bool prev_pid_match_prev_next_pid = false;
- auto* pending_sched = &pending_sched_per_cpu_[cpu];
+ auto* pending_sched = PendingSchedByCPU(cpu);
uint32_t pending_slice_idx = pending_sched->pending_slice_storage_idx;
if (pending_slice_idx < std::numeric_limits<uint32_t>::max()) {
prev_pid_match_prev_next_pid = prev_pid == pending_sched->last_pid;
@@ -135,12 +139,11 @@ void SchedEventTracker::PushSchedSwitchCompact(uint32_t cpu,
return;
}
context_->event_tracker->UpdateMaxTimestamp(ts);
- PERFETTO_DCHECK(cpu < kMaxCpus);
UniqueTid next_utid = context_->process_tracker->UpdateThreadName(
next_pid, next_comm_id, ThreadNamePriority::kFtrace);
- auto* pending_sched = &pending_sched_per_cpu_[cpu];
+ auto* pending_sched = PendingSchedByCPU(cpu);
// If we're processing the first compact event for this cpu, don't start a
// slice since we're missing the "prev_*" fields. The successive events will
@@ -172,7 +175,9 @@ void SchedEventTracker::PushSchedSwitchCompact(uint32_t cpu,
// Do a fresh task name lookup in case it was updated by a task_rename while
// scheduled.
- StringId prev_comm_id = context_->storage->thread_table().name()[prev_utid];
+ StringId prev_comm_id =
+ context_->storage->thread_table().name()[prev_utid].value_or(
+ kNullStringId);
auto new_slice_idx = AddRawEventAndStartSlice(
cpu, ts, prev_utid, prev_pid, prev_comm_id, prev_prio, prev_state,
@@ -275,14 +280,13 @@ void SchedEventTracker::PushSchedWakingCompact(uint32_t cpu,
return;
}
context_->event_tracker->UpdateMaxTimestamp(ts);
- PERFETTO_DCHECK(cpu < kMaxCpus);
// We infer the task that emitted the event (i.e. common_pid) from the
// scheduling slices. Drop the event if we haven't seen any sched_switch
// events for this cpu yet.
// Note that if sched_switch wasn't enabled, we will have to skip all
// compact waking events.
- auto* pending_sched = &pending_sched_per_cpu_[cpu];
+ auto* pending_sched = PendingSchedByCPU(cpu);
if (pending_sched->last_utid == std::numeric_limits<UniqueTid>::max()) {
context_->storage->IncrementStats(stats::compact_sched_waking_skipped);
return;
@@ -317,7 +321,11 @@ void SchedEventTracker::PushSchedWakingCompact(uint32_t cpu,
auto* instants = context_->storage->mutable_instant_table();
auto ref_type_id = context_->storage->InternString(
GetRefTypeStringMap()[static_cast<size_t>(RefType::kRefUtid)]);
- instants->Insert({ts, sched_waking_id_, wakee_utid, ref_type_id});
+ tables::InstantTable::Id id =
+ instants->Insert({ts, sched_waking_id_, wakee_utid, ref_type_id}).id;
+
+ context_->args_tracker->AddArgsTo(id).AddArg(
+ waker_utid_id_, Variadic::UnsignedInteger(curr_utid));
}
void SchedEventTracker::FlushPendingEvents() {
@@ -339,7 +347,11 @@ void SchedEventTracker::FlushPendingEvents() {
slices->mutable_end_state()->Set(row, id);
}
- pending_sched_per_cpu_ = {};
+ // Re-initialize the pending_sched_per_cpu_ vector with default values, we do
+ // this instead of calling .clear() to avoid having to frequently resize the
+ // vector.
+ std::fill(pending_sched_per_cpu_.begin(), pending_sched_per_cpu_.end(),
+ PendingSchedInfo{});
}
} // namespace trace_processor
diff --git a/src/trace_processor/importers/ftrace/sched_event_tracker.h b/src/trace_processor/importers/ftrace/sched_event_tracker.h
index a4e8602ea..eff442cc5 100644
--- a/src/trace_processor/importers/ftrace/sched_event_tracker.h
+++ b/src/trace_processor/importers/ftrace/sched_event_tracker.h
@@ -110,8 +110,16 @@ class SchedEventTracker : public Destructible {
void ClosePendingSlice(uint32_t slice_idx, int64_t ts, int64_t prev_state);
- // Infromation retained from the preceding sched_switch seen on a given cpu.
- std::array<PendingSchedInfo, kMaxCpus> pending_sched_per_cpu_{};
+ // Information retained from the preceding sched_switch seen on a given cpu.
+ std::vector<PendingSchedInfo> pending_sched_per_cpu_;
+
+ // Get the sched info for the given CPU, resizing the vector if necessary.
+ PendingSchedInfo* PendingSchedByCPU(uint32_t cpu) {
+ if (PERFETTO_UNLIKELY(cpu >= pending_sched_per_cpu_.size())) {
+ pending_sched_per_cpu_.resize(cpu + 1);
+ }
+ return &pending_sched_per_cpu_[cpu];
+ }
static constexpr uint8_t kSchedSwitchMaxFieldId = 7;
std::array<StringId, kSchedSwitchMaxFieldId + 1> sched_switch_field_ids_;
@@ -121,6 +129,8 @@ class SchedEventTracker : public Destructible {
std::array<StringId, kSchedWakingMaxFieldId + 1> sched_waking_field_ids_;
StringId sched_waking_id_;
+ StringId waker_utid_id_;
+
TraceProcessorContext* const context_;
};
diff --git a/src/trace_processor/importers/ftrace/sched_event_tracker_unittest.cc b/src/trace_processor/importers/ftrace/sched_event_tracker_unittest.cc
index 15f6eca64..802990fc2 100644
--- a/src/trace_processor/importers/ftrace/sched_event_tracker_unittest.cc
+++ b/src/trace_processor/importers/ftrace/sched_event_tracker_unittest.cc
@@ -69,8 +69,7 @@ TEST_F(SchedEventTrackerTest, InsertSecondSched) {
ASSERT_EQ(timestamps[0], timestamp);
ASSERT_EQ(context.storage->thread_table().start_ts()[1], base::nullopt);
- auto name =
- context.storage->GetString(context.storage->thread_table().name()[1]);
+ auto name = context.storage->thread_table().name().GetString(1);
ASSERT_STREQ(name.c_str(), kCommProc1);
ASSERT_EQ(context.storage->sched_slice_table().utid()[0], 1u);
ASSERT_EQ(context.storage->sched_slice_table().dur()[0], 1);
diff --git a/src/trace_processor/importers/fuchsia/fuchsia_record.h b/src/trace_processor/importers/fuchsia/fuchsia_record.h
index 9518c358c..f90d039b9 100644
--- a/src/trace_processor/importers/fuchsia/fuchsia_record.h
+++ b/src/trace_processor/importers/fuchsia/fuchsia_record.h
@@ -17,7 +17,7 @@
#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_FUCHSIA_FUCHSIA_RECORD_H_
#define SRC_TRACE_PROCESSOR_IMPORTERS_FUCHSIA_FUCHSIA_RECORD_H_
-#include "src/trace_processor/importers/common/trace_blob_view.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
#include "src/trace_processor/importers/fuchsia/fuchsia_trace_utils.h"
#include "src/trace_processor/storage/trace_storage.h"
@@ -32,7 +32,7 @@ namespace trace_processor {
// the binary record after arbitrary reordering.
class FuchsiaRecord {
public:
- FuchsiaRecord(TraceBlobView record_view)
+ explicit FuchsiaRecord(TraceBlobView record_view)
: record_view_(std::move(record_view)) {}
struct StringTableEntry {
diff --git a/src/trace_processor/importers/fuchsia/fuchsia_trace_parser.cc b/src/trace_processor/importers/fuchsia/fuchsia_trace_parser.cc
index 5e6147595..def414c7f 100644
--- a/src/trace_processor/importers/fuchsia/fuchsia_trace_parser.cc
+++ b/src/trace_processor/importers/fuchsia/fuchsia_trace_parser.cc
@@ -262,20 +262,13 @@ void FuchsiaTraceParser::ParseTracePacket(int64_t, TimestampedTracePiece ttp) {
UniqueTid utid =
procs->UpdateThread(static_cast<uint32_t>(tinfo.tid),
static_cast<uint32_t>(tinfo.pid));
- InstantId id = context_->event_tracker->PushInstant(
- ts, name, utid, RefType::kRefUtid);
- auto inserter = context_->args_tracker->AddArgsTo(id);
- for (const Arg& arg : args) {
- inserter.AddArg(
- arg.name, arg.value.ToStorageVariadic(context_->storage.get()));
- }
- context_->args_tracker->Flush();
+ TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
+ slices->Scoped(ts, track_id, cat, name, 0, insert_args);
break;
}
case kCounter: {
- UniqueTid utid =
- procs->UpdateThread(static_cast<uint32_t>(tinfo.tid),
- static_cast<uint32_t>(tinfo.pid));
+ UniquePid upid =
+ procs->GetOrCreateProcess(static_cast<uint32_t>(tinfo.pid));
std::string name_str =
context_->storage->GetString(name).ToStdString();
// Note: In the Fuchsia trace format, counter values are stored in the
@@ -321,8 +314,9 @@ void FuchsiaTraceParser::ParseTracePacket(int64_t, TimestampedTracePiece ttp) {
if (is_valid_value) {
StringId counter_name_id = context_->storage->InternString(
base::StringView(counter_name_str));
- TrackId track = context_->track_tracker->InternThreadCounterTrack(
- counter_name_id, utid);
+ TrackId track =
+ context_->track_tracker->InternProcessCounterTrack(
+ counter_name_id, upid);
context_->event_tracker->PushCounter(ts, counter_value, track);
}
}
@@ -379,9 +373,6 @@ void FuchsiaTraceParser::ParseTracePacket(int64_t, TimestampedTracePiece ttp) {
break;
}
case kAsyncInstant: {
- // TODO(eseckler): Consider storing these instants as 0-duration
- // slices instead, so that they get nested underneath begin/end
- // slices.
int64_t correlation_id;
if (!cursor.ReadInt64(&correlation_id)) {
context_->storage->IncrementStats(stats::fuchsia_invalid_event);
@@ -391,15 +382,7 @@ void FuchsiaTraceParser::ParseTracePacket(int64_t, TimestampedTracePiece ttp) {
procs->GetOrCreateProcess(static_cast<uint32_t>(tinfo.pid));
TrackId track_id = context_->track_tracker->InternFuchsiaAsyncTrack(
name, upid, correlation_id);
- InstantId id = context_->event_tracker->PushInstant(
- ts, name, track_id.value, RefType::kRefTrack);
- auto inserter = context_->args_tracker->AddArgsTo(id);
- for (const Arg& arg : args) {
- inserter.AddArg(
- arg.name, arg.name,
- arg.value.ToStorageVariadic(context_->storage.get()));
- }
- context_->args_tracker->Flush();
+ slices->Scoped(ts, track_id, cat, name, 0, insert_args);
break;
}
case kAsyncEnd: {
diff --git a/src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.cc b/src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.cc
index a78e89681..6628c41c6 100644
--- a/src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.cc
+++ b/src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.cc
@@ -16,11 +16,11 @@
#include "src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.h"
-#include <inttypes.h>
-#include <unordered_map>
+#include <cinttypes>
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/string_view.h"
+#include "perfetto/trace_processor/trace_blob.h"
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/importers/common/slice_tracker.h"
#include "src/trace_processor/importers/fuchsia/fuchsia_record.h"
@@ -70,8 +70,9 @@ FuchsiaTraceTokenizer::FuchsiaTraceTokenizer(TraceProcessorContext* context)
FuchsiaTraceTokenizer::~FuchsiaTraceTokenizer() = default;
-util::Status FuchsiaTraceTokenizer::Parse(std::unique_ptr<uint8_t[]> data,
- size_t size) {
+util::Status FuchsiaTraceTokenizer::Parse(TraceBlobView blob) {
+ size_t size = blob.size();
+
// The relevant internal state is |leftover_bytes_|. Each call to Parse should
// maintain the following properties, unless a fatal error occurs in which
// case it should return false and no assumptions should be made about the
@@ -95,8 +96,8 @@ util::Status FuchsiaTraceTokenizer::Parse(std::unique_ptr<uint8_t[]> data,
if (leftover_bytes_.size() + size < 8) {
// Even with the new bytes, we can't even read the header of the next
// record, so just add the new bytes to |leftover_bytes_| and return.
- leftover_bytes_.insert(leftover_bytes_.end(), data.get() + byte_offset,
- data.get() + size);
+ leftover_bytes_.insert(leftover_bytes_.end(), blob.data() + byte_offset,
+ blob.data() + size);
return util::OkStatus();
}
if (!leftover_bytes_.empty()) {
@@ -106,8 +107,8 @@ util::Status FuchsiaTraceTokenizer::Parse(std::unique_ptr<uint8_t[]> data,
// Copy bytes into |leftover_bytes_| so that the whole header is present,
// and update |byte_offset| and |size| accordingly.
size_t needed_bytes = 8 - leftover_bytes_.size();
- leftover_bytes_.insert(leftover_bytes_.end(), data.get() + byte_offset,
- data.get() + needed_bytes);
+ leftover_bytes_.insert(leftover_bytes_.end(), blob.data() + byte_offset,
+ blob.data() + needed_bytes);
byte_offset += needed_bytes;
size -= needed_bytes;
}
@@ -128,25 +129,24 @@ util::Status FuchsiaTraceTokenizer::Parse(std::unique_ptr<uint8_t[]> data,
if (missing_bytes <= size) {
// We have enough bytes to complete the partial record. Create a new
// buffer for that record.
- std::unique_ptr<uint8_t[]> buf(new uint8_t[record_len_bytes]);
- memcpy(&buf[0], leftover_bytes_.data(), leftover_bytes_.size());
- memcpy(&buf[leftover_bytes_.size()], &data[byte_offset], missing_bytes);
+ TraceBlob buf = TraceBlob::Allocate(record_len_bytes);
+ memcpy(buf.data(), leftover_bytes_.data(), leftover_bytes_.size());
+ memcpy(buf.data() + leftover_bytes_.size(), blob.data() + byte_offset,
+ missing_bytes);
byte_offset += missing_bytes;
size -= missing_bytes;
leftover_bytes_.clear();
-
- TraceBlobView leftover_record(std::move(buf), 0, record_len_bytes);
- ParseRecord(std::move(leftover_record));
+ ParseRecord(TraceBlobView(std::move(buf)));
} else {
// There are not enough bytes for the full record. Add all the bytes we
// have to leftover_bytes_ and wait for more.
- leftover_bytes_.insert(leftover_bytes_.end(), data.get() + byte_offset,
- data.get() + byte_offset + size);
+ leftover_bytes_.insert(leftover_bytes_.end(), blob.data() + byte_offset,
+ blob.data() + byte_offset + size);
return util::OkStatus();
}
}
- TraceBlobView full_view(std::move(data), byte_offset, size);
+ TraceBlobView full_view = blob.slice_off(byte_offset, size);
// |record_offset| is a number of bytes past |byte_offset| where the record
// under consideration starts. As a result, it must always be in the range [0,
@@ -164,8 +164,7 @@ util::Status FuchsiaTraceTokenizer::Parse(std::unique_ptr<uint8_t[]> data,
if (record_offset + record_len_bytes > size)
break;
- TraceBlobView record =
- full_view.slice(byte_offset + record_offset, record_len_bytes);
+ TraceBlobView record = full_view.slice_off(record_offset, record_len_bytes);
ParseRecord(std::move(record));
record_offset += record_len_bytes;
diff --git a/src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.h b/src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.h
index 0881fd512..258a922fa 100644
--- a/src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.h
+++ b/src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.h
@@ -18,7 +18,6 @@
#define SRC_TRACE_PROCESSOR_IMPORTERS_FUCHSIA_FUCHSIA_TRACE_TOKENIZER_H_
#include "src/trace_processor/importers/common/chunked_trace_reader.h"
-#include "src/trace_processor/importers/common/trace_blob_view.h"
#include "src/trace_processor/importers/fuchsia/fuchsia_trace_utils.h"
#include "src/trace_processor/storage/trace_storage.h"
@@ -35,7 +34,7 @@ class FuchsiaTraceTokenizer : public ChunkedTraceReader {
~FuchsiaTraceTokenizer() override;
// ChunkedTraceReader implementation
- util::Status Parse(std::unique_ptr<uint8_t[]>, size_t) override;
+ util::Status Parse(TraceBlobView) override;
void NotifyEndOfFile() override;
private:
diff --git a/src/trace_processor/importers/fuchsia/fuchsia_trace_utils.h b/src/trace_processor/importers/fuchsia/fuchsia_trace_utils.h
index f6f99d05b..518be4b85 100644
--- a/src/trace_processor/importers/fuchsia/fuchsia_trace_utils.h
+++ b/src/trace_processor/importers/fuchsia/fuchsia_trace_utils.h
@@ -22,7 +22,7 @@
#include <functional>
#include "perfetto/ext/base/string_view.h"
-#include "src/trace_processor/importers/common/trace_blob_view.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
#include "src/trace_processor/storage/trace_storage.h"
namespace perfetto {
diff --git a/src/trace_processor/importers/gzip/gzip_trace_parser.cc b/src/trace_processor/importers/gzip/gzip_trace_parser.cc
index bc42db397..640f2f19b 100644
--- a/src/trace_processor/importers/gzip/gzip_trace_parser.cc
+++ b/src/trace_processor/importers/gzip/gzip_trace_parser.cc
@@ -21,7 +21,9 @@
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/string_view.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
#include "src/trace_processor/forwarding_trace_parser.h"
+#include "src/trace_processor/util/gzip_utils.h"
#include "src/trace_processor/util/status_macros.h"
namespace perfetto {
@@ -29,7 +31,7 @@ namespace trace_processor {
namespace {
-using ResultCode = GzipDecompressor::ResultCode;
+using ResultCode = util::GzipDecompressor::ResultCode;
} // namespace
@@ -41,9 +43,8 @@ GzipTraceParser::GzipTraceParser(std::unique_ptr<ChunkedTraceReader> reader)
GzipTraceParser::~GzipTraceParser() = default;
-util::Status GzipTraceParser::Parse(std::unique_ptr<uint8_t[]> data,
- size_t size) {
- return ParseUnowned(data.get(), size);
+util::Status GzipTraceParser::Parse(TraceBlobView blob) {
+ return ParseUnowned(blob.data(), blob.size());
}
util::Status GzipTraceParser::ParseUnowned(const uint8_t* data, size_t size) {
@@ -74,7 +75,7 @@ util::Status GzipTraceParser::ParseUnowned(const uint8_t* data, size_t size) {
constexpr size_t kUncompressedBufferSize = 32 * 1024 * 1024;
needs_more_input_ = false;
- decompressor_.SetInput(start, len);
+ decompressor_.Feed(start, len);
for (auto ret = ResultCode::kOk; ret != ResultCode::kEof;) {
if (!buffer_) {
@@ -83,10 +84,10 @@ util::Status GzipTraceParser::ParseUnowned(const uint8_t* data, size_t size) {
}
auto result =
- decompressor_.Decompress(buffer_.get() + bytes_written_,
- kUncompressedBufferSize - bytes_written_);
+ decompressor_.ExtractOutput(buffer_.get() + bytes_written_,
+ kUncompressedBufferSize - bytes_written_);
ret = result.ret;
- if (ret == ResultCode::kError || ret == ResultCode::kNoProgress)
+ if (ret == ResultCode::kError)
return util::ErrStatus("Failed to decompress trace chunk");
if (ret == ResultCode::kNeedsMoreInput) {
@@ -96,8 +97,11 @@ util::Status GzipTraceParser::ParseUnowned(const uint8_t* data, size_t size) {
}
bytes_written_ += result.bytes_written;
- if (bytes_written_ == kUncompressedBufferSize || ret == ResultCode::kEof)
- RETURN_IF_ERROR(inner_->Parse(std::move(buffer_), bytes_written_));
+ if (bytes_written_ == kUncompressedBufferSize || ret == ResultCode::kEof) {
+ TraceBlob blob =
+ TraceBlob::TakeOwnership(std::move(buffer_), bytes_written_);
+ RETURN_IF_ERROR(inner_->Parse(TraceBlobView(std::move(blob))));
+ }
}
return util::OkStatus();
}
diff --git a/src/trace_processor/importers/gzip/gzip_trace_parser.h b/src/trace_processor/importers/gzip/gzip_trace_parser.h
index 82b4cd938..6689939ce 100644
--- a/src/trace_processor/importers/gzip/gzip_trace_parser.h
+++ b/src/trace_processor/importers/gzip/gzip_trace_parser.h
@@ -18,7 +18,7 @@
#define SRC_TRACE_PROCESSOR_IMPORTERS_GZIP_GZIP_TRACE_PARSER_H_
#include "src/trace_processor/importers/common/chunked_trace_reader.h"
-#include "src/trace_processor/importers/gzip/gzip_utils.h"
+#include "src/trace_processor/util/gzip_utils.h"
namespace perfetto {
namespace trace_processor {
@@ -32,7 +32,7 @@ class GzipTraceParser : public ChunkedTraceReader {
~GzipTraceParser() override;
// ChunkedTraceReader implementation
- util::Status Parse(std::unique_ptr<uint8_t[]>, size_t) override;
+ util::Status Parse(TraceBlobView) override;
void NotifyEndOfFile() override;
util::Status ParseUnowned(const uint8_t*, size_t);
@@ -41,7 +41,7 @@ class GzipTraceParser : public ChunkedTraceReader {
private:
TraceProcessorContext* const context_;
- GzipDecompressor decompressor_;
+ util::GzipDecompressor decompressor_;
std::unique_ptr<ChunkedTraceReader> inner_;
std::unique_ptr<uint8_t[]> buffer_;
diff --git a/src/trace_processor/importers/gzip/gzip_utils.cc b/src/trace_processor/importers/gzip/gzip_utils.cc
deleted file mode 100644
index 8a30c7f32..000000000
--- a/src/trace_processor/importers/gzip/gzip_utils.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/trace_processor/importers/gzip/gzip_utils.h"
-
-// For bazel build.
-#include "perfetto/base/build_config.h"
-#include "perfetto/base/compiler.h"
-
-#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
-#include <zlib.h>
-#else
-struct z_stream_s {};
-#endif
-
-namespace perfetto {
-namespace trace_processor {
-namespace gzip {
-
-bool IsGzipSupported() {
-#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
- return true;
-#else
- return false;
-#endif
-}
-
-} // namespace gzip
-
-#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
-GzipDecompressor::GzipDecompressor() : z_stream_(new z_stream()) {
- z_stream_->zalloc = Z_NULL;
- z_stream_->zfree = Z_NULL;
- z_stream_->opaque = Z_NULL;
- inflateInit2(z_stream_.get(), 32 + 15);
-}
-#else
-GzipDecompressor::GzipDecompressor() = default;
-#endif
-
-GzipDecompressor::~GzipDecompressor() {
-#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
- // Ensure the call to inflateEnd to prevent leaks of internal state.
- inflateEnd(z_stream_.get());
-#endif
-}
-
-void GzipDecompressor::Reset() {
-#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
- inflateReset(z_stream_.get());
-#endif
-}
-
-void GzipDecompressor::SetInput(const uint8_t* data, size_t size) {
-#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
- // This const_cast is not harmfull as zlib will not modify the data in this
- // pointer. This is only necessary because of the build flags we use to be
- // compatible with other embedders.
- z_stream_->next_in = const_cast<uint8_t*>(data);
- z_stream_->avail_in = static_cast<uInt>(size);
-#else
- base::ignore_result(data);
- base::ignore_result(size);
-#endif
-}
-
-GzipDecompressor::Result GzipDecompressor::Decompress(uint8_t* out,
- size_t out_size) {
-#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
- if (z_stream_->avail_in == 0)
- return Result{ResultCode::kNeedsMoreInput, 0};
-
- z_stream_->next_out = out;
- z_stream_->avail_out = static_cast<uInt>(out_size);
-
- int ret = inflate(z_stream_.get(), Z_NO_FLUSH);
- switch (ret) {
- case Z_NEED_DICT:
- case Z_DATA_ERROR:
- case Z_MEM_ERROR:
- // Ignore inflateEnd error as we will error out anyway.
- inflateEnd(z_stream_.get());
- return Result{ResultCode::kError, 0};
- case Z_STREAM_END:
- return Result{ResultCode::kEof, out_size - z_stream_->avail_out};
- case Z_BUF_ERROR:
- return Result{ResultCode::kNoProgress, 0};
- default:
- return Result{ResultCode::kOk, out_size - z_stream_->avail_out};
- }
-#else
- base::ignore_result(out);
- base::ignore_result(out_size);
- return Result{ResultCode::kError, 0};
-#endif
-}
-
-} // namespace trace_processor
-} // namespace perfetto
diff --git a/src/trace_processor/importers/gzip/gzip_utils.h b/src/trace_processor/importers/gzip/gzip_utils.h
deleted file mode 100644
index 624363ff6..000000000
--- a/src/trace_processor/importers/gzip/gzip_utils.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_GZIP_GZIP_UTILS_H_
-#define SRC_TRACE_PROCESSOR_IMPORTERS_GZIP_GZIP_UTILS_H_
-
-#include <memory>
-
-struct z_stream_s;
-
-namespace perfetto {
-namespace trace_processor {
-
-namespace gzip {
-
-// Returns whether gzip related functioanlity is supported with the current
-// build flags.
-bool IsGzipSupported();
-
-} // namespace gzip
-
-class GzipDecompressor {
- public:
- enum class ResultCode {
- kOk,
- kEof,
- kError,
- kNoProgress,
- kNeedsMoreInput,
- };
- struct Result {
- // The return code of the decompression.
- ResultCode ret;
-
- // The amount of bytes written to output.
- // Only valid if |ResultCode::kOk|.
- size_t bytes_written;
- };
-
- GzipDecompressor();
- ~GzipDecompressor();
-
- // Sets the input pointer and size of the gzip stream to inflate.
- void SetInput(const uint8_t* data, size_t size);
-
- // Decompresses the input previously provided in |SetInput|.
- Result Decompress(uint8_t* out, size_t out_size);
-
- // Sets the state of the decompressor to reuse with other gzip streams.
- void Reset();
-
- private:
- std::unique_ptr<z_stream_s> z_stream_;
-};
-
-} // namespace trace_processor
-} // namespace perfetto
-
-#endif // SRC_TRACE_PROCESSOR_IMPORTERS_GZIP_GZIP_UTILS_H_
diff --git a/src/trace_processor/importers/json/json_trace_parser.cc b/src/trace_processor/importers/json/json_trace_parser.cc
index eabd57df1..600c4f006 100644
--- a/src/trace_processor/importers/json/json_trace_parser.cc
+++ b/src/trace_processor/importers/json/json_trace_parser.cc
@@ -16,21 +16,22 @@
#include "src/trace_processor/importers/json/json_trace_parser.h"
-#include <inttypes.h>
-
+#include <cinttypes>
#include <limits>
#include <string>
#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/string_view.h"
#include "perfetto/ext/base/utils.h"
+#include "src/trace_processor/importers/common/event_tracker.h"
#include "src/trace_processor/importers/common/flow_tracker.h"
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/importers/common/slice_tracker.h"
#include "src/trace_processor/importers/common/track_tracker.h"
-#include "src/trace_processor/importers/json/json_tracker.h"
#include "src/trace_processor/importers/json/json_utils.h"
+#include "src/trace_processor/tables/slice_tables.h"
#include "src/trace_processor/types/trace_processor_context.h"
namespace perfetto {
@@ -125,29 +126,139 @@ void JsonTraceParser::ParseTracePacket(int64_t timestamp,
inserter);
}
};
+
+ // Only used for 'B', 'E', and 'X' events so wrap in lambda so it gets
+ // ignored in other cases. This lambda is only safe to call within the
+ // scope of this function due to the capture by reference.
+ auto make_thread_slice_row = [&](TrackId track_id) {
+ tables::ThreadSliceTable::Row row;
+ row.ts = timestamp;
+ row.track_id = track_id;
+ row.category = cat_id;
+ row.name = name_id;
+ row.thread_ts = json::CoerceToTs(value["tts"]);
+ // tdur will only exist on 'X' events.
+ row.thread_dur = json::CoerceToTs(value["tdur"]);
+ // JSON traces don't report these counters as part of slices.
+ row.thread_instruction_count = base::nullopt;
+ row.thread_instruction_delta = base::nullopt;
+ return row;
+ };
+
switch (phase) {
case 'B': { // TRACE_EVENT_BEGIN.
TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
- slice_tracker->Begin(timestamp, track_id, cat_id, name_id, args_inserter);
+ slice_tracker->BeginTyped(storage->mutable_thread_slice_table(),
+ make_thread_slice_row(track_id), args_inserter);
MaybeAddFlow(track_id, value);
break;
}
case 'E': { // TRACE_EVENT_END.
TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
- slice_tracker->End(timestamp, track_id, cat_id, name_id, args_inserter);
+ auto opt_slice_id = slice_tracker->End(timestamp, track_id, cat_id,
+ name_id, args_inserter);
+ // Now try to update thread_dur if we have a tts field.
+ auto opt_tts = json::CoerceToTs(value["tts"]);
+ if (opt_slice_id.has_value() && opt_tts) {
+ auto* thread_slice = storage->mutable_thread_slice_table();
+ auto maybe_row = thread_slice->id().IndexOf(*opt_slice_id);
+ PERFETTO_DCHECK(maybe_row.has_value());
+ auto start_tts = thread_slice->thread_ts()[*maybe_row];
+ if (start_tts) {
+ thread_slice->mutable_thread_dur()->Set(*maybe_row,
+ *opt_tts - *start_tts);
+ }
+ }
break;
}
case 'X': { // TRACE_EVENT (scoped event).
- base::Optional<int64_t> opt_dur =
- JsonTracker::GetOrCreate(context_)->CoerceToTs(value["dur"]);
+ base::Optional<int64_t> opt_dur = json::CoerceToTs(value["dur"]);
if (!opt_dur.has_value())
return;
TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
- slice_tracker->Scoped(timestamp, track_id, cat_id, name_id,
- opt_dur.value(), args_inserter);
+ auto row = make_thread_slice_row(track_id);
+ row.dur = opt_dur.value();
+ slice_tracker->ScopedTyped(storage->mutable_thread_slice_table(),
+ std::move(row), args_inserter);
MaybeAddFlow(track_id, value);
break;
}
+ case 'C': { // TRACE_EVENT_COUNTER
+ auto args = value["args"];
+ if (!args.isObject()) {
+ context_->storage->IncrementStats(stats::json_parser_failure);
+ break;
+ }
+
+ std::string counter_name_prefix = name.ToStdString();
+ if (value.isMember("id")) {
+ counter_name_prefix += " id: " + value["id"].asString();
+ }
+
+ for (auto it = args.begin(); it != args.end(); ++it) {
+ double counter;
+ if (it->isString()) {
+ auto opt = base::CStringToDouble(it->asCString());
+ if (!opt.has_value()) {
+ context_->storage->IncrementStats(stats::json_parser_failure);
+ continue;
+ }
+ counter = opt.value();
+ } else if (it->isNumeric()) {
+ counter = it->asDouble();
+ } else {
+ context_->storage->IncrementStats(stats::json_parser_failure);
+ continue;
+ }
+ std::string counter_name = counter_name_prefix + " " + it.name();
+ StringId counter_name_id =
+ context_->storage->InternString(base::StringView(counter_name));
+ context_->event_tracker->PushProcessCounterForThread(
+ timestamp, counter, counter_name_id, utid);
+ }
+ break;
+ }
+ case 'i': { // TRACE_EVENT_INSTANT
+ base::StringView scope;
+ if (value.isMember("s")) {
+ scope = value["s"].asCString();
+ }
+
+ TrackId track_id;
+ if (scope == "g") {
+ track_id = context_->track_tracker
+ ->GetOrCreateLegacyChromeGlobalInstantTrack();
+ } else if (scope == "p") {
+ if (!opt_pid) {
+ context_->storage->IncrementStats(stats::json_parser_failure);
+ break;
+ }
+ UniquePid upid = context_->process_tracker->GetOrCreateProcess(pid);
+ track_id =
+ context_->track_tracker->InternLegacyChromeProcessInstantTrack(
+ upid);
+ } else if (scope == "t" || scope.data() == nullptr) {
+ if (!opt_tid) {
+ context_->storage->IncrementStats(stats::json_parser_failure);
+ break;
+ }
+ track_id = context_->track_tracker->InternThreadTrack(utid);
+ auto row = make_thread_slice_row(track_id);
+ row.dur = 0;
+ if (row.thread_ts) {
+ // Only set thread_dur to zero if we have a thread_ts.
+ row.thread_dur = 0;
+ }
+ slice_tracker->ScopedTyped(storage->mutable_thread_slice_table(),
+ std::move(row), args_inserter);
+ break;
+ } else {
+ context_->storage->IncrementStats(stats::json_parser_failure);
+ break;
+ }
+ context_->slice_tracker->Scoped(timestamp, track_id, cat_id, name_id, 0);
+ break;
+ }
case 's': { // TRACE_EVENT_FLOW_START
TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
auto opt_source_id =
@@ -191,16 +302,14 @@ void JsonTraceParser::ParseTracePacket(int64_t timestamp,
break;
}
case 'M': { // Metadata events (process and thread names).
- if (strcmp(value["name"].asCString(), "thread_name") == 0 &&
- !value["args"]["name"].empty()) {
+ if (name == "thread_name" && !value["args"]["name"].empty()) {
const char* thread_name = value["args"]["name"].asCString();
auto thread_name_id = context_->storage->InternString(thread_name);
procs->UpdateThreadName(tid, thread_name_id,
ThreadNamePriority::kOther);
break;
}
- if (strcmp(value["name"].asCString(), "process_name") == 0 &&
- !value["args"]["name"].empty()) {
+ if (name == "process_name" && !value["args"]["name"].empty()) {
const char* proc_name = value["args"]["name"].asCString();
procs->SetProcessMetadata(pid, base::nullopt, proc_name,
base::StringView());
@@ -241,4 +350,3 @@ void JsonTraceParser::MaybeAddFlow(TrackId track_id, const Json::Value& event) {
} // namespace trace_processor
} // namespace perfetto
-
diff --git a/src/trace_processor/importers/json/json_trace_parser.h b/src/trace_processor/importers/json/json_trace_parser.h
index 2084c4b6e..20d1e85a0 100644
--- a/src/trace_processor/importers/json/json_trace_parser.h
+++ b/src/trace_processor/importers/json/json_trace_parser.h
@@ -21,10 +21,8 @@
#include <memory>
#include <tuple>
-#include <unordered_map>
#include "src/trace_processor/importers/common/trace_parser.h"
-#include "src/trace_processor/importers/json/json_tracker.h"
#include "src/trace_processor/importers/systrace/systrace_line_parser.h"
#include "src/trace_processor/timestamped_trace_piece.h"
diff --git a/src/trace_processor/importers/json/json_trace_tokenizer.cc b/src/trace_processor/importers/json/json_trace_tokenizer.cc
index cdf7020c8..367703374 100644
--- a/src/trace_processor/importers/json/json_trace_tokenizer.cc
+++ b/src/trace_processor/importers/json/json_trace_tokenizer.cc
@@ -21,8 +21,7 @@
#include "perfetto/base/build_config.h"
#include "perfetto/ext/base/string_utils.h"
-#include "src/trace_processor/importers/common/trace_blob_view.h"
-#include "src/trace_processor/importers/json/json_tracker.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
#include "src/trace_processor/importers/json/json_utils.h"
#include "src/trace_processor/storage/stats.h"
#include "src/trace_processor/trace_sorter.h"
@@ -33,8 +32,6 @@ namespace trace_processor {
namespace {
-#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
-
util::Status AppendUnescapedCharacter(char c,
bool is_escaping,
std::string* key) {
@@ -60,9 +57,12 @@ util::Status AppendUnescapedCharacter(char c,
case 't':
key->push_back('\t');
break;
+ case 'u':
+ // Just pass through \uxxxx escape sequences which JSON supports but is
+ // not worth the effort to parse as we never use them here.
+ key->append("\\u");
+ break;
default:
- // We don't support any other escape sequences (concretely \uxxxx
- // which JSON supports but is too much effort for us to parse).
return util::ErrStatus("Illegal character in JSON");
}
} else if (c != '\\') {
@@ -103,11 +103,8 @@ ReadStringRes ReadOneJsonString(const char* start,
return ReadStringRes::kNeedsMoreData;
}
-#endif // PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
-
} // namespace
-#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
ReadDictRes ReadOneJsonDict(const char* start,
const char* end,
base::StringView* value,
@@ -365,37 +362,19 @@ ReadSystemLineRes ReadOneSystemTraceLine(const char* start,
}
return ReadSystemLineRes::kNeedsMoreData;
}
-#endif // PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
JsonTraceTokenizer::JsonTraceTokenizer(TraceProcessorContext* ctx)
: context_(ctx) {}
JsonTraceTokenizer::~JsonTraceTokenizer() = default;
-util::Status JsonTraceTokenizer::Parse(std::unique_ptr<uint8_t[]> data,
- size_t size) {
+util::Status JsonTraceTokenizer::Parse(TraceBlobView blob) {
PERFETTO_DCHECK(json::IsJsonSupported());
-#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
- buffer_.insert(buffer_.end(), data.get(), data.get() + size);
+ buffer_.insert(buffer_.end(), blob.data(), blob.data() + blob.size());
const char* buf = buffer_.data();
const char* next = buf;
const char* end = buf + buffer_.size();
- JsonTracker* json_tracker = JsonTracker::GetOrCreate(context_);
-
- // It's possible the displayTimeUnit key is at the end of the json
- // file so to be correct we ought to parse the whole file looking
- // for this key before parsing any events however this would require
- // two passes on the file so for now we only handle displayTimeUnit
- // correctly if it is at the beginning of the file.
- const base::StringView view(buf, size);
- if (view.find("\"displayTimeUnit\":\"ns\"") != base::StringView::npos) {
- json_tracker->SetTimeUnit(json::TimeUnit::kNs);
- } else if (view.find("\"displayTimeUnit\":\"ms\"") !=
- base::StringView::npos) {
- json_tracker->SetTimeUnit(json::TimeUnit::kMs);
- }
-
if (offset_ == 0) {
// Strip leading whitespace.
while (next != end && isspace(*next)) {
@@ -436,23 +415,12 @@ util::Status JsonTraceTokenizer::Parse(std::unique_ptr<uint8_t[]> data,
offset_ += static_cast<uint64_t>(next - buf);
buffer_.erase(buffer_.begin(), buffer_.begin() + (next - buf));
return util::OkStatus();
-#else
- perfetto::base::ignore_result(data);
- perfetto::base::ignore_result(size);
- perfetto::base::ignore_result(context_);
- perfetto::base::ignore_result(format_);
- perfetto::base::ignore_result(position_);
- perfetto::base::ignore_result(offset_);
- return util::ErrStatus("Cannot parse JSON trace due to missing JSON support");
-#endif // PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
}
-#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
util::Status JsonTraceTokenizer::ParseInternal(const char* start,
const char* end,
const char** out) {
PERFETTO_DCHECK(json::IsJsonSupported());
- JsonTracker* json_tracker = JsonTracker::GetOrCreate(context_);
auto* trace_sorter = context_->sorter.get();
const char* next = start;
@@ -484,13 +452,22 @@ util::Status JsonTraceTokenizer::ParseInternal(const char* start,
return ParseInternal(next + 1, end, out);
} else if (key == "displayTimeUnit") {
std::string time_unit;
- auto string_res = ReadOneJsonString(next + 1, end, &time_unit, &next);
- if (string_res == ReadStringRes::kFatalError)
+ auto result = ReadOneJsonString(next + 1, end, &time_unit, &next);
+ if (result == ReadStringRes::kFatalError)
return util::ErrStatus("Could not parse displayTimeUnit");
- if (string_res == ReadStringRes::kNeedsMoreData)
- return util::ErrStatus("displayTimeUnit too large");
- if (time_unit != "ms" && time_unit != "ns")
- return util::ErrStatus("displayTimeUnit unknown");
+ context_->storage->IncrementStats(stats::json_display_time_unit);
+ return ParseInternal(next, end, out);
+ } else if (key == "otherData") {
+ base::StringView unparsed;
+ const auto other = ReadOneJsonDict(next, end, &unparsed, &next);
+ if (other == ReadDictRes::kEndOfArray)
+ return util::ErrStatus(
+ "Failure parsing JSON: Missing ] in otherData");
+ if (other == ReadDictRes::kEndOfTrace)
+ return util::ErrStatus(
+ "Failure parsing JSON: Failed parsing otherData");
+ if (other == ReadDictRes::kNeedsMoreData)
+ return util::ErrStatus("Failure parsing JSON: otherData too large");
return ParseInternal(next, end, out);
} else {
// If we don't recognize the key, just ignore the rest of the trace and
@@ -571,7 +548,7 @@ util::Status JsonTraceTokenizer::ParseInternal(const char* start,
base::Optional<std::string> opt_raw_ts;
RETURN_IF_ERROR(ExtractValueForJsonKey(unparsed, "ts", &opt_raw_ts));
base::Optional<int64_t> opt_ts =
- opt_raw_ts ? json_tracker->CoerceToTs(*opt_raw_ts) : base::nullopt;
+ opt_raw_ts ? json::CoerceToTs(*opt_raw_ts) : base::nullopt;
int64_t ts = 0;
if (opt_ts.has_value()) {
ts = opt_ts.value();
@@ -595,7 +572,6 @@ util::Status JsonTraceTokenizer::ParseInternal(const char* start,
*out = next;
return util::OkStatus();
}
-#endif // PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
void JsonTraceTokenizer::NotifyEndOfFile() {}
diff --git a/src/trace_processor/importers/json/json_trace_tokenizer.h b/src/trace_processor/importers/json/json_trace_tokenizer.h
index 86f573191..8074b6132 100644
--- a/src/trace_processor/importers/json/json_trace_tokenizer.h
+++ b/src/trace_processor/importers/json/json_trace_tokenizer.h
@@ -20,6 +20,7 @@
#include <stdint.h>
#include "src/trace_processor/importers/common/chunked_trace_reader.h"
+#include "src/trace_processor/importers/json/json_utils.h"
#include "src/trace_processor/importers/systrace/systrace_line_tokenizer.h"
#include "src/trace_processor/storage/trace_storage.h"
@@ -32,7 +33,6 @@ namespace trace_processor {
class TraceProcessorContext;
-#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
// Visible for testing.
enum class ReadDictRes {
kFoundDict,
@@ -93,7 +93,6 @@ ReadSystemLineRes ReadOneSystemTraceLine(const char* start,
const char* end,
std::string* line,
const char** next);
-#endif
// Reads a JSON trace in chunks and extracts top level json objects.
class JsonTraceTokenizer : public ChunkedTraceReader {
@@ -102,7 +101,7 @@ class JsonTraceTokenizer : public ChunkedTraceReader {
~JsonTraceTokenizer() override;
// ChunkedTraceReader implementation.
- util::Status Parse(std::unique_ptr<uint8_t[]>, size_t) override;
+ util::Status Parse(TraceBlobView) override;
void NotifyEndOfFile() override;
private:
@@ -139,11 +138,9 @@ class JsonTraceTokenizer : public ChunkedTraceReader {
kEof,
};
-#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
util::Status ParseInternal(const char* start,
const char* end,
const char** next);
-#endif
TraceProcessorContext* const context_;
diff --git a/src/trace_processor/importers/json/json_tracker.cc b/src/trace_processor/importers/json/json_tracker.cc
deleted file mode 100644
index 971042ad2..000000000
--- a/src/trace_processor/importers/json/json_tracker.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/trace_processor/importers/json/json_tracker.h"
-
-namespace perfetto {
-namespace trace_processor {
-
-JsonTracker::JsonTracker(TraceProcessorContext*) {}
-JsonTracker::~JsonTracker() = default;
-
-} // namespace trace_processor
-} // namespace perfetto
diff --git a/src/trace_processor/importers/json/json_tracker.h b/src/trace_processor/importers/json/json_tracker.h
deleted file mode 100644
index d786bf1ab..000000000
--- a/src/trace_processor/importers/json/json_tracker.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_JSON_JSON_TRACKER_H_
-#define SRC_TRACE_PROCESSOR_IMPORTERS_JSON_JSON_TRACKER_H_
-
-#include "src/trace_processor/importers/json/json_utils.h"
-#include "src/trace_processor/types/destructible.h"
-#include "src/trace_processor/types/trace_processor_context.h"
-
-namespace Json {
-class Value;
-}
-
-namespace perfetto {
-namespace trace_processor {
-
-class JsonTracker : public Destructible {
- public:
- JsonTracker(const JsonTracker&) = delete;
- JsonTracker& operator=(const JsonTracker&) = delete;
- explicit JsonTracker(TraceProcessorContext*);
- ~JsonTracker() override;
-
- static JsonTracker* GetOrCreate(TraceProcessorContext* context) {
- if (!context->json_tracker) {
- context->json_tracker.reset(new JsonTracker(context));
- }
- return static_cast<JsonTracker*>(context->json_tracker.get());
- }
-
- void SetTimeUnit(json::TimeUnit time_unit) { time_unit_ = time_unit; }
-
- base::Optional<int64_t> CoerceToTs(const Json::Value& value) {
- return json::CoerceToTs(time_unit_, value);
- }
-
- private:
- json::TimeUnit time_unit_ = json::TimeUnit::kUs;
-};
-
-} // namespace trace_processor
-} // namespace perfetto
-
-#endif // SRC_TRACE_PROCESSOR_IMPORTERS_JSON_JSON_TRACKER_H_
diff --git a/src/trace_processor/importers/json/json_tracker_unittest.cc b/src/trace_processor/importers/json/json_tracker_unittest.cc
deleted file mode 100644
index 4ae60099f..000000000
--- a/src/trace_processor/importers/json/json_tracker_unittest.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/trace_processor/importers/json/json_tracker.h"
-
-#include "test/gtest_and_gmock.h"
-
-#include <json/value.h>
-
-namespace perfetto {
-namespace trace_processor {
-namespace {
-
-TEST(JsonTrackerTest, Ns) {
- JsonTracker tracker(nullptr);
- tracker.SetTimeUnit(json::TimeUnit::kNs);
- ASSERT_EQ(tracker.CoerceToTs(Json::Value(42)).value_or(-1), 42);
-}
-
-TEST(JsonTraceUtilsTest, Us) {
- JsonTracker tracker(nullptr);
- ASSERT_EQ(tracker.CoerceToTs(Json::Value(42)).value_or(-1), 42000);
-}
-
-} // namespace
-} // namespace trace_processor
-} // namespace perfetto
diff --git a/src/trace_processor/importers/json/json_utils.cc b/src/trace_processor/importers/json/json_utils.cc
index 5d0b2d13a..432ddbefc 100644
--- a/src/trace_processor/importers/json/json_utils.cc
+++ b/src/trace_processor/importers/json/json_utils.cc
@@ -28,15 +28,6 @@
namespace perfetto {
namespace trace_processor {
namespace json {
-namespace {
-
-#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
-int64_t TimeUnitToNs(TimeUnit unit) {
- return static_cast<int64_t>(unit);
-}
-#endif
-
-} // namespace
bool IsJsonSupported() {
#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
@@ -46,43 +37,48 @@ bool IsJsonSupported() {
#endif
}
-base::Optional<int64_t> CoerceToTs(TimeUnit unit, const Json::Value& value) {
+base::Optional<int64_t> CoerceToTs(const Json::Value& value) {
PERFETTO_DCHECK(IsJsonSupported());
#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
switch (static_cast<size_t>(value.type())) {
case Json::realValue:
- return static_cast<int64_t>(value.asDouble() *
- static_cast<double>(TimeUnitToNs(unit)));
+ return static_cast<int64_t>(value.asDouble() * 1000.0);
case Json::uintValue:
case Json::intValue:
- return value.asInt64() * TimeUnitToNs(unit);
- case Json::stringValue: {
- std::string s = value.asString();
- size_t lhs_end = std::min<size_t>(s.find('.'), s.size());
- size_t rhs_start = std::min<size_t>(lhs_end + 1, s.size());
- base::Optional<int64_t> lhs = base::StringToInt64(s.substr(0, lhs_end));
- base::Optional<double> rhs =
- base::StringToDouble("0." + s.substr(rhs_start, std::string::npos));
- if ((!lhs.has_value() && lhs_end > 0) ||
- (!rhs.has_value() && rhs_start < s.size())) {
- return base::nullopt;
- }
- int64_t factor = TimeUnitToNs(unit);
- return lhs.value_or(0) * factor +
- static_cast<int64_t>(rhs.value_or(0) *
- static_cast<double>(factor));
- }
+ return value.asInt64() * 1000;
+ case Json::stringValue:
+ return CoerceToTs(value.asString());
default:
return base::nullopt;
}
#else
- perfetto::base::ignore_result(unit);
perfetto::base::ignore_result(value);
return base::nullopt;
#endif
}
+base::Optional<int64_t> CoerceToTs(const std::string& s) {
+ PERFETTO_DCHECK(IsJsonSupported());
+
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
+ size_t lhs_end = std::min<size_t>(s.find('.'), s.size());
+ size_t rhs_start = std::min<size_t>(lhs_end + 1, s.size());
+ base::Optional<int64_t> lhs = base::StringToInt64(s.substr(0, lhs_end));
+ base::Optional<double> rhs =
+ base::StringToDouble("0." + s.substr(rhs_start, std::string::npos));
+ if ((!lhs.has_value() && lhs_end > 0) ||
+ (!rhs.has_value() && rhs_start < s.size())) {
+ return base::nullopt;
+ }
+ return lhs.value_or(0) * 1000 +
+ static_cast<int64_t>(rhs.value_or(0) * 1000.0);
+#else
+ perfetto::base::ignore_result(s);
+ return base::nullopt;
+#endif
+}
+
base::Optional<int64_t> CoerceToInt64(const Json::Value& value) {
PERFETTO_DCHECK(IsJsonSupported());
diff --git a/src/trace_processor/importers/json/json_utils.h b/src/trace_processor/importers/json/json_utils.h
index f4a70b3bd..1cbcae837 100644
--- a/src/trace_processor/importers/json/json_utils.h
+++ b/src/trace_processor/importers/json/json_utils.h
@@ -40,8 +40,8 @@ namespace json {
// build flags.
bool IsJsonSupported();
-enum class TimeUnit { kNs = 1, kUs = 1000, kMs = 1000000 };
-base::Optional<int64_t> CoerceToTs(TimeUnit unit, const Json::Value& value);
+base::Optional<int64_t> CoerceToTs(const Json::Value& value);
+base::Optional<int64_t> CoerceToTs(const std::string& value);
base::Optional<int64_t> CoerceToInt64(const Json::Value& value);
base::Optional<uint32_t> CoerceToUint32(const Json::Value& value);
diff --git a/src/trace_processor/importers/json/json_utils_unittest.cc b/src/trace_processor/importers/json/json_utils_unittest.cc
index a3846ea2f..7f01ad646 100644
--- a/src/trace_processor/importers/json/json_utils_unittest.cc
+++ b/src/trace_processor/importers/json/json_utils_unittest.cc
@@ -43,26 +43,17 @@ TEST(JsonTraceUtilsTest, CoerceToInt64) {
}
TEST(JsonTraceUtilsTest, CoerceToTs) {
- ASSERT_EQ(CoerceToTs(TimeUnit::kUs, Json::Value(42)).value_or(-1), 42000);
- ASSERT_EQ(CoerceToTs(TimeUnit::kUs, Json::Value("42")).value_or(-1), 42000);
- ASSERT_EQ(CoerceToTs(TimeUnit::kUs, Json::Value(42.1)).value_or(-1), 42100);
- ASSERT_EQ(CoerceToTs(TimeUnit::kUs, Json::Value("42.1")).value_or(-1), 42100);
- ASSERT_EQ(CoerceToTs(TimeUnit::kUs, Json::Value(".42")).value_or(-1), 420);
- ASSERT_EQ(CoerceToTs(TimeUnit::kUs, Json::Value("42.")).value_or(-1), 42000);
- ASSERT_EQ(CoerceToTs(TimeUnit::kUs, Json::Value("42.0")).value_or(-1), 42000);
- ASSERT_EQ(CoerceToTs(TimeUnit::kUs, Json::Value("0.2")).value_or(-1), 200);
- ASSERT_EQ(CoerceToTs(TimeUnit::kUs, Json::Value("0.2e-1")).value_or(-1), 20);
- ASSERT_EQ(CoerceToTs(TimeUnit::kNs, Json::Value(42)).value_or(-1), 42);
- ASSERT_EQ(CoerceToTs(TimeUnit::kMs, Json::Value(42)).value_or(-1), 42000000);
- ASSERT_EQ(CoerceToTs(TimeUnit::kUs, Json::Value(".")).value_or(-1), 0);
- ASSERT_FALSE(CoerceToTs(TimeUnit::kNs, Json::Value("foo")).has_value());
- ASSERT_FALSE(CoerceToTs(TimeUnit::kNs, Json::Value(".foo")).has_value());
- ASSERT_FALSE(CoerceToTs(TimeUnit::kNs, Json::Value("0.foo")).has_value());
- ASSERT_FALSE(CoerceToTs(TimeUnit::kNs, Json::Value("foo0.23")).has_value());
- ASSERT_FALSE(CoerceToTs(TimeUnit::kNs, Json::Value("23.12foo")).has_value());
- ASSERT_FALSE(CoerceToTs(TimeUnit::kNs, Json::Value("1234!")).has_value());
- ASSERT_FALSE(CoerceToTs(TimeUnit::kUs, Json::Value("1234!")).has_value());
- ASSERT_FALSE(CoerceToTs(TimeUnit::kMs, Json::Value("1234!")).has_value());
+ ASSERT_EQ(CoerceToTs(Json::Value(42)).value_or(-1), 42000);
+ ASSERT_EQ(CoerceToTs(Json::Value("42")).value_or(-1), 42000);
+ ASSERT_EQ(CoerceToTs(Json::Value(42.1)).value_or(-1), 42100);
+ ASSERT_EQ(CoerceToTs(Json::Value("42.1")).value_or(-1), 42100);
+ ASSERT_EQ(CoerceToTs(Json::Value(".42")).value_or(-1), 420);
+ ASSERT_EQ(CoerceToTs(Json::Value("42.")).value_or(-1), 42000);
+ ASSERT_EQ(CoerceToTs(Json::Value("42.0")).value_or(-1), 42000);
+ ASSERT_EQ(CoerceToTs(Json::Value("0.2")).value_or(-1), 200);
+ ASSERT_EQ(CoerceToTs(Json::Value("0.2e-1")).value_or(-1), 20);
+ ASSERT_EQ(CoerceToTs(Json::Value(".")).value_or(-1), 0);
+ ASSERT_FALSE(CoerceToTs(Json::Value("1234!")).has_value());
}
} // namespace
diff --git a/src/trace_processor/importers/memory_tracker/graph_processor_unittest.cc b/src/trace_processor/importers/memory_tracker/graph_processor_unittest.cc
index 8d1cc3149..4275b36e7 100644
--- a/src/trace_processor/importers/memory_tracker/graph_processor_unittest.cc
+++ b/src/trace_processor/importers/memory_tracker/graph_processor_unittest.cc
@@ -18,8 +18,6 @@
#include <stddef.h>
-#include <unordered_map>
-
#include "perfetto/base/build_config.h"
#include "test/gtest_and_gmock.h"
diff --git a/src/trace_processor/importers/memory_tracker/memory_allocator_node_id.cc b/src/trace_processor/importers/memory_tracker/memory_allocator_node_id.cc
index 9d801016a..6fe4d4a1c 100644
--- a/src/trace_processor/importers/memory_tracker/memory_allocator_node_id.cc
+++ b/src/trace_processor/importers/memory_tracker/memory_allocator_node_id.cc
@@ -16,10 +16,12 @@
#include "perfetto/ext/trace_processor/importers/memory_tracker/memory_allocator_node_id.h"
-#include <inttypes.h>
#include <stdio.h>
+#include <cinttypes>
+
#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/string_utils.h"
namespace perfetto {
namespace trace_processor {
@@ -32,9 +34,8 @@ std::string MemoryAllocatorNodeId::ToString() const {
size_t max_size = 19; // Max uint64 is 0xFFFFFFFFFFFFFFFF + 1 for null byte.
std::string buf;
buf.resize(max_size);
- auto final_size = snprintf(&buf[0], max_size, "%" PRIu64, id_);
- PERFETTO_DCHECK(final_size >= 0);
- buf.resize(static_cast<size_t>(final_size)); // Cuts off the final null byte.
+ size_t final_size = base::SprintfTrunc(&buf[0], max_size, "%" PRIu64, id_);
+ buf.resize(final_size); // Cuts off the final null byte.
return buf;
}
diff --git a/src/trace_processor/importers/memory_tracker/raw_process_memory_node.cc b/src/trace_processor/importers/memory_tracker/raw_process_memory_node.cc
index faaf0848f..73ee3f1fc 100644
--- a/src/trace_processor/importers/memory_tracker/raw_process_memory_node.cc
+++ b/src/trace_processor/importers/memory_tracker/raw_process_memory_node.cc
@@ -16,10 +16,10 @@
#include "perfetto/ext/trace_processor/importers/memory_tracker/raw_process_memory_node.h"
-#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
+#include <cinttypes>
#include <functional>
#include <memory>
diff --git a/src/trace_processor/importers/memory_tracker/raw_process_memory_node_unittest.cc b/src/trace_processor/importers/memory_tracker/raw_process_memory_node_unittest.cc
index 91a27ec0f..653dfe01b 100644
--- a/src/trace_processor/importers/memory_tracker/raw_process_memory_node_unittest.cc
+++ b/src/trace_processor/importers/memory_tracker/raw_process_memory_node_unittest.cc
@@ -18,8 +18,6 @@
#include <stddef.h>
-#include <unordered_map>
-
#include "perfetto/base/build_config.h"
#include "test/gtest_and_gmock.h"
diff --git a/src/trace_processor/importers/ninja/ninja_log_parser.cc b/src/trace_processor/importers/ninja/ninja_log_parser.cc
index af668f1d1..bf186bb90 100644
--- a/src/trace_processor/importers/ninja/ninja_log_parser.cc
+++ b/src/trace_processor/importers/ninja/ninja_log_parser.cc
@@ -32,13 +32,13 @@ using base::StringSplitter;
NinjaLogParser::NinjaLogParser(TraceProcessorContext* ctx) : ctx_(ctx) {}
NinjaLogParser::~NinjaLogParser() = default;
-util::Status NinjaLogParser::Parse(std::unique_ptr<uint8_t[]> buf, size_t len) {
+util::Status NinjaLogParser::Parse(TraceBlobView blob) {
// A trace is read in chunks of arbitrary size (for http fetch() pipeliniing),
// not necessarily aligned on a line boundary.
// Here we push everything into a vector and, on each call, consume only
// the leading part until the last \n, keeping the rest for the next call.
- const char* src = reinterpret_cast<const char*>(&buf[0]);
- log_.insert(log_.end(), src, src + len);
+ const char* src = reinterpret_cast<const char*>(blob.data());
+ log_.insert(log_.end(), src, src + blob.size());
// Find the last \n.
size_t valid_size = log_.size();
@@ -167,9 +167,8 @@ void NinjaLogParser::NotifyEndOfFile() {
} else {
// All workers are busy, allocate a new one.
uint32_t worker_id = ++last_worker_id;
- char name[32];
- snprintf(name, sizeof(name), "Worker %zu", workers.size() + 1);
- StringId name_id = ctx_->storage->InternString(name);
+ base::StackString<32> name("Worker %zu", workers.size() + 1);
+ StringId name_id = ctx_->storage->InternString(name.string_view());
auto utid = ctx_->process_tracker->UpdateThread(worker_id, job.build_id);
ctx_->process_tracker->UpdateThreadNameByUtid(utid, name_id,
ThreadNamePriority::kOther);
diff --git a/src/trace_processor/importers/ninja/ninja_log_parser.h b/src/trace_processor/importers/ninja/ninja_log_parser.h
index f010e7316..39a0806e9 100644
--- a/src/trace_processor/importers/ninja/ninja_log_parser.h
+++ b/src/trace_processor/importers/ninja/ninja_log_parser.h
@@ -50,7 +50,7 @@ class NinjaLogParser : public ChunkedTraceReader {
NinjaLogParser& operator=(const NinjaLogParser&) = delete;
// ChunkedTraceReader implementation
- util::Status Parse(std::unique_ptr<uint8_t[]>, size_t) override;
+ util::Status Parse(TraceBlobView) override;
void NotifyEndOfFile() override;
private:
diff --git a/src/trace_processor/importers/proto/android_camera_event_module.cc b/src/trace_processor/importers/proto/android_camera_event_module.cc
new file mode 100644
index 000000000..708231041
--- /dev/null
+++ b/src/trace_processor/importers/proto/android_camera_event_module.cc
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "src/trace_processor/importers/proto/android_camera_event_module.h"
+
+#include "perfetto/ext/base/string_utils.h"
+#include "protos/perfetto/trace/android/camera_event.pbzero.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+#include "src/trace_processor/importers/common/slice_tracker.h"
+#include "src/trace_processor/importers/common/track_tracker.h"
+#include "src/trace_processor/importers/proto/async_track_set_tracker.h"
+#include "src/trace_processor/storage/trace_storage.h"
+#include "src/trace_processor/timestamped_trace_piece.h"
+#include "src/trace_processor/trace_sorter.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+using perfetto::protos::pbzero::TracePacket;
+
+AndroidCameraEventModule::AndroidCameraEventModule(
+ TraceProcessorContext* context)
+ : context_(context) {
+ RegisterForField(TracePacket::kAndroidCameraFrameEventFieldNumber, context);
+}
+
+AndroidCameraEventModule::~AndroidCameraEventModule() = default;
+
+ModuleResult AndroidCameraEventModule::TokenizePacket(
+ const protos::pbzero::TracePacket::Decoder& decoder,
+ TraceBlobView* packet,
+ int64_t /*packet_timestamp*/,
+ PacketSequenceState* state,
+ uint32_t field_id) {
+ if (field_id != TracePacket::kAndroidCameraFrameEventFieldNumber) {
+ return ModuleResult::Ignored();
+ }
+ const auto android_camera_frame_event =
+ protos::pbzero::AndroidCameraFrameEvent::Decoder(
+ decoder.android_camera_frame_event());
+ context_->sorter->PushTracePacket(
+ android_camera_frame_event.request_processing_started_ns(), state,
+ std::move(*packet));
+ return ModuleResult::Handled();
+}
+
+void AndroidCameraEventModule::ParsePacket(const TracePacket::Decoder& decoder,
+ const TimestampedTracePiece& /*ttp*/,
+ uint32_t field_id) {
+ if (field_id != TracePacket::kAndroidCameraFrameEventFieldNumber) {
+ return;
+ }
+ InsertCameraFrameSlice(decoder.android_camera_frame_event());
+}
+
+void AndroidCameraEventModule::InsertCameraFrameSlice(
+ protozero::ConstBytes bytes) {
+ const auto android_camera_frame_event =
+ protos::pbzero::AndroidCameraFrameEvent::Decoder(bytes);
+ StringId track_name = context_->storage->InternString(
+ base::StackString<32>("Camera %d Frames",
+ android_camera_frame_event.camera_id())
+ .string_view());
+ StringId slice_name = context_->storage->InternString(
+ base::StackString<32>("Frame %" PRId64,
+ android_camera_frame_event.frame_number())
+ .string_view());
+ int64_t ts = android_camera_frame_event.request_processing_started_ns();
+ int64_t dur = android_camera_frame_event.responses_all_sent_ns() -
+ android_camera_frame_event.request_processing_started_ns();
+ auto track_set_id =
+ context_->async_track_set_tracker->InternGlobalTrackSet(track_name);
+ auto track_id =
+ context_->async_track_set_tracker->Scoped(track_set_id, ts, dur);
+ context_->slice_tracker->Scoped(ts, track_id, /*category=*/kNullStringId,
+ slice_name, dur);
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/proto/android_camera_event_module.h b/src/trace_processor/importers/proto/android_camera_event_module.h
new file mode 100644
index 000000000..fd117c60c
--- /dev/null
+++ b/src/trace_processor/importers/proto/android_camera_event_module.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ANDROID_CAMERA_EVENT_MODULE_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ANDROID_CAMERA_EVENT_MODULE_H_
+
+#include <cstdint>
+#include <unordered_map>
+
+#include "perfetto/ext/base/optional.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+#include "src/trace_processor/importers/proto/proto_importer_module.h"
+#include "src/trace_processor/tables/slice_tables.h"
+#include "src/trace_processor/tables/track_tables.h"
+#include "src/trace_processor/types/trace_processor_context.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class AndroidCameraEventModule : public ProtoImporterModule {
+ public:
+ explicit AndroidCameraEventModule(TraceProcessorContext* context);
+
+ ~AndroidCameraEventModule() override;
+
+ ModuleResult TokenizePacket(const protos::pbzero::TracePacket::Decoder& decoder,
+ TraceBlobView* packet,
+ int64_t packet_timestamp,
+ PacketSequenceState* state,
+ uint32_t field_id) override;
+
+ void ParsePacket(const protos::pbzero::TracePacket::Decoder& decoder,
+ const TimestampedTracePiece& ttp,
+ uint32_t field_id) override;
+
+ private:
+ void InsertCameraFrameSlice(protozero::ConstBytes bytes);
+
+ TraceProcessorContext* context_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ANDROID_CAMERA_EVENT_MODULE_H_
diff --git a/src/trace_processor/importers/proto/android_probes_module.cc b/src/trace_processor/importers/proto/android_probes_module.cc
index 604741932..559c78eb9 100644
--- a/src/trace_processor/importers/proto/android_probes_module.cc
+++ b/src/trace_processor/importers/proto/android_probes_module.cc
@@ -41,7 +41,9 @@ const char* MapToFriendlyPowerRailName(base::StringView raw) {
return "cpu.big";
} else if (raw == "S5M_VDD_INT") {
return "system.fabric";
- } else if (raw == "PPVAR_VSYS_PWR_DISP") {
+ } else if (raw == "S10M_VDD_TPU") {
+ return "tpu";
+ } else if (raw == "PPVAR_VSYS_PWR_DISP" || raw == "VSYS_PWR_DISPLAY") {
return "display";
} else if (raw == "VSYS_PWR_MODEM") {
return "modem";
@@ -148,10 +150,9 @@ ModuleResult AndroidProbesModule::TokenizePacket(
energy->set_timestamp_ms(static_cast<uint64_t>(actual_ts / 1000000));
std::vector<uint8_t> vec = data_packet.SerializeAsArray();
- std::unique_ptr<uint8_t[]> buffer(new uint8_t[vec.size()]);
- memcpy(buffer.get(), vec.data(), vec.size());
- context_->sorter->PushTracePacket(
- actual_ts, state, TraceBlobView(std::move(buffer), 0, vec.size()));
+ TraceBlob blob = TraceBlob::CopyFrom(vec.data(), vec.size());
+ context_->sorter->PushTracePacket(actual_ts, state,
+ TraceBlobView(std::move(blob)));
}
return ModuleResult::Handled();
diff --git a/src/trace_processor/importers/proto/android_probes_parser.cc b/src/trace_processor/importers/proto/android_probes_parser.cc
index c001cb5ee..882191d10 100644
--- a/src/trace_processor/importers/proto/android_probes_parser.cc
+++ b/src/trace_processor/importers/proto/android_probes_parser.cc
@@ -17,6 +17,7 @@
#include "src/trace_processor/importers/proto/android_probes_parser.h"
#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/traced/sys_stats_counters.h"
#include "src/trace_processor/importers/common/args_tracker.h"
#include "src/trace_processor/importers/common/clock_tracker.h"
@@ -140,24 +141,27 @@ void AndroidProbesParser::ParseAndroidLogEvent(ConstBytes blob) {
char* arg_str = &arg_msg[0];
*arg_str = '\0';
auto arg_avail = [&arg_msg, &arg_str]() {
- return sizeof(arg_msg) - static_cast<size_t>(arg_str - arg_msg);
+ size_t used = static_cast<size_t>(arg_str - arg_msg);
+ PERFETTO_CHECK(used <= sizeof(arg_msg));
+ return sizeof(arg_msg) - used;
};
for (auto it = evt.args(); it; ++it) {
protos::pbzero::AndroidLogPacket::LogEvent::Arg::Decoder arg(*it);
if (!arg.has_name())
continue;
- arg_str +=
- snprintf(arg_str, arg_avail(),
- " %.*s=", static_cast<int>(arg.name().size), arg.name().data);
+ arg_str += base::SprintfTrunc(arg_str, arg_avail(),
+ " %.*s=", static_cast<int>(arg.name().size),
+ arg.name().data);
if (arg.has_string_value()) {
- arg_str += snprintf(arg_str, arg_avail(), "\"%.*s\"",
- static_cast<int>(arg.string_value().size),
- arg.string_value().data);
+ arg_str += base::SprintfTrunc(arg_str, arg_avail(), "\"%.*s\"",
+ static_cast<int>(arg.string_value().size),
+ arg.string_value().data);
} else if (arg.has_int_value()) {
- arg_str += snprintf(arg_str, arg_avail(), "%" PRId64, arg.int_value());
+ arg_str +=
+ base::SprintfTrunc(arg_str, arg_avail(), "%" PRId64, arg.int_value());
} else if (arg.has_float_value()) {
- arg_str += snprintf(arg_str, arg_avail(), "%f",
- static_cast<double>(arg.float_value()));
+ arg_str += base::SprintfTrunc(arg_str, arg_avail(), "%f",
+ static_cast<double>(arg.float_value()));
}
}
diff --git a/src/trace_processor/importers/proto/async_track_set_tracker.cc b/src/trace_processor/importers/proto/async_track_set_tracker.cc
index 4f2714c54..2593a126f 100644
--- a/src/trace_processor/importers/proto/async_track_set_tracker.cc
+++ b/src/trace_processor/importers/proto/async_track_set_tracker.cc
@@ -17,13 +17,15 @@
#include "src/trace_processor/importers/proto/async_track_set_tracker.h"
#include "src/trace_processor/importers/common/track_tracker.h"
+#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/trace_processor_context.h"
namespace perfetto {
namespace trace_processor {
AsyncTrackSetTracker::AsyncTrackSetTracker(TraceProcessorContext* context)
- : context_(context) {}
+ : android_source_(context->storage->InternString("android")),
+ context_(context) {}
AsyncTrackSetTracker::TrackSetId AsyncTrackSetTracker::InternGlobalTrackSet(
StringId name) {
@@ -42,45 +44,45 @@ AsyncTrackSetTracker::TrackSetId AsyncTrackSetTracker::InternGlobalTrackSet(
return global_track_set_ids_[name] = id;
}
-AsyncTrackSetTracker::TrackSetId AsyncTrackSetTracker::InternAndroidSet(
+AsyncTrackSetTracker::TrackSetId AsyncTrackSetTracker::InternProcessTrackSet(
UniquePid upid,
StringId name) {
- AndroidTuple tuple{upid, name};
+ ProcessTuple tuple{upid, name};
- auto it = android_track_set_ids_.find(tuple);
- if (it != android_track_set_ids_.end())
+ auto it = process_track_set_ids_.find(tuple);
+ if (it != process_track_set_ids_.end())
return it->second;
uint32_t id = static_cast<uint32_t>(track_sets_.size());
TrackSet set;
- set.android_tuple = tuple;
- set.type = TrackSetType::kAndroid;
- set.nesting_behaviour = NestingBehaviour::kLegacySaturatingUnnestable;
+ set.process_tuple = tuple;
+ set.type = TrackSetType::kProcess;
+ set.nesting_behaviour = NestingBehaviour::kUnnestable;
track_sets_.emplace_back(set);
- android_track_set_ids_[tuple] = id;
+ process_track_set_ids_[tuple] = id;
return id;
}
-AsyncTrackSetTracker::TrackSetId AsyncTrackSetTracker::InternFrameTimelineSet(
- UniquePid upid,
- StringId name) {
- FrameTimelineTuple tuple{upid, name};
+AsyncTrackSetTracker::TrackSetId
+AsyncTrackSetTracker::InternAndroidLegacyUnnestableTrackSet(UniquePid upid,
+ StringId name) {
+ ProcessTuple tuple{upid, name};
- auto it = frame_timeline_track_set_ids_.find(tuple);
- if (it != frame_timeline_track_set_ids_.end())
+ auto it = android_legacy_unnestable_track_set_ids_.find(tuple);
+ if (it != android_legacy_unnestable_track_set_ids_.end())
return it->second;
uint32_t id = static_cast<uint32_t>(track_sets_.size());
TrackSet set;
- set.frame_timeline_tuple = tuple;
- set.type = TrackSetType::kFrameTimeline;
- set.nesting_behaviour = NestingBehaviour::kUnnestable;
+ set.process_tuple = tuple;
+ set.type = TrackSetType::kAndroidLegacyUnnestable;
+ set.nesting_behaviour = NestingBehaviour::kLegacySaturatingUnnestable;
track_sets_.emplace_back(set);
- frame_timeline_track_set_ids_[tuple] = id;
+ android_legacy_unnestable_track_set_ids_[tuple] = id;
return id;
}
@@ -131,8 +133,10 @@ TrackId AsyncTrackSetTracker::Scoped(TrackSetId id, int64_t ts, int64_t dur) {
return state.slice_type == TrackState::SliceType::kTimestamp &&
state.ts_end <= ts;
});
- if (it != set.tracks.end())
+ if (it != set.tracks.end()) {
+ it->ts_end = ts + dur;
return it->id;
+ }
TrackState state;
state.slice_type = TrackState::SliceType::kTimestamp;
@@ -178,14 +182,18 @@ AsyncTrackSetTracker::GetOrCreateTrackForCookie(TrackSet& set, int64_t cookie) {
TrackId AsyncTrackSetTracker::CreateTrackForSet(const TrackSet& set) {
switch (set.type) {
case TrackSetType::kGlobal:
+ // TODO(lalitm): propogate source from callers rather than just passing
+ // kNullStringId here.
return context_->track_tracker->CreateGlobalAsyncTrack(
- set.global_track_name);
- case TrackSetType::kAndroid:
- return context_->track_tracker->CreateAndroidAsyncTrack(
- set.android_tuple.name, set.android_tuple.upid);
- case TrackSetType::kFrameTimeline:
- return context_->track_tracker->CreateFrameTimelineAsyncTrack(
- set.frame_timeline_tuple.name, set.frame_timeline_tuple.upid);
+ set.global_track_name, kNullStringId);
+ case TrackSetType::kProcess:
+ // TODO(lalitm): propogate source from callers rather than just passing
+ // kNullStringId here.
+ return context_->track_tracker->CreateProcessAsyncTrack(
+ set.process_tuple.name, set.process_tuple.upid, kNullStringId);
+ case TrackSetType::kAndroidLegacyUnnestable:
+ return context_->track_tracker->CreateProcessAsyncTrack(
+ set.process_tuple.name, set.process_tuple.upid, android_source_);
}
PERFETTO_FATAL("For GCC");
}
diff --git a/src/trace_processor/importers/proto/async_track_set_tracker.h b/src/trace_processor/importers/proto/async_track_set_tracker.h
index b3dd836c8..83fd95c17 100644
--- a/src/trace_processor/importers/proto/async_track_set_tracker.h
+++ b/src/trace_processor/importers/proto/async_track_set_tracker.h
@@ -17,8 +17,6 @@
#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ASYNC_TRACK_SET_TRACKER_H_
#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ASYNC_TRACK_SET_TRACKER_H_
-#include <unordered_map>
-
#include "src/trace_processor/storage/trace_storage.h"
namespace perfetto {
@@ -44,7 +42,7 @@ class AsyncTrackSetTrackerUnittest;
// The intended usage of this class is for callers to first call one of the
// Intern* methods to obtain a TrackSetId followed by Begin/End just before
// calling into SliceTracker's Begin/End respectively. For example:
-// TrackSetId set_id = track_set_tracker->InternAndroidSet(upid, name);
+// TrackSetId set_id = track_set_tracker->InternProcessTrackSet(upid, name);
// if (event.begin) {
// TrackId id = track_set_tracker->Begin(set_id, cookie);
// slice_tracker->Begin(ts, id, ...)
@@ -63,18 +61,18 @@ class AsyncTrackSetTracker {
// Interns a set of global async slice tracks associated with the given name.
TrackSetId InternGlobalTrackSet(StringId name);
- // Interns a set of Android async slice tracks associated with the given
- // upid and name.
+ // Interns a set of process async slice tracks associated with the given name
+ // and upid.
+ TrackSetId InternProcessTrackSet(UniquePid, StringId name);
+
+ // Interns a set of Android legacy unnesteable async slice tracks
+ // associated with the given upid and name.
// Scoped is *not* supported for this track set type.
- TrackSetId InternAndroidSet(UniquePid, StringId name);
+ TrackSetId InternAndroidLegacyUnnestableTrackSet(UniquePid, StringId name);
// Starts a new slice on the given async track set which has the given cookie.
TrackId Begin(TrackSetId id, int64_t cookie);
- // Interns the expected and actual timeline tracks coming from FrameTimeline
- // producer for the associated upid.
- TrackSetId InternFrameTimelineSet(UniquePid, StringId name);
-
// Ends a new slice on the given async track set which has the given cookie.
TrackId End(TrackSetId id, int64_t cookie);
@@ -88,21 +86,11 @@ class AsyncTrackSetTracker {
private:
friend class AsyncTrackSetTrackerUnittest;
- struct AndroidTuple {
+ struct ProcessTuple {
UniquePid upid;
StringId name;
- friend bool operator<(const AndroidTuple& l, const AndroidTuple& r) {
- return std::tie(l.upid, l.name) < std::tie(r.upid, r.name);
- }
- };
-
- struct FrameTimelineTuple {
- UniquePid upid;
- StringId name;
-
- friend bool operator<(const FrameTimelineTuple& l,
- const FrameTimelineTuple& r) {
+ friend bool operator<(const ProcessTuple& l, const ProcessTuple& r) {
return std::tie(l.upid, l.name) < std::tie(r.upid, r.name);
}
};
@@ -127,8 +115,8 @@ class AsyncTrackSetTracker {
enum class TrackSetType {
kGlobal,
- kAndroid,
- kFrameTimeline,
+ kProcess,
+ kAndroidLegacyUnnestable,
};
struct TrackState {
@@ -152,11 +140,11 @@ class AsyncTrackSetTracker {
struct TrackSet {
TrackSetType type;
union {
+ // Only set when |type| == |TrackSetType::kGlobal|.
StringId global_track_name;
- // Only set when |type| == |TrackSetType::kAndroid|.
- AndroidTuple android_tuple;
- // Only set when |type| == |TrackSetType::kFrameTimeline|.
- FrameTimelineTuple frame_timeline_tuple;
+ // Only set when |type| == |TrackSetType::kFrameTimeline| or
+ // |TrackSetType::kAndroidLegacyUnnestable|.
+ ProcessTuple process_tuple;
};
NestingBehaviour nesting_behaviour;
std::vector<TrackState> tracks;
@@ -164,8 +152,8 @@ class AsyncTrackSetTracker {
TrackSetId CreateUnnestableTrackSetForTesting(UniquePid upid, StringId name) {
AsyncTrackSetTracker::TrackSet set;
- set.android_tuple = AndroidTuple{upid, name};
- set.type = AsyncTrackSetTracker::TrackSetType::kAndroid;
+ set.process_tuple = ProcessTuple{upid, name};
+ set.type = AsyncTrackSetTracker::TrackSetType::kAndroidLegacyUnnestable;
set.nesting_behaviour = NestingBehaviour::kUnnestable;
track_sets_.emplace_back(set);
return static_cast<TrackSetId>(track_sets_.size() - 1);
@@ -182,10 +170,12 @@ class AsyncTrackSetTracker {
TrackId CreateTrackForSet(const TrackSet& set);
std::map<StringId, TrackSetId> global_track_set_ids_;
- std::map<AndroidTuple, TrackSetId> android_track_set_ids_;
- std::map<FrameTimelineTuple, TrackSetId> frame_timeline_track_set_ids_;
+ std::map<ProcessTuple, TrackSetId> process_track_set_ids_;
+ std::map<ProcessTuple, TrackSetId> android_legacy_unnestable_track_set_ids_;
std::vector<TrackSet> track_sets_;
+ const StringId android_source_ = kNullStringId;
+
TraceProcessorContext* const context_;
};
diff --git a/src/trace_processor/importers/proto/async_track_set_tracker_unittest.cc b/src/trace_processor/importers/proto/async_track_set_tracker_unittest.cc
index 852c5c292..eb2e041a6 100644
--- a/src/trace_processor/importers/proto/async_track_set_tracker_unittest.cc
+++ b/src/trace_processor/importers/proto/async_track_set_tracker_unittest.cc
@@ -39,8 +39,8 @@ class AsyncTrackSetTrackerUnittest : public testing::Test {
unnestable_id_ = tracker_->CreateUnnestableTrackSetForTesting(
1, storage_->InternString("test"));
- legacy_unnestable_id_ =
- tracker_->InternAndroidSet(2, storage_->InternString("test"));
+ legacy_unnestable_id_ = tracker_->InternAndroidLegacyUnnestableTrackSet(
+ 2, storage_->InternString("test"));
}
protected:
@@ -57,7 +57,8 @@ class AsyncTrackSetTrackerUnittest : public testing::Test {
namespace {
TEST_F(AsyncTrackSetTrackerUnittest, Smoke) {
- auto set_id = tracker_->InternAndroidSet(1, storage_->InternString("test"));
+ auto set_id = tracker_->InternAndroidLegacyUnnestableTrackSet(
+ 1, storage_->InternString("test"));
auto begin = tracker_->Begin(set_id, 1);
auto end = tracker_->End(set_id, 1);
diff --git a/src/trace_processor/importers/proto/chrome_string_lookup.cc b/src/trace_processor/importers/proto/chrome_string_lookup.cc
index 1559dafcc..7de67f0a1 100644
--- a/src/trace_processor/importers/proto/chrome_string_lookup.cc
+++ b/src/trace_processor/importers/proto/chrome_string_lookup.cc
@@ -106,6 +106,7 @@ constexpr ProcessName kProcessNames[] = {
"Service: recording.mojom.RecordingService"},
{ChromeProcessDescriptor::PROCESS_SERVICE_SHAPEDETECTION,
"Service: shape_detection.mojom.ShapeDetectionService"},
+ {ChromeProcessDescriptor::PROCESS_RENDERER_EXTENSION, "Extension Renderer"},
};
struct ThreadName {
@@ -166,6 +167,7 @@ constexpr ThreadName kThreadNames[] = {
{ChromeThreadDescriptor::THREAD_NETWORKCONFIGWATCHER,
"NetworkConfigWatcher"},
{ChromeThreadDescriptor::THREAD_WASAPI_RENDER, "wasapi_render_thread"},
+ {ChromeThreadDescriptor::THREAD_LOADER_LOCK_SAMPLER, "LoaderLockSampler"},
};
} // namespace
diff --git a/src/trace_processor/importers/proto/flamegraph_construction_algorithms.cc b/src/trace_processor/importers/proto/flamegraph_construction_algorithms.cc
new file mode 100644
index 000000000..77dc9ec9f
--- /dev/null
+++ b/src/trace_processor/importers/proto/flamegraph_construction_algorithms.cc
@@ -0,0 +1,436 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "flamegraph_construction_algorithms.h"
+
+#include <set>
+#include <unordered_set>
+
+#include "perfetto/ext/base/string_splitter.h"
+#include "perfetto/ext/base/string_utils.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+namespace {
+struct MergedCallsite {
+ StringId frame_name;
+ StringId mapping_name;
+ base::Optional<StringId> source_file;
+ base::Optional<uint32_t> line_number;
+ base::Optional<uint32_t> parent_idx;
+ bool operator<(const MergedCallsite& o) const {
+ return std::tie(frame_name, mapping_name, parent_idx) <
+ std::tie(o.frame_name, o.mapping_name, o.parent_idx);
+ }
+};
+
+struct FlamegraphTableAndMergedCallsites {
+ std::unique_ptr<tables::ExperimentalFlamegraphNodesTable> tbl;
+ std::vector<uint32_t> callsite_to_merged_callsite;
+};
+
+std::vector<MergedCallsite> GetMergedCallsites(TraceStorage* storage,
+ uint32_t callstack_row) {
+ const tables::StackProfileCallsiteTable& callsites_tbl =
+ storage->stack_profile_callsite_table();
+ const tables::StackProfileFrameTable& frames_tbl =
+ storage->stack_profile_frame_table();
+ const tables::SymbolTable& symbols_tbl = storage->symbol_table();
+ const tables::StackProfileMappingTable& mapping_tbl =
+ storage->stack_profile_mapping_table();
+
+ uint32_t frame_idx =
+ *frames_tbl.id().IndexOf(callsites_tbl.frame_id()[callstack_row]);
+
+ uint32_t mapping_idx =
+ *mapping_tbl.id().IndexOf(frames_tbl.mapping()[frame_idx]);
+ StringId mapping_name = mapping_tbl.name()[mapping_idx];
+
+ base::Optional<uint32_t> symbol_set_id =
+ frames_tbl.symbol_set_id()[frame_idx];
+
+ if (!symbol_set_id) {
+ StringId frame_name = frames_tbl.name()[frame_idx];
+ base::Optional<StringId> deobfuscated_name =
+ frames_tbl.deobfuscated_name()[frame_idx];
+ return {{deobfuscated_name ? *deobfuscated_name : frame_name, mapping_name,
+ base::nullopt, base::nullopt, base::nullopt}};
+ }
+
+ std::vector<MergedCallsite> result;
+ // id == symbol_set_id for the bottommost frame.
+ // TODO(lalitm): Encode this optimization in the table and remove this
+ // custom optimization.
+ uint32_t symbol_set_idx = *symbols_tbl.id().IndexOf(SymbolId(*symbol_set_id));
+ for (uint32_t i = symbol_set_idx;
+ i < symbols_tbl.row_count() &&
+ symbols_tbl.symbol_set_id()[i] == *symbol_set_id;
+ ++i) {
+ result.emplace_back(MergedCallsite{
+ symbols_tbl.name()[i], mapping_name, symbols_tbl.source_file()[i],
+ symbols_tbl.line_number()[i], base::nullopt});
+ }
+ std::reverse(result.begin(), result.end());
+ return result;
+}
+} // namespace
+
+static FlamegraphTableAndMergedCallsites BuildFlamegraphTableTreeStructure(
+ TraceStorage* storage,
+ base::Optional<UniquePid> upid,
+ base::Optional<std::string> upid_group,
+ int64_t default_timestamp,
+ StringId profile_type) {
+ const tables::StackProfileCallsiteTable& callsites_tbl =
+ storage->stack_profile_callsite_table();
+
+ std::vector<uint32_t> callsite_to_merged_callsite(callsites_tbl.row_count(),
+ 0);
+ std::map<MergedCallsite, uint32_t> merged_callsites_to_table_idx;
+
+ std::unique_ptr<tables::ExperimentalFlamegraphNodesTable> tbl(
+ new tables::ExperimentalFlamegraphNodesTable(
+ storage->mutable_string_pool(), nullptr));
+
+ // FORWARD PASS:
+ // Aggregate callstacks by frame name / mapping name. Use symbolization
+ // data.
+ for (uint32_t i = 0; i < callsites_tbl.row_count(); ++i) {
+ base::Optional<uint32_t> parent_idx;
+
+ auto opt_parent_id = callsites_tbl.parent_id()[i];
+ if (opt_parent_id) {
+ parent_idx = callsites_tbl.id().IndexOf(*opt_parent_id);
+ // Make sure what we index into has been populated already.
+ PERFETTO_CHECK(*parent_idx < i);
+ parent_idx = callsite_to_merged_callsite[*parent_idx];
+ }
+
+ auto callsites = GetMergedCallsites(storage, i);
+ // Loop below needs to run at least once for parent_idx to get updated.
+ PERFETTO_CHECK(!callsites.empty());
+ std::map<MergedCallsite, uint32_t> callsites_to_rowid;
+ for (MergedCallsite& merged_callsite : callsites) {
+ merged_callsite.parent_idx = parent_idx;
+ auto it = merged_callsites_to_table_idx.find(merged_callsite);
+ if (it == merged_callsites_to_table_idx.end()) {
+ std::tie(it, std::ignore) = merged_callsites_to_table_idx.emplace(
+ merged_callsite, merged_callsites_to_table_idx.size());
+ tables::ExperimentalFlamegraphNodesTable::Row row{};
+ if (parent_idx) {
+ row.depth = tbl->depth()[*parent_idx] + 1;
+ } else {
+ row.depth = 0;
+ }
+
+ // The 'ts' column is given a default value, taken from the query.
+ // So if the query is:
+ // `select * form experimental_flamegraph
+ // where ts = 605908369259172
+ // and upid = 1
+ // and profile_type = 'native'`
+ // then row.ts == 605908369259172, for all rows
+ // This is not accurate. However, at present there is no other
+ // straightforward way of assigning timestamps to non-leaf nodes in the
+ // flamegraph tree. Non-leaf nodes would have to be assigned >= 1
+ // timestamps, which would increase data size without an advantage.
+ row.ts = default_timestamp;
+ if (upid) {
+ row.upid = *upid;
+ }
+ if (upid_group) {
+ row.upid_group = storage->InternString(base::StringView(*upid_group));
+ }
+ row.profile_type = profile_type;
+ row.name = merged_callsite.frame_name;
+ row.map_name = merged_callsite.mapping_name;
+ if (parent_idx)
+ row.parent_id = tbl->id()[*parent_idx];
+ tbl->Insert(row);
+ callsites_to_rowid[merged_callsite] =
+ static_cast<uint32_t>(merged_callsites_to_table_idx.size() - 1);
+
+ PERFETTO_CHECK(merged_callsites_to_table_idx.size() ==
+ tbl->row_count());
+ } else {
+ MergedCallsite saved_callsite = it->first;
+ callsites_to_rowid.erase(saved_callsite);
+ if (saved_callsite.source_file != merged_callsite.source_file) {
+ saved_callsite.source_file = base::nullopt;
+ }
+ if (saved_callsite.line_number != merged_callsite.line_number) {
+ saved_callsite.line_number = base::nullopt;
+ }
+ callsites_to_rowid[saved_callsite] = it->second;
+ }
+ parent_idx = it->second;
+ }
+
+ for (const auto& it : callsites_to_rowid) {
+ if (it.first.source_file) {
+ tbl->mutable_source_file()->Set(it.second, *it.first.source_file);
+ }
+ if (it.first.line_number) {
+ tbl->mutable_line_number()->Set(it.second, *it.first.line_number);
+ }
+ }
+
+ PERFETTO_CHECK(parent_idx);
+ callsite_to_merged_callsite[i] = *parent_idx;
+ }
+
+ return {std::move(tbl), callsite_to_merged_callsite};
+}
+
+static std::unique_ptr<tables::ExperimentalFlamegraphNodesTable>
+BuildFlamegraphTableHeapSizeAndCount(
+ std::unique_ptr<tables::ExperimentalFlamegraphNodesTable> tbl,
+ const std::vector<uint32_t>& callsite_to_merged_callsite,
+ const Table& filtered) {
+ for (auto it = filtered.IterateRows(); it; it.Next()) {
+ int64_t size =
+ it.Get(static_cast<uint32_t>(
+ tables::HeapProfileAllocationTable::ColumnIndex::size))
+ .long_value;
+ int64_t count =
+ it.Get(static_cast<uint32_t>(
+ tables::HeapProfileAllocationTable::ColumnIndex::count))
+ .long_value;
+ int64_t callsite_id =
+ it
+ .Get(static_cast<uint32_t>(
+ tables::HeapProfileAllocationTable::ColumnIndex::callsite_id))
+ .long_value;
+
+ PERFETTO_CHECK((size <= 0 && count <= 0) || (size >= 0 && count >= 0));
+ uint32_t merged_idx =
+ callsite_to_merged_callsite[static_cast<unsigned long>(callsite_id)];
+ // On old heapprofd producers, the count field is incorrectly set and we
+ // zero it in proto_trace_parser.cc.
+ // As such, we cannot depend on count == 0 to imply size == 0, so we check
+ // for both of them separately.
+ if (size > 0) {
+ tbl->mutable_alloc_size()->Set(merged_idx,
+ tbl->alloc_size()[merged_idx] + size);
+ }
+ if (count > 0) {
+ tbl->mutable_alloc_count()->Set(merged_idx,
+ tbl->alloc_count()[merged_idx] + count);
+ }
+
+ tbl->mutable_size()->Set(merged_idx, tbl->size()[merged_idx] + size);
+ tbl->mutable_count()->Set(merged_idx, tbl->count()[merged_idx] + count);
+ }
+
+ // BACKWARD PASS:
+ // Propagate sizes to parents.
+ for (int64_t i = tbl->row_count() - 1; i >= 0; --i) {
+ auto idx = static_cast<uint32_t>(i);
+
+ tbl->mutable_cumulative_size()->Set(
+ idx, tbl->cumulative_size()[idx] + tbl->size()[idx]);
+ tbl->mutable_cumulative_count()->Set(
+ idx, tbl->cumulative_count()[idx] + tbl->count()[idx]);
+
+ tbl->mutable_cumulative_alloc_size()->Set(
+ idx, tbl->cumulative_alloc_size()[idx] + tbl->alloc_size()[idx]);
+ tbl->mutable_cumulative_alloc_count()->Set(
+ idx, tbl->cumulative_alloc_count()[idx] + tbl->alloc_count()[idx]);
+
+ auto parent = tbl->parent_id()[idx];
+ if (parent) {
+ uint32_t parent_idx = *tbl->id().IndexOf(
+ tables::ExperimentalFlamegraphNodesTable::Id(*parent));
+ tbl->mutable_cumulative_size()->Set(
+ parent_idx,
+ tbl->cumulative_size()[parent_idx] + tbl->cumulative_size()[idx]);
+ tbl->mutable_cumulative_count()->Set(
+ parent_idx,
+ tbl->cumulative_count()[parent_idx] + tbl->cumulative_count()[idx]);
+
+ tbl->mutable_cumulative_alloc_size()->Set(
+ parent_idx, tbl->cumulative_alloc_size()[parent_idx] +
+ tbl->cumulative_alloc_size()[idx]);
+ tbl->mutable_cumulative_alloc_count()->Set(
+ parent_idx, tbl->cumulative_alloc_count()[parent_idx] +
+ tbl->cumulative_alloc_count()[idx]);
+ }
+ }
+
+ return tbl;
+}
+
+static std::unique_ptr<tables::ExperimentalFlamegraphNodesTable>
+BuildFlamegraphTableCallstackSizeAndCount(
+ std::unique_ptr<tables::ExperimentalFlamegraphNodesTable> tbl,
+ const std::vector<uint32_t>& callsite_to_merged_callsite,
+ const Table& filtered) {
+ for (auto it = filtered.IterateRows(); it; it.Next()) {
+ int64_t callsite_id =
+ it.Get(static_cast<uint32_t>(
+ tables::PerfSampleTable::ColumnIndex::callsite_id))
+ .long_value;
+ int64_t ts =
+ it.Get(static_cast<uint32_t>(tables::PerfSampleTable::ColumnIndex::ts))
+ .long_value;
+
+ uint32_t merged_idx =
+ callsite_to_merged_callsite[static_cast<unsigned long>(callsite_id)];
+ tbl->mutable_size()->Set(merged_idx, tbl->size()[merged_idx] + 1);
+ tbl->mutable_count()->Set(merged_idx, tbl->count()[merged_idx] + 1);
+ tbl->mutable_ts()->Set(merged_idx, ts);
+ }
+
+ // BACKWARD PASS:
+ // Propagate sizes to parents.
+ for (int64_t i = tbl->row_count() - 1; i >= 0; --i) {
+ auto idx = static_cast<uint32_t>(i);
+
+ tbl->mutable_cumulative_size()->Set(
+ idx, tbl->cumulative_size()[idx] + tbl->size()[idx]);
+ tbl->mutable_cumulative_count()->Set(
+ idx, tbl->cumulative_count()[idx] + tbl->count()[idx]);
+
+ auto parent = tbl->parent_id()[idx];
+ if (parent) {
+ uint32_t parent_idx = *tbl->id().IndexOf(
+ tables::ExperimentalFlamegraphNodesTable::Id(*parent));
+ tbl->mutable_cumulative_size()->Set(
+ parent_idx,
+ tbl->cumulative_size()[parent_idx] + tbl->cumulative_size()[idx]);
+ tbl->mutable_cumulative_count()->Set(
+ parent_idx,
+ tbl->cumulative_count()[parent_idx] + tbl->cumulative_count()[idx]);
+ }
+ }
+ return tbl;
+}
+
+std::unique_ptr<tables::ExperimentalFlamegraphNodesTable>
+BuildNativeHeapProfileFlamegraph(TraceStorage* storage,
+ UniquePid upid,
+ int64_t timestamp) {
+ const tables::HeapProfileAllocationTable& allocation_tbl =
+ storage->heap_profile_allocation_table();
+ // PASS OVER ALLOCATIONS:
+ // Aggregate allocations into the newly built tree.
+ auto filtered = allocation_tbl.Filter(
+ {allocation_tbl.ts().le(timestamp), allocation_tbl.upid().eq(upid)});
+ if (filtered.row_count() == 0) {
+ return nullptr;
+ }
+ StringId profile_type = storage->InternString("native");
+ FlamegraphTableAndMergedCallsites table_and_callsites =
+ BuildFlamegraphTableTreeStructure(storage, upid, base::nullopt, timestamp,
+ profile_type);
+ return BuildFlamegraphTableHeapSizeAndCount(
+ std::move(table_and_callsites.tbl),
+ table_and_callsites.callsite_to_merged_callsite, filtered);
+}
+
+std::unique_ptr<tables::ExperimentalFlamegraphNodesTable>
+BuildNativeCallStackSamplingFlamegraph(
+ TraceStorage* storage,
+ base::Optional<UniquePid> upid,
+ base::Optional<std::string> upid_group,
+ const std::vector<TimeConstraints>& time_constraints) {
+ // 1.Extract required upids from input.
+ std::unordered_set<UniquePid> upids;
+ if (upid) {
+ upids.insert(*upid);
+ } else {
+ for (base::StringSplitter sp(*upid_group, ','); sp.Next();) {
+ base::Optional<uint32_t> maybe = base::CStringToUInt32(sp.cur_token());
+ if (maybe) {
+ upids.insert(*maybe);
+ }
+ }
+ }
+
+ // 2.Create set of all utids mapped to the given vector of upids
+ std::set<tables::ThreadTable::Id> utids;
+ RowMap threads_in_pid_rm;
+ for (uint32_t i = 0; i < storage->thread_table().row_count(); ++i) {
+ base::Optional<uint32_t> row_upid = storage->thread_table().upid()[i];
+ if (row_upid && upids.count(*row_upid) > 0) {
+ threads_in_pid_rm.Insert(i);
+ }
+ }
+
+ for (auto it = threads_in_pid_rm.IterateRows(); it; it.Next()) {
+ utids.insert(storage->thread_table().id()[it.index()]);
+ }
+
+ // 3.Get all row indices in perf_sample that correspond to the requested utids
+ std::vector<uint32_t> cs_rows;
+ for (uint32_t i = 0; i < storage->perf_sample_table().row_count(); ++i) {
+ if (utids.find(static_cast<tables::ThreadTable::Id>(
+ storage->perf_sample_table().utid()[i])) != utids.end()) {
+ cs_rows.push_back(i);
+ }
+ }
+
+ // 4.Filter rows that correspond to the selected utids
+ RowMap filtered_rm = RowMap(std::move(cs_rows));
+ Table filtered = storage->perf_sample_table().Apply(std::move(filtered_rm));
+
+ // 5.Filter rows by time constraints
+ for (const auto& tc : time_constraints) {
+ if (!(tc.op == FilterOp::kGt || tc.op == FilterOp::kLt ||
+ tc.op == FilterOp::kGe || tc.op == FilterOp::kLe)) {
+ PERFETTO_FATAL("Filter operation %d not permitted for perf.",
+ static_cast<int>(tc.op));
+ }
+ Constraint cs = Constraint{
+ static_cast<uint32_t>(tables::PerfSampleTable::ColumnIndex::ts), tc.op,
+ SqlValue::Long(tc.value)};
+ filtered = filtered.Filter({cs});
+ }
+ if (filtered.row_count() == 0) {
+ std::unique_ptr<tables::ExperimentalFlamegraphNodesTable> empty_tbl(
+ new tables::ExperimentalFlamegraphNodesTable(
+ storage->mutable_string_pool(), nullptr));
+ return empty_tbl;
+ }
+
+ // The logic underneath is selecting a default timestamp to be used by all
+ // frames which do not have a timestamp. The timestamp is taken from the query
+ // value and it's not meaningful for the row. It prevents however the rows
+ // with no timestamp from being filtered out by Sqlite, after we create the
+ // table ExperimentalFlamegraphNodesTable in this class.
+ int64_t default_timestamp = 0;
+ if (!time_constraints.empty()) {
+ auto& tc = time_constraints[0];
+ if (tc.op == FilterOp::kGt) {
+ default_timestamp = tc.value + 1;
+ } else if (tc.op == FilterOp::kLt) {
+ default_timestamp = tc.value - 1;
+ } else {
+ default_timestamp = tc.value;
+ }
+ }
+ StringId profile_type = storage->InternString("perf");
+ FlamegraphTableAndMergedCallsites table_and_callsites =
+ BuildFlamegraphTableTreeStructure(storage, upid, upid_group,
+ default_timestamp, profile_type);
+ return BuildFlamegraphTableCallstackSizeAndCount(
+ std::move(table_and_callsites.tbl),
+ table_and_callsites.callsite_to_merged_callsite, filtered);
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/proto/flamegraph_construction_algorithms.h b/src/trace_processor/importers/proto/flamegraph_construction_algorithms.h
new file mode 100644
index 000000000..b17556522
--- /dev/null
+++ b/src/trace_processor/importers/proto/flamegraph_construction_algorithms.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_FLAMEGRAPH_CONSTRUCTION_ALGORITHMS_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_FLAMEGRAPH_CONSTRUCTION_ALGORITHMS_H_
+
+#include "src/trace_processor/storage/trace_storage.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+// Represents a time boundary for a column.
+struct TimeConstraints {
+ FilterOp op;
+ int64_t value;
+};
+
+std::unique_ptr<tables::ExperimentalFlamegraphNodesTable>
+BuildNativeHeapProfileFlamegraph(TraceStorage* storage,
+ UniquePid upid,
+ int64_t timestamp);
+
+std::unique_ptr<tables::ExperimentalFlamegraphNodesTable>
+BuildNativeCallStackSamplingFlamegraph(
+ TraceStorage* storage,
+ base::Optional<UniquePid> upid,
+ base::Optional<std::string> upid_group,
+ const std::vector<TimeConstraints>& time_constraints);
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_FLAMEGRAPH_CONSTRUCTION_ALGORITHMS_H_
diff --git a/src/trace_processor/importers/proto/frame_timeline_event_parser.cc b/src/trace_processor/importers/proto/frame_timeline_event_parser.cc
index f52931f96..d03dc73d2 100644
--- a/src/trace_processor/importers/proto/frame_timeline_event_parser.cc
+++ b/src/trace_processor/importers/proto/frame_timeline_event_parser.cc
@@ -16,7 +16,7 @@
#include "src/trace_processor/importers/proto/frame_timeline_event_parser.h"
-#include <inttypes.h>
+#include <cinttypes>
#include "perfetto/ext/base/utils.h"
#include "perfetto/protozero/field.h"
@@ -92,20 +92,29 @@ static StringId JankTypeBitmaskToStringId(TraceProcessorContext* context,
}
static bool DisplayFrameJanky(int32_t jank_type) {
- if (jank_type == FrameTimelineEvent::JANK_UNSPECIFIED || jank_type == FrameTimelineEvent::JANK_NONE)
+ if (jank_type == FrameTimelineEvent::JANK_UNSPECIFIED ||
+ jank_type == FrameTimelineEvent::JANK_NONE)
return false;
- int32_t display_frame_jank_bitmask = FrameTimelineEvent::JANK_SF_SCHEDULING | FrameTimelineEvent::JANK_PREDICTION_ERROR | FrameTimelineEvent::JANK_DISPLAY_HAL | FrameTimelineEvent::JANK_SF_CPU_DEADLINE_MISSED | FrameTimelineEvent::JANK_SF_GPU_DEADLINE_MISSED;
+ int32_t display_frame_jank_bitmask =
+ FrameTimelineEvent::JANK_SF_SCHEDULING |
+ FrameTimelineEvent::JANK_PREDICTION_ERROR |
+ FrameTimelineEvent::JANK_DISPLAY_HAL |
+ FrameTimelineEvent::JANK_SF_CPU_DEADLINE_MISSED |
+ FrameTimelineEvent::JANK_SF_GPU_DEADLINE_MISSED;
if (jank_type & display_frame_jank_bitmask)
- return true;
+ return true;
return false;
}
static bool SurfaceFrameJanky(int32_t jank_type) {
- if (jank_type == FrameTimelineEvent::JANK_UNSPECIFIED || jank_type == FrameTimelineEvent::JANK_NONE)
+ if (jank_type == FrameTimelineEvent::JANK_UNSPECIFIED ||
+ jank_type == FrameTimelineEvent::JANK_NONE)
return false;
- int32_t surface_frame_jank_bitmask = FrameTimelineEvent::JANK_APP_DEADLINE_MISSED | FrameTimelineEvent::JANK_UNKNOWN;
+ int32_t surface_frame_jank_bitmask =
+ FrameTimelineEvent::JANK_APP_DEADLINE_MISSED |
+ FrameTimelineEvent::JANK_UNKNOWN;
if (jank_type & surface_frame_jank_bitmask)
return true;
return false;
@@ -206,7 +215,7 @@ void FrameTimelineEventParser::ParseExpectedDisplayFrameStart(
UniquePid upid = context_->process_tracker->GetOrCreateProcess(
static_cast<uint32_t>(event.pid()));
auto expected_track_set_id =
- context_->async_track_set_tracker->InternFrameTimelineSet(
+ context_->async_track_set_tracker->InternProcessTrackSet(
upid, expected_timeline_track_name_);
cookie_track_set_id_map_[cookie] = expected_track_set_id;
@@ -255,7 +264,7 @@ void FrameTimelineEventParser::ParseActualDisplayFrameStart(
UniquePid upid = context_->process_tracker->GetOrCreateProcess(
static_cast<uint32_t>(event.pid()));
auto actual_track_set_id =
- context_->async_track_set_tracker->InternFrameTimelineSet(
+ context_->async_track_set_tracker->InternProcessTrackSet(
upid, actual_timeline_track_name_);
cookie_track_set_id_map_[cookie] = actual_track_set_id;
@@ -291,22 +300,21 @@ void FrameTimelineEventParser::ParseActualDisplayFrameStart(
actual_row.jank_tag = jank_tag_none_id_;
}
- base::Optional<SliceId> opt_slice_id =
- context_->slice_tracker->BeginTyped(
- context_->storage->mutable_actual_frame_timeline_slice_table(),
- actual_row,
- [this, token, jank_type, present_type, prediction_type,
- &event](ArgsTracker::BoundInserter* inserter) {
- inserter->AddArg(display_frame_token_id_, Variadic::Integer(token));
- inserter->AddArg(present_type_id_, Variadic::String(present_type));
- inserter->AddArg(on_time_finish_id_,
- Variadic::Integer(event.on_time_finish()));
- inserter->AddArg(gpu_composition_id_,
- Variadic::Integer(event.gpu_composition()));
- inserter->AddArg(jank_type_id_, Variadic::String(jank_type));
- inserter->AddArg(prediction_type_id_,
- Variadic::String(prediction_type));
- });
+ base::Optional<SliceId> opt_slice_id = context_->slice_tracker->BeginTyped(
+ context_->storage->mutable_actual_frame_timeline_slice_table(),
+ actual_row,
+ [this, token, jank_type, present_type, prediction_type,
+ &event](ArgsTracker::BoundInserter* inserter) {
+ inserter->AddArg(display_frame_token_id_, Variadic::Integer(token));
+ inserter->AddArg(present_type_id_, Variadic::String(present_type));
+ inserter->AddArg(on_time_finish_id_,
+ Variadic::Integer(event.on_time_finish()));
+ inserter->AddArg(gpu_composition_id_,
+ Variadic::Integer(event.gpu_composition()));
+ inserter->AddArg(jank_type_id_, Variadic::String(jank_type));
+ inserter->AddArg(prediction_type_id_,
+ Variadic::String(prediction_type));
+ });
// SurfaceFrames will always be parsed before the matching DisplayFrame
// (since the app works on the frame before SurfaceFlinger does). Because
@@ -380,7 +388,7 @@ void FrameTimelineEventParser::ParseExpectedSurfaceFrameStart(
context_->storage->InternString(base::StringView(std::to_string(token)));
auto expected_track_set_id =
- context_->async_track_set_tracker->InternFrameTimelineSet(
+ context_->async_track_set_tracker->InternProcessTrackSet(
upid, expected_timeline_track_name_);
cookie_track_set_id_map_[cookie] = expected_track_set_id;
@@ -446,7 +454,7 @@ void FrameTimelineEventParser::ParseActualSurfaceFrameStart(
context_->storage->InternString(base::StringView(std::to_string(token)));
auto actual_track_set_id =
- context_->async_track_set_tracker->InternFrameTimelineSet(
+ context_->async_track_set_tracker->InternProcessTrackSet(
upid, actual_timeline_track_name_);
cookie_track_set_id_map_[cookie] = actual_track_set_id;
@@ -498,27 +506,26 @@ void FrameTimelineEventParser::ParseActualSurfaceFrameStart(
is_buffer = context_->storage->InternString("No");
}
- base::Optional<SliceId> opt_slice_id =
- context_->slice_tracker->BeginTyped(
- context_->storage->mutable_actual_frame_timeline_slice_table(),
- actual_row,
- [this, jank_type, present_type, token, layer_name_id,
- display_frame_token, prediction_type, is_buffer,
- &event](ArgsTracker::BoundInserter* inserter) {
- inserter->AddArg(surface_frame_token_id_, Variadic::Integer(token));
- inserter->AddArg(display_frame_token_id_,
- Variadic::Integer(display_frame_token));
- inserter->AddArg(layer_name_id_, Variadic::String(layer_name_id));
- inserter->AddArg(present_type_id_, Variadic::String(present_type));
- inserter->AddArg(on_time_finish_id_,
- Variadic::Integer(event.on_time_finish()));
- inserter->AddArg(gpu_composition_id_,
- Variadic::Integer(event.gpu_composition()));
- inserter->AddArg(jank_type_id_, Variadic::String(jank_type));
- inserter->AddArg(prediction_type_id_,
- Variadic::String(prediction_type));
- inserter->AddArg(is_buffer_id_, Variadic::String(is_buffer));
- });
+ base::Optional<SliceId> opt_slice_id = context_->slice_tracker->BeginTyped(
+ context_->storage->mutable_actual_frame_timeline_slice_table(),
+ actual_row,
+ [this, jank_type, present_type, token, layer_name_id, display_frame_token,
+ prediction_type, is_buffer,
+ &event](ArgsTracker::BoundInserter* inserter) {
+ inserter->AddArg(surface_frame_token_id_, Variadic::Integer(token));
+ inserter->AddArg(display_frame_token_id_,
+ Variadic::Integer(display_frame_token));
+ inserter->AddArg(layer_name_id_, Variadic::String(layer_name_id));
+ inserter->AddArg(present_type_id_, Variadic::String(present_type));
+ inserter->AddArg(on_time_finish_id_,
+ Variadic::Integer(event.on_time_finish()));
+ inserter->AddArg(gpu_composition_id_,
+ Variadic::Integer(event.gpu_composition()));
+ inserter->AddArg(jank_type_id_, Variadic::String(jank_type));
+ inserter->AddArg(prediction_type_id_,
+ Variadic::String(prediction_type));
+ inserter->AddArg(is_buffer_id_, Variadic::String(is_buffer));
+ });
if (opt_slice_id) {
display_token_to_surface_slice_.emplace(display_frame_token, *opt_slice_id);
diff --git a/src/trace_processor/importers/proto/gpu_event_parser.cc b/src/trace_processor/importers/proto/gpu_event_parser.cc
index 317e7b439..414a8206c 100644
--- a/src/trace_processor/importers/proto/gpu_event_parser.cc
+++ b/src/trace_processor/importers/proto/gpu_event_parser.cc
@@ -16,7 +16,7 @@
#include "src/trace_processor/importers/proto/gpu_event_parser.h"
-#include <inttypes.h>
+#include <cinttypes>
#include "perfetto/ext/base/utils.h"
#include "perfetto/protozero/field.h"
@@ -238,9 +238,8 @@ const StringId GpuEventParser::GetFullStageName(
if (stage_id < gpu_render_stage_ids_.size()) {
stage_name = gpu_render_stage_ids_[static_cast<size_t>(stage_id)].first;
} else {
- char buffer[64];
- snprintf(buffer, sizeof(buffer), "render stage(%" PRIu64 ")", stage_id);
- stage_name = context_->storage->InternString(buffer);
+ base::StackString<64> name("render stage(%" PRIu64 ")", stage_id);
+ stage_name = context_->storage->InternString(name.string_view());
}
}
return stage_name;
diff --git a/src/trace_processor/importers/proto/graphics_frame_event_parser.cc b/src/trace_processor/importers/proto/graphics_frame_event_parser.cc
index b115d14da..aa6742ee8 100644
--- a/src/trace_processor/importers/proto/graphics_frame_event_parser.cc
+++ b/src/trace_processor/importers/proto/graphics_frame_event_parser.cc
@@ -16,7 +16,7 @@
#include "src/trace_processor/importers/proto/graphics_frame_event_parser.h"
-#include <inttypes.h>
+#include <cinttypes>
#include "perfetto/ext/base/utils.h"
#include "perfetto/protozero/field.h"
diff --git a/src/trace_processor/importers/proto/heap_graph_module.cc b/src/trace_processor/importers/proto/heap_graph_module.cc
index 530c14b44..21725330c 100644
--- a/src/trace_processor/importers/proto/heap_graph_module.cc
+++ b/src/trace_processor/importers/proto/heap_graph_module.cc
@@ -138,6 +138,7 @@ void HeapGraphModule::ParsePacket(
decoder.heap_graph());
return;
case TracePacket::kDeobfuscationMappingFieldNumber:
+ HeapGraphTracker::GetOrCreate(context_)->FinalizeAllProfiles();
ParseDeobfuscationMapping(decoder.deobfuscation_mapping());
return;
}
@@ -163,6 +164,8 @@ void HeapGraphModule::ParseHeapGraph(uint32_t seq_id,
obj.self_size = object.self_size();
obj.type_id = object.type_id();
+ // Even though the field is named reference_field_id_base, it has always
+ // been used as a base for reference_object_id.
uint64_t base_obj_id = object.reference_field_id_base();
// In S+ traces, this field will not be set for normal instances. It will be
@@ -186,6 +189,11 @@ void HeapGraphModule::ParseHeapGraph(uint32_t seq_id,
});
}
+ if (object.has_native_allocation_registry_size_field()) {
+ obj.native_allocation_registry_size =
+ object.native_allocation_registry_size_field();
+ }
+
if (parse_error) {
context_->storage->IncrementIndexedStats(
stats::heap_graph_malformed_packet, static_cast<int>(upid));
@@ -281,7 +289,6 @@ void HeapGraphModule::DeobfuscateClass(
const std::vector<tables::HeapGraphClassTable::Id>* cls_objects =
heap_graph_tracker->RowsForType(package_name_id,
obfuscated_class_name_id);
-
if (cls_objects) {
for (tables::HeapGraphClassTable::Id id : *cls_objects) {
uint32_t row =
@@ -368,7 +375,7 @@ void HeapGraphModule::ParseDeobfuscationMapping(protozero::ConstBytes blob) {
void HeapGraphModule::NotifyEndOfFile() {
auto* heap_graph_tracker = HeapGraphTracker::GetOrCreate(context_);
- heap_graph_tracker->NotifyEndOfFile();
+ heap_graph_tracker->FinalizeAllProfiles();
}
} // namespace trace_processor
diff --git a/src/trace_processor/importers/proto/heap_graph_tracker.cc b/src/trace_processor/importers/proto/heap_graph_tracker.cc
index e9b400d71..f4d5ad3eb 100644
--- a/src/trace_processor/importers/proto/heap_graph_tracker.cc
+++ b/src/trace_processor/importers/proto/heap_graph_tracker.cc
@@ -30,6 +30,11 @@ namespace trace_processor {
namespace {
+// Iterates all the references owned by the object `id`.
+//
+// Calls bool(*fn)(uint32_t) with the row index of each reference owned by `id`
+// in the `storage.heap_graph_reference()` table. When `fn` returns false (or
+// when there are no more rows owned by `id`), stops the iteration.
template <typename F>
void ForReferenceSet(const TraceStorage& storage,
tables::HeapGraphObjectTable::Id id,
@@ -183,6 +188,14 @@ BuildSuperclassMap(UniquePid upid, int64_t ts, TraceStorage* storage) {
return superclass_map;
}
+// Extract the size from `nar_size`, which is the value of a
+// libcore.util.NativeAllocationRegistry.size field: it encodes the size, but
+// uses the least significant bit to represent the source of the allocation.
+int64_t GetSizeFromNativeAllocationRegistry(int64_t nar_size) {
+ constexpr uint64_t kIsMalloced = 1;
+ return static_cast<int64_t>(static_cast<uint64_t>(nar_size) & ~kIsMalloced);
+}
+
} // namespace
void MarkRoot(TraceStorage* storage,
@@ -275,7 +288,17 @@ std::string DenormalizeTypeName(NormalizedType normalized,
}
HeapGraphTracker::HeapGraphTracker(TraceProcessorContext* context)
- : context_(context) {}
+ : context_(context),
+ cleaner_thunk_str_id_(
+ context_->storage->InternString("sun.misc.Cleaner.thunk")),
+ referent_str_id_(
+ context_->storage->InternString("java.lang.ref.Reference.referent")),
+ cleaner_thunk_this0_str_id_(context_->storage->InternString(
+ "libcore.util.NativeAllocationRegistry$CleanerThunk.this$0")),
+ native_size_str_id_(context_->storage->InternString(
+ "libcore.util.NativeAllocationRegistry.size")),
+ cleaner_next_str_id_(
+ context_->storage->InternString("sun.misc.Cleaner.next")) {}
HeapGraphTracker::SequenceState& HeapGraphTracker::GetOrCreateSequence(
uint32_t seq_id) {
@@ -309,6 +332,7 @@ tables::HeapGraphObjectTable::Id HeapGraphTracker::GetOrInsertObject(
{sequence_state->current_upid,
sequence_state->current_ts,
-1,
+ 0,
/*reference_set_id=*/base::nullopt,
/*reachable=*/0,
{},
@@ -397,6 +421,11 @@ void HeapGraphTracker::AddObject(uint32_t seq_id,
owner_id);
}
}
+
+ if (obj.native_allocation_registry_size.has_value()) {
+ sequence_state.nar_size_by_obj_id[owner_id] =
+ *obj.native_allocation_registry_size;
+ }
}
void HeapGraphTracker::AddRoot(uint32_t seq_id,
@@ -580,14 +609,14 @@ void HeapGraphTracker::FinalizeProfile(uint32_t seq_id) {
current_type->field_name_ids[field_offset_in_cls++];
auto it = sequence_state.interned_fields.find(field_id);
if (it == sequence_state.interned_fields.end()) {
- PERFETTO_ELOG("Invalid field id.");
+ PERFETTO_DLOG("Invalid field id.");
context_->storage->IncrementIndexedStats(
stats::heap_graph_malformed_packet,
static_cast<int>(sequence_state.current_upid));
return true;
}
const InternedField& field = it->second;
- auto hgr =
+ auto* hgr =
context_->storage->mutable_heap_graph_reference_table();
hgr->mutable_field_name()->Set(reference_row, field.name);
hgr->mutable_field_type_name()->Set(reference_row,
@@ -614,48 +643,37 @@ void HeapGraphTracker::FinalizeProfile(uint32_t seq_id) {
base::StringView normalized_type =
NormalizeTypeName(context_->storage->GetString(interned_type.name));
- // Annoyingly, some apps have a relative path to base.apk. We take this to
- // mean the main package, so we treat it as if the location was unknown.
- bool is_base_apk = false;
+ base::Optional<StringPool::Id> class_package;
if (location_name) {
- base::StringView base_apk("base.apk");
- is_base_apk = context_->storage->GetString(*location_name)
- .substr(0, base_apk.size()) == base_apk;
- }
-
- if (location_name && !is_base_apk) {
base::Optional<std::string> package_name =
PackageFromLocation(context_->storage.get(),
context_->storage->GetString(*location_name));
if (package_name) {
- class_to_rows_[std::make_pair(
- context_->storage->InternString(
- base::StringView(*package_name)),
- context_->storage->InternString(normalized_type))]
- .emplace_back(type_id);
+ class_package =
+ context_->storage->InternString(base::StringView(*package_name));
+ }
+ }
+ if (!class_package) {
+ auto app_id = context_->storage->process_table()
+ .android_appid()[sequence_state.current_upid];
+ if (app_id) {
+ auto pkg_row =
+ context_->storage->package_list_table().uid().IndexOf(*app_id);
+ if (pkg_row) {
+ class_package =
+ context_->storage->package_list_table().package_name()[*pkg_row];
+ }
}
- } else {
- // TODO(b/153552977): Remove this workaround.
- // For profiles collected for old versions of perfetto_hprof, we do not
- // have any location information. We store them using the nullopt
- // location, and assume they are all part of the main APK.
- //
- // This is to keep ingestion of old profiles working (especially
- // important for the UI).
- class_to_rows_[std::make_pair(
- base::nullopt,
- context_->storage->InternString(normalized_type))]
- .emplace_back(type_id);
}
- }
- if (!sequence_state.deferred_size_objects_for_type_.empty()) {
- context_->storage->IncrementIndexedStats(
- stats::heap_graph_malformed_packet,
- static_cast<int>(sequence_state.current_upid));
+ class_to_rows_[std::make_pair(
+ class_package,
+ context_->storage->InternString(normalized_type))]
+ .emplace_back(type_id);
}
- if (!sequence_state.deferred_reference_objects_for_type_.empty()) {
+ if (!sequence_state.deferred_size_objects_for_type_.empty() ||
+ !sequence_state.deferred_reference_objects_for_type_.empty()) {
context_->storage->IncrementIndexedStats(
stats::heap_graph_malformed_packet,
static_cast<int>(sequence_state.current_upid));
@@ -679,9 +697,112 @@ void HeapGraphTracker::FinalizeProfile(uint32_t seq_id) {
}
PopulateSuperClasses(sequence_state);
+ PopulateNativeSize(sequence_state);
sequence_state_.erase(seq_id);
}
+base::Optional<tables::HeapGraphObjectTable::Id>
+HeapGraphTracker::GetReferenceByFieldName(tables::HeapGraphObjectTable::Id obj,
+ StringPool::Id field) {
+ const auto& refs_tbl = context_->storage->heap_graph_reference_table();
+
+ base::Optional<tables::HeapGraphObjectTable::Id> referred;
+
+ ForReferenceSet(*context_->storage, obj, [&](uint32_t ref_row) -> bool {
+ if (refs_tbl.field_name()[ref_row] == field) {
+ referred = refs_tbl.owned_id()[ref_row];
+ return false;
+ }
+ return true;
+ });
+
+ return referred;
+}
+
+void HeapGraphTracker::PopulateNativeSize(const SequenceState& seq) {
+ // +-------------------------------+ .referent +--------+
+ // | sun.misc.Cleaner | -----------> | Object |
+ // +-------------------------------+ +--------+
+ // |
+ // | .thunk
+ // v
+ // +----------------------------------------------------+
+ // | libcore.util.NativeAllocationRegistry$CleanerThunk |
+ // +----------------------------------------------------+
+ // |
+ // | .this$0
+ // v
+ // +----------------------------------------------------+
+ // | libcore.util.NativeAllocationRegistry |
+ // | .size |
+ // +----------------------------------------------------+
+ //
+ // `.size` should be attributed as the native size of Object
+
+ const auto& class_tbl = context_->storage->heap_graph_class_table();
+ const auto& objects_tbl = context_->storage->heap_graph_object_table();
+
+ struct Cleaner {
+ tables::HeapGraphObjectTable::Id referent;
+ tables::HeapGraphObjectTable::Id thunk;
+ };
+ std::vector<Cleaner> cleaners;
+
+ auto cleaner_classes =
+ class_tbl.FilterToRowMap({class_tbl.name().eq("sun.misc.Cleaner")});
+ for (auto class_it = cleaner_classes.IterateRows(); class_it;
+ class_it.Next()) {
+ auto class_id = class_tbl.id()[class_it.index()];
+ auto cleaner_objs = objects_tbl.FilterToRowMap(
+ {objects_tbl.type_id().eq(class_id.value),
+ objects_tbl.upid().eq(seq.current_upid),
+ objects_tbl.graph_sample_ts().eq(seq.current_ts)});
+ for (auto obj_it = cleaner_objs.IterateRows(); obj_it; obj_it.Next()) {
+ tables::HeapGraphObjectTable::Id cleaner_obj_id =
+ objects_tbl.id()[obj_it.index()];
+ base::Optional<tables::HeapGraphObjectTable::Id> referent_id =
+ GetReferenceByFieldName(cleaner_obj_id, referent_str_id_);
+ base::Optional<tables::HeapGraphObjectTable::Id> thunk_id =
+ GetReferenceByFieldName(cleaner_obj_id, cleaner_thunk_str_id_);
+
+ if (!referent_id || !thunk_id) {
+ continue;
+ }
+
+ base::Optional<tables::HeapGraphObjectTable::Id> next_id =
+ GetReferenceByFieldName(cleaner_obj_id, cleaner_next_str_id_);
+ if (next_id.has_value() && *next_id == cleaner_obj_id) {
+ // sun.misc.Cleaner.next points to the sun.misc.Cleaner: this means
+ // that the sun.misc.Cleaner.clean() has already been called. Skip this.
+ continue;
+ }
+ cleaners.push_back(Cleaner{*referent_id, *thunk_id});
+ }
+ }
+
+ for (const auto& cleaner : cleaners) {
+ base::Optional<tables::HeapGraphObjectTable::Id> this0 =
+ GetReferenceByFieldName(cleaner.thunk, cleaner_thunk_this0_str_id_);
+ if (!this0) {
+ continue;
+ }
+
+ auto nar_size_it = seq.nar_size_by_obj_id.find(*this0);
+ if (nar_size_it == seq.nar_size_by_obj_id.end()) {
+ continue;
+ }
+
+ uint32_t referent_row = *objects_tbl.id().IndexOf(cleaner.referent);
+ int64_t native_size =
+ GetSizeFromNativeAllocationRegistry(nar_size_it->second);
+ int64_t total_native_size =
+ objects_tbl.native_size()[referent_row] + native_size;
+ context_->storage->mutable_heap_graph_object_table()
+ ->mutable_native_size()
+ ->Set(referent_row, total_native_size);
+ }
+}
+
// TODO(fmayer): For Android S+ traces, use the superclass_id from the trace.
void HeapGraphTracker::PopulateSuperClasses(const SequenceState& seq) {
// Maps from normalized class name and location, to superclass.
@@ -738,7 +859,7 @@ void FindPathFromRoot(TraceStorage* storage,
size_t parent_id; // id of parent node in the result tree.
size_t i; // Index of the next child of this node to handle.
uint32_t depth; // Depth in the resulting tree
- // (including artifical root).
+ // (including artificial root).
std::vector<tables::HeapGraphObjectTable::Id> children;
};
@@ -795,9 +916,31 @@ void FindPathFromRoot(TraceStorage* storage,
GetChildren(*storage, n);
children.assign(children_set.cbegin(), children_set.cend());
PERFETTO_CHECK(children.size() == children_set.size());
+
+ if (storage->heap_graph_object_table().native_size()[row]) {
+ StringPool::Id native_class_name_id = storage->InternString(
+ base::StringView(std::string("[native] ") +
+ storage->GetString(class_name_id).ToStdString()));
+ std::map<StringId, size_t>::iterator native_it;
+ bool inserted_new_node;
+ std::tie(native_it, inserted_new_node) =
+ path->nodes[path_id].children.insert({native_class_name_id, 0});
+ if (inserted_new_node) {
+ native_it->second = path->nodes.size();
+ path->nodes.emplace_back(PathFromRoot::Node{});
+
+ path->nodes.back().class_name_id = native_class_name_id;
+ path->nodes.back().depth = depth + 1;
+ path->nodes.back().parent_id = path_id;
+ }
+ PathFromRoot::Node* new_output_tree_node = &path->nodes[native_it->second];
+
+ new_output_tree_node->size += storage->heap_graph_object_table().native_size()[row];
+ new_output_tree_node->count++;
+ }
}
- // Otherwise we have already handled this node and just need to get its
- // i-th child.
+
+ // We have already handled this node and just need to get its i-th child.
if (!children.empty()) {
PERFETTO_CHECK(i < children.size());
tables::HeapGraphObjectTable::Id child = children[i];
@@ -867,8 +1010,8 @@ HeapGraphTracker::BuildFlamegraph(const int64_t current_ts,
FindPathFromRoot(context_->storage.get(), root, &init_path);
}
- std::vector<int32_t> node_to_cumulative_size(init_path.nodes.size());
- std::vector<int32_t> node_to_cumulative_count(init_path.nodes.size());
+ std::vector<int64_t> node_to_cumulative_size(init_path.nodes.size());
+ std::vector<int64_t> node_to_cumulative_count(init_path.nodes.size());
// i > 0 is to skip the artifical root node.
for (size_t i = init_path.nodes.size() - 1; i > 0; --i) {
const PathFromRoot::Node& node = init_path.nodes[i];
@@ -908,7 +1051,7 @@ HeapGraphTracker::BuildFlamegraph(const int64_t current_ts,
return tbl;
}
-void HeapGraphTracker::NotifyEndOfFile() {
+void HeapGraphTracker::FinalizeAllProfiles() {
if (!sequence_state_.empty()) {
context_->storage->IncrementStats(stats::heap_graph_non_finalized_graph);
// There might still be valuable data even though the trace is truncated.
diff --git a/src/trace_processor/importers/proto/heap_graph_tracker.h b/src/trace_processor/importers/proto/heap_graph_tracker.h
index 1cf31e23f..525563937 100644
--- a/src/trace_processor/importers/proto/heap_graph_tracker.h
+++ b/src/trace_processor/importers/proto/heap_graph_tracker.h
@@ -80,6 +80,10 @@ class HeapGraphTracker : public Destructible {
std::vector<uint64_t> field_name_ids;
std::vector<uint64_t> referred_objects;
+
+ // If this object is an instance of `libcore.util.NativeAllocationRegistry`,
+ // this is the value of its `size` field.
+ base::Optional<int64_t> native_allocation_registry_size;
};
struct SourceRoot {
@@ -115,10 +119,10 @@ class HeapGraphTracker : public Destructible {
uint64_t intern_id,
StringPool::Id str);
void FinalizeProfile(uint32_t seq);
+ void FinalizeAllProfiles();
void SetPacketIndex(uint32_t seq_id, uint64_t index);
~HeapGraphTracker() override;
- void NotifyEndOfFile();
const std::vector<tables::HeapGraphClassTable::Id>* RowsForType(
base::Optional<StringPool::Id> package_name,
@@ -182,6 +186,9 @@ class HeapGraphTracker : public Destructible {
std::map<tables::HeapGraphClassTable::Id,
std::vector<tables::HeapGraphObjectTable::Id>>
deferred_size_objects_for_type_;
+ // Contains the value of the "size" field for each
+ // "libcore.util.NativeAllocationRegistry" object.
+ std::map<tables::HeapGraphObjectTable::Id, int64_t> nar_size_by_obj_id;
bool truncated = false;
};
@@ -197,6 +204,18 @@ class HeapGraphTracker : public Destructible {
const InternedType* current_type);
bool IsTruncated(UniquePid upid, int64_t ts);
+ // Returns the object pointed to by `field` in `obj`.
+ base::Optional<tables::HeapGraphObjectTable::Id> GetReferenceByFieldName(
+ tables::HeapGraphObjectTable::Id obj,
+ StringPool::Id field);
+
+ // Populates HeapGraphObject::native_size by walking the graph for
+ // `seq`.
+ //
+ // This should be called only once (it is not idempotent) per seq, after the
+ // all the other tables have been fully populated.
+ void PopulateNativeSize(const SequenceState& seq);
+
TraceProcessorContext* const context_;
std::map<uint32_t, SequenceState> sequence_state_;
@@ -212,6 +231,12 @@ class HeapGraphTracker : public Destructible {
std::set<tables::HeapGraphObjectTable::Id>>
roots_;
std::set<std::pair<UniquePid, int64_t>> truncated_graphs_;
+
+ StringPool::Id cleaner_thunk_str_id_;
+ StringPool::Id referent_str_id_;
+ StringPool::Id cleaner_thunk_this0_str_id_;
+ StringPool::Id native_size_str_id_;
+ StringPool::Id cleaner_next_str_id_;
};
} // namespace trace_processor
diff --git a/src/trace_processor/importers/proto/heap_graph_tracker_unittest.cc b/src/trace_processor/importers/proto/heap_graph_tracker_unittest.cc
index 26b0ca59e..71714876e 100644
--- a/src/trace_processor/importers/proto/heap_graph_tracker_unittest.cc
+++ b/src/trace_processor/importers/proto/heap_graph_tracker_unittest.cc
@@ -16,9 +16,9 @@
#include "src/trace_processor/importers/proto/heap_graph_tracker.h"
-#include "src/trace_processor/importers/proto/profiler_util.h"
-
#include "perfetto/base/logging.h"
+#include "src/trace_processor/importers/common/process_tracker.h"
+#include "src/trace_processor/importers/proto/profiler_util.h"
#include "test/gtest_and_gmock.h"
namespace perfetto {
@@ -28,22 +28,167 @@ namespace {
using ::testing::UnorderedElementsAre;
TEST(HeapGraphTrackerTest, PackageFromLocationApp) {
- TraceStorage storage;
- EXPECT_EQ(
- PackageFromLocation(&storage,
- "/data/app/~~ASDFGH1234QWerT==/"
- "com.twitter.android-MNBVCX7890SDTst6==/test.apk"),
- "com.twitter.android");
- EXPECT_EQ(PackageFromLocation(
- &storage,
- "/data/app/com.google.android.webview-6XfQhnaSkFwGK0sYL9is0G==/"
- "base.apk"),
- "com.google.android.webview");
- EXPECT_EQ(PackageFromLocation(&storage,
- "/data/app/"
- "com.google.android.apps.wellbeing-"
- "qfQCaB4uJ7P0OPpZQqOu0Q==/oat/arm64/base.odex"),
+ std::unique_ptr<TraceStorage> storage(new TraceStorage());
+
+ const char data_app_path[] =
+ "/data/app/org.perfetto.test-6XfQhnaSkFwGK0sYL9is0G==/base.apk";
+ EXPECT_EQ(PackageFromLocation(storage.get(), data_app_path),
+ "org.perfetto.test");
+
+ const char with_extra_dir[] =
+ "/data/app/~~ASDFGH1234QWerT==/"
+ "com.perfetto.test-MNBVCX7890SDTst6==/test.apk";
+ EXPECT_EQ(PackageFromLocation(storage.get(), with_extra_dir),
+ "com.perfetto.test");
+
+ const char odex[] =
+ "/data/app/com.google.android.apps.wellbeing-"
+ "qfQCaB4uJ7P0OPpZQqOu0Q==/oat/arm64/base.odex";
+ EXPECT_EQ(PackageFromLocation(storage.get(), odex),
"com.google.android.apps.wellbeing");
+
+ const char inmem_dex[] =
+ "[anon:dalvik-classes.dex extracted in memory from "
+ "/data/app/~~uUgHYtbjPNr2VFa3byIF4Q==/"
+ "com.perfetto.example-aC94wTfXRC60l2HJU5YvjQ==/base.apk]";
+ EXPECT_EQ(PackageFromLocation(storage.get(), inmem_dex),
+ "com.perfetto.example");
+}
+
+TEST(HeapGraphTrackerTest, PopulateNativeSize) {
+ constexpr uint64_t kSeqId = 1;
+ constexpr UniquePid kPid = 1;
+ constexpr int64_t kTimestamp = 1;
+
+ TraceProcessorContext context;
+ context.storage.reset(new TraceStorage());
+ context.process_tracker.reset(new ProcessTracker(&context));
+ context.process_tracker->GetOrCreateProcess(kPid);
+
+ HeapGraphTracker tracker(&context);
+
+ StringPool::Id normal_kind = context.storage->InternString("KIND_NORMAL");
+
+ constexpr uint64_t kLocation = 0;
+ tracker.AddInternedLocationName(kSeqId, kLocation,
+ context.storage->InternString("location"));
+
+ enum Fields : uint64_t { kReferent = 1, kThunk, kThis0, kNext };
+
+ tracker.AddInternedFieldName(kSeqId, kReferent,
+ "java.lang.ref.Reference.referent");
+ tracker.AddInternedFieldName(kSeqId, kThunk, "sun.misc.Cleaner.thunk");
+ tracker.AddInternedFieldName(
+ kSeqId, kThis0,
+ "libcore.util.NativeAllocationRegistry$CleanerThunk.this$0");
+ tracker.AddInternedFieldName(kSeqId, kNext, "sun.misc.Cleaner.next");
+
+ enum Types : uint64_t {
+ kTypeBitmap = 1,
+ kTypeCleaner,
+ kTypeCleanerThunk,
+ kTypeNativeAllocationRegistry,
+ };
+
+ tracker.AddInternedType(
+ kSeqId, kTypeBitmap,
+ context.storage->InternString("android.graphics.Bitmap"), kLocation,
+ /*object_size=*/0,
+ /*reference_field_name_ids=*/{}, /*superclass_id=*/0,
+ /*classloader_id=*/0, /*no_reference_fields=*/false,
+ /*kind=*/normal_kind);
+
+ tracker.AddInternedType(
+ kSeqId, kTypeCleaner, context.storage->InternString("sun.misc.Cleaner"),
+ kLocation, /*object_size=*/0,
+ /*reference_field_name_ids=*/{kReferent, kThunk, kNext}, /*superclass_id=*/0,
+ /*classloader_id=*/0, /*no_reference_fields=*/false,
+ /*kind=*/normal_kind);
+
+ tracker.AddInternedType(
+ kSeqId, kTypeCleanerThunk,
+ context.storage->InternString(
+ "libcore.util.NativeAllocationRegistry$CleanerThunk"),
+ kLocation, /*object_size=*/0,
+ /*reference_field_name_ids=*/{kThis0}, /*superclass_id=*/0,
+ /*classloader_id=*/0, /*no_reference_fields=*/false,
+ /*kind=*/normal_kind);
+
+ tracker.AddInternedType(
+ kSeqId, kTypeNativeAllocationRegistry,
+ context.storage->InternString("libcore.util.NativeAllocationRegistry"),
+ kLocation, /*object_size=*/0,
+ /*reference_field_name_ids=*/{}, /*superclass_id=*/0,
+ /*classloader_id=*/0, /*no_reference_fields=*/false,
+ /*kind=*/normal_kind);
+
+ enum Objects : uint64_t {
+ kObjBitmap = 1,
+ kObjCleaner,
+ kObjThunk,
+ kObjNativeAllocationRegistry,
+ };
+
+ {
+ HeapGraphTracker::SourceObject obj;
+ obj.object_id = kObjBitmap;
+ obj.type_id = kTypeBitmap;
+
+ tracker.AddObject(kSeqId, kPid, kTimestamp, std::move(obj));
+ }
+
+ {
+ HeapGraphTracker::SourceObject obj;
+ obj.object_id = kObjCleaner;
+ obj.type_id = kTypeCleaner;
+ obj.referred_objects = {kObjBitmap, kObjThunk, 0};
+
+ tracker.AddObject(kSeqId, kPid, kTimestamp, std::move(obj));
+ }
+
+ {
+ HeapGraphTracker::SourceObject obj;
+ obj.object_id = kObjThunk;
+ obj.type_id = kTypeCleanerThunk;
+ obj.referred_objects = {kObjNativeAllocationRegistry};
+
+ tracker.AddObject(kSeqId, kPid, kTimestamp, std::move(obj));
+ }
+
+ {
+ HeapGraphTracker::SourceObject obj;
+ obj.object_id = kObjNativeAllocationRegistry;
+ obj.type_id = kTypeNativeAllocationRegistry;
+
+ // NativeAllocationRegistry.size least significant bit is used to encode the
+ // source of the allocation (1: malloc, 0: other).
+ obj.native_allocation_registry_size = 24242 | 1;
+
+ tracker.AddObject(kSeqId, kPid, kTimestamp, std::move(obj));
+ }
+
+ tracker.FinalizeProfile(kSeqId);
+
+ const auto& objs_table = context.storage->heap_graph_object_table();
+ const auto& class_table = context.storage->heap_graph_class_table();
+ size_t count_bitmaps = 0;
+ for (uint32_t obj_row = 0; obj_row < objs_table.row_count(); ++obj_row) {
+ base::Optional<uint32_t> class_row =
+ class_table.id().IndexOf(objs_table.type_id()[obj_row]);
+ ASSERT_TRUE(class_row.has_value());
+ if (context.storage->string_pool().Get(class_table.name()[*class_row]) ==
+ "android.graphics.Bitmap") {
+ EXPECT_EQ(objs_table.native_size()[obj_row], 24242);
+ count_bitmaps++;
+ } else {
+ EXPECT_EQ(objs_table.native_size()[obj_row], 0)
+ << context.storage->string_pool()
+ .Get(class_table.name()[*class_row])
+ .c_str()
+ << " has non zero native_size";
+ }
+ }
+ EXPECT_EQ(count_bitmaps, 1u);
}
TEST(HeapGraphTrackerTest, BuildFlamegraph) {
@@ -59,6 +204,8 @@ TEST(HeapGraphTrackerTest, BuildFlamegraph) {
TraceProcessorContext context;
context.storage.reset(new TraceStorage());
+ context.process_tracker.reset(new ProcessTracker(&context));
+ context.process_tracker->GetOrCreateProcess(kPid);
HeapGraphTracker tracker(&context);
diff --git a/src/trace_processor/importers/proto/heap_profile_tracker.cc b/src/trace_processor/importers/proto/heap_profile_tracker.cc
index 968da7d26..ea2010869 100644
--- a/src/trace_processor/importers/proto/heap_profile_tracker.cc
+++ b/src/trace_processor/importers/proto/heap_profile_tracker.cc
@@ -26,214 +26,10 @@
namespace perfetto {
namespace trace_processor {
-namespace {
-struct MergedCallsite {
- StringId frame_name;
- StringId mapping_name;
- base::Optional<uint32_t> parent_idx;
- bool operator<(const MergedCallsite& o) const {
- return std::tie(frame_name, mapping_name, parent_idx) <
- std::tie(o.frame_name, o.mapping_name, o.parent_idx);
- }
-};
-
-std::vector<MergedCallsite> GetMergedCallsites(TraceStorage* storage,
- uint32_t callstack_row) {
- const tables::StackProfileCallsiteTable& callsites_tbl =
- storage->stack_profile_callsite_table();
- const tables::StackProfileFrameTable& frames_tbl =
- storage->stack_profile_frame_table();
- const tables::SymbolTable& symbols_tbl = storage->symbol_table();
- const tables::StackProfileMappingTable& mapping_tbl =
- storage->stack_profile_mapping_table();
-
- uint32_t frame_idx =
- *frames_tbl.id().IndexOf(callsites_tbl.frame_id()[callstack_row]);
-
- uint32_t mapping_idx =
- *mapping_tbl.id().IndexOf(frames_tbl.mapping()[frame_idx]);
- StringId mapping_name = mapping_tbl.name()[mapping_idx];
-
- base::Optional<uint32_t> symbol_set_id =
- frames_tbl.symbol_set_id()[frame_idx];
-
- if (!symbol_set_id) {
- StringId frame_name = frames_tbl.name()[frame_idx];
- base::Optional<StringId> deobfuscated_name =
- frames_tbl.deobfuscated_name()[frame_idx];
- return {{deobfuscated_name ? *deobfuscated_name : frame_name, mapping_name,
- base::nullopt}};
- }
-
- std::vector<MergedCallsite> result;
- // id == symbol_set_id for the bottommost frame.
- // TODO(lalitm): Encode this optimization in the table and remove this
- // custom optimization.
- uint32_t symbol_set_idx = *symbols_tbl.id().IndexOf(SymbolId(*symbol_set_id));
- for (uint32_t i = symbol_set_idx;
- i < symbols_tbl.row_count() &&
- symbols_tbl.symbol_set_id()[i] == *symbol_set_id;
- ++i) {
- result.emplace_back(
- MergedCallsite{symbols_tbl.name()[i], mapping_name, base::nullopt});
- }
- std::reverse(result.begin(), result.end());
- return result;
-}
-} // namespace
-
-std::unique_ptr<tables::ExperimentalFlamegraphNodesTable> BuildNativeFlamegraph(
- TraceStorage* storage,
- UniquePid upid,
- int64_t timestamp) {
- const tables::HeapProfileAllocationTable& allocation_tbl =
- storage->heap_profile_allocation_table();
- const tables::StackProfileCallsiteTable& callsites_tbl =
- storage->stack_profile_callsite_table();
-
- StringId profile_type = storage->InternString("native");
-
- std::vector<uint32_t> callsite_to_merged_callsite(callsites_tbl.row_count(),
- 0);
- std::map<MergedCallsite, uint32_t> merged_callsites_to_table_idx;
-
- std::unique_ptr<tables::ExperimentalFlamegraphNodesTable> tbl(
- new tables::ExperimentalFlamegraphNodesTable(
- storage->mutable_string_pool(), nullptr));
-
- // FORWARD PASS:
- // Aggregate callstacks by frame name / mapping name. Use symbolization
- // data.
- for (uint32_t i = 0; i < callsites_tbl.row_count(); ++i) {
- base::Optional<uint32_t> parent_idx;
-
- auto opt_parent_id = callsites_tbl.parent_id()[i];
- if (opt_parent_id) {
- parent_idx = callsites_tbl.id().IndexOf(*opt_parent_id);
- // Make sure what we index into has been populated already.
- PERFETTO_CHECK(*parent_idx < i);
- parent_idx = callsite_to_merged_callsite[*parent_idx];
- }
-
- auto callsites = GetMergedCallsites(storage, i);
- // Loop below needs to run at least once for parent_idx to get updated.
- PERFETTO_CHECK(!callsites.empty());
- for (MergedCallsite& merged_callsite : callsites) {
- merged_callsite.parent_idx = parent_idx;
- auto it = merged_callsites_to_table_idx.find(merged_callsite);
- if (it == merged_callsites_to_table_idx.end()) {
- std::tie(it, std::ignore) = merged_callsites_to_table_idx.emplace(
- merged_callsite, merged_callsites_to_table_idx.size());
- tables::ExperimentalFlamegraphNodesTable::Row row{};
- if (parent_idx) {
- row.depth = tbl->depth()[*parent_idx] + 1;
- } else {
- row.depth = 0;
- }
- row.ts = timestamp;
- row.upid = upid;
- row.profile_type = profile_type;
- row.name = merged_callsite.frame_name;
- row.map_name = merged_callsite.mapping_name;
- if (parent_idx)
- row.parent_id = tbl->id()[*parent_idx];
-
- parent_idx = tbl->Insert(std::move(row)).row;
- PERFETTO_CHECK(merged_callsites_to_table_idx.size() ==
- tbl->row_count());
- }
- parent_idx = it->second;
- }
-
- PERFETTO_CHECK(parent_idx);
- callsite_to_merged_callsite[i] = *parent_idx;
- }
-
- // PASS OVER ALLOCATIONS:
- // Aggregate allocations into the newly built tree.
- auto filtered = allocation_tbl.Filter(
- {allocation_tbl.ts().le(timestamp), allocation_tbl.upid().eq(upid)});
-
- if (filtered.row_count() == 0) {
- return nullptr;
- }
-
- for (auto it = filtered.IterateRows(); it; it.Next()) {
- int64_t size =
- it.Get(static_cast<uint32_t>(
- tables::HeapProfileAllocationTable::ColumnIndex::size))
- .long_value;
- int64_t count =
- it.Get(static_cast<uint32_t>(
- tables::HeapProfileAllocationTable::ColumnIndex::count))
- .long_value;
- int64_t callsite_id =
- it
- .Get(static_cast<uint32_t>(
- tables::HeapProfileAllocationTable::ColumnIndex::callsite_id))
- .long_value;
-
- PERFETTO_CHECK((size <= 0 && count <= 0) || (size >= 0 && count >= 0));
- uint32_t merged_idx =
- callsite_to_merged_callsite[*callsites_tbl.id().IndexOf(
- CallsiteId(static_cast<uint32_t>(callsite_id)))];
- // On old heapprofd producers, the count field is incorrectly set and we
- // zero it in proto_trace_parser.cc.
- // As such, we cannot depend on count == 0 to imply size == 0, so we check
- // for both of them separately.
- if (size > 0) {
- tbl->mutable_alloc_size()->Set(merged_idx,
- tbl->alloc_size()[merged_idx] + size);
- }
- if (count > 0) {
- tbl->mutable_alloc_count()->Set(merged_idx,
- tbl->alloc_count()[merged_idx] + count);
- }
-
- tbl->mutable_size()->Set(merged_idx, tbl->size()[merged_idx] + size);
- tbl->mutable_count()->Set(merged_idx, tbl->count()[merged_idx] + count);
- }
-
- // BACKWARD PASS:
- // Propagate sizes to parents.
- for (int64_t i = tbl->row_count() - 1; i >= 0; --i) {
- uint32_t idx = static_cast<uint32_t>(i);
-
- tbl->mutable_cumulative_size()->Set(
- idx, tbl->cumulative_size()[idx] + tbl->size()[idx]);
- tbl->mutable_cumulative_count()->Set(
- idx, tbl->cumulative_count()[idx] + tbl->count()[idx]);
-
- tbl->mutable_cumulative_alloc_size()->Set(
- idx, tbl->cumulative_alloc_size()[idx] + tbl->alloc_size()[idx]);
- tbl->mutable_cumulative_alloc_count()->Set(
- idx, tbl->cumulative_alloc_count()[idx] + tbl->alloc_count()[idx]);
-
- auto parent = tbl->parent_id()[idx];
- if (parent) {
- uint32_t parent_idx = *tbl->id().IndexOf(
- tables::ExperimentalFlamegraphNodesTable::Id(*parent));
- tbl->mutable_cumulative_size()->Set(
- parent_idx,
- tbl->cumulative_size()[parent_idx] + tbl->cumulative_size()[idx]);
- tbl->mutable_cumulative_count()->Set(
- parent_idx,
- tbl->cumulative_count()[parent_idx] + tbl->cumulative_count()[idx]);
-
- tbl->mutable_cumulative_alloc_size()->Set(
- parent_idx, tbl->cumulative_alloc_size()[parent_idx] +
- tbl->cumulative_alloc_size()[idx]);
- tbl->mutable_cumulative_alloc_count()->Set(
- parent_idx, tbl->cumulative_alloc_count()[parent_idx] +
- tbl->cumulative_alloc_count()[idx]);
- }
- }
-
- return tbl;
-}
-
HeapProfileTracker::HeapProfileTracker(TraceProcessorContext* context)
- : context_(context), empty_(context_->storage->InternString({"", 0})) {}
+ : context_(context),
+ empty_(context_->storage->InternString({"", 0})),
+ art_heap_(context_->storage->InternString("com.android.art")) {}
HeapProfileTracker::~HeapProfileTracker() = default;
@@ -364,7 +160,12 @@ void HeapProfileTracker::AddAllocation(
context_->storage->mutable_heap_profile_allocation_table()->Insert(
alloc_delta);
}
- if (free_delta.count || free_delta.size) {
+
+ // ART only reports allocations, and not frees. This throws off our logic
+ // that assumes that if a new object was allocated with the same address,
+ // the old one has to have been freed in the meantime.
+ // See HeapTracker::RecordMalloc in bookkeeping.cc.
+ if (alloc.heap_name != art_heap_ && (free_delta.count || free_delta.size)) {
context_->storage->mutable_heap_profile_allocation_table()->Insert(
free_delta);
}
diff --git a/src/trace_processor/importers/proto/heap_profile_tracker.h b/src/trace_processor/importers/proto/heap_profile_tracker.h
index 066c238eb..03b1d7b90 100644
--- a/src/trace_processor/importers/proto/heap_profile_tracker.h
+++ b/src/trace_processor/importers/proto/heap_profile_tracker.h
@@ -27,9 +27,6 @@
namespace perfetto {
namespace trace_processor {
-std::unique_ptr<tables::ExperimentalFlamegraphNodesTable>
-BuildNativeFlamegraph(TraceStorage* storage, UniquePid upid, int64_t timestamp);
-
class TraceProcessorContext;
class HeapProfileTracker {
@@ -120,6 +117,7 @@ class HeapProfileTracker {
std::map<uint32_t, SequenceState> sequence_state_;
TraceProcessorContext* const context_;
const StringId empty_;
+ const StringId art_heap_;
};
} // namespace trace_processor
diff --git a/src/trace_processor/importers/proto/metadata_module.cc b/src/trace_processor/importers/proto/metadata_module.cc
index b6a082fbc..cfb644b36 100644
--- a/src/trace_processor/importers/proto/metadata_module.cc
+++ b/src/trace_processor/importers/proto/metadata_module.cc
@@ -16,7 +16,7 @@
#include "src/trace_processor/importers/proto/metadata_module.h"
-#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/base64.h"
#include "src/trace_processor/importers/common/slice_tracker.h"
#include "src/trace_processor/importers/common/track_tracker.h"
#include "src/trace_processor/importers/proto/metadata_tracker.h"
@@ -31,7 +31,10 @@ namespace trace_processor {
using perfetto::protos::pbzero::TracePacket;
MetadataModule::MetadataModule(TraceProcessorContext* context)
- : context_(context) {
+ : context_(context),
+ producer_name_key_id_(context_->storage->InternString("producer_name")),
+ trusted_producer_uid_key_id_(
+ context_->storage->InternString("trusted_producer_uid")) {
RegisterForField(TracePacket::kUiStateFieldNumber, context);
RegisterForField(TracePacket::kChromeMetadataFieldNumber, context);
RegisterForField(TracePacket::kChromeBenchmarkMetadataFieldNumber, context);
@@ -160,15 +163,16 @@ void MetadataModule::ParseTrigger(int64_t ts, ConstBytes blob) {
ts, track_id, cat_id, name_id,
/* duration = */ 0,
[&trigger, this](ArgsTracker::BoundInserter* args_table) {
- StringId producer_name_key =
- context_->storage->InternString("producer_name");
- args_table->AddArg(producer_name_key,
- Variadic::String(context_->storage->InternString(
- trigger.producer_name())));
- StringId trusted_producer_uid_key =
- context_->storage->InternString("trusted_producer_uid");
- args_table->AddArg(trusted_producer_uid_key,
- Variadic::Integer(trigger.trusted_producer_uid()));
+ StringId producer_name =
+ context_->storage->InternString(trigger.producer_name());
+ if (!producer_name.is_null()) {
+ args_table->AddArg(producer_name_key_id_,
+ Variadic::String(producer_name));
+ }
+ if (trigger.has_trusted_producer_uid()) {
+ args_table->AddArg(trusted_producer_uid_key_id_,
+ Variadic::Integer(trigger.trusted_producer_uid()));
+ }
});
}
diff --git a/src/trace_processor/importers/proto/metadata_module.h b/src/trace_processor/importers/proto/metadata_module.h
index 55ac6664a..38a6a5644 100644
--- a/src/trace_processor/importers/proto/metadata_module.h
+++ b/src/trace_processor/importers/proto/metadata_module.h
@@ -49,6 +49,8 @@ class MetadataModule : public ProtoImporterModule {
void ParseTrigger(int64_t ts, ConstBytes);
TraceProcessorContext* context_;
+ StringId producer_name_key_id_ = kNullStringId;
+ StringId trusted_producer_uid_key_id_ = kNullStringId;
};
} // namespace trace_processor
diff --git a/src/trace_processor/importers/proto/metadata_tracker.cc b/src/trace_processor/importers/proto/metadata_tracker.cc
index a0f9c3d52..7f324b9c7 100644
--- a/src/trace_processor/importers/proto/metadata_tracker.cc
+++ b/src/trace_processor/importers/proto/metadata_tracker.cc
@@ -16,12 +16,20 @@
#include "src/trace_processor/importers/proto/metadata_tracker.h"
+#include "perfetto/ext/base/crash_keys.h"
#include "src/trace_processor/importers/common/process_tracker.h"
+#include "src/trace_processor/storage/metadata.h"
#include "src/trace_processor/types/trace_processor_context.h"
namespace perfetto {
namespace trace_processor {
+namespace {
+
+base::CrashKey g_crash_key_uuid("trace_uuid");
+
+}
+
MetadataTracker::MetadataTracker(TraceProcessorContext* context)
: context_(context) {
for (uint32_t i = 0; i < kNumKeys; ++i) {
@@ -37,6 +45,13 @@ MetadataId MetadataTracker::SetMetadata(metadata::KeyId key, Variadic value) {
PERFETTO_DCHECK(metadata::kKeyTypes[key] == metadata::KeyType::kSingle);
PERFETTO_DCHECK(value.type == metadata::kValueTypes[key]);
+ // When the trace_uuid is set, store a copy in a crash key, so in case of
+ // a crash in the pipelines we can tell which trace caused the crash.
+ if (key == metadata::trace_uuid && value.type == Variadic::kString) {
+ auto uuid_string_view = context_->storage->GetString(value.string_value);
+ g_crash_key_uuid.Set(uuid_string_view);
+ }
+
auto* metadata_table = context_->storage->mutable_metadata_table();
uint32_t key_idx = static_cast<uint32_t>(key);
base::Optional<uint32_t> opt_row =
@@ -55,7 +70,7 @@ MetadataId MetadataTracker::SetMetadata(metadata::KeyId key, Variadic value) {
return id_and_row.id;
}
-SqlValue MetadataTracker::GetMetadataForTesting(metadata::KeyId key) {
+SqlValue MetadataTracker::GetMetadata(metadata::KeyId key) {
// KeyType::kMulti not yet supported by this method:
PERFETTO_CHECK(metadata::kKeyTypes[key] == metadata::KeyType::kSingle);
@@ -63,7 +78,23 @@ SqlValue MetadataTracker::GetMetadataForTesting(metadata::KeyId key) {
uint32_t key_idx = static_cast<uint32_t>(key);
uint32_t row =
metadata_table->name().IndexOf(metadata::kNames[key_idx]).value();
- return metadata_table->mutable_str_value()->Get(row);
+
+ auto value_type = metadata::kValueTypes[key];
+ switch (value_type) {
+ case Variadic::kInt:
+ return metadata_table->mutable_int_value()->Get(row);
+ case Variadic::kString:
+ return metadata_table->mutable_str_value()->Get(row);
+ case Variadic::kNull:
+ return SqlValue();
+ case Variadic::kJson:
+ case Variadic::kUint:
+ case Variadic::kPointer:
+ case Variadic::kReal:
+ case Variadic::kBool:
+ PERFETTO_FATAL("Invalid metadata value type %zu", value_type);
+ }
+ PERFETTO_FATAL("For GCC");
}
MetadataId MetadataTracker::AppendMetadata(metadata::KeyId key,
@@ -110,6 +141,7 @@ void MetadataTracker::WriteValue(uint32_t row, Variadic value) {
case Variadic::Type::kPointer:
case Variadic::Type::kUint:
case Variadic::Type::kReal:
+ case Variadic::Type::kNull:
PERFETTO_FATAL("Unsupported value type");
}
}
diff --git a/src/trace_processor/importers/proto/metadata_tracker.h b/src/trace_processor/importers/proto/metadata_tracker.h
index dabdda07a..23f48a128 100644
--- a/src/trace_processor/importers/proto/metadata_tracker.h
+++ b/src/trace_processor/importers/proto/metadata_tracker.h
@@ -46,8 +46,8 @@ class MetadataTracker {
MetadataId SetDynamicMetadata(StringId key, Variadic value);
// Reads back a set metadata value.
- // For use in tests only.
- SqlValue GetMetadataForTesting(metadata::KeyId key);
+ // Only kSingle types are supported right now.
+ SqlValue GetMetadata(metadata::KeyId key);
// Tracks how many ChromeMetadata bundles have been parsed.
uint32_t IncrementChromeMetadataBundleCount() {
diff --git a/src/trace_processor/importers/proto/packet_sequence_state.h b/src/trace_processor/importers/proto/packet_sequence_state.h
index fc5288c27..d98557282 100644
--- a/src/trace_processor/importers/proto/packet_sequence_state.h
+++ b/src/trace_processor/importers/proto/packet_sequence_state.h
@@ -24,10 +24,12 @@
#include "perfetto/base/compiler.h"
#include "perfetto/protozero/proto_decoder.h"
-#include "src/trace_processor/importers/common/trace_blob_view.h"
+#include "perfetto/trace_processor/ref_counted.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
#include "src/trace_processor/importers/proto/stack_profile_tracker.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/trace_processor_context.h"
+#include "src/trace_processor/util/interned_message_view.h"
#include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
#include "protos/perfetto/trace/track_event/track_event.pbzero.h"
@@ -35,114 +37,6 @@
namespace perfetto {
namespace trace_processor {
-#if PERFETTO_DCHECK_IS_ON()
-// When called from GetOrCreateDecoder(), should include the stringified name of
-// the MessageType.
-#define PERFETTO_TYPE_IDENTIFIER PERFETTO_DEBUG_FUNCTION_IDENTIFIER()
-#else // PERFETTO_DCHECK_IS_ON()
-#define PERFETTO_TYPE_IDENTIFIER nullptr
-#endif // PERFETTO_DCHECK_IS_ON()
-
-// Entry in an interning index, refers to the interned message.
-class InternedMessageView {
- public:
- InternedMessageView(TraceBlobView msg) : message_(std::move(msg)) {}
-
- InternedMessageView(InternedMessageView&&) = default;
- InternedMessageView& operator=(InternedMessageView&&) = default;
-
- // Allow copy by cloning the TraceBlobView. This is required for
- // UpdateTracePacketDefaults().
- InternedMessageView(const InternedMessageView& view)
- : message_(view.message_.slice(0, view.message_.length())) {}
- InternedMessageView& operator=(const InternedMessageView& view) {
- this->message_ = view.message_.slice(0, view.message_.length());
- this->decoder_ = nullptr;
- this->decoder_type_ = nullptr;
- this->submessages_.clear();
- return *this;
- }
-
- // Lazily initializes and returns the decoder object for the message. The
- // decoder is stored in the InternedMessageView to avoid having to parse the
- // message multiple times.
- template <typename MessageType>
- typename MessageType::Decoder* GetOrCreateDecoder() {
- if (!decoder_) {
- // Lazy init the decoder and save it away, so that we don't have to
- // reparse the message every time we access the interning entry.
- decoder_ = std::unique_ptr<void, std::function<void(void*)>>(
- new typename MessageType::Decoder(message_.data(), message_.length()),
- [](void* obj) {
- delete reinterpret_cast<typename MessageType::Decoder*>(obj);
- });
- decoder_type_ = PERFETTO_TYPE_IDENTIFIER;
- }
- // Verify that the type of the decoder didn't change.
- if (PERFETTO_TYPE_IDENTIFIER &&
- strcmp(decoder_type_,
- // GCC complains if this arg can be null.
- PERFETTO_TYPE_IDENTIFIER ? PERFETTO_TYPE_IDENTIFIER : "") != 0) {
- PERFETTO_FATAL(
- "Interning entry accessed under different types! previous type: "
- "%s. new type: %s.",
- decoder_type_, PERFETTO_DEBUG_FUNCTION_IDENTIFIER());
- }
- return reinterpret_cast<typename MessageType::Decoder*>(decoder_.get());
- }
-
- // Lookup a submessage of the interned message, which is then itself stored
- // as InternedMessageView, so that we only need to parse it once. Returns
- // nullptr if the field isn't set.
- // TODO(eseckler): Support repeated fields.
- template <typename MessageType, uint32_t FieldId>
- InternedMessageView* GetOrCreateSubmessageView() {
- auto it = submessages_.find(FieldId);
- if (it != submessages_.end())
- return it->second.get();
- auto* decoder = GetOrCreateDecoder<MessageType>();
- // Calls the at() template method on the decoder.
- auto field = decoder->template at<FieldId>().as_bytes();
- if (!field.data)
- return nullptr;
- const size_t offset = message_.offset_of(field.data);
- TraceBlobView submessage = message_.slice(offset, field.size);
- InternedMessageView* submessage_view =
- new InternedMessageView(std::move(submessage));
- submessages_.emplace_hint(
- it, FieldId, std::unique_ptr<InternedMessageView>(submessage_view));
- return submessage_view;
- }
-
- const TraceBlobView& message() { return message_; }
-
- private:
- using SubMessageViewMap =
- std::unordered_map<uint32_t /*field_id*/,
- std::unique_ptr<InternedMessageView>>;
-
- TraceBlobView message_;
-
- // Stores the decoder for the message_, so that the message does not have to
- // be re-decoded every time the interned message is looked up. Lazily
- // initialized in GetOrCreateDecoder(). Since we don't know the type of the
- // decoder until GetOrCreateDecoder() is called, we store the decoder as a
- // void* unique_pointer with a destructor function that's supplied in
- // GetOrCreateDecoder() when the decoder is created.
- std::unique_ptr<void, std::function<void(void*)>> decoder_;
-
- // Type identifier for the decoder. Only valid in debug builds and on
- // supported platforms. Used to verify that GetOrCreateDecoder() is always
- // called with the same template argument.
- const char* decoder_type_ = nullptr;
-
- // Views of submessages of the interned message. Submessages are lazily
- // added by GetOrCreateSubmessageView(). By storing submessages and their
- // decoders, we avoid having to decode submessages multiple times if they
- // looked up often.
- SubMessageViewMap submessages_;
-};
-
using InternedMessageMap =
std::unordered_map<uint64_t /*iid*/, InternedMessageView>;
using InternedFieldMap =
@@ -150,7 +44,7 @@ using InternedFieldMap =
class PacketSequenceState;
-class PacketSequenceStateGeneration {
+class PacketSequenceStateGeneration : public RefCounted {
public:
// Returns |nullptr| if the message with the given |iid| was not found (also
// records a stat in this case).
@@ -225,7 +119,7 @@ class PacketSequenceStateGeneration {
class PacketSequenceState {
public:
- PacketSequenceState(TraceProcessorContext* context)
+ explicit PacketSequenceState(TraceProcessorContext* context)
: context_(context), sequence_stack_profile_tracker_(context) {
current_generation_.reset(
new PacketSequenceStateGeneration(this, generation_index_++));
@@ -304,7 +198,7 @@ class PacketSequenceState {
}
// Returns a ref-counted ptr to the current generation.
- std::shared_ptr<PacketSequenceStateGeneration> current_generation() const {
+ RefPtr<PacketSequenceStateGeneration> current_generation() const {
return current_generation_;
}
@@ -349,7 +243,7 @@ class PacketSequenceState {
int64_t track_event_thread_timestamp_ns_ = 0;
int64_t track_event_thread_instruction_count_ = 0;
- std::shared_ptr<PacketSequenceStateGeneration> current_generation_;
+ RefPtr<PacketSequenceStateGeneration> current_generation_;
SequenceStackProfileTracker sequence_stack_profile_tracker_;
};
diff --git a/src/trace_processor/importers/proto/perf_sample_tracker.cc b/src/trace_processor/importers/proto/perf_sample_tracker.cc
index d14d2aaed..4da16addc 100644
--- a/src/trace_processor/importers/proto/perf_sample_tracker.cc
+++ b/src/trace_processor/importers/proto/perf_sample_tracker.cc
@@ -15,9 +15,11 @@
*/
#include "src/trace_processor/importers/proto/perf_sample_tracker.h"
-#include <inttypes.h>
#include <stdio.h>
+#include <cinttypes>
+
+#include "perfetto/ext/base/string_utils.h"
#include "src/trace_processor/importers/common/track_tracker.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/trace_processor_context.h"
@@ -34,17 +36,53 @@ namespace {
const char* StringifyCounter(int32_t counter) {
using protos::pbzero::PerfEvents;
switch (counter) {
- case (PerfEvents::SW_CPU_CLOCK):
+ // software:
+ case PerfEvents::SW_CPU_CLOCK:
return "cpu-clock";
- case (PerfEvents::SW_PAGE_FAULTS):
+ case PerfEvents::SW_PAGE_FAULTS:
return "page-faults";
- case (PerfEvents::HW_CPU_CYCLES):
+ case PerfEvents::SW_TASK_CLOCK:
+ return "task-clock";
+ case PerfEvents::SW_CONTEXT_SWITCHES:
+ return "context-switches";
+ case PerfEvents::SW_CPU_MIGRATIONS:
+ return "cpu-migrations";
+ case PerfEvents::SW_PAGE_FAULTS_MIN:
+ return "minor-faults";
+ case PerfEvents::SW_PAGE_FAULTS_MAJ:
+ return "major-faults";
+ case PerfEvents::SW_ALIGNMENT_FAULTS:
+ return "alignment-faults";
+ case PerfEvents::SW_EMULATION_FAULTS:
+ return "emulation-faults";
+ case PerfEvents::SW_DUMMY:
+ return "dummy";
+ // hardware:
+ case PerfEvents::HW_CPU_CYCLES:
return "cpu-cycles";
- case (PerfEvents::HW_INSTRUCTIONS):
+ case PerfEvents::HW_INSTRUCTIONS:
return "instructions";
+ case PerfEvents::HW_CACHE_REFERENCES:
+ return "cache-references";
+ case PerfEvents::HW_CACHE_MISSES:
+ return "cache-misses";
+ case PerfEvents::HW_BRANCH_INSTRUCTIONS:
+ return "branch-instructions";
+ case PerfEvents::HW_BRANCH_MISSES:
+ return "branch-misses";
+ case PerfEvents::HW_BUS_CYCLES:
+ return "bus-cycles";
+ case PerfEvents::HW_STALLED_CYCLES_FRONTEND:
+ return "stalled-cycles-frontend";
+ case PerfEvents::HW_STALLED_CYCLES_BACKEND:
+ return "stalled-cycles-backend";
+ case PerfEvents::HW_REF_CPU_CYCLES:
+ return "ref-cycles";
+
default:
break;
}
+ PERFETTO_DLOG("Unknown PerfEvents::Counter enum value");
return "unknown";
}
@@ -55,11 +93,29 @@ StringId InternTimebaseCounterName(
PerfSampleDefaults::Decoder perf_defaults(defaults->perf_sample_defaults());
PerfEvents::Timebase::Decoder timebase(perf_defaults.timebase());
- if (timebase.counter() != PerfEvents::UNKNOWN_COUNTER) {
+ auto config_given_name = timebase.name();
+ if (config_given_name.size > 0) {
+ return context->storage->InternString(config_given_name);
+ }
+ if (timebase.has_counter()) {
return context->storage->InternString(StringifyCounter(timebase.counter()));
}
- PerfEvents::Tracepoint::Decoder tracepoint(timebase.tracepoint());
- return context->storage->InternString(tracepoint.name());
+ if (timebase.has_tracepoint()) {
+ PerfEvents::Tracepoint::Decoder tracepoint(timebase.tracepoint());
+ return context->storage->InternString(tracepoint.name());
+ }
+ if (timebase.has_raw_event()) {
+ PerfEvents::RawEvent::Decoder raw(timebase.raw_event());
+ // This doesn't follow any pre-existing naming scheme, but aims to be a
+ // short-enough default that is distinguishable.
+ base::StackString<128> name(
+ "raw.0x%" PRIx32 ".0x%" PRIx64 ".0x%" PRIx64 ".0x%" PRIx64, raw.type(),
+ raw.config(), raw.config1(), raw.config2());
+ return context->storage->InternString(name.string_view());
+ }
+
+ PERFETTO_DLOG("Could not name the perf timebase counter");
+ return context->storage->InternString("unknown");
}
} // namespace
diff --git a/src/trace_processor/importers/proto/perf_sample_tracker_unittest.cc b/src/trace_processor/importers/proto/perf_sample_tracker_unittest.cc
index 16c65b3ba..23b1d1d61 100644
--- a/src/trace_processor/importers/proto/perf_sample_tracker_unittest.cc
+++ b/src/trace_processor/importers/proto/perf_sample_tracker_unittest.cc
@@ -150,6 +150,40 @@ TEST_F(PerfSampleTrackerTest, UnknownCounterTreatedAsCpuClock) {
ASSERT_EQ(track_name, "cpu-clock");
}
+// Like TimebaseTrackName_Counter, but with a config supplying an explicit name
+// for the counter.
+TEST_F(PerfSampleTrackerTest, TimebaseTrackName_ConfigSuppliedName) {
+ uint32_t seq_id = 42;
+ uint32_t cpu0 = 0;
+
+ protos::gen::TracePacketDefaults defaults;
+ auto* perf_defaults = defaults.mutable_perf_sample_defaults();
+ perf_defaults->mutable_timebase()->set_name("test-name");
+ perf_defaults->mutable_timebase()->set_frequency(100);
+ perf_defaults->mutable_timebase()->set_counter(
+ protos::gen::PerfEvents::SW_PAGE_FAULTS);
+ auto defaults_pb = defaults.SerializeAsString();
+ protos::pbzero::TracePacketDefaults::Decoder defaults_decoder(defaults_pb);
+
+ auto stream = context.perf_sample_tracker->GetSamplingStreamInfo(
+ seq_id, cpu0, &defaults_decoder);
+
+ TrackId track_id = stream.timebase_track_id;
+ const auto& track_table = context.storage->perf_counter_track_table();
+ auto row_id = track_table.id().IndexOf(track_id);
+
+ // track exists and looks sensible
+ ASSERT_TRUE(row_id.has_value());
+ EXPECT_EQ(track_table.perf_session_id()[*row_id], stream.perf_session_id);
+ EXPECT_EQ(track_table.cpu()[*row_id], cpu0);
+ EXPECT_TRUE(track_table.is_timebase()[*row_id]);
+
+ // Using the config-supplied name for the track.
+ std::string track_name =
+ context.storage->GetString(track_table.name()[*row_id]).ToStdString();
+ ASSERT_EQ(track_name, "test-name");
+}
+
} // namespace
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/importers/proto/profile_module.cc b/src/trace_processor/importers/proto/profile_module.cc
index ca72192bb..f679ca947 100644
--- a/src/trace_processor/importers/proto/profile_module.cc
+++ b/src/trace_processor/importers/proto/profile_module.cc
@@ -17,12 +17,15 @@
#include "src/trace_processor/importers/proto/profile_module.h"
#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/string_utils.h"
#include "src/trace_processor/importers/common/clock_tracker.h"
#include "src/trace_processor/importers/common/event_tracker.h"
#include "src/trace_processor/importers/common/process_tracker.h"
+#include "src/trace_processor/importers/proto/heap_profile_tracker.h"
#include "src/trace_processor/importers/proto/packet_sequence_state.h"
#include "src/trace_processor/importers/proto/perf_sample_tracker.h"
#include "src/trace_processor/importers/proto/profile_packet_utils.h"
+#include "src/trace_processor/importers/proto/profiler_util.h"
#include "src/trace_processor/importers/proto/stack_profile_tracker.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/tables/profiler_tables.h"
@@ -32,7 +35,10 @@
#include "protos/perfetto/common/builtin_clock.pbzero.h"
#include "protos/perfetto/common/perf_events.pbzero.h"
+#include "protos/perfetto/trace/profiling/deobfuscation.pbzero.h"
+#include "protos/perfetto/trace/profiling/profile_common.pbzero.h"
#include "protos/perfetto/trace/profiling/profile_packet.pbzero.h"
+#include "protos/perfetto/trace/profiling/smaps.pbzero.h"
namespace perfetto {
namespace trace_processor {
@@ -44,6 +50,11 @@ ProfileModule::ProfileModule(TraceProcessorContext* context)
: context_(context) {
RegisterForField(TracePacket::kStreamingProfilePacketFieldNumber, context);
RegisterForField(TracePacket::kPerfSampleFieldNumber, context);
+ RegisterForField(TracePacket::kProfilePacketFieldNumber, context);
+ RegisterForField(TracePacket::kModuleSymbolsFieldNumber, context);
+ // note: deobfuscation mappings also handled by HeapGraphModule.
+ RegisterForField(TracePacket::kDeobfuscationMappingFieldNumber, context);
+ RegisterForField(TracePacket::kSmapsPacketFieldNumber, context);
}
ProfileModule::~ProfileModule() = default;
@@ -76,6 +87,27 @@ void ProfileModule::ParsePacket(const TracePacket::Decoder& decoder,
ParsePerfSample(ttp.timestamp, ttp.packet_data.sequence_state.get(),
decoder);
return;
+ case TracePacket::kProfilePacketFieldNumber:
+ PERFETTO_DCHECK(ttp.type == TimestampedTracePiece::Type::kTracePacket);
+ ParseProfilePacket(ttp.timestamp, ttp.packet_data.sequence_state.get(),
+ decoder.trusted_packet_sequence_id(),
+ decoder.profile_packet());
+ return;
+ case TracePacket::kModuleSymbolsFieldNumber:
+ PERFETTO_DCHECK(ttp.type == TimestampedTracePiece::Type::kTracePacket);
+ ParseModuleSymbols(decoder.module_symbols());
+ return;
+ case TracePacket::kDeobfuscationMappingFieldNumber:
+ PERFETTO_DCHECK(ttp.type == TimestampedTracePiece::Type::kTracePacket);
+ ParseDeobfuscationMapping(ttp.timestamp,
+ ttp.packet_data.sequence_state.get(),
+ decoder.trusted_packet_sequence_id(),
+ decoder.deobfuscation_mapping());
+ return;
+ case TracePacket::kSmapsPacketFieldNumber:
+ PERFETTO_DCHECK(ttp.type == TimestampedTracePiece::Type::kTracePacket);
+ ParseSmapsPacket(ttp.timestamp, decoder.smaps_packet());
+ return;
}
}
@@ -217,9 +249,6 @@ void ProfileModule::ParsePerfSample(
ts, static_cast<double>(sample.timebase_count()),
sampling_stream.timebase_track_id);
- // TODO(rsavitski): empty callsite is not an error for counter-only samples.
- // But consider identifying sequences which *should* have a callstack in every
- // sample, as an invalid stack there is a bug.
SequenceStackProfileTracker& stack_tracker =
sequence_state->state()->sequence_stack_profile_tracker();
ProfilePacketInternLookup intern_lookup(sequence_state);
@@ -227,6 +256,27 @@ void ProfileModule::ParsePerfSample(
base::Optional<CallsiteId> cs_id =
stack_tracker.FindOrInsertCallstack(callstack_iid, &intern_lookup);
+ // A failed lookup of the interned callstack can mean either:
+ // (a) This is a counter-only profile without callstacks. Due to an
+ // implementation quirk, these packets still set callstack_iid
+ // corresponding to a callstack with no frames. To reliably identify this
+ // case (without resorting to config parsing) we further need to rely on
+ // the fact that the implementation (callstack_trie.h) always assigns this
+ // callstack the id "1". Such callstacks should not occur outside of
+ // counter-only profiles, as there should always be at least a synthetic
+ // error frame if the unwinding completely failed.
+ // (b) This is a ring-buffer profile where some of the referenced internings
+ // have been overwritten, and the build predates perf_sample_defaults and
+ // SEQ_NEEDS_INCREMENTAL_STATE sequence flag in perf_sample packets.
+ // Such packets should be discarded.
+ if (!cs_id && callstack_iid != 1) {
+ PERFETTO_DLOG("Discarding perf_sample since callstack_iid [%" PRIu64
+ "] references a missing/partially lost interning according "
+ "to stack_profile_tracker",
+ callstack_iid);
+ return;
+ }
+
UniqueTid utid =
context_->process_tracker->UpdateThread(sample.tid(), sample.pid());
@@ -250,5 +300,287 @@ void ProfileModule::ParsePerfSample(
context_->storage->mutable_perf_sample_table()->Insert(sample_row);
}
+void ProfileModule::ParseProfilePacket(
+ int64_t ts,
+ PacketSequenceStateGeneration* sequence_state,
+ uint32_t seq_id,
+ ConstBytes blob) {
+ protos::pbzero::ProfilePacket::Decoder packet(blob.data, blob.size);
+ context_->heap_profile_tracker->SetProfilePacketIndex(seq_id, packet.index());
+
+ for (auto it = packet.strings(); it; ++it) {
+ protos::pbzero::InternedString::Decoder entry(*it);
+
+ const char* str = reinterpret_cast<const char*>(entry.str().data);
+ auto str_view = base::StringView(str, entry.str().size);
+ sequence_state->state()->sequence_stack_profile_tracker().AddString(
+ entry.iid(), str_view);
+ }
+
+ for (auto it = packet.mappings(); it; ++it) {
+ protos::pbzero::Mapping::Decoder entry(*it);
+ SequenceStackProfileTracker::SourceMapping src_mapping =
+ ProfilePacketUtils::MakeSourceMapping(entry);
+ sequence_state->state()->sequence_stack_profile_tracker().AddMapping(
+ entry.iid(), src_mapping);
+ }
+
+ for (auto it = packet.frames(); it; ++it) {
+ protos::pbzero::Frame::Decoder entry(*it);
+ SequenceStackProfileTracker::SourceFrame src_frame =
+ ProfilePacketUtils::MakeSourceFrame(entry);
+ sequence_state->state()->sequence_stack_profile_tracker().AddFrame(
+ entry.iid(), src_frame);
+ }
+
+ for (auto it = packet.callstacks(); it; ++it) {
+ protos::pbzero::Callstack::Decoder entry(*it);
+ SequenceStackProfileTracker::SourceCallstack src_callstack =
+ ProfilePacketUtils::MakeSourceCallstack(entry);
+ sequence_state->state()->sequence_stack_profile_tracker().AddCallstack(
+ entry.iid(), src_callstack);
+ }
+
+ for (auto it = packet.process_dumps(); it; ++it) {
+ protos::pbzero::ProfilePacket::ProcessHeapSamples::Decoder entry(*it);
+
+ auto maybe_timestamp = context_->clock_tracker->ToTraceTime(
+ protos::pbzero::BUILTIN_CLOCK_MONOTONIC_COARSE,
+ static_cast<int64_t>(entry.timestamp()));
+
+ // ToTraceTime() increments the clock_sync_failure error stat in this case.
+ if (!maybe_timestamp)
+ continue;
+
+ int64_t timestamp = *maybe_timestamp;
+
+ int pid = static_cast<int>(entry.pid());
+ context_->storage->SetIndexedStats(stats::heapprofd_last_profile_timestamp,
+ pid, ts);
+
+ if (entry.disconnected())
+ context_->storage->IncrementIndexedStats(
+ stats::heapprofd_client_disconnected, pid);
+ if (entry.buffer_corrupted())
+ context_->storage->IncrementIndexedStats(
+ stats::heapprofd_buffer_corrupted, pid);
+ if (entry.buffer_overran() ||
+ entry.client_error() ==
+ protos::pbzero::ProfilePacket::ProcessHeapSamples::
+ CLIENT_ERROR_HIT_TIMEOUT) {
+ context_->storage->IncrementIndexedStats(stats::heapprofd_buffer_overran,
+ pid);
+ }
+ if (entry.client_error()) {
+ context_->storage->SetIndexedStats(stats::heapprofd_client_error, pid,
+ entry.client_error());
+ }
+ if (entry.rejected_concurrent())
+ context_->storage->IncrementIndexedStats(
+ stats::heapprofd_rejected_concurrent, pid);
+ if (entry.hit_guardrail())
+ context_->storage->IncrementIndexedStats(stats::heapprofd_hit_guardrail,
+ pid);
+ if (entry.orig_sampling_interval_bytes()) {
+ context_->storage->SetIndexedStats(
+ stats::heapprofd_sampling_interval_adjusted, pid,
+ static_cast<int64_t>(entry.sampling_interval_bytes()) -
+ static_cast<int64_t>(entry.orig_sampling_interval_bytes()));
+ }
+
+ protos::pbzero::ProfilePacket::ProcessStats::Decoder stats(entry.stats());
+ context_->storage->IncrementIndexedStats(
+ stats::heapprofd_unwind_time_us, static_cast<int>(entry.pid()),
+ static_cast<int64_t>(stats.total_unwinding_time_us()));
+ context_->storage->IncrementIndexedStats(
+ stats::heapprofd_unwind_samples, static_cast<int>(entry.pid()),
+ static_cast<int64_t>(stats.heap_samples()));
+ context_->storage->IncrementIndexedStats(
+ stats::heapprofd_client_spinlock_blocked, static_cast<int>(entry.pid()),
+ static_cast<int64_t>(stats.client_spinlock_blocked_us()));
+
+ // orig_sampling_interval_bytes was introduced slightly after a bug with
+ // self_max_count was fixed in the producer. We use this as a proxy
+ // whether or not we are getting this data from a fixed producer or not.
+ bool trustworthy_max_count = entry.orig_sampling_interval_bytes() > 0;
+
+ for (auto sample_it = entry.samples(); sample_it; ++sample_it) {
+ protos::pbzero::ProfilePacket::HeapSample::Decoder sample(*sample_it);
+
+ HeapProfileTracker::SourceAllocation src_allocation;
+ src_allocation.pid = entry.pid();
+ if (entry.heap_name().size != 0) {
+ src_allocation.heap_name =
+ context_->storage->InternString(entry.heap_name());
+ } else {
+ src_allocation.heap_name = context_->storage->InternString("malloc");
+ }
+ src_allocation.timestamp = timestamp;
+ src_allocation.callstack_id = sample.callstack_id();
+ if (sample.has_self_max()) {
+ src_allocation.self_allocated = sample.self_max();
+ if (trustworthy_max_count)
+ src_allocation.alloc_count = sample.self_max_count();
+ } else {
+ src_allocation.self_allocated = sample.self_allocated();
+ src_allocation.self_freed = sample.self_freed();
+ src_allocation.alloc_count = sample.alloc_count();
+ src_allocation.free_count = sample.free_count();
+ }
+
+ context_->heap_profile_tracker->StoreAllocation(seq_id, src_allocation);
+ }
+ }
+ if (!packet.continued()) {
+ PERFETTO_CHECK(sequence_state);
+ ProfilePacketInternLookup intern_lookup(sequence_state);
+ context_->heap_profile_tracker->FinalizeProfile(
+ seq_id, &sequence_state->state()->sequence_stack_profile_tracker(),
+ &intern_lookup);
+ }
+}
+
+void ProfileModule::ParseModuleSymbols(ConstBytes blob) {
+ protos::pbzero::ModuleSymbols::Decoder module_symbols(blob.data, blob.size);
+ StringId build_id;
+ // TODO(b/148109467): Remove workaround once all active Chrome versions
+ // write raw bytes instead of a string as build_id.
+ if (module_symbols.build_id().size == 33) {
+ build_id = context_->storage->InternString(module_symbols.build_id());
+ } else {
+ build_id = context_->storage->InternString(base::StringView(base::ToHex(
+ module_symbols.build_id().data, module_symbols.build_id().size)));
+ }
+
+ auto mapping_ids = context_->global_stack_profile_tracker->FindMappingRow(
+ context_->storage->InternString(module_symbols.path()), build_id);
+ if (mapping_ids.empty()) {
+ context_->storage->IncrementStats(stats::stackprofile_invalid_mapping_id);
+ return;
+ }
+ for (auto addr_it = module_symbols.address_symbols(); addr_it; ++addr_it) {
+ protos::pbzero::AddressSymbols::Decoder address_symbols(*addr_it);
+
+ uint32_t symbol_set_id = context_->storage->symbol_table().row_count();
+
+ bool has_lines = false;
+ for (auto line_it = address_symbols.lines(); line_it; ++line_it) {
+ protos::pbzero::Line::Decoder line(*line_it);
+ context_->storage->mutable_symbol_table()->Insert(
+ {symbol_set_id, context_->storage->InternString(line.function_name()),
+ context_->storage->InternString(line.source_file_name()),
+ line.line_number()});
+ has_lines = true;
+ }
+ if (!has_lines) {
+ continue;
+ }
+ bool frame_found = false;
+ for (MappingId mapping_id : mapping_ids) {
+ std::vector<FrameId> frame_ids =
+ context_->global_stack_profile_tracker->FindFrameIds(
+ mapping_id, address_symbols.address());
+
+ for (const FrameId frame_id : frame_ids) {
+ auto* frames = context_->storage->mutable_stack_profile_frame_table();
+ uint32_t frame_row = *frames->id().IndexOf(frame_id);
+ frames->mutable_symbol_set_id()->Set(frame_row, symbol_set_id);
+ frame_found = true;
+ }
+ }
+
+ if (!frame_found) {
+ context_->storage->IncrementStats(stats::stackprofile_invalid_frame_id);
+ continue;
+ }
+ }
+}
+
+void ProfileModule::ParseDeobfuscationMapping(int64_t,
+ PacketSequenceStateGeneration*,
+ uint32_t /* seq_id */,
+ ConstBytes blob) {
+ protos::pbzero::DeobfuscationMapping::Decoder deobfuscation_mapping(
+ blob.data, blob.size);
+ if (deobfuscation_mapping.package_name().size == 0)
+ return;
+
+ auto opt_package_name_id = context_->storage->string_pool().GetId(
+ deobfuscation_mapping.package_name());
+ auto opt_memfd_id = context_->storage->string_pool().GetId("memfd");
+ if (!opt_package_name_id && !opt_memfd_id)
+ return;
+
+ for (auto class_it = deobfuscation_mapping.obfuscated_classes(); class_it;
+ ++class_it) {
+ protos::pbzero::ObfuscatedClass::Decoder cls(*class_it);
+ for (auto member_it = cls.obfuscated_methods(); member_it; ++member_it) {
+ protos::pbzero::ObfuscatedMember::Decoder member(*member_it);
+ std::string merged_obfuscated = cls.obfuscated_name().ToStdString() +
+ "." +
+ member.obfuscated_name().ToStdString();
+ auto merged_obfuscated_id = context_->storage->string_pool().GetId(
+ base::StringView(merged_obfuscated));
+ if (!merged_obfuscated_id)
+ continue;
+ std::string merged_deobfuscated =
+ FullyQualifiedDeobfuscatedName(cls, member);
+
+ std::vector<tables::StackProfileFrameTable::Id> frames;
+ if (opt_package_name_id) {
+ const std::vector<tables::StackProfileFrameTable::Id>* pkg_frames =
+ context_->global_stack_profile_tracker->JavaFramesForName(
+ {*merged_obfuscated_id, *opt_package_name_id});
+ if (pkg_frames) {
+ frames.insert(frames.end(), pkg_frames->begin(), pkg_frames->end());
+ }
+ }
+ if (opt_memfd_id) {
+ const std::vector<tables::StackProfileFrameTable::Id>* memfd_frames =
+ context_->global_stack_profile_tracker->JavaFramesForName(
+ {*merged_obfuscated_id, *opt_memfd_id});
+ if (memfd_frames) {
+ frames.insert(frames.end(), memfd_frames->begin(),
+ memfd_frames->end());
+ }
+ }
+
+ for (tables::StackProfileFrameTable::Id frame_id : frames) {
+ auto* frames_tbl =
+ context_->storage->mutable_stack_profile_frame_table();
+ frames_tbl->mutable_deobfuscated_name()->Set(
+ *frames_tbl->id().IndexOf(frame_id),
+ context_->storage->InternString(
+ base::StringView(merged_deobfuscated)));
+ }
+ }
+ }
+}
+
+void ProfileModule::ParseSmapsPacket(int64_t ts, ConstBytes blob) {
+ protos::pbzero::SmapsPacket::Decoder sp(blob.data, blob.size);
+ auto upid = context_->process_tracker->GetOrCreateProcess(sp.pid());
+
+ for (auto it = sp.entries(); it; ++it) {
+ protos::pbzero::SmapsEntry::Decoder e(*it);
+ context_->storage->mutable_profiler_smaps_table()->Insert(
+ {upid, ts, context_->storage->InternString(e.path()),
+ static_cast<int64_t>(e.size_kb()),
+ static_cast<int64_t>(e.private_dirty_kb()),
+ static_cast<int64_t>(e.swap_kb()),
+ context_->storage->InternString(e.file_name()),
+ static_cast<int64_t>(e.start_address()),
+ static_cast<int64_t>(e.module_timestamp()),
+ context_->storage->InternString(e.module_debugid()),
+ context_->storage->InternString(e.module_debug_path()),
+ static_cast<int32_t>(e.protection_flags()),
+ static_cast<int64_t>(e.private_clean_resident_kb()),
+ static_cast<int64_t>(e.shared_dirty_resident_kb()),
+ static_cast<int64_t>(e.shared_clean_resident_kb()),
+ static_cast<int64_t>(e.locked_kb()),
+ static_cast<int64_t>(e.proportional_resident_kb())});
+ }
+}
+
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/importers/proto/profile_module.h b/src/trace_processor/importers/proto/profile_module.h
index f2fd43bbd..92f3384f8 100644
--- a/src/trace_processor/importers/proto/profile_module.h
+++ b/src/trace_processor/importers/proto/profile_module.h
@@ -45,6 +45,7 @@ class ProfileModule : public ProtoImporterModule {
uint32_t field_id) override;
private:
+ // chrome stack sampling:
ModuleResult TokenizeStreamingProfilePacket(
PacketSequenceState*,
TraceBlobView* packet,
@@ -54,10 +55,23 @@ class ProfileModule : public ProtoImporterModule {
PacketSequenceStateGeneration*,
protozero::ConstBytes streaming_profile_packet);
+ // perf event profiling:
void ParsePerfSample(int64_t ts,
PacketSequenceStateGeneration* sequence_state,
const protos::pbzero::TracePacket::Decoder& decoder);
+ // heap profiling:
+ void ParseProfilePacket(int64_t ts,
+ PacketSequenceStateGeneration*,
+ uint32_t seq_id,
+ protozero::ConstBytes);
+ void ParseDeobfuscationMapping(int64_t ts,
+ PacketSequenceStateGeneration*,
+ uint32_t seq_id,
+ protozero::ConstBytes);
+ void ParseModuleSymbols(protozero::ConstBytes);
+ void ParseSmapsPacket(int64_t ts, protozero::ConstBytes);
+
TraceProcessorContext* context_;
};
diff --git a/src/trace_processor/importers/proto/profile_packet_utils.h b/src/trace_processor/importers/proto/profile_packet_utils.h
index 2dde3889f..08c8a46d5 100644
--- a/src/trace_processor/importers/proto/profile_packet_utils.h
+++ b/src/trace_processor/importers/proto/profile_packet_utils.h
@@ -113,6 +113,12 @@ class ProfilePacketUtils {
return "thread_timeout";
case Profiling::UNWIND_ERROR_THREAD_DOES_NOT_EXIST:
return "thread_does_not_exist";
+ case Profiling::UNWIND_ERROR_BAD_ARCH:
+ return "bad_arch";
+ case Profiling::UNWIND_ERROR_MAPS_PARSE:
+ return "maps_parse";
+ case Profiling::UNWIND_ERROR_INVALID_PARAMETER:
+ return "invalid_parameter";
}
return "unknown"; // switch should be complete, but gcc needs a hint
}
diff --git a/src/trace_processor/importers/proto/profiler_util.cc b/src/trace_processor/importers/proto/profiler_util.cc
index 175942f9a..add6ce476 100644
--- a/src/trace_processor/importers/proto/profiler_util.cc
+++ b/src/trace_processor/importers/proto/profiler_util.cc
@@ -24,23 +24,28 @@ namespace perfetto {
namespace trace_processor {
namespace {
+// Try to extract the package name from a path like:
+// * /data/app/[packageName]-[randomString]/base.apk
+// * /data/app/~~[randomStringA]/[packageName]-[randomStringB]/base.apk
+// The latter is newer (R+), and was added to avoid leaking package names via
+// mountinfo of incremental apk mounts.
base::Optional<base::StringView> PackageFromApp(base::StringView location) {
location = location.substr(base::StringView("/data/app/").size());
size_t start = 0;
if (location.at(0) == '~') {
size_t slash = location.find('/');
- if (slash == std::string::npos) {
+ if (slash == base::StringView::npos) {
return base::nullopt;
}
start = slash + 1;
}
size_t end = location.find('/', start + 1);
- if (end == std::string::npos) {
+ if (end == base::StringView::npos) {
return base::nullopt;
}
location = location.substr(start, end);
size_t minus = location.find('-');
- if (minus == std::string::npos) {
+ if (minus == base::StringView::npos) {
return base::nullopt;
}
return location.substr(0, minus);
@@ -99,12 +104,23 @@ base::Optional<std::string> PackageFromLocation(TraceStorage* storage,
return "com.google.android.as";
}
+ if (location.find("DeviceIntelligenceNetworkPrebuilt") !=
+ base::StringView::npos) {
+ return "com.google.android.as.oss";
+ }
+
+ if (location.find("SettingsIntelligenceGooglePrebuilt") !=
+ base::StringView::npos) {
+ return "com.google.android.settings.intelligence";
+ }
+
base::StringView gm("/product/app/PrebuiltGmail/PrebuiltGmail.apk");
if (location.size() >= gm.size() && location.substr(0, gm.size()) == gm) {
return "com.google.android.gm";
}
- if (location.find("PrebuiltGmsCore") != std::string::npos) {
+ if (location.find("PrebuiltGmsCore") != base::StringView::npos ||
+ location.find("com.google.android.gms") != base::StringView::npos) {
return "com.google.android.gms";
}
@@ -127,16 +143,39 @@ base::Optional<std::string> PackageFromLocation(TraceStorage* storage,
return "com.google.android.apps.messaging";
}
- base::StringView data_app("/data/app/");
- if (location.substr(0, data_app.size()) == data_app) {
- auto package = PackageFromApp(location);
+ // Deal with paths to /data/app/...
+
+ auto extract_package =
+ [storage](base::StringView path) -> base::Optional<std::string> {
+ auto package = PackageFromApp(path);
if (!package) {
- PERFETTO_DLOG("Failed to parse %s", location.ToStdString().c_str());
+ PERFETTO_DLOG("Failed to parse %s", path.ToStdString().c_str());
storage->IncrementStats(stats::deobfuscate_location_parse_error);
return base::nullopt;
}
return package->ToStdString();
+ };
+
+ base::StringView data_app("/data/app/");
+ size_t data_app_sz = data_app.size();
+ if (location.substr(0, data_app.size()) == data_app) {
+ return extract_package(location);
}
+
+ // Check for in-memory decompressed dexfile, example prefixes:
+ // * "[anon:dalvik-classes.dex extracted in memory from"
+ // * "/dev/ashmem/dalvik-classes.dex extracted in memory from"
+ // The latter form is for older devices (Android P and before).
+ // We cannot hardcode the filename since it could be for example
+ // "classes2.dex" for multidex apks.
+ base::StringView inmem_dex("dex extracted in memory from /data/app/");
+ size_t match_pos = location.find(inmem_dex);
+ if (match_pos != base::StringView::npos) {
+ auto data_app_path =
+ location.substr(match_pos + inmem_dex.size() - data_app_sz);
+ return extract_package(data_app_path);
+ }
+
return base::nullopt;
}
diff --git a/src/trace_processor/importers/proto/proto_importer_module.h b/src/trace_processor/importers/proto/proto_importer_module.h
index d0a023a6b..c56f0344f 100644
--- a/src/trace_processor/importers/proto/proto_importer_module.h
+++ b/src/trace_processor/importers/proto/proto_importer_module.h
@@ -19,7 +19,6 @@
#include "perfetto/ext/base/optional.h"
#include "perfetto/trace_processor/status.h"
-#include "src/trace_processor/importers/common/trace_blob_view.h"
namespace perfetto {
@@ -34,6 +33,7 @@ namespace trace_processor {
class PacketSequenceState;
struct TimestampedTracePiece;
+class TraceBlobView;
class TraceProcessorContext;
// This file contains a base class for ProtoTraceReader/Parser modules.
diff --git a/src/trace_processor/importers/proto/proto_trace_parser.cc b/src/trace_processor/importers/proto/proto_trace_parser.cc
index 26383f2c7..521dc62d3 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser.cc
@@ -16,14 +16,13 @@
#include "src/trace_processor/importers/proto/proto_trace_parser.h"
-#include <inttypes.h>
#include <string.h>
+#include <cinttypes>
#include <string>
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/metatrace_events.h"
-#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/string_view.h"
#include "perfetto/ext/base/string_writer.h"
#include "perfetto/ext/base/utils.h"
@@ -38,15 +37,10 @@
#include "src/trace_processor/importers/common/track_tracker.h"
#include "src/trace_processor/importers/config.descriptor.h"
#include "src/trace_processor/importers/ftrace/ftrace_module.h"
-#include "src/trace_processor/importers/proto/heap_profile_tracker.h"
#include "src/trace_processor/importers/proto/metadata_tracker.h"
#include "src/trace_processor/importers/proto/packet_sequence_state.h"
-#include "src/trace_processor/importers/proto/profile_packet_utils.h"
-#include "src/trace_processor/importers/proto/profiler_util.h"
-#include "src/trace_processor/importers/proto/stack_profile_tracker.h"
#include "src/trace_processor/storage/metadata.h"
#include "src/trace_processor/storage/stats.h"
-#include "src/trace_processor/tables/profiler_tables.h"
#include "src/trace_processor/timestamped_trace_piece.h"
#include "src/trace_processor/types/trace_processor_context.h"
#include "src/trace_processor/types/variadic.h"
@@ -59,10 +53,6 @@
#include "protos/perfetto/trace/chrome/chrome_trace_event.pbzero.h"
#include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
#include "protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h"
-#include "protos/perfetto/trace/profiling/deobfuscation.pbzero.h"
-#include "protos/perfetto/trace/profiling/profile_common.pbzero.h"
-#include "protos/perfetto/trace/profiling/profile_packet.pbzero.h"
-#include "protos/perfetto/trace/profiling/smaps.pbzero.h"
#include "protos/perfetto/trace/trace.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
@@ -111,16 +101,8 @@ void ProtoTraceParser::ParseTracePacket(int64_t ts, TimestampedTracePiece ttp) {
void ProtoTraceParser::ParseTracePacketImpl(
int64_t ts,
const TimestampedTracePiece& ttp,
- PacketSequenceStateGeneration* sequence_state,
+ PacketSequenceStateGeneration* /*sequence_state*/,
const protos::pbzero::TracePacket::Decoder& packet) {
- // This needs to get handled both by the HeapGraphModule and
- // ProtoTraceParser (for StackProfileTracker).
- if (packet.has_deobfuscation_mapping()) {
- ParseDeobfuscationMapping(ts, sequence_state,
- packet.trusted_packet_sequence_id(),
- packet.deobfuscation_mapping());
- }
-
// Chrome doesn't honor the one-of in TracePacket for this field and sets it
// together with chrome_metadata, which is handled by a module. Thus, we have
// to parse this field before the modules get to parse other fields.
@@ -143,11 +125,6 @@ void ProtoTraceParser::ParseTracePacketImpl(
if (packet.has_trace_stats())
ParseTraceStats(packet.trace_stats());
- if (packet.has_profile_packet()) {
- ParseProfilePacket(ts, sequence_state, packet.trusted_packet_sequence_id(),
- packet.profile_packet());
- }
-
if (packet.has_perfetto_metatrace()) {
ParseMetatraceEvent(ts, packet.perfetto_metatrace());
}
@@ -155,14 +132,6 @@ void ProtoTraceParser::ParseTracePacketImpl(
if (packet.has_trace_config()) {
ParseTraceConfig(packet.trace_config());
}
-
- if (packet.has_module_symbols()) {
- ParseModuleSymbols(packet.module_symbols());
- }
-
- if (packet.has_smaps_packet()) {
- ParseSmapsPacket(ts, packet.smaps_packet());
- }
}
void ProtoTraceParser::ParseFtracePacket(uint32_t cpu,
@@ -197,6 +166,22 @@ void ProtoTraceParser::ParseTraceStats(ConstBytes blob) {
static_cast<int64_t>(evt.chunks_discarded()));
storage->SetStats(stats::traced_patches_discarded,
static_cast<int64_t>(evt.patches_discarded()));
+ storage->SetStats(stats::traced_flushes_requested,
+ static_cast<int64_t>(evt.flushes_requested()));
+ storage->SetStats(stats::traced_flushes_succeeded,
+ static_cast<int64_t>(evt.flushes_succeeded()));
+ storage->SetStats(stats::traced_flushes_failed,
+ static_cast<int64_t>(evt.flushes_failed()));
+ switch (evt.final_flush_outcome()) {
+ case protos::pbzero::TraceStats::FINAL_FLUSH_SUCCEEDED:
+ storage->IncrementStats(stats::traced_final_flush_succeeded, 1);
+ break;
+ case protos::pbzero::TraceStats::FINAL_FLUSH_FAILED:
+ storage->IncrementStats(stats::traced_final_flush_failed, 1);
+ break;
+ case protos::pbzero::TraceStats::FINAL_FLUSH_UNSPECIFIED:
+ break;
+ }
int buf_num = 0;
for (auto it = evt.buffer_stats(); it; ++it, ++buf_num) {
@@ -236,213 +221,14 @@ void ProtoTraceParser::ParseTraceStats(ConstBytes blob) {
static_cast<int64_t>(buf.readaheads_succeeded()));
storage->SetIndexedStats(stats::traced_buf_readaheads_failed, buf_num,
static_cast<int64_t>(buf.readaheads_failed()));
+ storage->SetIndexedStats(stats::traced_buf_abi_violations, buf_num,
+ static_cast<int64_t>(buf.abi_violations()));
storage->SetIndexedStats(
stats::traced_buf_trace_writer_packet_loss, buf_num,
static_cast<int64_t>(buf.trace_writer_packet_loss()));
}
}
-void ProtoTraceParser::ParseProfilePacket(
- int64_t ts,
- PacketSequenceStateGeneration* sequence_state,
- uint32_t seq_id,
- ConstBytes blob) {
- protos::pbzero::ProfilePacket::Decoder packet(blob.data, blob.size);
- context_->heap_profile_tracker->SetProfilePacketIndex(seq_id, packet.index());
-
- for (auto it = packet.strings(); it; ++it) {
- protos::pbzero::InternedString::Decoder entry(*it);
-
- const char* str = reinterpret_cast<const char*>(entry.str().data);
- auto str_view = base::StringView(str, entry.str().size);
- sequence_state->state()->sequence_stack_profile_tracker().AddString(
- entry.iid(), str_view);
- }
-
- for (auto it = packet.mappings(); it; ++it) {
- protos::pbzero::Mapping::Decoder entry(*it);
- SequenceStackProfileTracker::SourceMapping src_mapping =
- ProfilePacketUtils::MakeSourceMapping(entry);
- sequence_state->state()->sequence_stack_profile_tracker().AddMapping(
- entry.iid(), src_mapping);
- }
-
- for (auto it = packet.frames(); it; ++it) {
- protos::pbzero::Frame::Decoder entry(*it);
- SequenceStackProfileTracker::SourceFrame src_frame =
- ProfilePacketUtils::MakeSourceFrame(entry);
- sequence_state->state()->sequence_stack_profile_tracker().AddFrame(
- entry.iid(), src_frame);
- }
-
- for (auto it = packet.callstacks(); it; ++it) {
- protos::pbzero::Callstack::Decoder entry(*it);
- SequenceStackProfileTracker::SourceCallstack src_callstack =
- ProfilePacketUtils::MakeSourceCallstack(entry);
- sequence_state->state()->sequence_stack_profile_tracker().AddCallstack(
- entry.iid(), src_callstack);
- }
-
- for (auto it = packet.process_dumps(); it; ++it) {
- protos::pbzero::ProfilePacket::ProcessHeapSamples::Decoder entry(*it);
-
- auto maybe_timestamp = context_->clock_tracker->ToTraceTime(
- protos::pbzero::BUILTIN_CLOCK_MONOTONIC_COARSE,
- static_cast<int64_t>(entry.timestamp()));
-
- // ToTraceTime() increments the clock_sync_failure error stat in this case.
- if (!maybe_timestamp)
- continue;
-
- int64_t timestamp = *maybe_timestamp;
-
- int pid = static_cast<int>(entry.pid());
- context_->storage->SetIndexedStats(stats::heapprofd_last_profile_timestamp,
- pid, ts);
-
- if (entry.disconnected())
- context_->storage->IncrementIndexedStats(
- stats::heapprofd_client_disconnected, pid);
- if (entry.buffer_corrupted())
- context_->storage->IncrementIndexedStats(
- stats::heapprofd_buffer_corrupted, pid);
- if (entry.buffer_overran() ||
- entry.client_error() ==
- protos::pbzero::ProfilePacket::ProcessHeapSamples::
- CLIENT_ERROR_HIT_TIMEOUT) {
- context_->storage->IncrementIndexedStats(stats::heapprofd_buffer_overran,
- pid);
- }
- if (entry.client_error()) {
- context_->storage->SetIndexedStats(stats::heapprofd_client_error, pid,
- entry.client_error());
- }
- if (entry.rejected_concurrent())
- context_->storage->IncrementIndexedStats(
- stats::heapprofd_rejected_concurrent, pid);
- if (entry.hit_guardrail())
- context_->storage->IncrementIndexedStats(stats::heapprofd_hit_guardrail,
- pid);
- if (entry.orig_sampling_interval_bytes()) {
- context_->storage->SetIndexedStats(
- stats::heapprofd_sampling_interval_adjusted, pid,
- static_cast<int64_t>(entry.sampling_interval_bytes()) -
- static_cast<int64_t>(entry.orig_sampling_interval_bytes()));
- }
-
- protos::pbzero::ProfilePacket::ProcessStats::Decoder stats(entry.stats());
- context_->storage->IncrementIndexedStats(
- stats::heapprofd_unwind_time_us, static_cast<int>(entry.pid()),
- static_cast<int64_t>(stats.total_unwinding_time_us()));
- context_->storage->IncrementIndexedStats(
- stats::heapprofd_unwind_samples, static_cast<int>(entry.pid()),
- static_cast<int64_t>(stats.heap_samples()));
- context_->storage->IncrementIndexedStats(
- stats::heapprofd_client_spinlock_blocked, static_cast<int>(entry.pid()),
- static_cast<int64_t>(stats.client_spinlock_blocked_us()));
-
- // orig_sampling_interval_bytes was introduced slightly after a bug with
- // self_max_count was fixed in the producer. We use this as a proxy
- // whether or not we are getting this data from a fixed producer or not.
- bool trustworthy_max_count = entry.orig_sampling_interval_bytes() > 0;
-
- for (auto sample_it = entry.samples(); sample_it; ++sample_it) {
- protos::pbzero::ProfilePacket::HeapSample::Decoder sample(*sample_it);
-
- HeapProfileTracker::SourceAllocation src_allocation;
- src_allocation.pid = entry.pid();
- if (entry.heap_name().size != 0) {
- src_allocation.heap_name =
- context_->storage->InternString(entry.heap_name());
- } else {
- src_allocation.heap_name = context_->storage->InternString("malloc");
- }
- src_allocation.timestamp = timestamp;
- src_allocation.callstack_id = sample.callstack_id();
- if (sample.has_self_max()) {
- src_allocation.self_allocated = sample.self_max();
- if (trustworthy_max_count)
- src_allocation.alloc_count = sample.self_max_count();
- } else {
- src_allocation.self_allocated = sample.self_allocated();
- src_allocation.self_freed = sample.self_freed();
- src_allocation.alloc_count = sample.alloc_count();
- src_allocation.free_count = sample.free_count();
- }
-
- context_->heap_profile_tracker->StoreAllocation(seq_id, src_allocation);
- }
- }
- if (!packet.continued()) {
- PERFETTO_CHECK(sequence_state);
- ProfilePacketInternLookup intern_lookup(sequence_state);
- context_->heap_profile_tracker->FinalizeProfile(
- seq_id, &sequence_state->state()->sequence_stack_profile_tracker(),
- &intern_lookup);
- }
-}
-
-void ProtoTraceParser::ParseDeobfuscationMapping(int64_t,
- PacketSequenceStateGeneration*,
- uint32_t /* seq_id */,
- ConstBytes blob) {
- protos::pbzero::DeobfuscationMapping::Decoder deobfuscation_mapping(
- blob.data, blob.size);
- if (deobfuscation_mapping.package_name().size == 0)
- return;
-
- auto opt_package_name_id = context_->storage->string_pool().GetId(
- deobfuscation_mapping.package_name());
- auto opt_memfd_id = context_->storage->string_pool().GetId("memfd");
- if (!opt_package_name_id && !opt_memfd_id)
- return;
-
- for (auto class_it = deobfuscation_mapping.obfuscated_classes(); class_it;
- ++class_it) {
- protos::pbzero::ObfuscatedClass::Decoder cls(*class_it);
- for (auto member_it = cls.obfuscated_methods(); member_it; ++member_it) {
- protos::pbzero::ObfuscatedMember::Decoder member(*member_it);
- std::string merged_obfuscated = cls.obfuscated_name().ToStdString() +
- "." +
- member.obfuscated_name().ToStdString();
- auto merged_obfuscated_id = context_->storage->string_pool().GetId(
- base::StringView(merged_obfuscated));
- if (!merged_obfuscated_id)
- continue;
- std::string merged_deobfuscated =
- FullyQualifiedDeobfuscatedName(cls, member);
-
- std::vector<tables::StackProfileFrameTable::Id> frames;
- if (opt_package_name_id) {
- const std::vector<tables::StackProfileFrameTable::Id>* pkg_frames =
- context_->global_stack_profile_tracker->JavaFramesForName(
- {*merged_obfuscated_id, *opt_package_name_id});
- if (pkg_frames) {
- frames.insert(frames.end(), pkg_frames->begin(), pkg_frames->end());
- }
- }
- if (opt_memfd_id) {
- const std::vector<tables::StackProfileFrameTable::Id>* memfd_frames =
- context_->global_stack_profile_tracker->JavaFramesForName(
- {*merged_obfuscated_id, *opt_memfd_id});
- if (memfd_frames) {
- frames.insert(frames.end(), memfd_frames->begin(),
- memfd_frames->end());
- }
- }
-
- for (tables::StackProfileFrameTable::Id frame_id : frames) {
- auto* frames_tbl =
- context_->storage->mutable_stack_profile_frame_table();
- frames_tbl->mutable_deobfuscated_name()->Set(
- *frames_tbl->id().IndexOf(frame_id),
- context_->storage->InternString(
- base::StringView(merged_deobfuscated)));
- }
- }
- }
-}
-
void ProtoTraceParser::ParseChromeEvents(int64_t ts, ConstBytes blob) {
TraceStorage* storage = context_->storage.get();
protos::pbzero::ChromeEventBundle::Decoder bundle(blob.data, blob.size);
@@ -604,8 +390,9 @@ void ProtoTraceParser::ParseMetatraceEvent(int64_t ts, ConstBytes blob) {
name_id = context_->storage->InternString(event.event_name());
}
TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
- context_->slice_tracker->Scoped(ts, track_id, cat_id, name_id,
- event.event_duration_ns(), args_fn);
+ context_->slice_tracker->Scoped(
+ ts, track_id, cat_id, name_id,
+ static_cast<int64_t>(event.event_duration_ns()), args_fn);
} else if (event.has_counter_id() || event.has_counter_name()) {
if (event.has_counter_id()) {
auto cid = event.counter_id();
@@ -649,6 +436,7 @@ void ProtoTraceParser::ParseTraceConfig(ConstBytes blob) {
StringId id = context_->storage->InternString(base::StringView(str));
context_->metadata_tracker->SetMetadata(metadata::trace_uuid,
Variadic::String(id));
+ context_->uuid_found_in_trace = true;
}
if (trace_config.has_unique_session_name()) {
@@ -670,86 +458,5 @@ void ProtoTraceParser::ParseTraceConfig(ConstBytes blob) {
Variadic::String(id));
}
-void ProtoTraceParser::ParseModuleSymbols(ConstBytes blob) {
- protos::pbzero::ModuleSymbols::Decoder module_symbols(blob.data, blob.size);
- StringId build_id;
- // TODO(b/148109467): Remove workaround once all active Chrome versions
- // write raw bytes instead of a string as build_id.
- if (module_symbols.build_id().size == 33) {
- build_id = context_->storage->InternString(module_symbols.build_id());
- } else {
- build_id = context_->storage->InternString(base::StringView(base::ToHex(
- module_symbols.build_id().data, module_symbols.build_id().size)));
- }
-
- auto mapping_ids = context_->global_stack_profile_tracker->FindMappingRow(
- context_->storage->InternString(module_symbols.path()), build_id);
- if (mapping_ids.empty()) {
- context_->storage->IncrementStats(stats::stackprofile_invalid_mapping_id);
- return;
- }
- for (auto addr_it = module_symbols.address_symbols(); addr_it; ++addr_it) {
- protos::pbzero::AddressSymbols::Decoder address_symbols(*addr_it);
-
- uint32_t symbol_set_id = context_->storage->symbol_table().row_count();
-
- bool has_lines = false;
- for (auto line_it = address_symbols.lines(); line_it; ++line_it) {
- protos::pbzero::Line::Decoder line(*line_it);
- context_->storage->mutable_symbol_table()->Insert(
- {symbol_set_id, context_->storage->InternString(line.function_name()),
- context_->storage->InternString(line.source_file_name()),
- line.line_number()});
- has_lines = true;
- }
- if (!has_lines) {
- continue;
- }
- bool frame_found = false;
- for (MappingId mapping_id : mapping_ids) {
- std::vector<FrameId> frame_ids =
- context_->global_stack_profile_tracker->FindFrameIds(
- mapping_id, address_symbols.address());
-
- for (const FrameId frame_id : frame_ids) {
- auto* frames = context_->storage->mutable_stack_profile_frame_table();
- uint32_t frame_row = *frames->id().IndexOf(frame_id);
- frames->mutable_symbol_set_id()->Set(frame_row, symbol_set_id);
- frame_found = true;
- }
- }
-
- if (!frame_found) {
- context_->storage->IncrementStats(stats::stackprofile_invalid_frame_id);
- continue;
- }
- }
-}
-
-void ProtoTraceParser::ParseSmapsPacket(int64_t ts, ConstBytes blob) {
- protos::pbzero::SmapsPacket::Decoder sp(blob.data, blob.size);
- auto upid = context_->process_tracker->GetOrCreateProcess(sp.pid());
-
- for (auto it = sp.entries(); it; ++it) {
- protos::pbzero::SmapsEntry::Decoder e(*it);
- context_->storage->mutable_profiler_smaps_table()->Insert(
- {upid, ts, context_->storage->InternString(e.path()),
- static_cast<int64_t>(e.size_kb()),
- static_cast<int64_t>(e.private_dirty_kb()),
- static_cast<int64_t>(e.swap_kb()),
- context_->storage->InternString(e.file_name()),
- static_cast<int64_t>(e.start_address()),
- static_cast<int64_t>(e.module_timestamp()),
- context_->storage->InternString(e.module_debugid()),
- context_->storage->InternString(e.module_debug_path()),
- static_cast<int32_t>(e.protection_flags()),
- static_cast<int64_t>(e.private_clean_resident_kb()),
- static_cast<int64_t>(e.shared_dirty_resident_kb()),
- static_cast<int64_t>(e.shared_clean_resident_kb()),
- static_cast<int64_t>(e.locked_kb()),
- static_cast<int64_t>(e.proportional_resident_kb())});
- }
-}
-
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/importers/proto/proto_trace_parser.h b/src/trace_processor/importers/proto/proto_trace_parser.h
index 53a6099e7..0061d49ec 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser.h
+++ b/src/trace_processor/importers/proto/proto_trace_parser.h
@@ -25,7 +25,7 @@
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/string_view.h"
#include "perfetto/protozero/field.h"
-#include "src/trace_processor/importers/common/trace_blob_view.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
#include "src/trace_processor/importers/common/trace_parser.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/timestamped_trace_piece.h"
@@ -40,7 +40,6 @@ class TracePacket_Decoder;
namespace trace_processor {
-class ArgsTracker;
class PacketSequenceState;
class TraceProcessorContext;
@@ -62,19 +61,9 @@ class ProtoTraceParser : public TraceParser {
const protos::pbzero::TracePacket_Decoder&);
void ParseTraceStats(ConstBytes);
- void ParseProfilePacket(int64_t ts,
- PacketSequenceStateGeneration*,
- uint32_t seq_id,
- ConstBytes);
- void ParseDeobfuscationMapping(int64_t ts,
- PacketSequenceStateGeneration*,
- uint32_t seq_id,
- ConstBytes);
void ParseChromeEvents(int64_t ts, ConstBytes);
void ParseMetatraceEvent(int64_t ts, ConstBytes);
void ParseTraceConfig(ConstBytes);
- void ParseModuleSymbols(ConstBytes);
- void ParseSmapsPacket(int64_t ts, ConstBytes);
private:
TraceProcessorContext* context_;
diff --git a/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc b/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
index 1812f146f..4108205fd 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
@@ -19,6 +19,7 @@
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/string_view.h"
#include "perfetto/protozero/scattered_heap_buffer.h"
+#include "perfetto/trace_processor/trace_blob.h"
#include "src/trace_processor/importers/additional_modules.h"
#include "src/trace_processor/importers/common/args_tracker.h"
#include "src/trace_processor/importers/common/clock_tracker.h"
@@ -216,19 +217,6 @@ class MockSliceTracker : public SliceTracker {
std::function<SliceId()> inserter));
};
-class MockFlowTracker : public FlowTracker {
- public:
- MockFlowTracker(TraceProcessorContext* context) : FlowTracker(context) {}
-
- MOCK_METHOD2(Begin, void(TrackId track_id, FlowId flow_id));
- MOCK_METHOD2(Step, void(TrackId track_id, FlowId flow_id));
- MOCK_METHOD4(End,
- void(TrackId track_id,
- FlowId flow_id,
- bool bind_enclosing,
- bool close_flow));
-};
-
class ProtoTraceParserTest : public ::testing::Test {
public:
ProtoTraceParserTest() {
@@ -248,11 +236,12 @@ class ProtoTraceParserTest : public ::testing::Test {
context_.process_tracker.reset(process_);
slice_ = new MockSliceTracker(&context_);
context_.slice_tracker.reset(slice_);
- flow_ = new MockFlowTracker(&context_);
- context_.flow_tracker.reset(flow_);
+ context_.slice_translation_table.reset(new SliceTranslationTable(storage_));
clock_ = new ClockTracker(&context_);
context_.clock_tracker.reset(clock_);
- context_.sorter.reset(new TraceSorter(CreateParser(), 0 /*window size*/));
+ context_.flow_tracker.reset(new FlowTracker(&context_));
+ context_.sorter.reset(new TraceSorter(&context_, CreateParser(),
+ TraceSorter::SortingMode::kFullSort));
context_.descriptor_pool_.reset(new DescriptorPool());
RegisterDefaultModules(&context_);
@@ -269,8 +258,8 @@ class ProtoTraceParserTest : public ::testing::Test {
std::unique_ptr<uint8_t[]> raw_trace(new uint8_t[trace_bytes.size()]);
memcpy(raw_trace.get(), trace_bytes.data(), trace_bytes.size());
context_.chunk_reader.reset(new ProtoTraceReader(&context_));
- auto status =
- context_.chunk_reader->Parse(std::move(raw_trace), trace_bytes.size());
+ auto status = context_.chunk_reader->Parse(TraceBlobView(
+ TraceBlob::TakeOwnership(std::move(raw_trace), trace_bytes.size())));
ResetTraceBuffers();
return status;
@@ -281,9 +270,9 @@ class ProtoTraceParserTest : public ::testing::Test {
RowMap rm = args.FilterToRowMap({args.arg_set_id().eq(set_id)});
bool found = false;
for (auto it = rm.IterateRows(); it; it.Next()) {
- if (args.key()[it.row()] == key_id) {
- EXPECT_EQ(args.flat_key()[it.row()], key_id);
- if (storage_->GetArgValue(it.row()) == value) {
+ if (args.key()[it.index()] == key_id) {
+ EXPECT_EQ(args.flat_key()[it.index()], key_id);
+ if (storage_->GetArgValue(it.index()) == value) {
found = true;
break;
}
@@ -303,7 +292,6 @@ class ProtoTraceParserTest : public ::testing::Test {
MockSchedEventTracker* sched_;
MockProcessTracker* process_;
MockSliceTracker* slice_;
- MockFlowTracker* flow_;
ClockTracker* clock_;
TraceStorage* storage_;
};
@@ -333,6 +321,7 @@ TEST_F(ProtoTraceParserTest, LoadSingleEvent) {
PushSchedSwitch(10, 1000, 10, base::StringView(kProc2Name), 256,
32, 100, base::StringView(kProc1Name), 1024));
Tokenize();
+ context_.sorter->ExtractEventsForced();
}
TEST_F(ProtoTraceParserTest, LoadEventsIntoRaw) {
@@ -364,6 +353,7 @@ TEST_F(ProtoTraceParserTest, LoadEventsIntoRaw) {
EXPECT_CALL(*process_, GetOrCreateProcess(123));
Tokenize();
+ context_.sorter->ExtractEventsForced();
const auto& raw = context_.storage->raw_table();
ASSERT_EQ(raw.row_count(), 2u);
@@ -414,6 +404,7 @@ TEST_F(ProtoTraceParserTest, LoadGenericFtrace) {
field->set_uint_value(3);
Tokenize();
+ context_.sorter->ExtractEventsForced();
const auto& raw = storage_->raw_table();
@@ -481,6 +472,7 @@ TEST_F(ProtoTraceParserTest, LoadMultipleEvents) {
32, 10, base::StringView(kProcName2), 512));
Tokenize();
+ context_.sorter->ExtractEventsForced();
}
TEST_F(ProtoTraceParserTest, LoadMultiplePackets) {
@@ -526,6 +518,7 @@ TEST_F(ProtoTraceParserTest, LoadMultiplePackets) {
PushSchedSwitch(10, 1001, 100, base::StringView(kProcName1), 256,
32, 10, base::StringView(kProcName2), 512));
Tokenize();
+ context_.sorter->ExtractEventsForced();
}
TEST_F(ProtoTraceParserTest, RepeatedLoadSinglePacket) {
@@ -548,6 +541,7 @@ TEST_F(ProtoTraceParserTest, RepeatedLoadSinglePacket) {
PushSchedSwitch(10, 1000, 10, base::StringView(kProcName2), 256,
32, 100, base::StringView(kProcName1), 1024));
Tokenize();
+ context_.sorter->ExtractEventsForced();
bundle = trace_->add_packet()->set_ftrace_events();
bundle->set_cpu(10);
@@ -567,6 +561,7 @@ TEST_F(ProtoTraceParserTest, RepeatedLoadSinglePacket) {
PushSchedSwitch(10, 1001, 100, base::StringView(kProcName1), 256,
32, 10, base::StringView(kProcName2), 512));
Tokenize();
+ context_.sorter->ExtractEventsForced();
}
TEST_F(ProtoTraceParserTest, LoadCpuFreq) {
@@ -581,10 +576,33 @@ TEST_F(ProtoTraceParserTest, LoadCpuFreq) {
EXPECT_CALL(*event_, PushCounter(1000, DoubleEq(2000), TrackId{0}));
Tokenize();
+ context_.sorter->ExtractEventsForced();
EXPECT_EQ(context_.storage->cpu_counter_track_table().cpu()[0], 10u);
}
+TEST_F(ProtoTraceParserTest, LoadCpuFreqKHz) {
+ auto* packet = trace_->add_packet();
+ uint64_t ts = 1000;
+ packet->set_timestamp(ts);
+ auto* bundle = packet->set_sys_stats();
+ bundle->add_cpufreq_khz(2650000u);
+ bundle->add_cpufreq_khz(3698200u);
+
+ EXPECT_CALL(*event_, PushCounter(static_cast<int64_t>(ts), DoubleEq(2650000u),
+ TrackId{0u}));
+ EXPECT_CALL(*event_, PushCounter(static_cast<int64_t>(ts), DoubleEq(3698200u),
+ TrackId{1u}));
+ Tokenize();
+ context_.sorter->ExtractEventsForced();
+
+ EXPECT_EQ(context_.storage->track_table().row_count(), 2u);
+ EXPECT_EQ(context_.storage->track_table().name().GetString(0),
+ "CPU 0 Freq in kHz");
+ EXPECT_EQ(context_.storage->track_table().name().GetString(1),
+ "CPU 1 Freq in kHz");
+}
+
TEST_F(ProtoTraceParserTest, LoadMemInfo) {
auto* packet = trace_->add_packet();
uint64_t ts = 1000;
@@ -598,6 +616,7 @@ TEST_F(ProtoTraceParserTest, LoadMemInfo) {
EXPECT_CALL(*event_, PushCounter(static_cast<int64_t>(ts),
DoubleEq(value * 1024.0), TrackId{0u}));
Tokenize();
+ context_.sorter->ExtractEventsForced();
EXPECT_EQ(context_.storage->track_table().row_count(), 1u);
}
@@ -615,6 +634,7 @@ TEST_F(ProtoTraceParserTest, LoadVmStats) {
EXPECT_CALL(*event_, PushCounter(static_cast<int64_t>(ts), DoubleEq(value),
TrackId{0u}));
Tokenize();
+ context_.sorter->ExtractEventsForced();
EXPECT_EQ(context_.storage->track_table().row_count(), 1u);
}
@@ -632,6 +652,7 @@ TEST_F(ProtoTraceParserTest, LoadProcessPacket) {
SetProcessMetadata(1, Eq(3u), base::StringView(kProcName1),
base::StringView(kProcName1)));
Tokenize();
+ context_.sorter->ExtractEventsForced();
}
TEST_F(ProtoTraceParserTest, LoadProcessPacket_FirstCmdline) {
@@ -649,6 +670,7 @@ TEST_F(ProtoTraceParserTest, LoadProcessPacket_FirstCmdline) {
SetProcessMetadata(1, Eq(3u), base::StringView(kProcName1),
base::StringView("proc1 proc2")));
Tokenize();
+ context_.sorter->ExtractEventsForced();
}
TEST_F(ProtoTraceParserTest, LoadThreadPacket) {
@@ -659,11 +681,10 @@ TEST_F(ProtoTraceParserTest, LoadThreadPacket) {
EXPECT_CALL(*process_, UpdateThread(1, 2));
Tokenize();
+ context_.sorter->ExtractEventsForced();
}
TEST_F(ProtoTraceParserTest, ProcessNameFromProcessDescriptor) {
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
{
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
@@ -707,8 +728,6 @@ TEST_F(ProtoTraceParserTest, ProcessNameFromProcessDescriptor) {
}
TEST_F(ProtoTraceParserTest, ThreadNameFromThreadDescriptor) {
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
{
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
@@ -763,9 +782,6 @@ TEST_F(ProtoTraceParserTest, ThreadNameFromThreadDescriptor) {
}
TEST_F(ProtoTraceParserTest, TrackEventWithoutInternedData) {
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
{
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
@@ -815,8 +831,7 @@ TEST_F(ProtoTraceParserTest, TrackEventWithoutInternedData) {
Tokenize();
- EXPECT_CALL(*process_, UpdateThread(16, 15))
- .WillRepeatedly(Return(1));
+ EXPECT_CALL(*process_, UpdateThread(16, 15)).WillRepeatedly(Return(1));
tables::ThreadTable::Row row(16);
row.upid = 1u;
@@ -860,9 +875,6 @@ TEST_F(ProtoTraceParserTest, TrackEventWithoutInternedData) {
}
TEST_F(ProtoTraceParserTest, TrackEventWithoutInternedDataWithTypes) {
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
{
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
@@ -909,8 +921,7 @@ TEST_F(ProtoTraceParserTest, TrackEventWithoutInternedDataWithTypes) {
Tokenize();
- EXPECT_CALL(*process_, UpdateThread(16, 15))
- .WillRepeatedly(Return(1));
+ EXPECT_CALL(*process_, UpdateThread(16, 15)).WillRepeatedly(Return(1));
tables::ThreadTable::Row row(16);
row.upid = 1u;
@@ -953,9 +964,6 @@ TEST_F(ProtoTraceParserTest, TrackEventWithoutInternedDataWithTypes) {
}
TEST_F(ProtoTraceParserTest, TrackEventWithInternedData) {
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
{
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
@@ -1087,8 +1095,7 @@ TEST_F(ProtoTraceParserTest, TrackEventWithInternedData) {
Tokenize();
- EXPECT_CALL(*process_, UpdateThread(16, 15))
- .WillRepeatedly(Return(1));
+ EXPECT_CALL(*process_, UpdateThread(16, 15)).WillRepeatedly(Return(1));
tables::ThreadTable::Row row(16);
row.upid = 2u;
@@ -1114,12 +1121,6 @@ TEST_F(ProtoTraceParserTest, TrackEventWithInternedData) {
.WillOnce(DoAll(IgnoreResult(InvokeArgument<3>()),
InvokeArgument<2>(&inserter), Return(SliceId(0u))));
- EXPECT_CALL(*flow_, Begin(_, _));
-
- EXPECT_CALL(*flow_, Step(_, _));
-
- EXPECT_CALL(*flow_, End(_, _, false, false));
-
EXPECT_CALL(*event_, PushCounter(1010000, testing::DoubleEq(2005000),
thread_time_track));
EXPECT_CALL(*event_, PushCounter(1010000, testing::DoubleEq(3020),
@@ -1178,9 +1179,6 @@ TEST_F(ProtoTraceParserTest, TrackEventWithInternedData) {
}
TEST_F(ProtoTraceParserTest, TrackEventAsyncEvents) {
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
{
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
@@ -1334,9 +1332,6 @@ TEST_F(ProtoTraceParserTest, TrackEventAsyncEvents) {
// TODO(eseckler): Also test instant events on separate tracks.
TEST_F(ProtoTraceParserTest, TrackEventWithTrackDescriptors) {
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
// Sequence 1.
{
auto* packet = trace_->add_packet();
@@ -1540,9 +1535,6 @@ TEST_F(ProtoTraceParserTest, TrackEventWithTrackDescriptors) {
}
TEST_F(ProtoTraceParserTest, TrackEventWithResortedCounterDescriptor) {
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
// Descriptors with timestamps after the event below. They will be tokenized
// in the order they appear here, but then resorted before parsing to appear
// after the events below.
@@ -1643,9 +1635,6 @@ TEST_F(ProtoTraceParserTest, TrackEventWithResortedCounterDescriptor) {
}
TEST_F(ProtoTraceParserTest, TrackEventWithoutIncrementalStateReset) {
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
{
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
@@ -1704,9 +1693,6 @@ TEST_F(ProtoTraceParserTest, TrackEventWithoutIncrementalStateReset) {
}
TEST_F(ProtoTraceParserTest, TrackEventWithoutThreadDescriptor) {
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
{
// Event should be discarded because it specifies delta timestamps and no
// thread descriptor was seen yet.
@@ -1746,9 +1732,6 @@ TEST_F(ProtoTraceParserTest, TrackEventWithoutThreadDescriptor) {
}
TEST_F(ProtoTraceParserTest, TrackEventWithDataLoss) {
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
{
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
@@ -1762,7 +1745,7 @@ TEST_F(ProtoTraceParserTest, TrackEventWithDataLoss) {
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
auto* event = packet->set_track_event();
- event->set_timestamp_delta_us(10); // absolute: 1010.
+ event->set_timestamp_delta_us(10); // absolute: 1010.
event->add_category_iids(1);
auto* legacy_event = event->set_legacy_event();
legacy_event->set_name_iid(1);
@@ -1815,7 +1798,7 @@ TEST_F(ProtoTraceParserTest, TrackEventWithDataLoss) {
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
auto* event = packet->set_track_event();
- event->set_timestamp_delta_us(10); // absolute: 2010.
+ event->set_timestamp_delta_us(10); // absolute: 2010.
event->add_category_iids(1);
auto* legacy_event = event->set_legacy_event();
legacy_event->set_name_iid(1);
@@ -1840,9 +1823,6 @@ TEST_F(ProtoTraceParserTest, TrackEventWithDataLoss) {
}
TEST_F(ProtoTraceParserTest, TrackEventMultipleSequences) {
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
{
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
@@ -1856,7 +1836,7 @@ TEST_F(ProtoTraceParserTest, TrackEventMultipleSequences) {
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
auto* event = packet->set_track_event();
- event->set_timestamp_delta_us(10); // absolute: 1010.
+ event->set_timestamp_delta_us(10); // absolute: 1010.
event->add_category_iids(1);
auto* legacy_event = event->set_legacy_event();
legacy_event->set_name_iid(1);
@@ -1883,7 +1863,7 @@ TEST_F(ProtoTraceParserTest, TrackEventMultipleSequences) {
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(2);
auto* event = packet->set_track_event();
- event->set_timestamp_delta_us(10); // absolute: 1005.
+ event->set_timestamp_delta_us(10); // absolute: 1005.
event->add_category_iids(1);
auto* legacy_event = event->set_legacy_event();
legacy_event->set_name_iid(1);
@@ -1901,7 +1881,7 @@ TEST_F(ProtoTraceParserTest, TrackEventMultipleSequences) {
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
auto* event = packet->set_track_event();
- event->set_timestamp_delta_us(10); // absolute: 1020.
+ event->set_timestamp_delta_us(10); // absolute: 1020.
event->add_category_iids(1);
auto* legacy_event = event->set_legacy_event();
legacy_event->set_name_iid(1);
@@ -1911,7 +1891,7 @@ TEST_F(ProtoTraceParserTest, TrackEventMultipleSequences) {
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(2);
auto* event = packet->set_track_event();
- event->set_timestamp_delta_us(10); // absolute: 1015.
+ event->set_timestamp_delta_us(10); // absolute: 1015.
event->add_category_iids(1);
auto* legacy_event = event->set_legacy_event();
legacy_event->set_name_iid(1);
@@ -1920,10 +1900,8 @@ TEST_F(ProtoTraceParserTest, TrackEventMultipleSequences) {
Tokenize();
- EXPECT_CALL(*process_, UpdateThread(16, 15))
- .WillRepeatedly(Return(1));
- EXPECT_CALL(*process_, UpdateThread(17, 15))
- .WillRepeatedly(Return(2));
+ EXPECT_CALL(*process_, UpdateThread(16, 15)).WillRepeatedly(Return(1));
+ EXPECT_CALL(*process_, UpdateThread(17, 15)).WillRepeatedly(Return(2));
tables::ThreadTable::Row t1(16);
t1.upid = 1u;
@@ -1950,8 +1928,6 @@ TEST_F(ProtoTraceParserTest, TrackEventMultipleSequences) {
}
TEST_F(ProtoTraceParserTest, TrackEventWithDebugAnnotations) {
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
MockBoundInserter inserter;
{
@@ -1967,7 +1943,7 @@ TEST_F(ProtoTraceParserTest, TrackEventWithDebugAnnotations) {
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
auto* event = packet->set_track_event();
- event->set_timestamp_delta_us(10); // absolute: 1010.
+ event->set_timestamp_delta_us(10); // absolute: 1010.
event->add_category_iids(1);
auto* annotation1 = event->add_debug_annotations();
annotation1->set_name_iid(1);
@@ -2019,7 +1995,7 @@ TEST_F(ProtoTraceParserTest, TrackEventWithDebugAnnotations) {
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
auto* event = packet->set_track_event();
- event->set_timestamp_delta_us(10); // absolute: 1020.
+ event->set_timestamp_delta_us(10); // absolute: 1020.
event->add_category_iids(1);
auto* annotation3 = event->add_debug_annotations();
annotation3->set_name_iid(3);
@@ -2153,9 +2129,6 @@ TEST_F(ProtoTraceParserTest, TrackEventWithDebugAnnotations) {
}
TEST_F(ProtoTraceParserTest, TrackEventWithTaskExecution) {
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
{
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
@@ -2169,7 +2142,7 @@ TEST_F(ProtoTraceParserTest, TrackEventWithTaskExecution) {
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
auto* event = packet->set_track_event();
- event->set_timestamp_delta_us(10); // absolute: 1010.
+ event->set_timestamp_delta_us(10); // absolute: 1010.
event->add_category_iids(1);
auto* task_execution = event->set_task_execution();
task_execution->set_posted_from_iid(1);
@@ -2218,9 +2191,6 @@ TEST_F(ProtoTraceParserTest, TrackEventWithTaskExecution) {
}
TEST_F(ProtoTraceParserTest, TrackEventWithLogMessage) {
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
{
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
@@ -2234,7 +2204,7 @@ TEST_F(ProtoTraceParserTest, TrackEventWithLogMessage) {
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
auto* event = packet->set_track_event();
- event->set_timestamp_delta_us(10); // absolute: 1010.
+ event->set_timestamp_delta_us(10); // absolute: 1010.
event->add_category_iids(1);
auto* log_message = event->set_log_message();
@@ -2294,9 +2264,6 @@ TEST_F(ProtoTraceParserTest, TrackEventWithLogMessage) {
}
TEST_F(ProtoTraceParserTest, TrackEventParseLegacyEventIntoRawTable) {
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
{
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
@@ -2398,9 +2365,6 @@ TEST_F(ProtoTraceParserTest, TrackEventParseLegacyEventIntoRawTable) {
}
TEST_F(ProtoTraceParserTest, TrackEventLegacyTimestampsWithClockSnapshot) {
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
clock_->AddSnapshot({{protos::pbzero::BUILTIN_CLOCK_BOOTTIME, 0},
{protos::pbzero::BUILTIN_CLOCK_MONOTONIC, 1000000}});
@@ -2442,9 +2406,6 @@ TEST_F(ProtoTraceParserTest, TrackEventLegacyTimestampsWithClockSnapshot) {
}
TEST_F(ProtoTraceParserTest, ParseEventWithClockIdButWithoutClockSnapshot) {
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
{
auto* packet = trace_->add_packet();
packet->set_timestamp(1000);
@@ -2471,9 +2432,6 @@ TEST_F(ProtoTraceParserTest, ParseChromeMetadataEventIntoRawTable) {
static const char kIntName[] = "int_name";
static const int kIntValue = 123;
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
{
auto* packet = trace_->add_packet();
packet->set_timestamp(1000);
@@ -2511,9 +2469,6 @@ TEST_F(ProtoTraceParserTest, ParseChromeCombinedMetadataPacket) {
static const char kStringName[] = "string_name";
static const char kStringValue[] = "string_value";
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
{
auto* packet = trace_->add_packet();
packet->set_timestamp(1000);
@@ -2558,9 +2513,6 @@ TEST_F(ProtoTraceParserTest, ParseChromeLegacyFtraceIntoRawTable) {
static const char kDataPart1[] = "bbb";
static const char kFullData[] = "aaabbb";
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
{
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
@@ -2588,9 +2540,6 @@ TEST_F(ProtoTraceParserTest, ParseChromeLegacyFtraceIntoRawTable) {
TEST_F(ProtoTraceParserTest, ParseChromeLegacyJsonIntoRawTable) {
static const char kUserTraceEvent[] = "{\"user\":1}";
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
{
auto* packet = trace_->add_packet();
packet->set_trusted_packet_sequence_id(1);
@@ -2622,9 +2571,6 @@ TEST_F(ProtoTraceParserTest, LoadChromeBenchmarkMetadata) {
static const char kTag1[] = "tag1";
static const char kTag2[] = "tag2";
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
auto* metadata = trace_->add_packet()->set_chrome_benchmark_metadata();
metadata->set_benchmark_name(kName);
metadata->add_story_tags(kTag1);
@@ -2653,9 +2599,6 @@ TEST_F(ProtoTraceParserTest, LoadChromeBenchmarkMetadata) {
}
TEST_F(ProtoTraceParserTest, LoadChromeMetadata) {
- context_.sorter.reset(new TraceSorter(
- CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
-
auto* track_event = trace_->add_packet()->set_chrome_events();
{
auto* metadata = track_event->add_metadata();
@@ -2723,6 +2666,7 @@ TEST_F(ProtoTraceParserTest, AndroidPackagesList) {
}
Tokenize();
+ context_.sorter->ExtractEventsForced();
// Packet-level errors reflected in stats storage.
const auto& stats = context_.storage->stats();
@@ -2775,6 +2719,7 @@ TEST_F(ProtoTraceParserTest, AndroidPackagesListDuplicate) {
}
Tokenize();
+ context_.sorter->ExtractEventsForced();
// Packet-level errors reflected in stats storage.
const auto& stats = context_.storage->stats();
@@ -2860,10 +2805,10 @@ TEST_F(ProtoTraceParserTest, ParseCPUProfileSamplesIntoTable) {
samples->set_process_priority(30);
}
- EXPECT_CALL(*process_, UpdateThread(16, 15))
- .WillRepeatedly(Return(1));
+ EXPECT_CALL(*process_, UpdateThread(16, 15)).WillRepeatedly(Return(1));
Tokenize();
+ context_.sorter->ExtractEventsForced();
// Verify cpu_profile_samples.
const auto& samples = storage_->cpu_profile_stack_sample_table();
@@ -2950,6 +2895,7 @@ TEST_F(ProtoTraceParserTest, CPUProfileSamplesTimestampsAreClockMonotonic) {
EXPECT_CALL(*process_, UpdateThread(16, 15)).WillRepeatedly(Return(1));
Tokenize();
+ context_.sorter->ExtractEventsForced();
const auto& samples = storage_->cpu_profile_stack_sample_table();
EXPECT_EQ(samples.row_count(), 1u);
@@ -2966,10 +2912,11 @@ TEST_F(ProtoTraceParserTest, ConfigUuid) {
config->set_trace_uuid_msb(2);
ASSERT_TRUE(Tokenize().ok());
+ context_.sorter->ExtractEventsForced();
- SqlValue value =
- context_.metadata_tracker->GetMetadataForTesting(metadata::trace_uuid);
+ SqlValue value = context_.metadata_tracker->GetMetadata(metadata::trace_uuid);
EXPECT_STREQ(value.string_value, "00000000-0000-0002-0000-000000000001");
+ ASSERT_TRUE(context_.uuid_found_in_trace);
}
TEST_F(ProtoTraceParserTest, ConfigPbtxt) {
@@ -2977,9 +2924,10 @@ TEST_F(ProtoTraceParserTest, ConfigPbtxt) {
config->add_buffers()->set_size_kb(42);
ASSERT_TRUE(Tokenize().ok());
+ context_.sorter->ExtractEventsForced();
- SqlValue value = context_.metadata_tracker->GetMetadataForTesting(
- metadata::trace_config_pbtxt);
+ SqlValue value =
+ context_.metadata_tracker->GetMetadata(metadata::trace_config_pbtxt);
EXPECT_THAT(value.string_value, HasSubstr("size_kb: 42"));
}
diff --git a/src/trace_processor/importers/proto/proto_trace_reader.cc b/src/trace_processor/importers/proto/proto_trace_reader.cc
index ee03db396..e6dd7c65a 100644
--- a/src/trace_processor/importers/proto/proto_trace_reader.cc
+++ b/src/trace_processor/importers/proto/proto_trace_reader.cc
@@ -30,7 +30,6 @@
#include "src/trace_processor/importers/common/event_tracker.h"
#include "src/trace_processor/importers/common/track_tracker.h"
#include "src/trace_processor/importers/ftrace/ftrace_module.h"
-#include "src/trace_processor/importers/gzip/gzip_utils.h"
#include "src/trace_processor/importers/proto/metadata_tracker.h"
#include "src/trace_processor/importers/proto/packet_sequence_state.h"
#include "src/trace_processor/importers/proto/proto_incremental_state.h"
@@ -38,6 +37,7 @@
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/trace_sorter.h"
#include "src/trace_processor/util/descriptors.h"
+#include "src/trace_processor/util/gzip_utils.h"
#include "protos/perfetto/common/builtin_clock.pbzero.h"
#include "protos/perfetto/config/trace_config.pbzero.h"
@@ -55,11 +55,10 @@ ProtoTraceReader::ProtoTraceReader(TraceProcessorContext* ctx)
: context_(ctx) {}
ProtoTraceReader::~ProtoTraceReader() = default;
-util::Status ProtoTraceReader::Parse(std::unique_ptr<uint8_t[]> owned_buf,
- size_t size) {
- return tokenizer_.Tokenize(
- std::move(owned_buf), size,
- [this](TraceBlobView packet) { return ParsePacket(std::move(packet)); });
+util::Status ProtoTraceReader::Parse(TraceBlobView blob) {
+ return tokenizer_.Tokenize(std::move(blob), [this](TraceBlobView packet) {
+ return ParsePacket(std::move(packet));
+ });
}
util::Status ProtoTraceReader::ParseExtensionDescriptor(ConstBytes descriptor) {
@@ -69,6 +68,7 @@ util::Status ProtoTraceReader::ParseExtensionDescriptor(ConstBytes descriptor) {
auto extension = decoder.extension_set();
return context_->descriptor_pool_->AddFromFileDescriptorSet(
extension.data, extension.size,
+ /*skip_prefixes*/ {},
/*merge_existing_messages=*/true);
}
@@ -99,14 +99,12 @@ util::Status ProtoTraceReader::ParsePacket(TraceBlobView packet) {
// the timestamp, since the defaults could affect them.
if (decoder.has_trace_packet_defaults()) {
auto field = decoder.trace_packet_defaults();
- const size_t offset = packet.offset_of(field.data);
- ParseTracePacketDefaults(decoder, packet.slice(offset, field.size));
+ ParseTracePacketDefaults(decoder, packet.slice(field.data, field.size));
}
if (decoder.has_interned_data()) {
auto field = decoder.interned_data();
- const size_t offset = packet.offset_of(field.data);
- ParseInternedData(decoder, packet.slice(offset, field.size));
+ ParseInternedData(decoder, packet.slice(field.data, field.size));
}
if (decoder.has_clock_snapshot()) {
@@ -232,49 +230,12 @@ util::Status ProtoTraceReader::ParsePacket(TraceBlobView packet) {
void ProtoTraceReader::ParseTraceConfig(protozero::ConstBytes blob) {
protos::pbzero::TraceConfig::Decoder trace_config(blob);
- // If we're forcing a full sort, we can keep using the INT_MAX duration set
- // when we created the sorter.
- const auto& cfg = context_->config;
- if (cfg.sorting_mode == SortingMode::kForceFullSort) {
- return;
- }
-
- base::Optional<int64_t> flush_period_window_size_ns;
- if (trace_config.has_flush_period_ms() &&
- trace_config.flush_period_ms() > 0) {
- flush_period_window_size_ns =
- static_cast<int64_t>(trace_config.flush_period_ms()) * 2 * 1000 * 1000;
- }
-
- // If we're trying to force flush period based sorting, use that as the
- // window size if it exists.
- if (cfg.sorting_mode == SortingMode::kForceFlushPeriodWindowedSort &&
- flush_period_window_size_ns.has_value()) {
- context_->sorter->SetWindowSizeNs(flush_period_window_size_ns.value());
- return;
- }
-
- // If we end up here, we should use heuristics because either the sorting mode
- // was set as such or we don't have a flush period to force the window size
- // to.
-
- // If we're not forcing anything and this is a write_into_file trace, then
- // use flush_period_ms as an indiciator for how big the sliding window for the
- // sorter should be.
- if (trace_config.write_into_file()) {
- int64_t window_size_ns;
- if (flush_period_window_size_ns.has_value()) {
- window_size_ns = flush_period_window_size_ns.value();
- } else {
- constexpr uint64_t kDefaultWindowNs =
- 180 * 1000 * 1000 * 1000ULL; // 3 minutes.
- PERFETTO_ELOG(
- "It is strongly recommended to have flush_period_ms set when "
- "write_into_file is turned on. You will likely have many dropped "
- "events because of inability to sort the events correctly.");
- window_size_ns = static_cast<int64_t>(kDefaultWindowNs);
- }
- context_->sorter->SetWindowSizeNs(window_size_ns);
+ if (trace_config.write_into_file() && !trace_config.flush_period_ms()) {
+ PERFETTO_ELOG(
+ "It is strongly recommended to have flush_period_ms set when "
+ "write_into_file is turned on. This trace will be loaded fully "
+ "into memory before sorting which increases the likliehoold of "
+ "OOMs.");
}
}
@@ -346,8 +307,7 @@ void ProtoTraceReader::ParseInternedData(
for (protozero::Field f = decoder.ReadField(); f.valid();
f = decoder.ReadField()) {
auto bytes = f.as_bytes();
- auto offset = interned_data.offset_of(bytes.data);
- state->InternMessage(f.id(), interned_data.slice(offset, bytes.size));
+ state->InternMessage(f.id(), interned_data.slice(bytes.data, bytes.size));
}
}
@@ -447,6 +407,12 @@ util::Status ProtoTraceReader::ParseServiceEvent(int64_t ts, ConstBytes blob) {
context_->metadata_tracker->SetMetadata(
metadata::all_data_source_started_ns, Variadic::Integer(ts));
}
+ if (tse.all_data_sources_flushed()) {
+ context_->sorter->NotifyFlushEvent();
+ }
+ if (tse.read_tracing_buffers_completed()) {
+ context_->sorter->NotifyReadBufferEvent();
+ }
return util::OkStatus();
}
diff --git a/src/trace_processor/importers/proto/proto_trace_reader.h b/src/trace_processor/importers/proto/proto_trace_reader.h
index 1adb84151..ed3e43ea2 100644
--- a/src/trace_processor/importers/proto/proto_trace_reader.h
+++ b/src/trace_processor/importers/proto/proto_trace_reader.h
@@ -22,7 +22,6 @@
#include <memory>
#include "src/trace_processor/importers/common/chunked_trace_reader.h"
-#include "src/trace_processor/importers/common/trace_blob_view.h"
#include "src/trace_processor/importers/proto/proto_incremental_state.h"
#include "src/trace_processor/importers/proto/proto_trace_tokenizer.h"
@@ -58,7 +57,7 @@ class ProtoTraceReader : public ChunkedTraceReader {
~ProtoTraceReader() override;
// ChunkedTraceReader implementation.
- util::Status Parse(std::unique_ptr<uint8_t[]>, size_t size) override;
+ util::Status Parse(TraceBlobView) override;
void NotifyEndOfFile() override;
private:
diff --git a/src/trace_processor/importers/proto/proto_trace_tokenizer.cc b/src/trace_processor/importers/proto/proto_trace_tokenizer.cc
index fdc7bcdd9..b6b59375e 100644
--- a/src/trace_processor/importers/proto/proto_trace_tokenizer.cc
+++ b/src/trace_processor/importers/proto/proto_trace_tokenizer.cc
@@ -15,6 +15,7 @@
*/
#include "src/trace_processor/importers/proto/proto_trace_tokenizer.h"
+#include "perfetto/trace_processor/trace_blob.h"
#include "perfetto/ext/base/utils.h"
@@ -25,33 +26,27 @@ ProtoTraceTokenizer::ProtoTraceTokenizer() = default;
util::Status ProtoTraceTokenizer::Decompress(TraceBlobView input,
TraceBlobView* output) {
- PERFETTO_DCHECK(gzip::IsGzipSupported());
-
- uint8_t out[4096];
+ PERFETTO_DCHECK(util::IsGzipSupported());
std::vector<uint8_t> data;
data.reserve(input.length());
// Ensure that the decompressor is able to cope with a new stream of data.
decompressor_.Reset();
- decompressor_.SetInput(input.data(), input.length());
-
- using ResultCode = GzipDecompressor::ResultCode;
- for (auto ret = ResultCode::kOk; ret != ResultCode::kEof;) {
- auto res = decompressor_.Decompress(out, base::ArraySize(out));
- ret = res.ret;
- if (ret == ResultCode::kError || ret == ResultCode::kNoProgress ||
- ret == ResultCode::kNeedsMoreInput) {
- return util::ErrStatus("Failed to decompress (error code: %d)",
- static_cast<int>(ret));
- }
-
- data.insert(data.end(), out, out + res.bytes_written);
+ using ResultCode = util::GzipDecompressor::ResultCode;
+ ResultCode ret = decompressor_.FeedAndExtract(
+ input.data(), input.length(),
+ [&data](const uint8_t* buffer, size_t buffer_len) {
+ data.insert(data.end(), buffer, buffer + buffer_len);
+ });
+
+ if (ret == ResultCode::kError || ret == ResultCode::kNeedsMoreInput) {
+ return util::ErrStatus("Failed to decompress (error code: %d)",
+ static_cast<int>(ret));
}
- std::unique_ptr<uint8_t[]> out_data(new uint8_t[data.size()]);
- memcpy(out_data.get(), data.data(), data.size());
- *output = TraceBlobView(std::move(out_data), 0, data.size());
+ TraceBlob out_blob = TraceBlob::CopyFrom(data.data(), data.size());
+ *output = TraceBlobView(std::move(out_blob));
return util::OkStatus();
}
diff --git a/src/trace_processor/importers/proto/proto_trace_tokenizer.h b/src/trace_processor/importers/proto/proto_trace_tokenizer.h
index 76a0f42e9..1b51e563c 100644
--- a/src/trace_processor/importers/proto/proto_trace_tokenizer.h
+++ b/src/trace_processor/importers/proto/proto_trace_tokenizer.h
@@ -21,8 +21,9 @@
#include "perfetto/protozero/proto_utils.h"
#include "perfetto/trace_processor/status.h"
-#include "src/trace_processor/importers/common/trace_blob_view.h"
-#include "src/trace_processor/importers/gzip/gzip_utils.h"
+#include "perfetto/trace_processor/trace_blob.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
+#include "src/trace_processor/util/gzip_utils.h"
#include "src/trace_processor/util/status_macros.h"
#include "protos/perfetto/trace/trace.pbzero.h"
@@ -38,10 +39,9 @@ class ProtoTraceTokenizer {
ProtoTraceTokenizer();
template <typename Callback = util::Status(TraceBlobView)>
- util::Status Tokenize(std::unique_ptr<uint8_t[]> owned_buf,
- size_t size,
- Callback callback) {
- uint8_t* data = &owned_buf[0];
+ util::Status Tokenize(TraceBlobView blob, Callback callback) {
+ const uint8_t* data = blob.data();
+ size_t size = blob.size();
if (!partial_buf_.empty()) {
// It takes ~5 bytes for a proto preamble + the varint size.
const size_t kHeaderBytes = 5;
@@ -86,24 +86,23 @@ class ProtoTraceTokenizer {
// that we might have consumed already a few bytes form |data|
// earlier in this function, hence we need to keep |off| into
// account).
- std::unique_ptr<uint8_t[]> buf(new uint8_t[size_incl_header]);
- memcpy(&buf[0], partial_buf_.data(), partial_buf_.size());
+ TraceBlob glued = TraceBlob::Allocate(size_incl_header);
+ memcpy(glued.data(), partial_buf_.data(), partial_buf_.size());
// |size_missing| is the number of bytes for the rest of the TracePacket
// in |data|.
size_t size_missing = size_incl_header - partial_buf_.size();
- memcpy(&buf[partial_buf_.size()], &data[0], size_missing);
+ memcpy(glued.data() + partial_buf_.size(), &data[0], size_missing);
data += size_missing;
size -= size_missing;
partial_buf_.clear();
- uint8_t* buf_start = &buf[0]; // Note that buf is std::moved below.
- RETURN_IF_ERROR(ParseInternal(std::move(buf), buf_start,
- size_incl_header, callback));
+ RETURN_IF_ERROR(
+ ParseInternal(TraceBlobView(std::move(glued)), callback));
} else {
partial_buf_.insert(partial_buf_.end(), data, &data[size]);
return util::OkStatus();
}
}
- return ParseInternal(std::move(owned_buf), data, size, callback);
+ return ParseInternal(blob.slice(data, size), callback);
}
private:
@@ -112,28 +111,20 @@ class ProtoTraceTokenizer {
protos::pbzero::Trace::kPacketFieldNumber);
template <typename Callback = util::Status(TraceBlobView)>
- util::Status ParseInternal(std::unique_ptr<uint8_t[]> owned_buf,
- uint8_t* data,
- size_t size,
- Callback callback) {
- PERFETTO_DCHECK(data >= &owned_buf[0]);
- const uint8_t* start = &owned_buf[0];
- const size_t data_off = static_cast<size_t>(data - start);
- TraceBlobView whole_buf(std::move(owned_buf), data_off, size);
-
- protos::pbzero::Trace::Decoder decoder(data, size);
+ util::Status ParseInternal(TraceBlobView whole_buf, Callback callback) {
+ const uint8_t* const start = whole_buf.data();
+ protos::pbzero::Trace::Decoder decoder(whole_buf.data(), whole_buf.size());
for (auto it = decoder.packet(); it; ++it) {
protozero::ConstBytes packet = *it;
- size_t field_offset = whole_buf.offset_of(packet.data);
- TraceBlobView sliced = whole_buf.slice(field_offset, packet.size);
+ TraceBlobView sliced = whole_buf.slice(packet.data, packet.size);
RETURN_IF_ERROR(ParsePacket(std::move(sliced), callback));
}
const size_t bytes_left = decoder.bytes_left();
if (bytes_left > 0) {
PERFETTO_DCHECK(partial_buf_.empty());
- partial_buf_.insert(partial_buf_.end(), &data[decoder.read_offset()],
- &data[decoder.read_offset() + bytes_left]);
+ partial_buf_.insert(partial_buf_.end(), &start[decoder.read_offset()],
+ &start[decoder.read_offset() + bytes_left]);
}
return util::OkStatus();
}
@@ -143,15 +134,14 @@ class ProtoTraceTokenizer {
protos::pbzero::TracePacket::Decoder decoder(packet.data(),
packet.length());
if (decoder.has_compressed_packets()) {
- if (!gzip::IsGzipSupported()) {
+ if (!util::IsGzipSupported()) {
return util::Status(
"Cannot decode compressed packets. Zlib not enabled");
}
protozero::ConstBytes field = decoder.compressed_packets();
- const size_t field_off = packet.offset_of(field.data);
- TraceBlobView compressed_packets = packet.slice(field_off, field.size);
- TraceBlobView packets(nullptr, 0, 0);
+ TraceBlobView compressed_packets = packet.slice(field.data, field.size);
+ TraceBlobView packets;
RETURN_IF_ERROR(Decompress(std::move(compressed_packets), &packets));
@@ -159,18 +149,18 @@ class ProtoTraceTokenizer {
const uint8_t* end = packets.data() + packets.length();
const uint8_t* ptr = start;
while ((end - ptr) > 2) {
- const uint8_t* packet_start = ptr;
+ const uint8_t* packet_outer = ptr;
if (PERFETTO_UNLIKELY(*ptr != kTracePacketTag))
return util::ErrStatus("Expected TracePacket tag");
uint64_t packet_size = 0;
ptr = protozero::proto_utils::ParseVarInt(++ptr, end, &packet_size);
- size_t packet_offset = static_cast<size_t>(ptr - start);
+ const uint8_t* packet_start = ptr;
ptr += packet_size;
- if (PERFETTO_UNLIKELY((ptr - packet_start) < 2 || ptr > end))
+ if (PERFETTO_UNLIKELY((ptr - packet_outer) < 2 || ptr > end))
return util::ErrStatus("Invalid packet size");
TraceBlobView sliced =
- packets.slice(packet_offset, static_cast<size_t>(packet_size));
+ packets.slice(packet_start, static_cast<size_t>(packet_size));
RETURN_IF_ERROR(ParsePacket(std::move(sliced), callback));
}
return util::OkStatus();
@@ -185,7 +175,7 @@ class ProtoTraceTokenizer {
std::vector<uint8_t> partial_buf_;
// Allows support for compressed trace packets.
- GzipDecompressor decompressor_;
+ util::GzipDecompressor decompressor_;
};
} // namespace trace_processor
diff --git a/src/trace_processor/importers/proto/stack_profile_tracker.cc b/src/trace_processor/importers/proto/stack_profile_tracker.cc
index 52e4dbd0d..6bf9a737e 100644
--- a/src/trace_processor/importers/proto/stack_profile_tracker.cc
+++ b/src/trace_processor/importers/proto/stack_profile_tracker.cc
@@ -185,7 +185,7 @@ base::Optional<FrameId> SequenceStackProfileTracker::AddFrame(
cur_id = frames->Insert(row).id;
context_->global_stack_profile_tracker->InsertFrameRow(
mapping_id, static_cast<uint64_t>(row.rel_pc), *cur_id);
- if (name.find('.') != std::string::npos) {
+ if (base::Contains(name, '.')) {
// Java frames always contain a '.'
base::Optional<std::string> package =
PackageFromLocation(context_->storage.get(), mapping_name);
diff --git a/src/trace_processor/importers/proto/system_probes_parser.cc b/src/trace_processor/importers/proto/system_probes_parser.cc
index 214c0fab1..63bdda725 100644
--- a/src/trace_processor/importers/proto/system_probes_parser.cc
+++ b/src/trace_processor/importers/proto/system_probes_parser.cc
@@ -44,6 +44,60 @@ namespace {
// pid == 2 on Linux and Android.
const uint32_t kKthreaddPid = 2;
const char kKthreaddName[] = "kthreadd";
+
+base::Optional<int> VersionStringToSdkVersion(const std::string& version) {
+ // TODO(lalitm): remove this when the SDK version polling saturates
+ // S/T traces in practice.
+ if (base::StartsWith(version, "T") || base::StartsWith(version, "S")) {
+ return 31;
+ }
+
+ // Documentation for this mapping can be found at
+ // https://source.android.com/compatibility/cdd.
+ if (version == "12") {
+ return 31;
+ } else if (version == "11") {
+ return 30;
+ } else if (version == "10") {
+ return 29;
+ } else if (version == "9") {
+ return 28;
+ } else if (version == "8.1") {
+ return 27;
+ } else if (version == "8.0") {
+ return 26;
+ } else if (version == "7.1") {
+ return 25;
+ } else if (version == "7.0") {
+ return 24;
+ } else if (version == "6.0") {
+ return 23;
+ } else if (version == "5.1" || version == "5.1.1") {
+ return 22;
+ } else if (version == "5.0" || version == "5.0.1" || version == "5.0.2") {
+ return 21;
+ }
+ // If we reached this point, we don't know how to parse this version
+ // so just return null.
+ return base::nullopt;
+}
+
+base::Optional<int> FingerprintToSdkVersion(const std::string& fingerprint) {
+ // Try to parse the SDK version from the fingerprint.
+ // Examples of fingerprints:
+ // google/shamu/shamu:7.0/NBD92F/3753956:userdebug/dev-keys
+ // google/coral/coral:12/SP1A.210812.015/7679548:userdebug/dev-keys
+ size_t colon = fingerprint.find(':');
+ if (colon == std::string::npos)
+ return base::nullopt;
+
+ size_t slash = fingerprint.find('/', colon);
+ if (slash == std::string::npos)
+ return base::nullopt;
+
+ std::string version = fingerprint.substr(colon + 1, slash - (colon + 1));
+ return VersionStringToSdkVersion(version);
+}
} // namespace
SystemProbesParser::SystemProbesParser(TraceProcessorContext* context)
@@ -122,17 +176,26 @@ void SystemProbesParser::ParseSysStats(int64_t ts, ConstBytes blob) {
for (auto it = sys_stats.devfreq(); it; ++it) {
protos::pbzero::SysStats::DevfreqValue::Decoder vm(*it);
auto key = static_cast<base::StringView>(vm.key());
- // Append " Frequency" to align names with FtraceParser::ParseClockSetRate
+ // Append " Frequency" to align names with
+ // FtraceParser::ParseClockSetRate
base::StringView devfreq_subtitle("Frequency");
- char counter_name[255];
- snprintf(counter_name, sizeof(counter_name), "%.*s %.*s", int(key.size()),
- key.data(), int(devfreq_subtitle.size()), devfreq_subtitle.data());
- StringId name = context_->storage->InternString(counter_name);
+ base::StackString<255> counter_name(
+ "%.*s %.*s", int(key.size()), key.data(), int(devfreq_subtitle.size()),
+ devfreq_subtitle.data());
+ StringId name = context_->storage->InternString(counter_name.string_view());
TrackId track = context_->track_tracker->InternGlobalCounterTrack(name);
context_->event_tracker->PushCounter(ts, static_cast<double>(vm.value()),
track);
}
+ int c = 0;
+ for (auto it = sys_stats.cpufreq_khz(); it; ++it, ++c) {
+ base::StackString<255> counter_name("CPU %d Freq in kHz", c);
+ StringId name = context_->storage->InternString(counter_name.string_view());
+ TrackId track = context_->track_tracker->InternGlobalCounterTrack(name);
+ context_->event_tracker->PushCounter(ts, static_cast<double>(*it), track);
+ }
+
for (auto it = sys_stats.vmstat(); it; ++it) {
protos::pbzero::SysStats::VmstatValue::Decoder vm(*it);
auto key = static_cast<size_t>(vm.key());
@@ -241,8 +304,17 @@ void SystemProbesParser::ParseProcessTree(ConstBytes blob) {
auto pid = static_cast<uint32_t>(proc.pid());
auto ppid = static_cast<uint32_t>(proc.ppid());
+ if (proc.has_nspid()) {
+ std::vector<uint32_t> nspid;
+ for (auto nspid_it = proc.nspid(); nspid_it; nspid_it++) {
+ nspid.emplace_back(static_cast<uint32_t>(*nspid_it));
+ }
+ context_->process_tracker->UpdateNamespacedProcess(pid, std::move(nspid));
+ }
+
// If the parent pid is kthreadd's pid, even though this pid is of a
- // "process", we want to treat it as being a child thread of kthreadd.
+ // "process", we want to treat it as being a child thread of
+ // kthreadd.
if (ppid == kKthreaddPid) {
context_->process_tracker->SetProcessMetadata(
kKthreaddPid, base::nullopt, kKthreaddName, base::StringView());
@@ -250,6 +322,14 @@ void SystemProbesParser::ParseProcessTree(ConstBytes blob) {
} else {
auto raw_cmdline = proc.cmdline();
base::StringView argv0 = raw_cmdline ? *raw_cmdline : base::StringView();
+ // Chrome child process overwrites /proc/self/cmdline and replaces all
+ // '\0' with ' '. This makes argv0 contain the full command line. Extract
+ // the actual argv0 if it's Chrome.
+ static const char kChromeBinary[] = "/chrome ";
+ auto pos = argv0.find(kChromeBinary);
+ if (pos != base::StringView::npos) {
+ argv0 = argv0.substr(0, pos + strlen(kChromeBinary) - 1);
+ }
std::string cmdline_str;
for (auto cmdline_it = raw_cmdline; cmdline_it;) {
@@ -280,6 +360,15 @@ void SystemProbesParser::ParseProcessTree(ConstBytes blob) {
context_->process_tracker->UpdateThreadName(
tid, thread_name_id, ThreadNamePriority::kProcessTree);
}
+
+ if (thd.has_nstid()) {
+ std::vector<uint32_t> nstid;
+ for (auto nstid_it = thd.nstid(); nstid_it; nstid_it++) {
+ nstid.emplace_back(static_cast<uint32_t>(*nstid_it));
+ }
+ context_->process_tracker->UpdateNamespacedThread(tgid, tid,
+ std::move(nstid));
+ }
}
}
@@ -448,14 +537,29 @@ void SystemProbesParser::ParseSystemInfo(ConstBytes blob) {
packet.android_build_fingerprint())));
}
+ // If we have the SDK version in the trace directly just use that.
+ // Otherwise, try and parse it from the fingerprint.
+ base::Optional<int64_t> opt_sdk_version;
+ if (packet.has_android_sdk_version()) {
+ opt_sdk_version = static_cast<int64_t>(packet.android_sdk_version());
+ } else if (packet.has_android_build_fingerprint()) {
+ opt_sdk_version = FingerprintToSdkVersion(
+ packet.android_build_fingerprint().ToStdString());
+ }
+
+ if (opt_sdk_version) {
+ context_->metadata_tracker->SetMetadata(
+ metadata::android_sdk_version, Variadic::Integer(*opt_sdk_version));
+ }
+
int64_t hz = packet.hz();
if (hz > 0)
ms_per_tick_ = 1000u / static_cast<uint64_t>(hz);
}
void SystemProbesParser::ParseCpuInfo(ConstBytes blob) {
- // invalid_freq is used as the guard in thread_time_in_state_cpu_freq_ids_,
- // see IsValidCpuFreqIndex.
+ // invalid_freq is used as the guard in
+ // thread_time_in_state_cpu_freq_ids_, see IsValidCpuFreqIndex.
uint32_t invalid_freq = 0;
thread_time_in_state_cpu_freqs_.push_back(invalid_freq);
diff --git a/src/trace_processor/importers/proto/system_probes_parser.h b/src/trace_processor/importers/proto/system_probes_parser.h
index c9f66c03b..df03ae029 100644
--- a/src/trace_processor/importers/proto/system_probes_parser.h
+++ b/src/trace_processor/importers/proto/system_probes_parser.h
@@ -32,6 +32,7 @@ class TraceProcessorContext;
class SystemProbesParser {
public:
using ConstBytes = protozero::ConstBytes;
+ using ConstChars = protozero::ConstChars;
explicit SystemProbesParser(TraceProcessorContext*);
diff --git a/src/trace_processor/importers/proto/track_event_parser.cc b/src/trace_processor/importers/proto/track_event_parser.cc
index 8ad817788..faa8261d8 100644
--- a/src/trace_processor/importers/proto/track_event_parser.cc
+++ b/src/trace_processor/importers/proto/track_event_parser.cc
@@ -24,6 +24,7 @@
#include "perfetto/ext/base/string_writer.h"
#include "perfetto/trace_processor/status.h"
#include "src/trace_processor/importers/common/args_tracker.h"
+#include "src/trace_processor/importers/common/args_translation_table.h"
#include "src/trace_processor/importers/common/event_tracker.h"
#include "src/trace_processor/importers/common/flow_tracker.h"
#include "src/trace_processor/importers/common/process_tracker.h"
@@ -31,6 +32,7 @@
#include "src/trace_processor/importers/json/json_utils.h"
#include "src/trace_processor/importers/proto/packet_sequence_state.h"
#include "src/trace_processor/importers/proto/track_event_tracker.h"
+#include "src/trace_processor/util/debug_annotation_parser.h"
#include "src/trace_processor/util/proto_to_args_parser.h"
#include "src/trace_processor/util/status_macros.h"
@@ -69,10 +71,13 @@ class TrackEventArgsParser : public util::ProtoToArgsParser::Delegate {
public:
TrackEventArgsParser(BoundInserter& inserter,
TraceStorage& storage,
- PacketSequenceStateGeneration& sequence_state)
+ PacketSequenceStateGeneration& sequence_state,
+ ArgsTranslationTable& args_translation_table)
: inserter_(inserter),
storage_(storage),
- sequence_state_(sequence_state) {}
+ sequence_state_(sequence_state),
+ args_translation_table_(args_translation_table) {}
+
~TrackEventArgsParser() override;
using Key = util::ProtoToArgsParser::Key;
@@ -83,6 +88,10 @@ class TrackEventArgsParser : public util::ProtoToArgsParser::Delegate {
Variadic::Integer(value));
}
void AddUnsignedInteger(const Key& key, uint64_t value) final {
+ if (args_translation_table_.TranslateUnsignedIntegerArg(key, value,
+ inserter_)) {
+ return;
+ }
inserter_.AddArg(storage_.InternString(base::StringView(key.flat_key)),
storage_.InternString(base::StringView(key.key)),
Variadic::UnsignedInteger(value));
@@ -107,10 +116,28 @@ class TrackEventArgsParser : public util::ProtoToArgsParser::Delegate {
storage_.InternString(base::StringView(key.key)),
Variadic::Boolean(value));
}
- void AddJson(const Key& key, const protozero::ConstChars& value) final {
+ bool AddJson(const Key& key, const protozero::ConstChars& value) final {
+ auto json_value = json::ParseJsonString(value);
+ if (!json_value)
+ return false;
+ return json::AddJsonValueToArgs(*json_value, base::StringView(key.flat_key),
+ base::StringView(key.key), &storage_,
+ &inserter_);
+ }
+ void AddNull(const Key& key) final {
inserter_.AddArg(storage_.InternString(base::StringView(key.flat_key)),
storage_.InternString(base::StringView(key.key)),
- Variadic::Json(storage_.InternString(value)));
+ Variadic::Null());
+ }
+
+ size_t GetArrayEntryIndex(const std::string& array_key) final {
+ return inserter_.GetNextArrayEntryIndex(
+ storage_.InternString(base::StringView(array_key)));
+ }
+
+ size_t IncrementArrayEntryIndex(const std::string& array_key) final {
+ return inserter_.IncrementArrayEntryIndex(
+ storage_.InternString(base::StringView(array_key)));
}
InternedMessageView* GetInternedMessageView(uint32_t field_id,
@@ -122,6 +149,7 @@ class TrackEventArgsParser : public util::ProtoToArgsParser::Delegate {
BoundInserter& inserter_;
TraceStorage& storage_;
PacketSequenceStateGeneration& sequence_state_;
+ ArgsTranslationTable& args_translation_table_;
};
TrackEventArgsParser::~TrackEventArgsParser() = default;
@@ -148,13 +176,6 @@ base::Optional<base::Status> MaybeParseSourceLocation(
return base::OkStatus();
}
-std::string SanitizeDebugAnnotationName(const std::string& raw_name) {
- std::string result = raw_name;
- std::replace(result.begin(), result.end(), '.', '_');
- std::replace(result.begin(), result.end(), '[', '_');
- std::replace(result.begin(), result.end(), ']', '_');
- return result;
-}
} // namespace
class TrackEventParser::EventImporter {
@@ -641,7 +662,7 @@ class TrackEventParser::EventImporter {
[this](BoundInserter* inserter) { ParseTrackEventArgs(inserter); });
if (opt_slice_id.has_value()) {
- MaybeParseFlowEvents();
+ MaybeParseFlowEvents(opt_slice_id.value());
}
return util::OkStatus();
@@ -672,6 +693,7 @@ class TrackEventParser::EventImporter {
thread_slices->mutable_thread_instruction_delta()->Set(
*maybe_row, *event_data_->thread_instruction_count - *tic);
}
+ MaybeParseFlowEvents(opt_slice_id.value());
}
return util::OkStatus();
@@ -701,7 +723,7 @@ class TrackEventParser::EventImporter {
[this](BoundInserter* inserter) { ParseTrackEventArgs(inserter); });
if (opt_slice_id.has_value()) {
- MaybeParseFlowEvents();
+ MaybeParseFlowEvents(opt_slice_id.value());
}
return util::OkStatus();
@@ -742,16 +764,16 @@ class TrackEventParser::EventImporter {
return util::OkStatus();
}
- void MaybeParseTrackEventFlows() {
+ void MaybeParseTrackEventFlows(SliceId slice_id) {
if (event_.has_flow_ids()) {
auto it = event_.flow_ids();
for (; it; ++it) {
FlowId flow_id = *it;
if (!context_->flow_tracker->IsActive(flow_id)) {
- context_->flow_tracker->Begin(track_id_, flow_id);
+ context_->flow_tracker->Begin(slice_id, flow_id);
continue;
}
- context_->flow_tracker->Step(track_id_, flow_id);
+ context_->flow_tracker->Step(slice_id, flow_id);
}
}
if (event_.has_terminating_flow_ids()) {
@@ -763,14 +785,13 @@ class TrackEventParser::EventImporter {
// active already.
continue;
}
- context_->flow_tracker->End(track_id_, flow_id,
- /* bind_enclosing_slice = */ true,
+ context_->flow_tracker->End(slice_id, flow_id,
/* close_flow = */ true);
}
}
}
- void MaybeParseFlowEventV2() {
+ void MaybeParseFlowEventV2(SliceId slice_id) {
if (!legacy_event_.has_bind_id()) {
return;
}
@@ -782,14 +803,13 @@ class TrackEventParser::EventImporter {
auto bind_id = legacy_event_.bind_id();
switch (legacy_event_.flow_direction()) {
case LegacyEvent::FLOW_OUT:
- context_->flow_tracker->Begin(track_id_, bind_id);
+ context_->flow_tracker->Begin(slice_id, bind_id);
break;
case LegacyEvent::FLOW_INOUT:
- context_->flow_tracker->Step(track_id_, bind_id);
+ context_->flow_tracker->Step(slice_id, bind_id);
break;
case LegacyEvent::FLOW_IN:
- context_->flow_tracker->End(track_id_, bind_id,
- /* bind_enclosing_slice = */ true,
+ context_->flow_tracker->End(slice_id, bind_id,
/* close_flow = */ false);
break;
default:
@@ -797,9 +817,9 @@ class TrackEventParser::EventImporter {
}
}
- void MaybeParseFlowEvents() {
- MaybeParseFlowEventV2();
- MaybeParseTrackEventFlows();
+ void MaybeParseFlowEvents(SliceId slice_id) {
+ MaybeParseFlowEventV2(slice_id);
+ MaybeParseTrackEventFlows(slice_id);
}
util::Status ParseThreadInstantEvent(char phase) {
@@ -838,7 +858,7 @@ class TrackEventParser::EventImporter {
if (!opt_slice_id.has_value()) {
return util::OkStatus();
}
- MaybeParseFlowEvents();
+ MaybeParseFlowEvents(opt_slice_id.value());
return util::OkStatus();
}
@@ -860,7 +880,7 @@ class TrackEventParser::EventImporter {
if (!opt_slice_id.has_value()) {
return util::OkStatus();
}
- MaybeParseFlowEvents();
+ MaybeParseFlowEvents(opt_slice_id.value());
// For the time being, we only create vtrack slice rows if we need to
// store thread timestamps/counters.
if (legacy_event_.use_async_tts()) {
@@ -883,7 +903,10 @@ class TrackEventParser::EventImporter {
auto opt_slice_id = context_->slice_tracker->End(
ts_, track_id_, category_id_, name_id_,
[this](BoundInserter* inserter) { ParseTrackEventArgs(inserter); });
- if (legacy_event_.use_async_tts() && opt_slice_id.has_value()) {
+ if (!opt_slice_id.has_value())
+ return util::OkStatus();
+ MaybeParseFlowEvents(opt_slice_id.value());
+ if (legacy_event_.use_async_tts()) {
auto* vtrack_slices = storage_->mutable_virtual_track_slices();
int64_t tts =
event_data_->thread_timestamp ? *event_data_->thread_timestamp : 0;
@@ -928,7 +951,7 @@ class TrackEventParser::EventImporter {
if (!opt_slice_id.has_value()) {
return util::OkStatus();
}
- MaybeParseFlowEvents();
+ MaybeParseFlowEvents(opt_slice_id.value());
if (legacy_event_.use_async_tts()) {
auto* vtrack_slices = storage_->mutable_virtual_track_slices();
PERFETTO_DCHECK(!vtrack_slices->slice_count() ||
@@ -1092,10 +1115,6 @@ class TrackEventParser::EventImporter {
PERFETTO_DLOG("ParseTrackEventArgs error: %s", status.c_message());
};
- for (auto it = event_.debug_annotations(); it; ++it) {
- log_errors(ParseDebugAnnotation(*it, inserter));
- }
-
if (event_.has_source_location_iid()) {
log_errors(AddSourceLocationArgs(event_.source_location_iid(), inserter));
}
@@ -1111,180 +1130,30 @@ class TrackEventParser::EventImporter {
ParseHistogramName(event_.chrome_histogram_sample(), inserter));
}
- TrackEventArgsParser args_writer(*inserter, *storage_, *sequence_state_);
+ TrackEventArgsParser args_writer(*inserter, *storage_, *sequence_state_,
+ *context_->args_translation_table);
+ int unknown_extensions = 0;
log_errors(parser_->args_parser_.ParseMessage(
blob_, ".perfetto.protos.TrackEvent", &parser_->reflect_fields_,
- args_writer));
-
- if (legacy_passthrough_utid_) {
- inserter->AddArg(parser_->legacy_event_passthrough_utid_id_,
- Variadic::UnsignedInteger(*legacy_passthrough_utid_),
- ArgsTracker::UpdatePolicy::kSkipIfExists);
- }
- }
-
- util::Status ParseDebugAnnotation(ConstBytes data, BoundInserter* inserter) {
- protos::pbzero::DebugAnnotation::Decoder annotation(data);
-
- std::string name;
- util::Status name_parse_result = ParseDebugAnnotationName(annotation, name);
- if (!name_parse_result.ok())
- return name_parse_result;
-
- return ParseDebugAnnotationValue(annotation, inserter, "debug." + name);
- }
-
- util::Status ParseDebugAnnotationName(
- protos::pbzero::DebugAnnotation::Decoder& annotation,
- std::string& result) {
- uint64_t name_iid = annotation.name_iid();
- if (PERFETTO_LIKELY(name_iid)) {
- auto* decoder = sequence_state_->LookupInternedMessage<
- protos::pbzero::InternedData::kDebugAnnotationNamesFieldNumber,
- protos::pbzero::DebugAnnotationName>(name_iid);
- if (!decoder)
- return util::ErrStatus("Debug annotation with invalid name_iid");
-
- result = SanitizeDebugAnnotationName(decoder->name().ToStdString());
- } else if (annotation.has_name()) {
- result = SanitizeDebugAnnotationName(annotation.name().ToStdString());
- } else {
- return util::ErrStatus("Debug annotation without name");
+ args_writer, &unknown_extensions));
+ if (unknown_extensions > 0) {
+ context_->storage->IncrementStats(stats::unknown_extension_fields,
+ unknown_extensions);
}
- return util::OkStatus();
- }
- util::Status ParseDebugAnnotationValue(
- protos::pbzero::DebugAnnotation::Decoder& annotation,
- BoundInserter* inserter,
- const std::string& context_name) {
- StringId name_id = storage_->InternString(base::StringView(context_name));
-
- if (annotation.has_bool_value()) {
- inserter->AddArg(name_id, Variadic::Boolean(annotation.bool_value()));
- } else if (annotation.has_uint_value()) {
- inserter->AddArg(name_id,
- Variadic::UnsignedInteger(annotation.uint_value()));
- } else if (annotation.has_int_value()) {
- inserter->AddArg(name_id, Variadic::Integer(annotation.int_value()));
- } else if (annotation.has_double_value()) {
- inserter->AddArg(name_id, Variadic::Real(annotation.double_value()));
- } else if (annotation.has_string_value()) {
- inserter->AddArg(
- name_id,
- Variadic::String(storage_->InternString(annotation.string_value())));
- } else if (annotation.has_pointer_value()) {
- inserter->AddArg(name_id, Variadic::Pointer(annotation.pointer_value()));
- } else if (annotation.has_dict_entries()) {
- for (auto it = annotation.dict_entries(); it; ++it) {
- protos::pbzero::DebugAnnotation::Decoder key_value(*it);
- std::string key;
- util::Status key_parse_result =
- ParseDebugAnnotationName(key_value, key);
- if (!key_parse_result.ok())
- return key_parse_result;
-
- std::string child_flat_key = context_name + "." + key;
- util::Status value_parse_result =
- ParseDebugAnnotationValue(key_value, inserter, child_flat_key);
- if (!value_parse_result.ok())
- return value_parse_result;
- }
- } else if (annotation.has_array_values()) {
- size_t index = 0;
- for (auto it = annotation.array_values(); it; ++it) {
- protos::pbzero::DebugAnnotation::Decoder value(*it);
-
- std::string child_flat_key =
- context_name + "[" + std::to_string(index) + "]";
- util::Status value_parse_result =
- ParseDebugAnnotationValue(value, inserter, child_flat_key);
- if (!value_parse_result.ok())
- return value_parse_result;
- ++index;
+ {
+ auto key = parser_->args_parser_.EnterDictionary("debug");
+ util::DebugAnnotationParser parser(parser_->args_parser_);
+ for (auto it = event_.debug_annotations(); it; ++it) {
+ log_errors(parser.Parse(*it, args_writer));
}
- } else if (annotation.has_legacy_json_value()) {
- if (!json::IsJsonSupported())
- return util::ErrStatus("Ignoring legacy_json_value (no json support)");
-
- auto value = json::ParseJsonString(annotation.legacy_json_value());
- auto name = storage_->GetString(name_id);
- json::AddJsonValueToArgs(*value, name, name, storage_, inserter);
- } else if (annotation.has_nested_value()) {
- auto name = storage_->GetString(name_id);
- ParseNestedValueArgs(annotation.nested_value(), name, name, inserter);
}
- return util::OkStatus();
- }
-
- bool ParseNestedValueArgs(ConstBytes nested_value,
- base::StringView flat_key,
- base::StringView key,
- BoundInserter* inserter) {
- protos::pbzero::DebugAnnotation::NestedValue::Decoder value(nested_value);
- switch (value.nested_type()) {
- case protos::pbzero::DebugAnnotation::NestedValue::UNSPECIFIED: {
- auto flat_key_id = storage_->InternString(flat_key);
- auto key_id = storage_->InternString(key);
- // Leaf value.
- if (value.has_bool_value()) {
- inserter->AddArg(flat_key_id, key_id,
- Variadic::Boolean(value.bool_value()));
- return true;
- }
- if (value.has_int_value()) {
- inserter->AddArg(flat_key_id, key_id,
- Variadic::Integer(value.int_value()));
- return true;
- }
- if (value.has_double_value()) {
- inserter->AddArg(flat_key_id, key_id,
- Variadic::Real(value.double_value()));
- return true;
- }
- if (value.has_string_value()) {
- inserter->AddArg(
- flat_key_id, key_id,
- Variadic::String(storage_->InternString(value.string_value())));
- return true;
- }
- return false;
- }
- case protos::pbzero::DebugAnnotation::NestedValue::DICT: {
- auto key_it = value.dict_keys();
- auto value_it = value.dict_values();
- bool inserted = false;
- for (; key_it && value_it; ++key_it, ++value_it) {
- std::string child_name =
- SanitizeDebugAnnotationName((*key_it).ToStdString());
- std::string child_flat_key =
- flat_key.ToStdString() + "." + child_name;
- std::string child_key = key.ToStdString() + "." + child_name;
- inserted |=
- ParseNestedValueArgs(*value_it, base::StringView(child_flat_key),
- base::StringView(child_key), inserter);
- }
- return inserted;
- }
- case protos::pbzero::DebugAnnotation::NestedValue::ARRAY: {
- bool inserted_any = false;
- std::string array_key = key.ToStdString();
- StringId array_key_id = storage_->InternString(key);
- for (auto value_it = value.array_values(); value_it; ++value_it) {
- size_t array_index = inserter->GetNextArrayEntryIndex(array_key_id);
- std::string child_key =
- array_key + "[" + std::to_string(array_index) + "]";
- bool inserted = ParseNestedValueArgs(
- *value_it, flat_key, base::StringView(child_key), inserter);
- if (inserted)
- inserter->IncrementArrayEntryIndex(array_key_id);
- inserted_any |= inserted;
- }
- return inserted_any;
- }
+ if (legacy_passthrough_utid_) {
+ inserter->AddArg(parser_->legacy_event_passthrough_utid_id_,
+ Variadic::UnsignedInteger(*legacy_passthrough_utid_),
+ ArgsTracker::UpdatePolicy::kSkipIfExists);
}
- return false;
}
util::Status ParseTaskExecutionArgs(ConstBytes task_execution,
@@ -1510,26 +1379,28 @@ TrackEventParser::TrackEventParser(TraceProcessorContext* context,
context->storage->InternString("chrome.host_app_package_name")),
chrome_crash_trace_id_name_id_(
context->storage->InternString("chrome.crash_trace_id")),
+ chrome_process_label_flat_key_id_(
+ context->storage->InternString("chrome.process_label")),
chrome_string_lookup_(context->storage.get()),
counter_unit_ids_{{kNullStringId, context_->storage->InternString("ns"),
context_->storage->InternString("count"),
context_->storage->InternString("bytes")}} {
// Switch |source_location_iid| into its interned data variant.
- args_parser_.AddParsingOverride(
+ args_parser_.AddParsingOverrideForField(
"begin_impl_frame_args.current_args.source_location_iid",
[](const protozero::Field& field,
util::ProtoToArgsParser::Delegate& delegate) {
return MaybeParseSourceLocation("begin_impl_frame_args.current_args",
field, delegate);
});
- args_parser_.AddParsingOverride(
+ args_parser_.AddParsingOverrideForField(
"begin_impl_frame_args.last_args.source_location_iid",
[](const protozero::Field& field,
util::ProtoToArgsParser::Delegate& delegate) {
return MaybeParseSourceLocation("begin_impl_frame_args.last_args",
field, delegate);
});
- args_parser_.AddParsingOverride(
+ args_parser_.AddParsingOverrideForField(
"begin_frame_observer_state.last_begin_frame_args.source_location_iid",
[](const protozero::Field& field,
util::ProtoToArgsParser::Delegate& delegate) {
@@ -1537,7 +1408,7 @@ TrackEventParser::TrackEventParser(TraceProcessorContext* context,
"begin_frame_observer_state.last_begin_frame_args", field,
delegate);
});
- args_parser_.AddParsingOverride(
+ args_parser_.AddParsingOverrideForField(
"chrome_memory_pressure_notification.creation_location_iid",
[](const protozero::Field& field,
util::ProtoToArgsParser::Delegate& delegate) {
@@ -1545,6 +1416,18 @@ TrackEventParser::TrackEventParser(TraceProcessorContext* context,
field, delegate);
});
+ // Parse DebugAnnotations.
+ args_parser_.AddParsingOverrideForType(
+ ".perfetto.protos.DebugAnnotation",
+ [&](util::ProtoToArgsParser::ScopedNestedKeyContext& key,
+ const protozero::ConstBytes& data,
+ util::ProtoToArgsParser::Delegate& delegate) {
+ // Do not add "debug_annotations" to the final key.
+ key.RemoveFieldSuffix();
+ util::DebugAnnotationParser annotation_parser(args_parser_);
+ return annotation_parser.Parse(data, delegate);
+ });
+
for (uint16_t index : kReflectFields) {
reflect_fields_.push_back(index);
}
@@ -1599,6 +1482,17 @@ UniquePid TrackEventParser::ParseProcessDescriptor(
// Don't override system-provided names.
context_->process_tracker->SetProcessNameIfUnset(upid, name_id);
}
+ int label_index = 0;
+ for (auto it = decoder.process_labels(); it; it++) {
+ StringId label_id = context_->storage->InternString(*it);
+ std::string key = "chrome.process_label[";
+ key.append(std::to_string(label_index++));
+ key.append("]");
+ context_->process_tracker->AddArgsTo(upid).AddArg(
+ chrome_process_label_flat_key_id_,
+ context_->storage->InternString(base::StringView(key)),
+ Variadic::String(label_id));
+ }
return upid;
}
diff --git a/src/trace_processor/importers/proto/track_event_parser.h b/src/trace_processor/importers/proto/track_event_parser.h
index 2b807017d..ddf19a4a9 100644
--- a/src/trace_processor/importers/proto/track_event_parser.h
+++ b/src/trace_processor/importers/proto/track_event_parser.h
@@ -109,6 +109,7 @@ class TrackEventParser {
const StringId chrome_legacy_ipc_line_args_key_id_;
const StringId chrome_host_app_package_name_id_;
const StringId chrome_crash_trace_id_name_id_;
+ const StringId chrome_process_label_flat_key_id_;
ChromeStringLookup chrome_string_lookup_;
std::array<StringId, 4> counter_unit_ids_;
diff --git a/src/trace_processor/importers/proto/track_event_tokenizer.cc b/src/trace_processor/importers/proto/track_event_tokenizer.cc
index 9d28e469c..eafae7ef0 100644
--- a/src/trace_processor/importers/proto/track_event_tokenizer.cc
+++ b/src/trace_processor/importers/proto/track_event_tokenizer.cc
@@ -17,9 +17,9 @@
#include "src/trace_processor/importers/proto/track_event_tokenizer.h"
#include "perfetto/base/logging.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
#include "src/trace_processor/importers/common/clock_tracker.h"
#include "src/trace_processor/importers/common/process_tracker.h"
-#include "src/trace_processor/importers/common/trace_blob_view.h"
#include "src/trace_processor/importers/common/track_tracker.h"
#include "src/trace_processor/importers/proto/packet_sequence_state.h"
#include "src/trace_processor/importers/proto/proto_trace_reader.h"
@@ -72,6 +72,11 @@ ModuleResult TrackEventTokenizer::TokenizeTrackDescriptorPacket(
if (track.has_name())
name_id = context_->storage->InternString(track.name());
+ if (packet.has_trusted_pid()) {
+ context_->process_tracker->UpdateTrustedPid(
+ static_cast<uint32_t>(packet.trusted_pid()), track.uuid());
+ }
+
if (track.has_thread()) {
protos::pbzero::ThreadDescriptor::Decoder thread(track.thread());
diff --git a/src/trace_processor/importers/proto/track_event_tracker.cc b/src/trace_processor/importers/proto/track_event_tracker.cc
index bed158a2c..fc736fb4d 100644
--- a/src/trace_processor/importers/proto/track_event_tracker.cc
+++ b/src/trace_processor/importers/proto/track_event_tracker.cc
@@ -291,8 +291,28 @@ TrackEventTracker::ResolveDescriptorTrack(
if (reservation_it == reserved_descriptor_tracks_.end())
return base::nullopt;
- auto resolved_track = ResolveDescriptorTrackImpl(uuid, reservation_it->second,
- descendent_uuids);
+ // Resolve process and thread id for tracks produced from within a pid
+ // namespace.
+ // Get the root-level trusted_pid for the process that produces the track
+ // event.
+ auto opt_trusted_pid = context_->process_tracker->GetTrustedPid(uuid);
+ auto& reservation = reservation_it->second;
+ // Try to resolve to root-level pid and tid if the process is pid-namespaced.
+ if (opt_trusted_pid && reservation.tid) {
+ auto opt_resolved_tid = context_->process_tracker->ResolveNamespacedTid(
+ *opt_trusted_pid, *reservation.tid);
+ if (opt_resolved_tid)
+ reservation.tid = *opt_resolved_tid;
+ }
+ if (opt_trusted_pid && reservation.pid) {
+ auto opt_resolved_pid = context_->process_tracker->ResolveNamespacedTid(
+ *opt_trusted_pid, *reservation.pid);
+ if (opt_resolved_pid)
+ reservation.pid = *opt_resolved_pid;
+ }
+
+ auto resolved_track =
+ ResolveDescriptorTrackImpl(uuid, reservation, descendent_uuids);
resolved_descriptor_tracks_[uuid] = resolved_track;
return resolved_track;
}
@@ -392,7 +412,8 @@ TrackEventTracker::ResolveDescriptorTrackImpl(
reservation.min_timestamp);
upid = context_->process_tracker->StartNewProcess(
- base::nullopt, base::nullopt, *reservation.pid, kNullStringId);
+ base::nullopt, base::nullopt, *reservation.pid, kNullStringId,
+ ThreadNamePriority::kTrackDescriptor);
descriptor_uuids_by_upid_[upid] = uuid;
}
diff --git a/src/trace_processor/importers/proto/translation_table_module.cc b/src/trace_processor/importers/proto/translation_table_module.cc
new file mode 100644
index 000000000..bc3f6e255
--- /dev/null
+++ b/src/trace_processor/importers/proto/translation_table_module.cc
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "src/trace_processor/importers/proto/translation_table_module.h"
+
+#include "src/trace_processor/importers/common/args_translation_table.h"
+#include "src/trace_processor/importers/common/slice_translation_table.h"
+
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+#include "protos/perfetto/trace/translation/translation_table.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+using perfetto::protos::pbzero::TracePacket;
+
+TranslationTableModule::TranslationTableModule(TraceProcessorContext* context)
+ : context_(context) {
+ RegisterForField(TracePacket::kTranslationTableFieldNumber, context);
+}
+
+TranslationTableModule::~TranslationTableModule() = default;
+
+void TranslationTableModule::ParsePacket(const TracePacket::Decoder& decoder,
+ const TimestampedTracePiece& /*ttp*/,
+ uint32_t field_id) {
+ if (field_id != TracePacket::kTranslationTableFieldNumber) {
+ return;
+ }
+ const auto translation_table =
+ protos::pbzero::TranslationTable::Decoder(decoder.translation_table());
+ if (translation_table.has_chrome_histogram()) {
+ ParseChromeHistogramRules(translation_table.chrome_histogram());
+ } else if (translation_table.has_chrome_user_event()) {
+ ParseChromeUserEventRules(translation_table.chrome_user_event());
+ } else if (translation_table.has_chrome_performance_mark()) {
+ ParseChromePerformanceMarkRules(
+ translation_table.chrome_performance_mark());
+ } else if (translation_table.has_slice_name()) {
+ ParseSliceNameRules(translation_table.slice_name());
+ }
+}
+
+void TranslationTableModule::ParseChromeHistogramRules(
+ protozero::ConstBytes bytes) {
+ const auto chrome_histogram =
+ protos::pbzero::ChromeHistorgramTranslationTable::Decoder(bytes);
+ for (auto it = chrome_histogram.hash_to_name(); it; ++it) {
+ protos::pbzero::ChromeHistorgramTranslationTable::HashToNameEntry::Decoder
+ entry(*it);
+ context_->args_translation_table->AddChromeHistogramTranslationRule(
+ entry.key(), entry.value());
+ }
+}
+
+void TranslationTableModule::ParseChromeUserEventRules(
+ protozero::ConstBytes bytes) {
+ const auto chrome_user_event =
+ protos::pbzero::ChromeUserEventTranslationTable::Decoder(bytes);
+ for (auto it = chrome_user_event.action_hash_to_name(); it; ++it) {
+ protos::pbzero::ChromeUserEventTranslationTable::ActionHashToNameEntry::
+ Decoder entry(*it);
+ context_->args_translation_table->AddChromeUserEventTranslationRule(
+ entry.key(), entry.value());
+ }
+}
+
+void TranslationTableModule::ParseChromePerformanceMarkRules(
+ protozero::ConstBytes bytes) {
+ const auto chrome_performance_mark =
+ protos::pbzero::ChromePerformanceMarkTranslationTable::Decoder(bytes);
+ for (auto it = chrome_performance_mark.site_hash_to_name(); it; ++it) {
+ protos::pbzero::ChromePerformanceMarkTranslationTable::SiteHashToNameEntry::
+ Decoder entry(*it);
+ context_->args_translation_table
+ ->AddChromePerformanceMarkSiteTranslationRule(entry.key(),
+ entry.value());
+ }
+ for (auto it = chrome_performance_mark.mark_hash_to_name(); it; ++it) {
+ protos::pbzero::ChromePerformanceMarkTranslationTable::MarkHashToNameEntry::
+ Decoder entry(*it);
+ context_->args_translation_table
+ ->AddChromePerformanceMarkMarkTranslationRule(entry.key(),
+ entry.value());
+ }
+}
+
+void TranslationTableModule::ParseSliceNameRules(protozero::ConstBytes bytes) {
+ const auto slice_name =
+ protos::pbzero::SliceNameTranslationTable::Decoder(bytes);
+ for (auto it = slice_name.raw_to_deobfuscated_name(); it; ++it) {
+ protos::pbzero::SliceNameTranslationTable::RawToDeobfuscatedNameEntry::
+ Decoder entry(*it);
+ context_->slice_translation_table->AddNameTranslationRule(entry.key(),
+ entry.value());
+ }
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/proto/translation_table_module.h b/src/trace_processor/importers/proto/translation_table_module.h
new file mode 100644
index 000000000..73b193103
--- /dev/null
+++ b/src/trace_processor/importers/proto/translation_table_module.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_TRANSLATION_TABLE_MODULE_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_TRANSLATION_TABLE_MODULE_H_
+
+#include <cstdint>
+
+#include "perfetto/ext/base/optional.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+#include "src/trace_processor/importers/proto/proto_importer_module.h"
+#include "src/trace_processor/types/trace_processor_context.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class TranslationTableModule : public ProtoImporterModule {
+ public:
+ explicit TranslationTableModule(TraceProcessorContext* context);
+
+ ~TranslationTableModule() override;
+
+ void ParsePacket(const protos::pbzero::TracePacket::Decoder& decoder,
+ const TimestampedTracePiece& ttp,
+ uint32_t field_id) override;
+
+ private:
+ void ParseChromeHistogramRules(protozero::ConstBytes bytes);
+ void ParseChromeUserEventRules(protozero::ConstBytes bytes);
+ void ParseChromePerformanceMarkRules(protozero::ConstBytes bytes);
+ void ParseSliceNameRules(protozero::ConstBytes bytes);
+
+ TraceProcessorContext* context_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_TRANSLATION_TABLE_MODULE_H_
diff --git a/src/trace_processor/importers/syscalls/syscall_tracker.cc b/src/trace_processor/importers/syscalls/syscall_tracker.cc
index 129502d72..a60be09fb 100644
--- a/src/trace_processor/importers/syscalls/syscall_tracker.cc
+++ b/src/trace_processor/importers/syscalls/syscall_tracker.cc
@@ -16,11 +16,10 @@
#include "src/trace_processor/importers/syscalls/syscall_tracker.h"
+#include <cinttypes>
#include <type_traits>
#include <utility>
-#include <inttypes.h>
-
#include "src/trace_processor/storage/stats.h"
#include "src/trace_processor/importers/syscalls/syscalls_aarch32.h"
diff --git a/src/trace_processor/importers/systrace/systrace_line.h b/src/trace_processor/importers/systrace/systrace_line.h
index 817672ba0..80ce931e8 100644
--- a/src/trace_processor/importers/systrace/systrace_line.h
+++ b/src/trace_processor/importers/systrace/systrace_line.h
@@ -17,7 +17,7 @@
#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_SYSTRACE_SYSTRACE_LINE_H_
#define SRC_TRACE_PROCESSOR_IMPORTERS_SYSTRACE_SYSTRACE_LINE_H_
-#include <inttypes.h>
+#include <cinttypes>
#include <string>
namespace perfetto {
diff --git a/src/trace_processor/importers/systrace/systrace_line_parser.cc b/src/trace_processor/importers/systrace/systrace_line_parser.cc
index d41245811..4cfd788e8 100644
--- a/src/trace_processor/importers/systrace/systrace_line_parser.cc
+++ b/src/trace_processor/importers/systrace/systrace_line_parser.cc
@@ -16,6 +16,7 @@
#include "src/trace_processor/importers/systrace/systrace_line_parser.h"
+#include "perfetto/ext/base/flat_hash_map.h"
#include "perfetto/ext/base/string_splitter.h"
#include "perfetto/ext/base/string_utils.h"
#include "src/trace_processor/importers/common/args_tracker.h"
@@ -28,10 +29,9 @@
#include "src/trace_processor/importers/systrace/systrace_parser.h"
#include "src/trace_processor/types/task_state.h"
-#include <inttypes.h>
#include <cctype>
+#include <cinttypes>
#include <string>
-#include <unordered_map>
namespace perfetto {
namespace trace_processor {
@@ -40,11 +40,14 @@ SystraceLineParser::SystraceLineParser(TraceProcessorContext* ctx)
: context_(ctx),
rss_stat_tracker_(context_),
sched_wakeup_name_id_(ctx->storage->InternString("sched_wakeup")),
+ sched_waking_name_id_(ctx->storage->InternString("sched_waking")),
+ cpufreq_name_id_(ctx->storage->InternString("cpufreq")),
cpuidle_name_id_(ctx->storage->InternString("cpuidle")),
workqueue_name_id_(ctx->storage->InternString("workqueue")),
sched_blocked_reason_id_(
ctx->storage->InternString("sched_blocked_reason")),
- io_wait_id_(ctx->storage->InternString("io_wait")) {}
+ io_wait_id_(ctx->storage->InternString("io_wait")),
+ waker_utid_id_(ctx->storage->InternString("waker_utid")) {}
util::Status SystraceLineParser::ParseLine(const SystraceLine& line) {
auto utid = context_->process_tracker->UpdateThreadName(
@@ -58,14 +61,14 @@ util::Status SystraceLineParser::ParseLine(const SystraceLine& line) {
}
}
- std::unordered_map<std::string, std::string> args;
+ base::FlatHashMap<std::string, std::string> args;
for (base::StringSplitter ss(line.args_str, ' '); ss.Next();) {
std::string key;
std::string value;
if (!base::Contains(ss.cur_token(), "=")) {
key = "name";
value = ss.cur_token();
- args.emplace(std::move(key), std::move(value));
+ args.Insert(std::move(key), std::move(value));
continue;
}
for (base::StringSplitter inner(ss.cur_token(), '='); inner.Next();) {
@@ -75,7 +78,7 @@ util::Status SystraceLineParser::ParseLine(const SystraceLine& line) {
value = inner.cur_token();
}
}
- args.emplace(std::move(key), std::move(value));
+ args.Insert(std::move(key), std::move(value));
}
if (line.event_name == "sched_switch") {
auto prev_state_str = args["prev_state"];
@@ -101,7 +104,8 @@ util::Status SystraceLineParser::ParseLine(const SystraceLine& line) {
line.event_name == "0" || line.event_name == "print") {
SystraceParser::GetOrCreate(context_)->ParsePrintEvent(
line.ts, line.pid, line.args_str.c_str());
- } else if (line.event_name == "sched_wakeup") {
+ } else if (line.event_name == "sched_wakeup" ||
+ line.event_name == "sched_waking") {
auto comm = args["comm"];
base::Optional<uint32_t> wakee_pid = base::StringToUInt32(args["pid"]);
if (!wakee_pid.has_value()) {
@@ -111,8 +115,28 @@ util::Status SystraceLineParser::ParseLine(const SystraceLine& line) {
StringId name_id = context_->storage->InternString(base::StringView(comm));
auto wakee_utid = context_->process_tracker->UpdateThreadName(
wakee_pid.value(), name_id, ThreadNamePriority::kFtrace);
- context_->event_tracker->PushInstant(line.ts, sched_wakeup_name_id_,
- wakee_utid, RefType::kRefUtid);
+
+ StringId event_name_id = line.event_name == "sched_wakeup"
+ ? sched_wakeup_name_id_
+ : sched_waking_name_id_;
+ InstantId instant_id = context_->event_tracker->PushInstant(
+ line.ts, event_name_id, wakee_utid, RefType::kRefUtid);
+ context_->args_tracker->AddArgsTo(instant_id)
+ .AddArg(waker_utid_id_, Variadic::UnsignedInteger(utid));
+
+ } else if (line.event_name == "cpu_frequency") {
+ base::Optional<uint32_t> event_cpu = base::StringToUInt32(args["cpu_id"]);
+ base::Optional<double> new_state = base::StringToDouble(args["state"]);
+ if (!event_cpu.has_value()) {
+ return util::Status("Could not convert event cpu");
+ }
+ if (!event_cpu.has_value()) {
+ return util::Status("Could not convert state");
+ }
+
+ TrackId track = context_->track_tracker->InternCpuCounterTrack(
+ cpufreq_name_id_, event_cpu.value());
+ context_->event_tracker->PushCounter(line.ts, new_state.value(), track);
} else if (line.event_name == "cpu_idle") {
base::Optional<uint32_t> event_cpu = base::StringToUInt32(args["cpu_id"]);
base::Optional<double> new_state = base::StringToDouble(args["state"]);
@@ -129,8 +153,8 @@ util::Status SystraceLineParser::ParseLine(const SystraceLine& line) {
} else if (line.event_name == "binder_transaction") {
auto id = base::StringToInt32(args["transaction"]);
auto dest_node = base::StringToInt32(args["dest_node"]);
- auto dest_tgid = base::StringToInt32(args["dest_proc"]);
- auto dest_tid = base::StringToInt32(args["dest_thread"]);
+ auto dest_tgid = base::StringToUInt32(args["dest_proc"]);
+ auto dest_tid = base::StringToUInt32(args["dest_thread"]);
auto is_reply = base::StringToInt32(args["reply"]).value() == 1;
auto flags_str = args["flags"];
char* end;
diff --git a/src/trace_processor/importers/systrace/systrace_line_parser.h b/src/trace_processor/importers/systrace/systrace_line_parser.h
index 071ee316b..126fca7b6 100644
--- a/src/trace_processor/importers/systrace/systrace_line_parser.h
+++ b/src/trace_processor/importers/systrace/systrace_line_parser.h
@@ -36,11 +36,15 @@ class SystraceLineParser {
private:
TraceProcessorContext* const context_;
RssStatTracker rss_stat_tracker_;
+
const StringId sched_wakeup_name_id_ = kNullStringId;
+ const StringId sched_waking_name_id_ = kNullStringId;
+ const StringId cpufreq_name_id_ = kNullStringId;
const StringId cpuidle_name_id_ = kNullStringId;
const StringId workqueue_name_id_ = kNullStringId;
const StringId sched_blocked_reason_id_ = kNullStringId;
const StringId io_wait_id_ = kNullStringId;
+ const StringId waker_utid_id_ = kNullStringId;
};
} // namespace trace_processor
diff --git a/src/trace_processor/importers/systrace/systrace_parser.cc b/src/trace_processor/importers/systrace/systrace_parser.cc
index 607b2ba4d..a8c585478 100644
--- a/src/trace_processor/importers/systrace/systrace_parser.cc
+++ b/src/trace_processor/importers/systrace/systrace_parser.cc
@@ -17,11 +17,13 @@
#include "src/trace_processor/importers/systrace/systrace_parser.h"
#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/string_utils.h"
#include "src/trace_processor/importers/common/event_tracker.h"
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/importers/common/slice_tracker.h"
#include "src/trace_processor/importers/common/track_tracker.h"
#include "src/trace_processor/importers/proto/async_track_set_tracker.h"
+#include "src/trace_processor/storage/trace_storage.h"
namespace perfetto {
namespace trace_processor {
@@ -29,6 +31,7 @@ namespace trace_processor {
SystraceParser::SystraceParser(TraceProcessorContext* ctx)
: context_(ctx),
lmk_id_(ctx->storage->InternString("mem.lmk")),
+ oom_score_adj_id_(ctx->storage->InternString("oom_score_adj")),
screen_state_id_(ctx->storage->InternString("ScreenState")),
cookie_id_(ctx->storage->InternString("cookie")) {}
@@ -59,7 +62,7 @@ void SystraceParser::ParseZeroEvent(int64_t ts,
int64_t value) {
systrace_utils::SystraceTracePoint point{};
point.name = name;
- point.value = static_cast<double>(value);
+ point.int_value = value;
// Hardcode the tgid to 0 (i.e. no tgid available) because zero events can
// come from kernel threads and as we group kernel threads into the kthreadd
@@ -108,7 +111,7 @@ void SystraceParser::ParseTracingMarkWrite(int64_t ts,
// the UI.
point.tgid = 0;
- point.value = static_cast<double>(value);
+ point.int_value = value;
// Some versions of this trace point fill trace_type with one of (B/E/C),
// others use the trace_begin boolean and only support begin/end events:
if (trace_type == 0) {
@@ -127,18 +130,20 @@ void SystraceParser::ParseSystracePoint(
int64_t ts,
uint32_t pid,
systrace_utils::SystraceTracePoint point) {
+ auto get_utid = [pid, &point, this]() {
+ if (point.tgid == 0)
+ return context_->process_tracker->GetOrCreateThread(pid);
+ return context_->process_tracker->UpdateThread(pid, point.tgid);
+ };
+
switch (point.phase) {
case 'B': {
StringId name_id = context_->storage->InternString(point.name);
- UniqueTid utid;
- if (point.tgid == 0) {
- utid = context_->process_tracker->GetOrCreateThread(pid);
- } else {
- utid = context_->process_tracker->UpdateThread(pid, point.tgid);
- }
+ UniqueTid utid = get_utid();
TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
context_->slice_tracker->Begin(ts, track_id, kNullStringId /* cat */,
name_id);
+ PostProcessSpecialSliceBegin(ts, point.name);
break;
}
@@ -164,12 +169,13 @@ void SystraceParser::ParseSystracePoint(
case 'S':
case 'F': {
StringId name_id = context_->storage->InternString(point.name);
- int64_t cookie = static_cast<int64_t>(point.value);
+ int64_t cookie = point.int_value;
UniquePid upid =
context_->process_tracker->GetOrCreateProcess(point.tgid);
auto track_set_id =
- context_->async_track_set_tracker->InternAndroidSet(upid, name_id);
+ context_->async_track_set_tracker
+ ->InternAndroidLegacyUnnestableTrackSet(upid, name_id);
if (point.phase == 'S') {
// Historically, async slices on Android did not support nesting async
@@ -185,7 +191,7 @@ void SystraceParser::ParseSystracePoint(
// the *most recent* emitted 'S' event which leads even more inaccurate
// behaviour. To support these quirks, we have the special 'unnestable'
// slice concept which implements workarounds for these very specific
- // issues. No other code should ever use this method.
+ // issues. No other code should ever use |BeginLegacyUnnestable|.
tables::SliceTable::Row row;
row.ts = ts;
row.track_id =
@@ -203,6 +209,42 @@ void SystraceParser::ParseSystracePoint(
break;
}
+ case 'I': {
+ StringId name_id = context_->storage->InternString(point.name);
+ UniqueTid utid = get_utid();
+ TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
+ context_->slice_tracker->Scoped(ts, track_id, kNullStringId, name_id, 0);
+ break;
+ }
+
+ case 'N':
+ case 'T':
+ case 'U': {
+ StringId name_id = context_->storage->InternString(point.name);
+ StringId track_name_id = context_->storage->InternString(point.str_value);
+ UniquePid upid =
+ context_->process_tracker->GetOrCreateProcess(point.tgid);
+ auto track_set_id =
+ context_->async_track_set_tracker->InternProcessTrackSet(
+ upid, track_name_id);
+
+ if (point.phase == 'N') {
+ TrackId track_id =
+ context_->async_track_set_tracker->Scoped(track_set_id, ts, 0);
+ context_->slice_tracker->Scoped(ts, track_id, kNullStringId, name_id,
+ 0);
+ } else if (point.phase == 'T') {
+ TrackId track_id = context_->async_track_set_tracker->Begin(
+ track_set_id, point.int_value);
+ context_->slice_tracker->Begin(ts, track_id, kNullStringId, name_id);
+ } else if (point.phase == 'U') {
+ TrackId track_id = context_->async_track_set_tracker->End(
+ track_set_id, point.int_value);
+ context_->slice_tracker->End(ts, track_id);
+ }
+ break;
+ }
+
case 'C': {
// LMK events from userspace are hacked as counter events with the "value"
// of the counter representing the pid of the killed process which is
@@ -210,7 +252,7 @@ void SystraceParser::ParseSystracePoint(
// Homogenise this with kernel LMK events as an instant event, ignoring
// the resets to 0.
if (point.name == "kill_one_process") {
- auto killed_pid = static_cast<uint32_t>(point.value);
+ auto killed_pid = static_cast<uint32_t>(point.int_value);
if (killed_pid != 0) {
UniquePid killed_upid =
context_->process_tracker->GetOrCreateProcess(killed_pid);
@@ -223,7 +265,8 @@ void SystraceParser::ParseSystracePoint(
// Promote ScreenState to its own top level counter.
TrackId track =
context_->track_tracker->InternGlobalCounterTrack(screen_state_id_);
- context_->event_tracker->PushCounter(ts, point.value, track);
+ context_->event_tracker->PushCounter(
+ ts, static_cast<double>(point.int_value), track);
return;
}
@@ -243,10 +286,40 @@ void SystraceParser::ParseSystracePoint(
track_id =
context_->track_tracker->InternProcessCounterTrack(name_id, upid);
}
- context_->event_tracker->PushCounter(ts, point.value, track_id);
+ context_->event_tracker->PushCounter(
+ ts, static_cast<double>(point.int_value), track_id);
}
}
}
+void SystraceParser::PostProcessSpecialSliceBegin(int64_t ts,
+ base::StringView name) {
+ if (name.StartsWith("lmk,")) {
+ // LMK events introduced with http://aosp/1782391 are treated specially
+ // to parse the killed process oom_score_adj out of them.
+ // Format is 'lmk,pid,reason,oom adj,...'
+ std::vector<std::string> toks = base::SplitString(name.ToStdString(), ",");
+ if (toks.size() < 4) {
+ return;
+ }
+ auto killed_pid = base::StringToUInt32(toks[1]);
+ auto oom_score_adj = base::StringToInt32(toks[3]);
+ if (!killed_pid || !oom_score_adj) {
+ return;
+ }
+
+ UniquePid killed_upid =
+ context_->process_tracker->GetOrCreateProcess(*killed_pid);
+ // Add the oom score entry
+ TrackId track = context_->track_tracker->InternProcessCounterTrack(
+ oom_score_adj_id_, killed_upid);
+ context_->event_tracker->PushCounter(ts, *oom_score_adj, track);
+
+ // Add mem.lmk instant event for consistency with other methods.
+ context_->event_tracker->PushInstant(ts, lmk_id_, killed_upid,
+ RefType::kRefUpid);
+ }
+}
+
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/importers/systrace/systrace_parser.h b/src/trace_processor/importers/systrace/systrace_parser.h
index 2531150f6..af0f21f27 100644
--- a/src/trace_processor/importers/systrace/systrace_parser.h
+++ b/src/trace_processor/importers/systrace/systrace_parser.h
@@ -39,174 +39,221 @@ struct SystraceTracePoint {
SystraceTracePoint() {}
static SystraceTracePoint B(uint32_t tgid, base::StringView name) {
- return SystraceTracePoint('B', tgid, std::move(name), 0);
+ return SystraceTracePoint('B', tgid, std::move(name), 0, {});
}
static SystraceTracePoint E(uint32_t tgid) {
- return SystraceTracePoint('E', tgid, {}, 0);
+ return SystraceTracePoint('E', tgid, {}, 0, {});
}
static SystraceTracePoint C(uint32_t tgid,
base::StringView name,
- double value,
- base::StringView category_group = "") {
- return SystraceTracePoint('C', tgid, std::move(name), value,
- category_group);
+ int64_t value) {
+ return SystraceTracePoint('C', tgid, std::move(name), value, {});
}
static SystraceTracePoint S(uint32_t tgid,
base::StringView name,
- double value) {
- return SystraceTracePoint('S', tgid, std::move(name), value);
+ int64_t cookie) {
+ return SystraceTracePoint('S', tgid, std::move(name), cookie, {});
}
static SystraceTracePoint F(uint32_t tgid,
base::StringView name,
- double value) {
- return SystraceTracePoint('F', tgid, std::move(name), value);
+ int64_t cookie) {
+ return SystraceTracePoint('F', tgid, std::move(name), cookie, {});
+ }
+
+ static SystraceTracePoint I(uint32_t tgid, base::StringView name) {
+ return SystraceTracePoint('I', tgid, std::move(name), 0, {});
+ }
+
+ static SystraceTracePoint N(uint32_t tgid,
+ base::StringView track_name,
+ base::StringView name) {
+ return SystraceTracePoint('N', tgid, std::move(name), 0,
+ std::move(track_name));
+ }
+
+ static SystraceTracePoint T(uint32_t tgid,
+ base::StringView track_name,
+ base::StringView name,
+ int64_t cookie) {
+ return SystraceTracePoint('T', tgid, std::move(name), cookie,
+ std::move(track_name));
+ }
+
+ static SystraceTracePoint U(uint32_t tgid,
+ base::StringView track_name,
+ base::StringView name,
+ int64_t cookie) {
+ return SystraceTracePoint('U', tgid, std::move(name), cookie,
+ std::move(track_name));
}
SystraceTracePoint(char p,
uint32_t tg,
base::StringView n,
- double v,
- base::StringView c = "")
- : phase(p), tgid(tg), name(std::move(n)), value(v), category_group(c) {}
+ int64_t v,
+ base::StringView s)
+ : phase(p), tgid(tg), name(std::move(n)), int_value(v), str_value(s) {}
- // Phase can be one of B, E, C, S, F.
+ // Phase can be one of B, E, C, S, F, I, N, T, U.
char phase = '\0';
uint32_t tgid = 0;
- // For phase = 'B' and phase = 'C' only.
+ // For phase = B, C, S, F, N, U, T, U.
base::StringView name;
- // For phase = 'C' only.
- double value = 0;
+ // For phase = C (counter value) and B, S, F, N, T, U (async cookie).
+ int64_t int_value = 0;
- // For phase = 'C' only (from Chrome).
- base::StringView category_group;
+ // For phase = N, T, U (track name)
+ base::StringView str_value;
// Visible for unittesting.
friend std::ostream& operator<<(std::ostream& os,
const SystraceTracePoint& point) {
return os << "SystraceTracePoint{'" << point.phase << "', " << point.tgid
- << ", \"" << point.name.ToStdString() << "\", " << point.value
+ << ", \"" << point.name.ToStdString() << "\", " << point.int_value
+ << ", \"" << point.str_value.ToStdString() << "\""
<< "}";
}
};
// We have to handle trace_marker events of a few different types:
-// 1. some random text
-// 2. B|1636|pokeUserActivity
-// 3. E|1636
-// 4. C|1636|wq:monitor|0
-// 5. S|1636|frame_capture|123
-// 6. F|1636|frame_capture|456
-// 7. C|3209|TransfersBytesPendingOnDisk-value|0|Blob
-// Visible for unittesting.
-inline SystraceParseResult ParseSystraceTracePoint(base::StringView str,
- SystraceTracePoint* out) {
- const char* s = str.data();
- size_t len = str.size();
+// 1. some random text
+// 2. B|1636|pokeUserActivity
+// 3. E|1636
+// 4. C|1636|wq:monitor|0
+// 5. S|1636|frame_capture|123
+// 6. F|1636|frame_capture|456
+// 7. C|3209|TransfersBytesPendingOnDisk-value|0|Blob
+// 8. I|4820|instant
+// 9. N|1938|track_name|instant_name
+// 10. T|1339|track_name|slice_name|789
+// 11. U|6890|track_name|slice_name|135
+// Counters emitted by chromium can have a further "category group" appended
+// ("Blob" in the example below). We ignore the category group.
+inline SystraceParseResult ParseSystraceTracePoint(
+ base::StringView str_untrimmed,
+ SystraceTracePoint* out) {
*out = {};
- // We don't support empty events.
- if (len == 0)
- return SystraceParseResult::kFailure;
-
- constexpr const char* kClockSyncPrefix = "trace_event_clock_sync:";
- if (len >= strlen(kClockSyncPrefix) &&
- strncmp(kClockSyncPrefix, s, strlen(kClockSyncPrefix)) == 0)
- return SystraceParseResult::kUnsupported;
-
- char ph = s[0];
- if (ph != 'B' && ph != 'E' && ph != 'C' && ph != 'S' && ph != 'F')
- return SystraceParseResult::kFailure;
-
- out->phase = ph;
-
- // We only support E events with no arguments.
- if (len == 1 && ph != 'E')
- return SystraceParseResult::kFailure;
+ // Strip trailing \n and \0. StringViews are not null-terminated, but the
+ // writer could have appended a stray \0 depending on where the trace comes
+ // from.
+ size_t len = str_untrimmed.size();
+ for (; len > 0; --len) {
+ char last_char = str_untrimmed.at(len - 1);
+ if (last_char != '\n' && last_char != '\0')
+ break;
+ }
+ base::StringView str = str_untrimmed.substr(0, len);
+
+ size_t off = 0;
+
+ // This function reads the next field up to the next '|', '\0' or end(). It
+ // advances |off| as it goes through fields.
+ auto read_next_field = [&off, &str, len]() {
+ for (size_t field_start = off;; ++off) {
+ char c = off >= len ? '\0' : str.at(off);
+ if (c == '|' || c == '\0') {
+ auto res = str.substr(field_start, off - field_start);
+ ++off; // Eat the separator.
+ return res;
+ }
+ }
+ };
- // If str matches '[BEC]\|[0-9]+[\|\n]?' set tgid_length to the length of
- // the number. Otherwise return kFailure.
- if (len >= 2 && s[1] != '|' && s[1] != '\n')
+ auto f0_phase = read_next_field();
+ if (PERFETTO_UNLIKELY(f0_phase.empty()))
return SystraceParseResult::kFailure;
+ out->phase = f0_phase.at(0);
- size_t tgid_length = 0;
- for (size_t i = 2; i < len; i++) {
- if (s[i] == '|' || s[i] == '\n') {
- break;
- }
- if (s[i] < '0' || s[i] > '9')
- return SystraceParseResult::kFailure;
- tgid_length++;
- }
+ auto f1_tgid = read_next_field();
+ auto opt_tgid = base::StringToUInt32(f1_tgid.ToStdString());
+ out->tgid = opt_tgid.value_or(0);
+ const bool has_tgid = opt_tgid.has_value();
- // If len == 1, tgid_length will be 0 which will ensure we don't do
- // an out of bounds read.
- std::string tgid_str(s + 2, tgid_length);
- out->tgid = base::StringToUInt32(tgid_str).value_or(0);
-
- switch (ph) {
- case 'B': {
- size_t name_index = 2 + tgid_length + 1;
- out->name = base::StringView(
- s + name_index, len - name_index - (s[len - 1] == '\n' ? 1 : 0));
- if (out->name.empty()) {
- static const char kEmptySliceName[] = "[empty slice name]";
- out->name = base::StringView(kEmptySliceName);
+ switch (out->phase) {
+ case 'B': { // Begin thread-scoped synchronous slice.
+ if (!has_tgid)
+ return SystraceParseResult::kFailure;
+ auto f2_name = str.substr(off); // It's fine even if |off| >= end().
+ if (f2_name.empty()) {
+ out->name = base::StringView("[empty slice name]");
+ } else {
+ out->name = f2_name;
}
return SystraceParseResult::kSuccess;
}
- case 'E': {
+ case 'E': // End thread-scoped synchronous slice.
+ // Some non-Android traces (Flutter) use just "E" (aosp/1244409). Allow
+ // empty TGID on end slices. By design they are thread-scoped anyways.
return SystraceParseResult::kSuccess;
- }
- case 'S':
- case 'F':
- case 'C': {
- size_t name_index = 2 + tgid_length + 1;
- base::Optional<size_t> name_length;
- for (size_t i = name_index; i < len; i++) {
- if (s[i] == '|') {
- name_length = i - name_index;
- break;
- }
+ case 'S': // Begin of async slice.
+ case 'F': { // End of async slice.
+ auto f2_name = read_next_field();
+ auto f3_cookie = read_next_field();
+ auto maybe_cookie = base::StringToInt64(f3_cookie.ToStdString());
+ if (PERFETTO_UNLIKELY(!has_tgid || f2_name.empty() || f3_cookie.empty() ||
+ !maybe_cookie)) {
+ return SystraceParseResult::kFailure;
}
- if (!name_length.has_value())
+ out->name = f2_name;
+ out->int_value = *maybe_cookie;
+ return SystraceParseResult::kSuccess;
+ }
+ case 'I': { // Instant.
+ auto f2_name = read_next_field();
+ if (PERFETTO_UNLIKELY(!has_tgid || f2_name.empty())) {
return SystraceParseResult::kFailure;
- out->name = base::StringView(s + name_index, name_length.value());
-
- size_t value_index = name_index + name_length.value() + 1;
- size_t value_pipe = str.find('|', value_index);
- size_t value_len = value_pipe == base::StringView::npos
- ? len - value_index
- : value_pipe - value_index;
- if (value_len == 0)
+ }
+ out->name = f2_name;
+ return SystraceParseResult::kSuccess;
+ }
+ case 'N': { // Instant on track.
+ auto f2_track_name = read_next_field();
+ auto f3_name = read_next_field();
+ if (PERFETTO_UNLIKELY(!has_tgid || f2_track_name.empty() ||
+ f3_name.empty())) {
return SystraceParseResult::kFailure;
- if (s[value_index + value_len - 1] == '\n')
- value_len--;
- std::string value_str(s + value_index, value_len);
- base::Optional<double> maybe_value = base::StringToDouble(value_str);
- if (!maybe_value.has_value()) {
+ }
+ out->name = f3_name;
+ out->str_value = f2_track_name;
+ return SystraceParseResult::kSuccess;
+ }
+ case 'C': { // Counter.
+ auto f2_name = read_next_field();
+ auto f3_value = read_next_field();
+ auto maybe_value = base::StringToInt64(f3_value.ToStdString());
+ if (PERFETTO_UNLIKELY(!has_tgid || f2_name.empty() || f3_value.empty() ||
+ !maybe_value)) {
return SystraceParseResult::kFailure;
}
- out->value = maybe_value.value();
-
- if (value_pipe != base::StringView::npos) {
- size_t group_len = len - value_pipe - 1;
- if (group_len == 0)
- return SystraceParseResult::kFailure;
- if (s[len - 1] == '\n')
- group_len--;
- out->category_group = base::StringView(s + value_pipe + 1, group_len);
+ out->name = f2_name;
+ out->int_value = *maybe_value;
+ return SystraceParseResult::kSuccess;
+ }
+ case 'T': // Begin of async slice on track.
+ case 'U': { // End of async slice on track.
+ auto f2_track_name = read_next_field();
+ auto f3_name = read_next_field();
+ auto maybe_cookie = base::StringToInt64(read_next_field().ToStdString());
+ if (PERFETTO_UNLIKELY(!has_tgid || f2_track_name.empty() ||
+ f3_name.empty() || !maybe_cookie)) {
+ return SystraceParseResult::kFailure;
}
-
+ out->name = f3_name;
+ out->str_value = f2_track_name;
+ out->int_value = *maybe_cookie;
return SystraceParseResult::kSuccess;
}
default:
+ if (str.find("trace_event_clock_sync:") == 0)
+ return SystraceParseResult::kUnsupported;
return SystraceParseResult::kFailure;
}
}
@@ -214,8 +261,8 @@ inline SystraceParseResult ParseSystraceTracePoint(base::StringView str,
// Visible for unittesting.
inline bool operator==(const SystraceTracePoint& x,
const SystraceTracePoint& y) {
- return std::tie(x.phase, x.tgid, x.name, x.value) ==
- std::tie(y.phase, y.tgid, y.name, y.value);
+ return std::tie(x.phase, x.tgid, x.name, x.int_value, x.str_value) ==
+ std::tie(y.phase, y.tgid, y.name, y.int_value, y.str_value);
}
} // namespace systrace_utils
@@ -252,9 +299,11 @@ class SystraceParser : public Destructible {
void ParseSystracePoint(int64_t ts,
uint32_t pid,
systrace_utils::SystraceTracePoint event);
+ void PostProcessSpecialSliceBegin(int64_t ts, base::StringView name);
TraceProcessorContext* const context_;
const StringId lmk_id_;
+ const StringId oom_score_adj_id_;
const StringId screen_state_id_;
const StringId cookie_id_;
};
diff --git a/src/trace_processor/importers/systrace/systrace_parser_unittest.cc b/src/trace_processor/importers/systrace/systrace_parser_unittest.cc
index b0e9de185..07431c6b5 100644
--- a/src/trace_processor/importers/systrace/systrace_parser_unittest.cc
+++ b/src/trace_processor/importers/systrace/systrace_parser_unittest.cc
@@ -38,9 +38,15 @@ TEST(SystraceParserTest, SystraceEvent) {
ASSERT_EQ(ParseSystraceTracePoint("||\n", &result), Result::kFailure);
ASSERT_EQ(ParseSystraceTracePoint("||\n", &result), Result::kFailure);
ASSERT_EQ(ParseSystraceTracePoint("B", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("B\n", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("C\n", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("S\n", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("F\n", &result), Result::kFailure);
ASSERT_EQ(ParseSystraceTracePoint("C", &result), Result::kFailure);
ASSERT_EQ(ParseSystraceTracePoint("S", &result), Result::kFailure);
ASSERT_EQ(ParseSystraceTracePoint("F", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("I", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("N", &result), Result::kFailure);
ASSERT_EQ(ParseSystraceTracePoint("B|42|\n", &result), Result::kSuccess);
EXPECT_EQ(result, SystraceTracePoint::B(42, "[empty slice name]"));
@@ -63,14 +69,13 @@ TEST(SystraceParserTest, SystraceEvent) {
ASSERT_EQ(ParseSystraceTracePoint("E|42", &result), Result::kSuccess);
EXPECT_EQ(result, SystraceTracePoint::E(42));
- ASSERT_EQ(ParseSystraceTracePoint("C|543|foo|", &result), Result::kFailure);
ASSERT_EQ(ParseSystraceTracePoint("C|543|foo|8", &result), Result::kSuccess);
EXPECT_EQ(result, SystraceTracePoint::C(543, "foo", 8));
- ASSERT_EQ(ParseSystraceTracePoint("C|543|foo|8|", &result), Result::kFailure);
- ASSERT_EQ(ParseSystraceTracePoint("C|543|foo|8|group", &result),
- Result::kSuccess);
- EXPECT_EQ(result, SystraceTracePoint::C(543, "foo", 8, "group"));
+ ASSERT_EQ(
+ ParseSystraceTracePoint("C|543|foo|8|chromium_group_ignored", &result),
+ Result::kSuccess);
+ EXPECT_EQ(result, SystraceTracePoint::C(543, "foo", 8));
ASSERT_EQ(ParseSystraceTracePoint("S|", &result), Result::kFailure);
@@ -82,6 +87,19 @@ TEST(SystraceParserTest, SystraceEvent) {
Result::kSuccess);
EXPECT_EQ(result, SystraceTracePoint::F(123, "foo", 456));
+ ASSERT_EQ(ParseSystraceTracePoint("I||test", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("I|123|", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("I|123|event\n", &result),
+ Result::kSuccess);
+ EXPECT_EQ(result, SystraceTracePoint::I(123, "event"));
+
+ ASSERT_EQ(ParseSystraceTracePoint("N||test|test", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("N|123|test|", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("N|123||test", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("N|123|track|event\n", &result),
+ Result::kSuccess);
+ EXPECT_EQ(result, SystraceTracePoint::N(123, "track", "event"));
+
ASSERT_EQ(ParseSystraceTracePoint("trace_event_clock_sync: parent_ts=0.123\n",
&result),
Result::kUnsupported);
@@ -90,6 +108,32 @@ TEST(SystraceParserTest, SystraceEvent) {
Result::kUnsupported);
}
+TEST(SystraceParserTest, AsyncTrackEvents) {
+ SystraceTracePoint result{};
+ ASSERT_EQ(ParseSystraceTracePoint("T", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("U", &result), Result::kFailure);
+
+ ASSERT_EQ(ParseSystraceTracePoint("T||test|test|", &result),
+ Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("T|123|test||", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("T|123||test|", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("T|123|track|event|", &result),
+ Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("T|123|track|event|456", &result),
+ Result::kSuccess);
+ EXPECT_EQ(result, SystraceTracePoint::T(123, "track", "event", 456));
+
+ ASSERT_EQ(ParseSystraceTracePoint("U||test|test|", &result),
+ Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("U|123|test||", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("U|123||test|", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("U|123|track|event|", &result),
+ Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("U|123|track|event|456", &result),
+ Result::kSuccess);
+ EXPECT_EQ(result, SystraceTracePoint::U(123, "track", "event", 456));
+}
+
} // namespace
} // namespace systrace_utils
} // namespace trace_processor
diff --git a/src/trace_processor/importers/systrace/systrace_trace_parser.cc b/src/trace_processor/importers/systrace/systrace_trace_parser.cc
index d333af3cd..0fe878187 100644
--- a/src/trace_processor/importers/systrace/systrace_trace_parser.cc
+++ b/src/trace_processor/importers/systrace/systrace_trace_parser.cc
@@ -19,11 +19,12 @@
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/string_splitter.h"
#include "perfetto/ext/base/string_utils.h"
+#include "src/trace_processor/forwarding_trace_parser.h"
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/trace_sorter.h"
-#include <inttypes.h>
#include <cctype>
+#include <cinttypes>
#include <string>
#include <unordered_map>
@@ -64,13 +65,25 @@ SystraceTraceParser::SystraceTraceParser(TraceProcessorContext* ctx)
: line_parser_(ctx), ctx_(ctx) {}
SystraceTraceParser::~SystraceTraceParser() = default;
-util::Status SystraceTraceParser::Parse(std::unique_ptr<uint8_t[]> owned_buf,
- size_t size) {
+util::Status SystraceTraceParser::Parse(TraceBlobView blob) {
if (state_ == ParseState::kEndOfSystrace)
return util::OkStatus();
- partial_buf_.insert(partial_buf_.end(), &owned_buf[0], &owned_buf[size]);
+ partial_buf_.insert(partial_buf_.end(), blob.data(),
+ blob.data() + blob.size());
if (state_ == ParseState::kBeforeParse) {
+ // Remove anything before the TRACE:\n marker, which is emitted when
+ // obtaining traces via `adb shell "atrace -t 1 sched" > out.txt`.
+ std::array<uint8_t, 7> kAtraceMarker = {'T', 'R', 'A', 'C', 'E', ':', '\n'};
+ auto search_end = partial_buf_.begin() +
+ static_cast<int>(std::min(partial_buf_.size(),
+ kGuessTraceMaxLookahead));
+ auto it = std::search(partial_buf_.begin(), search_end,
+ kAtraceMarker.begin(), kAtraceMarker.end());
+ if (it != search_end)
+ partial_buf_.erase(partial_buf_.begin(), it + kAtraceMarker.size());
+
+ // Deal with HTML traces.
state_ = partial_buf_[0] == '<' ? ParseState::kHtmlBeforeSystrace
: ParseState::kSystrace;
}
diff --git a/src/trace_processor/importers/systrace/systrace_trace_parser.h b/src/trace_processor/importers/systrace/systrace_trace_parser.h
index bcb5ea871..972187905 100644
--- a/src/trace_processor/importers/systrace/systrace_trace_parser.h
+++ b/src/trace_processor/importers/systrace/systrace_trace_parser.h
@@ -35,7 +35,7 @@ class SystraceTraceParser : public ChunkedTraceReader {
~SystraceTraceParser() override;
// ChunkedTraceReader implementation.
- util::Status Parse(std::unique_ptr<uint8_t[]>, size_t size) override;
+ util::Status Parse(TraceBlobView) override;
void NotifyEndOfFile() override;
private:
diff --git a/src/trace_processor/iterator_impl.cc b/src/trace_processor/iterator_impl.cc
index 6539e9a62..5ee1e1d7f 100644
--- a/src/trace_processor/iterator_impl.cc
+++ b/src/trace_processor/iterator_impl.cc
@@ -18,6 +18,7 @@
#include "perfetto/base/time.h"
#include "perfetto/trace_processor/trace_processor_storage.h"
+#include "src/trace_processor/sqlite/scoped_db.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/trace_processor_impl.h"
@@ -26,15 +27,15 @@ namespace trace_processor {
IteratorImpl::IteratorImpl(TraceProcessorImpl* trace_processor,
sqlite3* db,
+ base::Status status,
ScopedStmt stmt,
- uint32_t column_count,
- util::Status status,
+ StmtMetadata metadata,
uint32_t sql_stats_row)
: trace_processor_(trace_processor),
db_(db),
+ status_(std::move(status)),
stmt_(std::move(stmt)),
- column_count_(column_count),
- status_(status),
+ stmt_metadata_(std::move(metadata)),
sql_stats_row_(sql_stats_row) {}
IteratorImpl::~IteratorImpl() {
@@ -58,7 +59,7 @@ Iterator::Iterator(std::unique_ptr<IteratorImpl> iterator)
Iterator::~Iterator() = default;
Iterator::Iterator(Iterator&&) noexcept = default;
-Iterator& Iterator::operator=(Iterator&&) = default;
+Iterator& Iterator::operator=(Iterator&&) noexcept = default;
bool Iterator::Next() {
return iterator_->Next();
@@ -76,9 +77,17 @@ uint32_t Iterator::ColumnCount() {
return iterator_->ColumnCount();
}
-util::Status Iterator::Status() {
+base::Status Iterator::Status() {
return iterator_->Status();
}
+uint32_t Iterator::StatementCount() {
+ return iterator_->StatementCount();
+}
+
+uint32_t Iterator::StatementWithOutputCount() {
+ return iterator_->StatementCountWithOutput();
+}
+
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/iterator_impl.h b/src/trace_processor/iterator_impl.h
index f286f2c59..68068e6b9 100644
--- a/src/trace_processor/iterator_impl.h
+++ b/src/trace_processor/iterator_impl.h
@@ -28,6 +28,7 @@
#include "perfetto/trace_processor/iterator.h"
#include "perfetto/trace_processor/status.h"
#include "src/trace_processor/sqlite/scoped_db.h"
+#include "src/trace_processor/sqlite/sqlite_utils.h"
namespace perfetto {
namespace trace_processor {
@@ -36,11 +37,17 @@ class TraceProcessorImpl;
class IteratorImpl {
public:
+ struct StmtMetadata {
+ uint32_t column_count = 0;
+ uint32_t statement_count = 0;
+ uint32_t statement_count_with_output = 0;
+ };
+
IteratorImpl(TraceProcessorImpl* impl,
sqlite3* db,
+ base::Status,
ScopedStmt,
- uint32_t column_count,
- util::Status,
+ StmtMetadata,
uint32_t sql_stats_row);
~IteratorImpl();
@@ -52,10 +59,25 @@ class IteratorImpl {
// Methods called by the base Iterator class.
bool Next() {
- // Delegate to the cc file to prevent trace_storage.h include in this file.
+ PERFETTO_DCHECK(stmt_ || !status_.ok());
+
if (!called_next_) {
+ // Delegate to the cc file to prevent trace_storage.h include in this
+ // file.
RecordFirstNextInSqlStats();
called_next_ = true;
+
+ // In the past, we used to call sqlite3_step for the first time in this
+ // function which 1:1 matched Next calls to sqlite3_step calls. However,
+ // with the introduction of multi-statement support, we call
+ // sqlite3_step when tokenizing the queries and so we need to *not* call
+ // step the first time Next is called.
+ //
+ // Aside: if we could, we would change the API to match the new setup
+ // (i.e. implement operator bool, make Next return nothing similar to C++
+ // iterators); however, too many clients depend on the current behavior so
+ // we have to keep the API as is.
+ return status_.ok() && !sqlite_utils::IsStmtDone(*stmt_);
}
if (!status_.ok())
@@ -63,7 +85,8 @@ class IteratorImpl {
int ret = sqlite3_step(*stmt_);
if (PERFETTO_UNLIKELY(ret != SQLITE_ROW && ret != SQLITE_DONE)) {
- status_ = util::ErrStatus("%s", sqlite3_errmsg(db_));
+ status_ = base::ErrStatus("%s (errcode %d)", sqlite3_errmsg(db_), ret);
+ stmt_.reset();
return false;
}
return ret == SQLITE_ROW;
@@ -101,12 +124,18 @@ class IteratorImpl {
}
std::string GetColumnName(uint32_t col) {
- return sqlite3_column_name(stmt_.get(), static_cast<int>(col));
+ return stmt_ ? sqlite3_column_name(*stmt_, static_cast<int>(col)) : "";
}
- uint32_t ColumnCount() { return column_count_; }
+ base::Status Status() { return status_; }
+
+ uint32_t ColumnCount() { return stmt_metadata_.column_count; }
- util::Status Status() { return status_; }
+ uint32_t StatementCount() { return stmt_metadata_.statement_count; }
+
+ uint32_t StatementCountWithOutput() {
+ return stmt_metadata_.statement_count_with_output;
+ }
private:
// Dummy function to pass to ScopedResource.
@@ -125,9 +154,10 @@ class IteratorImpl {
ScopedTraceProcessor trace_processor_;
sqlite3* db_ = nullptr;
+ base::Status status_;
+
ScopedStmt stmt_;
- uint32_t column_count_ = 0;
- util::Status status_;
+ StmtMetadata stmt_metadata_;
uint32_t sql_stats_row_ = 0;
bool called_next_ = false;
diff --git a/src/trace_processor/metrics/BUILD.gn b/src/trace_processor/metrics/BUILD.gn
index 00a1e4ecf..8731f78e7 100644
--- a/src/trace_processor/metrics/BUILD.gn
+++ b/src/trace_processor/metrics/BUILD.gn
@@ -13,143 +13,21 @@
# limitations under the License.
import("../../../gn/perfetto.gni")
+import("../../../gn/perfetto_cc_proto_descriptor.gni")
import("../../../gn/test.gni")
-sql_files = [
- "trace_metadata.sql",
- "trace_stats.sql",
- "android/android_batt.sql",
- "android/android_cpu.sql",
- "android/android_surfaceflinger.sql",
- "android/android_cpu_agg.sql",
- "android/android_cpu_raw_metrics_per_core.sql",
- "android/android_dma_heap.sql",
- "android/android_fastrpc.sql",
- "android/android_gpu.sql",
- "android/android_hwui_threads.sql",
- "android/android_mem.sql",
- "android/android_mem_unagg.sql",
- "android/android_ion.sql",
- "android/composer_execution.sql",
- "android/composition_layers.sql",
- "android/frame_missed.sql",
- "android/android_jank.sql",
- "android/android_lmk_reason.sql",
- "android/android_lmk.sql",
- "android/android_powrails.sql",
- "android/android_proxy_power.sql",
- "android/android_startup_launches.sql",
- "android/android_startup.sql",
- "android/android_package_list.sql",
- "android/android_task_names.sql",
- "android/android_thread_time_in_state.sql",
- "android/cpu_info.sql",
- "android/display_metrics.sql",
- "android/g2d.sql",
- "android/g2d_duration.sql",
- "android/hsc_startups.sql",
- "android/android_hwcomposer.sql",
- "android/android_hwui_metric.sql",
- "android/java_heap_histogram.sql",
- "android/java_heap_stats.sql",
- "android/power_drain_in_watts.sql",
- "android/power_profile_data.sql",
- "android/process_unagg_mem_view.sql",
- "android/process_mem.sql",
- "android/process_metadata.sql",
- "android/process_oom_score.sql",
- "android/mem_stats_priority_breakdown.sql",
- "android/span_view_stats.sql",
- "android/android_sysui_cuj.sql",
- "android/process_counter_span_view.sql",
- "android/global_counter_span_view.sql",
- "android/unsymbolized_frames.sql",
- "chrome/actual_power_by_category.sql",
- "chrome/actual_power_by_rail_mode.sql",
- "chrome/chrome_event_metadata.sql",
- "chrome/chrome_processes.sql",
- "chrome/chrome_thread_slice_with_cpu_time.sql",
- "chrome/cpu_time_by_category.sql",
- "chrome/cpu_time_by_rail_mode.sql",
- "chrome/estimated_power_by_category.sql",
- "chrome/estimated_power_by_rail_mode.sql",
- "chrome/rail_modes.sql",
- "chrome/scroll_jank.sql",
- "chrome/scroll_jank_cause.sql",
- "chrome/scroll_jank_cause_blocking_task.sql",
- "chrome/scroll_jank_cause_blocking_touch_move.sql",
- "chrome/scroll_jank_cause_get_bitmap.sql",
- "chrome/scroll_jank_cause_queuing_delay.sql",
- "chrome/scroll_flow_event.sql",
- "chrome/scroll_flow_event_queuing_delay.sql",
- "chrome/test_chrome_metric.sql",
- "experimental/blink_gc_metric.sql",
- "experimental/frame_times.sql",
- "experimental/media_metric.sql",
- "experimental/reported_by_page.sql",
- "webview/webview_power_usage.sql",
-]
-
-config("gen_config") {
- include_dirs = [ "${root_gen_dir}/${perfetto_root_path}" ]
-}
-
-action("gen_merged_sql_metrics") {
- script = "../../../tools/gen_merged_sql_metrics.py"
- generated_header = "${target_gen_dir}/sql_metrics.h"
- args = rebase_path(sql_files, root_build_dir) + [
- "--cpp_out",
- rebase_path(generated_header, root_build_dir),
- ]
- inputs = sql_files
- outputs = [ generated_header ]
- public_configs = [ ":gen_config" ]
-}
-
-action("gen_cc_metrics_descriptor") {
+perfetto_cc_proto_descriptor("gen_cc_metrics_descriptor") {
+ descriptor_name = "metrics.descriptor"
descriptor_target = "../../../protos/perfetto/metrics:descriptor"
- generated_header = "${target_gen_dir}/metrics.descriptor.h"
-
- descriptor_file_path = get_label_info(descriptor_target, "target_gen_dir") +
- "/metrics.descriptor"
-
- script = "../../../tools/gen_cc_proto_descriptor.py"
- deps = [ descriptor_target ]
- args = [
- "--gen_dir",
- rebase_path(root_gen_dir, root_build_dir),
- "--cpp_out",
- rebase_path(generated_header, root_build_dir),
- rebase_path(descriptor_file_path, root_build_dir),
- ]
- inputs = [ descriptor_file_path ]
- outputs = [ generated_header ]
- public_configs = [ ":gen_config" ]
}
-action("gen_cc_all_chrome_metrics_descriptor") {
+perfetto_cc_proto_descriptor("gen_cc_all_chrome_metrics_descriptor") {
+ descriptor_name = "all_chrome_metrics.descriptor"
descriptor_target = "../../../protos/perfetto/metrics/chrome:descriptor"
- generated_header = "${target_gen_dir}/chrome/all_chrome_metrics.descriptor.h"
-
- descriptor_file_path = get_label_info(descriptor_target, "target_gen_dir") +
- "/all_chrome_metrics.descriptor"
-
- script = "../../../tools/gen_cc_proto_descriptor.py"
- deps = [ descriptor_target ]
- args = [
- "--gen_dir",
- rebase_path(root_gen_dir, root_build_dir),
- "--cpp_out",
- rebase_path(generated_header, root_build_dir),
- rebase_path(descriptor_file_path, root_build_dir),
- ]
- inputs = [ descriptor_file_path ]
- outputs = [ generated_header ]
- public_configs = [ ":gen_config" ]
}
if (enable_perfetto_trace_processor_sqlite) {
- source_set("lib") {
+ source_set("metrics") {
sources = [
"metrics.cc",
"metrics.h",
@@ -168,9 +46,9 @@ if (enable_perfetto_trace_processor_sqlite) {
public_deps = [
":gen_cc_all_chrome_metrics_descriptor",
":gen_cc_metrics_descriptor",
- ":gen_merged_sql_metrics",
"../util",
"../util:descriptors",
+ "sql:gen_amalgamated_sql_metrics",
]
}
@@ -178,7 +56,7 @@ if (enable_perfetto_trace_processor_sqlite) {
testonly = true
sources = [ "metrics_unittest.cc" ]
deps = [
- ":lib",
+ ":metrics",
"..:lib",
"../../../gn:default_deps",
"../../../gn:gtest_and_gmock",
diff --git a/src/trace_processor/metrics/android/android_batt.sql b/src/trace_processor/metrics/android/android_batt.sql
deleted file mode 100644
index db0fbf302..000000000
--- a/src/trace_processor/metrics/android/android_batt.sql
+++ /dev/null
@@ -1,278 +0,0 @@
---
--- Copyright 2019 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-DROP VIEW IF EXISTS battery_view;
-CREATE VIEW battery_view AS
-SELECT
- all_ts.ts as ts,
- current_avg_ua,
- capacity_percent,
- charge_uah,
- current_ua
-FROM (
- SELECT distinct(ts) AS ts
- FROM counter c
- JOIN counter_track t on c.track_id = t.id
- WHERE name LIKE 'batt.%'
-) AS all_ts
-LEFT JOIN (
- SELECT ts, value AS current_avg_ua
- FROM counter c
- JOIN counter_track t on c.track_id = t.id
- WHERE name='batt.current.avg_ua'
-) USING(ts)
-LEFT JOIN (
- SELECT ts, value AS capacity_percent
- FROM counter c
- JOIN counter_track t on c.track_id = t.id
- WHERE name='batt.capacity_pct'
-) USING(ts)
-LEFT JOIN (
- SELECT ts, value AS charge_uah
- FROM counter c
- JOIN counter_track t on c.track_id = t.id
- WHERE name='batt.charge_uah'
-) USING(ts)
-LEFT JOIN (
- SELECT ts, value AS current_ua
- FROM counter c
- JOIN counter_track t on c.track_id = t.id
- WHERE name='batt.current_ua'
-) USING(ts)
-ORDER BY ts;
-
-DROP TABLE IF EXISTS android_batt_wakelocks_merged;
-CREATE TABLE android_batt_wakelocks_merged AS
-SELECT
- MIN(ts) AS ts,
- MAX(ts_end) AS ts_end
-FROM (
- SELECT
- *,
- SUM(new_group) OVER (ORDER BY ts) AS group_id
- FROM (
- SELECT
- ts,
- ts + dur AS ts_end,
- -- There is a new group if there was a gap before this wakelock.
- -- i.e. the max end timestamp of all preceding wakelocks is before
- -- the start timestamp of this one.
- -- The null check is for the first row which is always a new group.
- IFNULL(
- MAX(ts + dur) OVER (
- ORDER BY ts
- ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
- ) < ts,
- true
- ) AS new_group
- FROM slice
- WHERE slice.name LIKE 'WakeLock %' AND dur != -1
- )
-)
-GROUP BY group_id;
-
--- Different device kernels log different actions when suspending. This table
--- tells us the action that straddles the actual suspend period.
-DROP TABLE IF EXISTS device_action_mapping;
-CREATE TABLE device_action_mapping (device TEXT, action TEXT);
-INSERT INTO device_action_mapping VALUES
-('blueline', 'timekeeping_freeze'),
-('crosshatch', 'timekeeping_freeze'),
-('bonito', 'timekeeping_freeze'),
-('sargo', 'timekeeping_freeze'),
-('coral', 'timekeeping_freeze'),
-('flame', 'timekeeping_freeze'),
-('sunfish', 'timekeeping_freeze'),
-('redfin', 'syscore_resume'),
-('bramble', 'syscore_resume');
-
-DROP TABLE IF EXISTS device_action;
-CREATE TABLE device_action AS
-SELECT action
-FROM device_action_mapping dam
-WHERE EXISTS (
- SELECT 1 FROM metadata
- WHERE name = 'android_build_fingerprint' AND str_value LIKE '%' || dam.device || '%');
-
-DROP TABLE IF EXISTS suspend_slice_;
-CREATE TABLE suspend_slice_ AS
--- Traces from after b/70292203 was fixed have the action string so just look
--- for it.
-SELECT
- ts,
- dur,
- true as trustworthy
-FROM (
- SELECT
- ts,
- LEAD(ts) OVER (ORDER BY ts, start DESC) - ts AS dur,
- start
- FROM (
- SELECT
- ts,
- EXTRACT_ARG(arg_set_id, 'action') AS action,
- EXTRACT_ARG(arg_set_id, 'start') AS start
- FROM raw
- WHERE name = 'suspend_resume'
- ) JOIN device_action USING(action)
-)
-WHERE start = 1
-UNION ALL
--- Traces from before b/70292203 was fixed (approx Nov 2020) do not have the
--- action string so we do some convoluted pattern matching that mostly works.
--- TODO(simonmacm) remove this when enough time has passed (mid 2021?)
-SELECT
- ts,
- dur,
- false as trustworthy
-FROM (
- SELECT
- ts,
- ts - lag(ts) OVER w AS lag_dur,
- lead(ts) OVER w - ts AS dur,
- action,
- start,
- event,
- lag(start) OVER w AS lag_start,
- lag(event) OVER w AS lag_event,
- lag(start, 2) OVER w AS lag_2_start,
- lag(event, 2) OVER w AS lag_2_event,
- lead(start) OVER w AS lead_start,
- lead(event) OVER w AS lead_event,
- lead(start, 2) OVER w AS lead_2_start,
- lead(event, 2) OVER w AS lead_2_event
- FROM (
- SELECT
- ts,
- EXTRACT_ARG(arg_set_id, 'action') AS action,
- EXTRACT_ARG(arg_set_id, 'start') AS start,
- EXTRACT_ARG(arg_set_id, 'val') AS event
- FROM raw
- WHERE name = 'suspend_resume'
- )
- WINDOW w AS (ORDER BY ts)
-)
-WHERE action IS NULL AND (
--- We want to find the start and end events with action='timekeeping_freeze'.
--- In practice, these events often show up in a sequence like the following:
--- start = 1, event = 1 [string would have been 'machine_suspend']
--- start = 1, event = (any) [string would have been 'timekeeping_freeze'] *
---
--- (sleep happens here)
---
--- start = 0, event = (any) [string would have been 'timekeeping_freeze']
--- start = 0, event = 1 [string would have been 'machine_suspend']
---
--- So we look for this pattern of start and event, anchored on the event marked
--- with "*".
- (
- lag_start = 1 AND lag_event = 1
- AND start = 1
- AND lead_start = 0
- AND lead_2_start = 0 AND lead_2_event = 1
- )
--- Or in newer kernels we seem to have a very different pattern. We can take
--- advantage of that fact that we get several events with identical timestamp
--- just before sleeping (normally this never happens):
--- gap = 0, start = 1, event = 3
--- gap = 0, start = 0, event = 3
--- gap = 0, start = 1, event = 0
---
--- (sleep happens here)
---
--- gap = (any), start = 0, event = 0
- OR (
- lag_dur = 0
- AND lead_start = 0 AND lead_event = 0
- AND start = 1 AND event = 0
- AND lag_start = 0 AND lag_event = 3
- AND lag_2_start = 1 AND lag_2_event = 3
- )
-);
-
-DROP TABLE device_action_mapping;
-DROP TABLE device_action;
-
-SELECT RUN_METRIC('android/global_counter_span_view.sql',
- 'table_name', 'screen_state',
- 'counter_name', 'ScreenState');
-
-DROP TABLE IF EXISTS screen_state_span_with_suspend;
-CREATE VIRTUAL TABLE screen_state_span_with_suspend
- USING span_join(screen_state_span, suspend_slice_);
-
-DROP VIEW IF EXISTS android_batt_event;
-CREATE VIEW android_batt_event AS
-SELECT
- ts,
- dur,
- 'Suspended' AS slice_name,
- 'Suspend / resume' AS track_name,
- 'slice' AS track_type
-FROM suspend_slice_;
-
-DROP VIEW IF EXISTS android_batt_output;
-CREATE VIEW android_batt_output AS
-SELECT AndroidBatteryMetric(
- 'battery_counters', (
- SELECT RepeatedField(
- AndroidBatteryMetric_BatteryCounters(
- 'timestamp_ns', ts,
- 'charge_counter_uah', charge_uah,
- 'capacity_percent', capacity_percent,
- 'current_ua', current_ua,
- 'current_avg_ua', current_avg_ua
- )
- )
- FROM battery_view
- ),
- 'battery_aggregates', (
- SELECT NULL_IF_EMPTY(AndroidBatteryMetric_BatteryAggregates(
- 'total_screen_off_ns',
- SUM(CASE WHEN state = 1.0 AND tbl = 'total' THEN dur ELSE 0 END),
- 'total_screen_on_ns',
- SUM(CASE WHEN state = 2.0 AND tbl = 'total' THEN dur ELSE 0 END),
- 'total_screen_doze_ns',
- SUM(CASE WHEN state = 3.0 AND tbl = 'total' THEN dur ELSE 0 END),
- 'sleep_ns',
- (SELECT SUM(dur) FROM suspend_slice_),
- 'sleep_screen_off_ns',
- SUM(CASE WHEN state = 1.0 AND tbl = 'sleep' THEN dur ELSE 0 END),
- 'sleep_screen_on_ns',
- SUM(CASE WHEN state = 2.0 AND tbl = 'sleep' THEN dur ELSE 0 END),
- 'sleep_screen_doze_ns',
- SUM(CASE WHEN state = 3.0 AND tbl = 'sleep' THEN dur ELSE 0 END),
- 'total_wakelock_ns',
- (SELECT SUM(ts_end - ts) FROM android_batt_wakelocks_merged)
- ))
- FROM (
- SELECT dur, screen_state_val AS state, 'total' AS tbl
- FROM screen_state_span
- UNION ALL
- SELECT dur, screen_state_val AS state, 'sleep' AS tbl
- FROM screen_state_span_with_suspend
- )
- ),
- 'suspend_period', (
- SELECT RepeatedField(
- AndroidBatteryMetric_SuspendPeriod(
- 'timestamp_ns', ts,
- 'duration_ns', dur
- )
- )
- FROM suspend_slice_
- WHERE trustworthy
- )
-);
diff --git a/src/trace_processor/metrics/android/android_fastrpc.sql b/src/trace_processor/metrics/android/android_fastrpc.sql
deleted file mode 100644
index 81da811c6..000000000
--- a/src/trace_processor/metrics/android/android_fastrpc.sql
+++ /dev/null
@@ -1,72 +0,0 @@
-DROP VIEW IF EXISTS fastrpc_timeline;
-CREATE VIEW fastrpc_timeline AS
-SELECT
- ts,
- LEAD(ts, 1, (SELECT end_ts FROM trace_bounds))
- OVER(PARTITION BY track_id ORDER BY ts) - ts AS dur,
- RTRIM(SUBSTR(name, 13), ']') AS subsystem_name,
- track_id,
- value
-FROM counter JOIN counter_track
- ON counter.track_id = counter_track.id
-WHERE (name LIKE 'mem.fastrpc[%');
-
-DROP VIEW IF EXISTS fastrpc_subsystem_stats;
-CREATE VIEW fastrpc_subsystem_stats AS
-SELECT
- subsystem_name,
- SUM(value * dur) / SUM(dur) AS avg_size,
- MIN(value) AS min_size,
- MAX(value) AS max_size
-FROM fastrpc_timeline
-GROUP BY 1;
-
-DROP VIEW IF EXISTS fastrpc_raw_allocs;
-CREATE VIEW fastrpc_raw_allocs AS
-SELECT
- RTRIM(SUBSTR(name, 20), ']') AS subsystem_name,
- ts,
- value AS instant_value,
- SUM(value) OVER win AS value
-FROM counter c JOIN thread_counter_track t ON c.track_id = t.id
-WHERE name LIKE 'mem.fastrpc_change%' AND value > 0
-WINDOW win AS (
- PARTITION BY name ORDER BY ts
- ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
-);
-
-DROP VIEW IF EXISTS fastrpc_alloc_stats;
-CREATE VIEW fastrpc_alloc_stats AS
-SELECT
- subsystem_name,
- SUM(instant_value) AS total_alloc_size_bytes
-FROM fastrpc_raw_allocs
-GROUP BY 1;
-
--- We need to group by ts here as we can have two events from
--- different processes occurring at the same timestamp. We take the
--- max as this will take both allocations into account at that
--- timestamp.
-DROP VIEW IF EXISTS android_fastrpc_event;
-CREATE VIEW android_fastrpc_event AS
-SELECT
- 'counter' AS track_type,
- printf('fastrpc allocations (subsystem: %s)', subsystem_name) AS track_name,
- ts,
- MAX(value) AS value
-FROM fastrpc_raw_allocs
-GROUP BY 1, 2, 3;
-
-DROP VIEW IF EXISTS android_fastrpc_output;
-CREATE VIEW android_fastrpc_output AS
-SELECT AndroidFastrpcMetric(
- 'subsystem', RepeatedField(
- AndroidFastrpcMetric_Subsystem(
- 'name', subsystem_name,
- 'avg_size_bytes', avg_size,
- 'min_size_bytes', min_size,
- 'max_size_bytes', max_size,
- 'total_alloc_size_bytes', total_alloc_size_bytes
- )
- ))
-FROM fastrpc_subsystem_stats JOIN fastrpc_alloc_stats USING (subsystem_name);
diff --git a/src/trace_processor/metrics/android/android_gpu.sql b/src/trace_processor/metrics/android/android_gpu.sql
deleted file mode 100644
index 644f00d5d..000000000
--- a/src/trace_processor/metrics/android/android_gpu.sql
+++ /dev/null
@@ -1,67 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
-SELECT RUN_METRIC('android/global_counter_span_view.sql',
- 'table_name', 'global_gpu_memory',
- 'counter_name', 'GPU Memory');
-
-SELECT RUN_METRIC('android/process_counter_span_view.sql',
- 'table_name', 'proc_gpu_memory',
- 'counter_name', 'GPU Memory');
-
-DROP VIEW IF EXISTS proc_gpu_memory_view;
-CREATE VIEW proc_gpu_memory_view AS
-SELECT
- upid,
- MAX(proc_gpu_memory_val) as mem_max,
- MIN(proc_gpu_memory_val) as mem_min,
- SUM(proc_gpu_memory_val * dur) as mem_valxdur,
- SUM(dur) as mem_dur
-FROM proc_gpu_memory_span
-GROUP BY upid;
-
-DROP VIEW IF EXISTS agg_proc_gpu_view;
-CREATE VIEW agg_proc_gpu_view AS
-SELECT
- name,
- MAX(mem_max) as mem_max,
- MIN(mem_min) as mem_min,
- SUM(mem_valxdur) / SUM(mem_dur) as mem_avg
-FROM process
-JOIN proc_gpu_memory_view
-USING(upid)
-GROUP BY name;
-
-DROP VIEW IF EXISTS proc_gpu_view;
-CREATE VIEW proc_gpu_view AS
-SELECT
- AndroidGpuMetric_Process(
- 'name', name,
- 'mem_max', CAST(mem_max as INT64),
- 'mem_min', CAST(mem_min as INT64),
- 'mem_avg', CAST(mem_avg as INT64)
- ) AS proto
-FROM agg_proc_gpu_view;
-
-DROP VIEW IF EXISTS android_gpu_output;
-CREATE VIEW android_gpu_output AS
-SELECT AndroidGpuMetric(
- 'processes', (SELECT RepeatedField(proto) FROM proc_gpu_view),
- 'mem_max', CAST(MAX(global_gpu_memory_val) as INT64),
- 'mem_min', CAST(MIN(global_gpu_memory_val) as INT64),
- 'mem_avg', CAST(SUM(global_gpu_memory_val * dur) / SUM(dur) as INT64)
-)
-FROM global_gpu_memory_span;
diff --git a/src/trace_processor/metrics/android/android_hwcomposer.sql b/src/trace_processor/metrics/android/android_hwcomposer.sql
deleted file mode 100644
index 7c46107a4..000000000
--- a/src/trace_processor/metrics/android/android_hwcomposer.sql
+++ /dev/null
@@ -1,83 +0,0 @@
---
--- Copyright 2021 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
-
-SELECT RUN_METRIC(
- 'android/composition_layers.sql',
- 'track_name', 'HWComposer: Total Layer',
- 'output', 'total_layers'
-);
-
-SELECT RUN_METRIC(
- 'android/composition_layers.sql',
- 'track_name', 'HWComposer: DPU Layer',
- 'output', 'dpu_layers'
-);
-
-SELECT RUN_METRIC(
- 'android/composition_layers.sql',
- 'track_name', 'HWComposer: GPU Layer',
- 'output', 'gpu_layers'
-);
-
-SELECT RUN_METRIC(
- 'android/composition_layers.sql',
- 'track_name', 'HWComposer: DPU Cached Layer',
- 'output', 'dpu_cached_layers'
-);
-
-SELECT RUN_METRIC(
- 'android/composition_layers.sql',
- 'track_name', 'HWComposer: SF Cached Layer',
- 'output', 'sf_cached_layers'
-);
-
-SELECT RUN_METRIC(
- 'android/composer_execution.sql',
- 'output', 'hwc_execution_spans'
-);
-
-DROP VIEW IF EXISTS android_hwcomposer_output;
-CREATE VIEW android_hwcomposer_output AS
-SELECT AndroidHwcomposerMetrics(
- 'composition_total_layers', (SELECT AVG(value) FROM total_layers),
- 'composition_dpu_layers', (SELECT AVG(value) FROM dpu_layers),
- 'composition_gpu_layers', (SELECT AVG(value) FROM gpu_layers),
- 'composition_dpu_cached_layers', (SELECT AVG(value) FROM dpu_cached_layers),
- 'composition_sf_cached_layers', (SELECT AVG(value) FROM sf_cached_layers),
- 'skipped_validation_count',
- (SELECT COUNT(*) FROM hwc_execution_spans
- WHERE validation_type = 'skipped_validation'),
- 'unskipped_validation_count',
- (SELECT COUNT(*) FROM hwc_execution_spans
- WHERE validation_type = 'unskipped_validation'),
- 'separated_validation_count',
- (SELECT COUNT(*) FROM hwc_execution_spans
- WHERE validation_type = 'separated_validation'),
- 'unknown_validation_count',
- (SELECT COUNT(*) FROM hwc_execution_spans
- WHERE validation_type = 'unknown'),
- 'avg_all_execution_time_ms',
- (SELECT AVG(execution_time_ns) / 1e6 FROM hwc_execution_spans
- WHERE validation_type != 'unknown'),
- 'avg_skipped_execution_time_ms',
- (SELECT AVG(execution_time_ns) / 1e6 FROM hwc_execution_spans
- WHERE validation_type = 'skipped_validation'),
- 'avg_unskipped_execution_time_ms',
- (SELECT AVG(execution_time_ns) / 1e6 FROM hwc_execution_spans
- WHERE validation_type = 'unskipped_validation'),
- 'avg_separated_execution_time_ms',
- (SELECT AVG(execution_time_ns) / 1e6 FROM hwc_execution_spans
- WHERE validation_type = 'separated_validation')
-);
diff --git a/src/trace_processor/metrics/android/android_hwui_metric.sql b/src/trace_processor/metrics/android/android_hwui_metric.sql
deleted file mode 100644
index 585e515e1..000000000
--- a/src/trace_processor/metrics/android/android_hwui_metric.sql
+++ /dev/null
@@ -1,261 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
-
--- TOP processes that have a RenderThread, sorted by CPU time on RT
-DROP VIEW IF EXISTS hwui_processes;
-CREATE VIEW hwui_processes AS
-SELECT
- process.name as process_name,
- process.upid as process_upid,
- CAST(SUM(sched.dur) / 1e6 as INT64) as rt_cpu_time_ms,
- thread.utid as render_thread_id
-FROM sched
-INNER JOIN thread ON (thread.utid = sched.utid AND thread.name='RenderThread')
-INNER JOIN process ON (process.upid = thread.upid)
-GROUP BY process.name
-ORDER BY rt_cpu_time_ms DESC;
-
-DROP VIEW IF EXISTS hwui_draw_frame;
-CREATE VIEW hwui_draw_frame AS
-SELECT
- count(*) as draw_frame_count,
- max(dur) as draw_frame_max,
- min(dur) as draw_frame_min,
- avg(dur) as draw_frame_avg,
- thread_track.utid as render_thread_id
-FROM slice
-INNER JOIN thread_track ON (thread_track.id = slice.track_id)
-WHERE slice.name LIKE 'DrawFrame%' AND slice.dur >= 0
-GROUP BY thread_track.utid;
-
-DROP VIEW IF EXISTS hwui_flush_commands;
-CREATE VIEW hwui_flush_commands AS
-SELECT
- count(*) as flush_count,
- max(dur) as flush_max,
- min(dur) as flush_min,
- avg(dur) as flush_avg,
- thread_track.utid as render_thread_id
-FROM slice
-INNER JOIN thread_track ON (thread_track.id = slice.track_id)
-WHERE slice.name='flush commands' AND slice.dur >= 0
-GROUP BY thread_track.utid;
-
-DROP VIEW IF EXISTS hwui_prepare_tree;
-CREATE VIEW hwui_prepare_tree AS
-SELECT
- count(*) as prepare_tree_count,
- max(dur) as prepare_tree_max,
- min(dur) as prepare_tree_min,
- avg(dur) as prepare_tree_avg,
- thread_track.utid as render_thread_id
-FROM slice
-INNER JOIN thread_track ON (thread_track.id = slice.track_id)
-WHERE slice.name='prepareTree' AND slice.dur >= 0
-GROUP BY thread_track.utid;
-
-DROP VIEW IF EXISTS hwui_gpu_completion;
-CREATE VIEW hwui_gpu_completion AS
-SELECT
- count(*) as gpu_completion_count,
- max(dur) as gpu_completion_max,
- min(dur) as gpu_completion_min,
- avg(dur) as gpu_completion_avg,
- thread.upid as process_upid
-FROM slice
-INNER JOIN thread_track ON (thread_track.id = slice.track_id)
-INNER JOIN thread ON (thread.name='GPU completion' AND thread.utid = thread_track.utid)
-WHERE slice.name LIKE 'waiting for GPU completion%' AND slice.dur >= 0
-GROUP BY thread_track.utid;
-
-DROP VIEW IF EXISTS hwui_ui_record;
-CREATE VIEW hwui_ui_record AS
-SELECT
- count(*) as ui_record_count,
- max(dur) as ui_record_max,
- min(dur) as ui_record_min,
- avg(dur) as ui_record_avg,
- thread.upid as process_upid
-FROM slice
-INNER JOIN thread_track ON (thread_track.id = slice.track_id)
-INNER JOIN thread ON (thread.name=substr(process.name,-15) AND thread.utid = thread_track.utid)
-INNER JOIN process ON (process.upid = thread.upid)
-WHERE slice.name='Record View#draw()' AND slice.dur >= 0
-GROUP BY thread_track.utid;
-
-DROP VIEW IF EXISTS hwui_shader_compile;
-CREATE VIEW hwui_shader_compile AS
-SELECT
- count(*) as shader_compile_count,
- sum(dur) as shader_compile_time,
- avg(dur) as shader_compile_avg,
- thread_track.utid as render_thread_id
-FROM slice
-INNER JOIN thread_track ON (thread_track.id = slice.track_id)
-WHERE slice.name='shader_compile' AND slice.dur >= 0
-GROUP BY thread_track.utid;
-
-DROP VIEW IF EXISTS hwui_cache_hit;
-CREATE VIEW hwui_cache_hit AS
-SELECT
- count(*) as cache_hit_count,
- sum(dur) as cache_hit_time,
- avg(dur) as cache_hit_avg,
- thread_track.utid as render_thread_id
-FROM slice
-INNER JOIN thread_track ON (thread_track.id = slice.track_id)
-WHERE slice.name='cache_hit' AND slice.dur >= 0
-GROUP BY thread_track.utid;
-
-DROP VIEW IF EXISTS hwui_cache_miss;
-CREATE VIEW hwui_cache_miss AS
-SELECT
- count(*) as cache_miss_count,
- sum(dur) as cache_miss_time,
- avg(dur) as cache_miss_avg,
- thread_track.utid as render_thread_id
-FROM slice
-INNER JOIN thread_track ON (thread_track.id = slice.track_id)
-WHERE slice.name='cache_miss' AND slice.dur >= 0
-GROUP BY thread_track.utid;
-
-DROP VIEW IF EXISTS hwui_graphics_cpu_mem;
-CREATE VIEW hwui_graphics_cpu_mem AS
-SELECT
- max(value) as graphics_cpu_mem_max,
- min(value) as graphics_cpu_mem_min,
- avg(value) as graphics_cpu_mem_avg,
- process_counter_track.upid as process_upid
-FROM counter
-INNER JOIN process_counter_track ON (counter.track_id = process_counter_track.id)
-WHERE name='HWUI CPU Memory' AND counter.value >= 0
-GROUP BY process_counter_track.upid;
-
-DROP VIEW IF EXISTS hwui_graphics_gpu_mem;
-CREATE VIEW hwui_graphics_gpu_mem AS
-SELECT
- max(value) as graphics_gpu_mem_max,
- min(value) as graphics_gpu_mem_min,
- avg(value) as graphics_gpu_mem_avg,
- process_counter_track.upid as process_upid
-FROM counter
-INNER JOIN process_counter_track ON (counter.track_id = process_counter_track.id)
-WHERE name='HWUI Misc Memory' AND counter.value >= 0
-GROUP BY process_counter_track.upid;
-
-DROP VIEW IF EXISTS hwui_texture_mem;
-CREATE VIEW hwui_texture_mem AS
-SELECT
- max(value) as texture_mem_max,
- min(value) as texture_mem_min,
- avg(value) as texture_mem_avg,
- process_counter_track.upid as process_upid
-FROM counter
-INNER JOIN process_counter_track ON (counter.track_id = process_counter_track.id)
-WHERE name='HWUI Texture Memory' AND counter.value >= 0
-GROUP BY process_counter_track.upid;
-
-DROP VIEW IF EXISTS hwui_all_mem;
-CREATE VIEW hwui_all_mem AS
-SELECT
- max(value) as all_mem_max,
- min(value) as all_mem_min,
- avg(value) as all_mem_avg,
- process_counter_track.upid as process_upid
-FROM counter
-INNER JOIN process_counter_track ON (counter.track_id = process_counter_track.id)
-WHERE name='HWUI All Memory' AND counter.value >= 0
-GROUP BY process_counter_track.upid;
-
-DROP VIEW IF EXISTS android_hwui_metric_output;
-CREATE VIEW android_hwui_metric_output AS
-SELECT AndroidHwuiMetric(
- 'process_info', (
- SELECT RepeatedField(
- ProcessRenderInfo(
- 'process_name', process_name,
- 'rt_cpu_time_ms', rt_cpu_time_ms,
-
- 'draw_frame_count', hwui_draw_frame.draw_frame_count,
- 'draw_frame_max', hwui_draw_frame.draw_frame_max,
- 'draw_frame_min', hwui_draw_frame.draw_frame_min,
- 'draw_frame_avg', hwui_draw_frame.draw_frame_avg,
-
- 'flush_count', hwui_flush_commands.flush_count,
- 'flush_max', hwui_flush_commands.flush_max,
- 'flush_min', hwui_flush_commands.flush_min,
- 'flush_avg', hwui_flush_commands.flush_avg,
-
- 'prepare_tree_count', hwui_prepare_tree.prepare_tree_count,
- 'prepare_tree_max', hwui_prepare_tree.prepare_tree_max,
- 'prepare_tree_min', hwui_prepare_tree.prepare_tree_min,
- 'prepare_tree_avg', hwui_prepare_tree.prepare_tree_avg,
-
- 'gpu_completion_count', hwui_gpu_completion.gpu_completion_count,
- 'gpu_completion_max', hwui_gpu_completion.gpu_completion_max,
- 'gpu_completion_min', hwui_gpu_completion.gpu_completion_min,
- 'gpu_completion_avg', hwui_gpu_completion.gpu_completion_avg,
-
- 'ui_record_count', hwui_ui_record.ui_record_count,
- 'ui_record_max', hwui_ui_record.ui_record_max,
- 'ui_record_min', hwui_ui_record.ui_record_min,
- 'ui_record_avg', hwui_ui_record.ui_record_avg,
-
- 'shader_compile_count', hwui_shader_compile.shader_compile_count,
- 'shader_compile_time', hwui_shader_compile.shader_compile_time,
- 'shader_compile_avg', hwui_shader_compile.shader_compile_avg,
-
- 'cache_hit_count', hwui_cache_hit.cache_hit_count,
- 'cache_hit_time', hwui_cache_hit.cache_hit_time,
- 'cache_hit_avg', hwui_cache_hit.cache_hit_avg,
-
- 'cache_miss_count', hwui_cache_miss.cache_miss_count,
- 'cache_miss_time', hwui_cache_miss.cache_miss_time,
- 'cache_miss_avg', hwui_cache_miss.cache_miss_avg,
-
- 'graphics_cpu_mem_max', CAST(hwui_graphics_cpu_mem.graphics_cpu_mem_max as INT64),
- 'graphics_cpu_mem_min', CAST(hwui_graphics_cpu_mem.graphics_cpu_mem_min as INT64),
- 'graphics_cpu_mem_avg', hwui_graphics_cpu_mem.graphics_cpu_mem_avg,
-
- 'graphics_gpu_mem_max', CAST(hwui_graphics_gpu_mem.graphics_gpu_mem_max as INT64),
- 'graphics_gpu_mem_min', CAST(hwui_graphics_gpu_mem.graphics_gpu_mem_min as INT64),
- 'graphics_gpu_mem_avg', hwui_graphics_gpu_mem.graphics_gpu_mem_avg,
-
- 'texture_mem_max', CAST(hwui_texture_mem.texture_mem_max as INT64),
- 'texture_mem_min', CAST(hwui_texture_mem.texture_mem_min as INT64),
- 'texture_mem_avg', hwui_texture_mem.texture_mem_avg,
-
- 'all_mem_max', CAST(hwui_all_mem.all_mem_max as INT64),
- 'all_mem_min', CAST(hwui_all_mem.all_mem_min as INT64),
- 'all_mem_avg', hwui_all_mem.all_mem_avg
- )
- )
- FROM hwui_processes
- LEFT JOIN hwui_draw_frame ON (hwui_draw_frame.render_thread_id = hwui_processes.render_thread_id)
- LEFT JOIN hwui_flush_commands ON (hwui_flush_commands.render_thread_id = hwui_processes.render_thread_id)
- LEFT JOIN hwui_prepare_tree ON (hwui_prepare_tree.render_thread_id = hwui_processes.render_thread_id)
- LEFT JOIN hwui_gpu_completion ON (hwui_gpu_completion.process_upid = hwui_processes.process_upid)
- LEFT JOIN hwui_ui_record ON (hwui_ui_record.process_upid = hwui_processes.process_upid)
- LEFT JOIN hwui_shader_compile ON (hwui_shader_compile.render_thread_id = hwui_processes.render_thread_id)
- LEFT JOIN hwui_cache_hit ON (hwui_cache_hit.render_thread_id = hwui_processes.render_thread_id)
- LEFT JOIN hwui_cache_miss ON (hwui_cache_miss.render_thread_id = hwui_processes.render_thread_id)
- LEFT JOIN hwui_graphics_cpu_mem ON (hwui_graphics_cpu_mem.process_upid = hwui_processes.process_upid)
- LEFT JOIN hwui_graphics_gpu_mem ON (hwui_graphics_gpu_mem.process_upid = hwui_processes.process_upid)
- LEFT JOIN hwui_texture_mem ON (hwui_texture_mem.process_upid = hwui_processes.process_upid)
- LEFT JOIN hwui_all_mem ON (hwui_all_mem.process_upid = hwui_processes.process_upid)
- )
-);
diff --git a/src/trace_processor/metrics/android/android_hwui_threads.sql b/src/trace_processor/metrics/android/android_hwui_threads.sql
deleted file mode 100644
index 942005b8a..000000000
--- a/src/trace_processor/metrics/android/android_hwui_threads.sql
+++ /dev/null
@@ -1,122 +0,0 @@
---
--- Copyright 2019 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
-
-DROP VIEW IF EXISTS {{table_name_prefix}}_main_thread;
-CREATE VIEW {{table_name_prefix}}_main_thread AS
- SELECT
- process.name as process_name,
- thread.utid
- FROM thread
- JOIN {{process_allowlist_table}} process USING (upid)
- WHERE thread.is_main_thread;
-
-DROP VIEW IF EXISTS {{table_name_prefix}}_render_thread;
-CREATE VIEW {{table_name_prefix}}_render_thread AS
- SELECT
- process.name as process_name,
- thread.utid
- FROM thread
- JOIN {{process_allowlist_table}} process USING (upid)
- WHERE thread.name = 'RenderThread';
-
-DROP VIEW IF EXISTS {{table_name_prefix}}_gpu_completion_thread;
-CREATE VIEW {{table_name_prefix}}_gpu_completion_thread AS
- SELECT
- process.name as process_name,
- thread.utid
- FROM thread
- JOIN {{process_allowlist_table}} process USING (upid)
- WHERE thread.name = 'GPU completion';
-
-DROP VIEW IF EXISTS {{table_name_prefix}}_hwc_release_thread;
-CREATE VIEW {{table_name_prefix}}_hwc_release_thread AS
- SELECT
- process.name as process_name,
- thread.utid
- FROM thread
- JOIN {{process_allowlist_table}} process USING (upid)
- WHERE thread.name = 'HWC release';
-
-DROP TABLE IF EXISTS {{table_name_prefix}}_main_thread_slices;
-CREATE TABLE {{table_name_prefix}}_main_thread_slices AS
- SELECT
- process_name,
- thread.utid,
- slice.*,
- ts + dur AS ts_end
- FROM slice
- JOIN thread_track ON slice.track_id = thread_track.id
- JOIN {{table_name_prefix}}_main_thread thread USING (utid)
- WHERE dur > 0;
-
-DROP VIEW IF EXISTS {{table_name_prefix}}_do_frame_slices;
-CREATE VIEW {{table_name_prefix}}_do_frame_slices AS
- SELECT
- *,
- CAST(STR_SPLIT(name, ' ', 1) AS INTEGER) as vsync
- FROM {{table_name_prefix}}_main_thread_slices
- WHERE name LIKE 'Choreographer#doFrame%';
-
-DROP TABLE IF EXISTS {{table_name_prefix}}_render_thread_slices;
-CREATE TABLE {{table_name_prefix}}_render_thread_slices AS
- SELECT
- process_name,
- thread.utid,
- slice.*,
- ts + dur AS ts_end
- FROM slice
- JOIN thread_track ON slice.track_id = thread_track.id
- JOIN {{table_name_prefix}}_render_thread thread USING (utid)
- WHERE dur > 0;
-
-DROP VIEW IF EXISTS {{table_name_prefix}}_draw_frame_slices;
-CREATE VIEW {{table_name_prefix}}_draw_frame_slices AS
- SELECT
- *,
- CAST(STR_SPLIT(name, ' ', 1) AS INTEGER) as vsync
- FROM {{table_name_prefix}}_render_thread_slices
- WHERE name LIKE 'DrawFrame%';
-
-DROP VIEW IF EXISTS {{table_name_prefix}}_gpu_completion_slices;
-CREATE VIEW {{table_name_prefix}}_gpu_completion_slices AS
- SELECT
- process_name,
- thread.utid,
- slice.*,
- ts + dur AS ts_end,
- -- Extracts 1234 from 'waiting for GPU completion 1234'
- CAST(STR_SPLIT(slice.name, ' ', 4) AS INTEGER) as idx
- FROM slice
- JOIN thread_track ON slice.track_id = thread_track.id
- JOIN {{table_name_prefix}}_gpu_completion_thread thread USING (utid)
- WHERE slice.name LIKE 'waiting for GPU completion %'
- AND dur > 0;
-
-DROP VIEW IF EXISTS {{table_name_prefix}}_hwc_release_slices;
-CREATE VIEW {{table_name_prefix}}_hwc_release_slices AS
- SELECT
- process_name,
- thread.utid,
- slice.*,
- ts + dur as ts_end,
- -- Extracts 1234 from 'waiting for HWC release 1234'
- CAST(STR_SPLIT(slice.name, ' ', 4) AS INTEGER) as idx
- FROM slice
- JOIN thread_track ON slice.track_id = thread_track.id
- JOIN {{table_name_prefix}}_hwc_release_thread thread USING (utid)
- WHERE slice.name LIKE 'waiting for HWC release %'
- AND dur > 0;
diff --git a/src/trace_processor/metrics/android/android_ion.sql b/src/trace_processor/metrics/android/android_ion.sql
deleted file mode 100644
index 93fe8ac42..000000000
--- a/src/trace_processor/metrics/android/android_ion.sql
+++ /dev/null
@@ -1,94 +0,0 @@
---
--- Copyright 2019 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
-DROP VIEW IF EXISTS ion_timeline;
-CREATE VIEW ion_timeline AS
-SELECT
- ts,
- LEAD(ts, 1, (SELECT end_ts FROM trace_bounds))
- OVER(PARTITION BY track_id ORDER BY ts) - ts AS dur,
- CASE name
- WHEN 'mem.ion' THEN 'all'
- ELSE SUBSTR(name, 9)
- END AS heap_name,
- track_id,
- value
-FROM counter JOIN counter_track
- ON counter.track_id = counter_track.id
-WHERE (name LIKE 'mem.ion.%' OR name = 'mem.ion');
-
-DROP VIEW IF EXISTS ion_heap_stats;
-CREATE VIEW ion_heap_stats AS
-SELECT
- heap_name,
- SUM(value * dur) / SUM(dur) AS avg_size,
- MIN(value) AS min_size,
- MAX(value) AS max_size
-FROM ion_timeline
-GROUP BY 1;
-
-DROP VIEW IF EXISTS ion_raw_allocs;
-CREATE VIEW ion_raw_allocs AS
-SELECT
- CASE name
- WHEN 'mem.ion_change' THEN 'all'
- ELSE SUBSTR(name, 16)
- END AS heap_name,
- ts,
- value AS instant_value,
- SUM(value) OVER win AS value
-FROM counter c JOIN thread_counter_track t ON c.track_id = t.id
-WHERE (name LIKE 'mem.ion_change.%' OR name = 'mem.ion_change') AND value > 0
-WINDOW win AS (
- PARTITION BY name ORDER BY ts
- ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
-);
-
-DROP VIEW IF EXISTS ion_alloc_stats;
-CREATE VIEW ion_alloc_stats AS
-SELECT
- heap_name,
- SUM(instant_value) AS total_alloc_size_bytes
-FROM ion_raw_allocs
-GROUP BY 1;
-
--- We need to group by ts here as we can have two ion events from
--- different processes occurring at the same timestamp. We take the
--- max as this will take both allocations into account at that
--- timestamp.
-DROP VIEW IF EXISTS android_ion_event;
-CREATE VIEW android_ion_event AS
-SELECT
- 'counter' AS track_type,
- printf('ION allocations (heap: %s)', heap_name) AS track_name,
- ts,
- MAX(value) AS value
-FROM ion_raw_allocs
-GROUP BY 1, 2, 3;
-
-DROP VIEW IF EXISTS android_ion_output;
-CREATE VIEW android_ion_output AS
-SELECT AndroidIonMetric(
- 'buffer', RepeatedField(
- AndroidIonMetric_Buffer(
- 'name', heap_name,
- 'avg_size_bytes', avg_size,
- 'min_size_bytes', min_size,
- 'max_size_bytes', max_size,
- 'total_alloc_size_bytes', total_alloc_size_bytes
- )
- ))
-FROM ion_heap_stats JOIN ion_alloc_stats USING (heap_name);
diff --git a/src/trace_processor/metrics/android/android_jank.sql b/src/trace_processor/metrics/android/android_jank.sql
deleted file mode 100644
index 44f7d8157..000000000
--- a/src/trace_processor/metrics/android/android_jank.sql
+++ /dev/null
@@ -1,284 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
-
-
-DROP TABLE IF EXISTS android_jank_process_allowlist;
-CREATE TABLE android_jank_process_allowlist AS
-SELECT process.name, process.upid
-FROM process
-WHERE process.name IN (
- 'com.android.systemui',
- 'com.google.android.apps.nexuslauncher',
- 'com.google.android.inputmethod.latin'
-);
-
-SELECT RUN_METRIC(
- 'android/android_hwui_threads.sql',
- 'table_name_prefix', 'android_jank',
- 'process_allowlist_table', 'android_jank_process_allowlist');
-
-DROP TABLE IF EXISTS android_jank_thread_state_running;
-CREATE TABLE android_jank_thread_state_running AS
-SELECT utid, ts, dur, state
-FROM thread_state
-WHERE utid IN (SELECT utid FROM android_jank_main_thread_slices)
-AND state = 'Running'
-AND dur > 0;
-
-DROP TABLE IF EXISTS android_jank_thread_state_scheduled;
-CREATE TABLE android_jank_thread_state_scheduled AS
-SELECT utid, ts, dur, state
-FROM thread_state
-WHERE utid IN (SELECT utid FROM android_jank_main_thread_slices)
-AND (state = 'R' OR state = 'R+')
-AND dur > 0;
-
-DROP TABLE IF EXISTS android_jank_thread_state_io_wait;
-CREATE TABLE android_jank_thread_state_io_wait AS
-SELECT utid, ts, dur, state
-FROM thread_state
-WHERE utid IN (SELECT utid FROM android_jank_main_thread_slices)
-AND (((state = 'D' OR state = 'DK') AND io_wait) OR (state = 'DK' AND io_wait IS NULL))
-AND dur > 0;
-
---
--- Main Thread alerts
---
-
--- Expensive measure/layout
-
-DROP TABLE IF EXISTS android_jank_measure_layout_slices;
-CREATE TABLE android_jank_measure_layout_slices AS
-SELECT
- process_name,
- utid,
- id,
- ts,
- dur
-FROM android_jank_main_thread_slices
-WHERE name in ('measure', 'layout')
-AND dur >= 3000000;
-
-CREATE VIRTUAL TABLE IF NOT EXISTS android_jank_measure_layout_slices_state
-USING span_join(android_jank_measure_layout_slices PARTITIONED utid, android_jank_thread_state_running PARTITIONED utid);
-
-DROP TABLE IF EXISTS android_jank_measure_layout_slices_high_cpu;
-CREATE TABLE android_jank_measure_layout_slices_high_cpu AS
-SELECT id FROM android_jank_measure_layout_slices_state
-GROUP BY id
-HAVING SUM(dur) > 3000000;
-
-DROP TABLE IF EXISTS android_jank_measure_layout_alerts;
-CREATE TABLE android_jank_measure_layout_alerts AS
-SELECT
- process_name,
- ts,
- dur,
- 'Expensive measure/layout pass' as alert_name,
- id
-FROM android_jank_measure_layout_slices
-JOIN android_jank_measure_layout_slices_high_cpu USING (id);
-
--- Inflation during ListView recycling
--- as additional alerts for expensive layout slices
-
-DROP TABLE IF EXISTS android_jank_listview_inflation_alerts;
-CREATE TABLE android_jank_listview_inflation_alerts AS
-SELECT
- process_name,
- ts,
- dur,
- 'Inflation during ListView recycling' as alert_name
-FROM android_jank_main_thread_slices
-WHERE name IN ('obtainView', 'setupListItem')
-AND EXISTS (
- SELECT 1
- FROM descendant_slice(android_jank_main_thread_slices.id)
- WHERE name = 'inflate')
-AND EXISTS(
- SELECT 1
- FROM android_jank_measure_layout_alerts
- JOIN ancestor_slice(android_jank_main_thread_slices.id) USING (id)
-);
-
--- Long View#draw()
-
-DROP TABLE IF EXISTS android_jank_view_draw_slices;
-CREATE TABLE android_jank_view_draw_slices AS
-SELECT
- process_name,
- utid,
- id,
- ts,
- dur
-FROM android_jank_main_thread_slices
-WHERE name in ('getDisplayList', 'Record View#draw()')
-AND dur >= 3000000;
-
-CREATE VIRTUAL TABLE IF NOT EXISTS android_jank_view_draw_slices_state
-USING span_join(android_jank_view_draw_slices PARTITIONED utid, android_jank_thread_state_running PARTITIONED utid);
-
-DROP TABLE IF EXISTS android_jank_view_draw_slices_high_cpu;
-CREATE TABLE android_jank_view_draw_slices_high_cpu AS
-SELECT id FROM android_jank_view_draw_slices_state
-GROUP BY id
-HAVING SUM(dur) > 3000000;
-
-DROP TABLE IF EXISTS android_jank_view_draw_alerts;
-CREATE TABLE android_jank_view_draw_alerts AS
-SELECT
- process_name,
- ts,
- dur,
- 'Long View#draw()' as alert_name
-FROM android_jank_main_thread_slices
-JOIN android_jank_view_draw_slices_high_cpu USING (id);
-
--- Scheduling delay and Blocking I/O delay
-
-DROP TABLE IF EXISTS android_jank_long_do_frame_slices;
-CREATE TABLE android_jank_long_do_frame_slices AS
-SELECT
- process_name,
- utid,
- id,
- ts,
- dur
-FROM android_jank_main_thread_slices
-WHERE name LIKE 'Choreographer#doFrame%'
-AND dur >= 5000000;
-
-CREATE VIRTUAL TABLE IF NOT EXISTS android_jank_do_frame_slices_state_scheduled
-USING span_join(android_jank_long_do_frame_slices PARTITIONED utid, android_jank_thread_state_scheduled PARTITIONED utid);
-
-
-DROP TABLE IF EXISTS android_jank_do_frame_slices_long_scheduled;
-CREATE TABLE android_jank_do_frame_slices_long_scheduled AS
-SELECT id FROM android_jank_do_frame_slices_state_scheduled
-GROUP BY id
-HAVING SUM(dur) > 5000000;
-
-DROP TABLE IF EXISTS android_jank_scheduling_delay_alerts;
-CREATE TABLE android_jank_scheduling_delay_alerts AS
-SELECT
- process_name,
- ts,
- dur,
- 'Scheduling delay' as alert_name
-FROM android_jank_long_do_frame_slices
-JOIN android_jank_do_frame_slices_long_scheduled USING (id);
-
-CREATE VIRTUAL TABLE IF NOT EXISTS android_jank_do_frame_slices_state_io_wait
-USING span_join(android_jank_long_do_frame_slices PARTITIONED utid, android_jank_thread_state_io_wait PARTITIONED utid);
-
-DROP TABLE IF EXISTS android_jank_do_frame_slices_long_io_wait;
-CREATE TABLE android_jank_do_frame_slices_long_io_wait AS
-SELECT id FROM android_jank_do_frame_slices_state_io_wait
-GROUP BY id
-HAVING SUM(dur) > 5000000;
-
-DROP TABLE IF EXISTS android_jank_blocking_delay_alerts;
-CREATE TABLE android_jank_blocking_delay_alerts AS
-SELECT
- process_name,
- ts,
- dur,
- 'Blocking I/O delay' as alert_name
-FROM android_jank_do_frame_slices
-JOIN android_jank_do_frame_slices_long_io_wait USING (id);
-
---
--- Render Thread alerts
---
-
--- Expensive Canvas#saveLayer()
-
-DROP TABLE IF EXISTS android_jank_save_layer_alerts;
-CREATE TABLE android_jank_save_layer_alerts AS
-SELECT
- process_name,
- ts,
- dur,
- 'Expensive rendering with Canvas#saveLayer()' as alert_name
-FROM android_jank_render_thread_slices
-WHERE name LIKE '%alpha caused %saveLayer %'
-AND dur >= 1000000;
-
--- Path texture churn
-
-DROP TABLE IF EXISTS android_jank_generate_path_alerts;
-CREATE TABLE android_jank_generate_path_alerts AS
-SELECT
- process_name,
- ts,
- dur,
- 'Path texture churn' as alert_name
-FROM android_jank_render_thread_slices
-WHERE name = 'Generate Path Texture'
-AND dur >= 3000000;
-
--- Expensive Bitmap uploads
-
-DROP TABLE IF EXISTS android_jank_upload_texture_alerts;
-CREATE TABLE android_jank_upload_texture_alerts AS
-SELECT
- process_name,
- ts,
- dur,
- 'Expensive Bitmap uploads' as alert_name
-FROM android_jank_render_thread_slices
-WHERE name LIKE 'Upload %x% Texture'
-AND dur >= 3000000;
-
--- Merge all alerts tables into one table
-DROP TABLE IF EXISTS android_jank_alerts;
-CREATE TABLE android_jank_alerts AS
-SELECT process_name, ts, dur, alert_name FROM android_jank_measure_layout_alerts
-UNION ALL
-SELECT process_name, ts, dur, alert_name FROM android_jank_listview_inflation_alerts
-UNION ALL
-SELECT process_name, ts, dur, alert_name FROM android_jank_scheduling_delay_alerts
-UNION ALL
-SELECT process_name, ts, dur, alert_name FROM android_jank_blocking_delay_alerts
-UNION ALL
-SELECT process_name, ts, dur, alert_name FROM android_jank_save_layer_alerts
-UNION ALL
-SELECT process_name, ts, dur, alert_name FROM android_jank_generate_path_alerts
-UNION ALL
-SELECT process_name, ts, dur, alert_name FROM android_jank_upload_texture_alerts;
-
-DROP VIEW IF EXISTS android_jank_event;
-CREATE VIEW android_jank_event AS
-SELECT
- 'slice' as track_type,
- process_name || ' warnings' as track_name,
- ts,
- 0 as dur,
- group_concat(alert_name) as slice_name
-FROM android_jank_alerts
-GROUP BY track_type, track_name, ts;
-
-DROP VIEW IF EXISTS android_jank_output;
-CREATE VIEW android_jank_output AS
-SELECT AndroidJankMetrics(
- 'warnings', (
- SELECT RepeatedField(
- AndroidJankMetrics_Warning(
- 'ts', ts,
- 'dur', dur,
- 'process_name', process_name,
- 'warning_text', alert_name))
- FROM android_jank_alerts
- ORDER BY process_name, ts, dur));
diff --git a/src/trace_processor/metrics/android/android_lmk.sql b/src/trace_processor/metrics/android/android_lmk.sql
deleted file mode 100644
index e4f697492..000000000
--- a/src/trace_processor/metrics/android/android_lmk.sql
+++ /dev/null
@@ -1,93 +0,0 @@
---
--- Copyright 2019 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
-SELECT RUN_METRIC('android/process_oom_score.sql');
-
--- All LMK events ordered by timestamp
-DROP TABLE IF EXISTS lmk_events;
-CREATE TABLE lmk_events AS
-WITH raw_events AS (
- SELECT ref AS upid, MIN(ts) AS ts
- FROM instants
- WHERE name = 'mem.lmk' AND ref_type = 'upid'
- GROUP BY 1
-)
-SELECT
- raw_events.ts,
- raw_events.upid,
- oom_scores.oom_score_val AS score
-FROM raw_events
-LEFT JOIN oom_score_span oom_scores
- ON (raw_events.upid = oom_scores.upid AND
- raw_events.ts >= oom_scores.ts AND
- raw_events.ts < oom_scores.ts + oom_scores.dur)
-ORDER BY 1;
-
-DROP VIEW IF EXISTS android_lmk_event;
-CREATE VIEW android_lmk_event AS
-WITH raw_events AS (
- SELECT
- ts,
- LEAD(ts) OVER (ORDER BY ts) - ts AS dur,
- value AS tid
- FROM counter c
- JOIN counter_track t ON t.id = c.track_id
- WHERE t.name = 'kill_one_process'
-),
-lmks_with_proc_name AS (
- SELECT
- *,
- process.name as process_name
- FROM raw_events
- LEFT JOIN thread ON
- thread.tid = raw_events.tid AND
- raw_events.ts BETWEEN thread.start_ts AND thread.end_ts
- LEFT JOIN process USING(upid)
- WHERE raw_events.tid != 0
-)
-SELECT
- 'slice' as track_type,
- 'Low Memory Kills (LMKs)' as track_name,
- ts,
- dur,
- CASE
- WHEN process_name IS NULL THEN printf('Process %d', lmk.pid)
- ELSE printf('%s (pid: %d)', process_name, lmk.pid)
- END AS slice_name
-FROM lmks_with_proc_name as lmk;
-
-DROP VIEW IF EXISTS android_lmk_output;
-CREATE VIEW android_lmk_output AS
-WITH lmk_counts AS (
- SELECT score, COUNT(1) AS count
- FROM lmk_events
- GROUP BY score
-)
-SELECT AndroidLmkMetric(
- 'total_count', (SELECT COUNT(1) FROM lmk_events),
- 'by_oom_score', (
- SELECT
- RepeatedField(AndroidLmkMetric_ByOomScore(
- 'oom_score_adj', score,
- 'count', count
- ))
- FROM lmk_counts
- WHERE score IS NOT NULL
- ),
- 'oom_victim_count', (
- SELECT COUNT(1) FROM instants WHERE name = 'mem.oom_kill'
- )
-);
diff --git a/src/trace_processor/metrics/android/android_powrails.sql b/src/trace_processor/metrics/android/android_powrails.sql
deleted file mode 100644
index d05324af0..000000000
--- a/src/trace_processor/metrics/android/android_powrails.sql
+++ /dev/null
@@ -1,51 +0,0 @@
---
--- Copyright 2019 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
--- View of Power Rail counters with ts converted from ns to ms.
-DROP VIEW IF EXISTS power_rails_counters;
-CREATE VIEW power_rails_counters AS
-SELECT value, ts/1000000 AS ts, name
-FROM counter c
-JOIN counter_track t on c.track_id = t.id
-WHERE name LIKE 'power.%';
-
-DROP VIEW IF EXISTS power_rails_view;
-CREATE VIEW power_rails_view AS
-WITH RECURSIVE name AS (SELECT DISTINCT name FROM power_rails_counters)
-SELECT
- name,
- ts,
- AndroidPowerRails_PowerRails(
- 'name', name,
- 'energy_data', RepeatedField(
- AndroidPowerRails_EnergyData(
- 'timestamp_ms', ts,
- 'energy_uws', value
- )
- )
- ) AS power_rails_proto
-FROM power_rails_counters
-GROUP BY name
-ORDER BY ts ASC;
-
-DROP VIEW IF EXISTS android_powrails_output;
-CREATE VIEW android_powrails_output AS
-SELECT AndroidPowerRails(
- 'power_rails', (
- SELECT RepeatedField(power_rails_proto)
- FROM power_rails_view
- )
-);
diff --git a/src/trace_processor/metrics/android/android_startup.sql b/src/trace_processor/metrics/android/android_startup.sql
deleted file mode 100644
index b97a2abc3..000000000
--- a/src/trace_processor/metrics/android/android_startup.sql
+++ /dev/null
@@ -1,553 +0,0 @@
---
--- Copyright 2019 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
--- Create the base tables and views containing the launch spans.
-SELECT RUN_METRIC('android/android_startup_launches.sql');
-SELECT RUN_METRIC('android/process_metadata.sql');
-SELECT RUN_METRIC('android/hsc_startups.sql');
-
--- Create the base CPU span join table.
-SELECT RUN_METRIC('android/android_cpu_agg.sql');
-
--- Create a span join safe launches view; since both views
--- being span joined have an "id" column, we need to rename
--- the id column for launches to disambiguate the two.
-DROP VIEW IF EXISTS launches_span_join_safe;
-CREATE VIEW launches_span_join_safe AS
-SELECT ts, dur, id AS launch_id
-FROM launches;
-
--- Span join the CPU table with the launches table to get the
--- breakdown per-cpu.
-DROP TABLE IF EXISTS cpu_freq_sched_per_thread_per_launch;
-CREATE VIRTUAL TABLE cpu_freq_sched_per_thread_per_launch
-USING SPAN_JOIN(
- launches_span_join_safe,
- cpu_freq_sched_per_thread PARTITIONED cpu
-);
-
-SELECT RUN_METRIC('android/cpu_info.sql');
-
-DROP VIEW IF EXISTS mcycles_per_core_type_per_launch;
-CREATE VIEW mcycles_per_core_type_per_launch AS
-SELECT
- launch_id,
- IFNULL(core_type_per_cpu.core_type, 'unknown') AS core_type,
- CAST(SUM(dur * freq_khz / 1000) / 1e9 AS INT) AS mcycles
-FROM cpu_freq_sched_per_thread_per_launch
-LEFT JOIN core_type_per_cpu USING (cpu)
-WHERE utid != 0
-GROUP BY 1, 2;
-
--- Slices for forked processes. Never present in hot starts.
--- Prefer this over process start_ts, since the process might have
--- been preforked.
-DROP VIEW IF EXISTS zygote_fork_slice;
-CREATE VIEW zygote_fork_slice AS
-SELECT slice.ts, slice.dur, STR_SPLIT(slice.name, ": ", 1) AS process_name
-FROM slice WHERE name LIKE 'Start proc: %';
-
-DROP TABLE IF EXISTS zygote_forks_by_id;
-CREATE TABLE zygote_forks_by_id AS
-SELECT
- launches.id,
- zygote_fork_slice.ts,
- zygote_fork_slice.dur
-FROM zygote_fork_slice
-JOIN launches
-ON (launches.ts < zygote_fork_slice.ts
- AND zygote_fork_slice.ts + zygote_fork_slice.dur < launches.ts_end
- AND zygote_fork_slice.process_name = launches.package
-);
-
-DROP VIEW IF EXISTS launch_main_threads;
-CREATE VIEW launch_main_threads AS
-SELECT
- launches.ts AS ts,
- launches.dur AS dur,
- launches.id AS launch_id,
- thread.utid AS utid
-FROM launches
-JOIN launch_processes ON launches.id = launch_processes.launch_id
-JOIN process USING(upid)
-JOIN thread ON (process.upid = thread.upid AND process.pid = thread.tid)
-ORDER BY ts;
-
-DROP VIEW IF EXISTS thread_state_extended;
-CREATE VIEW thread_state_extended AS
-SELECT
- ts,
- IIF(dur = -1, (SELECT end_ts FROM trace_bounds), dur) AS dur,
- utid,
- state
-FROM thread_state;
-
-DROP TABLE IF EXISTS main_thread_state;
-CREATE VIRTUAL TABLE main_thread_state
-USING SPAN_JOIN(
- launch_main_threads PARTITIONED utid,
- thread_state_extended PARTITIONED utid);
-
-DROP VIEW IF EXISTS launch_by_thread_state;
-CREATE VIEW launch_by_thread_state AS
-SELECT launch_id, state, SUM(dur) AS dur
-FROM main_thread_state
-GROUP BY 1, 2;
-
--- Tracks all main thread process threads.
-DROP VIEW IF EXISTS launch_threads;
-CREATE VIEW launch_threads AS
-SELECT
- launches.id AS launch_id,
- launches.ts AS ts,
- launches.dur AS dur,
- thread.utid AS utid,
- thread.name AS thread_name
-FROM launches
-JOIN launch_processes ON (launches.id = launch_processes.launch_id)
-JOIN thread ON (launch_processes.upid = thread.upid);
-
--- Tracks all slices for the main process threads
-DROP VIEW IF EXISTS main_process_slice_unaggregated;
-CREATE VIEW main_process_slice_unaggregated AS
-SELECT
- launch_threads.launch_id AS launch_id,
- launch_threads.utid AS utid,
- launch_threads.thread_name AS thread_name,
- slice.name AS slice_name,
- slice.ts AS slice_ts,
- slice.dur AS slice_dur
-FROM launch_threads
-JOIN thread_track USING (utid)
-JOIN slice ON (
- slice.track_id = thread_track.id
- AND slice.ts BETWEEN launch_threads.ts AND launch_threads.ts + launch_threads.dur)
-WHERE slice.name IN (
- 'PostFork',
- 'ActivityThreadMain',
- 'bindApplication',
- 'activityStart',
- 'activityRestart',
- 'activityResume',
- 'inflate',
- 'ResourcesManager#getResources',
- 'binder transaction')
- OR slice.name LIKE 'performResume:%'
- OR slice.name LIKE 'performCreate:%'
- OR slice.name LIKE 'location=% status=% filter=% reason=%'
- OR slice.name LIKE 'OpenDexFilesFromOat%'
- OR slice.name LIKE 'VerifyClass%'
- OR slice.name LIKE 'Choreographer#doFrame%'
- OR slice.name LIKE 'JIT compiling%'
- OR slice.name LIKE '%mark sweep GC'
- OR slice.name LIKE '%concurrent copying GC'
- OR slice.name LIKE '%semispace GC';
-
-DROP TABLE IF EXISTS main_process_slice;
-CREATE TABLE main_process_slice AS
-SELECT
- launch_id,
- CASE
- WHEN slice_name LIKE 'OpenDexFilesFromOat%' THEN 'OpenDexFilesFromOat'
- WHEN slice_name LIKE 'VerifyClass%' THEN 'VerifyClass'
- WHEN slice_name LIKE 'JIT compiling%' THEN 'JIT compiling'
- WHEN slice_name LIKE '%mark sweep GC' THEN 'GC'
- WHEN slice_name LIKE '%concurrent copying GC' THEN 'GC'
- WHEN slice_name LIKE '%semispace GC' THEN 'GC'
- ELSE slice_name
- END AS name,
- AndroidStartupMetric_Slice(
- 'dur_ns', SUM(slice_dur),
- 'dur_ms', SUM(slice_dur) / 1e6
- ) AS slice_proto
-FROM main_process_slice_unaggregated
-GROUP BY 1, 2;
-
-DROP TABLE IF EXISTS report_fully_drawn_per_launch;
-CREATE TABLE report_fully_drawn_per_launch AS
-WITH report_fully_drawn_launch_slices AS (
- SELECT
- launches.id AS launch_id,
- launches.ts AS launch_ts,
- min(slice.ts) as report_fully_drawn_ts
- FROM launches
- JOIN launch_processes ON (launches.id = launch_processes.launch_id)
- JOIN thread ON (launch_processes.upid = thread.upid)
- JOIN thread_track USING (utid)
- JOIN slice ON (
- slice.track_id = thread_track.id
- AND slice.ts >= launches.ts)
- WHERE slice.name LIKE 'reportFullyDrawn%'
- GROUP BY launches.id
-)
-SELECT
- launch_id,
- report_fully_drawn_ts - launch_ts as report_fully_drawn_dur
-FROM report_fully_drawn_launch_slices;
-
-DROP VIEW IF EXISTS to_event_protos;
-CREATE VIEW to_event_protos AS
-SELECT
- slice.name as slice_name,
- launch_id,
- AndroidStartupMetric_Slice(
- 'dur_ns', slice.ts - l.ts,
- 'dur_ms', (slice.ts - l.ts) / 1e6
- ) as slice_proto
-FROM launch_main_threads l
-JOIN thread_track USING (utid)
-JOIN slice ON (
- slice.track_id = thread_track.id
- AND slice.ts BETWEEN l.ts AND l.ts + l.dur);
-
-DROP VIEW IF EXISTS gc_slices;
-CREATE VIEW gc_slices AS
- SELECT
- slice_ts AS ts,
- slice_dur AS dur,
- utid,
- launch_id
- FROM main_process_slice_unaggregated
- WHERE (
- slice_name LIKE '%mark sweep GC'
- OR slice_name LIKE '%concurrent copying GC'
- OR slice_name LIKE '%semispace GC');
-
-DROP TABLE IF EXISTS gc_slices_by_state;
-CREATE VIRTUAL TABLE gc_slices_by_state
-USING SPAN_JOIN(gc_slices PARTITIONED utid, thread_state_extended PARTITIONED utid);
-
-DROP TABLE IF EXISTS gc_slices_by_state_materialized;
-CREATE TABLE gc_slices_by_state_materialized AS
-SELECT launch_id, SUM(dur) as sum_dur
-FROM gc_slices_by_state
-WHERE state = 'Running'
-GROUP BY launch_id;
-
-DROP TABLE IF EXISTS launch_threads_cpu;
-CREATE VIRTUAL TABLE launch_threads_cpu
-USING SPAN_JOIN(launch_threads PARTITIONED utid, thread_state_extended PARTITIONED utid);
-
-DROP TABLE IF EXISTS launch_threads_cpu_materialized;
-CREATE TABLE launch_threads_cpu_materialized AS
-SELECT launch_id, SUM(dur) as sum_dur
-FROM launch_threads_cpu
-WHERE thread_name = 'Jit thread pool' AND state = 'Running'
-GROUP BY launch_id;
-
-DROP TABLE IF EXISTS activity_names_materialized;
-CREATE TABLE activity_names_materialized AS
-SELECT launch_id, slice_name, slice_ts
-FROM main_process_slice_unaggregated
-WHERE (slice_name LIKE 'performResume:%' OR slice_name LIKE 'performCreate:%');
-
-DROP TABLE IF EXISTS jit_compiled_methods_materialized;
-CREATE TABLE jit_compiled_methods_materialized AS
-SELECT
- launch_id,
- COUNT(1) as count
-FROM main_process_slice_unaggregated
-WHERE
- slice_name LIKE 'JIT compiling%'
- AND thread_name = 'Jit thread pool'
-GROUP BY launch_id;
-
-DROP TABLE IF EXISTS long_binder_transactions;
-CREATE TABLE long_binder_transactions AS
-SELECT
- launch_id, slice_dur, thread_name
-FROM
- main_process_slice_unaggregated
-WHERE
- slice_name = 'binder transaction'
- AND slice_dur >= 1e8;
-
-DROP VIEW IF EXISTS startup_view;
-CREATE VIEW startup_view AS
-SELECT
- AndroidStartupMetric_Startup(
- 'startup_id', launches.id,
- 'package_name', launches.package,
- 'process_name', (
- SELECT p.name
- FROM launch_processes lp
- JOIN process p USING (upid)
- WHERE lp.launch_id = launches.id
- LIMIT 1
- ),
- 'process', (
- SELECT m.metadata
- FROM process_metadata m
- JOIN launch_processes p USING (upid)
- WHERE p.launch_id = launches.id
- LIMIT 1
- ),
- 'activities', (
- SELECT RepeatedField(AndroidStartupMetric_Activity(
- 'name', (SELECT STR_SPLIT(s.slice_name, ':', 1)),
- 'method', (SELECT STR_SPLIT(s.slice_name, ':', 0)),
- 'ts_method_start', s.slice_ts
- ))
- FROM activity_names_materialized s
- WHERE s.launch_id = launches.id
- ),
- 'long_binder_transactions', (
- SELECT RepeatedField(AndroidStartupMetric_BinderTransaction(
- 'duration', AndroidStartupMetric_Slice(
- 'dur_ns', lbt.slice_dur,
- 'dur_ms', lbt.slice_dur / 1e6
- ),
- 'thread', lbt.thread_name
- ))
- FROM long_binder_transactions lbt
- WHERE lbt.launch_id = launches.id
- ),
- 'zygote_new_process', EXISTS(SELECT TRUE FROM zygote_forks_by_id WHERE id = launches.id),
- 'activity_hosting_process_count', (
- SELECT COUNT(1) FROM launch_processes p
- WHERE p.launch_id = launches.id
- ),
- 'event_timestamps', AndroidStartupMetric_EventTimestamps(
- 'intent_received', launches.ts,
- 'first_frame', launches.ts_end
- ),
- 'to_first_frame', AndroidStartupMetric_ToFirstFrame(
- 'dur_ns', launches.dur,
- 'dur_ms', launches.dur / 1e6,
- 'main_thread_by_task_state', AndroidStartupMetric_TaskStateBreakdown(
- 'running_dur_ns', IFNULL(
- (
- SELECT dur FROM launch_by_thread_state l
- WHERE l.launch_id = launches.id AND state = 'Running'
- ), 0),
- 'runnable_dur_ns', IFNULL(
- (
- SELECT dur FROM launch_by_thread_state l
- WHERE l.launch_id = launches.id AND state = 'R'
- ), 0),
- 'uninterruptible_sleep_dur_ns', IFNULL(
- (
- SELECT dur FROM launch_by_thread_state l
- WHERE l.launch_id = launches.id AND (state = 'D' or state = 'DK')
- ), 0),
- 'interruptible_sleep_dur_ns', IFNULL(
- (
- SELECT dur FROM launch_by_thread_state l
- WHERE l.launch_id = launches.id AND state = 'S'
- ), 0)
- ),
- 'mcycles_by_core_type', AndroidStartupMetric_McyclesByCoreType(
- 'little', (
- SELECT mcycles
- FROM mcycles_per_core_type_per_launch m
- WHERE m.launch_id = launches.id AND m.core_type = 'little'
- ),
- 'big', (
- SELECT mcycles
- FROM mcycles_per_core_type_per_launch m
- WHERE m.launch_id = launches.id AND m.core_type = 'big'
- ),
- 'bigger', (
- SELECT mcycles
- FROM mcycles_per_core_type_per_launch m
- WHERE m.launch_id = launches.id AND m.core_type = 'bigger'
- ),
- 'unknown', (
- SELECT mcycles
- FROM mcycles_per_core_type_per_launch m
- WHERE m.launch_id = launches.id AND m.core_type = 'unknown'
- )
- ),
- 'to_post_fork', (
- SELECT slice_proto
- FROM to_event_protos p
- WHERE p.launch_id = launches.id AND slice_name = 'PostFork'
- ),
- 'to_activity_thread_main', (
- SELECT slice_proto
- FROM to_event_protos p
- WHERE p.launch_id = launches.id AND slice_name = 'ActivityThreadMain'
- ),
- 'to_bind_application', (
- SELECT slice_proto
- FROM to_event_protos p
- WHERE p.launch_id = launches.id AND slice_name = 'bindApplication'
- ),
- 'other_processes_spawned_count', (
- SELECT COUNT(1) FROM process
- WHERE (process.name IS NULL OR process.name != launches.package)
- AND process.start_ts BETWEEN launches.ts AND launches.ts + launches.dur
- ),
- 'time_activity_manager', (
- SELECT AndroidStartupMetric_Slice(
- 'dur_ns', l.ts - launches.ts,
- 'dur_ms', (l.ts - launches.ts) / 1e6
- )
- FROM launching_events l
- WHERE l.ts BETWEEN launches.ts AND launches.ts + launches.dur
- ),
- 'time_post_fork', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name = 'PostFork'
- ),
- 'time_activity_thread_main', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name = 'ActivityThreadMain'
- ),
- 'time_bind_application', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name = 'bindApplication'
- ),
- 'time_activity_start', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name = 'activityStart'
- ),
- 'time_activity_resume', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name = 'activityResume'
- ),
- 'time_activity_restart', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name = 'activityRestart'
- ),
- 'time_choreographer', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name LIKE 'Choreographer#doFrame%'
- ),
- 'time_before_start_process', (
- SELECT AndroidStartupMetric_Slice(
- 'dur_ns', ts - launches.ts,
- 'dur_ms', (ts - launches.ts) / 1e6
- )
- FROM zygote_forks_by_id z
- WHERE z.id = launches.id
- ),
- 'time_during_start_process', (
- SELECT AndroidStartupMetric_Slice(
- 'dur_ns', dur,
- 'dur_ms', dur / 1e6
- )
- FROM zygote_forks_by_id z
- WHERE z.id = launches.id
- ),
- 'time_inflate', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name = 'inflate'
- ),
- 'time_get_resources', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id
- AND name = 'ResourcesManager#getResources'
- ),
- 'time_dex_open', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name = 'OpenDexFilesFromOat'
- ),
- 'time_verify_class', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name = 'VerifyClass'
- ),
- 'jit_compiled_methods', (
- SELECT count
- FROM jit_compiled_methods_materialized s
- WHERE s.launch_id = launches.id
- ),
- 'time_jit_thread_pool_on_cpu', (
- SELECT
- NULL_IF_EMPTY(AndroidStartupMetric_Slice(
- 'dur_ns', sum_dur,
- 'dur_ms', sum_dur / 1e6
- ))
- FROM launch_threads_cpu_materialized
- WHERE launch_id = launches.id
- ),
- 'time_gc_total', (
- SELECT slice_proto
- FROM main_process_slice s
- WHERE s.launch_id = launches.id AND name = 'GC'
- ),
- 'time_gc_on_cpu', (
- SELECT
- NULL_IF_EMPTY(AndroidStartupMetric_Slice(
- 'dur_ns', sum_dur,
- 'dur_ms', sum_dur / 1e6
- ))
- FROM gc_slices_by_state_materialized
- WHERE launch_id = launches.id
- )
- ),
- 'hsc', (
- SELECT NULL_IF_EMPTY(AndroidStartupMetric_HscMetrics(
- 'full_startup', (
- SELECT AndroidStartupMetric_Slice(
- 'dur_ns', h.ts_total,
- 'dur_ms', h.ts_total / 1e6
- )
- FROM hsc_based_startup_times h
- WHERE h.id = launches.id
- )
- ))
- ),
- 'report_fully_drawn', (
- SELECT NULL_IF_EMPTY(AndroidStartupMetric_Slice(
- 'dur_ns', report_fully_drawn_dur,
- 'dur_ms', report_fully_drawn_dur / 1e6
- ))
- FROM report_fully_drawn_per_launch r
- WHERE r.launch_id = launches.id
- ),
- 'optimization_status',(
- SELECT RepeatedField(AndroidStartupMetric_OptimizationStatus(
- 'location', SUBSTR(STR_SPLIT(name, ' status=', 0), LENGTH('location=') + 1),
- 'odex_status', STR_SPLIT(STR_SPLIT(name, ' status=', 1), ' filter=', 0),
- 'compilation_filter', STR_SPLIT(STR_SPLIT(name, ' filter=', 1), ' reason=', 0),
- 'compilation_reason', STR_SPLIT(name, ' reason=', 1)
- ))
- FROM main_process_slice s
- WHERE name LIKE 'location=% status=% filter=% reason=%'
- )
- ) as startup
-FROM launches;
-
-DROP VIEW IF EXISTS android_startup_event;
-CREATE VIEW android_startup_event AS
-SELECT
- 'slice' as track_type,
- 'Android App Startups' as track_name,
- l.ts as ts,
- l.dur as dur,
- l.package as slice_name
-FROM launches l;
-
-DROP VIEW IF EXISTS android_startup_output;
-CREATE VIEW android_startup_output AS
-SELECT
- AndroidStartupMetric(
- 'startup', (
- SELECT RepeatedField(startup) FROM startup_view
- )
- );
diff --git a/src/trace_processor/metrics/android/android_startup_launches.sql b/src/trace_processor/metrics/android/android_startup_launches.sql
deleted file mode 100644
index 2cfb4b999..000000000
--- a/src/trace_processor/metrics/android/android_startup_launches.sql
+++ /dev/null
@@ -1,115 +0,0 @@
---
--- Copyright 2019 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
--- The start of the launching event corresponds to the end of the AM handling
--- the startActivity intent, whereas the end corresponds to the first frame drawn.
--- Only successful app launches have a launching event.
-DROP TABLE IF EXISTS launching_events;
-CREATE TABLE launching_events AS
-SELECT
- ts,
- dur,
- ts + dur AS ts_end,
- STR_SPLIT(s.name, ": ", 1) AS package_name
-FROM slice s
-JOIN process_track t ON s.track_id = t.id
-JOIN process USING(upid)
-WHERE s.name LIKE 'launching: %'
-AND (process.name IS NULL OR process.name = 'system_server');
-
--- Marks the beginning of the trace and is equivalent to when the statsd launch
--- logging begins.
-DROP VIEW IF EXISTS activity_intent_received;
-CREATE VIEW activity_intent_received AS
-SELECT ts FROM slice
-WHERE name = 'MetricsLogger:launchObserverNotifyIntentStarted';
-
--- Successful activity launch. The end of the 'launching' event is not related
--- to whether it actually succeeded or not.
-DROP VIEW IF EXISTS activity_intent_launch_successful;
-CREATE VIEW activity_intent_launch_successful AS
-SELECT ts FROM slice
-WHERE name = 'MetricsLogger:launchObserverNotifyActivityLaunchFinished';
-
--- We partition the trace into spans based on posted activity intents.
--- We will refine these progressively in the next steps to only encompass
--- activity starts.
-DROP TABLE IF EXISTS activity_intent_recv_spans;
-CREATE TABLE activity_intent_recv_spans(id INT, ts BIG INT, dur BIG INT);
-
-INSERT INTO activity_intent_recv_spans
-SELECT
- ROW_NUMBER()
- OVER(ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS id,
- ts,
- LEAD(ts, 1, (SELECT end_ts FROM trace_bounds)) OVER(ORDER BY ts) - ts AS dur
-FROM activity_intent_received
-ORDER BY ts;
-
--- Filter activity_intent_recv_spans, keeping only the ones that triggered
--- a launch.
-DROP VIEW IF EXISTS launch_partitions;
-CREATE VIEW launch_partitions AS
-SELECT * FROM activity_intent_recv_spans AS spans
-WHERE 1 = (
- SELECT COUNT(1)
- FROM launching_events
- WHERE launching_events.ts BETWEEN spans.ts AND spans.ts + spans.dur);
-
--- All activity launches in the trace, keyed by ID.
-DROP TABLE IF EXISTS launches;
-CREATE TABLE launches(
- ts BIG INT,
- ts_end BIG INT,
- dur BIG INT,
- id INT,
- package STRING);
-
--- Use the starting event package name. The finish event package name
--- is not reliable in the case of failed launches.
-INSERT INTO launches
-SELECT
- lpart.ts AS ts,
- launching_events.ts_end AS ts_end,
- launching_events.ts_end - lpart.ts AS dur,
- lpart.id AS id,
- package_name AS package
-FROM launch_partitions AS lpart
-JOIN launching_events ON
- (launching_events.ts BETWEEN lpart.ts AND lpart.ts + lpart.dur) AND
- (launching_events.ts_end BETWEEN lpart.ts AND lpart.ts + lpart.dur)
-WHERE (
- SELECT COUNT(1)
- FROM activity_intent_launch_successful AS successful
- WHERE successful.ts BETWEEN lpart.ts AND lpart.ts + lpart.dur
-) > 0;
-
--- Maps a launch to the corresponding set of processes that handled the
--- activity start. The vast majority of cases should be a single process.
--- However it is possible that the process dies during the activity launch
--- and is respawned.
-DROP TABLE IF EXISTS launch_processes;
-CREATE TABLE launch_processes(launch_id INT, upid BIG INT);
-
--- We make the (not always correct) simplification that process == package
-INSERT INTO launch_processes
-SELECT launches.id, process.upid
-FROM launches
- JOIN process ON launches.package = process.name
- JOIN thread ON (process.upid = thread.upid AND process.pid = thread.tid)
-WHERE (process.start_ts IS NULL OR process.start_ts < launches.ts_end)
-AND (thread.end_ts IS NULL OR thread.end_ts > launches.ts_end)
-ORDER BY process.start_ts DESC;
diff --git a/src/trace_processor/metrics/android/android_surfaceflinger.sql b/src/trace_processor/metrics/android/android_surfaceflinger.sql
deleted file mode 100644
index b0d761f62..000000000
--- a/src/trace_processor/metrics/android/android_surfaceflinger.sql
+++ /dev/null
@@ -1,53 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
-
-SELECT RUN_METRIC(
- 'android/frame_missed.sql',
- 'track_name', 'PrevFrameMissed',
- 'output', 'frame_missed'
-);
-SELECT RUN_METRIC(
- 'android/frame_missed.sql',
- 'track_name', 'PrevHwcFrameMissed',
- 'output', 'hwc_frame_missed'
-);
-SELECT RUN_METRIC(
- 'android/frame_missed.sql',
- 'track_name', 'PrevGpuFrameMissed',
- 'output', 'gpu_frame_missed'
-);
-
-DROP VIEW IF EXISTS android_surfaceflinger_event;
-CREATE VIEW android_surfaceflinger_event AS
-SELECT
- 'slice' AS track_type,
- 'Android Missed Frames' AS track_name,
- ts,
- dur,
- 'Frame missed' AS slice_name
-FROM frame_missed
-WHERE value = 1 AND ts IS NOT NULL;
-
-DROP VIEW IF EXISTS android_surfaceflinger_output;
-CREATE VIEW android_surfaceflinger_output AS
-SELECT
- AndroidSurfaceflingerMetric(
- 'missed_frames', (SELECT COUNT(1) FROM frame_missed WHERE value=1),
- 'missed_hwc_frames', (SELECT COUNT(1) FROM hwc_frame_missed WHERE value=1),
- 'missed_gpu_frames', (SELECT COUNT(1) FROM gpu_frame_missed WHERE value=1),
- 'missed_frame_rate', (SELECT AVG(value) FROM frame_missed),
- 'missed_hwc_frame_rate', (SELECT AVG(value) FROM hwc_frame_missed),
- 'missed_gpu_frame_rate', (SELECT AVG(value) FROM gpu_frame_missed)
- );
diff --git a/src/trace_processor/metrics/android/android_sysui_cuj.sql b/src/trace_processor/metrics/android/android_sysui_cuj.sql
deleted file mode 100644
index 2a0bba1d4..000000000
--- a/src/trace_processor/metrics/android/android_sysui_cuj.sql
+++ /dev/null
@@ -1,439 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
-
-SELECT RUN_METRIC('android/process_metadata.sql');
-
-DROP TABLE IF EXISTS android_sysui_cuj_last_cuj;
-CREATE TABLE android_sysui_cuj_last_cuj AS
- SELECT
- process.name AS name,
- process.upid AS upid,
- process_metadata.metadata AS process_metadata,
- SUBSTR(slice.name, 3, LENGTH(slice.name) - 3) AS cuj_name,
- ts AS ts_start,
- ts + dur AS ts_end,
- dur AS dur
- FROM slice
- JOIN process_track ON slice.track_id = process_track.id
- JOIN process USING (upid)
- JOIN process_metadata USING (upid)
- WHERE
- slice.name LIKE 'J<%>'
- AND slice.dur > 0
- AND (
- process.name LIKE 'com.google.android%'
- OR process.name = 'com.android.systemui')
- ORDER BY ts desc
- LIMIT 1;
-
-SELECT RUN_METRIC(
- 'android/android_hwui_threads.sql',
- 'table_name_prefix', 'android_sysui_cuj',
- 'process_allowlist_table', 'android_sysui_cuj_last_cuj');
-
-DROP VIEW IF EXISTS android_sysui_cuj_thread;
-CREATE VIEW android_sysui_cuj_thread AS
-SELECT
- process.name as process_name,
- thread.utid,
- thread.name
-FROM thread
-JOIN android_sysui_cuj_last_cuj process USING (upid);
-
-DROP VIEW IF EXISTS android_sysui_cuj_slices_in_cuj;
-CREATE VIEW android_sysui_cuj_slices_in_cuj AS
-SELECT
- process_name,
- thread.utid,
- thread.name as thread_name,
- slice.*,
- ts + slice.dur AS ts_end
-FROM slice
-JOIN thread_track ON slice.track_id = thread_track.id
-JOIN android_sysui_cuj_thread thread USING (utid)
-JOIN android_sysui_cuj_last_cuj last_cuj
-ON ts >= last_cuj.ts_start AND ts <= last_cuj.ts_end
-WHERE slice.dur > 0;
-
-DROP TABLE IF EXISTS android_sysui_cuj_main_thread_slices_in_cuj;
-CREATE TABLE android_sysui_cuj_main_thread_slices_in_cuj AS
-SELECT slices.* FROM android_sysui_cuj_main_thread_slices slices
-JOIN android_sysui_cuj_last_cuj last_cuj
-ON ts >= last_cuj.ts_start AND ts <= last_cuj.ts_end;
-
-DROP TABLE IF EXISTS android_sysui_cuj_do_frame_slices_in_cuj;
-CREATE TABLE android_sysui_cuj_do_frame_slices_in_cuj AS
-SELECT slices.* FROM android_sysui_cuj_do_frame_slices slices
-JOIN android_sysui_cuj_last_cuj last_cuj
-ON ts >= last_cuj.ts_start AND ts <= last_cuj.ts_end;
-
-DROP TABLE IF EXISTS android_sysui_cuj_render_thread_slices_in_cuj;
-CREATE TABLE android_sysui_cuj_render_thread_slices_in_cuj AS
-SELECT slices.* FROM android_sysui_cuj_render_thread_slices slices
-JOIN android_sysui_cuj_last_cuj last_cuj
-ON ts >= last_cuj.ts_start AND ts <= last_cuj.ts_end;
-
-DROP TABLE IF EXISTS android_sysui_cuj_draw_frame_slices_in_cuj;
-CREATE TABLE android_sysui_cuj_draw_frame_slices_in_cuj AS
-SELECT slices.* FROM android_sysui_cuj_draw_frame_slices slices
-JOIN android_sysui_cuj_last_cuj last_cuj
-ON ts >= last_cuj.ts_start AND ts <= last_cuj.ts_end;
-
-DROP TABLE IF EXISTS android_sysui_cuj_hwc_release_slices_in_cuj;
-CREATE TABLE android_sysui_cuj_hwc_release_slices_in_cuj AS
-SELECT slices.* FROM android_sysui_cuj_hwc_release_slices slices
-JOIN android_sysui_cuj_last_cuj last_cuj
-ON ts >= last_cuj.ts_start AND ts <= last_cuj.ts_end;
-
-DROP TABLE IF EXISTS android_sysui_cuj_gpu_completion_slices_in_cuj;
-CREATE TABLE android_sysui_cuj_gpu_completion_slices_in_cuj AS
-SELECT slices.* FROM android_sysui_cuj_gpu_completion_slices slices
-JOIN android_sysui_cuj_last_cuj last_cuj
-ON ts >= last_cuj.ts_start AND ts <= last_cuj.ts_end;
-
-DROP TABLE IF EXISTS android_sysui_cuj_jit_slices;
-CREATE TABLE android_sysui_cuj_jit_slices AS
-SELECT *
-FROM android_sysui_cuj_slices_in_cuj
-WHERE thread_name LIKE 'Jit thread pool%'
-AND name LIKE 'JIT compiling%'
-AND parent_id IS NULL;
-
-DROP TABLE IF EXISTS android_sysui_cuj_frame_timeline_events;
-CREATE TABLE android_sysui_cuj_frame_timeline_events AS
- SELECT
- expected.ts as ts_expected,
- expected.dur as dur_expected,
- expected.layer_name as layer_name,
- actual.name as vsync,
- actual.ts as ts_actual,
- actual.dur as dur_actual,
- actual.jank_type LIKE '%App Deadline Missed%' as app_missed,
- actual.jank_type,
- actual.on_time_finish
- FROM expected_frame_timeline_slice expected
- JOIN android_sysui_cuj_last_cuj cuj
- ON expected.upid = cuj.upid
- AND expected.ts + expected.dur > cuj.ts_start
- AND expected.ts < cuj.ts_end
- JOIN actual_frame_timeline_slice actual
- ON expected.surface_frame_token = actual.surface_frame_token
- AND expected.upid = actual.upid
- AND expected.layer_name = actual.layer_name;
-
-DROP TABLE IF EXISTS android_sysui_cuj_frames;
-CREATE TABLE android_sysui_cuj_frames AS
- WITH gcs_to_rt_match AS (
- -- Match GPU Completion with the last RT slice before it
- SELECT
- gcs.ts as gcs_ts,
- gcs.ts_end as gcs_ts_end,
- gcs.dur as gcs_dur,
- gcs.idx as idx,
- MAX(rts.ts) as rts_ts
- FROM android_sysui_cuj_gpu_completion_slices_in_cuj gcs
- JOIN android_sysui_cuj_render_thread_slices_in_cuj rts ON rts.ts < gcs.ts
- -- dispatchFrameCallbacks might be seen in case of
- -- drawing that happens on RT only (e.g. ripple effect)
- WHERE (rts.name LIKE 'DrawFrame%' OR rts.name = 'dispatchFrameCallbacks')
- GROUP BY gcs.ts, gcs.ts_end, gcs.dur, gcs.idx
- ),
- frame_boundaries AS (
- -- Match main thread doFrame with RT DrawFrame and optional GPU Completion
- SELECT
- mts.ts as mts_ts,
- mts.ts_end as mts_ts_end,
- mts.dur as mts_dur,
- mts.vsync as vsync,
- MAX(gcs_rt.gcs_ts) as gcs_ts_start,
- MAX(gcs_rt.gcs_ts_end) as gcs_ts_end
- FROM android_sysui_cuj_do_frame_slices_in_cuj mts
- JOIN android_sysui_cuj_draw_frame_slices_in_cuj rts
- ON mts.vsync = rts.vsync
- LEFT JOIN gcs_to_rt_match gcs_rt ON gcs_rt.rts_ts = rts.ts
- GROUP BY mts.ts, mts.ts_end, mts.dur
- )
- SELECT
- ROW_NUMBER() OVER (ORDER BY f.mts_ts) AS frame_number,
- f.vsync as vsync,
- f.mts_ts as ts_main_thread_start,
- f.mts_ts_end as ts_main_thread_end,
- f.mts_dur AS dur_main_thread,
- MIN(rts.ts) AS ts_render_thread_start,
- MAX(rts.ts_end) AS ts_render_thread_end,
- SUM(rts.dur) AS dur_render_thread,
- MAX(gcs_rt.gcs_ts_end) AS ts_frame_end,
- MAX(gcs_rt.gcs_ts_end) - f.mts_ts AS dur_frame,
- SUM(gcs_rt.gcs_ts_end - MAX(COALESCE(hwc.ts_end, 0), gcs_rt.gcs_ts)) as dur_gcs,
- COUNT(DISTINCT(rts.ts)) as draw_frames,
- COUNT(DISTINCT(gcs_rt.gcs_ts)) as gpu_completions
- FROM frame_boundaries f
- JOIN android_sysui_cuj_draw_frame_slices_in_cuj rts
- ON f.vsync = rts.vsync
- LEFT JOIN gcs_to_rt_match gcs_rt
- ON rts.ts = gcs_rt.rts_ts
- LEFT JOIN android_sysui_cuj_hwc_release_slices_in_cuj hwc USING (idx)
- GROUP BY f.mts_ts
- HAVING gpu_completions >= 1;
-
-DROP TABLE IF EXISTS android_sysui_cuj_missed_frames;
-CREATE TABLE android_sysui_cuj_missed_frames AS
- SELECT
- f.*,
- (SELECT MAX(fte.app_missed)
- FROM android_sysui_cuj_frame_timeline_events fte
- WHERE f.vsync = fte.vsync
- AND fte.on_time_finish = 0) as app_missed
- FROM android_sysui_cuj_frames f;
-
-DROP VIEW IF EXISTS android_sysui_cuj_frame_main_thread_bounds;
-CREATE VIEW android_sysui_cuj_frame_main_thread_bounds AS
-SELECT frame_number, ts_main_thread_start as ts, dur_main_thread as dur
-FROM android_sysui_cuj_missed_frames
-WHERE app_missed;
-
-DROP VIEW IF EXISTS android_sysui_cuj_main_thread_state_data;
-CREATE VIEW android_sysui_cuj_main_thread_state_data AS
-SELECT * FROM thread_state
-WHERE utid = (SELECT utid FROM android_sysui_cuj_main_thread);
-
-DROP TABLE IF EXISTS android_sysui_cuj_main_thread_state_vt;
-CREATE VIRTUAL TABLE android_sysui_cuj_main_thread_state_vt
-USING span_left_join(android_sysui_cuj_frame_main_thread_bounds, android_sysui_cuj_main_thread_state_data PARTITIONED utid);
-
-DROP TABLE IF EXISTS android_sysui_cuj_main_thread_state;
-CREATE TABLE android_sysui_cuj_main_thread_state AS
- SELECT
- frame_number,
- state,
- io_wait AS io_wait,
- SUM(dur) AS dur
- FROM android_sysui_cuj_main_thread_state_vt
- GROUP BY frame_number, state, io_wait
- HAVING dur > 0;
-
-DROP VIEW IF EXISTS android_sysui_cuj_frame_render_thread_bounds;
-CREATE VIEW android_sysui_cuj_frame_render_thread_bounds AS
-SELECT frame_number, ts_render_thread_start as ts, dur_render_thread as dur
-FROM android_sysui_cuj_missed_frames
-WHERE app_missed;
-
-DROP VIEW IF EXISTS android_sysui_cuj_render_thread_state_data;
-CREATE VIEW android_sysui_cuj_render_thread_state_data AS
-SELECT * FROM thread_state
-WHERE utid in (SELECT utid FROM android_sysui_cuj_render_thread);
-
-DROP TABLE IF EXISTS android_sysui_cuj_render_thread_state_vt;
-CREATE VIRTUAL TABLE android_sysui_cuj_render_thread_state_vt
-USING span_left_join(android_sysui_cuj_frame_render_thread_bounds, android_sysui_cuj_render_thread_state_data PARTITIONED utid);
-
-DROP TABLE IF EXISTS android_sysui_cuj_render_thread_state;
-CREATE TABLE android_sysui_cuj_render_thread_state AS
- SELECT
- frame_number,
- state,
- io_wait AS io_wait,
- SUM(dur) AS dur
- FROM android_sysui_cuj_render_thread_state_vt
- GROUP BY frame_number, state, io_wait
- HAVING dur > 0;
-
-DROP TABLE IF EXISTS android_sysui_cuj_main_thread_binder;
-CREATE TABLE android_sysui_cuj_main_thread_binder AS
- SELECT
- f.frame_number,
- SUM(mts.dur) AS dur,
- COUNT(*) AS call_count
- FROM android_sysui_cuj_missed_frames f
- JOIN android_sysui_cuj_main_thread_slices_in_cuj mts
- ON mts.ts >= f.ts_main_thread_start AND mts.ts < f.ts_main_thread_end
- WHERE mts.name = 'binder transaction'
- AND f.app_missed
- GROUP BY f.frame_number;
-
-DROP TABLE IF EXISTS android_sysui_cuj_sf_jank_causes;
-CREATE TABLE android_sysui_cuj_sf_jank_causes AS
- WITH RECURSIVE split_jank_type(frame_number, jank_cause, remainder) AS (
- SELECT f.frame_number, "", fte.jank_type || ","
- FROM android_sysui_cuj_frames f
- JOIN android_sysui_cuj_frame_timeline_events fte ON f.vsync = fte.vsync
- UNION ALL SELECT
- frame_number,
- STR_SPLIT(remainder, ",", 0) AS jank_cause,
- TRIM(SUBSTR(remainder, INSTR(remainder, ",") + 1)) AS remainder
- FROM split_jank_type
- WHERE remainder <> "")
- SELECT frame_number, jank_cause
- FROM split_jank_type
- WHERE jank_cause NOT IN ('', 'App Deadline Missed', 'None', 'Buffer Stuffing')
- ORDER BY frame_number ASC;
-
-DROP TABLE IF EXISTS android_sysui_cuj_missed_frames_hwui_times;
-CREATE TABLE android_sysui_cuj_missed_frames_hwui_times AS
-SELECT
- *,
- ts_main_thread_start AS ts,
- ts_render_thread_end - ts_main_thread_start AS dur
-FROM android_sysui_cuj_missed_frames;
-
-DROP TABLE IF EXISTS android_sysui_cuj_jit_slices_join_table;
-CREATE VIRTUAL TABLE android_sysui_cuj_jit_slices_join_table
-USING span_join(android_sysui_cuj_missed_frames_hwui_times partitioned frame_number, android_sysui_cuj_jit_slices);
-
-DROP TABLE IF EXISTS android_sysui_cuj_jank_causes;
-CREATE TABLE android_sysui_cuj_jank_causes AS
- SELECT
- frame_number,
- 'RenderThread - long shader_compile' AS jank_cause
- FROM android_sysui_cuj_missed_frames f
- JOIN android_sysui_cuj_render_thread_slices_in_cuj rts
- ON rts.ts >= f.ts_render_thread_start AND rts.ts < f.ts_render_thread_end
- WHERE rts.name = 'shader_compile'
- AND f.app_missed
- AND rts.dur > 8000000
-
- UNION ALL
- SELECT
- frame_number,
- 'RenderThread - long flush layers' AS jank_cause
- FROM android_sysui_cuj_missed_frames f
- JOIN android_sysui_cuj_render_thread_slices_in_cuj rts
- ON rts.ts >= f.ts_render_thread_start AND rts.ts < f.ts_render_thread_end
- WHERE rts.name = 'flush layers'
- AND rts.dur > 8000000
- AND f.app_missed
-
- UNION ALL
- SELECT
- frame_number,
- 'MainThread - IO wait time' AS jank_cause
- FROM android_sysui_cuj_main_thread_state
- WHERE
- ((state = 'D' OR state = 'DK') AND io_wait)
- OR (state = 'DK' AND io_wait IS NULL)
- GROUP BY frame_number
- HAVING SUM(dur) > 8000000
-
- UNION ALL
- SELECT
- frame_number,
- 'MainThread - scheduler' AS jank_cause
- FROM android_sysui_cuj_main_thread_state
- WHERE (state = 'R' OR state = 'R+')
- GROUP BY frame_number
- HAVING SUM(dur) > 8000000
-
- UNION ALL
- SELECT
- frame_number,
- 'RenderThread - IO wait time' AS jank_cause
- FROM android_sysui_cuj_render_thread_state
- WHERE
- ((state = 'D' OR state = 'DK') AND io_wait)
- OR (state = 'DK' AND io_wait IS NULL)
- GROUP BY frame_number
- HAVING SUM(dur) > 8000000
-
- UNION ALL
- SELECT
- frame_number,
- 'RenderThread - scheduler' AS jank_cause
- FROM android_sysui_cuj_render_thread_state
- WHERE (state = 'R' OR state = 'R+')
- GROUP BY frame_number
- HAVING SUM(dur) > 8000000
-
- UNION ALL
- SELECT
- frame_number,
- 'MainThread - binder transaction time' AS jank_cause
- FROM android_sysui_cuj_main_thread_binder
- WHERE dur > 8000000
-
- UNION ALL
- SELECT
- frame_number,
- 'MainThread - binder calls count' AS jank_cause
- FROM android_sysui_cuj_main_thread_binder
- WHERE call_count > 8
-
- UNION ALL
- SELECT
- frame_number,
- 'GPU completion - long completion time' AS jank_cause
- FROM android_sysui_cuj_missed_frames f
- WHERE dur_gcs > 8000000
- AND app_missed
-
- UNION ALL
- SELECT
- frame_number,
- 'Long running time' as jank_cause
- FROM android_sysui_cuj_main_thread_state mts
- JOIN android_sysui_cuj_render_thread_state rts USING(frame_number)
- WHERE
- mts.state = 'Running'
- AND rts.state = 'Running'
- AND mts.dur + rts.dur > 15000000
-
- UNION ALL
- SELECT
- f.frame_number,
- 'JIT compiling' as jank_cause
- FROM android_sysui_cuj_missed_frames f
- JOIN android_sysui_cuj_jit_slices_join_table jit USING (frame_number)
- WHERE f.app_missed
- GROUP BY f.frame_number
- HAVING SUM(jit.dur) > 8000000
-
- UNION ALL
- SELECT frame_number, jank_cause FROM android_sysui_cuj_sf_jank_causes
- GROUP BY frame_number, jank_cause;
-
--- TODO(b/175098682): Switch to use async slices
-DROP VIEW IF EXISTS android_sysui_cuj_event;
-CREATE VIEW android_sysui_cuj_event AS
- SELECT
- 'slice' as track_type,
- (SELECT cuj_name FROM android_sysui_cuj_last_cuj)
- || ' - jank cause' as track_name,
- f.ts_main_thread_start as ts,
- f.dur_main_thread as dur,
- group_concat(jc.jank_cause) as slice_name
-FROM android_sysui_cuj_frames f
-JOIN android_sysui_cuj_jank_causes jc USING (frame_number)
-GROUP BY track_type, track_name, ts, dur;
-
-DROP VIEW IF EXISTS android_sysui_cuj_output;
-CREATE VIEW android_sysui_cuj_output AS
-SELECT
- AndroidSysUiCujMetrics(
- 'cuj_name', cuj_name,
- 'cuj_start', ts_start,
- 'cuj_dur', dur,
- 'process', process_metadata,
- 'frames',
- (SELECT RepeatedField(
- AndroidSysUiCujMetrics_Frame(
- 'number', f.frame_number,
- 'vsync', f.vsync,
- 'ts', f.ts_main_thread_start,
- 'dur', f.dur_frame,
- 'jank_cause',
- (SELECT RepeatedField(jc.jank_cause)
- FROM android_sysui_cuj_jank_causes jc WHERE jc.frame_number = f.frame_number)))
- FROM android_sysui_cuj_frames f
- ORDER BY frame_number ASC))
- FROM android_sysui_cuj_last_cuj;
diff --git a/src/trace_processor/metrics/android/android_thread_time_in_state.sql b/src/trace_processor/metrics/android/android_thread_time_in_state.sql
deleted file mode 100644
index ace04ede6..000000000
--- a/src/trace_processor/metrics/android/android_thread_time_in_state.sql
+++ /dev/null
@@ -1,206 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
-SELECT RUN_METRIC('android/cpu_info.sql');
-SELECT RUN_METRIC('android/process_metadata.sql');
-
-DROP TABLE IF EXISTS android_thread_time_in_state_base;
-CREATE TABLE android_thread_time_in_state_base AS
-SELECT
- base.*,
- IFNULL(core_type_per_cpu.core_type, 'unknown') core_type
-FROM (
- SELECT
- ts,
- utid,
- EXTRACT_ARG(counter.arg_set_id, 'time_in_state_cpu_id') AS
- time_in_state_cpu,
- EXTRACT_ARG(counter.arg_set_id, 'freq') AS freq,
- CAST(value AS INT) AS runtime_ms_counter
- FROM counter
- JOIN thread_counter_track ON (counter.track_id = thread_counter_track.id)
- WHERE thread_counter_track.name = 'time_in_state'
-) base
-LEFT JOIN core_type_per_cpu ON (cpu = time_in_state_cpu);
-
-DROP VIEW IF EXISTS android_thread_time_in_state_raw;
-CREATE VIEW android_thread_time_in_state_raw AS
-SELECT
- utid,
- time_in_state_cpu,
- core_type,
- freq,
- MAX(runtime_ms_counter) - MIN(runtime_ms_counter) runtime_ms_diff
-FROM android_thread_time_in_state_base
-GROUP BY utid, time_in_state_cpu, core_type, freq;
-
-DROP TABLE IF EXISTS android_thread_time_in_state_counters;
-CREATE TABLE android_thread_time_in_state_counters AS
-SELECT
- utid,
- raw.time_in_state_cpu,
- raw.core_type,
- SUM(runtime_ms_diff) AS runtime_ms,
- SUM(raw.freq * runtime_ms_diff / 1000000) AS mcycles,
- SUM(power * runtime_ms_diff / 3600000) AS power_profile_mah
-FROM android_thread_time_in_state_raw AS raw
- LEFT OUTER JOIN cpu_cluster_power AS power USING(core_type, freq)
-GROUP BY utid, raw.time_in_state_cpu, raw.core_type
-HAVING runtime_ms > 0;
-
-DROP VIEW IF EXISTS android_thread_time_in_state_thread_metrics;
-CREATE VIEW android_thread_time_in_state_thread_metrics AS
-SELECT
- utid,
- RepeatedField(AndroidThreadTimeInStateMetric_MetricsByCoreType(
- 'time_in_state_cpu', time_in_state_cpu,
- 'core_type', core_type,
- 'runtime_ms', runtime_ms,
- 'mcycles', CAST(mcycles AS INT),
- 'power_profile_mah', power_profile_mah
- )) metrics
-FROM android_thread_time_in_state_counters
-GROUP BY utid;
-
-DROP VIEW IF EXISTS android_thread_time_in_state_threads;
-CREATE VIEW android_thread_time_in_state_threads AS
-SELECT
- upid,
- RepeatedField(AndroidThreadTimeInStateMetric_Thread(
- 'name',
- thread.name,
- 'main_thread',
- thread.is_main_thread,
- 'metrics_by_core_type',
- android_thread_time_in_state_thread_metrics.metrics
- )) threads
-FROM thread
-JOIN android_thread_time_in_state_thread_metrics USING (utid)
-GROUP BY upid;
-
-DROP VIEW IF EXISTS android_thread_time_in_state_process_metrics;
-CREATE VIEW android_thread_time_in_state_process_metrics AS
-WITH process_counters AS (
- SELECT
- upid,
- time_in_state_cpu,
- core_type,
- SUM(runtime_ms) AS runtime_ms,
- SUM(mcycles) AS mcycles,
- SUM(power_profile_mah) AS power_profile_mah
- FROM android_thread_time_in_state_counters
- JOIN thread USING (utid)
- GROUP BY upid, time_in_state_cpu, core_type
-)
-SELECT
- upid,
- RepeatedField(AndroidThreadTimeInStateMetric_MetricsByCoreType(
- 'time_in_state_cpu', time_in_state_cpu,
- 'core_type', core_type,
- 'runtime_ms', runtime_ms,
- 'mcycles', CAST(mcycles AS INT),
- 'power_profile_mah', power_profile_mah
- )) metrics
-FROM process_counters
-GROUP BY upid;
-
-DROP VIEW IF EXISTS android_thread_time_in_state_output;
-CREATE VIEW android_thread_time_in_state_output AS
-SELECT AndroidThreadTimeInStateMetric(
- 'processes', (
- SELECT
- RepeatedField(AndroidThreadTimeInStateMetric_Process(
- 'metadata', metadata,
- 'metrics_by_core_type',
- android_thread_time_in_state_process_metrics.metrics,
- 'threads', android_thread_time_in_state_threads.threads
- ))
- FROM process
- JOIN process_metadata USING (upid)
- JOIN android_thread_time_in_state_process_metrics USING (upid)
- JOIN android_thread_time_in_state_threads USING (upid)
- )
-);
-
--- Ensure we always get the previous clock tick for duration in
--- android_thread_time_in_state_event_raw.
-DROP VIEW IF EXISTS android_thread_time_in_state_event_clock;
-CREATE VIEW android_thread_time_in_state_event_clock AS
-SELECT
- ts,
- LAG(ts) OVER (ORDER BY ts) AS lag_ts
-FROM (
- SELECT DISTINCT ts from android_thread_time_in_state_base
-);
-
-DROP VIEW IF EXISTS android_thread_time_in_state_event_raw;
-CREATE VIEW android_thread_time_in_state_event_raw AS
-SELECT
- ts,
- ts - lag_ts AS dur,
- upid,
- core_type,
- utid,
- -- We need globally unique track names so add the utid even when we
- -- know the name. But when we don't, also use the tid because that's what
- -- the rest of the UI does.
- IFNULL(thread.name, 'Thread ' || thread.tid) || ' (' || thread.utid || ')'
- AS thread_track_name,
- freq,
- runtime_ms_counter - LAG(runtime_ms_counter)
- OVER (PARTITION BY core_type, utid, freq ORDER BY ts) AS runtime_ms
-FROM android_thread_time_in_state_base
- -- Join to keep only utids which have non-zero runtime in the trace.
- JOIN android_thread_time_in_state_counters USING (utid, core_type)
- JOIN android_thread_time_in_state_event_clock USING(ts)
- JOIN thread using (utid);
-
-DROP VIEW IF EXISTS android_thread_time_in_state_event_thread;
-CREATE VIEW android_thread_time_in_state_event_thread AS
-SELECT
- 'counter' AS track_type,
- thread_track_name || ' (' || core_type || ' core)' as track_name,
- ts,
- dur,
- upid,
- sum(runtime_ms * freq) as ms_freq
-FROM android_thread_time_in_state_event_raw
-WHERE runtime_ms IS NOT NULL
- AND dur != 0
-GROUP BY track_type, track_name, ts, dur, upid;
-
-DROP VIEW IF EXISTS android_thread_time_in_state_event_global;
-CREATE VIEW android_thread_time_in_state_event_global AS
-SELECT
- 'counter' AS track_type,
- 'Total ' || core_type || ' core cycles / sec' as track_name,
- ts,
- dur,
- 0 AS upid,
- SUM(runtime_ms * freq) AS ms_freq
-FROM android_thread_time_in_state_event_raw
-WHERE runtime_ms IS NOT NULL
-GROUP BY ts, track_name;
-
-DROP TABLE IF EXISTS android_thread_time_in_state_event;
-CREATE TABLE android_thread_time_in_state_event AS
-SELECT track_type, track_name, ts, dur, upid, ms_freq * 1000000 / dur AS value
-FROM android_thread_time_in_state_event_thread
-UNION ALL
-SELECT track_type, track_name, ts, dur, upid, ms_freq * 1000000 / dur AS value
-FROM android_thread_time_in_state_event_global
--- Biggest values at top of list in UI.
-ORDER BY value DESC;
diff --git a/src/trace_processor/metrics/android/cpu_info.sql b/src/trace_processor/metrics/android/cpu_info.sql
deleted file mode 100644
index 1e04a3e68..000000000
--- a/src/trace_processor/metrics/android/cpu_info.sql
+++ /dev/null
@@ -1,50 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
-SELECT RUN_METRIC('android/power_profile_data.sql');
-
-DROP TABLE IF EXISTS cluster_core_type;
-CREATE TABLE cluster_core_type AS
- SELECT 0 as cluster, 'little' as core_type
- UNION ALL
- SELECT 1, 'big'
- UNION ALL
- SELECT 2, 'bigger';
-
-DROP VIEW IF EXISTS device_power_profile;
-CREATE VIEW device_power_profile AS
-SELECT cpu, cluster, freq, power
-FROM power_profile pp
-WHERE EXISTS (
- SELECT 1 FROM metadata
- WHERE name = 'android_build_fingerprint' AND str_value LIKE '%' || pp.device || '%');
-
-DROP VIEW IF EXISTS core_cluster_per_cpu;
-CREATE VIEW core_cluster_per_cpu AS
-SELECT DISTINCT cpu, cluster
-FROM device_power_profile;
-
-DROP VIEW IF EXISTS core_type_per_cpu;
-CREATE VIEW core_type_per_cpu AS
-SELECT
- cpu,
- core_type
-FROM core_cluster_per_cpu JOIN cluster_core_type USING(cluster);
-
-DROP VIEW IF EXISTS cpu_cluster_power;
-CREATE VIEW cpu_cluster_power AS
-SELECT DISTINCT core_type, freq, power
-FROM device_power_profile pp JOIN cluster_core_type USING(cluster);
diff --git a/src/trace_processor/metrics/android/g2d_duration.sql b/src/trace_processor/metrics/android/g2d_duration.sql
deleted file mode 100644
index 7d96d0657..000000000
--- a/src/trace_processor/metrics/android/g2d_duration.sql
+++ /dev/null
@@ -1,68 +0,0 @@
---
--- Copyright 2021 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
-
-DROP VIEW IF EXISTS raw_g2d_{{g2d_type}}_spans;
-CREATE VIEW raw_g2d_{{g2d_type}}_spans AS
-SELECT
- ts,
- t.name AS track_name,
- LEAD(ts, 1, 0) OVER (PARTITION BY name ORDER BY ts) - ts AS dur,
- LAG(value, 1, -1) OVER (PARTITION BY name ORDER BY ts) AS prev_g2d_value,
- value AS g2d_value,
- LEAD(value, 1, -1) OVER (PARTITION BY name ORDER BY ts) AS next_g2d_value
-FROM counter c JOIN thread_counter_track t ON t.id = c.track_id
-WHERE t.name LIKE 'g2d_frame_{{g2d_type}}%';
-
-
-DROP VIEW IF EXISTS g2d_{{g2d_type}}_spans;
-CREATE VIEW g2d_{{g2d_type}}_spans AS
-SELECT ts, track_name, dur
-FROM raw_g2d_{{g2d_type}}_spans
-WHERE g2d_value = 1 AND next_g2d_value = 0;
-
-
-DROP VIEW IF EXISTS g2d_{{g2d_type}}_errors;
-CREATE VIEW g2d_{{g2d_type}}_errors AS
-SELECT ts, track_name, g2d_value
-FROM raw_g2d_{{g2d_type}}_spans
-WHERE (g2d_value = 1 AND next_g2d_value = 1) OR (prev_g2d_value = 0 AND g2d_value = 0);
-
-
-DROP VIEW IF EXISTS g2d_{{g2d_type}}_instances;
-CREATE VIEW g2d_{{g2d_type}}_instances AS
-SELECT
- G2dMetrics_G2dInstance(
- 'name', g.track_name,
- 'max_dur_ns', CAST(MAX(g.dur) AS INT64),
- 'min_dur_ns', CAST(MIN(g.dur) AS INT64),
- 'avg_dur_ns', CAST(AVG(g.dur) AS INT64),
- 'frame_count', COUNT(*),
- 'error_count', (SELECT COUNT(*) FROM g2d_{{g2d_type}}_errors e WHERE e.track_name = g.track_name)
- ) AS instance
-FROM g2d_{{g2d_type}}_spans g GROUP BY g.track_name;
-
-
-DROP VIEW IF EXISTS {{output_table}};
-CREATE VIEW {{output_table}} AS
-SELECT
- G2dMetrics_G2dMetric(
- 'instances', (SELECT RepeatedField(instance) FROM g2d_{{g2d_type}}_instances),
- 'max_dur_ns', CAST(MAX(dur) AS INT64),
- 'min_dur_ns', CAST(MIN(dur) AS INT64),
- 'avg_dur_ns', CAST(AVG(dur) AS INT64),
- 'frame_count', COUNT(*),
- 'error_count', (SELECT COUNT(*) FROM g2d_{{g2d_type}}_errors)
- ) AS metric
-FROM g2d_{{g2d_type}}_spans;
diff --git a/src/trace_processor/metrics/android/hsc_startups.sql b/src/trace_processor/metrics/android/hsc_startups.sql
deleted file mode 100644
index 5c0a6181e..000000000
--- a/src/trace_processor/metrics/android/hsc_startups.sql
+++ /dev/null
@@ -1,259 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
--- Must be invoked after populating launches table in android_startup.
-DROP VIEW IF EXISTS functions;
-CREATE VIEW functions AS
-SELECT
- slices.ts as ts,
- slices.dur as dur,
- process.name as process_name,
- thread.name as thread_name,
- slices.name as function_name
-FROM slices
-INNER JOIN thread_track on slices.track_id = thread_track.id
-INNER JOIN thread USING(utid)
-INNER JOIN process USING(upid);
-
--- Animators don't occur on threads, so add them here.
-DROP VIEW IF EXISTS animators;
-CREATE VIEW animators AS
-SELECT
- slices.ts AS ts,
- slices.dur AS dur,
- thread.name AS process_name,
- slices.name AS animator_name
-FROM slices
-INNER JOIN process_track on slices.track_id = process_track.id
-INNER JOIN thread USING(upid)
-WHERE slices.name LIKE "animator%";
-
-DROP VIEW IF EXISTS frame_times;
-CREATE VIEW frame_times AS
-SELECT
- functions.ts AS ts,
- functions.ts + functions.dur AS ts_end,
- launches.package AS name,
- launches.id AS launch_id,
- ROW_NUMBER() OVER(PARTITION BY launches.id ORDER BY functions.ts ASC) as number
-FROM functions
-INNER JOIN launches on launches.package LIKE '%' || functions.process_name || '%'
-WHERE functions.function_name LIKE "Choreographer#doFrame%" AND functions.ts > launches.ts;
-
-DROP TABLE IF EXISTS hsc_based_startup_times;
-CREATE TABLE hsc_based_startup_times(package STRING, id INT, ts_total INT);
-
--- Calculator
-INSERT INTO hsc_based_startup_times
-SELECT
- launches.package as package,
- launches.id as id,
- frame_times.ts_end - launches.ts as ts_total
-FROM frame_times
-INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
-WHERE frame_times.number=2 AND frame_times.name LIKE "%roid.calcul%" AND frame_times.launch_id = launches.id;
-
--- Calendar
-INSERT INTO hsc_based_startup_times
-SELECT
- launches.package as package,
- launches.id as id,
- frame_times.ts_end - launches.ts as ts_total
-FROM frame_times
-INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
-WHERE frame_times.name LIKE "%id.calendar%" AND frame_times.launch_id = launches.id
-ORDER BY ABS(frame_times.ts_end - (SELECT ts + dur FROM functions WHERE function_name LIKE "DrawFrame%" AND process_name LIKE "%id.calendar" ORDER BY ts LIMIT 1)) LIMIT 1;
-
--- Camera
-INSERT INTO hsc_based_startup_times
-SELECT
- launches.package as package,
- launches.id as id,
- frame_times.ts_end - launches.ts as ts_total
-FROM frame_times
-INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
-WHERE frame_times.number=2 AND frame_times.name LIKE "%GoogleCamera%" AND frame_times.launch_id = launches.id;
-
--- Chrome
-INSERT INTO hsc_based_startup_times
-SELECT
- launches.package as package,
- launches.id as id,
- frame_times.ts_end - launches.ts as ts_total
-FROM frame_times
-INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
-WHERE frame_times.number=1 AND frame_times.name LIKE "%chrome%" AND frame_times.launch_id = launches.id;
-
--- Clock
-INSERT INTO hsc_based_startup_times
-SELECT
- launches.package as package,
- launches.id as id,
- frame_times.ts_end - launches.ts as ts_total
-FROM frame_times
-INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
-WHERE frame_times.ts > (SELECT ts + dur FROM animators WHERE animator_name="animator:translationZ" AND process_name LIKE "%id.deskclock" ORDER BY (ts+dur) DESC LIMIT 1) AND frame_times.name LIKE "%id.deskclock" AND frame_times.launch_id = launches.id
-ORDER BY ts_total LIMIT 1;
-
--- Contacts
-INSERT INTO hsc_based_startup_times
-SELECT
- launches.package as package,
- launches.id as id,
- frame_times.ts_end - launches.ts as ts_total
-FROM frame_times
-INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
-WHERE frame_times.number=3 AND frame_times.name LIKE "%id.contacts" AND frame_times.launch_id=launches.id;
-
--- Dialer
-INSERT INTO hsc_based_startup_times
-SELECT
- launches.package as package,
- launches.id as id,
- frame_times.ts_end - launches.ts as ts_total
-FROM frame_times
-INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
-WHERE frame_times.number=1 AND frame_times.name LIKE "%id.dialer" AND frame_times.launch_id=launches.id;
-
--- Facebook
-INSERT INTO hsc_based_startup_times
-SELECT
- launches.package as package,
- launches.id as id,
- frame_times.ts_end - launches.ts as ts_total
-FROM frame_times
-INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
-WHERE frame_times.ts > (SELECT ts+dur FROM slices WHERE slices.name LIKE "fb_startup_complete" ORDER BY ts LIMIT 1) AND frame_times.name LIKE "%ok.katana" AND frame_times.launch_id = launches.id
-ORDER BY ts_total LIMIT 1;
-
--- Facebook Messenger
-INSERT INTO hsc_based_startup_times
-SELECT
- launches.package as package,
- launches.id as id,
- frame_times.ts_end - launches.ts as ts_total
-FROM frame_times
-INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
-WHERE frame_times.ts > (SELECT ts+dur FROM slices WHERE slices.name LIKE "msgr_cold_start_to_cached_content" ORDER BY ts LIMIT 1) AND frame_times.name LIKE "%book.orca" AND frame_times.launch_id = launches.id
-ORDER BY ts_total LIMIT 1;
-
--- Gmail
-INSERT INTO hsc_based_startup_times
-SELECT
- launches.package as package,
- launches.id as id,
- frame_times.ts_end - launches.ts as ts_total
-FROM frame_times
-INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
-WHERE frame_times.ts > (SELECT ts + dur FROM animators WHERE animator_name="animator:elevation" AND process_name LIKE "%android.gm" ORDER BY (ts+dur) DESC LIMIT 1) AND frame_times.name LIKE "%android.gm" AND frame_times.launch_id = launches.id
-ORDER BY ts_total LIMIT 1;
-
--- Instagram
-INSERT INTO hsc_based_startup_times
-SELECT
- launches.package as package,
- launches.id as id,
- frame_times.ts_end - launches.ts as ts_total
-FROM frame_times
-INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
-WHERE frame_times.ts > (SELECT ts+dur FROM slices WHERE slices.name LIKE "ig_cold_start_to_cached_content" ORDER BY ts LIMIT 1) AND frame_times.name LIKE "%gram.android" AND frame_times.launch_id = launches.id
-ORDER BY ts_total LIMIT 1;
-
--- Maps
-INSERT INTO hsc_based_startup_times
-SELECT
- launches.package as package,
- launches.id as id,
- frame_times.ts_end - launches.ts as ts_total
-FROM frame_times
-INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
-WHERE frame_times.number=1 AND frame_times.name LIKE "%maps%" AND frame_times.launch_id = launches.id;
-
--- Messages
-INSERT INTO hsc_based_startup_times
-SELECT
- launches.package as package,
- launches.id as id,
- frame_times.ts_end - launches.ts as ts_total
-FROM frame_times
-INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
-WHERE frame_times.ts_end > (SELECT ts + dur FROM animators WHERE animator_name="animator:translationZ" AND process_name LIKE "%apps.messaging%" ORDER BY ts LIMIT 1) AND frame_times.name LIKE "%apps.messaging%" AND frame_times.launch_id = launches.id
-ORDER BY ts_total LIMIT 1;
-
--- Netflix
-INSERT INTO hsc_based_startup_times
-SELECT
- launches.package as package,
- launches.id as id,
- frame_times.ts_end - launches.ts as ts_total
-FROM frame_times
-INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
-WHERE frame_times.ts < (SELECT ts FROM animators WHERE animator_name LIKE "animator%" AND process_name LIKE "%lix.mediaclient" ORDER BY ts LIMIT 1) AND frame_times.name LIKE "%lix.mediaclient%" AND frame_times.launch_id = launches.id
-ORDER BY ts_total DESC LIMIT 1;
-
--- Photos
-INSERT INTO hsc_based_startup_times
-SELECT
- launches.package as package,
- launches.id as id,
- frame_times.ts_end - launches.ts as ts_total
-FROM frame_times
-INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
-WHERE frame_times.number=1 AND frame_times.name LIKE "%apps.photos%" AND frame_times.launch_id = launches.id;
-
--- Settings was deprecated in favor of reportFullyDrawn b/169694037.
-
--- Snapchat
-INSERT INTO hsc_based_startup_times
-SELECT
- launches.package as package,
- launches.id as id,
- frame_times.ts_end - launches.ts as ts_total
-FROM frame_times
-INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
-WHERE frame_times.number=1 AND frame_times.name LIKE "%napchat.android" AND frame_times.launch_id = launches.id;
-
--- Twitter
-INSERT INTO hsc_based_startup_times
-SELECT
- launches.package as package,
- launches.id as id,
- frame_times.ts_end - launches.ts as ts_total
-FROM frame_times
-INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
-WHERE frame_times.ts_end > (SELECT ts FROM animators WHERE animator_name="animator" AND process_name LIKE "%tter.android" ORDER BY ts LIMIT 1) AND frame_times.name LIKE "%tter.android" AND frame_times.launch_id = launches.id
-ORDER BY ts_total LIMIT 1;
-
--- WhatsApp
-INSERT INTO hsc_based_startup_times
-SELECT
- launches.package as package,
- launches.id as id,
- frame_times.ts_end - launches.ts as ts_total
-FROM frame_times
-INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
-WHERE frame_times.ts > (SELECT ts+dur FROM slices WHERE slices.name LIKE "wa_startup_complete" ORDER BY ts LIMIT 1) AND frame_times.name LIKE "%om.whatsapp" AND frame_times.launch_id = launches.id
-ORDER BY ts_total LIMIT 1;
-
--- Youtube
-INSERT INTO hsc_based_startup_times
-SELECT
- launches.package as package,
- launches.id as id,
- frame_times.ts_end - launches.ts as ts_total
-FROM frame_times
-INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
-WHERE frame_times.number=2 AND frame_times.name LIKE "%id.youtube" AND frame_times.launch_id = launches.id;
diff --git a/src/trace_processor/metrics/android/java_heap_histogram.sql b/src/trace_processor/metrics/android/java_heap_histogram.sql
deleted file mode 100644
index 7fd968cb6..000000000
--- a/src/trace_processor/metrics/android/java_heap_histogram.sql
+++ /dev/null
@@ -1,92 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
-SELECT RUN_METRIC('android/process_metadata.sql');
-
-DROP TABLE IF EXISTS android_special_classes;
-CREATE TABLE android_special_classes AS
-WITH RECURSIVE cls_visitor(cls_id, category) AS (
- SELECT id, name FROM heap_graph_class WHERE name IN (
- 'android.view.View',
- 'android.app.Activity',
- 'android.app.Fragment',
- 'android.app.Service',
- 'android.content.ContentProvider',
- 'android.content.BroadcastReceiver',
- 'android.content.Context',
- 'android.content.Intent',
- 'android.content.res.ApkAssets',
- 'android.os.Handler',
- 'android.os.Parcel',
- 'android.graphics.Bitmap',
- 'android.graphics.BaseCanvas',
- 'com.android.server.am.PendingIntentRecord')
- UNION ALL
- SELECT child.id, parent.category
- FROM heap_graph_class child JOIN cls_visitor parent ON parent.cls_id = child.superclass_id
-)
-SELECT * FROM cls_visitor;
-
-DROP VIEW IF EXISTS java_heap_histogram_output;
-CREATE VIEW java_heap_histogram_output AS
-WITH
--- Base histogram table
-heap_obj_histograms AS (
- SELECT
- o.upid,
- o.graph_sample_ts,
- IFNULL(c.deobfuscated_name, c.name) AS type_name,
- special.category,
- COUNT(1) obj_count,
- SUM(CASE o.reachable WHEN TRUE THEN 1 ELSE 0 END) reachable_obj_count
- FROM heap_graph_object o
- JOIN heap_graph_class c ON o.type_id = c.id
- LEFT JOIN android_special_classes special ON special.cls_id = c.id
- GROUP BY 1, 2, 3, 4
- ORDER BY 6 DESC
-),
--- Group by to build the repeated field by upid, ts
-heap_obj_histogram_count_protos AS (
- SELECT
- upid,
- graph_sample_ts,
- RepeatedField(JavaHeapHistogram_TypeCount(
- 'type_name', type_name,
- 'category', category,
- 'obj_count', obj_count,
- 'reachable_obj_count', reachable_obj_count
- )) AS count_protos
- FROM heap_obj_histograms
- GROUP BY 1, 2
-),
--- Group by to build the repeated field by upid
-heap_obj_histogram_sample_protos AS (
- SELECT
- upid,
- RepeatedField(JavaHeapHistogram_Sample(
- 'ts', graph_sample_ts,
- 'type_count', count_protos
- )) AS sample_protos
- FROM heap_obj_histogram_count_protos
- GROUP BY 1
-)
-SELECT JavaHeapHistogram(
- 'instance_stats', RepeatedField(JavaHeapHistogram_InstanceStats(
- 'upid', upid,
- 'process', process_metadata.metadata,
- 'samples', sample_protos
- )))
-FROM heap_obj_histogram_sample_protos JOIN process_metadata USING (upid);
diff --git a/src/trace_processor/metrics/android/java_heap_stats.sql b/src/trace_processor/metrics/android/java_heap_stats.sql
deleted file mode 100644
index dfafbbd47..000000000
--- a/src/trace_processor/metrics/android/java_heap_stats.sql
+++ /dev/null
@@ -1,111 +0,0 @@
---
--- Copyright 2019 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
-SELECT RUN_METRIC('android/process_metadata.sql');
-SELECT RUN_METRIC('android/process_mem.sql');
-
-DROP VIEW IF EXISTS java_heap_stats_output;
-CREATE VIEW java_heap_stats_output AS
-WITH
--- Base view
-base_stat_counts AS (
- SELECT
- upid,
- graph_sample_ts,
- SUM(self_size) AS total_size,
- COUNT(1) AS total_obj_count,
- SUM(CASE reachable WHEN TRUE THEN self_size ELSE 0 END) AS reachable_size,
- SUM(CASE reachable WHEN TRUE THEN 1 ELSE 0 END) AS reachable_obj_count
- FROM heap_graph_object
- GROUP BY 1, 2
-),
-heap_roots AS (
- SELECT
- upid,
- graph_sample_ts,
- root_type,
- IFNULL(t.deobfuscated_name, t.name) type_name,
- COUNT(1) obj_count
- FROM heap_graph_object o
- JOIN heap_graph_class t ON o.type_id = t.id
- -- Classes are going to be particularly spammy and uninteresting
- -- from a memory analysis perspective (compared e.g. to local jni roots)
- WHERE root_type IS NOT NULL AND root_type != 'ROOT_STICKY_CLASS'
- GROUP BY 1, 2, 3, 4
- ORDER BY obj_count DESC
-),
-heap_roots_proto AS (
- SELECT
- upid,
- graph_sample_ts,
- RepeatedField(JavaHeapStats_HeapRoots(
- 'root_type', root_type,
- 'type_name', type_name,
- 'obj_count', obj_count
- )) roots
- FROM heap_roots
- GROUP BY 1, 2
-),
-base_stats AS (
- SELECT * FROM base_stat_counts JOIN heap_roots_proto USING (upid, graph_sample_ts)
-),
--- Find closest value
-closest_anon_swap AS (
- SELECT
- upid,
- graph_sample_ts,
- (
- SELECT anon_swap_val
- FROM (
- SELECT
- ts, dur,
- CAST(anon_and_swap_val AS INTEGER) anon_swap_val,
- ABS(ts - base_stats.graph_sample_ts) diff
- FROM anon_and_swap_span
- WHERE upid = base_stats.upid)
- WHERE
- (graph_sample_ts >= ts AND graph_sample_ts < ts + dur)
- -- If the first memory sample for the UPID comes *after* the heap profile
- -- accept it if close (500ms)
- OR (graph_sample_ts < ts AND diff <= 500 * 1e6)
- ORDER BY diff LIMIT 1
- ) val
- FROM base_stats
-),
--- Group by upid
-heap_graph_sample_protos AS (
- SELECT
- base_stats.upid,
- RepeatedField(JavaHeapStats_Sample(
- 'ts', graph_sample_ts,
- 'heap_size', total_size,
- 'obj_count', total_obj_count,
- 'reachable_heap_size', reachable_size,
- 'reachable_obj_count', reachable_obj_count,
- 'roots', roots,
- 'anon_rss_and_swap_size', closest_anon_swap.val
- )) sample_protos
- FROM base_stats
- LEFT JOIN closest_anon_swap USING (upid, graph_sample_ts)
- GROUP BY 1
-)
-SELECT JavaHeapStats(
- 'instance_stats', RepeatedField(JavaHeapStats_InstanceStats(
- 'upid', upid,
- 'process', process_metadata.metadata,
- 'samples', sample_protos
- )))
-FROM heap_graph_sample_protos JOIN process_metadata USING (upid);
diff --git a/src/trace_processor/metrics/android/power_drain_in_watts.sql b/src/trace_processor/metrics/android/power_drain_in_watts.sql
deleted file mode 100644
index 1fbfec300..000000000
--- a/src/trace_processor/metrics/android/power_drain_in_watts.sql
+++ /dev/null
@@ -1,91 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the 'License');
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an 'AS IS' BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
--- This is a mapping from counter names on different devices
--- to what subsystems they are measuring.
-DROP TABLE IF EXISTS power_counters;
-CREATE TABLE power_counters (name TEXT UNIQUE, subsystem TEXT);
-
-INSERT INTO power_counters
-VALUES ('power.VPH_PWR_S5C_S6C_uws', 'cpu_big'),
- ('power.VPH_PWR_S4C_uws', 'cpu_little'),
- ('power.VPH_PWR_S2C_S3C_uws', 'soc'),
- ('power.VPH_PWR_OLED_uws', 'display'),
- ('power.PPVAR_VPH_PWR_S1A_S9A_S10A_uws', 'soc'),
- ('power.PPVAR_VPH_PWR_S2A_S3A_uws', 'cpu_big'),
- ('power.PPVAR_VPH_PWR_S1C_uws', 'cpu_little'),
- ('power.WCN3998_VDD13 [from PP1304_L2C]_uws', 'wifi'),
- ('power.PPVAR_VPH_PWR_WLAN_uws', 'wifi'),
- ('power.PPVAR_VPH_PWR_OLED_uws', 'display'),
- ('power.PPVAR_VPH_PWR_QTM525_uws', 'cellular'),
- ('power.PPVAR_VPH_PWR_RF_uws', 'cellular'),
- ('power.rails.aoc.logic', 'aoc'),
- ('power.rails.aoc.memory', 'aoc'),
- ('power.rails.cpu.big', 'cpu_big'),
- ('power.rails.cpu.little', 'cpu_little'),
- ('power.rails.cpu.mid', 'cpu_mid'),
- ('power.rails.ddr.a', 'mem'),
- ('power.rails.ddr.b', 'mem'),
- ('power.rails.ddr.c', 'mem'),
- ('power.rails.gpu', 'gpu'),
- ('power.rails.display', 'display'),
- ('power.rails.gps', 'gps'),
- ('power.rails.memory.interface', 'mem'),
- ('power.rails.modem', 'cellular'),
- ('power.rails.radio.frontend', 'cellular'),
- ('power.rails.system.fabric', 'soc'),
- ('power.rails.wifi.bt', 'wifi');
-
--- Convert power counter data into table of events, where each event has
--- start timestamp, duration and the average power drain during its duration
--- in Watts.
--- Note that power counters wrap around at different values on different
--- devices. When that happens, we ignore the value before overflow, and only
--- take into account the value after it. This underestimates the actual power
--- drain between those counters.
-DROP VIEW IF EXISTS drain_in_watts;
-CREATE VIEW drain_in_watts AS
-SELECT name,
- ts,
- LEAD(ts) OVER (
- PARTITION BY track_id
- ORDER BY ts
- ) - ts AS dur,
- CASE
- WHEN LEAD(value) OVER (
- PARTITION BY track_id
- ORDER BY ts
- ) >= value THEN (
- LEAD(value) OVER (
- PARTITION BY track_id
- ORDER BY ts
- ) - value
- )
- ELSE LEAD(value) OVER (
- PARTITION BY track_id
- ORDER BY ts
- )
- END / (
- LEAD(ts) OVER (
- PARTITION BY track_id
- ORDER BY ts
- ) - ts
- ) * 1e3 AS drain_w
-FROM counter
- JOIN counter_track ON (counter.track_id = counter_track.id)
-WHERE counter_track.type = 'counter_track'
- AND name LIKE "power.%";
-
diff --git a/src/trace_processor/metrics/android/power_profile_data.sql b/src/trace_processor/metrics/android/power_profile_data.sql
deleted file mode 100644
index 5ea96ea02..000000000
--- a/src/trace_processor/metrics/android/power_profile_data.sql
+++ /dev/null
@@ -1,1366 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
-
-INSERT OR REPLACE INTO power_profile VALUES
-("marlin", 0, 0, 307200, 11.272),
-("marlin", 0, 0, 384000, 14.842),
-("marlin", 0, 0, 460800, 18.497),
-("marlin", 0, 0, 537600, 22.518),
-("marlin", 0, 0, 614400, 25.967),
-("marlin", 0, 0, 691200, 31.694),
-("marlin", 0, 0, 768000, 37.673),
-("marlin", 0, 0, 844800, 42.859),
-("marlin", 0, 0, 902600, 46.872),
-("marlin", 0, 0, 979200, 57.92),
-("marlin", 0, 0, 1056000, 67.561),
-("marlin", 0, 0, 1132800, 76.303),
-("marlin", 0, 0, 1209600, 87.613),
-("marlin", 0, 0, 1286400, 97.045),
-("marlin", 0, 0, 1363200, 109.544),
-("marlin", 0, 0, 1440000, 122.054),
-("marlin", 0, 0, 1516800, 136.345),
-("marlin", 0, 0, 1593600, 154.435),
-("marlin", 1, 0, 307200, 11.272),
-("marlin", 1, 0, 384000, 14.842),
-("marlin", 1, 0, 460800, 18.497),
-("marlin", 1, 0, 537600, 22.518),
-("marlin", 1, 0, 614400, 25.967),
-("marlin", 1, 0, 691200, 31.694),
-("marlin", 1, 0, 768000, 37.673),
-("marlin", 1, 0, 844800, 42.859),
-("marlin", 1, 0, 902600, 46.872),
-("marlin", 1, 0, 979200, 57.92),
-("marlin", 1, 0, 1056000, 67.561),
-("marlin", 1, 0, 1132800, 76.303),
-("marlin", 1, 0, 1209600, 87.613),
-("marlin", 1, 0, 1286400, 97.045),
-("marlin", 1, 0, 1363200, 109.544),
-("marlin", 1, 0, 1440000, 122.054),
-("marlin", 1, 0, 1516800, 136.345),
-("marlin", 1, 0, 1593600, 154.435),
-("marlin", 2, 1, 307200, 7.055),
-("marlin", 2, 1, 384000, 11.483),
-("marlin", 2, 1, 460800, 14.979),
-("marlin", 2, 1, 537600, 19.642),
-("marlin", 2, 1, 614400, 23.167),
-("marlin", 2, 1, 691200, 27.479),
-("marlin", 2, 1, 748800, 31.632),
-("marlin", 2, 1, 825600, 39.192),
-("marlin", 2, 1, 902400, 47.817),
-("marlin", 2, 1, 979200, 55.659),
-("marlin", 2, 1, 1056000, 64.908),
-("marlin", 2, 1, 1132800, 73.824),
-("marlin", 2, 1, 1209600, 85.299),
-("marlin", 2, 1, 1286400, 96.036),
-("marlin", 2, 1, 1363200, 109.233),
-("marlin", 2, 1, 1440000, 118.56),
-("marlin", 2, 1, 1516800, 132.959),
-("marlin", 2, 1, 1593600, 143.692),
-("marlin", 2, 1, 1670400, 161.378),
-("marlin", 2, 1, 1747200, 180.616),
-("marlin", 2, 1, 1824000, 193.897),
-("marlin", 2, 1, 1900800, 214.361),
-("marlin", 2, 1, 1977600, 238.338),
-("marlin", 2, 1, 2054400, 265.759),
-("marlin", 2, 1, 2150400, 297.918),
-("marlin", 3, 1, 307200, 7.055),
-("marlin", 3, 1, 384000, 11.483),
-("marlin", 3, 1, 460800, 14.979),
-("marlin", 3, 1, 537600, 19.642),
-("marlin", 3, 1, 614400, 23.167),
-("marlin", 3, 1, 691200, 27.479),
-("marlin", 3, 1, 748800, 31.632),
-("marlin", 3, 1, 825600, 39.192),
-("marlin", 3, 1, 902400, 47.817),
-("marlin", 3, 1, 979200, 55.659),
-("marlin", 3, 1, 1056000, 64.908),
-("marlin", 3, 1, 1132800, 73.824),
-("marlin", 3, 1, 1209600, 85.299),
-("marlin", 3, 1, 1286400, 96.036),
-("marlin", 3, 1, 1363200, 109.233),
-("marlin", 3, 1, 1440000, 118.56),
-("marlin", 3, 1, 1516800, 132.959),
-("marlin", 3, 1, 1593600, 143.692),
-("marlin", 3, 1, 1670400, 161.378),
-("marlin", 3, 1, 1747200, 180.616),
-("marlin", 3, 1, 1824000, 193.897),
-("marlin", 3, 1, 1900800, 214.361),
-("marlin", 3, 1, 1977600, 238.338),
-("marlin", 3, 1, 2054400, 265.759),
-("marlin", 3, 1, 2150400, 297.918),
-("sailfish", 0, 0, 307200, 11.272),
-("sailfish", 0, 0, 384000, 14.842),
-("sailfish", 0, 0, 460800, 18.497),
-("sailfish", 0, 0, 537600, 22.518),
-("sailfish", 0, 0, 614400, 25.967),
-("sailfish", 0, 0, 691200, 31.694),
-("sailfish", 0, 0, 768000, 37.673),
-("sailfish", 0, 0, 844800, 42.859),
-("sailfish", 0, 0, 902600, 46.872),
-("sailfish", 0, 0, 979200, 57.92),
-("sailfish", 0, 0, 1056000, 67.561),
-("sailfish", 0, 0, 1132800, 76.303),
-("sailfish", 0, 0, 1209600, 87.613),
-("sailfish", 0, 0, 1286400, 97.045),
-("sailfish", 0, 0, 1363200, 109.544),
-("sailfish", 0, 0, 1440000, 122.054),
-("sailfish", 0, 0, 1516800, 136.345),
-("sailfish", 0, 0, 1593600, 154.435),
-("sailfish", 1, 0, 307200, 11.272),
-("sailfish", 1, 0, 384000, 14.842),
-("sailfish", 1, 0, 460800, 18.497),
-("sailfish", 1, 0, 537600, 22.518),
-("sailfish", 1, 0, 614400, 25.967),
-("sailfish", 1, 0, 691200, 31.694),
-("sailfish", 1, 0, 768000, 37.673),
-("sailfish", 1, 0, 844800, 42.859),
-("sailfish", 1, 0, 902600, 46.872),
-("sailfish", 1, 0, 979200, 57.92),
-("sailfish", 1, 0, 1056000, 67.561),
-("sailfish", 1, 0, 1132800, 76.303),
-("sailfish", 1, 0, 1209600, 87.613),
-("sailfish", 1, 0, 1286400, 97.045),
-("sailfish", 1, 0, 1363200, 109.544),
-("sailfish", 1, 0, 1440000, 122.054),
-("sailfish", 1, 0, 1516800, 136.345),
-("sailfish", 1, 0, 1593600, 154.435),
-("sailfish", 2, 1, 307200, 7.055),
-("sailfish", 2, 1, 384000, 11.483),
-("sailfish", 2, 1, 460800, 14.979),
-("sailfish", 2, 1, 537600, 19.642),
-("sailfish", 2, 1, 614400, 23.167),
-("sailfish", 2, 1, 691200, 27.479),
-("sailfish", 2, 1, 748800, 31.632),
-("sailfish", 2, 1, 825600, 39.192),
-("sailfish", 2, 1, 902400, 47.817),
-("sailfish", 2, 1, 979200, 55.659),
-("sailfish", 2, 1, 1056000, 64.908),
-("sailfish", 2, 1, 1132800, 73.824),
-("sailfish", 2, 1, 1209600, 85.299),
-("sailfish", 2, 1, 1286400, 96.036),
-("sailfish", 2, 1, 1363200, 109.233),
-("sailfish", 2, 1, 1440000, 118.56),
-("sailfish", 2, 1, 1516800, 132.959),
-("sailfish", 2, 1, 1593600, 143.692),
-("sailfish", 2, 1, 1670400, 161.378),
-("sailfish", 2, 1, 1747200, 180.616),
-("sailfish", 2, 1, 1824000, 193.897),
-("sailfish", 2, 1, 1900800, 214.361),
-("sailfish", 2, 1, 1977600, 238.338),
-("sailfish", 2, 1, 2054400, 265.759),
-("sailfish", 2, 1, 2150400, 297.918),
-("sailfish", 3, 1, 307200, 7.055),
-("sailfish", 3, 1, 384000, 11.483),
-("sailfish", 3, 1, 460800, 14.979),
-("sailfish", 3, 1, 537600, 19.642),
-("sailfish", 3, 1, 614400, 23.167),
-("sailfish", 3, 1, 691200, 27.479),
-("sailfish", 3, 1, 748800, 31.632),
-("sailfish", 3, 1, 825600, 39.192),
-("sailfish", 3, 1, 902400, 47.817),
-("sailfish", 3, 1, 979200, 55.659),
-("sailfish", 3, 1, 1056000, 64.908),
-("sailfish", 3, 1, 1132800, 73.824),
-("sailfish", 3, 1, 1209600, 85.299),
-("sailfish", 3, 1, 1286400, 96.036),
-("sailfish", 3, 1, 1363200, 109.233),
-("sailfish", 3, 1, 1440000, 118.56),
-("sailfish", 3, 1, 1516800, 132.959),
-("sailfish", 3, 1, 1593600, 143.692),
-("sailfish", 3, 1, 1670400, 161.378),
-("sailfish", 3, 1, 1747200, 180.616),
-("sailfish", 3, 1, 1824000, 193.897),
-("sailfish", 3, 1, 1900800, 214.361),
-("sailfish", 3, 1, 1977600, 238.338),
-("sailfish", 3, 1, 2054400, 265.759),
-("sailfish", 3, 1, 2150400, 297.918),
-("walleye", 0, 0, 300000, 3.685),
-("walleye", 0, 0, 364800, 3.598),
-("walleye", 0, 0, 441600, 3.621),
-("walleye", 0, 0, 518400, 4.202),
-("walleye", 0, 0, 595200, 4.935),
-("walleye", 0, 0, 672000, 5.633),
-("walleye", 0, 0, 748800, 6.216),
-("walleye", 0, 0, 825600, 6.71),
-("walleye", 0, 0, 883200, 7.557),
-("walleye", 0, 0, 960000, 8.687),
-("walleye", 0, 0, 1036800, 9.882),
-("walleye", 0, 0, 1094400, 10.95),
-("walleye", 0, 0, 1171200, 12.075),
-("walleye", 0, 0, 1248000, 12.875),
-("walleye", 0, 0, 1324800, 14.424),
-("walleye", 0, 0, 1401600, 15.653),
-("walleye", 0, 0, 1478400, 17.345),
-("walleye", 0, 0, 1555200, 18.71),
-("walleye", 0, 0, 1670400, 21.587),
-("walleye", 0, 0, 1747200, 25.43),
-("walleye", 0, 0, 1824000, 27.165),
-("walleye", 0, 0, 1900800, 31.671),
-("walleye", 1, 0, 300000, 3.685),
-("walleye", 1, 0, 364800, 3.598),
-("walleye", 1, 0, 441600, 3.621),
-("walleye", 1, 0, 518400, 4.202),
-("walleye", 1, 0, 595200, 4.935),
-("walleye", 1, 0, 672000, 5.633),
-("walleye", 1, 0, 748800, 6.216),
-("walleye", 1, 0, 825600, 6.71),
-("walleye", 1, 0, 883200, 7.557),
-("walleye", 1, 0, 960000, 8.687),
-("walleye", 1, 0, 1036800, 9.882),
-("walleye", 1, 0, 1094400, 10.95),
-("walleye", 1, 0, 1171200, 12.075),
-("walleye", 1, 0, 1248000, 12.875),
-("walleye", 1, 0, 1324800, 14.424),
-("walleye", 1, 0, 1401600, 15.653),
-("walleye", 1, 0, 1478400, 17.345),
-("walleye", 1, 0, 1555200, 18.71),
-("walleye", 1, 0, 1670400, 21.587),
-("walleye", 1, 0, 1747200, 25.43),
-("walleye", 1, 0, 1824000, 27.165),
-("walleye", 1, 0, 1900800, 31.671),
-("walleye", 2, 0, 300000, 3.685),
-("walleye", 2, 0, 364800, 3.598),
-("walleye", 2, 0, 441600, 3.621),
-("walleye", 2, 0, 518400, 4.202),
-("walleye", 2, 0, 595200, 4.935),
-("walleye", 2, 0, 672000, 5.633),
-("walleye", 2, 0, 748800, 6.216),
-("walleye", 2, 0, 825600, 6.71),
-("walleye", 2, 0, 883200, 7.557),
-("walleye", 2, 0, 960000, 8.687),
-("walleye", 2, 0, 1036800, 9.882),
-("walleye", 2, 0, 1094400, 10.95),
-("walleye", 2, 0, 1171200, 12.075),
-("walleye", 2, 0, 1248000, 12.875),
-("walleye", 2, 0, 1324800, 14.424),
-("walleye", 2, 0, 1401600, 15.653),
-("walleye", 2, 0, 1478400, 17.345),
-("walleye", 2, 0, 1555200, 18.71),
-("walleye", 2, 0, 1670400, 21.587),
-("walleye", 2, 0, 1747200, 25.43),
-("walleye", 2, 0, 1824000, 27.165),
-("walleye", 2, 0, 1900800, 31.671),
-("walleye", 3, 0, 300000, 3.685),
-("walleye", 3, 0, 364800, 3.598),
-("walleye", 3, 0, 441600, 3.621),
-("walleye", 3, 0, 518400, 4.202),
-("walleye", 3, 0, 595200, 4.935),
-("walleye", 3, 0, 672000, 5.633),
-("walleye", 3, 0, 748800, 6.216),
-("walleye", 3, 0, 825600, 6.71),
-("walleye", 3, 0, 883200, 7.557),
-("walleye", 3, 0, 960000, 8.687),
-("walleye", 3, 0, 1036800, 9.882),
-("walleye", 3, 0, 1094400, 10.95),
-("walleye", 3, 0, 1171200, 12.075),
-("walleye", 3, 0, 1248000, 12.875),
-("walleye", 3, 0, 1324800, 14.424),
-("walleye", 3, 0, 1401600, 15.653),
-("walleye", 3, 0, 1478400, 17.345),
-("walleye", 3, 0, 1555200, 18.71),
-("walleye", 3, 0, 1670400, 21.587),
-("walleye", 3, 0, 1747200, 25.43),
-("walleye", 3, 0, 1824000, 27.165),
-("walleye", 3, 0, 1900800, 31.671),
-("walleye", 4, 1, 300000, 10.722),
-("walleye", 4, 1, 345600, 11.52),
-("walleye", 4, 1, 422400, 14.105),
-("walleye", 4, 1, 499200, 16.68),
-("walleye", 4, 1, 576000, 18.946),
-("walleye", 4, 1, 652800, 21.265),
-("walleye", 4, 1, 729600, 23.432),
-("walleye", 4, 1, 806400, 26.019),
-("walleye", 4, 1, 902400, 28.856),
-("walleye", 4, 1, 979200, 31.085),
-("walleye", 4, 1, 1056000, 33.615),
-("walleye", 4, 1, 1132800, 35.76),
-("walleye", 4, 1, 1190400, 40.608),
-("walleye", 4, 1, 1267200, 43.284),
-("walleye", 4, 1, 1344000, 47.347),
-("walleye", 4, 1, 1420800, 52.231),
-("walleye", 4, 1, 1497600, 57.225),
-("walleye", 4, 1, 1574400, 63.138),
-("walleye", 4, 1, 1651200, 69.251),
-("walleye", 4, 1, 1728000, 76.449),
-("walleye", 4, 1, 1804800, 84.71),
-("walleye", 4, 1, 1881600, 102.551),
-("walleye", 4, 1, 1958400, 107.115),
-("walleye", 4, 1, 2035200, 129.689),
-("walleye", 4, 1, 2112000, 135.832),
-("walleye", 4, 1, 2208000, 164.674),
-("walleye", 4, 1, 2265600, 180.279),
-("walleye", 4, 1, 2323200, 197.024),
-("walleye", 4, 1, 2342400, 204.511),
-("walleye", 4, 1, 2361600, 211.886),
-("walleye", 4, 1, 2457600, 212.147),
-("walleye", 5, 1, 300000, 10.722),
-("walleye", 5, 1, 345600, 11.52),
-("walleye", 5, 1, 422400, 14.105),
-("walleye", 5, 1, 499200, 16.68),
-("walleye", 5, 1, 576000, 18.946),
-("walleye", 5, 1, 652800, 21.265),
-("walleye", 5, 1, 729600, 23.432),
-("walleye", 5, 1, 806400, 26.019),
-("walleye", 5, 1, 902400, 28.856),
-("walleye", 5, 1, 979200, 31.085),
-("walleye", 5, 1, 1056000, 33.615),
-("walleye", 5, 1, 1132800, 35.76),
-("walleye", 5, 1, 1190400, 40.608),
-("walleye", 5, 1, 1267200, 43.284),
-("walleye", 5, 1, 1344000, 47.347),
-("walleye", 5, 1, 1420800, 52.231),
-("walleye", 5, 1, 1497600, 57.225),
-("walleye", 5, 1, 1574400, 63.138),
-("walleye", 5, 1, 1651200, 69.251),
-("walleye", 5, 1, 1728000, 76.449),
-("walleye", 5, 1, 1804800, 84.71),
-("walleye", 5, 1, 1881600, 102.551),
-("walleye", 5, 1, 1958400, 107.115),
-("walleye", 5, 1, 2035200, 129.689),
-("walleye", 5, 1, 2112000, 135.832),
-("walleye", 5, 1, 2208000, 164.674),
-("walleye", 5, 1, 2265600, 180.279),
-("walleye", 5, 1, 2323200, 197.024),
-("walleye", 5, 1, 2342400, 204.511),
-("walleye", 5, 1, 2361600, 211.886),
-("walleye", 5, 1, 2457600, 212.147),
-("walleye", 6, 1, 300000, 10.722),
-("walleye", 6, 1, 345600, 11.52),
-("walleye", 6, 1, 422400, 14.105),
-("walleye", 6, 1, 499200, 16.68),
-("walleye", 6, 1, 576000, 18.946),
-("walleye", 6, 1, 652800, 21.265),
-("walleye", 6, 1, 729600, 23.432),
-("walleye", 6, 1, 806400, 26.019),
-("walleye", 6, 1, 902400, 28.856),
-("walleye", 6, 1, 979200, 31.085),
-("walleye", 6, 1, 1056000, 33.615),
-("walleye", 6, 1, 1132800, 35.76),
-("walleye", 6, 1, 1190400, 40.608),
-("walleye", 6, 1, 1267200, 43.284),
-("walleye", 6, 1, 1344000, 47.347),
-("walleye", 6, 1, 1420800, 52.231),
-("walleye", 6, 1, 1497600, 57.225),
-("walleye", 6, 1, 1574400, 63.138),
-("walleye", 6, 1, 1651200, 69.251),
-("walleye", 6, 1, 1728000, 76.449),
-("walleye", 6, 1, 1804800, 84.71),
-("walleye", 6, 1, 1881600, 102.551),
-("walleye", 6, 1, 1958400, 107.115),
-("walleye", 6, 1, 2035200, 129.689),
-("walleye", 6, 1, 2112000, 135.832),
-("walleye", 6, 1, 2208000, 164.674),
-("walleye", 6, 1, 2265600, 180.279),
-("walleye", 6, 1, 2323200, 197.024),
-("walleye", 6, 1, 2342400, 204.511),
-("walleye", 6, 1, 2361600, 211.886),
-("walleye", 6, 1, 2457600, 212.147),
-("walleye", 7, 1, 300000, 10.722),
-("walleye", 7, 1, 345600, 11.52),
-("walleye", 7, 1, 422400, 14.105),
-("walleye", 7, 1, 499200, 16.68),
-("walleye", 7, 1, 576000, 18.946),
-("walleye", 7, 1, 652800, 21.265),
-("walleye", 7, 1, 729600, 23.432),
-("walleye", 7, 1, 806400, 26.019),
-("walleye", 7, 1, 902400, 28.856),
-("walleye", 7, 1, 979200, 31.085),
-("walleye", 7, 1, 1056000, 33.615),
-("walleye", 7, 1, 1132800, 35.76),
-("walleye", 7, 1, 1190400, 40.608),
-("walleye", 7, 1, 1267200, 43.284),
-("walleye", 7, 1, 1344000, 47.347),
-("walleye", 7, 1, 1420800, 52.231),
-("walleye", 7, 1, 1497600, 57.225),
-("walleye", 7, 1, 1574400, 63.138),
-("walleye", 7, 1, 1651200, 69.251),
-("walleye", 7, 1, 1728000, 76.449),
-("walleye", 7, 1, 1804800, 84.71),
-("walleye", 7, 1, 1881600, 102.551),
-("walleye", 7, 1, 1958400, 107.115),
-("walleye", 7, 1, 2035200, 129.689),
-("walleye", 7, 1, 2112000, 135.832),
-("walleye", 7, 1, 2208000, 164.674),
-("walleye", 7, 1, 2265600, 180.279),
-("walleye", 7, 1, 2323200, 197.024),
-("walleye", 7, 1, 2342400, 204.511),
-("walleye", 7, 1, 2361600, 211.886),
-("walleye", 7, 1, 2457600, 212.147),
-("taimen", 0, 0, 300000, 3.685),
-("taimen", 0, 0, 364800, 3.598),
-("taimen", 0, 0, 441600, 3.621),
-("taimen", 0, 0, 518400, 4.202),
-("taimen", 0, 0, 595200, 4.935),
-("taimen", 0, 0, 672000, 5.633),
-("taimen", 0, 0, 748800, 6.216),
-("taimen", 0, 0, 825600, 6.71),
-("taimen", 0, 0, 883200, 7.557),
-("taimen", 0, 0, 960000, 8.687),
-("taimen", 0, 0, 1036800, 9.882),
-("taimen", 0, 0, 1094400, 10.95),
-("taimen", 0, 0, 1171200, 12.075),
-("taimen", 0, 0, 1248000, 12.875),
-("taimen", 0, 0, 1324800, 14.424),
-("taimen", 0, 0, 1401600, 15.653),
-("taimen", 0, 0, 1478400, 17.345),
-("taimen", 0, 0, 1555200, 18.71),
-("taimen", 0, 0, 1670400, 21.587),
-("taimen", 0, 0, 1747200, 25.43),
-("taimen", 0, 0, 1824000, 27.165),
-("taimen", 0, 0, 1900800, 31.671),
-("taimen", 1, 0, 300000, 3.685),
-("taimen", 1, 0, 364800, 3.598),
-("taimen", 1, 0, 441600, 3.621),
-("taimen", 1, 0, 518400, 4.202),
-("taimen", 1, 0, 595200, 4.935),
-("taimen", 1, 0, 672000, 5.633),
-("taimen", 1, 0, 748800, 6.216),
-("taimen", 1, 0, 825600, 6.71),
-("taimen", 1, 0, 883200, 7.557),
-("taimen", 1, 0, 960000, 8.687),
-("taimen", 1, 0, 1036800, 9.882),
-("taimen", 1, 0, 1094400, 10.95),
-("taimen", 1, 0, 1171200, 12.075),
-("taimen", 1, 0, 1248000, 12.875),
-("taimen", 1, 0, 1324800, 14.424),
-("taimen", 1, 0, 1401600, 15.653),
-("taimen", 1, 0, 1478400, 17.345),
-("taimen", 1, 0, 1555200, 18.71),
-("taimen", 1, 0, 1670400, 21.587),
-("taimen", 1, 0, 1747200, 25.43),
-("taimen", 1, 0, 1824000, 27.165),
-("taimen", 1, 0, 1900800, 31.671),
-("taimen", 2, 0, 300000, 3.685),
-("taimen", 2, 0, 364800, 3.598),
-("taimen", 2, 0, 441600, 3.621),
-("taimen", 2, 0, 518400, 4.202),
-("taimen", 2, 0, 595200, 4.935),
-("taimen", 2, 0, 672000, 5.633),
-("taimen", 2, 0, 748800, 6.216),
-("taimen", 2, 0, 825600, 6.71),
-("taimen", 2, 0, 883200, 7.557),
-("taimen", 2, 0, 960000, 8.687),
-("taimen", 2, 0, 1036800, 9.882),
-("taimen", 2, 0, 1094400, 10.95),
-("taimen", 2, 0, 1171200, 12.075),
-("taimen", 2, 0, 1248000, 12.875),
-("taimen", 2, 0, 1324800, 14.424),
-("taimen", 2, 0, 1401600, 15.653),
-("taimen", 2, 0, 1478400, 17.345),
-("taimen", 2, 0, 1555200, 18.71),
-("taimen", 2, 0, 1670400, 21.587),
-("taimen", 2, 0, 1747200, 25.43),
-("taimen", 2, 0, 1824000, 27.165),
-("taimen", 2, 0, 1900800, 31.671),
-("taimen", 3, 0, 300000, 3.685),
-("taimen", 3, 0, 364800, 3.598),
-("taimen", 3, 0, 441600, 3.621),
-("taimen", 3, 0, 518400, 4.202),
-("taimen", 3, 0, 595200, 4.935),
-("taimen", 3, 0, 672000, 5.633),
-("taimen", 3, 0, 748800, 6.216),
-("taimen", 3, 0, 825600, 6.71),
-("taimen", 3, 0, 883200, 7.557),
-("taimen", 3, 0, 960000, 8.687),
-("taimen", 3, 0, 1036800, 9.882),
-("taimen", 3, 0, 1094400, 10.95),
-("taimen", 3, 0, 1171200, 12.075),
-("taimen", 3, 0, 1248000, 12.875),
-("taimen", 3, 0, 1324800, 14.424),
-("taimen", 3, 0, 1401600, 15.653),
-("taimen", 3, 0, 1478400, 17.345),
-("taimen", 3, 0, 1555200, 18.71),
-("taimen", 3, 0, 1670400, 21.587),
-("taimen", 3, 0, 1747200, 25.43),
-("taimen", 3, 0, 1824000, 27.165),
-("taimen", 3, 0, 1900800, 31.671),
-("taimen", 4, 1, 300000, 10.722),
-("taimen", 4, 1, 345600, 11.52),
-("taimen", 4, 1, 422400, 14.105),
-("taimen", 4, 1, 499200, 16.68),
-("taimen", 4, 1, 576000, 18.946),
-("taimen", 4, 1, 652800, 21.265),
-("taimen", 4, 1, 729600, 23.432),
-("taimen", 4, 1, 806400, 26.019),
-("taimen", 4, 1, 902400, 28.856),
-("taimen", 4, 1, 979200, 31.085),
-("taimen", 4, 1, 1056000, 33.615),
-("taimen", 4, 1, 1132800, 35.76),
-("taimen", 4, 1, 1190400, 40.608),
-("taimen", 4, 1, 1267200, 43.284),
-("taimen", 4, 1, 1344000, 47.347),
-("taimen", 4, 1, 1420800, 52.231),
-("taimen", 4, 1, 1497600, 57.225),
-("taimen", 4, 1, 1574400, 63.138),
-("taimen", 4, 1, 1651200, 69.251),
-("taimen", 4, 1, 1728000, 76.449),
-("taimen", 4, 1, 1804800, 84.71),
-("taimen", 4, 1, 1881600, 102.551),
-("taimen", 4, 1, 1958400, 107.115),
-("taimen", 4, 1, 2035200, 129.689),
-("taimen", 4, 1, 2112000, 135.832),
-("taimen", 4, 1, 2208000, 164.674),
-("taimen", 4, 1, 2265600, 180.279),
-("taimen", 4, 1, 2323200, 197.024),
-("taimen", 4, 1, 2342400, 204.511),
-("taimen", 4, 1, 2361600, 211.886),
-("taimen", 4, 1, 2457600, 212.147),
-("taimen", 5, 1, 300000, 10.722),
-("taimen", 5, 1, 345600, 11.52),
-("taimen", 5, 1, 422400, 14.105),
-("taimen", 5, 1, 499200, 16.68),
-("taimen", 5, 1, 576000, 18.946),
-("taimen", 5, 1, 652800, 21.265),
-("taimen", 5, 1, 729600, 23.432),
-("taimen", 5, 1, 806400, 26.019),
-("taimen", 5, 1, 902400, 28.856),
-("taimen", 5, 1, 979200, 31.085),
-("taimen", 5, 1, 1056000, 33.615),
-("taimen", 5, 1, 1132800, 35.76),
-("taimen", 5, 1, 1190400, 40.608),
-("taimen", 5, 1, 1267200, 43.284),
-("taimen", 5, 1, 1344000, 47.347),
-("taimen", 5, 1, 1420800, 52.231),
-("taimen", 5, 1, 1497600, 57.225),
-("taimen", 5, 1, 1574400, 63.138),
-("taimen", 5, 1, 1651200, 69.251),
-("taimen", 5, 1, 1728000, 76.449),
-("taimen", 5, 1, 1804800, 84.71),
-("taimen", 5, 1, 1881600, 102.551),
-("taimen", 5, 1, 1958400, 107.115),
-("taimen", 5, 1, 2035200, 129.689),
-("taimen", 5, 1, 2112000, 135.832),
-("taimen", 5, 1, 2208000, 164.674),
-("taimen", 5, 1, 2265600, 180.279),
-("taimen", 5, 1, 2323200, 197.024),
-("taimen", 5, 1, 2342400, 204.511),
-("taimen", 5, 1, 2361600, 211.886),
-("taimen", 5, 1, 2457600, 212.147),
-("taimen", 6, 1, 300000, 10.722),
-("taimen", 6, 1, 345600, 11.52),
-("taimen", 6, 1, 422400, 14.105),
-("taimen", 6, 1, 499200, 16.68),
-("taimen", 6, 1, 576000, 18.946),
-("taimen", 6, 1, 652800, 21.265),
-("taimen", 6, 1, 729600, 23.432),
-("taimen", 6, 1, 806400, 26.019),
-("taimen", 6, 1, 902400, 28.856),
-("taimen", 6, 1, 979200, 31.085),
-("taimen", 6, 1, 1056000, 33.615),
-("taimen", 6, 1, 1132800, 35.76),
-("taimen", 6, 1, 1190400, 40.608),
-("taimen", 6, 1, 1267200, 43.284),
-("taimen", 6, 1, 1344000, 47.347),
-("taimen", 6, 1, 1420800, 52.231),
-("taimen", 6, 1, 1497600, 57.225),
-("taimen", 6, 1, 1574400, 63.138),
-("taimen", 6, 1, 1651200, 69.251),
-("taimen", 6, 1, 1728000, 76.449),
-("taimen", 6, 1, 1804800, 84.71),
-("taimen", 6, 1, 1881600, 102.551),
-("taimen", 6, 1, 1958400, 107.115),
-("taimen", 6, 1, 2035200, 129.689),
-("taimen", 6, 1, 2112000, 135.832),
-("taimen", 6, 1, 2208000, 164.674),
-("taimen", 6, 1, 2265600, 180.279),
-("taimen", 6, 1, 2323200, 197.024),
-("taimen", 6, 1, 2342400, 204.511),
-("taimen", 6, 1, 2361600, 211.886),
-("taimen", 6, 1, 2457600, 212.147),
-("taimen", 7, 1, 300000, 10.722),
-("taimen", 7, 1, 345600, 11.52),
-("taimen", 7, 1, 422400, 14.105),
-("taimen", 7, 1, 499200, 16.68),
-("taimen", 7, 1, 576000, 18.946),
-("taimen", 7, 1, 652800, 21.265),
-("taimen", 7, 1, 729600, 23.432),
-("taimen", 7, 1, 806400, 26.019),
-("taimen", 7, 1, 902400, 28.856),
-("taimen", 7, 1, 979200, 31.085),
-("taimen", 7, 1, 1056000, 33.615),
-("taimen", 7, 1, 1132800, 35.76),
-("taimen", 7, 1, 1190400, 40.608),
-("taimen", 7, 1, 1267200, 43.284),
-("taimen", 7, 1, 1344000, 47.347),
-("taimen", 7, 1, 1420800, 52.231),
-("taimen", 7, 1, 1497600, 57.225),
-("taimen", 7, 1, 1574400, 63.138),
-("taimen", 7, 1, 1651200, 69.251),
-("taimen", 7, 1, 1728000, 76.449),
-("taimen", 7, 1, 1804800, 84.71),
-("taimen", 7, 1, 1881600, 102.551),
-("taimen", 7, 1, 1958400, 107.115),
-("taimen", 7, 1, 2035200, 129.689),
-("taimen", 7, 1, 2112000, 135.832),
-("taimen", 7, 1, 2208000, 164.674),
-("taimen", 7, 1, 2265600, 180.279),
-("taimen", 7, 1, 2323200, 197.024),
-("taimen", 7, 1, 2342400, 204.511),
-("taimen", 7, 1, 2361600, 211.886),
-("taimen", 7, 1, 2457600, 212.147),
-("crosshatch", 0, 0, 300000, 2.27),
-("crosshatch", 0, 0, 403200, 3.63),
-("crosshatch", 0, 0, 480000, 4.36),
-("crosshatch", 0, 0, 576000, 5.21),
-("crosshatch", 0, 0, 652800, 5.47),
-("crosshatch", 0, 0, 748800, 6.74),
-("crosshatch", 0, 0, 825600, 7.69),
-("crosshatch", 0, 0, 902400, 8.57),
-("crosshatch", 0, 0, 979200, 9.42),
-("crosshatch", 0, 0, 1056000, 10.41),
-("crosshatch", 0, 0, 1132800, 11.56),
-("crosshatch", 0, 0, 1228800, 12.87),
-("crosshatch", 0, 0, 1324800, 14.61),
-("crosshatch", 0, 0, 1420800, 16.49),
-("crosshatch", 0, 0, 1516800, 18.9),
-("crosshatch", 0, 0, 1612800, 21.62),
-("crosshatch", 0, 0, 1689600, 24.47),
-("crosshatch", 0, 0, 1766400, 26.45),
-("crosshatch", 1, 0, 300000, 2.27),
-("crosshatch", 1, 0, 403200, 3.63),
-("crosshatch", 1, 0, 480000, 4.36),
-("crosshatch", 1, 0, 576000, 5.21),
-("crosshatch", 1, 0, 652800, 5.47),
-("crosshatch", 1, 0, 748800, 6.74),
-("crosshatch", 1, 0, 825600, 7.69),
-("crosshatch", 1, 0, 902400, 8.57),
-("crosshatch", 1, 0, 979200, 9.42),
-("crosshatch", 1, 0, 1056000, 10.41),
-("crosshatch", 1, 0, 1132800, 11.56),
-("crosshatch", 1, 0, 1228800, 12.87),
-("crosshatch", 1, 0, 1324800, 14.61),
-("crosshatch", 1, 0, 1420800, 16.49),
-("crosshatch", 1, 0, 1516800, 18.9),
-("crosshatch", 1, 0, 1612800, 21.62),
-("crosshatch", 1, 0, 1689600, 24.47),
-("crosshatch", 1, 0, 1766400, 26.45),
-("crosshatch", 2, 0, 300000, 2.27),
-("crosshatch", 2, 0, 403200, 3.63),
-("crosshatch", 2, 0, 480000, 4.36),
-("crosshatch", 2, 0, 576000, 5.21),
-("crosshatch", 2, 0, 652800, 5.47),
-("crosshatch", 2, 0, 748800, 6.74),
-("crosshatch", 2, 0, 825600, 7.69),
-("crosshatch", 2, 0, 902400, 8.57),
-("crosshatch", 2, 0, 979200, 9.42),
-("crosshatch", 2, 0, 1056000, 10.41),
-("crosshatch", 2, 0, 1132800, 11.56),
-("crosshatch", 2, 0, 1228800, 12.87),
-("crosshatch", 2, 0, 1324800, 14.61),
-("crosshatch", 2, 0, 1420800, 16.49),
-("crosshatch", 2, 0, 1516800, 18.9),
-("crosshatch", 2, 0, 1612800, 21.62),
-("crosshatch", 2, 0, 1689600, 24.47),
-("crosshatch", 2, 0, 1766400, 26.45),
-("crosshatch", 3, 0, 300000, 2.27),
-("crosshatch", 3, 0, 403200, 3.63),
-("crosshatch", 3, 0, 480000, 4.36),
-("crosshatch", 3, 0, 576000, 5.21),
-("crosshatch", 3, 0, 652800, 5.47),
-("crosshatch", 3, 0, 748800, 6.74),
-("crosshatch", 3, 0, 825600, 7.69),
-("crosshatch", 3, 0, 902400, 8.57),
-("crosshatch", 3, 0, 979200, 9.42),
-("crosshatch", 3, 0, 1056000, 10.41),
-("crosshatch", 3, 0, 1132800, 11.56),
-("crosshatch", 3, 0, 1228800, 12.87),
-("crosshatch", 3, 0, 1324800, 14.61),
-("crosshatch", 3, 0, 1420800, 16.49),
-("crosshatch", 3, 0, 1516800, 18.9),
-("crosshatch", 3, 0, 1612800, 21.62),
-("crosshatch", 3, 0, 1689600, 24.47),
-("crosshatch", 3, 0, 1766400, 26.45),
-("crosshatch", 4, 1, 825600, 28.88),
-("crosshatch", 4, 1, 902400, 32.4),
-("crosshatch", 4, 1, 979200, 36.46),
-("crosshatch", 4, 1, 1056000, 39.99),
-("crosshatch", 4, 1, 1209600, 47.23),
-("crosshatch", 4, 1, 1286400, 51.39),
-("crosshatch", 4, 1, 1363200, 56.9),
-("crosshatch", 4, 1, 1459200, 64.26),
-("crosshatch", 4, 1, 1536000, 69.65),
-("crosshatch", 4, 1, 1612800, 75.14),
-("crosshatch", 4, 1, 1689600, 83.16),
-("crosshatch", 4, 1, 1766400, 91.75),
-("crosshatch", 4, 1, 1843200, 100.66),
-("crosshatch", 4, 1, 1920000, 111.45),
-("crosshatch", 4, 1, 1996800, 122.23),
-("crosshatch", 4, 1, 2092800, 143.54),
-("crosshatch", 4, 1, 2169600, 147.54),
-("crosshatch", 4, 1, 2246400, 153.09),
-("crosshatch", 4, 1, 2323200, 166.44),
-("crosshatch", 4, 1, 2400000, 184.69),
-("crosshatch", 4, 1, 2476800, 204.14),
-("crosshatch", 4, 1, 2553600, 223.37),
-("crosshatch", 4, 1, 2649600, 253.77),
-("crosshatch", 5, 1, 825600, 28.88),
-("crosshatch", 5, 1, 902400, 32.4),
-("crosshatch", 5, 1, 979200, 36.46),
-("crosshatch", 5, 1, 1056000, 39.99),
-("crosshatch", 5, 1, 1209600, 47.23),
-("crosshatch", 5, 1, 1286400, 51.39),
-("crosshatch", 5, 1, 1363200, 56.9),
-("crosshatch", 5, 1, 1459200, 64.26),
-("crosshatch", 5, 1, 1536000, 69.65),
-("crosshatch", 5, 1, 1612800, 75.14),
-("crosshatch", 5, 1, 1689600, 83.16),
-("crosshatch", 5, 1, 1766400, 91.75),
-("crosshatch", 5, 1, 1843200, 100.66),
-("crosshatch", 5, 1, 1920000, 111.45),
-("crosshatch", 5, 1, 1996800, 122.23),
-("crosshatch", 5, 1, 2092800, 143.54),
-("crosshatch", 5, 1, 2169600, 147.54),
-("crosshatch", 5, 1, 2246400, 153.09),
-("crosshatch", 5, 1, 2323200, 166.44),
-("crosshatch", 5, 1, 2400000, 184.69),
-("crosshatch", 5, 1, 2476800, 204.14),
-("crosshatch", 5, 1, 2553600, 223.37),
-("crosshatch", 5, 1, 2649600, 253.77),
-("crosshatch", 6, 1, 825600, 28.88),
-("crosshatch", 6, 1, 902400, 32.4),
-("crosshatch", 6, 1, 979200, 36.46),
-("crosshatch", 6, 1, 1056000, 39.99),
-("crosshatch", 6, 1, 1209600, 47.23),
-("crosshatch", 6, 1, 1286400, 51.39),
-("crosshatch", 6, 1, 1363200, 56.9),
-("crosshatch", 6, 1, 1459200, 64.26),
-("crosshatch", 6, 1, 1536000, 69.65),
-("crosshatch", 6, 1, 1612800, 75.14),
-("crosshatch", 6, 1, 1689600, 83.16),
-("crosshatch", 6, 1, 1766400, 91.75),
-("crosshatch", 6, 1, 1843200, 100.66),
-("crosshatch", 6, 1, 1920000, 111.45),
-("crosshatch", 6, 1, 1996800, 122.23),
-("crosshatch", 6, 1, 2092800, 143.54),
-("crosshatch", 6, 1, 2169600, 147.54),
-("crosshatch", 6, 1, 2246400, 153.09),
-("crosshatch", 6, 1, 2323200, 166.44),
-("crosshatch", 6, 1, 2400000, 184.69),
-("crosshatch", 6, 1, 2476800, 204.14),
-("crosshatch", 6, 1, 2553600, 223.37),
-("crosshatch", 6, 1, 2649600, 253.77),
-("crosshatch", 7, 1, 825600, 28.88),
-("crosshatch", 7, 1, 902400, 32.4),
-("crosshatch", 7, 1, 979200, 36.46),
-("crosshatch", 7, 1, 1056000, 39.99),
-("crosshatch", 7, 1, 1209600, 47.23),
-("crosshatch", 7, 1, 1286400, 51.39),
-("crosshatch", 7, 1, 1363200, 56.9),
-("crosshatch", 7, 1, 1459200, 64.26),
-("crosshatch", 7, 1, 1536000, 69.65),
-("crosshatch", 7, 1, 1612800, 75.14),
-("crosshatch", 7, 1, 1689600, 83.16),
-("crosshatch", 7, 1, 1766400, 91.75),
-("crosshatch", 7, 1, 1843200, 100.66),
-("crosshatch", 7, 1, 1920000, 111.45),
-("crosshatch", 7, 1, 1996800, 122.23),
-("crosshatch", 7, 1, 2092800, 143.54),
-("crosshatch", 7, 1, 2169600, 147.54),
-("crosshatch", 7, 1, 2246400, 153.09),
-("crosshatch", 7, 1, 2323200, 166.44),
-("crosshatch", 7, 1, 2400000, 184.69),
-("crosshatch", 7, 1, 2476800, 204.14),
-("crosshatch", 7, 1, 2553600, 223.37),
-("crosshatch", 7, 1, 2649600, 253.77),
-("blueline", 0, 0, 300000, 2.27),
-("blueline", 0, 0, 403200, 3.63),
-("blueline", 0, 0, 480000, 4.36),
-("blueline", 0, 0, 576000, 5.21),
-("blueline", 0, 0, 652800, 5.47),
-("blueline", 0, 0, 748800, 6.74),
-("blueline", 0, 0, 825600, 7.69),
-("blueline", 0, 0, 902400, 8.57),
-("blueline", 0, 0, 979200, 9.42),
-("blueline", 0, 0, 1056000, 10.41),
-("blueline", 0, 0, 1132800, 11.56),
-("blueline", 0, 0, 1228800, 12.87),
-("blueline", 0, 0, 1324800, 14.61),
-("blueline", 0, 0, 1420800, 16.49),
-("blueline", 0, 0, 1516800, 18.9),
-("blueline", 0, 0, 1612800, 21.62),
-("blueline", 0, 0, 1689600, 24.47),
-("blueline", 0, 0, 1766400, 26.45),
-("blueline", 1, 0, 300000, 2.27),
-("blueline", 1, 0, 403200, 3.63),
-("blueline", 1, 0, 480000, 4.36),
-("blueline", 1, 0, 576000, 5.21),
-("blueline", 1, 0, 652800, 5.47),
-("blueline", 1, 0, 748800, 6.74),
-("blueline", 1, 0, 825600, 7.69),
-("blueline", 1, 0, 902400, 8.57),
-("blueline", 1, 0, 979200, 9.42),
-("blueline", 1, 0, 1056000, 10.41),
-("blueline", 1, 0, 1132800, 11.56),
-("blueline", 1, 0, 1228800, 12.87),
-("blueline", 1, 0, 1324800, 14.61),
-("blueline", 1, 0, 1420800, 16.49),
-("blueline", 1, 0, 1516800, 18.9),
-("blueline", 1, 0, 1612800, 21.62),
-("blueline", 1, 0, 1689600, 24.47),
-("blueline", 1, 0, 1766400, 26.45),
-("blueline", 2, 0, 300000, 2.27),
-("blueline", 2, 0, 403200, 3.63),
-("blueline", 2, 0, 480000, 4.36),
-("blueline", 2, 0, 576000, 5.21),
-("blueline", 2, 0, 652800, 5.47),
-("blueline", 2, 0, 748800, 6.74),
-("blueline", 2, 0, 825600, 7.69),
-("blueline", 2, 0, 902400, 8.57),
-("blueline", 2, 0, 979200, 9.42),
-("blueline", 2, 0, 1056000, 10.41),
-("blueline", 2, 0, 1132800, 11.56),
-("blueline", 2, 0, 1228800, 12.87),
-("blueline", 2, 0, 1324800, 14.61),
-("blueline", 2, 0, 1420800, 16.49),
-("blueline", 2, 0, 1516800, 18.9),
-("blueline", 2, 0, 1612800, 21.62),
-("blueline", 2, 0, 1689600, 24.47),
-("blueline", 2, 0, 1766400, 26.45),
-("blueline", 3, 0, 300000, 2.27),
-("blueline", 3, 0, 403200, 3.63),
-("blueline", 3, 0, 480000, 4.36),
-("blueline", 3, 0, 576000, 5.21),
-("blueline", 3, 0, 652800, 5.47),
-("blueline", 3, 0, 748800, 6.74),
-("blueline", 3, 0, 825600, 7.69),
-("blueline", 3, 0, 902400, 8.57),
-("blueline", 3, 0, 979200, 9.42),
-("blueline", 3, 0, 1056000, 10.41),
-("blueline", 3, 0, 1132800, 11.56),
-("blueline", 3, 0, 1228800, 12.87),
-("blueline", 3, 0, 1324800, 14.61),
-("blueline", 3, 0, 1420800, 16.49),
-("blueline", 3, 0, 1516800, 18.9),
-("blueline", 3, 0, 1612800, 21.62),
-("blueline", 3, 0, 1689600, 24.47),
-("blueline", 3, 0, 1766400, 26.45),
-("blueline", 4, 1, 825600, 28.88),
-("blueline", 4, 1, 902400, 32.4),
-("blueline", 4, 1, 979200, 36.46),
-("blueline", 4, 1, 1056000, 39.99),
-("blueline", 4, 1, 1209600, 47.23),
-("blueline", 4, 1, 1286400, 51.39),
-("blueline", 4, 1, 1363200, 56.9),
-("blueline", 4, 1, 1459200, 64.26),
-("blueline", 4, 1, 1536000, 69.65),
-("blueline", 4, 1, 1612800, 75.14),
-("blueline", 4, 1, 1689600, 83.16),
-("blueline", 4, 1, 1766400, 91.75),
-("blueline", 4, 1, 1843200, 100.66),
-("blueline", 4, 1, 1920000, 111.45),
-("blueline", 4, 1, 1996800, 122.23),
-("blueline", 4, 1, 2092800, 143.54),
-("blueline", 4, 1, 2169600, 147.54),
-("blueline", 4, 1, 2246400, 153.09),
-("blueline", 4, 1, 2323200, 166.44),
-("blueline", 4, 1, 2400000, 184.69),
-("blueline", 4, 1, 2476800, 204.14),
-("blueline", 4, 1, 2553600, 223.37),
-("blueline", 4, 1, 2649600, 253.77),
-("blueline", 5, 1, 825600, 28.88),
-("blueline", 5, 1, 902400, 32.4),
-("blueline", 5, 1, 979200, 36.46),
-("blueline", 5, 1, 1056000, 39.99),
-("blueline", 5, 1, 1209600, 47.23),
-("blueline", 5, 1, 1286400, 51.39),
-("blueline", 5, 1, 1363200, 56.9),
-("blueline", 5, 1, 1459200, 64.26),
-("blueline", 5, 1, 1536000, 69.65),
-("blueline", 5, 1, 1612800, 75.14),
-("blueline", 5, 1, 1689600, 83.16),
-("blueline", 5, 1, 1766400, 91.75),
-("blueline", 5, 1, 1843200, 100.66),
-("blueline", 5, 1, 1920000, 111.45),
-("blueline", 5, 1, 1996800, 122.23),
-("blueline", 5, 1, 2092800, 143.54),
-("blueline", 5, 1, 2169600, 147.54),
-("blueline", 5, 1, 2246400, 153.09),
-("blueline", 5, 1, 2323200, 166.44),
-("blueline", 5, 1, 2400000, 184.69),
-("blueline", 5, 1, 2476800, 204.14),
-("blueline", 5, 1, 2553600, 223.37),
-("blueline", 5, 1, 2649600, 253.77),
-("blueline", 6, 1, 825600, 28.88),
-("blueline", 6, 1, 902400, 32.4),
-("blueline", 6, 1, 979200, 36.46),
-("blueline", 6, 1, 1056000, 39.99),
-("blueline", 6, 1, 1209600, 47.23),
-("blueline", 6, 1, 1286400, 51.39),
-("blueline", 6, 1, 1363200, 56.9),
-("blueline", 6, 1, 1459200, 64.26),
-("blueline", 6, 1, 1536000, 69.65),
-("blueline", 6, 1, 1612800, 75.14),
-("blueline", 6, 1, 1689600, 83.16),
-("blueline", 6, 1, 1766400, 91.75),
-("blueline", 6, 1, 1843200, 100.66),
-("blueline", 6, 1, 1920000, 111.45),
-("blueline", 6, 1, 1996800, 122.23),
-("blueline", 6, 1, 2092800, 143.54),
-("blueline", 6, 1, 2169600, 147.54),
-("blueline", 6, 1, 2246400, 153.09),
-("blueline", 6, 1, 2323200, 166.44),
-("blueline", 6, 1, 2400000, 184.69),
-("blueline", 6, 1, 2476800, 204.14),
-("blueline", 6, 1, 2553600, 223.37),
-("blueline", 6, 1, 2649600, 253.77),
-("blueline", 7, 1, 825600, 28.88),
-("blueline", 7, 1, 902400, 32.4),
-("blueline", 7, 1, 979200, 36.46),
-("blueline", 7, 1, 1056000, 39.99),
-("blueline", 7, 1, 1209600, 47.23),
-("blueline", 7, 1, 1286400, 51.39),
-("blueline", 7, 1, 1363200, 56.9),
-("blueline", 7, 1, 1459200, 64.26),
-("blueline", 7, 1, 1536000, 69.65),
-("blueline", 7, 1, 1612800, 75.14),
-("blueline", 7, 1, 1689600, 83.16),
-("blueline", 7, 1, 1766400, 91.75),
-("blueline", 7, 1, 1843200, 100.66),
-("blueline", 7, 1, 1920000, 111.45),
-("blueline", 7, 1, 1996800, 122.23),
-("blueline", 7, 1, 2092800, 143.54),
-("blueline", 7, 1, 2169600, 147.54),
-("blueline", 7, 1, 2246400, 153.09),
-("blueline", 7, 1, 2323200, 166.44),
-("blueline", 7, 1, 2400000, 184.69),
-("blueline", 7, 1, 2476800, 204.14),
-("blueline", 7, 1, 2553600, 223.37),
-("blueline", 7, 1, 2649600, 253.77),
-("bonito", 0, 0, 300000, 15.2466666667),
-("bonito", 0, 0, 576000, 18.2166666667),
-("bonito", 0, 0, 748800, 20.1866666667),
-("bonito", 0, 0, 998400, 23.29),
-("bonito", 0, 0, 1209600, 25.0116666667),
-("bonito", 0, 0, 1324800, 28.485),
-("bonito", 0, 0, 1516800, 31.6866666667),
-("bonito", 0, 0, 1708800, 35.79),
-("bonito", 1, 0, 300000, 15.2466666667),
-("bonito", 1, 0, 576000, 18.2166666667),
-("bonito", 1, 0, 748800, 20.1866666667),
-("bonito", 1, 0, 998400, 23.29),
-("bonito", 1, 0, 1209600, 25.0116666667),
-("bonito", 1, 0, 1324800, 28.485),
-("bonito", 1, 0, 1516800, 31.6866666667),
-("bonito", 1, 0, 1708800, 35.79),
-("bonito", 2, 0, 300000, 15.2466666667),
-("bonito", 2, 0, 576000, 18.2166666667),
-("bonito", 2, 0, 748800, 20.1866666667),
-("bonito", 2, 0, 998400, 23.29),
-("bonito", 2, 0, 1209600, 25.0116666667),
-("bonito", 2, 0, 1324800, 28.485),
-("bonito", 2, 0, 1516800, 31.6866666667),
-("bonito", 2, 0, 1708800, 35.79),
-("bonito", 3, 0, 300000, 15.2466666667),
-("bonito", 3, 0, 576000, 18.2166666667),
-("bonito", 3, 0, 748800, 20.1866666667),
-("bonito", 3, 0, 998400, 23.29),
-("bonito", 3, 0, 1209600, 25.0116666667),
-("bonito", 3, 0, 1324800, 28.485),
-("bonito", 3, 0, 1516800, 31.6866666667),
-("bonito", 3, 0, 1708800, 35.79),
-("bonito", 4, 0, 300000, 15.2466666667),
-("bonito", 4, 0, 576000, 18.2166666667),
-("bonito", 4, 0, 748800, 20.1866666667),
-("bonito", 4, 0, 998400, 23.29),
-("bonito", 4, 0, 1209600, 25.0116666667),
-("bonito", 4, 0, 1324800, 28.485),
-("bonito", 4, 0, 1516800, 31.6866666667),
-("bonito", 4, 0, 1708800, 35.79),
-("bonito", 5, 0, 300000, 15.2466666667),
-("bonito", 5, 0, 576000, 18.2166666667),
-("bonito", 5, 0, 748800, 20.1866666667),
-("bonito", 5, 0, 998400, 23.29),
-("bonito", 5, 0, 1209600, 25.0116666667),
-("bonito", 5, 0, 1324800, 28.485),
-("bonito", 5, 0, 1516800, 31.6866666667),
-("bonito", 5, 0, 1708800, 35.79),
-("bonito", 6, 1, 300000, 24.06),
-("bonito", 6, 1, 652800, 27.56),
-("bonito", 6, 1, 825600, 29.0),
-("bonito", 6, 1, 979200, 31.675),
-("bonito", 6, 1, 1132800, 34.53),
-("bonito", 6, 1, 1363200, 38.885),
-("bonito", 6, 1, 1536000, 43.075),
-("bonito", 6, 1, 1747200, 48.705),
-("bonito", 6, 1, 1843200, 64.57),
-("bonito", 6, 1, 1996800, 69.805),
-("bonito", 6, 1, 2016000, 76.545),
-("bonito", 7, 1, 300000, 24.06),
-("bonito", 7, 1, 652800, 27.56),
-("bonito", 7, 1, 825600, 29.0),
-("bonito", 7, 1, 979200, 31.675),
-("bonito", 7, 1, 1132800, 34.53),
-("bonito", 7, 1, 1363200, 38.885),
-("bonito", 7, 1, 1536000, 43.075),
-("bonito", 7, 1, 1747200, 48.705),
-("bonito", 7, 1, 1843200, 64.57),
-("bonito", 7, 1, 1996800, 69.805),
-("bonito", 7, 1, 2016000, 76.545),
-("sargo", 0, 0, 300000, 15.2466666667),
-("sargo", 0, 0, 576000, 18.2166666667),
-("sargo", 0, 0, 748800, 20.1866666667),
-("sargo", 0, 0, 998400, 23.29),
-("sargo", 0, 0, 1209600, 25.0116666667),
-("sargo", 0, 0, 1324800, 28.485),
-("sargo", 0, 0, 1516800, 31.6866666667),
-("sargo", 0, 0, 1708800, 35.79),
-("sargo", 1, 0, 300000, 15.2466666667),
-("sargo", 1, 0, 576000, 18.2166666667),
-("sargo", 1, 0, 748800, 20.1866666667),
-("sargo", 1, 0, 998400, 23.29),
-("sargo", 1, 0, 1209600, 25.0116666667),
-("sargo", 1, 0, 1324800, 28.485),
-("sargo", 1, 0, 1516800, 31.6866666667),
-("sargo", 1, 0, 1708800, 35.79),
-("sargo", 2, 0, 300000, 15.2466666667),
-("sargo", 2, 0, 576000, 18.2166666667),
-("sargo", 2, 0, 748800, 20.1866666667),
-("sargo", 2, 0, 998400, 23.29),
-("sargo", 2, 0, 1209600, 25.0116666667),
-("sargo", 2, 0, 1324800, 28.485),
-("sargo", 2, 0, 1516800, 31.6866666667),
-("sargo", 2, 0, 1708800, 35.79),
-("sargo", 3, 0, 300000, 15.2466666667),
-("sargo", 3, 0, 576000, 18.2166666667),
-("sargo", 3, 0, 748800, 20.1866666667),
-("sargo", 3, 0, 998400, 23.29),
-("sargo", 3, 0, 1209600, 25.0116666667),
-("sargo", 3, 0, 1324800, 28.485),
-("sargo", 3, 0, 1516800, 31.6866666667),
-("sargo", 3, 0, 1708800, 35.79),
-("sargo", 4, 0, 300000, 15.2466666667),
-("sargo", 4, 0, 576000, 18.2166666667),
-("sargo", 4, 0, 748800, 20.1866666667),
-("sargo", 4, 0, 998400, 23.29),
-("sargo", 4, 0, 1209600, 25.0116666667),
-("sargo", 4, 0, 1324800, 28.485),
-("sargo", 4, 0, 1516800, 31.6866666667),
-("sargo", 4, 0, 1708800, 35.79),
-("sargo", 5, 0, 300000, 15.2466666667),
-("sargo", 5, 0, 576000, 18.2166666667),
-("sargo", 5, 0, 748800, 20.1866666667),
-("sargo", 5, 0, 998400, 23.29),
-("sargo", 5, 0, 1209600, 25.0116666667),
-("sargo", 5, 0, 1324800, 28.485),
-("sargo", 5, 0, 1516800, 31.6866666667),
-("sargo", 5, 0, 1708800, 35.79),
-("sargo", 6, 1, 300000, 24.06),
-("sargo", 6, 1, 652800, 27.56),
-("sargo", 6, 1, 825600, 29.0),
-("sargo", 6, 1, 979200, 31.675),
-("sargo", 6, 1, 1132800, 34.53),
-("sargo", 6, 1, 1363200, 38.885),
-("sargo", 6, 1, 1536000, 43.075),
-("sargo", 6, 1, 1747200, 48.705),
-("sargo", 6, 1, 1843200, 64.57),
-("sargo", 6, 1, 1996800, 69.805),
-("sargo", 6, 1, 2016000, 76.545),
-("sargo", 7, 1, 300000, 24.06),
-("sargo", 7, 1, 652800, 27.56),
-("sargo", 7, 1, 825600, 29.0),
-("sargo", 7, 1, 979200, 31.675),
-("sargo", 7, 1, 1132800, 34.53),
-("sargo", 7, 1, 1363200, 38.885),
-("sargo", 7, 1, 1536000, 43.075),
-("sargo", 7, 1, 1747200, 48.705),
-("sargo", 7, 1, 1843200, 64.57),
-("sargo", 7, 1, 1996800, 69.805),
-("sargo", 7, 1, 2016000, 76.545),
-("coral", 0, 0, 300000, 9.86),
-("coral", 0, 0, 403200, 10.335),
-("coral", 0, 0, 499200, 10.8925),
-("coral", 0, 0, 576000, 11.37),
-("coral", 0, 0, 672000, 11.8),
-("coral", 0, 0, 768000, 12.41),
-("coral", 0, 0, 844800, 12.97),
-("coral", 0, 0, 940800, 13.335),
-("coral", 0, 0, 1036800, 14.1725),
-("coral", 0, 0, 1113600, 14.695),
-("coral", 0, 0, 1209600, 15.3525),
-("coral", 0, 0, 1305600, 16.2775),
-("coral", 0, 0, 1382400, 16.8725),
-("coral", 0, 0, 1478400, 17.6525),
-("coral", 0, 0, 1555200, 18.0975),
-("coral", 0, 0, 1632000, 18.8575),
-("coral", 0, 0, 1708800, 20.0525),
-("coral", 0, 0, 1785600, 21.2625),
-("coral", 1, 0, 300000, 9.86),
-("coral", 1, 0, 403200, 10.335),
-("coral", 1, 0, 499200, 10.8925),
-("coral", 1, 0, 576000, 11.37),
-("coral", 1, 0, 672000, 11.8),
-("coral", 1, 0, 768000, 12.41),
-("coral", 1, 0, 844800, 12.97),
-("coral", 1, 0, 940800, 13.335),
-("coral", 1, 0, 1036800, 14.1725),
-("coral", 1, 0, 1113600, 14.695),
-("coral", 1, 0, 1209600, 15.3525),
-("coral", 1, 0, 1305600, 16.2775),
-("coral", 1, 0, 1382400, 16.8725),
-("coral", 1, 0, 1478400, 17.6525),
-("coral", 1, 0, 1555200, 18.0975),
-("coral", 1, 0, 1632000, 18.8575),
-("coral", 1, 0, 1708800, 20.0525),
-("coral", 1, 0, 1785600, 21.2625),
-("coral", 2, 0, 300000, 9.86),
-("coral", 2, 0, 403200, 10.335),
-("coral", 2, 0, 499200, 10.8925),
-("coral", 2, 0, 576000, 11.37),
-("coral", 2, 0, 672000, 11.8),
-("coral", 2, 0, 768000, 12.41),
-("coral", 2, 0, 844800, 12.97),
-("coral", 2, 0, 940800, 13.335),
-("coral", 2, 0, 1036800, 14.1725),
-("coral", 2, 0, 1113600, 14.695),
-("coral", 2, 0, 1209600, 15.3525),
-("coral", 2, 0, 1305600, 16.2775),
-("coral", 2, 0, 1382400, 16.8725),
-("coral", 2, 0, 1478400, 17.6525),
-("coral", 2, 0, 1555200, 18.0975),
-("coral", 2, 0, 1632000, 18.8575),
-("coral", 2, 0, 1708800, 20.0525),
-("coral", 2, 0, 1785600, 21.2625),
-("coral", 3, 0, 300000, 9.86),
-("coral", 3, 0, 403200, 10.335),
-("coral", 3, 0, 499200, 10.8925),
-("coral", 3, 0, 576000, 11.37),
-("coral", 3, 0, 672000, 11.8),
-("coral", 3, 0, 768000, 12.41),
-("coral", 3, 0, 844800, 12.97),
-("coral", 3, 0, 940800, 13.335),
-("coral", 3, 0, 1036800, 14.1725),
-("coral", 3, 0, 1113600, 14.695),
-("coral", 3, 0, 1209600, 15.3525),
-("coral", 3, 0, 1305600, 16.2775),
-("coral", 3, 0, 1382400, 16.8725),
-("coral", 3, 0, 1478400, 17.6525),
-("coral", 3, 0, 1555200, 18.0975),
-("coral", 3, 0, 1632000, 18.8575),
-("coral", 3, 0, 1708800, 20.0525),
-("coral", 3, 0, 1785600, 21.2625),
-("coral", 4, 1, 710400, 16.7833333333),
-("coral", 4, 1, 825600, 18.3733333333),
-("coral", 4, 1, 940800, 20.4833333333),
-("coral", 4, 1, 1056000, 23.3066666667),
-("coral", 4, 1, 1171200, 25.8266666667),
-("coral", 4, 1, 1286400, 28.45),
-("coral", 4, 1, 1401600, 31.7233333333),
-("coral", 4, 1, 1497600, 34.42),
-("coral", 4, 1, 1612800, 39.3966666667),
-("coral", 4, 1, 1708800, 44.24),
-("coral", 4, 1, 1804800, 47.9433333333),
-("coral", 4, 1, 1920000, 51.97),
-("coral", 4, 1, 2016000, 63.3866666667),
-("coral", 4, 1, 2131200, 71.0366666667),
-("coral", 4, 1, 2227200, 79.32),
-("coral", 4, 1, 2323200, 88.99),
-("coral", 4, 1, 2419200, 100.68),
-("coral", 5, 1, 710400, 16.7833333333),
-("coral", 5, 1, 825600, 18.3733333333),
-("coral", 5, 1, 940800, 20.4833333333),
-("coral", 5, 1, 1056000, 23.3066666667),
-("coral", 5, 1, 1171200, 25.8266666667),
-("coral", 5, 1, 1286400, 28.45),
-("coral", 5, 1, 1401600, 31.7233333333),
-("coral", 5, 1, 1497600, 34.42),
-("coral", 5, 1, 1612800, 39.3966666667),
-("coral", 5, 1, 1708800, 44.24),
-("coral", 5, 1, 1804800, 47.9433333333),
-("coral", 5, 1, 1920000, 51.97),
-("coral", 5, 1, 2016000, 63.3866666667),
-("coral", 5, 1, 2131200, 71.0366666667),
-("coral", 5, 1, 2227200, 79.32),
-("coral", 5, 1, 2323200, 88.99),
-("coral", 5, 1, 2419200, 100.68),
-("coral", 6, 1, 710400, 16.7833333333),
-("coral", 6, 1, 825600, 18.3733333333),
-("coral", 6, 1, 940800, 20.4833333333),
-("coral", 6, 1, 1056000, 23.3066666667),
-("coral", 6, 1, 1171200, 25.8266666667),
-("coral", 6, 1, 1286400, 28.45),
-("coral", 6, 1, 1401600, 31.7233333333),
-("coral", 6, 1, 1497600, 34.42),
-("coral", 6, 1, 1612800, 39.3966666667),
-("coral", 6, 1, 1708800, 44.24),
-("coral", 6, 1, 1804800, 47.9433333333),
-("coral", 6, 1, 1920000, 51.97),
-("coral", 6, 1, 2016000, 63.3866666667),
-("coral", 6, 1, 2131200, 71.0366666667),
-("coral", 6, 1, 2227200, 79.32),
-("coral", 6, 1, 2323200, 88.99),
-("coral", 6, 1, 2419200, 100.68),
-("coral", 7, 2, 825600, 52.7),
-("coral", 7, 2, 940800, 55.9),
-("coral", 7, 2, 1056000, 59.73),
-("coral", 7, 2, 1171200, 63.66),
-("coral", 7, 2, 1286400, 67.28),
-("coral", 7, 2, 1401600, 71.66),
-("coral", 7, 2, 1497600, 76.47),
-("coral", 7, 2, 1612800, 80.92),
-("coral", 7, 2, 1708800, 85.81),
-("coral", 7, 2, 1804800, 93.19),
-("coral", 7, 2, 1920000, 98.06),
-("coral", 7, 2, 2016000, 119.08),
-("coral", 7, 2, 2131200, 127.88),
-("coral", 7, 2, 2227200, 129.85),
-("coral", 7, 2, 2323200, 140.37),
-("coral", 7, 2, 2419200, 151.22),
-("coral", 7, 2, 2534400, 160.73),
-("coral", 7, 2, 2649600, 175.5),
-("coral", 7, 2, 2745600, 186.29),
-("coral", 7, 2, 2841600, 223.89),
-("flame", 0, 0, 300000, 9.86),
-("flame", 0, 0, 403200, 10.335),
-("flame", 0, 0, 499200, 10.8925),
-("flame", 0, 0, 576000, 11.37),
-("flame", 0, 0, 672000, 11.8),
-("flame", 0, 0, 768000, 12.41),
-("flame", 0, 0, 844800, 12.97),
-("flame", 0, 0, 940800, 13.335),
-("flame", 0, 0, 1036800, 14.1725),
-("flame", 0, 0, 1113600, 14.695),
-("flame", 0, 0, 1209600, 15.3525),
-("flame", 0, 0, 1305600, 16.2775),
-("flame", 0, 0, 1382400, 16.8725),
-("flame", 0, 0, 1478400, 17.6525),
-("flame", 0, 0, 1555200, 18.0975),
-("flame", 0, 0, 1632000, 18.8575),
-("flame", 0, 0, 1708800, 20.0525),
-("flame", 0, 0, 1785600, 21.2625),
-("flame", 1, 0, 300000, 9.86),
-("flame", 1, 0, 403200, 10.335),
-("flame", 1, 0, 499200, 10.8925),
-("flame", 1, 0, 576000, 11.37),
-("flame", 1, 0, 672000, 11.8),
-("flame", 1, 0, 768000, 12.41),
-("flame", 1, 0, 844800, 12.97),
-("flame", 1, 0, 940800, 13.335),
-("flame", 1, 0, 1036800, 14.1725),
-("flame", 1, 0, 1113600, 14.695),
-("flame", 1, 0, 1209600, 15.3525),
-("flame", 1, 0, 1305600, 16.2775),
-("flame", 1, 0, 1382400, 16.8725),
-("flame", 1, 0, 1478400, 17.6525),
-("flame", 1, 0, 1555200, 18.0975),
-("flame", 1, 0, 1632000, 18.8575),
-("flame", 1, 0, 1708800, 20.0525),
-("flame", 1, 0, 1785600, 21.2625),
-("flame", 2, 0, 300000, 9.86),
-("flame", 2, 0, 403200, 10.335),
-("flame", 2, 0, 499200, 10.8925),
-("flame", 2, 0, 576000, 11.37),
-("flame", 2, 0, 672000, 11.8),
-("flame", 2, 0, 768000, 12.41),
-("flame", 2, 0, 844800, 12.97),
-("flame", 2, 0, 940800, 13.335),
-("flame", 2, 0, 1036800, 14.1725),
-("flame", 2, 0, 1113600, 14.695),
-("flame", 2, 0, 1209600, 15.3525),
-("flame", 2, 0, 1305600, 16.2775),
-("flame", 2, 0, 1382400, 16.8725),
-("flame", 2, 0, 1478400, 17.6525),
-("flame", 2, 0, 1555200, 18.0975),
-("flame", 2, 0, 1632000, 18.8575),
-("flame", 2, 0, 1708800, 20.0525),
-("flame", 2, 0, 1785600, 21.2625),
-("flame", 3, 0, 300000, 9.86),
-("flame", 3, 0, 403200, 10.335),
-("flame", 3, 0, 499200, 10.8925),
-("flame", 3, 0, 576000, 11.37),
-("flame", 3, 0, 672000, 11.8),
-("flame", 3, 0, 768000, 12.41),
-("flame", 3, 0, 844800, 12.97),
-("flame", 3, 0, 940800, 13.335),
-("flame", 3, 0, 1036800, 14.1725),
-("flame", 3, 0, 1113600, 14.695),
-("flame", 3, 0, 1209600, 15.3525),
-("flame", 3, 0, 1305600, 16.2775),
-("flame", 3, 0, 1382400, 16.8725),
-("flame", 3, 0, 1478400, 17.6525),
-("flame", 3, 0, 1555200, 18.0975),
-("flame", 3, 0, 1632000, 18.8575),
-("flame", 3, 0, 1708800, 20.0525),
-("flame", 3, 0, 1785600, 21.2625),
-("flame", 4, 1, 710400, 16.7833333333),
-("flame", 4, 1, 825600, 18.3733333333),
-("flame", 4, 1, 940800, 20.4833333333),
-("flame", 4, 1, 1056000, 23.3066666667),
-("flame", 4, 1, 1171200, 25.8266666667),
-("flame", 4, 1, 1286400, 28.45),
-("flame", 4, 1, 1401600, 31.7233333333),
-("flame", 4, 1, 1497600, 34.42),
-("flame", 4, 1, 1612800, 39.3966666667),
-("flame", 4, 1, 1708800, 44.24),
-("flame", 4, 1, 1804800, 47.9433333333),
-("flame", 4, 1, 1920000, 51.97),
-("flame", 4, 1, 2016000, 63.3866666667),
-("flame", 4, 1, 2131200, 71.0366666667),
-("flame", 4, 1, 2227200, 79.32),
-("flame", 4, 1, 2323200, 88.99),
-("flame", 4, 1, 2419200, 100.68),
-("flame", 5, 1, 710400, 16.7833333333),
-("flame", 5, 1, 825600, 18.3733333333),
-("flame", 5, 1, 940800, 20.4833333333),
-("flame", 5, 1, 1056000, 23.3066666667),
-("flame", 5, 1, 1171200, 25.8266666667),
-("flame", 5, 1, 1286400, 28.45),
-("flame", 5, 1, 1401600, 31.7233333333),
-("flame", 5, 1, 1497600, 34.42),
-("flame", 5, 1, 1612800, 39.3966666667),
-("flame", 5, 1, 1708800, 44.24),
-("flame", 5, 1, 1804800, 47.9433333333),
-("flame", 5, 1, 1920000, 51.97),
-("flame", 5, 1, 2016000, 63.3866666667),
-("flame", 5, 1, 2131200, 71.0366666667),
-("flame", 5, 1, 2227200, 79.32),
-("flame", 5, 1, 2323200, 88.99),
-("flame", 5, 1, 2419200, 100.68),
-("flame", 6, 1, 710400, 16.7833333333),
-("flame", 6, 1, 825600, 18.3733333333),
-("flame", 6, 1, 940800, 20.4833333333),
-("flame", 6, 1, 1056000, 23.3066666667),
-("flame", 6, 1, 1171200, 25.8266666667),
-("flame", 6, 1, 1286400, 28.45),
-("flame", 6, 1, 1401600, 31.7233333333),
-("flame", 6, 1, 1497600, 34.42),
-("flame", 6, 1, 1612800, 39.3966666667),
-("flame", 6, 1, 1708800, 44.24),
-("flame", 6, 1, 1804800, 47.9433333333),
-("flame", 6, 1, 1920000, 51.97),
-("flame", 6, 1, 2016000, 63.3866666667),
-("flame", 6, 1, 2131200, 71.0366666667),
-("flame", 6, 1, 2227200, 79.32),
-("flame", 6, 1, 2323200, 88.99),
-("flame", 6, 1, 2419200, 100.68),
-("flame", 7, 2, 825600, 52.7),
-("flame", 7, 2, 940800, 55.9),
-("flame", 7, 2, 1056000, 59.73),
-("flame", 7, 2, 1171200, 63.66),
-("flame", 7, 2, 1286400, 67.28),
-("flame", 7, 2, 1401600, 71.66),
-("flame", 7, 2, 1497600, 76.47),
-("flame", 7, 2, 1612800, 80.92),
-("flame", 7, 2, 1708800, 85.81),
-("flame", 7, 2, 1804800, 93.19),
-("flame", 7, 2, 1920000, 98.06),
-("flame", 7, 2, 2016000, 119.08),
-("flame", 7, 2, 2131200, 127.88),
-("flame", 7, 2, 2227200, 129.85),
-("flame", 7, 2, 2323200, 140.37),
-("flame", 7, 2, 2419200, 151.22),
-("flame", 7, 2, 2534400, 160.73),
-("flame", 7, 2, 2649600, 175.5),
-("flame", 7, 2, 2745600, 186.29),
-("flame", 7, 2, 2841600, 223.89);
diff --git a/src/trace_processor/metrics/android/process_mem.sql b/src/trace_processor/metrics/android/process_mem.sql
deleted file mode 100644
index af2d72664..000000000
--- a/src/trace_processor/metrics/android/process_mem.sql
+++ /dev/null
@@ -1,111 +0,0 @@
---
--- Copyright 2019 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
--- Create all the views used to generate the Android Memory metrics proto.
--- Anon RSS
-SELECT RUN_METRIC('android/process_counter_span_view.sql',
- 'table_name', 'anon_rss',
- 'counter_name', 'mem.rss.anon');
-
--- File RSS
-SELECT RUN_METRIC('android/process_counter_span_view.sql',
- 'table_name', 'file_rss',
- 'counter_name', 'mem.rss.file');
-
-SELECT RUN_METRIC('android/process_counter_span_view.sql',
- 'table_name', 'shmem_rss',
- 'counter_name', 'mem.rss.shmem');
-
--- Swap
-SELECT RUN_METRIC('android/process_counter_span_view.sql',
- 'table_name', 'swap',
- 'counter_name', 'mem.swap');
-
--- OOM score
-SELECT RUN_METRIC('android/process_oom_score.sql');
-
--- Anon RSS + Swap
-DROP TABLE IF EXISTS anon_and_swap_join;
-CREATE VIRTUAL TABLE anon_and_swap_join
-USING SPAN_OUTER_JOIN(anon_rss_span PARTITIONED upid, swap_span PARTITIONED upid);
-
-DROP VIEW IF EXISTS anon_and_swap_span;
-CREATE VIEW anon_and_swap_span AS
-SELECT
- ts, dur, upid,
- IFNULL(anon_rss_val, 0) + IFNULL(swap_val, 0) AS anon_and_swap_val
-FROM anon_and_swap_join;
-
--- Anon RSS + file RSS + Swap
-DROP TABLE IF EXISTS anon_and_file_and_swap_join;
-CREATE VIRTUAL TABLE anon_and_file_and_swap_join
-USING SPAN_OUTER_JOIN(
- anon_and_swap_join PARTITIONED upid,
- file_rss_span PARTITIONED upid
-);
-
--- RSS + Swap
-DROP TABLE IF EXISTS rss_and_swap_join;
-CREATE VIRTUAL TABLE rss_and_swap_join
-USING SPAN_OUTER_JOIN(
- anon_and_file_and_swap_join PARTITIONED upid,
- shmem_rss_span PARTITIONED upid
-);
-
-DROP VIEW IF EXISTS rss_and_swap_span;
-CREATE VIEW rss_and_swap_span AS
-SELECT
-ts, dur, upid,
-CAST(IFNULL(file_rss_val, 0) AS INT) file_rss_val,
-CAST(IFNULL(anon_rss_val, 0) AS INT) anon_rss_val,
-CAST(IFNULL(shmem_rss_val, 0) AS INT) shmem_rss_val,
-CAST(IFNULL(swap_val, 0) AS INT) swap_val,
-CAST(
- IFNULL(anon_rss_val, 0)
- + IFNULL(swap_val, 0)
- + IFNULL(file_rss_val, 0)
- + IFNULL(shmem_rss_val, 0) AS int) AS rss_and_swap_val
-FROM rss_and_swap_join;
-
--- If we have dalvik events enabled (for ART trace points) we can construct the java heap timeline.
-SELECT RUN_METRIC('android/process_counter_span_view.sql',
- 'table_name', 'java_heap_kb',
- 'counter_name', 'Heap size (KB)');
-
-DROP VIEW IF EXISTS java_heap_span;
-CREATE VIEW java_heap_span AS
-SELECT ts, dur, upid, java_heap_kb_val * 1024 AS java_heap_val
-FROM java_heap_kb_span;
-
-DROP TABLE IF EXISTS anon_rss_by_oom_span;
-CREATE VIRTUAL TABLE anon_rss_by_oom_span
-USING SPAN_JOIN(anon_rss_span PARTITIONED upid, oom_score_span PARTITIONED upid);
-
-DROP TABLE IF EXISTS file_rss_by_oom_span;
-CREATE VIRTUAL TABLE file_rss_by_oom_span
-USING SPAN_JOIN(file_rss_span PARTITIONED upid, oom_score_span PARTITIONED upid);
-
-DROP TABLE IF EXISTS swap_by_oom_span;
-CREATE VIRTUAL TABLE swap_by_oom_span
-USING SPAN_JOIN(swap_span PARTITIONED upid, oom_score_span PARTITIONED upid);
-
-DROP TABLE IF EXISTS anon_and_swap_by_oom_span;
-CREATE VIRTUAL TABLE anon_and_swap_by_oom_span
-USING SPAN_JOIN(anon_and_swap_span PARTITIONED upid, oom_score_span PARTITIONED upid);
-
-DROP TABLE IF EXISTS java_heap_by_oom_span;
-CREATE VIRTUAL TABLE java_heap_by_oom_span
-USING SPAN_JOIN(java_heap_span PARTITIONED upid, oom_score_span PARTITIONED upid);
diff --git a/src/trace_processor/metrics/android/process_metadata.sql b/src/trace_processor/metrics/android/process_metadata.sql
deleted file mode 100644
index 6e0e6d3bd..000000000
--- a/src/trace_processor/metrics/android/process_metadata.sql
+++ /dev/null
@@ -1,85 +0,0 @@
---
--- Copyright 2019 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
-DROP TABLE IF EXISTS uid_package_count;
-
-CREATE TABLE uid_package_count AS
-SELECT uid, COUNT(1) AS cnt
-FROM package_list
-GROUP BY 1;
-
-DROP TABLE IF EXISTS process_metadata_table;
-
-CREATE TABLE process_metadata_table AS
-SELECT
- process.upid,
- -- TODO(b/169226092) remove this workaround
- CASE
- -- cmdline gets rewritten after fork, if these are still there we must
- -- have seen a racy capture.
- WHEN length(process.name) = 15 AND (
- process.cmdline in ('zygote', 'zygote64', '<pre-initialized>')
- OR process.cmdline like '%' || process.name)
- THEN process.cmdline
- ELSE process.name
- END AS process_name,
- process.android_appid AS uid,
- CASE WHEN uid_package_count.cnt > 1 THEN TRUE ELSE NULL END AS shared_uid,
- plist.package_name,
- plist.version_code,
- plist.debuggable
-FROM process
-LEFT JOIN uid_package_count ON process.android_appid = uid_package_count.uid
-LEFT JOIN package_list plist
-ON (
- process.android_appid = plist.uid
- AND uid_package_count.uid = plist.uid
- AND (
- -- unique match
- uid_package_count.cnt = 1
- -- or process name starts with the package name
- OR process.name LIKE plist.package_name || '%')
- );
-
-DROP VIEW IF EXISTS process_metadata;
-
-CREATE VIEW process_metadata AS
-WITH upid_packages AS (
- SELECT
- upid,
- RepeatedField(AndroidProcessMetadata_Package(
- 'package_name', package_list.package_name,
- 'apk_version_code', package_list.version_code,
- 'debuggable', package_list.debuggable
- )) packages_for_uid
- FROM process
- JOIN package_list ON process.android_appid = package_list.uid
- GROUP BY upid
-)
-SELECT
- upid,
- NULL_IF_EMPTY(AndroidProcessMetadata(
- 'name', process_name,
- 'uid', uid,
- 'package', NULL_IF_EMPTY(AndroidProcessMetadata_Package(
- 'package_name', package_name,
- 'apk_version_code', version_code,
- 'debuggable', debuggable
- )),
- 'packages_for_uid', packages_for_uid
- )) AS metadata
-FROM process_metadata_table
-LEFT JOIN upid_packages USING (upid);
diff --git a/src/trace_processor/metrics/android/span_view_stats.sql b/src/trace_processor/metrics/android/span_view_stats.sql
deleted file mode 100644
index 5b8304789..000000000
--- a/src/trace_processor/metrics/android/span_view_stats.sql
+++ /dev/null
@@ -1,45 +0,0 @@
---
--- Copyright 2019 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
-DROP TABLE IF EXISTS {{table_name}}_stats;
-CREATE TABLE {{table_name}}_stats (
- process_name TEXT PRIMARY KEY,
- min_value REAL,
- max_value REAL,
- avg_value REAL
-);
-
-INSERT INTO {{table_name}}_stats
-SELECT
- process.name AS process_name,
- MIN(span.{{table_name}}_val) AS min_value,
- MAX(span.{{table_name}}_val) AS max_value,
- SUM(span.{{table_name}}_val * span.dur) / SUM(span.dur) AS avg_value
-FROM {{table_name}}_span AS span JOIN process USING(upid)
-WHERE process.name IS NOT NULL
-GROUP BY 1
-ORDER BY 1;
-
-DROP VIEW IF EXISTS {{table_name}}_stats_proto;
-CREATE VIEW {{table_name}}_stats_proto AS
-SELECT
- process_name,
- AndroidMemoryMetric_Counter(
- 'min', min_value,
- 'max', max_value,
- 'avg', avg_value
- ) AS proto
-FROM {{table_name}}_stats;
diff --git a/src/trace_processor/metrics/android/unsymbolized_frames.sql b/src/trace_processor/metrics/android/unsymbolized_frames.sql
deleted file mode 100644
index ed6046c38..000000000
--- a/src/trace_processor/metrics/android/unsymbolized_frames.sql
+++ /dev/null
@@ -1,35 +0,0 @@
---
--- Copyright 2019 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
-DROP VIEW IF EXISTS unsymbolized_frames_view;
-CREATE VIEW unsymbolized_frames_view AS
-SELECT UnsymbolizedFrames_Frame(
- 'module', spm.name,
- 'build_id', spm.build_id,
- 'address', spf.rel_pc
-) AS frame_proto
-FROM stack_profile_frame spf
-JOIN stack_profile_mapping spm
-ON spf.mapping = spm.id
-WHERE spm.build_id != ''
-AND (spf.symbol_set_id == 0 OR spf.symbol_set_id IS NULL);
-
-DROP VIEW IF EXISTS unsymbolized_frames_output;
-CREATE VIEW unsymbolized_frames_output AS
-SELECT UnsymbolizedFrames(
- 'frames',
- (SELECT RepeatedField(frame_proto) FROM unsymbolized_frames_view)
-);
diff --git a/src/trace_processor/metrics/chrome/chrome_processes.sql b/src/trace_processor/metrics/chrome/chrome_processes.sql
deleted file mode 100644
index dd3be5180..000000000
--- a/src/trace_processor/metrics/chrome/chrome_processes.sql
+++ /dev/null
@@ -1,128 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
--- Table to map any of the various chrome process names to a type (e.g. Browser,
--- Renderer, GPU Process, etc).
-DROP TABLE IF EXISTS chrome_process_name_type_mapping;
-CREATE TABLE chrome_process_name_type_mapping (
- original_name_pattern TEXT UNIQUE,
- type TEXT
-);
-
-WITH prefix (value) AS (
- SELECT *
- FROM (
- VALUES ("org.chromium.chrome"),
- ("com.google.android.apps.chrome"),
- ("com.android.chrome"),
- ("com.chrome.beta"),
- ("com.chrome.canary"),
- ("com.chrome.dev")
- )
-),
-suffix (value, TYPE) AS (
- SELECT *
- FROM (
- VALUES ("", "Browser"),
- (
- ":sandboxed_process*:org.chromium.content.app.SandboxedProcessService*",
- "Sandboxed"
- ),
- (":privileged_process*", "Privileged"),
- ("_zygote", "Zygote")
- )
-)
--- Insert the Chrome process names for a normal chrome trace
-INSERT INTO chrome_process_name_type_mapping
-VALUES ('Browser', 'Browser'),
- ('Renderer', 'Renderer'),
- ('GPU Process', 'Gpu'),
- ('Gpu', 'Gpu'),
- ('Zygote', 'Zygote'),
- ('Utility', 'Utility'),
- ('SandboxHelper', 'SandboxHelper'),
- ('PpapiPlugin', 'PpapiPlugin'),
- ('PpapiBroker', 'PpapiBroker')
-UNION ALL
--- Construct all the possible Chrome process names for an Android system chrome
--- trace.
-SELECT prefix.value || suffix.value AS name,
- suffix.type AS type
-FROM prefix,
- suffix;
-
--- Use GLOB here instead of LIKE as it's case-sensitive which means we don't
--- match the Android system zygote.
-DROP VIEW IF EXISTS all_chrome_processes;
-CREATE VIEW all_chrome_processes AS
-SELECT upid, m.type AS process_type
-FROM process JOIN chrome_process_name_type_mapping m
-ON name GLOB original_name_pattern;
-
--- A view of all Chrome threads.
-DROP VIEW IF EXISTS all_chrome_threads;
-CREATE VIEW all_chrome_threads AS
- SELECT utid, thread.upid, thread.name
- FROM thread, all_chrome_processes
- WHERE thread.upid = all_chrome_processes.upid;
-
--- For sandboxed and privileged processes (found in Android system traces), use
--- the main thread name to type of process.
-DROP VIEW IF EXISTS chrome_subprocess_types;
-CREATE VIEW chrome_subprocess_types AS
--- Sometimes you can get multiple threads in a trace marked main_thread, but
--- they appear to have the same name so just use one of them.
-SELECT DISTINCT p.upid,
- SUBSTR(t.name, 3, LENGTH(t.name) - 6) AS sandbox_type
-FROM all_chrome_processes p
- JOIN all_chrome_threads t ON p.upid = t.upid
-WHERE process_type IN ("Sandboxed", "Privileged")
- AND t.name GLOB "Cr*Main";
-
--- Contains all the chrome processes from process with an extra column,
--- process_type.
-DROP VIEW IF EXISTS chrome_process;
-CREATE VIEW chrome_process AS
-SELECT PROCESS.*,
- IIF(sandbox_type IS NULL, process_type, sandbox_type) AS process_type
-FROM PROCESS
- JOIN (
- SELECT a.upid,
- sandbox_type,
- process_type
- FROM all_chrome_processes a
- LEFT JOIN chrome_subprocess_types s ON a.upid = s.upid
- ) c ON PROCESS.upid = c.upid;
-
--- Contains all the chrome threads from thread with an extra column,
--- canonical_name, that should contain a thread that's the same in both chrome
--- and system traces.
-DROP VIEW IF EXISTS chrome_thread;
-
-CREATE VIEW chrome_thread AS
-SELECT thread.*,
- CASE
- WHEN thread.name GLOB "Cr*Main" THEN "CrProcessMain"
- WHEN thread.name IS NULL THEN "Unknown"
- ELSE thread.name
- END AS canonical_name
-FROM (
- SELECT t.utid,
- p.*
- FROM all_chrome_threads t
- JOIN chrome_process p ON t.upid = p.upid
- ) c
- JOIN thread ON thread.utid = c.utid;
diff --git a/src/trace_processor/metrics/chrome/chrome_thread_slice_with_cpu_time.sql b/src/trace_processor/metrics/chrome/chrome_thread_slice_with_cpu_time.sql
deleted file mode 100644
index 4af0d4589..000000000
--- a/src/trace_processor/metrics/chrome/chrome_thread_slice_with_cpu_time.sql
+++ /dev/null
@@ -1,98 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
-SELECT RUN_METRIC('chrome/chrome_processes.sql');
-
--- Grab all the thread tracks which are found in chrome threads.
-DROP VIEW IF EXISTS chrome_track;
-CREATE VIEW chrome_track AS
- SELECT
- *
- FROM thread_track
- WHERE utid IN (SELECT utid FROM chrome_thread);
-
--- From all the chrome thread tracks select all the slice details as well as
--- the utid of the track so we can join with counter table later.
-DROP VIEW IF EXISTS chrome_slice;
-CREATE VIEW chrome_slice AS
- SELECT
- slice.*,
- chrome_track.utid
- FROM
- slice JOIN
- chrome_track ON
- chrome_track.id = slice.track_id
- WHERE
- track_id in (SELECT id FROM chrome_track);
-
--- Using utid join the thread_counter_track to chrome thread slices. This allows
--- the filtering of the counter table to only counters associated to these
--- threads.
-DROP VIEW IF EXISTS chrome_slice_and_counter_track;
-CREATE VIEW chrome_slice_and_counter_track AS
- SELECT
- s.*,
- thread_counter_track.id as counter_track_id,
- thread_counter_track.name as counter_name
- FROM
- chrome_slice s JOIN
- thread_counter_track ON
- thread_counter_track.utid = s.utid AND
- thread_counter_track.name = "thread_time";
-
--- Join each slice with the recorded value at the beginning and the end, as
--- well as computing the total CPU time each slice took.
---
--- We use MIN and MAX inside because sometimes nested slices will have the exact
--- same timestamp and we need to select one, there is nothing tying a particular
--- counter value to which slice generated it so we always choose the minimum for
--- the start on ties and the maximum for ties on the end of the slice. This
--- means this is always an overestimate, but events being emitted at exactly the
--- same timestamp is relatively rare so shouldn't cause to much inflation.
-DROP VIEW IF EXISTS chrome_thread_slice_with_cpu_time;
-CREATE VIEW chrome_thread_slice_with_cpu_time AS
- SELECT
- end_cpu_time - start_cpu_time AS slice_cpu_time,
- *
- FROM (
- SELECT
- s.*,
- min_counter.start_cpu_time
- FROM
- chrome_slice_and_counter_track s LEFT JOIN (
- SELECT
- ts,
- track_id,
- MIN(value) AS start_cpu_time
- FROM counter
- GROUP BY 1, 2
- ) min_counter ON
- min_counter.ts = s.ts AND min_counter.track_id = s.counter_track_id
- ) min_and_slice LEFT JOIN (
- SELECT
- ts,
- track_id,
- MAX(value) AS end_cpu_time
- FROM counter
- GROUP BY 1, 2
- ) max_counter ON
- max_counter.ts =
- CASE WHEN min_and_slice.dur >= 0 THEN
- min_and_slice.ts + min_and_slice.dur
- ELSE
- min_and_slice.ts
- END AND
- max_counter.track_id = min_and_slice.counter_track_id;
diff --git a/src/trace_processor/metrics/chrome/rail_modes.sql b/src/trace_processor/metrics/chrome/rail_modes.sql
deleted file mode 100644
index d86c25fb6..000000000
--- a/src/trace_processor/metrics/chrome/rail_modes.sql
+++ /dev/null
@@ -1,562 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the 'License');
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an 'AS IS' BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
-SELECT RUN_METRIC('chrome/chrome_processes.sql') AS suppress_query_output;
-SELECT RUN_METRIC('chrome/chrome_event_metadata.sql') AS suppress_query_output;
-
--- Priority order for RAIL modes where response has the highest priority and
--- idle has the lowest.
-DROP TABLE IF EXISTS rail_modes;
-CREATE TABLE rail_modes (
- mode TEXT UNIQUE,
- ordering INT,
- short_name TEXT
-);
-
--- RAIL_MODE_IDLE is used when no frames are visible in the renderer and so this
--- interprets that as background.
--- RAIL_MODE_LOAD is for the time from a navigation until the first meaningful
--- paint (assuming there are no user interactions).
--- RAIL_MODE_RESPONSE is used when the main thread is dealing with a
--- user-interaction (but not for instance for scrolls which may be handled by
--- the compositor).
--- RAIL_MODE_ANIMATION is used when none of the above apply.
--- The enum in chrome is defined in:
--- https://source.chromium.org/chromium/chromium/src/+/master:third_party/blink/renderer/platform/scheduler/public/rail_mode_observer.h
-INSERT INTO rail_modes
-VALUES ('RAIL_MODE_IDLE', 0, 'background'),
- ('RAIL_MODE_ANIMATION', 1, "animation"),
- ('RAIL_MODE_LOAD', 2, "load"),
- ('RAIL_MODE_RESPONSE', 3, "response");
-
-
--- Find the max ts + dur for every process
-DROP TABLE IF EXISTS max_ts_per_process;
-CREATE TABLE max_ts_per_process AS
- -- MAX(dur, 0) means unclosed slices just contribute their start time.
-SELECT upid,
- MAX(ts + MAX(dur, 0)) AS ts
-FROM (
- SELECT upid,
- ts,
- dur
- FROM process_track t
- JOIN slice s
- WHERE s.track_id = t.id
- UNION ALL
- SELECT upid,
- ts,
- dur
- FROM thread_track t
- JOIN thread
- JOIN slice
- WHERE slice.track_id = t.id
- AND thread.utid = t.utid
- )
-GROUP BY upid;
-
--- View containing all Scheduler.RAILMode slices across all Chrome renderer
--- processes.
-DROP VIEW IF EXISTS original_rail_mode_slices;
-CREATE VIEW original_rail_mode_slices AS
-SELECT slice.id,
- slice.ts,
- CASE
- -- Add 1 to the duration to ensure you cannot get a zero-sized RAIL mode
- -- slice, which can throw off the later queries.
- WHEN dur == -1 THEN max_ts_per_process.ts - slice.ts + 1
- ELSE dur
- END AS dur,
- track_id,
- EXTRACT_ARG(
- slice.arg_set_id,
- "chrome_renderer_scheduler_state.rail_mode"
- ) AS rail_mode
-FROM max_ts_per_process,
- slice,
- process_track
-WHERE slice.name = "Scheduler.RAILMode"
- AND slice.track_id = process_track.id
- AND process_track.upid = max_ts_per_process.upid;
-
--- Detect if the trace has an unrealistic length (10 minutes) that probably
--- means some trace events have faulty timestamps and which could throw off any
--- metrics that use the trace.
-DROP VIEW IF EXISTS trace_has_realistic_length;
-CREATE VIEW trace_has_realistic_length AS
-SELECT (end_ts - start_ts) < 1e9 * 60 * 10 AS value
-FROM trace_bounds;
-
--- RAIL_MODE_LOAD seems to get stuck which makes it not very useful so remap it
--- to RAIL_MODE_ANIMATION so it doesn't dominate the overall RAIL mode.
-DROP VIEW IF EXISTS rail_mode_slices;
-CREATE VIEW rail_mode_slices AS
-SELECT ts, dur, track_id,
- CASE
- WHEN rail_mode == "RAIL_MODE_LOAD" THEN "RAIL_MODE_ANIMATION"
- ELSE rail_mode
- END AS rail_mode
-FROM original_rail_mode_slices;
-
--- View containing a collapsed view of rail_mode_slices where there is only one
--- RAIL mode active at a given time. The mode is derived using the priority
--- order in rail_modes.
-DROP VIEW IF EXISTS overall_rail_mode_slices;
-CREATE VIEW overall_rail_mode_slices AS
-SELECT s.ts,
- s.end_ts,
- rail_modes.short_name AS rail_mode,
- MAX(rail_modes.ordering)
-FROM (
- SELECT ts,
- LEAD(ts, 1, (SELECT MAX(ts + dur) FROM rail_mode_slices)) OVER (
- ORDER BY ts
- ) AS end_ts
- FROM (
- SELECT DISTINCT ts
- FROM rail_mode_slices
- ) start_times
- ) s,
- rail_mode_slices r,
- rail_modes,
- trace_has_realistic_length
-WHERE (
- (
- s.ts >= r.ts AND s.ts < r.ts + r.dur
- )
- OR (
- s.end_ts > r.ts AND s.end_ts <= r.ts + r.dur
- )
- )
- AND r.rail_mode == rail_modes.mode
- AND trace_has_realistic_length.value
-GROUP BY s.ts;
-
--- Contains the same data as overall_rail_mode_slices except adjacent slices
--- with the same RAIL mode are combined.
-DROP TABLE IF EXISTS combined_overall_rail_slices;
-CREATE TABLE combined_overall_rail_slices AS
-SELECT ROW_NUMBER() OVER () AS id,
- ts,
- end_ts - ts AS dur,
- rail_mode
-FROM (
- SELECT lag(l.end_ts, 1, FIRST) OVER (
- ORDER BY l.ts
- ) AS ts,
- l.end_ts,
- l.rail_mode
- FROM (
- SELECT ts,
- end_ts,
- rail_mode
- FROM overall_rail_mode_slices s
- WHERE NOT EXISTS (
- SELECT NULL
- FROM overall_rail_mode_slices s2
- WHERE s.rail_mode = s2.rail_mode
- AND s.end_ts = s2.ts
- )
- ) AS l,
- (
- SELECT min(ts) AS FIRST
- FROM overall_rail_mode_slices
- )
- );
-
--- Now we have the RAIL Mode, use other trace events to create a modified RAIL
--- mode that more accurately reflects what the browser/user are doing.
-
--- First create slices for when there's no animation as indicated by a large gap
--- between vsync events (since it's easier to find gaps than runs of adjacent
--- vsyncs).
-
--- Mark any large gaps between vsyncs.
--- The value in "not_animating" is always 1. It's just there to be a non-NULL
--- value so the later SPAN_JOIN can find the set-difference.
-DROP VIEW IF EXISTS not_animating_slices;
-CREATE VIEW not_animating_slices AS
-WITH const (vsync_padding, large_gap) AS (
- SELECT
- -- Pad 50ms either side of a vsync
- 50000000,
- -- A gap of >200ms between the adjacent vsyncs is treated as a gap in
- -- animation.
- 200000000
-)
-SELECT ts + const.vsync_padding AS ts,
- gap_to_next_vsync - const.vsync_padding * 2 AS dur, 1 AS not_animating
-FROM const, (SELECT name,
- ts,
- lead(ts) OVER () - ts AS gap_to_next_vsync,
- dur
- FROM slice
- WHERE name = "VSync")
-WHERE gap_to_next_vsync > const.large_gap
-UNION
--- Insert a slice between start_ts and the first vsync (or the end of the trace
--- if there are none).
-SELECT
- ts,
- dur,
- 1
-FROM (SELECT start_ts AS ts,
- COALESCE((
- SELECT MIN(ts)
- FROM slice
- WHERE name = "VSync"
- ) - start_ts - const.vsync_padding,
- end_ts - start_ts
- ) AS dur
-FROM trace_bounds, const)
-WHERE dur > 0
-UNION
--- Insert a slice between the last vsync and end_ts
-SELECT last_vsync AS ts,
- end_ts - last_vsync AS dur,
- 1
-FROM (
- SELECT MAX(ts) + const.vsync_padding AS last_vsync
- FROM slice, const
- WHERE name = "VSync"
- ),
- trace_bounds
-WHERE last_vsync < end_ts;
-
--- There are two types of InputLatency:: events:
--- 1) Simple ones that begin at ts and end at ts+dur
--- 2) Paired ones that begin with a "begin" slice and end at an "end" slice.
---
--- Paired events are even trickier because we can't guarantee that the "begin"
--- slice will even be in the trace and because it's possible for multiple begin
--- slices to appear without an intervening end slice.
-
--- Table of begin and end events along with the increment/decrement to be
--- applied to the appropriate counter (one for each type of paired event). Final
--- column dur_multiplier is used to find the timestamp to mark the event at in
--- the equation event_ts = ts + dur * dur_multiplier. End events have
--- dur_multiplier of 1, which makes their ts the end of the slice rather than
--- the start.
-DROP TABLE IF EXISTS input_latency_begin_end_names;
-CREATE TABLE input_latency_begin_end_names
-(
- full_name TEXT UNIQUE,
- prefix TEXT,
- scroll_increment INT,
- pinch_increment INT,
- touch_increment INT,
- fling_increment INT,
- pointer_increment INT,
- dur_multiplier INT
-);
-
-INSERT
- OR IGNORE INTO input_latency_begin_end_names
-VALUES
- ("InputLatency::GestureScrollBegin",
- "InputLatency::GestureScroll", 1, 0, 0, 0, 0, 0),
- ("InputLatency::GestureScrollEnd",
- "InputLatency::GestureScroll", -1, 0, 0, 0, 0, 1),
- ("InputLatency::GesturePinchBegin",
- "InputLatency::GesturePinch", 0, 1, 0, 0, 0, 0),
- ("InputLatency::GesturePinchEnd",
- "InputLatency::GesturePinch", 0, -1, 0, 0, 0, 1),
- ("InputLatency::TouchStart",
- "InputLatency::Touch", 0, 0, 1, 0, 0, 0),
- ("InputLatency::TouchEnd",
- "InputLatency::Touch", 0, 0, -1, 0, 0, 1),
- ("InputLatency::GestureFlingStart",
- "InputLatency::GestureFling", 0, 0, 0, 1, 0, 0),
- ("InputLatency::GestureFlingCancel",
- "InputLatency::GestureFling", 0, 0, 0, -1, 0, 1),
- ("InputLatency::PointerDown",
- "InputLatency::Pointer", 0, 0, 0, 0, 1, 0),
- ("InputLatency::PointerUp",
- "InputLatency::Pointer", 0, 0, 0, 0, -1, 1),
- ("InputLatency::PointerCancel",
- "InputLatency::Pointer", 0, 0, 0, 0, -1, 1);
-
--- Find all the slices that have split "begin" and "end" slices and maintain a
--- running total for each type, where >0 means that type of input event is
--- ongoing.
-DROP VIEW IF EXISTS input_begin_end_slices;
-CREATE VIEW input_begin_end_slices AS
-SELECT prefix,
- -- Mark the change at the start of "start" slices and the end of "end" slices.
- ts + dur * dur_multiplier AS ts,
- scroll_increment,
- pinch_increment,
- touch_increment,
- fling_increment,
- pointer_increment
-FROM slice
-JOIN input_latency_begin_end_names ON name = full_name
-ORDER BY ts;
-
--- Combine all the paired input events to get an indication of when any paired
--- input event is ongoing.
-DROP VIEW IF EXISTS unified_input_pair_increments;
-CREATE VIEW unified_input_pair_increments AS
-SELECT ts,
- scroll_increment +
- pinch_increment +
- touch_increment +
- fling_increment +
- pointer_increment AS increment
-FROM input_begin_end_slices;
-
--- It's possible there's an end slice without a start slice (as it occurred
--- before the trace started) which would result in (starts - ends) going
--- negative at some point. So find an offset that shifts up all counts so the
--- lowest values becomes zero. It's possible this could still do the wrong thing
--- if there were start AND end slices that are outside the trace bounds, in
--- which case it should count as covering the entire trace, but it's impossible
--- to compensate for that without augmenting the trace events themselves.
-DROP VIEW IF EXISTS initial_paired_increment;
-CREATE VIEW initial_paired_increment AS
-SELECT ts,
- MIN(0, MIN(scroll_total)) +
- MIN(0, MIN(pinch_total)) +
- MIN(0, MIN(touch_total)) +
- MIN(0, MIN(fling_total)) +
- MIN(0, MIN(pointer_total)) AS offset
-FROM (
- SELECT ts,
- SUM(scroll_increment) OVER(ROWS UNBOUNDED PRECEDING) AS scroll_total,
- SUM(pinch_increment) OVER(ROWS UNBOUNDED PRECEDING) AS pinch_total,
- SUM(touch_increment) OVER(ROWS UNBOUNDED PRECEDING) AS touch_total,
- SUM(fling_increment) OVER(ROWS UNBOUNDED PRECEDING) AS fling_total,
- SUM(pointer_increment) OVER(ROWS UNBOUNDED PRECEDING) AS pointer_total
- FROM input_begin_end_slices
- );
-
--- Now find all the simple input slices that fully enclose the input they're
--- marking (i.e. not the start or end of a pair).
-DROP VIEW IF EXISTS simple_input_slices;
-CREATE VIEW simple_input_slices AS
-SELECT id,
- name,
- ts,
- dur
-FROM slice s
-WHERE name LIKE "InputLatency::%"
- AND NOT EXISTS (
- SELECT 1
- FROM slice
- JOIN input_latency_begin_end_names
- WHERE s.name == full_name
- );
-
--- Turn the simple input slices into +1s and -1s at the start and end of each
--- slice.
-DROP VIEW IF EXISTS simple_input_increments;
-CREATE VIEW simple_input_increments AS
-SELECT ts,
- 1 AS increment
-FROM simple_input_slices
-UNION ALL
-SELECT ts + dur,
- -1
-FROM simple_input_slices
-ORDER BY ts;
-
--- Combine simple and paired inputs into one, summing all the increments at a
--- given ts.
-DROP VIEW IF EXISTS all_input_increments;
-CREATE VIEW all_input_increments AS
-SELECT ts,
- SUM(increment) AS increment
-FROM (
- SELECT *
- FROM simple_input_increments
- UNION ALL
- SELECT *
- FROM unified_input_pair_increments
- ORDER BY ts
- )
-GROUP BY ts;
-
--- Now calculate the cumulative sum of the increments as each ts, giving the
--- total number of outstanding input events at a given time.
-DROP VIEW IF EXISTS all_input_totals;
-CREATE VIEW all_input_totals AS
-SELECT ts,
- SUM(increment) OVER(ROWS UNBOUNDED PRECEDING) > 0 AS input_total
-FROM all_input_increments;
-
--- Now find the transitions from and to 0 and use that to create slices where
--- input events were occurring. The input_active column always contains 1, but
--- is there so that the SPAN_JOIN_LEFT can put NULL in it for RAIL Mode slices
--- that do not have corresponding input events.
-DROP VIEW IF EXISTS all_input_slices;
-CREATE VIEW all_input_slices AS
-SELECT ts,
- dur,
- input_active
-FROM (
- SELECT ts,
- lead(ts, 1, end_ts) OVER() - ts AS dur,
- input_active
- FROM trace_bounds,
- (
- SELECT ts,
- input_total > 0 AS input_active
- FROM (
- SELECT ts,
- input_total,
- lag(input_total) OVER() AS prev_input_total
- FROM all_input_totals
- )
- WHERE (input_total > 0 <> prev_input_total > 0)
- OR prev_input_total IS NULL
- )
- )
-WHERE input_active > 0;
-
--- Since the scheduler defaults to animation when none of the other RAIL modes
--- apply, animation overestimates the amount of time that actual animation is
--- occurring.
--- So instead we try to divide up animation in other buckets based on other
--- trace events.
-DROP VIEW IF EXISTS rail_mode_animation_slices;
-CREATE VIEW rail_mode_animation_slices AS
-SELECT * FROM combined_overall_rail_slices WHERE rail_mode = "animation";
-
--- Left-join rail mode animation slices with all_input_slices to find all
--- "animation" slices that should actually be labelled "response".
-DROP TABLE IF EXISTS rail_mode_join_inputs;
-CREATE VIRTUAL TABLE rail_mode_join_inputs
-USING SPAN_LEFT_JOIN(rail_mode_animation_slices, all_input_slices);
-
--- Left-join rail mode animation slices with not_animating_slices which is
--- based on the gaps between vsync events.
-DROP TABLE IF EXISTS rail_mode_join_inputs_join_animation;
-CREATE VIRTUAL TABLE rail_mode_join_inputs_join_animation
-USING SPAN_LEFT_JOIN(rail_mode_join_inputs, not_animating_slices);
-
-DROP VIEW IF EXISTS has_modified_rail_slices;
-CREATE VIEW has_modified_rail_slices AS
-SELECT (
- SELECT value
- FROM chrome_event_metadata
- WHERE name == "os-name"
- ) == "Android" AS value;
-
--- Mapping to allow CamelCased names to be produced from the modified rail
--- modes.
-DROP TABLE IF EXISTS modified_rail_mode_prettier;
-CREATE TABLE modified_rail_mode_prettier (
- orig_name TEXT UNIQUE,
- pretty_name TEXT
-);
-INSERT INTO modified_rail_mode_prettier
-VALUES ("background", "Background"),
- ("foreground_idle", "ForegroundIdle"),
- ("animation", "Animation"),
- ("load", "Load"),
- ("response", "Response");
-
--- When the RAIL mode is animation, use input/vsync data to conditionally change
--- the mode to response or foreground_idle.
-DROP VIEW IF EXISTS unmerged_modified_rail_slices;
-CREATE VIEW unmerged_modified_rail_slices AS
-SELECT ROW_NUMBER() OVER () AS id,
- ts,
- dur,
- mode
-FROM (
- SELECT ts,
- dur,
- CASE
- WHEN input_active IS NOT NULL THEN "response"
- WHEN not_animating IS NULL THEN "animation"
- ELSE "foreground_idle"
- END AS mode
- FROM rail_mode_join_inputs_join_animation
- UNION
- SELECT ts,
- dur,
- rail_mode AS mode
- FROM combined_overall_rail_slices
- WHERE rail_mode <> "animation"
- )
- -- Since VSync events are only emitted on Android (and the concept of a
- -- unified RAIL mode only makes sense if there's just a single Chrome window),
- -- don't output anything on other platforms. This will result in all the power
- -- and cpu time tables being empty rather than containing bogus results.
-WHERE (
- SELECT value
- FROM has_modified_rail_slices
- );
-
--- The previous query creating unmerged_modified_rail_slices, can create
--- adjacent slices with the same mode. This merges them together as well as
--- adding a unique id to each slice. Rather than directly merging slices
--- together, this instead looks for all the transitions and uses this to
--- reconstruct the slices that should occur between them.
-DROP TABLE IF EXISTS modified_rail_slices;
-CREATE TABLE modified_rail_slices AS
-WITH const (end_ts) AS (SELECT ts + dur
- FROM unmerged_modified_rail_slices
- ORDER BY ts DESC
- LIMIT 1)
-SELECT ROW_NUMBER() OVER () AS id, lag(next_ts) OVER() AS ts,
- ts + dur - lag(next_ts) OVER() AS dur,
- mode AS mode
-FROM (
- -- For each row in the original table, create a new row with the information
- -- from the following row, since you can't use lag/lead in WHERE clause.
- --
- -- Transition row at the beginning. "mode" is invalid, so a transition will
- -- always be recorded.
- SELECT *
- FROM (SELECT
- 0 AS ts,
- ts AS dur,
- "" AS mode,
- ts AS next_ts,
- dur AS next_dur,
- mode AS next_mode
- FROM unmerged_modified_rail_slices
- LIMIT 1
- )
- UNION ALL
- SELECT ts,
- dur,
- mode,
- lead(ts, 1, end_ts) OVER() AS next_ts,
- lead(dur) OVER() AS next_dur,
- lead(mode) OVER() AS next_mode
- FROM unmerged_modified_rail_slices, const
- UNION ALL
- -- Transition row at the end. "next_mode" is invalid, so a transition will
- -- always be recorded.
- SELECT *
- FROM (SELECT
- ts + dur AS ts,
- 0 AS dur,
- mode,
- ts + dur AS next_ts,
- 0,
- "" AS next_mode
- FROM unmerged_modified_rail_slices
- ORDER BY ts DESC
- LIMIT 1
- )
- )
-WHERE mode <> next_mode
--- Retrieve all but the first row.
-LIMIT -1 OFFSET 1;
diff --git a/src/trace_processor/metrics/chrome/scroll_flow_event.sql b/src/trace_processor/metrics/chrome/scroll_flow_event.sql
deleted file mode 100644
index 05699f4ce..000000000
--- a/src/trace_processor/metrics/chrome/scroll_flow_event.sql
+++ /dev/null
@@ -1,258 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the 'License');
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an 'AS IS' BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
--- While handling a InputLatency::GestureScrollUpdate event a sequence of Flows
--- define the critical path from Beginning to End. This metric breaks down the
--- flows for the same InputLatency::GestureScrollUpdate event.
---
--- WARNING: This metric should not be used as a source of truth. It is under
--- active development and the values & meaning might change without
--- notice.
-
--- Provides the scroll_jank table which gives us all the GestureScrollUpdate
--- events we care about and labels them janky or not.
-SELECT RUN_METRIC('chrome/scroll_jank.sql');
-
--- We get all latency_info that have valid trace_ids, And we make a synthetic
--- one for the beginning of each GestureScrollUpdate event so we can track the
--- time between receiving the input and being converted into a scroll.
---
--- flows with a trace_id of -1 are incomplete and are difficult to reason about
--- (especially if GestureScrollUpdate flows end up getting -1). so ignore them
--- for this table.
-DROP VIEW IF EXISTS latency_info_flow_step_and_ancestors;
-CREATE VIEW latency_info_flow_step_and_ancestors AS
- SELECT
- *
- FROM (
- SELECT
- slice.name,
- slice.id,
- slice.ts,
- slice.dur,
- slice.track_id,
- EXTRACT_ARG(slice.arg_set_id, 'chrome_latency_info.trace_id') AS trace_id,
- EXTRACT_ARG(slice.arg_set_id, 'chrome_latency_info.step') AS step,
- COALESCE(ancestor_zero.name, slice.name) AS ancestor_name_zero,
- COALESCE(ancestor_zero.id, slice.id) AS ancestor_id_zero,
- COALESCE(ancestor_zero.ts, slice.ts) AS ancestor_ts_zero,
- COALESCE(ancestor_zero.dur, slice.dur) AS ancestor_dur_zero,
- COALESCE(ancestor_one.name, slice.name) AS ancestor_name_one,
- COALESCE(ancestor_one.id, slice.id) AS ancestor_id_one,
- COALESCE(ancestor_one.ts, slice.ts) AS ancestor_ts_one,
- COALESCE(ancestor_one.dur, slice.dur) AS ancestor_dur_one
- FROM
- slice LEFT JOIN
- ancestor_slice(slice.id) AS ancestor_zero
- ON ancestor_zero.depth = 0 LEFT JOIN
- ancestor_slice(slice.id) AS ancestor_one ON ancestor_one.depth = 1
- WHERE
- slice.name = 'LatencyInfo.Flow' AND
- EXTRACT_ARG(slice.arg_set_id, 'chrome_latency_info.trace_id') != -1
- ) flow JOIN (
- SELECT
- id AS scroll_slice_id,
- ts AS scroll_ts,
- dur AS scroll_dur,
- track_id AS scroll_track_id,
- trace_id AS scroll_trace_id,
- jank,
- gesture_scroll_id
- FROM scroll_jank
- ) scroll ON
- flow.trace_id = scroll.scroll_trace_id
- UNION ALL
- SELECT
- 'InputLatency::GestureScrollUpdate' AS name,
- id,
- ts,
- dur,
- track_id,
- trace_id,
- 'AsyncBegin' AS step,
- 'InputLatency::GestureScrollUpdate' AS ancestor_name_zero,
- id AS ancestor_id_zero,
- ts AS ancestor_ts_zero,
- 0 AS ancestor_dur_zero,
- 'InputLatency::GestureScrollUpdate' AS ancestor_name_one,
- id AS ancestor_id_one,
- ts AS ancestor_ts_one,
- 0 AS ancestor_dur_one,
- id AS scroll_slice_id,
- ts AS scroll_ts,
- dur AS scroll_dur,
- track_id AS scroll_track_id,
- trace_id AS scroll_trace_id,
- jank,
- gesture_scroll_id
- FROM scroll_jank
- ORDER BY gesture_scroll_id ASC, trace_id ASC, ts ASC;
-
--- See b/184134310, but "ThreadController active" spans multiple tasks and when
--- the top level parent is this event we should use the second event instead.
-DROP VIEW IF EXISTS latency_info_flow_step;
-CREATE VIEW latency_info_flow_step AS
- SELECT
- *,
- CASE WHEN ancestor_name_zero != "ThreadController active" THEN
- ancestor_name_zero ELSE ancestor_name_one END AS ancestor_name,
- CASE WHEN ancestor_name_zero != "ThreadController active" THEN
- ancestor_id_zero ELSE ancestor_id_one END AS ancestor_id,
- CASE WHEN ancestor_name_zero != "ThreadController active" THEN
- ancestor_ts_zero ELSE ancestor_ts_one END AS ancestor_ts,
- CASE WHEN ancestor_name_zero != "ThreadController active" THEN
- ancestor_dur_zero ELSE ancestor_dur_one END AS ancestor_dur
- FROM latency_info_flow_step_and_ancestors;
-
--- This is a heuristic to figure out which flow event properly joins this
--- GestureScrollUpdate. This heuristic is only needed in traces before we added
--- gesture_scroll_id.
---
--- We select the first |ts| from a flow event after its corresponding
--- GestureScrollUpdate has ended. This allows us to use this |ts| to contain all
--- flow events from the start of a particular scroll_slice_id (the slice id of
--- the async event) to that |ts|.
---
--- The reason for this is if these flow events share the same trace_id which can
--- occur if multiple chrome browsers are in the trace (webview & chrome for
--- example). We would normally add flow events from different scrolls, but by
--- limiting by the GestureScrollUpdate end we can prevent incorrect duplication.
--- This breaks of course if the same trace_id happens at the exact same time in
--- both browsers but this is hopefully unlikely.
-DROP VIEW IF EXISTS max_latency_info_ts_per_trace_id;
-CREATE VIEW max_latency_info_ts_per_trace_id AS
- SELECT
- scroll_slice_id,
- MIN(ts) AS max_flow_ts
- FROM latency_info_flow_step
- WHERE
- trace_id = scroll_trace_id AND
- ts > scroll_ts + scroll_dur
- GROUP BY scroll_slice_id;
-
--- As described by the comments about this uses the heuristic to remove any flow
--- events that aren't contained within the |max_flow_ts| and the beginning of
--- the GestureScrollUpdate. This prevents other processes that share the same
--- trace_id from inserting events in the middle.
---
--- Note: Must be a TABLE because it uses a window function which can behave
--- strangely in views.
-DROP TABLE IF EXISTS latency_info_flow_step_filtered;
-CREATE TABLE latency_info_flow_step_filtered AS
- SELECT
- ROW_NUMBER() OVER (ORDER BY
- flow.gesture_scroll_id ASC, trace_id ASC, ts ASC) AS row_number,
- *
- FROM
- latency_info_flow_step flow JOIN
- max_latency_info_ts_per_trace_id max_flow on
- max_flow.scroll_slice_id = flow.scroll_slice_id
- WHERE
- ts >= scroll_ts AND
- ts <= max_flow_ts
- ORDER BY flow.gesture_scroll_id ASC, flow.trace_id ASC, flow.ts ASC;
-
--- Take all the LatencyInfo.Flow events and within a |trace_id| join it with the
--- previous and nextflows. Some events are 'Unknown' when they don't have a step
--- but occur in the middle of the critical path. Most of these are errors though
--- and we've weeded I think all of them out (citation needed).
---
--- Note: Must be a TABLE because it uses a window function which can behave
--- strangely in views.
-DROP TABLE IF EXISTS latency_info_flow_null_step_removed;
-CREATE TABLE latency_info_flow_null_step_removed AS
- SELECT
- ROW_NUMBER() OVER (ORDER BY
- curr.gesture_scroll_id ASC, curr.trace_id ASC, curr.ts ASC
- ) AS row_number,
- curr.id,
- curr.ts,
- curr.dur,
- curr.track_id,
- curr.trace_id,
- curr.gesture_scroll_id,
- curr.scroll_slice_id,
- curr.scroll_ts,
- curr.scroll_dur,
- curr.scroll_track_id,
- curr.jank,
- curr.ancestor_id,
- curr.ancestor_ts,
- curr.ancestor_dur,
- curr.ancestor_ts + curr.ancestor_dur AS ancestor_end,
- CASE WHEN curr.step IS NULL THEN
- CASE WHEN
- prev.gesture_scroll_id != curr.gesture_scroll_id OR
- prev.trace_id != curr.trace_id OR
- prev.trace_id IS NULL OR
- prev.step = 'AsyncBegin' THEN
- 'Begin'
- ELSE
- CASE WHEN
- next.gesture_scroll_id != curr.gesture_scroll_id OR
- next.trace_id != curr.trace_id OR
- next.trace_id IS NULL THEN
- 'End'
- ELSE
- 'Unknown'
- END
- END
- ELSE curr.step END AS step
- FROM
- latency_info_flow_step_filtered curr LEFT JOIN
- latency_info_flow_step_filtered prev ON
- curr.row_number - 1 = prev.row_number LEFT JOIN
- latency_info_flow_step_filtered next ON
- curr.row_number + 1 = next.row_number
- ORDER BY curr.gesture_scroll_id ASC, curr.trace_id ASC, curr.ts ASC;
-
--- Now that we've got the steps all named properly we want to join them with the
--- next step so we can compute the difference between the end of the current
--- step and the beginning of the next step.
-DROP VIEW IF EXISTS scroll_flow_event;
-CREATE VIEW scroll_flow_event AS
- SELECT
- curr.trace_id,
- curr.id,
- curr.ts,
- curr.dur,
- curr.track_id,
- curr.gesture_scroll_id,
- curr.scroll_slice_id,
- curr.scroll_ts,
- curr.scroll_dur,
- curr.scroll_track_id,
- curr.jank,
- curr.step,
- curr.ancestor_id,
- curr.ancestor_ts,
- curr.ancestor_dur,
- curr.ancestor_end,
- next.id as next_id,
- next.ts AS next_ts,
- next.dur AS next_dur,
- next.track_id AS next_track_id,
- next.trace_id AS next_trace_id,
- next.step AS next_step,
- CASE WHEN next.trace_id = curr.trace_id THEN
- next.ancestor_ts
- ELSE
- NULL
- END AS maybe_next_ancestor_ts
- FROM
- latency_info_flow_null_step_removed curr LEFT JOIN
- latency_info_flow_null_step_removed next ON
- curr.row_number + 1 = next.row_number
- ORDER BY curr.gesture_scroll_id, curr.trace_id, curr.ts;
diff --git a/src/trace_processor/metrics/chrome/scroll_flow_event_queuing_delay.sql b/src/trace_processor/metrics/chrome/scroll_flow_event_queuing_delay.sql
deleted file mode 100644
index 81eba409b..000000000
--- a/src/trace_processor/metrics/chrome/scroll_flow_event_queuing_delay.sql
+++ /dev/null
@@ -1,75 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the 'License');
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an 'AS IS' BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
--- This metric takes each flow event in a InputLatency::GestureScrollUpdate and
--- and computes the time from the ancestor_end of the current flow to the
--- ancestor_ts of the next flow event. This is a reasonable approximation of the
--- time we waited for the next step in the critical flow to start.
-
--- Provides the scroll_flow_event table which gives us all the flow events with
--- associated GestureScrollUpdate events we care about and labels them janky or
--- not.
-SELECT RUN_METRIC('chrome/scroll_flow_event.sql');
-
--- Take each flow and next flow (from scroll_flow_event table) and generate the
--- metric name as well as compute the time between.
-DROP VIEW IF EXISTS scroll_flow_event_queuing_delay;
-
-CREATE VIEW scroll_flow_event_queuing_delay AS
- SELECT
- trace_id,
- id,
- ts,
- dur,
- track_id,
- gesture_scroll_id,
- scroll_slice_id,
- scroll_ts,
- scroll_dur,
- scroll_track_id,
- jank,
- step,
- ancestor_id,
- ancestor_ts,
- ancestor_end,
- next_id,
- next_step,
- maybe_next_ancestor_ts,
- next_track_id,
- CASE WHEN trace_id = next_trace_id THEN
- 'InputLatency.LatencyInfo.Flow.QueuingDelay.' ||
- CASE WHEN
- jank IS NOT NULL AND
- jank = 1
- THEN
- 'Jank.'
- ELSE
- 'NoJank.'
- END
- || step || '-to-' || next_step
- ELSE
- step
- END AS description,
- CASE WHEN maybe_next_ancestor_ts IS NULL THEN
- NULL
- ELSE
- CASE WHEN maybe_next_ancestor_ts > ancestor_end THEN
- (maybe_next_ancestor_ts - ancestor_end)
- ELSE
- 0
- END
- END AS queuing_time_ns
- FROM scroll_flow_event
- ORDER BY gesture_scroll_id, trace_id, ts;
diff --git a/src/trace_processor/metrics/chrome/scroll_jank.sql b/src/trace_processor/metrics/chrome/scroll_jank.sql
deleted file mode 100644
index 0564bd50d..000000000
--- a/src/trace_processor/metrics/chrome/scroll_jank.sql
+++ /dev/null
@@ -1,303 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
--- A collection of metrics related to GestureScrollUpdate events.
---
--- We define a GestureScrollUpdate to be janky if comparing forwards or
--- backwards (ignoring coalesced updates) a given GestureScrollUpdate exceeds
--- the duration of its predecessor or successor by 50% of a vsync interval
--- (defaulted to 60 FPS).
---
--- WARNING: This metric should not be used as a source of truth. It is under
--- active development and the values & meaning might change without
--- notice.
-
--- Get all chrome processes and threads tables set up.
-SELECT RUN_METRIC('chrome/chrome_processes.sql');
-
--- When working on GestureScrollUpdate events we need to ensure we have all the
--- events from the browser, renderer, and GPU processes. This query isn't quite
--- perfect. In system tracing we could have 3 browser processes all in the
--- background and this would match, but for now its the best we can do (renderer
--- and GPU names on android are quite complicated, but this should filter 99% (
--- citation needed) of what we want.
---
--- See b/151077536 for historical context.
-DROP VIEW IF EXISTS sufficient_chrome_processes;
-CREATE VIEW sufficient_chrome_processes AS
- SELECT
- CASE WHEN (
- SELECT COUNT(*) FROM chrome_process) = 0
- THEN
- FALSE
- ELSE (
- SELECT COUNT(*) >= 3 FROM (
- SELECT name FROM chrome_process
- WHERE
- name LIKE "Browser" OR
- name LIKE "Renderer" OR
- name LIKE "Gpu" OR
- name LIKE 'com.android.chrome%' OR
- name LIKE 'com.chrome.beta%' OR
- name LIKE 'com.chrome.dev%' OR
- name LIKE 'com.chrome.canary%' OR
- name LIKE 'com.google.android.apps.chrome%' OR
- name LIKE 'org.chromium.chrome%'
- GROUP BY name
- )) END AS have_enough_chrome_processes;
-
--- A simple table that checks the time between VSync (this can be used to
--- determine if we're scrolling at 90 FPS or 60 FPS.
---
--- Note: In traces without the "Java" category there will be no VSync
--- TraceEvents and this table will be empty.
---
--- Note: Must be a TABLE because it uses a window function which can behave
--- strangely in views.
-DROP TABLE IF EXISTS vsync_intervals;
-CREATE TABLE vsync_intervals AS
- SELECT
- slice_id,
- ts,
- dur,
- track_id,
- LEAD(ts) OVER(PARTITION BY track_id ORDER BY ts) - ts AS time_to_next_vsync
- FROM slice
- WHERE name = "VSync"
- ORDER BY track_id, ts;
-
--- Get all the GestureScrollBegin and GestureScrollEnd events. We take their
--- IDs to group them together into scrolls later and the timestamp and duration
--- to compute the duration of the scroll.
-DROP VIEW IF EXISTS scroll_begin_and_end;
-CREATE VIEW scroll_begin_and_end AS
- SELECT
- slice.name,
- slice.id,
- slice.ts,
- slice.dur,
- slice.track_id,
- EXTRACT_ARG(arg_set_id, 'chrome_latency_info.gesture_scroll_id')
- AS gesture_scroll_id,
- EXTRACT_ARG(arg_set_id, "chrome_latency_info.trace_id") AS trace_id
- FROM
- slice
- WHERE
- slice.name IN (
- 'InputLatency::GestureScrollBegin',
- 'InputLatency::GestureScrollEnd'
- )
- ORDER BY ts;
-
--- Now we take the GestureScrollBegin and the GestureScrollEnd events and join
--- the information into a single row per scroll. We also compute the average
--- Vysnc interval of the scroll (hopefully this would be either 60 FPS for the
--- whole scroll or 90 FPS but that isn't always the case). If the trace doesn't
--- contain the VSync TraceEvent we just fall back on assuming its 60 FPS (this
--- is the 1.6e+7 in the COALESCE which corresponds to 16 ms or 60 FPS).
-DROP VIEW IF EXISTS joined_scroll_begin_and_end;
-CREATE VIEW joined_scroll_begin_and_end AS
- SELECT
- begin.id AS begin_id,
- begin.ts AS begin_ts,
- begin.dur AS begin_dur,
- begin.track_id AS begin_track_id,
- begin.trace_id AS begin_trace_id,
- COALESCE(begin.gesture_scroll_id, begin.trace_id)
- AS begin_gesture_scroll_id,
- end.ts AS end_ts,
- end.ts + end.dur AS end_ts_and_dur,
- end.trace_id AS end_trace_id,
- COALESCE((
- SELECT
- CAST(AVG(time_to_next_vsync) AS FLOAT)
- FROM vsync_intervals in_query
- WHERE
- time_to_next_vsync IS NOT NULL AND
- in_query.ts > begin.ts AND
- in_query.ts < end.ts
- ), 1.6e+7) AS avg_vsync_interval
- FROM scroll_begin_and_end begin JOIN scroll_begin_and_end end ON
- begin.trace_id < end.trace_id AND
- begin.name = 'InputLatency::GestureScrollBegin' AND
- end.name = 'InputLatency::GestureScrollEnd' AND (
- (
- begin.gesture_scroll_id IS NULL AND
- end.trace_id = (
- SELECT MIN(trace_id)
- FROM scroll_begin_and_end in_query
- WHERE
- name = 'InputLatency::GestureScrollEnd' AND
- in_query.trace_id > begin.trace_id
- )
- ) OR
- end.gesture_scroll_id = begin.gesture_scroll_id
- )
- ORDER BY begin.ts;
-
--- Get the GestureScrollUpdate events by name ordered by the
--- |gesture_scroll_id|, and timestamp. Then compute the number of frames (
--- relative to vsync interval) that each event took. 1.6e+7 is 16 ms in
--- nanoseconds and is used in case there are no VSync events to default to 60
--- fps. We join each GestureScrollUpdate event to the information about it'
--- begin and end events for easy computation later.
---
--- We remove updates with |dur| == -1 because this means we have no end event
--- and can't reasonably determine what it should be. We have separate tracking
--- to ensure this only happens at the end of the trace where its expected.
---
--- Note: Must be a TABLE because it uses a window function which can behave
--- strangely in views.
-DROP TABLE IF EXISTS gesture_scroll_update;
-CREATE TABLE gesture_scroll_update AS
- SELECT
- ROW_NUMBER() OVER (
- ORDER BY gesture_scroll_id ASC, ts ASC) AS row_number,
- begin_id,
- begin_ts,
- begin_dur,
- begin_track_id,
- begin_trace_id,
- COALESCE(gesture_scroll_id, begin_trace_id) AS gesture_scroll_id,
- CASE WHEN
- end_ts_and_dur > ts + dur THEN
- end_ts_and_dur
- ELSE
- ts + dur
- END AS maybe_scroll_end,
- id,
- ts,
- dur,
- track_id,
- trace_id,
- dur/avg_vsync_interval AS scroll_frames_exact
- FROM joined_scroll_begin_and_end begin_and_end JOIN (
- SELECT
- EXTRACT_ARG(arg_set_id, "chrome_latency_info.trace_id") AS trace_id,
- EXTRACT_ARG(arg_set_id, 'chrome_latency_info.gesture_scroll_id')
- AS gesture_scroll_id,
- *
- FROM
- slice JOIN track ON slice.track_id = track.id
- WHERE
- slice.name = 'InputLatency::GestureScrollUpdate' AND
- slice.dur != -1 AND
- NOT COALESCE(
- EXTRACT_ARG(arg_set_id, "chrome_latency_info.is_coalesced"),
- TRUE)
- ) scroll_update ON
- scroll_update.ts <= begin_and_end.end_ts AND
- scroll_update.ts >= begin_and_end.begin_ts AND
- scroll_update.trace_id > begin_and_end.begin_trace_id AND
- scroll_update.trace_id < begin_and_end.end_trace_id AND (
- scroll_update.gesture_scroll_id IS NULL OR
- scroll_update.gesture_scroll_id = begin_and_end.begin_gesture_scroll_id
- );
-
--- This takes the GestureScrollUpdate events and joins it to the previous
--- GestureScrollUpdate event (previous row and NULL if there isn't one) and the
--- next GestureScrollUpdate event (next row and again NULL if there isn't one).
--- Then we compute the duration of the event (relative to fps) and see if it
--- increased by more then 0.5 (which is 1/2 of 16 ms at 60 fps, and so on).
---
--- We only compare a GestureScrollUpdate event to another event within the same
--- scroll (gesture_scroll_id == prev/next gesture_scroll_id). This controls
--- somewhat for variability of scrolls.
---
--- Note: Must be a TABLE because it uses a window function which can behave
--- strangely in views.
-DROP TABLE IF EXISTS scroll_jank_maybe_null_prev_and_next;
-CREATE TABLE scroll_jank_maybe_null_prev_and_next AS
- SELECT
- currprev.*,
- CASE WHEN
- currprev.gesture_scroll_id != prev_gesture_scroll_id OR
- prev_ts IS NULL OR
- prev_ts < currprev.begin_ts OR
- prev_ts > currprev.maybe_scroll_end
- THEN
- FALSE
- ELSE
- currprev.scroll_frames_exact > prev_scroll_frames_exact + 0.5
- END AS prev_jank,
- CASE WHEN
- currprev.gesture_scroll_id != next.gesture_scroll_id OR
- next.ts IS NULL OR
- next.ts < currprev.begin_ts OR
- next.ts > currprev.maybe_scroll_end
- THEN
- FALSE
- ELSE
- currprev.scroll_frames_exact > next.scroll_frames_exact + 0.5
- END AS next_jank,
- next.scroll_frames_exact AS next_scroll_frames_exact
- FROM (
- SELECT
- curr.*,
- curr.maybe_scroll_end - curr.begin_ts AS scroll_dur,
- prev.ts AS prev_ts,
- prev.gesture_scroll_id AS prev_gesture_scroll_id,
- prev.scroll_frames_exact AS prev_scroll_frames_exact
- FROM
- gesture_scroll_update curr LEFT JOIN
- gesture_scroll_update prev ON prev.row_number + 1 = curr.row_number
- ) currprev LEFT JOIN
- gesture_scroll_update next ON currprev.row_number + 1 = next.row_number
- ORDER BY currprev.gesture_scroll_id ASC, currprev.ts ASC;
-
--- This just uses prev_jank and next_jank to see if each GestureScrollUpdate
--- event is a jank.
-DROP VIEW IF EXISTS scroll_jank;
-CREATE VIEW scroll_jank AS
- SELECT
- id AS slice_id,
- (next_jank IS NOT NULL AND next_jank) OR
- (prev_jank IS NOT NULL AND prev_jank)
- AS jank,
- *
- FROM scroll_jank_maybe_null_prev_and_next
- ORDER BY gesture_scroll_id ASC, ts ASC;
-
-DROP VIEW IF EXISTS scroll_jank_ms;
-
-DROP VIEW IF EXISTS scroll_jank_output;
-CREATE VIEW scroll_jank_output AS
- SELECT
- ScrollJank(
- 'scroll_jank_percentage', (
- SELECT
- (
- SUM(CASE WHEN jank THEN dur ELSE 0 END)/CAST(SUM(dur) AS REAL)
- ) * 100.0
- FROM scroll_jank
- ),
- 'scroll_ms', (
- SELECT
- CAST(SUM(scroll_dur)/1e6 AS REAL)
- FROM (
- SELECT
- MAX(scroll_dur) AS scroll_dur
- FROM scroll_jank
- GROUP BY gesture_scroll_id
- )
- ),
- 'scroll_processing_ms', CAST(SUM(dur)/1e6 AS REAL),
- 'scroll_jank_processing_ms', (
- SELECT CAST(SUM(dur)/1e6 AS REAL) FROM scroll_jank WHERE jank
- ),
- 'num_scroll_update_count', COUNT(*),
- 'num_scroll_update_jank_count', SUM(jank)
- )
- FROM scroll_jank;
diff --git a/src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_task.sql b/src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_task.sql
deleted file mode 100644
index d06141378..000000000
--- a/src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_task.sql
+++ /dev/null
@@ -1,294 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
-
--- Needed for the scroll_jank table to tell which updates were janky.
-SELECT RUN_METRIC('chrome/scroll_jank.sql');
-
---------------------------------------------------------------------------------
--- Get all the track ids relevant to the critical path.
---------------------------------------------------------------------------------
-
--- Grab the track of the browser. sendTouchEvent is a Java category event which
--- only occurs on the browser. This saves us the trouble of dealing with all the
--- different possible names of the browser (when including system tracing).
-DROP VIEW IF EXISTS browser_main_track_id;
-CREATE VIEW browser_main_track_id AS
-SELECT
- track_id AS id
-FROM slice
-WHERE
- name = "sendTouchEvent"
-LIMIT 1;
-
-DROP VIEW IF EXISTS viz_compositor_track_id;
-CREATE VIEW viz_compositor_track_id AS
-SELECT
- id
-FROM thread_track
-WHERE
- utid = (
- SELECT
- utid
- FROM thread
- WHERE
- name = "VizCompositorThread"
- )
-LIMIT 1;
-
--- Grab the track of the GPU. gpu/command_buffer is a toplevel category event
--- which only occurs on the gpu main. This saves us the trouble of dealing with
--- all the different possible names of the GPU process (when including system
--- tracing).
-DROP VIEW IF EXISTS gpu_main_track_id;
-CREATE VIEW gpu_main_track_id AS
-SELECT
- track_id AS id
-FROM slice
-WHERE
- EXTRACT_ARG(arg_set_id, "task.posted_from.file_name") LIKE
- "%gpu/command_buffer/service/scheduler.cc"
-LIMIT 1;
-
--- TODO(nuskos): Determine a good way to get all the renderer track_ids (each
--- scroll will have a single renderer main and a single renderer
--- compositor however different scroll updates could have
--- DIFFERENT renderers so bit tricky). Ignore this complexity for
--- now until we have a single task we want to blame jank on.
-
---------------------------------------------------------------------------------
--- Grab the last LatencyInfo.Flow for each trace_id on the browser main.
---------------------------------------------------------------------------------
-DROP VIEW IF EXISTS browser_flows;
-CREATE VIEW browser_flows AS
-SELECT
- EXTRACT_ARG(arg_set_id, "chrome_latency_info.trace_id") AS trace_id,
- EXTRACT_ARG(arg_set_id, "chrome_latency_info.step") AS flow_step,
- track_id,
- max(ts) AS ts
-FROM slice
-WHERE
- track_id = (
- SELECT id FROM browser_main_track_id
- ) AND
- name = "LatencyInfo.Flow"
- GROUP BY trace_id;
-
--- Grab the last LatencyInfo.Flow for each trace_id on the VizCompositor.
-DROP VIEW IF EXISTS viz_flows;
-CREATE VIEW viz_flows AS
-SELECT
- EXTRACT_ARG(arg_set_id, "chrome_latency_info.trace_id") AS trace_id,
- EXTRACT_ARG(arg_set_id, "chrome_latency_info.step") AS flow_step,
- track_id,
- max(ts) AS ts
-FROM slice
-WHERE
- track_id = (
- SELECT id FROM viz_compositor_track_id
- ) AND
- name = "LatencyInfo.Flow"
- GROUP BY trace_id;
-
--- Grab the last LatencyInfo.Flow for each trace_id on the GPU main.
-DROP VIEW IF EXISTS gpu_flows;
-CREATE VIEW gpu_flows AS
-SELECT
- EXTRACT_ARG(arg_set_id, "chrome_latency_info.trace_id") AS trace_id,
- EXTRACT_ARG(arg_set_id, "chrome_latency_info.step") AS flow_step,
- track_id,
- max(ts) AS ts
-FROM slice
-WHERE
- track_id = (
- SELECT id FROM gpu_main_track_id
- ) AND
- name = "LatencyInfo.Flow"
- GROUP BY trace_id;
-
---------------------------------------------------------------------------------
--- Finally join the relevant tracks/flows to the individual scrolls.
---------------------------------------------------------------------------------
-
--- Keeping only the GestureScrollUpdates join the maximum flows with their
--- associated scrolls. We only keep non-coalesced scrolls.
-DROP VIEW IF EXISTS scroll_with_browser_gpu_and_viz_flows;
-CREATE VIEW scroll_with_browser_gpu_and_viz_flows AS
-SELECT
- scroll.trace_id,
- scroll.scroll_id,
- scroll.ts,
- scroll.dur,
- scroll.track_id,
- browser_flows.ts AS browser_flow_ts,
- browser_flows.flow_step AS browser_flow_step,
- browser_flows.track_id AS browser_track_id,
- viz_flows.ts AS viz_flow_ts,
- viz_flows.flow_step AS viz_flow_step,
- viz_flows.track_id AS viz_track_id,
- gpu_flows.ts AS gpu_flow_ts,
- gpu_flows.flow_step AS gpu_flow_step,
- gpu_flows.track_id AS gpu_track_id
-FROM (
- SELECT
- trace_id,
- id AS scroll_id,
- ts,
- dur,
- track_id
- FROM scroll_jank
-) scroll JOIN browser_flows ON
- scroll.trace_id = browser_flows.trace_id
- JOIN viz_flows ON viz_flows.trace_id = scroll.trace_id
- JOIN gpu_flows ON gpu_flows.trace_id = scroll.trace_id;
-
---------------------------------------------------------------------------------
--- Below we determine individual causes of blocking tasks.
---------------------------------------------------------------------------------
-
---------------------------------------------------------------------------------
--- Determine if a CopyOutputRequest blocked any important threads.
---------------------------------------------------------------------------------
-
--- These are the events that block the Browser Main or the VizCompositor thread.
-DROP VIEW IF EXISTS blocking_browser_gpu_and_viz_copies;
-CREATE VIEW blocking_browser_gpu_and_viz_copies AS
-SELECT
- id,
- ts,
- dur,
- track_id
-FROM slice
-WHERE
- (
- (
- name = "viz.mojom.CopyOutputResultSender" OR
- name = "GLRenderer::CopyDrawnRenderPass"
- ) AND
- track_id = (SELECT id FROM browser_main_track_id)
- ) OR (
- EXTRACT_ARG(arg_set_id, "task.posted_from.file_name") LIKE
- "%components/viz/common/frame_sinks/copy_output_request.cc" AND
- track_id = (SELECT id FROM viz_compositor_track_id)
- ) OR (
- name = "SkiaOutputSurfaceImplOnGpu::CopyOutput" AND
- track_id = (SELECT id FROM gpu_main_track_id)
- );
-
--- Determine based on the LatencyInfo.Flow timestamp and the copy task overlap
--- if this scroll might have been delayed because of the copy.
-DROP VIEW IF EXISTS blocking_copy_tasks;
-CREATE VIEW blocking_copy_tasks AS
-SELECT
- scroll.scroll_id,
- scroll.trace_id,
- copy.id,
- copy.ts,
- copy.dur,
- copy.track_id,
- CASE WHEN copy.track_id = scroll.browser_track_id THEN
- CASE WHEN copy.ts < scroll.browser_flow_ts THEN
- TRUE
- ELSE
- FALSE
- END
- WHEN copy.track_id = scroll.viz_track_id THEN
- CASE WHEN copy.ts < scroll.viz_flow_ts THEN
- TRUE
- ELSE
- FALSE
- END
- WHEN copy.track_id = scroll.gpu_track_id THEN
- CASE WHEN copy.ts < scroll.gpu_flow_ts THEN
- TRUE
- ELSE
- FALSE
- END
- ELSE
- FALSE
- END AS blocked_by_copy
-FROM
- scroll_with_browser_gpu_and_viz_flows scroll JOIN
- blocking_browser_gpu_and_viz_copies copy ON
- scroll.ts + scroll.dur >= copy.ts AND
- copy.ts + copy.dur >= scroll.ts;
-
--- Group by scroll so we can equally join one reply to the ScrollJankAndCauses
--- view.
-DROP VIEW IF EXISTS screenshot_overlapping_scrolls;
-CREATE VIEW screenshot_overlapping_scrolls AS
-SELECT
- scroll_id, trace_id, SUM(blocked_by_copy) > 0 AS blocked_by_copy_request
-FROM blocking_copy_tasks
-GROUP BY 1, 2;
-
---------------------------------------------------------------------------------
--- Check for blocking language_detection on the browser thread
---------------------------------------------------------------------------------
-DROP VIEW IF EXISTS blocking_browser_language_detection;
-CREATE VIEW blocking_browser_language_detection AS
-SELECT
- id,
- ts,
- dur,
- track_id
-FROM slice
-WHERE
- (
- name = "language_detection.mojom.LanguageDetectionService" AND
- track_id = (SELECT id FROM browser_main_track_id)
- );
-
-DROP VIEW IF EXISTS blocking_language_detection_tasks;
-CREATE VIEW blocking_language_detection_tasks AS
-SELECT
- scroll.scroll_id,
- scroll.trace_id,
- lang.id,
- lang.ts,
- lang.dur,
- lang.track_id,
- CASE WHEN lang.track_id = scroll.browser_track_id THEN
- CASE WHEN lang.ts < scroll.browser_flow_ts THEN
- TRUE
- ELSE
- FALSE
- END
- END AS blocked_by_language_detection
-FROM
- scroll_with_browser_gpu_and_viz_flows scroll JOIN
- blocking_browser_language_detection lang ON
- scroll.ts + scroll.dur >= lang.ts AND
- lang.ts + lang.dur >= scroll.ts;
-
-DROP VIEW IF EXISTS language_detection_overlapping_scrolls;
-CREATE VIEW language_detection_overlapping_scrolls AS
-SELECT
- scroll_id, trace_id,
- SUM(blocked_by_language_detection) > 0 AS blocked_by_language_detection
-FROM blocking_language_detection_tasks
-GROUP BY 1, 2;
-
---------------------------------------------------------------------------------
--- Finally join the causes together for easy grouping.
---------------------------------------------------------------------------------
-DROP VIEW IF EXISTS scroll_jank_cause_blocking_task;
-CREATE VIEW scroll_jank_cause_blocking_task AS
- SELECT
- lang.scroll_id,
- lang.blocked_by_language_detection,
- copy.blocked_by_copy_request
- FROM
- language_detection_overlapping_scrolls lang JOIN
- screenshot_overlapping_scrolls copy ON copy.scroll_id = lang.scroll_id;
diff --git a/src/trace_processor/metrics/chrome/scroll_jank_cause_queuing_delay.sql b/src/trace_processor/metrics/chrome/scroll_jank_cause_queuing_delay.sql
deleted file mode 100644
index a57fe70f2..000000000
--- a/src/trace_processor/metrics/chrome/scroll_jank_cause_queuing_delay.sql
+++ /dev/null
@@ -1,306 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the 'License');
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an 'AS IS' BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
-
-SELECT RUN_METRIC('chrome/chrome_thread_slice_with_cpu_time.sql');
-SELECT RUN_METRIC('chrome/scroll_flow_event_queuing_delay.sql');
-
--- See b/184134310 why we remove ThreadController active.
-DROP VIEW IF EXISTS blocking_tasks_no_threadcontroller_active;
-CREATE VIEW blocking_tasks_no_threadcontroller_active AS
- SELECT
- slice.*,
- ancestor.id AS task_ancestor_id,
- ancestor.name AS task_ancestor_name
- FROM
- chrome_thread_slice_with_cpu_time AS slice LEFT JOIN
- ancestor_slice(slice.id) as ancestor ON ancestor.id = slice.parent_id
- WHERE
- slice.name != "ThreadController active" AND
- (slice.depth = 0 OR ancestor.name = "ThreadController active");
-
--- This view grabs any slice that could have prevented any GestureScrollUpdate
--- flow event from being run (queuing delays). For RunTask we know that its
--- generic (and thus hard to figure out whats the cause) so we grab the src
--- location to make it more meaningful.
---
--- See b/166441398 & crbug/1094361 for why we remove the -to-End step. In
--- essence -to-End is often reported on the ThreadPool after the fact with
--- explicit timestamps so it being blocked isn't noteworthy.
---
--- See b/184134310 for why we allow depth == 1 and ancestor.id is null (which
--- implies its a "ThreadController active" slice because we removed it
--- previously).
-DROP TABLE IF EXISTS blocking_tasks_queuing_delay;
-CREATE TABLE blocking_tasks_queuing_delay AS
- SELECT
- EXTRACT_ARG(slice.arg_set_id, "task.posted_from.file_name") as file,
- EXTRACT_ARG(slice.arg_set_id, "task.posted_from.function_name") as function,
- trace_id,
- queuing_time_ns,
- next_track_id,
- CASE WHEN queuing.ancestor_end <= slice.ts THEN
- CASE WHEN slice.ts + slice.dur <= queuing.maybe_next_ancestor_ts THEN
- slice.dur
- ELSE
- queuing.maybe_next_ancestor_ts - slice.ts
- END
- ELSE
- CASE WHEN slice.ts + slice.dur <= queuing.maybe_next_ancestor_ts THEN
- slice.ts + slice.dur - queuing.ancestor_end
- ELSE
- queuing.maybe_next_ancestor_ts - queuing.ancestor_end
- END
- END AS dur_overlapping_ns,
- description,
- scroll_slice_id,
- scroll_ts,
- scroll_dur,
- scroll_track_id,
- jank,
- slice.*
- FROM
- scroll_flow_event_queuing_delay queuing JOIN
- blocking_tasks_no_threadcontroller_active AS slice ON
- slice.ts + slice.dur > queuing.ancestor_end AND
- queuing.maybe_next_ancestor_ts > slice.ts AND
- slice.track_id = queuing.next_track_id AND
- queuing.description NOT LIKE
- "InputLatency.LatencyInfo.%ank.STEP_DRAW_AND_SWAP-to-End" AND
- queuing.description NOT LIKE
- "InputLatency.LatencyInfo.%ank.STEP_FINISHED_SWAP_BUFFERS-to-End"
- WHERE
- queuing_time_ns IS NOT NULL AND
- queuing_time_ns > 0;
-
--- Now for each toplevel task (depth = 0 from above) we want to grab all their
--- children slices. This is done by joining on descendant_slice which is a
--- trace processor defined operator. This will results in 1 row for every
--- descendant slice. So all fields in base.* will be repeated ONCE for each
--- child, but if it has no slice it will occur only once but all the
--- |descendant_.*| fields will be NULL because of the LEFT JOIN.
--- Additionally for mojo events, append "(interface_name)" to the end of the
--- descendant name.
-DROP VIEW IF EXISTS all_descendant_blocking_tasks_queuing_delay;
-CREATE VIEW all_descendant_blocking_tasks_queuing_delay AS
- SELECT
- descendant.id AS descendant_id,
- descendant.ts AS descendant_ts,
- descendant.dur AS descendant_dur,
- COALESCE(descendant.name || "(" ||
- IIF(descendant.arg_set_id IS NOT NULL,
- EXTRACT_ARG(descendant.arg_set_id,
- "chrome_mojo_event_info.watcher_notify_interface_tag"),
- NULL) || ")",
- descendant.name) AS descendant_name,
- descendant.parent_id As descendant_parent_id,
- descendant.depth AS descendant_depth,
- base.*
- FROM
- blocking_tasks_queuing_delay base LEFT JOIN
- descendant_slice(base.id) AS descendant;
-
-DROP TABLE IF EXISTS all_descendant_blocking_tasks_queuing_delay_with_cpu_time;
-CREATE TABLE all_descendant_blocking_tasks_queuing_delay_with_cpu_time AS
- SELECT
- cpu.slice_cpu_time AS descendant_slice_cpu_time,
- cpu.slice_cpu_time / descendant.slice_cpu_time AS descendant_cpu_percentage,
- cpu.slice_cpu_time /
- (descendant.slice_cpu_time /
- (1 << (descendant.descendant_depth - 1))) > 0.5
- AS descendant_cpu_time_above_relative_threshold,
- descendant_dur / descendant.dur AS descendant_dur_percentage,
- descendant_dur /
- (descendant.dur / (1 << (descendant.descendant_depth - 1))) > 0.5
- AS descendant_dur_above_relative_threshold,
- descendant.*
- FROM
- all_descendant_blocking_tasks_queuing_delay descendant LEFT JOIN (
- SELECT
- id, slice_cpu_time
- FROM chrome_thread_slice_with_cpu_time
- ) AS cpu ON
- cpu.id = descendant.descendant_id;
-
--- Now that we've generated the descendant count how many siblings each row
--- has. Recall that all the top level tasks are repeated but each row represents
--- a descendant slice. This means since we LEFT JOIN we will say a slice has 0
--- siblings if it has no descendants (which is true), and otherwise we will
--- compute the siblings as the count of all slices with the same parent minus
--- the current slice.
-DROP VIEW IF EXISTS counted_descendant_blocking_tasks_queuing_delay;
-CREATE VIEW counted_descendant_blocking_tasks_queuing_delay AS
- SELECT
- base.*,
- COALESCE(single_descendant.number_of_siblings, 0) AS number_of_siblings
- FROM
- all_descendant_blocking_tasks_queuing_delay_with_cpu_time base LEFT JOIN (
- SELECT
- descendant_parent_id,
- COUNT(*) - 1 AS number_of_siblings
- FROM all_descendant_blocking_tasks_queuing_delay_with_cpu_time
- WHERE descendant_parent_id IS NOT NULL
- GROUP BY 1
- ) single_descendant ON
- single_descendant.descendant_parent_id = base.descendant_parent_id;
-
--- Now we group by the |id| which is the top level task id and find the first
--- descendant_depth where we have a sibling. We need this because we only want
--- to include single descendant slices in our metric name to keep it easy to
--- reason about what that code is doing.
-DROP VIEW IF EXISTS blocking_tasks_queuing_delay_with_invalid_depth;
-CREATE VIEW blocking_tasks_queuing_delay_with_invalid_depth AS
- SELECT
- base.*,
- (
- descendant_cpu_time_above_relative_threshold AND
- descendant_cpu_percentage > 0.05
- ) OR (
- descendant_dur_above_relative_threshold AND
- descendant_dur_percentage > 0.05
- ) AS descendant_major_slice,
- COALESCE(depth.invalid_depth, 10) AS invalid_depth
- FROM
- counted_descendant_blocking_tasks_queuing_delay base LEFT JOIN (
- SELECT
- id,
- MIN(descendant_depth) AS invalid_depth
- FROM counted_descendant_blocking_tasks_queuing_delay
- WHERE number_of_siblings >= 1
- GROUP BY 1
- ) AS depth ON base.id = depth.id
- ORDER BY
- descendant_depth ASC,
- descendant_cpu_percentage DESC,
- descendant_dur_percentage DESC;
-
--- Now to get back to a single output per top level task we group by all the
--- toplevel fields and aggregate the descendant fields. We only include the
--- descendant if their depth is less than the first depth with siblings (the
--- |invalid_depth|).
-DROP VIEW IF EXISTS descendant_blocking_tasks_queuing_delay;
-CREATE VIEW descendant_blocking_tasks_queuing_delay AS
- SELECT
- id,
- ts,
- dur,
- track_id,
- trace_id,
- name,
- scroll_slice_id AS scroll_id,
- scroll_ts,
- scroll_dur,
- scroll_track_id,
- jank,
- queuing_time_ns,
- dur_overlapping_ns,
- description,
- replace(file, rtrim(file, replace(file, '/', '')), '') AS file,
- function,
- GROUP_CONCAT(
- CASE WHEN descendant_depth < invalid_depth OR descendant_major_slice THEN
- descendant_id
- ELSE
- NULL
- END
- , "-") AS descendant_id,
- GROUP_CONCAT(
- CASE WHEN descendant_depth < invalid_depth OR descendant_major_slice THEN
- descendant_ts
- ELSE
- NULL
- END
- , "-") AS descendant_ts,
- GROUP_CONCAT(
- CASE WHEN descendant_depth < invalid_depth OR descendant_major_slice THEN
- descendant_dur
- ELSE
- NULL
- END
- , "-") AS descendant_dur,
- GROUP_CONCAT(
- CASE WHEN descendant_depth < invalid_depth OR descendant_major_slice THEN
- descendant_name
- ELSE
- NULL
- END, "-") AS descendant_name,
- GROUP_CONCAT(
- CASE WHEN descendant_depth < invalid_depth OR descendant_major_slice THEN
- descendant_slice_cpu_time
- ELSE
- NULL
- END
- , "-") AS descendant_slice_cpu_time,
- GROUP_CONCAT(
- CASE WHEN descendant_depth < invalid_depth OR descendant_major_slice THEN
- descendant_cpu_percentage
- ELSE
- NULL
- END
- , "-") AS descendant_cpu_time
- FROM
- blocking_tasks_queuing_delay_with_invalid_depth
- GROUP BY 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
- ORDER BY descendant_cpu_percentage DESC;
-
--- Create a common name for each "cause" based on the slice stack we found.
-DROP VIEW IF EXISTS scroll_jank_cause_queuing_delay_temp;
-CREATE VIEW scroll_jank_cause_queuing_delay_temp AS
- SELECT
- CASE WHEN name = "ThreadControllerImpl::RunTask" THEN
- 'posted-from-' || function || '()-in-' || file
- ELSE
- name
- END || COALESCE("-" || descendant_name, "") AS location,
-
- base.*
- FROM descendant_blocking_tasks_queuing_delay base;
-
--- Figure out the average time taken during non-janky scrolls updates for each
--- TraceEvent (metric_name) stack.
-DROP VIEW IF EXISTS scroll_jank_cause_queuing_delay_average_no_jank_time;
-CREATE VIEW scroll_jank_cause_queuing_delay_average_no_jank_time AS
- SELECT
- location,
- AVG(dur_overlapping_ns) as avg_dur_overlapping_ns
- FROM scroll_jank_cause_queuing_delay_temp
- WHERE NOT jank
- GROUP BY 1;
-
--- Join every row (jank and non-jank with the average non-jank time for the
--- given metric_name).
-DROP VIEW IF EXISTS scroll_jank_cause_queuing_delay_unannotated;
-CREATE VIEW scroll_jank_cause_queuing_delay_unannotated AS
- SELECT
- base.*,
- 'InputLatency.LatencyInfo.Flow.QueuingDelay.' ||
- CASE WHEN jank THEN 'Jank' ELSE 'NoJank' END || '.BlockingTasksUs.' ||
- base.location as metric_name,
- COALESCE(avg_no_jank.avg_dur_overlapping_ns, 0)
- AS avg_no_jank_dur_overlapping_ns
- FROM
- scroll_jank_cause_queuing_delay_temp base LEFT JOIN
- scroll_jank_cause_queuing_delay_average_no_jank_time avg_no_jank ON
- base.location = avg_no_jank.location;
-
--- Annotate with process and thread names.
-DROP VIEW IF EXISTS scroll_jank_cause_queuing_delay;
-CREATE VIEW scroll_jank_cause_queuing_delay AS
-SELECT p.process_type AS process_name, ct.canonical_name AS thread_name, s.*
-FROM scroll_jank_cause_queuing_delay_unannotated s,
- thread_track tt, chrome_thread ct,
- chrome_process p
-WHERE s.track_id = tt.id
- AND tt.utid = ct.utid
- AND ct.upid = p.upid;
diff --git a/src/trace_processor/metrics/experimental/blink_gc_metric.sql b/src/trace_processor/metrics/experimental/blink_gc_metric.sql
deleted file mode 100644
index 096d9c350..000000000
--- a/src/trace_processor/metrics/experimental/blink_gc_metric.sql
+++ /dev/null
@@ -1,581 +0,0 @@
--- Maps non-aggregated Blink GC events in timeline to telemetry friendly
--- names.
---
--- This includes the old style or the new naming scheme one which only occur on
--- the main thread.
-DROP VIEW IF EXISTS blink_non_aggregated_gc_event_name;
-CREATE VIEW blink_non_aggregated_gc_event_name AS
-SELECT
- 'BlinkGC.AtomicPauseMarkEpilogue' AS name,
- 'blink-gc-atomic-pause-mark-epilogue' AS old_event_name,
- 'blink:gc:main_thread:cycle:full:atomic:mark:epilogue' AS new_event_name
-UNION ALL
-SELECT
- 'BlinkGC.AtomicPauseMarkPrologue',
- 'blink-gc-atomic-pause-mark-prologue',
- 'blink:gc:main_thread:cycle:full:atomic:mark:prologue'
-UNION ALL
-SELECT
- 'BlinkGC.AtomicPauseMarkRoots',
- 'blink-gc-atomic-pause-mark-roots',
- 'blink:gc:main_thread:cycle:full:atomic:mark:roots'
-UNION ALL
-SELECT
- 'BlinkGC.IncrementalMarkingStartMarking',
- 'blink-gc-incremental-start',
- 'blink:gc:main_thread:cycle:full:incremental:mark:start'
-UNION ALL
-SELECT
- 'BlinkGC.IncrementalMarkingStep',
- 'blink-gc-incremental-step',
- 'blink:gc:main_thread:cycle:full:incremental:mark:step'
-UNION ALL
-SELECT
- 'BlinkGC.UnifiedMarkingStep',
- 'blink-gc-unified-marking-by-v8',
- 'unified:gc:main_thread:cycle:full:mark:step'
-UNION ALL
-SELECT
- 'BlinkGC.CompleteSweep',
- 'blink-gc-complete-sweep',
- 'blink:gc:main_thread:cycle:full:sweep:complete'
-UNION ALL
-SELECT
- 'BlinkGC.LazySweepInIdle',
- 'blink-gc-sweep-task-foreground',
- 'blink:gc:main_thread:cycle:full:sweep:idle'
-UNION ALL
-SELECT
- 'BlinkGC.LazySweepOnAllocation',
- 'blink-gc-sweep-allocation',
- 'blink:gc:main_thread:cycle:full:sweep:on_allocation'
-UNION ALL
-SELECT
- 'BlinkGC.AtomicPauseSweepAndCompact' AS name,
- 'blink-gc-atomic-pause-sweep-and-compact' AS old_event_name,
- 'blink:gc:main_thread:cycle:full:atomic:sweep:compact' AS new_event_name;
-
--- Get all the slices we care about. These are ones that start with V8.GC or
--- BlinkGC. If you need more you need to modify the where clause for
--- blink_gc_cpu_slice.
-DROP TABLE IF EXISTS blink_gc_cpu_slice;
-CREATE TABLE blink_gc_cpu_slice AS
-SELECT
- CASE WHEN dur != 0 THEN cpuDurNs/1e6 ELSE 0.0 END AS cpuDurMs,
- *
-FROM (
- SELECT
- COALESCE(EXTRACT_ARG(arg_set_id, 'debug.forced'), FALSE) OR
- -- This subquery replaces
- -- metrics.v8.utils.isForcedGarbageCollectionEvent(event)
- (
- SELECT
- id
- FROM ANCESTOR_SLICE(slice.id) AS ancestor
- WHERE ancestor.name = 'V8.GCLowMemoryNotification' LIMIT 1
- ) IS NOT NULL AS forced,
- -- upid replaces pid, because its more fool proof ensuring uniqueness.
- thread.upid || ':' || EXTRACT_ARG(arg_set_id, 'debug.epoch') AS epoch,
- slice.thread_dur AS cpuDurNs,
- slice.*
- FROM thread_slice as slice
- INNER JOIN thread_track ON slice.track_id = thread_track.id
- INNER JOIN thread ON thread_track.utid = thread.id
- WHERE
- slice.dur >= 0 AND (
- slice.name LIKE "V8.GC%" OR (slice.name LIKE "BlinkGC%" AND NOT forced)
- )
-);
-
--- This grabs all the single events for "BlinkGC.*", and restricts to only
--- forced events.
-DROP TABLE IF EXISTS blink_slice;
-CREATE TABLE blink_slice AS
-SELECT
- event_name.old_event_name AS blink_non_aggregated_gc_event_name,
- event_name.new_event_name AS blink_non_aggregated_gc_events_new_name,
- blink_gc_cpu_slice.*
-FROM
- blink_gc_cpu_slice LEFT JOIN
- blink_non_aggregated_gc_event_name AS event_name ON
- event_name.name = blink_gc_cpu_slice.name
-WHERE
- blink_gc_cpu_slice.name LIKE "BlinkGC%" AND NOT forced;
-
--- This groups all the events by name and epoch for from "blink_slice" for easy
--- access.
-DROP TABLE IF EXISTS blink_per_epoch_slice;
-CREATE TABLE blink_per_epoch_slice AS
-SELECT
- name,
- epoch,
- blink_non_aggregated_gc_event_name,
- blink_non_aggregated_gc_events_new_name,
- SUM(cpuDurMs) AS cpuDurPerEpochMs
-FROM blink_slice
-GROUP BY 1, 2, 3, 4;
-
--- All events that should be summed up to 'blink-gc-mark-roots'.
-DROP VIEW IF EXISTS blink_top_gc_roots_marking_event;
-CREATE VIEW blink_top_gc_roots_marking_event AS
-SELECT * FROM blink_slice WHERE name in (
- 'BlinkGC.VisitRoots'
-);
-
--- All events that should be summed up to
--- 'blink-gc-atomic-pause-mark-transitive-closure'.
-DROP VIEW IF EXISTS blink_gc_atomic_pause_transitive_closure_event;
-CREATE VIEW blink_gc_atomic_pause_transitive_closure_event AS
-SELECT * FROM blink_slice WHERE name in (
- 'BlinkGC.AtomicPauseMarkTransitiveClosure'
-);
-
--- All events that should be summed up to 'blink-gc-mark-transitive-closure'.
-DROP VIEW IF EXISTS blink_gc_foreground_marking_transitive_closure_event;
-CREATE VIEW
- blink_gc_foreground_marking_transitive_closure_event AS
-SELECT * FROM blink_slice WHERE name in (
- 'BlinkGC.AtomicPauseMarkTransitiveClosure',
- 'BlinkGC.IncrementalMarkingStep',
- 'BlinkGC.UnifiedMarkingStep'
-);
-
--- Names of Blink GC foreground marking events in timeline.
-DROP VIEW IF EXISTS blink_top_gc_foreground_marking_event;
-CREATE VIEW blink_top_gc_foreground_marking_event AS
-SELECT * FROM blink_slice WHERE name in (
- 'BlinkGC.AtomicPauseMarkEpilogue',
- 'BlinkGC.AtomicPauseMarkPrologue',
- 'BlinkGC.AtomicPauseMarkRoots',
- 'BlinkGC.IncrementalMarkingStartMarking'
-)
-UNION ALL
-SELECT * FROM blink_gc_foreground_marking_transitive_closure_event;
-
--- Names of Blink GC foreground marking events in timeline.
-DROP VIEW IF EXISTS blink_gc_forced_foreground_marking_event;
-CREATE VIEW blink_gc_forced_foreground_marking_event AS
-SELECT * FROM blink_slice WHERE name in (
- 'BlinkGC.AtomicPauseMarkEpilogue',
- 'BlinkGC.AtomicPauseMarkPrologue',
- 'BlinkGC.AtomicPauseMarkRoots',
- 'BlinkGC.IncrementalMarkingStartMarking',
- 'BlinkGC.MarkBailOutObjects',
- 'BlinkGC.MarkFlushV8References',
- 'BlinkGC.MarkFlushEphemeronPairs'
-);
-
--- Names of Blink GC background marking events in timeline.
-DROP VIEW IF EXISTS blink_top_gc_background_marking_event;
-CREATE VIEW blink_top_gc_background_marking_event AS
-SELECT * FROM blink_slice WHERE name in (
- 'BlinkGC.ConcurrentMarkingStep'
-);
-
--- Names of Blink GC foreground sweeping events in timeline.
-DROP VIEW IF EXISTS blink_top_gc_foreground_sweeping_event;
-CREATE VIEW blink_top_gc_foreground_sweeping_event AS
-SELECT * FROM blink_slice WHERE name in (
- 'BlinkGC.CompleteSweep',
- 'BlinkGC.LazySweepInIdle',
- 'BlinkGC.LazySweepOnAllocation'
-);
-
--- Names of Blink GC background sweeping events in timeline.
-DROP VIEW IF EXISTS blink_top_gc_background_sweeping_event;
-CREATE VIEW blink_top_gc_background_sweeping_event AS
-SELECT * FROM blink_slice WHERE name in (
- 'BlinkGC.ConcurrentSweepingStep'
-);
-
--- Names of all Blink Unified GC events in timeline.
-DROP VIEW IF EXISTS blink_top_gc_event;
-CREATE VIEW blink_top_gc_event AS
-SELECT * FROM blink_slice WHERE name in (
- SELECT name FROM blink_non_aggregated_gc_event_name
-) OR name in (
- SELECT name FROM blink_gc_atomic_pause_transitive_closure_event
-);
-
--- All events that should be summed up to 'blink-gc-atomic-pause'. Note that
--- this events need to have an epoch counter in args.epoch.
-DROP VIEW IF EXISTS atomic_pause_event;
-CREATE VIEW atomic_pause_event AS
-SELECT * FROM blink_slice WHERE name in (
- 'BlinkGC.AtomicPauseMarkEpilogue',
- 'BlinkGC.AtomicPauseMarkPrologue',
- 'BlinkGC.AtomicPauseMarkRoots',
- 'BlinkGC.AtomicPauseMarkTransitiveClosure',
- 'BlinkGC.AtomicPauseSweepAndCompact'
-);
-
--- This is a more complex variable so benefits from additional comments so we
--- pull it out of the proto filling.
-DROP VIEW IF EXISTS unified_gc_total;
-CREATE VIEW unified_gc_total AS
-SELECT
- *
-FROM blink_gc_cpu_slice
-WHERE (
- -- This subclause replaces
- -- metrics.v8.utils.isNotForcedTopGarbageCollectionEvent()
-
- -- These names are found in isTopGarbageCollectionEvent().
- name in (
- 'V8.GCCompactor',
- 'V8.GCFinalizeMC',
- 'V8.GCFinalizeMCReduceMemory',
- 'V8.GCIncrementalMarking',
- 'V8.GCIncrementalMarkingFinalize',
- 'V8.GCIncrementalMarkingStart',
- 'V8.GCPhantomHandleProcessingCallback',
- 'V8.GCScavenger'
- ) AND (
- -- This replaces isForcedGarbageCollectionEvent.
- SELECT name FROM ANCESTOR_SLICE(blink_gc_cpu_slice.id) AS ancestor
- WHERE ancestor.name == 'V8.GCLowMemoryNotification'
- LIMIT 1
- ) IS NULL
-) OR (
- -- This subclause replaces isNonNestedNonForcedBlinkGarbageCollectionEvent().
- name IN (
- -- This subquery replaces isNonForcedBlinkGarbageCollectionEvent().
- SELECT name FROM blink_top_gc_event
- ) AND (
- -- This subquery replaces metrics.v8.utils.isGarbageCollectionEvent().
- SELECT name FROM ANCESTOR_SLICE(blink_gc_cpu_slice.id) AS ancestor
- WHERE
- ancestor.name LIKE "V8.GC%" AND
- ancestor.name != 'V8.GCLowMemoryNotification'
- LIMIT 1
- ) IS NULL
-);
-
--- This table name is just "file_name" + "_output" used by TBMv3 to know which
--- view to extract the proto BlinkGcMetric out of.
-DROP VIEW IF EXISTS blink_gc_metric_output;
-CREATE VIEW blink_gc_metric_output AS
-SELECT BlinkGcMetric(
- 'blink_gc_atomic_pause_mark_epilogue',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM blink_slice
- WHERE
- blink_non_aggregated_gc_event_name = 'blink-gc-atomic-pause-mark-epilogue'
- ),
- 'blink_gc_main_thread_cycle_full_atomic_mark_epilogue',
- (
- SELECT
- RepeatedField(cpuDurPerEpochMs)
- FROM blink_per_epoch_slice
- WHERE
- blink_non_aggregated_gc_events_new_name =
- 'blink:gc:main_thread:cycle:full:atomic:mark:epilogue'
- ),
- 'blink_gc_atomic_pause_mark_prologue',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM blink_slice
- WHERE
- blink_non_aggregated_gc_event_name =
- 'blink-gc-atomic-pause-mark-prologue'
- ),
- 'blink_gc_main_thread_cycle_full_atomic_mark_prologue',
- (
- SELECT
- RepeatedField(cpuDurPerEpochMs)
- FROM blink_per_epoch_slice
- WHERE
- blink_non_aggregated_gc_events_new_name =
- 'blink:gc:main_thread:cycle:full:atomic:mark:prologue'
- ),
- 'blink_gc_atomic_pause_mark_roots',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM blink_slice
- WHERE
- blink_non_aggregated_gc_event_name = 'blink-gc-atomic-pause-mark-roots'
- ),
- 'blink_gc_main_thread_cycle_full_atomic_mark_roots',
- (
- SELECT
- RepeatedField(cpuDurPerEpochMs)
- FROM blink_per_epoch_slice
- WHERE
- blink_non_aggregated_gc_events_new_name =
- 'blink:gc:main_thread:cycle:full:atomic:mark:roots'
- ),
- 'blink_gc_atomic_pause_sweep_and_compact',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM blink_slice
- WHERE
- blink_non_aggregated_gc_event_name =
- 'blink-gc-atomic-pause-sweep-and-compact'
- ),
- 'blink_gc_main_thread_cycle_full_atomic_sweep_compact',
- (
- SELECT
- RepeatedField(cpuDurPerEpochMs)
- FROM blink_per_epoch_slice
- WHERE
- blink_non_aggregated_gc_events_new_name =
- 'blink:gc:main_thread:cycle:full:atomic:sweep:compact'
- ),
- 'blink_gc_complete_sweep',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM blink_slice
- WHERE blink_non_aggregated_gc_event_name = 'blink-gc-complete-sweep'
- ),
- 'blink_gc_main_thread_cycle_full_sweep_complete',
- (
- SELECT
- RepeatedField(cpuDurPerEpochMs)
- FROM blink_per_epoch_slice
- WHERE
- blink_non_aggregated_gc_events_new_name =
- 'blink:gc:main_thread:cycle:full:sweep:complete'
- ),
- 'blink_gc_incremental_start',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM blink_slice
- WHERE blink_non_aggregated_gc_event_name = 'blink-gc-incremental-start'
- ),
- 'blink_gc_main_thread_cycle_full_incremental_mark_start',
- (
- SELECT
- RepeatedField(cpuDurPerEpochMs)
- FROM blink_per_epoch_slice
- WHERE
- blink_non_aggregated_gc_events_new_name =
- 'blink:gc:main_thread:cycle:full:incremental:mark:start'
- ),
- 'blink_gc_incremental_step',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM blink_slice
- WHERE blink_non_aggregated_gc_event_name = 'blink-gc-incremental-step'
- ),
- 'blink_gc_main_thread_cycle_full_incremental_mark_step',
- (
- SELECT
- RepeatedField(cpuDurPerEpochMs)
- FROM blink_per_epoch_slice
- WHERE
- blink_non_aggregated_gc_events_new_name =
- 'blink:gc:main_thread:cycle:full:incremental:mark:step'
- ),
- 'blink_gc_sweep_allocation',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM blink_slice
- WHERE blink_non_aggregated_gc_event_name = 'blink-gc-sweep-allocation'
- ),
- 'blink_gc_main_thread_cycle_full_sweep_on_allocation',
- (
- SELECT
- RepeatedField(cpuDurPerEpochMs)
- FROM blink_per_epoch_slice
- WHERE
- blink_non_aggregated_gc_events_new_name =
- 'blink:gc:main_thread:cycle:full:sweep:on_allocation'
- ),
- 'blink_gc_sweep_task_foreground',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM blink_slice
- WHERE blink_non_aggregated_gc_event_name = 'blink-gc-sweep-task-foreground'
- ),
- 'blink_gc_main_thread_cycle_full_sweep_idle',
- (
- SELECT
- RepeatedField(cpuDurPerEpochMs)
- FROM blink_per_epoch_slice
- WHERE
- blink_non_aggregated_gc_events_new_name =
- 'blink:gc:main_thread:cycle:full:sweep:idle'
- ),
- 'blink_gc_unified_marking_by_v8',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM blink_slice
- WHERE blink_non_aggregated_gc_event_name = 'blink-gc-unified-marking-by-v8'
- ),
- 'unified_gc_main_thread_cycle_full_mark_step',
- (
- SELECT
- RepeatedField(cpuDurPerEpochMs)
- FROM blink_per_epoch_slice
- WHERE
- blink_non_aggregated_gc_events_new_name =
- 'unified:gc:main_thread:cycle:full:mark:step'
- ),
- 'blink_gc_atomic_pause',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM atomic_pause_event
- ),
- 'blink_gc_main_thread_cycle_full_atomic',
- (
- SELECT RepeatedField(val) FROM (
- SELECT
- SUM(cpuDurMs) as val
- FROM atomic_pause_event
- GROUP BY epoch
- )
- ),
- 'blink_gc_atomic_pause_mark_transitive_closure',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM blink_gc_atomic_pause_transitive_closure_event
- ),
- 'blink_gc_main_thread_cycle_full_atomic_mark_transitive_closure',
- (
- SELECT RepeatedField(val) FROM (
- SELECT
- SUM(cpuDurMs) as val
- FROM blink_gc_atomic_pause_transitive_closure_event
- GROUP BY epoch
- )
- ),
- 'blink_gc_total',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM blink_top_gc_event
- ),
- 'blink_gc_main_thread_cycle_full',
- (
- SELECT RepeatedField(val) FROM (
- SELECT
- SUM(cpuDurMs) as val
- FROM blink_top_gc_event
- GROUP BY epoch
- )
- ),
- 'blink_gc_mark_roots',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM blink_top_gc_roots_marking_event
- ),
- 'blink_gc_main_thread_cycle_full_mark_roots',
- (
- SELECT RepeatedField(val) FROM (
- SELECT
- SUM(cpuDurMs) as val
- FROM blink_top_gc_roots_marking_event
- GROUP BY epoch
- )
- ),
- 'blink_gc_mark_transitive_closure',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM blink_gc_foreground_marking_transitive_closure_event
- ),
- 'blink_gc_main_thread_cycle_full_mark_transitive_closure',
- (
- SELECT RepeatedField(val) FROM (
- SELECT
- SUM(cpuDurMs) as val
- FROM blink_gc_foreground_marking_transitive_closure_event
- GROUP BY epoch
- )
- ),
- 'blink_gc_mark_foreground',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM blink_top_gc_foreground_marking_event
- ),
- 'blink_gc_main_thread_cycle_full_mark',
- (
- SELECT RepeatedField(val) FROM (
- SELECT
- SUM(cpuDurMs) as val
- FROM blink_top_gc_foreground_marking_event
- GROUP BY epoch
- )
- ),
- 'blink_gc_mark_foreground_forced',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM blink_gc_forced_foreground_marking_event
- ),
- 'blink_gc_main_thread_cycle_full_mark_forced',
- (
- SELECT RepeatedField(val) FROM (
- SELECT
- SUM(cpuDurMs) as val
- FROM blink_gc_forced_foreground_marking_event
- GROUP BY epoch
- )
- ),
- 'blink_gc_mark_background',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM blink_top_gc_background_marking_event
- ),
- 'blink_gc_concurrent_thread_cycle_full_mark',
- (
- SELECT RepeatedField(val) FROM (
- SELECT
- SUM(cpuDurMs) as val
- FROM blink_top_gc_background_marking_event
- GROUP BY epoch
- )
- ),
- 'blink_gc_sweep_foreground',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM blink_top_gc_foreground_sweeping_event
- ),
- 'blink_gc_main_thread_cycle_full_sweep',
- (
- SELECT RepeatedField(val) FROM (
- SELECT
- SUM(cpuDurMs) as val
- FROM blink_top_gc_foreground_sweeping_event
- GROUP BY epoch
- )
- ),
- 'blink_gc_sweep_background',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM blink_top_gc_background_sweeping_event
- ),
- 'blink_gc_concurrent_thread_cycle_full_sweep',
- (
- SELECT RepeatedField(val) FROM (
- SELECT
- SUM(cpuDurMs) as val
- FROM blink_top_gc_background_sweeping_event
- GROUP BY epoch
- )
- ),
- 'unified_gc_total',
- (
- SELECT
- RepeatedField(cpuDurMs)
- FROM unified_gc_total
- )
-);
diff --git a/src/trace_processor/metrics/experimental/frame_times.sql b/src/trace_processor/metrics/experimental/frame_times.sql
deleted file mode 100644
index 4e0ccdb72..000000000
--- a/src/trace_processor/metrics/experimental/frame_times.sql
+++ /dev/null
@@ -1,184 +0,0 @@
---
--- Copyright 2021 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
-
-DROP VIEW IF EXISTS InteractionEvents;
-CREATE VIEW InteractionEvents AS
-SELECT
- ts, dur, ts AS ts_ir, dur AS dur_ir
-FROM slice WHERE name LIKE 'Interaction.%';
-
-DROP VIEW IF EXISTS GestureLegacyEvents;
-CREATE VIEW GestureLegacyEvents AS
-SELECT
- ts,
- EXTRACT_ARG(arg_set_id, 'legacy_event.phase') AS phase
-FROM raw
-WHERE EXTRACT_ARG(arg_set_id, 'legacy_event.name') = 'SyntheticGestureController::running';
-
--- Convert pairs of 'S' and 'F' events into slices with ts and dur.
-DROP VIEW IF EXISTS GestureEvents;
-CREATE VIEW GestureEvents AS
-SELECT
- ts, dur, ts AS ts_ge, dur AS dur_ge
-FROM (
- SELECT
- ts,
- phase,
- LEAD(ts) OVER (ORDER BY ts) - ts as dur
- FROM GestureLegacyEvents
-)
-WHERE phase = 'S';
-
-DROP TABLE IF EXISTS InteractionEventsJoinGestureEvents;
-CREATE VIRTUAL TABLE InteractionEventsJoinGestureEvents
-USING SPAN_LEFT_JOIN(InteractionEvents, GestureEvents);
-
---------------------------------------------------------------------------------
--- Interesting segments are:
--- 1) If there's a gesture overlapping with interaction, then gesture's range.
--- 2) Else, interaction's range.
-
-DROP VIEW IF EXISTS InterestingSegments;
-CREATE VIEW InterestingSegments AS
-SELECT -- 1) Gestures overlapping interactions.
- ts_ge AS ts,
- dur_ge AS dur
-FROM InteractionEventsJoinGestureEvents
-WHERE ts_ge IS NOT NULL
-GROUP BY ts_ge
-UNION ALL
-SELECT -- 2) Interactions without gestures.
- ts_ir AS ts,
- dur_ir AS dur
-FROM InteractionEventsJoinGestureEvents
-WHERE ts_ge IS NULL
-GROUP BY ts_ir
-HAVING COUNT(*) = 1;
-
---------------------------------------------------------------------------------
--- On ChromeOS, DRM events, if they exist, are the source of truth. Otherwise,
--- look for display rendering stats.
--- On Android, the TBMv2 version relied on Surface Flinger events that are
--- currently unavailable in proto traces. So results may be different from
--- the TBMv2 version on this platform.
-
-DROP TABLE IF EXISTS DisplayCompositorPresentationEvents;
-CREATE TABLE DisplayCompositorPresentationEvents AS
-SELECT ts, FALSE AS exp
-FROM slice
-WHERE name = 'DrmEventFlipComplete'
-GROUP BY ts;
-
-INSERT INTO DisplayCompositorPresentationEvents
-SELECT ts, FALSE AS exp
-FROM slice
-WHERE
- name = 'vsync_before'
- AND NOT EXISTS (SELECT * FROM DisplayCompositorPresentationEvents)
-GROUP BY ts;
-
-INSERT INTO DisplayCompositorPresentationEvents
-SELECT ts, FALSE AS exp
-FROM slice
-WHERE
- name = 'BenchmarkInstrumentation::DisplayRenderingStats'
- AND NOT EXISTS (SELECT * FROM DisplayCompositorPresentationEvents)
-GROUP BY ts;
-
-INSERT INTO DisplayCompositorPresentationEvents
-SELECT ts, TRUE AS exp
-FROM slice
-WHERE name = 'Display::FrameDisplayed'
-GROUP BY ts;
-
-DROP VIEW IF EXISTS FrameSegments;
-CREATE VIEW FrameSegments AS
-SELECT
- ts,
- LEAD(ts) OVER wnd - ts as dur,
- ts as ts_fs,
- LEAD(ts) OVER wnd - ts as dur_fs,
- exp
-FROM DisplayCompositorPresentationEvents
-WINDOW wnd AS (PARTITION BY exp ORDER BY ts);
-
-DROP TABLE IF EXISTS FrameSegmentsJoinInterestingSegments;
-CREATE VIRTUAL TABLE FrameSegmentsJoinInterestingSegments USING
-SPAN_JOIN(FrameSegments, InterestingSegments);
-
-DROP VIEW IF EXISTS FrameTimes;
-CREATE VIEW FrameTimes AS
-SELECT dur / 1e6 AS dur_ms, exp
-FROM FrameSegmentsJoinInterestingSegments
-WHERE ts = ts_fs AND dur = dur_fs;
-
---------------------------------------------------------------------------------
--- Determine frame rate
-
-DROP VIEW IF EXISTS RefreshPeriodAndroid;
-CREATE VIEW RefreshPeriodAndroid AS
--- Not implemented yet.
-SELECT NULL AS interval_ms
-;
-
-DROP VIEW IF EXISTS RefreshPeriodNonAndroid;
-CREATE VIEW RefreshPeriodNonAndroid AS
-SELECT EXTRACT_ARG(arg_set_id, 'debug.args.interval_us') / 1e3 AS interval_ms
-FROM slice
-JOIN thread_track ON (slice.track_id = thread_track.id)
-JOIN thread ON (thread_track.utid = thread.utid)
-WHERE thread.name = 'Compositor' AND slice.name = 'Scheduler::BeginFrame'
-LIMIT 1;
-
-DROP VIEW IF EXISTS RefreshPeriodDefault;
-CREATE VIEW RefreshPeriodDefault AS
-SELECT 1000.0 / 60 AS interval_ms;
-
-DROP TABLE IF EXISTS RefreshPeriod;
-CREATE TABLE RefreshPeriod AS
-SELECT COALESCE(
- (SELECT interval_ms FROM RefreshPeriodAndroid),
- (SELECT interval_ms FROM RefreshPeriodNonAndroid),
- (SELECT interval_ms FROM RefreshPeriodDefault)
-) AS interval_ms;
-
---------------------------------------------------------------------------------
--- Compute average FPS
-
-DROP VIEW IF EXISTS ValidFrameTimes;
-CREATE VIEW ValidFrameTimes AS
-SELECT
- dur_ms / (SELECT interval_ms FROM RefreshPeriod) AS length,
- exp
-FROM FrameTimes
-WHERE dur_ms / (SELECT interval_ms FROM RefreshPeriod) >= 0.5;
-
-DROP VIEW IF EXISTS AvgSurfaceFps;
-CREATE VIEW AvgSurfaceFps AS
-SELECT
- exp,
- 1e3 * COUNT(*) / (SELECT SUM(dur_ms) FROM FrameTimes WHERE exp = valid.exp) AS fps
-FROM ValidFrameTimes valid
-GROUP BY exp;
-
-DROP VIEW IF EXISTS frame_times_output;
-CREATE VIEW frame_times_output AS
-SELECT FrameTimes(
- 'frame_time', (SELECT RepeatedField(dur_ms) FROM FrameTimes WHERE NOT exp),
- 'exp_frame_time', (SELECT RepeatedField(dur_ms) FROM FrameTimes WHERE exp),
- 'avg_surface_fps', (SELECT fps FROM AvgSurfaceFps WHERE NOT exp),
- 'exp_avg_surface_fps', (SELECT fps FROM AvgSurfaceFps WHERE exp)
-);
-
diff --git a/src/trace_processor/metrics/experimental/reported_by_page.sql b/src/trace_processor/metrics/experimental/reported_by_page.sql
deleted file mode 100644
index 268543308..000000000
--- a/src/trace_processor/metrics/experimental/reported_by_page.sql
+++ /dev/null
@@ -1,66 +0,0 @@
---
--- Copyright 2021 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
-
---------------------------------------------------------------------------------
--- Collect page-reported events for each renderer. Note that we don't need to
--- match up process ids, because the unique nav_id ensures we're only comparing
--- corresponding events.
-
-DROP VIEW IF EXISTS page_reported_events;
-CREATE VIEW page_reported_events AS
-SELECT ts, name, EXTRACT_ARG(arg_set_id, "debug.data.navigationId") as nav_id
-FROM slice
-WHERE category = 'blink.user_timing' AND
- (name = 'navigationStart' OR name LIKE 'telemetry:reported_by_page:%')
-ORDER BY nav_id, ts ASC;
-
---------------------------------------------------------------------------------
--- Compute the duration from the corresponding navigation start for each
--- reported event.
-
-DROP VIEW IF EXISTS page_reported_durations;
-CREATE VIEW page_reported_durations AS
-SELECT p.name, (p.ts - (
- SELECT MAX(ts) FROM page_reported_events
- WHERE
- nav_id = p.nav_id AND
- ts < p.ts AND (
- -- Viewable/interactive markers measure time from nav start.
- (p.name LIKE 'telemetry:reported_by_page:%' AND
- p.name NOT LIKE 'telemetry:reported_by_page:benchmark%' AND
- name = 'navigationStart') OR
- -- Benchmark end markers measure time from the most recent begin marker.
- (p.name = 'telemetry:reported_by_page:benchmark_end' AND
- name = 'telemetry:reported_by_page:benchmark_begin')
- ))
- ) / 1e6 as dur_ms
-FROM page_reported_events p;
-
---------------------------------------------------------------------------------
--- Combine results into the output table.
-
-DROP VIEW IF EXISTS reported_by_page_output;
-CREATE VIEW reported_by_page_output AS
-SELECT ReportedByPage(
- 'time_to_viewable', (
- SELECT RepeatedField(dur_ms) FROM page_reported_durations
- WHERE name = 'telemetry:reported_by_page:viewable'),
- 'time_to_interactive', (
- SELECT RepeatedField(dur_ms) FROM page_reported_durations
- WHERE name = 'telemetry:reported_by_page:interactive'),
- 'benchmark_time', (
- SELECT RepeatedField(dur_ms) FROM page_reported_durations
- WHERE name = 'telemetry:reported_by_page:benchmark_end')
-);
diff --git a/src/trace_processor/metrics/metrics.cc b/src/trace_processor/metrics/metrics.cc
index c58fb1f3d..929da0c7a 100644
--- a/src/trace_processor/metrics/metrics.cc
+++ b/src/trace_processor/metrics/metrics.cc
@@ -20,11 +20,13 @@
#include <unordered_map>
#include <vector>
+#include "perfetto/base/status.h"
#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/utils.h"
#include "perfetto/protozero/scattered_heap_buffer.h"
-#include "src/trace_processor/metrics/sql_metrics.h"
+#include "src/trace_processor/sqlite/sqlite_utils.h"
#include "src/trace_processor/tp_metatrace.h"
+#include "src/trace_processor/util/descriptors.h"
#include "src/trace_processor/util/status_macros.h"
#include "protos/perfetto/common/descriptor.pbzero.h"
@@ -36,45 +38,61 @@ namespace metrics {
namespace {
-// TODO(lalitm): delete this and use sqlite_utils when that is cleaned up of
-// trace processor dependencies.
-const char* ExtractSqliteValue(sqlite3_value* value) {
- auto type = sqlite3_value_type(value);
- PERFETTO_DCHECK(type == SQLITE_TEXT);
- return reinterpret_cast<const char*>(sqlite3_value_text(value));
-}
+base::Status ValidateSingleNonEmptyMessage(const uint8_t* ptr,
+ size_t size,
+ uint32_t schema_type,
+ const std::string& message_type,
+ protozero::ConstBytes* out) {
+ PERFETTO_DCHECK(size > 0);
-SqlValue SqlValueFromSqliteValue(sqlite3_value* value) {
- SqlValue sql_value;
- switch (sqlite3_value_type(value)) {
- case SQLITE_INTEGER:
- sql_value.type = SqlValue::Type::kLong;
- sql_value.long_value = sqlite3_value_int64(value);
- break;
- case SQLITE_FLOAT:
- sql_value.type = SqlValue::Type::kDouble;
- sql_value.double_value = sqlite3_value_double(value);
- break;
- case SQLITE_TEXT:
- sql_value.type = SqlValue::Type::kString;
- sql_value.string_value =
- reinterpret_cast<const char*>(sqlite3_value_text(value));
- break;
- case SQLITE_BLOB:
- sql_value.type = SqlValue::Type::kBytes;
- sql_value.bytes_value = sqlite3_value_blob(value);
- sql_value.bytes_count = static_cast<size_t>(sqlite3_value_bytes(value));
- break;
+ if (size > protozero::proto_utils::kMaxMessageLength) {
+ return base::ErrStatus(
+ "Message has size %zu which is larger than the maximum allowed message "
+ "size %zu",
+ size, protozero::proto_utils::kMaxMessageLength);
+ }
+
+ protos::pbzero::ProtoBuilderResult::Decoder decoder(ptr, size);
+ if (decoder.is_repeated()) {
+ return base::ErrStatus("Cannot handle nested repeated messages");
+ }
+
+ const auto& single_field = decoder.single();
+ protos::pbzero::SingleBuilderResult::Decoder single(single_field.data,
+ single_field.size);
+
+ if (single.type() != schema_type) {
+ return base::ErrStatus("Message field has wrong wire type %d",
+ single.type());
+ }
+
+ base::StringView actual_type(single.type_name());
+ if (actual_type != base::StringView(message_type)) {
+ return base::ErrStatus("Field has wrong type (expected %s, was %s)",
+ message_type.c_str(),
+ actual_type.ToStdString().c_str());
}
- return sql_value;
+
+ if (!single.has_protobuf()) {
+ return base::ErrStatus("Message has no proto bytes");
+ }
+
+ // We disallow 0 size fields here as they should have been reported as null
+ // one layer down.
+ *out = single.protobuf();
+ if (out->size == 0) {
+ return base::ErrStatus("Field has zero size");
+ }
+ return base::OkStatus();
}
} // namespace
-ProtoBuilder::ProtoBuilder(const ProtoDescriptor* descriptor)
- : descriptor_(descriptor) {}
+ProtoBuilder::ProtoBuilder(const DescriptorPool* pool,
+ const ProtoDescriptor* descriptor)
+ : pool_(pool), descriptor_(descriptor) {}
-util::Status ProtoBuilder::AppendSqlValue(const std::string& field_name,
+base::Status ProtoBuilder::AppendSqlValue(const std::string& field_name,
const SqlValue& value) {
switch (value.type) {
case SqlValue::kLong:
@@ -90,24 +108,24 @@ util::Status ProtoBuilder::AppendSqlValue(const std::string& field_name,
case SqlValue::kNull:
// If the value is null, it's treated as the field being absent so we
// don't append anything.
- return util::OkStatus();
+ return base::OkStatus();
}
PERFETTO_FATAL("For GCC");
}
-util::Status ProtoBuilder::AppendLong(const std::string& field_name,
+base::Status ProtoBuilder::AppendLong(const std::string& field_name,
int64_t value,
bool is_inside_repeated) {
auto field = descriptor_->FindFieldByName(field_name);
if (!field) {
- return util::ErrStatus("Field with name %s not found in proto type %s",
+ return base::ErrStatus("Field with name %s not found in proto type %s",
field_name.c_str(),
descriptor_->full_name().c_str());
}
using FieldDescriptorProto = protos::pbzero::FieldDescriptorProto;
if (field->is_repeated() && !is_inside_repeated) {
- return util::ErrStatus(
+ return base::ErrStatus(
"Unexpected long value for repeated field %s in proto type %s",
field_name.c_str(), descriptor_->full_name().c_str());
}
@@ -117,9 +135,32 @@ util::Status ProtoBuilder::AppendLong(const std::string& field_name,
case FieldDescriptorProto::TYPE_INT64:
case FieldDescriptorProto::TYPE_UINT32:
case FieldDescriptorProto::TYPE_BOOL:
- case FieldDescriptorProto::TYPE_ENUM:
message_->AppendVarInt(field->number(), value);
break;
+ case FieldDescriptorProto::TYPE_ENUM: {
+ auto opt_enum_descriptor_idx =
+ pool_->FindDescriptorIdx(field->resolved_type_name());
+ if (!opt_enum_descriptor_idx) {
+ return base::ErrStatus(
+ "Unable to find enum type %s to fill field %s (in proto message "
+ "%s)",
+ field->resolved_type_name().c_str(), field->name().c_str(),
+ descriptor_->full_name().c_str());
+ }
+ const auto& enum_desc = pool_->descriptors()[*opt_enum_descriptor_idx];
+ auto opt_enum_str = enum_desc.FindEnumString(static_cast<int32_t>(value));
+ if (!opt_enum_str) {
+ return base::ErrStatus("Invalid enum value %" PRId64
+ " "
+ "in enum type %s; encountered while filling "
+ "field %s (in proto message %s)",
+ value, field->resolved_type_name().c_str(),
+ field->name().c_str(),
+ descriptor_->full_name().c_str());
+ }
+ message_->AppendVarInt(field->number(), value);
+ break;
+ }
case FieldDescriptorProto::TYPE_SINT32:
case FieldDescriptorProto::TYPE_SINT64:
message_->AppendSignedVarInt(field->number(), value);
@@ -130,30 +171,36 @@ util::Status ProtoBuilder::AppendLong(const std::string& field_name,
case FieldDescriptorProto::TYPE_SFIXED64:
message_->AppendFixed(field->number(), value);
break;
+ case FieldDescriptorProto::TYPE_UINT64:
+ return base::ErrStatus(
+ "Field %s (in proto message %s) is using a uint64 type. uint64 in "
+ "metric messages is not supported by trace processor; use an int64 "
+ "field instead.",
+ field->name().c_str(), descriptor_->full_name().c_str());
default: {
- return util::ErrStatus(
+ return base::ErrStatus(
"Tried to write value of type long into field %s (in proto type %s) "
"which has type %d",
field->name().c_str(), descriptor_->full_name().c_str(),
field->type());
}
}
- return util::OkStatus();
+ return base::OkStatus();
}
-util::Status ProtoBuilder::AppendDouble(const std::string& field_name,
+base::Status ProtoBuilder::AppendDouble(const std::string& field_name,
double value,
bool is_inside_repeated) {
auto field = descriptor_->FindFieldByName(field_name);
if (!field) {
- return util::ErrStatus("Field with name %s not found in proto type %s",
+ return base::ErrStatus("Field with name %s not found in proto type %s",
field_name.c_str(),
descriptor_->full_name().c_str());
}
using FieldDescriptorProto = protos::pbzero::FieldDescriptorProto;
if (field->is_repeated() && !is_inside_repeated) {
- return util::ErrStatus(
+ return base::ErrStatus(
"Unexpected double value for repeated field %s in proto type %s",
field_name.c_str(), descriptor_->full_name().c_str());
}
@@ -169,29 +216,29 @@ util::Status ProtoBuilder::AppendDouble(const std::string& field_name,
break;
}
default: {
- return util::ErrStatus(
+ return base::ErrStatus(
"Tried to write value of type double into field %s (in proto type "
"%s) which has type %d",
field->name().c_str(), descriptor_->full_name().c_str(),
field->type());
}
}
- return util::OkStatus();
+ return base::OkStatus();
}
-util::Status ProtoBuilder::AppendString(const std::string& field_name,
+base::Status ProtoBuilder::AppendString(const std::string& field_name,
base::StringView data,
bool is_inside_repeated) {
const FieldDescriptor* field = descriptor_->FindFieldByName(field_name);
if (!field) {
- return util::ErrStatus("Field with name %s not found in proto type %s",
+ return base::ErrStatus("Field with name %s not found in proto type %s",
field_name.c_str(),
descriptor_->full_name().c_str());
}
using FieldDescriptorProto = protos::pbzero::FieldDescriptorProto;
if (field->is_repeated() && !is_inside_repeated) {
- return util::ErrStatus(
+ return base::ErrStatus(
"Unexpected string value for repeated field %s in proto type %s",
field_name.c_str(), descriptor_->full_name().c_str());
}
@@ -201,24 +248,48 @@ util::Status ProtoBuilder::AppendString(const std::string& field_name,
message_->AppendBytes(field->number(), data.data(), data.size());
break;
}
+ case FieldDescriptorProto::TYPE_ENUM: {
+ auto opt_enum_descriptor_idx =
+ pool_->FindDescriptorIdx(field->resolved_type_name());
+ if (!opt_enum_descriptor_idx) {
+ return base::ErrStatus(
+ "Unable to find enum type %s to fill field %s (in proto message "
+ "%s)",
+ field->resolved_type_name().c_str(), field->name().c_str(),
+ descriptor_->full_name().c_str());
+ }
+ const auto& enum_desc = pool_->descriptors()[*opt_enum_descriptor_idx];
+ std::string enum_str = data.ToStdString();
+ auto opt_enum_value = enum_desc.FindEnumValue(enum_str);
+ if (!opt_enum_value) {
+ return base::ErrStatus(
+ "Invalid enum string %s "
+ "in enum type %s; encountered while filling "
+ "field %s (in proto message %s)",
+ enum_str.c_str(), field->resolved_type_name().c_str(),
+ field->name().c_str(), descriptor_->full_name().c_str());
+ }
+ message_->AppendVarInt(field->number(), *opt_enum_value);
+ break;
+ }
default: {
- return util::ErrStatus(
+ return base::ErrStatus(
"Tried to write value of type string into field %s (in proto type "
"%s) which has type %d",
field->name().c_str(), descriptor_->full_name().c_str(),
field->type());
}
}
- return util::OkStatus();
+ return base::OkStatus();
}
-util::Status ProtoBuilder::AppendBytes(const std::string& field_name,
+base::Status ProtoBuilder::AppendBytes(const std::string& field_name,
const uint8_t* ptr,
size_t size,
bool is_inside_repeated) {
const FieldDescriptor* field = descriptor_->FindFieldByName(field_name);
if (!field) {
- return util::ErrStatus("Field with name %s not found in proto type %s",
+ return base::ErrStatus("Field with name %s not found in proto type %s",
field_name.c_str(),
descriptor_->full_name().c_str());
}
@@ -231,7 +302,7 @@ util::Status ProtoBuilder::AppendBytes(const std::string& field_name,
return AppendSingleMessage(*field, ptr, size);
if (size == 0) {
- return util::ErrStatus(
+ return base::ErrStatus(
"Tried to write zero-sized value into field %s (in proto type "
"%s). Nulls are only supported for message protos; all other types "
"should ensure that nulls are not passed to proto builder functions by "
@@ -239,13 +310,13 @@ util::Status ProtoBuilder::AppendBytes(const std::string& field_name,
field->name().c_str(), descriptor_->full_name().c_str());
}
- return util::ErrStatus(
+ return base::ErrStatus(
"Tried to write value of type bytes into field %s (in proto type %s) "
"which has type %d",
field->name().c_str(), descriptor_->full_name().c_str(), field->type());
}
-util::Status ProtoBuilder::AppendSingleMessage(const FieldDescriptor& field,
+base::Status ProtoBuilder::AppendSingleMessage(const FieldDescriptor& field,
const uint8_t* ptr,
size_t size) {
// If we have an zero sized bytes, we still want to propogate that the field
@@ -255,53 +326,35 @@ util::Status ProtoBuilder::AppendSingleMessage(const FieldDescriptor& field,
// just pass an empty string (which will have a valid pointer always) and
// zero as the size.
message_->AppendBytes(field.number(), "", 0);
- return util::OkStatus();
- }
-
- protos::pbzero::ProtoBuilderResult::Decoder decoder(ptr, size);
- if (decoder.is_repeated()) {
- return util::ErrStatus("Cannot handle nested repeated messages in field %s",
- field.name().c_str());
- }
-
- const auto& single_field = decoder.single();
- protos::pbzero::SingleBuilderResult::Decoder single(single_field.data,
- single_field.size);
-
- if (single.type() != field.type()) {
- return util::ErrStatus("Field %s has wrong type (expected %u, was %u)",
- field.name().c_str(), field.type(), single.type());
+ return base::OkStatus();
}
- auto actual_type_name = single.type_name().ToStdString();
- if (actual_type_name != field.resolved_type_name()) {
- return util::ErrStatus("Field %s has wrong type (expected %s, was %s)",
- field.name().c_str(), actual_type_name.c_str(),
- field.resolved_type_name().c_str());
+ protozero::ConstBytes bytes;
+ base::Status validation = ValidateSingleNonEmptyMessage(
+ ptr, size, field.type(), field.resolved_type_name(), &bytes);
+ if (!validation.ok()) {
+ return util::ErrStatus("[Field %s in message %s]: %s", field.name().c_str(),
+ descriptor_->full_name().c_str(),
+ validation.c_message());
}
-
- if (!single.has_protobuf()) {
- return util::ErrStatus("Field %s has no proto bytes", field.name().c_str());
- }
-
- // We disallow 0 size fields here as they should have been reported as null
- // one layer down.
- auto bytes = single.protobuf();
- if (bytes.size == 0) {
- return util::ErrStatus("Unexpected to see field %s with zero size",
- field.name().c_str());
- }
-
message_->AppendBytes(field.number(), bytes.data, bytes.size);
- return util::OkStatus();
+ return base::OkStatus();
}
-util::Status ProtoBuilder::AppendRepeated(const FieldDescriptor& field,
+base::Status ProtoBuilder::AppendRepeated(const FieldDescriptor& field,
const uint8_t* ptr,
size_t size) {
+ if (size > protozero::proto_utils::kMaxMessageLength) {
+ return base::ErrStatus(
+ "Message passed to field %s in proto message %s has size %zu which is "
+ "larger than the maximum allowed message size %zu",
+ field.name().c_str(), descriptor_->full_name().c_str(), size,
+ protozero::proto_utils::kMaxMessageLength);
+ }
+
protos::pbzero::ProtoBuilderResult::Decoder decoder(ptr, size);
if (!decoder.is_repeated()) {
- return util::ErrStatus(
+ return base::ErrStatus(
"Unexpected message value for repeated field %s in proto type %s",
field.name().c_str(), descriptor_->full_name().c_str());
}
@@ -311,7 +364,7 @@ util::Status ProtoBuilder::AppendRepeated(const FieldDescriptor& field,
for (auto it = repeated.value(); it; ++it) {
protos::pbzero::RepeatedBuilderResult::Value::Decoder value(*it);
- util::Status status;
+ base::Status status;
if (value.has_int_value()) {
status = AppendLong(field.name(), value.int_value(), true);
} else if (value.has_double_value()) {
@@ -323,13 +376,13 @@ util::Status ProtoBuilder::AppendRepeated(const FieldDescriptor& field,
const auto& bytes = value.bytes_value();
status = AppendBytes(field.name(), bytes.data, bytes.size, true);
} else {
- status = util::ErrStatus("Unknown type in repeated field");
+ status = base::ErrStatus("Unknown type in repeated field");
}
if (!status.ok())
return status;
}
- return util::OkStatus();
+ return base::OkStatus();
}
std::vector<uint8_t> ProtoBuilder::SerializeToProtoBuilderResult() {
@@ -357,7 +410,7 @@ RepeatedFieldBuilder::RepeatedFieldBuilder() {
repeated_ = message_->set_repeated();
}
-util::Status RepeatedFieldBuilder::AddSqlValue(SqlValue value) {
+base::Status RepeatedFieldBuilder::AddSqlValue(SqlValue value) {
switch (value.type) {
case SqlValue::kLong:
AddLong(value.long_value);
@@ -376,7 +429,7 @@ util::Status RepeatedFieldBuilder::AddSqlValue(SqlValue value) {
AddBytes(nullptr, 0);
break;
}
- return util::OkStatus();
+ return base::OkStatus();
}
void RepeatedFieldBuilder::AddLong(int64_t value) {
@@ -432,22 +485,24 @@ int TemplateReplace(
return 0;
}
-void NullIfEmpty(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
+base::Status NullIfEmpty::Run(void*,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors&) {
// SQLite should enforce this for us.
PERFETTO_CHECK(argc == 1);
if (sqlite3_value_type(argv[0]) != SQLITE_BLOB) {
- sqlite3_result_error(
- ctx, "NULL_IF_EMPTY: should only be called with bytes argument", -1);
- return;
+ return base::ErrStatus(
+ "NULL_IF_EMPTY: should only be called with bytes argument");
}
- if (sqlite3_value_bytes(argv[0]) == 0) {
- sqlite3_result_null(ctx);
- return;
- }
+ if (sqlite3_value_bytes(argv[0]) == 0)
+ return base::OkStatus();
- sqlite3_result_value(ctx, argv[0]);
+ out = sqlite_utils::SqliteValueToSqlValue(argv[0]);
+ return base::OkStatus();
}
void RepeatedFieldStep(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
@@ -470,7 +525,7 @@ void RepeatedFieldStep(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
*builder_ptr_ptr = new RepeatedFieldBuilder();
}
- auto value = SqlValueFromSqliteValue(argv[0]);
+ auto value = sqlite_utils::SqliteValueToSqlValue(argv[0]);
RepeatedFieldBuilder* builder = *builder_ptr_ptr;
auto status = builder->AddSqlValue(value);
if (!status.ok()) {
@@ -513,31 +568,26 @@ void RepeatedFieldFinal(sqlite3_context* ctx) {
// as byte blobs (as they were built recursively using this function).
// The return value is the built proto or an error about why the proto could
// not be built.
-void BuildProto(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
- const auto* fn_ctx =
- static_cast<const BuildProtoContext*>(sqlite3_user_data(ctx));
+base::Status BuildProto::Run(BuildProto::Context* ctx,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors& destructors) {
+ const ProtoDescriptor& desc = ctx->pool->descriptors()[ctx->descriptor_idx];
if (argc % 2 != 0) {
- util::Status error =
- util::ErrStatus("Invalid number of args to %s BuildProto (got %d)",
- fn_ctx->desc->full_name().c_str(), argc);
- sqlite3_result_error(ctx, error.c_message(), -1);
- return;
+ return base::ErrStatus("Invalid number of args to %s BuildProto (got %zu)",
+ desc.full_name().c_str(), argc);
}
- ProtoBuilder builder(fn_ctx->desc);
- for (int i = 0; i < argc; i += 2) {
+ ProtoBuilder builder(ctx->pool, &desc);
+ for (size_t i = 0; i < argc; i += 2) {
if (sqlite3_value_type(argv[i]) != SQLITE_TEXT) {
- sqlite3_result_error(ctx, "BuildProto: Invalid args", -1);
- return;
+ return base::ErrStatus("BuildProto: Invalid args");
}
auto* key = reinterpret_cast<const char*>(sqlite3_value_text(argv[i]));
- auto value = SqlValueFromSqliteValue(argv[i + 1]);
- auto status = builder.AppendSqlValue(key, value);
- if (!status.ok()) {
- sqlite3_result_error(ctx, status.c_message(), -1);
- return;
- }
+ auto value = sqlite_utils::SqliteValueToSqlValue(argv[i + 1]);
+ RETURN_IF_ERROR(builder.AppendSqlValue(key, value));
}
// Even if the message is empty, we don't return null here as we want the
@@ -546,78 +596,125 @@ void BuildProto(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
if (raw.empty()) {
// Passing nullptr to SQLite feels dangerous so just pass an empty string
// and zero as the size so we don't deref nullptr accidentially somewhere.
- sqlite3_result_blob(ctx, "", 0, nullptr);
- return;
+ destructors.bytes_destructor = sqlite_utils::kSqliteStatic;
+ out = SqlValue::Bytes("", 0);
+ return base::OkStatus();
}
std::unique_ptr<uint8_t[], base::FreeDeleter> data(
static_cast<uint8_t*>(malloc(raw.size())));
memcpy(data.get(), raw.data(), raw.size());
- sqlite3_result_blob(ctx, data.release(), static_cast<int>(raw.size()), free);
+
+ destructors.bytes_destructor = free;
+ out = SqlValue::Bytes(data.release(), raw.size());
+ return base::OkStatus();
}
-void RunMetric(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
- auto* fn_ctx = static_cast<RunMetricContext*>(sqlite3_user_data(ctx));
- if (argc == 0 || sqlite3_value_type(argv[0]) != SQLITE_TEXT) {
- sqlite3_result_error(ctx, "RUN_METRIC: Invalid arguments", -1);
- return;
- }
+base::Status RunMetric::Run(RunMetric::Context* ctx,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue&,
+ Destructors&) {
+ if (argc == 0 || sqlite3_value_type(argv[0]) != SQLITE_TEXT)
+ return base::ErrStatus("RUN_METRIC: Invalid arguments");
const char* path = reinterpret_cast<const char*>(sqlite3_value_text(argv[0]));
auto metric_it = std::find_if(
- fn_ctx->metrics->begin(), fn_ctx->metrics->end(),
+ ctx->metrics->begin(), ctx->metrics->end(),
[path](const SqlMetricFile& metric) { return metric.path == path; });
- if (metric_it == fn_ctx->metrics->end()) {
- sqlite3_result_error(ctx, "RUN_METRIC: Unknown filename provided", -1);
- return;
+ if (metric_it == ctx->metrics->end()) {
+ return base::ErrStatus("RUN_METRIC: Unknown filename provided %s", path);
}
- const auto& sql = metric_it->sql;
std::unordered_map<std::string, std::string> substitutions;
- for (int i = 1; i < argc; i += 2) {
- if (sqlite3_value_type(argv[i]) != SQLITE_TEXT) {
- sqlite3_result_error(ctx, "RUN_METRIC: Invalid args", -1);
- return;
+ for (size_t i = 1; i < argc; i += 2) {
+ if (sqlite3_value_type(argv[i]) != SQLITE_TEXT)
+ return base::ErrStatus("RUN_METRIC: all keys must be strings");
+
+ base::Optional<std::string> key_str = sqlite_utils::SqlValueToString(
+ sqlite_utils::SqliteValueToSqlValue(argv[i]));
+ base::Optional<std::string> value_str = sqlite_utils::SqlValueToString(
+ sqlite_utils::SqliteValueToSqlValue(argv[i + 1]));
+
+ if (!value_str) {
+ return base::ErrStatus(
+ "RUN_METRIC: all values must be convertible to strings");
}
+ substitutions[*key_str] = *value_str;
+ }
- auto* key_str = ExtractSqliteValue(argv[i]);
- auto* value_str = ExtractSqliteValue(argv[i + 1]);
- substitutions[key_str] = value_str;
+ std::string subbed_sql;
+ int ret = TemplateReplace(metric_it->sql, substitutions, &subbed_sql);
+ if (ret) {
+ return base::ErrStatus(
+ "RUN_METRIC: Error when performing substitutions: %s",
+ metric_it->sql.c_str());
}
- for (const auto& query : base::SplitString(sql, ";\n")) {
- std::string buffer;
- int ret = TemplateReplace(query, substitutions, &buffer);
- if (ret) {
- char* error = sqlite3_mprintf(
- "RUN_METRIC: Error when performing substitutions: %s", query.c_str());
- sqlite3_result_error(ctx, error, -1);
- return;
- }
+ auto it = ctx->tp->ExecuteQuery(subbed_sql);
+ it.Next();
- PERFETTO_DLOG("RUN_METRIC: Executing query: %s", buffer.c_str());
- auto it = fn_ctx->tp->ExecuteQuery(buffer);
- it.Next();
-
- util::Status status = it.Status();
- if (!status.ok()) {
- char* error =
- sqlite3_mprintf("RUN_METRIC: Error when running file %s: %s", path,
- status.c_message());
- sqlite3_result_error(ctx, error, -1);
- sqlite3_free(error);
- return;
- }
+ base::Status status = it.Status();
+ if (!status.ok()) {
+ return base::ErrStatus("RUN_METRIC: Error when running file %s: %s", path,
+ status.c_message());
}
- sqlite3_result_null(ctx);
+ return base::OkStatus();
}
-util::Status ComputeMetrics(TraceProcessor* tp,
+base::Status UnwrapMetricProto::Run(Context*,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors& destructors) {
+ if (argc != 2) {
+ return base::ErrStatus(
+ "UNWRAP_METRIC_PROTO: Expected exactly proto and message type as "
+ "arguments");
+ }
+
+ SqlValue proto = sqlite_utils::SqliteValueToSqlValue(argv[0]);
+ SqlValue message_type = sqlite_utils::SqliteValueToSqlValue(argv[1]);
+
+ if (proto.type != SqlValue::Type::kBytes)
+ return base::ErrStatus("UNWRAP_METRIC_PROTO: proto is not a blob");
+
+ if (message_type.type != SqlValue::Type::kString)
+ return base::ErrStatus("UNWRAP_METRIC_PROTO: message type is not string");
+
+ const uint8_t* ptr = static_cast<const uint8_t*>(proto.AsBytes());
+ size_t size = proto.bytes_count;
+ if (size == 0) {
+ destructors.bytes_destructor = sqlite_utils::kSqliteStatic;
+ out = SqlValue::Bytes("", 0);
+ return base::OkStatus();
+ }
+
+ static constexpr uint32_t kMessageType =
+ static_cast<uint32_t>(protozero::proto_utils::ProtoSchemaType::kMessage);
+ protozero::ConstBytes bytes;
+ base::Status validation = ValidateSingleNonEmptyMessage(
+ ptr, size, kMessageType, message_type.AsString(), &bytes);
+ if (!validation.ok())
+ return base::ErrStatus("UNWRAP_METRICS_PROTO: %s", validation.c_message());
+
+ std::unique_ptr<uint8_t[], base::FreeDeleter> data(
+ static_cast<uint8_t*>(malloc(bytes.size)));
+ memcpy(data.get(), bytes.data, bytes.size);
+
+ destructors.bytes_destructor = free;
+ out = SqlValue::Bytes(data.release(), bytes.size);
+
+ return base::OkStatus();
+}
+
+base::Status ComputeMetrics(TraceProcessor* tp,
const std::vector<std::string> metrics_to_compute,
const std::vector<SqlMetricFile>& sql_metrics,
+ const DescriptorPool& pool,
const ProtoDescriptor& root_descriptor,
std::vector<uint8_t>* metrics_proto) {
- ProtoBuilder metric_builder(&root_descriptor);
+ ProtoBuilder metric_builder(&pool, &root_descriptor);
for (const auto& name : metrics_to_compute) {
auto metric_it =
std::find_if(sql_metrics.begin(), sql_metrics.end(),
@@ -626,20 +723,15 @@ util::Status ComputeMetrics(TraceProcessor* tp,
name == metric.proto_field_name.value();
});
if (metric_it == sql_metrics.end())
- return util::ErrStatus("Unknown metric %s", name.c_str());
+ return base::ErrStatus("Unknown metric %s", name.c_str());
const auto& sql_metric = *metric_it;
- auto queries = base::SplitString(sql_metric.sql, ";\n");
- for (const auto& query : queries) {
- PERFETTO_DLOG("Executing query: %s", query.c_str());
- auto prep_it = tp->ExecuteQuery(query);
- prep_it.Next();
- RETURN_IF_ERROR(prep_it.Status());
- }
+ auto prep_it = tp->ExecuteQuery(sql_metric.sql);
+ prep_it.Next();
+ RETURN_IF_ERROR(prep_it.Status());
auto output_query =
"SELECT * FROM " + sql_metric.output_table_name.value() + ";";
- PERFETTO_DLOG("Executing output query: %s", output_query.c_str());
PERFETTO_TP_TRACE("COMPUTE_METRIC_QUERY", [&](metatrace::Record* r) {
r->AddArg("SQL", output_query);
});
@@ -657,27 +749,27 @@ util::Status ComputeMetrics(TraceProcessor* tp,
}
if (it.ColumnCount() != 1) {
- return util::ErrStatus("Output table %s should have exactly one column",
+ return base::ErrStatus("Output table %s should have exactly one column",
sql_metric.output_table_name.value().c_str());
}
SqlValue col = it.Get(0);
if (col.type != SqlValue::kBytes) {
- return util::ErrStatus("Output table %s column has invalid type",
+ return base::ErrStatus("Output table %s column has invalid type",
sql_metric.output_table_name.value().c_str());
}
RETURN_IF_ERROR(metric_builder.AppendSqlValue(field_name, col));
has_next = it.Next();
if (has_next) {
- return util::ErrStatus("Output table %s should have at most one row",
+ return base::ErrStatus("Output table %s should have at most one row",
sql_metric.output_table_name.value().c_str());
}
RETURN_IF_ERROR(it.Status());
}
*metrics_proto = metric_builder.SerializeRaw();
- return util::OkStatus();
+ return base::OkStatus();
}
} // namespace metrics
diff --git a/src/trace_processor/metrics/metrics.h b/src/trace_processor/metrics/metrics.h
index dea62f7bf..090d67332 100644
--- a/src/trace_processor/metrics/metrics.h
+++ b/src/trace_processor/metrics/metrics.h
@@ -27,6 +27,7 @@
#include "perfetto/protozero/message.h"
#include "perfetto/protozero/scattered_heap_buffer.h"
#include "perfetto/trace_processor/trace_processor.h"
+#include "src/trace_processor/sqlite/register_function.h"
#include "src/trace_processor/util/descriptors.h"
#include "protos/perfetto/trace_processor/metrics_impl.pbzero.h"
@@ -61,24 +62,24 @@ struct SqlMetricFile {
// Visible for testing.
class ProtoBuilder {
public:
- ProtoBuilder(const ProtoDescriptor*);
+ ProtoBuilder(const DescriptorPool*, const ProtoDescriptor*);
- util::Status AppendSqlValue(const std::string& field_name,
+ base::Status AppendSqlValue(const std::string& field_name,
const SqlValue& value);
// Note: all external callers to these functions should not
// |is_inside_repeated| to this function and instead rely on the default
// value.
- util::Status AppendLong(const std::string& field_name,
+ base::Status AppendLong(const std::string& field_name,
int64_t value,
bool is_inside_repeated = false);
- util::Status AppendDouble(const std::string& field_name,
+ base::Status AppendDouble(const std::string& field_name,
double value,
bool is_inside_repeated = false);
- util::Status AppendString(const std::string& field_name,
+ base::Status AppendString(const std::string& field_name,
base::StringView value,
bool is_inside_repeated = false);
- util::Status AppendBytes(const std::string& field_name,
+ base::Status AppendBytes(const std::string& field_name,
const uint8_t* data,
size_t size,
bool is_inside_repeated = false);
@@ -98,14 +99,15 @@ class ProtoBuilder {
std::vector<uint8_t> SerializeRaw();
private:
- util::Status AppendSingleMessage(const FieldDescriptor& field,
+ base::Status AppendSingleMessage(const FieldDescriptor& field,
const uint8_t* ptr,
size_t size);
- util::Status AppendRepeated(const FieldDescriptor& field,
+ base::Status AppendRepeated(const FieldDescriptor& field,
const uint8_t* ptr,
size_t size);
+ const DescriptorPool* pool_ = nullptr;
const ProtoDescriptor* descriptor_ = nullptr;
protozero::HeapBuffered<protozero::Message> message_;
};
@@ -117,7 +119,7 @@ class RepeatedFieldBuilder {
public:
RepeatedFieldBuilder();
- util::Status AddSqlValue(SqlValue value);
+ base::Status AddSqlValue(SqlValue value);
void AddLong(int64_t value);
void AddDouble(double value);
@@ -148,34 +150,58 @@ int TemplateReplace(
std::string* out);
// Implements the NULL_IF_EMPTY SQL function.
-void NullIfEmpty(sqlite3_context* ctx, int argc, sqlite3_value** argv);
-
-// These functions implement the RepeatedField SQL aggregate functions.
-void RepeatedFieldStep(sqlite3_context* ctx, int argc, sqlite3_value** argv);
-void RepeatedFieldFinal(sqlite3_context* ctx);
+struct NullIfEmpty : public SqlFunction {
+ static base::Status Run(void* ctx,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors&);
+};
-// Context struct for the below function.
-struct BuildProtoContext {
- TraceProcessor* tp;
- const DescriptorPool* pool;
- const ProtoDescriptor* desc;
+// Implements all the proto creation functions.
+struct BuildProto : public SqlFunction {
+ struct Context {
+ TraceProcessor* tp;
+ const DescriptorPool* pool;
+ uint32_t descriptor_idx;
+ };
+ static base::Status Run(Context* ctx,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors&);
};
-// This function implements all the proto creation functions.
-void BuildProto(sqlite3_context* ctx, int argc, sqlite3_value** argv);
+// Implements the RUN_METRIC SQL function.
+struct RunMetric : public SqlFunction {
+ struct Context {
+ TraceProcessor* tp;
+ std::vector<SqlMetricFile>* metrics;
+ };
+ static base::Status Run(Context* ctx,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors&);
+};
-// Context struct for the below function.
-struct RunMetricContext {
- TraceProcessor* tp;
- std::vector<SqlMetricFile>* metrics;
+// Implements the UNWRAP_METRIC_PROTO SQL function.
+struct UnwrapMetricProto : public SqlFunction {
+ static base::Status Run(Context* ctx,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors&);
};
-// This function implements the RUN_METRIC SQL function.
-void RunMetric(sqlite3_context* ctx, int argc, sqlite3_value** argv);
+// These functions implement the RepeatedField SQL aggregate functions.
+void RepeatedFieldStep(sqlite3_context* ctx, int argc, sqlite3_value** argv);
+void RepeatedFieldFinal(sqlite3_context* ctx);
-util::Status ComputeMetrics(TraceProcessor* impl,
+base::Status ComputeMetrics(TraceProcessor* impl,
const std::vector<std::string> metrics_to_compute,
const std::vector<SqlMetricFile>& metrics,
+ const DescriptorPool& pool,
const ProtoDescriptor& root_descriptor,
std::vector<uint8_t>* metrics_proto);
diff --git a/src/trace_processor/metrics/metrics_unittest.cc b/src/trace_processor/metrics/metrics_unittest.cc
index 661df3333..29f8f6d42 100644
--- a/src/trace_processor/metrics/metrics_unittest.cc
+++ b/src/trace_processor/metrics/metrics_unittest.cc
@@ -74,13 +74,14 @@ TEST_F(ProtoBuilderTest, AppendLong) {
// message TestProto {
// optional int64 int_value = 1;
// }
+ DescriptorPool pool;
ProtoDescriptor descriptor("file.proto", ".perfetto.protos",
".perfetto.protos.TestProto",
ProtoDescriptor::Type::kMessage, base::nullopt);
descriptor.AddField(FieldDescriptor(
"int_value", 1, FieldDescriptorProto::TYPE_INT64, "", false));
- ProtoBuilder builder(&descriptor);
+ ProtoBuilder builder(&pool, &descriptor);
ASSERT_TRUE(builder.AppendLong("int_value", 12345).ok());
auto result_ser = builder.SerializeToProtoBuilderResult();
@@ -96,13 +97,14 @@ TEST_F(ProtoBuilderTest, AppendDouble) {
// message TestProto {
// optional double double_value = 1;
// }
+ DescriptorPool pool;
ProtoDescriptor descriptor("file.proto", ".perfetto.protos",
".perfetto.protos.TestProto",
ProtoDescriptor::Type::kMessage, base::nullopt);
descriptor.AddField(FieldDescriptor(
"double_value", 1, FieldDescriptorProto::TYPE_DOUBLE, "", false));
- ProtoBuilder builder(&descriptor);
+ ProtoBuilder builder(&pool, &descriptor);
ASSERT_TRUE(builder.AppendDouble("double_value", 1.2345).ok());
auto result_ser = builder.SerializeToProtoBuilderResult();
@@ -118,13 +120,14 @@ TEST_F(ProtoBuilderTest, AppendString) {
// message TestProto {
// optional string string_value = 1;
// }
+ DescriptorPool pool;
ProtoDescriptor descriptor("file.proto", ".perfetto.protos",
".perfetto.protos.TestProto",
ProtoDescriptor::Type::kMessage, base::nullopt);
descriptor.AddField(FieldDescriptor(
"string_value", 1, FieldDescriptorProto::TYPE_STRING, "", false));
- ProtoBuilder builder(&descriptor);
+ ProtoBuilder builder(&pool, &descriptor);
ASSERT_TRUE(builder.AppendString("string_value", "hello world!").ok());
auto result_ser = builder.SerializeToProtoBuilderResult();
@@ -143,6 +146,7 @@ TEST_F(ProtoBuilderTest, AppendNested) {
// }
// optional NestedProto nested_value = 1;
// }
+ DescriptorPool pool;
ProtoDescriptor nested("file.proto", ".perfetto.protos",
".perfetto.protos.TestProto.NestedProto",
ProtoDescriptor::Type::kMessage, base::nullopt);
@@ -158,12 +162,12 @@ TEST_F(ProtoBuilderTest, AppendNested) {
field.set_resolved_type_name(".perfetto.protos.TestProto.NestedProto");
descriptor.AddField(field);
- ProtoBuilder nest_builder(&nested);
+ ProtoBuilder nest_builder(&pool, &nested);
ASSERT_TRUE(nest_builder.AppendLong("nested_int_value", 789).ok());
auto nest_ser = nest_builder.SerializeToProtoBuilderResult();
- ProtoBuilder builder(&descriptor);
+ ProtoBuilder builder(&pool, &descriptor);
ASSERT_TRUE(
builder.AppendBytes("nested_value", nest_ser.data(), nest_ser.size())
.ok());
@@ -190,6 +194,7 @@ TEST_F(ProtoBuilderTest, AppendRepeatedPrimitive) {
// message TestProto {
// repeated int64 int_value = 1;
// }
+ DescriptorPool pool;
ProtoDescriptor descriptor("file.proto", ".perfetto.protos",
".perfetto.protos.TestProto",
ProtoDescriptor::Type::kMessage, base::nullopt);
@@ -202,7 +207,7 @@ TEST_F(ProtoBuilderTest, AppendRepeatedPrimitive) {
std::vector<uint8_t> rep_ser = rep_builder.SerializeToProtoBuilderResult();
- ProtoBuilder builder(&descriptor);
+ ProtoBuilder builder(&pool, &descriptor);
ASSERT_TRUE(
builder.AppendBytes("rep_int_value", rep_ser.data(), rep_ser.size())
.ok());
@@ -215,6 +220,55 @@ TEST_F(ProtoBuilderTest, AppendRepeatedPrimitive) {
ASSERT_FALSE(++it);
}
+TEST_F(ProtoBuilderTest, AppendEnums) {
+ using FieldDescriptorProto = protos::pbzero::FieldDescriptorProto;
+
+ // Create the descriptor version of the following enum and message:
+ // enum TestEnum {
+ // FIRST = 1,
+ // SECOND = 2,
+ // THIRD = 3
+ // }
+ // message TestMessage {
+ // optional TestEnum enum_value = 1;
+ // }
+ DescriptorPool pool;
+ ProtoDescriptor enum_descriptor("file.proto", ".perfetto.protos",
+ ".perfetto.protos.TestEnum",
+ ProtoDescriptor::Type::kEnum, base::nullopt);
+ enum_descriptor.AddEnumValue(1, "FIRST");
+ enum_descriptor.AddEnumValue(2, "SECOND");
+ enum_descriptor.AddEnumValue(3, "THIRD");
+ pool.AddProtoDescriptorForTesting(enum_descriptor);
+
+ ProtoDescriptor descriptor("file.proto", ".perfetto.protos",
+ ".perfetto.protos.TestMessage",
+ ProtoDescriptor::Type::kMessage, base::nullopt);
+ FieldDescriptor enum_field("enum_value", 1, FieldDescriptorProto::TYPE_ENUM,
+ ".perfetto.protos.TestEnum", false);
+ enum_field.set_resolved_type_name(".perfetto.protos.TestEnum");
+ descriptor.AddField(enum_field);
+ pool.AddProtoDescriptorForTesting(descriptor);
+
+ ProtoBuilder value_builder(&pool, &descriptor);
+ ASSERT_FALSE(value_builder.AppendLong("enum_value", 4).ok());
+ ASSERT_TRUE(value_builder.AppendLong("enum_value", 3).ok());
+ ASSERT_FALSE(value_builder.AppendLong("enum_value", 6).ok());
+
+ auto value_proto = DecodeSingleFieldProto<false>(
+ value_builder.SerializeToProtoBuilderResult());
+ ASSERT_EQ(value_proto.Get(1).as_int32(), 3);
+
+ ProtoBuilder str_builder(&pool, &descriptor);
+ ASSERT_FALSE(str_builder.AppendString("enum_value", "FOURTH").ok());
+ ASSERT_TRUE(str_builder.AppendString("enum_value", "SECOND").ok());
+ ASSERT_FALSE(str_builder.AppendString("enum_value", "OTHER").ok());
+
+ auto str_proto = DecodeSingleFieldProto<false>(
+ str_builder.SerializeToProtoBuilderResult());
+ ASSERT_EQ(str_proto.Get(1).as_int32(), 2);
+}
+
} // namespace
} // namespace metrics
diff --git a/src/trace_processor/metrics/protos/README.md b/src/trace_processor/metrics/protos/README.md
new file mode 100644
index 000000000..8b6ab1ab0
--- /dev/null
+++ b/src/trace_processor/metrics/protos/README.md
@@ -0,0 +1,11 @@
+This empty folder exists to harmonize "built-in" metrics
+work with the "metric extension" functionality of trace processor.
+
+Essentially by adding a protos folder, we can pass
+src/trace_processor/metrics as an extension path to shell to
+override all built-in metrics. This means we can change the SQL
+files *without* needing to recompile trace processor.
+
+In the future, we might also move the protos here but that would
+be a bigger change which would need coordination across repos (
+e.g. Chrome because of the metrics autoroller for Chrome metrics).
diff --git a/src/trace_processor/metrics/sql/BUILD.gn b/src/trace_processor/metrics/sql/BUILD.gn
new file mode 100644
index 000000000..28f36d17d
--- /dev/null
+++ b/src/trace_processor/metrics/sql/BUILD.gn
@@ -0,0 +1,140 @@
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("../../../../gn/perfetto.gni")
+
+sql_files = [
+ "trace_metadata.sql",
+ "trace_stats.sql",
+ "android/android_batt.sql",
+ "android/android_camera.sql",
+ "android/android_camera_unagg.sql",
+ "android/android_cpu.sql",
+ "android/android_surfaceflinger.sql",
+ "android/android_cpu_agg.sql",
+ "android/android_cpu_raw_metrics_per_core.sql",
+ "android/android_dma_heap.sql",
+ "android/android_dvfs.sql",
+ "android/android_fastrpc.sql",
+ "android/android_gpu.sql",
+ "android/android_hwui_threads.sql",
+ "android/android_mem.sql",
+ "android/android_mem_unagg.sql",
+ "android/android_netperf.sql",
+ "android/android_ion.sql",
+ "android/composer_execution.sql",
+ "android/composition_layers.sql",
+ "android/frame_missed.sql",
+ "android/android_jank.sql",
+ "android/android_lmk_reason.sql",
+ "android/android_lmk.sql",
+ "android/android_other_traces.sql",
+ "android/android_powrails.sql",
+ "android/android_proxy_power.sql",
+ "android/android_simpleperf.sql",
+ "android/android_startup.sql",
+ "android/android_package_list.sql",
+ "android/android_task_names.sql",
+ "android/android_thread_time_in_state.sql",
+ "android/android_trace_quality.sql",
+ "android/cpu_info.sql",
+ "android/display_metrics.sql",
+ "android/g2d.sql",
+ "android/g2d_duration.sql",
+ "android/android_hwcomposer.sql",
+ "android/android_hwui_metric.sql",
+ "android/java_heap_histogram.sql",
+ "android/java_heap_stats.sql",
+ "android/power_drain_in_watts.sql",
+ "android/power_profile_data.sql",
+ "android/process_unagg_mem_view.sql",
+ "android/process_mem.sql",
+ "android/process_metadata.sql",
+ "android/process_oom_score.sql",
+ "android/profiler_smaps.sql",
+ "android/android_rt_runtime.sql",
+ "android/android_irq_runtime.sql",
+ "android/mem_stats_priority_breakdown.sql",
+ "android/android_multiuser.sql",
+ "android/android_multiuser_populator.sql",
+ "android/span_view_stats.sql",
+ "android/android_sysui_cuj.sql",
+ "android/android_sysui_cuj_surfaceflinger.sql",
+ "android/android_sysui_cuj_jank_query.sql",
+ "android/process_counter_span_view.sql",
+ "android/global_counter_span_view.sql",
+ "android/gpu_counter_span_view.sql",
+ "android/thread_counter_span_view.sql",
+ "android/android_trusty_workqueues.sql",
+ "android/unsymbolized_frames.sql",
+ "android/startup/launches_maxsdk28.sql",
+ "android/startup/launches_minsdk29.sql",
+ "android/startup/launches_minsdk33.sql",
+ "android/startup/launches.sql",
+ "android/startup/hsc.sql",
+ "chrome/actual_power_by_category.sql",
+ "chrome/actual_power_by_rail_mode.sql",
+ "chrome/chrome_event_metadata.sql",
+ "chrome/chrome_histogram_hashes.sql",
+ "chrome/chrome_performance_mark_hashes.sql",
+ "chrome/chrome_processes.sql",
+ "chrome/chrome_slice_names.sql",
+ "chrome/chrome_thread_slice.sql",
+ "chrome/chrome_user_event_hashes.sql",
+ "chrome/cpu_time_by_category.sql",
+ "chrome/cpu_time_by_rail_mode.sql",
+ "chrome/estimated_power_by_category.sql",
+ "chrome/estimated_power_by_rail_mode.sql",
+ "chrome/sufficient_chrome_processes.sql",
+ "chrome/gesture_jank.sql",
+ "chrome/jank_utilities.sql",
+ "chrome/gesture_flow_event.sql",
+ "chrome/gesture_flow_event_queuing_delay.sql",
+ "chrome/rail_modes.sql",
+ "chrome/scroll_jank.sql",
+ "chrome/scroll_jank_cause.sql",
+ "chrome/scroll_jank_cause_blocking_task.sql",
+ "chrome/scroll_jank_cause_blocking_touch_move.sql",
+ "chrome/scroll_jank_cause_get_bitmap.sql",
+ "chrome/scroll_jank_cause_queuing_delay.sql",
+ "chrome/scroll_flow_event.sql",
+ "chrome/scroll_flow_event_queuing_delay.sql",
+ "chrome/test_chrome_metric.sql",
+ "chrome/touch_flow_event.sql",
+ "chrome/touch_flow_event_queuing_delay.sql",
+ "chrome/touch_jank.sql",
+ "experimental/blink_gc_metric.sql",
+ "experimental/chrome_dropped_frames.sql",
+ "experimental/chrome_long_latency.sql",
+ "experimental/frame_times.sql",
+ "experimental/media_metric.sql",
+ "experimental/reported_by_page.sql",
+ "webview/webview_power_usage.sql",
+]
+
+config("gen_config") {
+ include_dirs = [ "${root_gen_dir}/${perfetto_root_path}" ]
+}
+
+action("gen_amalgamated_sql_metrics") {
+ script = "../../../../tools/gen_amalgamated_sql_metrics.py"
+ generated_header = "${target_gen_dir}/amalgamated_sql_metrics.h"
+ args = rebase_path(sql_files, root_build_dir) + [
+ "--cpp_out",
+ rebase_path(generated_header, root_build_dir),
+ ]
+ inputs = sql_files
+ outputs = [ generated_header ]
+ public_configs = [ ":gen_config" ]
+}
diff --git a/src/trace_processor/metrics/android/OWNERS b/src/trace_processor/metrics/sql/android/OWNERS
index 329c8a264..329c8a264 100644
--- a/src/trace_processor/metrics/android/OWNERS
+++ b/src/trace_processor/metrics/sql/android/OWNERS
diff --git a/src/trace_processor/metrics/sql/android/android_batt.sql b/src/trace_processor/metrics/sql/android/android_batt.sql
new file mode 100644
index 000000000..9b8de86bf
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_batt.sql
@@ -0,0 +1,257 @@
+--
+-- Copyright 2019 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+DROP VIEW IF EXISTS battery_view;
+CREATE VIEW battery_view AS
+SELECT
+ all_ts.ts as ts,
+ current_avg_ua,
+ capacity_percent,
+ charge_uah,
+ current_ua
+FROM (
+ SELECT distinct(ts) AS ts
+ FROM counter c
+ JOIN counter_track t on c.track_id = t.id
+ WHERE name GLOB 'batt.*'
+) AS all_ts
+LEFT JOIN (
+ SELECT ts, value AS current_avg_ua
+ FROM counter c
+ JOIN counter_track t on c.track_id = t.id
+ WHERE name='batt.current.avg_ua'
+) USING(ts)
+LEFT JOIN (
+ SELECT ts, value AS capacity_percent
+ FROM counter c
+ JOIN counter_track t on c.track_id = t.id
+ WHERE name='batt.capacity_pct'
+) USING(ts)
+LEFT JOIN (
+ SELECT ts, value AS charge_uah
+ FROM counter c
+ JOIN counter_track t on c.track_id = t.id
+ WHERE name='batt.charge_uah'
+) USING(ts)
+LEFT JOIN (
+ SELECT ts, value AS current_ua
+ FROM counter c
+ JOIN counter_track t on c.track_id = t.id
+ WHERE name='batt.current_ua'
+) USING(ts)
+ORDER BY ts;
+
+DROP TABLE IF EXISTS android_batt_wakelocks_merged;
+CREATE TABLE android_batt_wakelocks_merged AS
+SELECT
+ MIN(ts) AS ts,
+ MAX(ts_end) AS ts_end
+FROM (
+ SELECT
+ *,
+ SUM(new_group) OVER (ORDER BY ts) AS group_id
+ FROM (
+ SELECT
+ ts,
+ ts + dur AS ts_end,
+ -- There is a new group if there was a gap before this wakelock.
+ -- i.e. the max end timestamp of all preceding wakelocks is before
+ -- the start timestamp of this one.
+ -- The null check is for the first row which is always a new group.
+ IFNULL(
+ MAX(ts + dur) OVER (
+ ORDER BY ts
+ ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
+ ) < ts,
+ true
+ ) AS new_group
+ FROM slice
+ WHERE slice.name GLOB 'WakeLock *' AND dur != -1
+ )
+)
+GROUP BY group_id;
+
+DROP TABLE IF EXISTS suspend_slice_;
+CREATE TABLE suspend_slice_ AS
+-- Traces from after b/70292203 was fixed have the action string so just look
+-- for it.
+SELECT
+ ts,
+ dur,
+ true as trustworthy
+FROM (
+ SELECT
+ ts,
+ LEAD(ts) OVER (ORDER BY ts, start DESC) - ts AS dur,
+ start
+ FROM (
+ SELECT
+ ts,
+ EXTRACT_ARG(arg_set_id, 'action') AS action,
+ EXTRACT_ARG(arg_set_id, 'start') AS start
+ FROM raw
+ WHERE name = 'suspend_resume'
+ )
+ -- Different device kernels log different actions when suspending.
+ -- Fortunately each action only appears in the kernel in which it's
+ -- relevant so we can simply look for any of them.
+ WHERE action IN ('timekeeping_freeze', 'syscore_resume')
+)
+WHERE start = 1
+UNION ALL
+-- Traces from before b/70292203 was fixed (approx Nov 2020) do not have the
+-- action string so we do some convoluted pattern matching that mostly works.
+-- TODO(simonmacm) remove this when we no longer need suspend-resume from R
+-- phones.
+SELECT
+ ts,
+ dur,
+ false as trustworthy
+FROM (
+ SELECT
+ ts,
+ ts - lag(ts) OVER w AS lag_dur,
+ lead(ts) OVER w - ts AS dur,
+ action,
+ start,
+ event,
+ lag(start) OVER w AS lag_start,
+ lag(event) OVER w AS lag_event,
+ lag(start, 2) OVER w AS lag_2_start,
+ lag(event, 2) OVER w AS lag_2_event,
+ lead(start) OVER w AS lead_start,
+ lead(event) OVER w AS lead_event,
+ lead(start, 2) OVER w AS lead_2_start,
+ lead(event, 2) OVER w AS lead_2_event
+ FROM (
+ SELECT
+ ts,
+ EXTRACT_ARG(arg_set_id, 'action') AS action,
+ EXTRACT_ARG(arg_set_id, 'start') AS start,
+ EXTRACT_ARG(arg_set_id, 'val') AS event
+ FROM raw
+ WHERE name = 'suspend_resume'
+ )
+ WINDOW w AS (ORDER BY ts)
+)
+WHERE action IS NULL AND (
+-- We want to find the start and end events with action='timekeeping_freeze'.
+-- In practice, these events often show up in a sequence like the following:
+-- start = 1, event = 1 [string would have been 'machine_suspend']
+-- start = 1, event = (any) [string would have been 'timekeeping_freeze'] *
+--
+-- (sleep happens here)
+--
+-- start = 0, event = (any) [string would have been 'timekeeping_freeze']
+-- start = 0, event = 1 [string would have been 'machine_suspend']
+--
+-- So we look for this pattern of start and event, anchored on the event marked
+-- with "*".
+ (
+ lag_start = 1 AND lag_event = 1
+ AND start = 1
+ AND lead_start = 0
+ AND lead_2_start = 0 AND lead_2_event = 1
+ )
+-- Or in newer kernels we seem to have a very different pattern. We can take
+-- advantage of that fact that we get several events with identical timestamp
+-- just before sleeping (normally this never happens):
+-- gap = 0, start = 1, event = 3
+-- gap = 0, start = 0, event = 3
+-- gap = 0, start = 1, event = 0
+--
+-- (sleep happens here)
+--
+-- gap = (any), start = 0, event = 0
+ OR (
+ lag_dur = 0
+ AND lead_start = 0 AND lead_event = 0
+ AND start = 1 AND event = 0
+ AND lag_start = 0 AND lag_event = 3
+ AND lag_2_start = 1 AND lag_2_event = 3
+ )
+);
+
+SELECT RUN_METRIC('android/global_counter_span_view.sql',
+ 'table_name', 'screen_state',
+ 'counter_name', 'ScreenState');
+
+DROP TABLE IF EXISTS screen_state_span_with_suspend;
+CREATE VIRTUAL TABLE screen_state_span_with_suspend
+ USING span_join(screen_state_span, suspend_slice_);
+
+DROP VIEW IF EXISTS android_batt_event;
+CREATE VIEW android_batt_event AS
+SELECT
+ ts,
+ dur,
+ 'Suspended' AS slice_name,
+ 'Suspend / resume' AS track_name,
+ 'slice' AS track_type
+FROM suspend_slice_;
+
+DROP VIEW IF EXISTS android_batt_output;
+CREATE VIEW android_batt_output AS
+SELECT AndroidBatteryMetric(
+ 'battery_counters', (
+ SELECT RepeatedField(
+ AndroidBatteryMetric_BatteryCounters(
+ 'timestamp_ns', ts,
+ 'charge_counter_uah', charge_uah,
+ 'capacity_percent', capacity_percent,
+ 'current_ua', current_ua,
+ 'current_avg_ua', current_avg_ua
+ )
+ )
+ FROM battery_view
+ ),
+ 'battery_aggregates', (
+ SELECT NULL_IF_EMPTY(AndroidBatteryMetric_BatteryAggregates(
+ 'total_screen_off_ns',
+ SUM(CASE WHEN state = 1.0 AND tbl = 'total' THEN dur ELSE 0 END),
+ 'total_screen_on_ns',
+ SUM(CASE WHEN state = 2.0 AND tbl = 'total' THEN dur ELSE 0 END),
+ 'total_screen_doze_ns',
+ SUM(CASE WHEN state = 3.0 AND tbl = 'total' THEN dur ELSE 0 END),
+ 'sleep_ns',
+ (SELECT SUM(dur) FROM suspend_slice_),
+ 'sleep_screen_off_ns',
+ SUM(CASE WHEN state = 1.0 AND tbl = 'sleep' THEN dur ELSE 0 END),
+ 'sleep_screen_on_ns',
+ SUM(CASE WHEN state = 2.0 AND tbl = 'sleep' THEN dur ELSE 0 END),
+ 'sleep_screen_doze_ns',
+ SUM(CASE WHEN state = 3.0 AND tbl = 'sleep' THEN dur ELSE 0 END),
+ 'total_wakelock_ns',
+ (SELECT SUM(ts_end - ts) FROM android_batt_wakelocks_merged)
+ ))
+ FROM (
+ SELECT dur, screen_state_val AS state, 'total' AS tbl
+ FROM screen_state_span
+ UNION ALL
+ SELECT dur, screen_state_val AS state, 'sleep' AS tbl
+ FROM screen_state_span_with_suspend
+ )
+ ),
+ 'suspend_period', (
+ SELECT RepeatedField(
+ AndroidBatteryMetric_SuspendPeriod(
+ 'timestamp_ns', ts,
+ 'duration_ns', dur
+ )
+ )
+ FROM suspend_slice_
+ WHERE trustworthy
+ )
+);
diff --git a/src/trace_processor/metrics/sql/android/android_camera.sql b/src/trace_processor/metrics/sql/android/android_camera.sql
new file mode 100644
index 000000000..791c922a3
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_camera.sql
@@ -0,0 +1,117 @@
+--
+-- Copyright 2019 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+-- This gives us access to the RSS breakdowns.
+SELECT RUN_METRIC('android/process_mem.sql');
+
+-- Compute DMA spans.
+SELECT RUN_METRIC('android/global_counter_span_view.sql',
+ 'table_name', 'dma',
+ 'counter_name', 'mem.dma_heap');
+
+-- RSS of GCA.
+DROP VIEW IF EXISTS rss_gca;
+CREATE VIEW rss_gca AS
+SELECT ts, dur, rss_val AS gca_rss_val
+FROM rss_and_swap_span
+JOIN (
+ SELECT max(start_ts), upid
+ FROM process
+ WHERE name GLOB '*GoogleCamera*'
+ LIMIT 1
+) AS gca USING (upid);
+
+-- RSS of camera HAL.
+DROP VIEW IF EXISTS rss_camera_hal;
+CREATE VIEW rss_camera_hal AS
+SELECT ts, dur, rss_val AS hal_rss_val
+FROM rss_and_swap_span
+JOIN (
+ SELECT max(start_ts), upid
+ FROM process
+ WHERE name GLOB '*camera.provider*'
+ LIMIT 1
+) AS hal USING (upid);
+
+-- RSS of cameraserver.
+DROP VIEW IF EXISTS rss_cameraserver;
+CREATE VIEW rss_cameraserver AS
+SELECT ts, dur, rss_val AS cameraserver_rss_val
+FROM rss_and_swap_span
+JOIN (
+ SELECT max(start_ts), upid
+ FROM process
+ WHERE name = 'cameraserver'
+ LIMIT 1
+) AS cameraserver USING (upid);
+
+-- RSS of GCA + HAL.
+DROP TABLE IF EXISTS rss_gca_hal;
+CREATE VIRTUAL TABLE rss_gca_hal
+USING SPAN_OUTER_JOIN(rss_gca, rss_camera_hal);
+
+-- RSS of GCA + HAL + cameraserver.
+DROP TABLE IF EXISTS rss_all_camera;
+CREATE VIRTUAL TABLE rss_all_camera
+USING SPAN_OUTER_JOIN(rss_gca_hal, rss_cameraserver);
+
+-- RSS of GCA + HAL + cameraserver + DMA.
+DROP TABLE IF EXISTS rss_and_dma_all_camera_join;
+CREATE VIRTUAL TABLE rss_and_dma_all_camera_join
+USING SPAN_OUTER_JOIN(dma_span, rss_all_camera);
+
+DROP VIEW IF EXISTS rss_and_dma_all_camera_span;
+CREATE VIEW rss_and_dma_all_camera_span AS
+SELECT
+ ts,
+ dur,
+ CAST(
+ IFNULL(gca_rss_val, 0) +
+ IFNULL(hal_rss_val, 0) +
+ IFNULL(cameraserver_rss_val, 0) +
+ IFNULL(dma_val, 0) AS int) AS rss_and_dma_val
+FROM rss_and_dma_all_camera_join;
+
+-- we are dividing and casting to real when calculating avg_value
+-- to avoid issues such as the one in b/203613535
+DROP VIEW IF EXISTS rss_and_dma_all_camera_stats;
+CREATE VIEW rss_and_dma_all_camera_stats AS
+SELECT
+ MIN(rss_and_dma_val) AS min_value,
+ MAX(rss_and_dma_val) AS max_value,
+ SUM(rss_and_dma_val * dur / 1e3) / SUM(dur / 1e3) AS avg_value
+FROM rss_and_dma_all_camera_span;
+
+DROP VIEW IF EXISTS android_camera_event;
+CREATE VIEW android_camera_event AS
+SELECT
+ 'counter' AS track_type,
+ 'Camera Memory' AS track_name,
+ ts,
+ rss_and_dma_val AS value
+FROM rss_and_dma_all_camera_span;
+
+DROP VIEW IF EXISTS android_camera_output;
+CREATE VIEW android_camera_output AS
+SELECT
+ AndroidCameraMetric(
+ 'gc_rss_and_dma', AndroidCameraMetric_Counter(
+ 'min', CAST(min_value AS real),
+ 'max', CAST(max_value AS real),
+ 'avg', CAST(avg_value AS real)
+ )
+ )
+FROM rss_and_dma_all_camera_stats;
diff --git a/src/trace_processor/metrics/sql/android/android_camera_unagg.sql b/src/trace_processor/metrics/sql/android/android_camera_unagg.sql
new file mode 100644
index 000000000..29f4ca72c
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_camera_unagg.sql
@@ -0,0 +1,33 @@
+--
+-- Copyright 2019 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+-- This gives us access to the raw spans.
+SELECT RUN_METRIC('android/android_camera.sql');
+
+DROP VIEW IF EXISTS android_camera_unagg_output;
+CREATE VIEW android_camera_unagg_output AS
+SELECT
+ AndroidCameraUnaggregatedMetric(
+ 'gc_rss_and_dma', (
+ SELECT RepeatedField(
+ AndroidCameraUnaggregatedMetric_Value(
+ 'ts', ts,
+ 'value', CAST(rss_and_dma_val AS real)
+ )
+ )
+ FROM rss_and_dma_all_camera_span
+ )
+ );
diff --git a/src/trace_processor/metrics/android/android_cpu.sql b/src/trace_processor/metrics/sql/android/android_cpu.sql
index 2af9faf44..2af9faf44 100644
--- a/src/trace_processor/metrics/android/android_cpu.sql
+++ b/src/trace_processor/metrics/sql/android/android_cpu.sql
diff --git a/src/trace_processor/metrics/android/android_cpu_agg.sql b/src/trace_processor/metrics/sql/android/android_cpu_agg.sql
index d5f145e2f..d5f145e2f 100644
--- a/src/trace_processor/metrics/android/android_cpu_agg.sql
+++ b/src/trace_processor/metrics/sql/android/android_cpu_agg.sql
diff --git a/src/trace_processor/metrics/android/android_cpu_raw_metrics_per_core.sql b/src/trace_processor/metrics/sql/android/android_cpu_raw_metrics_per_core.sql
index bd1ec7de4..bd1ec7de4 100644
--- a/src/trace_processor/metrics/android/android_cpu_raw_metrics_per_core.sql
+++ b/src/trace_processor/metrics/sql/android/android_cpu_raw_metrics_per_core.sql
diff --git a/src/trace_processor/metrics/android/android_dma_heap.sql b/src/trace_processor/metrics/sql/android/android_dma_heap.sql
index afdab08ad..afdab08ad 100644
--- a/src/trace_processor/metrics/android/android_dma_heap.sql
+++ b/src/trace_processor/metrics/sql/android/android_dma_heap.sql
diff --git a/src/trace_processor/metrics/sql/android/android_dvfs.sql b/src/trace_processor/metrics/sql/android/android_dvfs.sql
new file mode 100644
index 000000000..d8162b1b2
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_dvfs.sql
@@ -0,0 +1,93 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+DROP VIEW IF EXISTS freq_slice;
+
+CREATE VIEW freq_slice AS
+ SELECT
+ counter.track_id AS track_id,
+ track.name AS freq_name,
+ ts,
+ value AS freq_value,
+ LEAD(ts, 1, (SELECT end_ts+1 FROM trace_bounds))
+ OVER (PARTITION by track.id ORDER BY ts) - ts AS duration
+ FROM counter
+ LEFT JOIN track ON counter.track_id = track.id
+ WHERE track.name GLOB "* Frequency"
+ ORDER BY ts;
+
+DROP VIEW IF EXISTS freq_total_duration;
+
+CREATE VIEW freq_total_duration AS
+ SELECT
+ track_id,
+ freq_name,
+ SUM(duration) AS total_duration
+ FROM freq_slice
+ WHERE duration > 0
+ GROUP BY track_id, freq_name;
+
+DROP VIEW IF EXISTS dvfs_per_band_view;
+
+CREATE VIEW dvfs_per_band_view AS
+WITH
+freq_duration AS (
+ SELECT
+ track_id,
+ freq_name,
+ CAST(freq_value AS int) AS freq_value,
+ SUM(duration) AS duration_ns
+ FROM freq_slice
+ WHERE duration > 0
+ GROUP BY track_id, freq_name, freq_value
+)
+SELECT
+ freq_duration.track_id,
+ freq_duration.freq_name,
+ AndroidDvfsMetric_BandStat(
+ 'freq_value', freq_value,
+ 'percentage', duration_ns / (total_duration / 1e2),
+ 'duration_ns', duration_ns
+ ) AS proto
+FROM freq_duration
+LEFT JOIN freq_total_duration
+USING(track_id)
+ORDER BY freq_duration.freq_name, freq_duration.freq_value;
+
+DROP VIEW IF EXISTS dvfs_per_freq_view;
+CREATE VIEW dvfs_per_freq_view AS
+ SELECT
+ AndroidDvfsMetric_FrequencyResidency(
+ 'freq_name', freq_total_duration.freq_name,
+ 'band_stat', (
+ SELECT
+ RepeatedField(proto)
+ FROM dvfs_per_band_view
+ WHERE dvfs_per_band_view.track_id = freq_total_duration.track_id
+ )
+ ) AS proto
+ FROM freq_total_duration
+ GROUP BY track_id, freq_name
+ ORDER BY freq_name;
+
+DROP VIEW IF EXISTS android_dvfs_output;
+CREATE VIEW android_dvfs_output AS
+ SELECT AndroidDVFSMetric(
+ 'freq_residencies', (
+ SELECT
+ RepeatedField(proto)
+ FROM dvfs_per_freq_view
+ )
+ );
diff --git a/src/trace_processor/metrics/sql/android/android_fastrpc.sql b/src/trace_processor/metrics/sql/android/android_fastrpc.sql
new file mode 100644
index 000000000..e38166857
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_fastrpc.sql
@@ -0,0 +1,72 @@
+DROP VIEW IF EXISTS fastrpc_timeline;
+CREATE VIEW fastrpc_timeline AS
+SELECT
+ ts,
+ LEAD(ts, 1, (SELECT end_ts FROM trace_bounds))
+ OVER(PARTITION BY track_id ORDER BY ts) - ts AS dur,
+ RTRIM(SUBSTR(name, 13), ']') AS subsystem_name,
+ track_id,
+ value
+FROM counter JOIN counter_track
+ ON counter.track_id = counter_track.id
+WHERE (name GLOB 'mem.fastrpc[[]*');
+
+DROP VIEW IF EXISTS fastrpc_subsystem_stats;
+CREATE VIEW fastrpc_subsystem_stats AS
+SELECT
+ subsystem_name,
+ SUM(value * dur) / SUM(dur) AS avg_size,
+ MIN(value) AS min_size,
+ MAX(value) AS max_size
+FROM fastrpc_timeline
+GROUP BY 1;
+
+DROP VIEW IF EXISTS fastrpc_raw_allocs;
+CREATE VIEW fastrpc_raw_allocs AS
+SELECT
+ RTRIM(SUBSTR(name, 20), ']') AS subsystem_name,
+ ts,
+ value AS instant_value,
+ SUM(value) OVER win AS value
+FROM counter c JOIN thread_counter_track t ON c.track_id = t.id
+WHERE name GLOB 'mem.fastrpc_change*' AND value > 0
+WINDOW win AS (
+ PARTITION BY name ORDER BY ts
+ ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+);
+
+DROP VIEW IF EXISTS fastrpc_alloc_stats;
+CREATE VIEW fastrpc_alloc_stats AS
+SELECT
+ subsystem_name,
+ SUM(instant_value) AS total_alloc_size_bytes
+FROM fastrpc_raw_allocs
+GROUP BY 1;
+
+-- We need to group by ts here as we can have two events from
+-- different processes occurring at the same timestamp. We take the
+-- max as this will take both allocations into account at that
+-- timestamp.
+DROP VIEW IF EXISTS android_fastrpc_event;
+CREATE VIEW android_fastrpc_event AS
+SELECT
+ 'counter' AS track_type,
+ printf('fastrpc allocations (subsystem: %s)', subsystem_name) AS track_name,
+ ts,
+ MAX(value) AS value
+FROM fastrpc_raw_allocs
+GROUP BY 1, 2, 3;
+
+DROP VIEW IF EXISTS android_fastrpc_output;
+CREATE VIEW android_fastrpc_output AS
+SELECT AndroidFastrpcMetric(
+ 'subsystem', RepeatedField(
+ AndroidFastrpcMetric_Subsystem(
+ 'name', subsystem_name,
+ 'avg_size_bytes', avg_size,
+ 'min_size_bytes', min_size,
+ 'max_size_bytes', max_size,
+ 'total_alloc_size_bytes', total_alloc_size_bytes
+ )
+ ))
+FROM fastrpc_subsystem_stats JOIN fastrpc_alloc_stats USING (subsystem_name);
diff --git a/src/trace_processor/metrics/sql/android/android_gpu.sql b/src/trace_processor/metrics/sql/android/android_gpu.sql
new file mode 100644
index 000000000..f0c04568b
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_gpu.sql
@@ -0,0 +1,113 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+SELECT RUN_METRIC('android/global_counter_span_view.sql',
+ 'table_name', 'global_gpu_memory',
+ 'counter_name', 'GPU Memory');
+
+SELECT RUN_METRIC('android/process_counter_span_view.sql',
+ 'table_name', 'proc_gpu_memory',
+ 'counter_name', 'GPU Memory');
+
+DROP VIEW IF EXISTS proc_gpu_memory_view;
+CREATE VIEW proc_gpu_memory_view AS
+SELECT
+ upid,
+ MAX(proc_gpu_memory_val) as mem_max,
+ MIN(proc_gpu_memory_val) as mem_min,
+ SUM(proc_gpu_memory_val * dur) as mem_valxdur,
+ SUM(dur) as mem_dur
+FROM proc_gpu_memory_span
+GROUP BY upid;
+
+DROP VIEW IF EXISTS agg_proc_gpu_view;
+CREATE VIEW agg_proc_gpu_view AS
+SELECT
+ name,
+ MAX(mem_max) as mem_max,
+ MIN(mem_min) as mem_min,
+ SUM(mem_valxdur) / SUM(mem_dur) as mem_avg
+FROM process
+JOIN proc_gpu_memory_view
+USING(upid)
+GROUP BY name;
+
+DROP VIEW IF EXISTS proc_gpu_view;
+CREATE VIEW proc_gpu_view AS
+SELECT
+ AndroidGpuMetric_Process(
+ 'name', name,
+ 'mem_max', CAST(mem_max as INT64),
+ 'mem_min', CAST(mem_min as INT64),
+ 'mem_avg', CAST(mem_avg as INT64)
+ ) AS proto
+FROM agg_proc_gpu_view;
+
+SELECT RUN_METRIC('android/gpu_counter_span_view.sql',
+ 'table_name', 'gpu_freq',
+ 'counter_name', 'gpufreq');
+
+DROP VIEW IF EXISTS metrics_per_freq_view;
+CREATE VIEW metrics_per_freq_view AS
+WITH
+total_dur_per_freq AS (
+ SELECT
+ gpu_id,
+ gpu_freq_val AS freq,
+ SUM(dur) AS dur_ns
+ FROM gpu_freq_span
+ GROUP BY gpu_id, gpu_freq_val
+),
+total_dur_per_gpu AS (
+ SELECT
+ gpu_id,
+ SUM(dur) AS dur_ns
+ FROM gpu_freq_span
+ GROUP BY gpu_id
+)
+SELECT
+ gpu_id,
+ AndroidGpuMetric_FrequencyMetric_MetricsPerFrequency(
+ 'freq', CAST(freq as INT64),
+ 'dur_ms', f.dur_ns / 1e6,
+ 'percentage', f.dur_ns * 100.0 / g.dur_ns
+ ) AS proto
+FROM total_dur_per_freq f LEFT JOIN total_dur_per_gpu g USING (gpu_id);
+
+DROP VIEW IF EXISTS gpu_freq_metrics_view;
+CREATE VIEW gpu_freq_metrics_view AS
+SELECT
+ AndroidGpuMetric_FrequencyMetric(
+ 'gpu_id', gpu_id,
+ 'freq_max', CAST(MAX(gpu_freq_val) as INT64),
+ 'freq_min', CAST(MIN(gpu_freq_val) as INT64),
+ 'freq_avg', SUM(gpu_freq_val * dur) / SUM(dur),
+ 'used_freqs', (SELECT RepeatedField(proto) FROM metrics_per_freq_view
+ WHERE metrics_per_freq_view.gpu_id = gpu_freq_span.gpu_id)
+ ) AS proto
+FROM gpu_freq_span
+GROUP BY gpu_id;
+
+DROP VIEW IF EXISTS android_gpu_output;
+CREATE VIEW android_gpu_output AS
+SELECT AndroidGpuMetric(
+ 'processes', (SELECT RepeatedField(proto) FROM proc_gpu_view),
+ 'mem_max', CAST(MAX(global_gpu_memory_val) as INT64),
+ 'mem_min', CAST(MIN(global_gpu_memory_val) as INT64),
+ 'mem_avg', CAST(SUM(global_gpu_memory_val * dur) / SUM(dur) as INT64),
+ 'freq_metrics', (SELECT RepeatedField(proto) FROM gpu_freq_metrics_view)
+)
+FROM global_gpu_memory_span;
diff --git a/src/trace_processor/metrics/sql/android/android_hwcomposer.sql b/src/trace_processor/metrics/sql/android/android_hwcomposer.sql
new file mode 100644
index 000000000..b8dc0dc91
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_hwcomposer.sql
@@ -0,0 +1,136 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+SELECT RUN_METRIC(
+ 'android/composition_layers.sql',
+ 'track_name', 'HWComposer: Total Layer',
+ 'output', 'total_layers'
+);
+
+SELECT RUN_METRIC(
+ 'android/composition_layers.sql',
+ 'track_name', 'HWComposer: DPU Layer',
+ 'output', 'dpu_layers'
+);
+
+SELECT RUN_METRIC(
+ 'android/composition_layers.sql',
+ 'track_name', 'HWComposer: GPU Layer',
+ 'output', 'gpu_layers'
+);
+
+SELECT RUN_METRIC(
+ 'android/composition_layers.sql',
+ 'track_name', 'HWComposer: DPU Cached Layer',
+ 'output', 'dpu_cached_layers'
+);
+
+SELECT RUN_METRIC(
+ 'android/composition_layers.sql',
+ 'track_name', 'HWComposer: SF Cached Layer',
+ 'output', 'sf_cached_layers'
+);
+
+SELECT RUN_METRIC(
+ 'android/composer_execution.sql',
+ 'output', 'hwc_execution_spans'
+);
+
+
+SELECT RUN_METRIC('android/thread_counter_span_view.sql',
+ 'table_name', 'dpu_vote_clock',
+ 'counter_name', 'dpu_vote_clock'
+);
+
+SELECT RUN_METRIC('android/thread_counter_span_view.sql',
+ 'table_name', 'dpu_vote_avg_bw',
+ 'counter_name', 'dpu_vote_avg_bw'
+);
+
+SELECT RUN_METRIC('android/thread_counter_span_view.sql',
+ 'table_name', 'dpu_vote_peak_bw',
+ 'counter_name', 'dpu_vote_peak_bw'
+);
+
+SELECT RUN_METRIC('android/thread_counter_span_view.sql',
+ 'table_name', 'dpu_vote_rt_bw',
+ 'counter_name', 'dpu_vote_rt_bw'
+);
+
+DROP VIEW IF EXISTS dpu_vote_thread;
+CREATE VIEW dpu_vote_thread AS
+SELECT DISTINCT s.utid, t.tid
+FROM (
+ SELECT utid FROM dpu_vote_clock_span
+ UNION
+ SELECT utid FROM dpu_vote_avg_bw_span
+ UNION
+ SELECT utid FROM dpu_vote_peak_bw_span
+) s JOIN thread t ON s.utid = t.utid;
+
+DROP VIEW IF EXISTS dpu_vote_metrics;
+CREATE VIEW dpu_vote_metrics AS
+SELECT AndroidHwcomposerMetrics_DpuVoteMetrics(
+ 'tid', tid,
+ 'avg_dpu_vote_clock',
+ (SELECT SUM(dpu_vote_clock_val * dur) / SUM(dur)
+ FROM dpu_vote_clock_span s WHERE s.utid = t.utid),
+ 'avg_dpu_vote_avg_bw',
+ (SELECT SUM(dpu_vote_avg_bw_val * dur) / SUM(dur)
+ FROM dpu_vote_avg_bw_span s WHERE s.utid = t.utid),
+ 'avg_dpu_vote_peak_bw',
+ (SELECT SUM(dpu_vote_peak_bw_val * dur) / SUM(dur)
+ FROM dpu_vote_peak_bw_span s WHERE s.utid = t.utid),
+ 'avg_dpu_vote_rt_bw',
+ (SELECT SUM(dpu_vote_rt_bw_val * dur) / SUM(dur)
+ FROM dpu_vote_rt_bw_span s WHERE s.utid = t.utid)
+) AS proto
+FROM dpu_vote_thread t
+ORDER BY tid;
+
+DROP VIEW IF EXISTS android_hwcomposer_output;
+CREATE VIEW android_hwcomposer_output AS
+SELECT AndroidHwcomposerMetrics(
+ 'composition_total_layers', (SELECT AVG(value) FROM total_layers),
+ 'composition_dpu_layers', (SELECT AVG(value) FROM dpu_layers),
+ 'composition_gpu_layers', (SELECT AVG(value) FROM gpu_layers),
+ 'composition_dpu_cached_layers', (SELECT AVG(value) FROM dpu_cached_layers),
+ 'composition_sf_cached_layers', (SELECT AVG(value) FROM sf_cached_layers),
+ 'skipped_validation_count',
+ (SELECT COUNT(*) FROM hwc_execution_spans
+ WHERE validation_type = 'skipped_validation'),
+ 'unskipped_validation_count',
+ (SELECT COUNT(*) FROM hwc_execution_spans
+ WHERE validation_type = 'unskipped_validation'),
+ 'separated_validation_count',
+ (SELECT COUNT(*) FROM hwc_execution_spans
+ WHERE validation_type = 'separated_validation'),
+ 'unknown_validation_count',
+ (SELECT COUNT(*) FROM hwc_execution_spans
+ WHERE validation_type = 'unknown'),
+ 'avg_all_execution_time_ms',
+ (SELECT AVG(execution_time_ns) / 1e6 FROM hwc_execution_spans
+ WHERE validation_type != 'unknown'),
+ 'avg_skipped_execution_time_ms',
+ (SELECT AVG(execution_time_ns) / 1e6 FROM hwc_execution_spans
+ WHERE validation_type = 'skipped_validation'),
+ 'avg_unskipped_execution_time_ms',
+ (SELECT AVG(execution_time_ns) / 1e6 FROM hwc_execution_spans
+ WHERE validation_type = 'unskipped_validation'),
+ 'avg_separated_execution_time_ms',
+ (SELECT AVG(execution_time_ns) / 1e6 FROM hwc_execution_spans
+ WHERE validation_type = 'separated_validation'),
+ 'dpu_vote_metrics', (SELECT RepeatedField(proto) FROM dpu_vote_metrics)
+);
diff --git a/src/trace_processor/metrics/sql/android/android_hwui_metric.sql b/src/trace_processor/metrics/sql/android/android_hwui_metric.sql
new file mode 100644
index 000000000..1a33e22d9
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_hwui_metric.sql
@@ -0,0 +1,261 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+
+-- TOP processes that have a RenderThread, sorted by CPU time on RT
+DROP VIEW IF EXISTS hwui_processes;
+CREATE VIEW hwui_processes AS
+SELECT
+ process.name as process_name,
+ process.upid as process_upid,
+ CAST(SUM(sched.dur) / 1e6 as INT64) as rt_cpu_time_ms,
+ thread.utid as render_thread_id
+FROM sched
+INNER JOIN thread ON (thread.utid = sched.utid AND thread.name='RenderThread')
+INNER JOIN process ON (process.upid = thread.upid)
+GROUP BY process.name
+ORDER BY rt_cpu_time_ms DESC;
+
+DROP VIEW IF EXISTS hwui_draw_frame;
+CREATE VIEW hwui_draw_frame AS
+SELECT
+ count(*) as draw_frame_count,
+ max(dur) as draw_frame_max,
+ min(dur) as draw_frame_min,
+ avg(dur) as draw_frame_avg,
+ thread_track.utid as render_thread_id
+FROM slice
+INNER JOIN thread_track ON (thread_track.id = slice.track_id)
+WHERE slice.name GLOB 'DrawFrame*' AND slice.dur >= 0
+GROUP BY thread_track.utid;
+
+DROP VIEW IF EXISTS hwui_flush_commands;
+CREATE VIEW hwui_flush_commands AS
+SELECT
+ count(*) as flush_count,
+ max(dur) as flush_max,
+ min(dur) as flush_min,
+ avg(dur) as flush_avg,
+ thread_track.utid as render_thread_id
+FROM slice
+INNER JOIN thread_track ON (thread_track.id = slice.track_id)
+WHERE slice.name='flush commands' AND slice.dur >= 0
+GROUP BY thread_track.utid;
+
+DROP VIEW IF EXISTS hwui_prepare_tree;
+CREATE VIEW hwui_prepare_tree AS
+SELECT
+ count(*) as prepare_tree_count,
+ max(dur) as prepare_tree_max,
+ min(dur) as prepare_tree_min,
+ avg(dur) as prepare_tree_avg,
+ thread_track.utid as render_thread_id
+FROM slice
+INNER JOIN thread_track ON (thread_track.id = slice.track_id)
+WHERE slice.name='prepareTree' AND slice.dur >= 0
+GROUP BY thread_track.utid;
+
+DROP VIEW IF EXISTS hwui_gpu_completion;
+CREATE VIEW hwui_gpu_completion AS
+SELECT
+ count(*) as gpu_completion_count,
+ max(dur) as gpu_completion_max,
+ min(dur) as gpu_completion_min,
+ avg(dur) as gpu_completion_avg,
+ thread.upid as process_upid
+FROM slice
+INNER JOIN thread_track ON (thread_track.id = slice.track_id)
+INNER JOIN thread ON (thread.name='GPU completion' AND thread.utid = thread_track.utid)
+WHERE slice.name GLOB 'waiting for GPU completion*' AND slice.dur >= 0
+GROUP BY thread_track.utid;
+
+DROP VIEW IF EXISTS hwui_ui_record;
+CREATE VIEW hwui_ui_record AS
+SELECT
+ count(*) as ui_record_count,
+ max(dur) as ui_record_max,
+ min(dur) as ui_record_min,
+ avg(dur) as ui_record_avg,
+ thread.upid as process_upid
+FROM slice
+INNER JOIN thread_track ON (thread_track.id = slice.track_id)
+INNER JOIN thread ON (thread.name=substr(process.name,-15) AND thread.utid = thread_track.utid)
+INNER JOIN process ON (process.upid = thread.upid)
+WHERE slice.name='Record View#draw()' AND slice.dur >= 0
+GROUP BY thread_track.utid;
+
+DROP VIEW IF EXISTS hwui_shader_compile;
+CREATE VIEW hwui_shader_compile AS
+SELECT
+ count(*) as shader_compile_count,
+ sum(dur) as shader_compile_time,
+ avg(dur) as shader_compile_avg,
+ thread_track.utid as render_thread_id
+FROM slice
+INNER JOIN thread_track ON (thread_track.id = slice.track_id)
+WHERE slice.name='shader_compile' AND slice.dur >= 0
+GROUP BY thread_track.utid;
+
+DROP VIEW IF EXISTS hwui_cache_hit;
+CREATE VIEW hwui_cache_hit AS
+SELECT
+ count(*) as cache_hit_count,
+ sum(dur) as cache_hit_time,
+ avg(dur) as cache_hit_avg,
+ thread_track.utid as render_thread_id
+FROM slice
+INNER JOIN thread_track ON (thread_track.id = slice.track_id)
+WHERE slice.name='cache_hit' AND slice.dur >= 0
+GROUP BY thread_track.utid;
+
+DROP VIEW IF EXISTS hwui_cache_miss;
+CREATE VIEW hwui_cache_miss AS
+SELECT
+ count(*) as cache_miss_count,
+ sum(dur) as cache_miss_time,
+ avg(dur) as cache_miss_avg,
+ thread_track.utid as render_thread_id
+FROM slice
+INNER JOIN thread_track ON (thread_track.id = slice.track_id)
+WHERE slice.name='cache_miss' AND slice.dur >= 0
+GROUP BY thread_track.utid;
+
+DROP VIEW IF EXISTS hwui_graphics_cpu_mem;
+CREATE VIEW hwui_graphics_cpu_mem AS
+SELECT
+ max(value) as graphics_cpu_mem_max,
+ min(value) as graphics_cpu_mem_min,
+ avg(value) as graphics_cpu_mem_avg,
+ process_counter_track.upid as process_upid
+FROM counter
+INNER JOIN process_counter_track ON (counter.track_id = process_counter_track.id)
+WHERE name='HWUI CPU Memory' AND counter.value >= 0
+GROUP BY process_counter_track.upid;
+
+DROP VIEW IF EXISTS hwui_graphics_gpu_mem;
+CREATE VIEW hwui_graphics_gpu_mem AS
+SELECT
+ max(value) as graphics_gpu_mem_max,
+ min(value) as graphics_gpu_mem_min,
+ avg(value) as graphics_gpu_mem_avg,
+ process_counter_track.upid as process_upid
+FROM counter
+INNER JOIN process_counter_track ON (counter.track_id = process_counter_track.id)
+WHERE name='HWUI Misc Memory' AND counter.value >= 0
+GROUP BY process_counter_track.upid;
+
+DROP VIEW IF EXISTS hwui_texture_mem;
+CREATE VIEW hwui_texture_mem AS
+SELECT
+ max(value) as texture_mem_max,
+ min(value) as texture_mem_min,
+ avg(value) as texture_mem_avg,
+ process_counter_track.upid as process_upid
+FROM counter
+INNER JOIN process_counter_track ON (counter.track_id = process_counter_track.id)
+WHERE name='HWUI Texture Memory' AND counter.value >= 0
+GROUP BY process_counter_track.upid;
+
+DROP VIEW IF EXISTS hwui_all_mem;
+CREATE VIEW hwui_all_mem AS
+SELECT
+ max(value) as all_mem_max,
+ min(value) as all_mem_min,
+ avg(value) as all_mem_avg,
+ process_counter_track.upid as process_upid
+FROM counter
+INNER JOIN process_counter_track ON (counter.track_id = process_counter_track.id)
+WHERE name='HWUI All Memory' AND counter.value >= 0
+GROUP BY process_counter_track.upid;
+
+DROP VIEW IF EXISTS android_hwui_metric_output;
+CREATE VIEW android_hwui_metric_output AS
+SELECT AndroidHwuiMetric(
+ 'process_info', (
+ SELECT RepeatedField(
+ ProcessRenderInfo(
+ 'process_name', process_name,
+ 'rt_cpu_time_ms', rt_cpu_time_ms,
+
+ 'draw_frame_count', hwui_draw_frame.draw_frame_count,
+ 'draw_frame_max', hwui_draw_frame.draw_frame_max,
+ 'draw_frame_min', hwui_draw_frame.draw_frame_min,
+ 'draw_frame_avg', hwui_draw_frame.draw_frame_avg,
+
+ 'flush_count', hwui_flush_commands.flush_count,
+ 'flush_max', hwui_flush_commands.flush_max,
+ 'flush_min', hwui_flush_commands.flush_min,
+ 'flush_avg', hwui_flush_commands.flush_avg,
+
+ 'prepare_tree_count', hwui_prepare_tree.prepare_tree_count,
+ 'prepare_tree_max', hwui_prepare_tree.prepare_tree_max,
+ 'prepare_tree_min', hwui_prepare_tree.prepare_tree_min,
+ 'prepare_tree_avg', hwui_prepare_tree.prepare_tree_avg,
+
+ 'gpu_completion_count', hwui_gpu_completion.gpu_completion_count,
+ 'gpu_completion_max', hwui_gpu_completion.gpu_completion_max,
+ 'gpu_completion_min', hwui_gpu_completion.gpu_completion_min,
+ 'gpu_completion_avg', hwui_gpu_completion.gpu_completion_avg,
+
+ 'ui_record_count', hwui_ui_record.ui_record_count,
+ 'ui_record_max', hwui_ui_record.ui_record_max,
+ 'ui_record_min', hwui_ui_record.ui_record_min,
+ 'ui_record_avg', hwui_ui_record.ui_record_avg,
+
+ 'shader_compile_count', hwui_shader_compile.shader_compile_count,
+ 'shader_compile_time', hwui_shader_compile.shader_compile_time,
+ 'shader_compile_avg', hwui_shader_compile.shader_compile_avg,
+
+ 'cache_hit_count', hwui_cache_hit.cache_hit_count,
+ 'cache_hit_time', hwui_cache_hit.cache_hit_time,
+ 'cache_hit_avg', hwui_cache_hit.cache_hit_avg,
+
+ 'cache_miss_count', hwui_cache_miss.cache_miss_count,
+ 'cache_miss_time', hwui_cache_miss.cache_miss_time,
+ 'cache_miss_avg', hwui_cache_miss.cache_miss_avg,
+
+ 'graphics_cpu_mem_max', CAST(hwui_graphics_cpu_mem.graphics_cpu_mem_max as INT64),
+ 'graphics_cpu_mem_min', CAST(hwui_graphics_cpu_mem.graphics_cpu_mem_min as INT64),
+ 'graphics_cpu_mem_avg', hwui_graphics_cpu_mem.graphics_cpu_mem_avg,
+
+ 'graphics_gpu_mem_max', CAST(hwui_graphics_gpu_mem.graphics_gpu_mem_max as INT64),
+ 'graphics_gpu_mem_min', CAST(hwui_graphics_gpu_mem.graphics_gpu_mem_min as INT64),
+ 'graphics_gpu_mem_avg', hwui_graphics_gpu_mem.graphics_gpu_mem_avg,
+
+ 'texture_mem_max', CAST(hwui_texture_mem.texture_mem_max as INT64),
+ 'texture_mem_min', CAST(hwui_texture_mem.texture_mem_min as INT64),
+ 'texture_mem_avg', hwui_texture_mem.texture_mem_avg,
+
+ 'all_mem_max', CAST(hwui_all_mem.all_mem_max as INT64),
+ 'all_mem_min', CAST(hwui_all_mem.all_mem_min as INT64),
+ 'all_mem_avg', hwui_all_mem.all_mem_avg
+ )
+ )
+ FROM hwui_processes
+ LEFT JOIN hwui_draw_frame ON (hwui_draw_frame.render_thread_id = hwui_processes.render_thread_id)
+ LEFT JOIN hwui_flush_commands ON (hwui_flush_commands.render_thread_id = hwui_processes.render_thread_id)
+ LEFT JOIN hwui_prepare_tree ON (hwui_prepare_tree.render_thread_id = hwui_processes.render_thread_id)
+ LEFT JOIN hwui_gpu_completion ON (hwui_gpu_completion.process_upid = hwui_processes.process_upid)
+ LEFT JOIN hwui_ui_record ON (hwui_ui_record.process_upid = hwui_processes.process_upid)
+ LEFT JOIN hwui_shader_compile ON (hwui_shader_compile.render_thread_id = hwui_processes.render_thread_id)
+ LEFT JOIN hwui_cache_hit ON (hwui_cache_hit.render_thread_id = hwui_processes.render_thread_id)
+ LEFT JOIN hwui_cache_miss ON (hwui_cache_miss.render_thread_id = hwui_processes.render_thread_id)
+ LEFT JOIN hwui_graphics_cpu_mem ON (hwui_graphics_cpu_mem.process_upid = hwui_processes.process_upid)
+ LEFT JOIN hwui_graphics_gpu_mem ON (hwui_graphics_gpu_mem.process_upid = hwui_processes.process_upid)
+ LEFT JOIN hwui_texture_mem ON (hwui_texture_mem.process_upid = hwui_processes.process_upid)
+ LEFT JOIN hwui_all_mem ON (hwui_all_mem.process_upid = hwui_processes.process_upid)
+ )
+);
diff --git a/src/trace_processor/metrics/sql/android/android_hwui_threads.sql b/src/trace_processor/metrics/sql/android/android_hwui_threads.sql
new file mode 100644
index 000000000..ee6a3abac
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_hwui_threads.sql
@@ -0,0 +1,122 @@
+--
+-- Copyright 2019 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+
+DROP VIEW IF EXISTS {{table_name_prefix}}_main_thread;
+CREATE VIEW {{table_name_prefix}}_main_thread AS
+ SELECT
+ process.name as process_name,
+ thread.utid
+ FROM thread
+ JOIN {{process_allowlist_table}} process USING (upid)
+ WHERE thread.is_main_thread;
+
+DROP VIEW IF EXISTS {{table_name_prefix}}_render_thread;
+CREATE VIEW {{table_name_prefix}}_render_thread AS
+ SELECT
+ process.name as process_name,
+ thread.utid
+ FROM thread
+ JOIN {{process_allowlist_table}} process USING (upid)
+ WHERE thread.name = 'RenderThread';
+
+DROP VIEW IF EXISTS {{table_name_prefix}}_gpu_completion_thread;
+CREATE VIEW {{table_name_prefix}}_gpu_completion_thread AS
+ SELECT
+ process.name as process_name,
+ thread.utid
+ FROM thread
+ JOIN {{process_allowlist_table}} process USING (upid)
+ WHERE thread.name = 'GPU completion';
+
+DROP VIEW IF EXISTS {{table_name_prefix}}_hwc_release_thread;
+CREATE VIEW {{table_name_prefix}}_hwc_release_thread AS
+ SELECT
+ process.name as process_name,
+ thread.utid
+ FROM thread
+ JOIN {{process_allowlist_table}} process USING (upid)
+ WHERE thread.name = 'HWC release';
+
+DROP TABLE IF EXISTS {{table_name_prefix}}_main_thread_slices;
+CREATE TABLE {{table_name_prefix}}_main_thread_slices AS
+ SELECT
+ process_name,
+ thread.utid,
+ slice.*,
+ ts + dur AS ts_end
+ FROM slice
+ JOIN thread_track ON slice.track_id = thread_track.id
+ JOIN {{table_name_prefix}}_main_thread thread USING (utid)
+ WHERE dur > 0;
+
+DROP VIEW IF EXISTS {{table_name_prefix}}_do_frame_slices;
+CREATE VIEW {{table_name_prefix}}_do_frame_slices AS
+ SELECT
+ *,
+ CAST(STR_SPLIT(name, ' ', 1) AS INTEGER) as vsync
+ FROM {{table_name_prefix}}_main_thread_slices
+ WHERE name GLOB 'Choreographer#doFrame*';
+
+DROP TABLE IF EXISTS {{table_name_prefix}}_render_thread_slices;
+CREATE TABLE {{table_name_prefix}}_render_thread_slices AS
+ SELECT
+ process_name,
+ thread.utid,
+ slice.*,
+ ts + dur AS ts_end
+ FROM slice
+ JOIN thread_track ON slice.track_id = thread_track.id
+ JOIN {{table_name_prefix}}_render_thread thread USING (utid)
+ WHERE dur > 0;
+
+DROP VIEW IF EXISTS {{table_name_prefix}}_draw_frame_slices;
+CREATE VIEW {{table_name_prefix}}_draw_frame_slices AS
+ SELECT
+ *,
+ CAST(STR_SPLIT(name, ' ', 1) AS INTEGER) as vsync
+ FROM {{table_name_prefix}}_render_thread_slices
+ WHERE name GLOB 'DrawFrame*';
+
+DROP VIEW IF EXISTS {{table_name_prefix}}_gpu_completion_slices;
+CREATE VIEW {{table_name_prefix}}_gpu_completion_slices AS
+ SELECT
+ process_name,
+ thread.utid,
+ slice.*,
+ ts + dur AS ts_end,
+ -- Extracts 1234 from 'waiting for GPU completion 1234'
+ CAST(STR_SPLIT(slice.name, ' ', 4) AS INTEGER) as idx
+ FROM slice
+ JOIN thread_track ON slice.track_id = thread_track.id
+ JOIN {{table_name_prefix}}_gpu_completion_thread thread USING (utid)
+ WHERE slice.name GLOB 'waiting for GPU completion *'
+ AND dur > 0;
+
+DROP VIEW IF EXISTS {{table_name_prefix}}_hwc_release_slices;
+CREATE VIEW {{table_name_prefix}}_hwc_release_slices AS
+ SELECT
+ process_name,
+ thread.utid,
+ slice.*,
+ ts + dur as ts_end,
+ -- Extracts 1234 from 'waiting for HWC release 1234'
+ CAST(STR_SPLIT(slice.name, ' ', 4) AS INTEGER) as idx
+ FROM slice
+ JOIN thread_track ON slice.track_id = thread_track.id
+ JOIN {{table_name_prefix}}_hwc_release_thread thread USING (utid)
+ WHERE slice.name GLOB 'waiting for HWC release *'
+ AND dur > 0;
diff --git a/src/trace_processor/metrics/sql/android/android_ion.sql b/src/trace_processor/metrics/sql/android/android_ion.sql
new file mode 100644
index 000000000..4d618434b
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_ion.sql
@@ -0,0 +1,94 @@
+--
+-- Copyright 2019 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+DROP VIEW IF EXISTS ion_timeline;
+CREATE VIEW ion_timeline AS
+SELECT
+ ts,
+ LEAD(ts, 1, (SELECT end_ts FROM trace_bounds))
+ OVER(PARTITION BY track_id ORDER BY ts) - ts AS dur,
+ CASE name
+ WHEN 'mem.ion' THEN 'all'
+ ELSE SUBSTR(name, 9)
+ END AS heap_name,
+ track_id,
+ value
+FROM counter JOIN counter_track
+ ON counter.track_id = counter_track.id
+WHERE (name GLOB 'mem.ion.*' OR name = 'mem.ion');
+
+DROP VIEW IF EXISTS ion_heap_stats;
+CREATE VIEW ion_heap_stats AS
+SELECT
+ heap_name,
+ SUM(value * dur) / SUM(dur) AS avg_size,
+ MIN(value) AS min_size,
+ MAX(value) AS max_size
+FROM ion_timeline
+GROUP BY 1;
+
+DROP VIEW IF EXISTS ion_raw_allocs;
+CREATE VIEW ion_raw_allocs AS
+SELECT
+ CASE name
+ WHEN 'mem.ion_change' THEN 'all'
+ ELSE SUBSTR(name, 16)
+ END AS heap_name,
+ ts,
+ value AS instant_value,
+ SUM(value) OVER win AS value
+FROM counter c JOIN thread_counter_track t ON c.track_id = t.id
+WHERE (name GLOB 'mem.ion_change.*' OR name = 'mem.ion_change') AND value > 0
+WINDOW win AS (
+ PARTITION BY name ORDER BY ts
+ ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+);
+
+DROP VIEW IF EXISTS ion_alloc_stats;
+CREATE VIEW ion_alloc_stats AS
+SELECT
+ heap_name,
+ SUM(instant_value) AS total_alloc_size_bytes
+FROM ion_raw_allocs
+GROUP BY 1;
+
+-- We need to group by ts here as we can have two ion events from
+-- different processes occurring at the same timestamp. We take the
+-- max as this will take both allocations into account at that
+-- timestamp.
+DROP VIEW IF EXISTS android_ion_event;
+CREATE VIEW android_ion_event AS
+SELECT
+ 'counter' AS track_type,
+ printf('ION allocations (heap: %s)', heap_name) AS track_name,
+ ts,
+ MAX(value) AS value
+FROM ion_raw_allocs
+GROUP BY 1, 2, 3;
+
+DROP VIEW IF EXISTS android_ion_output;
+CREATE VIEW android_ion_output AS
+SELECT AndroidIonMetric(
+ 'buffer', RepeatedField(
+ AndroidIonMetric_Buffer(
+ 'name', heap_name,
+ 'avg_size_bytes', avg_size,
+ 'min_size_bytes', min_size,
+ 'max_size_bytes', max_size,
+ 'total_alloc_size_bytes', total_alloc_size_bytes
+ )
+ ))
+FROM ion_heap_stats JOIN ion_alloc_stats USING (heap_name);
diff --git a/src/trace_processor/metrics/sql/android/android_irq_runtime.sql b/src/trace_processor/metrics/sql/android/android_irq_runtime.sql
new file mode 100644
index 000000000..e69683c08
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_irq_runtime.sql
@@ -0,0 +1,123 @@
+--
+-- Copyright 2022 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+DROP VIEW IF EXISTS irq_runtime_all;
+
+CREATE VIEW irq_runtime_all
+AS
+SELECT ts, dur, name
+FROM slice
+WHERE category = 'irq';
+
+DROP VIEW IF EXISTS hw_irq_runtime;
+
+CREATE VIEW hw_irq_runtime
+AS
+SELECT ts, dur, name
+FROM irq_runtime_all
+WHERE name GLOB 'IRQ (*)'
+ORDER BY dur DESC;
+
+DROP VIEW IF EXISTS hw_irq_runtime_statistics;
+
+CREATE VIEW hw_irq_runtime_statistics
+AS
+SELECT
+ MAX(dur) AS max_runtime,
+ COUNT(IIF(dur > 1e6, 1, NULL)) AS over_threshold_count,
+ COUNT(*) AS total_count
+FROM hw_irq_runtime;
+
+DROP VIEW IF EXISTS sw_irq_runtime;
+
+CREATE VIEW sw_irq_runtime
+AS
+SELECT ts, dur, name
+FROM irq_runtime_all
+WHERE name NOT GLOB 'IRQ (*)'
+ORDER BY dur DESC;
+
+CREATE VIEW sw_irq_runtime_statistics
+AS
+SELECT
+ MAX(dur) AS max_runtime,
+ COUNT(IIF(dur > 5e6, 1, NULL)) AS over_threshold_count,
+ COUNT(*) AS total_count
+FROM sw_irq_runtime;
+
+DROP VIEW IF EXISTS android_irq_runtime_output;
+
+CREATE VIEW android_irq_runtime_output
+AS
+SELECT
+ AndroidIrqRuntimeMetric(
+ 'hw_irq',
+ (
+ SELECT
+ AndroidIrqRuntimeMetric_IrqRuntimeMetric(
+ 'max_runtime',
+ max_runtime,
+ 'total_count',
+ total_count,
+ 'threshold_metric',
+ AndroidIrqRuntimeMetric_ThresholdMetric(
+ 'threshold',
+ '1ms',
+ 'over_threshold_count',
+ over_threshold_count,
+ 'anomaly_ratio',
+ CAST(
+ over_threshold_count AS DOUBLE)
+ / CAST(
+ total_count AS DOUBLE)),
+ 'longest_irq_slices',
+ (
+ SELECT
+ RepeatedField(
+ AndroidIrqRuntimeMetric_IrqSlice(
+ 'irq_name', name, 'ts', ts, 'dur', dur))
+ FROM (SELECT ts, dur, name FROM hw_irq_runtime LIMIT 10)
+ ))
+ FROM hw_irq_runtime_statistics
+ ),
+ 'sw_irq',
+ (
+ SELECT
+ AndroidIrqRuntimeMetric_IrqRuntimeMetric(
+ 'max_runtime',
+ max_runtime,
+ 'total_count',
+ total_count,
+ 'threshold_metric',
+ AndroidIrqRuntimeMetric_ThresholdMetric(
+ 'threshold',
+ '5ms',
+ 'over_threshold_count',
+ over_threshold_count,
+ 'anomaly_ratio',
+ CAST(
+ over_threshold_count AS DOUBLE)
+ / CAST(
+ total_count AS DOUBLE)),
+ 'longest_irq_slices',
+ (
+ SELECT
+ RepeatedField(
+ AndroidIrqRuntimeMetric_IrqSlice(
+ 'irq_name', name, 'ts', ts, 'dur', dur))
+ FROM (SELECT ts, dur, name FROM sw_irq_runtime LIMIT 10)
+ ))
+ FROM sw_irq_runtime_statistics
+ ));
diff --git a/src/trace_processor/metrics/sql/android/android_jank.sql b/src/trace_processor/metrics/sql/android/android_jank.sql
new file mode 100644
index 000000000..9c2cc22f9
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_jank.sql
@@ -0,0 +1,284 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+
+DROP TABLE IF EXISTS android_jank_process_allowlist;
+CREATE TABLE android_jank_process_allowlist AS
+SELECT process.name, process.upid
+FROM process
+WHERE process.name IN (
+ 'com.android.systemui',
+ 'com.google.android.apps.nexuslauncher',
+ 'com.google.android.inputmethod.latin'
+);
+
+SELECT RUN_METRIC(
+ 'android/android_hwui_threads.sql',
+ 'table_name_prefix', 'android_jank',
+ 'process_allowlist_table', 'android_jank_process_allowlist');
+
+DROP TABLE IF EXISTS android_jank_thread_state_running;
+CREATE TABLE android_jank_thread_state_running AS
+SELECT utid, ts, dur, state
+FROM thread_state
+WHERE utid IN (SELECT utid FROM android_jank_main_thread_slices)
+AND state = 'Running'
+AND dur > 0;
+
+DROP TABLE IF EXISTS android_jank_thread_state_scheduled;
+CREATE TABLE android_jank_thread_state_scheduled AS
+SELECT utid, ts, dur, state
+FROM thread_state
+WHERE utid IN (SELECT utid FROM android_jank_main_thread_slices)
+AND (state = 'R' OR state = 'R+')
+AND dur > 0;
+
+DROP TABLE IF EXISTS android_jank_thread_state_io_wait;
+CREATE TABLE android_jank_thread_state_io_wait AS
+SELECT utid, ts, dur, state
+FROM thread_state
+WHERE utid IN (SELECT utid FROM android_jank_main_thread_slices)
+AND (((state = 'D' OR state = 'DK') AND io_wait) OR (state = 'DK' AND io_wait IS NULL))
+AND dur > 0;
+
+--
+-- Main Thread alerts
+--
+
+-- Expensive measure/layout
+
+DROP TABLE IF EXISTS android_jank_measure_layout_slices;
+CREATE TABLE android_jank_measure_layout_slices AS
+SELECT
+ process_name,
+ utid,
+ id,
+ ts,
+ dur
+FROM android_jank_main_thread_slices
+WHERE name in ('measure', 'layout')
+AND dur >= 3000000;
+
+CREATE VIRTUAL TABLE IF NOT EXISTS android_jank_measure_layout_slices_state
+USING span_join(android_jank_measure_layout_slices PARTITIONED utid, android_jank_thread_state_running PARTITIONED utid);
+
+DROP TABLE IF EXISTS android_jank_measure_layout_slices_high_cpu;
+CREATE TABLE android_jank_measure_layout_slices_high_cpu AS
+SELECT id FROM android_jank_measure_layout_slices_state
+GROUP BY id
+HAVING SUM(dur) > 3000000;
+
+DROP TABLE IF EXISTS android_jank_measure_layout_alerts;
+CREATE TABLE android_jank_measure_layout_alerts AS
+SELECT
+ process_name,
+ ts,
+ dur,
+ 'Expensive measure/layout pass' as alert_name,
+ id
+FROM android_jank_measure_layout_slices
+JOIN android_jank_measure_layout_slices_high_cpu USING (id);
+
+-- Inflation during ListView recycling
+-- as additional alerts for expensive layout slices
+
+DROP TABLE IF EXISTS android_jank_listview_inflation_alerts;
+CREATE TABLE android_jank_listview_inflation_alerts AS
+SELECT
+ process_name,
+ ts,
+ dur,
+ 'Inflation during ListView recycling' as alert_name
+FROM android_jank_main_thread_slices
+WHERE name IN ('obtainView', 'setupListItem')
+AND EXISTS (
+ SELECT 1
+ FROM descendant_slice(android_jank_main_thread_slices.id)
+ WHERE name = 'inflate')
+AND EXISTS(
+ SELECT 1
+ FROM android_jank_measure_layout_alerts
+ JOIN ancestor_slice(android_jank_main_thread_slices.id) USING (id)
+);
+
+-- Long View#draw()
+
+DROP TABLE IF EXISTS android_jank_view_draw_slices;
+CREATE TABLE android_jank_view_draw_slices AS
+SELECT
+ process_name,
+ utid,
+ id,
+ ts,
+ dur
+FROM android_jank_main_thread_slices
+WHERE name in ('getDisplayList', 'Record View#draw()')
+AND dur >= 3000000;
+
+CREATE VIRTUAL TABLE IF NOT EXISTS android_jank_view_draw_slices_state
+USING span_join(android_jank_view_draw_slices PARTITIONED utid, android_jank_thread_state_running PARTITIONED utid);
+
+DROP TABLE IF EXISTS android_jank_view_draw_slices_high_cpu;
+CREATE TABLE android_jank_view_draw_slices_high_cpu AS
+SELECT id FROM android_jank_view_draw_slices_state
+GROUP BY id
+HAVING SUM(dur) > 3000000;
+
+DROP TABLE IF EXISTS android_jank_view_draw_alerts;
+CREATE TABLE android_jank_view_draw_alerts AS
+SELECT
+ process_name,
+ ts,
+ dur,
+ 'Long View#draw()' as alert_name
+FROM android_jank_main_thread_slices
+JOIN android_jank_view_draw_slices_high_cpu USING (id);
+
+-- Scheduling delay and Blocking I/O delay
+
+DROP TABLE IF EXISTS android_jank_long_do_frame_slices;
+CREATE TABLE android_jank_long_do_frame_slices AS
+SELECT
+ process_name,
+ utid,
+ id,
+ ts,
+ dur
+FROM android_jank_main_thread_slices
+WHERE name GLOB 'Choreographer#doFrame*'
+AND dur >= 5000000;
+
+CREATE VIRTUAL TABLE IF NOT EXISTS android_jank_do_frame_slices_state_scheduled
+USING span_join(android_jank_long_do_frame_slices PARTITIONED utid, android_jank_thread_state_scheduled PARTITIONED utid);
+
+
+DROP TABLE IF EXISTS android_jank_do_frame_slices_long_scheduled;
+CREATE TABLE android_jank_do_frame_slices_long_scheduled AS
+SELECT id FROM android_jank_do_frame_slices_state_scheduled
+GROUP BY id
+HAVING SUM(dur) > 5000000;
+
+DROP TABLE IF EXISTS android_jank_scheduling_delay_alerts;
+CREATE TABLE android_jank_scheduling_delay_alerts AS
+SELECT
+ process_name,
+ ts,
+ dur,
+ 'Scheduling delay' as alert_name
+FROM android_jank_long_do_frame_slices
+JOIN android_jank_do_frame_slices_long_scheduled USING (id);
+
+CREATE VIRTUAL TABLE IF NOT EXISTS android_jank_do_frame_slices_state_io_wait
+USING span_join(android_jank_long_do_frame_slices PARTITIONED utid, android_jank_thread_state_io_wait PARTITIONED utid);
+
+DROP TABLE IF EXISTS android_jank_do_frame_slices_long_io_wait;
+CREATE TABLE android_jank_do_frame_slices_long_io_wait AS
+SELECT id FROM android_jank_do_frame_slices_state_io_wait
+GROUP BY id
+HAVING SUM(dur) > 5000000;
+
+DROP TABLE IF EXISTS android_jank_blocking_delay_alerts;
+CREATE TABLE android_jank_blocking_delay_alerts AS
+SELECT
+ process_name,
+ ts,
+ dur,
+ 'Blocking I/O delay' as alert_name
+FROM android_jank_do_frame_slices
+JOIN android_jank_do_frame_slices_long_io_wait USING (id);
+
+--
+-- Render Thread alerts
+--
+
+-- Expensive Canvas#saveLayer()
+
+DROP TABLE IF EXISTS android_jank_save_layer_alerts;
+CREATE TABLE android_jank_save_layer_alerts AS
+SELECT
+ process_name,
+ ts,
+ dur,
+ 'Expensive rendering with Canvas#saveLayer()' as alert_name
+FROM android_jank_render_thread_slices
+WHERE name GLOB '*alpha caused *saveLayer *'
+AND dur >= 1000000;
+
+-- Path texture churn
+
+DROP TABLE IF EXISTS android_jank_generate_path_alerts;
+CREATE TABLE android_jank_generate_path_alerts AS
+SELECT
+ process_name,
+ ts,
+ dur,
+ 'Path texture churn' as alert_name
+FROM android_jank_render_thread_slices
+WHERE name = 'Generate Path Texture'
+AND dur >= 3000000;
+
+-- Expensive Bitmap uploads
+
+DROP TABLE IF EXISTS android_jank_upload_texture_alerts;
+CREATE TABLE android_jank_upload_texture_alerts AS
+SELECT
+ process_name,
+ ts,
+ dur,
+ 'Expensive Bitmap uploads' as alert_name
+FROM android_jank_render_thread_slices
+WHERE name GLOB 'Upload *x* Texture'
+AND dur >= 3000000;
+
+-- Merge all alerts tables into one table
+DROP TABLE IF EXISTS android_jank_alerts;
+CREATE TABLE android_jank_alerts AS
+SELECT process_name, ts, dur, alert_name FROM android_jank_measure_layout_alerts
+UNION ALL
+SELECT process_name, ts, dur, alert_name FROM android_jank_listview_inflation_alerts
+UNION ALL
+SELECT process_name, ts, dur, alert_name FROM android_jank_scheduling_delay_alerts
+UNION ALL
+SELECT process_name, ts, dur, alert_name FROM android_jank_blocking_delay_alerts
+UNION ALL
+SELECT process_name, ts, dur, alert_name FROM android_jank_save_layer_alerts
+UNION ALL
+SELECT process_name, ts, dur, alert_name FROM android_jank_generate_path_alerts
+UNION ALL
+SELECT process_name, ts, dur, alert_name FROM android_jank_upload_texture_alerts;
+
+DROP VIEW IF EXISTS android_jank_event;
+CREATE VIEW android_jank_event AS
+SELECT
+ 'slice' as track_type,
+ process_name || ' warnings' as track_name,
+ ts,
+ 0 as dur,
+ group_concat(alert_name) as slice_name
+FROM android_jank_alerts
+GROUP BY track_type, track_name, ts;
+
+DROP VIEW IF EXISTS android_jank_output;
+CREATE VIEW android_jank_output AS
+SELECT AndroidJankMetrics(
+ 'warnings', (
+ SELECT RepeatedField(
+ AndroidJankMetrics_Warning(
+ 'ts', ts,
+ 'dur', dur,
+ 'process_name', process_name,
+ 'warning_text', alert_name))
+ FROM android_jank_alerts
+ ORDER BY process_name, ts, dur));
diff --git a/src/trace_processor/metrics/sql/android/android_lmk.sql b/src/trace_processor/metrics/sql/android/android_lmk.sql
new file mode 100644
index 000000000..ca20c90a7
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_lmk.sql
@@ -0,0 +1,100 @@
+--
+-- Copyright 2019 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+SELECT RUN_METRIC('android/process_oom_score.sql');
+
+-- All LMK events ordered by timestamp
+DROP TABLE IF EXISTS lmk_events;
+CREATE TABLE lmk_events AS
+WITH raw_events AS (
+ SELECT ref AS upid, MIN(ts) AS ts
+ FROM instants
+ WHERE name = 'mem.lmk' AND ref_type = 'upid'
+ GROUP BY 1
+)
+SELECT
+ raw_events.ts,
+ raw_events.upid,
+ oom_scores.oom_score_val AS score
+FROM raw_events
+LEFT JOIN oom_score_span oom_scores
+ ON (raw_events.upid = oom_scores.upid AND
+ raw_events.ts >= oom_scores.ts AND
+ raw_events.ts < oom_scores.ts + oom_scores.dur)
+ORDER BY 1;
+
+DROP VIEW IF EXISTS android_lmk_event;
+CREATE VIEW android_lmk_event AS
+WITH raw_events AS (
+ SELECT
+ ts,
+ LEAD(ts) OVER (ORDER BY ts) - ts AS dur,
+ CAST(value AS INTEGER) AS pid
+ FROM counter c
+ JOIN counter_track t ON t.id = c.track_id
+ WHERE t.name = 'kill_one_process'
+ UNION ALL
+ SELECT
+ slice.ts,
+ slice.dur,
+ CAST(STR_SPLIT(slice.name, ",", 1) AS INTEGER) AS pid
+ FROM slice
+ WHERE slice.name GLOB 'lmk,*'
+),
+lmks_with_proc_name AS (
+ SELECT
+ *,
+ process.name as process_name
+ FROM raw_events
+ LEFT JOIN process ON
+ process.pid = raw_events.pid
+ AND (raw_events.ts >= process.start_ts OR process.start_ts IS NULL)
+ AND (raw_events.ts < process.end_ts OR process.end_ts IS NULL)
+ WHERE raw_events.pid != 0
+)
+SELECT
+ 'slice' as track_type,
+ 'Low Memory Kills (LMKs)' as track_name,
+ ts,
+ dur,
+ CASE
+ WHEN process_name IS NULL THEN printf('Process %d', lmk.pid)
+ ELSE printf('%s (pid: %d)', process_name, lmk.pid)
+ END AS slice_name
+FROM lmks_with_proc_name as lmk;
+
+DROP VIEW IF EXISTS android_lmk_output;
+CREATE VIEW android_lmk_output AS
+WITH lmk_counts AS (
+ SELECT score, COUNT(1) AS count
+ FROM lmk_events
+ GROUP BY score
+)
+SELECT AndroidLmkMetric(
+ 'total_count', (SELECT COUNT(1) FROM lmk_events),
+ 'by_oom_score', (
+ SELECT
+ RepeatedField(AndroidLmkMetric_ByOomScore(
+ 'oom_score_adj', score,
+ 'count', count
+ ))
+ FROM lmk_counts
+ WHERE score IS NOT NULL
+ ),
+ 'oom_victim_count', (
+ SELECT COUNT(1) FROM instants WHERE name = 'mem.oom_kill'
+ )
+);
diff --git a/src/trace_processor/metrics/android/android_lmk_reason.sql b/src/trace_processor/metrics/sql/android/android_lmk_reason.sql
index 0772c30bb..0772c30bb 100644
--- a/src/trace_processor/metrics/android/android_lmk_reason.sql
+++ b/src/trace_processor/metrics/sql/android/android_lmk_reason.sql
diff --git a/src/trace_processor/metrics/android/android_mem.sql b/src/trace_processor/metrics/sql/android/android_mem.sql
index d50b85af8..d50b85af8 100644
--- a/src/trace_processor/metrics/android/android_mem.sql
+++ b/src/trace_processor/metrics/sql/android/android_mem.sql
diff --git a/src/trace_processor/metrics/android/android_mem_unagg.sql b/src/trace_processor/metrics/sql/android/android_mem_unagg.sql
index da0675172..da0675172 100644
--- a/src/trace_processor/metrics/android/android_mem_unagg.sql
+++ b/src/trace_processor/metrics/sql/android/android_mem_unagg.sql
diff --git a/src/trace_processor/metrics/sql/android/android_multiuser.sql b/src/trace_processor/metrics/sql/android/android_multiuser.sql
new file mode 100644
index 000000000..bb5e4fca0
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_multiuser.sql
@@ -0,0 +1,26 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+SELECT RUN_METRIC('android/android_multiuser_populator.sql',
+ 'output_table_name', 'event_user_switch',
+ 'start_event', 'user_start',
+ 'end_event', 'launcher_end');
+
+DROP VIEW IF EXISTS android_multiuser_output;
+CREATE VIEW android_multiuser_output AS
+SELECT AndroidMultiuserMetric(
+ 'user_switch', (SELECT * FROM event_user_switch)
+);
diff --git a/src/trace_processor/metrics/sql/android/android_multiuser_populator.sql b/src/trace_processor/metrics/sql/android/android_multiuser_populator.sql
new file mode 100644
index 000000000..c1726ffb0
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_multiuser_populator.sql
@@ -0,0 +1,135 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+-- Create the base tables and views containing the launch spans.
+SELECT RUN_METRIC('android/startup/launches.sql');
+
+-- Collect the important timestamps for Multiuser events.
+DROP VIEW IF EXISTS multiuser_events;
+CREATE VIEW multiuser_events AS
+SELECT
+ {{start_event}}_time_ns AS event_start_time_ns,
+ {{end_event}}_time_ns AS event_end_time_ns
+FROM
+ (
+ SELECT MIN(slice.ts) AS user_start_time_ns
+ FROM slice
+ WHERE (
+ slice.name = "UserDetailView.Adapter#onClick" OR -- QuickSettings
+ slice.name = "UserDetailSettings.switchUser" OR -- Settings
+ slice.name = "shell_runSwitchUser" -- adb shell
+ )
+ ),
+ (
+ SELECT ts_end AS launcher_end_time_ns
+ FROM launches
+ WHERE (package = 'com.android.launcher3' OR package = 'com.google.android.apps.nexuslauncher')
+ ),
+ (
+ SELECT MIN(slice.ts) AS user_create_time_ns
+ FROM slice
+ WHERE (
+ slice.name = "UserDetailView.Adapter#onClick" OR -- QuickSettings
+ slice.name = "UserSettings.addUserNow" OR -- Settings
+ slice.name = "UserSettings.addGuest" OR -- Settings
+ slice.name = "shell_runCreateUser" -- adb shell
+ )
+ );
+
+-- Calculation of the duration of the Multiuser event of interest.
+DROP VIEW IF EXISTS multiuser_timing;
+CREATE VIEW multiuser_timing AS
+SELECT
+ CAST((event_end_time_ns - event_start_time_ns) / 1e6 + 0.5 AS INT) AS duration_ms
+FROM
+ multiuser_events;
+
+
+-- Calculate CPU usage during the Multiuser event of interest.
+
+-- Get all the scheduling slices.
+DROP VIEW IF EXISTS sp_sched;
+CREATE VIEW sp_sched AS
+SELECT ts, dur, cpu, utid
+FROM sched;
+-- Get all the cpu frequency slices.
+DROP VIEW IF EXISTS sp_frequency;
+CREATE VIEW sp_frequency AS
+SELECT
+ ts,
+ lead(ts) OVER (PARTITION BY track_id ORDER BY ts) - ts as dur,
+ cpu,
+ value as freq_khz
+FROM counter
+JOIN cpu_counter_track ON counter.track_id = cpu_counter_track.id;
+-- Create the span joined table which combines cpu frequency with scheduling slices.
+DROP TABLE IF EXISTS sched_with_frequency;
+CREATE VIRTUAL TABLE sched_with_frequency
+USING SPAN_JOIN(sp_sched PARTITIONED cpu, sp_frequency PARTITIONED cpu);
+
+-- Calculate the CPU cycles spent per process during the duration.
+DROP VIEW IF EXISTS cpu_usage_all;
+CREATE VIEW cpu_usage_all AS
+SELECT
+ process.uid / 100000 AS user_id,
+ process.name AS process_name,
+ SUM(dur * freq_khz) / 1e9 AS cpu_kcycles
+FROM
+ sched_with_frequency
+ JOIN thread USING (utid)
+ JOIN process USING (upid)
+WHERE
+ ts >= (SELECT event_start_time_ns FROM multiuser_events)
+ AND
+ ts <= (SELECT event_end_time_ns FROM multiuser_events)
+GROUP BY upid, process.name
+ORDER BY cpu_kcycles DESC;
+
+-- Get the data from cpu_usage_all, but also with the percentage.
+DROP VIEW IF EXISTS cpu_usage;
+CREATE VIEW cpu_usage AS
+SELECT
+ user_id,
+ process_name,
+ process_name || ":" || (CASE WHEN user_id = 0 THEN "system" ELSE "secondary" END) AS identifier,
+ CAST(cpu_kcycles / 1e3 AS INT) AS cpu_mcycles,
+ cpu_kcycles / (SELECT SUM(cpu_kcycles) FROM cpu_usage_all) * 100 AS cpu_percentage
+FROM
+ cpu_usage_all
+ORDER BY cpu_mcycles DESC LIMIT 25;
+
+
+-- Record the output for populating the proto.
+DROP VIEW IF EXISTS {{output_table_name}};
+CREATE VIEW {{output_table_name}} AS
+SELECT AndroidMultiuserMetric_EventData(
+ 'duration_ms', (
+ SELECT duration_ms
+ FROM multiuser_timing
+ ),
+ 'cpu_usage', (
+ SELECT RepeatedField(
+ AndroidMultiuserMetric_EventData_CpuUsage(
+ 'identifier', identifier,
+ 'user_id', user_id,
+ 'process_name', process_name,
+ 'cpu_mcycles', cpu_mcycles,
+ 'cpu_percentage', cpu_percentage
+ )
+ )
+ FROM cpu_usage
+ )
+);
diff --git a/src/trace_processor/metrics/sql/android/android_netperf.sql b/src/trace_processor/metrics/sql/android/android_netperf.sql
new file mode 100644
index 000000000..eb773ab06
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_netperf.sql
@@ -0,0 +1,296 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+DROP VIEW IF EXISTS rx_packets;
+CREATE VIEW rx_packets AS
+ SELECT
+ ts,
+ REPLACE(name, " Received KB", "") AS dev,
+ EXTRACT_ARG(arg_set_id, 'cpu') AS cpu,
+ EXTRACT_ARG(arg_set_id, 'len') AS len
+ FROM counter c
+ LEFT JOIN counter_track t
+ ON c.track_id = t.id
+ WHERE name GLOB "* Received KB"
+ ORDER BY ts DESC;
+
+DROP VIEW IF EXISTS gro_rx_packet_count;
+CREATE VIEW gro_rx_packet_count AS
+ SELECT
+ s.name AS dev,
+ COUNT(1) AS cnt
+ FROM slice s
+ LEFT JOIN track t
+ ON s.track_id = t.id
+ WHERE t.name GLOB "Napi Gro Cpu *"
+ GROUP BY s.name;
+
+DROP VIEW IF EXISTS tx_packets;
+CREATE VIEW tx_packets AS
+ SELECT
+ ts,
+ REPLACE(name, " Transmitted KB", "") AS dev,
+ EXTRACT_ARG(arg_set_id, 'cpu') AS cpu,
+ EXTRACT_ARG(arg_set_id, 'len') AS len
+ FROM counter c
+ LEFT JOIN counter_track t
+ ON c.track_id = t.id
+ WHERE name GLOB "* Transmitted KB"
+ ORDER BY ts DESC;
+
+DROP VIEW IF EXISTS net_devices;
+CREATE VIEW net_devices AS
+ SELECT DISTINCT dev
+ FROM tx_packets
+ UNION
+ SELECT DISTINCT dev
+ FROM rx_packets;
+
+DROP VIEW IF EXISTS tcp_retransmitted_count;
+CREATE VIEW tcp_retransmitted_count AS
+ SELECT
+ COUNT(1) AS cnt
+ FROM slice s
+ LEFT JOIN track t
+ ON s.track_id = t.id
+ WHERE
+ t.name = "TCP Retransmit Skb";
+
+DROP VIEW IF EXISTS kfree_skb_count;
+CREATE VIEW kfree_skb_count AS
+ SELECT
+ MAX(value) AS cnt
+ FROM counter c
+ LEFT JOIN track t
+ ON c.track_id = t.id
+ WHERE
+ t.name = "Kfree Skb IP Prot";
+
+DROP VIEW IF EXISTS device_per_core_ingress_traffic;
+CREATE VIEW device_per_core_ingress_traffic AS
+ SELECT
+ dev,
+ AndroidNetworkMetric_CorePacketStatistic(
+ 'id', cpu,
+ 'packet_statistic', AndroidNetworkMetric_PacketStatistic(
+ 'packets', COUNT(1),
+ 'bytes', SUM(len),
+ 'first_packet_timestamp_ns', MIN(ts),
+ 'last_packet_timestamp_ns', MAX(ts),
+ 'interval_ns', IIF((MAX(ts)-MIN(ts))>10000000, MAX(ts)-MIN(ts), 10000000),
+ 'data_rate_kbps', (SUM(len)*8)/(IIF((MAX(ts)-MIN(ts))>10000000, MAX(ts)-MIN(ts), 10000000)/1e9)/1024
+ )
+ ) AS proto
+ FROM rx_packets
+ GROUP BY dev, cpu;
+
+DROP VIEW IF EXISTS device_per_core_egress_traffic;
+CREATE VIEW device_per_core_egress_traffic AS
+ SELECT
+ dev,
+ AndroidNetworkMetric_CorePacketStatistic(
+ 'id', cpu,
+ 'packet_statistic', AndroidNetworkMetric_PacketStatistic(
+ 'packets', COUNT(1),
+ 'bytes', SUM(len),
+ 'first_packet_timestamp_ns', MIN(ts),
+ 'last_packet_timestamp_ns', MAX(ts),
+ 'interval_ns', IIF((MAX(ts)-MIN(ts))>10000000, MAX(ts)-MIN(ts), 10000000),
+ 'data_rate_kbps', (SUM(len)*8)/(IIF((MAX(ts)-MIN(ts))>10000000, MAX(ts)-MIN(ts), 10000000)/1e9)/1024
+ )
+ ) AS proto
+ FROM tx_packets
+ GROUP BY dev, cpu;
+
+DROP VIEW IF EXISTS device_total_ingress_traffic;
+CREATE VIEW device_total_ingress_traffic AS
+ SELECT
+ dev,
+ MIN(ts) AS start_ts,
+ MAX(ts) AS end_ts,
+ IIF((MAX(ts) - MIN(ts)) > 10000000, MAX(ts)-MIN(ts), 10000000) AS interval,
+ COUNT(1) AS packets,
+ SUM(len) AS bytes
+ FROM rx_packets
+ GROUP BY dev;
+
+DROP VIEW IF EXISTS device_total_egress_traffic;
+CREATE VIEW device_total_egress_traffic AS
+ SELECT
+ dev,
+ MIN(ts) AS start_ts,
+ MAX(ts) AS end_ts,
+ IIF((MAX(ts) - MIN(ts)) > 10000000, MAX(ts)-MIN(ts), 10000000) AS interval,
+ COUNT(1) AS packets,
+ SUM(len) AS bytes
+ FROM tx_packets
+ GROUP BY dev;
+
+DROP VIEW IF EXISTS device_traffic_statistic;
+CREATE VIEW device_traffic_statistic AS
+ SELECT
+ AndroidNetworkMetric_NetDevice(
+ 'name', net_devices.dev,
+ 'rx', (
+ SELECT
+ AndroidNetworkMetric_Rx(
+ 'total', AndroidNetworkMetric_PacketStatistic(
+ 'packets', packets,
+ 'bytes', bytes,
+ 'first_packet_timestamp_ns', start_ts,
+ 'last_packet_timestamp_ns', end_ts,
+ 'interval_ns', interval,
+ 'data_rate_kbps', (bytes*8)/(interval/1e9)/1024
+ ),
+ 'core', (
+ SELECT
+ RepeatedField(proto)
+ FROM device_per_core_ingress_traffic
+ WHERE device_per_core_ingress_traffic.dev = device_total_ingress_traffic.dev
+ ),
+ 'gro_aggregation_ratio', (
+ SELECT
+ CASE
+ WHEN packets > 0 THEN '1:' || CAST( (cnt*1.0/packets) AS text)
+ ELSE '0:' || cnt
+ END
+ FROM gro_rx_packet_count
+ WHERE gro_rx_packet_count.dev = net_devices.dev
+ )
+ )
+ FROM device_total_ingress_traffic
+ WHERE device_total_ingress_traffic.dev = net_devices.dev
+ ),
+ 'tx', (
+ SELECT
+ AndroidNetworkMetric_Tx(
+ 'total', AndroidNetworkMetric_PacketStatistic(
+ 'packets', packets,
+ 'bytes', bytes,
+ 'first_packet_timestamp_ns', start_ts,
+ 'last_packet_timestamp_ns', end_ts,
+ 'interval_ns', interval,
+ 'data_rate_kbps', (bytes*8)/(interval/1e9)/1024
+ ),
+ 'core', (
+ SELECT
+ RepeatedField(proto)
+ FROM device_per_core_egress_traffic
+ WHERE device_per_core_egress_traffic.dev = device_total_egress_traffic.dev
+ )
+ )
+ FROM device_total_egress_traffic
+ WHERE device_total_egress_traffic.dev = net_devices.dev
+ )
+ ) AS proto
+ FROM net_devices
+ ORDER BY dev;
+
+DROP VIEW IF EXISTS net_rx_actions;
+CREATE VIEW net_rx_actions AS
+ SELECT
+ s.ts,
+ s.dur,
+ CAST(SUBSTR(t.name, 13, 1) AS int) AS cpu
+ FROM slice s
+ LEFT JOIN track t
+ ON s.track_id = t.id
+ WHERE s.name = "NET_RX";
+
+DROP VIEW IF EXISTS cpu_freq_view;
+CREATE VIEW cpu_freq_view AS
+SELECT
+ cpu,
+ ts,
+ LEAD(ts, 1, (SELECT end_ts from trace_bounds))
+ OVER (PARTITION by cpu ORDER BY ts) - ts AS dur,
+ CAST(value AS INT) as freq_khz
+FROM counter
+JOIN cpu_counter_track on counter.track_id = cpu_counter_track.id
+WHERE name = 'cpufreq';
+
+DROP TABLE IF EXISTS cpu_freq_net_rx_action_per_core;
+CREATE VIRTUAL TABLE cpu_freq_net_rx_action_per_core
+USING SPAN_LEFT_JOIN(net_rx_actions PARTITIONED cpu, cpu_freq_view PARTITIONED cpu);
+
+DROP VIEW IF EXISTS total_net_rx_action_statistic;
+CREATE VIEW total_net_rx_action_statistic AS
+ SELECT
+ COUNT(1) AS times,
+ SUM(dur) AS runtime,
+ AVG(dur) AS avg_runtime,
+ (SELECT COUNT(1) FROM rx_packets) AS total_packet
+ FROM net_rx_actions;
+
+DROP VIEW IF EXISTS activated_cores;
+CREATE VIEW activated_cores AS
+ SELECT
+ DISTINCT cpu
+ FROM net_rx_actions;
+
+DROP VIEW IF EXISTS per_core_net_rx_action_statistic;
+CREATE VIEW per_core_net_rx_action_statistic AS
+ SELECT
+ AndroidNetworkMetric_CoreNetRxActionStatistic(
+ 'id', cpu,
+ 'net_rx_action_statistic', AndroidNetworkMetric_NetRxActionStatistic(
+ 'count', (SELECT COUNT(1) FROM net_rx_actions AS na WHERE na.cpu = ac.cpu),
+ 'runtime_ms', (SELECT SUM(dur)/1e6 FROM net_rx_actions AS na WHERE na.cpu = ac.cpu),
+ 'avg_runtime_ms', (SELECT AVG(dur)/1e6 FROM net_rx_actions AS na WHERE na.cpu = ac.cpu),
+ 'avg_freq_khz', (SELECT SUM(dur * freq_khz) / SUM(dur) FROM cpu_freq_net_rx_action_per_core AS cc WHERE cc.cpu = ac.cpu),
+ 'mcycles', (SELECT CAST(SUM(dur * freq_khz / 1000) / 1e9 AS INT) FROM cpu_freq_net_rx_action_per_core AS cc WHERE cc.cpu = ac.cpu)
+ )
+ ) AS proto
+ FROM activated_cores AS ac;
+
+DROP VIEW IF EXISTS android_netperf_output;
+CREATE VIEW android_netperf_output AS
+ SELECT AndroidNetworkMetric(
+ 'net_devices', (
+ SELECT
+ RepeatedField(proto)
+ FROM device_traffic_statistic
+ ),
+ 'net_rx_action', AndroidNetworkMetric_NetRxAction(
+ 'total', AndroidNetworkMetric_NetRxActionStatistic(
+ 'count', (SELECT times FROM total_net_rx_action_statistic),
+ 'runtime_ms', (SELECT runtime/1e6 FROM total_net_rx_action_statistic),
+ 'avg_runtime_ms', (SELECT avg_runtime/1e6 FROM total_net_rx_action_statistic),
+ 'avg_freq_khz', (SELECT SUM(dur * freq_khz) / SUM(dur) FROM cpu_freq_net_rx_action_per_core),
+ 'mcycles', (SELECT CAST(SUM(dur * freq_khz / 1000) / 1e9 AS INT) FROM cpu_freq_net_rx_action_per_core)
+ ),
+ 'core', (
+ SELECT
+ RepeatedField(proto)
+ FROM per_core_net_rx_action_statistic
+ ),
+ 'avg_interstack_latency_ms', (
+ SELECT
+ runtime/total_packet/1e6
+ FROM total_net_rx_action_statistic
+ )
+ ),
+ 'retransmission_rate', (
+ SELECT
+ (SELECT cnt FROM tcp_retransmitted_count) * 100.0 / COUNT(1)
+ FROM tx_packets
+ ),
+ 'kfree_skb_rate', (
+ SELECT
+ cnt * 100.0 / ((SELECT count(1) FROM rx_packets) + (SELECT count(1) FROM tx_packets))
+ FROM kfree_skb_count
+ )
+ );
+
diff --git a/src/trace_processor/metrics/sql/android/android_other_traces.sql b/src/trace_processor/metrics/sql/android/android_other_traces.sql
new file mode 100644
index 000000000..c1ec9fed2
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_other_traces.sql
@@ -0,0 +1,47 @@
+--
+-- Copyright 2022 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+DROP VIEW IF EXISTS android_other_traces_view;
+CREATE VIEW android_other_traces_view AS
+SELECT
+ ts,
+ dur,
+ SUBSTR(slice.name, 15) AS uuid,
+ 'Finalize' AS event_type
+FROM slice
+JOIN track
+ ON track.name = 'OtherTraces' AND slice.track_id = track.id
+WHERE
+ slice.name GLOB 'finalize-uuid-*';
+
+DROP VIEW IF EXISTS android_other_traces_event;
+CREATE VIEW android_other_traces_event AS
+SELECT
+ 'slice' AS track_type,
+ 'Other Traces' AS track_name,
+ ts,
+ dur,
+ event_type || ' ' || uuid AS slice_name
+FROM android_other_traces_view;
+
+DROP VIEW IF EXISTS android_other_traces_output;
+CREATE VIEW android_other_traces_output AS
+SELECT AndroidOtherTracesMetric(
+ 'finalized_traces_uuid', (
+ SELECT RepeatedField(uuid)
+ FROM android_other_traces_view
+ WHERE event_type = 'Finalize')
+ );
diff --git a/src/trace_processor/metrics/android/android_package_list.sql b/src/trace_processor/metrics/sql/android/android_package_list.sql
index 1c21678d3..1c21678d3 100644
--- a/src/trace_processor/metrics/android/android_package_list.sql
+++ b/src/trace_processor/metrics/sql/android/android_package_list.sql
diff --git a/src/trace_processor/metrics/sql/android/android_powrails.sql b/src/trace_processor/metrics/sql/android/android_powrails.sql
new file mode 100644
index 000000000..626f7c479
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_powrails.sql
@@ -0,0 +1,75 @@
+--
+-- Copyright 2019 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+-- View of Power Rail counters with ts converted from ns to ms.
+DROP VIEW IF EXISTS power_rails_counters;
+CREATE VIEW power_rails_counters AS
+SELECT value, ts/1000000 AS ts, name
+FROM counter c
+JOIN counter_track t on c.track_id = t.id
+WHERE name GLOB 'power.*';
+
+DROP VIEW IF EXISTS avg_used_powers;
+CREATE VIEW avg_used_powers AS
+SELECT
+ name,
+ avg_used_power
+FROM (
+ SELECT
+ name,
+ (LEAD(value) OVER (PARTITION BY name ORDER BY ts) - value) /
+ (LEAD(ts) OVER (PARTITION BY name ORDER BY ts) - ts) AS avg_used_power
+ FROM (
+ SELECT name, MIN(ts) AS ts, value
+ FROM power_rails_counters
+ GROUP BY name
+ UNION
+ SELECT name, MAX(ts) AS ts, value
+ FROM power_rails_counters
+ GROUP BY name
+ )
+ ORDER BY name, ts
+) WHERE avg_used_power IS NOT NULL;
+
+DROP VIEW IF EXISTS power_rails_view;
+CREATE VIEW power_rails_view AS
+WITH RECURSIVE name AS (SELECT DISTINCT name FROM power_rails_counters)
+SELECT
+ name,
+ ts,
+ AndroidPowerRails_PowerRails(
+ 'name', name,
+ 'energy_data', RepeatedField(
+ AndroidPowerRails_EnergyData(
+ 'timestamp_ms', ts,
+ 'energy_uws', value
+ )
+ ),
+ 'avg_used_power_mw', (SELECT avg_used_power FROM avg_used_powers
+ WHERE avg_used_powers.name = power_rails_counters.name)
+ ) AS power_rails_proto
+FROM power_rails_counters
+GROUP BY name
+ORDER BY ts ASC;
+
+DROP VIEW IF EXISTS android_powrails_output;
+CREATE VIEW android_powrails_output AS
+SELECT AndroidPowerRails(
+ 'power_rails', (
+ SELECT RepeatedField(power_rails_proto)
+ FROM power_rails_view
+ )
+);
diff --git a/src/trace_processor/metrics/android/android_proxy_power.sql b/src/trace_processor/metrics/sql/android/android_proxy_power.sql
index c356edda4..c356edda4 100644
--- a/src/trace_processor/metrics/android/android_proxy_power.sql
+++ b/src/trace_processor/metrics/sql/android/android_proxy_power.sql
diff --git a/src/trace_processor/metrics/sql/android/android_rt_runtime.sql b/src/trace_processor/metrics/sql/android/android_rt_runtime.sql
new file mode 100644
index 000000000..01d8a6483
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_rt_runtime.sql
@@ -0,0 +1,46 @@
+--
+-- Copyright 2022 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+DROP VIEW IF EXISTS rt_runtime_all;
+
+CREATE VIEW rt_runtime_all
+AS
+SELECT ts, dur, thread.name AS tname
+FROM sched_slice
+LEFT JOIN thread
+ USING (utid)
+LEFT JOIN process
+ USING (upid)
+WHERE priority < 100
+ORDER BY dur DESC;
+
+DROP VIEW IF EXISTS android_rt_runtime_output;
+
+CREATE VIEW android_rt_runtime_output
+AS
+SELECT
+ AndroidRtRuntimeMetric(
+ 'max_runtime',
+ (SELECT dur FROM rt_runtime_all LIMIT 1),
+ 'over_5ms_count',
+ (SELECT COUNT(*) FROM rt_runtime_all WHERE dur > 5e6),
+ 'longest_rt_slices',
+ (
+ SELECT
+ RepeatedField(
+ AndroidRtRuntimeMetric_RtSlice(
+ 'tname', tname, 'ts', ts, 'dur', dur))
+ FROM (SELECT ts, dur, tname FROM rt_runtime_all LIMIT 10)
+ ));
diff --git a/src/trace_processor/metrics/sql/android/android_simpleperf.sql b/src/trace_processor/metrics/sql/android/android_simpleperf.sql
new file mode 100644
index 000000000..1b7f85c1b
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_simpleperf.sql
@@ -0,0 +1,40 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+
+-- Find all counters from track that satisfies regex 'slc/qurg2_(wr|rd):lvl=0x(0|1|3|7)%'
+DROP VIEW IF EXISTS all_qurg2;
+CREATE VIEW all_qurg2 AS
+SELECT
+ ts,
+ track_id,
+ name,
+ value
+FROM counters
+WHERE name GLOB 'slc/qurg2_??:lvl=0x_*';
+
+-- Find all counters from track that satisfies regex 'slc/qurg2_(wr|rd):lvl=0x(1|3|7)%'
+DROP VIEW IF EXISTS non_zero_qurg2;
+CREATE VIEW non_zero_qurg2 AS
+SELECT
+ *
+FROM all_qurg2
+WHERE name NOT GLOB 'slc/qurg2_??:lvl=0x0*';
+
+DROP VIEW IF EXISTS android_simpleperf_output;
+CREATE VIEW android_simpleperf_output AS
+SELECT AndroidSimpleperfMetric(
+ 'urgent_ratio', (SELECT sum(value) FROM non_zero_qurg2) / (SELECT sum(value) FROM all_qurg2)
+);
diff --git a/src/trace_processor/metrics/sql/android/android_startup.sql b/src/trace_processor/metrics/sql/android/android_startup.sql
new file mode 100644
index 000000000..fda4553ef
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_startup.sql
@@ -0,0 +1,529 @@
+--
+-- Copyright 2019 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+-- Create the base tables and views containing the launch spans.
+SELECT RUN_METRIC('android/startup/launches.sql');
+SELECT RUN_METRIC('android/startup/hsc.sql');
+SELECT RUN_METRIC('android/process_metadata.sql');
+
+-- Create the base CPU span join table.
+SELECT RUN_METRIC('android/android_cpu_agg.sql');
+
+-- Create a span join safe launches view; since both views
+-- being span joined have an "id" column, we need to rename
+-- the id column for launches to disambiguate the two.
+DROP VIEW IF EXISTS launches_span_join_safe;
+CREATE VIEW launches_span_join_safe AS
+SELECT ts, dur, id AS launch_id
+FROM launches;
+
+-- Span join the CPU table with the launches table to get the
+-- breakdown per-cpu.
+DROP TABLE IF EXISTS cpu_freq_sched_per_thread_per_launch;
+CREATE VIRTUAL TABLE cpu_freq_sched_per_thread_per_launch
+USING SPAN_JOIN(
+ launches_span_join_safe,
+ cpu_freq_sched_per_thread PARTITIONED cpu
+);
+
+SELECT RUN_METRIC('android/cpu_info.sql');
+
+DROP VIEW IF EXISTS mcycles_per_core_type_per_launch;
+CREATE VIEW mcycles_per_core_type_per_launch AS
+SELECT
+ launch_id,
+ IFNULL(core_type_per_cpu.core_type, 'unknown') AS core_type,
+ CAST(SUM(dur * freq_khz / 1000) / 1e9 AS INT) AS mcycles
+FROM cpu_freq_sched_per_thread_per_launch
+LEFT JOIN core_type_per_cpu USING (cpu)
+WHERE utid != 0
+GROUP BY 1, 2;
+
+-- Slices for forked processes. Never present in hot starts.
+-- Prefer this over process start_ts, since the process might have
+-- been preforked.
+DROP VIEW IF EXISTS zygote_fork_slice;
+CREATE VIEW zygote_fork_slice AS
+SELECT slice.ts, slice.dur, STR_SPLIT(slice.name, ": ", 1) AS process_name
+FROM slice WHERE name GLOB 'Start proc: *';
+
+DROP TABLE IF EXISTS zygote_forks_by_id;
+CREATE TABLE zygote_forks_by_id AS
+SELECT
+ launches.id,
+ zygote_fork_slice.ts,
+ zygote_fork_slice.dur
+FROM zygote_fork_slice
+JOIN launches
+ON (launches.ts < zygote_fork_slice.ts
+ AND zygote_fork_slice.ts + zygote_fork_slice.dur < launches.ts_end
+ AND zygote_fork_slice.process_name = launches.package
+);
+
+DROP VIEW IF EXISTS launch_main_threads;
+CREATE VIEW launch_main_threads AS
+SELECT
+ launches.ts AS ts,
+ launches.dur AS dur,
+ launches.id AS launch_id,
+ thread.utid AS utid
+FROM launches
+JOIN launch_processes ON launches.id = launch_processes.launch_id
+JOIN process USING(upid)
+JOIN thread ON (process.upid = thread.upid AND process.pid = thread.tid)
+ORDER BY ts;
+
+DROP VIEW IF EXISTS thread_state_extended;
+CREATE VIEW thread_state_extended AS
+SELECT
+ ts,
+ IIF(dur = -1, (SELECT end_ts FROM trace_bounds), dur) AS dur,
+ utid,
+ state
+FROM thread_state;
+
+DROP TABLE IF EXISTS main_thread_state;
+CREATE VIRTUAL TABLE main_thread_state
+USING SPAN_JOIN(
+ launch_main_threads PARTITIONED utid,
+ thread_state_extended PARTITIONED utid);
+
+DROP VIEW IF EXISTS launch_by_thread_state;
+CREATE VIEW launch_by_thread_state AS
+SELECT launch_id, state, SUM(dur) AS dur
+FROM main_thread_state
+GROUP BY 1, 2;
+
+-- Tracks all main thread process threads.
+DROP VIEW IF EXISTS launch_threads;
+CREATE VIEW launch_threads AS
+SELECT
+ launches.id AS launch_id,
+ launches.ts AS ts,
+ launches.dur AS dur,
+ thread.utid AS utid,
+ thread.name AS thread_name
+FROM launches
+JOIN launch_processes ON (launches.id = launch_processes.launch_id)
+JOIN thread ON (launch_processes.upid = thread.upid);
+
+-- Tracks all slices for the main process threads
+DROP VIEW IF EXISTS main_process_slice_unaggregated;
+CREATE VIEW main_process_slice_unaggregated AS
+SELECT
+ launch_threads.launch_id AS launch_id,
+ launch_threads.utid AS utid,
+ launch_threads.thread_name AS thread_name,
+ slice.id AS slice_id,
+ slice.arg_set_id AS arg_set_id,
+ slice.name AS slice_name,
+ slice.ts AS slice_ts,
+ slice.dur AS slice_dur
+FROM launch_threads
+JOIN thread_track USING (utid)
+JOIN slice ON (
+ slice.track_id = thread_track.id
+ AND slice.ts BETWEEN launch_threads.ts AND launch_threads.ts + launch_threads.dur)
+WHERE slice.name IN (
+ 'PostFork',
+ 'ActivityThreadMain',
+ 'bindApplication',
+ 'activityStart',
+ 'activityRestart',
+ 'activityResume',
+ 'inflate',
+ 'ResourcesManager#getResources',
+ 'binder transaction')
+ OR slice.name GLOB 'performResume:*'
+ OR slice.name GLOB 'performCreate:*'
+ OR slice.name GLOB 'location=* status=* filter=* reason=*'
+ OR slice.name GLOB 'OpenDexFilesFromOat*'
+ OR slice.name GLOB 'VerifyClass*'
+ OR slice.name GLOB 'Choreographer#doFrame*'
+ OR slice.name GLOB 'JIT compiling*'
+ OR slice.name GLOB '*mark sweep GC'
+ OR slice.name GLOB '*concurrent copying GC'
+ OR slice.name GLOB '*semispace GC';
+
+DROP TABLE IF EXISTS main_process_slice;
+CREATE TABLE main_process_slice AS
+SELECT
+ launch_id,
+ CASE
+ WHEN slice_name GLOB 'OpenDexFilesFromOat*' THEN 'OpenDexFilesFromOat'
+ WHEN slice_name GLOB 'VerifyClass*' THEN 'VerifyClass'
+ WHEN slice_name GLOB 'JIT compiling*' THEN 'JIT compiling'
+ WHEN slice_name GLOB '*mark sweep GC' THEN 'GC'
+ WHEN slice_name GLOB '*concurrent copying GC' THEN 'GC'
+ WHEN slice_name GLOB '*semispace GC' THEN 'GC'
+ ELSE slice_name
+ END AS name,
+ AndroidStartupMetric_Slice(
+ 'dur_ns', SUM(slice_dur),
+ 'dur_ms', SUM(slice_dur) / 1e6
+ ) AS slice_proto
+FROM main_process_slice_unaggregated
+GROUP BY 1, 2;
+
+DROP TABLE IF EXISTS report_fully_drawn_per_launch;
+CREATE TABLE report_fully_drawn_per_launch AS
+WITH report_fully_drawn_launch_slices AS (
+ SELECT
+ launches.id AS launch_id,
+ launches.ts AS launch_ts,
+ min(slice.ts) as report_fully_drawn_ts
+ FROM launches
+ JOIN launch_processes ON (launches.id = launch_processes.launch_id)
+ JOIN thread ON (launch_processes.upid = thread.upid)
+ JOIN thread_track USING (utid)
+ JOIN slice ON (
+ slice.track_id = thread_track.id
+ AND slice.ts >= launches.ts)
+ WHERE slice.name GLOB 'reportFullyDrawn*'
+ GROUP BY launches.id
+)
+SELECT
+ launch_id,
+ report_fully_drawn_ts - launch_ts as report_fully_drawn_dur
+FROM report_fully_drawn_launch_slices;
+
+DROP VIEW IF EXISTS to_event_protos;
+CREATE VIEW to_event_protos AS
+SELECT
+ slice.name as slice_name,
+ launch_id,
+ AndroidStartupMetric_Slice(
+ 'dur_ns', slice.ts - l.ts,
+ 'dur_ms', (slice.ts - l.ts) / 1e6
+ ) as slice_proto
+FROM launch_main_threads l
+JOIN thread_track USING (utid)
+JOIN slice ON (
+ slice.track_id = thread_track.id
+ AND slice.ts BETWEEN l.ts AND l.ts + l.dur);
+
+DROP VIEW IF EXISTS gc_slices;
+CREATE VIEW gc_slices AS
+ SELECT
+ slice_ts AS ts,
+ slice_dur AS dur,
+ utid,
+ launch_id
+ FROM main_process_slice_unaggregated
+ WHERE (
+ slice_name GLOB '*mark sweep GC'
+ OR slice_name GLOB '*concurrent copying GC'
+ OR slice_name GLOB '*semispace GC');
+
+DROP TABLE IF EXISTS gc_slices_by_state;
+CREATE VIRTUAL TABLE gc_slices_by_state
+USING SPAN_JOIN(gc_slices PARTITIONED utid, thread_state_extended PARTITIONED utid);
+
+DROP TABLE IF EXISTS gc_slices_by_state_materialized;
+CREATE TABLE gc_slices_by_state_materialized AS
+SELECT launch_id, SUM(dur) as sum_dur
+FROM gc_slices_by_state
+WHERE state = 'Running'
+GROUP BY launch_id;
+
+DROP TABLE IF EXISTS launch_threads_cpu;
+CREATE VIRTUAL TABLE launch_threads_cpu
+USING SPAN_JOIN(launch_threads PARTITIONED utid, thread_state_extended PARTITIONED utid);
+
+DROP TABLE IF EXISTS launch_threads_cpu_materialized;
+CREATE TABLE launch_threads_cpu_materialized AS
+SELECT launch_id, SUM(dur) as sum_dur
+FROM launch_threads_cpu
+WHERE thread_name = 'Jit thread pool' AND state = 'Running'
+GROUP BY launch_id;
+
+DROP TABLE IF EXISTS activity_names_materialized;
+CREATE TABLE activity_names_materialized AS
+SELECT launch_id, slice_name, slice_ts
+FROM main_process_slice_unaggregated
+WHERE (slice_name GLOB 'performResume:*' OR slice_name GLOB 'performCreate:*');
+
+DROP TABLE IF EXISTS jit_compiled_methods_materialized;
+CREATE TABLE jit_compiled_methods_materialized AS
+SELECT
+ launch_id,
+ COUNT(1) as count
+FROM main_process_slice_unaggregated
+WHERE
+ slice_name GLOB 'JIT compiling*'
+ AND thread_name = 'Jit thread pool'
+GROUP BY launch_id;
+
+DROP TABLE IF EXISTS long_binder_transactions;
+CREATE TABLE long_binder_transactions AS
+SELECT
+ s.slice_id,
+ s.launch_id,
+ s.slice_dur,
+ s.thread_name,
+ EXTRACT_ARG(s.arg_set_id, 'destination name') AS destination_thread,
+ process.name AS destination_process,
+ EXTRACT_ARG(s.arg_set_id, 'flags') AS flags,
+ EXTRACT_ARG(s.arg_set_id, 'code') AS code,
+ EXTRACT_ARG(s.arg_set_id, 'data_size') AS data_size
+FROM
+ main_process_slice_unaggregated s
+JOIN process ON (EXTRACT_ARG(s.arg_set_id, 'destination process') = process.pid)
+WHERE
+ s.slice_name = 'binder transaction' AND
+ s.slice_dur >= 5e7;
+
+SELECT CREATE_FUNCTION(
+ 'MAIN_PROCESS_SLICE_PROTO(launch_id LONG, name STRING)',
+ 'PROTO', '
+ SELECT slice_proto
+ FROM main_process_slice s
+ WHERE s.launch_id = $launch_id AND name GLOB $name
+ LIMIT 1
+ ');
+
+DROP VIEW IF EXISTS startup_view;
+CREATE VIEW startup_view AS
+SELECT
+ AndroidStartupMetric_Startup(
+ 'startup_id', launches.id,
+ 'package_name', launches.package,
+ 'process_name', (
+ SELECT p.name
+ FROM launch_processes lp
+ JOIN process p USING (upid)
+ WHERE lp.launch_id = launches.id
+ LIMIT 1
+ ),
+ 'process', (
+ SELECT m.metadata
+ FROM process_metadata m
+ JOIN launch_processes p USING (upid)
+ WHERE p.launch_id = launches.id
+ LIMIT 1
+ ),
+ 'activities', (
+ SELECT RepeatedField(AndroidStartupMetric_Activity(
+ 'name', (SELECT STR_SPLIT(s.slice_name, ':', 1)),
+ 'method', (SELECT STR_SPLIT(s.slice_name, ':', 0)),
+ 'ts_method_start', s.slice_ts
+ ))
+ FROM activity_names_materialized s
+ WHERE s.launch_id = launches.id
+ ),
+ 'long_binder_transactions', (
+ SELECT RepeatedField(AndroidStartupMetric_BinderTransaction(
+ 'duration', AndroidStartupMetric_Slice(
+ 'dur_ns', lbt.slice_dur,
+ 'dur_ms', lbt.slice_dur / 1e6
+ ),
+ 'thread', lbt.thread_name,
+ 'destination_thread', lbt.destination_thread,
+ 'destination_process', lbt.destination_process,
+ 'flags', lbt.flags,
+ 'code', lbt.code,
+ 'data_size', lbt.data_size
+ ))
+ FROM long_binder_transactions lbt
+ WHERE lbt.launch_id = launches.id
+ ),
+ 'zygote_new_process', EXISTS(SELECT TRUE FROM zygote_forks_by_id WHERE id = launches.id),
+ 'activity_hosting_process_count', (
+ SELECT COUNT(1) FROM launch_processes p
+ WHERE p.launch_id = launches.id
+ ),
+ 'event_timestamps', AndroidStartupMetric_EventTimestamps(
+ 'intent_received', launches.ts,
+ 'first_frame', launches.ts_end
+ ),
+ 'to_first_frame', AndroidStartupMetric_ToFirstFrame(
+ 'dur_ns', launches.dur,
+ 'dur_ms', launches.dur / 1e6,
+ 'main_thread_by_task_state', AndroidStartupMetric_TaskStateBreakdown(
+ 'running_dur_ns', IFNULL(
+ (
+ SELECT dur FROM launch_by_thread_state l
+ WHERE l.launch_id = launches.id AND state = 'Running'
+ ), 0),
+ 'runnable_dur_ns', IFNULL(
+ (
+ SELECT dur FROM launch_by_thread_state l
+ WHERE l.launch_id = launches.id AND state = 'R'
+ ), 0),
+ 'uninterruptible_sleep_dur_ns', IFNULL(
+ (
+ SELECT dur FROM launch_by_thread_state l
+ WHERE l.launch_id = launches.id AND (state = 'D' or state = 'DK')
+ ), 0),
+ 'interruptible_sleep_dur_ns', IFNULL(
+ (
+ SELECT dur FROM launch_by_thread_state l
+ WHERE l.launch_id = launches.id AND state = 'S'
+ ), 0)
+ ),
+ 'mcycles_by_core_type', AndroidStartupMetric_McyclesByCoreType(
+ 'little', (
+ SELECT mcycles
+ FROM mcycles_per_core_type_per_launch m
+ WHERE m.launch_id = launches.id AND m.core_type = 'little'
+ ),
+ 'big', (
+ SELECT mcycles
+ FROM mcycles_per_core_type_per_launch m
+ WHERE m.launch_id = launches.id AND m.core_type = 'big'
+ ),
+ 'bigger', (
+ SELECT mcycles
+ FROM mcycles_per_core_type_per_launch m
+ WHERE m.launch_id = launches.id AND m.core_type = 'bigger'
+ ),
+ 'unknown', (
+ SELECT mcycles
+ FROM mcycles_per_core_type_per_launch m
+ WHERE m.launch_id = launches.id AND m.core_type = 'unknown'
+ )
+ ),
+ 'to_post_fork', (
+ SELECT slice_proto
+ FROM to_event_protos p
+ WHERE p.launch_id = launches.id AND slice_name = 'PostFork'
+ ),
+ 'to_activity_thread_main', (
+ SELECT slice_proto
+ FROM to_event_protos p
+ WHERE p.launch_id = launches.id AND slice_name = 'ActivityThreadMain'
+ ),
+ 'to_bind_application', (
+ SELECT slice_proto
+ FROM to_event_protos p
+ WHERE p.launch_id = launches.id AND slice_name = 'bindApplication'
+ ),
+ 'other_processes_spawned_count', (
+ SELECT COUNT(1) FROM process
+ WHERE (process.name IS NULL OR process.name != launches.package)
+ AND process.start_ts BETWEEN launches.ts AND launches.ts + launches.dur
+ ),
+ 'time_activity_manager', (
+ SELECT AndroidStartupMetric_Slice(
+ 'dur_ns', l.ts - launches.ts,
+ 'dur_ms', (l.ts - launches.ts) / 1e6
+ )
+ FROM launching_events l
+ WHERE l.ts BETWEEN launches.ts AND launches.ts + launches.dur
+ ),
+ 'time_post_fork', MAIN_PROCESS_SLICE_PROTO(launches.id, 'PostFork'),
+ 'time_activity_thread_main', MAIN_PROCESS_SLICE_PROTO(launches.id, 'ActivityThreadMain'),
+ 'time_bind_application', MAIN_PROCESS_SLICE_PROTO(launches.id, 'bindApplication'),
+ 'time_activity_start', MAIN_PROCESS_SLICE_PROTO(launches.id, 'activityStart'),
+ 'time_activity_resume', MAIN_PROCESS_SLICE_PROTO(launches.id, 'activityResume'),
+ 'time_activity_restart', MAIN_PROCESS_SLICE_PROTO(launches.id, 'activityRestart'),
+ 'time_choreographer', MAIN_PROCESS_SLICE_PROTO(launches.id, 'Choreographer#doFrame*'),
+ 'time_inflate', MAIN_PROCESS_SLICE_PROTO(launches.id, 'inflate'),
+ 'time_get_resources', MAIN_PROCESS_SLICE_PROTO(launches.id, 'ResourcesManager#getResources'),
+ 'time_dex_open', MAIN_PROCESS_SLICE_PROTO(launches.id, 'OpenDexFilesFromOat'),
+ 'time_verify_class', MAIN_PROCESS_SLICE_PROTO(launches.id, 'VerifyClass'),
+ 'time_gc_total', MAIN_PROCESS_SLICE_PROTO(launches.id, 'GC'),
+ 'time_before_start_process', (
+ SELECT AndroidStartupMetric_Slice(
+ 'dur_ns', ts - launches.ts,
+ 'dur_ms', (ts - launches.ts) / 1e6
+ )
+ FROM zygote_forks_by_id z
+ WHERE z.id = launches.id
+ ),
+ 'time_during_start_process', (
+ SELECT AndroidStartupMetric_Slice(
+ 'dur_ns', dur,
+ 'dur_ms', dur / 1e6
+ )
+ FROM zygote_forks_by_id z
+ WHERE z.id = launches.id
+ ),
+ 'jit_compiled_methods', (
+ SELECT count
+ FROM jit_compiled_methods_materialized s
+ WHERE s.launch_id = launches.id
+ ),
+ 'time_jit_thread_pool_on_cpu', (
+ SELECT
+ NULL_IF_EMPTY(AndroidStartupMetric_Slice(
+ 'dur_ns', sum_dur,
+ 'dur_ms', sum_dur / 1e6
+ ))
+ FROM launch_threads_cpu_materialized
+ WHERE launch_id = launches.id
+ ),
+ 'time_gc_on_cpu', (
+ SELECT
+ NULL_IF_EMPTY(AndroidStartupMetric_Slice(
+ 'dur_ns', sum_dur,
+ 'dur_ms', sum_dur / 1e6
+ ))
+ FROM gc_slices_by_state_materialized
+ WHERE launch_id = launches.id
+ )
+ ),
+ 'hsc', (
+ SELECT NULL_IF_EMPTY(AndroidStartupMetric_HscMetrics(
+ 'full_startup', (
+ SELECT AndroidStartupMetric_Slice(
+ 'dur_ns', h.ts_total,
+ 'dur_ms', h.ts_total / 1e6
+ )
+ FROM hsc_based_startup_times h
+ WHERE h.id = launches.id
+ )
+ ))
+ ),
+ 'report_fully_drawn', (
+ SELECT NULL_IF_EMPTY(AndroidStartupMetric_Slice(
+ 'dur_ns', report_fully_drawn_dur,
+ 'dur_ms', report_fully_drawn_dur / 1e6
+ ))
+ FROM report_fully_drawn_per_launch r
+ WHERE r.launch_id = launches.id
+ ),
+ 'optimization_status',(
+ SELECT RepeatedField(AndroidStartupMetric_OptimizationStatus(
+ 'location', SUBSTR(STR_SPLIT(name, ' status=', 0), LENGTH('location=') + 1),
+ 'odex_status', STR_SPLIT(STR_SPLIT(name, ' status=', 1), ' filter=', 0),
+ 'compilation_filter', STR_SPLIT(STR_SPLIT(name, ' filter=', 1), ' reason=', 0),
+ 'compilation_reason', STR_SPLIT(name, ' reason=', 1)
+ ))
+ FROM main_process_slice s
+ WHERE name GLOB 'location=* status=* filter=* reason=*'
+ )
+ ) as startup
+FROM launches;
+
+DROP VIEW IF EXISTS android_startup_event;
+CREATE VIEW android_startup_event AS
+SELECT
+ 'slice' as track_type,
+ 'Android App Startups' as track_name,
+ l.ts as ts,
+ l.dur as dur,
+ l.package as slice_name
+FROM launches l;
+
+DROP VIEW IF EXISTS android_startup_output;
+CREATE VIEW android_startup_output AS
+SELECT
+ AndroidStartupMetric(
+ 'startup', (
+ SELECT RepeatedField(startup) FROM startup_view
+ )
+ );
diff --git a/src/trace_processor/metrics/sql/android/android_surfaceflinger.sql b/src/trace_processor/metrics/sql/android/android_surfaceflinger.sql
new file mode 100644
index 000000000..b00e49162
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_surfaceflinger.sql
@@ -0,0 +1,103 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+SELECT RUN_METRIC(
+ 'android/frame_missed.sql',
+ 'track_name', 'PrevFrameMissed',
+ 'output', 'frame_missed'
+);
+SELECT RUN_METRIC(
+ 'android/frame_missed.sql',
+ 'track_name', 'PrevHwcFrameMissed',
+ 'output', 'hwc_frame_missed'
+);
+SELECT RUN_METRIC(
+ 'android/frame_missed.sql',
+ 'track_name', 'PrevGpuFrameMissed',
+ 'output', 'gpu_frame_missed'
+);
+
+DROP VIEW IF EXISTS android_surfaceflinger_event;
+CREATE VIEW android_surfaceflinger_event AS
+SELECT
+ 'slice' AS track_type,
+ 'Android Missed Frames' AS track_name,
+ ts,
+ dur,
+ 'Frame missed' AS slice_name
+FROM frame_missed
+WHERE value = 1 AND ts IS NOT NULL;
+
+DROP VIEW IF EXISTS surfaceflinger_track;
+CREATE VIEW surfaceflinger_track AS
+SELECT tr.id AS track_id, t.utid, t.tid
+FROM process p JOIN thread t ON p.upid = t.upid
+ JOIN thread_track tr ON tr.utid = t.utid
+WHERE p.cmdline='/system/bin/surfaceflinger';
+
+DROP VIEW IF EXISTS gpu_waiting_start;
+CREATE VIEW gpu_waiting_start AS
+SELECT
+ CAST(SUBSTR(s.name, 28) AS UINT32) AS fence_id,
+ ts AS start_ts
+FROM slices s JOIN surfaceflinger_track t ON s.track_id = t.track_id
+WHERE s.name GLOB 'Trace GPU completion fence *';
+
+DROP VIEW IF EXISTS gpu_waiting_end;
+CREATE VIEW gpu_waiting_end AS
+SELECT
+ CAST(SUBSTR(s.name, 28) AS UINT32) AS fence_id,
+ dur,
+ ts+dur AS end_ts
+FROM slices s JOIN surfaceflinger_track t ON s.track_id = t.track_id
+WHERE s.name GLOB 'waiting for GPU completion *';
+
+DROP VIEW IF EXISTS gpu_waiting_span;
+CREATE VIEW gpu_waiting_span AS
+SELECT
+ fence_id,
+ ts,
+ dur
+FROM (
+ SELECT
+ fence_id,
+ ts,
+ LEAD(ts) OVER (ORDER BY fence_id, event_type) - ts AS dur,
+ LEAD(fence_id) OVER (ORDER BY fence_id, event_type) AS next_fence_id,
+ event_type
+ FROM (
+ SELECT fence_id, start_ts AS ts, 0 AS event_type FROM gpu_waiting_start
+ UNION
+ SELECT fence_id, end_ts AS ts, 1 AS event_type FROM gpu_waiting_end
+ )
+ ORDER BY fence_id, event_type
+)
+WHERE event_type = 0 AND fence_id = next_fence_id;
+
+DROP VIEW IF EXISTS android_surfaceflinger_output;
+CREATE VIEW android_surfaceflinger_output AS
+SELECT
+ AndroidSurfaceflingerMetric(
+ 'missed_frames', (SELECT COUNT(1) FROM frame_missed WHERE value=1),
+ 'missed_hwc_frames', (SELECT COUNT(1) FROM hwc_frame_missed WHERE value=1),
+ 'missed_gpu_frames', (SELECT COUNT(1) FROM gpu_frame_missed WHERE value=1),
+ 'missed_frame_rate', (SELECT AVG(value) FROM frame_missed),
+ 'missed_hwc_frame_rate', (SELECT AVG(value) FROM hwc_frame_missed),
+ 'missed_gpu_frame_rate', (SELECT AVG(value) FROM gpu_frame_missed),
+ 'gpu_invocations', (SELECT COUNT(1) FROM gpu_waiting_end),
+ 'avg_gpu_waiting_dur_ms', (SELECT AVG(dur)/1e6 FROM gpu_waiting_span),
+ 'total_non_empty_gpu_waiting_dur_ms',
+ (SELECT SUM(dur)/1e6 FROM gpu_waiting_end)
+ );
diff --git a/src/trace_processor/metrics/sql/android/android_sysui_cuj.sql b/src/trace_processor/metrics/sql/android/android_sysui_cuj.sql
new file mode 100644
index 000000000..9785e32cd
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_sysui_cuj.sql
@@ -0,0 +1,487 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+SELECT RUN_METRIC('android/process_metadata.sql');
+
+DROP TABLE IF EXISTS android_sysui_cuj_last_cuj;
+CREATE TABLE android_sysui_cuj_last_cuj AS
+ SELECT
+ process.name AS name,
+ process.upid AS upid,
+ process_metadata.metadata AS process_metadata,
+ SUBSTR(slice.name, 3, LENGTH(slice.name) - 3) AS cuj_name,
+ ts AS ts_start,
+ ts + dur AS ts_end,
+ dur AS dur
+ FROM slice
+ JOIN process_track ON slice.track_id = process_track.id
+ JOIN process USING (upid)
+ JOIN process_metadata USING (upid)
+ WHERE
+ slice.name GLOB 'J<*>'
+ -- Filter out CUJs that are <4ms long - assuming CUJ was cancelled.
+ AND slice.dur > 4e6
+ AND (
+ process.name GLOB 'com.google.android*'
+ OR process.name GLOB 'com.android.*')
+ ORDER BY ts desc
+ LIMIT 1;
+
+SELECT RUN_METRIC(
+ 'android/android_hwui_threads.sql',
+ 'table_name_prefix', 'android_sysui_cuj',
+ 'process_allowlist_table', 'android_sysui_cuj_last_cuj');
+
+DROP TABLE IF EXISTS android_sysui_cuj_do_frame_slices_in_cuj;
+CREATE TABLE android_sysui_cuj_do_frame_slices_in_cuj AS
+SELECT
+ slices.*,
+ lag(slices.ts_end) OVER (ORDER BY vsync ASC) as ts_prev_frame_end
+FROM android_sysui_cuj_do_frame_slices slices
+JOIN android_sysui_cuj_last_cuj last_cuj
+ON ts + slices.dur >= last_cuj.ts_start AND ts <= last_cuj.ts_end;
+
+DROP TABLE IF EXISTS android_sysui_cuj_vsync_boundaries;
+CREATE TABLE android_sysui_cuj_vsync_boundaries AS
+SELECT MIN(vsync) as vsync_min, MAX(vsync) as vsync_max
+FROM android_sysui_cuj_do_frame_slices_in_cuj;
+
+DROP TABLE IF EXISTS android_sysui_cuj_frame_expected_timeline_events;
+CREATE TABLE android_sysui_cuj_frame_expected_timeline_events AS
+ SELECT
+ CAST(e.name as INTEGER) as vsync,
+ e.ts as ts_expected,
+ e.dur as dur_expected,
+ MIN(a.ts) as ts_actual_min,
+ MAX(a.ts + a.dur) as ts_end_actual_max
+ FROM android_sysui_cuj_last_cuj cuj
+ JOIN expected_frame_timeline_slice e USING (upid)
+ JOIN android_sysui_cuj_vsync_boundaries vsync
+ ON CAST(e.name as INTEGER) >= vsync.vsync_min
+ AND CAST(e.name as INTEGER) <= vsync.vsync_max
+ JOIN actual_frame_timeline_slice a ON e.upid = a.upid AND e.name = a.name
+ GROUP BY e.name, e.ts, e.dur;
+
+DROP TABLE IF EXISTS android_sysui_cuj_frame_timeline_events;
+CREATE TABLE android_sysui_cuj_frame_timeline_events AS
+ SELECT
+ actual.layer_name as layer_name,
+ CAST(actual.name as INTEGER) as vsync,
+ actual.ts as ts_actual,
+ actual.dur as dur_actual,
+ actual.jank_type GLOB '*App Deadline Missed*' as app_missed,
+ actual.jank_type,
+ actual.on_time_finish
+ FROM android_sysui_cuj_last_cuj cuj
+ JOIN actual_frame_timeline_slice actual USING (upid)
+ JOIN android_sysui_cuj_vsync_boundaries vsync
+ ON CAST(actual.name as INTEGER) >= vsync.vsync_min
+ AND CAST(actual.name as INTEGER) <= vsync.vsync_max;
+
+-- Adjust the timestamp when we consider the work on a given frame started,
+-- by looking at the time the previous frame finished on the main thread
+-- and the timing from the actual timeline.
+-- This is to detect cases where we started doFrame late due to some other work
+-- occupying the main thread.
+DROP TABLE IF EXISTS android_sysui_cuj_do_frame_slices_in_cuj_adjusted;
+CREATE TABLE android_sysui_cuj_do_frame_slices_in_cuj_adjusted AS
+SELECT
+ slices.*,
+ CASE
+ WHEN fte.ts_expected IS NULL
+ THEN ts
+ ELSE MAX(COALESCE(slices.ts_prev_frame_end, 0), fte.ts_expected)
+ END as ts_adjusted
+FROM android_sysui_cuj_do_frame_slices_in_cuj slices
+LEFT JOIN android_sysui_cuj_frame_expected_timeline_events fte
+ ON slices.vsync = fte.vsync
+-- In rare cases there is a clock drift after device suspends
+-- This may cause the actual/expected timeline to be misaligned with the rest
+-- of the trace for a short period.
+-- Do not use the timelines if it seems that this happened.
+AND slices.ts >= fte.ts_actual_min - 1e6 AND slices.ts <= fte.ts_end_actual_max;
+
+DROP TABLE IF EXISTS android_sysui_cuj_ts_boundaries;
+CREATE TABLE android_sysui_cuj_ts_boundaries AS
+SELECT ts, ts_end - ts as dur, ts_end FROM (
+SELECT
+(SELECT ts_adjusted FROM android_sysui_cuj_do_frame_slices_in_cuj_adjusted ORDER BY ts ASC LIMIT 1) as ts,
+(SELECT ts FROM android_sysui_cuj_do_frame_slices_in_cuj ORDER BY ts DESC LIMIT 1) +
+(SELECT dur_actual FROM android_sysui_cuj_frame_timeline_events ORDER BY vsync DESC LIMIT 1) as ts_end);
+
+DROP VIEW IF EXISTS android_sysui_cuj_thread;
+CREATE VIEW android_sysui_cuj_thread AS
+SELECT
+ process.name as process_name,
+ thread.utid,
+ thread.name
+FROM thread
+JOIN android_sysui_cuj_last_cuj process USING (upid);
+
+DROP VIEW IF EXISTS android_sysui_cuj_slices_in_cuj;
+CREATE VIEW android_sysui_cuj_slices_in_cuj AS
+SELECT
+ process_name,
+ thread.utid,
+ thread.name as thread_name,
+ slices.*,
+ slices.ts + slices.dur AS ts_end
+FROM slices
+JOIN thread_track ON slices.track_id = thread_track.id
+JOIN android_sysui_cuj_thread thread USING (utid)
+JOIN android_sysui_cuj_ts_boundaries cuj_boundaries
+ON slices.ts + slices.dur >= cuj_boundaries.ts AND slices.ts <= cuj_boundaries.ts_end
+WHERE slices.dur > 0;
+
+DROP TABLE IF EXISTS android_sysui_cuj_main_thread_slices_in_cuj;
+CREATE TABLE android_sysui_cuj_main_thread_slices_in_cuj AS
+SELECT slices.* FROM android_sysui_cuj_main_thread_slices slices
+JOIN android_sysui_cuj_ts_boundaries cuj_boundaries
+ON slices.ts + slices.dur >= cuj_boundaries.ts AND slices.ts <= cuj_boundaries.ts_end;
+
+DROP TABLE IF EXISTS android_sysui_cuj_render_thread_slices_in_cuj;
+CREATE TABLE android_sysui_cuj_render_thread_slices_in_cuj AS
+SELECT slices.* FROM android_sysui_cuj_render_thread_slices slices
+JOIN android_sysui_cuj_ts_boundaries cuj_boundaries
+ON slices.ts >= cuj_boundaries.ts AND slices.ts <= cuj_boundaries.ts_end;
+
+DROP TABLE IF EXISTS android_sysui_cuj_draw_frame_slices_in_cuj;
+CREATE TABLE android_sysui_cuj_draw_frame_slices_in_cuj AS
+SELECT slices.* FROM android_sysui_cuj_draw_frame_slices slices
+JOIN android_sysui_cuj_ts_boundaries cuj_boundaries
+ON slices.ts >= cuj_boundaries.ts AND slices.ts <= cuj_boundaries.ts_end;
+
+DROP TABLE IF EXISTS android_sysui_cuj_hwc_release_slices_in_cuj;
+CREATE TABLE android_sysui_cuj_hwc_release_slices_in_cuj AS
+SELECT slices.* FROM android_sysui_cuj_hwc_release_slices slices
+JOIN android_sysui_cuj_ts_boundaries cuj_boundaries
+ON slices.ts >= cuj_boundaries.ts AND slices.ts <= cuj_boundaries.ts_end;
+
+DROP TABLE IF EXISTS android_sysui_cuj_gpu_completion_slices_in_cuj;
+CREATE TABLE android_sysui_cuj_gpu_completion_slices_in_cuj AS
+SELECT slices.* FROM android_sysui_cuj_gpu_completion_slices slices
+JOIN android_sysui_cuj_ts_boundaries cuj_boundaries
+ON slices.ts >= cuj_boundaries.ts AND slices.ts <= cuj_boundaries.ts_end;
+
+DROP TABLE IF EXISTS android_sysui_cuj_jit_slices;
+CREATE TABLE android_sysui_cuj_jit_slices AS
+SELECT *
+FROM android_sysui_cuj_slices_in_cuj
+WHERE thread_name GLOB 'Jit thread pool*'
+AND name GLOB 'JIT compiling*'
+AND parent_id IS NULL;
+
+DROP TABLE IF EXISTS android_sysui_cuj_frames;
+CREATE TABLE android_sysui_cuj_frames AS
+ WITH gcs_to_rt_match AS (
+ SELECT
+ rts.ts,
+ CASE
+ WHEN rtfence.name GLOB 'GPU completion fence *'
+ THEN CAST(STR_SPLIT(rtfence.name, ' ', 3) AS INTEGER)
+ WHEN rtfence.name GLOB 'Trace GPU completion fence *'
+ THEN CAST(STR_SPLIT(rtfence.name, ' ', 4) AS INTEGER)
+ ELSE NULL
+ END AS idx
+ FROM android_sysui_cuj_render_thread_slices_in_cuj rts
+ JOIN descendant_slice(rts.id) rtfence ON rtfence.name GLOB '*GPU completion fence*'
+ -- dispatchFrameCallbacks might be seen in case of
+ -- drawing that happens on RT only (e.g. ripple effect)
+ WHERE (rts.name GLOB 'DrawFrame*' OR rts.name = 'dispatchFrameCallbacks')
+ )
+ SELECT
+ ROW_NUMBER() OVER (ORDER BY mts.ts) AS frame_number,
+ mts.vsync as vsync,
+ -- Main thread timings
+ mts.ts_adjusted as ts_main_thread_start,
+ mts.ts_end as ts_main_thread_end,
+ mts.ts_end - mts.ts_adjusted AS dur_main_thread,
+ -- RenderThread timings
+ MIN(rts.ts) AS ts_render_thread_start,
+ MAX(rts.ts_end) AS ts_render_thread_end,
+ SUM(rts.dur) AS dur_render_thread,
+ -- HWC and GPU
+ SUM(gcs.ts_end - MAX(COALESCE(hwc.ts_end, 0), gcs.ts)) as dur_gcs,
+ -- Overall frame timings
+ COALESCE(MAX(gcs.ts_end), MAX(rts.ts_end)) AS ts_frame_end,
+ COALESCE(MAX(gcs.ts_end), MAX(rts.ts_end)) - mts.ts_adjusted AS dur_frame,
+ MAX(gcs_rt.idx) IS NOT NULL as drew_anything
+ -- Match main thread doFrame with RT DrawFrame and optional GPU Completion
+ FROM android_sysui_cuj_do_frame_slices_in_cuj_adjusted mts
+ JOIN android_sysui_cuj_draw_frame_slices_in_cuj rts
+ ON mts.vsync = rts.vsync
+ LEFT JOIN gcs_to_rt_match gcs_rt ON gcs_rt.ts = rts.ts
+ LEFT JOIN android_sysui_cuj_gpu_completion_slices_in_cuj gcs USING(idx)
+ LEFT JOIN android_sysui_cuj_hwc_release_slices_in_cuj hwc USING (idx)
+ GROUP BY mts.vsync, mts.ts_adjusted, mts.ts_end
+ HAVING drew_anything;
+
+DROP TABLE IF EXISTS android_sysui_cuj_missed_frames;
+CREATE TABLE android_sysui_cuj_missed_frames AS
+ SELECT
+ f.*,
+ (SELECT MAX(fte.app_missed)
+ FROM android_sysui_cuj_frame_timeline_events fte
+ WHERE f.vsync = fte.vsync
+ AND fte.on_time_finish = 0) as app_missed
+ FROM android_sysui_cuj_frames f;
+
+DROP VIEW IF EXISTS android_sysui_cuj_frame_main_thread_bounds;
+CREATE VIEW android_sysui_cuj_frame_main_thread_bounds AS
+SELECT frame_number, ts_main_thread_start as ts, dur_main_thread as dur
+FROM android_sysui_cuj_missed_frames
+WHERE app_missed;
+
+DROP VIEW IF EXISTS android_sysui_cuj_main_thread_state_data;
+CREATE VIEW android_sysui_cuj_main_thread_state_data AS
+SELECT * FROM thread_state
+WHERE utid = (SELECT utid FROM android_sysui_cuj_main_thread);
+
+DROP TABLE IF EXISTS android_sysui_cuj_main_thread_state_vt;
+CREATE VIRTUAL TABLE android_sysui_cuj_main_thread_state_vt
+USING span_left_join(android_sysui_cuj_frame_main_thread_bounds, android_sysui_cuj_main_thread_state_data PARTITIONED utid);
+
+DROP TABLE IF EXISTS android_sysui_cuj_main_thread_state;
+CREATE TABLE android_sysui_cuj_main_thread_state AS
+ SELECT
+ frame_number,
+ state,
+ io_wait AS io_wait,
+ SUM(dur) AS dur
+ FROM android_sysui_cuj_main_thread_state_vt
+ GROUP BY frame_number, state, io_wait
+ HAVING dur > 0;
+
+DROP VIEW IF EXISTS android_sysui_cuj_frame_render_thread_bounds;
+CREATE VIEW android_sysui_cuj_frame_render_thread_bounds AS
+SELECT frame_number, ts_render_thread_start as ts, dur_render_thread as dur
+FROM android_sysui_cuj_missed_frames
+WHERE app_missed;
+
+DROP VIEW IF EXISTS android_sysui_cuj_render_thread_state_data;
+CREATE VIEW android_sysui_cuj_render_thread_state_data AS
+SELECT * FROM thread_state
+WHERE utid in (SELECT utid FROM android_sysui_cuj_render_thread);
+
+DROP TABLE IF EXISTS android_sysui_cuj_render_thread_state_vt;
+CREATE VIRTUAL TABLE android_sysui_cuj_render_thread_state_vt
+USING span_left_join(android_sysui_cuj_frame_render_thread_bounds, android_sysui_cuj_render_thread_state_data PARTITIONED utid);
+
+DROP TABLE IF EXISTS android_sysui_cuj_render_thread_state;
+CREATE TABLE android_sysui_cuj_render_thread_state AS
+ SELECT
+ frame_number,
+ state,
+ io_wait AS io_wait,
+ SUM(dur) AS dur
+ FROM android_sysui_cuj_render_thread_state_vt
+ GROUP BY frame_number, state, io_wait
+ HAVING dur > 0;
+
+DROP TABLE IF EXISTS android_sysui_cuj_main_thread_binder;
+CREATE TABLE android_sysui_cuj_main_thread_binder AS
+ SELECT
+ f.frame_number,
+ SUM(mts.dur) AS dur,
+ COUNT(*) AS call_count
+ FROM android_sysui_cuj_missed_frames f
+ JOIN android_sysui_cuj_main_thread_slices_in_cuj mts
+ ON mts.ts >= f.ts_main_thread_start AND mts.ts < f.ts_main_thread_end
+ WHERE mts.name = 'binder transaction'
+ AND f.app_missed
+ GROUP BY f.frame_number;
+
+DROP TABLE IF EXISTS android_sysui_cuj_sf_jank_causes;
+CREATE TABLE android_sysui_cuj_sf_jank_causes AS
+ WITH RECURSIVE split_jank_type(frame_number, jank_cause, remainder) AS (
+ SELECT f.frame_number, "", fte.jank_type || ","
+ FROM android_sysui_cuj_frames f
+ JOIN android_sysui_cuj_frame_timeline_events fte ON f.vsync = fte.vsync
+ UNION ALL SELECT
+ frame_number,
+ STR_SPLIT(remainder, ",", 0) AS jank_cause,
+ TRIM(SUBSTR(remainder, INSTR(remainder, ",") + 1)) AS remainder
+ FROM split_jank_type
+ WHERE remainder <> "")
+ SELECT frame_number, jank_cause
+ FROM split_jank_type
+ WHERE jank_cause NOT IN ('', 'App Deadline Missed', 'None', 'Buffer Stuffing')
+ ORDER BY frame_number ASC;
+
+DROP TABLE IF EXISTS android_sysui_cuj_missed_frames_hwui_times;
+CREATE TABLE android_sysui_cuj_missed_frames_hwui_times AS
+SELECT
+ *,
+ ts_main_thread_start AS ts,
+ ts_render_thread_end - ts_main_thread_start AS dur
+FROM android_sysui_cuj_missed_frames;
+
+DROP TABLE IF EXISTS android_sysui_cuj_jit_slices_join_table;
+CREATE VIRTUAL TABLE android_sysui_cuj_jit_slices_join_table
+USING span_join(android_sysui_cuj_missed_frames_hwui_times partitioned frame_number, android_sysui_cuj_jit_slices);
+
+DROP TABLE IF EXISTS android_sysui_cuj_jank_causes;
+CREATE TABLE android_sysui_cuj_jank_causes AS
+ SELECT
+ frame_number,
+ 'RenderThread - long shader_compile' AS jank_cause
+ FROM android_sysui_cuj_missed_frames f
+ JOIN android_sysui_cuj_render_thread_slices_in_cuj rts
+ ON rts.ts >= f.ts_render_thread_start AND rts.ts < f.ts_render_thread_end
+ WHERE rts.name = 'shader_compile'
+ AND f.app_missed
+ AND rts.dur > 8e6
+
+ UNION ALL
+ SELECT
+ frame_number,
+ 'RenderThread - long flush layers' AS jank_cause
+ FROM android_sysui_cuj_missed_frames f
+ JOIN android_sysui_cuj_render_thread_slices_in_cuj rts
+ ON rts.ts >= f.ts_render_thread_start AND rts.ts < f.ts_render_thread_end
+ WHERE rts.name = 'flush layers'
+ AND rts.dur > 8e6
+ AND f.app_missed
+
+ UNION ALL
+ SELECT
+ frame_number,
+ 'MainThread - IO wait time' AS jank_cause
+ FROM android_sysui_cuj_main_thread_state
+ WHERE
+ ((state = 'D' OR state = 'DK') AND io_wait)
+ OR (state = 'DK' AND io_wait IS NULL)
+ GROUP BY frame_number
+ HAVING SUM(dur) > 8e6
+
+ UNION ALL
+ SELECT
+ frame_number,
+ 'MainThread - scheduler' AS jank_cause
+ FROM android_sysui_cuj_main_thread_state
+ WHERE (state = 'R' OR state = 'R+')
+ GROUP BY frame_number
+ HAVING SUM(dur) > 8e6
+ AND SUM(dur) > (
+ SELECT 0.4 * dur_main_thread
+ FROM android_sysui_cuj_frames fs
+ WHERE fs.frame_number = android_sysui_cuj_main_thread_state.frame_number)
+
+ UNION ALL
+ SELECT
+ frame_number,
+ 'RenderThread - IO wait time' AS jank_cause
+ FROM android_sysui_cuj_render_thread_state
+ WHERE
+ ((state = 'D' OR state = 'DK') AND io_wait)
+ OR (state = 'DK' AND io_wait IS NULL)
+ GROUP BY frame_number
+ HAVING SUM(dur) > 8e6
+
+ UNION ALL
+ SELECT
+ frame_number,
+ 'RenderThread - scheduler' AS jank_cause
+ FROM android_sysui_cuj_render_thread_state
+ WHERE (state = 'R' OR state = 'R+')
+ GROUP BY frame_number
+ HAVING SUM(dur) > 8e6
+ AND SUM(dur) > (
+ SELECT 0.4 * dur_render_thread
+ FROM android_sysui_cuj_frames fs
+ WHERE fs.frame_number = android_sysui_cuj_render_thread_state.frame_number)
+
+ UNION ALL
+ SELECT
+ frame_number,
+ 'MainThread - binder transaction time' AS jank_cause
+ FROM android_sysui_cuj_main_thread_binder
+ WHERE dur > 8e6
+
+ UNION ALL
+ SELECT
+ frame_number,
+ 'MainThread - binder calls count' AS jank_cause
+ FROM android_sysui_cuj_main_thread_binder
+ WHERE call_count > 8
+
+ UNION ALL
+ SELECT
+ frame_number,
+ 'GPU completion - long completion time' AS jank_cause
+ FROM android_sysui_cuj_missed_frames f
+ WHERE dur_gcs > 8e6
+ AND app_missed
+
+ UNION ALL
+ SELECT
+ frame_number,
+ 'Long running time' as jank_cause
+ FROM android_sysui_cuj_main_thread_state mts
+ JOIN android_sysui_cuj_render_thread_state rts USING(frame_number)
+ WHERE
+ mts.state = 'Running'
+ AND rts.state = 'Running'
+ AND mts.dur + rts.dur > 15e6
+
+ UNION ALL
+ SELECT
+ f.frame_number,
+ 'JIT compiling' as jank_cause
+ FROM android_sysui_cuj_missed_frames f
+ JOIN android_sysui_cuj_jit_slices_join_table jit USING (frame_number)
+ WHERE f.app_missed
+ GROUP BY f.frame_number
+ HAVING SUM(jit.dur) > 8e6
+
+ UNION ALL
+ SELECT frame_number, jank_cause FROM android_sysui_cuj_sf_jank_causes
+ GROUP BY frame_number, jank_cause;
+
+-- TODO(b/175098682): Switch to use async slices
+DROP VIEW IF EXISTS android_sysui_cuj_event;
+CREATE VIEW android_sysui_cuj_event AS
+ SELECT
+ 'slice' as track_type,
+ (SELECT cuj_name FROM android_sysui_cuj_last_cuj)
+ || ' - jank cause' as track_name,
+ f.ts_main_thread_start as ts,
+ f.dur_main_thread as dur,
+ group_concat(jc.jank_cause) as slice_name
+FROM android_sysui_cuj_frames f
+JOIN android_sysui_cuj_jank_causes jc USING (frame_number)
+GROUP BY track_type, track_name, ts, dur;
+
+DROP VIEW IF EXISTS android_sysui_cuj_output;
+CREATE VIEW android_sysui_cuj_output AS
+SELECT
+ AndroidSysUiCujMetrics(
+ 'cuj_name', cuj_name,
+ 'cuj_start', ts_start,
+ 'cuj_dur', dur,
+ 'process', process_metadata,
+ 'frames',
+ (SELECT RepeatedField(
+ AndroidSysUiCujMetrics_Frame(
+ 'number', f.frame_number,
+ 'vsync', f.vsync,
+ 'ts', f.ts_main_thread_start,
+ 'dur', f.dur_frame,
+ 'jank_cause',
+ (SELECT RepeatedField(jc.jank_cause)
+ FROM android_sysui_cuj_jank_causes jc WHERE jc.frame_number = f.frame_number)))
+ FROM android_sysui_cuj_frames f
+ ORDER BY frame_number ASC))
+ FROM android_sysui_cuj_last_cuj;
diff --git a/src/trace_processor/metrics/sql/android/android_sysui_cuj_jank_query.sql b/src/trace_processor/metrics/sql/android/android_sysui_cuj_jank_query.sql
new file mode 100644
index 000000000..1a4e691e5
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_sysui_cuj_jank_query.sql
@@ -0,0 +1,50 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+DROP VIEW IF EXISTS {{table_name_prefix}}_relevant_slices_in_cuj;
+CREATE VIEW {{table_name_prefix}}_relevant_slices_in_cuj AS
+SELECT slice.ts, slice.dur FROM {{relevant_slices_table}} slice
+JOIN android_sysui_cuj_ts_boundaries boundaries
+ON slice.ts + slice.dur >= boundaries.ts AND slice.ts <= boundaries.ts_end;
+
+DROP TABLE IF EXISTS {{table_name_prefix}}_cuj_join_table;
+CREATE VIRTUAL TABLE {{table_name_prefix}}_cuj_join_table
+USING span_join(
+ android_sysui_cuj_ts_boundaries,
+ {{table_name_prefix}}_relevant_slices_in_cuj);
+
+DROP TABLE IF EXISTS {{table_name_prefix}}_frame_join_table;
+CREATE VIRTUAL TABLE {{table_name_prefix}}_frame_join_table
+USING span_join(
+ android_sysui_cuj_missed_frames_hwui_times partitioned frame_number,
+ {{table_name_prefix}}_relevant_slices_in_cuj);
+
+DROP VIEW IF EXISTS {{table_name_prefix}}_per_cuj_output_data;
+CREATE VIEW {{table_name_prefix}}_per_cuj_output_data AS
+SELECT SUM(dur) as dur_sum, MAX(dur) as dur_max
+FROM {{table_name_prefix}}_cuj_join_table;
+
+DROP VIEW IF EXISTS {{table_name_prefix}}_per_frame_output_data;
+CREATE VIEW {{table_name_prefix}}_per_frame_output_data AS
+SELECT
+f.frame_number,
+f.vsync,
+f.dur_frame,
+f.app_missed,
+SUM(jt.dur) as dur_sum,
+MAX(jt.dur) as dur_max
+FROM android_sysui_cuj_missed_frames f
+JOIN {{table_name_prefix}}_frame_join_table jt USING (frame_number)
+GROUP BY f.frame_number, f.vsync, f.dur_frame, f.app_missed;
diff --git a/src/trace_processor/metrics/sql/android/android_sysui_cuj_surfaceflinger.sql b/src/trace_processor/metrics/sql/android/android_sysui_cuj_surfaceflinger.sql
new file mode 100644
index 000000000..f88ed0f7b
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_sysui_cuj_surfaceflinger.sql
@@ -0,0 +1,260 @@
+-- Isolate the SurfaceFlinger process Id
+DROP TABLE IF EXISTS android_sysui_cuj_sf_process;
+CREATE TABLE android_sysui_cuj_sf_process AS
+SELECT name, upid FROM process
+WHERE process.name='/system/bin/surfaceflinger'
+LIMIT 1;
+
+DROP VIEW IF EXISTS android_sysui_cuj_sf_actual_frame_timeline_slice;
+CREATE VIEW android_sysui_cuj_sf_actual_frame_timeline_slice AS
+SELECT
+ actual.*,
+ actual.ts + actual.dur AS ts_end,
+ CAST(actual.name AS integer) AS vsync
+FROM actual_frame_timeline_slice actual JOIN android_sysui_cuj_sf_process USING (upid);
+
+DROP TABLE IF EXISTS android_sysui_cuj_surfaceflinger_main_thread;
+CREATE TABLE android_sysui_cuj_surfaceflinger_main_thread AS
+ SELECT android_sysui_cuj_sf_process.name AS process_name, thread.utid
+ FROM thread JOIN android_sysui_cuj_sf_process USING (upid)
+ WHERE thread.is_main_thread;
+
+DROP TABLE IF EXISTS android_sysui_cuj_sf_main_thread_track;
+CREATE TABLE android_sysui_cuj_sf_main_thread_track AS
+SELECT thread_track.id
+FROM thread_track
+JOIN android_sysui_cuj_surfaceflinger_main_thread thread USING (utid);
+
+DROP VIEW IF EXISTS android_sysui_cuj_surfaceflinger_gpu_completion_thread;
+CREATE VIEW android_sysui_cuj_surfaceflinger_gpu_completion_thread AS
+ SELECT android_sysui_cuj_sf_process.name AS process_name, thread.utid
+ FROM thread JOIN android_sysui_cuj_sf_process USING (upid)
+ WHERE thread.name = 'GPU completion';
+
+DROP VIEW IF EXISTS android_sysui_cuj_surfaceflinger_renderengine_thread;
+CREATE VIEW android_sysui_cuj_surfaceflinger_renderengine_thread AS
+ SELECT android_sysui_cuj_sf_process.name AS process_name, thread.utid
+ FROM thread JOIN android_sysui_cuj_sf_process USING (upid)
+ WHERE thread.name = 'RenderEngine';
+
+DROP VIEW IF EXISTS android_sysui_cuj_surfaceflinger_gpu_completion_slices;
+CREATE VIEW android_sysui_cuj_surfaceflinger_gpu_completion_slices AS
+ SELECT
+ process_name,
+ thread.utid,
+ slice.*,
+ slice.ts + slice.dur AS ts_end,
+ -- Extracts 1234 from 'waiting for GPU completion 1234'
+ CAST(STR_SPLIT(slice.name, ' ', 4) AS INTEGER) AS idx
+ FROM slice
+ JOIN thread_track ON slice.track_id = thread_track.id
+ JOIN android_sysui_cuj_surfaceflinger_gpu_completion_thread thread USING (utid)
+ WHERE slice.name GLOB 'waiting for GPU completion *'
+ AND dur > 0;
+
+-- Find flows between actual frame slices from app process to surfaceflinger, allowing us to
+-- correlate vsyncs.
+DROP VIEW IF EXISTS android_sysui_cuj_surfaceflinger_app_flow_vsyncs;
+CREATE VIEW android_sysui_cuj_surfaceflinger_app_flow_vsyncs AS
+SELECT
+ app_slice.name AS app_vsync,
+ app_slice.id AS app_slice_id,
+ cuj_process.name AS app_process,
+ sf_slice.name AS sf_vsync,
+ sf_slice.id AS sf_slice_id
+FROM android_sysui_cuj_sf_actual_frame_timeline_slice sf_slice
+JOIN directly_connected_flow(sf_slice.id) flow
+JOIN actual_frame_timeline_slice app_slice ON slice_in = app_slice.id
+JOIN android_sysui_cuj_last_cuj cuj_process ON app_slice.upid = cuj_process.upid
+GROUP BY app_vsync, sf_vsync;
+
+-- Filter to those SF frames which flow from app frames that are within the app vsync boundaries of
+-- the CUJ
+DROP TABLE IF EXISTS android_sysui_cuj_sf_frames_in_cuj;
+CREATE TABLE android_sysui_cuj_sf_frames_in_cuj AS
+SELECT
+ sf_frame.ts,
+ sf_frame.dur,
+ sf_frame.jank_type,
+ sf_frame.ts + sf_frame.dur AS ts_end,
+ flows.sf_vsync,
+ flows.app_vsync
+-- This table contains only the frame timeline slices within the CUJ app vsync boundaries
+FROM android_sysui_cuj_frame_timeline_events app_frames
+-- Find the matching SF frame via flow
+JOIN android_sysui_cuj_surfaceflinger_app_flow_vsyncs flows ON app_frames.vsync = flows.app_vsync
+JOIN android_sysui_cuj_sf_actual_frame_timeline_slice sf_frame ON sf_frame.id = flows.sf_slice_id
+GROUP BY flows.sf_vsync;
+
+-- Take the min and max vsync to define the SurfaceFlinger boundaries
+DROP TABLE IF EXISTS android_sysui_cuj_sf_vsync_boundaries;
+CREATE TABLE android_sysui_cuj_sf_vsync_boundaries AS
+SELECT MIN(sf_vsync) AS vsync_min, MAX(sf_vsync) AS vsync_max
+FROM android_sysui_cuj_sf_frames_in_cuj;
+
+-- Find just the commit slices, within the CUJ (by vsync)
+DROP TABLE IF EXISTS android_sysui_cuj_surfaceflinger_commit_slices_in_cuj;
+CREATE TABLE android_sysui_cuj_surfaceflinger_commit_slices_in_cuj AS
+SELECT * FROM
+ (SELECT
+ -- Extract the vsync number from name like 'commit 235991 vsyncIn 15.992ms'
+ CAST(STR_SPLIT(slice.name, ' ', 1) AS INTEGER) AS vsync,
+ CAST(CAST(STR_SPLIT(slice.name, ' ', 3) AS NUMBER) * 1e6 + slice.ts AS INTEGER) AS expected_vsync_ts,
+ slice.name,
+ slice.ts,
+ slice.dur,
+ slice.ts + slice.dur AS ts_end
+ FROM slice
+ JOIN android_sysui_cuj_sf_main_thread_track main_track ON slice.track_id = main_track.id
+ WHERE slice.dur > 0 AND slice.name GLOB 'commit *')
+JOIN android_sysui_cuj_sf_vsync_boundaries cuj_boundaries
+WHERE vsync >= cuj_boundaries.vsync_min AND vsync <= cuj_boundaries.vsync_max;
+
+-- Find just the onMessageInvalidate slices, within the CUJ (by vsync)
+DROP VIEW IF EXISTS android_sysui_cuj_surfaceflinger_on_message_invalidate_slices_in_cuj;
+CREATE VIEW android_sysui_cuj_surfaceflinger_on_message_invalidate_slices_in_cuj AS
+ WITH on_msg AS (SELECT
+ -- Extract the vsync number from name like 'onMessageInvalidate 235991 vsyncIn 15.992ms'
+ CAST(STR_SPLIT(slice.name, ' ', 1) AS INTEGER) AS vsync,
+ CAST(CAST(STR_SPLIT(slice.name, ' ', 3) AS NUMBER) * 1e6 + slice.ts AS INTEGER) AS expected_vsync_ts,
+ slice.ts,
+ slice.ts + slice.dur AS ts_end,
+ slice.dur
+ FROM slice
+ JOIN android_sysui_cuj_sf_main_thread_track main_track ON slice.track_id = main_track.id
+ WHERE slice.name GLOB 'onMessageInvalidate *'
+ )
+SELECT
+ on_msg.vsync,
+ on_msg.ts,
+ on_msg.ts_end,
+ on_msg.dur,
+ on_msg.expected_vsync_ts,
+ lag(on_msg.ts_end) OVER (ORDER BY on_msg.ts_end ASC) AS ts_prev_frame_end,
+ lead(on_msg.ts) OVER (ORDER BY on_msg.ts ASC) AS ts_next_frame_start
+FROM on_msg
+JOIN android_sysui_cuj_sf_vsync_boundaries cuj_boundaries
+WHERE on_msg.vsync >= cuj_boundaries.vsync_min AND on_msg.vsync <= cuj_boundaries.vsync_max;
+
+-- Find just the composite slices
+DROP TABLE IF EXISTS android_sysui_cuj_surfaceflinger_composite_slices;
+CREATE TABLE android_sysui_cuj_surfaceflinger_composite_slices AS
+ SELECT
+ slice.name,
+ slice.ts,
+ slice.dur,
+ slice.ts + slice.dur AS ts_end
+ FROM slice
+ JOIN android_sysui_cuj_sf_main_thread_track main_track ON slice.track_id = main_track.id
+ WHERE slice.dur > 0 AND slice.name = 'composite';
+
+DROP VIEW IF EXISTS android_sysui_cuj_surfaceflinger_commit_composite_frames_in_cuj;
+CREATE VIEW android_sysui_cuj_surfaceflinger_commit_composite_frames_in_cuj AS
+ WITH commit_to_composite AS (
+ SELECT
+ commits.vsync,
+ commits.ts AS commit_ts,
+ commits.name AS name,
+ commits.expected_vsync_ts,
+ min(composite.ts) AS composite_ts
+ FROM android_sysui_cuj_surfaceflinger_commit_slices_in_cuj commits
+ JOIN android_sysui_cuj_surfaceflinger_composite_slices composite ON composite.ts > commits.ts_end
+ GROUP BY commits.vsync
+ )
+ SELECT
+ vsync,
+ match.commit_ts AS ts,
+ composite.ts_end AS ts_end,
+ composite.ts_end - match.commit_ts AS dur,
+ match.expected_vsync_ts,
+ lag(composite.ts_end) OVER (ORDER BY composite.ts_end ASC) AS ts_prev_frame_end,
+ lead(match.commit_ts) OVER (ORDER BY match.commit_ts ASC) AS ts_next_frame_start
+ FROM commit_to_composite match
+ JOIN android_sysui_cuj_surfaceflinger_composite_slices composite ON match.composite_ts = composite.ts;
+
+-- All SF frames in the CUJ
+DROP TABLE IF EXISTS android_sysui_cuj_surfaceflinger_main_thread_frames;
+CREATE TABLE android_sysui_cuj_surfaceflinger_main_thread_frames AS
+SELECT * FROM android_sysui_cuj_surfaceflinger_on_message_invalidate_slices_in_cuj
+UNION ALL
+SELECT * FROM android_sysui_cuj_surfaceflinger_commit_composite_frames_in_cuj;
+
+-- Our timestamp boundaries are the earliest ts and latest ts_end of the main thread frames (e.g.
+-- onMessageInvalidate or commit/composite pair) which flow from app frames within the CUJ
+DROP TABLE IF EXISTS android_sysui_cuj_sf_ts_boundaries;
+CREATE TABLE android_sysui_cuj_sf_ts_boundaries AS
+SELECT ts, ts_end - ts AS dur, ts_end
+FROM (SELECT MIN(ts) AS ts, MAX(ts_end) AS ts_end FROM android_sysui_cuj_surfaceflinger_main_thread_frames);
+
+DROP TABLE IF EXISTS android_sysui_cuj_surfaceflinger_main_thread_slices_in_cuj;
+CREATE TABLE android_sysui_cuj_surfaceflinger_main_thread_slices_in_cuj AS
+ SELECT
+ slice.*,
+ slice.ts + slice.dur AS ts_end
+ FROM slice
+ JOIN android_sysui_cuj_sf_main_thread_track main_track ON slice.track_id = main_track.id
+ JOIN android_sysui_cuj_sf_ts_boundaries cuj_boundaries
+ ON slice.ts >= cuj_boundaries.ts AND slice.ts <= cuj_boundaries.ts_end
+ WHERE slice.dur > 0;
+
+-- Find SurfaceFlinger GPU completions that are within the CUJ
+DROP TABLE IF EXISTS android_sysui_cuj_surfaceflinger_gpu_completion_slices_in_cuj;
+CREATE TABLE android_sysui_cuj_surfaceflinger_gpu_completion_slices_in_cuj AS
+SELECT slice.* FROM android_sysui_cuj_surfaceflinger_gpu_completion_slices slice
+JOIN android_sysui_cuj_sf_ts_boundaries cuj_boundaries
+ON slice.ts >= cuj_boundaries.ts AND slice.ts <= cuj_boundaries.ts_end;
+
+DROP TABLE IF EXISTS android_sysui_cuj_surfaceflinger_renderengine_slices_in_cuj;
+CREATE TABLE android_sysui_cuj_surfaceflinger_renderengine_slices_in_cuj AS
+ SELECT
+ process_name,
+ thread.utid,
+ slice.*,
+ slice.ts + slice.dur AS ts_end
+ FROM slice
+ JOIN thread_track ON slice.track_id = thread_track.id
+ JOIN android_sysui_cuj_surfaceflinger_renderengine_thread thread USING (utid)
+ JOIN android_sysui_cuj_sf_ts_boundaries cuj_boundaries
+ ON slice.ts >= cuj_boundaries.ts AND slice.ts <= cuj_boundaries.ts_end
+ WHERE slice.dur > 0;
+
+DROP VIEW IF EXISTS android_sysui_cuj_gcs_to_mt_match;
+CREATE VIEW android_sysui_cuj_gcs_to_mt_match AS
+-- Match Mainthread slice with the first GPU Completion that begins during it
+SELECT
+gcs.ts AS gcs_ts,
+gcs.ts_end AS gcs_ts_end,
+gcs.dur AS gcs_dur,
+gcs.idx AS idx,
+mtf.ts AS mts_ts,
+mtf.vsync AS vsync
+FROM android_sysui_cuj_surfaceflinger_gpu_completion_slices_in_cuj gcs
+-- join with all previous render frames but take latest start time
+JOIN android_sysui_cuj_surfaceflinger_main_thread_frames mtf ON gcs.ts > mtf.ts AND gcs.ts < mtf.ts + mtf.dur
+GROUP BY gcs.ts, gcs.ts_end, gcs.dur, gcs.idx;
+
+-- Those SurfaceFlinger Frames where we missed the deadline
+-- To avoid overlap - which could result in counting janky slices more than once - we limit the
+-- definition of each frame to:
+-- * beginning when the shared timeline actual frame starts, or - if later -
+-- when the previous main thread computation ended
+-- * ending when the next main thread computation begins, but no later than the
+-- shared timeline actual frame ends
+DROP TABLE IF EXISTS android_sysui_cuj_sf_missed_frames;
+CREATE TABLE android_sysui_cuj_sf_missed_frames AS
+SELECT
+ CAST(frame.name AS integer) AS frame_number,
+ CAST(frame.name AS integer) AS vsync,
+ max(mtf.ts_prev_frame_end, frame.ts) AS ts,
+ min(mtf.ts_next_frame_start, frame.ts_end) AS ts_end,
+ min(mtf.ts_next_frame_start, frame.ts_end) - max(mtf.ts_prev_frame_end, frame.ts) AS dur,
+ -- Needed for compatibility with downstream scripts
+ CAST(min(mtf.ts_next_frame_start, frame.ts_end) - max(mtf.ts_prev_frame_end, frame.ts) AS INTEGER) AS dur_frame,
+ gcs.gcs_ts,
+ gcs.gcs_ts_end,
+ gcs.gcs_dur,
+ CAST(1 AS INTEGER) AS app_missed
+FROM android_sysui_cuj_sf_actual_frame_timeline_slice frame
+JOIN android_sysui_cuj_surfaceflinger_main_thread_frames mtf ON frame.name = mtf.vsync
+JOIN android_sysui_cuj_gcs_to_mt_match gcs ON gcs.vsync = frame.name
+WHERE frame.jank_type != 'None';
diff --git a/src/trace_processor/metrics/android/android_task_names.sql b/src/trace_processor/metrics/sql/android/android_task_names.sql
index b86186b70..b86186b70 100644
--- a/src/trace_processor/metrics/android/android_task_names.sql
+++ b/src/trace_processor/metrics/sql/android/android_task_names.sql
diff --git a/src/trace_processor/metrics/sql/android/android_thread_time_in_state.sql b/src/trace_processor/metrics/sql/android/android_thread_time_in_state.sql
new file mode 100644
index 000000000..160726b79
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_thread_time_in_state.sql
@@ -0,0 +1,197 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+SELECT RUN_METRIC('android/cpu_info.sql');
+SELECT RUN_METRIC('android/process_metadata.sql');
+
+DROP TABLE IF EXISTS android_thread_time_in_state_base;
+CREATE TABLE android_thread_time_in_state_base AS
+SELECT
+ base.*,
+ IFNULL(core_type_per_cpu.core_type, 'unknown') core_type
+FROM (
+ SELECT
+ ts,
+ utid,
+ EXTRACT_ARG(counter.arg_set_id, 'time_in_state_cpu_id') AS
+ time_in_state_cpu,
+ EXTRACT_ARG(counter.arg_set_id, 'freq') AS freq,
+ CAST(value AS INT) AS runtime_ms_counter
+ FROM counter
+ JOIN thread_counter_track ON (counter.track_id = thread_counter_track.id)
+ WHERE thread_counter_track.name = 'time_in_state'
+) base
+LEFT JOIN core_type_per_cpu ON (cpu = time_in_state_cpu);
+
+DROP VIEW IF EXISTS android_thread_time_in_state_raw;
+CREATE VIEW android_thread_time_in_state_raw AS
+SELECT
+ utid,
+ time_in_state_cpu,
+ core_type,
+ freq,
+ MAX(runtime_ms_counter) - MIN(runtime_ms_counter) runtime_ms_diff
+FROM android_thread_time_in_state_base
+GROUP BY utid, time_in_state_cpu, core_type, freq;
+
+DROP TABLE IF EXISTS android_thread_time_in_state_counters;
+CREATE TABLE android_thread_time_in_state_counters AS
+SELECT
+ utid,
+ raw.time_in_state_cpu,
+ raw.core_type,
+ SUM(runtime_ms_diff) AS runtime_ms,
+ SUM(raw.freq * runtime_ms_diff / 1000000) AS mcycles,
+ SUM(power * runtime_ms_diff / 3600000) AS power_profile_mah
+FROM android_thread_time_in_state_raw AS raw
+ LEFT OUTER JOIN cpu_cluster_power AS power USING(core_type, freq)
+GROUP BY utid, raw.time_in_state_cpu, raw.core_type
+HAVING runtime_ms > 0;
+
+DROP VIEW IF EXISTS android_thread_time_in_state_thread_metrics;
+CREATE VIEW android_thread_time_in_state_thread_metrics AS
+SELECT
+ utid,
+ RepeatedField(AndroidThreadTimeInStateMetric_MetricsByCoreType(
+ 'time_in_state_cpu', time_in_state_cpu,
+ 'core_type', core_type,
+ 'runtime_ms', runtime_ms,
+ 'mcycles', CAST(mcycles AS INT),
+ 'power_profile_mah', power_profile_mah
+ )) metrics
+FROM android_thread_time_in_state_counters
+GROUP BY utid;
+
+DROP VIEW IF EXISTS android_thread_time_in_state_threads;
+CREATE VIEW android_thread_time_in_state_threads AS
+SELECT
+ upid,
+ RepeatedField(AndroidThreadTimeInStateMetric_Thread(
+ 'name',
+ thread.name,
+ 'main_thread',
+ thread.is_main_thread,
+ 'metrics_by_core_type',
+ android_thread_time_in_state_thread_metrics.metrics
+ )) threads
+FROM thread
+JOIN android_thread_time_in_state_thread_metrics USING (utid)
+GROUP BY upid;
+
+DROP VIEW IF EXISTS android_thread_time_in_state_process_metrics;
+CREATE VIEW android_thread_time_in_state_process_metrics AS
+WITH process_counters AS (
+ SELECT
+ upid,
+ time_in_state_cpu,
+ core_type,
+ SUM(runtime_ms) AS runtime_ms,
+ SUM(mcycles) AS mcycles,
+ SUM(power_profile_mah) AS power_profile_mah
+ FROM android_thread_time_in_state_counters
+ JOIN thread USING (utid)
+ GROUP BY upid, time_in_state_cpu, core_type
+)
+SELECT
+ upid,
+ RepeatedField(AndroidThreadTimeInStateMetric_MetricsByCoreType(
+ 'time_in_state_cpu', time_in_state_cpu,
+ 'core_type', core_type,
+ 'runtime_ms', runtime_ms,
+ 'mcycles', CAST(mcycles AS INT),
+ 'power_profile_mah', power_profile_mah
+ )) metrics
+FROM process_counters
+GROUP BY upid;
+
+DROP VIEW IF EXISTS android_thread_time_in_state_output;
+CREATE VIEW android_thread_time_in_state_output AS
+SELECT AndroidThreadTimeInStateMetric(
+ 'processes', (
+ SELECT
+ RepeatedField(AndroidThreadTimeInStateMetric_Process(
+ 'metadata', metadata,
+ 'metrics_by_core_type',
+ android_thread_time_in_state_process_metrics.metrics,
+ 'threads', android_thread_time_in_state_threads.threads
+ ))
+ FROM process
+ JOIN process_metadata USING (upid)
+ JOIN android_thread_time_in_state_process_metrics USING (upid)
+ JOIN android_thread_time_in_state_threads USING (upid)
+ )
+);
+
+DROP VIEW IF EXISTS android_thread_time_in_state_event_raw;
+CREATE VIEW android_thread_time_in_state_event_raw AS
+SELECT
+ ts,
+ utid,
+ core_type,
+ freq,
+ time_in_state_cpu,
+ runtime_ms_counter - LAG(runtime_ms_counter) OVER win AS runtime_ms_diff
+FROM android_thread_time_in_state_base
+WINDOW win AS (PARTITION BY utid, core_type, time_in_state_cpu, freq ORDER BY ts);
+
+DROP VIEW IF EXISTS android_thread_time_in_state_by_core_type;
+CREATE VIEW android_thread_time_in_state_by_core_type AS
+SELECT
+ ts,
+ utid,
+ core_type,
+ freq,
+ SUM(runtime_ms_diff) runtime_ms_diff
+FROM android_thread_time_in_state_event_raw
+GROUP BY ts, utid, core_type, freq
+HAVING runtime_ms_diff > 0;
+
+DROP VIEW IF EXISTS android_thread_time_in_state_event_thread;
+CREATE VIEW android_thread_time_in_state_event_thread AS
+SELECT
+ -- We need globally unique track names so add the utid even when we
+ -- know the name. But when we don't, also use the tid because that's what
+ -- the rest of the UI does.
+ IFNULL(thread.name, 'Thread ' || thread.tid) || ' (' || thread.utid || ')'
+ || ' (' || core_type || ' core) mcycles' AS track_name,
+ ts,
+ upid,
+ SUM(runtime_ms_diff * freq) OVER win AS cycles
+FROM android_thread_time_in_state_by_core_type
+JOIN thread USING (utid)
+GROUP BY ts, upid, track_name
+WINDOW win AS (PARTITION BY utid ORDER BY ts);
+
+DROP VIEW IF EXISTS android_thread_time_in_state_event_global;
+CREATE VIEW android_thread_time_in_state_event_global AS
+SELECT
+ 'Total ' || core_type || ' core mcycles' as track_name,
+ ts,
+ 0 AS upid,
+ SUM(runtime_ms_diff * freq) OVER win as cycles
+FROM android_thread_time_in_state_by_core_type
+GROUP BY ts, track_name
+WINDOW win AS (ORDER BY ts);
+
+DROP TABLE IF EXISTS android_thread_time_in_state_event;
+CREATE TABLE android_thread_time_in_state_event AS
+SELECT 'counter' as track_type, track_name, upid, ts, cycles / 1000000.0 AS value
+FROM android_thread_time_in_state_event_thread
+UNION ALL
+SELECT 'counter' as track_type, track_name, upid, ts, cycles / 1000000.0 AS value
+FROM android_thread_time_in_state_event_global
+-- Biggest values at top of list in UI.
+ORDER BY value DESC;
diff --git a/src/trace_processor/metrics/sql/android/android_trace_quality.sql b/src/trace_processor/metrics/sql/android/android_trace_quality.sql
new file mode 100644
index 000000000..a68c053d3
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_trace_quality.sql
@@ -0,0 +1,35 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+DROP VIEW IF EXISTS android_trace_quality_failures;
+CREATE VIEW android_trace_quality_failures AS
+-- Check that all the sched slices are less than 1 week long.
+SELECT
+ 'sched_slice_too_long' as name,
+ MAX(dur) > 1 * 7 * 24 * 60 * 60 * 1000 * 1000 * 1000 as failed
+FROM sched;
+
+DROP VIEW IF EXISTS android_trace_quality_output;
+CREATE VIEW android_trace_quality_output AS
+SELECT AndroidTraceQualityMetric(
+ 'failures', (
+ SELECT RepeatedField(AndroidTraceQualityMetric_Failure(
+ 'name', name
+ ))
+ FROM android_trace_quality_failures
+ WHERE failed
+ )
+);
diff --git a/src/trace_processor/metrics/sql/android/android_trusty_workqueues.sql b/src/trace_processor/metrics/sql/android/android_trusty_workqueues.sql
new file mode 100644
index 000000000..a036c9d6a
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_trusty_workqueues.sql
@@ -0,0 +1,21 @@
+-- Gather the `nop_work_func` slices and the CPU they each ran on and use that
+-- information to generate a metric that displays just the Trusty workqueue
+-- events grouped by CPU.
+DROP VIEW IF EXISTS android_trusty_workqueues_event;
+CREATE VIEW android_trusty_workqueues_event AS
+SELECT
+ 'slice' as track_type,
+ name as slice_name,
+ ts,
+ dur,
+ 'Cpu ' || EXTRACT_ARG(arg_set_id, 'cpu') as track_name,
+ 'Trusty Workqueues' as group_name
+FROM slice
+WHERE slice.name GLOB 'nop_work_func*';
+
+-- Generate the final metric output. This is empty because we're only using the
+-- metric to generate custom tracks, and so don't have any aggregate data to
+-- generate.
+DROP VIEW IF EXISTS android_trusty_workqueues_output;
+CREATE VIEW android_trusty_workqueues_output AS
+SELECT AndroidTrustyWorkqueues();
diff --git a/src/trace_processor/metrics/android/composer_execution.sql b/src/trace_processor/metrics/sql/android/composer_execution.sql
index bec4fdcdd..bec4fdcdd 100644
--- a/src/trace_processor/metrics/android/composer_execution.sql
+++ b/src/trace_processor/metrics/sql/android/composer_execution.sql
diff --git a/src/trace_processor/metrics/android/composition_layers.sql b/src/trace_processor/metrics/sql/android/composition_layers.sql
index 0790296fb..0790296fb 100644
--- a/src/trace_processor/metrics/android/composition_layers.sql
+++ b/src/trace_processor/metrics/sql/android/composition_layers.sql
diff --git a/src/trace_processor/metrics/sql/android/cpu_info.sql b/src/trace_processor/metrics/sql/android/cpu_info.sql
new file mode 100644
index 000000000..0f2c0f00d
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/cpu_info.sql
@@ -0,0 +1,50 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+SELECT RUN_METRIC('android/power_profile_data.sql');
+
+DROP TABLE IF EXISTS cluster_core_type;
+CREATE TABLE cluster_core_type AS
+ SELECT 0 as cluster, 'little' as core_type
+ UNION ALL
+ SELECT 1, 'big'
+ UNION ALL
+ SELECT 2, 'bigger';
+
+DROP VIEW IF EXISTS device_power_profile;
+CREATE VIEW device_power_profile AS
+SELECT cpu, cluster, freq, power
+FROM power_profile pp
+WHERE EXISTS (
+ SELECT 1 FROM metadata
+ WHERE name = 'android_build_fingerprint' AND str_value GLOB '*' || pp.device || '*');
+
+DROP VIEW IF EXISTS core_cluster_per_cpu;
+CREATE VIEW core_cluster_per_cpu AS
+SELECT DISTINCT cpu, cluster
+FROM device_power_profile;
+
+DROP VIEW IF EXISTS core_type_per_cpu;
+CREATE VIEW core_type_per_cpu AS
+SELECT
+ cpu,
+ core_type
+FROM core_cluster_per_cpu JOIN cluster_core_type USING(cluster);
+
+DROP VIEW IF EXISTS cpu_cluster_power;
+CREATE VIEW cpu_cluster_power AS
+SELECT DISTINCT core_type, freq, power
+FROM device_power_profile pp JOIN cluster_core_type USING(cluster);
diff --git a/src/trace_processor/metrics/android/display_metrics.sql b/src/trace_processor/metrics/sql/android/display_metrics.sql
index daec2131f..daec2131f 100644
--- a/src/trace_processor/metrics/android/display_metrics.sql
+++ b/src/trace_processor/metrics/sql/android/display_metrics.sql
diff --git a/src/trace_processor/metrics/android/frame_missed.sql b/src/trace_processor/metrics/sql/android/frame_missed.sql
index 45499faf9..45499faf9 100644
--- a/src/trace_processor/metrics/android/frame_missed.sql
+++ b/src/trace_processor/metrics/sql/android/frame_missed.sql
diff --git a/src/trace_processor/metrics/android/g2d.sql b/src/trace_processor/metrics/sql/android/g2d.sql
index 5e474b7ac..5e474b7ac 100644
--- a/src/trace_processor/metrics/android/g2d.sql
+++ b/src/trace_processor/metrics/sql/android/g2d.sql
diff --git a/src/trace_processor/metrics/sql/android/g2d_duration.sql b/src/trace_processor/metrics/sql/android/g2d_duration.sql
new file mode 100644
index 000000000..653af6b63
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/g2d_duration.sql
@@ -0,0 +1,68 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+DROP VIEW IF EXISTS raw_g2d_{{g2d_type}}_spans;
+CREATE VIEW raw_g2d_{{g2d_type}}_spans AS
+SELECT
+ ts,
+ t.name AS track_name,
+ LEAD(ts, 1, 0) OVER (PARTITION BY name ORDER BY ts) - ts AS dur,
+ LAG(value, 1, -1) OVER (PARTITION BY name ORDER BY ts) AS prev_g2d_value,
+ value AS g2d_value,
+ LEAD(value, 1, -1) OVER (PARTITION BY name ORDER BY ts) AS next_g2d_value
+FROM counter c JOIN thread_counter_track t ON t.id = c.track_id
+WHERE t.name GLOB 'g2d_frame_{{g2d_type}}*';
+
+
+DROP VIEW IF EXISTS g2d_{{g2d_type}}_spans;
+CREATE VIEW g2d_{{g2d_type}}_spans AS
+SELECT ts, track_name, dur
+FROM raw_g2d_{{g2d_type}}_spans
+WHERE g2d_value = 1 AND next_g2d_value = 0;
+
+
+DROP VIEW IF EXISTS g2d_{{g2d_type}}_errors;
+CREATE VIEW g2d_{{g2d_type}}_errors AS
+SELECT ts, track_name, g2d_value
+FROM raw_g2d_{{g2d_type}}_spans
+WHERE (g2d_value = 1 AND next_g2d_value = 1) OR (prev_g2d_value = 0 AND g2d_value = 0);
+
+
+DROP VIEW IF EXISTS g2d_{{g2d_type}}_instances;
+CREATE VIEW g2d_{{g2d_type}}_instances AS
+SELECT
+ G2dMetrics_G2dInstance(
+ 'name', g.track_name,
+ 'max_dur_ms', MAX(dur) / 1e6,
+ 'min_dur_ms', MIN(dur) / 1e6,
+ 'avg_dur_ms', AVG(dur) / 1e6,
+ 'frame_count', COUNT(*),
+ 'error_count', (SELECT COUNT(*) FROM g2d_{{g2d_type}}_errors e WHERE e.track_name = g.track_name)
+ ) AS instance
+FROM g2d_{{g2d_type}}_spans g GROUP BY g.track_name;
+
+
+DROP VIEW IF EXISTS {{output_table}};
+CREATE VIEW {{output_table}} AS
+SELECT
+ G2dMetrics_G2dMetric(
+ 'instances', (SELECT RepeatedField(instance) FROM g2d_{{g2d_type}}_instances),
+ 'max_dur_ms', MAX(dur) / 1e6,
+ 'min_dur_ms', MIN(dur) / 1e6,
+ 'avg_dur_ms', AVG(dur) / 1e6,
+ 'frame_count', COUNT(*),
+ 'error_count', (SELECT COUNT(*) FROM g2d_{{g2d_type}}_errors)
+ ) AS metric
+FROM g2d_{{g2d_type}}_spans;
diff --git a/src/trace_processor/metrics/android/global_counter_span_view.sql b/src/trace_processor/metrics/sql/android/global_counter_span_view.sql
index 0b531a672..0b531a672 100644
--- a/src/trace_processor/metrics/android/global_counter_span_view.sql
+++ b/src/trace_processor/metrics/sql/android/global_counter_span_view.sql
diff --git a/src/trace_processor/metrics/sql/android/gpu_counter_span_view.sql b/src/trace_processor/metrics/sql/android/gpu_counter_span_view.sql
new file mode 100644
index 000000000..7a40fd092
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/gpu_counter_span_view.sql
@@ -0,0 +1,27 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+DROP VIEW IF EXISTS {{table_name}}_span;
+CREATE VIEW {{table_name}}_span AS
+SELECT
+ ts,
+ LEAD(ts, 1, (SELECT end_ts+1 FROM trace_bounds))
+ OVER (PARTITION BY track_id ORDER BY ts) - ts AS dur,
+ gpu_id,
+ value AS {{table_name}}_val
+FROM counter c JOIN gpu_counter_track t
+ ON t.id = c.track_id
+WHERE name = '{{counter_name}}' AND gpu_id IS NOT NULL;
diff --git a/src/trace_processor/metrics/sql/android/java_heap_histogram.sql b/src/trace_processor/metrics/sql/android/java_heap_histogram.sql
new file mode 100644
index 000000000..75185948b
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/java_heap_histogram.sql
@@ -0,0 +1,99 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+SELECT RUN_METRIC('android/process_metadata.sql');
+
+DROP TABLE IF EXISTS android_special_classes;
+CREATE TABLE android_special_classes AS
+WITH RECURSIVE cls_visitor(cls_id, category) AS (
+ SELECT id, name FROM heap_graph_class WHERE name IN (
+ 'android.view.View',
+ 'android.app.Activity',
+ 'android.app.Fragment',
+ 'android.app.Service',
+ 'android.content.ContentProvider',
+ 'android.content.BroadcastReceiver',
+ 'android.content.Context',
+ 'android.content.Intent',
+ 'android.content.res.ApkAssets',
+ 'android.os.Handler',
+ 'android.os.Parcel',
+ 'android.graphics.Bitmap',
+ 'android.graphics.BaseCanvas',
+ 'com.android.server.am.PendingIntentRecord')
+ UNION ALL
+ SELECT child.id, parent.category
+ FROM heap_graph_class child JOIN cls_visitor parent ON parent.cls_id = child.superclass_id
+)
+SELECT * FROM cls_visitor;
+
+DROP TABLE IF EXISTS heap_obj_histograms;
+CREATE TABLE heap_obj_histograms AS
+ SELECT
+ o.upid,
+ o.graph_sample_ts,
+ o.type_id cls_id,
+ COUNT(1) obj_count,
+ SUM(IIF(o.reachable, 1, 0)) reachable_obj_count,
+ SUM(self_size) / 1024 size_kb,
+ SUM(IIF(o.reachable, self_size, 0)) / 1024 reachable_size_kb,
+ SUM(native_size) / 1024 native_size_kb,
+ SUM(IIF(o.reachable, native_size, 0)) / 1024 reachable_native_size_kb
+ FROM heap_graph_object o
+ GROUP BY 1, 2, 3
+ ORDER BY 1, 2, 3;
+
+DROP VIEW IF EXISTS java_heap_histogram_output;
+CREATE VIEW java_heap_histogram_output AS
+WITH
+-- Group by to build the repeated field by upid, ts
+heap_obj_histogram_count_protos AS (
+ SELECT
+ upid,
+ graph_sample_ts,
+ RepeatedField(JavaHeapHistogram_TypeCount(
+ 'type_name', IFNULL(c.deobfuscated_name, c.name),
+ 'category', category,
+ 'obj_count', obj_count,
+ 'reachable_obj_count', reachable_obj_count,
+ 'size_kb', size_kb,
+ 'reachable_size_kb', reachable_size_kb,
+ 'native_size_kb', native_size_kb,
+ 'reachable_native_size_kb', reachable_native_size_kb
+ )) AS count_protos
+ FROM heap_obj_histograms hist
+ JOIN heap_graph_class c ON hist.cls_id = c.id
+ LEFT JOIN android_special_classes special USING(cls_id)
+ GROUP BY 1, 2
+),
+-- Group by to build the repeated field by upid
+heap_obj_histogram_sample_protos AS (
+ SELECT
+ upid,
+ RepeatedField(JavaHeapHistogram_Sample(
+ 'ts', graph_sample_ts,
+ 'type_count', count_protos
+ )) AS sample_protos
+ FROM heap_obj_histogram_count_protos
+ GROUP BY 1
+)
+SELECT JavaHeapHistogram(
+ 'instance_stats', RepeatedField(JavaHeapHistogram_InstanceStats(
+ 'upid', upid,
+ 'process', process_metadata.metadata,
+ 'samples', sample_protos
+ )))
+FROM heap_obj_histogram_sample_protos JOIN process_metadata USING (upid);
diff --git a/src/trace_processor/metrics/sql/android/java_heap_stats.sql b/src/trace_processor/metrics/sql/android/java_heap_stats.sql
new file mode 100644
index 000000000..9f22a8ad7
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/java_heap_stats.sql
@@ -0,0 +1,115 @@
+--
+-- Copyright 2019 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+SELECT RUN_METRIC('android/process_metadata.sql');
+SELECT RUN_METRIC('android/process_mem.sql');
+
+DROP VIEW IF EXISTS java_heap_stats_output;
+CREATE VIEW java_heap_stats_output AS
+WITH
+-- Base view
+base_stat_counts AS (
+ SELECT
+ upid,
+ graph_sample_ts,
+ SUM(self_size) AS total_size,
+ SUM(native_size) AS total_native_size,
+ COUNT(1) AS total_obj_count,
+ SUM(IIF(reachable, self_size, 0)) AS reachable_size,
+ SUM(IIF(reachable, native_size, 0)) AS reachable_native_size,
+ SUM(IIF(reachable, 1, 0)) AS reachable_obj_count
+ FROM heap_graph_object
+ GROUP BY 1, 2
+),
+heap_roots AS (
+ SELECT
+ upid,
+ graph_sample_ts,
+ root_type,
+ IFNULL(t.deobfuscated_name, t.name) type_name,
+ COUNT(1) obj_count
+ FROM heap_graph_object o
+ JOIN heap_graph_class t ON o.type_id = t.id
+ -- Classes are going to be particularly spammy and uninteresting
+ -- from a memory analysis perspective (compared e.g. to local jni roots)
+ WHERE root_type IS NOT NULL AND root_type != 'ROOT_STICKY_CLASS'
+ GROUP BY 1, 2, 3, 4
+ ORDER BY obj_count DESC
+),
+heap_roots_proto AS (
+ SELECT
+ upid,
+ graph_sample_ts,
+ RepeatedField(JavaHeapStats_HeapRoots(
+ 'root_type', root_type,
+ 'type_name', type_name,
+ 'obj_count', obj_count
+ )) roots
+ FROM heap_roots
+ GROUP BY 1, 2
+),
+base_stats AS (
+ SELECT * FROM base_stat_counts JOIN heap_roots_proto USING (upid, graph_sample_ts)
+),
+-- Find closest value
+closest_anon_swap AS (
+ SELECT
+ upid,
+ graph_sample_ts,
+ (
+ SELECT anon_swap_val
+ FROM (
+ SELECT
+ ts, dur,
+ CAST(anon_and_swap_val AS INTEGER) anon_swap_val,
+ ABS(ts - base_stats.graph_sample_ts) diff
+ FROM anon_and_swap_span
+ WHERE upid = base_stats.upid)
+ WHERE
+ (graph_sample_ts >= ts AND graph_sample_ts < ts + dur)
+ -- If the first memory sample for the UPID comes *after* the heap profile
+ -- accept it if close (500ms)
+ OR (graph_sample_ts < ts AND diff <= 500 * 1e6)
+ ORDER BY diff LIMIT 1
+ ) val
+ FROM base_stats
+),
+-- Group by upid
+heap_graph_sample_protos AS (
+ SELECT
+ base_stats.upid,
+ RepeatedField(JavaHeapStats_Sample(
+ 'ts', graph_sample_ts,
+ 'heap_size', total_size,
+ 'heap_native_size', total_native_size,
+ 'obj_count', total_obj_count,
+ 'reachable_heap_size', reachable_size,
+ 'reachable_heap_native_size', reachable_native_size,
+ 'reachable_obj_count', reachable_obj_count,
+ 'roots', roots,
+ 'anon_rss_and_swap_size', closest_anon_swap.val
+ )) sample_protos
+ FROM base_stats
+ LEFT JOIN closest_anon_swap USING (upid, graph_sample_ts)
+ GROUP BY 1
+)
+SELECT JavaHeapStats(
+ 'instance_stats', RepeatedField(JavaHeapStats_InstanceStats(
+ 'upid', upid,
+ 'process', process_metadata.metadata,
+ 'samples', sample_protos
+ )))
+FROM heap_graph_sample_protos JOIN process_metadata USING (upid);
diff --git a/src/trace_processor/metrics/android/mem_stats_priority_breakdown.sql b/src/trace_processor/metrics/sql/android/mem_stats_priority_breakdown.sql
index 645b8bb63..645b8bb63 100644
--- a/src/trace_processor/metrics/android/mem_stats_priority_breakdown.sql
+++ b/src/trace_processor/metrics/sql/android/mem_stats_priority_breakdown.sql
diff --git a/src/trace_processor/metrics/sql/android/power_drain_in_watts.sql b/src/trace_processor/metrics/sql/android/power_drain_in_watts.sql
new file mode 100644
index 000000000..464da59b3
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/power_drain_in_watts.sql
@@ -0,0 +1,90 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the 'License');
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an 'AS IS' BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+-- This is a mapping from counter names on different devices
+-- to what subsystems they are measuring.
+DROP TABLE IF EXISTS power_counters;
+CREATE TABLE power_counters (name TEXT UNIQUE, subsystem TEXT);
+
+INSERT INTO power_counters
+VALUES ('power.VPH_PWR_S5C_S6C_uws', 'cpu_big'),
+ ('power.VPH_PWR_S4C_uws', 'cpu_little'),
+ ('power.VPH_PWR_S2C_S3C_uws', 'soc'),
+ ('power.VPH_PWR_OLED_uws', 'display'),
+ ('power.PPVAR_VPH_PWR_S1A_S9A_S10A_uws', 'soc'),
+ ('power.PPVAR_VPH_PWR_S2A_S3A_uws', 'cpu_big'),
+ ('power.PPVAR_VPH_PWR_S1C_uws', 'cpu_little'),
+ ('power.WCN3998_VDD13 [from PP1304_L2C]_uws', 'wifi'),
+ ('power.PPVAR_VPH_PWR_WLAN_uws', 'wifi'),
+ ('power.PPVAR_VPH_PWR_OLED_uws', 'display'),
+ ('power.PPVAR_VPH_PWR_QTM525_uws', 'cellular'),
+ ('power.PPVAR_VPH_PWR_RF_uws', 'cellular'),
+ ('power.rails.aoc.logic', 'aoc'),
+ ('power.rails.aoc.memory', 'aoc'),
+ ('power.rails.cpu.big', 'cpu_big'),
+ ('power.rails.cpu.little', 'cpu_little'),
+ ('power.rails.cpu.mid', 'cpu_mid'),
+ ('power.rails.ddr.a', 'mem'),
+ ('power.rails.ddr.b', 'mem'),
+ ('power.rails.ddr.c', 'mem'),
+ ('power.rails.gpu', 'gpu'),
+ ('power.rails.display', 'display'),
+ ('power.rails.gps', 'gps'),
+ ('power.rails.memory.interface', 'mem'),
+ ('power.rails.modem', 'cellular'),
+ ('power.rails.radio.frontend', 'cellular'),
+ ('power.rails.system.fabric', 'soc'),
+ ('power.rails.wifi.bt', 'wifi');
+
+-- Convert power counter data into table of events, where each event has
+-- start timestamp, duration and the average power drain during its duration
+-- in Watts.
+-- Note that power counters wrap around at different values on different
+-- devices. When that happens, we ignore the value before overflow, and only
+-- take into account the value after it. This underestimates the actual power
+-- drain between those counters.
+DROP VIEW IF EXISTS drain_in_watts;
+CREATE VIEW drain_in_watts AS
+SELECT name,
+ ts,
+ LEAD(ts) OVER (
+ PARTITION BY track_id
+ ORDER BY ts
+ ) - ts AS dur,
+ CASE
+ WHEN LEAD(value) OVER (
+ PARTITION BY track_id
+ ORDER BY ts
+ ) >= value THEN (
+ LEAD(value) OVER (
+ PARTITION BY track_id
+ ORDER BY ts
+ ) - value
+ )
+ ELSE LEAD(value) OVER (
+ PARTITION BY track_id
+ ORDER BY ts
+ )
+ END / (
+ LEAD(ts) OVER (
+ PARTITION BY track_id
+ ORDER BY ts
+ ) - ts
+ ) * 1e3 AS drain_w
+FROM counter
+ JOIN counter_track ON (counter.track_id = counter_track.id)
+WHERE counter_track.type = 'counter_track'
+ AND name GLOB "power.*";
diff --git a/src/trace_processor/metrics/sql/android/power_profile_data.sql b/src/trace_processor/metrics/sql/android/power_profile_data.sql
new file mode 100644
index 000000000..c124c8a74
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/power_profile_data.sql
@@ -0,0 +1,1592 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+INSERT OR REPLACE INTO power_profile VALUES
+("marlin", 0, 0, 307200, 11.272),
+("marlin", 0, 0, 384000, 14.842),
+("marlin", 0, 0, 460800, 18.497),
+("marlin", 0, 0, 537600, 22.518),
+("marlin", 0, 0, 614400, 25.967),
+("marlin", 0, 0, 691200, 31.694),
+("marlin", 0, 0, 768000, 37.673),
+("marlin", 0, 0, 844800, 42.859),
+("marlin", 0, 0, 902600, 46.872),
+("marlin", 0, 0, 979200, 57.92),
+("marlin", 0, 0, 1056000, 67.561),
+("marlin", 0, 0, 1132800, 76.303),
+("marlin", 0, 0, 1209600, 87.613),
+("marlin", 0, 0, 1286400, 97.045),
+("marlin", 0, 0, 1363200, 109.544),
+("marlin", 0, 0, 1440000, 122.054),
+("marlin", 0, 0, 1516800, 136.345),
+("marlin", 0, 0, 1593600, 154.435),
+("marlin", 1, 0, 307200, 11.272),
+("marlin", 1, 0, 384000, 14.842),
+("marlin", 1, 0, 460800, 18.497),
+("marlin", 1, 0, 537600, 22.518),
+("marlin", 1, 0, 614400, 25.967),
+("marlin", 1, 0, 691200, 31.694),
+("marlin", 1, 0, 768000, 37.673),
+("marlin", 1, 0, 844800, 42.859),
+("marlin", 1, 0, 902600, 46.872),
+("marlin", 1, 0, 979200, 57.92),
+("marlin", 1, 0, 1056000, 67.561),
+("marlin", 1, 0, 1132800, 76.303),
+("marlin", 1, 0, 1209600, 87.613),
+("marlin", 1, 0, 1286400, 97.045),
+("marlin", 1, 0, 1363200, 109.544),
+("marlin", 1, 0, 1440000, 122.054),
+("marlin", 1, 0, 1516800, 136.345),
+("marlin", 1, 0, 1593600, 154.435),
+("marlin", 2, 1, 307200, 7.055),
+("marlin", 2, 1, 384000, 11.483),
+("marlin", 2, 1, 460800, 14.979),
+("marlin", 2, 1, 537600, 19.642),
+("marlin", 2, 1, 614400, 23.167),
+("marlin", 2, 1, 691200, 27.479),
+("marlin", 2, 1, 748800, 31.632),
+("marlin", 2, 1, 825600, 39.192),
+("marlin", 2, 1, 902400, 47.817),
+("marlin", 2, 1, 979200, 55.659),
+("marlin", 2, 1, 1056000, 64.908),
+("marlin", 2, 1, 1132800, 73.824),
+("marlin", 2, 1, 1209600, 85.299),
+("marlin", 2, 1, 1286400, 96.036),
+("marlin", 2, 1, 1363200, 109.233),
+("marlin", 2, 1, 1440000, 118.56),
+("marlin", 2, 1, 1516800, 132.959),
+("marlin", 2, 1, 1593600, 143.692),
+("marlin", 2, 1, 1670400, 161.378),
+("marlin", 2, 1, 1747200, 180.616),
+("marlin", 2, 1, 1824000, 193.897),
+("marlin", 2, 1, 1900800, 214.361),
+("marlin", 2, 1, 1977600, 238.338),
+("marlin", 2, 1, 2054400, 265.759),
+("marlin", 2, 1, 2150400, 297.918),
+("marlin", 3, 1, 307200, 7.055),
+("marlin", 3, 1, 384000, 11.483),
+("marlin", 3, 1, 460800, 14.979),
+("marlin", 3, 1, 537600, 19.642),
+("marlin", 3, 1, 614400, 23.167),
+("marlin", 3, 1, 691200, 27.479),
+("marlin", 3, 1, 748800, 31.632),
+("marlin", 3, 1, 825600, 39.192),
+("marlin", 3, 1, 902400, 47.817),
+("marlin", 3, 1, 979200, 55.659),
+("marlin", 3, 1, 1056000, 64.908),
+("marlin", 3, 1, 1132800, 73.824),
+("marlin", 3, 1, 1209600, 85.299),
+("marlin", 3, 1, 1286400, 96.036),
+("marlin", 3, 1, 1363200, 109.233),
+("marlin", 3, 1, 1440000, 118.56),
+("marlin", 3, 1, 1516800, 132.959),
+("marlin", 3, 1, 1593600, 143.692),
+("marlin", 3, 1, 1670400, 161.378),
+("marlin", 3, 1, 1747200, 180.616),
+("marlin", 3, 1, 1824000, 193.897),
+("marlin", 3, 1, 1900800, 214.361),
+("marlin", 3, 1, 1977600, 238.338),
+("marlin", 3, 1, 2054400, 265.759),
+("marlin", 3, 1, 2150400, 297.918),
+("sailfish", 0, 0, 307200, 11.272),
+("sailfish", 0, 0, 384000, 14.842),
+("sailfish", 0, 0, 460800, 18.497),
+("sailfish", 0, 0, 537600, 22.518),
+("sailfish", 0, 0, 614400, 25.967),
+("sailfish", 0, 0, 691200, 31.694),
+("sailfish", 0, 0, 768000, 37.673),
+("sailfish", 0, 0, 844800, 42.859),
+("sailfish", 0, 0, 902600, 46.872),
+("sailfish", 0, 0, 979200, 57.92),
+("sailfish", 0, 0, 1056000, 67.561),
+("sailfish", 0, 0, 1132800, 76.303),
+("sailfish", 0, 0, 1209600, 87.613),
+("sailfish", 0, 0, 1286400, 97.045),
+("sailfish", 0, 0, 1363200, 109.544),
+("sailfish", 0, 0, 1440000, 122.054),
+("sailfish", 0, 0, 1516800, 136.345),
+("sailfish", 0, 0, 1593600, 154.435),
+("sailfish", 1, 0, 307200, 11.272),
+("sailfish", 1, 0, 384000, 14.842),
+("sailfish", 1, 0, 460800, 18.497),
+("sailfish", 1, 0, 537600, 22.518),
+("sailfish", 1, 0, 614400, 25.967),
+("sailfish", 1, 0, 691200, 31.694),
+("sailfish", 1, 0, 768000, 37.673),
+("sailfish", 1, 0, 844800, 42.859),
+("sailfish", 1, 0, 902600, 46.872),
+("sailfish", 1, 0, 979200, 57.92),
+("sailfish", 1, 0, 1056000, 67.561),
+("sailfish", 1, 0, 1132800, 76.303),
+("sailfish", 1, 0, 1209600, 87.613),
+("sailfish", 1, 0, 1286400, 97.045),
+("sailfish", 1, 0, 1363200, 109.544),
+("sailfish", 1, 0, 1440000, 122.054),
+("sailfish", 1, 0, 1516800, 136.345),
+("sailfish", 1, 0, 1593600, 154.435),
+("sailfish", 2, 1, 307200, 7.055),
+("sailfish", 2, 1, 384000, 11.483),
+("sailfish", 2, 1, 460800, 14.979),
+("sailfish", 2, 1, 537600, 19.642),
+("sailfish", 2, 1, 614400, 23.167),
+("sailfish", 2, 1, 691200, 27.479),
+("sailfish", 2, 1, 748800, 31.632),
+("sailfish", 2, 1, 825600, 39.192),
+("sailfish", 2, 1, 902400, 47.817),
+("sailfish", 2, 1, 979200, 55.659),
+("sailfish", 2, 1, 1056000, 64.908),
+("sailfish", 2, 1, 1132800, 73.824),
+("sailfish", 2, 1, 1209600, 85.299),
+("sailfish", 2, 1, 1286400, 96.036),
+("sailfish", 2, 1, 1363200, 109.233),
+("sailfish", 2, 1, 1440000, 118.56),
+("sailfish", 2, 1, 1516800, 132.959),
+("sailfish", 2, 1, 1593600, 143.692),
+("sailfish", 2, 1, 1670400, 161.378),
+("sailfish", 2, 1, 1747200, 180.616),
+("sailfish", 2, 1, 1824000, 193.897),
+("sailfish", 2, 1, 1900800, 214.361),
+("sailfish", 2, 1, 1977600, 238.338),
+("sailfish", 2, 1, 2054400, 265.759),
+("sailfish", 2, 1, 2150400, 297.918),
+("sailfish", 3, 1, 307200, 7.055),
+("sailfish", 3, 1, 384000, 11.483),
+("sailfish", 3, 1, 460800, 14.979),
+("sailfish", 3, 1, 537600, 19.642),
+("sailfish", 3, 1, 614400, 23.167),
+("sailfish", 3, 1, 691200, 27.479),
+("sailfish", 3, 1, 748800, 31.632),
+("sailfish", 3, 1, 825600, 39.192),
+("sailfish", 3, 1, 902400, 47.817),
+("sailfish", 3, 1, 979200, 55.659),
+("sailfish", 3, 1, 1056000, 64.908),
+("sailfish", 3, 1, 1132800, 73.824),
+("sailfish", 3, 1, 1209600, 85.299),
+("sailfish", 3, 1, 1286400, 96.036),
+("sailfish", 3, 1, 1363200, 109.233),
+("sailfish", 3, 1, 1440000, 118.56),
+("sailfish", 3, 1, 1516800, 132.959),
+("sailfish", 3, 1, 1593600, 143.692),
+("sailfish", 3, 1, 1670400, 161.378),
+("sailfish", 3, 1, 1747200, 180.616),
+("sailfish", 3, 1, 1824000, 193.897),
+("sailfish", 3, 1, 1900800, 214.361),
+("sailfish", 3, 1, 1977600, 238.338),
+("sailfish", 3, 1, 2054400, 265.759),
+("sailfish", 3, 1, 2150400, 297.918),
+("walleye", 0, 0, 300000, 3.685),
+("walleye", 0, 0, 364800, 3.598),
+("walleye", 0, 0, 441600, 3.621),
+("walleye", 0, 0, 518400, 4.202),
+("walleye", 0, 0, 595200, 4.935),
+("walleye", 0, 0, 672000, 5.633),
+("walleye", 0, 0, 748800, 6.216),
+("walleye", 0, 0, 825600, 6.71),
+("walleye", 0, 0, 883200, 7.557),
+("walleye", 0, 0, 960000, 8.687),
+("walleye", 0, 0, 1036800, 9.882),
+("walleye", 0, 0, 1094400, 10.95),
+("walleye", 0, 0, 1171200, 12.075),
+("walleye", 0, 0, 1248000, 12.875),
+("walleye", 0, 0, 1324800, 14.424),
+("walleye", 0, 0, 1401600, 15.653),
+("walleye", 0, 0, 1478400, 17.345),
+("walleye", 0, 0, 1555200, 18.71),
+("walleye", 0, 0, 1670400, 21.587),
+("walleye", 0, 0, 1747200, 25.43),
+("walleye", 0, 0, 1824000, 27.165),
+("walleye", 0, 0, 1900800, 31.671),
+("walleye", 1, 0, 300000, 3.685),
+("walleye", 1, 0, 364800, 3.598),
+("walleye", 1, 0, 441600, 3.621),
+("walleye", 1, 0, 518400, 4.202),
+("walleye", 1, 0, 595200, 4.935),
+("walleye", 1, 0, 672000, 5.633),
+("walleye", 1, 0, 748800, 6.216),
+("walleye", 1, 0, 825600, 6.71),
+("walleye", 1, 0, 883200, 7.557),
+("walleye", 1, 0, 960000, 8.687),
+("walleye", 1, 0, 1036800, 9.882),
+("walleye", 1, 0, 1094400, 10.95),
+("walleye", 1, 0, 1171200, 12.075),
+("walleye", 1, 0, 1248000, 12.875),
+("walleye", 1, 0, 1324800, 14.424),
+("walleye", 1, 0, 1401600, 15.653),
+("walleye", 1, 0, 1478400, 17.345),
+("walleye", 1, 0, 1555200, 18.71),
+("walleye", 1, 0, 1670400, 21.587),
+("walleye", 1, 0, 1747200, 25.43),
+("walleye", 1, 0, 1824000, 27.165),
+("walleye", 1, 0, 1900800, 31.671),
+("walleye", 2, 0, 300000, 3.685),
+("walleye", 2, 0, 364800, 3.598),
+("walleye", 2, 0, 441600, 3.621),
+("walleye", 2, 0, 518400, 4.202),
+("walleye", 2, 0, 595200, 4.935),
+("walleye", 2, 0, 672000, 5.633),
+("walleye", 2, 0, 748800, 6.216),
+("walleye", 2, 0, 825600, 6.71),
+("walleye", 2, 0, 883200, 7.557),
+("walleye", 2, 0, 960000, 8.687),
+("walleye", 2, 0, 1036800, 9.882),
+("walleye", 2, 0, 1094400, 10.95),
+("walleye", 2, 0, 1171200, 12.075),
+("walleye", 2, 0, 1248000, 12.875),
+("walleye", 2, 0, 1324800, 14.424),
+("walleye", 2, 0, 1401600, 15.653),
+("walleye", 2, 0, 1478400, 17.345),
+("walleye", 2, 0, 1555200, 18.71),
+("walleye", 2, 0, 1670400, 21.587),
+("walleye", 2, 0, 1747200, 25.43),
+("walleye", 2, 0, 1824000, 27.165),
+("walleye", 2, 0, 1900800, 31.671),
+("walleye", 3, 0, 300000, 3.685),
+("walleye", 3, 0, 364800, 3.598),
+("walleye", 3, 0, 441600, 3.621),
+("walleye", 3, 0, 518400, 4.202),
+("walleye", 3, 0, 595200, 4.935),
+("walleye", 3, 0, 672000, 5.633),
+("walleye", 3, 0, 748800, 6.216),
+("walleye", 3, 0, 825600, 6.71),
+("walleye", 3, 0, 883200, 7.557),
+("walleye", 3, 0, 960000, 8.687),
+("walleye", 3, 0, 1036800, 9.882),
+("walleye", 3, 0, 1094400, 10.95),
+("walleye", 3, 0, 1171200, 12.075),
+("walleye", 3, 0, 1248000, 12.875),
+("walleye", 3, 0, 1324800, 14.424),
+("walleye", 3, 0, 1401600, 15.653),
+("walleye", 3, 0, 1478400, 17.345),
+("walleye", 3, 0, 1555200, 18.71),
+("walleye", 3, 0, 1670400, 21.587),
+("walleye", 3, 0, 1747200, 25.43),
+("walleye", 3, 0, 1824000, 27.165),
+("walleye", 3, 0, 1900800, 31.671),
+("walleye", 4, 1, 300000, 10.722),
+("walleye", 4, 1, 345600, 11.52),
+("walleye", 4, 1, 422400, 14.105),
+("walleye", 4, 1, 499200, 16.68),
+("walleye", 4, 1, 576000, 18.946),
+("walleye", 4, 1, 652800, 21.265),
+("walleye", 4, 1, 729600, 23.432),
+("walleye", 4, 1, 806400, 26.019),
+("walleye", 4, 1, 902400, 28.856),
+("walleye", 4, 1, 979200, 31.085),
+("walleye", 4, 1, 1056000, 33.615),
+("walleye", 4, 1, 1132800, 35.76),
+("walleye", 4, 1, 1190400, 40.608),
+("walleye", 4, 1, 1267200, 43.284),
+("walleye", 4, 1, 1344000, 47.347),
+("walleye", 4, 1, 1420800, 52.231),
+("walleye", 4, 1, 1497600, 57.225),
+("walleye", 4, 1, 1574400, 63.138),
+("walleye", 4, 1, 1651200, 69.251),
+("walleye", 4, 1, 1728000, 76.449),
+("walleye", 4, 1, 1804800, 84.71),
+("walleye", 4, 1, 1881600, 102.551),
+("walleye", 4, 1, 1958400, 107.115),
+("walleye", 4, 1, 2035200, 129.689),
+("walleye", 4, 1, 2112000, 135.832),
+("walleye", 4, 1, 2208000, 164.674),
+("walleye", 4, 1, 2265600, 180.279),
+("walleye", 4, 1, 2323200, 197.024),
+("walleye", 4, 1, 2342400, 204.511),
+("walleye", 4, 1, 2361600, 211.886),
+("walleye", 4, 1, 2457600, 212.147),
+("walleye", 5, 1, 300000, 10.722),
+("walleye", 5, 1, 345600, 11.52),
+("walleye", 5, 1, 422400, 14.105),
+("walleye", 5, 1, 499200, 16.68),
+("walleye", 5, 1, 576000, 18.946),
+("walleye", 5, 1, 652800, 21.265),
+("walleye", 5, 1, 729600, 23.432),
+("walleye", 5, 1, 806400, 26.019),
+("walleye", 5, 1, 902400, 28.856),
+("walleye", 5, 1, 979200, 31.085),
+("walleye", 5, 1, 1056000, 33.615),
+("walleye", 5, 1, 1132800, 35.76),
+("walleye", 5, 1, 1190400, 40.608),
+("walleye", 5, 1, 1267200, 43.284),
+("walleye", 5, 1, 1344000, 47.347),
+("walleye", 5, 1, 1420800, 52.231),
+("walleye", 5, 1, 1497600, 57.225),
+("walleye", 5, 1, 1574400, 63.138),
+("walleye", 5, 1, 1651200, 69.251),
+("walleye", 5, 1, 1728000, 76.449),
+("walleye", 5, 1, 1804800, 84.71),
+("walleye", 5, 1, 1881600, 102.551),
+("walleye", 5, 1, 1958400, 107.115),
+("walleye", 5, 1, 2035200, 129.689),
+("walleye", 5, 1, 2112000, 135.832),
+("walleye", 5, 1, 2208000, 164.674),
+("walleye", 5, 1, 2265600, 180.279),
+("walleye", 5, 1, 2323200, 197.024),
+("walleye", 5, 1, 2342400, 204.511),
+("walleye", 5, 1, 2361600, 211.886),
+("walleye", 5, 1, 2457600, 212.147),
+("walleye", 6, 1, 300000, 10.722),
+("walleye", 6, 1, 345600, 11.52),
+("walleye", 6, 1, 422400, 14.105),
+("walleye", 6, 1, 499200, 16.68),
+("walleye", 6, 1, 576000, 18.946),
+("walleye", 6, 1, 652800, 21.265),
+("walleye", 6, 1, 729600, 23.432),
+("walleye", 6, 1, 806400, 26.019),
+("walleye", 6, 1, 902400, 28.856),
+("walleye", 6, 1, 979200, 31.085),
+("walleye", 6, 1, 1056000, 33.615),
+("walleye", 6, 1, 1132800, 35.76),
+("walleye", 6, 1, 1190400, 40.608),
+("walleye", 6, 1, 1267200, 43.284),
+("walleye", 6, 1, 1344000, 47.347),
+("walleye", 6, 1, 1420800, 52.231),
+("walleye", 6, 1, 1497600, 57.225),
+("walleye", 6, 1, 1574400, 63.138),
+("walleye", 6, 1, 1651200, 69.251),
+("walleye", 6, 1, 1728000, 76.449),
+("walleye", 6, 1, 1804800, 84.71),
+("walleye", 6, 1, 1881600, 102.551),
+("walleye", 6, 1, 1958400, 107.115),
+("walleye", 6, 1, 2035200, 129.689),
+("walleye", 6, 1, 2112000, 135.832),
+("walleye", 6, 1, 2208000, 164.674),
+("walleye", 6, 1, 2265600, 180.279),
+("walleye", 6, 1, 2323200, 197.024),
+("walleye", 6, 1, 2342400, 204.511),
+("walleye", 6, 1, 2361600, 211.886),
+("walleye", 6, 1, 2457600, 212.147),
+("walleye", 7, 1, 300000, 10.722),
+("walleye", 7, 1, 345600, 11.52),
+("walleye", 7, 1, 422400, 14.105),
+("walleye", 7, 1, 499200, 16.68),
+("walleye", 7, 1, 576000, 18.946),
+("walleye", 7, 1, 652800, 21.265),
+("walleye", 7, 1, 729600, 23.432),
+("walleye", 7, 1, 806400, 26.019),
+("walleye", 7, 1, 902400, 28.856),
+("walleye", 7, 1, 979200, 31.085),
+("walleye", 7, 1, 1056000, 33.615),
+("walleye", 7, 1, 1132800, 35.76),
+("walleye", 7, 1, 1190400, 40.608),
+("walleye", 7, 1, 1267200, 43.284),
+("walleye", 7, 1, 1344000, 47.347),
+("walleye", 7, 1, 1420800, 52.231),
+("walleye", 7, 1, 1497600, 57.225),
+("walleye", 7, 1, 1574400, 63.138),
+("walleye", 7, 1, 1651200, 69.251),
+("walleye", 7, 1, 1728000, 76.449),
+("walleye", 7, 1, 1804800, 84.71),
+("walleye", 7, 1, 1881600, 102.551),
+("walleye", 7, 1, 1958400, 107.115),
+("walleye", 7, 1, 2035200, 129.689),
+("walleye", 7, 1, 2112000, 135.832),
+("walleye", 7, 1, 2208000, 164.674),
+("walleye", 7, 1, 2265600, 180.279),
+("walleye", 7, 1, 2323200, 197.024),
+("walleye", 7, 1, 2342400, 204.511),
+("walleye", 7, 1, 2361600, 211.886),
+("walleye", 7, 1, 2457600, 212.147),
+("taimen", 0, 0, 300000, 3.685),
+("taimen", 0, 0, 364800, 3.598),
+("taimen", 0, 0, 441600, 3.621),
+("taimen", 0, 0, 518400, 4.202),
+("taimen", 0, 0, 595200, 4.935),
+("taimen", 0, 0, 672000, 5.633),
+("taimen", 0, 0, 748800, 6.216),
+("taimen", 0, 0, 825600, 6.71),
+("taimen", 0, 0, 883200, 7.557),
+("taimen", 0, 0, 960000, 8.687),
+("taimen", 0, 0, 1036800, 9.882),
+("taimen", 0, 0, 1094400, 10.95),
+("taimen", 0, 0, 1171200, 12.075),
+("taimen", 0, 0, 1248000, 12.875),
+("taimen", 0, 0, 1324800, 14.424),
+("taimen", 0, 0, 1401600, 15.653),
+("taimen", 0, 0, 1478400, 17.345),
+("taimen", 0, 0, 1555200, 18.71),
+("taimen", 0, 0, 1670400, 21.587),
+("taimen", 0, 0, 1747200, 25.43),
+("taimen", 0, 0, 1824000, 27.165),
+("taimen", 0, 0, 1900800, 31.671),
+("taimen", 1, 0, 300000, 3.685),
+("taimen", 1, 0, 364800, 3.598),
+("taimen", 1, 0, 441600, 3.621),
+("taimen", 1, 0, 518400, 4.202),
+("taimen", 1, 0, 595200, 4.935),
+("taimen", 1, 0, 672000, 5.633),
+("taimen", 1, 0, 748800, 6.216),
+("taimen", 1, 0, 825600, 6.71),
+("taimen", 1, 0, 883200, 7.557),
+("taimen", 1, 0, 960000, 8.687),
+("taimen", 1, 0, 1036800, 9.882),
+("taimen", 1, 0, 1094400, 10.95),
+("taimen", 1, 0, 1171200, 12.075),
+("taimen", 1, 0, 1248000, 12.875),
+("taimen", 1, 0, 1324800, 14.424),
+("taimen", 1, 0, 1401600, 15.653),
+("taimen", 1, 0, 1478400, 17.345),
+("taimen", 1, 0, 1555200, 18.71),
+("taimen", 1, 0, 1670400, 21.587),
+("taimen", 1, 0, 1747200, 25.43),
+("taimen", 1, 0, 1824000, 27.165),
+("taimen", 1, 0, 1900800, 31.671),
+("taimen", 2, 0, 300000, 3.685),
+("taimen", 2, 0, 364800, 3.598),
+("taimen", 2, 0, 441600, 3.621),
+("taimen", 2, 0, 518400, 4.202),
+("taimen", 2, 0, 595200, 4.935),
+("taimen", 2, 0, 672000, 5.633),
+("taimen", 2, 0, 748800, 6.216),
+("taimen", 2, 0, 825600, 6.71),
+("taimen", 2, 0, 883200, 7.557),
+("taimen", 2, 0, 960000, 8.687),
+("taimen", 2, 0, 1036800, 9.882),
+("taimen", 2, 0, 1094400, 10.95),
+("taimen", 2, 0, 1171200, 12.075),
+("taimen", 2, 0, 1248000, 12.875),
+("taimen", 2, 0, 1324800, 14.424),
+("taimen", 2, 0, 1401600, 15.653),
+("taimen", 2, 0, 1478400, 17.345),
+("taimen", 2, 0, 1555200, 18.71),
+("taimen", 2, 0, 1670400, 21.587),
+("taimen", 2, 0, 1747200, 25.43),
+("taimen", 2, 0, 1824000, 27.165),
+("taimen", 2, 0, 1900800, 31.671),
+("taimen", 3, 0, 300000, 3.685),
+("taimen", 3, 0, 364800, 3.598),
+("taimen", 3, 0, 441600, 3.621),
+("taimen", 3, 0, 518400, 4.202),
+("taimen", 3, 0, 595200, 4.935),
+("taimen", 3, 0, 672000, 5.633),
+("taimen", 3, 0, 748800, 6.216),
+("taimen", 3, 0, 825600, 6.71),
+("taimen", 3, 0, 883200, 7.557),
+("taimen", 3, 0, 960000, 8.687),
+("taimen", 3, 0, 1036800, 9.882),
+("taimen", 3, 0, 1094400, 10.95),
+("taimen", 3, 0, 1171200, 12.075),
+("taimen", 3, 0, 1248000, 12.875),
+("taimen", 3, 0, 1324800, 14.424),
+("taimen", 3, 0, 1401600, 15.653),
+("taimen", 3, 0, 1478400, 17.345),
+("taimen", 3, 0, 1555200, 18.71),
+("taimen", 3, 0, 1670400, 21.587),
+("taimen", 3, 0, 1747200, 25.43),
+("taimen", 3, 0, 1824000, 27.165),
+("taimen", 3, 0, 1900800, 31.671),
+("taimen", 4, 1, 300000, 10.722),
+("taimen", 4, 1, 345600, 11.52),
+("taimen", 4, 1, 422400, 14.105),
+("taimen", 4, 1, 499200, 16.68),
+("taimen", 4, 1, 576000, 18.946),
+("taimen", 4, 1, 652800, 21.265),
+("taimen", 4, 1, 729600, 23.432),
+("taimen", 4, 1, 806400, 26.019),
+("taimen", 4, 1, 902400, 28.856),
+("taimen", 4, 1, 979200, 31.085),
+("taimen", 4, 1, 1056000, 33.615),
+("taimen", 4, 1, 1132800, 35.76),
+("taimen", 4, 1, 1190400, 40.608),
+("taimen", 4, 1, 1267200, 43.284),
+("taimen", 4, 1, 1344000, 47.347),
+("taimen", 4, 1, 1420800, 52.231),
+("taimen", 4, 1, 1497600, 57.225),
+("taimen", 4, 1, 1574400, 63.138),
+("taimen", 4, 1, 1651200, 69.251),
+("taimen", 4, 1, 1728000, 76.449),
+("taimen", 4, 1, 1804800, 84.71),
+("taimen", 4, 1, 1881600, 102.551),
+("taimen", 4, 1, 1958400, 107.115),
+("taimen", 4, 1, 2035200, 129.689),
+("taimen", 4, 1, 2112000, 135.832),
+("taimen", 4, 1, 2208000, 164.674),
+("taimen", 4, 1, 2265600, 180.279),
+("taimen", 4, 1, 2323200, 197.024),
+("taimen", 4, 1, 2342400, 204.511),
+("taimen", 4, 1, 2361600, 211.886),
+("taimen", 4, 1, 2457600, 212.147),
+("taimen", 5, 1, 300000, 10.722),
+("taimen", 5, 1, 345600, 11.52),
+("taimen", 5, 1, 422400, 14.105),
+("taimen", 5, 1, 499200, 16.68),
+("taimen", 5, 1, 576000, 18.946),
+("taimen", 5, 1, 652800, 21.265),
+("taimen", 5, 1, 729600, 23.432),
+("taimen", 5, 1, 806400, 26.019),
+("taimen", 5, 1, 902400, 28.856),
+("taimen", 5, 1, 979200, 31.085),
+("taimen", 5, 1, 1056000, 33.615),
+("taimen", 5, 1, 1132800, 35.76),
+("taimen", 5, 1, 1190400, 40.608),
+("taimen", 5, 1, 1267200, 43.284),
+("taimen", 5, 1, 1344000, 47.347),
+("taimen", 5, 1, 1420800, 52.231),
+("taimen", 5, 1, 1497600, 57.225),
+("taimen", 5, 1, 1574400, 63.138),
+("taimen", 5, 1, 1651200, 69.251),
+("taimen", 5, 1, 1728000, 76.449),
+("taimen", 5, 1, 1804800, 84.71),
+("taimen", 5, 1, 1881600, 102.551),
+("taimen", 5, 1, 1958400, 107.115),
+("taimen", 5, 1, 2035200, 129.689),
+("taimen", 5, 1, 2112000, 135.832),
+("taimen", 5, 1, 2208000, 164.674),
+("taimen", 5, 1, 2265600, 180.279),
+("taimen", 5, 1, 2323200, 197.024),
+("taimen", 5, 1, 2342400, 204.511),
+("taimen", 5, 1, 2361600, 211.886),
+("taimen", 5, 1, 2457600, 212.147),
+("taimen", 6, 1, 300000, 10.722),
+("taimen", 6, 1, 345600, 11.52),
+("taimen", 6, 1, 422400, 14.105),
+("taimen", 6, 1, 499200, 16.68),
+("taimen", 6, 1, 576000, 18.946),
+("taimen", 6, 1, 652800, 21.265),
+("taimen", 6, 1, 729600, 23.432),
+("taimen", 6, 1, 806400, 26.019),
+("taimen", 6, 1, 902400, 28.856),
+("taimen", 6, 1, 979200, 31.085),
+("taimen", 6, 1, 1056000, 33.615),
+("taimen", 6, 1, 1132800, 35.76),
+("taimen", 6, 1, 1190400, 40.608),
+("taimen", 6, 1, 1267200, 43.284),
+("taimen", 6, 1, 1344000, 47.347),
+("taimen", 6, 1, 1420800, 52.231),
+("taimen", 6, 1, 1497600, 57.225),
+("taimen", 6, 1, 1574400, 63.138),
+("taimen", 6, 1, 1651200, 69.251),
+("taimen", 6, 1, 1728000, 76.449),
+("taimen", 6, 1, 1804800, 84.71),
+("taimen", 6, 1, 1881600, 102.551),
+("taimen", 6, 1, 1958400, 107.115),
+("taimen", 6, 1, 2035200, 129.689),
+("taimen", 6, 1, 2112000, 135.832),
+("taimen", 6, 1, 2208000, 164.674),
+("taimen", 6, 1, 2265600, 180.279),
+("taimen", 6, 1, 2323200, 197.024),
+("taimen", 6, 1, 2342400, 204.511),
+("taimen", 6, 1, 2361600, 211.886),
+("taimen", 6, 1, 2457600, 212.147),
+("taimen", 7, 1, 300000, 10.722),
+("taimen", 7, 1, 345600, 11.52),
+("taimen", 7, 1, 422400, 14.105),
+("taimen", 7, 1, 499200, 16.68),
+("taimen", 7, 1, 576000, 18.946),
+("taimen", 7, 1, 652800, 21.265),
+("taimen", 7, 1, 729600, 23.432),
+("taimen", 7, 1, 806400, 26.019),
+("taimen", 7, 1, 902400, 28.856),
+("taimen", 7, 1, 979200, 31.085),
+("taimen", 7, 1, 1056000, 33.615),
+("taimen", 7, 1, 1132800, 35.76),
+("taimen", 7, 1, 1190400, 40.608),
+("taimen", 7, 1, 1267200, 43.284),
+("taimen", 7, 1, 1344000, 47.347),
+("taimen", 7, 1, 1420800, 52.231),
+("taimen", 7, 1, 1497600, 57.225),
+("taimen", 7, 1, 1574400, 63.138),
+("taimen", 7, 1, 1651200, 69.251),
+("taimen", 7, 1, 1728000, 76.449),
+("taimen", 7, 1, 1804800, 84.71),
+("taimen", 7, 1, 1881600, 102.551),
+("taimen", 7, 1, 1958400, 107.115),
+("taimen", 7, 1, 2035200, 129.689),
+("taimen", 7, 1, 2112000, 135.832),
+("taimen", 7, 1, 2208000, 164.674),
+("taimen", 7, 1, 2265600, 180.279),
+("taimen", 7, 1, 2323200, 197.024),
+("taimen", 7, 1, 2342400, 204.511),
+("taimen", 7, 1, 2361600, 211.886),
+("taimen", 7, 1, 2457600, 212.147),
+("crosshatch", 0, 0, 300000, 2.27),
+("crosshatch", 0, 0, 403200, 3.63),
+("crosshatch", 0, 0, 480000, 4.36),
+("crosshatch", 0, 0, 576000, 5.21),
+("crosshatch", 0, 0, 652800, 5.47),
+("crosshatch", 0, 0, 748800, 6.74),
+("crosshatch", 0, 0, 825600, 7.69),
+("crosshatch", 0, 0, 902400, 8.57),
+("crosshatch", 0, 0, 979200, 9.42),
+("crosshatch", 0, 0, 1056000, 10.41),
+("crosshatch", 0, 0, 1132800, 11.56),
+("crosshatch", 0, 0, 1228800, 12.87),
+("crosshatch", 0, 0, 1324800, 14.61),
+("crosshatch", 0, 0, 1420800, 16.49),
+("crosshatch", 0, 0, 1516800, 18.9),
+("crosshatch", 0, 0, 1612800, 21.62),
+("crosshatch", 0, 0, 1689600, 24.47),
+("crosshatch", 0, 0, 1766400, 26.45),
+("crosshatch", 1, 0, 300000, 2.27),
+("crosshatch", 1, 0, 403200, 3.63),
+("crosshatch", 1, 0, 480000, 4.36),
+("crosshatch", 1, 0, 576000, 5.21),
+("crosshatch", 1, 0, 652800, 5.47),
+("crosshatch", 1, 0, 748800, 6.74),
+("crosshatch", 1, 0, 825600, 7.69),
+("crosshatch", 1, 0, 902400, 8.57),
+("crosshatch", 1, 0, 979200, 9.42),
+("crosshatch", 1, 0, 1056000, 10.41),
+("crosshatch", 1, 0, 1132800, 11.56),
+("crosshatch", 1, 0, 1228800, 12.87),
+("crosshatch", 1, 0, 1324800, 14.61),
+("crosshatch", 1, 0, 1420800, 16.49),
+("crosshatch", 1, 0, 1516800, 18.9),
+("crosshatch", 1, 0, 1612800, 21.62),
+("crosshatch", 1, 0, 1689600, 24.47),
+("crosshatch", 1, 0, 1766400, 26.45),
+("crosshatch", 2, 0, 300000, 2.27),
+("crosshatch", 2, 0, 403200, 3.63),
+("crosshatch", 2, 0, 480000, 4.36),
+("crosshatch", 2, 0, 576000, 5.21),
+("crosshatch", 2, 0, 652800, 5.47),
+("crosshatch", 2, 0, 748800, 6.74),
+("crosshatch", 2, 0, 825600, 7.69),
+("crosshatch", 2, 0, 902400, 8.57),
+("crosshatch", 2, 0, 979200, 9.42),
+("crosshatch", 2, 0, 1056000, 10.41),
+("crosshatch", 2, 0, 1132800, 11.56),
+("crosshatch", 2, 0, 1228800, 12.87),
+("crosshatch", 2, 0, 1324800, 14.61),
+("crosshatch", 2, 0, 1420800, 16.49),
+("crosshatch", 2, 0, 1516800, 18.9),
+("crosshatch", 2, 0, 1612800, 21.62),
+("crosshatch", 2, 0, 1689600, 24.47),
+("crosshatch", 2, 0, 1766400, 26.45),
+("crosshatch", 3, 0, 300000, 2.27),
+("crosshatch", 3, 0, 403200, 3.63),
+("crosshatch", 3, 0, 480000, 4.36),
+("crosshatch", 3, 0, 576000, 5.21),
+("crosshatch", 3, 0, 652800, 5.47),
+("crosshatch", 3, 0, 748800, 6.74),
+("crosshatch", 3, 0, 825600, 7.69),
+("crosshatch", 3, 0, 902400, 8.57),
+("crosshatch", 3, 0, 979200, 9.42),
+("crosshatch", 3, 0, 1056000, 10.41),
+("crosshatch", 3, 0, 1132800, 11.56),
+("crosshatch", 3, 0, 1228800, 12.87),
+("crosshatch", 3, 0, 1324800, 14.61),
+("crosshatch", 3, 0, 1420800, 16.49),
+("crosshatch", 3, 0, 1516800, 18.9),
+("crosshatch", 3, 0, 1612800, 21.62),
+("crosshatch", 3, 0, 1689600, 24.47),
+("crosshatch", 3, 0, 1766400, 26.45),
+("crosshatch", 4, 1, 825600, 28.88),
+("crosshatch", 4, 1, 902400, 32.4),
+("crosshatch", 4, 1, 979200, 36.46),
+("crosshatch", 4, 1, 1056000, 39.99),
+("crosshatch", 4, 1, 1209600, 47.23),
+("crosshatch", 4, 1, 1286400, 51.39),
+("crosshatch", 4, 1, 1363200, 56.9),
+("crosshatch", 4, 1, 1459200, 64.26),
+("crosshatch", 4, 1, 1536000, 69.65),
+("crosshatch", 4, 1, 1612800, 75.14),
+("crosshatch", 4, 1, 1689600, 83.16),
+("crosshatch", 4, 1, 1766400, 91.75),
+("crosshatch", 4, 1, 1843200, 100.66),
+("crosshatch", 4, 1, 1920000, 111.45),
+("crosshatch", 4, 1, 1996800, 122.23),
+("crosshatch", 4, 1, 2092800, 143.54),
+("crosshatch", 4, 1, 2169600, 147.54),
+("crosshatch", 4, 1, 2246400, 153.09),
+("crosshatch", 4, 1, 2323200, 166.44),
+("crosshatch", 4, 1, 2400000, 184.69),
+("crosshatch", 4, 1, 2476800, 204.14),
+("crosshatch", 4, 1, 2553600, 223.37),
+("crosshatch", 4, 1, 2649600, 253.77),
+("crosshatch", 5, 1, 825600, 28.88),
+("crosshatch", 5, 1, 902400, 32.4),
+("crosshatch", 5, 1, 979200, 36.46),
+("crosshatch", 5, 1, 1056000, 39.99),
+("crosshatch", 5, 1, 1209600, 47.23),
+("crosshatch", 5, 1, 1286400, 51.39),
+("crosshatch", 5, 1, 1363200, 56.9),
+("crosshatch", 5, 1, 1459200, 64.26),
+("crosshatch", 5, 1, 1536000, 69.65),
+("crosshatch", 5, 1, 1612800, 75.14),
+("crosshatch", 5, 1, 1689600, 83.16),
+("crosshatch", 5, 1, 1766400, 91.75),
+("crosshatch", 5, 1, 1843200, 100.66),
+("crosshatch", 5, 1, 1920000, 111.45),
+("crosshatch", 5, 1, 1996800, 122.23),
+("crosshatch", 5, 1, 2092800, 143.54),
+("crosshatch", 5, 1, 2169600, 147.54),
+("crosshatch", 5, 1, 2246400, 153.09),
+("crosshatch", 5, 1, 2323200, 166.44),
+("crosshatch", 5, 1, 2400000, 184.69),
+("crosshatch", 5, 1, 2476800, 204.14),
+("crosshatch", 5, 1, 2553600, 223.37),
+("crosshatch", 5, 1, 2649600, 253.77),
+("crosshatch", 6, 1, 825600, 28.88),
+("crosshatch", 6, 1, 902400, 32.4),
+("crosshatch", 6, 1, 979200, 36.46),
+("crosshatch", 6, 1, 1056000, 39.99),
+("crosshatch", 6, 1, 1209600, 47.23),
+("crosshatch", 6, 1, 1286400, 51.39),
+("crosshatch", 6, 1, 1363200, 56.9),
+("crosshatch", 6, 1, 1459200, 64.26),
+("crosshatch", 6, 1, 1536000, 69.65),
+("crosshatch", 6, 1, 1612800, 75.14),
+("crosshatch", 6, 1, 1689600, 83.16),
+("crosshatch", 6, 1, 1766400, 91.75),
+("crosshatch", 6, 1, 1843200, 100.66),
+("crosshatch", 6, 1, 1920000, 111.45),
+("crosshatch", 6, 1, 1996800, 122.23),
+("crosshatch", 6, 1, 2092800, 143.54),
+("crosshatch", 6, 1, 2169600, 147.54),
+("crosshatch", 6, 1, 2246400, 153.09),
+("crosshatch", 6, 1, 2323200, 166.44),
+("crosshatch", 6, 1, 2400000, 184.69),
+("crosshatch", 6, 1, 2476800, 204.14),
+("crosshatch", 6, 1, 2553600, 223.37),
+("crosshatch", 6, 1, 2649600, 253.77),
+("crosshatch", 7, 1, 825600, 28.88),
+("crosshatch", 7, 1, 902400, 32.4),
+("crosshatch", 7, 1, 979200, 36.46),
+("crosshatch", 7, 1, 1056000, 39.99),
+("crosshatch", 7, 1, 1209600, 47.23),
+("crosshatch", 7, 1, 1286400, 51.39),
+("crosshatch", 7, 1, 1363200, 56.9),
+("crosshatch", 7, 1, 1459200, 64.26),
+("crosshatch", 7, 1, 1536000, 69.65),
+("crosshatch", 7, 1, 1612800, 75.14),
+("crosshatch", 7, 1, 1689600, 83.16),
+("crosshatch", 7, 1, 1766400, 91.75),
+("crosshatch", 7, 1, 1843200, 100.66),
+("crosshatch", 7, 1, 1920000, 111.45),
+("crosshatch", 7, 1, 1996800, 122.23),
+("crosshatch", 7, 1, 2092800, 143.54),
+("crosshatch", 7, 1, 2169600, 147.54),
+("crosshatch", 7, 1, 2246400, 153.09),
+("crosshatch", 7, 1, 2323200, 166.44),
+("crosshatch", 7, 1, 2400000, 184.69),
+("crosshatch", 7, 1, 2476800, 204.14),
+("crosshatch", 7, 1, 2553600, 223.37),
+("crosshatch", 7, 1, 2649600, 253.77),
+("blueline", 0, 0, 300000, 2.27),
+("blueline", 0, 0, 403200, 3.63),
+("blueline", 0, 0, 480000, 4.36),
+("blueline", 0, 0, 576000, 5.21),
+("blueline", 0, 0, 652800, 5.47),
+("blueline", 0, 0, 748800, 6.74),
+("blueline", 0, 0, 825600, 7.69),
+("blueline", 0, 0, 902400, 8.57),
+("blueline", 0, 0, 979200, 9.42),
+("blueline", 0, 0, 1056000, 10.41),
+("blueline", 0, 0, 1132800, 11.56),
+("blueline", 0, 0, 1228800, 12.87),
+("blueline", 0, 0, 1324800, 14.61),
+("blueline", 0, 0, 1420800, 16.49),
+("blueline", 0, 0, 1516800, 18.9),
+("blueline", 0, 0, 1612800, 21.62),
+("blueline", 0, 0, 1689600, 24.47),
+("blueline", 0, 0, 1766400, 26.45),
+("blueline", 1, 0, 300000, 2.27),
+("blueline", 1, 0, 403200, 3.63),
+("blueline", 1, 0, 480000, 4.36),
+("blueline", 1, 0, 576000, 5.21),
+("blueline", 1, 0, 652800, 5.47),
+("blueline", 1, 0, 748800, 6.74),
+("blueline", 1, 0, 825600, 7.69),
+("blueline", 1, 0, 902400, 8.57),
+("blueline", 1, 0, 979200, 9.42),
+("blueline", 1, 0, 1056000, 10.41),
+("blueline", 1, 0, 1132800, 11.56),
+("blueline", 1, 0, 1228800, 12.87),
+("blueline", 1, 0, 1324800, 14.61),
+("blueline", 1, 0, 1420800, 16.49),
+("blueline", 1, 0, 1516800, 18.9),
+("blueline", 1, 0, 1612800, 21.62),
+("blueline", 1, 0, 1689600, 24.47),
+("blueline", 1, 0, 1766400, 26.45),
+("blueline", 2, 0, 300000, 2.27),
+("blueline", 2, 0, 403200, 3.63),
+("blueline", 2, 0, 480000, 4.36),
+("blueline", 2, 0, 576000, 5.21),
+("blueline", 2, 0, 652800, 5.47),
+("blueline", 2, 0, 748800, 6.74),
+("blueline", 2, 0, 825600, 7.69),
+("blueline", 2, 0, 902400, 8.57),
+("blueline", 2, 0, 979200, 9.42),
+("blueline", 2, 0, 1056000, 10.41),
+("blueline", 2, 0, 1132800, 11.56),
+("blueline", 2, 0, 1228800, 12.87),
+("blueline", 2, 0, 1324800, 14.61),
+("blueline", 2, 0, 1420800, 16.49),
+("blueline", 2, 0, 1516800, 18.9),
+("blueline", 2, 0, 1612800, 21.62),
+("blueline", 2, 0, 1689600, 24.47),
+("blueline", 2, 0, 1766400, 26.45),
+("blueline", 3, 0, 300000, 2.27),
+("blueline", 3, 0, 403200, 3.63),
+("blueline", 3, 0, 480000, 4.36),
+("blueline", 3, 0, 576000, 5.21),
+("blueline", 3, 0, 652800, 5.47),
+("blueline", 3, 0, 748800, 6.74),
+("blueline", 3, 0, 825600, 7.69),
+("blueline", 3, 0, 902400, 8.57),
+("blueline", 3, 0, 979200, 9.42),
+("blueline", 3, 0, 1056000, 10.41),
+("blueline", 3, 0, 1132800, 11.56),
+("blueline", 3, 0, 1228800, 12.87),
+("blueline", 3, 0, 1324800, 14.61),
+("blueline", 3, 0, 1420800, 16.49),
+("blueline", 3, 0, 1516800, 18.9),
+("blueline", 3, 0, 1612800, 21.62),
+("blueline", 3, 0, 1689600, 24.47),
+("blueline", 3, 0, 1766400, 26.45),
+("blueline", 4, 1, 825600, 28.88),
+("blueline", 4, 1, 902400, 32.4),
+("blueline", 4, 1, 979200, 36.46),
+("blueline", 4, 1, 1056000, 39.99),
+("blueline", 4, 1, 1209600, 47.23),
+("blueline", 4, 1, 1286400, 51.39),
+("blueline", 4, 1, 1363200, 56.9),
+("blueline", 4, 1, 1459200, 64.26),
+("blueline", 4, 1, 1536000, 69.65),
+("blueline", 4, 1, 1612800, 75.14),
+("blueline", 4, 1, 1689600, 83.16),
+("blueline", 4, 1, 1766400, 91.75),
+("blueline", 4, 1, 1843200, 100.66),
+("blueline", 4, 1, 1920000, 111.45),
+("blueline", 4, 1, 1996800, 122.23),
+("blueline", 4, 1, 2092800, 143.54),
+("blueline", 4, 1, 2169600, 147.54),
+("blueline", 4, 1, 2246400, 153.09),
+("blueline", 4, 1, 2323200, 166.44),
+("blueline", 4, 1, 2400000, 184.69),
+("blueline", 4, 1, 2476800, 204.14),
+("blueline", 4, 1, 2553600, 223.37),
+("blueline", 4, 1, 2649600, 253.77),
+("blueline", 5, 1, 825600, 28.88),
+("blueline", 5, 1, 902400, 32.4),
+("blueline", 5, 1, 979200, 36.46),
+("blueline", 5, 1, 1056000, 39.99),
+("blueline", 5, 1, 1209600, 47.23),
+("blueline", 5, 1, 1286400, 51.39),
+("blueline", 5, 1, 1363200, 56.9),
+("blueline", 5, 1, 1459200, 64.26),
+("blueline", 5, 1, 1536000, 69.65),
+("blueline", 5, 1, 1612800, 75.14),
+("blueline", 5, 1, 1689600, 83.16),
+("blueline", 5, 1, 1766400, 91.75),
+("blueline", 5, 1, 1843200, 100.66),
+("blueline", 5, 1, 1920000, 111.45),
+("blueline", 5, 1, 1996800, 122.23),
+("blueline", 5, 1, 2092800, 143.54),
+("blueline", 5, 1, 2169600, 147.54),
+("blueline", 5, 1, 2246400, 153.09),
+("blueline", 5, 1, 2323200, 166.44),
+("blueline", 5, 1, 2400000, 184.69),
+("blueline", 5, 1, 2476800, 204.14),
+("blueline", 5, 1, 2553600, 223.37),
+("blueline", 5, 1, 2649600, 253.77),
+("blueline", 6, 1, 825600, 28.88),
+("blueline", 6, 1, 902400, 32.4),
+("blueline", 6, 1, 979200, 36.46),
+("blueline", 6, 1, 1056000, 39.99),
+("blueline", 6, 1, 1209600, 47.23),
+("blueline", 6, 1, 1286400, 51.39),
+("blueline", 6, 1, 1363200, 56.9),
+("blueline", 6, 1, 1459200, 64.26),
+("blueline", 6, 1, 1536000, 69.65),
+("blueline", 6, 1, 1612800, 75.14),
+("blueline", 6, 1, 1689600, 83.16),
+("blueline", 6, 1, 1766400, 91.75),
+("blueline", 6, 1, 1843200, 100.66),
+("blueline", 6, 1, 1920000, 111.45),
+("blueline", 6, 1, 1996800, 122.23),
+("blueline", 6, 1, 2092800, 143.54),
+("blueline", 6, 1, 2169600, 147.54),
+("blueline", 6, 1, 2246400, 153.09),
+("blueline", 6, 1, 2323200, 166.44),
+("blueline", 6, 1, 2400000, 184.69),
+("blueline", 6, 1, 2476800, 204.14),
+("blueline", 6, 1, 2553600, 223.37),
+("blueline", 6, 1, 2649600, 253.77),
+("blueline", 7, 1, 825600, 28.88),
+("blueline", 7, 1, 902400, 32.4),
+("blueline", 7, 1, 979200, 36.46),
+("blueline", 7, 1, 1056000, 39.99),
+("blueline", 7, 1, 1209600, 47.23),
+("blueline", 7, 1, 1286400, 51.39),
+("blueline", 7, 1, 1363200, 56.9),
+("blueline", 7, 1, 1459200, 64.26),
+("blueline", 7, 1, 1536000, 69.65),
+("blueline", 7, 1, 1612800, 75.14),
+("blueline", 7, 1, 1689600, 83.16),
+("blueline", 7, 1, 1766400, 91.75),
+("blueline", 7, 1, 1843200, 100.66),
+("blueline", 7, 1, 1920000, 111.45),
+("blueline", 7, 1, 1996800, 122.23),
+("blueline", 7, 1, 2092800, 143.54),
+("blueline", 7, 1, 2169600, 147.54),
+("blueline", 7, 1, 2246400, 153.09),
+("blueline", 7, 1, 2323200, 166.44),
+("blueline", 7, 1, 2400000, 184.69),
+("blueline", 7, 1, 2476800, 204.14),
+("blueline", 7, 1, 2553600, 223.37),
+("blueline", 7, 1, 2649600, 253.77),
+("bonito", 0, 0, 300000, 15.2466666667),
+("bonito", 0, 0, 576000, 18.2166666667),
+("bonito", 0, 0, 748800, 20.1866666667),
+("bonito", 0, 0, 998400, 23.29),
+("bonito", 0, 0, 1209600, 25.0116666667),
+("bonito", 0, 0, 1324800, 28.485),
+("bonito", 0, 0, 1516800, 31.6866666667),
+("bonito", 0, 0, 1708800, 35.79),
+("bonito", 1, 0, 300000, 15.2466666667),
+("bonito", 1, 0, 576000, 18.2166666667),
+("bonito", 1, 0, 748800, 20.1866666667),
+("bonito", 1, 0, 998400, 23.29),
+("bonito", 1, 0, 1209600, 25.0116666667),
+("bonito", 1, 0, 1324800, 28.485),
+("bonito", 1, 0, 1516800, 31.6866666667),
+("bonito", 1, 0, 1708800, 35.79),
+("bonito", 2, 0, 300000, 15.2466666667),
+("bonito", 2, 0, 576000, 18.2166666667),
+("bonito", 2, 0, 748800, 20.1866666667),
+("bonito", 2, 0, 998400, 23.29),
+("bonito", 2, 0, 1209600, 25.0116666667),
+("bonito", 2, 0, 1324800, 28.485),
+("bonito", 2, 0, 1516800, 31.6866666667),
+("bonito", 2, 0, 1708800, 35.79),
+("bonito", 3, 0, 300000, 15.2466666667),
+("bonito", 3, 0, 576000, 18.2166666667),
+("bonito", 3, 0, 748800, 20.1866666667),
+("bonito", 3, 0, 998400, 23.29),
+("bonito", 3, 0, 1209600, 25.0116666667),
+("bonito", 3, 0, 1324800, 28.485),
+("bonito", 3, 0, 1516800, 31.6866666667),
+("bonito", 3, 0, 1708800, 35.79),
+("bonito", 4, 0, 300000, 15.2466666667),
+("bonito", 4, 0, 576000, 18.2166666667),
+("bonito", 4, 0, 748800, 20.1866666667),
+("bonito", 4, 0, 998400, 23.29),
+("bonito", 4, 0, 1209600, 25.0116666667),
+("bonito", 4, 0, 1324800, 28.485),
+("bonito", 4, 0, 1516800, 31.6866666667),
+("bonito", 4, 0, 1708800, 35.79),
+("bonito", 5, 0, 300000, 15.2466666667),
+("bonito", 5, 0, 576000, 18.2166666667),
+("bonito", 5, 0, 748800, 20.1866666667),
+("bonito", 5, 0, 998400, 23.29),
+("bonito", 5, 0, 1209600, 25.0116666667),
+("bonito", 5, 0, 1324800, 28.485),
+("bonito", 5, 0, 1516800, 31.6866666667),
+("bonito", 5, 0, 1708800, 35.79),
+("bonito", 6, 1, 300000, 24.06),
+("bonito", 6, 1, 652800, 27.56),
+("bonito", 6, 1, 825600, 29.0),
+("bonito", 6, 1, 979200, 31.675),
+("bonito", 6, 1, 1132800, 34.53),
+("bonito", 6, 1, 1363200, 38.885),
+("bonito", 6, 1, 1536000, 43.075),
+("bonito", 6, 1, 1747200, 48.705),
+("bonito", 6, 1, 1843200, 64.57),
+("bonito", 6, 1, 1996800, 69.805),
+("bonito", 6, 1, 2016000, 76.545),
+("bonito", 7, 1, 300000, 24.06),
+("bonito", 7, 1, 652800, 27.56),
+("bonito", 7, 1, 825600, 29.0),
+("bonito", 7, 1, 979200, 31.675),
+("bonito", 7, 1, 1132800, 34.53),
+("bonito", 7, 1, 1363200, 38.885),
+("bonito", 7, 1, 1536000, 43.075),
+("bonito", 7, 1, 1747200, 48.705),
+("bonito", 7, 1, 1843200, 64.57),
+("bonito", 7, 1, 1996800, 69.805),
+("bonito", 7, 1, 2016000, 76.545),
+("sargo", 0, 0, 300000, 15.2466666667),
+("sargo", 0, 0, 576000, 18.2166666667),
+("sargo", 0, 0, 748800, 20.1866666667),
+("sargo", 0, 0, 998400, 23.29),
+("sargo", 0, 0, 1209600, 25.0116666667),
+("sargo", 0, 0, 1324800, 28.485),
+("sargo", 0, 0, 1516800, 31.6866666667),
+("sargo", 0, 0, 1708800, 35.79),
+("sargo", 1, 0, 300000, 15.2466666667),
+("sargo", 1, 0, 576000, 18.2166666667),
+("sargo", 1, 0, 748800, 20.1866666667),
+("sargo", 1, 0, 998400, 23.29),
+("sargo", 1, 0, 1209600, 25.0116666667),
+("sargo", 1, 0, 1324800, 28.485),
+("sargo", 1, 0, 1516800, 31.6866666667),
+("sargo", 1, 0, 1708800, 35.79),
+("sargo", 2, 0, 300000, 15.2466666667),
+("sargo", 2, 0, 576000, 18.2166666667),
+("sargo", 2, 0, 748800, 20.1866666667),
+("sargo", 2, 0, 998400, 23.29),
+("sargo", 2, 0, 1209600, 25.0116666667),
+("sargo", 2, 0, 1324800, 28.485),
+("sargo", 2, 0, 1516800, 31.6866666667),
+("sargo", 2, 0, 1708800, 35.79),
+("sargo", 3, 0, 300000, 15.2466666667),
+("sargo", 3, 0, 576000, 18.2166666667),
+("sargo", 3, 0, 748800, 20.1866666667),
+("sargo", 3, 0, 998400, 23.29),
+("sargo", 3, 0, 1209600, 25.0116666667),
+("sargo", 3, 0, 1324800, 28.485),
+("sargo", 3, 0, 1516800, 31.6866666667),
+("sargo", 3, 0, 1708800, 35.79),
+("sargo", 4, 0, 300000, 15.2466666667),
+("sargo", 4, 0, 576000, 18.2166666667),
+("sargo", 4, 0, 748800, 20.1866666667),
+("sargo", 4, 0, 998400, 23.29),
+("sargo", 4, 0, 1209600, 25.0116666667),
+("sargo", 4, 0, 1324800, 28.485),
+("sargo", 4, 0, 1516800, 31.6866666667),
+("sargo", 4, 0, 1708800, 35.79),
+("sargo", 5, 0, 300000, 15.2466666667),
+("sargo", 5, 0, 576000, 18.2166666667),
+("sargo", 5, 0, 748800, 20.1866666667),
+("sargo", 5, 0, 998400, 23.29),
+("sargo", 5, 0, 1209600, 25.0116666667),
+("sargo", 5, 0, 1324800, 28.485),
+("sargo", 5, 0, 1516800, 31.6866666667),
+("sargo", 5, 0, 1708800, 35.79),
+("sargo", 6, 1, 300000, 24.06),
+("sargo", 6, 1, 652800, 27.56),
+("sargo", 6, 1, 825600, 29.0),
+("sargo", 6, 1, 979200, 31.675),
+("sargo", 6, 1, 1132800, 34.53),
+("sargo", 6, 1, 1363200, 38.885),
+("sargo", 6, 1, 1536000, 43.075),
+("sargo", 6, 1, 1747200, 48.705),
+("sargo", 6, 1, 1843200, 64.57),
+("sargo", 6, 1, 1996800, 69.805),
+("sargo", 6, 1, 2016000, 76.545),
+("sargo", 7, 1, 300000, 24.06),
+("sargo", 7, 1, 652800, 27.56),
+("sargo", 7, 1, 825600, 29.0),
+("sargo", 7, 1, 979200, 31.675),
+("sargo", 7, 1, 1132800, 34.53),
+("sargo", 7, 1, 1363200, 38.885),
+("sargo", 7, 1, 1536000, 43.075),
+("sargo", 7, 1, 1747200, 48.705),
+("sargo", 7, 1, 1843200, 64.57),
+("sargo", 7, 1, 1996800, 69.805),
+("sargo", 7, 1, 2016000, 76.545),
+("coral", 0, 0, 300000, 9.86),
+("coral", 0, 0, 403200, 10.335),
+("coral", 0, 0, 499200, 10.8925),
+("coral", 0, 0, 576000, 11.37),
+("coral", 0, 0, 672000, 11.8),
+("coral", 0, 0, 768000, 12.41),
+("coral", 0, 0, 844800, 12.97),
+("coral", 0, 0, 940800, 13.335),
+("coral", 0, 0, 1036800, 14.1725),
+("coral", 0, 0, 1113600, 14.695),
+("coral", 0, 0, 1209600, 15.3525),
+("coral", 0, 0, 1305600, 16.2775),
+("coral", 0, 0, 1382400, 16.8725),
+("coral", 0, 0, 1478400, 17.6525),
+("coral", 0, 0, 1555200, 18.0975),
+("coral", 0, 0, 1632000, 18.8575),
+("coral", 0, 0, 1708800, 20.0525),
+("coral", 0, 0, 1785600, 21.2625),
+("coral", 1, 0, 300000, 9.86),
+("coral", 1, 0, 403200, 10.335),
+("coral", 1, 0, 499200, 10.8925),
+("coral", 1, 0, 576000, 11.37),
+("coral", 1, 0, 672000, 11.8),
+("coral", 1, 0, 768000, 12.41),
+("coral", 1, 0, 844800, 12.97),
+("coral", 1, 0, 940800, 13.335),
+("coral", 1, 0, 1036800, 14.1725),
+("coral", 1, 0, 1113600, 14.695),
+("coral", 1, 0, 1209600, 15.3525),
+("coral", 1, 0, 1305600, 16.2775),
+("coral", 1, 0, 1382400, 16.8725),
+("coral", 1, 0, 1478400, 17.6525),
+("coral", 1, 0, 1555200, 18.0975),
+("coral", 1, 0, 1632000, 18.8575),
+("coral", 1, 0, 1708800, 20.0525),
+("coral", 1, 0, 1785600, 21.2625),
+("coral", 2, 0, 300000, 9.86),
+("coral", 2, 0, 403200, 10.335),
+("coral", 2, 0, 499200, 10.8925),
+("coral", 2, 0, 576000, 11.37),
+("coral", 2, 0, 672000, 11.8),
+("coral", 2, 0, 768000, 12.41),
+("coral", 2, 0, 844800, 12.97),
+("coral", 2, 0, 940800, 13.335),
+("coral", 2, 0, 1036800, 14.1725),
+("coral", 2, 0, 1113600, 14.695),
+("coral", 2, 0, 1209600, 15.3525),
+("coral", 2, 0, 1305600, 16.2775),
+("coral", 2, 0, 1382400, 16.8725),
+("coral", 2, 0, 1478400, 17.6525),
+("coral", 2, 0, 1555200, 18.0975),
+("coral", 2, 0, 1632000, 18.8575),
+("coral", 2, 0, 1708800, 20.0525),
+("coral", 2, 0, 1785600, 21.2625),
+("coral", 3, 0, 300000, 9.86),
+("coral", 3, 0, 403200, 10.335),
+("coral", 3, 0, 499200, 10.8925),
+("coral", 3, 0, 576000, 11.37),
+("coral", 3, 0, 672000, 11.8),
+("coral", 3, 0, 768000, 12.41),
+("coral", 3, 0, 844800, 12.97),
+("coral", 3, 0, 940800, 13.335),
+("coral", 3, 0, 1036800, 14.1725),
+("coral", 3, 0, 1113600, 14.695),
+("coral", 3, 0, 1209600, 15.3525),
+("coral", 3, 0, 1305600, 16.2775),
+("coral", 3, 0, 1382400, 16.8725),
+("coral", 3, 0, 1478400, 17.6525),
+("coral", 3, 0, 1555200, 18.0975),
+("coral", 3, 0, 1632000, 18.8575),
+("coral", 3, 0, 1708800, 20.0525),
+("coral", 3, 0, 1785600, 21.2625),
+("coral", 4, 1, 710400, 16.7833333333),
+("coral", 4, 1, 825600, 18.3733333333),
+("coral", 4, 1, 940800, 20.4833333333),
+("coral", 4, 1, 1056000, 23.3066666667),
+("coral", 4, 1, 1171200, 25.8266666667),
+("coral", 4, 1, 1286400, 28.45),
+("coral", 4, 1, 1401600, 31.7233333333),
+("coral", 4, 1, 1497600, 34.42),
+("coral", 4, 1, 1612800, 39.3966666667),
+("coral", 4, 1, 1708800, 44.24),
+("coral", 4, 1, 1804800, 47.9433333333),
+("coral", 4, 1, 1920000, 51.97),
+("coral", 4, 1, 2016000, 63.3866666667),
+("coral", 4, 1, 2131200, 71.0366666667),
+("coral", 4, 1, 2227200, 79.32),
+("coral", 4, 1, 2323200, 88.99),
+("coral", 4, 1, 2419200, 100.68),
+("coral", 5, 1, 710400, 16.7833333333),
+("coral", 5, 1, 825600, 18.3733333333),
+("coral", 5, 1, 940800, 20.4833333333),
+("coral", 5, 1, 1056000, 23.3066666667),
+("coral", 5, 1, 1171200, 25.8266666667),
+("coral", 5, 1, 1286400, 28.45),
+("coral", 5, 1, 1401600, 31.7233333333),
+("coral", 5, 1, 1497600, 34.42),
+("coral", 5, 1, 1612800, 39.3966666667),
+("coral", 5, 1, 1708800, 44.24),
+("coral", 5, 1, 1804800, 47.9433333333),
+("coral", 5, 1, 1920000, 51.97),
+("coral", 5, 1, 2016000, 63.3866666667),
+("coral", 5, 1, 2131200, 71.0366666667),
+("coral", 5, 1, 2227200, 79.32),
+("coral", 5, 1, 2323200, 88.99),
+("coral", 5, 1, 2419200, 100.68),
+("coral", 6, 1, 710400, 16.7833333333),
+("coral", 6, 1, 825600, 18.3733333333),
+("coral", 6, 1, 940800, 20.4833333333),
+("coral", 6, 1, 1056000, 23.3066666667),
+("coral", 6, 1, 1171200, 25.8266666667),
+("coral", 6, 1, 1286400, 28.45),
+("coral", 6, 1, 1401600, 31.7233333333),
+("coral", 6, 1, 1497600, 34.42),
+("coral", 6, 1, 1612800, 39.3966666667),
+("coral", 6, 1, 1708800, 44.24),
+("coral", 6, 1, 1804800, 47.9433333333),
+("coral", 6, 1, 1920000, 51.97),
+("coral", 6, 1, 2016000, 63.3866666667),
+("coral", 6, 1, 2131200, 71.0366666667),
+("coral", 6, 1, 2227200, 79.32),
+("coral", 6, 1, 2323200, 88.99),
+("coral", 6, 1, 2419200, 100.68),
+("coral", 7, 2, 825600, 52.7),
+("coral", 7, 2, 940800, 55.9),
+("coral", 7, 2, 1056000, 59.73),
+("coral", 7, 2, 1171200, 63.66),
+("coral", 7, 2, 1286400, 67.28),
+("coral", 7, 2, 1401600, 71.66),
+("coral", 7, 2, 1497600, 76.47),
+("coral", 7, 2, 1612800, 80.92),
+("coral", 7, 2, 1708800, 85.81),
+("coral", 7, 2, 1804800, 93.19),
+("coral", 7, 2, 1920000, 98.06),
+("coral", 7, 2, 2016000, 119.08),
+("coral", 7, 2, 2131200, 127.88),
+("coral", 7, 2, 2227200, 129.85),
+("coral", 7, 2, 2323200, 140.37),
+("coral", 7, 2, 2419200, 151.22),
+("coral", 7, 2, 2534400, 160.73),
+("coral", 7, 2, 2649600, 175.5),
+("coral", 7, 2, 2745600, 186.29),
+("coral", 7, 2, 2841600, 223.89),
+("flame", 0, 0, 300000, 9.86),
+("flame", 0, 0, 403200, 10.335),
+("flame", 0, 0, 499200, 10.8925),
+("flame", 0, 0, 576000, 11.37),
+("flame", 0, 0, 672000, 11.8),
+("flame", 0, 0, 768000, 12.41),
+("flame", 0, 0, 844800, 12.97),
+("flame", 0, 0, 940800, 13.335),
+("flame", 0, 0, 1036800, 14.1725),
+("flame", 0, 0, 1113600, 14.695),
+("flame", 0, 0, 1209600, 15.3525),
+("flame", 0, 0, 1305600, 16.2775),
+("flame", 0, 0, 1382400, 16.8725),
+("flame", 0, 0, 1478400, 17.6525),
+("flame", 0, 0, 1555200, 18.0975),
+("flame", 0, 0, 1632000, 18.8575),
+("flame", 0, 0, 1708800, 20.0525),
+("flame", 0, 0, 1785600, 21.2625),
+("flame", 1, 0, 300000, 9.86),
+("flame", 1, 0, 403200, 10.335),
+("flame", 1, 0, 499200, 10.8925),
+("flame", 1, 0, 576000, 11.37),
+("flame", 1, 0, 672000, 11.8),
+("flame", 1, 0, 768000, 12.41),
+("flame", 1, 0, 844800, 12.97),
+("flame", 1, 0, 940800, 13.335),
+("flame", 1, 0, 1036800, 14.1725),
+("flame", 1, 0, 1113600, 14.695),
+("flame", 1, 0, 1209600, 15.3525),
+("flame", 1, 0, 1305600, 16.2775),
+("flame", 1, 0, 1382400, 16.8725),
+("flame", 1, 0, 1478400, 17.6525),
+("flame", 1, 0, 1555200, 18.0975),
+("flame", 1, 0, 1632000, 18.8575),
+("flame", 1, 0, 1708800, 20.0525),
+("flame", 1, 0, 1785600, 21.2625),
+("flame", 2, 0, 300000, 9.86),
+("flame", 2, 0, 403200, 10.335),
+("flame", 2, 0, 499200, 10.8925),
+("flame", 2, 0, 576000, 11.37),
+("flame", 2, 0, 672000, 11.8),
+("flame", 2, 0, 768000, 12.41),
+("flame", 2, 0, 844800, 12.97),
+("flame", 2, 0, 940800, 13.335),
+("flame", 2, 0, 1036800, 14.1725),
+("flame", 2, 0, 1113600, 14.695),
+("flame", 2, 0, 1209600, 15.3525),
+("flame", 2, 0, 1305600, 16.2775),
+("flame", 2, 0, 1382400, 16.8725),
+("flame", 2, 0, 1478400, 17.6525),
+("flame", 2, 0, 1555200, 18.0975),
+("flame", 2, 0, 1632000, 18.8575),
+("flame", 2, 0, 1708800, 20.0525),
+("flame", 2, 0, 1785600, 21.2625),
+("flame", 3, 0, 300000, 9.86),
+("flame", 3, 0, 403200, 10.335),
+("flame", 3, 0, 499200, 10.8925),
+("flame", 3, 0, 576000, 11.37),
+("flame", 3, 0, 672000, 11.8),
+("flame", 3, 0, 768000, 12.41),
+("flame", 3, 0, 844800, 12.97),
+("flame", 3, 0, 940800, 13.335),
+("flame", 3, 0, 1036800, 14.1725),
+("flame", 3, 0, 1113600, 14.695),
+("flame", 3, 0, 1209600, 15.3525),
+("flame", 3, 0, 1305600, 16.2775),
+("flame", 3, 0, 1382400, 16.8725),
+("flame", 3, 0, 1478400, 17.6525),
+("flame", 3, 0, 1555200, 18.0975),
+("flame", 3, 0, 1632000, 18.8575),
+("flame", 3, 0, 1708800, 20.0525),
+("flame", 3, 0, 1785600, 21.2625),
+("flame", 4, 1, 710400, 16.7833333333),
+("flame", 4, 1, 825600, 18.3733333333),
+("flame", 4, 1, 940800, 20.4833333333),
+("flame", 4, 1, 1056000, 23.3066666667),
+("flame", 4, 1, 1171200, 25.8266666667),
+("flame", 4, 1, 1286400, 28.45),
+("flame", 4, 1, 1401600, 31.7233333333),
+("flame", 4, 1, 1497600, 34.42),
+("flame", 4, 1, 1612800, 39.3966666667),
+("flame", 4, 1, 1708800, 44.24),
+("flame", 4, 1, 1804800, 47.9433333333),
+("flame", 4, 1, 1920000, 51.97),
+("flame", 4, 1, 2016000, 63.3866666667),
+("flame", 4, 1, 2131200, 71.0366666667),
+("flame", 4, 1, 2227200, 79.32),
+("flame", 4, 1, 2323200, 88.99),
+("flame", 4, 1, 2419200, 100.68),
+("flame", 5, 1, 710400, 16.7833333333),
+("flame", 5, 1, 825600, 18.3733333333),
+("flame", 5, 1, 940800, 20.4833333333),
+("flame", 5, 1, 1056000, 23.3066666667),
+("flame", 5, 1, 1171200, 25.8266666667),
+("flame", 5, 1, 1286400, 28.45),
+("flame", 5, 1, 1401600, 31.7233333333),
+("flame", 5, 1, 1497600, 34.42),
+("flame", 5, 1, 1612800, 39.3966666667),
+("flame", 5, 1, 1708800, 44.24),
+("flame", 5, 1, 1804800, 47.9433333333),
+("flame", 5, 1, 1920000, 51.97),
+("flame", 5, 1, 2016000, 63.3866666667),
+("flame", 5, 1, 2131200, 71.0366666667),
+("flame", 5, 1, 2227200, 79.32),
+("flame", 5, 1, 2323200, 88.99),
+("flame", 5, 1, 2419200, 100.68),
+("flame", 6, 1, 710400, 16.7833333333),
+("flame", 6, 1, 825600, 18.3733333333),
+("flame", 6, 1, 940800, 20.4833333333),
+("flame", 6, 1, 1056000, 23.3066666667),
+("flame", 6, 1, 1171200, 25.8266666667),
+("flame", 6, 1, 1286400, 28.45),
+("flame", 6, 1, 1401600, 31.7233333333),
+("flame", 6, 1, 1497600, 34.42),
+("flame", 6, 1, 1612800, 39.3966666667),
+("flame", 6, 1, 1708800, 44.24),
+("flame", 6, 1, 1804800, 47.9433333333),
+("flame", 6, 1, 1920000, 51.97),
+("flame", 6, 1, 2016000, 63.3866666667),
+("flame", 6, 1, 2131200, 71.0366666667),
+("flame", 6, 1, 2227200, 79.32),
+("flame", 6, 1, 2323200, 88.99),
+("flame", 6, 1, 2419200, 100.68),
+("flame", 7, 2, 825600, 52.7),
+("flame", 7, 2, 940800, 55.9),
+("flame", 7, 2, 1056000, 59.73),
+("flame", 7, 2, 1171200, 63.66),
+("flame", 7, 2, 1286400, 67.28),
+("flame", 7, 2, 1401600, 71.66),
+("flame", 7, 2, 1497600, 76.47),
+("flame", 7, 2, 1612800, 80.92),
+("flame", 7, 2, 1708800, 85.81),
+("flame", 7, 2, 1804800, 93.19),
+("flame", 7, 2, 1920000, 98.06),
+("flame", 7, 2, 2016000, 119.08),
+("flame", 7, 2, 2131200, 127.88),
+("flame", 7, 2, 2227200, 129.85),
+("flame", 7, 2, 2323200, 140.37),
+("flame", 7, 2, 2419200, 151.22),
+("flame", 7, 2, 2534400, 160.73),
+("flame", 7, 2, 2649600, 175.5),
+("flame", 7, 2, 2745600, 186.29),
+("flame", 7, 2, 2841600, 223.89),
+("sunfish", 0, 0, 300000, 5.75833333333),
+("sunfish", 0, 0, 576000, 7.76166666667),
+("sunfish", 0, 0, 768000, 9.14),
+("sunfish", 0, 0, 1017600, 11.36),
+("sunfish", 0, 0, 1248000, 13.45),
+("sunfish", 0, 0, 1324800, 14.4333333333),
+("sunfish", 0, 0, 1497600, 16.5216666667),
+("sunfish", 0, 0, 1612800, 18.5083333333),
+("sunfish", 0, 0, 1708800, 19.9316666667),
+("sunfish", 0, 0, 1804800, 21.4083333333),
+("sunfish", 1, 0, 300000, 5.75833333333),
+("sunfish", 1, 0, 576000, 7.76166666667),
+("sunfish", 1, 0, 768000, 9.14),
+("sunfish", 1, 0, 1017600, 11.36),
+("sunfish", 1, 0, 1248000, 13.45),
+("sunfish", 1, 0, 1324800, 14.4333333333),
+("sunfish", 1, 0, 1497600, 16.5216666667),
+("sunfish", 1, 0, 1612800, 18.5083333333),
+("sunfish", 1, 0, 1708800, 19.9316666667),
+("sunfish", 1, 0, 1804800, 21.4083333333),
+("sunfish", 2, 0, 300000, 5.75833333333),
+("sunfish", 2, 0, 576000, 7.76166666667),
+("sunfish", 2, 0, 768000, 9.14),
+("sunfish", 2, 0, 1017600, 11.36),
+("sunfish", 2, 0, 1248000, 13.45),
+("sunfish", 2, 0, 1324800, 14.4333333333),
+("sunfish", 2, 0, 1497600, 16.5216666667),
+("sunfish", 2, 0, 1612800, 18.5083333333),
+("sunfish", 2, 0, 1708800, 19.9316666667),
+("sunfish", 2, 0, 1804800, 21.4083333333),
+("sunfish", 3, 0, 300000, 5.75833333333),
+("sunfish", 3, 0, 576000, 7.76166666667),
+("sunfish", 3, 0, 768000, 9.14),
+("sunfish", 3, 0, 1017600, 11.36),
+("sunfish", 3, 0, 1248000, 13.45),
+("sunfish", 3, 0, 1324800, 14.4333333333),
+("sunfish", 3, 0, 1497600, 16.5216666667),
+("sunfish", 3, 0, 1612800, 18.5083333333),
+("sunfish", 3, 0, 1708800, 19.9316666667),
+("sunfish", 3, 0, 1804800, 21.4083333333),
+("sunfish", 4, 0, 300000, 5.75833333333),
+("sunfish", 4, 0, 576000, 7.76166666667),
+("sunfish", 4, 0, 768000, 9.14),
+("sunfish", 4, 0, 1017600, 11.36),
+("sunfish", 4, 0, 1248000, 13.45),
+("sunfish", 4, 0, 1324800, 14.4333333333),
+("sunfish", 4, 0, 1497600, 16.5216666667),
+("sunfish", 4, 0, 1612800, 18.5083333333),
+("sunfish", 4, 0, 1708800, 19.9316666667),
+("sunfish", 4, 0, 1804800, 21.4083333333),
+("sunfish", 5, 0, 300000, 5.75833333333),
+("sunfish", 5, 0, 576000, 7.76166666667),
+("sunfish", 5, 0, 768000, 9.14),
+("sunfish", 5, 0, 1017600, 11.36),
+("sunfish", 5, 0, 1248000, 13.45),
+("sunfish", 5, 0, 1324800, 14.4333333333),
+("sunfish", 5, 0, 1497600, 16.5216666667),
+("sunfish", 5, 0, 1612800, 18.5083333333),
+("sunfish", 5, 0, 1708800, 19.9316666667),
+("sunfish", 5, 0, 1804800, 21.4083333333),
+("sunfish", 6, 1, 300000, 21.115),
+("sunfish", 6, 1, 652800, 28.46),
+("sunfish", 6, 1, 806400, 31.705),
+("sunfish", 6, 1, 979200, 36.515),
+("sunfish", 6, 1, 1094400, 40.19),
+("sunfish", 6, 1, 1209600, 43.585),
+("sunfish", 6, 1, 1324800, 48.275),
+("sunfish", 6, 1, 1555200, 62.805),
+("sunfish", 6, 1, 1708800, 72.755),
+("sunfish", 6, 1, 1843200, 91.47),
+("sunfish", 6, 1, 1939200, 99.46),
+("sunfish", 6, 1, 2169600, 119.27),
+("sunfish", 6, 1, 2208000, 133.105),
+("sunfish", 7, 1, 300000, 21.115),
+("sunfish", 7, 1, 652800, 28.46),
+("sunfish", 7, 1, 806400, 31.705),
+("sunfish", 7, 1, 979200, 36.515),
+("sunfish", 7, 1, 1094400, 40.19),
+("sunfish", 7, 1, 1209600, 43.585),
+("sunfish", 7, 1, 1324800, 48.275),
+("sunfish", 7, 1, 1555200, 62.805),
+("sunfish", 7, 1, 1708800, 72.755),
+("sunfish", 7, 1, 1843200, 91.47),
+("sunfish", 7, 1, 1939200, 99.46),
+("sunfish", 7, 1, 2169600, 119.27),
+("sunfish", 7, 1, 2208000, 133.105),
+("redfin", 0, 0, 300000, 6.98666666667),
+("redfin", 0, 0, 576000, 9.93166666667),
+("redfin", 0, 0, 614400, 10.3216666667),
+("redfin", 0, 0, 864000, 13.31),
+("redfin", 0, 0, 1075200, 15.9866666667),
+("redfin", 0, 0, 1363200, 20.3283333333),
+("redfin", 0, 0, 1516800, 23.4533333333),
+("redfin", 0, 0, 1651200, 26.53),
+("redfin", 0, 0, 1804800, 29.365),
+("redfin", 1, 0, 300000, 6.98666666667),
+("redfin", 1, 0, 576000, 9.93166666667),
+("redfin", 1, 0, 614400, 10.3216666667),
+("redfin", 1, 0, 864000, 13.31),
+("redfin", 1, 0, 1075200, 15.9866666667),
+("redfin", 1, 0, 1363200, 20.3283333333),
+("redfin", 1, 0, 1516800, 23.4533333333),
+("redfin", 1, 0, 1651200, 26.53),
+("redfin", 1, 0, 1804800, 29.365),
+("redfin", 2, 0, 300000, 6.98666666667),
+("redfin", 2, 0, 576000, 9.93166666667),
+("redfin", 2, 0, 614400, 10.3216666667),
+("redfin", 2, 0, 864000, 13.31),
+("redfin", 2, 0, 1075200, 15.9866666667),
+("redfin", 2, 0, 1363200, 20.3283333333),
+("redfin", 2, 0, 1516800, 23.4533333333),
+("redfin", 2, 0, 1651200, 26.53),
+("redfin", 2, 0, 1804800, 29.365),
+("redfin", 3, 0, 300000, 6.98666666667),
+("redfin", 3, 0, 576000, 9.93166666667),
+("redfin", 3, 0, 614400, 10.3216666667),
+("redfin", 3, 0, 864000, 13.31),
+("redfin", 3, 0, 1075200, 15.9866666667),
+("redfin", 3, 0, 1363200, 20.3283333333),
+("redfin", 3, 0, 1516800, 23.4533333333),
+("redfin", 3, 0, 1651200, 26.53),
+("redfin", 3, 0, 1804800, 29.365),
+("redfin", 4, 0, 300000, 6.98666666667),
+("redfin", 4, 0, 576000, 9.93166666667),
+("redfin", 4, 0, 614400, 10.3216666667),
+("redfin", 4, 0, 864000, 13.31),
+("redfin", 4, 0, 1075200, 15.9866666667),
+("redfin", 4, 0, 1363200, 20.3283333333),
+("redfin", 4, 0, 1516800, 23.4533333333),
+("redfin", 4, 0, 1651200, 26.53),
+("redfin", 4, 0, 1804800, 29.365),
+("redfin", 5, 0, 300000, 6.98666666667),
+("redfin", 5, 0, 576000, 9.93166666667),
+("redfin", 5, 0, 614400, 10.3216666667),
+("redfin", 5, 0, 864000, 13.31),
+("redfin", 5, 0, 1075200, 15.9866666667),
+("redfin", 5, 0, 1363200, 20.3283333333),
+("redfin", 5, 0, 1516800, 23.4533333333),
+("redfin", 5, 0, 1651200, 26.53),
+("redfin", 5, 0, 1804800, 29.365),
+("redfin", 6, 1, 652800, 32.13),
+("redfin", 6, 1, 940800, 35.98),
+("redfin", 6, 1, 1152000, 40.03),
+("redfin", 6, 1, 1478400, 51.02),
+("redfin", 6, 1, 1728000, 77.06),
+("redfin", 6, 1, 1900800, 86.25),
+("redfin", 6, 1, 2092800, 97.3),
+("redfin", 6, 1, 2208000, 101.61),
+("redfin", 7, 2, 806400, 56.44),
+("redfin", 7, 2, 1094400, 65.72),
+("redfin", 7, 2, 1401600, 77.01),
+("redfin", 7, 2, 1766400, 104.91),
+("redfin", 7, 2, 1996800, 112.35),
+("redfin", 7, 2, 2188800, 118.53),
+("redfin", 7, 2, 2304000, 122.34),
+("redfin", 7, 2, 2400000, 135.0),
+("bramble", 0, 0, 300000, 6.98666666667),
+("bramble", 0, 0, 576000, 9.93166666667),
+("bramble", 0, 0, 614400, 10.3216666667),
+("bramble", 0, 0, 864000, 13.31),
+("bramble", 0, 0, 1075200, 15.9866666667),
+("bramble", 0, 0, 1363200, 20.3283333333),
+("bramble", 0, 0, 1516800, 23.4533333333),
+("bramble", 0, 0, 1651200, 26.53),
+("bramble", 0, 0, 1804800, 29.365),
+("bramble", 1, 0, 300000, 6.98666666667),
+("bramble", 1, 0, 576000, 9.93166666667),
+("bramble", 1, 0, 614400, 10.3216666667),
+("bramble", 1, 0, 864000, 13.31),
+("bramble", 1, 0, 1075200, 15.9866666667),
+("bramble", 1, 0, 1363200, 20.3283333333),
+("bramble", 1, 0, 1516800, 23.4533333333),
+("bramble", 1, 0, 1651200, 26.53),
+("bramble", 1, 0, 1804800, 29.365),
+("bramble", 2, 0, 300000, 6.98666666667),
+("bramble", 2, 0, 576000, 9.93166666667),
+("bramble", 2, 0, 614400, 10.3216666667),
+("bramble", 2, 0, 864000, 13.31),
+("bramble", 2, 0, 1075200, 15.9866666667),
+("bramble", 2, 0, 1363200, 20.3283333333),
+("bramble", 2, 0, 1516800, 23.4533333333),
+("bramble", 2, 0, 1651200, 26.53),
+("bramble", 2, 0, 1804800, 29.365),
+("bramble", 3, 0, 300000, 6.98666666667),
+("bramble", 3, 0, 576000, 9.93166666667),
+("bramble", 3, 0, 614400, 10.3216666667),
+("bramble", 3, 0, 864000, 13.31),
+("bramble", 3, 0, 1075200, 15.9866666667),
+("bramble", 3, 0, 1363200, 20.3283333333),
+("bramble", 3, 0, 1516800, 23.4533333333),
+("bramble", 3, 0, 1651200, 26.53),
+("bramble", 3, 0, 1804800, 29.365),
+("bramble", 4, 0, 300000, 6.98666666667),
+("bramble", 4, 0, 576000, 9.93166666667),
+("bramble", 4, 0, 614400, 10.3216666667),
+("bramble", 4, 0, 864000, 13.31),
+("bramble", 4, 0, 1075200, 15.9866666667),
+("bramble", 4, 0, 1363200, 20.3283333333),
+("bramble", 4, 0, 1516800, 23.4533333333),
+("bramble", 4, 0, 1651200, 26.53),
+("bramble", 4, 0, 1804800, 29.365),
+("bramble", 5, 0, 300000, 6.98666666667),
+("bramble", 5, 0, 576000, 9.93166666667),
+("bramble", 5, 0, 614400, 10.3216666667),
+("bramble", 5, 0, 864000, 13.31),
+("bramble", 5, 0, 1075200, 15.9866666667),
+("bramble", 5, 0, 1363200, 20.3283333333),
+("bramble", 5, 0, 1516800, 23.4533333333),
+("bramble", 5, 0, 1651200, 26.53),
+("bramble", 5, 0, 1804800, 29.365),
+("bramble", 6, 1, 652800, 32.13),
+("bramble", 6, 1, 940800, 35.98),
+("bramble", 6, 1, 1152000, 40.03),
+("bramble", 6, 1, 1478400, 51.02),
+("bramble", 6, 1, 1728000, 77.06),
+("bramble", 6, 1, 1900800, 86.25),
+("bramble", 6, 1, 2092800, 97.3),
+("bramble", 6, 1, 2208000, 101.61),
+("bramble", 7, 2, 806400, 56.44),
+("bramble", 7, 2, 1094400, 65.72),
+("bramble", 7, 2, 1401600, 77.01),
+("bramble", 7, 2, 1766400, 104.91),
+("bramble", 7, 2, 1996800, 112.35),
+("bramble", 7, 2, 2188800, 118.53),
+("bramble", 7, 2, 2304000, 122.34),
+("bramble", 7, 2, 2400000, 135.0); \ No newline at end of file
diff --git a/src/trace_processor/metrics/android/process_counter_span_view.sql b/src/trace_processor/metrics/sql/android/process_counter_span_view.sql
index f1f8493b7..f1f8493b7 100644
--- a/src/trace_processor/metrics/android/process_counter_span_view.sql
+++ b/src/trace_processor/metrics/sql/android/process_counter_span_view.sql
diff --git a/src/trace_processor/metrics/sql/android/process_mem.sql b/src/trace_processor/metrics/sql/android/process_mem.sql
new file mode 100644
index 000000000..908f11d1c
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/process_mem.sql
@@ -0,0 +1,115 @@
+--
+-- Copyright 2019 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+-- Create all the views used to generate the Android Memory metrics proto.
+-- Anon RSS
+SELECT RUN_METRIC('android/process_counter_span_view.sql',
+ 'table_name', 'anon_rss',
+ 'counter_name', 'mem.rss.anon');
+
+-- File RSS
+SELECT RUN_METRIC('android/process_counter_span_view.sql',
+ 'table_name', 'file_rss',
+ 'counter_name', 'mem.rss.file');
+
+SELECT RUN_METRIC('android/process_counter_span_view.sql',
+ 'table_name', 'shmem_rss',
+ 'counter_name', 'mem.rss.shmem');
+
+-- Swap
+SELECT RUN_METRIC('android/process_counter_span_view.sql',
+ 'table_name', 'swap',
+ 'counter_name', 'mem.swap');
+
+-- OOM score
+SELECT RUN_METRIC('android/process_oom_score.sql');
+
+-- Anon RSS + Swap
+DROP TABLE IF EXISTS anon_and_swap_join;
+CREATE VIRTUAL TABLE anon_and_swap_join
+USING SPAN_OUTER_JOIN(anon_rss_span PARTITIONED upid, swap_span PARTITIONED upid);
+
+DROP VIEW IF EXISTS anon_and_swap_span;
+CREATE VIEW anon_and_swap_span AS
+SELECT
+ ts, dur, upid,
+ IFNULL(anon_rss_val, 0) + IFNULL(swap_val, 0) AS anon_and_swap_val
+FROM anon_and_swap_join;
+
+-- Anon RSS + file RSS + Swap
+DROP TABLE IF EXISTS anon_and_file_and_swap_join;
+CREATE VIRTUAL TABLE anon_and_file_and_swap_join
+USING SPAN_OUTER_JOIN(
+ anon_and_swap_join PARTITIONED upid,
+ file_rss_span PARTITIONED upid
+);
+
+-- RSS + Swap
+DROP TABLE IF EXISTS rss_and_swap_join;
+CREATE VIRTUAL TABLE rss_and_swap_join
+USING SPAN_OUTER_JOIN(
+ anon_and_file_and_swap_join PARTITIONED upid,
+ shmem_rss_span PARTITIONED upid
+);
+
+DROP VIEW IF EXISTS rss_and_swap_span;
+CREATE VIEW rss_and_swap_span AS
+SELECT
+ ts, dur, upid,
+ CAST(IFNULL(file_rss_val, 0) AS INT) file_rss_val,
+ CAST(IFNULL(anon_rss_val, 0) AS INT) anon_rss_val,
+ CAST(IFNULL(shmem_rss_val, 0) AS INT) shmem_rss_val,
+ CAST(IFNULL(swap_val, 0) AS INT) swap_val,
+ CAST(
+ IFNULL(anon_rss_val, 0) +
+ IFNULL(file_rss_val, 0) +
+ IFNULL(shmem_rss_val, 0) AS int) AS rss_val,
+ CAST(
+ IFNULL(anon_rss_val, 0)
+ + IFNULL(swap_val, 0)
+ + IFNULL(file_rss_val, 0)
+ + IFNULL(shmem_rss_val, 0) AS int) AS rss_and_swap_val
+FROM rss_and_swap_join;
+
+-- If we have dalvik events enabled (for ART trace points) we can construct the java heap timeline.
+SELECT RUN_METRIC('android/process_counter_span_view.sql',
+ 'table_name', 'java_heap_kb',
+ 'counter_name', 'Heap size (KB)');
+
+DROP VIEW IF EXISTS java_heap_span;
+CREATE VIEW java_heap_span AS
+SELECT ts, dur, upid, java_heap_kb_val * 1024 AS java_heap_val
+FROM java_heap_kb_span;
+
+DROP TABLE IF EXISTS anon_rss_by_oom_span;
+CREATE VIRTUAL TABLE anon_rss_by_oom_span
+USING SPAN_JOIN(anon_rss_span PARTITIONED upid, oom_score_span PARTITIONED upid);
+
+DROP TABLE IF EXISTS file_rss_by_oom_span;
+CREATE VIRTUAL TABLE file_rss_by_oom_span
+USING SPAN_JOIN(file_rss_span PARTITIONED upid, oom_score_span PARTITIONED upid);
+
+DROP TABLE IF EXISTS swap_by_oom_span;
+CREATE VIRTUAL TABLE swap_by_oom_span
+USING SPAN_JOIN(swap_span PARTITIONED upid, oom_score_span PARTITIONED upid);
+
+DROP TABLE IF EXISTS anon_and_swap_by_oom_span;
+CREATE VIRTUAL TABLE anon_and_swap_by_oom_span
+USING SPAN_JOIN(anon_and_swap_span PARTITIONED upid, oom_score_span PARTITIONED upid);
+
+DROP TABLE IF EXISTS java_heap_by_oom_span;
+CREATE VIRTUAL TABLE java_heap_by_oom_span
+USING SPAN_JOIN(java_heap_span PARTITIONED upid, oom_score_span PARTITIONED upid);
diff --git a/src/trace_processor/metrics/sql/android/process_metadata.sql b/src/trace_processor/metrics/sql/android/process_metadata.sql
new file mode 100644
index 000000000..7167e1282
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/process_metadata.sql
@@ -0,0 +1,86 @@
+--
+-- Copyright 2019 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+DROP TABLE IF EXISTS uid_package_count;
+
+CREATE TABLE uid_package_count AS
+SELECT uid, COUNT(1) AS cnt
+FROM package_list
+GROUP BY 1;
+
+DROP TABLE IF EXISTS process_metadata_table;
+
+CREATE TABLE process_metadata_table AS
+SELECT
+ process.upid,
+ -- workaround for b/169226092: the bug has been fixed it Android T, but
+ -- we support ingesting traces from older Android versions.
+ CASE
+ -- cmdline gets rewritten after fork, if these are still there we must
+ -- have seen a racy capture.
+ WHEN length(process.name) = 15 AND (
+ process.cmdline in ('zygote', 'zygote64', '<pre-initialized>')
+ OR process.cmdline GLOB '*' || process.name)
+ THEN process.cmdline
+ ELSE process.name
+ END AS process_name,
+ process.android_appid AS uid,
+ CASE WHEN uid_package_count.cnt > 1 THEN TRUE ELSE NULL END AS shared_uid,
+ plist.package_name,
+ plist.version_code,
+ plist.debuggable
+FROM process
+LEFT JOIN uid_package_count ON process.android_appid = uid_package_count.uid
+LEFT JOIN package_list plist
+ON (
+ process.android_appid = plist.uid
+ AND uid_package_count.uid = plist.uid
+ AND (
+ -- unique match
+ uid_package_count.cnt = 1
+ -- or process name starts with the package name
+ OR process.name GLOB plist.package_name || '*')
+ );
+
+DROP VIEW IF EXISTS process_metadata;
+
+CREATE VIEW process_metadata AS
+WITH upid_packages AS (
+ SELECT
+ upid,
+ RepeatedField(AndroidProcessMetadata_Package(
+ 'package_name', package_list.package_name,
+ 'apk_version_code', package_list.version_code,
+ 'debuggable', package_list.debuggable
+ )) packages_for_uid
+ FROM process
+ JOIN package_list ON process.android_appid = package_list.uid
+ GROUP BY upid
+)
+SELECT
+ upid,
+ NULL_IF_EMPTY(AndroidProcessMetadata(
+ 'name', process_name,
+ 'uid', uid,
+ 'package', NULL_IF_EMPTY(AndroidProcessMetadata_Package(
+ 'package_name', package_name,
+ 'apk_version_code', version_code,
+ 'debuggable', debuggable
+ )),
+ 'packages_for_uid', packages_for_uid
+ )) AS metadata
+FROM process_metadata_table
+LEFT JOIN upid_packages USING (upid);
diff --git a/src/trace_processor/metrics/android/process_oom_score.sql b/src/trace_processor/metrics/sql/android/process_oom_score.sql
index 3a5368842..3a5368842 100644
--- a/src/trace_processor/metrics/android/process_oom_score.sql
+++ b/src/trace_processor/metrics/sql/android/process_oom_score.sql
diff --git a/src/trace_processor/metrics/android/process_unagg_mem_view.sql b/src/trace_processor/metrics/sql/android/process_unagg_mem_view.sql
index d19c4e26d..d19c4e26d 100644
--- a/src/trace_processor/metrics/android/process_unagg_mem_view.sql
+++ b/src/trace_processor/metrics/sql/android/process_unagg_mem_view.sql
diff --git a/src/trace_processor/metrics/sql/android/profiler_smaps.sql b/src/trace_processor/metrics/sql/android/profiler_smaps.sql
new file mode 100644
index 000000000..481c74e15
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/profiler_smaps.sql
@@ -0,0 +1,53 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+SELECT RUN_METRIC('android/process_metadata.sql') as unused;
+
+DROP VIEW IF EXISTS profiler_smaps_output;
+CREATE VIEW profiler_smaps_output AS
+ WITH base_stat_counts AS (
+ SELECT
+ ts,
+ upid,
+ path,
+ SUM(size_kb) size_kb,
+ SUM(private_dirty_kb) private_dirty_kb,
+ SUM(swap_kb) swap_kb
+ FROM profiler_smaps
+ GROUP BY 1, 2, 3
+ ORDER BY 4 DESC
+ ),
+ mapping_protos AS (
+ SELECT
+ ts,
+ upid,
+ RepeatedField(ProfilerSmaps_Mapping(
+ 'path', path,
+ 'size_kb', size_kb,
+ 'private_dirty_kb', private_dirty_kb,
+ 'swap_kb', swap_kb
+ )) mappings
+ FROM base_stat_counts
+ GROUP BY 1, 2
+ )
+ SELECT ProfilerSmaps(
+ 'instance', RepeatedField(
+ ProfilerSmaps_Instance(
+ 'process', process_metadata.metadata,
+ 'mappings', mappings
+ ))
+ )
+ FROM mapping_protos JOIN process_metadata USING (upid);
diff --git a/src/trace_processor/metrics/sql/android/span_view_stats.sql b/src/trace_processor/metrics/sql/android/span_view_stats.sql
new file mode 100644
index 000000000..80f73f565
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/span_view_stats.sql
@@ -0,0 +1,71 @@
+--
+-- Copyright 2019 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+DROP TABLE IF EXISTS {{table_name}}_stats;
+CREATE TABLE {{table_name}}_stats (
+ process_name TEXT PRIMARY KEY,
+ min_value REAL,
+ max_value REAL,
+ avg_value REAL,
+ max_delta_value REAL
+);
+
+DROP TABLE IF EXISTS {{table_name}}_delta;
+CREATE TABLE {{table_name}}_delta AS
+WITH rolling_delta AS (
+ -- emits one row per ts point
+ SELECT
+ upid,
+ {{table_name}}_val - MIN({{table_name}}_val) OVER win AS delta
+ FROM {{table_name}}_span
+ WINDOW win AS (
+ PARTITION BY upid
+ ORDER BY ts
+ ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+ )
+)
+SELECT
+ upid,
+ -- max over all ts
+ MAX(delta) delta
+FROM rolling_delta
+GROUP BY 1;
+
+INSERT INTO {{table_name}}_stats
+SELECT
+ process.name AS process_name,
+ MIN(span.{{table_name}}_val) AS min_value,
+ MAX(span.{{table_name}}_val) AS max_value,
+ SUM(span.{{table_name}}_val * span.dur) / SUM(span.dur) AS avg_value,
+ MAX(delta.delta) AS max_delta_value
+FROM {{table_name}}_span AS span
+JOIN {{table_name}}_delta AS delta USING(upid)
+JOIN process USING(upid)
+WHERE process.name IS NOT NULL
+GROUP BY 1
+ORDER BY 1;
+
+DROP VIEW IF EXISTS {{table_name}}_stats_proto;
+CREATE VIEW {{table_name}}_stats_proto AS
+SELECT
+ process_name,
+ AndroidMemoryMetric_Counter(
+ 'min', min_value,
+ 'max', max_value,
+ 'avg', avg_value,
+ 'delta', max_delta_value
+ ) AS proto
+FROM {{table_name}}_stats;
diff --git a/src/trace_processor/metrics/sql/android/startup/hsc.sql b/src/trace_processor/metrics/sql/android/startup/hsc.sql
new file mode 100644
index 000000000..09db7d94d
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/startup/hsc.sql
@@ -0,0 +1,259 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+-- Must be invoked after populating launches table in android_startup.
+DROP VIEW IF EXISTS functions;
+CREATE VIEW functions AS
+SELECT
+ slices.ts as ts,
+ slices.dur as dur,
+ process.name as process_name,
+ thread.name as thread_name,
+ slices.name as function_name
+FROM slices
+INNER JOIN thread_track on slices.track_id = thread_track.id
+INNER JOIN thread USING(utid)
+INNER JOIN process USING(upid);
+
+-- Animators don't occur on threads, so add them here.
+DROP VIEW IF EXISTS animators;
+CREATE VIEW animators AS
+SELECT
+ slices.ts AS ts,
+ slices.dur AS dur,
+ thread.name AS process_name,
+ slices.name AS animator_name
+FROM slices
+INNER JOIN process_track on slices.track_id = process_track.id
+INNER JOIN thread USING(upid)
+WHERE slices.name GLOB "animator*";
+
+DROP VIEW IF EXISTS frame_times;
+CREATE VIEW frame_times AS
+SELECT
+ functions.ts AS ts,
+ functions.ts + functions.dur AS ts_end,
+ launches.package AS name,
+ launches.id AS launch_id,
+ ROW_NUMBER() OVER(PARTITION BY launches.id ORDER BY functions.ts ASC) as number
+FROM functions
+INNER JOIN launches on launches.package GLOB '*' || functions.process_name || '*'
+WHERE functions.function_name GLOB "Choreographer#doFrame*" AND functions.ts > launches.ts;
+
+DROP TABLE IF EXISTS hsc_based_startup_times;
+CREATE TABLE hsc_based_startup_times(package STRING, id INT, ts_total INT);
+
+-- Calculator
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package GLOB '*' || frame_times.name || '*'
+WHERE frame_times.number=2 AND frame_times.name GLOB "*roid.calcul*" AND frame_times.launch_id = launches.id;
+
+-- Calendar
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package GLOB '*' || frame_times.name || '*'
+WHERE frame_times.name GLOB "*id.calendar*" AND frame_times.launch_id = launches.id
+ORDER BY ABS(frame_times.ts_end - (SELECT ts + dur FROM functions WHERE function_name GLOB "DrawFrame*" AND process_name GLOB "*id.calendar" ORDER BY ts LIMIT 1)) LIMIT 1;
+
+-- Camera
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package GLOB '*' || frame_times.name || '*'
+WHERE frame_times.number=2 AND frame_times.name GLOB "*GoogleCamera*" AND frame_times.launch_id = launches.id;
+
+-- Chrome
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package GLOB '*' || frame_times.name || '*'
+WHERE frame_times.number=1 AND frame_times.name GLOB "*chrome*" AND frame_times.launch_id = launches.id;
+
+-- Clock
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package GLOB '*' || frame_times.name || '*'
+WHERE frame_times.ts > (SELECT ts + dur FROM animators WHERE animator_name="animator:translationZ" AND process_name GLOB "*id.deskclock" ORDER BY (ts+dur) DESC LIMIT 1) AND frame_times.name GLOB "*id.deskclock" AND frame_times.launch_id = launches.id
+ORDER BY ts_total LIMIT 1;
+
+-- Contacts
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package GLOB '*' || frame_times.name || '*'
+WHERE frame_times.number=3 AND frame_times.name GLOB "*id.contacts" AND frame_times.launch_id=launches.id;
+
+-- Dialer
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package GLOB '*' || frame_times.name || '*'
+WHERE frame_times.number=1 AND frame_times.name GLOB "*id.dialer" AND frame_times.launch_id=launches.id;
+
+-- Facebook
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package GLOB '*' || frame_times.name || '*'
+WHERE frame_times.ts > (SELECT ts+dur FROM slices WHERE slices.name GLOB "fb_startup_complete" ORDER BY ts LIMIT 1) AND frame_times.name GLOB "*ok.katana" AND frame_times.launch_id = launches.id
+ORDER BY ts_total LIMIT 1;
+
+-- Facebook Messenger
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package GLOB '*' || frame_times.name || '*'
+WHERE frame_times.ts > (SELECT ts+dur FROM slices WHERE slices.name GLOB "msgr_cold_start_to_cached_content" ORDER BY ts LIMIT 1) AND frame_times.name GLOB "*book.orca" AND frame_times.launch_id = launches.id
+ORDER BY ts_total LIMIT 1;
+
+-- Gmail
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package GLOB '*' || frame_times.name || '*'
+WHERE frame_times.ts > (SELECT ts + dur FROM animators WHERE animator_name="animator:elevation" AND process_name GLOB "*android.gm" ORDER BY (ts+dur) DESC LIMIT 1) AND frame_times.name GLOB "*android.gm" AND frame_times.launch_id = launches.id
+ORDER BY ts_total LIMIT 1;
+
+-- Instagram
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package GLOB '*' || frame_times.name || '*'
+WHERE frame_times.ts > (SELECT ts+dur FROM slices WHERE slices.name GLOB "ig_cold_start_to_cached_content" ORDER BY ts LIMIT 1) AND frame_times.name GLOB "*gram.android" AND frame_times.launch_id = launches.id
+ORDER BY ts_total LIMIT 1;
+
+-- Maps
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package GLOB '*' || frame_times.name || '*'
+WHERE frame_times.number=1 AND frame_times.name GLOB "*maps*" AND frame_times.launch_id = launches.id;
+
+-- Messages
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package GLOB '*' || frame_times.name || '*'
+WHERE frame_times.ts_end > (SELECT ts + dur FROM animators WHERE animator_name="animator:translationZ" AND process_name GLOB "*apps.messaging*" ORDER BY ts LIMIT 1) AND frame_times.name GLOB "*apps.messaging*" AND frame_times.launch_id = launches.id
+ORDER BY ts_total LIMIT 1;
+
+-- Netflix
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package GLOB '*' || frame_times.name || '*'
+WHERE frame_times.ts < (SELECT ts FROM animators WHERE animator_name GLOB "animator*" AND process_name GLOB "*lix.mediaclient" ORDER BY ts LIMIT 1) AND frame_times.name GLOB "*lix.mediaclient*" AND frame_times.launch_id = launches.id
+ORDER BY ts_total DESC LIMIT 1;
+
+-- Photos
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package GLOB '*' || frame_times.name || '*'
+WHERE frame_times.number=1 AND frame_times.name GLOB "*apps.photos*" AND frame_times.launch_id = launches.id;
+
+-- Settings was deprecated in favor of reportFullyDrawn b/169694037.
+
+-- Snapchat
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package GLOB '*' || frame_times.name || '*'
+WHERE frame_times.number=1 AND frame_times.name GLOB "*napchat.android" AND frame_times.launch_id = launches.id;
+
+-- Twitter
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package GLOB '*' || frame_times.name || '*'
+WHERE frame_times.ts_end > (SELECT ts FROM animators WHERE animator_name="animator" AND process_name GLOB "*tter.android" ORDER BY ts LIMIT 1) AND frame_times.name GLOB "*tter.android" AND frame_times.launch_id = launches.id
+ORDER BY ts_total LIMIT 1;
+
+-- WhatsApp
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package GLOB '*' || frame_times.name || '*'
+WHERE frame_times.ts > (SELECT ts+dur FROM slices WHERE slices.name GLOB "wa_startup_complete" ORDER BY ts LIMIT 1) AND frame_times.name GLOB "*om.whatsapp" AND frame_times.launch_id = launches.id
+ORDER BY ts_total LIMIT 1;
+
+-- Youtube
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package GLOB '*' || frame_times.name || '*'
+WHERE frame_times.number=2 AND frame_times.name GLOB "*id.youtube" AND frame_times.launch_id = launches.id;
diff --git a/src/trace_processor/metrics/sql/android/startup/launches.sql b/src/trace_processor/metrics/sql/android/startup/launches.sql
new file mode 100644
index 000000000..60c1cabb4
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/startup/launches.sql
@@ -0,0 +1,100 @@
+--
+-- Copyright 2019 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+-- The start of the launching event corresponds to the end of the AM handling
+-- the startActivity intent, whereas the end corresponds to the first frame drawn.
+-- Only successful app launches have a launching event.
+DROP TABLE IF EXISTS launching_events;
+CREATE TABLE launching_events AS
+SELECT
+ ts,
+ dur,
+ ts + dur AS ts_end,
+ STR_SPLIT(s.name, ": ", 1) AS package_name
+FROM slice s
+JOIN process_track t ON s.track_id = t.id
+JOIN process USING(upid)
+WHERE s.name GLOB 'launching: *'
+AND (process.name IS NULL OR process.name = 'system_server');
+
+SELECT CREATE_FUNCTION(
+ 'SLICE_COUNT(slice_glob STRING)',
+ 'INT',
+ 'SELECT COUNT(1) FROM slice WHERE name GLOB $slice_glob'
+);
+
+-- All activity launches in the trace, keyed by ID.
+-- Populated by different scripts depending on the platform version / contents.
+-- See android/startup/launches*.sql
+DROP TABLE IF EXISTS launches;
+CREATE TABLE launches(
+ id INTEGER PRIMARY KEY,
+ ts BIG INT,
+ ts_end BIG INT,
+ dur BIG INT,
+ package STRING
+);
+
+-- Note: on Q, we didn't have Android fingerprints but we *did*
+-- have ActivityMetricsLogger events so we will use this approach
+-- if we see any such events.
+SELECT CASE
+ WHEN SLICE_COUNT('launchingActivity#*:*') > 0
+ THEN RUN_METRIC('android/startup/launches_minsdk33.sql')
+ WHEN SLICE_COUNT('MetricsLogger:*') > 0
+ THEN RUN_METRIC('android/startup/launches_minsdk29.sql')
+ ELSE RUN_METRIC('android/startup/launches_maxsdk28.sql')
+END;
+
+-- Maps a launch to the corresponding set of processes that handled the
+-- activity start. The vast majority of cases should be a single process.
+-- However it is possible that the process dies during the activity launch
+-- and is respawned.
+DROP TABLE IF EXISTS launch_processes;
+CREATE TABLE launch_processes(launch_id INT, upid BIG INT, launch_type STRING);
+
+SELECT CREATE_FUNCTION(
+ 'STARTUP_SLICE_COUNT(start_ts LONG, end_ts LONG, utid INT, name STRING)',
+ 'INT',
+ '
+ SELECT COUNT(1)
+ FROM thread_track t
+ JOIN slice s ON s.track_id = t.id
+ WHERE
+ t.utid = $utid AND
+ s.ts >= $start_ts AND
+ s.ts < $end_ts AND
+ s.name = $name
+ '
+);
+
+INSERT INTO launch_processes(launch_id, upid, launch_type)
+SELECT
+ l.id AS launch_id,
+ p.upid,
+ CASE
+ WHEN STARTUP_SLICE_COUNT(l.ts, l.ts_end, t.utid, 'bindApplication') > 0
+ THEN 'cold'
+ WHEN STARTUP_SLICE_COUNT(l.ts, l.ts_end, t.utid, 'activityStart') > 0
+ THEN 'warm'
+ WHEN STARTUP_SLICE_COUNT(l.ts, l.ts_end, t.utid, 'activityResume') > 0
+ THEN 'hot'
+ ELSE NULL
+ END AS launch_type
+FROM launches l
+LEFT JOIN package_list ON (l.package = package_list.package_name)
+JOIN process p ON (l.package = p.name OR p.uid = package_list.uid)
+JOIN thread t ON (p.upid = t.upid AND t.is_main_thread)
+WHERE launch_type IS NOT NULL;
diff --git a/src/trace_processor/metrics/sql/android/startup/launches_maxsdk28.sql b/src/trace_processor/metrics/sql/android/startup/launches_maxsdk28.sql
new file mode 100644
index 000000000..35c797eeb
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/startup/launches_maxsdk28.sql
@@ -0,0 +1,28 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+-- Cold/warm starts emitted launching slices on API level 28-.
+INSERT INTO launches(id, ts, ts_end, dur, package)
+SELECT
+ ROW_NUMBER() OVER(ORDER BY ts) AS id,
+ launching_events.ts AS ts,
+ launching_events.ts_end AS ts_end,
+ launching_events.ts_end - launching_events.ts AS dur,
+ package_name AS package
+FROM launching_events
+ORDER BY ts;
+
+-- TODO(lalitm): add handling of hot starts using frame timings.
diff --git a/src/trace_processor/metrics/sql/android/startup/launches_minsdk29.sql b/src/trace_processor/metrics/sql/android/startup/launches_minsdk29.sql
new file mode 100644
index 000000000..e5631bfd3
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/startup/launches_minsdk29.sql
@@ -0,0 +1,73 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+-- Marks the beginning of the trace and is equivalent to when the statsd launch
+-- logging begins.
+DROP VIEW IF EXISTS activity_intent_received;
+CREATE VIEW activity_intent_received AS
+SELECT ts FROM slice
+WHERE name = 'MetricsLogger:launchObserverNotifyIntentStarted';
+
+-- We partition the trace into spans based on posted activity intents.
+-- We will refine these progressively in the next steps to only encompass
+-- activity starts.
+DROP TABLE IF EXISTS activity_intent_recv_spans;
+CREATE TABLE activity_intent_recv_spans(id INT, ts BIG INT, dur BIG INT);
+
+INSERT INTO activity_intent_recv_spans
+SELECT
+ ROW_NUMBER()
+ OVER(ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS id,
+ ts,
+ LEAD(ts, 1, (SELECT end_ts FROM trace_bounds)) OVER(ORDER BY ts) - ts AS dur
+FROM activity_intent_received
+ORDER BY ts;
+
+-- Filter activity_intent_recv_spans, keeping only the ones that triggered
+-- a launch.
+DROP VIEW IF EXISTS launch_partitions;
+CREATE VIEW launch_partitions AS
+SELECT * FROM activity_intent_recv_spans AS spans
+WHERE 1 = (
+ SELECT COUNT(1)
+ FROM launching_events
+ WHERE launching_events.ts BETWEEN spans.ts AND spans.ts + spans.dur);
+
+-- Successful activity launch. The end of the 'launching' event is not related
+-- to whether it actually succeeded or not.
+DROP VIEW IF EXISTS activity_intent_launch_successful;
+CREATE VIEW activity_intent_launch_successful AS
+SELECT ts FROM slice
+WHERE name = 'MetricsLogger:launchObserverNotifyActivityLaunchFinished';
+
+-- Use the starting event package name. The finish event package name
+-- is not reliable in the case of failed launches.
+INSERT INTO launches(id, ts, ts_end, dur, package)
+SELECT
+ lpart.id AS id,
+ lpart.ts AS ts,
+ launching_events.ts_end AS ts_end,
+ launching_events.ts_end - lpart.ts AS dur,
+ package_name AS package
+FROM launch_partitions AS lpart
+JOIN launching_events ON
+ (launching_events.ts BETWEEN lpart.ts AND lpart.ts + lpart.dur) AND
+ (launching_events.ts_end BETWEEN lpart.ts AND lpart.ts + lpart.dur)
+WHERE (
+ SELECT COUNT(1)
+ FROM activity_intent_launch_successful AS successful
+ WHERE successful.ts BETWEEN lpart.ts AND lpart.ts + lpart.dur
+) > 0;
diff --git a/src/trace_processor/metrics/sql/android/startup/launches_minsdk33.sql b/src/trace_processor/metrics/sql/android/startup/launches_minsdk33.sql
new file mode 100644
index 000000000..f3773bb7a
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/startup/launches_minsdk33.sql
@@ -0,0 +1,47 @@
+--
+-- Copyright 2022 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+DROP VIEW IF EXISTS launch_async_events;
+CREATE VIEW launch_async_events AS
+SELECT
+ ts,
+ dur,
+ SUBSTR(name, 19) id
+FROM slice
+WHERE
+ name GLOB 'launchingActivity#*'
+ AND dur != 0
+ AND INSTR(name, ':') = 0;
+
+DROP VIEW IF EXISTS launch_complete_events;
+CREATE VIEW launch_complete_events AS
+SELECT
+ STR_SPLIT(completed, ':completed:', 0) id,
+ STR_SPLIT(completed, ':completed:', 1) package_name
+FROM (
+ SELECT SUBSTR(name, 19) completed
+ FROM slice
+ WHERE dur = 0 AND name GLOB 'launchingActivity#*:completed:*'
+);
+
+INSERT INTO launches(id, ts, ts_end, dur, package)
+SELECT
+ id,
+ ts,
+ ts + dur ts_end,
+ dur,
+ package_name
+FROM launch_async_events JOIN launch_complete_events USING (id);
diff --git a/src/trace_processor/metrics/sql/android/thread_counter_span_view.sql b/src/trace_processor/metrics/sql/android/thread_counter_span_view.sql
new file mode 100644
index 000000000..da13734b4
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/thread_counter_span_view.sql
@@ -0,0 +1,32 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+DROP VIEW IF EXISTS {{table_name}}_span;
+CREATE VIEW {{table_name}}_span AS
+SELECT
+ ts,
+ LEAD(ts, 1, (
+ SELECT IFNULL(
+ end_ts,
+ (SELECT end_ts FROM trace_bounds)
+ )
+ FROM thread th WHERE th.utid = t.utid) + 1
+ ) OVER(PARTITION BY track_id ORDER BY ts) - ts AS dur,
+ utid,
+ value AS {{table_name}}_val
+FROM counter c JOIN thread_counter_track t
+ ON t.id = c.track_id
+WHERE name = '{{counter_name}}' AND utid IS NOT NULL;
diff --git a/src/trace_processor/metrics/sql/android/unsymbolized_frames.sql b/src/trace_processor/metrics/sql/android/unsymbolized_frames.sql
new file mode 100644
index 000000000..9a0ecd6c0
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/unsymbolized_frames.sql
@@ -0,0 +1,75 @@
+--
+-- Copyright 2019 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+-- On Linux/Android perfetto profilers (heapprofd, traced_perf) record the
+-- .note.gnu.build-id as build_id. Within Google, this can be used as a lookup
+-- key for most cases, but not for Chrome/Webview. Chrome is special and stores
+-- symbols indexed by "breadkpad module ID". Breakpad module ID can be derived
+-- with the following formula:
+-- base::StrCat({module_id->substr(6, 2), module_id->substr(4, 2),
+-- module_id->substr(2, 2), module_id->substr(0, 2),
+-- module_id->substr(10, 2), module_id->substr(8, 2),
+-- module_id->substr(14, 2), module_id->substr(12, 2),
+-- module_id->substr(16, 16), "0"});
+-- See also https://source.chromium.org/chromium/chromium/src/+/main:services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.cc;l=603;drc=cba00174ca338153b9c4f0c31ddbabaac7dd38c7
+-- Note that in SQL SUBSTR() indexes are 1-based, not 0 based.
+DROP VIEW IF EXISTS mangled_stack_profile_mapping;
+CREATE VIEW mangled_stack_profile_mapping AS
+ SELECT
+ id,
+ name,
+ build_id,
+ CASE ((name GLOB '*libmonochrome_64.so'
+ OR name GLOB '*libchrome.so'
+ OR name GLOB '*libmonochrome.so'
+ OR name GLOB '*libwebviewchromium.so'
+ OR name GLOB '*libchromium_android_linker.so'
+ ) AND length(build_id) >= 40)
+ WHEN 0 THEN build_id
+ ELSE (
+ SUBSTR(build_id, 7, 2) ||
+ SUBSTR(build_id, 5, 2) ||
+ SUBSTR(build_id, 3, 2) ||
+ SUBSTR(build_id, 1, 2) ||
+ SUBSTR(build_id, 11, 2) ||
+ SUBSTR(build_id, 9, 2) ||
+ SUBSTR(build_id, 15, 2) ||
+ SUBSTR(build_id, 13, 2) ||
+ SUBSTR(build_id, 17, 16) ||
+ '0')
+ END as google_lookup_id
+ FROM stack_profile_mapping;
+
+DROP VIEW IF EXISTS unsymbolized_frames_view;
+CREATE VIEW unsymbolized_frames_view AS
+SELECT UnsymbolizedFrames_Frame(
+ 'module', spm.name,
+ 'build_id', spm.build_id,
+ 'address', spf.rel_pc,
+ 'google_lookup_id', spm.google_lookup_id
+) AS frame_proto
+FROM stack_profile_frame spf
+JOIN mangled_stack_profile_mapping spm
+ON spf.mapping = spm.id
+WHERE spm.build_id != ''
+AND (spf.symbol_set_id == 0 OR spf.symbol_set_id IS NULL);
+
+DROP VIEW IF EXISTS unsymbolized_frames_output;
+CREATE VIEW unsymbolized_frames_output AS
+SELECT UnsymbolizedFrames(
+ 'frames',
+ (SELECT RepeatedField(frame_proto) FROM unsymbolized_frames_view)
+);
diff --git a/src/trace_processor/metrics/chrome/OWNERS b/src/trace_processor/metrics/sql/chrome/OWNERS
index cbde4c97f..cbde4c97f 100644
--- a/src/trace_processor/metrics/chrome/OWNERS
+++ b/src/trace_processor/metrics/sql/chrome/OWNERS
diff --git a/src/trace_processor/metrics/chrome/actual_power_by_category.sql b/src/trace_processor/metrics/sql/chrome/actual_power_by_category.sql
index 27b632e88..27b632e88 100644
--- a/src/trace_processor/metrics/chrome/actual_power_by_category.sql
+++ b/src/trace_processor/metrics/sql/chrome/actual_power_by_category.sql
diff --git a/src/trace_processor/metrics/chrome/actual_power_by_rail_mode.sql b/src/trace_processor/metrics/sql/chrome/actual_power_by_rail_mode.sql
index 901a07baa..901a07baa 100644
--- a/src/trace_processor/metrics/chrome/actual_power_by_rail_mode.sql
+++ b/src/trace_processor/metrics/sql/chrome/actual_power_by_rail_mode.sql
diff --git a/src/trace_processor/metrics/chrome/chrome_event_metadata.sql b/src/trace_processor/metrics/sql/chrome/chrome_event_metadata.sql
index cc2300498..cc2300498 100644
--- a/src/trace_processor/metrics/chrome/chrome_event_metadata.sql
+++ b/src/trace_processor/metrics/sql/chrome/chrome_event_metadata.sql
diff --git a/src/trace_processor/metrics/sql/chrome/chrome_histogram_hashes.sql b/src/trace_processor/metrics/sql/chrome/chrome_histogram_hashes.sql
new file mode 100644
index 000000000..ef5d918de
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/chrome_histogram_hashes.sql
@@ -0,0 +1,26 @@
+--
+-- Copyright 2022 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+DROP VIEW IF EXISTS chrome_histogram_hashes_output;
+
+CREATE VIEW chrome_histogram_hashes_output AS
+SELECT ChromeHistogramHashes(
+ 'hash', (
+ SELECT RepeatedField(int_value)
+ FROM args
+ WHERE key = 'chrome_histogram_sample.name_hash'
+ ORDER BY int_value
+ )
+);
diff --git a/src/trace_processor/metrics/sql/chrome/chrome_performance_mark_hashes.sql b/src/trace_processor/metrics/sql/chrome/chrome_performance_mark_hashes.sql
new file mode 100644
index 000000000..b424adb94
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/chrome_performance_mark_hashes.sql
@@ -0,0 +1,33 @@
+--
+-- Copyright 2022 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+DROP VIEW IF EXISTS chrome_performance_mark_hashes_output;
+
+CREATE VIEW chrome_performance_mark_hashes_output AS
+SELECT ChromePerformanceMarkHashes(
+ 'site_hash', (
+ SELECT RepeatedField(int_value)
+ FROM args
+ WHERE key = 'chrome_hashed_performance_mark.site_hash'
+ ORDER BY int_value
+ ),
+ 'mark_hash', (
+ SELECT RepeatedField(int_value)
+ FROM args
+ WHERE key = 'chrome_hashed_performance_mark.mark_hash'
+ ORDER BY int_value
+ )
+);
+
diff --git a/src/trace_processor/metrics/sql/chrome/chrome_processes.sql b/src/trace_processor/metrics/sql/chrome/chrome_processes.sql
new file mode 100644
index 000000000..a7b378b83
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/chrome_processes.sql
@@ -0,0 +1,126 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+-- Table to map any of the various chrome process names to a type (e.g. Browser,
+-- Renderer, GPU Process, etc).
+DROP TABLE IF EXISTS chrome_process_name_type_mapping;
+CREATE TABLE chrome_process_name_type_mapping (
+ original_name_pattern TEXT UNIQUE,
+ type TEXT
+);
+
+WITH prefix (value) AS (
+ SELECT *
+ FROM (
+ VALUES ("org.chromium.chrome"),
+ ("com.google.android.apps.chrome"),
+ ("com.android.chrome"),
+ ("com.chrome.beta"),
+ ("com.chrome.canary"),
+ ("com.chrome.dev")
+ )
+),
+suffix (value, TYPE) AS (
+ SELECT *
+ FROM (
+ VALUES ("", "Browser"),
+ (
+ ":sandboxed_process*:org.chromium.content.app.SandboxedProcessService*",
+ "Sandboxed"
+ ),
+ (":privileged_process*", "Privileged"),
+ ("_zygote", "Zygote")
+ )
+)
+-- Insert the Chrome process names for a normal chrome trace
+INSERT INTO chrome_process_name_type_mapping
+VALUES ('Browser', 'Browser'),
+ ('Renderer', 'Renderer'),
+ ('GPU Process', 'Gpu'),
+ ('Gpu', 'Gpu'),
+ ('Zygote', 'Zygote'),
+ ('Utility', 'Utility'),
+ ('SandboxHelper', 'SandboxHelper'),
+ ('PpapiPlugin', 'PpapiPlugin'),
+ ('PpapiBroker', 'PpapiBroker')
+UNION ALL
+-- Construct all the possible Chrome process names for an Android system chrome
+-- trace.
+SELECT prefix.value || suffix.value AS name,
+ suffix.type AS type
+FROM prefix,
+ suffix;
+
+DROP VIEW IF EXISTS all_chrome_processes;
+CREATE VIEW all_chrome_processes AS
+SELECT upid, m.type AS process_type
+FROM process JOIN chrome_process_name_type_mapping m
+ON name GLOB original_name_pattern;
+
+-- A view of all Chrome threads.
+DROP VIEW IF EXISTS all_chrome_threads;
+CREATE VIEW all_chrome_threads AS
+ SELECT utid, thread.upid, thread.name
+ FROM thread, all_chrome_processes
+ WHERE thread.upid = all_chrome_processes.upid;
+
+-- For sandboxed and privileged processes (found in Android system traces), use
+-- the main thread name to type of process.
+DROP VIEW IF EXISTS chrome_subprocess_types;
+CREATE VIEW chrome_subprocess_types AS
+-- Sometimes you can get multiple threads in a trace marked main_thread, but
+-- they appear to have the same name so just use one of them.
+SELECT DISTINCT p.upid,
+ SUBSTR(t.name, 3, LENGTH(t.name) - 6) AS sandbox_type
+FROM all_chrome_processes p
+ JOIN all_chrome_threads t ON p.upid = t.upid
+WHERE process_type IN ("Sandboxed", "Privileged")
+ AND t.name GLOB "Cr*Main";
+
+-- Contains all the chrome processes from process with an extra column,
+-- process_type.
+DROP VIEW IF EXISTS chrome_process;
+CREATE VIEW chrome_process AS
+SELECT PROCESS.*,
+ IIF(sandbox_type IS NULL, process_type, sandbox_type) AS process_type
+FROM PROCESS
+ JOIN (
+ SELECT a.upid,
+ sandbox_type,
+ process_type
+ FROM all_chrome_processes a
+ LEFT JOIN chrome_subprocess_types s ON a.upid = s.upid
+ ) c ON PROCESS.upid = c.upid;
+
+-- Contains all the chrome threads from thread with an extra column,
+-- canonical_name, that should contain a thread that's the same in both chrome
+-- and system traces.
+DROP VIEW IF EXISTS chrome_thread;
+
+CREATE VIEW chrome_thread AS
+SELECT thread.*,
+ CASE
+ WHEN thread.name GLOB "Cr*Main" THEN "CrProcessMain"
+ WHEN thread.name IS NULL THEN "Unknown"
+ ELSE thread.name
+ END AS canonical_name
+FROM (
+ SELECT t.utid,
+ p.*
+ FROM all_chrome_threads t
+ JOIN chrome_process p ON t.upid = p.upid
+ ) c
+ JOIN thread ON thread.utid = c.utid;
diff --git a/src/trace_processor/metrics/sql/chrome/chrome_slice_names.sql b/src/trace_processor/metrics/sql/chrome/chrome_slice_names.sql
new file mode 100644
index 000000000..95ea99523
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/chrome_slice_names.sql
@@ -0,0 +1,32 @@
+--
+-- Copyright 2022 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+
+DROP VIEW IF EXISTS chrome_slice_names_output;
+
+CREATE VIEW chrome_slice_names_output AS
+SELECT ChromeSliceNames(
+ 'chrome_version_code', (
+ SELECT RepeatedField(int_value)
+ FROM metadata
+ WHERE name = 'cr-playstore_version_code'
+ ORDER BY int_value
+ ),
+ 'slice_name', (
+ SELECT RepeatedField(DISTINCT(name))
+ FROM slice
+ ORDER BY name
+ )
+);
diff --git a/src/trace_processor/metrics/sql/chrome/chrome_thread_slice.sql b/src/trace_processor/metrics/sql/chrome/chrome_thread_slice.sql
new file mode 100644
index 000000000..273d3e728
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/chrome_thread_slice.sql
@@ -0,0 +1,38 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+SELECT RUN_METRIC('chrome/chrome_processes.sql');
+
+-- Grab all the thread tracks which are found in chrome threads.
+DROP VIEW IF EXISTS chrome_track;
+CREATE VIEW chrome_track AS
+ SELECT
+ *
+ FROM thread_track
+ WHERE utid IN (SELECT utid FROM chrome_thread);
+
+-- From all the chrome thread tracks select all the slice details for thread
+-- slices.
+DROP VIEW IF EXISTS chrome_thread_slice;
+CREATE VIEW chrome_thread_slice AS
+ SELECT
+ thread_slice.*
+ FROM
+ thread_slice JOIN
+ chrome_track ON
+ chrome_track.id = thread_slice.track_id
+ WHERE
+ track_id in (SELECT id FROM chrome_track); \ No newline at end of file
diff --git a/src/trace_processor/metrics/sql/chrome/chrome_user_event_hashes.sql b/src/trace_processor/metrics/sql/chrome/chrome_user_event_hashes.sql
new file mode 100644
index 000000000..005e2ad3d
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/chrome_user_event_hashes.sql
@@ -0,0 +1,26 @@
+--
+-- Copyright 2022 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+DROP VIEW IF EXISTS chrome_user_event_hashes_output;
+
+CREATE VIEW chrome_user_event_hashes_output AS
+SELECT ChromeUserEventHashes(
+ 'action_hash', (
+ SELECT RepeatedField(int_value)
+ FROM args
+ WHERE key = 'chrome_user_event.action_hash'
+ ORDER BY int_value
+ )
+);
diff --git a/src/trace_processor/metrics/chrome/cpu_time_by_category.sql b/src/trace_processor/metrics/sql/chrome/cpu_time_by_category.sql
index 2981ebd56..2981ebd56 100644
--- a/src/trace_processor/metrics/chrome/cpu_time_by_category.sql
+++ b/src/trace_processor/metrics/sql/chrome/cpu_time_by_category.sql
diff --git a/src/trace_processor/metrics/chrome/cpu_time_by_rail_mode.sql b/src/trace_processor/metrics/sql/chrome/cpu_time_by_rail_mode.sql
index 426bd25b2..426bd25b2 100644
--- a/src/trace_processor/metrics/chrome/cpu_time_by_rail_mode.sql
+++ b/src/trace_processor/metrics/sql/chrome/cpu_time_by_rail_mode.sql
diff --git a/src/trace_processor/metrics/chrome/estimated_power_by_category.sql b/src/trace_processor/metrics/sql/chrome/estimated_power_by_category.sql
index 506d2a1f9..506d2a1f9 100644
--- a/src/trace_processor/metrics/chrome/estimated_power_by_category.sql
+++ b/src/trace_processor/metrics/sql/chrome/estimated_power_by_category.sql
diff --git a/src/trace_processor/metrics/chrome/estimated_power_by_rail_mode.sql b/src/trace_processor/metrics/sql/chrome/estimated_power_by_rail_mode.sql
index a0b9b22ae..a0b9b22ae 100644
--- a/src/trace_processor/metrics/chrome/estimated_power_by_rail_mode.sql
+++ b/src/trace_processor/metrics/sql/chrome/estimated_power_by_rail_mode.sql
diff --git a/src/trace_processor/metrics/sql/chrome/gesture_flow_event.sql b/src/trace_processor/metrics/sql/chrome/gesture_flow_event.sql
new file mode 100644
index 000000000..69b824d74
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/gesture_flow_event.sql
@@ -0,0 +1,262 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the 'License');
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an 'AS IS' BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- While handling a InputLatency::{{gesture_update}} event a sequence of Flows
+-- define the critical path from Beginning to End. This metric breaks down the
+-- flows for the same InputLatency::{{gesture_update}} event.
+--
+-- WARNING: This metric should not be used as a source of truth. It is under
+-- active development and the values & meaning might change without
+-- notice.
+
+-- Provides the {{prefix}}_jank table which gives us all the {{gesture_update}}
+-- events we care about and labels them janky or not.
+SELECT RUN_METRIC('chrome/{{prefix}}_jank.sql');
+
+-- We get all latency_info that have valid trace_ids, And we make a synthetic
+-- one for the beginning of each {{gesture_update}} event so we can track the
+-- time between receiving the input and being converted into a gesture.
+--
+-- flows with a trace_id of -1 are incomplete and are difficult to reason about
+-- (especially if {{gesture_update}} flows end up getting -1). so ignore them
+-- for this table.
+DROP VIEW IF EXISTS {{prefix}}_latency_info_flow_step_and_ancestors;
+CREATE VIEW {{prefix}}_latency_info_flow_step_and_ancestors AS
+ SELECT
+ *
+ FROM (
+ SELECT
+ slice.name,
+ slice.id,
+ slice.ts,
+ slice.dur,
+ slice.track_id,
+ EXTRACT_ARG(slice.arg_set_id, 'chrome_latency_info.trace_id') AS trace_id,
+ EXTRACT_ARG(slice.arg_set_id, 'chrome_latency_info.step') AS step,
+ COALESCE(ancestor_zero.name, slice.name) AS ancestor_name_zero,
+ COALESCE(ancestor_zero.id, slice.id) AS ancestor_id_zero,
+ COALESCE(ancestor_zero.ts, slice.ts) AS ancestor_ts_zero,
+ COALESCE(ancestor_zero.dur, slice.dur) AS ancestor_dur_zero,
+ COALESCE(ancestor_one.name, slice.name) AS ancestor_name_one,
+ COALESCE(ancestor_one.id, slice.id) AS ancestor_id_one,
+ COALESCE(ancestor_one.ts, slice.ts) AS ancestor_ts_one,
+ COALESCE(ancestor_one.dur, slice.dur) AS ancestor_dur_one
+ FROM
+ slice LEFT JOIN
+ ancestor_slice(slice.id) AS ancestor_zero
+ ON ancestor_zero.depth = 0 LEFT JOIN
+ ancestor_slice(slice.id) AS ancestor_one ON ancestor_one.depth = 1
+ WHERE
+ slice.name = 'LatencyInfo.Flow' AND
+ EXTRACT_ARG(slice.arg_set_id, 'chrome_latency_info.trace_id') != -1
+ ) flow JOIN (
+ SELECT
+ id AS gesture_slice_id,
+ ts AS gesture_ts,
+ dur AS {{prefix}}_dur,
+ track_id AS gesture_track_id,
+ trace_id AS {{prefix}}_trace_id,
+ jank,
+ {{id_field}},
+ avg_vsync_interval
+ FROM {{prefix}}_jank
+ ) gesture ON
+ flow.trace_id = gesture.{{prefix}}_trace_id
+ UNION ALL
+ SELECT
+ 'InputLatency::{{gesture_update}}' AS name,
+ id,
+ ts,
+ dur,
+ track_id,
+ trace_id,
+ 'AsyncBegin' AS step,
+ 'InputLatency::{{gesture_update}}' AS ancestor_name_zero,
+ id AS ancestor_id_zero,
+ ts AS ancestor_ts_zero,
+ 0 AS ancestor_dur_zero,
+ 'InputLatency::{{gesture_update}}' AS ancestor_name_one,
+ id AS ancestor_id_one,
+ ts AS ancestor_ts_one,
+ 0 AS ancestor_dur_one,
+ id AS gesture_slice_id,
+ ts AS gesture_ts,
+ dur AS {{prefix}}_dur,
+ track_id AS gesture_track_id,
+ trace_id AS {{prefix}}_trace_id,
+ jank,
+ {{id_field}},
+ avg_vsync_interval
+ FROM {{prefix}}_jank
+ ORDER BY {{id_field}} ASC, trace_id ASC, ts ASC;
+
+-- See b/184134310, but "ThreadController active" spans multiple tasks and when
+-- the top level parent is this event we should use the second event instead.
+DROP VIEW IF EXISTS {{prefix}}_latency_info_flow_step;
+CREATE VIEW {{prefix}}_latency_info_flow_step AS
+ SELECT
+ *,
+ CASE WHEN ancestor_name_zero != "ThreadController active" THEN
+ ancestor_name_zero ELSE ancestor_name_one END AS ancestor_name,
+ CASE WHEN ancestor_name_zero != "ThreadController active" THEN
+ ancestor_id_zero ELSE ancestor_id_one END AS ancestor_id,
+ CASE WHEN ancestor_name_zero != "ThreadController active" THEN
+ ancestor_ts_zero ELSE ancestor_ts_one END AS ancestor_ts,
+ CASE WHEN ancestor_name_zero != "ThreadController active" THEN
+ ancestor_dur_zero ELSE ancestor_dur_one END AS ancestor_dur
+ FROM {{prefix}}_latency_info_flow_step_and_ancestors;
+
+-- This is a heuristic to figure out which flow event properly joins this
+-- {{gesture_update}}. This heuristic is only needed in traces before we added
+-- {{id_field}}.
+--
+-- We select the first |ts| from a flow event after its corresponding
+-- {{gesture_update}} has ended. This allows us to use this |ts| to contain all
+-- flow events from the start of a particular gesture_slice_id (the slice id of
+-- the async event) to that |ts|.
+--
+-- The reason for this is if these flow events share the same trace_id which can
+-- occur if multiple chrome browsers are in the trace (webview & chrome for
+-- example). We would normally add flow events from different gestures, but by
+-- limiting by the {{gesture_update}} end we can prevent incorrect duplication.
+-- This breaks of course if the same trace_id happens at the exact same time in
+-- both browsers but this is hopefully unlikely.
+DROP VIEW IF EXISTS {{prefix}}_max_latency_info_ts_per_trace_id;
+CREATE VIEW {{prefix}}_max_latency_info_ts_per_trace_id AS
+ SELECT
+ gesture_slice_id,
+ MIN(ts) AS max_flow_ts
+ FROM {{prefix}}_latency_info_flow_step
+ WHERE
+ trace_id = {{prefix}}_trace_id AND
+ ts > gesture_ts + {{prefix}}_dur
+ GROUP BY gesture_slice_id;
+
+-- As described by the comments about this uses the heuristic to remove any flow
+-- events that aren't contained within the |max_flow_ts| and the beginning of
+-- the {{gesture_update}}. This prevents other processes that share the same
+-- trace_id from inserting events in the middle.
+--
+-- Note: Must be a TABLE because it uses a window function which can behave
+-- strangely in views.
+DROP TABLE IF EXISTS {{prefix}}_latency_info_flow_step_filtered;
+CREATE TABLE {{prefix}}_latency_info_flow_step_filtered AS
+ SELECT
+ ROW_NUMBER() OVER (ORDER BY
+ flow.{{id_field}} ASC, trace_id ASC, ts ASC) AS row_number,
+ *
+ FROM
+ {{prefix}}_latency_info_flow_step flow JOIN
+ {{prefix}}_max_latency_info_ts_per_trace_id max_flow on
+ max_flow.gesture_slice_id = flow.gesture_slice_id
+ WHERE
+ ts >= gesture_ts AND
+ ts <= max_flow_ts
+ ORDER BY flow.{{id_field}} ASC, flow.trace_id ASC, flow.ts ASC;
+
+-- Take all the LatencyInfo.Flow events and within a |trace_id| join it with the
+-- previous and nextflows. Some events are 'Unknown' when they don't have a step
+-- but occur in the middle of the critical path. Most of these are errors though
+-- and we've weeded I think all of them out (citation needed).
+--
+-- Note: Must be a TABLE because it uses a window function which can behave
+-- strangely in views.
+DROP TABLE IF EXISTS {{prefix}}_latency_info_flow_null_step_removed;
+CREATE TABLE {{prefix}}_latency_info_flow_null_step_removed AS
+ SELECT
+ ROW_NUMBER() OVER (ORDER BY
+ curr.{{id_field}} ASC, curr.trace_id ASC, curr.ts ASC
+ ) AS row_number,
+ curr.id,
+ curr.ts,
+ curr.dur,
+ curr.track_id,
+ curr.trace_id,
+ curr.{{id_field}},
+ curr.avg_vsync_interval,
+ curr.gesture_slice_id,
+ curr.gesture_ts,
+ curr.{{prefix}}_dur,
+ curr.gesture_track_id,
+ curr.jank,
+ curr.ancestor_id,
+ curr.ancestor_ts,
+ curr.ancestor_dur,
+ curr.ancestor_ts + curr.ancestor_dur AS ancestor_end,
+ CASE WHEN curr.step IS NULL THEN
+ CASE WHEN
+ prev.{{id_field}} != curr.{{id_field}} OR
+ prev.trace_id != curr.trace_id OR
+ prev.trace_id IS NULL OR
+ prev.step = 'AsyncBegin' THEN
+ 'Begin'
+ ELSE
+ CASE WHEN
+ next.{{id_field}} != curr.{{id_field}} OR
+ next.trace_id != curr.trace_id OR
+ next.trace_id IS NULL THEN
+ 'End'
+ ELSE
+ 'Unknown'
+ END
+ END
+ ELSE curr.step END AS step
+ FROM
+ {{prefix}}_latency_info_flow_step_filtered curr LEFT JOIN
+ {{prefix}}_latency_info_flow_step_filtered prev ON
+ curr.row_number - 1 = prev.row_number LEFT JOIN
+ {{prefix}}_latency_info_flow_step_filtered next ON
+ curr.row_number + 1 = next.row_number
+ ORDER BY curr.{{id_field}} ASC, curr.trace_id ASC, curr.ts ASC;
+
+-- Now that we've got the steps all named properly we want to join them with the
+-- next step so we can compute the difference between the end of the current
+-- step and the beginning of the next step.
+DROP VIEW IF EXISTS {{prefix}}_flow_event;
+CREATE VIEW {{prefix}}_flow_event AS
+ SELECT
+ curr.trace_id,
+ curr.id,
+ curr.ts,
+ curr.dur,
+ curr.track_id,
+ curr.{{id_field}},
+ curr.avg_vsync_interval,
+ curr.gesture_slice_id AS {{prefix}}_slice_id,
+ curr.gesture_ts AS {{prefix}}_ts,
+ curr.{{prefix}}_dur AS {{prefix}}_dur,
+ curr.gesture_track_id AS {{prefix}}_track_id,
+ curr.jank,
+ curr.step,
+ curr.ancestor_id,
+ curr.ancestor_ts,
+ curr.ancestor_dur,
+ curr.ancestor_end,
+ next.id as next_id,
+ next.ts AS next_ts,
+ next.dur AS next_dur,
+ next.track_id AS next_track_id,
+ next.trace_id AS next_trace_id,
+ next.step AS next_step,
+ CASE WHEN next.trace_id = curr.trace_id THEN
+ next.ancestor_ts
+ ELSE
+ NULL
+ END AS maybe_next_ancestor_ts
+ FROM
+ {{prefix}}_latency_info_flow_null_step_removed curr LEFT JOIN
+ {{prefix}}_latency_info_flow_null_step_removed next ON
+ curr.row_number + 1 = next.row_number
+ ORDER BY curr.{{id_field}}, curr.trace_id, curr.ts;
diff --git a/src/trace_processor/metrics/sql/chrome/gesture_flow_event_queuing_delay.sql b/src/trace_processor/metrics/sql/chrome/gesture_flow_event_queuing_delay.sql
new file mode 100644
index 000000000..e2c069c11
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/gesture_flow_event_queuing_delay.sql
@@ -0,0 +1,76 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the 'License');
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an 'AS IS' BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- This metric takes each flow event in a InputLatency::{gesture_update} and
+-- and computes the time from the ancestor_end of the current flow to the
+-- ancestor_ts of the next flow event. This is a reasonable approximation of the
+-- time we waited for the next step in the critical flow to start.
+
+-- Provides the {{prefix}}_flow_event table which gives us all the flow events
+-- with associated {gesture_update} events we care about and labels them
+-- janky or not.
+SELECT RUN_METRIC('chrome/{{prefix}}_flow_event.sql');
+
+-- Take each flow and next flow (from {{prefix}}_flow_event table) and generate
+-- the metric name as well as compute the time between.
+DROP VIEW IF EXISTS {{prefix}}_flow_event_queuing_delay;
+
+CREATE VIEW {{prefix}}_flow_event_queuing_delay AS
+ SELECT
+ trace_id,
+ id,
+ ts,
+ dur,
+ track_id,
+ {{id_field}},
+ avg_vsync_interval,
+ {{prefix}}_slice_id,
+ {{prefix}}_ts,
+ {{prefix}}_dur,
+ {{prefix}}_track_id,
+ jank,
+ step,
+ ancestor_id,
+ ancestor_ts,
+ ancestor_end,
+ next_id,
+ next_step,
+ maybe_next_ancestor_ts,
+ next_track_id,
+ CASE WHEN trace_id = next_trace_id THEN
+ 'InputLatency.LatencyInfo.Flow.QueuingDelay.' ||
+ CASE WHEN
+ jank IS NOT NULL AND
+ jank = 1
+ THEN
+ 'Jank.'
+ ELSE
+ 'NoJank.'
+ END
+ || step || '-to-' || next_step
+ ELSE
+ step
+ END AS description,
+ CASE WHEN maybe_next_ancestor_ts IS NULL THEN
+ NULL
+ ELSE
+ CASE WHEN maybe_next_ancestor_ts > ancestor_end THEN
+ (maybe_next_ancestor_ts - ancestor_end)
+ ELSE
+ 0
+ END
+ END AS queuing_time_ns
+ FROM {{prefix}}_flow_event
+ ORDER BY {{id_field}}, trace_id, ts;
diff --git a/src/trace_processor/metrics/sql/chrome/gesture_jank.sql b/src/trace_processor/metrics/sql/chrome/gesture_jank.sql
new file mode 100644
index 000000000..6e7ea1adf
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/gesture_jank.sql
@@ -0,0 +1,293 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- A collection of templated metrics related to continuous motion gestures that
+-- have start, end and update events.
+--
+-- We define an update to be janky if comparing forwards or backwards (ignoring
+-- coalesced updates) a given updates exceeds the duration of its predecessor or
+-- successor by 50% of a vsync interval (defaulted to 60 FPS).
+--
+-- WARNING: This metric should not be used as a source of truth. It is under
+-- active development and the values & meaning might change without
+-- notice.
+
+-- A simple table that checks the time between VSync (this can be used to
+-- determine if we're refreshing at 90 FPS or 60 FPS.
+--
+-- Note: In traces without the "Java" category there will be no VSync
+-- TraceEvents and this table will be empty.
+
+SELECT RUN_METRIC('chrome/jank_utilities.sql');
+
+-- Note: Must be a TABLE because it uses a window function which can behave
+-- strangely in views.
+DROP TABLE IF EXISTS vsync_intervals;
+CREATE TABLE vsync_intervals AS
+ SELECT
+ slice_id,
+ ts,
+ dur,
+ track_id,
+ LEAD(ts) OVER(PARTITION BY track_id ORDER BY ts) - ts AS time_to_next_vsync
+ FROM slice
+ WHERE name = "VSync"
+ ORDER BY track_id, ts;
+
+-- Get all the "begin" and "end" events. We take their IDs to group them
+-- together into gestures later and the timestamp and duration to compute the
+-- duration of the gesture.
+DROP VIEW IF EXISTS {{prefix}}_begin_and_end;
+CREATE VIEW {{prefix}}_begin_and_end AS
+ SELECT
+ slice.name,
+ slice.id,
+ slice.ts,
+ slice.dur,
+ slice.track_id,
+ EXTRACT_ARG(arg_set_id, 'chrome_latency_info.{{id_field}}')
+ AS {{id_field}},
+ EXTRACT_ARG(arg_set_id, "chrome_latency_info.trace_id") AS trace_id
+ FROM
+ slice
+ WHERE
+ slice.name IN (
+ 'InputLatency::{{gesture_start}}',
+ 'InputLatency::{{gesture_end}}'
+ )
+ ORDER BY ts;
+
+-- Now we take the "begin" and the "end" events and join the information into a
+-- single row per gesture. We also compute the average Vysnc interval of the
+-- gesture (hopefully this would be either 60 FPS for the whole gesture or 90
+-- FPS but that isn't always the case). If the trace doesn't contain the VSync
+-- TraceEvent we just fall back on assuming its 60 FPS (this is the 1.6e+7 in
+-- the COALESCE which corresponds to 16 ms or 60 FPS).
+DROP VIEW IF EXISTS joined_{{prefix}}_begin_and_end;
+CREATE VIEW joined_{{prefix}}_begin_and_end AS
+ SELECT
+ begin.id AS begin_id,
+ begin.ts AS begin_ts,
+ begin.dur AS begin_dur,
+ begin.track_id AS begin_track_id,
+ begin.trace_id AS begin_trace_id,
+ COALESCE(begin.{{id_field}}, begin.trace_id)
+ AS begin_{{id_field}},
+ end.ts AS end_ts,
+ end.ts + end.dur AS end_ts_and_dur,
+ end.trace_id AS end_trace_id,
+ COALESCE((
+ SELECT
+ CAST(AVG(time_to_next_vsync) AS FLOAT)
+ FROM vsync_intervals in_query
+ WHERE
+ time_to_next_vsync IS NOT NULL AND
+ in_query.ts > begin.ts AND
+ in_query.ts < end.ts
+ ), 1e+9 / 60) AS avg_vsync_interval
+ FROM {{prefix}}_begin_and_end begin JOIN {{prefix}}_begin_and_end end ON
+ begin.trace_id < end.trace_id AND
+ begin.name = 'InputLatency::{{gesture_start}}' AND
+ end.name = 'InputLatency::{{gesture_end}}' AND (
+ (
+ begin.{{id_field}} IS NULL AND
+ end.trace_id = (
+ SELECT MIN(trace_id)
+ FROM {{prefix}}_begin_and_end in_query
+ WHERE
+ name = 'InputLatency::{{gesture_end}}' AND
+ in_query.trace_id > begin.trace_id
+ )
+ ) OR
+ end.{{id_field}} = begin.{{id_field}}
+ )
+ ORDER BY begin.ts;
+
+-- Prepare all gesture updates that were not coalesced to be joined with their
+-- respective scrolls to calculate jank
+DROP VIEW IF EXISTS gesture_update;
+CREATE VIEW gesture_update AS
+ SELECT
+ EXTRACT_ARG(arg_set_id, "chrome_latency_info.trace_id") AS trace_id,
+ EXTRACT_ARG(arg_set_id, 'chrome_latency_info.{{id_field}}')
+ AS {{id_field}},
+ *
+ FROM
+ slice JOIN track ON slice.track_id = track.id
+ WHERE
+ slice.name = 'InputLatency::{{gesture_update}}' AND
+ slice.dur != -1 AND
+ NOT COALESCE(
+ EXTRACT_ARG(arg_set_id, "chrome_latency_info.is_coalesced"),
+ TRUE)
+ AND slice.arg_set_id IN (
+ SELECT arg_set_id
+ FROM args
+ WHERE args.arg_set_id = slice.arg_set_id
+ AND flat_key = 'chrome_latency_info.component_info.component_type'
+ AND string_value = 'COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER'
+ );
+
+-- Get the "update" events by name ordered by the |{{id_field}}|, and
+-- timestamp. Then compute the number of frames (relative to vsync interval)
+-- that each event took. 1.6e+7 is 16 ms in nanoseconds and is used in case
+-- there are no VSync events to default to 60 fps. We join each
+-- {{gesture_update}} event to the information about its "begin" and "end"
+-- events for easy computation later.
+--
+-- We remove updates with |dur| == -1 because this means we have no "end" event
+-- and can't reasonably determine what it should be. We have separate tracking
+-- to ensure this only happens at the end of the trace where its expected.
+DROP VIEW IF EXISTS {{id_field}}_update;
+CREATE VIEW {{id_field}}_update AS
+ SELECT
+ begin_id,
+ begin_ts,
+ begin_dur,
+ begin_track_id,
+ begin_trace_id,
+ COALESCE({{id_field}}, begin_trace_id) AS {{id_field}},
+ CASE WHEN
+ end_ts_and_dur > ts + dur THEN
+ end_ts_and_dur
+ ELSE
+ ts + dur
+ END AS maybe_gesture_end,
+ id,
+ ts,
+ dur,
+ track_id,
+ trace_id,
+ dur/avg_vsync_interval AS gesture_frames_exact,
+ avg_vsync_interval
+ FROM joined_{{prefix}}_begin_and_end begin_and_end JOIN gesture_update ON
+ gesture_update.ts <= begin_and_end.end_ts AND
+ gesture_update.ts >= begin_and_end.begin_ts AND
+ gesture_update.trace_id > begin_and_end.begin_trace_id AND
+ gesture_update.trace_id < begin_and_end.end_trace_id AND (
+ gesture_update.{{id_field}} IS NULL OR
+ gesture_update.{{id_field}} = begin_and_end.begin_{{id_field}}
+ )
+ ORDER BY {{id_field}} ASC, ts ASC;
+
+-- This takes the "update" events and get to the previous "update" event through LAG
+-- (previous row and NULL if there isn't one) and the next "update" event through LEAD
+-- (next row and again NULL if there isn't one). Then we compute the duration of the
+-- event (relative to fps).
+--
+-- We only compare an "update" event to another event within the same gesture
+-- ({{id_field}} == prev/next {{id_field}}). This controls somewhat for
+-- variability of gestures.
+--
+-- Note: Must be a TABLE because it uses a window function which can behave
+-- strangely in views.
+
+DROP TABLE IF EXISTS {{prefix}}_jank_maybe_null_prev_and_next_without_precompute;
+CREATE TABLE {{prefix}}_jank_maybe_null_prev_and_next_without_precompute AS
+ SELECT
+ *,
+ maybe_gesture_end - begin_ts AS {{prefix}}_dur,
+ LAG(ts) OVER sorted_frames AS prev_ts,
+ LAG({{id_field}}) OVER sorted_frames AS prev_{{id_field}},
+ LAG(gesture_frames_exact) OVER sorted_frames AS prev_gesture_frames_exact,
+ LEAD(ts) OVER sorted_frames AS next_ts,
+ LEAD({{id_field}}) OVER sorted_frames AS next_{{id_field}},
+ LEAD(gesture_frames_exact) OVER sorted_frames AS next_gesture_frames_exact
+ FROM {{id_field}}_update
+ WINDOW sorted_frames AS (ORDER BY {{id_field}} ASC, ts ASC)
+ ORDER BY {{id_field}} ASC, ts ASC;
+
+
+-- We compute the duration of the event (relative to fps) and see if it
+-- increased by more than 0.5 (which is 1/2 of 16 ms at 60 fps, and so on).
+--
+-- A small number is added to 0.5 in order to make sure that the comparison does
+-- not filter out ratios that are precisely 0.5, which can fall a little above
+-- or below exact value due to inherent inaccuracy of operations with
+-- floating-point numbers. Value 1e-9 have been chosen as follows: the ratio has
+-- nanoseconds in numerator and VSync interval in denominator. Assuming refresh
+-- rate more than 1 FPS (and therefore VSync interval less than a second), this
+-- ratio should increase with increments more than minimal value in numerator
+-- (1ns) divided by maximum value in denominator, giving 1e-9.
+-- Note: Logic is inside the IsJankyFrame function found in jank_utilities.sql.
+DROP VIEW IF EXISTS {{prefix}}_jank_maybe_null_prev_and_next;
+CREATE VIEW {{prefix}}_jank_maybe_null_prev_and_next AS
+ SELECT
+ *,
+ IsJankyFrame({{id_field}}, prev_{{id_field}},
+ prev_ts, begin_ts, maybe_gesture_end,
+ gesture_frames_exact, prev_gesture_frames_exact) AS prev_jank,
+ IsJankyFrame({{id_field}}, next_{{id_field}},
+ next_ts, begin_ts, maybe_gesture_end,
+ gesture_frames_exact, next_gesture_frames_exact) AS next_jank
+ FROM {{prefix}}_jank_maybe_null_prev_and_next_without_precompute
+ ORDER BY {{id_field}} ASC, ts ASC;
+
+-- This just uses prev_jank and next_jank to see if each "update" event is a
+-- jank.
+--
+-- JankBudget is the time in ns that we need to reduce the current
+-- gesture (|id|) for this frame not to be considered janky (i.e., how much
+-- faster for IsJankyFrame() to have not returned true).
+--
+-- For JankBudget we use the frames_exact of current, previous and next to find
+-- the jank budget in exact frame count. We then multiply by avg_vsync_internal
+-- to get the jank budget time.
+-- Note: Logic is inside the JankBudget function found in jank_utilities.sql.
+DROP VIEW IF EXISTS {{prefix}}_jank;
+CREATE VIEW {{prefix}}_jank AS
+ SELECT
+ id AS slice_id,
+ (next_jank IS NOT NULL AND next_jank) OR
+ (prev_jank IS NOT NULL AND prev_jank)
+ AS jank,
+ JankBudget(gesture_frames_exact, prev_gesture_frames_exact,
+ next_gesture_frames_exact) * avg_vsync_interval AS jank_budget,
+ *
+ FROM {{prefix}}_jank_maybe_null_prev_and_next
+ ORDER BY {{id_field}} ASC, ts ASC;
+
+DROP VIEW IF EXISTS {{prefix}}_jank_output;
+CREATE VIEW {{prefix}}_jank_output AS
+ SELECT
+ {{proto_name}}(
+ '{{prefix}}_jank_percentage', (
+ SELECT
+ (
+ SUM(CASE WHEN jank THEN dur ELSE 0 END)/CAST(SUM(dur) AS REAL)
+ ) * 100.0
+ FROM {{prefix}}_jank
+ ),
+ '{{prefix}}_ms', (
+ SELECT
+ CAST(SUM({{prefix}}_dur)/1e6 AS REAL)
+ FROM (
+ SELECT
+ MAX({{prefix}}_dur) AS {{prefix}}_dur
+ FROM {{prefix}}_jank
+ GROUP BY {{id_field}}
+ )
+ ),
+ '{{prefix}}_processing_ms', CAST(SUM(dur)/1e6 AS REAL),
+ '{{prefix}}_jank_processing_ms', (
+ SELECT CAST(SUM(dur)/1e6 AS REAL) FROM {{prefix}}_jank WHERE jank
+ ),
+ 'num_{{prefix}}_update_count', COUNT(*),
+ 'num_{{prefix}}_update_jank_count', SUM(jank),
+ '{{prefix}}_jank_budget_ms', (
+ SELECT CAST(SUM(jank_budget) AS REAL) FROM {{prefix}}_jank WHERE jank
+ )
+ )
+ FROM {{prefix}}_jank;
diff --git a/src/trace_processor/metrics/sql/chrome/jank_utilities.sql b/src/trace_processor/metrics/sql/chrome/jank_utilities.sql
new file mode 100644
index 000000000..44edb4262
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/jank_utilities.sql
@@ -0,0 +1,83 @@
+--
+-- Copyright 2022 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Those are helper functions used in computing jank metrics
+
+-- This function takes timestamps of two consecutive frames and determines if
+-- its janky by a delay of more than 0.5 of a frame in order to make sure that
+-- the comparison does not filter out ratios that are precisely 0.5, which can
+-- fall a little above or below exact value due to inherent inaccuracy of operations with
+-- floating-point numbers. Value 1e-9 have been chosen as follows: the ratio has
+-- nanoseconds in numerator and VSync interval in denominator. Assuming refresh
+-- rate more than 1 FPS (and therefore VSync interval less than a second), this
+-- ratio should increase with increments more than minimal value in numerator
+-- (1ns) divided by maximum value in denominator, giving 1e-9.
+
+SELECT CREATE_FUNCTION(
+ -- Function : function takes scroll ids of frames to verify it's from
+ -- the same scroll, and makes sure the frame ts occured within the scroll
+ -- timestamp of the neighbour and computes whether the frame was janky or not.
+ 'IsJankyFrame(cur_id LONG,next_id LONG,neighbour_ts LONG,' ||
+ 'cur_begin_ts LONG,cur_gesture_end LONG,cur_frame_exact FLOAT,' ||
+ 'neighbour_frame_exact FLOAT)',
+ -- Returns true if the frame was janky, false otherwise
+ 'BOOL',
+ 'SELECT
+ CASE WHEN
+ $cur_id != $next_id OR
+ $neighbour_ts IS NULL OR
+ $neighbour_ts < $cur_begin_ts OR
+ $neighbour_ts > $cur_gesture_end THEN
+ FALSE ELSE
+ $cur_frame_exact > $neighbour_frame_exact + 0.5 + 1e-9
+ END'
+);
+
+SELECT CREATE_FUNCTION(
+ -- Function : function takes the cur_frame_exact, prev_frame_exact and
+ -- next_frame_exact and returns the value of the jank budget of the current
+ -- frame.
+ --
+ -- JankBudget is the minimum amount of frames/time we need to reduce the frame
+ -- duration by for it to be no longer considered janky.
+ 'JankBudget(cur_frame_exact FLOAT, prev_frame_exact FLOAT, ' ||
+ ' next_frame_exact FLOAT)',
+ -- Returns the jank budget in percentage (i.e. 0.75) of vsync interval
+ -- percentage.
+ --
+ -- We determine the difference between the frame count of the current frame
+ -- and its consecutive frames by subtracting with the frame_exact values. We
+ -- null check for cases when the neighbor frame count can be null for the
+ -- first and last frames.
+ --
+ -- Since a frame is considered janky, if the difference in the frame count
+ -- with its adjacent frame is greater than 0.5 (half a vsync) which means we
+ -- need to reduce the frame count by a value less than 0.5 of maximum
+ -- difference in frame count for it to be no longer janky. We subtract 1e-9 as
+ -- we want to output minimum amount required.
+ 'FLOAT',
+ 'SELECT
+ COALESCE(
+ -- Could be null if next or previous is null.
+ MAX(
+ ($cur_frame_exact - $prev_frame_exact),
+ ($cur_frame_exact - $next_frame_exact)
+ ),
+ -- If one of them is null output the first non-null.
+ ($cur_frame_exact - $prev_frame_exact),
+ ($cur_frame_exact - $next_frame_exact)
+ -- Otherwise return null
+ ) - 0.5 - 1e-9'
+);
diff --git a/src/trace_processor/metrics/sql/chrome/rail_modes.sql b/src/trace_processor/metrics/sql/chrome/rail_modes.sql
new file mode 100644
index 000000000..d28f665e6
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/rail_modes.sql
@@ -0,0 +1,562 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the 'License');
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an 'AS IS' BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+SELECT RUN_METRIC('chrome/chrome_processes.sql') AS suppress_query_output;
+SELECT RUN_METRIC('chrome/chrome_event_metadata.sql') AS suppress_query_output;
+
+-- Priority order for RAIL modes where response has the highest priority and
+-- idle has the lowest.
+DROP TABLE IF EXISTS rail_modes;
+CREATE TABLE rail_modes (
+ mode TEXT UNIQUE,
+ ordering INT,
+ short_name TEXT
+);
+
+-- RAIL_MODE_IDLE is used when no frames are visible in the renderer and so this
+-- interprets that as background.
+-- RAIL_MODE_LOAD is for the time from a navigation until the first meaningful
+-- paint (assuming there are no user interactions).
+-- RAIL_MODE_RESPONSE is used when the main thread is dealing with a
+-- user-interaction (but not for instance for scrolls which may be handled by
+-- the compositor).
+-- RAIL_MODE_ANIMATION is used when none of the above apply.
+-- The enum in chrome is defined in:
+-- https://source.chromium.org/chromium/chromium/src/+/master:third_party/blink/renderer/platform/scheduler/public/rail_mode_observer.h
+INSERT INTO rail_modes
+VALUES ('RAIL_MODE_IDLE', 0, 'background'),
+ ('RAIL_MODE_ANIMATION', 1, "animation"),
+ ('RAIL_MODE_LOAD', 2, "load"),
+ ('RAIL_MODE_RESPONSE', 3, "response");
+
+
+-- Find the max ts + dur for every process
+DROP TABLE IF EXISTS max_ts_per_process;
+CREATE TABLE max_ts_per_process AS
+ -- MAX(dur, 0) means unclosed slices just contribute their start time.
+SELECT upid,
+ MAX(ts + MAX(dur, 0)) AS ts
+FROM (
+ SELECT upid,
+ ts,
+ dur
+ FROM process_track t
+ JOIN slice s
+ WHERE s.track_id = t.id
+ UNION ALL
+ SELECT upid,
+ ts,
+ dur
+ FROM thread_track t
+ JOIN thread
+ JOIN slice
+ WHERE slice.track_id = t.id
+ AND thread.utid = t.utid
+ )
+GROUP BY upid;
+
+-- View containing all Scheduler.RAILMode slices across all Chrome renderer
+-- processes.
+DROP VIEW IF EXISTS original_rail_mode_slices;
+CREATE VIEW original_rail_mode_slices AS
+SELECT slice.id,
+ slice.ts,
+ CASE
+ -- Add 1 to the duration to ensure you cannot get a zero-sized RAIL mode
+ -- slice, which can throw off the later queries.
+ WHEN dur == -1 THEN max_ts_per_process.ts - slice.ts + 1
+ ELSE dur
+ END AS dur,
+ track_id,
+ EXTRACT_ARG(
+ slice.arg_set_id,
+ "chrome_renderer_scheduler_state.rail_mode"
+ ) AS rail_mode
+FROM max_ts_per_process,
+ slice,
+ process_track
+WHERE slice.name = "Scheduler.RAILMode"
+ AND slice.track_id = process_track.id
+ AND process_track.upid = max_ts_per_process.upid;
+
+-- Detect if the trace has an unrealistic length (10 minutes) that probably
+-- means some trace events have faulty timestamps and which could throw off any
+-- metrics that use the trace.
+DROP VIEW IF EXISTS trace_has_realistic_length;
+CREATE VIEW trace_has_realistic_length AS
+SELECT (end_ts - start_ts) < 1e9 * 60 * 10 AS value
+FROM trace_bounds;
+
+-- RAIL_MODE_LOAD seems to get stuck which makes it not very useful so remap it
+-- to RAIL_MODE_ANIMATION so it doesn't dominate the overall RAIL mode.
+DROP VIEW IF EXISTS rail_mode_slices;
+CREATE VIEW rail_mode_slices AS
+SELECT ts, dur, track_id,
+ CASE
+ WHEN rail_mode == "RAIL_MODE_LOAD" THEN "RAIL_MODE_ANIMATION"
+ ELSE rail_mode
+ END AS rail_mode
+FROM original_rail_mode_slices;
+
+-- View containing a collapsed view of rail_mode_slices where there is only one
+-- RAIL mode active at a given time. The mode is derived using the priority
+-- order in rail_modes.
+DROP VIEW IF EXISTS overall_rail_mode_slices;
+CREATE VIEW overall_rail_mode_slices AS
+SELECT s.ts,
+ s.end_ts,
+ rail_modes.short_name AS rail_mode,
+ MAX(rail_modes.ordering)
+FROM (
+ SELECT ts,
+ LEAD(ts, 1, (SELECT MAX(ts + dur) FROM rail_mode_slices)) OVER (
+ ORDER BY ts
+ ) AS end_ts
+ FROM (
+ SELECT DISTINCT ts
+ FROM rail_mode_slices
+ ) start_times
+ ) s,
+ rail_mode_slices r,
+ rail_modes,
+ trace_has_realistic_length
+WHERE (
+ (
+ s.ts >= r.ts AND s.ts < r.ts + r.dur
+ )
+ OR (
+ s.end_ts > r.ts AND s.end_ts <= r.ts + r.dur
+ )
+ )
+ AND r.rail_mode == rail_modes.mode
+ AND trace_has_realistic_length.value
+GROUP BY s.ts;
+
+-- Contains the same data as overall_rail_mode_slices except adjacent slices
+-- with the same RAIL mode are combined.
+DROP TABLE IF EXISTS combined_overall_rail_slices;
+CREATE TABLE combined_overall_rail_slices AS
+SELECT ROW_NUMBER() OVER () AS id,
+ ts,
+ end_ts - ts AS dur,
+ rail_mode
+FROM (
+ SELECT lag(l.end_ts, 1, FIRST) OVER (
+ ORDER BY l.ts
+ ) AS ts,
+ l.end_ts,
+ l.rail_mode
+ FROM (
+ SELECT ts,
+ end_ts,
+ rail_mode
+ FROM overall_rail_mode_slices s
+ WHERE NOT EXISTS (
+ SELECT NULL
+ FROM overall_rail_mode_slices s2
+ WHERE s.rail_mode = s2.rail_mode
+ AND s.end_ts = s2.ts
+ )
+ ) AS l,
+ (
+ SELECT min(ts) AS FIRST
+ FROM overall_rail_mode_slices
+ )
+ );
+
+-- Now we have the RAIL Mode, use other trace events to create a modified RAIL
+-- mode that more accurately reflects what the browser/user are doing.
+
+-- First create slices for when there's no animation as indicated by a large gap
+-- between vsync events (since it's easier to find gaps than runs of adjacent
+-- vsyncs).
+
+-- Mark any large gaps between vsyncs.
+-- The value in "not_animating" is always 1. It's just there to be a non-NULL
+-- value so the later SPAN_JOIN can find the set-difference.
+DROP VIEW IF EXISTS not_animating_slices;
+CREATE VIEW not_animating_slices AS
+WITH const (vsync_padding, large_gap) AS (
+ SELECT
+ -- Pad 50ms either side of a vsync
+ 50000000,
+ -- A gap of >200ms between the adjacent vsyncs is treated as a gap in
+ -- animation.
+ 200000000
+)
+SELECT ts + const.vsync_padding AS ts,
+ gap_to_next_vsync - const.vsync_padding * 2 AS dur, 1 AS not_animating
+FROM const, (SELECT name,
+ ts,
+ lead(ts) OVER () - ts AS gap_to_next_vsync,
+ dur
+ FROM slice
+ WHERE name = "VSync")
+WHERE gap_to_next_vsync > const.large_gap
+UNION
+-- Insert a slice between start_ts and the first vsync (or the end of the trace
+-- if there are none).
+SELECT
+ ts,
+ dur,
+ 1
+FROM (SELECT start_ts AS ts,
+ COALESCE((
+ SELECT MIN(ts)
+ FROM slice
+ WHERE name = "VSync"
+ ) - start_ts - const.vsync_padding,
+ end_ts - start_ts
+ ) AS dur
+FROM trace_bounds, const)
+WHERE dur > 0
+UNION
+-- Insert a slice between the last vsync and end_ts
+SELECT last_vsync AS ts,
+ end_ts - last_vsync AS dur,
+ 1
+FROM (
+ SELECT MAX(ts) + const.vsync_padding AS last_vsync
+ FROM slice, const
+ WHERE name = "VSync"
+ ),
+ trace_bounds
+WHERE last_vsync < end_ts;
+
+-- There are two types of InputLatency:: events:
+-- 1) Simple ones that begin at ts and end at ts+dur
+-- 2) Paired ones that begin with a "begin" slice and end at an "end" slice.
+--
+-- Paired events are even trickier because we can't guarantee that the "begin"
+-- slice will even be in the trace and because it's possible for multiple begin
+-- slices to appear without an intervening end slice.
+
+-- Table of begin and end events along with the increment/decrement to be
+-- applied to the appropriate counter (one for each type of paired event). Final
+-- column dur_multiplier is used to find the timestamp to mark the event at in
+-- the equation event_ts = ts + dur * dur_multiplier. End events have
+-- dur_multiplier of 1, which makes their ts the end of the slice rather than
+-- the start.
+DROP TABLE IF EXISTS input_latency_begin_end_names;
+CREATE TABLE input_latency_begin_end_names
+(
+ full_name TEXT UNIQUE,
+ prefix TEXT,
+ scroll_increment INT,
+ pinch_increment INT,
+ touch_increment INT,
+ fling_increment INT,
+ pointer_increment INT,
+ dur_multiplier INT
+);
+
+INSERT
+ OR IGNORE INTO input_latency_begin_end_names
+VALUES
+ ("InputLatency::GestureScrollBegin",
+ "InputLatency::GestureScroll", 1, 0, 0, 0, 0, 0),
+ ("InputLatency::GestureScrollEnd",
+ "InputLatency::GestureScroll", -1, 0, 0, 0, 0, 1),
+ ("InputLatency::GesturePinchBegin",
+ "InputLatency::GesturePinch", 0, 1, 0, 0, 0, 0),
+ ("InputLatency::GesturePinchEnd",
+ "InputLatency::GesturePinch", 0, -1, 0, 0, 0, 1),
+ ("InputLatency::TouchStart",
+ "InputLatency::Touch", 0, 0, 1, 0, 0, 0),
+ ("InputLatency::TouchEnd",
+ "InputLatency::Touch", 0, 0, -1, 0, 0, 1),
+ ("InputLatency::GestureFlingStart",
+ "InputLatency::GestureFling", 0, 0, 0, 1, 0, 0),
+ ("InputLatency::GestureFlingCancel",
+ "InputLatency::GestureFling", 0, 0, 0, -1, 0, 1),
+ ("InputLatency::PointerDown",
+ "InputLatency::Pointer", 0, 0, 0, 0, 1, 0),
+ ("InputLatency::PointerUp",
+ "InputLatency::Pointer", 0, 0, 0, 0, -1, 1),
+ ("InputLatency::PointerCancel",
+ "InputLatency::Pointer", 0, 0, 0, 0, -1, 1);
+
+-- Find all the slices that have split "begin" and "end" slices and maintain a
+-- running total for each type, where >0 means that type of input event is
+-- ongoing.
+DROP VIEW IF EXISTS input_begin_end_slices;
+CREATE VIEW input_begin_end_slices AS
+SELECT prefix,
+ -- Mark the change at the start of "start" slices and the end of "end" slices.
+ ts + dur * dur_multiplier AS ts,
+ scroll_increment,
+ pinch_increment,
+ touch_increment,
+ fling_increment,
+ pointer_increment
+FROM slice
+JOIN input_latency_begin_end_names ON name = full_name
+ORDER BY ts;
+
+-- Combine all the paired input events to get an indication of when any paired
+-- input event is ongoing.
+DROP VIEW IF EXISTS unified_input_pair_increments;
+CREATE VIEW unified_input_pair_increments AS
+SELECT ts,
+ scroll_increment +
+ pinch_increment +
+ touch_increment +
+ fling_increment +
+ pointer_increment AS increment
+FROM input_begin_end_slices;
+
+-- It's possible there's an end slice without a start slice (as it occurred
+-- before the trace started) which would result in (starts - ends) going
+-- negative at some point. So find an offset that shifts up all counts so the
+-- lowest values becomes zero. It's possible this could still do the wrong thing
+-- if there were start AND end slices that are outside the trace bounds, in
+-- which case it should count as covering the entire trace, but it's impossible
+-- to compensate for that without augmenting the trace events themselves.
+DROP VIEW IF EXISTS initial_paired_increment;
+CREATE VIEW initial_paired_increment AS
+SELECT ts,
+ MIN(0, MIN(scroll_total)) +
+ MIN(0, MIN(pinch_total)) +
+ MIN(0, MIN(touch_total)) +
+ MIN(0, MIN(fling_total)) +
+ MIN(0, MIN(pointer_total)) AS offset
+FROM (
+ SELECT ts,
+ SUM(scroll_increment) OVER(ROWS UNBOUNDED PRECEDING) AS scroll_total,
+ SUM(pinch_increment) OVER(ROWS UNBOUNDED PRECEDING) AS pinch_total,
+ SUM(touch_increment) OVER(ROWS UNBOUNDED PRECEDING) AS touch_total,
+ SUM(fling_increment) OVER(ROWS UNBOUNDED PRECEDING) AS fling_total,
+ SUM(pointer_increment) OVER(ROWS UNBOUNDED PRECEDING) AS pointer_total
+ FROM input_begin_end_slices
+ );
+
+-- Now find all the simple input slices that fully enclose the input they're
+-- marking (i.e. not the start or end of a pair).
+DROP VIEW IF EXISTS simple_input_slices;
+CREATE VIEW simple_input_slices AS
+SELECT id,
+ name,
+ ts,
+ dur
+FROM slice s
+WHERE name GLOB "InputLatency::*"
+ AND NOT EXISTS (
+ SELECT 1
+ FROM slice
+ JOIN input_latency_begin_end_names
+ WHERE s.name == full_name
+ );
+
+-- Turn the simple input slices into +1s and -1s at the start and end of each
+-- slice.
+DROP VIEW IF EXISTS simple_input_increments;
+CREATE VIEW simple_input_increments AS
+SELECT ts,
+ 1 AS increment
+FROM simple_input_slices
+UNION ALL
+SELECT ts + dur,
+ -1
+FROM simple_input_slices
+ORDER BY ts;
+
+-- Combine simple and paired inputs into one, summing all the increments at a
+-- given ts.
+DROP VIEW IF EXISTS all_input_increments;
+CREATE VIEW all_input_increments AS
+SELECT ts,
+ SUM(increment) AS increment
+FROM (
+ SELECT *
+ FROM simple_input_increments
+ UNION ALL
+ SELECT *
+ FROM unified_input_pair_increments
+ ORDER BY ts
+ )
+GROUP BY ts;
+
+-- Now calculate the cumulative sum of the increments as each ts, giving the
+-- total number of outstanding input events at a given time.
+DROP VIEW IF EXISTS all_input_totals;
+CREATE VIEW all_input_totals AS
+SELECT ts,
+ SUM(increment) OVER(ROWS UNBOUNDED PRECEDING) > 0 AS input_total
+FROM all_input_increments;
+
+-- Now find the transitions from and to 0 and use that to create slices where
+-- input events were occurring. The input_active column always contains 1, but
+-- is there so that the SPAN_JOIN_LEFT can put NULL in it for RAIL Mode slices
+-- that do not have corresponding input events.
+DROP VIEW IF EXISTS all_input_slices;
+CREATE VIEW all_input_slices AS
+SELECT ts,
+ dur,
+ input_active
+FROM (
+ SELECT ts,
+ lead(ts, 1, end_ts) OVER() - ts AS dur,
+ input_active
+ FROM trace_bounds,
+ (
+ SELECT ts,
+ input_total > 0 AS input_active
+ FROM (
+ SELECT ts,
+ input_total,
+ lag(input_total) OVER() AS prev_input_total
+ FROM all_input_totals
+ )
+ WHERE (input_total > 0 <> prev_input_total > 0)
+ OR prev_input_total IS NULL
+ )
+ )
+WHERE input_active > 0;
+
+-- Since the scheduler defaults to animation when none of the other RAIL modes
+-- apply, animation overestimates the amount of time that actual animation is
+-- occurring.
+-- So instead we try to divide up animation in other buckets based on other
+-- trace events.
+DROP VIEW IF EXISTS rail_mode_animation_slices;
+CREATE VIEW rail_mode_animation_slices AS
+SELECT * FROM combined_overall_rail_slices WHERE rail_mode = "animation";
+
+-- Left-join rail mode animation slices with all_input_slices to find all
+-- "animation" slices that should actually be labelled "response".
+DROP TABLE IF EXISTS rail_mode_join_inputs;
+CREATE VIRTUAL TABLE rail_mode_join_inputs
+USING SPAN_LEFT_JOIN(rail_mode_animation_slices, all_input_slices);
+
+-- Left-join rail mode animation slices with not_animating_slices which is
+-- based on the gaps between vsync events.
+DROP TABLE IF EXISTS rail_mode_join_inputs_join_animation;
+CREATE VIRTUAL TABLE rail_mode_join_inputs_join_animation
+USING SPAN_LEFT_JOIN(rail_mode_join_inputs, not_animating_slices);
+
+DROP VIEW IF EXISTS has_modified_rail_slices;
+CREATE VIEW has_modified_rail_slices AS
+SELECT (
+ SELECT value
+ FROM chrome_event_metadata
+ WHERE name == "os-name"
+ ) == "Android" AS value;
+
+-- Mapping to allow CamelCased names to be produced from the modified rail
+-- modes.
+DROP TABLE IF EXISTS modified_rail_mode_prettier;
+CREATE TABLE modified_rail_mode_prettier (
+ orig_name TEXT UNIQUE,
+ pretty_name TEXT
+);
+INSERT INTO modified_rail_mode_prettier
+VALUES ("background", "Background"),
+ ("foreground_idle", "ForegroundIdle"),
+ ("animation", "Animation"),
+ ("load", "Load"),
+ ("response", "Response");
+
+-- When the RAIL mode is animation, use input/vsync data to conditionally change
+-- the mode to response or foreground_idle.
+DROP VIEW IF EXISTS unmerged_modified_rail_slices;
+CREATE VIEW unmerged_modified_rail_slices AS
+SELECT ROW_NUMBER() OVER () AS id,
+ ts,
+ dur,
+ mode
+FROM (
+ SELECT ts,
+ dur,
+ CASE
+ WHEN input_active IS NOT NULL THEN "response"
+ WHEN not_animating IS NULL THEN "animation"
+ ELSE "foreground_idle"
+ END AS mode
+ FROM rail_mode_join_inputs_join_animation
+ UNION
+ SELECT ts,
+ dur,
+ rail_mode AS mode
+ FROM combined_overall_rail_slices
+ WHERE rail_mode <> "animation"
+ )
+ -- Since VSync events are only emitted on Android (and the concept of a
+ -- unified RAIL mode only makes sense if there's just a single Chrome window),
+ -- don't output anything on other platforms. This will result in all the power
+ -- and cpu time tables being empty rather than containing bogus results.
+WHERE (
+ SELECT value
+ FROM has_modified_rail_slices
+ );
+
+-- The previous query creating unmerged_modified_rail_slices, can create
+-- adjacent slices with the same mode. This merges them together as well as
+-- adding a unique id to each slice. Rather than directly merging slices
+-- together, this instead looks for all the transitions and uses this to
+-- reconstruct the slices that should occur between them.
+DROP TABLE IF EXISTS modified_rail_slices;
+CREATE TABLE modified_rail_slices AS
+WITH const (end_ts) AS (SELECT ts + dur
+ FROM unmerged_modified_rail_slices
+ ORDER BY ts DESC
+ LIMIT 1)
+SELECT ROW_NUMBER() OVER () AS id, lag(next_ts) OVER() AS ts,
+ ts + dur - lag(next_ts) OVER() AS dur,
+ mode AS mode
+FROM (
+ -- For each row in the original table, create a new row with the information
+ -- from the following row, since you can't use lag/lead in WHERE clause.
+ --
+ -- Transition row at the beginning. "mode" is invalid, so a transition will
+ -- always be recorded.
+ SELECT *
+ FROM (SELECT
+ 0 AS ts,
+ ts AS dur,
+ "" AS mode,
+ ts AS next_ts,
+ dur AS next_dur,
+ mode AS next_mode
+ FROM unmerged_modified_rail_slices
+ LIMIT 1
+ )
+ UNION ALL
+ SELECT ts,
+ dur,
+ mode,
+ lead(ts, 1, end_ts) OVER() AS next_ts,
+ lead(dur) OVER() AS next_dur,
+ lead(mode) OVER() AS next_mode
+ FROM unmerged_modified_rail_slices, const
+ UNION ALL
+ -- Transition row at the end. "next_mode" is invalid, so a transition will
+ -- always be recorded.
+ SELECT *
+ FROM (SELECT
+ ts + dur AS ts,
+ 0 AS dur,
+ mode,
+ ts + dur AS next_ts,
+ 0,
+ "" AS next_mode
+ FROM unmerged_modified_rail_slices
+ ORDER BY ts DESC
+ LIMIT 1
+ )
+ )
+WHERE mode <> next_mode
+-- Retrieve all but the first row.
+LIMIT -1 OFFSET 1;
diff --git a/src/trace_processor/metrics/sql/chrome/scroll_flow_event.sql b/src/trace_processor/metrics/sql/chrome/scroll_flow_event.sql
new file mode 100644
index 000000000..083c35d5d
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/scroll_flow_event.sql
@@ -0,0 +1,31 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the 'License');
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an 'AS IS' BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- While handling a InputLatency::GestureScrollUpdate event a sequence of Flows
+-- define the critical path from Beginning to End. This metric breaks down the
+-- flows for the same InputLatency::GestureScrollUpdate event.
+--
+-- WARNING: This metric should not be used as a source of truth. It is under
+-- active development and the values & meaning might change without
+-- notice.
+
+-- Provides the scroll_jank table which gives us all the GestureScrollUpdate
+-- events we care about and labels them janky or not.
+SELECT RUN_METRIC(
+ 'chrome/gesture_flow_event.sql',
+ 'prefix', 'scroll',
+ 'gesture_update', 'GestureScrollUpdate',
+ 'id_field', 'gesture_scroll_id'
+ );
diff --git a/src/trace_processor/metrics/sql/chrome/scroll_flow_event_queuing_delay.sql b/src/trace_processor/metrics/sql/chrome/scroll_flow_event_queuing_delay.sql
new file mode 100644
index 000000000..94a8f4813
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/scroll_flow_event_queuing_delay.sql
@@ -0,0 +1,27 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the 'License');
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an 'AS IS' BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- This metric takes each flow event in a InputLatency::GestureScrollUpdate and
+-- and computes the time from the ancestor_end of the current flow to the
+-- ancestor_ts of the next flow event. This is a reasonable approximation of the
+-- time we waited for the next step in the critical flow to start.
+
+-- Provides the scroll_flow_event table which gives us all the flow events with
+-- associated GestureScrollUpdate events we care about and labels them janky or
+-- not.
+SELECT RUN_METRIC('chrome/gesture_flow_event_queuing_delay.sql',
+ 'prefix', 'scroll',
+ 'id_field', 'gesture_scroll_id');
+
diff --git a/src/trace_processor/metrics/sql/chrome/scroll_jank.sql b/src/trace_processor/metrics/sql/chrome/scroll_jank.sql
new file mode 100644
index 000000000..984a6c786
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/scroll_jank.sql
@@ -0,0 +1,38 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- A collection of metrics related to GestureScrollUpdate events.
+--
+-- We define a GestureScrollUpdate to be janky if comparing forwards or
+-- backwards (ignoring coalesced updates) a given GestureScrollUpdate exceeds
+-- the duration of its predecessor or successor by 50% of a vsync interval
+-- (defaulted to 60 FPS).
+--
+-- WARNING: This metric should not be used as a source of truth. It is under
+-- active development and the values & meaning might change without
+-- notice.
+
+SELECT RUN_METRIC(
+ 'chrome/gesture_jank.sql',
+ 'prefix', 'scroll',
+ 'gesture_start', 'GestureScrollBegin',
+ 'gesture_update', 'GestureScrollUpdate',
+ 'gesture_end', 'GestureScrollEnd',
+ 'id_field', 'gesture_scroll_id',
+ 'proto_name', 'ScrollJank');
+
+-- TODO(b/200149773): Remove this once chrometto no longer depends on it.
+DROP VIEW IF EXISTS gesture_scroll_update;
+CREATE VIEW gesture_scroll_update AS SELECT * FROM gesture_scroll_id_update;
diff --git a/src/trace_processor/metrics/chrome/scroll_jank_cause.sql b/src/trace_processor/metrics/sql/chrome/scroll_jank_cause.sql
index 030ab3211..030ab3211 100644
--- a/src/trace_processor/metrics/chrome/scroll_jank_cause.sql
+++ b/src/trace_processor/metrics/sql/chrome/scroll_jank_cause.sql
diff --git a/src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_task.sql b/src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_task.sql
new file mode 100644
index 000000000..14ddd8309
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_task.sql
@@ -0,0 +1,294 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+-- Needed for the scroll_jank table to tell which updates were janky.
+SELECT RUN_METRIC('chrome/scroll_jank.sql');
+
+--------------------------------------------------------------------------------
+-- Get all the track ids relevant to the critical path.
+--------------------------------------------------------------------------------
+
+-- Grab the track of the browser. sendTouchEvent is a Java category event which
+-- only occurs on the browser. This saves us the trouble of dealing with all the
+-- different possible names of the browser (when including system tracing).
+DROP VIEW IF EXISTS browser_main_track_id;
+CREATE VIEW browser_main_track_id AS
+SELECT
+ track_id AS id
+FROM slice
+WHERE
+ name = "sendTouchEvent"
+LIMIT 1;
+
+DROP VIEW IF EXISTS viz_compositor_track_id;
+CREATE VIEW viz_compositor_track_id AS
+SELECT
+ id
+FROM thread_track
+WHERE
+ utid = (
+ SELECT
+ utid
+ FROM thread
+ WHERE
+ name = "VizCompositorThread"
+ )
+LIMIT 1;
+
+-- Grab the track of the GPU. gpu/command_buffer is a toplevel category event
+-- which only occurs on the gpu main. This saves us the trouble of dealing with
+-- all the different possible names of the GPU process (when including system
+-- tracing).
+DROP VIEW IF EXISTS gpu_main_track_id;
+CREATE VIEW gpu_main_track_id AS
+SELECT
+ track_id AS id
+FROM slice
+WHERE
+ EXTRACT_ARG(arg_set_id, "task.posted_from.file_name") GLOB
+ "*gpu/command_buffer/service/scheduler.cc"
+LIMIT 1;
+
+-- TODO(nuskos): Determine a good way to get all the renderer track_ids (each
+-- scroll will have a single renderer main and a single renderer
+-- compositor however different scroll updates could have
+-- DIFFERENT renderers so bit tricky). Ignore this complexity for
+-- now until we have a single task we want to blame jank on.
+
+--------------------------------------------------------------------------------
+-- Grab the last LatencyInfo.Flow for each trace_id on the browser main.
+--------------------------------------------------------------------------------
+DROP VIEW IF EXISTS browser_flows;
+CREATE VIEW browser_flows AS
+SELECT
+ EXTRACT_ARG(arg_set_id, "chrome_latency_info.trace_id") AS trace_id,
+ EXTRACT_ARG(arg_set_id, "chrome_latency_info.step") AS flow_step,
+ track_id,
+ max(ts) AS ts
+FROM slice
+WHERE
+ track_id = (
+ SELECT id FROM browser_main_track_id
+ ) AND
+ name = "LatencyInfo.Flow"
+ GROUP BY trace_id;
+
+-- Grab the last LatencyInfo.Flow for each trace_id on the VizCompositor.
+DROP VIEW IF EXISTS viz_flows;
+CREATE VIEW viz_flows AS
+SELECT
+ EXTRACT_ARG(arg_set_id, "chrome_latency_info.trace_id") AS trace_id,
+ EXTRACT_ARG(arg_set_id, "chrome_latency_info.step") AS flow_step,
+ track_id,
+ max(ts) AS ts
+FROM slice
+WHERE
+ track_id = (
+ SELECT id FROM viz_compositor_track_id
+ ) AND
+ name = "LatencyInfo.Flow"
+ GROUP BY trace_id;
+
+-- Grab the last LatencyInfo.Flow for each trace_id on the GPU main.
+DROP VIEW IF EXISTS gpu_flows;
+CREATE VIEW gpu_flows AS
+SELECT
+ EXTRACT_ARG(arg_set_id, "chrome_latency_info.trace_id") AS trace_id,
+ EXTRACT_ARG(arg_set_id, "chrome_latency_info.step") AS flow_step,
+ track_id,
+ max(ts) AS ts
+FROM slice
+WHERE
+ track_id = (
+ SELECT id FROM gpu_main_track_id
+ ) AND
+ name = "LatencyInfo.Flow"
+ GROUP BY trace_id;
+
+--------------------------------------------------------------------------------
+-- Finally join the relevant tracks/flows to the individual scrolls.
+--------------------------------------------------------------------------------
+
+-- Keeping only the GestureScrollUpdates join the maximum flows with their
+-- associated scrolls. We only keep non-coalesced scrolls.
+DROP VIEW IF EXISTS scroll_with_browser_gpu_and_viz_flows;
+CREATE VIEW scroll_with_browser_gpu_and_viz_flows AS
+SELECT
+ scroll.trace_id,
+ scroll.scroll_id,
+ scroll.ts,
+ scroll.dur,
+ scroll.track_id,
+ browser_flows.ts AS browser_flow_ts,
+ browser_flows.flow_step AS browser_flow_step,
+ browser_flows.track_id AS browser_track_id,
+ viz_flows.ts AS viz_flow_ts,
+ viz_flows.flow_step AS viz_flow_step,
+ viz_flows.track_id AS viz_track_id,
+ gpu_flows.ts AS gpu_flow_ts,
+ gpu_flows.flow_step AS gpu_flow_step,
+ gpu_flows.track_id AS gpu_track_id
+FROM (
+ SELECT
+ trace_id,
+ id AS scroll_id,
+ ts,
+ dur,
+ track_id
+ FROM scroll_jank
+) scroll JOIN browser_flows ON
+ scroll.trace_id = browser_flows.trace_id
+ JOIN viz_flows ON viz_flows.trace_id = scroll.trace_id
+ JOIN gpu_flows ON gpu_flows.trace_id = scroll.trace_id;
+
+--------------------------------------------------------------------------------
+-- Below we determine individual causes of blocking tasks.
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- Determine if a CopyOutputRequest blocked any important threads.
+--------------------------------------------------------------------------------
+
+-- These are the events that block the Browser Main or the VizCompositor thread.
+DROP VIEW IF EXISTS blocking_browser_gpu_and_viz_copies;
+CREATE VIEW blocking_browser_gpu_and_viz_copies AS
+SELECT
+ id,
+ ts,
+ dur,
+ track_id
+FROM slice
+WHERE
+ (
+ (
+ name = "viz.mojom.CopyOutputResultSender" OR
+ name = "GLRenderer::CopyDrawnRenderPass"
+ ) AND
+ track_id = (SELECT id FROM browser_main_track_id)
+ ) OR (
+ EXTRACT_ARG(arg_set_id, "task.posted_from.file_name") GLOB
+ "*components/viz/common/frame_sinks/copy_output_request.cc" AND
+ track_id = (SELECT id FROM viz_compositor_track_id)
+ ) OR (
+ name = "SkiaOutputSurfaceImplOnGpu::CopyOutput" AND
+ track_id = (SELECT id FROM gpu_main_track_id)
+ );
+
+-- Determine based on the LatencyInfo.Flow timestamp and the copy task overlap
+-- if this scroll might have been delayed because of the copy.
+DROP VIEW IF EXISTS blocking_copy_tasks;
+CREATE VIEW blocking_copy_tasks AS
+SELECT
+ scroll.scroll_id,
+ scroll.trace_id,
+ copy.id,
+ copy.ts,
+ copy.dur,
+ copy.track_id,
+ CASE WHEN copy.track_id = scroll.browser_track_id THEN
+ CASE WHEN copy.ts < scroll.browser_flow_ts THEN
+ TRUE
+ ELSE
+ FALSE
+ END
+ WHEN copy.track_id = scroll.viz_track_id THEN
+ CASE WHEN copy.ts < scroll.viz_flow_ts THEN
+ TRUE
+ ELSE
+ FALSE
+ END
+ WHEN copy.track_id = scroll.gpu_track_id THEN
+ CASE WHEN copy.ts < scroll.gpu_flow_ts THEN
+ TRUE
+ ELSE
+ FALSE
+ END
+ ELSE
+ FALSE
+ END AS blocked_by_copy
+FROM
+ scroll_with_browser_gpu_and_viz_flows scroll JOIN
+ blocking_browser_gpu_and_viz_copies copy ON
+ scroll.ts + scroll.dur >= copy.ts AND
+ copy.ts + copy.dur >= scroll.ts;
+
+-- Group by scroll so we can equally join one reply to the ScrollJankAndCauses
+-- view.
+DROP VIEW IF EXISTS screenshot_overlapping_scrolls;
+CREATE VIEW screenshot_overlapping_scrolls AS
+SELECT
+ scroll_id, trace_id, SUM(blocked_by_copy) > 0 AS blocked_by_copy_request
+FROM blocking_copy_tasks
+GROUP BY 1, 2;
+
+--------------------------------------------------------------------------------
+-- Check for blocking language_detection on the browser thread
+--------------------------------------------------------------------------------
+DROP VIEW IF EXISTS blocking_browser_language_detection;
+CREATE VIEW blocking_browser_language_detection AS
+SELECT
+ id,
+ ts,
+ dur,
+ track_id
+FROM slice
+WHERE
+ (
+ name = "language_detection.mojom.LanguageDetectionService" AND
+ track_id = (SELECT id FROM browser_main_track_id)
+ );
+
+DROP VIEW IF EXISTS blocking_language_detection_tasks;
+CREATE VIEW blocking_language_detection_tasks AS
+SELECT
+ scroll.scroll_id,
+ scroll.trace_id,
+ lang.id,
+ lang.ts,
+ lang.dur,
+ lang.track_id,
+ CASE WHEN lang.track_id = scroll.browser_track_id THEN
+ CASE WHEN lang.ts < scroll.browser_flow_ts THEN
+ TRUE
+ ELSE
+ FALSE
+ END
+ END AS blocked_by_language_detection
+FROM
+ scroll_with_browser_gpu_and_viz_flows scroll JOIN
+ blocking_browser_language_detection lang ON
+ scroll.ts + scroll.dur >= lang.ts AND
+ lang.ts + lang.dur >= scroll.ts;
+
+DROP VIEW IF EXISTS language_detection_overlapping_scrolls;
+CREATE VIEW language_detection_overlapping_scrolls AS
+SELECT
+ scroll_id, trace_id,
+ SUM(blocked_by_language_detection) > 0 AS blocked_by_language_detection
+FROM blocking_language_detection_tasks
+GROUP BY 1, 2;
+
+--------------------------------------------------------------------------------
+-- Finally join the causes together for easy grouping.
+--------------------------------------------------------------------------------
+DROP VIEW IF EXISTS scroll_jank_cause_blocking_task;
+CREATE VIEW scroll_jank_cause_blocking_task AS
+ SELECT
+ lang.scroll_id,
+ lang.blocked_by_language_detection,
+ copy.blocked_by_copy_request
+ FROM
+ language_detection_overlapping_scrolls lang JOIN
+ screenshot_overlapping_scrolls copy ON copy.scroll_id = lang.scroll_id;
diff --git a/src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_touch_move.sql b/src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_touch_move.sql
index e07bb327e..e07bb327e 100644
--- a/src/trace_processor/metrics/chrome/scroll_jank_cause_blocking_touch_move.sql
+++ b/src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_touch_move.sql
diff --git a/src/trace_processor/metrics/chrome/scroll_jank_cause_get_bitmap.sql b/src/trace_processor/metrics/sql/chrome/scroll_jank_cause_get_bitmap.sql
index e0a67e05e..e0a67e05e 100644
--- a/src/trace_processor/metrics/chrome/scroll_jank_cause_get_bitmap.sql
+++ b/src/trace_processor/metrics/sql/chrome/scroll_jank_cause_get_bitmap.sql
diff --git a/src/trace_processor/metrics/sql/chrome/scroll_jank_cause_queuing_delay.sql b/src/trace_processor/metrics/sql/chrome/scroll_jank_cause_queuing_delay.sql
new file mode 100644
index 000000000..9b45876e0
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/scroll_jank_cause_queuing_delay.sql
@@ -0,0 +1,512 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the 'License');
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an 'AS IS' BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+SELECT RUN_METRIC('chrome/chrome_thread_slice.sql');
+SELECT RUN_METRIC('chrome/scroll_flow_event_queuing_delay.sql');
+
+-- See b/184134310 why we remove ThreadController active.
+DROP VIEW IF EXISTS blocking_tasks_no_threadcontroller_active;
+CREATE VIEW blocking_tasks_no_threadcontroller_active AS
+ SELECT
+ slice.*,
+ ancestor.id AS task_ancestor_id,
+ ancestor.name AS task_ancestor_name
+ FROM
+ chrome_thread_slice AS slice LEFT JOIN
+ ancestor_slice(slice.id) as ancestor ON ancestor.id = slice.parent_id
+ WHERE
+ slice.name != "ThreadController active" AND
+ (slice.depth = 0 OR ancestor.name = "ThreadController active");
+
+-- Sort track ids to optimize joining with slices
+-- as engine doesn't do the sort to join in O(LogN)
+-- per row by default
+DROP VIEW IF EXISTS chrome_annotated_threads_and_processes;
+CREATE VIEW chrome_annotated_threads_and_processes AS
+ SELECT
+ thread_track.id AS track_id,
+ chrome_thread.canonical_name AS thread_name,
+ chrome_process.process_type AS process_name
+ FROM
+ thread_track JOIN
+ chrome_thread JOIN
+ chrome_process ON
+ thread_track.utid = chrome_thread.utid AND
+ chrome_thread.upid = chrome_process.upid
+ ORDER BY
+ track_id ASC;
+
+-- See b/166441398 & crbug/1094361 for why we remove threadpool (originally
+-- the -to-End step). In essence -to-End is often reported on the ThreadPool
+-- after the fact with explicit timestamps so it being blocked isn't noteworthy.
+DROP VIEW IF EXISTS blocking_chrome_tasks_without_threadpool;
+CREATE VIEW blocking_chrome_tasks_without_threadpool AS
+ SELECT
+ slice.*,
+ annotations.thread_name AS thread_name,
+ annotations.process_name AS process_name
+ FROM
+ blocking_tasks_no_threadcontroller_active AS slice JOIN
+ chrome_annotated_threads_and_processes AS annotations ON
+ annotations.track_id = slice.track_id
+ WHERE
+ NOT (thread_name GLOB "*ThreadPool*");
+
+-- This view grabs any slice that could have prevented any GestureScrollUpdate
+-- flow event from being run (queuing delays). For RunTask we know that its
+-- generic (and thus hard to figure out whats the cause) so we grab the src
+-- location to make it more meaningful.
+--
+-- See b/184134310 for why we allow depth == 1 and ancestor.id is null (which
+-- implies its a "ThreadController active" slice because we removed it
+-- previously).
+DROP TABLE IF EXISTS blocking_tasks_queuing_delay;
+CREATE TABLE blocking_tasks_queuing_delay AS
+ SELECT
+ EXTRACT_ARG(slice.arg_set_id, "task.posted_from.file_name") as file,
+ EXTRACT_ARG(slice.arg_set_id, "task.posted_from.function_name") as function,
+ trace_id,
+ queuing_time_ns,
+ avg_vsync_interval,
+ next_track_id,
+ CASE WHEN queuing.ancestor_end <= slice.ts THEN
+ CASE WHEN slice.ts + slice.dur <= queuing.maybe_next_ancestor_ts THEN
+ slice.dur
+ ELSE
+ queuing.maybe_next_ancestor_ts - slice.ts
+ END
+ ELSE
+ CASE WHEN slice.ts + slice.dur <= queuing.maybe_next_ancestor_ts THEN
+ slice.ts + slice.dur - queuing.ancestor_end
+ ELSE
+ queuing.maybe_next_ancestor_ts - queuing.ancestor_end
+ END
+ END AS dur_overlapping_ns,
+ description,
+ scroll_slice_id,
+ scroll_ts,
+ scroll_dur,
+ scroll_track_id,
+ jank,
+ slice.*
+ FROM
+ scroll_flow_event_queuing_delay queuing JOIN
+ blocking_chrome_tasks_without_threadpool AS slice ON
+ slice.ts + slice.dur > queuing.ancestor_end AND
+ queuing.maybe_next_ancestor_ts > slice.ts AND
+ slice.track_id = queuing.next_track_id
+ WHERE
+ queuing_time_ns IS NOT NULL AND
+ queuing_time_ns > 0;
+
+-- Now for each toplevel task (depth = 0 from above) we want to grab all their
+-- children slices. This is done by joining on descendant_slice which is a
+-- trace processor defined operator. This will results in 1 row for every
+-- descendant slice. So all fields in base.* will be repeated ONCE for each
+-- child, but if it has no slice it will occur only once but all the
+-- |descendant_.*| fields will be NULL because of the LEFT JOIN.
+-- Additionally for mojo events we replace the descendant_name with just the
+-- "interface_name" since that is more descriptive for our jank purposes.
+DROP VIEW IF EXISTS all_descendant_blocking_tasks_queuing_delay;
+CREATE VIEW all_descendant_blocking_tasks_queuing_delay AS
+ SELECT
+ descendant.id AS descendant_id,
+ descendant.ts AS descendant_ts,
+ descendant.dur AS descendant_dur,
+ COALESCE(
+ IIF(descendant.arg_set_id IS NOT NULL,
+ EXTRACT_ARG(descendant.arg_set_id,
+ "chrome_mojo_event_info.watcher_notify_interface_tag"),
+ NULL),
+ IIF(descendant.arg_set_id IS NOT NULL,
+ EXTRACT_ARG(descendant.arg_set_id,
+ "chrome_mojo_event_info.mojo_interface_tag"),
+ NULL),
+ descendant.name) AS descendant_name,
+ EXTRACT_ARG(descendant.arg_set_id,
+ "chrome_mojo_event_info.ipc_hash") AS descendant_ipc_hash,
+ descendant.parent_id As descendant_parent_id,
+ descendant.depth AS descendant_depth,
+ descendant.category AS descendant_category,
+ base.*
+ FROM
+ blocking_tasks_queuing_delay base LEFT JOIN
+ descendant_slice(base.id) AS descendant;
+
+DROP TABLE IF EXISTS all_descendant_blocking_tasks_queuing_delay_with_cpu_time;
+CREATE TABLE all_descendant_blocking_tasks_queuing_delay_with_cpu_time AS
+ SELECT
+ cpu.thread_dur AS descendant_thread_dur,
+ CAST(cpu.thread_dur AS REAL) / descendant.thread_dur
+ AS descendant_cpu_percentage,
+ CAST(cpu.thread_dur AS REAL) /
+ (descendant.thread_dur /
+ (1 << (descendant.descendant_depth - 1))) > 0.5
+ AS descendant_cpu_time_above_relative_threshold,
+ descendant_dur / descendant.dur AS descendant_dur_percentage,
+ descendant_dur /
+ (descendant.dur / (1 << (descendant.descendant_depth - 1))) > 0.5
+ AS descendant_dur_above_relative_threshold,
+ descendant.*
+ FROM
+ all_descendant_blocking_tasks_queuing_delay descendant LEFT JOIN (
+ SELECT
+ id, thread_dur
+ FROM chrome_thread_slice
+ ) AS cpu ON
+ cpu.id = descendant.descendant_id;
+
+-- Now that we've generated the descendant count how many siblings each row
+-- has. Recall that all the top level tasks are repeated but each row represents
+-- a descendant slice. This means since we LEFT JOIN we will say a slice has 0
+-- siblings if it has no descendants (which is true), and otherwise we will
+-- compute the siblings as the count of all slices with the same parent minus
+-- the current slice.
+DROP VIEW IF EXISTS counted_descendant_blocking_tasks_queuing_delay;
+CREATE VIEW counted_descendant_blocking_tasks_queuing_delay AS
+ SELECT
+ base.*,
+ COALESCE(single_descendant.number_of_siblings, 0) AS number_of_siblings
+ FROM
+ all_descendant_blocking_tasks_queuing_delay_with_cpu_time base LEFT JOIN (
+ SELECT
+ descendant_parent_id,
+ COUNT(*) - 1 AS number_of_siblings
+ FROM all_descendant_blocking_tasks_queuing_delay_with_cpu_time
+ WHERE descendant_parent_id IS NOT NULL
+ GROUP BY 1
+ ) single_descendant ON
+ single_descendant.descendant_parent_id = base.descendant_parent_id;
+
+-- Now we group by the |id| which is the top level task id and find the first
+-- descendant_depth where we have a sibling. We need this because we only want
+-- to include single descendant slices in our metric name to keep it easy to
+-- reason about what that code is doing.
+DROP VIEW IF EXISTS blocking_tasks_queuing_delay_with_invalid_depth;
+CREATE VIEW blocking_tasks_queuing_delay_with_invalid_depth AS
+ SELECT
+ base.*,
+ (
+ descendant_cpu_time_above_relative_threshold AND
+ descendant_cpu_percentage > 0.05
+ ) OR (
+ descendant_dur_above_relative_threshold AND
+ descendant_dur_percentage > 0.05
+ ) AS descendant_major_slice,
+ COALESCE(depth.invalid_depth, 10) AS invalid_depth
+ FROM
+ counted_descendant_blocking_tasks_queuing_delay base LEFT JOIN (
+ SELECT
+ id,
+ MIN(descendant_depth) AS invalid_depth
+ FROM counted_descendant_blocking_tasks_queuing_delay
+ WHERE number_of_siblings >= 1
+ GROUP BY 1
+ ) AS depth ON base.id = depth.id
+ ORDER BY
+ descendant_depth ASC,
+ descendant_cpu_percentage DESC,
+ descendant_dur_percentage DESC;
+
+-- Now to get back to a single output per top level task we group by all the
+-- toplevel fields and aggregate the descendant fields. We only include the
+-- descendant if their depth is less than the first depth with siblings (the
+-- |invalid_depth|).
+DROP VIEW IF EXISTS descendant_blocking_tasks_queuing_delay;
+CREATE VIEW descendant_blocking_tasks_queuing_delay AS
+ SELECT
+ id,
+ ts,
+ dur,
+ track_id,
+ trace_id,
+ name,
+ category,
+ scroll_slice_id AS scroll_id,
+ scroll_ts,
+ scroll_dur,
+ scroll_track_id,
+ jank,
+ queuing_time_ns,
+ dur_overlapping_ns,
+ description,
+ replace(file, rtrim(file, replace(file, '/', '')), '') AS file,
+ thread_name,
+ process_name,
+ function,
+ avg_vsync_interval,
+ GROUP_CONCAT(
+ CASE WHEN descendant_depth < invalid_depth OR descendant_major_slice THEN
+ descendant_id
+ ELSE
+ NULL
+ END
+ , "-") AS descendant_id,
+ GROUP_CONCAT(
+ CASE WHEN descendant_depth < invalid_depth OR descendant_major_slice THEN
+ descendant_ts
+ ELSE
+ NULL
+ END
+ , "-") AS descendant_ts,
+ GROUP_CONCAT(
+ CASE WHEN descendant_depth < invalid_depth OR descendant_major_slice THEN
+ descendant_dur
+ ELSE
+ NULL
+ END
+ , "-") AS descendant_dur,
+ GROUP_CONCAT(
+ CASE WHEN descendant_depth < invalid_depth OR descendant_major_slice THEN
+ descendant_name
+ ELSE
+ NULL
+ END, "-") AS descendant_name,
+ GROUP_CONCAT(
+ CASE WHEN descendant_depth < invalid_depth OR descendant_major_slice THEN
+ descendant_thread_dur
+ ELSE
+ NULL
+ END
+ , "-") AS descendant_thread_dur,
+ GROUP_CONCAT(
+ CASE WHEN descendant_depth < invalid_depth OR descendant_major_slice THEN
+ descendant_cpu_percentage
+ ELSE
+ NULL
+ END
+ , "-") AS descendant_cpu_time,
+ GROUP_CONCAT(
+ CASE WHEN descendant_category = "mojom" THEN
+ descendant_name
+ ELSE
+ NULL
+ END
+ , "-") AS mojom_name,
+ -- All ipc_hashes should be equal so just select the first non-null one.
+ MIN(descendant_ipc_hash) AS mojom_ipc_hash,
+ GROUP_CONCAT(
+ CASE WHEN
+ descendant_category = "toplevel" AND
+ descendant_name NOT GLOB "*ThreadController*" THEN
+ descendant_name
+ ELSE
+ NULL
+ END
+ , "-") AS toplevel_name,
+ GROUP_CONCAT(
+ CASE WHEN descendant_category = "Java" THEN
+ descendant_name
+ ELSE
+ NULL
+ END
+ , "-") AS java_name
+ FROM
+ blocking_tasks_queuing_delay_with_invalid_depth
+ GROUP BY 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
+ ORDER BY descendant_cpu_percentage DESC;
+
+SELECT CREATE_FUNCTION(
+ -- Function prototype: takes a '-' separated list of slice names (formed by
+ -- the GROUP_CONCAT above) and returns the first slice if any or NULL
+ -- otherwise.
+ 'GetFirstSliceNameOrNull(name STRING)',
+ -- Returns the first slice name or NULL
+ 'STRING',
+ -- Preforms the actual string modification, takes the either the whole string
+ -- if there is no '-' or up to the first '-'. SUBSTR returns NULL if $name is
+ -- NULL.
+ 'SELECT SUBSTR($name, 0,
+ CASE WHEN INSTR($name, "-") = 0 THEN
+ LENGTH($name)+1 ELSE
+ INSTR($name, "-")
+ END)'
+);
+
+SELECT CREATE_FUNCTION(
+ -- Function prototype: takes a '-' separated list of slice names (formed by
+ -- the GROUP_CONCAT above) and checks for certain important view names and
+ -- falls back on GetFirstSliceNameOrNull if it can't find one.
+ 'GetJavaSliceSummaryOrNull(name STRING)',
+ -- Returns the summary of the provided list of java slice names.
+ 'STRING',
+ -- Performs a bunch of GLOB matches in an order, now there could be multiple
+ -- matches (both Toolbar & TabList could be true) so the order matters in
+ -- tagging since we don't support multiple tagging of values. Ideally we would
+ -- determine which one was the longest duration, but this should be sufficient
+ -- for now.
+ 'SELECT
+ CASE WHEN $name GLOB "*ToolbarControlContainer*" THEN
+ "ToolbarControlContainer"
+ WHEN $name GLOB "*ToolbarProgressBar*" THEN
+ "ToolbarProgressBar"
+ WHEN $name GLOB "*TabGroupUiToolbarView*" THEN
+ "TabGroupUiToolbarView"
+ WHEN $name GLOB "*TabGridThumbnailView*" THEN
+ "TabGridThumbnailView"
+ WHEN $name GLOB "*TabGridDialogView*" THEN
+ "TabGridDialogView"
+ WHEN $name GLOB "*BottomContainer*" THEN
+ "BottomContainer"
+ WHEN $name GLOB "*FeedSwipeRefreshLayout*" THEN
+ "FeedSwipeRefreshLayout"
+ WHEN $name GLOB "*AutocompleteEditText*" THEN
+ "AutocompleteEditText"
+ WHEN $name GLOB "*HomeButton*" THEN
+ "HomeButton"
+ WHEN $name GLOB "*ToggleTabStackButton*" THEN
+ "ToggleTabStackButton"
+ WHEN $name GLOB "*ListMenuButton*" THEN
+ "ListMenuButton"
+ WHEN $name GLOB "*ScrimView*" THEN
+ "ScrimView"
+ WHEN $name GLOB "*ChromeImageView*" THEN
+ "ChromeImageView"
+ WHEN $name GLOB "*AppCompatImageView*" THEN
+ "AppCompatImageView"
+ WHEN $name GLOB "*ChromeImageButton*" THEN
+ "ChromeImageButton"
+ WHEN $name GLOB "*AppCompatImageButton*" THEN
+ "AppCompatImageButton"
+ WHEN $name GLOB "*TabListRecyclerView*" THEN
+ "TabListRecyclerView"
+ ELSE
+ GetFirstSliceNameOrNull($name)
+ END'
+);
+
+SELECT CREATE_FUNCTION(
+ -- Function prototype: takes slice name, category and descendant_name and
+ -- determines if this event should be classified as unknown or not.
+ 'UnknownEventOrEmptyString(name STRING, cat STRING, has_descendant STRING)',
+ -- Returns either "-UnknownEvent" or "".
+ 'STRING',
+ -- If our current event has a posted from we consider it already categorized
+ -- even if we don't have events underneath it. If its java often we won't have
+ -- sub events, and finally if its a single event we just use its name there
+ -- isn't anything under to use so just leave it at that.
+ 'SELECT
+ CASE WHEN
+ $name = "ThreadControllerImpl::RunTask" OR
+ $cat = "Java" OR
+ $has_descendant IS NULL THEN
+ "" ELSE
+ "-UnknownEvent"
+ END'
+);
+
+SELECT CREATE_FUNCTION(
+ -- Function prototype: Takes a slice name, function, and file, and determines
+ -- if we should use the slice name, or if its a RunTask event uses the
+ -- function & file name, however if the RunTask posted from is one of the
+ -- simple_watcher paths we collapse them for attributation.
+ 'TopLevelName(name STRING, function STRING, file STRING)',
+ 'STRING',
+ -- The difference for the mojom functions are:
+ -- 1) PostDispatchNextMessageFromPipe:
+ -- We knew that there is a message in the pipe, didn't try to set up a
+ -- SimpleWatcher to monitor when a new one arrives.
+ -- 2) ArmOrNotify:
+ -- We tried to set up SimpleWatcher, but the setup failed as the
+ -- message arrived as we were setting this up, so we posted a task
+ -- instead.
+ -- 3) Notify:
+ -- SimpleWatcher was set up and after a period of monitoring detected
+ -- a new message.
+ -- For our jank use case this distinction isn't very useful so we group them
+ -- together.
+ 'SELECT
+ CASE WHEN $name = "ThreadControllerImpl::RunTask" THEN
+ CASE WHEN $function IN
+ ("PostDispatchNextMessageFromPipe", "ArmOrNotify", "Notify") THEN
+ "posted-from-mojo-pipe"
+ ELSE
+ "posted-from-" || $function || "()-in-" || $file
+ END
+ ELSE
+ $name
+ END'
+);
+
+-- Create a common name for each "cause" based on the slice stack we found.
+DROP VIEW IF EXISTS scroll_jank_cause_queuing_delay_temp;
+CREATE VIEW scroll_jank_cause_queuing_delay_temp AS
+ SELECT
+ TopLevelName(name, function, file) || COALESCE(
+ "-" || descendant_name, "") AS location,
+ TopLevelName(name, function, file) || COALESCE(
+ "-" || GetFirstSliceNameOrNull(mojom_name)
+ || COALESCE("(ipc=" || mojom_ipc_hash || ")", ""),
+ "-" || GetFirstSliceNameOrNull(toplevel_name)
+ || COALESCE("(ipc=" || mojom_ipc_hash || ")", ""),
+ "-" || GetJavaSliceSummaryOrNull(java_name),
+ UnknownEventOrEmptyString(name, category, descendant_name)
+ ) AS restricted_location,
+ base.*
+ FROM descendant_blocking_tasks_queuing_delay base;
+
+-- Figure out the average time taken during non-janky scrolls updates for each
+-- TraceEvent (metric_name) stack.
+DROP VIEW IF EXISTS scroll_jank_cause_queuing_delay_average_no_jank_time;
+CREATE VIEW scroll_jank_cause_queuing_delay_average_no_jank_time AS
+ SELECT
+ location,
+ AVG(dur_overlapping_ns) as avg_dur_overlapping_ns
+ FROM scroll_jank_cause_queuing_delay_temp
+ WHERE NOT jank
+ GROUP BY 1;
+
+-- Again figure out the average time, but based on a more restricted set of
+-- trace events.
+DROP VIEW IF EXISTS scroll_jank_cause_queuing_delay_average_no_jank_time_restricted;
+CREATE VIEW scroll_jank_cause_queuing_delay_average_no_jank_time_restricted AS
+ SELECT
+ restricted_location,
+ AVG(dur_overlapping_ns) as avg_dur_overlapping_ns_restricted
+ FROM scroll_jank_cause_queuing_delay_temp
+ WHERE NOT jank
+ GROUP BY 1;
+
+
+-- Join every row (jank and non-jank with the average non-jank time for the
+-- given metric_name).
+DROP VIEW IF EXISTS scroll_jank_cause_queuing_delay_unannotated;
+CREATE VIEW scroll_jank_cause_queuing_delay_unannotated AS
+ SELECT
+ base.*,
+ 'InputLatency.LatencyInfo.Flow.QueuingDelay.' ||
+ CASE WHEN jank THEN 'Jank' ELSE 'NoJank' END || '.BlockingTasksUs.' ||
+ base.location as metric_name,
+ COALESCE(avg_no_jank.avg_dur_overlapping_ns, 0)
+ AS avg_no_jank_dur_overlapping_ns
+ FROM
+ scroll_jank_cause_queuing_delay_temp base LEFT JOIN
+ scroll_jank_cause_queuing_delay_average_no_jank_time avg_no_jank ON
+ base.location = avg_no_jank.location;
+
+-- Join in the restricted set of trace events average as well to form the final output.
+DROP VIEW IF EXISTS scroll_jank_cause_queuing_delay;
+CREATE VIEW scroll_jank_cause_queuing_delay AS
+ SELECT
+ base.*,
+ 'QueuingDelay.' ||
+ CASE WHEN jank THEN 'Jank' ELSE 'NoJank' END || '.BlockingTasksUs.' ||
+ base.restricted_location AS restricted_metric_name,
+ COALESCE(avg_no_jank.avg_dur_overlapping_ns_restricted, 0)
+ AS avg_no_jank_dur_overlapping_ns_restricted
+ FROM
+ scroll_jank_cause_queuing_delay_unannotated base LEFT JOIN
+ scroll_jank_cause_queuing_delay_average_no_jank_time_restricted avg_no_jank ON
+ base.restricted_location = avg_no_jank.restricted_location;
diff --git a/src/trace_processor/metrics/sql/chrome/sufficient_chrome_processes.sql b/src/trace_processor/metrics/sql/chrome/sufficient_chrome_processes.sql
new file mode 100644
index 000000000..c44270ebd
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/sufficient_chrome_processes.sql
@@ -0,0 +1,48 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Get all chrome processes and threads tables set up.
+SELECT RUN_METRIC('chrome/chrome_processes.sql');
+
+-- When working on InputLatency events we need to ensure we have all the events
+-- from the browser, renderer, and GPU processes. This query isn't quite
+-- perfect. In system tracing we could have 3 browser processes all in the
+-- background and this would match, but for now its the best we can do (renderer
+-- and GPU names on android are quite complicated, but this should filter 99%
+-- (citation needed) of what we want.
+--
+-- See b/151077536 for historical context.
+DROP VIEW IF EXISTS sufficient_chrome_processes;
+CREATE VIEW sufficient_chrome_processes AS
+ SELECT
+ CASE WHEN (
+ SELECT COUNT(*) FROM chrome_process) = 0
+ THEN
+ FALSE
+ ELSE (
+ SELECT COUNT(*) >= 3 FROM (
+ SELECT name FROM chrome_process
+ WHERE
+ name GLOB "Browser" OR
+ name GLOB "Renderer" OR
+ name GLOB "Gpu" OR
+ name GLOB 'com.android.chrome*' OR
+ name GLOB 'com.chrome.beta*' OR
+ name GLOB 'com.chrome.dev*' OR
+ name GLOB 'com.chrome.canary*' OR
+ name GLOB 'com.google.android.apps.chrome*' OR
+ name GLOB 'org.chromium.chrome*'
+ GROUP BY name
+ )) END AS have_enough_chrome_processes; \ No newline at end of file
diff --git a/src/trace_processor/metrics/chrome/test_chrome_metric.sql b/src/trace_processor/metrics/sql/chrome/test_chrome_metric.sql
index 2e9ee322c..2e9ee322c 100644
--- a/src/trace_processor/metrics/chrome/test_chrome_metric.sql
+++ b/src/trace_processor/metrics/sql/chrome/test_chrome_metric.sql
diff --git a/src/trace_processor/metrics/sql/chrome/touch_flow_event.sql b/src/trace_processor/metrics/sql/chrome/touch_flow_event.sql
new file mode 100644
index 000000000..3318ff7de
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/touch_flow_event.sql
@@ -0,0 +1,31 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the 'License');
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an 'AS IS' BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- While handling a InputLatency::TouchMove event a sequence of Flows define the
+-- critical path from Beginning to End. This metric breaks down the flows for
+-- the same InputLatency::TouchMove event.
+--
+-- WARNING: This metric should not be used as a source of truth. It is under
+-- active development and the values & meaning might change without
+-- notice.
+
+-- Provides the touch_jank table which gives us all the TouchMove events we care
+-- about and labels them janky or not.
+SELECT RUN_METRIC(
+ 'chrome/gesture_flow_event.sql',
+ 'prefix', 'touch',
+ 'gesture_update', 'TouchMove',
+ 'id_field', 'touch_id'
+ );
diff --git a/src/trace_processor/metrics/sql/chrome/touch_flow_event_queuing_delay.sql b/src/trace_processor/metrics/sql/chrome/touch_flow_event_queuing_delay.sql
new file mode 100644
index 000000000..2c493d1ea
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/touch_flow_event_queuing_delay.sql
@@ -0,0 +1,26 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the 'License');
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an 'AS IS' BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- This metric takes each flow event in a InputLatency::GestureScrollUpdate and
+-- and computes the time from the ancestor_end of the current flow to the
+-- ancestor_ts of the next flow event. This is a reasonable approximation of the
+-- time we waited for the next step in the critical flow to start.
+
+-- Provides the scroll_flow_event table which gives us all the flow events with
+-- associated TouchMove events we care about and labels them janky or not.
+SELECT RUN_METRIC('chrome/gesture_flow_event_queuing_delay.sql',
+ 'prefix', 'touch',
+ 'id_field', 'touch_id');
+
diff --git a/src/trace_processor/metrics/sql/chrome/touch_jank.sql b/src/trace_processor/metrics/sql/chrome/touch_jank.sql
new file mode 100644
index 000000000..2920099f7
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/touch_jank.sql
@@ -0,0 +1,33 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- A collection of metrics related to TouchMove events.
+--
+-- We define a TouchMove to be janky if comparing forwards or backwards
+-- (ignoring coalesced updates) a given TouchMove exceeds the duration of its
+-- predecessor or successor by 50% of a vsync interval (defaulted to 60 FPS).
+--
+-- WARNING: This metric should not be used as a source of truth. It is under
+-- active development and the values & meaning might change without
+-- notice.
+
+SELECT RUN_METRIC(
+ 'chrome/gesture_jank.sql',
+ 'prefix', 'touch',
+ 'gesture_start', 'TouchStart',
+ 'gesture_update', 'TouchMove',
+ 'gesture_end', 'TouchEnd',
+ 'id_field', 'touch_id',
+ 'proto_name', 'TouchJank');
diff --git a/src/trace_processor/metrics/sql/experimental/OWNERS b/src/trace_processor/metrics/sql/experimental/OWNERS
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/trace_processor/metrics/sql/experimental/OWNERS
diff --git a/src/trace_processor/metrics/sql/experimental/blink_gc_metric.sql b/src/trace_processor/metrics/sql/experimental/blink_gc_metric.sql
new file mode 100644
index 000000000..c2603321d
--- /dev/null
+++ b/src/trace_processor/metrics/sql/experimental/blink_gc_metric.sql
@@ -0,0 +1,581 @@
+-- Maps non-aggregated Blink GC events in timeline to telemetry friendly
+-- names.
+--
+-- This includes the old style or the new naming scheme one which only occur on
+-- the main thread.
+DROP VIEW IF EXISTS blink_non_aggregated_gc_event_name;
+CREATE VIEW blink_non_aggregated_gc_event_name AS
+SELECT
+ 'BlinkGC.AtomicPauseMarkEpilogue' AS name,
+ 'blink-gc-atomic-pause-mark-epilogue' AS old_event_name,
+ 'blink:gc:main_thread:cycle:full:atomic:mark:epilogue' AS new_event_name
+UNION ALL
+SELECT
+ 'BlinkGC.AtomicPauseMarkPrologue',
+ 'blink-gc-atomic-pause-mark-prologue',
+ 'blink:gc:main_thread:cycle:full:atomic:mark:prologue'
+UNION ALL
+SELECT
+ 'BlinkGC.AtomicPauseMarkRoots',
+ 'blink-gc-atomic-pause-mark-roots',
+ 'blink:gc:main_thread:cycle:full:atomic:mark:roots'
+UNION ALL
+SELECT
+ 'BlinkGC.IncrementalMarkingStartMarking',
+ 'blink-gc-incremental-start',
+ 'blink:gc:main_thread:cycle:full:incremental:mark:start'
+UNION ALL
+SELECT
+ 'BlinkGC.IncrementalMarkingStep',
+ 'blink-gc-incremental-step',
+ 'blink:gc:main_thread:cycle:full:incremental:mark:step'
+UNION ALL
+SELECT
+ 'BlinkGC.UnifiedMarkingStep',
+ 'blink-gc-unified-marking-by-v8',
+ 'unified:gc:main_thread:cycle:full:mark:step'
+UNION ALL
+SELECT
+ 'BlinkGC.CompleteSweep',
+ 'blink-gc-complete-sweep',
+ 'blink:gc:main_thread:cycle:full:sweep:complete'
+UNION ALL
+SELECT
+ 'BlinkGC.LazySweepInIdle',
+ 'blink-gc-sweep-task-foreground',
+ 'blink:gc:main_thread:cycle:full:sweep:idle'
+UNION ALL
+SELECT
+ 'BlinkGC.LazySweepOnAllocation',
+ 'blink-gc-sweep-allocation',
+ 'blink:gc:main_thread:cycle:full:sweep:on_allocation'
+UNION ALL
+SELECT
+ 'BlinkGC.AtomicPauseSweepAndCompact' AS name,
+ 'blink-gc-atomic-pause-sweep-and-compact' AS old_event_name,
+ 'blink:gc:main_thread:cycle:full:atomic:sweep:compact' AS new_event_name;
+
+-- Get all the slices we care about. These are ones that start with V8.GC or
+-- BlinkGC. If you need more you need to modify the where clause for
+-- blink_gc_cpu_slice.
+DROP TABLE IF EXISTS blink_gc_cpu_slice;
+CREATE TABLE blink_gc_cpu_slice AS
+SELECT
+ CASE WHEN dur != 0 THEN cpuDurNs/1e6 ELSE 0.0 END AS cpuDurMs,
+ *
+FROM (
+ SELECT
+ COALESCE(EXTRACT_ARG(arg_set_id, 'debug.forced'), FALSE) OR
+ -- This subquery replaces
+ -- metrics.v8.utils.isForcedGarbageCollectionEvent(event)
+ (
+ SELECT
+ id
+ FROM ANCESTOR_SLICE(slice.id) AS ancestor
+ WHERE ancestor.name = 'V8.GCLowMemoryNotification' LIMIT 1
+ ) IS NOT NULL AS forced,
+ -- upid replaces pid, because its more fool proof ensuring uniqueness.
+ thread.upid || ':' || EXTRACT_ARG(arg_set_id, 'debug.epoch') AS epoch,
+ slice.thread_dur AS cpuDurNs,
+ slice.*
+ FROM thread_slice as slice
+ INNER JOIN thread_track ON slice.track_id = thread_track.id
+ INNER JOIN thread ON thread_track.utid = thread.id
+ WHERE
+ slice.dur >= 0 AND (
+ slice.name GLOB "V8.GC*" OR (slice.name GLOB "BlinkGC*" AND NOT forced)
+ )
+);
+
+-- This grabs all the single events for "BlinkGC.*", and restricts to only
+-- forced events.
+DROP TABLE IF EXISTS blink_slice;
+CREATE TABLE blink_slice AS
+SELECT
+ event_name.old_event_name AS blink_non_aggregated_gc_event_name,
+ event_name.new_event_name AS blink_non_aggregated_gc_events_new_name,
+ blink_gc_cpu_slice.*
+FROM
+ blink_gc_cpu_slice LEFT JOIN
+ blink_non_aggregated_gc_event_name AS event_name ON
+ event_name.name = blink_gc_cpu_slice.name
+WHERE
+ blink_gc_cpu_slice.name GLOB "BlinkGC*" AND NOT forced;
+
+-- This groups all the events by name and epoch for from "blink_slice" for easy
+-- access.
+DROP TABLE IF EXISTS blink_per_epoch_slice;
+CREATE TABLE blink_per_epoch_slice AS
+SELECT
+ name,
+ epoch,
+ blink_non_aggregated_gc_event_name,
+ blink_non_aggregated_gc_events_new_name,
+ SUM(cpuDurMs) AS cpuDurPerEpochMs
+FROM blink_slice
+GROUP BY 1, 2, 3, 4;
+
+-- All events that should be summed up to 'blink-gc-mark-roots'.
+DROP VIEW IF EXISTS blink_top_gc_roots_marking_event;
+CREATE VIEW blink_top_gc_roots_marking_event AS
+SELECT * FROM blink_slice WHERE name in (
+ 'BlinkGC.VisitRoots'
+);
+
+-- All events that should be summed up to
+-- 'blink-gc-atomic-pause-mark-transitive-closure'.
+DROP VIEW IF EXISTS blink_gc_atomic_pause_transitive_closure_event;
+CREATE VIEW blink_gc_atomic_pause_transitive_closure_event AS
+SELECT * FROM blink_slice WHERE name in (
+ 'BlinkGC.AtomicPauseMarkTransitiveClosure'
+);
+
+-- All events that should be summed up to 'blink-gc-mark-transitive-closure'.
+DROP VIEW IF EXISTS blink_gc_foreground_marking_transitive_closure_event;
+CREATE VIEW
+ blink_gc_foreground_marking_transitive_closure_event AS
+SELECT * FROM blink_slice WHERE name in (
+ 'BlinkGC.AtomicPauseMarkTransitiveClosure',
+ 'BlinkGC.IncrementalMarkingStep',
+ 'BlinkGC.UnifiedMarkingStep'
+);
+
+-- Names of Blink GC foreground marking events in timeline.
+DROP VIEW IF EXISTS blink_top_gc_foreground_marking_event;
+CREATE VIEW blink_top_gc_foreground_marking_event AS
+SELECT * FROM blink_slice WHERE name in (
+ 'BlinkGC.AtomicPauseMarkEpilogue',
+ 'BlinkGC.AtomicPauseMarkPrologue',
+ 'BlinkGC.AtomicPauseMarkRoots',
+ 'BlinkGC.IncrementalMarkingStartMarking'
+)
+UNION ALL
+SELECT * FROM blink_gc_foreground_marking_transitive_closure_event;
+
+-- Names of Blink GC foreground marking events in timeline.
+DROP VIEW IF EXISTS blink_gc_forced_foreground_marking_event;
+CREATE VIEW blink_gc_forced_foreground_marking_event AS
+SELECT * FROM blink_slice WHERE name in (
+ 'BlinkGC.AtomicPauseMarkEpilogue',
+ 'BlinkGC.AtomicPauseMarkPrologue',
+ 'BlinkGC.AtomicPauseMarkRoots',
+ 'BlinkGC.IncrementalMarkingStartMarking',
+ 'BlinkGC.MarkBailOutObjects',
+ 'BlinkGC.MarkFlushV8References',
+ 'BlinkGC.MarkFlushEphemeronPairs'
+);
+
+-- Names of Blink GC background marking events in timeline.
+DROP VIEW IF EXISTS blink_top_gc_background_marking_event;
+CREATE VIEW blink_top_gc_background_marking_event AS
+SELECT * FROM blink_slice WHERE name in (
+ 'BlinkGC.ConcurrentMarkingStep'
+);
+
+-- Names of Blink GC foreground sweeping events in timeline.
+DROP VIEW IF EXISTS blink_top_gc_foreground_sweeping_event;
+CREATE VIEW blink_top_gc_foreground_sweeping_event AS
+SELECT * FROM blink_slice WHERE name in (
+ 'BlinkGC.CompleteSweep',
+ 'BlinkGC.LazySweepInIdle',
+ 'BlinkGC.LazySweepOnAllocation'
+);
+
+-- Names of Blink GC background sweeping events in timeline.
+DROP VIEW IF EXISTS blink_top_gc_background_sweeping_event;
+CREATE VIEW blink_top_gc_background_sweeping_event AS
+SELECT * FROM blink_slice WHERE name in (
+ 'BlinkGC.ConcurrentSweepingStep'
+);
+
+-- Names of all Blink Unified GC events in timeline.
+DROP VIEW IF EXISTS blink_top_gc_event;
+CREATE VIEW blink_top_gc_event AS
+SELECT * FROM blink_slice WHERE name in (
+ SELECT name FROM blink_non_aggregated_gc_event_name
+) OR name in (
+ SELECT name FROM blink_gc_atomic_pause_transitive_closure_event
+);
+
+-- All events that should be summed up to 'blink-gc-atomic-pause'. Note that
+-- this events need to have an epoch counter in args.epoch.
+DROP VIEW IF EXISTS atomic_pause_event;
+CREATE VIEW atomic_pause_event AS
+SELECT * FROM blink_slice WHERE name in (
+ 'BlinkGC.AtomicPauseMarkEpilogue',
+ 'BlinkGC.AtomicPauseMarkPrologue',
+ 'BlinkGC.AtomicPauseMarkRoots',
+ 'BlinkGC.AtomicPauseMarkTransitiveClosure',
+ 'BlinkGC.AtomicPauseSweepAndCompact'
+);
+
+-- This is a more complex variable so benefits from additional comments so we
+-- pull it out of the proto filling.
+DROP VIEW IF EXISTS unified_gc_total;
+CREATE VIEW unified_gc_total AS
+SELECT
+ *
+FROM blink_gc_cpu_slice
+WHERE (
+ -- This subclause replaces
+ -- metrics.v8.utils.isNotForcedTopGarbageCollectionEvent()
+
+ -- These names are found in isTopGarbageCollectionEvent().
+ name in (
+ 'V8.GCCompactor',
+ 'V8.GCFinalizeMC',
+ 'V8.GCFinalizeMCReduceMemory',
+ 'V8.GCIncrementalMarking',
+ 'V8.GCIncrementalMarkingFinalize',
+ 'V8.GCIncrementalMarkingStart',
+ 'V8.GCPhantomHandleProcessingCallback',
+ 'V8.GCScavenger'
+ ) AND (
+ -- This replaces isForcedGarbageCollectionEvent.
+ SELECT name FROM ANCESTOR_SLICE(blink_gc_cpu_slice.id) AS ancestor
+ WHERE ancestor.name == 'V8.GCLowMemoryNotification'
+ LIMIT 1
+ ) IS NULL
+) OR (
+ -- This subclause replaces isNonNestedNonForcedBlinkGarbageCollectionEvent().
+ name IN (
+ -- This subquery replaces isNonForcedBlinkGarbageCollectionEvent().
+ SELECT name FROM blink_top_gc_event
+ ) AND (
+ -- This subquery replaces metrics.v8.utils.isGarbageCollectionEvent().
+ SELECT name FROM ANCESTOR_SLICE(blink_gc_cpu_slice.id) AS ancestor
+ WHERE
+ ancestor.name GLOB "V8.GC*" AND
+ ancestor.name != 'V8.GCLowMemoryNotification'
+ LIMIT 1
+ ) IS NULL
+);
+
+-- This table name is just "file_name" + "_output" used by TBMv3 to know which
+-- view to extract the proto BlinkGcMetric out of.
+DROP VIEW IF EXISTS blink_gc_metric_output;
+CREATE VIEW blink_gc_metric_output AS
+SELECT BlinkGcMetric(
+ 'blink_gc_atomic_pause_mark_epilogue',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM blink_slice
+ WHERE
+ blink_non_aggregated_gc_event_name = 'blink-gc-atomic-pause-mark-epilogue'
+ ),
+ 'blink_gc_main_thread_cycle_full_atomic_mark_epilogue',
+ (
+ SELECT
+ RepeatedField(cpuDurPerEpochMs)
+ FROM blink_per_epoch_slice
+ WHERE
+ blink_non_aggregated_gc_events_new_name =
+ 'blink:gc:main_thread:cycle:full:atomic:mark:epilogue'
+ ),
+ 'blink_gc_atomic_pause_mark_prologue',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM blink_slice
+ WHERE
+ blink_non_aggregated_gc_event_name =
+ 'blink-gc-atomic-pause-mark-prologue'
+ ),
+ 'blink_gc_main_thread_cycle_full_atomic_mark_prologue',
+ (
+ SELECT
+ RepeatedField(cpuDurPerEpochMs)
+ FROM blink_per_epoch_slice
+ WHERE
+ blink_non_aggregated_gc_events_new_name =
+ 'blink:gc:main_thread:cycle:full:atomic:mark:prologue'
+ ),
+ 'blink_gc_atomic_pause_mark_roots',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM blink_slice
+ WHERE
+ blink_non_aggregated_gc_event_name = 'blink-gc-atomic-pause-mark-roots'
+ ),
+ 'blink_gc_main_thread_cycle_full_atomic_mark_roots',
+ (
+ SELECT
+ RepeatedField(cpuDurPerEpochMs)
+ FROM blink_per_epoch_slice
+ WHERE
+ blink_non_aggregated_gc_events_new_name =
+ 'blink:gc:main_thread:cycle:full:atomic:mark:roots'
+ ),
+ 'blink_gc_atomic_pause_sweep_and_compact',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM blink_slice
+ WHERE
+ blink_non_aggregated_gc_event_name =
+ 'blink-gc-atomic-pause-sweep-and-compact'
+ ),
+ 'blink_gc_main_thread_cycle_full_atomic_sweep_compact',
+ (
+ SELECT
+ RepeatedField(cpuDurPerEpochMs)
+ FROM blink_per_epoch_slice
+ WHERE
+ blink_non_aggregated_gc_events_new_name =
+ 'blink:gc:main_thread:cycle:full:atomic:sweep:compact'
+ ),
+ 'blink_gc_complete_sweep',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM blink_slice
+ WHERE blink_non_aggregated_gc_event_name = 'blink-gc-complete-sweep'
+ ),
+ 'blink_gc_main_thread_cycle_full_sweep_complete',
+ (
+ SELECT
+ RepeatedField(cpuDurPerEpochMs)
+ FROM blink_per_epoch_slice
+ WHERE
+ blink_non_aggregated_gc_events_new_name =
+ 'blink:gc:main_thread:cycle:full:sweep:complete'
+ ),
+ 'blink_gc_incremental_start',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM blink_slice
+ WHERE blink_non_aggregated_gc_event_name = 'blink-gc-incremental-start'
+ ),
+ 'blink_gc_main_thread_cycle_full_incremental_mark_start',
+ (
+ SELECT
+ RepeatedField(cpuDurPerEpochMs)
+ FROM blink_per_epoch_slice
+ WHERE
+ blink_non_aggregated_gc_events_new_name =
+ 'blink:gc:main_thread:cycle:full:incremental:mark:start'
+ ),
+ 'blink_gc_incremental_step',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM blink_slice
+ WHERE blink_non_aggregated_gc_event_name = 'blink-gc-incremental-step'
+ ),
+ 'blink_gc_main_thread_cycle_full_incremental_mark_step',
+ (
+ SELECT
+ RepeatedField(cpuDurPerEpochMs)
+ FROM blink_per_epoch_slice
+ WHERE
+ blink_non_aggregated_gc_events_new_name =
+ 'blink:gc:main_thread:cycle:full:incremental:mark:step'
+ ),
+ 'blink_gc_sweep_allocation',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM blink_slice
+ WHERE blink_non_aggregated_gc_event_name = 'blink-gc-sweep-allocation'
+ ),
+ 'blink_gc_main_thread_cycle_full_sweep_on_allocation',
+ (
+ SELECT
+ RepeatedField(cpuDurPerEpochMs)
+ FROM blink_per_epoch_slice
+ WHERE
+ blink_non_aggregated_gc_events_new_name =
+ 'blink:gc:main_thread:cycle:full:sweep:on_allocation'
+ ),
+ 'blink_gc_sweep_task_foreground',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM blink_slice
+ WHERE blink_non_aggregated_gc_event_name = 'blink-gc-sweep-task-foreground'
+ ),
+ 'blink_gc_main_thread_cycle_full_sweep_idle',
+ (
+ SELECT
+ RepeatedField(cpuDurPerEpochMs)
+ FROM blink_per_epoch_slice
+ WHERE
+ blink_non_aggregated_gc_events_new_name =
+ 'blink:gc:main_thread:cycle:full:sweep:idle'
+ ),
+ 'blink_gc_unified_marking_by_v8',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM blink_slice
+ WHERE blink_non_aggregated_gc_event_name = 'blink-gc-unified-marking-by-v8'
+ ),
+ 'unified_gc_main_thread_cycle_full_mark_step',
+ (
+ SELECT
+ RepeatedField(cpuDurPerEpochMs)
+ FROM blink_per_epoch_slice
+ WHERE
+ blink_non_aggregated_gc_events_new_name =
+ 'unified:gc:main_thread:cycle:full:mark:step'
+ ),
+ 'blink_gc_atomic_pause',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM atomic_pause_event
+ ),
+ 'blink_gc_main_thread_cycle_full_atomic',
+ (
+ SELECT RepeatedField(val) FROM (
+ SELECT
+ SUM(cpuDurMs) as val
+ FROM atomic_pause_event
+ GROUP BY epoch
+ )
+ ),
+ 'blink_gc_atomic_pause_mark_transitive_closure',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM blink_gc_atomic_pause_transitive_closure_event
+ ),
+ 'blink_gc_main_thread_cycle_full_atomic_mark_transitive_closure',
+ (
+ SELECT RepeatedField(val) FROM (
+ SELECT
+ SUM(cpuDurMs) as val
+ FROM blink_gc_atomic_pause_transitive_closure_event
+ GROUP BY epoch
+ )
+ ),
+ 'blink_gc_total',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM blink_top_gc_event
+ ),
+ 'blink_gc_main_thread_cycle_full',
+ (
+ SELECT RepeatedField(val) FROM (
+ SELECT
+ SUM(cpuDurMs) as val
+ FROM blink_top_gc_event
+ GROUP BY epoch
+ )
+ ),
+ 'blink_gc_mark_roots',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM blink_top_gc_roots_marking_event
+ ),
+ 'blink_gc_main_thread_cycle_full_mark_roots',
+ (
+ SELECT RepeatedField(val) FROM (
+ SELECT
+ SUM(cpuDurMs) as val
+ FROM blink_top_gc_roots_marking_event
+ GROUP BY epoch
+ )
+ ),
+ 'blink_gc_mark_transitive_closure',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM blink_gc_foreground_marking_transitive_closure_event
+ ),
+ 'blink_gc_main_thread_cycle_full_mark_transitive_closure',
+ (
+ SELECT RepeatedField(val) FROM (
+ SELECT
+ SUM(cpuDurMs) as val
+ FROM blink_gc_foreground_marking_transitive_closure_event
+ GROUP BY epoch
+ )
+ ),
+ 'blink_gc_mark_foreground',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM blink_top_gc_foreground_marking_event
+ ),
+ 'blink_gc_main_thread_cycle_full_mark',
+ (
+ SELECT RepeatedField(val) FROM (
+ SELECT
+ SUM(cpuDurMs) as val
+ FROM blink_top_gc_foreground_marking_event
+ GROUP BY epoch
+ )
+ ),
+ 'blink_gc_mark_foreground_forced',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM blink_gc_forced_foreground_marking_event
+ ),
+ 'blink_gc_main_thread_cycle_full_mark_forced',
+ (
+ SELECT RepeatedField(val) FROM (
+ SELECT
+ SUM(cpuDurMs) as val
+ FROM blink_gc_forced_foreground_marking_event
+ GROUP BY epoch
+ )
+ ),
+ 'blink_gc_mark_background',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM blink_top_gc_background_marking_event
+ ),
+ 'blink_gc_concurrent_thread_cycle_full_mark',
+ (
+ SELECT RepeatedField(val) FROM (
+ SELECT
+ SUM(cpuDurMs) as val
+ FROM blink_top_gc_background_marking_event
+ GROUP BY epoch
+ )
+ ),
+ 'blink_gc_sweep_foreground',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM blink_top_gc_foreground_sweeping_event
+ ),
+ 'blink_gc_main_thread_cycle_full_sweep',
+ (
+ SELECT RepeatedField(val) FROM (
+ SELECT
+ SUM(cpuDurMs) as val
+ FROM blink_top_gc_foreground_sweeping_event
+ GROUP BY epoch
+ )
+ ),
+ 'blink_gc_sweep_background',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM blink_top_gc_background_sweeping_event
+ ),
+ 'blink_gc_concurrent_thread_cycle_full_sweep',
+ (
+ SELECT RepeatedField(val) FROM (
+ SELECT
+ SUM(cpuDurMs) as val
+ FROM blink_top_gc_background_sweeping_event
+ GROUP BY epoch
+ )
+ ),
+ 'unified_gc_total',
+ (
+ SELECT
+ RepeatedField(cpuDurMs)
+ FROM unified_gc_total
+ )
+);
diff --git a/src/trace_processor/metrics/sql/experimental/chrome_dropped_frames.sql b/src/trace_processor/metrics/sql/experimental/chrome_dropped_frames.sql
new file mode 100644
index 000000000..70b83cabe
--- /dev/null
+++ b/src/trace_processor/metrics/sql/experimental/chrome_dropped_frames.sql
@@ -0,0 +1,93 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+-- Find all dropped frames, i.e. all PipelineReporters slices whose
+-- state is 'STATE_DROPPED'.
+DROP VIEW IF EXISTS dropped_pipeline_reporter_slice;
+CREATE VIEW dropped_pipeline_reporter_slice AS
+SELECT slice.* FROM slice
+INNER JOIN args
+ON slice.arg_set_id = args.arg_set_id
+WHERE
+ slice.name = 'PipelineReporter' AND
+ args.string_value = 'STATE_DROPPED';
+
+-- Find the upid of the proccesses where the dropped frames occur.
+DROP VIEW IF EXISTS dropped_frames_with_upid;
+CREATE VIEW dropped_frames_with_upid AS
+SELECT
+ dropped_pipeline_reporter_slice.ts,
+ process_track.upid
+FROM dropped_pipeline_reporter_slice
+INNER JOIN process_track
+ON dropped_pipeline_reporter_slice.track_id = process_track.id;
+
+-- Find the name and pid of the processes.
+DROP VIEW IF EXISTS dropped_frames_with_process_info;
+CREATE VIEW dropped_frames_with_process_info AS
+SELECT
+ dropped_frames_with_upid.ts,
+ process.name AS process_name,
+ process.pid AS process_id
+FROM dropped_frames_with_upid
+INNER JOIN process
+ON dropped_frames_with_upid.upid = process.upid;
+
+-- Create the derived event track for dropped frames.
+-- All tracks generated from chrome_dropped_frames_event are
+-- placed under a track group named 'Dropped Frames', whose summary
+-- track is the first track ('All Processes') in chrome_dropped_frames_event.
+-- Note that the 'All Processes' track is generated only when dropped frames
+-- come from more than one origin process.
+DROP VIEW IF EXISTS chrome_dropped_frames_event;
+CREATE VIEW chrome_dropped_frames_event AS
+SELECT
+ 'slice' AS track_type,
+ 'All Processes' AS track_name,
+ ts,
+ 0 AS dur,
+ 'Dropped Frame' AS slice_name,
+ 'Dropped Frames' AS group_name
+FROM dropped_frames_with_process_info
+WHERE (SELECT COUNT(DISTINCT process_id)
+ FROM dropped_frames_with_process_info) > 1
+GROUP BY ts
+UNION ALL
+SELECT
+ 'slice' AS track_type,
+ process_name || ' ' || process_id AS track_name,
+ ts,
+ 0 AS dur,
+ 'Dropped Frame' AS slice_name,
+ 'Dropped Frames' AS group_name
+FROM dropped_frames_with_process_info
+GROUP BY process_id, ts;
+
+-- Create the dropped frames metric output.
+DROP VIEW IF EXISTS chrome_dropped_frames_output;
+CREATE VIEW chrome_dropped_frames_output AS
+SELECT ChromeDroppedFrames(
+ 'dropped_frame', (
+ SELECT RepeatedField(
+ ChromeDroppedFrames_DroppedFrame(
+ 'ts', ts,
+ 'process_name', process_name,
+ 'pid', process_id
+ )
+ )
+ FROM dropped_frames_with_process_info
+ ORDER BY ts
+ )
+); \ No newline at end of file
diff --git a/src/trace_processor/metrics/sql/experimental/chrome_long_latency.sql b/src/trace_processor/metrics/sql/experimental/chrome_long_latency.sql
new file mode 100644
index 000000000..4d6993bd1
--- /dev/null
+++ b/src/trace_processor/metrics/sql/experimental/chrome_long_latency.sql
@@ -0,0 +1,104 @@
+--
+-- Copyright 2022 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+-- Find all long EventLatency slices > 100ms and also get the
+-- type of the event stored as 'debug.event' argument.
+-- In order to group all events
+-- Note that a long latency event is represented by the the ending time
+-- of an EventLatency slice, i.e. the timestamp of the frame presentation
+-- that reflects the event.
+DROP VIEW IF EXISTS long_eventlatency_slice;
+CREATE VIEW long_eventlatency_slice AS
+SELECT
+ ts + dur AS ts,
+ dur,
+ id,
+ track_id,
+ EXTRACT_ARG(arg_set_id, 'debug.event') AS event_type
+FROM slice WHERE name = 'EventLatency' AND dur > 100000000;
+
+-- Find the upid of the proccesses where the long latency occur.
+DROP VIEW IF EXISTS long_latency_with_upid;
+CREATE VIEW long_latency_with_upid AS
+SELECT
+ long_eventlatency_slice.ts,
+ long_eventlatency_slice.event_type,
+ process_track.upid
+FROM long_eventlatency_slice
+INNER JOIN process_track
+ON long_eventlatency_slice.track_id = process_track.id;
+
+-- Find the name and pid of the processes.
+-- Long latency events with the same timestamp and from the same process
+-- are considered one single long latency occurrence.
+DROP VIEW IF EXISTS long_latency_with_process_info;
+CREATE VIEW long_latency_with_process_info AS
+SELECT
+ long_latency_with_upid.ts,
+ GROUP_CONCAT(DISTINCT long_latency_with_upid.event_type) AS event_type,
+ process.name AS process_name,
+ process.pid AS process_id
+FROM long_latency_with_upid
+INNER JOIN process
+ON long_latency_with_upid.upid = process.upid
+GROUP BY ts, process.pid;
+
+-- Create the derived event track for long latency.
+-- All tracks generated from chrome_long_latency_event are
+-- placed under a track group named 'Long Latency', whose summary
+-- track is the first track ('All Processes') in chrome_long_latency_event.
+-- Note that the 'All Processes' track is generated only when there are more
+-- than one source of long latency events.
+DROP VIEW IF EXISTS chrome_long_latency_event;
+CREATE VIEW chrome_long_latency_event AS
+SELECT
+ 'slice' AS track_type,
+ 'All Processes' AS track_name,
+ ts,
+ 0 AS dur,
+ event_type AS slice_name,
+ 'Long Latency' AS group_name
+FROM long_latency_with_process_info
+WHERE (SELECT COUNT(DISTINCT process_id)
+ FROM long_latency_with_process_info) > 1
+GROUP BY ts
+UNION ALL
+SELECT
+ 'slice' AS track_type,
+ process_name || ' ' || process_id AS track_name,
+ ts,
+ 0 AS dur,
+ event_type AS slice_name,
+ 'Long Latency' AS group_name
+FROM long_latency_with_process_info
+GROUP BY ts;
+
+-- Create the long latency metric output.
+DROP VIEW IF EXISTS chrome_long_latency_output;
+CREATE VIEW chrome_long_latency_output AS
+SELECT ChromeLongLatency(
+ 'long_latency', (
+ SELECT RepeatedField(
+ ChromeLongLatency_LongLatency(
+ 'ts', ts,
+ 'event_type', event_type,
+ 'process_name', process_name,
+ 'pid', process_id
+ )
+ )
+ FROM long_latency_with_process_info
+ ORDER BY ts
+ )
+); \ No newline at end of file
diff --git a/src/trace_processor/metrics/sql/experimental/frame_times.sql b/src/trace_processor/metrics/sql/experimental/frame_times.sql
new file mode 100644
index 000000000..488963f3c
--- /dev/null
+++ b/src/trace_processor/metrics/sql/experimental/frame_times.sql
@@ -0,0 +1,184 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+DROP VIEW IF EXISTS InteractionEvents;
+CREATE VIEW InteractionEvents AS
+SELECT
+ ts, dur, ts AS ts_ir, dur AS dur_ir
+FROM slice WHERE name GLOB 'Interaction.*';
+
+DROP VIEW IF EXISTS GestureLegacyEvents;
+CREATE VIEW GestureLegacyEvents AS
+SELECT
+ ts,
+ EXTRACT_ARG(arg_set_id, 'legacy_event.phase') AS phase
+FROM raw
+WHERE EXTRACT_ARG(arg_set_id, 'legacy_event.name') = 'SyntheticGestureController::running';
+
+-- Convert pairs of 'S' and 'F' events into slices with ts and dur.
+DROP VIEW IF EXISTS GestureEvents;
+CREATE VIEW GestureEvents AS
+SELECT
+ ts, dur, ts AS ts_ge, dur AS dur_ge
+FROM (
+ SELECT
+ ts,
+ phase,
+ LEAD(ts) OVER (ORDER BY ts) - ts as dur
+ FROM GestureLegacyEvents
+)
+WHERE phase = 'S';
+
+DROP TABLE IF EXISTS InteractionEventsJoinGestureEvents;
+CREATE VIRTUAL TABLE InteractionEventsJoinGestureEvents
+USING SPAN_LEFT_JOIN(InteractionEvents, GestureEvents);
+
+--------------------------------------------------------------------------------
+-- Interesting segments are:
+-- 1) If there's a gesture overlapping with interaction, then gesture's range.
+-- 2) Else, interaction's range.
+
+DROP VIEW IF EXISTS InterestingSegments;
+CREATE VIEW InterestingSegments AS
+SELECT -- 1) Gestures overlapping interactions.
+ ts_ge AS ts,
+ dur_ge AS dur
+FROM InteractionEventsJoinGestureEvents
+WHERE ts_ge IS NOT NULL
+GROUP BY ts_ge
+UNION ALL
+SELECT -- 2) Interactions without gestures.
+ ts_ir AS ts,
+ dur_ir AS dur
+FROM InteractionEventsJoinGestureEvents
+WHERE ts_ge IS NULL
+GROUP BY ts_ir
+HAVING COUNT(*) = 1;
+
+--------------------------------------------------------------------------------
+-- On ChromeOS, DRM events, if they exist, are the source of truth. Otherwise,
+-- look for display rendering stats.
+-- On Android, the TBMv2 version relied on Surface Flinger events that are
+-- currently unavailable in proto traces. So results may be different from
+-- the TBMv2 version on this platform.
+
+DROP TABLE IF EXISTS DisplayCompositorPresentationEvents;
+CREATE TABLE DisplayCompositorPresentationEvents AS
+SELECT ts, FALSE AS exp
+FROM slice
+WHERE name = 'DrmEventFlipComplete'
+GROUP BY ts;
+
+INSERT INTO DisplayCompositorPresentationEvents
+SELECT ts, FALSE AS exp
+FROM slice
+WHERE
+ name = 'vsync_before'
+ AND NOT EXISTS (SELECT * FROM DisplayCompositorPresentationEvents)
+GROUP BY ts;
+
+INSERT INTO DisplayCompositorPresentationEvents
+SELECT ts, FALSE AS exp
+FROM slice
+WHERE
+ name = 'BenchmarkInstrumentation::DisplayRenderingStats'
+ AND NOT EXISTS (SELECT * FROM DisplayCompositorPresentationEvents)
+GROUP BY ts;
+
+INSERT INTO DisplayCompositorPresentationEvents
+SELECT ts, TRUE AS exp
+FROM slice
+WHERE name = 'Display::FrameDisplayed'
+GROUP BY ts;
+
+DROP VIEW IF EXISTS FrameSegments;
+CREATE VIEW FrameSegments AS
+SELECT
+ ts,
+ LEAD(ts) OVER wnd - ts as dur,
+ ts as ts_fs,
+ LEAD(ts) OVER wnd - ts as dur_fs,
+ exp
+FROM DisplayCompositorPresentationEvents
+WINDOW wnd AS (PARTITION BY exp ORDER BY ts);
+
+DROP TABLE IF EXISTS FrameSegmentsJoinInterestingSegments;
+CREATE VIRTUAL TABLE FrameSegmentsJoinInterestingSegments USING
+SPAN_JOIN(FrameSegments, InterestingSegments);
+
+DROP VIEW IF EXISTS FrameTimes;
+CREATE VIEW FrameTimes AS
+SELECT dur / 1e6 AS dur_ms, exp
+FROM FrameSegmentsJoinInterestingSegments
+WHERE ts = ts_fs AND dur = dur_fs;
+
+--------------------------------------------------------------------------------
+-- Determine frame rate
+
+DROP VIEW IF EXISTS RefreshPeriodAndroid;
+CREATE VIEW RefreshPeriodAndroid AS
+-- Not implemented yet.
+SELECT NULL AS interval_ms
+;
+
+DROP VIEW IF EXISTS RefreshPeriodNonAndroid;
+CREATE VIEW RefreshPeriodNonAndroid AS
+SELECT EXTRACT_ARG(arg_set_id, 'debug.args.interval_us') / 1e3 AS interval_ms
+FROM slice
+JOIN thread_track ON (slice.track_id = thread_track.id)
+JOIN thread ON (thread_track.utid = thread.utid)
+WHERE thread.name = 'Compositor' AND slice.name = 'Scheduler::BeginFrame'
+LIMIT 1;
+
+DROP VIEW IF EXISTS RefreshPeriodDefault;
+CREATE VIEW RefreshPeriodDefault AS
+SELECT 1000.0 / 60 AS interval_ms;
+
+DROP TABLE IF EXISTS RefreshPeriod;
+CREATE TABLE RefreshPeriod AS
+SELECT COALESCE(
+ (SELECT interval_ms FROM RefreshPeriodAndroid),
+ (SELECT interval_ms FROM RefreshPeriodNonAndroid),
+ (SELECT interval_ms FROM RefreshPeriodDefault)
+) AS interval_ms;
+
+--------------------------------------------------------------------------------
+-- Compute average FPS
+
+DROP VIEW IF EXISTS ValidFrameTimes;
+CREATE VIEW ValidFrameTimes AS
+SELECT
+ dur_ms / (SELECT interval_ms FROM RefreshPeriod) AS length,
+ exp
+FROM FrameTimes
+WHERE dur_ms / (SELECT interval_ms FROM RefreshPeriod) >= 0.5;
+
+DROP VIEW IF EXISTS AvgSurfaceFps;
+CREATE VIEW AvgSurfaceFps AS
+SELECT
+ exp,
+ 1e3 * COUNT(*) / (SELECT SUM(dur_ms) FROM FrameTimes WHERE exp = valid.exp) AS fps
+FROM ValidFrameTimes valid
+GROUP BY exp;
+
+DROP VIEW IF EXISTS frame_times_output;
+CREATE VIEW frame_times_output AS
+SELECT FrameTimes(
+ 'frame_time', (SELECT RepeatedField(dur_ms) FROM FrameTimes WHERE NOT exp),
+ 'exp_frame_time', (SELECT RepeatedField(dur_ms) FROM FrameTimes WHERE exp),
+ 'avg_surface_fps', (SELECT fps FROM AvgSurfaceFps WHERE NOT exp),
+ 'exp_avg_surface_fps', (SELECT fps FROM AvgSurfaceFps WHERE exp)
+);
+
diff --git a/src/trace_processor/metrics/experimental/media_metric.sql b/src/trace_processor/metrics/sql/experimental/media_metric.sql
index eb2351f8a..eb2351f8a 100644
--- a/src/trace_processor/metrics/experimental/media_metric.sql
+++ b/src/trace_processor/metrics/sql/experimental/media_metric.sql
diff --git a/src/trace_processor/metrics/sql/experimental/reported_by_page.sql b/src/trace_processor/metrics/sql/experimental/reported_by_page.sql
new file mode 100644
index 000000000..9936b31d5
--- /dev/null
+++ b/src/trace_processor/metrics/sql/experimental/reported_by_page.sql
@@ -0,0 +1,66 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+--------------------------------------------------------------------------------
+-- Collect page-reported events for each renderer. Note that we don't need to
+-- match up process ids, because the unique nav_id ensures we're only comparing
+-- corresponding events.
+
+DROP VIEW IF EXISTS page_reported_events;
+CREATE VIEW page_reported_events AS
+SELECT ts, name, EXTRACT_ARG(arg_set_id, "debug.data.navigationId") as nav_id
+FROM slice
+WHERE category = 'blink.user_timing' AND
+ (name = 'navigationStart' OR name GLOB 'telemetry:reported_by_page:*')
+ORDER BY nav_id, ts ASC;
+
+--------------------------------------------------------------------------------
+-- Compute the duration from the corresponding navigation start for each
+-- reported event.
+
+DROP VIEW IF EXISTS page_reported_durations;
+CREATE VIEW page_reported_durations AS
+SELECT p.name, (p.ts - (
+ SELECT MAX(ts) FROM page_reported_events
+ WHERE
+ nav_id = p.nav_id AND
+ ts < p.ts AND (
+ -- Viewable/interactive markers measure time from nav start.
+ (p.name GLOB 'telemetry:reported_by_page:*' AND
+ p.name NOT GLOB 'telemetry:reported_by_page:benchmark*' AND
+ name = 'navigationStart') OR
+ -- Benchmark end markers measure time from the most recent begin marker.
+ (p.name = 'telemetry:reported_by_page:benchmark_end' AND
+ name = 'telemetry:reported_by_page:benchmark_begin')
+ ))
+ ) / 1e6 as dur_ms
+FROM page_reported_events p;
+
+--------------------------------------------------------------------------------
+-- Combine results into the output table.
+
+DROP VIEW IF EXISTS reported_by_page_output;
+CREATE VIEW reported_by_page_output AS
+SELECT ReportedByPage(
+ 'time_to_viewable', (
+ SELECT RepeatedField(dur_ms) FROM page_reported_durations
+ WHERE name = 'telemetry:reported_by_page:viewable'),
+ 'time_to_interactive', (
+ SELECT RepeatedField(dur_ms) FROM page_reported_durations
+ WHERE name = 'telemetry:reported_by_page:interactive'),
+ 'benchmark_time', (
+ SELECT RepeatedField(dur_ms) FROM page_reported_durations
+ WHERE name = 'telemetry:reported_by_page:benchmark_end')
+);
diff --git a/src/trace_processor/metrics/sql/trace_metadata.sql b/src/trace_processor/metrics/sql/trace_metadata.sql
new file mode 100644
index 000000000..7a91ed1e0
--- /dev/null
+++ b/src/trace_processor/metrics/sql/trace_metadata.sql
@@ -0,0 +1,61 @@
+--
+-- Copyright 2019 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+-- Expose all clock snapshots as instant events.
+DROP VIEW IF EXISTS trace_metadata_event;
+CREATE VIEW trace_metadata_event AS
+SELECT
+ 'slice' as track_type,
+ 'Clock Snapshots' as track_name,
+ ts,
+ 0 as dur,
+ 'Snapshot' as slice_name
+FROM clock_snapshot
+GROUP BY ts;
+
+DROP VIEW IF EXISTS trace_metadata_output;
+CREATE VIEW trace_metadata_output AS
+SELECT TraceMetadata(
+ 'trace_duration_ns', CAST((SELECT end_ts - start_ts FROM trace_bounds) AS INT),
+ 'trace_uuid', (SELECT str_value FROM metadata WHERE name = 'trace_uuid'),
+ 'android_build_fingerprint', (
+ SELECT str_value FROM metadata WHERE name = 'android_build_fingerprint'
+ ),
+ 'statsd_triggering_subscription_id', (
+ SELECT int_value FROM metadata
+ WHERE name = 'statsd_triggering_subscription_id'
+ ),
+ 'unique_session_name', (
+ SELECT str_value FROM metadata
+ WHERE name = 'unique_session_name'
+ ),
+ 'trace_size_bytes', (
+ SELECT int_value FROM metadata
+ WHERE name = 'trace_size_bytes'
+ ),
+ 'trace_trigger', (
+ SELECT RepeatedField(slice.name)
+ FROM track JOIN slice ON track.id = slice.track_id
+ WHERE track.name = 'Trace Triggers'
+ ),
+ 'trace_config_pbtxt', (
+ SELECT str_value FROM metadata
+ WHERE name = 'trace_config_pbtxt'
+ ),
+ 'sched_duration_ns', (
+ SELECT MAX(ts) - MIN(ts) from sched
+ )
+);
diff --git a/src/trace_processor/metrics/sql/trace_stats.sql b/src/trace_processor/metrics/sql/trace_stats.sql
new file mode 100644
index 000000000..702fc91e3
--- /dev/null
+++ b/src/trace_processor/metrics/sql/trace_stats.sql
@@ -0,0 +1,39 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+DROP VIEW IF EXISTS trace_stats_output;
+CREATE VIEW trace_stats_output AS
+SELECT TraceAnalysisStats(
+ 'stat', (
+ SELECT RepeatedField(TraceAnalysisStats_Stat(
+ 'name', name,
+ 'idx', idx,
+ 'count', value,
+ 'source', CASE source
+ WHEN 'trace' THEN 'SOURCE_TRACE'
+ WHEN 'analysis' THEN 'SOURCE_ANALYSIS'
+ ELSE 'SOURCE_UNKNOWN'
+ END,
+ 'severity', CASE severity
+ WHEN 'info' THEN 'SEVERITY_INFO'
+ WHEN 'data_loss' THEN 'SEVERITY_DATA_LOSS'
+ WHEN 'error' THEN 'SEVERITY_ERROR'
+ ELSE 'SEVERITY_UNKNOWN'
+ END
+ ))
+ FROM stats ORDER BY name ASC
+ )
+);
diff --git a/src/trace_processor/metrics/sql/webview/webview_power_usage.sql b/src/trace_processor/metrics/sql/webview/webview_power_usage.sql
new file mode 100644
index 000000000..29dad5067
--- /dev/null
+++ b/src/trace_processor/metrics/sql/webview/webview_power_usage.sql
@@ -0,0 +1,276 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+-- WebView is embedded in the hosting app's main process, which means it shares some threads
+-- with the host app's work. We approximate WebView-related power usage
+-- by selecting user slices that belong to WebView and estimating their power use
+-- through the CPU time they consume at different core frequencies.
+-- This file populates a summary table that can be used to produce metrics in different formats.
+
+SELECT RUN_METRIC('android/android_proxy_power.sql');
+SELECT RUN_METRIC('android/cpu_info.sql');
+
+DROP TABLE IF EXISTS top_level_slice;
+
+-- Select topmost slices from the 'toplevel' and 'Java' categories.
+-- Filter out Looper events since they are likely to belong to the host app.
+-- Slices are only used to calculate the contribution of the browser process,
+-- renderer contribution will be calculated as the sum of all renderer processes' usage.
+CREATE TABLE top_level_slice AS
+ SELECT *
+ FROM slice WHERE
+ depth = 0 AND
+ ((category GLOB '*toplevel*' OR category = 'Java') AND
+ name NOT GLOB '*looper*');
+
+DROP TABLE IF EXISTS webview_browser_slices;
+
+-- Match top-level slices to threads and hosting apps.
+-- This excludes any renderer slices because renderer processes are counted
+-- as a whole separately.
+-- Slices from Chrome browser processes are also excluded.
+CREATE TABLE webview_browser_slices AS
+ SELECT
+ top_level_slice.ts,
+ top_level_slice.dur,
+ thread_track.utid,
+ process.upid AS upid,
+ extract_arg(process.arg_set_id, 'chrome.host_app_package_name') AS app_name
+ FROM top_level_slice
+ INNER JOIN thread_track
+ ON top_level_slice.track_id = thread_track.id
+ INNER JOIN process
+ ON thread.upid = process.upid
+ INNER JOIN thread
+ ON thread_track.utid = thread.utid
+ WHERE process.name NOT GLOB '*SandboxedProcessService*'
+ AND process.name NOT GLOB '*chrome*'
+ AND app_name IS NOT NULL;
+
+DROP TABLE IF EXISTS webview_browser_slices_power;
+
+-- Assign power usage to WebView browser slices.
+CREATE VIRTUAL TABLE webview_browser_slices_power
+USING SPAN_JOIN(power_per_thread PARTITIONED utid,
+ webview_browser_slices PARTITIONED utid);
+
+DROP TABLE IF EXISTS webview_browser_slices_power_summary;
+
+-- Calculate the power usage of all WebView browser slices for each app
+-- in milliampere-seconds.
+CREATE TABLE webview_browser_slices_power_summary AS
+SELECT
+ app_name,
+ SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
+ FROM webview_browser_slices_power
+ GROUP BY app_name;
+
+DROP TABLE IF EXISTS webview_renderer_threads;
+
+-- All threads of all WebView renderer processes.
+CREATE TABLE webview_renderer_threads AS
+SELECT
+ thread.utid AS utid,
+ extract_arg(process.arg_set_id, 'chrome.host_app_package_name') as app_name
+ FROM process
+ INNER JOIN thread
+ ON thread.upid = process.upid
+ WHERE process.name GLOB '*webview*SandboxedProcessService*'
+ AND app_name IS NOT NULL;
+
+DROP TABLE IF EXISTS webview_renderer_power_summary;
+
+-- Calculate the power usage of all WebView renderer processes for each app
+-- in milliampere-seconds.
+CREATE TABLE webview_renderer_power_summary AS
+ SELECT
+ app_name,
+ SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
+ FROM power_per_thread
+ INNER JOIN webview_renderer_threads
+ ON power_per_thread.utid = webview_renderer_threads.utid
+ GROUP BY app_name;
+
+DROP TABLE IF EXISTS webview_renderer_power_per_core_type;
+
+-- Calculate the power usage of all WebView renderer processes for each app
+-- in milliampere-seconds grouped by core type.
+CREATE TABLE webview_renderer_power_per_core_type AS
+SELECT
+ app_name,
+ core_type_per_cpu.core_type AS core_type,
+ SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
+FROM power_per_thread
+INNER JOIN webview_renderer_threads
+ ON power_per_thread.utid = webview_renderer_threads.utid
+INNER JOIN core_type_per_cpu
+ ON power_per_thread.cpu = core_type_per_cpu.cpu
+GROUP BY app_name, core_type_per_cpu.core_type;
+
+DROP TABLE IF EXISTS host_app_threads;
+
+-- All threads of hosting apps (this is a superset of webview_browser_slices).
+-- 1) select all threads that had any WebView browser slices associated with them;
+-- 2) get all threads for processes matching threads from 1).
+-- For example, only some of app's threads wrote any slices, but we are selecting
+-- all threads for this app's process.
+-- Excludes all renderer processes and Chrome browser processes.
+CREATE TABLE host_app_threads AS
+SELECT
+ thread.utid AS utid,
+ thread.name AS name,
+ extract_arg(process.arg_set_id, 'chrome.host_app_package_name') as app_name
+ FROM thread
+ JOIN process ON thread.upid = process.upid
+ WHERE thread.upid IN
+ (SELECT DISTINCT(webview_browser_slices.upid) FROM webview_browser_slices)
+ AND process.name NOT GLOB '*SandboxedProcessService*'
+ AND process.name NOT GLOB '*chrome*'
+ AND app_name IS NOT NULL;
+
+DROP TABLE IF EXISTS host_app_power_summary;
+
+-- Calculate the power usage of all WebView (host app+browser) processes for each app
+-- in milliampere-seconds.
+CREATE TABLE host_app_power_summary AS
+ SELECT
+ app_name,
+ SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
+ FROM power_per_thread
+ INNER JOIN host_app_threads
+ ON power_per_thread.utid = host_app_threads.utid
+ GROUP BY app_name;
+
+DROP TABLE IF EXISTS host_app_power_per_core_type;
+
+-- Calculate the power usage of all WebView (host app+browser) processes for each app
+-- in milliampere-seconds grouped by core type.
+CREATE TABLE host_app_power_per_core_type AS
+SELECT
+ app_name,
+ core_type_per_cpu.core_type AS core_type,
+ SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
+FROM power_per_thread
+INNER JOIN host_app_threads
+ ON power_per_thread.utid = host_app_threads.utid
+INNER JOIN core_type_per_cpu
+ ON power_per_thread.cpu = core_type_per_cpu.cpu
+GROUP BY app_name, core_type_per_cpu.core_type;
+
+DROP TABLE IF EXISTS webview_only_threads;
+
+-- A subset of the host app threads that are WebView-specific.
+CREATE TABLE webview_only_threads AS
+SELECT *
+FROM host_app_threads
+ WHERE name GLOB 'Chrome*' OR name GLOB 'CookieMonster*'
+ OR name GLOB 'CompositorTileWorker*' OR name GLOB 'ThreadPool*ground*'
+ OR NAME GLOB 'ThreadPoolService*' OR name GLOB 'VizCompositorThread*'
+ OR name IN ('AudioThread', 'DedicatedWorker thread', 'GpuMemoryThread',
+ 'JavaBridge', 'LevelDBEnv.IDB', 'MemoryInfra', 'NetworkService', 'VizWebView');
+
+DROP TABLE IF EXISTS webview_only_power_summary;
+
+-- Calculate the power usage of all WebView-specific host app threads
+-- (browser + in-process renderers) for each app in milliampere-seconds.
+CREATE TABLE webview_only_power_summary AS
+ SELECT
+ app_name,
+ SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
+ FROM power_per_thread
+ INNER JOIN webview_only_threads
+ ON power_per_thread.utid = webview_only_threads.utid
+ GROUP BY app_name;
+
+DROP TABLE IF EXISTS webview_only_power_per_core_type;
+
+-- Calculate the power usage of all WebView-specific host app threads
+-- for each app in milliampere-seconds grouped by core type.
+CREATE TABLE webview_only_power_per_core_type AS
+ SELECT app_name,
+ core_type_per_cpu.core_type AS core_type,
+ SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
+FROM power_per_thread
+INNER JOIN webview_only_threads
+ ON power_per_thread.utid = webview_only_threads.utid
+INNER JOIN core_type_per_cpu
+ ON power_per_thread.cpu = core_type_per_cpu.cpu
+GROUP BY app_name, core_type_per_cpu.core_type;
+
+-- Create views for output.
+
+DROP TABLE IF EXISTS total_app_power_output;
+
+CREATE TABLE total_app_power_output AS
+ SELECT
+ host_app_power_summary.app_name as app_name,
+ host_app_power_summary.power_mas AS total_mas,
+ host_app_power_little_cores_mas.power_mas AS little_cores_mas,
+ host_app_power_big_cores_mas.power_mas AS big_cores_mas,
+ host_app_power_bigger_cores_mas.power_mas AS bigger_cores_mas
+ FROM host_app_power_summary LEFT JOIN host_app_power_per_core_type AS host_app_power_little_cores_mas
+ ON host_app_power_summary.app_name = host_app_power_little_cores_mas.app_name
+ AND host_app_power_little_cores_mas.core_type = 'little'
+ LEFT JOIN host_app_power_per_core_type AS host_app_power_big_cores_mas
+ ON host_app_power_summary.app_name = host_app_power_big_cores_mas.app_name
+ AND host_app_power_big_cores_mas.core_type = 'big'
+ LEFT JOIN host_app_power_per_core_type AS host_app_power_bigger_cores_mas
+ ON host_app_power_summary.app_name = host_app_power_bigger_cores_mas.app_name
+ AND host_app_power_bigger_cores_mas.core_type = 'bigger';
+
+DROP TABLE IF EXISTS webview_renderer_power_output;
+
+CREATE TABLE webview_renderer_power_output AS
+ SELECT
+ webview_renderer_power_summary.app_name AS app_name,
+ webview_renderer_power_summary.power_mas AS total_mas,
+ webview_renderer_little_power.power_mas AS little_cores_mas,
+ webview_renderer_big_power.power_mas AS big_cores_mas,
+ webview_renderer_bigger_power.power_mas AS bigger_cores_mas
+ FROM webview_renderer_power_summary LEFT JOIN webview_renderer_power_per_core_type AS webview_renderer_little_power
+ ON webview_renderer_power_summary.app_name = webview_renderer_little_power.app_name
+ AND webview_renderer_little_power.core_type = 'little'
+ LEFT JOIN webview_renderer_power_per_core_type AS webview_renderer_big_power
+ ON webview_renderer_power_summary.app_name = webview_renderer_big_power.app_name
+ AND webview_renderer_big_power.core_type = 'big'
+ LEFT JOIN webview_renderer_power_per_core_type AS webview_renderer_bigger_power
+ ON webview_renderer_power_summary.app_name = webview_renderer_bigger_power.app_name
+ AND webview_renderer_bigger_power.core_type = 'bigger';
+
+DROP TABLE IF EXISTS webview_only_power_output;
+
+CREATE TABLE webview_only_power_output AS
+ SELECT
+ webview_only_power_summary.app_name AS app_name,
+ webview_only_power_summary.power_mas AS total_mas,
+ webview_only_power_little_cores_mas.power_mas AS little_cores_mas,
+ webview_only_power_big_cores_mas.power_mas AS big_cores_mas,
+ webview_only_power_bigger_cores_mas.power_mas AS bigger_cores_mas
+ FROM webview_only_power_summary LEFT JOIN webview_only_power_per_core_type AS webview_only_power_little_cores_mas
+ ON webview_only_power_summary.app_name = webview_only_power_little_cores_mas.app_name
+ AND webview_only_power_little_cores_mas.core_type = 'little'
+ LEFT JOIN webview_only_power_per_core_type AS webview_only_power_big_cores_mas
+ ON webview_only_power_summary.app_name = webview_only_power_big_cores_mas.app_name
+ AND webview_only_power_big_cores_mas.core_type = 'big'
+ LEFT JOIN webview_only_power_per_core_type AS webview_only_power_bigger_cores_mas
+ ON webview_only_power_summary.app_name = webview_only_power_bigger_cores_mas.app_name
+ AND webview_only_power_bigger_cores_mas.core_type = 'bigger';
+
+DROP TABLE IF EXISTS total_device_power;
+
+-- Calculate the power usage of the device in milliampere-seconds.
+CREATE TABLE total_device_power AS
+ SELECT SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
+ FROM power_per_thread;
diff --git a/src/trace_processor/metrics/trace_metadata.sql b/src/trace_processor/metrics/trace_metadata.sql
deleted file mode 100644
index 838116b12..000000000
--- a/src/trace_processor/metrics/trace_metadata.sql
+++ /dev/null
@@ -1,49 +0,0 @@
---
--- Copyright 2019 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
-DROP VIEW IF EXISTS trace_metadata_output;
-CREATE VIEW trace_metadata_output AS
-SELECT TraceMetadata(
- 'trace_duration_ns', CAST((SELECT end_ts - start_ts FROM trace_bounds) AS INT),
- 'trace_uuid', (SELECT str_value FROM metadata WHERE name = 'trace_uuid'),
- 'android_build_fingerprint', (
- SELECT str_value FROM metadata WHERE name = 'android_build_fingerprint'
- ),
- 'statsd_triggering_subscription_id', (
- SELECT int_value FROM metadata
- WHERE name = 'statsd_triggering_subscription_id'
- ),
- 'unique_session_name', (
- SELECT str_value FROM metadata
- WHERE name = 'unique_session_name'
- ),
- 'trace_size_bytes', (
- SELECT int_value FROM metadata
- WHERE name = 'trace_size_bytes'
- ),
- 'trace_trigger', (
- SELECT RepeatedField(slice.name)
- FROM track JOIN slice ON track.id = slice.track_id
- WHERE track.name = 'Trace Triggers'
- ),
- 'trace_config_pbtxt', (
- SELECT str_value FROM metadata
- WHERE name = 'trace_config_pbtxt'
- ),
- 'sched_duration_ns', (
- SELECT MAX(ts) - MIN(ts) from sched
- )
-);
diff --git a/src/trace_processor/metrics/trace_stats.sql b/src/trace_processor/metrics/trace_stats.sql
deleted file mode 100644
index f64744232..000000000
--- a/src/trace_processor/metrics/trace_stats.sql
+++ /dev/null
@@ -1,39 +0,0 @@
---
--- Copyright 2021 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
-DROP VIEW IF EXISTS trace_stats_output;
-CREATE VIEW trace_stats_output AS
-SELECT TraceAnalysisStats(
- 'stat', (
- SELECT RepeatedField(TraceAnalysisStats_Stat(
- 'name', name,
- 'idx', idx,
- 'count', value,
- -- TraceAnalysisStats.Source enum:
- 'source', CASE source
- WHEN 'trace' THEN 1
- WHEN 'analysis' THEN 2
- END,
- -- TraceAnalysisStats.Severity enum:
- 'severity', CASE severity
- WHEN 'info' THEN 1
- WHEN 'data_loss' THEN 2
- WHEN 'error' THEN 3
- END
- ))
- FROM stats ORDER BY name ASC
- )
-);
diff --git a/src/trace_processor/metrics/webview/webview_power_usage.sql b/src/trace_processor/metrics/webview/webview_power_usage.sql
deleted file mode 100644
index 7ac8efcbf..000000000
--- a/src/trace_processor/metrics/webview/webview_power_usage.sql
+++ /dev/null
@@ -1,278 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
-
--- WebView is embedded in the hosting app's main process, which means it shares some threads
--- with the host app's work. We approximate WebView-related power usage
--- by selecting user slices that belong to WebView and estimating their power use
--- through the CPU time they consume at different core frequencies.
--- This file populates a summary table that can be used to produce metrics in different formats.
-
-SELECT RUN_METRIC('android/android_proxy_power.sql');
-SELECT RUN_METRIC('android/cpu_info.sql');
-
-DROP VIEW IF EXISTS top_level_slice;
-
--- Select topmost slices from the 'toplevel' and 'Java' categories.
--- Filter out Looper events since they are likely to belong to the host app.
--- Slices are only used to calculate the contribution of the browser process,
--- renderer contribution will be calculated as the sum of all renderer processes' usage.
-CREATE VIEW top_level_slice AS
- SELECT *
- FROM slice WHERE
- depth = 0 AND
- ((category like '%toplevel%' OR category = 'Java') AND
- name NOT LIKE '%looper%');
-
-DROP VIEW IF EXISTS webview_browser_slices;
-
--- Match top-level slices to threads and hosting apps.
--- This excludes any renderer slices because renderer processes are counted
--- as a whole separately.
--- Slices from Chrome browser processes are also excluded.
-CREATE VIEW webview_browser_slices AS
- SELECT
- top_level_slice.ts,
- top_level_slice.dur,
- thread_track.utid,
- process.upid AS upid,
- extract_arg(process.arg_set_id, 'chrome.host_app_package_name') AS app_name
- FROM top_level_slice
- INNER JOIN thread_track
- ON top_level_slice.track_id = thread_track.id
- INNER JOIN process
- ON thread.upid = process.upid
- INNER JOIN thread
- ON thread_track.utid = thread.utid
- WHERE process.name NOT LIKE '%SandboxedProcessService%'
- AND process.name NOT LIKE '%chrome%'
- AND app_name IS NOT NULL;
-
-DROP TABLE IF EXISTS webview_browser_slices_power;
-
--- Assign power usage to WebView browser slices.
-CREATE VIRTUAL TABLE webview_browser_slices_power
-USING SPAN_JOIN(power_per_thread PARTITIONED utid,
- webview_browser_slices PARTITIONED utid);
-
-DROP VIEW IF EXISTS webview_browser_slices_power_summary;
-
--- Calculate the power usage of all WebView browser slices for each app
--- in milliampere-seconds.
-CREATE VIEW webview_browser_slices_power_summary AS
-SELECT
- app_name,
- SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
- FROM webview_browser_slices_power
- GROUP BY app_name;
-
-DROP VIEW IF EXISTS webview_renderer_threads;
-
--- All threads of all WebView renderer processes.
-CREATE VIEW webview_renderer_threads AS
-SELECT
- thread.utid AS utid,
- extract_arg(process.arg_set_id, 'chrome.host_app_package_name') as app_name
- FROM process
- INNER JOIN thread
- ON thread.upid = process.upid
- WHERE process.name LIKE '%webview%SandboxedProcessService%'
- AND app_name IS NOT NULL;
-
-DROP VIEW IF EXISTS webview_renderer_power_summary;
-
--- Calculate the power usage of all WebView renderer processes for each app
--- in milliampere-seconds.
-CREATE VIEW webview_renderer_power_summary AS
- SELECT
- app_name,
- SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
- FROM power_per_thread
- INNER JOIN webview_renderer_threads
- ON power_per_thread.utid = webview_renderer_threads.utid
- GROUP BY app_name;
-
-DROP VIEW IF EXISTS webview_renderer_power_per_core_type;
-
--- Calculate the power usage of all WebView renderer processes for each app
--- in milliampere-seconds grouped by core type.
-CREATE VIEW webview_renderer_power_per_core_type AS
-SELECT
- app_name,
- core_type_per_cpu.core_type AS core_type,
- SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
-FROM power_per_thread
-INNER JOIN webview_renderer_threads
- ON power_per_thread.utid = webview_renderer_threads.utid
-INNER JOIN core_type_per_cpu
- ON power_per_thread.cpu = core_type_per_cpu.cpu
-GROUP BY app_name, core_type_per_cpu.core_type;
-
-DROP VIEW IF EXISTS host_app_threads;
-
--- All threads of hosting apps (this is a superset of webview_browser_slices).
--- 1) select all threads that had any WebView browser slices associated with them;
--- 2) get all threads for processes matching threads from 1).
--- For example, only some of app's threads wrote any slices, but we are selecting
--- all threads for this app's process.
--- Excludes all renderer processes and Chrome browser processes.
-CREATE VIEW host_app_threads AS
-SELECT
- thread.utid AS utid,
- thread.name AS name,
- extract_arg(process.arg_set_id, 'chrome.host_app_package_name') as app_name
- FROM thread
- JOIN process ON thread.upid = process.upid
- WHERE thread.upid IN
- (SELECT DISTINCT(webview_browser_slices.upid) FROM webview_browser_slices)
- AND process.name NOT LIKE '%SandboxedProcessService%'
- AND process.name NOT LIKE '%chrome%'
- AND app_name IS NOT NULL;
-
-DROP VIEW IF EXISTS host_app_power_summary;
-
--- Calculate the power usage of all WebView (host app+browser) processes for each app
--- in milliampere-seconds.
-CREATE VIEW host_app_power_summary AS
- SELECT
- app_name,
- SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
- FROM power_per_thread
- INNER JOIN host_app_threads
- ON power_per_thread.utid = host_app_threads.utid
- GROUP BY app_name;
-
-DROP VIEW IF EXISTS host_app_power_per_core_type;
-
--- Calculate the power usage of all WebView (host app+browser) processes for each app
--- in milliampere-seconds grouped by core type.
-CREATE VIEW host_app_power_per_core_type AS
-SELECT
- app_name,
- core_type_per_cpu.core_type AS core_type,
- SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
-FROM power_per_thread
-INNER JOIN host_app_threads
- ON power_per_thread.utid = host_app_threads.utid
-INNER JOIN core_type_per_cpu
- ON power_per_thread.cpu = core_type_per_cpu.cpu
-GROUP BY app_name, core_type_per_cpu.core_type;
-
-DROP VIEW IF EXISTS webview_only_threads;
-
--- A subset of the host app threads that are WebView-specific.
-CREATE VIEW webview_only_threads AS
-SELECT *
-FROM host_app_threads
- WHERE name LIKE 'Chrome%' OR name LIKE 'CookieMonster%'
- OR name LIKE 'CompositorTileWorker%' OR name LIKE 'ThreadPool%ground%'
- OR NAME LIKE 'ThreadPoolService%' OR name like 'VizCompositorThread%'
- OR name IN ('AudioThread', 'DedicatedWorker thread', 'GpuMemoryThread',
- 'JavaBridge', 'LevelDBEnv.IDB', 'MemoryInfra', 'NetworkService', 'VizWebView');
-
-DROP VIEW IF EXISTS webview_only_power_summary;
-
--- Calculate the power usage of all WebView-specific host app threads
--- (browser + in-process renderers) for each app in milliampere-seconds.
-CREATE VIEW webview_only_power_summary AS
- SELECT
- app_name,
- SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
- FROM power_per_thread
- INNER JOIN webview_only_threads
- ON power_per_thread.utid = webview_only_threads.utid
- GROUP BY app_name;
-
-DROP VIEW IF EXISTS webview_only_power_per_core_type;
-
--- Calculate the power usage of all WebView-specific host app threads
--- for each app in milliampere-seconds grouped by core type.
-CREATE VIEW webview_only_power_per_core_type AS
- SELECT app_name,
- core_type_per_cpu.core_type AS core_type,
- SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
-FROM power_per_thread
-INNER JOIN webview_only_threads
- ON power_per_thread.utid = webview_only_threads.utid
-INNER JOIN core_type_per_cpu
- ON power_per_thread.cpu = core_type_per_cpu.cpu
-GROUP BY app_name, core_type_per_cpu.core_type;
-
--- Create views for output.
-
-DROP VIEW IF EXISTS total_app_power_output;
-
-CREATE VIEW total_app_power_output AS
- SELECT
- host_app_power_summary.app_name as app_name,
- host_app_power_summary.power_mas AS total_mas,
- host_app_power_little_cores_mas.power_mas AS little_cores_mas,
- host_app_power_big_cores_mas.power_mas AS big_cores_mas,
- host_app_power_bigger_cores_mas.power_mas AS bigger_cores_mas
- FROM host_app_power_summary LEFT JOIN host_app_power_per_core_type AS host_app_power_little_cores_mas
- ON host_app_power_summary.app_name = host_app_power_little_cores_mas.app_name
- AND host_app_power_little_cores_mas.core_type = 'little'
- LEFT JOIN host_app_power_per_core_type AS host_app_power_big_cores_mas
- ON host_app_power_summary.app_name = host_app_power_big_cores_mas.app_name
- AND host_app_power_big_cores_mas.core_type = 'big'
- LEFT JOIN host_app_power_per_core_type AS host_app_power_bigger_cores_mas
- ON host_app_power_summary.app_name = host_app_power_bigger_cores_mas.app_name
- AND host_app_power_bigger_cores_mas.core_type = 'bigger';
-
-DROP VIEW IF EXISTS webview_renderer_power_output;
-
-CREATE VIEW webview_renderer_power_output AS
- SELECT
- webview_renderer_power_summary.app_name AS app_name,
- webview_renderer_power_summary.power_mas AS total_mas,
- webview_renderer_little_power.power_mas AS little_cores_mas,
- webview_renderer_big_power.power_mas AS big_cores_mas,
- webview_renderer_bigger_power.power_mas AS bigger_cores_mas
- FROM webview_renderer_power_summary LEFT JOIN webview_renderer_power_per_core_type AS webview_renderer_little_power
- ON webview_renderer_power_summary.app_name = webview_renderer_little_power.app_name
- AND webview_renderer_little_power.core_type = 'little'
- LEFT JOIN webview_renderer_power_per_core_type AS webview_renderer_big_power
- ON webview_renderer_power_summary.app_name = webview_renderer_big_power.app_name
- AND webview_renderer_big_power.core_type = 'big'
- LEFT JOIN webview_renderer_power_per_core_type AS webview_renderer_bigger_power
- ON webview_renderer_power_summary.app_name = webview_renderer_bigger_power.app_name
- AND webview_renderer_bigger_power.core_type = 'bigger';
-
-DROP VIEW IF EXISTS webview_only_power_output;
-
-CREATE VIEW webview_only_power_output AS
- SELECT
- webview_only_power_summary.app_name AS app_name,
- webview_only_power_summary.power_mas AS total_mas,
- webview_only_power_little_cores_mas.power_mas AS little_cores_mas,
- webview_only_power_big_cores_mas.power_mas AS big_cores_mas,
- webview_only_power_bigger_cores_mas.power_mas AS bigger_cores_mas
- FROM webview_only_power_summary LEFT JOIN webview_only_power_per_core_type AS webview_only_power_little_cores_mas
- ON webview_only_power_summary.app_name = webview_only_power_little_cores_mas.app_name
- AND webview_only_power_little_cores_mas.core_type = 'little'
- LEFT JOIN webview_only_power_per_core_type AS webview_only_power_big_cores_mas
- ON webview_only_power_summary.app_name = webview_only_power_big_cores_mas.app_name
- AND webview_only_power_big_cores_mas.core_type = 'big'
- LEFT JOIN webview_only_power_per_core_type AS webview_only_power_bigger_cores_mas
- ON webview_only_power_summary.app_name = webview_only_power_bigger_cores_mas.app_name
- AND webview_only_power_bigger_cores_mas.core_type = 'bigger';
-
-DROP VIEW IF EXISTS total_device_power;
-
--- Calculate the power usage of the device in milliampere-seconds.
-CREATE VIEW total_device_power AS
- SELECT SUM(dur * COALESCE(power_ma, 0) / 1e9) AS power_mas
- FROM power_per_thread;
-
-DROP VIEW IF EXISTS webview_power_summary;
diff --git a/src/trace_processor/python/example.py b/src/trace_processor/python/example.py
deleted file mode 100644
index b3925a4ff..000000000
--- a/src/trace_processor/python/example.py
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (C) 2020 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import argparse
-
-from perfetto.trace_processor import TraceProcessor
-
-
-def main():
- # Parse arguments passed from command line
- parser = argparse.ArgumentParser()
- parser.add_argument(
- "-a",
- "--address",
- help="Address at which trace_processor is being run, e.g. localhost:9001",
- type=str)
- parser.add_argument(
- "-b",
- "--binary",
- help="Absolute path to a trace processor binary",
- type=str)
- parser.add_argument("-f", "--file", help="Absolute path to trace", type=str)
- args = parser.parse_args()
-
- # Pass arguments into api to construct the trace processor and load the trace
- if args.address is None and args.file is None:
- raise Exception("You must specify an address or a file path to trace")
- elif args.address is None:
- tp = TraceProcessor(file_path=args.file, bin_path=args.binary)
- elif args.file is None:
- tp = TraceProcessor(addr=args.address)
- else:
- tp = TraceProcessor(
- addr=args.address, file_path=args.file, bin_path=args.binary)
-
- # Iterate through QueryResultIterator
- res_it = tp.query('select * from slice limit 10')
- for row in res_it:
- print(row.name)
-
- # Convert QueryResultIterator into a pandas dataframe + iterate. This yields
- # the same results as the function above.
- try:
- res_df = tp.query('select * from slice limit 10').as_pandas_dataframe()
- for index, row in res_df.iterrows():
- print(row['name'])
- except Exception:
- pass
-
- # Call another function on the loaded trace
- am_metrics = tp.metric(['android_mem'])
- tp.close()
-
-
-if __name__ == "__main__":
- main()
diff --git a/src/trace_processor/python/perfetto/trace_processor/__init__.py b/src/trace_processor/python/perfetto/trace_processor/__init__.py
deleted file mode 100644
index fbbffcd57..000000000
--- a/src/trace_processor/python/perfetto/trace_processor/__init__.py
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (C) 2020 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from .api import TraceProcessor
-from .http import TraceProcessorHttp \ No newline at end of file
diff --git a/src/trace_processor/python/perfetto/trace_processor/api.py b/src/trace_processor/python/perfetto/trace_processor/api.py
deleted file mode 100644
index 9cabf07df..000000000
--- a/src/trace_processor/python/perfetto/trace_processor/api.py
+++ /dev/null
@@ -1,245 +0,0 @@
-# Copyright (C) 2020 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from urllib.parse import urlparse
-
-from .http import TraceProcessorHttp
-from .loader import get_loader
-from .protos import ProtoFactory
-from .shell import load_shell
-
-
-# Custom exception raised if any trace_processor functions return a
-# response with an error defined
-class TraceProcessorException(Exception):
-
- def __init__(self, message):
- super().__init__(message)
-
-
-class TraceProcessor:
-
- # Values of these constants correspond to the QueryResponse message at
- # protos/perfetto/trace_processor/trace_processor.proto
- # Value 0 corresponds to CELL_INVALID, which is represented as None in
- # this class
- QUERY_CELL_NULL_FIELD_ID = 1
- QUERY_CELL_VARINT_FIELD_ID = 2
- QUERY_CELL_FLOAT64_FIELD_ID = 3
- QUERY_CELL_STRING_FIELD_ID = 4
- QUERY_CELL_BLOB_FIELD_ID = 5
-
- # This is the class returned to the user and contains one row of the
- # resultant query. Each column name is stored as an attribute of this
- # class, with the value corresponding to the column name and row in
- # the query results table.
- class Row(object):
-
- def __str__(self):
- return str(self.__dict__)
-
- def __repr__(self):
- return self.__dict__
-
- class QueryResultIterator:
-
- def __init__(self, column_names, batches):
- self.__batches = batches
- self.__column_names = column_names
- self.__batch_index = 0
- self.__next_index = 0
- # TODO(lalitm): Look into changing string_cells to bytes in the protobuf
- self.__string_cells = memoryview(bytes(batches[0].string_cells, 'utf-8'))
- self.__string_index = 0
-
- def get_cell_list(self, proto_index):
- if proto_index == TraceProcessor.QUERY_CELL_NULL_FIELD_ID:
- return None
- elif proto_index == TraceProcessor.QUERY_CELL_VARINT_FIELD_ID:
- return self.__batches[self.__batch_index].varint_cells
- elif proto_index == TraceProcessor.QUERY_CELL_FLOAT64_FIELD_ID:
- return self.__batches[self.__batch_index].float64_cells
- elif proto_index == TraceProcessor.QUERY_CELL_BLOB_FIELD_ID:
- return self.__batches[self.__batch_index].blob_cells
- else:
- raise TraceProcessorException('Invalid cell type')
-
- def cells(self):
- return self.__batches[self.__batch_index].cells
-
- # To use the query result as a populated Pandas dataframe, this
- # function must be called directly after calling query inside
- # TraceProcesor.
- def as_pandas_dataframe(self):
- try:
- import numpy as np
- import pandas as pd
-
- df = pd.DataFrame(columns=self.__column_names)
-
- # Populate the dataframe with the query results
- while True:
- # If all cells are read, then check if last batch before
- # returning the populated dataframe
- if self.__next_index >= len(self.__batches[self.__batch_index].cells):
- if self.__batches[self.__batch_index].is_last_batch:
- ordered_df = df.reset_index(drop=True)
- return ordered_df
- self.__batch_index += 1
- self.__next_index = 0
- self.__string_cells = memoryview(
- bytes(self.__batches[self.__batch_index].string_cells, 'utf-8'))
- self.__string_index = 0
-
- row = []
- for num, column_name in enumerate(self.__column_names):
- cell_type = self.__batches[self.__batch_index].cells[
- self.__next_index + num]
- if cell_type == TraceProcessor.QUERY_CELL_STRING_FIELD_ID:
- start_index = self.__string_index
- while self.__string_cells[self.__string_index] != 0:
- self.__string_index += 1
- row.append(
- str(self.__string_cells[start_index:self.__string_index],
- 'utf-8'))
- self.__string_index += 1
- else:
- cell_list = self.get_cell_list(cell_type)
- if cell_list is None:
- row.append(np.NAN)
- else:
- row.append(cell_list.pop(0))
- df.loc[-1] = row
- df.index = df.index + 1
- self.__next_index = self.__next_index + len(self.__column_names)
-
- except ModuleNotFoundError:
- raise TraceProcessorException(
- 'The sufficient libraries are not installed')
-
- def __iter__(self):
- return self
-
- def __next__(self):
- # If all cells are read, then check if last batch before raising
- # StopIteration
- if self.__next_index >= len(self.cells()):
- if self.__batches[self.__batch_index].is_last_batch:
- raise StopIteration
- self.__batch_index += 1
- self.__next_index = 0
- self.__string_cells = memoryview(
- bytes(self.__batches[self.__batch_index].string_cells, 'utf-8'))
- self.__string_index = 0
-
- row = TraceProcessor.Row()
- for num, column_name in enumerate(self.__column_names):
- cell_type = self.__batches[self.__batch_index].cells[self.__next_index +
- num]
- if cell_type == TraceProcessor.QUERY_CELL_STRING_FIELD_ID:
- start_index = self.__string_index
- while self.__string_cells[self.__string_index] != 0:
- self.__string_index += 1
- setattr(
- row, column_name,
- str(self.__string_cells[start_index:self.__string_index],
- 'utf-8'))
- self.__string_index += 1
- else:
- cell_list = self.get_cell_list(cell_type)
- if cell_list is None:
- setattr(row, column_name, None)
- else:
- setattr(row, column_name, cell_list.pop(0))
- self.__next_index = self.__next_index + len(self.__column_names)
- return row
-
- def __init__(self, addr=None, file_path=None, bin_path=None,
- unique_port=True):
- # Load trace_processor_shell or access via given address
- if addr:
- p = urlparse(addr)
- tp = TraceProcessorHttp(p.netloc if p.netloc else p.path)
- else:
- url, self.subprocess = load_shell(
- bin_path=bin_path, unique_port=unique_port)
- tp = TraceProcessorHttp(url)
- self.http = tp
- self.protos = ProtoFactory()
-
- # Parse trace by its file_path into the loaded instance of trace_processor
- if file_path:
- get_loader().parse_file(self.http, file_path)
-
- def query(self, sql):
- """Executes passed in SQL query using class defined HTTP API, and returns
- the response as a QueryResultIterator. Raises TraceProcessorException if
- the response returns with an error.
-
- Args:
- sql: SQL query written as a String
-
- Returns:
- A class which can iterate through each row of the results table. This
- can also be converted to a pandas dataframe by calling the
- as_pandas_dataframe() function after calling query.
- """
- response = self.http.execute_query(sql)
- if response.error:
- raise TraceProcessorException(response.error)
-
- return TraceProcessor.QueryResultIterator(response.column_names,
- response.batch)
-
- def metric(self, metrics):
- """Returns the metrics data corresponding to the passed in trace metric.
- Raises TraceProcessorException if the response returns with an error.
-
- Args:
- metrics: A list of valid metrics as defined in TraceMetrics
-
- Returns:
- The metrics data as a proto message
- """
- response = self.http.compute_metric(metrics)
- if response.error:
- raise TraceProcessorException(response.error)
-
- metrics = self.protos.TraceMetrics()
- metrics.ParseFromString(response.metrics)
- return metrics
-
- def enable_metatrace(self):
- """Enable metatrace for the currently running trace_processor.
- """
- return self.http.enable_metatrace()
-
- def disable_and_read_metatrace(self):
- """Disable and return the metatrace formed from the currently running
- trace_processor. This must be enabled before attempting to disable. This
- returns the serialized bytes of the metatrace data directly. Raises
- TraceProcessorException if the response returns with an error.
- """
- response = self.http.disable_and_read_metatrace()
- if response.error:
- raise TraceProcessorException(response.error)
-
- return response.metatrace
-
- # TODO(@aninditaghosh): Investigate context managers for
- # cleaner usage
- def close(self):
- if hasattr(self, 'subprocess'):
- self.subprocess.kill()
- self.http.conn.close()
diff --git a/src/trace_processor/python/perfetto/trace_processor/http.py b/src/trace_processor/python/perfetto/trace_processor/http.py
deleted file mode 100644
index bf751f984..000000000
--- a/src/trace_processor/python/perfetto/trace_processor/http.py
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (C) 2020 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import http.client
-
-from .protos import ProtoFactory
-
-
-class TraceProcessorHttp:
-
- def __init__(self, url):
- self.protos = ProtoFactory()
- self.conn = http.client.HTTPConnection(url)
-
- def execute_query(self, query):
- args = self.protos.RawQueryArgs()
- args.sql_query = query
- byte_data = args.SerializeToString()
- self.conn.request('POST', '/query', body=byte_data)
- with self.conn.getresponse() as f:
- result = self.protos.QueryResult()
- result.ParseFromString(f.read())
- return result
-
- def compute_metric(self, metrics):
- args = self.protos.ComputeMetricArgs()
- args.metric_names.extend(metrics)
- byte_data = args.SerializeToString()
- self.conn.request('POST', '/compute_metric', body=byte_data)
- with self.conn.getresponse() as f:
- result = self.protos.ComputeMetricResult()
- result.ParseFromString(f.read())
- return result
-
- def parse(self, chunk):
- self.conn.request('POST', '/parse', body=chunk)
- with self.conn.getresponse() as f:
- return f.read()
-
- def notify_eof(self):
- self.conn.request('GET', '/notify_eof')
- with self.conn.getresponse() as f:
- return f.read()
-
- def status(self):
- self.conn.request('GET', '/status')
- with self.conn.getresponse() as f:
- result = self.protos.StatusResult()
- result.ParseFromString(f.read())
- return result
-
- def enable_metatrace(self):
- self.conn.request('GET', '/enable_metatrace')
- with self.conn.getresponse() as f:
- return f.read()
-
- def disable_and_read_metatrace(self):
- self.conn.request('GET', '/disable_and_read_metatrace')
- with self.conn.getresponse() as f:
- result = self.protos.DisableAndReadMetatraceResult()
- result.ParseFromString(f.read())
- return result
diff --git a/src/trace_processor/python/perfetto/trace_processor/loader.py b/src/trace_processor/python/perfetto/trace_processor/loader.py
deleted file mode 100644
index e57145f91..000000000
--- a/src/trace_processor/python/perfetto/trace_processor/loader.py
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (C) 2020 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-import socket
-import subprocess
-import tempfile
-from urllib import request
-
-
-# This class contains all functions that first try to use a vendor to fulfil
-# their function
-class LoaderStandalone:
- # Limit parsing file to 32MB to maintain parity with the UI
- MAX_BYTES_LOADED = 32 * 1024 * 1024
-
- # URL to download script to run trace_processor
- SHELL_URL = 'http://get.perfetto.dev/trace_processor'
-
- # Default port that trace_processor_shell runs on
- TP_PORT = '9001'
-
- def read_tp_descriptor():
- ws = os.path.dirname(__file__)
- with open(os.path.join(ws, 'trace_processor.descriptor'), 'rb') as x:
- return x.read()
-
- def read_metrics_descriptor():
- ws = os.path.dirname(__file__)
- with open(os.path.join(ws, 'metrics.descriptor'), 'rb') as x:
- return x.read()
-
- def parse_file(tp_http, file_path):
- with open(file_path, 'rb') as f:
- f_size = os.path.getsize(file_path)
- bytes_read = 0
- while (bytes_read < f_size):
- chunk = f.read(LoaderStandalone.MAX_BYTES_LOADED)
- tp_http.parse(chunk)
- bytes_read += len(chunk)
- tp_http.notify_eof()
- return tp_http
-
- def get_shell_path(bin_path=None):
- # Try to use preexisting binary before attempting to download
- # trace_processor
- if bin_path is None:
- with tempfile.NamedTemporaryFile(delete=False) as file:
- req = request.Request(LoaderStandalone.SHELL_URL)
- with request.urlopen(req) as req:
- file.write(req.read())
- subprocess.check_output(['chmod', '+x', file.name])
- return file.name
- else:
- if not os.path.isfile(bin_path):
- raise Exception('Path to binary is not valid')
- return bin_path
-
- def get_free_port(unique_port=False):
- if not unique_port:
- return LoaderStandalone.TP_PORT, f'localhost:{LoaderStandalone.TP_PORT}'
- free_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- free_socket.bind(('', 0))
- free_socket.listen(5)
- port = free_socket.getsockname()[1]
- free_socket.close()
- return str(port), f"localhost:{str(port)}"
-
-
-# Return vendor class if it exists before falling back on LoaderStandalone
-def get_loader():
- try:
- from .loader_vendor import LoaderVendor
- return LoaderVendor
- except ModuleNotFoundError:
- return LoaderStandalone
diff --git a/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor b/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor
deleted file mode 100644
index b5e2561d5..000000000
--- a/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor
+++ /dev/null
@@ -1,572 +0,0 @@
-
-¤
-1protos/perfetto/metrics/android/batt_metric.protoperfetto.protos"Ý
-AndroidBatteryMetric`
-battery_counters ( 25.perfetto.protos.AndroidBatteryMetric.BatteryCountersRbatteryCountersf
-battery_aggregates ( 27.perfetto.protos.AndroidBatteryMetric.BatteryAggregatesRbatteryAggregatesZ
-suspend_period ( 23.perfetto.protos.AndroidBatteryMetric.SuspendPeriodR suspendPeriodÒ
-BatteryCounters!
- timestamp_ns (R timestampNs,
-charge_counter_uah (RchargeCounterUah)
-capacity_percent (RcapacityPercent
-
-current_ua (R currentUa$
-current_avg_ua (R currentAvgUaô
-BatteryAggregates-
-total_screen_off_ns (RtotalScreenOffNs+
-total_screen_on_ns (RtotalScreenOnNs/
-total_screen_doze_ns (RtotalScreenDozeNs*
-total_wakelock_ns (RtotalWakelockNs
-sleep_ns (RsleepNs-
-sleep_screen_off_ns (RsleepScreenOffNs+
-sleep_screen_on_ns (RsleepScreenOnNs/
-sleep_screen_doze_ns (RsleepScreenDozeNsS
- SuspendPeriod!
- timestamp_ns (R timestampNs
- duration_ns (R
-durationNs
-Ô
-0protos/perfetto/metrics/android/cpu_metric.protoperfetto.protos"Ž
-AndroidCpuMetricL
- process_info ( 2).perfetto.protos.AndroidCpuMetric.ProcessR processInfo¨
-Metrics
-mcycles (Rmcycles
-
-runtime_ns (R runtimeNs
- min_freq_khz (R
-minFreqKhz
- max_freq_khz (R
-maxFreqKhz
- avg_freq_khz (R
-avgFreqKhze
-CoreData
-id ( RidC
-metrics ( 2).perfetto.protos.AndroidCpuMetric.MetricsRmetricsJg
- CoreTypeData
-type ( RtypeC
-metrics ( 2).perfetto.protos.AndroidCpuMetric.MetricsRmetricsô
-Thread
-name ( RnameC
-metrics ( 2).perfetto.protos.AndroidCpuMetric.MetricsRmetrics>
-core ( 2*.perfetto.protos.AndroidCpuMetric.CoreDataRcoreK
- core_type ( 2..perfetto.protos.AndroidCpuMetric.CoreTypeDataRcoreTypeJ¹
-Process
-name ( RnameC
-metrics ( 2).perfetto.protos.AndroidCpuMetric.MetricsRmetricsB
-threads ( 2(.perfetto.protos.AndroidCpuMetric.ThreadRthreads>
-core ( 2*.perfetto.protos.AndroidCpuMetric.CoreDataRcoreK
- core_type ( 2..perfetto.protos.AndroidCpuMetric.CoreTypeDataRcoreTypeJ
-·
-5protos/perfetto/metrics/android/display_metrics.protoperfetto.protos"ì
-AndroidDisplayMetrics4
-total_duplicate_frames ( RtotalDuplicateFrames6
-duplicate_frames_logged ( RduplicateFramesLogged7
-total_dpu_underrun_count ( RtotalDpuUnderrunCount2
-refresh_rate_switches ( RrefreshRateSwitchesd
-refresh_rate_stats ( 26.perfetto.protos.AndroidDisplayMetrics.RefreshRateStatRrefreshRateStats‘
-RefreshRateStat(
-refresh_rate_fps ( RrefreshRateFps
-count ( Rcount
- total_dur_ms (R
-totalDurMs
-
-avg_dur_ms (RavgDurMs
-ˆ
-5protos/perfetto/metrics/android/dma_heap_metric.protoperfetto.protos"½
-AndroidDmaHeapMetric$
-avg_size_bytes (R avgSizeBytes$
-min_size_bytes (R minSizeBytes$
-max_size_bytes (R maxSizeBytes3
-total_alloc_size_bytes (RtotalAllocSizeBytes
-ø
-4protos/perfetto/metrics/android/fastrpc_metric.protoperfetto.protos"®
-AndroidFastrpcMetricM
- subsystem ( 2/.perfetto.protos.AndroidFastrpcMetric.SubsystemR subsystemÆ
- Subsystem
-name ( Rname$
-avg_size_bytes (R avgSizeBytes$
-min_size_bytes (R minSizeBytes$
-max_size_bytes (R maxSizeBytes3
-total_alloc_size_bytes (RtotalAllocSizeBytes
-ÿ
-0protos/perfetto/metrics/android/g2d_metric.protoperfetto.protos"¹
-
-G2dMetrics<
-g2d_hw ( 2%.perfetto.protos.G2dMetrics.G2dMetricRg2dHw<
-g2d_sw ( 2%.perfetto.protos.G2dMetrics.G2dMetricRg2dSw½
- G2dInstance
-name ( Rname
-
-max_dur_ns (RmaxDurNs
-
-min_dur_ns (RminDurNs
-
-avg_dur_ns (RavgDurNs
- frame_count ( R
-frameCount
- error_count ( R
-errorCountî
- G2dMetricE
- instances ( 2'.perfetto.protos.G2dMetrics.G2dInstanceR instances
-
-max_dur_ns (RmaxDurNs
-
-min_dur_ns (RminDurNs
-
-avg_dur_ns (RavgDurNs
- frame_count ( R
-frameCount
- error_count ( R
-errorCount
-Ö
-0protos/perfetto/metrics/android/gpu_metric.protoperfetto.protos"
-AndroidGpuMetricG
- processes ( 2).perfetto.protos.AndroidGpuMetric.ProcessR processes
-mem_max (RmemMax
-mem_min (RmemMin
-mem_avg (RmemAvgh
-Process
-name ( Rname
-mem_max (RmemMax
-mem_min (RmemMin
-mem_avg (RmemAvg
-‚
-0protos/perfetto/metrics/android/hwcomposer.protoperfetto.protos"¼
-AndroidHwcomposerMetrics8
-composition_total_layers (RcompositionTotalLayers4
-composition_dpu_layers (RcompositionDpuLayers4
-composition_gpu_layers (RcompositionGpuLayersA
-composition_dpu_cached_layers (RcompositionDpuCachedLayers?
-composition_sf_cached_layers (RcompositionSfCachedLayers8
-skipped_validation_count (RskippedValidationCount<
-unskipped_validation_count (RunskippedValidationCount<
-separated_validation_count (RseparatedValidationCount8
-unknown_validation_count (RunknownValidationCount8
-avg_all_execution_time_ms
- (RavgAllExecutionTimeMs@
-avg_skipped_execution_time_ms (RavgSkippedExecutionTimeMsD
-avg_unskipped_execution_time_ms (RavgUnskippedExecutionTimeMsD
-avg_separated_execution_time_ms (RavgSeparatedExecutionTimeMs
-†
-1protos/perfetto/metrics/android/hwui_metric.protoperfetto.protos"ã
-ProcessRenderInfo!
- process_name ( R processName#
-rt_cpu_time_ms (R rtCpuTimeMs(
-draw_frame_count ( RdrawFrameCount$
-draw_frame_max (R drawFrameMax$
-draw_frame_min (R drawFrameMin$
-draw_frame_avg (R drawFrameAvg
- flush_count ( R
-flushCount
- flush_max (RflushMax
- flush_min (RflushMin
- flush_avg
- (RflushAvg,
-prepare_tree_count ( RprepareTreeCount(
-prepare_tree_max (RprepareTreeMax(
-prepare_tree_min (RprepareTreeMin(
-prepare_tree_avg (RprepareTreeAvg0
-gpu_completion_count ( RgpuCompletionCount,
-gpu_completion_max (RgpuCompletionMax,
-gpu_completion_min (RgpuCompletionMin,
-gpu_completion_avg (RgpuCompletionAvg&
-ui_record_count ( R uiRecordCount"
- ui_record_max (R uiRecordMax"
- ui_record_min (R uiRecordMin"
- ui_record_avg (R uiRecordAvg0
-shader_compile_count ( RshaderCompileCount.
-shader_compile_time (RshaderCompileTime,
-shader_compile_avg (RshaderCompileAvg&
-cache_hit_count ( R cacheHitCount$
-cache_hit_time (R cacheHitTime"
- cache_hit_avg (R cacheHitAvg(
-cache_miss_count ( RcacheMissCount&
-cache_miss_time (R cacheMissTime$
-cache_miss_avg (R cacheMissAvg/
-graphics_cpu_mem_max (RgraphicsCpuMemMax/
-graphics_cpu_mem_min! (RgraphicsCpuMemMin/
-graphics_cpu_mem_avg" (RgraphicsCpuMemAvg/
-graphics_gpu_mem_max# (RgraphicsGpuMemMax/
-graphics_gpu_mem_min$ (RgraphicsGpuMemMin/
-graphics_gpu_mem_avg% (RgraphicsGpuMemAvg&
-texture_mem_max& (R textureMemMax&
-texture_mem_min' (R textureMemMin&
-texture_mem_avg( (R textureMemAvg
- all_mem_max) (R allMemMax
- all_mem_min* (R allMemMin
- all_mem_avg+ (R allMemAvg"Z
-AndroidHwuiMetricE
- process_info ( 2".perfetto.protos.ProcessRenderInfoR processInfo
-à
-0protos/perfetto/metrics/android/ion_metric.protoperfetto.protos"š
-AndroidIonMetric@
-buffer ( 2(.perfetto.protos.AndroidIonMetric.BufferRbufferÃ
-Buffer
-name ( Rname$
-avg_size_bytes (R avgSizeBytes$
-min_size_bytes (R minSizeBytes$
-max_size_bytes (R maxSizeBytes3
-total_alloc_size_bytes (RtotalAllocSizeBytes
-—
-1protos/perfetto/metrics/android/jank_metric.protoperfetto.protos"Ð
-AndroidJankMetricsG
-warnings ( 2+.perfetto.protos.AndroidJankMetrics.WarningRwarningsq
-Warning
-ts (Rts
-dur (Rdur!
- process_name ( R processName!
- warning_text ( R warningText
-À
-6protos/perfetto/metrics/android/process_metadata.protoperfetto.protos"ô
-AndroidProcessMetadata
-name ( Rname
-uid (RuidI
-package ( 2/.perfetto.protos.AndroidProcessMetadata.PackageRpackageY
-packages_for_uid ( 2/.perfetto.protos.AndroidProcessMetadata.PackageRpackagesForUidv
-Package!
- package_name ( R packageName(
-apk_version_code (RapkVersionCode
-
-debuggable (R
-debuggableJJJJ
-œ
-9protos/perfetto/metrics/android/java_heap_histogram.protoperfetto.protos6protos/perfetto/metrics/android/process_metadata.proto"•
-JavaHeapHistogramW
-instance_stats ( 20.perfetto.protos.JavaHeapHistogram.InstanceStatsR instanceStats‘
- TypeCount
- type_name ( RtypeName
-category ( Rcategory
- obj_count ( RobjCount.
-reachable_obj_count ( RreachableObjCounte
-Sample
-ts (RtsK
-
-type_count ( 2,.perfetto.protos.JavaHeapHistogram.TypeCountR typeCount«
- InstanceStats
-upid ( RupidA
-process ( 2'.perfetto.protos.AndroidProcessMetadataRprocessC
-samples ( 2).perfetto.protos.JavaHeapHistogram.SampleRsamples
-ž
-5protos/perfetto/metrics/android/java_heap_stats.protoperfetto.protos6protos/perfetto/metrics/android/process_metadata.proto"›
- JavaHeapStatsS
-instance_stats ( 2,.perfetto.protos.JavaHeapStats.InstanceStatsR instanceStatsb
- HeapRoots
- root_type ( RrootType
- type_name ( RtypeName
- obj_count (RobjCount¦
-Sample
-ts (Rts
- heap_size (RheapSize
- obj_count (RobjCount.
-reachable_heap_size (RreachableHeapSize.
-reachable_obj_count (RreachableObjCount2
-anon_rss_and_swap_size (RanonRssAndSwapSize>
-roots ( 2(.perfetto.protos.JavaHeapStats.HeapRootsRroots§
- InstanceStats
-upid ( RupidA
-process ( 2'.perfetto.protos.AndroidProcessMetadataRprocess?
-samples ( 2%.perfetto.protos.JavaHeapStats.SampleRsamples
-»
-0protos/perfetto/metrics/android/lmk_metric.protoperfetto.protos"õ
-AndroidLmkMetric
- total_count (R
-totalCountN
- by_oom_score ( 2,.perfetto.protos.AndroidLmkMetric.ByOomScoreR
-byOomScore(
-oom_victim_count (RoomVictimCountF
-
-ByOomScore"
- oom_score_adj (R oomScoreAdj
-count (Rcount
-Ì
-7protos/perfetto/metrics/android/lmk_reason_metric.protoperfetto.protos6protos/perfetto/metrics/android/process_metadata.proto"Ç
-AndroidLmkReasonMetric?
-lmks ( 2+.perfetto.protos.AndroidLmkReasonMetric.LmkRlmks—
-ProcessA
-process ( 2'.perfetto.protos.AndroidProcessMetadataRprocess"
- oom_score_adj (R oomScoreAdj
-size (Rsize$
-file_rss_bytes (R fileRssBytes$
-anon_rss_bytes (R anonRssBytes&
-shmem_rss_bytes (R shmemRssBytes
-
-swap_bytes (R swapBytesÑ
-Lmk"
- oom_score_adj (R oomScoreAdj&
-ion_heaps_bytes (R ionHeapsBytes/
-system_ion_heap_size (RsystemIonHeapSizeM
- processes ( 2/.perfetto.protos.AndroidLmkReasonMetric.ProcessR processes
-
-0protos/perfetto/metrics/android/mem_metric.protoperfetto.protos"É
-AndroidMemoryMetric\
-process_metrics ( 23.perfetto.protos.AndroidMemoryMetric.ProcessMetricsRprocessMetricsý
-ProcessMetrics!
- process_name ( R processNamea
-total_counters ( 2:.perfetto.protos.AndroidMemoryMetric.ProcessMemoryCountersR totalCounterse
-priority_breakdown ( 26.perfetto.protos.AndroidMemoryMetric.PriorityBreakdownRpriorityBreakdown‡
-PriorityBreakdown
-priority ( RpriorityV
-counters ( 2:.perfetto.protos.AndroidMemoryMetric.ProcessMemoryCountersRcountersˆ
-ProcessMemoryCountersG
-anon_rss ( 2,.perfetto.protos.AndroidMemoryMetric.CounterRanonRssG
-file_rss ( 2,.perfetto.protos.AndroidMemoryMetric.CounterRfileRss@
-swap ( 2,.perfetto.protos.AndroidMemoryMetric.CounterRswapP
- anon_and_swap ( 2,.perfetto.protos.AndroidMemoryMetric.CounterR anonAndSwapI
- java_heap ( 2,.perfetto.protos.AndroidMemoryMetric.CounterRjavaHeap?
-Counter
-min (Rmin
-max (Rmax
-avg (Ravg
- 
-6protos/perfetto/metrics/android/mem_unagg_metric.protoperfetto.protos"Ô
-AndroidMemoryUnaggregatedMetrice
-process_values ( 2>.perfetto.protos.AndroidMemoryUnaggregatedMetric.ProcessValuesR processValues—
- ProcessValues!
- process_name ( R processNamec
-
-mem_values ( 2D.perfetto.protos.AndroidMemoryUnaggregatedMetric.ProcessMemoryValuesR memValuesã
-ProcessMemoryValuesQ
-anon_rss ( 26.perfetto.protos.AndroidMemoryUnaggregatedMetric.ValueRanonRssQ
-file_rss ( 26.perfetto.protos.AndroidMemoryUnaggregatedMetric.ValueRfileRssJ
-swap ( 26.perfetto.protos.AndroidMemoryUnaggregatedMetric.ValueRswapZ
- anon_and_swap ( 26.perfetto.protos.AndroidMemoryUnaggregatedMetric.ValueR anonAndSwapJ
-Value
-ts (Rts
- oom_score (RoomScore
-value (Rvalue
-ˆ
-2protos/perfetto/metrics/android/package_list.protoperfetto.protos"À
-AndroidPackageListG
-packages ( 2+.perfetto.protos.AndroidPackageList.PackageRpackagesa
-Package!
- package_name ( R packageName
-uid (Ruid!
- version_code (R versionCode
-ð
-5protos/perfetto/metrics/android/powrails_metric.protoperfetto.protos"¥
-AndroidPowerRailsN
- power_rails ( 2-.perfetto.protos.AndroidPowerRails.PowerRailsR
-powerRailsN
-
-EnergyData!
- timestamp_ms (R timestampMs
-
-energy_uws (R energyUwsp
-
-PowerRails
-name ( RnameN
- energy_data ( 2-.perfetto.protos.AndroidPowerRails.EnergyDataR
-energyData
-Í"
-4protos/perfetto/metrics/android/startup_metric.protoperfetto.protos6protos/perfetto/metrics/android/process_metadata.proto"Ë!
-AndroidStartupMetricG
-startup ( 2-.perfetto.protos.AndroidStartupMetric.StartupRstartupà
-TaskStateBreakdown$
-running_dur_ns (R runningDurNs&
-runnable_dur_ns (R runnableDurNs?
-uninterruptible_sleep_dur_ns (RuninterruptibleSleepDurNs;
-interruptible_sleep_dur_ns (RinterruptibleSleepDurNso
-McyclesByCoreType
-little (Rlittle
-big (Rbig
-bigger (Rbigger
-unknown (Runknown5
-Slice
-dur_ns (RdurNs
-dur_ms (RdurMsß
- ToFirstFrame
-dur_ns (RdurNs
-dur_ms (RdurMsr
-main_thread_by_task_state ( 28.perfetto.protos.AndroidStartupMetric.TaskStateBreakdownRmainThreadByTaskStateh
-mcycles_by_core_type ( 27.perfetto.protos.AndroidStartupMetric.McyclesByCoreTypeRmcyclesByCoreTypeA
-other_processes_spawned_count ( RotherProcessesSpawnedCount_
-time_activity_manager ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeActivityManagerf
-time_activity_thread_main ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeActivityThreadMain_
-time_bind_application ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeBindApplication[
-time_activity_start ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeActivityStart]
-time_activity_resume ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeActivityResume_
-time_activity_restart ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeActivityRestartZ
-time_choreographer ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeChoreographerN
- time_inflate ( 2+.perfetto.protos.AndroidStartupMetric.SliceR timeInflateY
-time_get_resources ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeGetResourcesf
-time_before_start_process
- ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeBeforeStartProcessf
-time_during_start_process ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeDuringStartProcessM
- to_post_fork ( 2+.perfetto.protos.AndroidStartupMetric.SliceR
-toPostForkb
-to_activity_thread_main ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtoActivityThreadMain[
-to_bind_application ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtoBindApplicationQ
-time_post_fork ( 2+.perfetto.protos.AndroidStartupMetric.SliceR timePostForkO
- time_dex_open ( 2+.perfetto.protos.AndroidStartupMetric.SliceR timeDexOpenW
-time_verify_class ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeVerifyClass0
-jit_compiled_methods ( RjitCompiledMethodsh
-time_jit_thread_pool_on_cpu ( 2+.perfetto.protos.AndroidStartupMetric.SliceRtimeJitThreadPoolOnCpuO
- time_gc_total ( 2+.perfetto.protos.AndroidStartupMetric.SliceR timeGcTotalP
-time_gc_on_cpu ( 2+.perfetto.protos.AndroidStartupMetric.SliceR timeGcOnCpuJ  J JJ\
-
-HscMetricsN
- full_startup ( 2+.perfetto.protos.AndroidStartupMetric.SliceR fullStartupd
-Activity
-name ( Rname
-method ( Rmethod&
-ts_method_start (R tsMethodStartJt
-BinderTransactionG
-duration ( 2+.perfetto.protos.AndroidStartupMetric.SliceRduration
-thread ( Rthread¯
-OptimizationStatus
- odex_status ( R
-odexStatus-
-compilation_filter ( RcompilationFilter-
-compilation_reason ( RcompilationReason
-location ( Rlocation[
-EventTimestamps'
-intent_received (RintentReceived
- first_frame (R
-firstFrame³
-Startup
-
-startup_id ( R startupId!
- package_name ( R packageName!
- process_name ( R processNameN
-
-activities ( 2..perfetto.protos.AndroidStartupMetric.ActivityR
-activitiesq
-long_binder_transactions ( 27.perfetto.protos.AndroidStartupMetric.BinderTransactionRlongBinderTransactions,
-zygote_new_process (RzygoteNewProcessC
-activity_hosting_process_count ( RactivityHostingProcessCount`
-event_timestamps ( 25.perfetto.protos.AndroidStartupMetric.EventTimestampsReventTimestampsX
-to_first_frame ( 22.perfetto.protos.AndroidStartupMetric.ToFirstFrameR toFirstFrameA
-process ( 2'.perfetto.protos.AndroidProcessMetadataRprocessB
-hsc ( 20.perfetto.protos.AndroidStartupMetric.HscMetricsRhscY
-report_fully_drawn ( 2+.perfetto.protos.AndroidStartupMetric.SliceRreportFullyDrawni
-optimization_status ( 28.perfetto.protos.AndroidStartupMetric.OptimizationStatusRoptimizationStatusJ
-
-ö
-4protos/perfetto/metrics/android/surfaceflinger.protoperfetto.protos"¬
-AndroidSurfaceflingerMetric#
- missed_frames ( R missedFrames*
-missed_hwc_frames ( RmissedHwcFrames*
-missed_gpu_frames ( RmissedGpuFrames*
-missed_frame_rate (RmissedFrameRate1
-missed_hwc_frame_rate (RmissedHwcFrameRate1
-missed_gpu_frame_rate (RmissedGpuFrameRate
-ð
-7protos/perfetto/metrics/android/sysui_cuj_metrics.protoperfetto.protos6protos/perfetto/metrics/android/process_metadata.proto"ë
-AndroidSysUiCujMetricsE
-frames ( 2-.perfetto.protos.AndroidSysUiCujMetrics.FrameRframes
-cuj_name ( RcujName
- cuj_start (RcujStart
-cuj_dur (RcujDurA
-process ( 2'.perfetto.protos.AndroidProcessMetadataRprocessv
-Frame
-number (Rnumber
-vsync (Rvsync
-ts (Rts
-dur (Rdur
-
-jank_cause ( R jankCause
-»
-0protos/perfetto/metrics/android/task_names.protoperfetto.protos"õ
-AndroidTaskNamesC
-process ( 2).perfetto.protos.AndroidTaskNames.ProcessRprocess›
-Process
-pid (Rpid!
- process_name ( R processName
- thread_name ( R
-threadName
-uid (Ruid(
-uid_package_name ( RuidPackageName
-”
-Aprotos/perfetto/metrics/android/thread_time_in_state_metric.protoperfetto.protos6protos/perfetto/metrics/android/process_metadata.proto"…
-AndroidThreadTimeInStateMetricU
- processes ( 27.perfetto.protos.AndroidThreadTimeInStateMetric.ProcessR processesÀ
-MetricsByCoreType)
-time_in_state_cpu (RtimeInStateCpu
- core_type ( RcoreType
-
-runtime_ms (R runtimeMs
-mcycles (Rmcycles*
-power_profile_mah (RpowerProfileMah±
-Thread
-name ( Rname
- main_thread (R
-mainThreadr
-metrics_by_core_type ( 2A.perfetto.protos.AndroidThreadTimeInStateMetric.MetricsByCoreTypeRmetricsByCoreType”
-ProcessC
-metadata ( 2'.perfetto.protos.AndroidProcessMetadataRmetadatar
-metrics_by_core_type ( 2A.perfetto.protos.AndroidThreadTimeInStateMetric.MetricsByCoreTypeRmetricsByCoreTypeP
-threads ( 26.perfetto.protos.AndroidThreadTimeInStateMetric.ThreadRthreads
-ü
-9protos/perfetto/metrics/android/unsymbolized_frames.protoperfetto.protos"­
-UnsymbolizedFramesA
-frames ( 2).perfetto.protos.UnsymbolizedFrames.FrameRframesT
-Frame
-module ( Rmodule
-build_id ( RbuildId
-address (Raddress
-²#
-%protos/perfetto/metrics/metrics.protoperfetto.protos1protos/perfetto/metrics/android/batt_metric.proto0protos/perfetto/metrics/android/cpu_metric.proto5protos/perfetto/metrics/android/display_metrics.proto5protos/perfetto/metrics/android/dma_heap_metric.proto4protos/perfetto/metrics/android/fastrpc_metric.proto0protos/perfetto/metrics/android/g2d_metric.proto0protos/perfetto/metrics/android/gpu_metric.proto0protos/perfetto/metrics/android/hwcomposer.proto1protos/perfetto/metrics/android/hwui_metric.proto0protos/perfetto/metrics/android/ion_metric.proto1protos/perfetto/metrics/android/jank_metric.proto9protos/perfetto/metrics/android/java_heap_histogram.proto5protos/perfetto/metrics/android/java_heap_stats.proto0protos/perfetto/metrics/android/lmk_metric.proto7protos/perfetto/metrics/android/lmk_reason_metric.proto0protos/perfetto/metrics/android/mem_metric.proto6protos/perfetto/metrics/android/mem_unagg_metric.proto2protos/perfetto/metrics/android/package_list.proto5protos/perfetto/metrics/android/powrails_metric.proto4protos/perfetto/metrics/android/startup_metric.proto4protos/perfetto/metrics/android/surfaceflinger.proto7protos/perfetto/metrics/android/sysui_cuj_metrics.proto0protos/perfetto/metrics/android/task_names.protoAprotos/perfetto/metrics/android/thread_time_in_state_metric.proto9protos/perfetto/metrics/android/unsymbolized_frames.proto"À
- TraceMetadata*
-trace_duration_ns (RtraceDurationNs
-
-trace_uuid ( R traceUuid:
-android_build_fingerprint ( RandroidBuildFingerprintI
-!statsd_triggering_subscription_id (RstatsdTriggeringSubscriptionId(
-trace_size_bytes (RtraceSizeBytes#
- trace_trigger ( R traceTrigger.
-unique_session_name ( RuniqueSessionName,
-trace_config_pbtxt ( RtraceConfigPbtxt*
-sched_duration_ns
- (RschedDurationNsJ"Ë
-TraceAnalysisStats<
-stat ( 2(.perfetto.protos.TraceAnalysisStats.StatRstatÐ
-Stat
-name ( Rname
-idx ( RidxH
-severity (2,.perfetto.protos.TraceAnalysisStats.SeverityRseverityB
-source (2*.perfetto.protos.TraceAnalysisStats.SourceRsource
-count (Rcount"_
-Severity
-SEVERITY_UNKNOWN
- SEVERITY_INFO
-SEVERITY_DATA_LOSS
-SEVERITY_ERROR"C
-Source
-SOURCE_UNKNOWN
- SOURCE_TRACE
-SOURCE_ANALYSIS"¨
- TraceMetricsH
- android_batt ( 2%.perfetto.protos.AndroidBatteryMetricR androidBattB
- android_cpu ( 2!.perfetto.protos.AndroidCpuMetricR
-androidCpuE
- android_mem ( 2$.perfetto.protos.AndroidMemoryMetricR
-androidMem\
-android_mem_unagg ( 20.perfetto.protos.AndroidMemoryUnaggregatedMetricRandroidMemUnaggU
-android_package_list ( 2#.perfetto.protos.AndroidPackageListRandroidPackageListB
- android_ion ( 2!.perfetto.protos.AndroidIonMetricR
-androidIonN
-android_fastrpc ( 2%.perfetto.protos.AndroidFastrpcMetricRandroidFastrpcB
- android_lmk ( 2!.perfetto.protos.AndroidLmkMetricR
-androidLmkM
-android_powrails ( 2".perfetto.protos.AndroidPowerRailsRandroidPowrailsN
-android_startup ( 2%.perfetto.protos.AndroidStartupMetricRandroidStartupE
-trace_metadata ( 2.perfetto.protos.TraceMetadataR traceMetadataD
- trace_stats! ( 2#.perfetto.protos.TraceAnalysisStatsR
-traceStatsT
-unsymbolized_frames ( 2#.perfetto.protos.UnsymbolizedFramesRunsymbolizedFramesF
-java_heap_stats ( 2.perfetto.protos.JavaHeapStatsR javaHeapStatsR
-java_heap_histogram ( 2".perfetto.protos.JavaHeapHistogramRjavaHeapHistogramU
-android_lmk_reason ( 2'.perfetto.protos.AndroidLmkReasonMetricRandroidLmkReasonR
-android_hwui_metric ( 2".perfetto.protos.AndroidHwuiMetricRandroidHwuiMetricO
-display_metrics ( 2&.perfetto.protos.AndroidDisplayMetricsRdisplayMetricsO
-android_task_names ( 2!.perfetto.protos.AndroidTaskNamesRandroidTaskNameso
-android_thread_time_in_state ( 2/.perfetto.protos.AndroidThreadTimeInStateMetricRandroidThreadTimeInStatec
-android_surfaceflinger ( 2,.perfetto.protos.AndroidSurfaceflingerMetricRandroidSurfaceflingerB
- android_gpu ( 2!.perfetto.protos.AndroidGpuMetricR
-androidGpuS
-android_sysui_cuj ( 2'.perfetto.protos.AndroidSysUiCujMetricsRandroidSysuiCujX
-android_hwcomposer ( 2).perfetto.protos.AndroidHwcomposerMetricsRandroidHwcomposerF
- android_jank ( 2#.perfetto.protos.AndroidJankMetricsR androidJank-
-g2d ( 2.perfetto.protos.G2dMetricsRg2dO
-android_dma_heap ( 2%.perfetto.protos.AndroidDmaHeapMetricRandroidDmaHeap*Âô*ôé*éÑJJ
- J JJJ \ No newline at end of file
diff --git a/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor.sha1 b/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor.sha1
deleted file mode 100644
index a876fff76..000000000
--- a/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor.sha1
+++ /dev/null
@@ -1,6 +0,0 @@
-
-// SHA1(tools/gen_binary_descriptors)
-// 30f9a74885dae344b1a42f7ba94d8909c9d07ad0
-// SHA1(protos/perfetto/metrics/metrics.proto)
-// 64a90d4e7177aa7a8ba57919313037430848325c
- \ No newline at end of file
diff --git a/src/trace_processor/python/perfetto/trace_processor/protos.py b/src/trace_processor/python/perfetto/trace_processor/protos.py
deleted file mode 100644
index b5e370053..000000000
--- a/src/trace_processor/python/perfetto/trace_processor/protos.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright (C) 2020 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from google.protobuf import descriptor_pb2
-from google.protobuf import message_factory
-from google.protobuf.descriptor_pool import DescriptorPool
-
-from .loader import get_loader
-
-
-class ProtoFactory:
-
- def __init__(self):
- # Declare descriptor pool
- self.descriptor_pool = DescriptorPool()
-
- # Load trace processor descriptor and add to descriptor pool
- tp_descriptor_bytes = get_loader().read_tp_descriptor()
- tp_file_desc_set_pb2 = descriptor_pb2.FileDescriptorSet()
- tp_file_desc_set_pb2.MergeFromString(tp_descriptor_bytes)
-
- for f_desc_pb2 in tp_file_desc_set_pb2.file:
- self.descriptor_pool.Add(f_desc_pb2)
-
- # Load metrics descriptor and add to descriptor pool
- metrics_descriptor_bytes = get_loader().read_metrics_descriptor()
- metrics_file_desc_set_pb2 = descriptor_pb2.FileDescriptorSet()
- metrics_file_desc_set_pb2.MergeFromString(metrics_descriptor_bytes)
-
- for f_desc_pb2 in metrics_file_desc_set_pb2.file:
- self.descriptor_pool.Add(f_desc_pb2)
-
- def create_message_factory(message_type):
- message_desc = self.descriptor_pool.FindMessageTypeByName(message_type)
- return message_factory.MessageFactory().GetPrototype(message_desc)
-
- # Create proto messages to correctly communicate with the RPC API by sending
- # and receiving data as protos
- self.StatusResult = create_message_factory('perfetto.protos.StatusResult')
- self.ComputeMetricArgs = create_message_factory(
- 'perfetto.protos.ComputeMetricArgs')
- self.ComputeMetricResult = create_message_factory(
- 'perfetto.protos.ComputeMetricResult')
- self.RawQueryArgs = create_message_factory('perfetto.protos.RawQueryArgs')
- self.QueryResult = create_message_factory('perfetto.protos.QueryResult')
- self.TraceMetrics = create_message_factory('perfetto.protos.TraceMetrics')
- self.DisableAndReadMetatraceResult = create_message_factory(
- 'perfetto.protos.DisableAndReadMetatraceResult')
- self.CellsBatch = create_message_factory(
- 'perfetto.protos.QueryResult.CellsBatch')
diff --git a/src/trace_processor/python/perfetto/trace_processor/shell.py b/src/trace_processor/python/perfetto/trace_processor/shell.py
deleted file mode 100644
index 44da342f9..000000000
--- a/src/trace_processor/python/perfetto/trace_processor/shell.py
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (C) 2020 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-import subprocess
-import time
-from urllib import request, error
-
-from .loader import get_loader
-
-
-def load_shell(bin_path=None, unique_port=False):
- shell_path = get_loader().get_shell_path(bin_path=bin_path)
- port, url = get_loader().get_free_port(unique_port=unique_port)
- p = subprocess.Popen([shell_path, '-D', '--http-port', port],
- stdout=subprocess.DEVNULL)
-
- while True:
- try:
- if p.poll() != None:
- if unique_port:
- raise Exception(
- "Random port allocation failed, please file a bug at https://goto.google.com/perfetto-bug"
- )
- raise Exception(
- "Trace processor failed to start, please file a bug at https://goto.google.com/perfetto-bug"
- )
- req = request.urlretrieve(f'http://{url}/status')
- time.sleep(1)
- break
- except error.URLError:
- pass
-
- return url, p
diff --git a/src/trace_processor/python/perfetto/trace_processor/trace_processor.descriptor b/src/trace_processor/python/perfetto/trace_processor/trace_processor.descriptor
deleted file mode 100644
index 3d2bf28c9..000000000
--- a/src/trace_processor/python/perfetto/trace_processor/trace_processor.descriptor
+++ /dev/null
Binary files differ
diff --git a/src/trace_processor/python/perfetto/trace_processor/trace_processor.descriptor.sha1 b/src/trace_processor/python/perfetto/trace_processor/trace_processor.descriptor.sha1
deleted file mode 100644
index 5ac17ddaa..000000000
--- a/src/trace_processor/python/perfetto/trace_processor/trace_processor.descriptor.sha1
+++ /dev/null
@@ -1,6 +0,0 @@
-
-// SHA1(tools/gen_binary_descriptors)
-// 30f9a74885dae344b1a42f7ba94d8909c9d07ad0
-// SHA1(protos/perfetto/trace_processor/trace_processor.proto)
-// 8320f306d6d5bbcb5ef6ba8cd62cc70a0994d102
- \ No newline at end of file
diff --git a/src/trace_processor/python/setup.py b/src/trace_processor/python/setup.py
deleted file mode 100644
index c8268246d..000000000
--- a/src/trace_processor/python/setup.py
+++ /dev/null
@@ -1,29 +0,0 @@
-from distutils.core import setup
-
-setup(
- name='perfetto',
- packages=['perfetto', 'perfetto.trace_processor'],
- package_data={'perfetto.trace_processor': ['*.descriptor']},
- include_package_data=True,
- version='0.2.9',
- license='apache-2.0',
- description='Python API for Perfetto\'s Trace Processor',
- author='Perfetto',
- author_email='perfetto-pypi@google.com',
- url='https://perfetto.dev/',
- download_url='https://github.com/google/perfetto/archive/v6.0.tar.gz',
- keywords=['trace processor', 'tracing', 'perfetto'],
- install_requires=[
- 'protobuf',
- ],
- classifiers=[
- 'Development Status :: 3 - Alpha',
- 'License :: OSI Approved :: Apache Software License',
- "Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.5",
- "Programming Language :: Python :: 3.6",
- "Programming Language :: Python :: 3.7",
- "Programming Language :: Python :: 3.8",
- "Programming Language :: Python :: 3.9",
- ],
-)
diff --git a/src/trace_processor/read_trace.cc b/src/trace_processor/read_trace.cc
index 8f5b6f045..c4cb67aa0 100644
--- a/src/trace_processor/read_trace.cc
+++ b/src/trace_processor/read_trace.cc
@@ -23,24 +23,21 @@
#include "perfetto/protozero/proto_utils.h"
#include "perfetto/trace_processor/trace_processor.h"
+#include "perfetto/trace_processor/trace_blob.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
#include "src/trace_processor/forwarding_trace_parser.h"
#include "src/trace_processor/importers/gzip/gzip_trace_parser.h"
-#include "src/trace_processor/importers/gzip/gzip_utils.h"
#include "src/trace_processor/importers/proto/proto_trace_tokenizer.h"
+#include "src/trace_processor/util/gzip_utils.h"
#include "src/trace_processor/util/status_macros.h"
#include "protos/perfetto/trace/trace.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
- PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
-#define PERFETTO_HAS_AIO_H() 1
-#else
-#define PERFETTO_HAS_AIO_H() 0
-#endif
-
-#if PERFETTO_HAS_AIO_H()
-#include <aio.h>
+#if TRACE_PROCESSOR_HAS_MMAP()
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <unistd.h>
#endif
namespace perfetto {
@@ -60,8 +57,8 @@ util::Status ReadTraceUsingRead(
if (progress_callback && i % 128 == 0)
progress_callback(*file_size);
- std::unique_ptr<uint8_t[]> buf(new uint8_t[kChunkSize]);
- auto rsize = base::Read(fd, buf.get(), kChunkSize);
+ TraceBlob blob = TraceBlob::Allocate(kChunkSize);
+ auto rsize = base::Read(fd, blob.data(), blob.size());
if (rsize == 0)
break;
@@ -71,30 +68,30 @@ util::Status ReadTraceUsingRead(
}
*file_size += static_cast<uint64_t>(rsize);
-
- RETURN_IF_ERROR(tp->Parse(std::move(buf), static_cast<size_t>(rsize)));
+ TraceBlobView blob_view(std::move(blob), 0, static_cast<size_t>(rsize));
+ RETURN_IF_ERROR(tp->Parse(std::move(blob_view)));
}
return util::OkStatus();
}
class SerializingProtoTraceReader : public ChunkedTraceReader {
public:
- SerializingProtoTraceReader(std::vector<uint8_t>* output) : output_(output) {}
-
- util::Status Parse(std::unique_ptr<uint8_t[]> data, size_t size) override {
- return tokenizer_.Tokenize(
- std::move(data), size, [this](TraceBlobView packet) {
- uint8_t buffer[protozero::proto_utils::kMaxSimpleFieldEncodedSize];
-
- uint8_t* pos = buffer;
- pos = protozero::proto_utils::WriteVarInt(kTracePacketTag, pos);
- pos = protozero::proto_utils::WriteVarInt(packet.length(), pos);
- output_->insert(output_->end(), buffer, pos);
-
- output_->insert(output_->end(), packet.data(),
- packet.data() + packet.length());
- return util::OkStatus();
- });
+ explicit SerializingProtoTraceReader(std::vector<uint8_t>* output)
+ : output_(output) {}
+
+ util::Status Parse(TraceBlobView blob) override {
+ return tokenizer_.Tokenize(std::move(blob), [this](TraceBlobView packet) {
+ uint8_t buffer[protozero::proto_utils::kMaxSimpleFieldEncodedSize];
+
+ uint8_t* pos = buffer;
+ pos = protozero::proto_utils::WriteVarInt(kTracePacketTag, pos);
+ pos = protozero::proto_utils::WriteVarInt(packet.length(), pos);
+ output_->insert(output_->end(), buffer, pos);
+
+ output_->insert(output_->end(), packet.data(),
+ packet.data() + packet.length());
+ return util::OkStatus();
+ });
}
void NotifyEndOfFile() override {}
@@ -118,70 +115,45 @@ util::Status ReadTrace(
if (!fd)
return util::ErrStatus("Could not open trace file (path: %s)", filename);
- uint64_t file_size = 0;
-
-#if PERFETTO_HAS_AIO_H()
- // Load the trace in chunks using async IO. We create a simple pipeline where,
- // at each iteration, we parse the current chunk and asynchronously start
- // reading the next chunk.
- struct aiocb cb {};
- cb.aio_nbytes = kChunkSize;
- cb.aio_fildes = *fd;
-
- std::unique_ptr<uint8_t[]> aio_buf(new uint8_t[kChunkSize]);
-#if defined(MEMORY_SANITIZER)
- // Just initialize the memory to make the memory sanitizer happy as it
- // cannot track aio calls below.
- memset(aio_buf.get(), 0, kChunkSize);
-#endif // defined(MEMORY_SANITIZER)
- cb.aio_buf = aio_buf.get();
-
- PERFETTO_CHECK(aio_read(&cb) == 0);
- struct aiocb* aio_list[1] = {&cb};
-
- for (int i = 0;; i++) {
- if (progress_callback && i % 128 == 0)
- progress_callback(file_size);
-
- // Block waiting for the pending read to complete.
- PERFETTO_CHECK(aio_suspend(aio_list, 1, nullptr) == 0);
- auto rsize = aio_return(&cb);
- if (rsize <= 0)
- break;
- file_size += static_cast<uint64_t>(rsize);
-
- // Take ownership of the completed buffer and enqueue a new async read
- // with a fresh buffer.
- std::unique_ptr<uint8_t[]> buf(std::move(aio_buf));
- aio_buf.reset(new uint8_t[kChunkSize]);
-#if defined(MEMORY_SANITIZER)
- // Just initialize the memory to make the memory sanitizer happy as it
- // cannot track aio calls below.
- memset(aio_buf.get(), 0, kChunkSize);
-#endif // defined(MEMORY_SANITIZER)
- cb.aio_buf = aio_buf.get();
- cb.aio_offset += rsize;
- PERFETTO_CHECK(aio_read(&cb) == 0);
-
- // Parse the completed buffer while the async read is in-flight.
- RETURN_IF_ERROR(tp->Parse(std::move(buf), static_cast<size_t>(rsize)));
+ uint64_t bytes_read = 0;
+
+#if TRACE_PROCESSOR_HAS_MMAP()
+ char* no_mmap = getenv("TRACE_PROCESSOR_NO_MMAP");
+ uint64_t whole_size_64 = static_cast<uint64_t>(lseek(*fd, 0, SEEK_END));
+ lseek(*fd, 0, SEEK_SET);
+ bool use_mmap = !no_mmap || *no_mmap != '1';
+ if (sizeof(size_t) < 8 && whole_size_64 > 2147483648ULL)
+ use_mmap = false; // Cannot use mmap on 32-bit systems for files > 2GB.
+
+ if (use_mmap) {
+ const size_t whole_size = static_cast<size_t>(whole_size_64);
+ void* file_mm = mmap(nullptr, whole_size, PROT_READ, MAP_PRIVATE, *fd, 0);
+ if (file_mm != MAP_FAILED) {
+ TraceBlobView whole_mmap(TraceBlob::FromMmap(file_mm, whole_size));
+ // Parse the file in chunks so we get some status update on stdio.
+ static constexpr size_t kMmapChunkSize = 128ul * 1024 * 1024;
+ while (bytes_read < whole_size_64) {
+ progress_callback(bytes_read);
+ const size_t bytes_read_z = static_cast<size_t>(bytes_read);
+ size_t slice_size = std::min(whole_size - bytes_read_z, kMmapChunkSize);
+ TraceBlobView slice = whole_mmap.slice_off(bytes_read_z, slice_size);
+ RETURN_IF_ERROR(tp->Parse(std::move(slice)));
+ bytes_read += slice_size;
+ } // while (slices)
+ } // if (!MAP_FAILED)
+ } // if (use_mmap)
+ if (bytes_read == 0)
+ PERFETTO_LOG("Cannot use mmap on this system. Falling back on read()");
+#endif // TRACE_PROCESSOR_HAS_MMAP()
+ if (bytes_read == 0) {
+ RETURN_IF_ERROR(
+ ReadTraceUsingRead(tp, *fd, &bytes_read, progress_callback));
}
-
- if (file_size == 0) {
- PERFETTO_ILOG(
- "Failed to read any data using AIO. This is expected and not an error "
- "on WSL. Falling back to read()");
- RETURN_IF_ERROR(ReadTraceUsingRead(tp, *fd, &file_size, progress_callback));
- }
-#else // PERFETTO_HAS_AIO_H()
- RETURN_IF_ERROR(ReadTraceUsingRead(tp, *fd, &file_size, progress_callback));
-#endif // PERFETTO_HAS_AIO_H()
-
tp->NotifyEndOfFile();
tp->SetCurrentTraceName(filename);
if (progress_callback)
- progress_callback(file_size);
+ progress_callback(bytes_read);
return util::OkStatus();
}
@@ -210,7 +182,7 @@ util::Status DecompressTrace(const uint8_t* data,
PERFETTO_CHECK(type == TraceType::kProtoTraceType);
protos::pbzero::Trace::Decoder decoder(data, size);
- GzipDecompressor decompressor;
+ util::GzipDecompressor decompressor;
if (size > 0 && !decoder.packet()) {
return util::ErrStatus("Trace does not contain valid packets");
}
@@ -224,18 +196,13 @@ util::Status DecompressTrace(const uint8_t* data,
// Make sure that to reset the stream between the gzip streams.
auto bytes = packet.compressed_packets();
decompressor.Reset();
- decompressor.SetInput(bytes.data, bytes.size);
-
- using ResultCode = GzipDecompressor::ResultCode;
- uint8_t out[4096];
- for (auto ret = ResultCode::kOk; ret != ResultCode::kEof;) {
- auto res = decompressor.Decompress(out, base::ArraySize(out));
- ret = res.ret;
- if (ret == ResultCode::kError || ret == ResultCode::kNoProgress ||
- ret == ResultCode::kNeedsMoreInput) {
- return util::ErrStatus("Failed while decompressing stream");
- }
- output->insert(output->end(), out, out + res.bytes_written);
+ using ResultCode = util::GzipDecompressor::ResultCode;
+ ResultCode ret = decompressor.FeedAndExtract(
+ bytes.data, bytes.size, [&output](const uint8_t* buf, size_t buf_len) {
+ output->insert(output->end(), buf, buf + buf_len);
+ });
+ if (ret == ResultCode::kError || ret == ResultCode::kNeedsMoreInput) {
+ return util::ErrStatus("Failed while decompressing stream");
}
}
return util::OkStatus();
diff --git a/src/trace_processor/read_trace_integrationtest.cc b/src/trace_processor/read_trace_integrationtest.cc
index 390a7ef9f..439f1fa16 100644
--- a/src/trace_processor/read_trace_integrationtest.cc
+++ b/src/trace_processor/read_trace_integrationtest.cc
@@ -103,7 +103,7 @@ TEST(ReadTraceIntegrationTest, DoubleGzipDecompressTrace) {
std::vector<uint8_t> decompressed;
util::Status status = trace_processor::DecompressTrace(
raw_compressed_trace.data(), raw_compressed_trace.size(), &decompressed);
- ASSERT_TRUE(status.ok());
+ ASSERT_TRUE(status.ok()) << status.message();
protos::pbzero::Trace::Decoder decoder(decompressed.data(),
decompressed.size());
diff --git a/src/trace_processor/ref_counted_unittest.cc b/src/trace_processor/ref_counted_unittest.cc
new file mode 100644
index 000000000..541b49a14
--- /dev/null
+++ b/src/trace_processor/ref_counted_unittest.cc
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "perfetto/trace_processor/ref_counted.h"
+
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace trace_processor {
+namespace {
+
+int g_instances = 0;
+
+class RObj : public RefCounted {
+ public:
+ RObj() { ++g_instances; }
+ ~RObj() { --g_instances; }
+};
+
+TEST(RefCountedTest, CreateAndReset) {
+ RefPtr<RObj> ptr;
+ EXPECT_FALSE(ptr);
+ EXPECT_EQ(ptr.get(), nullptr);
+
+ g_instances = 0;
+
+ for (int i = 0; i < 3; i++) {
+ ptr.reset(new RObj());
+ EXPECT_TRUE(ptr);
+ EXPECT_NE(ptr.get(), nullptr);
+ EXPECT_EQ(g_instances, 1);
+ }
+
+ ptr.reset();
+ EXPECT_EQ(g_instances, 0);
+ EXPECT_FALSE(ptr);
+
+ ptr.reset(new RObj());
+ ptr.reset(nullptr);
+ EXPECT_EQ(g_instances, 0);
+ EXPECT_FALSE(ptr);
+
+ // Test RAII.
+ {
+ RefPtr<RObj> ptr1(new RObj());
+ EXPECT_EQ(g_instances, 1);
+ {
+ RefPtr<RObj> ptr2(new RObj());
+ EXPECT_EQ(g_instances, 2);
+ }
+ EXPECT_EQ(g_instances, 1);
+ }
+ EXPECT_EQ(g_instances, 0);
+}
+
+TEST(RefCountedTest, CopyOperators) {
+ g_instances = 0;
+
+ RefPtr<RObj> x1(new RObj());
+ RefPtr<RObj> y1(new RObj());
+ EXPECT_EQ(g_instances, 2);
+
+ auto x2 = x1;
+ EXPECT_EQ(g_instances, 2);
+
+ auto y2 = y1;
+ EXPECT_EQ(g_instances, 2);
+
+ EXPECT_EQ(x1.get(), x2.get());
+ EXPECT_EQ(&*y1, &*y2);
+
+ x1.reset();
+ y2.reset();
+ EXPECT_EQ(g_instances, 2);
+
+ x2.reset();
+ EXPECT_EQ(g_instances, 1);
+
+ y1 = x2;
+ EXPECT_EQ(g_instances, 0);
+
+ {
+ RefPtr<RObj> nested1(new RObj());
+ EXPECT_EQ(g_instances, 1);
+ {
+ RefPtr<RObj> nested2(new RObj());
+ EXPECT_EQ(g_instances, 2);
+ nested1 = nested2;
+ EXPECT_EQ(g_instances, 1);
+ }
+ EXPECT_EQ(g_instances, 1);
+ }
+ EXPECT_EQ(g_instances, 0);
+}
+
+TEST(RefCountedTest, MoveOperators) {
+ g_instances = 0;
+
+ RefPtr<RObj> x1(new RObj());
+ RefPtr<RObj> y1(new RObj());
+ EXPECT_EQ(g_instances, 2);
+
+ auto x2 = std::move(x1);
+ EXPECT_EQ(g_instances, 2);
+ EXPECT_FALSE(x1);
+
+ auto y2 = std::move(y1);
+ EXPECT_EQ(g_instances, 2);
+ EXPECT_FALSE(y1);
+
+ // Test recycling.
+ x1 = RefPtr<RObj>(new RObj());
+ EXPECT_EQ(g_instances, 3);
+
+ // y1 is still null;
+ y2 = std::move(y1);
+ EXPECT_FALSE(y1);
+ EXPECT_FALSE(y2);
+ EXPECT_EQ(g_instances, 2); // y2 goes away.
+
+ // We are left with x1 and x2.
+ EXPECT_TRUE(x1);
+ EXPECT_TRUE(x2);
+ EXPECT_NE(&*x1, &*x2);
+
+ x1 = std::move(x2); // Now only x1 is left.
+ EXPECT_EQ(g_instances, 1);
+ EXPECT_FALSE(x2);
+
+ x1 = std::move(x2);
+ EXPECT_EQ(g_instances, 0);
+
+ {
+ RefPtr<RObj> nested1(new RObj());
+ EXPECT_EQ(g_instances, 1);
+ {
+ RefPtr<RObj> nested2(new RObj());
+ EXPECT_EQ(g_instances, 2);
+ nested1 = std::move(nested2);
+ EXPECT_EQ(g_instances, 1);
+ }
+ EXPECT_EQ(g_instances, 1);
+ }
+ EXPECT_EQ(g_instances, 0);
+}
+
+} // namespace
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/rpc/BUILD.gn b/src/trace_processor/rpc/BUILD.gn
index 63cc752df..7246ec11d 100644
--- a/src/trace_processor/rpc/BUILD.gn
+++ b/src/trace_processor/rpc/BUILD.gn
@@ -23,8 +23,6 @@ assert(enable_perfetto_trace_processor)
# interface) and by the :httpd module for the HTTP interface.
source_set("rpc") {
sources = [
- "proto_ring_buffer.cc",
- "proto_ring_buffer.h",
"query_result_serializer.cc",
"query_result_serializer.h",
"rpc.cc",
@@ -38,15 +36,13 @@ source_set("rpc") {
"../../../protos/perfetto/trace_processor:zero",
"../../base",
"../../protozero",
+ "../../protozero:proto_ring_buffer",
]
}
perfetto_unittest_source_set("unittests") {
testonly = true
- sources = [
- "proto_ring_buffer_unittest.cc",
- "query_result_serializer_unittest.cc",
- ]
+ sources = [ "query_result_serializer_unittest.cc" ]
deps = [
":rpc",
"..:lib",
@@ -70,7 +66,7 @@ if (enable_perfetto_trace_processor_httpd) {
"../../../include/perfetto/trace_processor",
"../../../protos/perfetto/trace_processor:zero",
"../../base",
- "../../base:unix_socket",
+ "../../base/http",
"../../protozero",
]
}
diff --git a/src/trace_processor/rpc/httpd.cc b/src/trace_processor/rpc/httpd.cc
index 1a061aa65..2e876b1ff 100644
--- a/src/trace_processor/rpc/httpd.cc
+++ b/src/trace_processor/rpc/httpd.cc
@@ -20,14 +20,11 @@
#include "src/trace_processor/rpc/httpd.h"
-#include <map>
-#include <string>
-
-#include "perfetto/ext/base/paged_memory.h"
+#include "perfetto/ext/base/http/http_server.h"
#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/string_view.h"
-#include "perfetto/ext/base/unix_socket.h"
#include "perfetto/ext/base/unix_task_runner.h"
+#include "perfetto/ext/base/utils.h"
#include "perfetto/protozero/scattered_heap_buffer.h"
#include "perfetto/trace_processor/trace_processor.h"
#include "src/trace_processor/rpc/rpc.h"
@@ -39,281 +36,161 @@ namespace trace_processor {
namespace {
-constexpr char kBindPort[] = "9001";
-constexpr size_t kOmitContentLength = static_cast<size_t>(-1);
-
-// 32 MiB payload + 128K for HTTP headers.
-constexpr size_t kMaxRequestSize = (32 * 1024 + 128) * 1024;
-
-// Owns the socket and data for one HTTP client connection.
-struct Client {
- Client(std::unique_ptr<base::UnixSocket> s)
- : sock(std::move(s)),
- rxbuf(base::PagedMemory::Allocate(kMaxRequestSize)) {}
- size_t rxbuf_avail() { return rxbuf.size() - rxbuf_used; }
-
- std::unique_ptr<base::UnixSocket> sock;
- base::PagedMemory rxbuf;
- size_t rxbuf_used = 0;
-};
+constexpr int kBindPort = 9001;
-struct HttpRequest {
- base::StringView method;
- base::StringView uri;
- base::StringView origin;
- base::StringView body;
- int id = 0;
+// Sets the Access-Control-Allow-Origin: $origin on the following origins.
+// This affects only browser clients that use CORS. Other HTTP clients (e.g. the
+// python API) don't look at CORS headers.
+const char* kAllowedCORSOrigins[] = {
+ "https://ui.perfetto.dev",
+ "http://localhost:10000",
+ "http://127.0.0.1:10000",
};
-class HttpServer : public base::UnixSocket::EventListener {
+class Httpd : public base::HttpRequestHandler {
public:
- explicit HttpServer(std::unique_ptr<TraceProcessor>);
- ~HttpServer() override;
- void Run(const char*, const char*);
+ explicit Httpd(std::unique_ptr<TraceProcessor>);
+ ~Httpd() override;
+ void Run(int port);
private:
- size_t ParseOneHttpRequest(Client* client);
- void HandleRequest(Client*, const HttpRequest&);
+ // HttpRequestHandler implementation.
+ void OnHttpRequest(const base::HttpRequest&) override;
+ void OnWebsocketMessage(const base::WebsocketMessage&) override;
- void OnNewIncomingConnection(base::UnixSocket*,
- std::unique_ptr<base::UnixSocket>) override;
- void OnConnect(base::UnixSocket* self, bool connected) override;
- void OnDisconnect(base::UnixSocket* self) override;
- void OnDataAvailable(base::UnixSocket* self) override;
+ void ServeHelpPage(const base::HttpRequest&);
Rpc trace_processor_rpc_;
base::UnixTaskRunner task_runner_;
- std::unique_ptr<base::UnixSocket> sock4_;
- std::unique_ptr<base::UnixSocket> sock6_;
- std::vector<Client> clients_;
+ base::HttpServer http_srv_;
};
-void Append(std::vector<char>& buf, const char* str) {
- buf.insert(buf.end(), str, str + strlen(str));
-}
+base::HttpServerConnection* g_cur_conn;
-void Append(std::vector<char>& buf, const std::string& str) {
- buf.insert(buf.end(), str.begin(), str.end());
+base::StringView Vec2Sv(const std::vector<uint8_t>& v) {
+ return base::StringView(reinterpret_cast<const char*>(v.data()), v.size());
}
-void HttpReply(base::UnixSocket* sock,
- const char* http_code,
- std::initializer_list<const char*> headers = {},
- const uint8_t* content = nullptr,
- size_t content_length = 0) {
- std::vector<char> response;
- response.reserve(4096);
- Append(response, "HTTP/1.1 ");
- Append(response, http_code);
- Append(response, "\r\n");
- for (const char* hdr : headers) {
- Append(response, hdr);
- Append(response, "\r\n");
+// Used both by websockets and /rpc chunked HTTP endpoints.
+void SendRpcChunk(const void* data, uint32_t len) {
+ if (data == nullptr) {
+ // Unrecoverable RPC error case.
+ if (!g_cur_conn->is_websocket())
+ g_cur_conn->SendResponseBody("0\r\n\r\n", 5);
+ g_cur_conn->Close();
+ return;
}
- if (content_length != kOmitContentLength) {
- Append(response, "Content-Length: ");
- Append(response, std::to_string(content_length));
- Append(response, "\r\n");
+ if (g_cur_conn->is_websocket()) {
+ g_cur_conn->SendWebsocketMessage(data, len);
+ } else {
+ base::StackString<32> chunk_hdr("%x\r\n", len);
+ g_cur_conn->SendResponseBody(chunk_hdr.c_str(), chunk_hdr.len());
+ g_cur_conn->SendResponseBody(data, len);
+ g_cur_conn->SendResponseBody("\r\n", 2);
}
- Append(response, "\r\n"); // End-of-headers marker.
- sock->Send(response.data(), response.size()); // Send response headers.
- if (content_length > 0 && content_length != kOmitContentLength)
- sock->Send(content, content_length); // Send response payload.
-}
-
-void ShutdownBadRequest(base::UnixSocket* sock, const char* reason) {
- HttpReply(sock, "500 Bad Request", {},
- reinterpret_cast<const uint8_t*>(reason), strlen(reason));
- sock->Shutdown(/*notify=*/true);
}
-HttpServer::HttpServer(std::unique_ptr<TraceProcessor> preloaded_instance)
- : trace_processor_rpc_(std::move(preloaded_instance)) {}
-HttpServer::~HttpServer() = default;
-
-void HttpServer::Run(const char* kBindAddr4, const char* kBindAddr6) {
- PERFETTO_ILOG("[HTTP] Starting RPC server on %s and %s", kBindAddr4,
- kBindAddr6);
-
- sock4_ = base::UnixSocket::Listen(kBindAddr4, this, &task_runner_,
- base::SockFamily::kInet,
- base::SockType::kStream);
- bool ipv4_listening = sock4_ && sock4_->is_listening();
- if (!ipv4_listening) {
- PERFETTO_ILOG("Failed to listen on IPv4 socket");
- }
-
- sock6_ = base::UnixSocket::Listen(kBindAddr6, this, &task_runner_,
- base::SockFamily::kInet6,
- base::SockType::kStream);
- bool ipv6_listening = sock6_ && sock6_->is_listening();
- if (!ipv6_listening) {
- PERFETTO_ILOG("Failed to listen on IPv6 socket");
- }
-
- PERFETTO_CHECK(ipv4_listening || ipv6_listening);
-
+Httpd::Httpd(std::unique_ptr<TraceProcessor> preloaded_instance)
+ : trace_processor_rpc_(std::move(preloaded_instance)),
+ http_srv_(&task_runner_, this) {}
+Httpd::~Httpd() = default;
+
+void Httpd::Run(int port) {
+ PERFETTO_ILOG("[HTTP] Starting RPC server on localhost:%d", port);
+ PERFETTO_LOG(
+ "[HTTP] This server can be used by reloading https://ui.perfetto.dev and "
+ "clicking on YES on the \"Trace Processor native acceleration\" dialog "
+ "or through the Python API (see "
+ "https://perfetto.dev/docs/analysis/trace-processor#python-api).");
+
+ for (size_t i = 0; i < base::ArraySize(kAllowedCORSOrigins); ++i)
+ http_srv_.AddAllowedOrigin(kAllowedCORSOrigins[i]);
+ http_srv_.Start(port);
task_runner_.Run();
}
-void HttpServer::OnNewIncomingConnection(
- base::UnixSocket*,
- std::unique_ptr<base::UnixSocket> sock) {
- PERFETTO_LOG("[HTTP] New connection");
- clients_.emplace_back(std::move(sock));
-}
-
-void HttpServer::OnConnect(base::UnixSocket*, bool) {}
-
-void HttpServer::OnDisconnect(base::UnixSocket* sock) {
- PERFETTO_LOG("[HTTP] Client disconnected");
- for (auto it = clients_.begin(); it != clients_.end(); ++it) {
- if (it->sock.get() == sock) {
- clients_.erase(it);
- return;
- }
- }
- PERFETTO_DFATAL("[HTTP] untracked client in OnDisconnect()");
-}
-
-void HttpServer::OnDataAvailable(base::UnixSocket* sock) {
- Client* client = nullptr;
- for (auto it = clients_.begin(); it != clients_.end() && !client; ++it)
- client = (it->sock.get() == sock) ? &*it : nullptr;
- PERFETTO_CHECK(client);
-
- char* rxbuf = reinterpret_cast<char*>(client->rxbuf.Get());
- for (;;) {
- size_t avail = client->rxbuf_avail();
- PERFETTO_CHECK(avail <= kMaxRequestSize);
- if (avail == 0)
- return ShutdownBadRequest(sock, "Request body too big");
- size_t rsize = sock->Receive(&rxbuf[client->rxbuf_used], avail);
- client->rxbuf_used += rsize;
- if (rsize == 0 || client->rxbuf_avail() == 0)
- break;
- }
-
- // At this point |rxbuf| can contain a partial HTTP request, a full one or
- // more (in case of HTTP Keepalive pipelining).
- for (;;) {
- size_t bytes_consumed = ParseOneHttpRequest(client);
- if (bytes_consumed == 0)
- break;
- memmove(rxbuf, &rxbuf[bytes_consumed], client->rxbuf_used - bytes_consumed);
- client->rxbuf_used -= bytes_consumed;
+void Httpd::OnHttpRequest(const base::HttpRequest& req) {
+ base::HttpServerConnection& conn = *req.conn;
+ if (req.uri == "/") {
+ // If a user tries to open http://127.0.0.1:9001/ show a minimal help page.
+ return ServeHelpPage(req);
}
-}
-
-// Parses the HTTP request and invokes HandleRequest(). It returns the size of
-// the HTTP header + body that has been processed or 0 if there isn't enough
-// data for a full HTTP request in the buffer.
-size_t HttpServer::ParseOneHttpRequest(Client* client) {
- auto* rxbuf = reinterpret_cast<char*>(client->rxbuf.Get());
- base::StringView buf_view(rxbuf, client->rxbuf_used);
- size_t pos = 0;
- size_t body_offset = 0;
- size_t body_size = 0;
- bool has_parsed_first_line = false;
- HttpRequest http_req;
-
- // This loop parses the HTTP request headers and sets the |body_offset|.
- for (;;) {
- size_t next = buf_view.find("\r\n", pos);
- size_t col;
- if (next == std::string::npos)
- break;
-
- if (!has_parsed_first_line) {
- // Parse the "GET /xxx HTTP/1.1" line.
- has_parsed_first_line = true;
- size_t space = buf_view.find(' ');
- if (space == std::string::npos || space + 2 >= client->rxbuf_used) {
- ShutdownBadRequest(client->sock.get(), "Malformed HTTP request");
- return 0;
- }
- http_req.method = buf_view.substr(0, space);
- size_t uri_size = buf_view.find(' ', space + 1) - space - 1;
- http_req.uri = buf_view.substr(space + 1, uri_size);
- } else if (next == pos) {
- // The CR-LF marker that separates headers from body.
- body_offset = next + 2;
- break;
- } else if ((col = buf_view.find(':', pos)) < next) {
- // Parse HTTP headers. They look like: "Content-Length: 1234".
- auto hdr_name = buf_view.substr(pos, col - pos);
- auto hdr_value = buf_view.substr(col + 2, next - col - 2);
- if (hdr_name.CaseInsensitiveEq("content-length")) {
- body_size = static_cast<size_t>(atoi(hdr_value.ToStdString().c_str()));
- } else if (hdr_name.CaseInsensitiveEq("origin")) {
- http_req.origin = hdr_value;
- } else if (hdr_name.CaseInsensitiveEq("x-seq-id")) {
- http_req.id = atoi(hdr_value.ToStdString().c_str());
- }
- }
- pos = next + 2;
- }
-
- // If we have a full header but not yet the full body, return and try again
- // next time we receive some more data.
- size_t http_req_size = body_offset + body_size;
- if (!body_offset || client->rxbuf_used < http_req_size)
- return 0;
-
- http_req.body = base::StringView(&rxbuf[body_offset], body_size);
- HandleRequest(client, http_req);
- return http_req_size;
-}
-void HttpServer::HandleRequest(Client* client, const HttpRequest& req) {
static int last_req_id = 0;
- if (req.id) {
- if (last_req_id && req.id != last_req_id + 1 && req.id != 1)
+ auto seq_hdr = req.GetHeader("x-seq-id").value_or(base::StringView());
+ int seq_id = base::StringToInt32(seq_hdr.ToStdString()).value_or(0);
+
+ if (seq_id) {
+ if (last_req_id && seq_id != last_req_id + 1 && seq_id != 1)
PERFETTO_ELOG("HTTP Request out of order");
- last_req_id = req.id;
+ last_req_id = seq_id;
}
- PERFETTO_LOG("[HTTP] %04d %s %s (body: %zu bytes)", req.id,
- req.method.ToStdString().c_str(), req.uri.ToStdString().c_str(),
- req.body.size());
- std::string allow_origin_hdr =
- "Access-Control-Allow-Origin: " + req.origin.ToStdString();
-
// This is the default. Overridden by the /query handler for chunked replies.
char transfer_encoding_hdr[255] = "Transfer-Encoding: identity";
std::initializer_list<const char*> headers = {
- "Connection: Keep-Alive", //
"Cache-Control: no-cache", //
- "Keep-Alive: timeout=5, max=1000", //
"Content-Type: application/x-protobuf", //
transfer_encoding_hdr, //
- allow_origin_hdr.c_str()};
-
- if (req.method == "OPTIONS") {
- // CORS headers.
- return HttpReply(client->sock.get(), "204 No Content",
- {
- "Access-Control-Allow-Methods: POST, GET, OPTIONS",
- "Access-Control-Allow-Headers: *",
- "Access-Control-Max-Age: 86400",
- allow_origin_hdr.c_str(),
- });
+ };
+
+ if (req.uri == "/status") {
+ auto status = trace_processor_rpc_.GetStatus();
+ return conn.SendResponse("200 OK", headers, Vec2Sv(status));
+ }
+
+ if (req.uri == "/websocket" && req.is_websocket_handshake) {
+ // Will trigger OnWebsocketMessage() when is received.
+ // It returns a 403 if the origin is not in kAllowedCORSOrigins.
+ return conn.UpgradeToWebsocket(req);
+ }
+
+ // --- Everything below this line is a legacy endpoint not used by the UI.
+ // There are two generations of pre-websocket legacy-ness:
+ // 1. The /rpc based endpoint. This is based on a chunked transfer, doing one
+ // POST request for each RPC invocation. All RPC methods are multiplexed
+ // into this one. This is still used by the python API.
+ // 2. The REST API, with one enpoint per RPC method (/parse, /query, ...).
+ // This is unused and will be removed at some point.
+
+ if (req.uri == "/rpc") {
+ // Start the chunked reply.
+ base::StringCopy(transfer_encoding_hdr, "Transfer-Encoding: chunked",
+ sizeof(transfer_encoding_hdr));
+ conn.SendResponseHeaders("200 OK", headers,
+ base::HttpServerConnection::kOmitContentLength);
+ PERFETTO_CHECK(g_cur_conn == nullptr);
+ g_cur_conn = req.conn;
+ trace_processor_rpc_.SetRpcResponseFunction(SendRpcChunk);
+ // OnRpcRequest() will call SendRpcChunk() one or more times.
+ trace_processor_rpc_.OnRpcRequest(req.body.data(), req.body.size());
+ trace_processor_rpc_.SetRpcResponseFunction(nullptr);
+ g_cur_conn = nullptr;
+
+ // Terminate chunked stream.
+ conn.SendResponseBody("0\r\n\r\n", 5);
+ return;
}
if (req.uri == "/parse") {
- trace_processor_rpc_.Parse(
+ base::Status status = trace_processor_rpc_.Parse(
reinterpret_cast<const uint8_t*>(req.body.data()), req.body.size());
- return HttpReply(client->sock.get(), "200 OK", headers);
+ protozero::HeapBuffered<protos::pbzero::AppendTraceDataResult> result;
+ if (!status.ok()) {
+ result->set_error(status.c_message());
+ }
+ return conn.SendResponse("200 OK", headers,
+ Vec2Sv(result.SerializeAsArray()));
}
if (req.uri == "/notify_eof") {
trace_processor_rpc_.NotifyEndOfFile();
- return HttpReply(client->sock.get(), "200 OK", headers);
+ return conn.SendResponse("200 OK", headers);
}
if (req.uri == "/restore_initial_tables") {
trace_processor_rpc_.RestoreInitialTables();
- return HttpReply(client->sock.get(), "200 OK", headers);
+ return conn.SendResponse("200 OK", headers);
}
// New endpoint, returns data in batches using chunked transfer encoding.
@@ -324,10 +201,10 @@ void HttpServer::HandleRequest(Client* client, const HttpRequest& req) {
std::vector<uint8_t> response;
// Start the chunked reply.
- strncpy(transfer_encoding_hdr, "Transfer-Encoding: chunked",
- sizeof(transfer_encoding_hdr));
- base::UnixSocket* cli_sock = client->sock.get();
- HttpReply(cli_sock, "200 OK", headers, nullptr, kOmitContentLength);
+ base::StringCopy(transfer_encoding_hdr, "Transfer-Encoding: chunked",
+ sizeof(transfer_encoding_hdr));
+ conn.SendResponseHeaders("200 OK", headers,
+ base::HttpServerConnection::kOmitContentLength);
// |on_result_chunk| will be called nested within the same callstack of the
// rpc.Query() call. No further calls will be made once Query() returns.
@@ -335,12 +212,12 @@ void HttpServer::HandleRequest(Client* client, const HttpRequest& req) {
PERFETTO_DLOG("Sending response chunk, len=%zu eof=%d", len, !has_more);
char chunk_hdr[32];
auto hdr_len = static_cast<size_t>(sprintf(chunk_hdr, "%zx\r\n", len));
- cli_sock->Send(chunk_hdr, hdr_len);
- cli_sock->Send(buf, len);
- cli_sock->Send("\r\n", 2);
+ conn.SendResponseBody(chunk_hdr, hdr_len);
+ conn.SendResponseBody(buf, len);
+ conn.SendResponseBody("\r\n", 2);
if (!has_more) {
hdr_len = static_cast<size_t>(sprintf(chunk_hdr, "0\r\n\r\n"));
- cli_sock->Send(chunk_hdr, hdr_len);
+ conn.SendResponseBody(chunk_hdr, hdr_len);
}
};
trace_processor_rpc_.Query(
@@ -355,56 +232,74 @@ void HttpServer::HandleRequest(Client* client, const HttpRequest& req) {
if (req.uri == "/raw_query") {
std::vector<uint8_t> response = trace_processor_rpc_.RawQuery(
reinterpret_cast<const uint8_t*>(req.body.data()), req.body.size());
- return HttpReply(client->sock.get(), "200 OK", headers, response.data(),
- response.size());
- }
-
- if (req.uri == "/status") {
- protozero::HeapBuffered<protos::pbzero::StatusResult> res;
- res->set_loaded_trace_name(
- trace_processor_rpc_.GetCurrentTraceName().c_str());
- std::vector<uint8_t> buf = res.SerializeAsArray();
- return HttpReply(client->sock.get(), "200 OK", headers, buf.data(),
- buf.size());
+ return conn.SendResponse("200 OK", headers, Vec2Sv(response));
}
if (req.uri == "/compute_metric") {
std::vector<uint8_t> res = trace_processor_rpc_.ComputeMetric(
reinterpret_cast<const uint8_t*>(req.body.data()), req.body.size());
- return HttpReply(client->sock.get(), "200 OK", headers, res.data(),
- res.size());
- }
-
- if (req.uri == "/get_metric_descriptors") {
- std::vector<uint8_t> res = trace_processor_rpc_.GetMetricDescriptors(
- reinterpret_cast<const uint8_t*>(req.body.data()), req.body.size());
- return HttpReply(client->sock.get(), "200 OK", headers, res.data(),
- res.size());
+ return conn.SendResponse("200 OK", headers, Vec2Sv(res));
}
if (req.uri == "/enable_metatrace") {
trace_processor_rpc_.EnableMetatrace();
- return HttpReply(client->sock.get(), "200 OK", headers);
+ return conn.SendResponse("200 OK", headers);
}
if (req.uri == "/disable_and_read_metatrace") {
std::vector<uint8_t> res = trace_processor_rpc_.DisableAndReadMetatrace();
- return HttpReply(client->sock.get(), "200 OK", headers, res.data(),
- res.size());
+ return conn.SendResponse("200 OK", headers, Vec2Sv(res));
}
- return HttpReply(client->sock.get(), "404 Not Found", headers);
+ return conn.SendResponseAndClose("404 Not Found", headers);
+}
+
+void Httpd::OnWebsocketMessage(const base::WebsocketMessage& msg) {
+ PERFETTO_CHECK(g_cur_conn == nullptr);
+ g_cur_conn = msg.conn;
+ trace_processor_rpc_.SetRpcResponseFunction(SendRpcChunk);
+ // OnRpcRequest() will call SendRpcChunk() one or more times.
+ trace_processor_rpc_.OnRpcRequest(msg.data.data(), msg.data.size());
+ trace_processor_rpc_.SetRpcResponseFunction(nullptr);
+ g_cur_conn = nullptr;
}
} // namespace
void RunHttpRPCServer(std::unique_ptr<TraceProcessor> preloaded_instance,
std::string port_number) {
- HttpServer srv(std::move(preloaded_instance));
- std::string port = port_number.empty() ? kBindPort : port_number;
- std::string ipv4_addr = "127.0.0.1:" + port;
- std::string ipv6_addr = "[::1]:" + port;
- srv.Run(ipv4_addr.c_str(), ipv6_addr.c_str());
+ Httpd srv(std::move(preloaded_instance));
+ base::Optional<int> port_opt = base::StringToInt32(port_number);
+ int port = port_opt.has_value() ? *port_opt : kBindPort;
+ srv.Run(port);
+}
+
+void Httpd::ServeHelpPage(const base::HttpRequest& req) {
+ static const char kPage[] = R"(Perfetto Trace Processor RPC Server
+
+
+This service can be used in two ways:
+
+1. Open or reload https://ui.perfetto.dev/
+
+It will automatically try to connect and use the server on localhost:9001 when
+available. Click YES when prompted to use Trace Processor Native Acceleration
+in the UI dialog.
+See https://perfetto.dev/docs/visualization/large-traces for more.
+
+
+2. Python API.
+
+Example: perfetto.TraceProcessor(addr='localhost:9001')
+See https://perfetto.dev/docs/analysis/trace-processor#python-api for more.
+
+
+For questions:
+https://perfetto.dev/docs/contributing/getting-started#community
+)";
+
+ std::initializer_list<const char*> headers{"Content-Type: text/plain"};
+ req.conn->SendResponse("200 OK", headers, kPage);
}
} // namespace trace_processor
diff --git a/src/trace_processor/rpc/proto_ring_buffer.cc b/src/trace_processor/rpc/proto_ring_buffer.cc
deleted file mode 100644
index 3354efed9..000000000
--- a/src/trace_processor/rpc/proto_ring_buffer.cc
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/trace_processor/rpc/proto_ring_buffer.h"
-
-#include "perfetto/base/logging.h"
-#include "perfetto/ext/base/paged_memory.h"
-#include "perfetto/protozero/proto_utils.h"
-
-namespace perfetto {
-namespace trace_processor {
-
-namespace {
-constexpr size_t kGrowBytes = 128 * 1024;
-
-inline ProtoRingBuffer::Message FramingError() {
- ProtoRingBuffer::Message msg{};
- msg.fatal_framing_error = true;
- return msg;
-}
-
-// Tries to decode a length-delimited proto field from |start|.
-// Returns a valid boundary if the preamble is valid and the length is within
-// |end|, or an invalid message otherwise.
-ProtoRingBuffer::Message TryReadMessage(const uint8_t* start,
- const uint8_t* end) {
- namespace proto_utils = protozero::proto_utils;
- uint64_t field_tag = 0;
- auto* start_of_len = proto_utils::ParseVarInt(start, end, &field_tag);
- if (start_of_len == start)
- return ProtoRingBuffer::Message{}; // Not enough data.
-
- const uint32_t tag = field_tag & 0x07;
- if (tag !=
- static_cast<uint32_t>(proto_utils::ProtoWireType::kLengthDelimited)) {
- PERFETTO_ELOG("RPC framing error, unexpected msg tag 0x%xu", tag);
- return FramingError();
- }
-
- uint64_t msg_len = 0;
- auto* start_of_msg = proto_utils::ParseVarInt(start_of_len, end, &msg_len);
- if (start_of_msg == start_of_len)
- return ProtoRingBuffer::Message{}; // Not enough data.
-
- if (msg_len > ProtoRingBuffer::kMaxMsgSize) {
- PERFETTO_ELOG("RPC framing error, message too large (%" PRIu64 " > %zu)",
- msg_len, ProtoRingBuffer::kMaxMsgSize);
- return FramingError();
- }
-
- if (start_of_msg + msg_len > end)
- return ProtoRingBuffer::Message{}; // Not enough data.
-
- ProtoRingBuffer::Message msg{};
- msg.start = start_of_msg;
- msg.len = static_cast<uint32_t>(msg_len);
- msg.field_id = static_cast<uint32_t>(field_tag >> 3);
- return msg;
-}
-
-} // namespace
-
-ProtoRingBuffer::ProtoRingBuffer()
- : buf_(base::PagedMemory::Allocate(kGrowBytes)) {}
-ProtoRingBuffer::~ProtoRingBuffer() = default;
-
-void ProtoRingBuffer::Append(const void* data_void, size_t data_len) {
- if (failed_)
- return;
- const uint8_t* data = static_cast<const uint8_t*>(data_void);
- PERFETTO_DCHECK(wr_ <= buf_.size());
- PERFETTO_DCHECK(wr_ >= rd_);
-
- // If the last call to ReadMessage() consumed all the data in the buffer and
- // there are no incomplete messages pending, restart from the beginning rather
- // than keep ringing. This is the most common case.
- if (rd_ == wr_)
- rd_ = wr_ = 0;
-
- // The caller is expected to always issue a ReadMessage() after each Append().
- PERFETTO_CHECK(!fastpath_.valid());
- if (rd_ == wr_) {
- auto msg = TryReadMessage(data, data + data_len);
- if (msg.valid() && msg.end() == (data + data_len)) {
- // Fastpath: in many cases, the underlying stream will effectively
- // preserve the atomicity of messages for most small messages.
- // In this case we can avoid the extra buf_ roundtrip and just pass a
- // pointer to |data| + (proto preamble len).
- // The next call to ReadMessage)= will return |fastpath_|.
- fastpath_ = std::move(msg);
- return;
- }
- }
-
- size_t avail = buf_.size() - wr_;
- if (data_len > avail) {
- // This whole section should be hit extremely rare.
-
- // Try first just recompacting the buffer by moving everything to the left.
- // This can happen if we received "a message and a bit" on each Append call
- // so we ended pup in a situation like:
- // buf_: [unused space] [msg1 incomplete]
- // ^rd_ ^wr_
- //
- // After recompaction:
- // buf_: [msg1 incomplete]
- // ^rd_ ^wr_
- uint8_t* buf = static_cast<uint8_t*>(buf_.Get());
- memmove(&buf[0], &buf[rd_], wr_ - rd_);
- avail += rd_;
- wr_ -= rd_;
- rd_ = 0;
- if (data_len > avail) {
- // The compaction didn't free up enough space and we need to expand the
- // ring buffer. Yes, we could have detected this earlier and split the
- // code paths, rather than first compacting and then realizing it wasn't
- // sufficient. However, that would make the code harder to reason about,
- // creating code paths that are nearly never hit, hence making it more
- // likely to accumulate bugs in future. All this is very rare.
- size_t new_size = buf_.size();
- while (data_len > new_size - wr_)
- new_size += kGrowBytes;
- if (new_size > kMaxMsgSize * 2) {
- failed_ = true;
- return;
- }
- auto new_buf = base::PagedMemory::Allocate(new_size);
- memcpy(new_buf.Get(), buf_.Get(), buf_.size());
- buf_ = std::move(new_buf);
- avail = new_size - wr_;
- // No need to touch rd_ / wr_ cursors.
- }
- }
-
- // Append the received data at the end of the ring buffer.
- uint8_t* buf = static_cast<uint8_t*>(buf_.Get());
- memcpy(&buf[wr_], data, data_len);
- wr_ += data_len;
-}
-
-ProtoRingBuffer::Message ProtoRingBuffer::ReadMessage() {
- if (failed_)
- return FramingError();
-
- if (fastpath_.valid()) {
- // The fastpath can only be hit when the buffer is empty.
- PERFETTO_CHECK(rd_ == wr_);
- auto msg = std::move(fastpath_);
- fastpath_ = Message{};
- return msg;
- }
-
- uint8_t* buf = static_cast<uint8_t*>(buf_.Get());
-
- PERFETTO_DCHECK(rd_ <= wr_);
- if (rd_ >= wr_)
- return Message{}; // Completely empty.
-
- auto msg = TryReadMessage(&buf[rd_], &buf[wr_]);
- if (!msg.valid()) {
- failed_ = failed_ || msg.fatal_framing_error;
- return msg; // Return |msg| because it could be a framing error.
- }
-
- // Note: msg.start is > buf[rd_], because it skips the proto preamble.
- PERFETTO_DCHECK(msg.start > &buf[rd_]);
- const uint8_t* msg_end = msg.start + msg.len;
- PERFETTO_CHECK(msg_end > &buf[rd_] && msg_end <= &buf[wr_]);
- auto msg_outer_len = static_cast<size_t>(msg_end - &buf[rd_]);
- rd_ += msg_outer_len;
- return msg;
-}
-
-} // namespace trace_processor
-} // namespace perfetto
diff --git a/src/trace_processor/rpc/proto_ring_buffer.h b/src/trace_processor/rpc/proto_ring_buffer.h
deleted file mode 100644
index 62934ca81..000000000
--- a/src/trace_processor/rpc/proto_ring_buffer.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SRC_TRACE_PROCESSOR_RPC_PROTO_RING_BUFFER_H_
-#define SRC_TRACE_PROCESSOR_RPC_PROTO_RING_BUFFER_H_
-
-#include <stdint.h>
-
-#include "perfetto/ext/base/paged_memory.h"
-
-namespace perfetto {
-namespace trace_processor {
-
-// This class buffers and tokenizes proto messages used for the TraceProcessor
-// RPC interface (See comments in trace_processor.proto).
-// From a logical level, the RPC is a sequence of protos like this.
-// [ header 1 ] [ payload 1 ]
-// [ header 2 ] [ payload 2 ]
-// [ header 3 ] [ payload 3 ]
-// Where [ header ] is a variable-length sequence of:
-// [ Field ID = 1, type = length-delimited] [ length (varint) ].
-// The RPC pipe is byte-oriented, not message-oriented (like a TCP stream).
-// The pipe is not required to respect the boundaries of each message, it only
-// guarantees that data is not lost or duplicated. The following sequence of
-// inbound events is possible:
-// 1. [ hdr 1 (incomplete) ... ]
-// 2. [ ... hdr 1 ] [ payload 1 ] [ hdr 2 ] [ payoad 2 ] [ hdr 3 ] [ pay... ]
-// 3. [ ...load 3 ]
-//
-// This class maintains inbound requests in a ring buffer.
-// The expected usage is:
-// ring_buf.Append(data, len);
-// for (;;) {
-// auto msg = ring_buf.ReadMessage();
-// if (!msg.valid())
-// break;
-// Decode(msg);
-// }
-//
-// After each call to Append, the caller is expected to call ReadMessage() until
-// it returns an invalid message (signalling no more messages could be decoded).
-// Note that a single Append can "unblock" > 1 messages, which is why the caller
-// needs to keep calling ReadMessage in a loop.
-//
-// Internal architecture
-// ---------------------
-// Internally this is similar to a ring-buffer, with the caveat that it never
-// wraps, it only expands. Expansions are rare. The deal is that in most cases
-// the read cursor follows very closely the write cursor. For instance, if the
-// uderlying behaves as a dgram socket, after each Append, the read cursor will
-// chase completely the write cursor. Even if the underyling stream is not
-// always atomic, the expectation is that the read cursor will eventually reach
-// the write one within few messages.
-// A visual example, imagine we have four messages: 2it 4will 2be 4fine
-// Visually:
-//
-// Append("2it4wi"): A message and a bit:
-// [ 2it 4wi ]
-// ^R ^W
-//
-// After the ReadMessage(), the 1st message will be read, but not the 2nd.
-// [ 2it 4wi ]
-// ^R ^W
-//
-// Append("ll2be4f")
-// [ 2it 4will 2be 4f ]
-// ^R ^W
-//
-// After the ReadMessage() loop:
-// [ 2it 4will 2be 4f ]
-// ^R ^W
-// Append("ine")
-// [ 2it 4will 2be 4fine ]
-// ^R ^W
-//
-// In the next ReadMessage() the R cursor will chase the W cursor. When this
-// happens (very frequent) we can just reset both cursors to 0 and restart.
-// If we are unlucky and get to the end of the buffer, two things happen:
-// 1. We try first to recompact the buffer, moving everything left by R.
-// 2. If still there isn't enough space, we expand the buffer.
-// Given that each message is expected to be at most kMaxMsgSize (64 MB), the
-// expansion is bound at 2 * kMaxMsgSize.
-class ProtoRingBuffer {
- public:
- static constexpr size_t kMaxMsgSize = 64 * 1024 * 1024;
- struct Message {
- const uint8_t* start = nullptr;
- uint32_t len = 0;
- uint32_t field_id = 0;
- bool fatal_framing_error = false;
- const uint8_t* end() const { return start + len; }
- inline bool valid() const { return !!start; }
- };
-
- ProtoRingBuffer();
- ~ProtoRingBuffer();
- ProtoRingBuffer(const ProtoRingBuffer&) = delete;
- ProtoRingBuffer& operator=(const ProtoRingBuffer&) = delete;
-
- // Appends data into the ring buffer, recompacting or resizing it if needed.
- // Will invaildate the pointers previously handed out.
- void Append(const void* data, size_t len);
-
- // If a protobuf message can be read, it returns the boundaries of the message
- // (without including the preamble) and advances the read cursor.
- // If no message is avaiable, returns a null range.
- // The returned pointer is only valid until the next call to Append(), as
- // that can recompact or resize the underlying buffer.
- Message ReadMessage();
-
- // Exposed for testing.
- size_t capacity() const { return buf_.size(); }
- size_t avail() const { return buf_.size() - (wr_ - rd_); }
-
- private:
- base::PagedMemory buf_;
- Message fastpath_{};
- bool failed_ = false; // Set in case of an unrecoverable framing faiulre.
- size_t rd_ = 0; // Offset of the read cursor in |buf_|.
- size_t wr_ = 0; // Offset of the write cursor in |buf_|.
-};
-
-} // namespace trace_processor
-} // namespace perfetto
-
-#endif // SRC_TRACE_PROCESSOR_RPC_PROTO_RING_BUFFER_H_
diff --git a/src/trace_processor/rpc/proto_ring_buffer_unittest.cc b/src/trace_processor/rpc/proto_ring_buffer_unittest.cc
deleted file mode 100644
index 0e3944cda..000000000
--- a/src/trace_processor/rpc/proto_ring_buffer_unittest.cc
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/trace_processor/rpc/proto_ring_buffer.h"
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <list>
-#include <ostream>
-#include <random>
-#include <vector>
-
-#include "perfetto/ext/base/utils.h"
-#include "perfetto/protozero/proto_utils.h"
-#include "test/gtest_and_gmock.h"
-
-using testing::ElementsAre;
-
-namespace perfetto {
-namespace trace_processor {
-
-// For ASSERT_EQ()
-inline bool operator==(const ProtoRingBuffer::Message& a,
- const ProtoRingBuffer::Message& b) {
- if (a.field_id != b.field_id || a.len != b.len || a.valid() != b.valid())
- return false;
- if (!a.valid())
- return true;
- return memcmp(a.start, b.start, a.len) == 0;
-}
-
-inline std::ostream& operator<<(std::ostream& stream,
- const ProtoRingBuffer::Message& msg) {
- stream << "Message{field_id:" << msg.field_id << ", len:" << msg.len;
- stream << ", payload: \"";
- static constexpr uint32_t kTruncLen = 16;
- for (uint32_t i = 0; i < std::min(msg.len, kTruncLen); i++)
- stream << static_cast<char>(msg.start[i]);
- if (msg.len > kTruncLen)
- stream << "...";
- stream << "\"}";
- return stream;
-}
-
-namespace {
-
-constexpr uint32_t kMaxMsgSize = ProtoRingBuffer::kMaxMsgSize;
-
-class ProtoRingBufferTest : public ::testing::Test {
- public:
- ProtoRingBuffer::Message MakeProtoMessage(uint32_t field_id,
- uint32_t len,
- bool append = false) {
- ProtoRingBuffer::Message msg{};
- namespace proto_utils = protozero::proto_utils;
- const uint8_t* initial_ptr = last_msg_.data();
- if (!append)
- last_msg_.clear();
- size_t initial_size = last_msg_.size();
-
- // 20 is an over-estimation of the preamble (fixed by the 2nd resize below).
- last_msg_.resize(initial_size + len + 20);
- uint8_t* wptr = &last_msg_[initial_size];
- auto tag = proto_utils::MakeTagLengthDelimited(field_id);
- wptr = proto_utils::WriteVarInt(tag, wptr);
- wptr = proto_utils::WriteVarInt(len, wptr);
- msg.start = wptr;
- msg.len = len;
- msg.field_id = field_id;
- for (uint32_t i = 0; i < len; i++)
- *(wptr++) = '0' + ((len + i) % 73); // 73 prime for more unique patterns.
-
- PERFETTO_CHECK(wptr <= &last_msg_.back());
- last_msg_.resize(static_cast<size_t>(wptr - &last_msg_[0]));
-
- // Vector must not expand, because the returned Mesdage relies on pointer
- // stability. The TEST_F must reserve enough capacity.
- if (append)
- PERFETTO_CHECK(last_msg_.data() == initial_ptr);
- return msg;
- }
-
- std::vector<uint8_t> last_msg_;
-};
-
-// Test that when appending buffers that contain whole messages the ring buffer
-// is skipped.
-TEST_F(ProtoRingBufferTest, Fastpath) {
- ProtoRingBuffer buf;
- for (uint32_t i = 0; i < 10; i++) {
- // Write a whole message that hits the fastpath.
- auto expected = MakeProtoMessage(/*field_id=*/i + 1, /*len=*/i * 7);
- buf.Append(last_msg_.data(), last_msg_.size());
- // Shouln't take any space the buffer because it hits the fastpath.
- EXPECT_EQ(buf.avail(), buf.capacity());
- auto actual = buf.ReadMessage();
- ASSERT_TRUE(actual.valid());
- EXPECT_EQ(actual.start, expected.start); // Should point to the same buf.
- EXPECT_EQ(actual, expected);
-
- // Now write a message in two fragments. It won't hit the fastpath
- expected = MakeProtoMessage(/*field_id*/ 1, /*len=*/32);
- buf.Append(last_msg_.data(), 13);
- EXPECT_LT(buf.avail(), buf.capacity());
- EXPECT_FALSE(buf.ReadMessage().valid());
-
- // Append 2nd fragment.
- buf.Append(last_msg_.data() + 13, last_msg_.size() - 13);
- actual = buf.ReadMessage();
- ASSERT_TRUE(actual.valid());
- EXPECT_EQ(actual, expected);
- }
-}
-
-TEST_F(ProtoRingBufferTest, CoalescingStream) {
- ProtoRingBuffer buf;
- last_msg_.reserve(1024);
- std::list<ProtoRingBuffer::Message> expected;
-
- // Build 6 messages of 100 bytes each (100 does not include preambles).
- for (uint32_t i = 1; i <= 6; i++)
- expected.emplace_back(MakeProtoMessage(i, 100, /*append=*/true));
-
- uint32_t frag_lens[] = {120, 20, 471, 1};
- uint32_t frag_sum = 0;
- for (uint32_t i = 0; i < base::ArraySize(frag_lens); i++)
- frag_sum += frag_lens[i];
- ASSERT_EQ(frag_sum, last_msg_.size());
-
- // Append the messages in such a way that each appen either passes a portion
- // of a message (the 20 ones) or more than a message.
- uint32_t written = 0;
- for (uint32_t i = 0; i < base::ArraySize(frag_lens); i++) {
- buf.Append(&last_msg_[written], frag_lens[i]);
- written += frag_lens[i];
- for (;;) {
- auto msg = buf.ReadMessage();
- if (!msg.valid())
- break;
- ASSERT_FALSE(expected.empty());
- ASSERT_EQ(expected.front(), msg);
- expected.pop_front();
- }
- }
- EXPECT_TRUE(expected.empty());
-}
-
-TEST_F(ProtoRingBufferTest, RandomSizes) {
- ProtoRingBuffer buf;
- std::minstd_rand0 rnd(0);
-
- last_msg_.reserve(1024 * 1024 * 64);
- std::list<ProtoRingBuffer::Message> expected;
-
- const uint32_t kNumMsg = 100;
- for (uint32_t i = 0; i < kNumMsg; i++) {
- uint32_t field_id = static_cast<uint32_t>(1 + (rnd() % 1024u));
- uint32_t rndval = static_cast<uint32_t>(rnd());
- uint32_t len = 1 + (rndval % 1024);
- if ((rndval % 100) < 2) {
- len *= 10 * 1024; // 2% of messages will get close to kMaxMsgSize
- } else if ((rndval % 100) < 20) {
- len *= 512; // 18% will be around 500K;
- }
- len = std::max(std::min(len, kMaxMsgSize), 1u);
- expected.push_back(MakeProtoMessage(field_id, len, /*append=*/true));
- }
-
- uint32_t total = static_cast<uint32_t>(last_msg_.size());
- for (uint32_t frag_sum = 0; frag_sum < total;) {
- uint32_t frag_len = static_cast<uint32_t>(1 + (rnd() % 32768));
- frag_len = std::min(frag_len, total - frag_sum);
- buf.Append(&last_msg_[frag_sum], frag_len);
- frag_sum += frag_len;
- for (;;) {
- auto msg = buf.ReadMessage();
- if (!msg.valid())
- break;
- ASSERT_FALSE(expected.empty());
- ASSERT_EQ(expected.front(), msg);
- expected.pop_front();
- }
- }
- EXPECT_TRUE(expected.empty());
-}
-
-TEST_F(ProtoRingBufferTest, HandleProtoErrorsGracefully) {
- ProtoRingBuffer buf;
-
- // Apppend a partial valid 32 byte message, followed by some invalild
- // data.
- auto expected = MakeProtoMessage(1, 32);
- buf.Append(last_msg_.data(), last_msg_.size() - 1);
- auto msg = buf.ReadMessage();
- EXPECT_FALSE(msg.valid());
- EXPECT_FALSE(msg.fatal_framing_error);
-
- uint8_t invalid[] = {0x7f, 0x7f, 0x7f, 0x7f};
- invalid[0] = last_msg_.back();
- buf.Append(invalid, sizeof(invalid));
-
- // The first message shoudl be valild
- msg = buf.ReadMessage();
- EXPECT_EQ(msg, expected);
-
- // All the rest should be a framing error.
- for (int i = 0; i < 3; i++) {
- msg = buf.ReadMessage();
- EXPECT_FALSE(msg.valid());
- EXPECT_TRUE(msg.fatal_framing_error);
-
- buf.Append(invalid, sizeof(invalid));
- }
-}
-
-} // namespace
-} // namespace trace_processor
-} // namespace perfetto
diff --git a/src/trace_processor/rpc/query_result_serializer.cc b/src/trace_processor/rpc/query_result_serializer.cc
index f6042fd9c..d3b9ba2e1 100644
--- a/src/trace_processor/rpc/query_result_serializer.cc
+++ b/src/trace_processor/rpc/query_result_serializer.cc
@@ -62,9 +62,9 @@ bool QueryResultSerializer::Serialize(std::vector<uint8_t>* buf) {
bool QueryResultSerializer::Serialize(protos::pbzero::QueryResult* res) {
PERFETTO_CHECK(!eof_reached_);
- if (!did_write_column_names_) {
- SerializeColumnNames(res);
- did_write_column_names_ = true;
+ if (!did_write_metadata_) {
+ SerializeMetadata(res);
+ did_write_metadata_ = true;
}
// In case of an error we still want to go through SerializeBatch(). That will
@@ -258,11 +258,13 @@ void QueryResultSerializer::MaybeSerializeError(
res->set_error(err);
}
-void QueryResultSerializer::SerializeColumnNames(
+void QueryResultSerializer::SerializeMetadata(
protos::pbzero::QueryResult* res) {
- PERFETTO_DCHECK(!did_write_column_names_);
+ PERFETTO_DCHECK(!did_write_metadata_);
for (uint32_t c = 0; c < num_cols_; c++)
res->add_column_names(iter_->GetColumnName(c));
+ res->set_statement_count(iter_->StatementCount());
+ res->set_statement_with_output_count(iter_->StatementCountWithOutput());
}
} // namespace trace_processor
diff --git a/src/trace_processor/rpc/query_result_serializer.h b/src/trace_processor/rpc/query_result_serializer.h
index 9c05e0bff..6cc55df03 100644
--- a/src/trace_processor/rpc/query_result_serializer.h
+++ b/src/trace_processor/rpc/query_result_serializer.h
@@ -53,6 +53,7 @@ class IteratorImpl;
// chunked-encoded HTTP response, or through a repetition of Wasm calls.
class QueryResultSerializer {
public:
+ static constexpr uint32_t kDefaultBatchSplitThreshold = 128 * 1024;
explicit QueryResultSerializer(Iterator);
~QueryResultSerializer();
@@ -75,13 +76,13 @@ class QueryResultSerializer {
}
private:
- void SerializeColumnNames(protos::pbzero::QueryResult*);
+ void SerializeMetadata(protos::pbzero::QueryResult*);
void SerializeBatch(protos::pbzero::QueryResult*);
void MaybeSerializeError(protos::pbzero::QueryResult*);
std::unique_ptr<IteratorImpl> iter_;
const uint32_t num_cols_;
- bool did_write_column_names_ = false;
+ bool did_write_metadata_ = false;
bool eof_reached_ = false;
uint32_t col_ = UINT32_MAX;
@@ -92,7 +93,7 @@ class QueryResultSerializer {
// the limit (it splits on the next row *after* the limit is hit).
// Overridable for testing only.
uint32_t cells_per_batch_ = 50000;
- uint32_t batch_split_threshold_ = 1024 * 128;
+ uint32_t batch_split_threshold_ = kDefaultBatchSplitThreshold;
};
} // namespace trace_processor
diff --git a/src/trace_processor/rpc/query_result_serializer_unittest.cc b/src/trace_processor/rpc/query_result_serializer_unittest.cc
index a6554104a..85c882dbd 100644
--- a/src/trace_processor/rpc/query_result_serializer_unittest.cc
+++ b/src/trace_processor/rpc/query_result_serializer_unittest.cc
@@ -408,7 +408,7 @@ TEST(QueryResultSerializerTest, ErrorBeforeStartingQuery) {
TestDeserializer deser;
deser.SerializeAndDeserialize(&ser);
EXPECT_EQ(deser.cells.size(), 0u);
- EXPECT_EQ(deser.error, "incomplete input");
+ EXPECT_EQ(deser.error, "incomplete input (errcode: 1)");
EXPECT_TRUE(deser.eof_reached);
}
diff --git a/src/trace_processor/rpc/rpc.cc b/src/trace_processor/rpc/rpc.cc
index 7a9a5959b..a58cd7cc4 100644
--- a/src/trace_processor/rpc/rpc.cc
+++ b/src/trace_processor/rpc/rpc.cc
@@ -16,38 +16,258 @@
#include "src/trace_processor/rpc/rpc.h"
+#include <string.h>
+
#include <vector>
+#include "perfetto/base/logging.h"
#include "perfetto/base/time.h"
+#include "perfetto/ext/base/utils.h"
+#include "perfetto/ext/base/version.h"
#include "perfetto/protozero/scattered_heap_buffer.h"
+#include "perfetto/protozero/scattered_stream_writer.h"
#include "perfetto/trace_processor/trace_processor.h"
-#include "protos/perfetto/trace_processor/trace_processor.pbzero.h"
+#include "src/protozero/proto_ring_buffer.h"
#include "src/trace_processor/rpc/query_result_serializer.h"
#include "src/trace_processor/tp_metatrace.h"
+#include "protos/perfetto/trace_processor/trace_processor.pbzero.h"
+
namespace perfetto {
namespace trace_processor {
-using ColumnValues = protos::pbzero::RawQueryResult::ColumnValues;
-using ColumnDesc = protos::pbzero::RawQueryResult::ColumnDesc;
-
+namespace {
// Writes a "Loading trace ..." update every N bytes.
constexpr size_t kProgressUpdateBytes = 50 * 1000 * 1000;
+using TraceProcessorRpcStream = protos::pbzero::TraceProcessorRpcStream;
+using RpcProto = protos::pbzero::TraceProcessorRpc;
+
+// Most RPC messages are either very small or a query results.
+// QueryResultSerializer splits rows into batches of approximately 128KB. Try
+// avoid extra heap allocations for the nominal case.
+constexpr auto kSliceSize =
+ QueryResultSerializer::kDefaultBatchSplitThreshold + 4096;
+
+// Holds a trace_processor::TraceProcessorRpc pbzero message. Avoids extra
+// copies by doing direct scattered calls from the fragmented heap buffer onto
+// the RpcResponseFunction (the receiver is expected to deal with arbitrary
+// fragmentation anyways). It also takes care of prefixing each message with
+// the proto preamble and varint size.
+class Response {
+ public:
+ Response(int64_t seq, int method);
+ Response(const Response&) = delete;
+ Response& operator=(const Response&) = delete;
+ RpcProto* operator->() { return msg_; }
+ void Send(Rpc::RpcResponseFunction);
+
+ private:
+ RpcProto* msg_ = nullptr;
+
+ // The reason why we use TraceProcessorRpcStream as root message is because
+ // the RPC wire protocol expects each message to be prefixed with a proto
+ // preamble and varint size. This happens to be the same serialization of a
+ // repeated field (this is really the same trick we use between
+ // Trace and TracePacket in trace.proto)
+ protozero::HeapBuffered<TraceProcessorRpcStream> buf_;
+};
+
+Response::Response(int64_t seq, int method) : buf_(kSliceSize, kSliceSize) {
+ msg_ = buf_->add_msg();
+ msg_->set_seq(seq);
+ msg_->set_response(static_cast<RpcProto::TraceProcessorMethod>(method));
+}
+
+void Response::Send(Rpc::RpcResponseFunction send_fn) {
+ buf_->Finalize();
+ for (const auto& slice : buf_.GetSlices()) {
+ auto range = slice.GetUsedRange();
+ send_fn(range.begin, static_cast<uint32_t>(range.size()));
+ }
+}
+
+} // namespace
Rpc::Rpc(std::unique_ptr<TraceProcessor> preloaded_instance)
- : trace_processor_(std::move(preloaded_instance)) {}
+ : trace_processor_(std::move(preloaded_instance)) {
+ if (!trace_processor_)
+ ResetTraceProcessor();
+}
Rpc::Rpc() : Rpc(nullptr) {}
-
Rpc::~Rpc() = default;
+void Rpc::ResetTraceProcessor() {
+ trace_processor_ = TraceProcessor::CreateInstance(Config());
+ bytes_parsed_ = bytes_last_progress_ = 0;
+ t_parse_started_ = base::GetWallTimeNs().count();
+ // Deliberately not resetting the RPC channel state (rxbuf_, {tx,rx}_seq_id_).
+ // This is invoked from the same client to clear the current trace state
+ // before loading a new one. The IPC channel is orthogonal to that and the
+ // message numbering continues regardless of the reset.
+}
+
+void Rpc::OnRpcRequest(const void* data, size_t len) {
+ rxbuf_.Append(data, len);
+ for (;;) {
+ auto msg = rxbuf_.ReadMessage();
+ if (!msg.valid()) {
+ if (msg.fatal_framing_error) {
+ protozero::HeapBuffered<TraceProcessorRpcStream> err_msg;
+ err_msg->add_msg()->set_fatal_error("RPC framing error");
+ auto err = err_msg.SerializeAsArray();
+ rpc_response_fn_(err.data(), static_cast<uint32_t>(err.size()));
+ rpc_response_fn_(nullptr, 0); // Disconnect.
+ }
+ break;
+ }
+ ParseRpcRequest(msg.start, msg.len);
+ }
+}
+
+// [data, len] here is a tokenized TraceProcessorRpc proto message, without the
+// size header.
+void Rpc::ParseRpcRequest(const uint8_t* data, size_t len) {
+ RpcProto::Decoder req(data, len);
+
+ // We allow restarting the sequence from 0. This happens when refreshing the
+ // browser while using the external trace_processor_shell --httpd.
+ if (req.seq() != 0 && rx_seq_id_ != 0 && req.seq() != rx_seq_id_ + 1) {
+ char err_str[255];
+ // "(ERR:rpc_seq)" is intercepted by error_dialog.ts in the UI.
+ sprintf(err_str,
+ "RPC request out of order. Expected %" PRId64 ", got %" PRId64
+ " (ERR:rpc_seq)",
+ rx_seq_id_ + 1, req.seq());
+ PERFETTO_ELOG("%s", err_str);
+ protozero::HeapBuffered<TraceProcessorRpcStream> err_msg;
+ err_msg->add_msg()->set_fatal_error(err_str);
+ auto err = err_msg.SerializeAsArray();
+ rpc_response_fn_(err.data(), static_cast<uint32_t>(err.size()));
+ rpc_response_fn_(nullptr, 0); // Disconnect.
+ return;
+ }
+ rx_seq_id_ = req.seq();
+
+ // The static cast is to prevent that the compiler breaks future proofness.
+ const int req_type = static_cast<int>(req.request());
+ static const char kErrFieldNotSet[] = "RPC error: request field not set";
+ switch (req_type) {
+ case RpcProto::TPM_APPEND_TRACE_DATA: {
+ Response resp(tx_seq_id_++, req_type);
+ auto* result = resp->set_append_result();
+ if (!req.has_append_trace_data()) {
+ result->set_error(kErrFieldNotSet);
+ } else {
+ protozero::ConstBytes byte_range = req.append_trace_data();
+ util::Status res = Parse(byte_range.data, byte_range.size);
+ if (!res.ok()) {
+ result->set_error(res.message());
+ }
+ }
+ resp.Send(rpc_response_fn_);
+ break;
+ }
+ case RpcProto::TPM_FINALIZE_TRACE_DATA: {
+ Response resp(tx_seq_id_++, req_type);
+ NotifyEndOfFile();
+ resp.Send(rpc_response_fn_);
+ break;
+ }
+ case RpcProto::TPM_QUERY_STREAMING: {
+ if (!req.has_query_args()) {
+ Response resp(tx_seq_id_++, req_type);
+ auto* result = resp->set_query_result();
+ result->set_error(kErrFieldNotSet);
+ resp.Send(rpc_response_fn_);
+ } else {
+ protozero::ConstBytes args = req.query_args();
+ auto it = QueryInternal(args.data, args.size);
+ QueryResultSerializer serializer(std::move(it));
+ for (bool has_more = true; has_more;) {
+ Response resp(tx_seq_id_++, req_type);
+ has_more = serializer.Serialize(resp->set_query_result());
+ resp.Send(rpc_response_fn_);
+ }
+ }
+ break;
+ }
+ case RpcProto::TPM_QUERY_RAW_DEPRECATED: {
+ Response resp(tx_seq_id_++, req_type);
+ auto* result = resp->set_raw_query_result();
+ if (!req.has_raw_query_args()) {
+ result->set_error(kErrFieldNotSet);
+ } else {
+ protozero::ConstBytes args = req.raw_query_args();
+ RawQueryInternal(args.data, args.size, result);
+ }
+ resp.Send(rpc_response_fn_);
+ break;
+ }
+ case RpcProto::TPM_COMPUTE_METRIC: {
+ Response resp(tx_seq_id_++, req_type);
+ auto* result = resp->set_metric_result();
+ if (!req.has_compute_metric_args()) {
+ result->set_error(kErrFieldNotSet);
+ } else {
+ protozero::ConstBytes args = req.compute_metric_args();
+ ComputeMetricInternal(args.data, args.size, result);
+ }
+ resp.Send(rpc_response_fn_);
+ break;
+ }
+ case RpcProto::TPM_GET_METRIC_DESCRIPTORS: {
+ Response resp(tx_seq_id_++, req_type);
+ auto descriptor_set = trace_processor_->GetMetricDescriptors();
+ auto* result = resp->set_metric_descriptors();
+ result->AppendRawProtoBytes(descriptor_set.data(), descriptor_set.size());
+ resp.Send(rpc_response_fn_);
+ break;
+ }
+ case RpcProto::TPM_RESTORE_INITIAL_TABLES: {
+ trace_processor_->RestoreInitialTables();
+ Response resp(tx_seq_id_++, req_type);
+ resp.Send(rpc_response_fn_);
+ break;
+ }
+ case RpcProto::TPM_ENABLE_METATRACE: {
+ trace_processor_->EnableMetatrace();
+ Response resp(tx_seq_id_++, req_type);
+ resp.Send(rpc_response_fn_);
+ break;
+ }
+ case RpcProto::TPM_DISABLE_AND_READ_METATRACE: {
+ Response resp(tx_seq_id_++, req_type);
+ DisableAndReadMetatraceInternal(resp->set_metatrace());
+ resp.Send(rpc_response_fn_);
+ break;
+ }
+ case RpcProto::TPM_GET_STATUS: {
+ Response resp(tx_seq_id_++, req_type);
+ std::vector<uint8_t> status = GetStatus();
+ resp->set_status()->AppendRawProtoBytes(status.data(), status.size());
+ resp.Send(rpc_response_fn_);
+ break;
+ }
+ default: {
+ // This can legitimately happen if the client is newer. We reply with a
+ // generic "unkown request" response, so the client can do feature
+ // detection
+ PERFETTO_DLOG("[RPC] Uknown request type (%d), size=%zu", req_type, len);
+ Response resp(tx_seq_id_++, req_type);
+ resp->set_invalid_request(
+ static_cast<RpcProto::TraceProcessorMethod>(req_type));
+ resp.Send(rpc_response_fn_);
+ break;
+ }
+ } // switch(req_type)
+}
+
util::Status Rpc::Parse(const uint8_t* data, size_t len) {
if (eof_) {
- // Reset the trace processor state if this is either the first call ever or
- // if another trace has been previously fully loaded.
- trace_processor_ = TraceProcessor::CreateInstance(Config());
- bytes_parsed_ = bytes_last_progress_ = 0;
- t_parse_started_ = base::GetWallTimeNs().count();
+ // Reset the trace processor state if another trace has been previously
+ // loaded.
+ ResetTraceProcessor();
}
eof_ = false;
@@ -64,8 +284,6 @@ util::Status Rpc::Parse(const uint8_t* data, size_t len) {
}
void Rpc::NotifyEndOfFile() {
- if (!trace_processor_)
- return;
trace_processor_->NotifyEndOfFile();
eof_ = true;
MaybePrintProgress();
@@ -88,23 +306,7 @@ void Rpc::MaybePrintProgress() {
void Rpc::Query(const uint8_t* args,
size_t len,
QueryResultBatchCallback result_callback) {
- protos::pbzero::RawQueryArgs::Decoder query(args, len);
- std::string sql = query.sql_query().ToStdString();
- PERFETTO_DLOG("[RPC] Query < %s", sql.c_str());
- PERFETTO_TP_TRACE("RPC_QUERY",
- [&](metatrace::Record* r) { r->AddArg("SQL", sql); });
-
- if (!trace_processor_) {
- static const char kErr[] = "Query() called before Parse()";
- PERFETTO_ELOG("[RPC] %s", kErr);
- protozero::HeapBuffered<protos::pbzero::QueryResult> result;
- result->set_error(kErr);
- auto vec = result.SerializeAsArray();
- result_callback(vec.data(), vec.size(), /*has_more=*/false);
- return;
- }
-
- auto it = trace_processor_->ExecuteQuery(sql.c_str());
+ auto it = QueryInternal(args, len);
QueryResultSerializer serializer(std::move(it));
std::vector<uint8_t> res;
@@ -115,21 +317,34 @@ void Rpc::Query(const uint8_t* args,
}
}
+Iterator Rpc::QueryInternal(const uint8_t* args, size_t len) {
+ protos::pbzero::RawQueryArgs::Decoder query(args, len);
+ std::string sql = query.sql_query().ToStdString();
+ PERFETTO_DLOG("[RPC] Query < %s", sql.c_str());
+ PERFETTO_TP_TRACE("RPC_QUERY",
+ [&](metatrace::Record* r) { r->AddArg("SQL", sql); });
+
+ return trace_processor_->ExecuteQuery(sql.c_str());
+}
+
std::vector<uint8_t> Rpc::RawQuery(const uint8_t* args, size_t len) {
protozero::HeapBuffered<protos::pbzero::RawQueryResult> result;
+ RawQueryInternal(args, len, result.get());
+ return result.SerializeAsArray();
+}
+
+void Rpc::RawQueryInternal(const uint8_t* args,
+ size_t len,
+ protos::pbzero::RawQueryResult* result) {
+ using ColumnValues = protos::pbzero::RawQueryResult::ColumnValues;
+ using ColumnDesc = protos::pbzero::RawQueryResult::ColumnDesc;
+
protos::pbzero::RawQueryArgs::Decoder query(args, len);
std::string sql = query.sql_query().ToStdString();
PERFETTO_DLOG("[RPC] RawQuery < %s", sql.c_str());
PERFETTO_TP_TRACE("RPC_RAW_QUERY",
[&](metatrace::Record* r) { r->AddArg("SQL", sql); });
- if (!trace_processor_) {
- static const char kErr[] = "RawQuery() called before Parse()";
- PERFETTO_ELOG("[RPC] %s", kErr);
- result->set_error(kErr);
- return result.SerializeAsArray();
- }
-
auto it = trace_processor_->ExecuteQuery(sql.c_str());
// This vector contains a standalone protozero message per column. The problem
@@ -244,28 +459,21 @@ std::vector<uint8_t> Rpc::RawQuery(const uint8_t* args, size_t len) {
if (!status.ok())
result->set_error(status.c_message());
PERFETTO_DLOG("[RPC] RawQuery > %d rows (err: %d)", rows, !status.ok());
-
- return result.SerializeAsArray();
-}
-
-std::string Rpc::GetCurrentTraceName() {
- if (!trace_processor_)
- return "";
- return trace_processor_->GetCurrentTraceName();
}
void Rpc::RestoreInitialTables() {
- if (trace_processor_)
- trace_processor_->RestoreInitialTables();
+ trace_processor_->RestoreInitialTables();
}
-std::vector<uint8_t> Rpc::ComputeMetric(const uint8_t* data, size_t len) {
+std::vector<uint8_t> Rpc::ComputeMetric(const uint8_t* args, size_t len) {
protozero::HeapBuffered<protos::pbzero::ComputeMetricResult> result;
- if (!trace_processor_) {
- result->set_error("Null trace processor instance");
- return result.SerializeAsArray();
- }
+ ComputeMetricInternal(args, len, result.get());
+ return result.SerializeAsArray();
+}
+void Rpc::ComputeMetricInternal(const uint8_t* data,
+ size_t len,
+ protos::pbzero::ComputeMetricResult* result) {
protos::pbzero::ComputeMetricArgs::Decoder args(data, len);
std::vector<std::string> metric_names;
for (auto it = args.metric_names(); it; ++it) {
@@ -279,15 +487,16 @@ std::vector<uint8_t> Rpc::ComputeMetric(const uint8_t* data, size_t len) {
}
});
+ PERFETTO_DLOG("[RPC] ComputeMetrics(%zu, %s), format=%d", metric_names.size(),
+ metric_names.empty() ? "" : metric_names.front().c_str(),
+ args.format());
switch (args.format()) {
case protos::pbzero::ComputeMetricArgs::BINARY_PROTOBUF: {
std::vector<uint8_t> metrics_proto;
util::Status status =
trace_processor_->ComputeMetric(metric_names, &metrics_proto);
if (status.ok()) {
- result->AppendBytes(
- protos::pbzero::ComputeMetricResult::kMetricsFieldNumber,
- metrics_proto.data(), metrics_proto.size());
+ result->set_metrics(metrics_proto.data(), metrics_proto.size());
} else {
result->set_error(status.message());
}
@@ -299,44 +508,27 @@ std::vector<uint8_t> Rpc::ComputeMetric(const uint8_t* data, size_t len) {
metric_names, TraceProcessor::MetricResultFormat::kProtoText,
&metrics_string);
if (status.ok()) {
- result->AppendString(
- protos::pbzero::ComputeMetricResult::kMetricsAsPrototextFieldNumber,
- metrics_string);
+ result->set_metrics_as_prototext(metrics_string);
} else {
result->set_error(status.message());
}
break;
}
}
- return result.SerializeAsArray();
-}
-
-std::vector<uint8_t> Rpc::GetMetricDescriptors(const uint8_t*, size_t) {
- protozero::HeapBuffered<protos::pbzero::GetMetricDescriptorsResult> result;
- if (!trace_processor_) {
- return result.SerializeAsArray();
- }
- std::vector<uint8_t> descriptor_set =
- trace_processor_->GetMetricDescriptors();
- result->AppendBytes(
- protos::pbzero::GetMetricDescriptorsResult::kDescriptorSetFieldNumber,
- descriptor_set.data(), descriptor_set.size());
- return result.SerializeAsArray();
}
void Rpc::EnableMetatrace() {
- if (!trace_processor_)
- return;
trace_processor_->EnableMetatrace();
}
std::vector<uint8_t> Rpc::DisableAndReadMetatrace() {
protozero::HeapBuffered<protos::pbzero::DisableAndReadMetatraceResult> result;
- if (!trace_processor_) {
- result->set_error("Null trace processor instance");
- return result.SerializeAsArray();
- }
+ DisableAndReadMetatraceInternal(result.get());
+ return result.SerializeAsArray();
+}
+void Rpc::DisableAndReadMetatraceInternal(
+ protos::pbzero::DisableAndReadMetatraceResult* result) {
std::vector<uint8_t> trace_proto;
util::Status status = trace_processor_->DisableAndReadMetatrace(&trace_proto);
if (status.ok()) {
@@ -344,7 +536,14 @@ std::vector<uint8_t> Rpc::DisableAndReadMetatrace() {
} else {
result->set_error(status.message());
}
- return result.SerializeAsArray();
+}
+
+std::vector<uint8_t> Rpc::GetStatus() {
+ protozero::HeapBuffered<protos::pbzero::StatusResult> status;
+ status->set_loaded_trace_name(trace_processor_->GetCurrentTraceName());
+ status->set_human_readable_version(base::GetVersionString());
+ status->set_api_version(protos::pbzero::TRACE_PROCESSOR_CURRENT_API_VERSION);
+ return status.SerializeAsArray();
}
} // namespace trace_processor
diff --git a/src/trace_processor/rpc/rpc.h b/src/trace_processor/rpc/rpc.h
index bddc1aa7e..8501b562c 100644
--- a/src/trace_processor/rpc/rpc.h
+++ b/src/trace_processor/rpc/rpc.h
@@ -25,10 +25,21 @@
#include <stdint.h>
#include "perfetto/trace_processor/status.h"
+#include "src/protozero/proto_ring_buffer.h"
namespace perfetto {
+
+namespace protos {
+namespace pbzero {
+class RawQueryResult;
+class ComputeMetricResult;
+class DisableAndReadMetatraceResult;
+} // namespace pbzero
+} // namespace protos
+
namespace trace_processor {
+class Iterator;
class TraceProcessor;
// This class handles the binary {,un}marshalling for the Trace Processor RPC
@@ -54,17 +65,53 @@ class Rpc {
Rpc();
~Rpc();
+ // 1. TraceProcessor byte-pipe RPC interface.
+ // This is a bidirectional channel with a remote TraceProcessor instance. All
+ // it needs is a byte-oriented pipe (e.g., a TCP socket, a pipe(2) between two
+ // processes or a postmessage channel in the JS+Wasm case). The messages
+ // exchanged on these pipes are TraceProcessorRpc protos (defined in
+ // trace_processor.proto). This has been introduced in Perfetto v15.
+
+ // Pushes data received by the RPC channel into the parser. Inbound messages
+ // are tokenized and turned into TraceProcessor method invocations. |data|
+ // does not need to be a whole TraceProcessorRpc message. It can be a portion
+ // of it or a union of >1 messages.
+ // Responses are sent throught the RpcResponseFunction (below).
+ void OnRpcRequest(const void* data, size_t len);
+
+ // The size argument is a uint32_t and not size_t to avoid ABI mismatches
+ // with Wasm, where size_t = uint32_t.
+ // (nullptr, 0) has the semantic of "close the channel" and is issued when an
+ // unrecoverable wire-protocol framing error is detected.
+ using RpcResponseFunction = void (*)(const void* /*data*/, uint32_t /*len*/);
+ void SetRpcResponseFunction(RpcResponseFunction f) { rpc_response_fn_ = f; }
+
+ // 2. TraceProcessor legacy RPC endpoints.
+ // The methods below are exposed for the old RPC interfaces, where each RPC
+ // implementation deals with the method demuxing: (i) wasm_bridge.cc has one
+ // exported C function per method (going away soon); (ii) httpd.cc has one
+ // REST endpoint per method. Over time this turned out to have too much
+ // duplicated boilerplate and we moved to the byte-pipe model above.
+ // We still keep these endpoints around, because httpd.cc still exposes the
+ // individual REST endpoints to legacy clients (TP's Python API). The
+ // mainteinance cost of those is very low. Both the new byte-pipe and the
+ // old endpoints run exactly the same code. The {de,}serialization format is
+ // the same, the only difference is only who does the method demuxing.
// The methods of this class are mirrors (modulo {un,}marshalling of args) of
// the corresponding names in trace_processor.h . See that header for docs.
util::Status Parse(const uint8_t* data, size_t len);
void NotifyEndOfFile();
- void RestoreInitialTables();
std::string GetCurrentTraceName();
std::vector<uint8_t> ComputeMetric(const uint8_t* data, size_t len);
- std::vector<uint8_t> GetMetricDescriptors(const uint8_t* data, size_t len);
void EnableMetatrace();
std::vector<uint8_t> DisableAndReadMetatrace();
+ std::vector<uint8_t> GetStatus();
+
+ // Creates a new RPC session by deleting all tables and views that have been
+ // created (by the UI or user) after the trace was loaded; built-in
+ // tables/view created by the ingestion process are preserved.
+ void RestoreInitialTables();
// Runs a query and returns results in batch. Each batch is a proto-encoded
// TraceProcessor.QueryResult message and contains a variable number of rows.
@@ -87,10 +134,25 @@ class Rpc {
std::vector<uint8_t> RawQuery(const uint8_t* args, size_t len);
private:
+ void ParseRpcRequest(const uint8_t* data, size_t len);
+ void ResetTraceProcessor();
void MaybePrintProgress();
+ Iterator QueryInternal(const uint8_t* args, size_t len);
+ void RawQueryInternal(const uint8_t* args,
+ size_t len,
+ protos::pbzero::RawQueryResult*);
+ void ComputeMetricInternal(const uint8_t* args,
+ size_t len,
+ protos::pbzero::ComputeMetricResult*);
+ void DisableAndReadMetatraceInternal(
+ protos::pbzero::DisableAndReadMetatraceResult*);
std::unique_ptr<TraceProcessor> trace_processor_;
- bool eof_ = true; // Reset when calling Parse().
+ RpcResponseFunction rpc_response_fn_;
+ protozero::ProtoRingBuffer rxbuf_;
+ int64_t tx_seq_id_ = 0;
+ int64_t rx_seq_id_ = 0;
+ bool eof_ = false;
int64_t t_parse_started_ = 0;
size_t bytes_last_progress_ = 0;
size_t bytes_parsed_ = 0;
diff --git a/src/trace_processor/rpc/wasm_bridge.cc b/src/trace_processor/rpc/wasm_bridge.cc
index 79e5dae78..6e266b85d 100644
--- a/src/trace_processor/rpc/wasm_bridge.cc
+++ b/src/trace_processor/rpc/wasm_bridge.cc
@@ -15,8 +15,6 @@
*/
#include <emscripten/emscripten.h>
-#include <map>
-#include <string>
#include "perfetto/base/logging.h"
#include "perfetto/trace_processor/trace_processor.h"
@@ -25,24 +23,12 @@
namespace perfetto {
namespace trace_processor {
-using RequestID = uint32_t;
-
-// Reply(): replies to a RPC method invocation.
-// Called asynchronously (i.e. in a separate task) by the C++ code inside the
-// trace processor to return data for a RPC method call.
-// The function is generic and thankfully we need just one for all methods
-// because the output is always a protobuf buffer.
-using ReplyFunction = void (*)(const char* /*proto_reply_data*/,
- uint32_t /*len*/);
-
namespace {
Rpc* g_trace_processor_rpc;
-ReplyFunction g_reply;
// The buffer used to pass the request arguments. The caller (JS) decides how
// big this buffer should be in the Initialize() call.
uint8_t* g_req_buf;
-
} // namespace
// +---------------------------------------------------------------------------+
@@ -51,71 +37,26 @@ uint8_t* g_req_buf;
extern "C" {
// Returns the address of the allocated request buffer.
-uint8_t* EMSCRIPTEN_KEEPALIVE Initialize(ReplyFunction, uint32_t);
-uint8_t* Initialize(ReplyFunction reply_function, uint32_t req_buffer_size) {
+uint8_t* EMSCRIPTEN_KEEPALIVE trace_processor_rpc_init(Rpc::RpcResponseFunction,
+ uint32_t);
+uint8_t* trace_processor_rpc_init(Rpc::RpcResponseFunction resp_function,
+ uint32_t req_buffer_size) {
g_trace_processor_rpc = new Rpc();
- g_reply = reply_function;
- g_req_buf = new uint8_t[req_buffer_size];
- return g_req_buf;
-}
-
-// Ingests trace data.
-void EMSCRIPTEN_KEEPALIVE trace_processor_parse(uint32_t);
-void trace_processor_parse(uint32_t size) {
- // TODO(primiano): Parse() makes a copy of the data, which is unfortunate.
- // Ideally there should be a way to take the Blob coming from JS and move it.
- // See https://github.com/WebAssembly/design/issues/1162.
- auto status = g_trace_processor_rpc->Parse(g_req_buf, size);
- if (status.ok()) {
- g_reply("", 0);
- } else {
- PERFETTO_FATAL("Fatal failure while parsing the trace: %s",
- status.c_message());
- }
-}
-// We keep the same signature as other methods even though we don't take input
-// arguments for simplicity.
-void EMSCRIPTEN_KEEPALIVE trace_processor_notify_eof(uint32_t);
-void trace_processor_notify_eof(uint32_t /* size, not used. */) {
- g_trace_processor_rpc->NotifyEndOfFile();
- g_reply("", 0);
-}
+ // |resp_function| is a JS-bound function passed by wasm_bridge.ts. It will
+ // call back into JavaScript. There the JS code will copy the passed
+ // buffer with the response (a proto-encoded TraceProcessorRpc message) and
+ // postMessage() it to the controller. See the comment in wasm_bridge.ts for
+ // an overview of the JS<>Wasm callstack.
+ g_trace_processor_rpc->SetRpcResponseFunction(resp_function);
-void EMSCRIPTEN_KEEPALIVE trace_processor_raw_query(uint32_t);
-void trace_processor_raw_query(uint32_t size) {
- std::vector<uint8_t> res = g_trace_processor_rpc->RawQuery(g_req_buf, size);
- g_reply(reinterpret_cast<const char*>(res.data()),
- static_cast<uint32_t>(res.size()));
-}
-
-void EMSCRIPTEN_KEEPALIVE trace_processor_compute_metric(uint32_t);
-void trace_processor_compute_metric(uint32_t size) {
- std::vector<uint8_t> res =
- g_trace_processor_rpc->ComputeMetric(g_req_buf, size);
- g_reply(reinterpret_cast<const char*>(res.data()),
- static_cast<uint32_t>(res.size()));
-}
-
-void EMSCRIPTEN_KEEPALIVE trace_processor_get_metric_descriptors(uint32_t);
-void trace_processor_get_metric_descriptors(uint32_t size) {
- std::vector<uint8_t> res =
- g_trace_processor_rpc->GetMetricDescriptors(g_req_buf, size);
- g_reply(reinterpret_cast<const char*>(res.data()),
- static_cast<uint32_t>(res.size()));
-}
-
-void EMSCRIPTEN_KEEPALIVE trace_processor_enable_metatrace(uint32_t);
-void trace_processor_enable_metatrace(uint32_t) {
- g_trace_processor_rpc->EnableMetatrace();
- g_reply("", 0);
+ g_req_buf = new uint8_t[req_buffer_size];
+ return g_req_buf;
}
-void EMSCRIPTEN_KEEPALIVE trace_processor_disable_and_read_metatrace(uint32_t);
-void trace_processor_disable_and_read_metatrace(uint32_t) {
- std::vector<uint8_t> res = g_trace_processor_rpc->DisableAndReadMetatrace();
- g_reply(reinterpret_cast<const char*>(res.data()),
- static_cast<uint32_t>(res.size()));
+void EMSCRIPTEN_KEEPALIVE trace_processor_on_rpc_request(uint32_t);
+void trace_processor_on_rpc_request(uint32_t size) {
+ g_trace_processor_rpc->OnRpcRequest(g_req_buf, size);
}
} // extern "C"
@@ -123,13 +64,13 @@ void trace_processor_disable_and_read_metatrace(uint32_t) {
} // namespace perfetto
int main(int, char**) {
- // This is unused but is needed for the following series of reason:
+ // This is unused but is needed for the following reasons:
// - We need the callMain() Emscripten JS helper function for traceconv (but
// not for trace_processor).
// - Newer versions of emscripten require that callMain is explicitly exported
// via EXTRA_EXPORTED_RUNTIME_METHODS = ['callMain'].
// - We have one set of EXTRA_EXPORTED_RUNTIME_METHODS for both
- // trace_processor.wasm (which does not need a main) and traceconv (which
+ // trace_processor.wasm (which does not need a main()) and traceconv (which
// does).
// - Without this main(), the Wasm bootstrap code will cause a JS error at
// runtime when trying to load trace_processor.js.
diff --git a/src/trace_processor/sqlite/BUILD.gn b/src/trace_processor/sqlite/BUILD.gn
index 71b691833..ed354ceff 100644
--- a/src/trace_processor/sqlite/BUILD.gn
+++ b/src/trace_processor/sqlite/BUILD.gn
@@ -17,11 +17,19 @@ import("../../../gn/test.gni")
if (enable_perfetto_trace_processor_sqlite) {
source_set("sqlite") {
sources = [
+ "create_function.cc",
+ "create_function.h",
+ "create_function_internal.cc",
+ "create_function_internal.h",
+ "create_view_function.cc",
+ "create_view_function.h",
"db_sqlite_table.cc",
"db_sqlite_table.h",
"query_cache.h",
"query_constraints.cc",
"query_constraints.h",
+ "register_function.cc",
+ "register_function.h",
"scoped_db.h",
"span_join_operator_table.cc",
"span_join_operator_table.h",
@@ -47,10 +55,12 @@ if (enable_perfetto_trace_processor_sqlite) {
"../../../include/perfetto/trace_processor",
"../../../protos/perfetto/trace/ftrace:zero",
"../../base",
+ "../containers",
"../db",
"../importers/common",
"../storage",
"../types",
+ "../util",
]
}
diff --git a/src/trace_processor/sqlite/create_function.cc b/src/trace_processor/sqlite/create_function.cc
new file mode 100644
index 000000000..6e676667e
--- /dev/null
+++ b/src/trace_processor/sqlite/create_function.cc
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/sqlite/create_function.h"
+
+#include "perfetto/base/status.h"
+#include "perfetto/trace_processor/basic_types.h"
+#include "src/trace_processor/sqlite/create_function_internal.h"
+#include "src/trace_processor/sqlite/scoped_db.h"
+#include "src/trace_processor/sqlite/sqlite_utils.h"
+#include "src/trace_processor/util/status_macros.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+namespace {
+
+struct CreatedFunction : public SqlFunction {
+ struct Context {
+ sqlite3* db;
+ Prototype prototype;
+ SqlValue::Type return_type;
+ std::string sql;
+ sqlite3_stmt* stmt;
+ };
+
+ static base::Status Run(Context* ctx,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors&);
+ static base::Status Cleanup(Context*);
+};
+
+base::Status CreatedFunction::Run(CreatedFunction::Context* ctx,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors&) {
+ if (argc != ctx->prototype.arguments.size()) {
+ return base::ErrStatus(
+ "%s: invalid number of args; expected %zu, received %zu",
+ ctx->prototype.function_name.c_str(), ctx->prototype.arguments.size(),
+ argc);
+ }
+
+ // Type check all the arguments.
+ for (size_t i = 0; i < argc; ++i) {
+ sqlite3_value* arg = argv[i];
+ base::Status status =
+ TypeCheckSqliteValue(arg, ctx->prototype.arguments[i].type);
+ if (!status.ok()) {
+ return base::ErrStatus("%s[arg=%s]: argument %zu %s",
+ ctx->prototype.function_name.c_str(),
+ sqlite3_value_text(arg), i, status.c_message());
+ }
+ }
+
+ // Bind all the arguments to the appropriate places in the function.
+ for (size_t i = 0; i < argc; ++i) {
+ RETURN_IF_ERROR(MaybeBindArgument(ctx->stmt, ctx->prototype.function_name,
+ ctx->prototype.arguments[i], argv[i]));
+ }
+
+ int ret = sqlite3_step(ctx->stmt);
+ RETURN_IF_ERROR(
+ SqliteRetToStatus(ctx->db, ctx->prototype.function_name, ret));
+ if (ret == SQLITE_DONE)
+ // No return value means we just return don't set |out|.
+ return base::OkStatus();
+
+ PERFETTO_DCHECK(ret == SQLITE_ROW);
+ size_t col_count = static_cast<size_t>(sqlite3_column_count(ctx->stmt));
+ if (col_count != 1) {
+ return base::ErrStatus(
+ "%s: SQL definition should only return one column: returned %zu "
+ "columns",
+ ctx->prototype.function_name.c_str(), col_count);
+ }
+
+ out = sqlite_utils::SqliteValueToSqlValue(sqlite3_column_value(ctx->stmt, 0));
+ return base::OkStatus();
+}
+
+base::Status CreatedFunction::Cleanup(CreatedFunction::Context* ctx) {
+ int ret = sqlite3_step(ctx->stmt);
+ RETURN_IF_ERROR(
+ SqliteRetToStatus(ctx->db, ctx->prototype.function_name, ret));
+ if (ret == SQLITE_ROW) {
+ return base::ErrStatus(
+ "%s: multiple values were returned when executing function body",
+ ctx->prototype.function_name.c_str());
+ }
+ PERFETTO_DCHECK(ret == SQLITE_DONE);
+
+ // Make sure to reset the statement to remove any bindings.
+ ret = sqlite3_reset(ctx->stmt);
+ if (ret != SQLITE_OK) {
+ return base::ErrStatus("%s: error while resetting metric",
+ ctx->prototype.function_name.c_str());
+ }
+ return base::OkStatus();
+}
+
+} // namespace
+
+size_t CreateFunction::NameAndArgc::Hasher::operator()(
+ const NameAndArgc& s) const noexcept {
+ base::Hash hash;
+ hash.Update(s.name.data(), s.name.size());
+ hash.Update(s.argc);
+ return static_cast<size_t>(hash.digest());
+}
+
+base::Status CreateFunction::Run(CreateFunction::Context* ctx,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue&,
+ Destructors&) {
+ if (argc != 3) {
+ return base::ErrStatus(
+ "CREATE_FUNCTION: invalid number of args; expected %u, received %zu",
+ 3u, argc);
+ }
+
+ sqlite3_value* prototype_value = argv[0];
+ sqlite3_value* return_type_value = argv[1];
+ sqlite3_value* sql_defn_value = argv[2];
+
+ // Type check all the arguments.
+ {
+ auto type_check = [prototype_value](sqlite3_value* value,
+ SqlValue::Type type, const char* desc) {
+ base::Status status = TypeCheckSqliteValue(value, type);
+ if (!status.ok()) {
+ return base::ErrStatus("CREATE_FUNCTION[prototype=%s]: %s %s",
+ sqlite3_value_text(prototype_value), desc,
+ status.c_message());
+ }
+ return base::OkStatus();
+ };
+
+ RETURN_IF_ERROR(type_check(prototype_value, SqlValue::Type::kString,
+ "function prototype (first argument)"));
+ RETURN_IF_ERROR(type_check(return_type_value, SqlValue::Type::kString,
+ "return type (second argument)"));
+ RETURN_IF_ERROR(type_check(sql_defn_value, SqlValue::Type::kString,
+ "SQL definition (third argument)"));
+ }
+
+ // Extract the arguments from the value wrappers.
+ auto extract_string = [](sqlite3_value* value) -> base::StringView {
+ return reinterpret_cast<const char*>(sqlite3_value_text(value));
+ };
+ base::StringView prototype_str = extract_string(prototype_value);
+ base::StringView return_type_str = extract_string(return_type_value);
+ std::string sql_defn_str = extract_string(sql_defn_value).ToStdString();
+
+ // Parse all the arguments into a more friendly form.
+ Prototype prototype;
+ base::Status status = ParsePrototype(prototype_str, prototype);
+ if (!status.ok()) {
+ return base::ErrStatus("CREATE_FUNCTION[prototype=%s]: %s",
+ prototype_str.ToStdString().c_str(),
+ status.c_message());
+ }
+
+ // Parse the return type into a enum format.
+ auto opt_return_type = ParseType(return_type_str);
+ if (!opt_return_type) {
+ return base::ErrStatus(
+ "CREATE_FUNCTION[prototype=%s, return=%s]: unknown return type "
+ "specified",
+ prototype_str.ToStdString().c_str(),
+ return_type_str.ToStdString().c_str());
+ }
+ SqlValue::Type return_type = *opt_return_type;
+
+ int created_argc = static_cast<int>(prototype.arguments.size());
+ NameAndArgc key{prototype.function_name, created_argc};
+ auto it = ctx->state->find(key);
+ if (it != ctx->state->end()) {
+ // If the function already exists, just verify that the prototype, return
+ // type and SQL matches exactly with what we already had registered. By
+ // doing this, we can avoid the problem plaguing C++ macros where macro
+ // ordering determines which one gets run.
+ auto* created_ctx = static_cast<CreatedFunction::Context*>(
+ it->second.created_functon_context);
+
+ if (created_ctx->prototype != prototype) {
+ return base::ErrStatus(
+ "CREATE_FUNCTION[prototype=%s]: function prototype changed",
+ prototype_str.ToStdString().c_str());
+ }
+
+ if (created_ctx->return_type != return_type) {
+ return base::ErrStatus(
+ "CREATE_FUNCTION[prototype=%s]: return type changed from %s to %s",
+ prototype_str.ToStdString().c_str(),
+ SqliteTypeToFriendlyString(created_ctx->return_type),
+ return_type_str.ToStdString().c_str());
+ }
+
+ if (created_ctx->sql != sql_defn_str) {
+ return base::ErrStatus(
+ "CREATE_FUNCTION[prototype=%s]: function SQL changed from %s to %s",
+ prototype_str.ToStdString().c_str(), created_ctx->sql.c_str(),
+ sql_defn_str.c_str());
+ }
+ return base::OkStatus();
+ }
+
+ // Prepare the SQL definition as a statement using SQLite.
+ ScopedStmt stmt;
+ sqlite3_stmt* stmt_raw = nullptr;
+ int ret = sqlite3_prepare_v2(ctx->db, sql_defn_str.data(),
+ static_cast<int>(sql_defn_str.size()), &stmt_raw,
+ nullptr);
+ if (ret != SQLITE_OK) {
+ return base::ErrStatus(
+ "CREATE_FUNCTION[prototype=%s]: SQLite error when preparing "
+ "statement "
+ "%s",
+ prototype_str.ToStdString().c_str(), sqlite3_errmsg(ctx->db));
+ }
+ stmt.reset(stmt_raw);
+
+ std::unique_ptr<CreatedFunction::Context> created(
+ new CreatedFunction::Context{ctx->db, std::move(prototype), return_type,
+ std::move(sql_defn_str), stmt.get()});
+ CreatedFunction::Context* created_ptr = created.get();
+ RETURN_IF_ERROR(RegisterSqlFunction<CreatedFunction>(
+ ctx->db, key.name.c_str(), created_argc, std::move(created)));
+ ctx->state->emplace(key, PerFunctionState{std::move(stmt), created_ptr});
+
+ // CREATE_FUNCTION doesn't have a return value so just don't sent |out|.
+ return base::OkStatus();
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/sqlite/create_function.h b/src/trace_processor/sqlite/create_function.h
new file mode 100644
index 000000000..c6778c24e
--- /dev/null
+++ b/src/trace_processor/sqlite/create_function.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_SQLITE_CREATE_FUNCTION_H_
+#define SRC_TRACE_PROCESSOR_SQLITE_CREATE_FUNCTION_H_
+
+#include <sqlite3.h>
+#include <unordered_map>
+
+#include "src/trace_processor/sqlite/register_function.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+// Implementation of CREATE_FUNCTION SQL function.
+// See https://perfetto.dev/docs/analysis/metrics#metric-helper-functions for
+// usage of this function.
+struct CreateFunction : public SqlFunction {
+ struct PerFunctionState {
+ ScopedStmt stmt;
+ // void* to avoid leaking state.
+ void* created_functon_context;
+ };
+ struct NameAndArgc {
+ std::string name;
+ int argc;
+
+ struct Hasher {
+ std::size_t operator()(const NameAndArgc& s) const noexcept;
+ };
+ bool operator==(const NameAndArgc& other) const {
+ return name == other.name && argc == other.argc;
+ }
+ };
+ using State = std::unordered_map<NameAndArgc,
+ CreateFunction::PerFunctionState,
+ NameAndArgc::Hasher>;
+
+ struct Context {
+ sqlite3* db;
+ State* state;
+ };
+
+ static base::Status Run(Context* ctx,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors&);
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_SQLITE_CREATE_FUNCTION_H_
diff --git a/src/trace_processor/sqlite/create_function_internal.cc b/src/trace_processor/sqlite/create_function_internal.cc
new file mode 100644
index 000000000..57489316a
--- /dev/null
+++ b/src/trace_processor/sqlite/create_function_internal.cc
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/sqlite/create_function_internal.h"
+
+#include "perfetto/base/status.h"
+#include "perfetto/ext/base/string_view.h"
+#include "src/trace_processor/sqlite/sqlite_utils.h"
+#include "src/trace_processor/util/status_macros.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+bool IsValidName(base::StringView str) {
+ auto pred = [](char c) { return !(isalnum(c) || c == '_'); };
+ return std::find_if(str.begin(), str.end(), pred) == str.end();
+}
+
+base::Optional<SqlValue::Type> ParseType(base::StringView str) {
+ if (str == "INT" || str == "LONG" || str == "BOOL") {
+ return SqlValue::Type::kLong;
+ } else if (str == "DOUBLE" || str == "FLOAT") {
+ return SqlValue::Type::kDouble;
+ } else if (str == "STRING") {
+ return SqlValue::Type::kString;
+ } else if (str == "PROTO" || str == "BYTES") {
+ return SqlValue::Type::kBytes;
+ }
+ return base::nullopt;
+}
+
+const char* SqliteTypeToFriendlyString(SqlValue::Type type) {
+ switch (type) {
+ case SqlValue::Type::kNull:
+ return "NULL";
+ case SqlValue::Type::kLong:
+ return "INT/LONG/BOOL";
+ case SqlValue::Type::kDouble:
+ return "FLOAT/DOUBLE";
+ case SqlValue::Type::kString:
+ return "STRING";
+ case SqlValue::Type::kBytes:
+ return "BYTES/PROTO";
+ }
+ PERFETTO_FATAL("For GCC");
+}
+
+base::Status TypeCheckSqliteValue(sqlite3_value* value,
+ SqlValue::Type expected_type) {
+ SqlValue::Type actual_type =
+ sqlite_utils::SqliteTypeToSqlValueType(sqlite3_value_type(value));
+ if (actual_type != SqlValue::Type::kNull && actual_type != expected_type) {
+ return base::ErrStatus(
+ "does not have expected type: expected %s, actual %s",
+ SqliteTypeToFriendlyString(expected_type),
+ SqliteTypeToFriendlyString(actual_type));
+ }
+ return base::OkStatus();
+}
+
+base::Status ParseFunctionName(base::StringView raw, base::StringView& out) {
+ size_t function_name_end = raw.find('(');
+ if (function_name_end == base::StringView::npos)
+ return base::ErrStatus("unable to find bracket starting argument list");
+
+ base::StringView function_name = raw.substr(0, function_name_end);
+ if (!IsValidName(function_name)) {
+ return base::ErrStatus("function name %s is not alphanumeric",
+ function_name.ToStdString().c_str());
+ }
+ out = function_name;
+ return base::OkStatus();
+}
+
+base::Status ParseArgs(std::string args,
+ std::vector<Prototype::Argument>& out) {
+ for (const auto& arg : base::SplitString(args, ",")) {
+ const auto& arg_name_and_type = base::SplitString(arg, " ");
+ if (arg_name_and_type.size() != 2) {
+ return base::ErrStatus(
+ "argument %s in function prototype should be of the form `name type`",
+ arg.c_str());
+ }
+
+ const auto& arg_name = arg_name_and_type[0];
+ const auto& arg_type_str = arg_name_and_type[1];
+ if (!IsValidName(base::StringView(arg_name)))
+ return base::ErrStatus("argument %s is not alphanumeric", arg.c_str());
+
+ auto opt_arg_type = ParseType(base::StringView(arg_type_str));
+ if (!opt_arg_type)
+ return base::ErrStatus("unknown argument type in argument %s",
+ arg.c_str());
+
+ SqlValue::Type arg_type = *opt_arg_type;
+ PERFETTO_DCHECK(arg_type != SqlValue::Type::kNull);
+ out.push_back({arg_name, "$" + arg_name, arg_type});
+ }
+ return base::OkStatus();
+}
+
+base::Status ParsePrototype(base::StringView raw, Prototype& out) {
+ // Examples of function prototypes:
+ // ANDROID_SDK_LEVEL()
+ // STARTUP_SLICE(dur_ns INT)
+ // FIND_NEXT_SLICE_WITH_NAME(ts INT, name STRING)
+
+ base::StringView function_name;
+ RETURN_IF_ERROR(ParseFunctionName(raw, function_name));
+
+ size_t function_name_end = function_name.size();
+ size_t args_start = function_name_end + 1;
+ size_t args_end = raw.find(')', args_start);
+ if (args_end == base::StringView::npos)
+ return base::ErrStatus("unable to find bracket ending argument list");
+
+ base::StringView args_str = raw.substr(args_start, args_end - args_start);
+ RETURN_IF_ERROR(ParseArgs(args_str.ToStdString(), out.arguments));
+
+ out.function_name = function_name.ToStdString();
+ return base::OkStatus();
+}
+
+base::Status SqliteRetToStatus(sqlite3* db,
+ const std::string& function_name,
+ int ret) {
+ if (ret != SQLITE_ROW && ret != SQLITE_DONE) {
+ return base::ErrStatus("%s: SQLite error while executing function body: %s",
+ function_name.c_str(), sqlite3_errmsg(db));
+ }
+ return base::OkStatus();
+}
+
+base::Status MaybeBindArgument(sqlite3_stmt* stmt,
+ const std::string& function_name,
+ const Prototype::Argument& arg,
+ sqlite3_value* value) {
+ int index = sqlite3_bind_parameter_index(stmt, arg.dollar_name.c_str());
+
+ // If the argument is not in the query, this just means its an unused
+ // argument which we can just ignore.
+ if (index == 0)
+ return base::Status();
+
+ int ret = sqlite3_bind_value(stmt, index, value);
+ if (ret != SQLITE_OK) {
+ return base::ErrStatus(
+ "%s: SQLite error while binding value to argument %s: %s",
+ function_name.c_str(), arg.name.c_str(),
+ sqlite3_errmsg(sqlite3_db_handle(stmt)));
+ }
+ return base::OkStatus();
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/sqlite/create_function_internal.h b/src/trace_processor/sqlite/create_function_internal.h
new file mode 100644
index 000000000..7150adeda
--- /dev/null
+++ b/src/trace_processor/sqlite/create_function_internal.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_SQLITE_CREATE_FUNCTION_INTERNAL_H_
+#define SRC_TRACE_PROCESSOR_SQLITE_CREATE_FUNCTION_INTERNAL_H_
+
+#include <sqlite3.h>
+#include <string>
+
+#include "perfetto/base/status.h"
+#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/string_view.h"
+#include "perfetto/trace_processor/basic_types.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+bool IsValidName(base::StringView str);
+
+base::Optional<SqlValue::Type> ParseType(base::StringView str);
+
+const char* SqliteTypeToFriendlyString(SqlValue::Type type);
+
+base::Status TypeCheckSqliteValue(sqlite3_value* value,
+ SqlValue::Type expected_type);
+
+struct Prototype {
+ struct Argument {
+ std::string name;
+ std::string dollar_name;
+ SqlValue::Type type;
+
+ bool operator==(const Argument& other) const {
+ return name == other.name && dollar_name == other.dollar_name &&
+ type == other.type;
+ }
+ };
+ std::string function_name;
+ std::vector<Argument> arguments;
+
+ bool operator==(const Prototype& other) const {
+ return function_name == other.function_name && arguments == other.arguments;
+ }
+ bool operator!=(const Prototype& other) const { return !(*this == other); }
+};
+
+base::Status ParseFunctionName(base::StringView raw,
+ base::StringView& function_name);
+
+base::Status ParsePrototype(base::StringView raw, Prototype& out);
+
+base::Status ParseArgs(std::string args, std::vector<Prototype::Argument>&);
+
+base::Status SqliteRetToStatus(sqlite3* db,
+ const std::string& function_name,
+ int ret);
+
+base::Status MaybeBindArgument(sqlite3_stmt*,
+ const std::string& function_name,
+ const Prototype::Argument&,
+ sqlite3_value*);
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_SQLITE_CREATE_FUNCTION_INTERNAL_H_
diff --git a/src/trace_processor/sqlite/create_view_function.cc b/src/trace_processor/sqlite/create_view_function.cc
new file mode 100644
index 000000000..211251a77
--- /dev/null
+++ b/src/trace_processor/sqlite/create_view_function.cc
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/sqlite/create_view_function.h"
+
+#include <numeric>
+
+#include "perfetto/base/status.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/string_view.h"
+#include "perfetto/trace_processor/basic_types.h"
+#include "src/trace_processor/sqlite/create_function_internal.h"
+#include "src/trace_processor/sqlite/scoped_db.h"
+#include "src/trace_processor/sqlite/sqlite_table.h"
+#include "src/trace_processor/sqlite/sqlite_utils.h"
+#include "src/trace_processor/util/status_macros.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+namespace {
+
+class CreatedViewFunction : public SqliteTable {
+ public:
+ class Cursor : public SqliteTable::Cursor {
+ public:
+ explicit Cursor(CreatedViewFunction* table);
+ ~Cursor() override;
+
+ int Filter(const QueryConstraints& qc,
+ sqlite3_value**,
+ FilterHistory) override;
+ int Next() override;
+ int Eof() override;
+ int Column(sqlite3_context* context, int N) override;
+
+ private:
+ sqlite3_stmt* stmt_ = nullptr;
+ CreatedViewFunction* table_ = nullptr;
+ bool is_eof_ = false;
+ };
+
+ CreatedViewFunction(sqlite3*, CreateViewFunction::State* state);
+ ~CreatedViewFunction() override;
+
+ base::Status Init(int argc, const char* const* argv, Schema*) override;
+ std::unique_ptr<SqliteTable::Cursor> CreateCursor() override;
+ int BestIndex(const QueryConstraints& qc, BestIndexInfo* info) override;
+
+ static void Register(sqlite3* db, CreateViewFunction::State* state) {
+ SqliteTable::Register<CreatedViewFunction>(
+ db, state, "internal_view_function_impl", false, true);
+ }
+
+ private:
+ Schema CreateSchema();
+
+ sqlite3* db_ = nullptr;
+
+ Prototype prototype_;
+ std::vector<Prototype::Argument> return_values_;
+
+ std::string prototype_str_;
+ std::string sql_defn_str_;
+
+ CreateViewFunction::State* state_;
+};
+
+CreatedViewFunction::CreatedViewFunction(sqlite3* db,
+ CreateViewFunction::State* state)
+ : db_(db), state_(state) {}
+CreatedViewFunction::~CreatedViewFunction() = default;
+
+base::Status CreatedViewFunction::Init(int argc,
+ const char* const* argv,
+ Schema* schema) {
+ // The first three args are SQLite ones which we ignore.
+ PERFETTO_CHECK(argc == 6);
+
+ prototype_str_ = argv[3];
+ std::string return_prototype_str = argv[4];
+ sql_defn_str_ = argv[5];
+
+ // SQLite gives us strings with quotes included (i.e. 'string'). Strip these
+ // from the front and back.
+ prototype_str_ = prototype_str_.substr(1, prototype_str_.size() - 2);
+ return_prototype_str =
+ return_prototype_str.substr(1, return_prototype_str.size() - 2);
+ sql_defn_str_ = sql_defn_str_.substr(1, sql_defn_str_.size() - 2);
+
+ // Parse all the arguments into a more friendly form.
+ base::Status status =
+ ParsePrototype(base::StringView(prototype_str_), prototype_);
+ if (!status.ok()) {
+ return base::ErrStatus("CREATE_VIEW_FUNCTION[prototype=%s]: %s",
+ prototype_str_.c_str(), status.c_message());
+ }
+
+ // Parse the return type into a enum format.
+ status = ParseArgs(return_prototype_str, return_values_);
+ if (!status.ok()) {
+ return base::ErrStatus(
+ "CREATE_VIEW_FUNCTION[prototype=%s, return=%s]: unknown return type "
+ "specified",
+ prototype_str_.c_str(), return_prototype_str.c_str());
+ }
+
+ // Now we've parsed prototype and return values, create the schema.
+ *schema = CreateSchema();
+
+ return base::OkStatus();
+}
+
+SqliteTable::Schema CreatedViewFunction::CreateSchema() {
+ std::vector<Column> columns;
+ for (size_t i = 0; i < return_values_.size(); ++i) {
+ const auto& ret = return_values_[i];
+ columns.push_back(Column(columns.size(), ret.name, ret.type, false));
+ }
+ for (size_t i = 0; i < prototype_.arguments.size(); ++i) {
+ const auto& arg = prototype_.arguments[i];
+ columns.push_back(Column(columns.size(), arg.name, arg.type, true));
+ }
+
+ std::vector<size_t> primary_keys(return_values_.size());
+ std::iota(primary_keys.begin(), primary_keys.end(), 0);
+
+ return SqliteTable::Schema(std::move(columns), std::move(primary_keys));
+}
+
+std::unique_ptr<SqliteTable::Cursor> CreatedViewFunction::CreateCursor() {
+ return std::unique_ptr<Cursor>(new Cursor(this));
+}
+
+int CreatedViewFunction::BestIndex(const QueryConstraints& qc,
+ BestIndexInfo* info) {
+ for (size_t i = 0; i < info->sqlite_omit_constraint.size(); ++i) {
+ size_t col = static_cast<size_t>(qc.constraints()[i].column);
+ if (schema().columns()[col].hidden()) {
+ info->sqlite_omit_constraint[i] = true;
+ }
+ }
+ return SQLITE_OK;
+}
+
+CreatedViewFunction::Cursor::Cursor(CreatedViewFunction* table)
+ : SqliteTable::Cursor(table), table_(table) {}
+
+CreatedViewFunction::Cursor::~Cursor() = default;
+
+int CreatedViewFunction::Cursor::Filter(const QueryConstraints& qc,
+ sqlite3_value** argv,
+ FilterHistory) {
+ auto col_to_arg_idx = [this](int col) {
+ return static_cast<size_t>(col) - table_->return_values_.size();
+ };
+
+ size_t seen_hidden_constraints = 0;
+ for (size_t i = 0; i < qc.constraints().size(); ++i) {
+ const auto& cs = qc.constraints()[i];
+
+ // Only consider hidden columns (i.e. input parameters) as we're delegating
+ // the rest to SQLite.
+ if (!table_->schema().columns()[static_cast<size_t>(cs.column)].hidden())
+ continue;
+
+ // We only support equality constraints as we're expecting "input arguments"
+ // to our "function".
+ if (!sqlite_utils::IsOpEq(cs.op)) {
+ table_->SetErrorMessage(
+ sqlite3_mprintf("%s: non-equality constraint passed",
+ table_->prototype_.function_name.c_str()));
+ return SQLITE_ERROR;
+ }
+
+ SqlValue::Type type =
+ sqlite_utils::SqliteTypeToSqlValueType(sqlite3_value_type(argv[i]));
+ if (type != table_->prototype_.arguments[col_to_arg_idx(cs.column)].type) {
+ table_->SetErrorMessage(
+ sqlite3_mprintf("%s: type of input argument does not match",
+ table_->prototype_.function_name.c_str()));
+ return SQLITE_ERROR;
+ }
+
+ seen_hidden_constraints++;
+ }
+
+ // Verify that we saw one valid constriant for every input argument.
+ if (seen_hidden_constraints < table_->prototype_.arguments.size()) {
+ table_->SetErrorMessage(
+ sqlite3_mprintf("%s: missing value for input argument",
+ table_->prototype_.function_name.c_str()));
+ return SQLITE_ERROR;
+ }
+
+ // Prepare the SQL definition as a statement using SQLite.
+ // TODO(lalitm): see if we can reuse this prepared statement rather than
+ // creating it very time.
+ // TODO(lalitm): measure and implement whether it would be a good idea to
+ // forward constraints here when we build the nested query.
+ ScopedStmt stmt;
+ int ret = sqlite3_prepare_v2(table_->db_, table_->sql_defn_str_.data(),
+ static_cast<int>(table_->sql_defn_str_.size()),
+ &stmt_, nullptr);
+ stmt.reset(stmt_);
+ if (ret != SQLITE_OK) {
+ table_->SetErrorMessage(sqlite3_mprintf(
+ "%s: SQLite error when preparing statement %s",
+ table_->prototype_.function_name.c_str(), sqlite3_errmsg(table_->db_)));
+ return SQLITE_ERROR;
+ }
+
+ // Bind all the arguments to the appropriate places in the function.
+ for (size_t i = 0; i < qc.constraints().size(); ++i) {
+ const auto& cs = qc.constraints()[i];
+ const auto& arg = table_->prototype_.arguments[col_to_arg_idx(cs.column)];
+ auto status = MaybeBindArgument(stmt_, table_->prototype_.function_name,
+ arg, argv[i]);
+ if (!status.ok()) {
+ table_->SetErrorMessage(sqlite3_mprintf("%s", status.c_message()));
+ return SQLITE_ERROR;
+ }
+ }
+
+ ret = Next();
+ if (ret != SQLITE_OK)
+ return ret;
+
+ // Keep track of the scoped statements in the stmts vector so we can clean
+ // all these up before destroying trace processor.
+ table_->state_->erase(table_->prototype_.function_name);
+ table_->state_->emplace(table_->prototype_.function_name, std::move(stmt));
+
+ return SQLITE_OK;
+}
+
+int CreatedViewFunction::Cursor::Next() {
+ int ret = sqlite3_step(stmt_);
+ is_eof_ = ret == SQLITE_DONE;
+ if (ret != SQLITE_ROW && ret != SQLITE_DONE) {
+ table_->SetErrorMessage(sqlite3_mprintf(
+ "%s: SQLite error while stepping statement: %s",
+ table_->prototype_.function_name.c_str(), sqlite3_errmsg(table_->db_)));
+ return ret;
+ }
+ return SQLITE_OK;
+}
+
+int CreatedViewFunction::Cursor::Eof() {
+ return is_eof_;
+}
+
+int CreatedViewFunction::Cursor::Column(sqlite3_context* ctx, int i) {
+ size_t idx = static_cast<size_t>(i);
+ if (idx < table_->return_values_.size()) {
+ sqlite3_result_value(ctx, sqlite3_column_value(stmt_, i));
+ } else {
+ sqlite3_result_null(ctx);
+ }
+ return SQLITE_OK;
+}
+
+} // namespace
+
+base::Status CreateViewFunction::Run(CreateViewFunction::Context* ctx,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue&,
+ Destructors&) {
+ if (argc != 3) {
+ return base::ErrStatus(
+ "CREATE_VIEW_FUNCTION: invalid number of args; expected %u, received "
+ "%zu",
+ 3u, argc);
+ }
+
+ sqlite3_value* prototype_value = argv[0];
+ sqlite3_value* return_prototype_value = argv[1];
+ sqlite3_value* sql_defn_value = argv[2];
+
+ // Type check all the arguments.
+ {
+ auto type_check = [prototype_value](sqlite3_value* value,
+ SqlValue::Type type, const char* desc) {
+ base::Status status = TypeCheckSqliteValue(value, type);
+ if (!status.ok()) {
+ return base::ErrStatus("CREATE_VIEW_FUNCTION[prototype=%s]: %s %s",
+ sqlite3_value_text(prototype_value), desc,
+ status.c_message());
+ }
+ return base::OkStatus();
+ };
+
+ RETURN_IF_ERROR(type_check(prototype_value, SqlValue::Type::kString,
+ "function prototype (first argument)"));
+ RETURN_IF_ERROR(type_check(return_prototype_value, SqlValue::Type::kString,
+ "return prototype (second argument)"));
+ RETURN_IF_ERROR(type_check(sql_defn_value, SqlValue::Type::kString,
+ "SQL definition (third argument)"));
+ }
+
+ // Extract the arguments from the value wrappers.
+ auto extract_string = [](sqlite3_value* value) -> const char* {
+ return reinterpret_cast<const char*>(sqlite3_value_text(value));
+ };
+ const char* prototype_str = extract_string(prototype_value);
+ const char* return_prototype_str = extract_string(return_prototype_value);
+ const char* sql_defn_str = extract_string(sql_defn_value);
+
+ base::StringView function_name;
+ RETURN_IF_ERROR(ParseFunctionName(prototype_str, function_name));
+
+ base::StackString<1024> sql(
+ "CREATE OR REPLACE VIRTUAL TABLE %s USING "
+ "INTERNAL_VIEW_FUNCTION_IMPL('%s', '%s', '%s');",
+ function_name.ToStdString().c_str(), prototype_str, return_prototype_str,
+ sql_defn_str);
+
+ ScopedSqliteString errmsg;
+ char* errmsg_raw = nullptr;
+ int ret = sqlite3_exec(ctx->db, sql.c_str(), nullptr, nullptr, &errmsg_raw);
+ errmsg.reset(errmsg_raw);
+ if (ret != SQLITE_OK)
+ return base::ErrStatus("%s", errmsg.get());
+
+ // CREATE_VIEW_FUNCTION doesn't have a return value so just don't sent |out|.
+ return base::OkStatus();
+}
+
+void CreateViewFunction::RegisterTable(sqlite3* db,
+ CreateViewFunction::State* state) {
+ CreatedViewFunction::Register(db, state);
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/sqlite/create_view_function.h b/src/trace_processor/sqlite/create_view_function.h
new file mode 100644
index 000000000..f047e3503
--- /dev/null
+++ b/src/trace_processor/sqlite/create_view_function.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_SQLITE_CREATE_VIEW_FUNCTION_H_
+#define SRC_TRACE_PROCESSOR_SQLITE_CREATE_VIEW_FUNCTION_H_
+
+#include <sqlite3.h>
+#include <unordered_map>
+
+#include "src/trace_processor/sqlite/register_function.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+// Implementation of CREATE_VIEW_FUNCTION SQL function.
+// See https://perfetto.dev/docs/analysis/metrics#metric-helper-functions for
+// usage of this function.
+struct CreateViewFunction : public SqlFunction {
+ using State = std::unordered_map<std::string, ScopedStmt>;
+ struct Context {
+ sqlite3* db;
+ };
+
+ static base::Status Run(Context* ctx,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors&);
+
+ static void RegisterTable(sqlite3* db, State* state);
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_SQLITE_CREATE_VIEW_FUNCTION_H_
diff --git a/src/trace_processor/sqlite/db_sqlite_table.cc b/src/trace_processor/sqlite/db_sqlite_table.cc
index 8dc57f995..272151cc8 100644
--- a/src/trace_processor/sqlite/db_sqlite_table.cc
+++ b/src/trace_processor/sqlite/db_sqlite_table.cc
@@ -17,6 +17,7 @@
#include "src/trace_processor/sqlite/db_sqlite_table.h"
#include "perfetto/ext/base/string_writer.h"
+#include "src/trace_processor/containers/bit_vector.h"
#include "src/trace_processor/sqlite/query_cache.h"
#include "src/trace_processor/sqlite/sqlite_utils.h"
#include "src/trace_processor/tp_metatrace.h"
@@ -49,6 +50,15 @@ base::Optional<FilterOp> SqliteOpToFilterOp(int sqlite_op) {
case SQLITE_INDEX_CONSTRAINT_LIKE:
case SQLITE_INDEX_CONSTRAINT_GLOB:
return base::nullopt;
+#if SQLITE_VERSION_NUMBER >= 3038000
+ // LIMIT and OFFSET constraints were introduced in 3.38 but we
+ // still build for older versions in most places. We still need
+ // to handle this here as Chrome is very good at staying up to date
+ // with SQLite versions and crashes if we don't have this.
+ case SQLITE_INDEX_CONSTRAINT_LIMIT:
+ case SQLITE_INDEX_CONSTRAINT_OFFSET:
+ return base::nullopt;
+#endif
default:
PERFETTO_FATAL("Currently unsupported constraint");
}
@@ -83,6 +93,17 @@ SqlValue SqliteValueToSqlValue(sqlite3_value* sqlite_val) {
return value;
}
+BitVector ColsUsedBitVector(uint64_t sqlite_cols_used, size_t col_count) {
+ return BitVector::Range(
+ 0, static_cast<uint32_t>(col_count), [sqlite_cols_used](uint32_t idx) {
+ // If the lowest bit of |sqlite_cols_used| is set, the first column is
+ // used. The second lowest bit corresponds to the second column etc. If
+ // the most significant bit of |sqlite_cols_used| is set, that means
+ // that any column after the first 63 columns could be used.
+ return sqlite_cols_used & (1ull << std::min(idx, 63u));
+ });
+}
+
} // namespace
DbSqliteTable::DbSqliteTable(sqlite3*, Context context)
@@ -111,7 +132,8 @@ void DbSqliteTable::RegisterTable(
// Figure out if the table needs explicit args (in the form of constraints
// on hidden columns) passed to it in order to make the query valid.
- util::Status status = generator->ValidateConstraints({});
+ base::Status status = generator->ValidateConstraints(
+ QueryConstraints(std::numeric_limits<uint64_t>::max()));
bool requires_args = !status.ok();
Context context{cache, std::move(schema), TableComputation::kDynamic, nullptr,
@@ -120,9 +142,9 @@ void DbSqliteTable::RegisterTable(
false, requires_args);
}
-util::Status DbSqliteTable::Init(int, const char* const*, Schema* schema) {
+base::Status DbSqliteTable::Init(int, const char* const*, Schema* schema) {
*schema = ComputeSchema(schema_, name().c_str());
- return util::OkStatus();
+ return base::OkStatus();
}
SqliteTable::Schema DbSqliteTable::ComputeSchema(const Table::Schema& schema,
@@ -156,7 +178,7 @@ int DbSqliteTable::BestIndex(const QueryConstraints& qc, BestIndexInfo* info) {
BestIndex(schema_, static_table_->row_count(), qc, info);
break;
case TableComputation::kDynamic:
- util::Status status = generator_->ValidateConstraints(qc);
+ base::Status status = generator_->ValidateConstraints(qc);
if (!status.ok())
return SQLITE_CONSTRAINT;
BestIndex(schema_, generator_->EstimateRowCount(), qc, info);
@@ -278,9 +300,13 @@ DbSqliteTable::QueryCost DbSqliteTable::EstimateCost(
break;
const auto& col_schema = schema.columns[static_cast<uint32_t>(c.column)];
if (sqlite_utils::IsOpEq(c.op) && col_schema.is_id) {
- // If we have an id equality constraint, it's a bit expensive to find
- // the exact row but it filters down to a single row.
- filter_cost += 100;
+ // If we have an id equality constraint, we can very efficiently filter
+ // down to a single row in C++. However, if we're joining with another
+ // table, SQLite will do this once per row which can be extremely
+ // expensive because of all the virtual table (which is implemented using
+ // virtual function calls) machinery. Indicate this by saying that an
+ // entire filter call is ~10x the cost of iterating a single row.
+ filter_cost += 10;
current_row_count = 1;
} else if (sqlite_utils::IsOpEq(c.op)) {
// If there is only a single equality constraint, we have special logic
@@ -291,12 +317,26 @@ DbSqliteTable::QueryCost DbSqliteTable::EstimateCost(
// search logic so we have the same low cost (even better because we don't
// have to sort at all).
filter_cost += cs.size() == 1 || col_schema.is_sorted
- ? (2 * current_row_count) / log2(current_row_count)
+ ? log2(current_row_count)
: current_row_count;
- // We assume that an equalty constraint will cut down the number of rows
- // by approximate log of the number of rows.
- double estimated_rows = current_row_count / log2(current_row_count);
+ // As an extremely rough heuristic, assume that an equalty constraint will
+ // cut down the number of rows by approximately double log of the number
+ // of rows.
+ double estimated_rows = current_row_count / (2 * log2(current_row_count));
+ current_row_count = std::max(static_cast<uint32_t>(estimated_rows), 1u);
+ } else if (col_schema.is_sorted &&
+ (sqlite_utils::IsOpLe(c.op) || sqlite_utils::IsOpLt(c.op) ||
+ sqlite_utils::IsOpGt(c.op) || sqlite_utils::IsOpGe(c.op))) {
+ // On a sorted column, if we see any partition constraints, we can do this
+ // filter very efficiently. Model this using the log of the number of
+ // rows as a good approximation.
+ filter_cost += log2(current_row_count);
+
+ // As an extremely rough heuristic, assume that an partition constraint
+ // will cut down the number of rows by approximately double log of the
+ // number of rows.
+ double estimated_rows = current_row_count / (2 * log2(current_row_count));
current_row_count = std::max(static_cast<uint32_t>(estimated_rows), 1u);
} else {
// Otherwise, we will need to do a full table scan and we estimate we will
@@ -313,7 +353,7 @@ DbSqliteTable::QueryCost DbSqliteTable::EstimateCost(
static_cast<double>(qc.order_by().size() * current_row_count) *
log2(current_row_count);
- // The cost of iterating rows is more expensive than filtering the rows
+ // The cost of iterating rows is more expensive than just filtering the rows
// so multiply by an appropriate factor.
double iteration_cost = current_row_count * 2.0;
@@ -387,10 +427,6 @@ void DbSqliteTable::Cursor::TryCacheCreateSortedTable(
int DbSqliteTable::Cursor::Filter(const QueryConstraints& qc,
sqlite3_value** argv,
FilterHistory history) {
- PERFETTO_TP_TRACE("DB_TABLE_XFILTER", [this](metatrace::Record* r) {
- r->AddArg("Table", db_sqlite_table_->name());
- });
-
// Clear out the iterator before filtering to ensure the destructor is run
// before the table's destructor.
iterator_ = base::nullopt;
@@ -438,11 +474,21 @@ int DbSqliteTable::Cursor::Filter(const QueryConstraints& qc,
});
// If we have a dynamically created table, regenerate the table based on
// the new constraints.
- dynamic_table_ =
- db_sqlite_table_->generator_->ComputeTable(constraints_, orders_);
- upstream_table_ = dynamic_table_.get();
- if (!upstream_table_)
+ std::unique_ptr<Table> computed_table;
+ BitVector cols_used_bv = ColsUsedBitVector(
+ qc.cols_used(), db_sqlite_table_->schema_.columns.size());
+ auto status = db_sqlite_table_->generator_->ComputeTable(
+ constraints_, orders_, cols_used_bv, computed_table);
+
+ if (!status.ok()) {
+ auto* sqlite_err = sqlite3_mprintf(
+ "%s: %s", db_sqlite_table_->name().c_str(), status.c_message());
+ db_sqlite_table_->SetErrorMessage(sqlite_err);
return SQLITE_CONSTRAINT;
+ }
+ PERFETTO_DCHECK(computed_table);
+ dynamic_table_ = std::move(computed_table);
+ upstream_table_ = dynamic_table_.get();
break;
}
}
@@ -502,6 +548,7 @@ int DbSqliteTable::Cursor::Filter(const QueryConstraints& qc,
break;
}
}
+ r->AddArg("Table", db_sqlite_table_->name());
r->AddArg("Constraint", writer.GetStringView());
}
@@ -574,35 +621,15 @@ int DbSqliteTable::Cursor::Column(sqlite3_context* ctx, int raw_col) {
SqlValue value = mode_ == Mode::kSingleRow
? SourceTable()->GetColumn(column).Get(*single_row_)
: iterator_->Get(column);
- switch (value.type) {
- case SqlValue::Type::kLong:
- sqlite3_result_int64(ctx, value.long_value);
- break;
- case SqlValue::Type::kDouble:
- sqlite3_result_double(ctx, value.double_value);
- break;
- case SqlValue::Type::kString: {
- // We can say kSqliteStatic here because all strings are expected to
- // come from the string pool and thus will be valid for the lifetime
- // of trace processor.
- sqlite3_result_text(ctx, value.string_value, -1,
- sqlite_utils::kSqliteStatic);
- break;
- }
- case SqlValue::Type::kBytes: {
- // We can say kSqliteStatic here because for our iterator will hold
- // onto the pointer as long as we don't call Next() but that only
- // happens with Next() is called on the Cursor itself at which point
- // SQLite no longer cares about the bytes pointer.
- sqlite3_result_blob(ctx, value.bytes_value,
- static_cast<int>(value.bytes_count),
- sqlite_utils::kSqliteStatic);
- break;
- }
- case SqlValue::Type::kNull:
- sqlite3_result_null(ctx);
- break;
- }
+ // We can say kSqliteStatic for strings because all strings are expected to
+ // come from the string pool and thus will be valid for the lifetime
+ // of trace processor.
+ // Similarily for bytes we can also use kSqliteStatic because for our iterator
+ // will hold onto the pointer as long as we don't call Next() but that only
+ // happens with Next() is called on the Cursor itself at which point
+ // SQLite no longer cares about the bytes pointer.
+ sqlite_utils::ReportSqlValue(ctx, value, sqlite_utils::kSqliteStatic,
+ sqlite_utils::kSqliteStatic);
return SQLITE_OK;
}
diff --git a/src/trace_processor/sqlite/db_sqlite_table.h b/src/trace_processor/sqlite/db_sqlite_table.h
index 64231de05..e1a35b86a 100644
--- a/src/trace_processor/sqlite/db_sqlite_table.h
+++ b/src/trace_processor/sqlite/db_sqlite_table.h
@@ -17,6 +17,7 @@
#ifndef SRC_TRACE_PROCESSOR_SQLITE_DB_SQLITE_TABLE_H_
#define SRC_TRACE_PROCESSOR_SQLITE_DB_SQLITE_TABLE_H_
+#include "src/trace_processor/containers/bit_vector.h"
#include "src/trace_processor/db/table.h"
#include "src/trace_processor/sqlite/query_cache.h"
#include "src/trace_processor/sqlite/sqlite_table.h"
@@ -56,16 +57,19 @@ class DbSqliteTable : public SqliteTable {
// Checks that the constraint set is valid.
//
- // Returning util::OkStatus means that the required constraints are present
+ // Returning base::OkStatus means that the required constraints are present
// in |qc| for dynamically computing the table (e.g. any required
// constraints on hidden columns for table-valued functions are present).
- virtual util::Status ValidateConstraints(const QueryConstraints& qc) = 0;
+ virtual base::Status ValidateConstraints(const QueryConstraints& qc) = 0;
// Dynamically computes the table given the constraints and order by
// vectors.
- virtual std::unique_ptr<Table> ComputeTable(
- const std::vector<Constraint>& cs,
- const std::vector<Order>& ob) = 0;
+ // The table is returned via |table_return|. There are no guarantees on
+ // its value if the method returns a non-ok status.
+ virtual base::Status ComputeTable(const std::vector<Constraint>& cs,
+ const std::vector<Order>& ob,
+ const BitVector& cols_used,
+ std::unique_ptr<Table>& table_return) = 0;
};
class Cursor : public SqliteTable::Cursor {
@@ -164,7 +168,7 @@ class DbSqliteTable : public SqliteTable {
virtual ~DbSqliteTable() override;
// Table implementation.
- util::Status Init(int,
+ base::Status Init(int,
const char* const*,
SqliteTable::Schema*) override final;
std::unique_ptr<SqliteTable::Cursor> CreateCursor() override;
diff --git a/src/trace_processor/sqlite/query_constraints.cc b/src/trace_processor/sqlite/query_constraints.cc
index 9ff242fc7..67f1812ef 100644
--- a/src/trace_processor/sqlite/query_constraints.cc
+++ b/src/trace_processor/sqlite/query_constraints.cc
@@ -21,14 +21,17 @@
#include <string>
#include "perfetto/ext/base/string_splitter.h"
+#include "perfetto/ext/base/string_utils.h"
namespace perfetto {
namespace trace_processor {
-QueryConstraints::QueryConstraints() = default;
+QueryConstraints::QueryConstraints(uint64_t cols_used)
+ : cols_used_(cols_used) {}
QueryConstraints::~QueryConstraints() = default;
QueryConstraints::QueryConstraints(QueryConstraints&&) noexcept = default;
-QueryConstraints& QueryConstraints::operator=(QueryConstraints&&) = default;
+QueryConstraints& QueryConstraints::operator=(QueryConstraints&&) noexcept =
+ default;
int QueryConstraints::FreeSqliteString(char* resource) {
sqlite3_free(resource);
@@ -37,7 +40,8 @@ int QueryConstraints::FreeSqliteString(char* resource) {
bool QueryConstraints::operator==(const QueryConstraints& other) const {
if ((other.constraints().size() != constraints().size()) ||
- (other.order_by().size() != order_by().size())) {
+ (other.order_by().size() != order_by().size()) ||
+ other.cols_used() != cols_used()) {
return false;
}
@@ -78,6 +82,8 @@ void QueryConstraints::AddOrderBy(int column, unsigned char desc) {
QueryConstraints::SqliteString QueryConstraints::ToNewSqlite3String() const {
std::string str_result;
str_result.reserve(512);
+
+ // Add all the constraints.
str_result.append("C");
str_result.append(std::to_string(constraints_.size()));
str_result.append(",");
@@ -87,6 +93,9 @@ QueryConstraints::SqliteString QueryConstraints::ToNewSqlite3String() const {
str_result.append(std::to_string(cs.op));
str_result.append(",");
}
+ str_result.back() = ';';
+
+ // Add all the clauses.
str_result.append("O");
str_result.append(std::to_string(order_by_.size()));
str_result.append(",");
@@ -96,46 +105,67 @@ QueryConstraints::SqliteString QueryConstraints::ToNewSqlite3String() const {
str_result.append(std::to_string(ob.desc));
str_result.append(",");
}
+ str_result.back() = ';';
- // The last char is a "," so overwriting with the null terminator on purpose.
- SqliteString result(
- static_cast<char*>(sqlite3_malloc(static_cast<int>(str_result.size()))));
- strncpy(result.get(), str_result.c_str(), str_result.size());
- (*result)[str_result.size() - 1] = '\0';
+ // Add the columns used.
+ str_result.append("U");
+ str_result.append(std::to_string(cols_used_));
+ SqliteString result(static_cast<char*>(
+ sqlite3_malloc(static_cast<int>(str_result.size() + 1))));
+ base::StringCopy(result.get(), str_result.c_str(), str_result.size() + 1);
return result;
}
QueryConstraints QueryConstraints::FromString(const char* idxStr) {
QueryConstraints qc;
- base::StringSplitter splitter(std::string(idxStr), ',');
-
- PERFETTO_CHECK(splitter.Next() && splitter.cur_token_size() > 1);
- // The '+ 1' skips the letter 'C' in the first token.
- long num_constraints = strtol(splitter.cur_token() + 1, nullptr, 10);
- for (int i = 0; i < num_constraints; ++i) {
- PERFETTO_CHECK(splitter.Next());
- int col = static_cast<int>(strtol(splitter.cur_token(), nullptr, 10));
- PERFETTO_CHECK(splitter.Next());
- unsigned char op =
- static_cast<unsigned char>(strtol(splitter.cur_token(), nullptr, 10));
- qc.AddConstraint(col, op, 0);
+ base::StringSplitter outer_splitter(std::string(idxStr), ';');
+
+ // Handle the CONSTRAINT section of the string.
+ PERFETTO_CHECK(outer_splitter.Next() && outer_splitter.cur_token_size() > 1);
+ {
+ base::StringSplitter splitter(&outer_splitter, ',');
+ PERFETTO_CHECK(splitter.Next() && splitter.cur_token_size() > 1);
+
+ // The '[1]' skips the letter 'C' in the first token.
+ int64_t num_constraints = *base::CStringToInt64(&splitter.cur_token()[1]);
+ for (int i = 0; i < num_constraints; ++i) {
+ PERFETTO_CHECK(splitter.Next());
+ int col = static_cast<int>(*base::CStringToInt32(splitter.cur_token()));
+ PERFETTO_CHECK(splitter.Next());
+ unsigned char op = static_cast<unsigned char>(
+ *base::CStringToUInt32(splitter.cur_token()));
+ qc.AddConstraint(col, op, 0);
+ }
+ }
+
+ // Handle the ORDER BY section of the string.
+ PERFETTO_CHECK(outer_splitter.Next() && outer_splitter.cur_token_size() > 1);
+ {
+ base::StringSplitter splitter(&outer_splitter, ',');
+ PERFETTO_CHECK(splitter.Next() && splitter.cur_token_size() > 1);
+
+ // The '[1]' skips the letter 'O' in the current token.
+ int64_t num_order_by = *base::CStringToInt64(&splitter.cur_token()[1]);
+ for (int i = 0; i < num_order_by; ++i) {
+ PERFETTO_CHECK(splitter.Next());
+ int col = static_cast<int>(*base::CStringToInt32(splitter.cur_token()));
+ PERFETTO_CHECK(splitter.Next());
+ unsigned char desc = static_cast<unsigned char>(
+ *base::CStringToUInt32(splitter.cur_token()));
+ qc.AddOrderBy(col, desc);
+ }
}
- PERFETTO_CHECK(splitter.Next() && splitter.cur_token_size() > 1);
- // The '+ 1' skips the letter 'O' in the current token.
- long num_order_by = strtol(splitter.cur_token() + 1, nullptr, 10);
- for (int i = 0; i < num_order_by; ++i) {
- PERFETTO_CHECK(splitter.Next());
- int col = static_cast<int>(strtol(splitter.cur_token(), nullptr, 10));
- PERFETTO_CHECK(splitter.Next());
- unsigned char desc =
- static_cast<unsigned char>(strtol(splitter.cur_token(), nullptr, 10));
- qc.AddOrderBy(col, desc);
+ // Handle the COLS USED section of the string.
+ PERFETTO_CHECK(outer_splitter.Next() && outer_splitter.cur_token_size() > 1);
+ {
+ // The '[1]' skips the letter 'U' in the current token.
+ qc.cols_used_ = *base::CStringToUInt64(&outer_splitter.cur_token()[1]);
}
- PERFETTO_DCHECK(!splitter.Next());
+ PERFETTO_DCHECK(!outer_splitter.Next());
return qc;
}
diff --git a/src/trace_processor/sqlite/query_constraints.h b/src/trace_processor/sqlite/query_constraints.h
index 54c1b4551..10ee3e64a 100644
--- a/src/trace_processor/sqlite/query_constraints.h
+++ b/src/trace_processor/sqlite/query_constraints.h
@@ -19,6 +19,7 @@
#include <sqlite3.h>
+#include <limits>
#include <vector>
#include "perfetto/ext/base/scoped_file.h"
@@ -57,10 +58,11 @@ class QueryConstraints {
using SqliteString = base::ScopedResource<char*, FreeSqliteString, nullptr>;
- QueryConstraints();
+ explicit QueryConstraints(
+ uint64_t cols_used = std::numeric_limits<uint64_t>::max());
~QueryConstraints();
QueryConstraints(QueryConstraints&&) noexcept;
- QueryConstraints& operator=(QueryConstraints&&);
+ QueryConstraints& operator=(QueryConstraints&&) noexcept;
// Two QueryConstraints with the same constraint and orderby vectors
// are equal.
@@ -89,12 +91,20 @@ class QueryConstraints {
std::vector<Constraint>* mutable_constraints() { return &constraints_; }
+ uint64_t cols_used() const { return cols_used_; }
+
private:
QueryConstraints(const QueryConstraints&) = delete;
QueryConstraints& operator=(const QueryConstraints&) = delete;
std::vector<OrderBy> order_by_;
std::vector<Constraint> constraints_;
+
+ // Stores information about which column is used by this query.
+ // If the lowest bit of is set, the first column is used. The second lowest
+ // bit corresponds to the second column etc. If the most significant bit is
+ // set, that means that any column after the first 63 columns could be used.
+ uint64_t cols_used_ = std::numeric_limits<uint64_t>::max();
};
} // namespace trace_processor
diff --git a/src/trace_processor/sqlite/query_constraints_unittest.cc b/src/trace_processor/sqlite/query_constraints_unittest.cc
index 402bc7039..d4be555be 100644
--- a/src/trace_processor/sqlite/query_constraints_unittest.cc
+++ b/src/trace_processor/sqlite/query_constraints_unittest.cc
@@ -35,11 +35,11 @@ class QueryConstraintsTest : public ::testing::Test {
};
TEST_F(QueryConstraintsTest, ConvertToAndFromSqlString) {
- QueryConstraints qc;
+ QueryConstraints qc(0);
qc.AddConstraint(12, 0, 0);
QueryConstraints::SqliteString only_constraint = qc.ToNewSqlite3String();
- ASSERT_TRUE(strcmp(only_constraint.get(), "C1,12,0,O0") == 0);
+ ASSERT_TRUE(strcmp(only_constraint.get(), "C1,12,0;O0;U0") == 0);
QueryConstraints qc_constraint =
QueryConstraints::FromString(only_constraint.get());
@@ -49,17 +49,17 @@ TEST_F(QueryConstraintsTest, ConvertToAndFromSqlString) {
qc.AddOrderBy(21, true);
QueryConstraints::SqliteString result = qc.ToNewSqlite3String();
- ASSERT_TRUE(strcmp(result.get(), "C1,12,0,O2,1,0,21,1") == 0);
+ ASSERT_TRUE(strcmp(result.get(), "C1,12,0;O2,1,0,21,1;U0") == 0);
QueryConstraints qc_result = QueryConstraints::FromString(result.get());
ASSERT_EQ(qc, qc_result);
}
TEST_F(QueryConstraintsTest, CheckEmptyConstraints) {
- QueryConstraints qc;
+ QueryConstraints qc(0);
QueryConstraints::SqliteString string_result = qc.ToNewSqlite3String();
- ASSERT_TRUE(strcmp(string_result.get(), "C0,O0") == 0);
+ ASSERT_TRUE(strcmp(string_result.get(), "C0;O0;U0") == 0);
QueryConstraints qc_result =
QueryConstraints::FromString(string_result.get());
@@ -68,17 +68,35 @@ TEST_F(QueryConstraintsTest, CheckEmptyConstraints) {
}
TEST_F(QueryConstraintsTest, OnlyOrderBy) {
- QueryConstraints qc;
+ QueryConstraints qc(0);
qc.AddOrderBy(3, true);
QueryConstraints::SqliteString string_result = qc.ToNewSqlite3String();
- ASSERT_TRUE(strcmp(string_result.get(), "C0,O1,3,1") == 0);
+ ASSERT_TRUE(strcmp(string_result.get(), "C0;O1,3,1;U0") == 0);
QueryConstraints qc_result =
QueryConstraints::FromString(string_result.get());
ASSERT_EQ(qc, qc_result);
}
+TEST_F(QueryConstraintsTest, ColsUsed) {
+ ASSERT_EQ(QueryConstraints(0), QueryConstraints::FromString("C0;O0;U0"));
+
+ ASSERT_EQ(QueryConstraints(4), QueryConstraints::FromString("C0;O0;U4"));
+
+ ASSERT_EQ(QueryConstraints(1ull << 63),
+ QueryConstraints::FromString("C0;O0;U9223372036854775808"));
+
+ ASSERT_EQ(QueryConstraints(9223372036854775807ull),
+ QueryConstraints::FromString("C0;O0;U9223372036854775807"));
+
+ ASSERT_EQ(QueryConstraints(),
+ QueryConstraints::FromString("C0;O0;U18446744073709551615"));
+
+ auto str = QueryConstraints(0xFFFFFFFFFFFFFFFF).ToNewSqlite3String();
+ ASSERT_STREQ(str.get(), "C0;O0;U18446744073709551615");
+}
+
} // namespace
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/sqlite/register_function.cc b/src/trace_processor/sqlite/register_function.cc
new file mode 100644
index 000000000..431e4d66f
--- /dev/null
+++ b/src/trace_processor/sqlite/register_function.cc
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/sqlite/register_function.h"
+#include "sqlite3.h"
+#include "src/trace_processor/sqlite/sqlite_utils.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+base::Status SqlFunction::Cleanup(Context*) {
+ return base::OkStatus();
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/sqlite/register_function.h b/src/trace_processor/sqlite/register_function.h
new file mode 100644
index 000000000..1761af429
--- /dev/null
+++ b/src/trace_processor/sqlite/register_function.h
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_SQLITE_REGISTER_FUNCTION_H_
+#define SRC_TRACE_PROCESSOR_SQLITE_REGISTER_FUNCTION_H_
+
+#include <sqlite3.h>
+#include <memory>
+
+#include "src/trace_processor/sqlite/sqlite_utils.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+// Prototype for a C++ function which can be registered with SQLite.
+//
+// Usage
+//
+// Define a subclass of this struct as follows:
+// struct YourFunction : public SqlFunction {
+// // Optional if you want a custom context object (i.e. an object
+// // passed in at registration time which will be passed to Run on
+// // every invocation)
+// struct YourContext { /* define context fields here */ };
+//
+// static base::Status Run(/* see parameters below */) {
+// /* function body here */
+// }
+//
+// static base::Status Cleanup(/* see parameters below */) {
+// /* function body here */
+// }
+// }
+//
+// Then, register this function with SQLite using RegisterFunction (see below);
+// you'll likely want to do this in TraceProcessorImpl:
+// RegisterFunction<YourFunction>(/* see arguments below */)
+struct SqlFunction {
+ // The type of the context object which will be passed to the function.
+ // Can be redefined in any sub-classes to override the context.
+ using Context = void;
+
+ // Struct which holds destructors for strings/bytes returned from the
+ // function. Passed as an argument to |Run| to allow implementations to
+ // override the destructors.
+ struct Destructors {
+ sqlite3_destructor_type string_destructor = sqlite_utils::kSqliteTransient;
+ sqlite3_destructor_type bytes_destructor = sqlite_utils::kSqliteTransient;
+ };
+
+ // The function which will be exectued with the arguments from SQL.
+ //
+ // Implementations MUST define this function themselves; this function is
+ // declared but *not* defined so linker errors will be thrown if not defined.
+ //
+ // |ctx|: the context object passed at registration time.
+ // |argc|: number of arguments.
+ // |argv|: arguments to the function.
+ // |out|: the return value of the function.
+ // |destructors|: destructors for string/bytes return values.
+ static base::Status Run(Context* ctx,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors& destructors);
+
+ // Executed after the result from |Run| is reported to SQLite.
+ // Allows any pending state to be cleaned up post-copy of results by SQLite.
+ //
+ // Implementations do not need to define this function; a default no-op
+ // implementation will be used in this case.
+ static base::Status Cleanup(Context*);
+};
+
+// Registers a C++ function to be runnable from SQL.
+// The format of the function is given by the |SqlFunction|; see the
+// documentaion above.
+//
+// |db|: sqlite3 database object
+// |name|: name of the function in SQL
+// |argc|: number of arguments for this function, -1 if variable
+// |ctx|: context object for the function (see SqlFunction::Run above);
+// this object *must* outlive the function so should likely be
+// either static or scoped to the lifetime of TraceProcessor.
+// |determistic|: whether this function has deterministic output given the
+// same set of arguments.
+template <typename Function>
+base::Status RegisterSqlFunction(sqlite3* db,
+ const char* name,
+ int argc,
+ typename Function::Context* ctx,
+ bool deterministic = true);
+
+// Same as above except allows a unique_ptr to be passed for the context; this
+// allows for SQLite to manage the lifetime of this pointer instead of the
+// essentially static requirement of the context pointer above.
+template <typename Function>
+base::Status RegisterSqlFunction(
+ sqlite3* db,
+ const char* name,
+ int argc,
+ std::unique_ptr<typename Function::Context> ctx,
+ bool deterministic = true);
+
+} // namespace trace_processor
+} // namespace perfetto
+
+// The rest of this file is just implementation details which we need
+// in the header file because it is templated code. We separate it out
+// like this to keep the API people actually care about easy to read.
+
+namespace perfetto {
+namespace trace_processor {
+
+namespace sqlite_internal {
+template <typename Function>
+void WrapSqlFunction(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
+ using Context = typename Function::Context;
+ auto* ud = static_cast<Context*>(sqlite3_user_data(ctx));
+
+ SqlValue value{};
+ SqlFunction::Destructors destructors{};
+ base::Status status =
+ Function::Run(ud, static_cast<size_t>(argc), argv, value, destructors);
+
+ if (!status.ok()) {
+ sqlite3_result_error(ctx, status.c_message(), -1);
+ return;
+ }
+ sqlite_utils::ReportSqlValue(ctx, value, destructors.string_destructor,
+ destructors.bytes_destructor);
+
+ status = Function::Cleanup(ud);
+ if (!status.ok()) {
+ sqlite3_result_error(ctx, status.c_message(), -1);
+ return;
+ }
+}
+} // namespace sqlite_internal
+
+template <typename Function>
+base::Status RegisterSqlFunction(sqlite3* db,
+ const char* name,
+ int argc,
+ typename Function::Context* ctx,
+ bool deterministic) {
+ int flags = SQLITE_UTF8 | (deterministic ? SQLITE_DETERMINISTIC : 0);
+ int ret = sqlite3_create_function_v2(
+ db, name, static_cast<int>(argc), flags, ctx,
+ sqlite_internal::WrapSqlFunction<Function>, nullptr, nullptr, nullptr);
+ if (ret != SQLITE_OK) {
+ return base::ErrStatus("Unable to register function with name %s", name);
+ }
+ return base::OkStatus();
+}
+
+template <typename Function>
+base::Status RegisterSqlFunction(
+ sqlite3* db,
+ const char* name,
+ int argc,
+ std::unique_ptr<typename Function::Context> user_data,
+ bool deterministic) {
+ int flags = SQLITE_UTF8 | (deterministic ? SQLITE_DETERMINISTIC : 0);
+ int ret = sqlite3_create_function_v2(
+ db, name, static_cast<int>(argc), flags, user_data.release(),
+ sqlite_internal::WrapSqlFunction<Function>, nullptr, nullptr,
+ [](void* ptr) { delete static_cast<typename Function::Context*>(ptr); });
+ if (ret != SQLITE_OK) {
+ return base::ErrStatus("Unable to register function with name %s", name);
+ }
+ return base::OkStatus();
+}
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_SQLITE_REGISTER_FUNCTION_H_
diff --git a/src/trace_processor/sqlite/scoped_db.h b/src/trace_processor/sqlite/scoped_db.h
index 857b316f1..7923635d9 100644
--- a/src/trace_processor/sqlite/scoped_db.h
+++ b/src/trace_processor/sqlite/scoped_db.h
@@ -37,6 +37,13 @@ using ScopedStmt = base::ScopedResource<sqlite3_stmt*,
nullptr,
/*CheckClose=*/false>;
+inline int FreeSqliteString(char* ptr) {
+ sqlite3_free(ptr);
+ return 0;
+}
+using ScopedSqliteString =
+ base::ScopedResource<char*, FreeSqliteString, nullptr>;
+
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/sqlite/span_join_operator_table.cc b/src/trace_processor/sqlite/span_join_operator_table.cc
index c6c3b78a1..37a41ba1a 100644
--- a/src/trace_processor/sqlite/span_join_operator_table.cc
+++ b/src/trace_processor/sqlite/span_join_operator_table.cc
@@ -29,6 +29,7 @@
#include "perfetto/ext/base/string_view.h"
#include "src/trace_processor/sqlite/sqlite_utils.h"
#include "src/trace_processor/tp_metatrace.h"
+#include "src/trace_processor/util/status_macros.h"
namespace perfetto {
namespace trace_processor {
@@ -144,10 +145,6 @@ util::Status SpanJoinOperatorTable::Init(int argc,
partitioning_ = t1_desc.IsPartitioned()
? PartitioningType::kSamePartitioning
: PartitioningType::kNoPartitioning;
- if (partitioning_ == PartitioningType::kNoPartitioning && IsOuterJoin()) {
- return util::ErrStatus(
- "SPAN_JOIN: Outer join not supported for no partition tables");
- }
} else if (t1_desc.IsPartitioned() && t2_desc.IsPartitioned()) {
return util::ErrStatus(
"SPAN_JOIN: mismatching partitions between the two tables; "
@@ -155,10 +152,6 @@ util::Status SpanJoinOperatorTable::Init(int argc,
t1_desc.partition_col.c_str(), t1_desc.name.c_str(),
t2_desc.partition_col.c_str(), t2_desc.name.c_str());
} else {
- if (IsOuterJoin()) {
- return util::ErrStatus(
- "SPAN_JOIN: Outer join not supported for mixed partitioned tables");
- }
partitioning_ = PartitioningType::kMixedPartitioning;
}
@@ -210,7 +203,7 @@ util::Status SpanJoinOperatorTable::Init(int argc,
// Check if any column has : in its name. This often happens when SELECT *
// is used to create a view with the same column name in two joined tables.
for (const auto& col : cols) {
- if (col.name().find(':') != std::string::npos) {
+ if (base::Contains(col.name(), ':')) {
return util::ErrStatus("SPAN_JOIN: column %s has illegal character :",
col.name().c_str());
}
@@ -421,16 +414,24 @@ int SpanJoinOperatorTable::Cursor::Filter(const QueryConstraints& qc,
FilterHistory) {
PERFETTO_TP_TRACE("SPAN_JOIN_XFILTER");
- util::Status status =
- t1_.Initialize(qc, argv, Query::InitialEofBehavior::kTreatAsEof);
+ bool t1_partitioned_mixed =
+ t1_.definition()->IsPartitioned() &&
+ table_->partitioning_ == PartitioningType::kMixedPartitioning;
+ auto t1_eof = table_->IsOuterJoin() && !t1_partitioned_mixed
+ ? Query::InitialEofBehavior::kTreatAsMissingPartitionShadow
+ : Query::InitialEofBehavior::kTreatAsEof;
+ util::Status status = t1_.Initialize(qc, argv, t1_eof);
if (!status.ok())
return SQLITE_ERROR;
- status = t2_.Initialize(
- qc, argv,
- table_->IsLeftJoin()
+ bool t2_partitioned_mixed =
+ t2_.definition()->IsPartitioned() &&
+ table_->partitioning_ == PartitioningType::kMixedPartitioning;
+ auto t2_eof =
+ (table_->IsLeftJoin() || table_->IsOuterJoin()) && !t2_partitioned_mixed
? Query::InitialEofBehavior::kTreatAsMissingPartitionShadow
- : Query::InitialEofBehavior::kTreatAsEof);
+ : Query::InitialEofBehavior::kTreatAsEof;
+ status = t2_.Initialize(qc, argv, t2_eof);
if (!status.ok())
return SQLITE_ERROR;
@@ -636,9 +637,7 @@ util::Status SpanJoinOperatorTable::Query::Initialize(
}
util::Status SpanJoinOperatorTable::Query::Next() {
- util::Status status = NextSliceState();
- if (!status.ok())
- return status;
+ RETURN_IF_ERROR(NextSliceState());
return FindNextValidSlice();
}
@@ -671,9 +670,7 @@ util::Status SpanJoinOperatorTable::Query::FindNextValidSlice() {
// This has proved to be a lot cleaner to implement than trying to choose
// when to emit and not emit shadows directly.
while (!IsEof() && !IsValidSlice()) {
- util::Status status = NextSliceState();
- if (!status.ok())
- return status;
+ RETURN_IF_ERROR(NextSliceState());
}
return util::OkStatus();
}
@@ -682,9 +679,7 @@ util::Status SpanJoinOperatorTable::Query::NextSliceState() {
switch (state_) {
case State::kReal: {
// Forward the cursor to figure out where the next slice should be.
- util::Status status = CursorNext();
- if (!status.ok())
- return status;
+ RETURN_IF_ERROR(CursorNext());
// Depending on the next slice, we can do two things here:
// 1. If the next slice is on the same partition, we can just emit a
@@ -763,9 +758,7 @@ util::Status SpanJoinOperatorTable::Query::Rewind() {
if (res != SQLITE_OK)
return util::ErrStatus("%s", sqlite3_errmsg(db_));
- util::Status status = CursorNext();
- if (!status.ok())
- return status;
+ RETURN_IF_ERROR(CursorNext());
// Setup the first slice as a missing partition shadow from the lowest
// partition until the first slice partition. We will handle finding the real
@@ -798,13 +791,17 @@ util::Status SpanJoinOperatorTable::Query::CursorNext() {
res = sqlite3_step(stmt);
row_type = sqlite3_column_type(stmt, partition_idx);
} while (res == SQLITE_ROW && row_type == SQLITE_NULL);
+
+ if (res == SQLITE_ROW && row_type != SQLITE_INTEGER) {
+ return util::ErrStatus("SPAN_JOIN: partition is not an int");
+ }
} else {
res = sqlite3_step(stmt);
}
cursor_eof_ = res != SQLITE_ROW;
return res == SQLITE_ROW || res == SQLITE_DONE
? util::OkStatus()
- : util::ErrStatus("%s", sqlite3_errmsg(db_));
+ : util::ErrStatus("SPAN_JOIN: %s", sqlite3_errmsg(db_));
}
std::string SpanJoinOperatorTable::Query::CreateSqlQuery(
diff --git a/src/trace_processor/sqlite/span_join_operator_table.h b/src/trace_processor/sqlite/span_join_operator_table.h
index ebfb867d7..a6256f867 100644
--- a/src/trace_processor/sqlite/span_join_operator_table.h
+++ b/src/trace_processor/sqlite/span_join_operator_table.h
@@ -25,9 +25,9 @@
#include <map>
#include <memory>
#include <string>
-#include <unordered_map>
#include <vector>
+#include "perfetto/ext/base/flat_hash_map.h"
#include "perfetto/trace_processor/basic_types.h"
#include "perfetto/trace_processor/status.h"
#include "src/trace_processor/sqlite/scoped_db.h"
@@ -39,7 +39,7 @@ namespace trace_processor {
// Implements the SPAN JOIN operation between two tables on a particular column.
//
// Span:
-// A span is a row with a timestamp and a duration. It can is used to model
+// A span is a row with a timestamp and a duration. It is used to model
// operations which run for a particular *span* of time.
//
// We draw spans like so (time on the x-axis):
@@ -428,7 +428,7 @@ class SpanJoinOperatorTable : public SqliteTable {
TableDefinition t1_defn_;
TableDefinition t2_defn_;
PartitioningType partitioning_;
- std::unordered_map<size_t, ColumnLocator> global_index_to_column_locator_;
+ base::FlatHashMap<size_t, ColumnLocator> global_index_to_column_locator_;
sqlite3* const db_;
};
diff --git a/src/trace_processor/sqlite/sql_stats_table.cc b/src/trace_processor/sqlite/sql_stats_table.cc
index 372dc1e04..59022577b 100644
--- a/src/trace_processor/sqlite/sql_stats_table.cc
+++ b/src/trace_processor/sqlite/sql_stats_table.cc
@@ -39,8 +39,6 @@ util::Status SqlStatsTable::Init(int, const char* const*, Schema* schema) {
*schema = Schema(
{
SqliteTable::Column(Column::kQuery, "query", SqlValue::Type::kString),
- SqliteTable::Column(Column::kTimeQueued, "queued",
- SqlValue::Type::kLong),
SqliteTable::Column(Column::kTimeStarted, "started",
SqlValue::Type::kLong),
SqliteTable::Column(Column::kTimeFirstNext, "first_next",
@@ -48,7 +46,7 @@ util::Status SqlStatsTable::Init(int, const char* const*, Schema* schema) {
SqliteTable::Column(Column::kTimeEnded, "ended",
SqlValue::Type::kLong),
},
- {Column::kTimeQueued});
+ {Column::kTimeStarted});
return util::OkStatus();
}
@@ -89,9 +87,6 @@ int SqlStatsTable::Cursor::Column(sqlite3_context* context, int col) {
sqlite3_result_text(context, stats.queries()[row_].c_str(), -1,
sqlite_utils::kSqliteStatic);
break;
- case Column::kTimeQueued:
- sqlite3_result_int64(context, stats.times_queued()[row_]);
- break;
case Column::kTimeStarted:
sqlite3_result_int64(context, stats.times_started()[row_]);
break;
diff --git a/src/trace_processor/sqlite/sql_stats_table.h b/src/trace_processor/sqlite/sql_stats_table.h
index c146ee8f0..d2d1c5d46 100644
--- a/src/trace_processor/sqlite/sql_stats_table.h
+++ b/src/trace_processor/sqlite/sql_stats_table.h
@@ -34,10 +34,9 @@ class SqlStatsTable : public SqliteTable {
public:
enum Column {
kQuery = 0,
- kTimeQueued = 1,
- kTimeStarted = 2,
- kTimeFirstNext = 3,
- kTimeEnded = 4,
+ kTimeStarted = 1,
+ kTimeFirstNext = 2,
+ kTimeEnded = 3,
};
// Implementation of the SQLite cursor interface.
diff --git a/src/trace_processor/sqlite/sqlite_raw_table.cc b/src/trace_processor/sqlite/sqlite_raw_table.cc
index b02abf4e0..a42d83baa 100644
--- a/src/trace_processor/sqlite/sqlite_raw_table.cc
+++ b/src/trace_processor/sqlite/sqlite_raw_table.cc
@@ -16,7 +16,7 @@
#include "src/trace_processor/sqlite/sqlite_raw_table.h"
-#include <inttypes.h>
+#include <cinttypes>
#include "perfetto/base/compiler.h"
#include "perfetto/ext/base/string_utils.h"
@@ -29,6 +29,7 @@
#include "src/trace_processor/types/variadic.h"
#include "protos/perfetto/trace/ftrace/binder.pbzero.h"
+#include "protos/perfetto/trace/ftrace/cgroup.pbzero.h"
#include "protos/perfetto/trace/ftrace/clk.pbzero.h"
#include "protos/perfetto/trace/ftrace/dpu.pbzero.h"
#include "protos/perfetto/trace/ftrace/filemap.pbzero.h"
@@ -58,7 +59,7 @@ class ArgsSerializer {
ArgsSerializer(TraceProcessorContext*,
ArgSetId arg_set_id,
NullTermStringView event_name,
- std::vector<uint32_t>* field_id_to_arg_index,
+ std::vector<base::Optional<uint32_t>>* field_id_to_arg_index,
base::StringWriter*);
void SerializeArgs();
@@ -67,43 +68,35 @@ class ArgsSerializer {
using ValueWriter = std::function<void(const Variadic&)>;
using SerializerValueWriter = void (ArgsSerializer::*)(const Variadic&);
- void WriteArgForField(uint32_t field_id) {
- WriteArgForField(field_id,
- [this](const Variadic& v) { return WriteValue(v); });
- }
-
- void WriteArgForField(uint32_t field_id, SerializerValueWriter writer) {
- WriteArgForField(field_id, [this, writer](const Variadic& variadic) {
- (this->*writer)(variadic);
- });
- }
-
+ // Arg writing functions.
void WriteArgForField(uint32_t field_id, ValueWriter writer) {
- WriteArgAtRow(FieldIdToRow(field_id), writer);
+ base::Optional<uint32_t> row = FieldIdToRow(field_id);
+ if (!row)
+ return;
+ WriteArgAtRow(*row, writer);
}
-
- void WriteValueForField(uint32_t field_id) {
- WriteValueForField(field_id,
- [this](const Variadic& v) { return WriteValue(v); });
+ void WriteArgForField(uint32_t field_id,
+ base::StringView key,
+ ValueWriter writer) {
+ base::Optional<uint32_t> row = FieldIdToRow(field_id);
+ if (!row)
+ return;
+ WriteArg(key, storage_->GetArgValue(*row), writer);
}
-
- void WriteValueForField(uint32_t field_id, SerializerValueWriter writer) {
- WriteValueForField(field_id, [this, writer](const Variadic& variadic) {
- (this->*writer)(variadic);
- });
+ void WriteArgAtRow(uint32_t arg_row, ValueWriter writer) {
+ const auto& args = storage_->arg_table();
+ const auto& key = storage_->GetString(args.key()[arg_row]);
+ WriteArg(key, storage_->GetArgValue(arg_row), writer);
}
+ void WriteArg(base::StringView key, Variadic value, ValueWriter writer);
+ // Value writing functions.
void WriteValueForField(uint32_t field_id, ValueWriter writer) {
- writer(storage_->GetArgValue(FieldIdToRow(field_id)));
+ base::Optional<uint32_t> row = FieldIdToRow(field_id);
+ if (!row)
+ return;
+ writer(storage_->GetArgValue(*row));
}
-
- void WriteArgAtRow(uint32_t arg_index) {
- WriteArgAtRow(arg_index,
- [this](const Variadic& v) { return WriteValue(v); });
- }
-
- void WriteArgAtRow(uint32_t arg_index, ValueWriter writer);
-
void WriteKernelFnValue(const Variadic& value) {
if (value.type == Variadic::Type::kUint) {
writer_->AppendHexInt(value.uint_value);
@@ -113,21 +106,30 @@ class ArgsSerializer {
PERFETTO_DFATAL("Invalid field type %d", static_cast<int>(value.type));
}
}
-
void WriteValue(const Variadic& variadic);
- uint32_t FieldIdToRow(uint32_t field_id) {
+ // The default value writer which uses the |WriteValue| function.
+ ValueWriter DVW() { return Wrap(&ArgsSerializer::WriteValue); }
+ ValueWriter Wrap(SerializerValueWriter writer) {
+ return [this, writer](const Variadic& v) { (this->*writer)(v); };
+ }
+
+ // Converts a field id to a row in the args table.
+ base::Optional<uint32_t> FieldIdToRow(uint32_t field_id) {
PERFETTO_DCHECK(field_id > 0);
PERFETTO_DCHECK(field_id < field_id_to_arg_index_->size());
- uint32_t index_in_arg_set = (*field_id_to_arg_index_)[field_id];
- return start_row_ + index_in_arg_set;
+ base::Optional<uint32_t> index_in_arg_set =
+ (*field_id_to_arg_index_)[field_id];
+ return index_in_arg_set.has_value()
+ ? base::make_optional(start_row_ + *index_in_arg_set)
+ : base::nullopt;
}
const TraceStorage* storage_ = nullptr;
TraceProcessorContext* context_ = nullptr;
ArgSetId arg_set_id_ = kInvalidArgSetId;
NullTermStringView event_name_;
- std::vector<uint32_t>* field_id_to_arg_index_;
+ std::vector<base::Optional<uint32_t>>* field_id_to_arg_index_;
RowMap row_map_;
uint32_t start_row_ = 0;
@@ -135,11 +137,12 @@ class ArgsSerializer {
base::StringWriter* writer_ = nullptr;
};
-ArgsSerializer::ArgsSerializer(TraceProcessorContext* context,
- ArgSetId arg_set_id,
- NullTermStringView event_name,
- std::vector<uint32_t>* field_id_to_arg_index,
- base::StringWriter* writer)
+ArgsSerializer::ArgsSerializer(
+ TraceProcessorContext* context,
+ ArgSetId arg_set_id,
+ NullTermStringView event_name,
+ std::vector<base::Optional<uint32_t>>* field_id_to_arg_index,
+ base::StringWriter* writer)
: context_(context),
arg_set_id_(arg_set_id),
event_name_(event_name),
@@ -179,9 +182,9 @@ ArgsSerializer::ArgsSerializer(TraceProcessorContext* context,
// Go through each field id and find the entry in the args table for that
for (uint32_t i = 1; i <= max; ++i) {
for (auto it = row_map_.IterateRows(); it; it.Next()) {
- base::StringView key = args.key().GetString(it.row());
+ base::StringView key = args.key().GetString(it.index());
if (key == descriptor->fields[i].name) {
- (*field_id_to_arg_index)[i] = it.index();
+ (*field_id_to_arg_index)[i] = it.row();
break;
}
}
@@ -195,9 +198,9 @@ void ArgsSerializer::SerializeArgs() {
if (event_name_ == "sched_switch") {
using SS = protos::pbzero::SchedSwitchFtraceEvent;
- WriteArgForField(SS::kPrevCommFieldNumber);
- WriteArgForField(SS::kPrevPidFieldNumber);
- WriteArgForField(SS::kPrevPrioFieldNumber);
+ WriteArgForField(SS::kPrevCommFieldNumber, DVW());
+ WriteArgForField(SS::kPrevPidFieldNumber, DVW());
+ WriteArgForField(SS::kPrevPrioFieldNumber, DVW());
WriteArgForField(SS::kPrevStateFieldNumber, [this](const Variadic& value) {
PERFETTO_DCHECK(value.type == Variadic::Type::kInt);
auto state = static_cast<uint16_t>(value.int_value);
@@ -207,15 +210,15 @@ void ArgsSerializer::SerializeArgs() {
ftrace_utils::TaskState(state, kernel_version).ToString('|').data());
});
writer_->AppendLiteral(" ==>");
- WriteArgForField(SS::kNextCommFieldNumber);
- WriteArgForField(SS::kNextPidFieldNumber);
- WriteArgForField(SS::kNextPrioFieldNumber);
+ WriteArgForField(SS::kNextCommFieldNumber, DVW());
+ WriteArgForField(SS::kNextPidFieldNumber, DVW());
+ WriteArgForField(SS::kNextPrioFieldNumber, DVW());
return;
} else if (event_name_ == "sched_wakeup") {
using SW = protos::pbzero::SchedWakeupFtraceEvent;
- WriteArgForField(SW::kCommFieldNumber);
- WriteArgForField(SW::kPidFieldNumber);
- WriteArgForField(SW::kPrioFieldNumber);
+ WriteArgForField(SW::kCommFieldNumber, DVW());
+ WriteArgForField(SW::kPidFieldNumber, DVW());
+ WriteArgForField(SW::kPrioFieldNumber, DVW());
WriteArgForField(SW::kTargetCpuFieldNumber, [this](const Variadic& value) {
PERFETTO_DCHECK(value.type == Variadic::Type::kInt);
writer_->AppendPaddedInt<'0', 3>(value.int_value);
@@ -224,28 +227,28 @@ void ArgsSerializer::SerializeArgs() {
} else if (event_name_ == "clock_set_rate") {
using CSR = protos::pbzero::ClockSetRateFtraceEvent;
writer_->AppendLiteral(" ");
- WriteValueForField(CSR::kNameFieldNumber);
- WriteArgForField(CSR::kStateFieldNumber);
- WriteArgForField(CSR::kCpuIdFieldNumber);
+ WriteValueForField(CSR::kNameFieldNumber, DVW());
+ WriteArgForField(CSR::kStateFieldNumber, DVW());
+ WriteArgForField(CSR::kCpuIdFieldNumber, DVW());
return;
} else if (event_name_ == "clk_set_rate") {
using CSR = protos::pbzero::ClkSetRateFtraceEvent;
writer_->AppendLiteral(" ");
- WriteValueForField(CSR::kNameFieldNumber);
+ WriteValueForField(CSR::kNameFieldNumber, DVW());
writer_->AppendLiteral(" ");
- WriteValueForField(CSR::kRateFieldNumber);
+ WriteValueForField(CSR::kRateFieldNumber, DVW());
return;
} else if (event_name_ == "clock_enable") {
using CE = protos::pbzero::ClockEnableFtraceEvent;
- WriteValueForField(CE::kNameFieldNumber);
- WriteArgForField(CE::kStateFieldNumber);
- WriteArgForField(CE::kCpuIdFieldNumber);
+ WriteValueForField(CE::kNameFieldNumber, DVW());
+ WriteArgForField(CE::kStateFieldNumber, DVW());
+ WriteArgForField(CE::kCpuIdFieldNumber, DVW());
return;
} else if (event_name_ == "clock_disable") {
using CD = protos::pbzero::ClockDisableFtraceEvent;
- WriteValueForField(CD::kNameFieldNumber);
- WriteArgForField(CD::kStateFieldNumber);
- WriteArgForField(CD::kCpuIdFieldNumber);
+ WriteValueForField(CD::kNameFieldNumber, DVW());
+ WriteArgForField(CD::kStateFieldNumber, DVW());
+ WriteArgForField(CD::kCpuIdFieldNumber, DVW());
return;
} else if (event_name_ == "binder_transaction") {
using BT = protos::pbzero::BinderTransactionFtraceEvent;
@@ -263,13 +266,13 @@ void ArgsSerializer::SerializeArgs() {
});
writer_->AppendString(" dest_proc=");
- WriteValueForField(BT::kToProcFieldNumber);
+ WriteValueForField(BT::kToProcFieldNumber, DVW());
writer_->AppendString(" dest_thread=");
- WriteValueForField(BT::kToThreadFieldNumber);
+ WriteValueForField(BT::kToThreadFieldNumber, DVW());
writer_->AppendString(" reply=");
- WriteValueForField(BT::kReplyFieldNumber);
+ WriteValueForField(BT::kReplyFieldNumber, DVW());
writer_->AppendString(" flags=0x");
WriteValueForField(BT::kFlagsFieldNumber, [this](const Variadic& value) {
@@ -291,8 +294,8 @@ void ArgsSerializer::SerializeArgs() {
PERFETTO_DCHECK(value.type == Variadic::Type::kInt);
writer_->AppendUnsignedInt(static_cast<uint32_t>(value.int_value));
});
- WriteArgForField(BTAB::kDataSizeFieldNumber);
- WriteArgForField(BTAB::kOffsetsSizeFieldNumber);
+ WriteArgForField(BTAB::kDataSizeFieldNumber, DVW());
+ WriteArgForField(BTAB::kOffsetsSizeFieldNumber, DVW());
return;
} else if (event_name_ == "binder_transaction_received") {
using BTR = protos::pbzero::BinderTransactionReceivedFtraceEvent;
@@ -321,7 +324,7 @@ void ArgsSerializer::SerializeArgs() {
});
writer_->AppendString(" page=0000000000000000");
writer_->AppendString(" pfn=");
- WriteValueForField(MFA::kPfnFieldNumber);
+ WriteValueForField(MFA::kPfnFieldNumber, DVW());
writer_->AppendString(" ofs=");
WriteValueForField(MFA::kIndexFieldNumber, [this](const Variadic& value) {
PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
@@ -345,10 +348,10 @@ void ArgsSerializer::SerializeArgs() {
return;
} else if (event_name_ == "sched_blocked_reason") {
using SBR = protos::pbzero::SchedBlockedReasonFtraceEvent;
- WriteArgForField(SBR::kPidFieldNumber);
- WriteArgForField(SBR::kIoWaitFieldNumber);
+ WriteArgForField(SBR::kPidFieldNumber, DVW());
+ WriteArgForField(SBR::kIoWaitFieldNumber, DVW());
WriteArgForField(SBR::kCallerFieldNumber,
- &ArgsSerializer::WriteKernelFnValue);
+ Wrap(&ArgsSerializer::WriteKernelFnValue));
return;
} else if (event_name_ == "workqueue_activate_work") {
using WAW = protos::pbzero::WorkqueueActivateWorkFtraceEvent;
@@ -367,7 +370,7 @@ void ArgsSerializer::SerializeArgs() {
});
writer_->AppendString(": function ");
WriteValueForField(WES::kFunctionFieldNumber,
- &ArgsSerializer::WriteKernelFnValue);
+ Wrap(&ArgsSerializer::WriteKernelFnValue));
return;
} else if (event_name_ == "workqueue_execute_end") {
using WE = protos::pbzero::WorkqueueExecuteEndFtraceEvent;
@@ -385,31 +388,31 @@ void ArgsSerializer::SerializeArgs() {
writer_->AppendHexInt(value.uint_value);
});
WriteArgForField(WQW::kFunctionFieldNumber,
- &ArgsSerializer::WriteKernelFnValue);
+ Wrap(&ArgsSerializer::WriteKernelFnValue));
WriteArgForField(WQW::kWorkqueueFieldNumber, [this](const Variadic& value) {
PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
writer_->AppendHexInt(value.uint_value);
});
- WriteValueForField(WQW::kReqCpuFieldNumber);
- WriteValueForField(WQW::kCpuFieldNumber);
+ WriteValueForField(WQW::kReqCpuFieldNumber, DVW());
+ WriteValueForField(WQW::kCpuFieldNumber, DVW());
return;
} else if (event_name_ == "irq_handler_entry") {
using IEN = protos::pbzero::IrqHandlerEntryFtraceEvent;
- WriteArgForField(IEN::kIrqFieldNumber);
- WriteArgForField(IEN::kNameFieldNumber);
+ WriteArgForField(IEN::kIrqFieldNumber, DVW());
+ WriteArgForField(IEN::kNameFieldNumber, DVW());
return;
} else if (event_name_ == "irq_handler_exit") {
using IEX = protos::pbzero::IrqHandlerExitFtraceEvent;
- WriteArgForField(IEX::kIrqFieldNumber);
+ WriteArgForField(IEX::kIrqFieldNumber, DVW());
writer_->AppendString(" ret=");
WriteValueForField(IEX::kRetFieldNumber, [this](const Variadic& value) {
- PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
- writer_->AppendString(value.uint_value ? "handled" : "unhandled");
+ PERFETTO_DCHECK(value.type == Variadic::Type::kInt);
+ writer_->AppendString(value.int_value ? "handled" : "unhandled");
});
return;
} else if (event_name_ == "softirq_entry") {
using SIE = protos::pbzero::SoftirqEntryFtraceEvent;
- WriteArgForField(SIE::kVecFieldNumber);
+ WriteArgForField(SIE::kVecFieldNumber, DVW());
writer_->AppendString(" [action=");
WriteValueForField(SIE::kVecFieldNumber, [this](const Variadic& value) {
PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
@@ -419,7 +422,7 @@ void ArgsSerializer::SerializeArgs() {
return;
} else if (event_name_ == "softirq_exit") {
using SIX = protos::pbzero::SoftirqExitFtraceEvent;
- WriteArgForField(SIX::kVecFieldNumber);
+ WriteArgForField(SIX::kVecFieldNumber, DVW());
writer_->AppendString(" [action=");
WriteValueForField(SIX::kVecFieldNumber, [this](const Variadic& value) {
PERFETTO_DCHECK(value.type == Variadic::Type::kUint);
@@ -434,11 +437,11 @@ void ArgsSerializer::SerializeArgs() {
writer_->AppendChar(static_cast<char>(value.uint_value));
});
writer_->AppendString("|");
- WriteValueForField(TMW::kPidFieldNumber);
+ WriteValueForField(TMW::kPidFieldNumber, DVW());
writer_->AppendString("|");
- WriteValueForField(TMW::kNameFieldNumber);
+ WriteValueForField(TMW::kNameFieldNumber, DVW());
writer_->AppendString("|");
- WriteValueForField(TMW::kValueFieldNumber);
+ WriteValueForField(TMW::kValueFieldNumber, DVW());
return;
} else if (event_name_ == "g2d_tracing_mark_write") {
using TMW = protos::pbzero::G2dTracingMarkWriteFtraceEvent;
@@ -447,25 +450,33 @@ void ArgsSerializer::SerializeArgs() {
writer_->AppendChar(static_cast<char>(value.uint_value));
});
writer_->AppendString("|");
- WriteValueForField(TMW::kPidFieldNumber);
+ WriteValueForField(TMW::kPidFieldNumber, DVW());
writer_->AppendString("|");
- WriteValueForField(TMW::kNameFieldNumber);
+ WriteValueForField(TMW::kNameFieldNumber, DVW());
writer_->AppendString("|");
- WriteValueForField(TMW::kValueFieldNumber);
+ WriteValueForField(TMW::kValueFieldNumber, DVW());
+ return;
+ } else if (event_name_ == "cgroup_attach_task") {
+ using CAT = protos::pbzero::CgroupAttachTaskFtraceEvent;
+ WriteArgForField(CAT::kDstRootFieldNumber, DVW());
+ WriteArgForField(CAT::kDstIdFieldNumber, DVW());
+ WriteArgForField(CAT::kCnameFieldNumber, "cgroup", DVW());
+ WriteArgForField(CAT::kDstLevelFieldNumber, DVW());
+ WriteArgForField(CAT::kDstPathFieldNumber, DVW());
+ WriteArgForField(CAT::kPidFieldNumber, DVW());
+ WriteArgForField(CAT::kCommFieldNumber, DVW());
return;
}
for (auto it = row_map_.IterateRows(); it; it.Next()) {
- WriteArgAtRow(it.row());
+ WriteArgAtRow(it.index(), DVW());
}
}
-void ArgsSerializer::WriteArgAtRow(uint32_t arg_row, ValueWriter writer) {
- const auto& args = storage_->arg_table();
- const auto& key = storage_->GetString(args.key()[arg_row]);
- auto value = storage_->GetArgValue(arg_row);
-
+void ArgsSerializer::WriteArg(base::StringView key,
+ Variadic value,
+ ValueWriter writer) {
writer_->AppendChar(' ');
- writer_->AppendString(key.c_str(), key.size());
+ writer_->AppendString(key.data(), key.size());
writer_->AppendChar('=');
if (key == "gfp_flags") {
@@ -504,6 +515,9 @@ void ArgsSerializer::WriteValue(const Variadic& value) {
writer_->AppendString(str.c_str(), str.size());
break;
}
+ case Variadic::kNull:
+ writer_->AppendLiteral("[NULL]");
+ break;
}
}
@@ -543,7 +557,13 @@ void SqliteRawTable::ToSystrace(sqlite3_context* ctx,
uint32_t row = static_cast<uint32_t>(sqlite3_value_int64(argv[0]));
auto str = serializer_.SerializeToString(row);
- sqlite3_result_text(ctx, str.release(), -1, free);
+ if (str.get() == nullptr) {
+ base::StackString<128> err("to_ftrace: Cannot serialize row id %u", row);
+ sqlite3_result_error(ctx, err.c_str(), -1);
+ return;
+ }
+
+ sqlite3_result_text(ctx, str.release(), -1, str.get_deleter());
}
SystraceSerializer::SystraceSerializer(TraceProcessorContext* context)
@@ -558,10 +578,15 @@ SystraceSerializer::ScopedCString SystraceSerializer::SerializeToString(
char line[4096];
base::StringWriter writer(line, sizeof(line));
- SerializePrefix(raw_row, &writer);
-
StringId event_name_id = raw.name()[raw_row];
NullTermStringView event_name = storage_->GetString(event_name_id);
+ if (event_name.StartsWith("chrome_event.") ||
+ event_name.StartsWith("track_event.")) {
+ return ScopedCString(nullptr, nullptr);
+ }
+
+ SerializePrefix(raw_row, &writer);
+
writer.AppendChar(' ');
if (event_name == "print" || event_name == "g2d_tracing_mark_write" ||
event_name == "dpu_tracing_mark_write") {
@@ -594,7 +619,7 @@ void SystraceSerializer::SerializePrefix(uint32_t raw_row,
if (opt_upid.has_value()) {
tgid = storage_->process_table().pid()[*opt_upid];
}
- auto name = storage_->GetString(storage_->thread_table().name()[utid]);
+ auto name = storage_->thread_table().name().GetString(utid);
FtraceTime ftrace_time(ts);
if (tid == 0) {
diff --git a/src/trace_processor/sqlite/sqlite_raw_table.h b/src/trace_processor/sqlite/sqlite_raw_table.h
index 3722d9bf4..a3ec5c2bb 100644
--- a/src/trace_processor/sqlite/sqlite_raw_table.h
+++ b/src/trace_processor/sqlite/sqlite_raw_table.h
@@ -18,6 +18,7 @@
#define SRC_TRACE_PROCESSOR_SQLITE_SQLITE_RAW_TABLE_H_
#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/flat_hash_map.h"
#include "perfetto/ext/base/string_writer.h"
#include "src/trace_processor/sqlite/db_sqlite_table.h"
#include "src/trace_processor/storage/trace_storage.h"
@@ -31,12 +32,13 @@ class SystraceSerializer {
public:
using ScopedCString = std::unique_ptr<char, void (*)(void*)>;
- SystraceSerializer(TraceProcessorContext* context);
+ explicit SystraceSerializer(TraceProcessorContext* context);
ScopedCString SerializeToString(uint32_t raw_row);
private:
- using StringIdMap = std::unordered_map<StringId, std::vector<uint32_t>>;
+ using StringIdMap =
+ base::FlatHashMap<StringId, std::vector<base::Optional<uint32_t>>>;
void SerializePrefix(uint32_t raw_row, base::StringWriter* writer);
diff --git a/src/trace_processor/sqlite/sqlite_table.cc b/src/trace_processor/sqlite/sqlite_table.cc
index 2540a75a5..4336e4f84 100644
--- a/src/trace_processor/sqlite/sqlite_table.cc
+++ b/src/trace_processor/sqlite/sqlite_table.cc
@@ -16,10 +16,9 @@
#include "src/trace_processor/sqlite/sqlite_table.h"
-#include <ctype.h>
-#include <inttypes.h>
#include <string.h>
#include <algorithm>
+#include <cinttypes>
#include <map>
#include "perfetto/base/logging.h"
@@ -45,6 +44,66 @@ std::string TypeToString(SqlValue::Type type) {
PERFETTO_FATAL("Not reached"); // For gcc
}
+std::string OpToString(int op) {
+ switch (op) {
+ case SQLITE_INDEX_CONSTRAINT_EQ:
+ return "=";
+ case SQLITE_INDEX_CONSTRAINT_NE:
+ return "!=";
+ case SQLITE_INDEX_CONSTRAINT_GE:
+ return ">=";
+ case SQLITE_INDEX_CONSTRAINT_GT:
+ return ">";
+ case SQLITE_INDEX_CONSTRAINT_LE:
+ return "<=";
+ case SQLITE_INDEX_CONSTRAINT_LT:
+ return "<";
+ case SQLITE_INDEX_CONSTRAINT_LIKE:
+ return "like";
+ case SQLITE_INDEX_CONSTRAINT_ISNULL:
+ return "is null";
+ case SQLITE_INDEX_CONSTRAINT_ISNOTNULL:
+ return "is not null";
+ case SQLITE_INDEX_CONSTRAINT_GLOB:
+ return "glob";
+ default:
+ PERFETTO_FATAL("Operator to string conversion not impemented for %d", op);
+ }
+}
+
+std::string QcDebugStr(const QueryConstraints& qc,
+ const SqliteTable::Schema& schema) {
+ std::string str_result;
+ str_result.reserve(512);
+
+ str_result.append("C");
+ str_result.append(std::to_string(qc.constraints().size()));
+ str_result.append(",");
+ for (const auto& cs : qc.constraints()) {
+ str_result.append(schema.columns()[static_cast<size_t>(cs.column)].name());
+ str_result.append(" ");
+ str_result.append(OpToString(cs.op));
+ str_result.append(",");
+ }
+ str_result.back() = ';';
+
+ str_result.append("O");
+ str_result.append(std::to_string(qc.order_by().size()));
+ str_result.append(",");
+ for (const auto& ob : qc.order_by()) {
+ str_result.append(schema.columns()[static_cast<size_t>(ob.iColumn)].name());
+ str_result.append(" ");
+ str_result.append(std::to_string(ob.desc));
+ str_result.append(",");
+ }
+ str_result.back() = ';';
+
+ str_result.append("U");
+ str_result.append(std::to_string(qc.cols_used()));
+
+ return str_result;
+}
+
} // namespace
// static
@@ -60,7 +119,7 @@ int SqliteTable::OpenInternal(sqlite3_vtab_cursor** ppCursor) {
}
int SqliteTable::BestIndexInternal(sqlite3_index_info* idx) {
- QueryConstraints qc;
+ QueryConstraints qc(idx->colUsed);
for (int i = 0; i < idx->nConstraint; i++) {
const auto& cs = idx->aConstraint[i];
@@ -125,7 +184,7 @@ int SqliteTable::BestIndexInternal(sqlite3_index_info* idx) {
PERFETTO_LOG(
"[%s::BestIndex] constraints=%s orderByConsumed=%d estimatedCost=%f "
"estimatedRows=%" PRId64,
- name_.c_str(), out_qc_str.get(), idx->orderByConsumed,
+ name_.c_str(), QcDebugStr(qc, schema()).c_str(), idx->orderByConsumed,
idx->estimatedCost, static_cast<int64_t>(idx->estimatedRows));
}
@@ -161,7 +220,7 @@ bool SqliteTable::ReadConstraints(int idxNum, const char* idxStr, int argc) {
// happens precisely when the constraint set from SQLite changes.)
if (SqliteTable::debug && !cache_hit) {
PERFETTO_LOG("[%s::ParseConstraints] constraints=%s argc=%d", name_.c_str(),
- idxStr, argc);
+ QcDebugStr(qc_cache_, schema_).c_str(), argc);
}
return cache_hit;
}
diff --git a/src/trace_processor/sqlite/sqlite_table.h b/src/trace_processor/sqlite/sqlite_table.h
index cfb7d439a..0d42ae4f9 100644
--- a/src/trace_processor/sqlite/sqlite_table.h
+++ b/src/trace_processor/sqlite/sqlite_table.h
@@ -90,7 +90,7 @@ class SqliteTable : public sqlite3_vtab {
kSame = 1,
};
- Cursor(SqliteTable* table);
+ explicit Cursor(SqliteTable* table);
virtual ~Cursor();
// Methods to be implemented by derived table classes.
diff --git a/src/trace_processor/sqlite/sqlite_utils.h b/src/trace_processor/sqlite/sqlite_utils.h
index 889ad95ef..ad2a2321f 100644
--- a/src/trace_processor/sqlite/sqlite_utils.h
+++ b/src/trace_processor/sqlite/sqlite_utils.h
@@ -20,13 +20,8 @@
#include <math.h>
#include <sqlite3.h>
-#include <functional>
-#include <limits>
-#include <string>
-
-#include "perfetto/base/logging.h"
-#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/trace_processor/basic_types.h"
#include "src/trace_processor/sqlite/scoped_db.h"
#include "src/trace_processor/sqlite/sqlite_table.h"
@@ -37,327 +32,135 @@ namespace sqlite_utils {
const auto kSqliteStatic = reinterpret_cast<sqlite3_destructor_type>(0);
const auto kSqliteTransient = reinterpret_cast<sqlite3_destructor_type>(-1);
-template <typename T>
-using is_numeric =
- typename std::enable_if<std::is_arithmetic<T>::value, T>::type;
-
-template <typename T>
-using is_float =
- typename std::enable_if<std::is_floating_point<T>::value, T>::type;
-
-template <typename T>
-using is_int = typename std::enable_if<std::is_integral<T>::value, T>::type;
-
inline bool IsOpEq(int op) {
return op == SQLITE_INDEX_CONSTRAINT_EQ;
}
-
-inline bool IsOpGe(int op) {
- return op == SQLITE_INDEX_CONSTRAINT_GE;
-}
-
-inline bool IsOpGt(int op) {
- return op == SQLITE_INDEX_CONSTRAINT_GT;
-}
-
inline bool IsOpLe(int op) {
return op == SQLITE_INDEX_CONSTRAINT_LE;
}
-
inline bool IsOpLt(int op) {
return op == SQLITE_INDEX_CONSTRAINT_LT;
}
-
-inline bool IsOpIsNull(int op) {
- return op == SQLITE_INDEX_CONSTRAINT_ISNULL;
-}
-
-inline bool IsOpIsNotNull(int op) {
- return op == SQLITE_INDEX_CONSTRAINT_ISNOTNULL;
-}
-
-template <typename T>
-T ExtractSqliteValue(sqlite3_value* value);
-
-template <>
-inline uint8_t ExtractSqliteValue(sqlite3_value* value) {
- auto type = sqlite3_value_type(value);
- PERFETTO_DCHECK(type == SQLITE_INTEGER);
- return static_cast<uint8_t>(sqlite3_value_int(value));
-}
-
-template <>
-inline uint32_t ExtractSqliteValue(sqlite3_value* value) {
- auto type = sqlite3_value_type(value);
- PERFETTO_DCHECK(type == SQLITE_INTEGER);
- return static_cast<uint32_t>(sqlite3_value_int64(value));
-}
-
-template <>
-inline int32_t ExtractSqliteValue(sqlite3_value* value) {
- auto type = sqlite3_value_type(value);
- PERFETTO_DCHECK(type == SQLITE_INTEGER);
- return sqlite3_value_int(value);
-}
-
-template <>
-inline int64_t ExtractSqliteValue(sqlite3_value* value) {
- auto type = sqlite3_value_type(value);
- PERFETTO_DCHECK(type == SQLITE_INTEGER);
- return static_cast<int64_t>(sqlite3_value_int64(value));
-}
-
-template <>
-inline double ExtractSqliteValue(sqlite3_value* value) {
- auto type = sqlite3_value_type(value);
- PERFETTO_DCHECK(type == SQLITE_FLOAT || type == SQLITE_INTEGER);
- return sqlite3_value_double(value);
-}
-
-template <>
-inline bool ExtractSqliteValue(sqlite3_value* value) {
- auto type = sqlite3_value_type(value);
- PERFETTO_DCHECK(type == SQLITE_INTEGER);
- return static_cast<bool>(sqlite3_value_int(value));
-}
-
-// Do not add a uint64_t version of ExtractSqliteValue. You should not be using
-// uint64_t at all given that SQLite doesn't support it.
-
-template <>
-inline const char* ExtractSqliteValue(sqlite3_value* value) {
- auto type = sqlite3_value_type(value);
- PERFETTO_DCHECK(type == SQLITE_TEXT);
- return reinterpret_cast<const char*>(sqlite3_value_text(value));
+inline bool IsOpGe(int op) {
+ return op == SQLITE_INDEX_CONSTRAINT_GE;
}
-
-template <>
-inline std::string ExtractSqliteValue(sqlite3_value* value) {
- return ExtractSqliteValue<const char*>(value);
+inline bool IsOpGt(int op) {
+ return op == SQLITE_INDEX_CONSTRAINT_GT;
}
-template <typename T>
-class NumericPredicate {
- public:
- NumericPredicate(int op, T constant) : op_(op), constant_(constant) {}
-
- PERFETTO_ALWAYS_INLINE bool operator()(T other) const {
- switch (op_) {
- case SQLITE_INDEX_CONSTRAINT_ISNULL:
- return false;
- case SQLITE_INDEX_CONSTRAINT_ISNOTNULL:
- return true;
- case SQLITE_INDEX_CONSTRAINT_EQ:
- case SQLITE_INDEX_CONSTRAINT_IS:
- return std::equal_to<T>()(other, constant_);
- case SQLITE_INDEX_CONSTRAINT_NE:
- case SQLITE_INDEX_CONSTRAINT_ISNOT:
- return std::not_equal_to<T>()(other, constant_);
- case SQLITE_INDEX_CONSTRAINT_GE:
- return std::greater_equal<T>()(other, constant_);
- case SQLITE_INDEX_CONSTRAINT_GT:
- return std::greater<T>()(other, constant_);
- case SQLITE_INDEX_CONSTRAINT_LE:
- return std::less_equal<T>()(other, constant_);
- case SQLITE_INDEX_CONSTRAINT_LT:
- return std::less<T>()(other, constant_);
- default:
- PERFETTO_FATAL("For GCC");
- }
+inline SqlValue::Type SqliteTypeToSqlValueType(int sqlite_type) {
+ switch (sqlite_type) {
+ case SQLITE_NULL:
+ return SqlValue::Type::kNull;
+ case SQLITE_BLOB:
+ return SqlValue::Type::kBytes;
+ case SQLITE_INTEGER:
+ return SqlValue::Type::kLong;
+ case SQLITE_FLOAT:
+ return SqlValue::Type::kDouble;
+ case SQLITE_TEXT:
+ return SqlValue::Type::kString;
}
-
- private:
- int op_;
- T constant_;
-};
-
-template <typename T, typename sqlite_utils::is_numeric<T>* = nullptr>
-NumericPredicate<T> CreateNumericPredicate(int op, sqlite3_value* value) {
- T extracted =
- IsOpIsNull(op) || IsOpIsNotNull(op) ? 0 : ExtractSqliteValue<T>(value);
- return NumericPredicate<T>(op, extracted);
+ PERFETTO_FATAL("Unknown SQLite type %d", sqlite_type);
}
-inline std::function<bool(const char*)> CreateStringPredicate(
- int op,
- sqlite3_value* value) {
- switch (op) {
- case SQLITE_INDEX_CONSTRAINT_ISNULL:
- return [](const char* f) { return f == nullptr; };
- case SQLITE_INDEX_CONSTRAINT_ISNOTNULL:
- return [](const char* f) { return f != nullptr; };
- }
-
- const char* val = reinterpret_cast<const char*>(sqlite3_value_text(value));
-
- // If the value compared against is null, then to stay consistent with SQL
- // handling, we have to return false for non-null operators.
- if (val == nullptr) {
- PERFETTO_CHECK(op != SQLITE_INDEX_CONSTRAINT_IS &&
- op != SQLITE_INDEX_CONSTRAINT_ISNOT);
- return [](const char*) { return false; };
+inline SqlValue SqliteValueToSqlValue(sqlite3_value* value) {
+ SqlValue sql_value;
+ switch (sqlite3_value_type(value)) {
+ case SQLITE_INTEGER:
+ sql_value.type = SqlValue::Type::kLong;
+ sql_value.long_value = sqlite3_value_int64(value);
+ break;
+ case SQLITE_FLOAT:
+ sql_value.type = SqlValue::Type::kDouble;
+ sql_value.double_value = sqlite3_value_double(value);
+ break;
+ case SQLITE_TEXT:
+ sql_value.type = SqlValue::Type::kString;
+ sql_value.string_value =
+ reinterpret_cast<const char*>(sqlite3_value_text(value));
+ break;
+ case SQLITE_BLOB:
+ sql_value.type = SqlValue::Type::kBytes;
+ sql_value.bytes_value = sqlite3_value_blob(value);
+ sql_value.bytes_count = static_cast<size_t>(sqlite3_value_bytes(value));
+ break;
}
-
- switch (op) {
- case SQLITE_INDEX_CONSTRAINT_EQ:
- case SQLITE_INDEX_CONSTRAINT_IS:
- return [val](const char* str) {
- return str != nullptr && strcmp(str, val) == 0;
- };
- case SQLITE_INDEX_CONSTRAINT_NE:
- case SQLITE_INDEX_CONSTRAINT_ISNOT:
- return [val](const char* str) {
- return str != nullptr && strcmp(str, val) != 0;
- };
- case SQLITE_INDEX_CONSTRAINT_GE:
- return [val](const char* str) {
- return str != nullptr && strcmp(str, val) >= 0;
- };
- case SQLITE_INDEX_CONSTRAINT_GT:
- return [val](const char* str) {
- return str != nullptr && strcmp(str, val) > 0;
- };
- case SQLITE_INDEX_CONSTRAINT_LE:
- return [val](const char* str) {
- return str != nullptr && strcmp(str, val) <= 0;
- };
- case SQLITE_INDEX_CONSTRAINT_LT:
- return [val](const char* str) {
- return str != nullptr && strcmp(str, val) < 0;
- };
- case SQLITE_INDEX_CONSTRAINT_LIKE:
- return [val](const char* str) {
- return str != nullptr && sqlite3_strlike(val, str, 0) == 0;
- };
- case SQLITE_INDEX_CONSTRAINT_GLOB:
- return [val](const char* str) {
- return str != nullptr && sqlite3_strglob(val, str) == 0;
- };
- default:
- PERFETTO_FATAL("For GCC");
+ return sql_value;
+}
+
+inline base::Optional<std::string> SqlValueToString(SqlValue value) {
+ switch (value.type) {
+ case SqlValue::Type::kString:
+ return value.AsString();
+ case SqlValue::Type::kDouble:
+ return std::to_string(value.AsDouble());
+ case SqlValue::Type::kLong:
+ return std::to_string(value.AsLong());
+ case SqlValue::Type::kBytes:
+ case SqlValue::Type::kNull:
+ return base::nullopt;
}
+ PERFETTO_FATAL("For GCC");
}
-// Greater bound for floating point numbers.
-template <typename T, typename sqlite_utils::is_float<T>* = nullptr>
-T FindGtBound(bool is_eq, sqlite3_value* sqlite_val) {
- constexpr auto kMax = static_cast<long double>(std::numeric_limits<T>::max());
- auto type = sqlite3_value_type(sqlite_val);
- if (type != SQLITE_INTEGER && type != SQLITE_FLOAT) {
- return kMax;
+inline void ReportSqlValue(
+ sqlite3_context* ctx,
+ const SqlValue& value,
+ sqlite3_destructor_type string_destructor = kSqliteTransient,
+ sqlite3_destructor_type bytes_destructor = kSqliteTransient) {
+ switch (value.type) {
+ case SqlValue::Type::kLong:
+ sqlite3_result_int64(ctx, value.long_value);
+ break;
+ case SqlValue::Type::kDouble:
+ sqlite3_result_double(ctx, value.double_value);
+ break;
+ case SqlValue::Type::kString: {
+ sqlite3_result_text(ctx, value.string_value, -1, string_destructor);
+ break;
+ }
+ case SqlValue::Type::kBytes:
+ sqlite3_result_blob(ctx, value.bytes_value,
+ static_cast<int>(value.bytes_count),
+ bytes_destructor);
+ break;
+ case SqlValue::Type::kNull:
+ sqlite3_result_null(ctx);
+ break;
}
-
- // If this is a strict gt bound then just get the next highest float
- // after value.
- auto value = ExtractSqliteValue<T>(sqlite_val);
- return is_eq ? value : nexttoward(value, kMax);
}
-template <typename T, typename sqlite_utils::is_int<T>* = nullptr>
-T FindGtBound(bool is_eq, sqlite3_value* sqlite_val) {
- auto type = sqlite3_value_type(sqlite_val);
- if (type == SQLITE_INTEGER) {
- auto value = ExtractSqliteValue<T>(sqlite_val);
- return is_eq ? value : value + 1;
- } else if (type == SQLITE_FLOAT) {
- auto value = ExtractSqliteValue<double>(sqlite_val);
- auto above = ceil(value);
- auto cast = static_cast<T>(above);
- return value < above ? cast : (is_eq ? cast : cast + 1);
- } else {
- return std::numeric_limits<T>::max();
- }
+inline base::Status PrepareStmt(sqlite3* db,
+ const char* sql,
+ ScopedStmt* stmt,
+ const char** tail) {
+ sqlite3_stmt* raw_stmt = nullptr;
+ int err = sqlite3_prepare_v2(db, sql, -1, &raw_stmt, tail);
+ stmt->reset(raw_stmt);
+ if (err != SQLITE_OK)
+ return base::ErrStatus("%s (errcode: %d)", sqlite3_errmsg(db), err);
+ return base::OkStatus();
}
-template <typename T, typename sqlite_utils::is_float<T>* = nullptr>
-T FindLtBound(bool is_eq, sqlite3_value* sqlite_val) {
- constexpr auto kMin =
- static_cast<long double>(std::numeric_limits<T>::lowest());
- auto type = sqlite3_value_type(sqlite_val);
- if (type != SQLITE_INTEGER && type != SQLITE_FLOAT) {
- return kMin;
- }
-
- // If this is a strict lt bound then just get the next lowest float
- // before value.
- auto value = ExtractSqliteValue<T>(sqlite_val);
- return is_eq ? value : nexttoward(value, kMin);
+inline bool IsStmtDone(sqlite3_stmt* stmt) {
+ return !sqlite3_stmt_busy(stmt);
}
-template <typename T, typename sqlite_utils::is_int<T>* = nullptr>
-T FindLtBound(bool is_eq, sqlite3_value* sqlite_val) {
- auto type = sqlite3_value_type(sqlite_val);
- if (type == SQLITE_INTEGER) {
- auto value = ExtractSqliteValue<T>(sqlite_val);
- return is_eq ? value : value - 1;
- } else if (type == SQLITE_FLOAT) {
- auto value = ExtractSqliteValue<double>(sqlite_val);
- auto below = floor(value);
- auto cast = static_cast<T>(below);
- return value > below ? cast : (is_eq ? cast : cast - 1);
- } else {
- return std::numeric_limits<T>::max();
- }
-}
+inline base::Status StepStmtUntilDone(sqlite3_stmt* stmt) {
+ PERFETTO_DCHECK(stmt);
-template <typename T, typename sqlite_utils::is_float<T>* = nullptr>
-T FindEqBound(sqlite3_value* sqlite_val) {
- auto type = sqlite3_value_type(sqlite_val);
- if (type != SQLITE_INTEGER && type != SQLITE_FLOAT) {
- return std::numeric_limits<T>::max();
- }
- return ExtractSqliteValue<T>(sqlite_val);
-}
+ if (IsStmtDone(stmt))
+ return base::OkStatus();
-template <typename T, typename sqlite_utils::is_int<T>* = nullptr>
-T FindEqBound(sqlite3_value* sqlite_val) {
- auto type = sqlite3_value_type(sqlite_val);
- if (type == SQLITE_INTEGER) {
- return ExtractSqliteValue<T>(sqlite_val);
- } else if (type == SQLITE_FLOAT) {
- auto value = ExtractSqliteValue<double>(sqlite_val);
- auto below = floor(value);
- auto cast = static_cast<T>(below);
- return value > below ? std::numeric_limits<T>::max() : cast;
- } else {
- return std::numeric_limits<T>::max();
+ int err;
+ for (err = sqlite3_step(stmt); err == SQLITE_ROW; err = sqlite3_step(stmt)) {
}
-}
-
-template <typename T>
-void ReportSqliteResult(sqlite3_context*, T value);
-
-// Do not add a uint64_t version of ReportSqliteResult. You should not be using
-// uint64_t at all given that SQLite doesn't support it.
-
-template <>
-inline void ReportSqliteResult(sqlite3_context* ctx, int32_t value) {
- sqlite3_result_int(ctx, value);
-}
-
-template <>
-inline void ReportSqliteResult(sqlite3_context* ctx, int64_t value) {
- sqlite3_result_int64(ctx, value);
-}
-
-template <>
-inline void ReportSqliteResult(sqlite3_context* ctx, uint8_t value) {
- sqlite3_result_int(ctx, value);
-}
-
-template <>
-inline void ReportSqliteResult(sqlite3_context* ctx, uint32_t value) {
- sqlite3_result_int64(ctx, value);
-}
-
-template <>
-inline void ReportSqliteResult(sqlite3_context* ctx, bool value) {
- sqlite3_result_int(ctx, value);
-}
-
-template <>
-inline void ReportSqliteResult(sqlite3_context* ctx, double value) {
- sqlite3_result_double(ctx, value);
+ if (err != SQLITE_DONE) {
+ return base::ErrStatus("%s (errcode: %d)",
+ sqlite3_errmsg(sqlite3_db_handle(stmt)), err);
+ }
+ return base::OkStatus();
}
inline util::Status GetColumnsForTable(
@@ -370,11 +173,12 @@ inline util::Status GetColumnsForTable(
// Support names which are table valued functions with arguments.
std::string table_name = raw_table_name.substr(0, raw_table_name.find('('));
- int n = snprintf(sql, sizeof(sql), kRawSql, table_name.c_str());
- PERFETTO_DCHECK(n >= 0 || static_cast<size_t>(n) < sizeof(sql));
+ size_t n = base::SprintfTrunc(sql, sizeof(sql), kRawSql, table_name.c_str());
+ PERFETTO_DCHECK(n > 0);
sqlite3_stmt* raw_stmt = nullptr;
- int err = sqlite3_prepare_v2(db, sql, n, &raw_stmt, nullptr);
+ int err =
+ sqlite3_prepare_v2(db, sql, static_cast<int>(n), &raw_stmt, nullptr);
if (err != SQLITE_OK) {
return util::ErrStatus("Preparing database failed");
}
@@ -408,7 +212,8 @@ inline util::Status GetColumnsForTable(
} else if (base::CaseInsensitiveEqual(raw_type, "BIG INT") ||
base::CaseInsensitiveEqual(raw_type, "UNSIGNED INT") ||
base::CaseInsensitiveEqual(raw_type, "INT") ||
- base::CaseInsensitiveEqual(raw_type, "BOOLEAN")) {
+ base::CaseInsensitiveEqual(raw_type, "BOOLEAN") ||
+ base::CaseInsensitiveEqual(raw_type, "INTEGER")) {
type = SqlValue::Type::kLong;
} else if (!*raw_type) {
PERFETTO_DLOG("Unknown column type for %s %s", raw_table_name.c_str(),
@@ -423,16 +228,6 @@ inline util::Status GetColumnsForTable(
return util::OkStatus();
}
-template <typename T>
-int CompareValuesAsc(const T& f, const T& s) {
- return f < s ? -1 : (f > s ? 1 : 0);
-}
-
-template <typename T>
-int CompareValuesDesc(const T& f, const T& s) {
- return -CompareValuesAsc(f, s);
-}
-
} // namespace sqlite_utils
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/storage/metadata.h b/src/trace_processor/storage/metadata.h
index ba68793e6..70e5e601c 100644
--- a/src/trace_processor/storage/metadata.h
+++ b/src/trace_processor/storage/metadata.h
@@ -29,29 +29,31 @@ namespace metadata {
// Compile time list of metadata items.
// clang-format off
#define PERFETTO_TP_METADATA(F) \
+ F(all_data_source_started_ns, KeyType::kSingle, Variadic::kInt), \
+ F(android_build_fingerprint, KeyType::kSingle, Variadic::kString), \
+ F(android_sdk_version, KeyType::kSingle, Variadic::kInt), \
F(benchmark_description, KeyType::kSingle, Variadic::kString), \
- F(benchmark_name, KeyType::kSingle, Variadic::kString), \
- F(benchmark_start_time_us, KeyType::kSingle, Variadic::kInt), \
F(benchmark_had_failures, KeyType::kSingle, Variadic::kInt), \
F(benchmark_label, KeyType::kSingle, Variadic::kString), \
+ F(benchmark_name, KeyType::kSingle, Variadic::kString), \
+ F(benchmark_start_time_us, KeyType::kSingle, Variadic::kInt), \
F(benchmark_story_name, KeyType::kSingle, Variadic::kString), \
F(benchmark_story_run_index, KeyType::kSingle, Variadic::kInt), \
F(benchmark_story_run_time_us, KeyType::kSingle, Variadic::kInt), \
F(benchmark_story_tags, KeyType::kMulti, Variadic::kString), \
+ F(ftrace_setup_errors, KeyType::kSingle, Variadic::kString), \
F(statsd_triggering_subscription_id, KeyType::kSingle, Variadic::kInt), \
- F(trace_uuid, KeyType::kSingle, Variadic::kString), \
- F(unique_session_name, KeyType::kSingle, Variadic::kString), \
+ F(system_machine, KeyType::kSingle, Variadic::kString), \
F(system_name, KeyType::kSingle, Variadic::kString), \
- F(system_version, KeyType::kSingle, Variadic::kString), \
F(system_release, KeyType::kSingle, Variadic::kString), \
- F(system_machine, KeyType::kSingle, Variadic::kString), \
- F(android_build_fingerprint, KeyType::kSingle, Variadic::kString), \
+ F(system_version, KeyType::kSingle, Variadic::kString), \
+ F(trace_config_pbtxt, KeyType::kSingle, Variadic::kString), \
F(trace_size_bytes, KeyType::kSingle, Variadic::kInt), \
- F(all_data_source_started_ns, KeyType::kSingle, Variadic::kInt), \
- F(tracing_started_ns, KeyType::kSingle, Variadic::kInt), \
+ F(trace_uuid, KeyType::kSingle, Variadic::kString), \
F(tracing_disabled_ns, KeyType::kSingle, Variadic::kInt), \
- F(trace_config_pbtxt, KeyType::kSingle, Variadic::kString), \
- F(ui_state, KeyType::kSingle, Variadic::kString)
+ F(tracing_started_ns, KeyType::kSingle, Variadic::kInt), \
+ F(ui_state, KeyType::kSingle, Variadic::kString), \
+ F(unique_session_name, KeyType::kSingle, Variadic::kString)
// clang-format on
// Compile time list of metadata items.
diff --git a/src/trace_processor/storage/stats.h b/src/trace_processor/storage/stats.h
index bc44fef4c..04480e689 100644
--- a/src/trace_processor/storage/stats.h
+++ b/src/trace_processor/storage/stats.h
@@ -35,22 +35,31 @@ namespace stats {
F(ftrace_bundle_tokenizer_errors, kSingle, kError, kAnalysis, ""), \
F(ftrace_cpu_bytes_read_begin, kIndexed, kInfo, kTrace, ""), \
F(ftrace_cpu_bytes_read_end, kIndexed, kInfo, kTrace, ""), \
- F(ftrace_cpu_commit_overrun_begin, kIndexed, kError, kTrace, ""), \
- F(ftrace_cpu_commit_overrun_end, kIndexed, kError, kTrace, ""), \
- F(ftrace_cpu_dropped_events_begin, kIndexed, kError, kTrace, ""), \
- F(ftrace_cpu_dropped_events_end, kIndexed, kError, kTrace, ""), \
+ F(ftrace_cpu_bytes_read_delta, kIndexed, kInfo, kTrace, ""), \
+ F(ftrace_cpu_commit_overrun_begin, kIndexed, kInfo, kTrace, ""), \
+ F(ftrace_cpu_commit_overrun_end, kIndexed, kInfo, kTrace, ""), \
+ F(ftrace_cpu_commit_overrun_delta, kIndexed, kError, kTrace, ""), \
+ F(ftrace_cpu_dropped_events_begin, kIndexed, kInfo, kTrace, ""), \
+ F(ftrace_cpu_dropped_events_end, kIndexed, kInfo, kTrace, ""), \
+ F(ftrace_cpu_dropped_events_delta, kIndexed, kError, kTrace, ""), \
F(ftrace_cpu_entries_begin, kIndexed, kInfo, kTrace, ""), \
F(ftrace_cpu_entries_end, kIndexed, kInfo, kTrace, ""), \
+ F(ftrace_cpu_entries_delta, kIndexed, kInfo, kTrace, ""), \
F(ftrace_cpu_now_ts_begin, kIndexed, kInfo, kTrace, ""), \
F(ftrace_cpu_now_ts_end, kIndexed, kInfo, kTrace, ""), \
F(ftrace_cpu_oldest_event_ts_begin, kIndexed, kInfo, kTrace, ""), \
F(ftrace_cpu_oldest_event_ts_end, kIndexed, kInfo, kTrace, ""), \
F(ftrace_cpu_overrun_begin, kIndexed, kInfo, kTrace, ""), \
- F(ftrace_cpu_overrun_end, kIndexed, kDataLoss, kTrace, \
+ F(ftrace_cpu_overrun_end, kIndexed, kInfo, kTrace, ""), \
+ F(ftrace_cpu_overrun_delta, kIndexed, kDataLoss, kTrace, \
"The kernel ftrace buffer cannot keep up with the rate of events " \
"produced. Indexed by CPU. This is likely a misconfiguration."), \
F(ftrace_cpu_read_events_begin, kIndexed, kInfo, kTrace, ""), \
F(ftrace_cpu_read_events_end, kIndexed, kInfo, kTrace, ""), \
+ F(ftrace_cpu_read_events_delta, kIndexed, kInfo, kTrace, ""), \
+ F(ftrace_setup_errors, kSingle, kError, kTrace, \
+ "One or more atrace/ftrace categories were not found or failed to enable. " \
+ "See ftrace_setup_errors in the metadata table for more details."), \
F(fuchsia_non_numeric_counters, kSingle, kError, kAnalysis, ""), \
F(fuchsia_timestamp_overflow, kSingle, kError, kAnalysis, ""), \
F(fuchsia_invalid_event, kSingle, kError, kAnalysis, ""), \
@@ -86,6 +95,7 @@ namespace stats {
F(stackprofile_parser_error, kSingle, kError, kTrace, ""), \
F(systrace_parse_failure, kSingle, kError, kAnalysis, ""), \
F(task_state_invalid, kSingle, kError, kAnalysis, ""), \
+ F(traced_buf_abi_violations, kIndexed, kDataLoss, kTrace, ""), \
F(traced_buf_buffer_size, kIndexed, kInfo, kTrace, ""), \
F(traced_buf_bytes_overwritten, kIndexed, kInfo, kTrace, ""), \
F(traced_buf_bytes_read, kIndexed, kInfo, kTrace, ""), \
@@ -108,6 +118,11 @@ namespace stats {
F(traced_chunks_discarded, kSingle, kInfo, kTrace, ""), \
F(traced_data_sources_registered, kSingle, kInfo, kTrace, ""), \
F(traced_data_sources_seen, kSingle, kInfo, kTrace, ""), \
+ F(traced_final_flush_failed, kSingle, kDataLoss, kTrace, ""), \
+ F(traced_final_flush_succeeded, kSingle, kInfo, kTrace, ""), \
+ F(traced_flushes_failed, kSingle, kDataLoss, kTrace, ""), \
+ F(traced_flushes_requested, kSingle, kInfo, kTrace, ""), \
+ F(traced_flushes_succeeded, kSingle, kInfo, kTrace, ""), \
F(traced_patches_discarded, kSingle, kInfo, kTrace, ""), \
F(traced_producers_connected, kSingle, kInfo, kTrace, ""), \
F(traced_producers_seen, kSingle, kInfo, kTrace, ""), \
@@ -124,6 +139,11 @@ namespace stats {
F(process_tracker_errors, kSingle, kError, kAnalysis, ""), \
F(json_tokenizer_failure, kSingle, kError, kTrace, ""), \
F(json_parser_failure, kSingle, kError, kTrace, ""), \
+ F(json_display_time_unit, kSingle, kInfo, kTrace, \
+ "The displayTimeUnit key was set in the JSON trace. In some prior " \
+ "versions of trace processor this key could effect how the trace " \
+ "processor parsed timestamps and durations. In this version the key is " \
+ "ignored which more closely matches the bavahiour of catapult."), \
F(heap_graph_invalid_string_id, kIndexed, kError, kTrace, ""), \
F(heap_graph_non_finalized_graph, kSingle, kError, kTrace, ""), \
F(heap_graph_malformed_packet, kIndexed, kError, kTrace, ""), \
@@ -181,7 +201,15 @@ namespace stats {
"the tracing service. This happens if the ftrace buffers were not " \
"cleared properly. These packets are silently dropped by trace " \
"processor."), \
- F(perf_guardrail_stop_ts, kIndexed, kDataLoss, kTrace, "")
+ F(perf_guardrail_stop_ts, kIndexed, kDataLoss, kTrace, ""), \
+ F(sorter_push_event_out_of_order, kSingle, kError, kTrace, \
+ "Trace events are out of order event after sorting. This can happen " \
+ "due to many factors including clock sync drift, producers emitting " \
+ "events out of order or a bug in trace processor's logic of sorting."), \
+ F(unknown_extension_fields, kSingle, kError, kTrace, \
+ "TraceEvent had unknown extension fields, which might result in " \
+ "missing some arguments. You may need a newer version of trace " \
+ "processor to parse them.")
// clang-format on
enum Type {
@@ -193,8 +221,7 @@ enum Severity {
kInfo, // Diagnostic counters
kDataLoss, // Correct operation that still resulted in data loss
kError // If any kError counter is > 0 trace_processor_shell will
- // raise an error. This is *not* surfaced in the web UI.
- // TODO(b/148587181): Surface these errors in the UI.
+ // raise an error. This is also surfaced in the web UI.
};
enum Source {
diff --git a/src/trace_processor/storage/trace_storage.cc b/src/trace_processor/storage/trace_storage.cc
index 20fdd516a..1260d8f73 100644
--- a/src/trace_processor/storage/trace_storage.cc
+++ b/src/trace_processor/storage/trace_storage.cc
@@ -80,18 +80,15 @@ TraceStorage::TraceStorage(const Config&) {
TraceStorage::~TraceStorage() {}
uint32_t TraceStorage::SqlStats::RecordQueryBegin(const std::string& query,
- int64_t time_queued,
int64_t time_started) {
if (queries_.size() >= kMaxLogEntries) {
queries_.pop_front();
- times_queued_.pop_front();
times_started_.pop_front();
times_first_next_.pop_front();
times_ended_.pop_front();
popped_queries_++;
}
queries_.push_back(query);
- times_queued_.push_back(time_queued);
times_started_.push_back(time_started);
times_first_next_.push_back(0);
times_ended_.push_back(0);
diff --git a/src/trace_processor/storage/trace_storage.h b/src/trace_processor/storage/trace_storage.h
index e2af2ce75..14ecdb38a 100644
--- a/src/trace_processor/storage/trace_storage.h
+++ b/src/trace_processor/storage/trace_storage.h
@@ -191,13 +191,11 @@ class TraceStorage {
public:
static constexpr size_t kMaxLogEntries = 100;
uint32_t RecordQueryBegin(const std::string& query,
- int64_t time_queued,
int64_t time_started);
void RecordQueryFirstNext(uint32_t row, int64_t time_first_next);
void RecordQueryEnd(uint32_t row, int64_t time_end);
size_t size() const { return queries_.size(); }
const std::deque<std::string>& queries() const { return queries_; }
- const std::deque<int64_t>& times_queued() const { return times_queued_; }
const std::deque<int64_t>& times_started() const { return times_started_; }
const std::deque<int64_t>& times_first_next() const {
return times_first_next_;
@@ -208,7 +206,6 @@ class TraceStorage {
uint32_t popped_queries_ = 0;
std::deque<std::string> queries_;
- std::deque<int64_t> times_queued_;
std::deque<int64_t> times_started_;
std::deque<int64_t> times_first_next_;
std::deque<int64_t> times_ended_;
@@ -256,6 +253,17 @@ class TraceStorage {
stats_[key].indexed_values[index] = value;
}
+ // Example usage: opt_cpu_failure = GetIndexedStats(stats::cpu_failure, 1);
+ base::Optional<int64_t> GetIndexedStats(size_t key, int index) {
+ PERFETTO_DCHECK(key < stats::kNumKeys);
+ PERFETTO_DCHECK(stats::kTypes[key] == stats::kIndexed);
+ auto kv = stats_[key].indexed_values.find(index);
+ if (kv != stats_[key].indexed_values.end()) {
+ return kv->second;
+ }
+ return base::nullopt;
+ }
+
class ScopedStatsTracer {
public:
ScopedStatsTracer(TraceStorage* storage, size_t key)
@@ -688,6 +696,8 @@ class TraceStorage {
v.json_value = opt_value ? *opt_value : kNullStringId;
break;
}
+ case Variadic::Type::kNull:
+ break;
}
return v;
}
diff --git a/src/trace_processor/tables/android_tables.h b/src/trace_processor/tables/android_tables.h
index 1686533a6..9aa2551da 100644
--- a/src/trace_processor/tables/android_tables.h
+++ b/src/trace_processor/tables/android_tables.h
@@ -40,7 +40,7 @@ namespace tables {
C(int64_t, ts) \
C(uint32_t, utid) \
C(uint32_t, prio) \
- C(StringPool::Id, tag) \
+ C(base::Optional<StringPool::Id>, tag) \
C(StringPool::Id, msg)
PERFETTO_TP_TABLE(PERFETTO_TP_ANDROID_LOG_TABLE_DEF);
diff --git a/src/trace_processor/tables/metadata_tables.h b/src/trace_processor/tables/metadata_tables.h
index 3f1bb9074..22431b9d8 100644
--- a/src/trace_processor/tables/metadata_tables.h
+++ b/src/trace_processor/tables/metadata_tables.h
@@ -35,8 +35,9 @@ namespace tables {
PERFETTO_TP_TABLE(PERFETTO_TP_RAW_TABLE_DEF);
+// @name args
#define PERFETTO_TP_ARG_TABLE_DEF(NAME, PARENT, C) \
- NAME(ArgTable, "args") \
+ NAME(ArgTable, "internal_args") \
PERFETTO_TP_ROOT_TABLE(PARENT, C) \
C(uint32_t, arg_set_id, Column::Flag::kSorted) \
C(StringPool::Id, flat_key) \
@@ -58,17 +59,36 @@ PERFETTO_TP_TABLE(PERFETTO_TP_ARG_TABLE_DEF);
PERFETTO_TP_TABLE(PERFETTO_TP_METADATA_TABLE_DEF);
+// Contains information of threads seen during the trace
+//
// @name thread
-// @param utid {uint32_t} Unique thread id. This is != the OS tid. This is a
-// monotonic number associated to each thread. The OS thread id (tid)
-// cannot be used as primary key because tids and pids are recycled
-// by most kernels.
-// @param upid {@joinable process.upid}
+// @param utid {uint32_t} Unique thread id. This is != the OS tid.
+// This is a monotonic number associated to each thread.
+// The OS thread id (tid) cannot be used as primary key
+// because tids and pids are recycled by most kernels.
+// @param tid The OS id for this thread. Note: this is *not*
+// unique over the lifetime of the trace so cannot be
+// used as a primary key. Use |utid| instead.
+// @param name The name of the thread. Can be populated from many
+// sources (e.g. ftrace, /proc scraping, track event
+// etc).
+// @param start_ts The start timestamp of this thread (if known). Is
+// null in most cases unless a thread creation event is
+// enabled (e.g. task_newtask ftrace event on
+// Linux/Android).
+// @param end_ts The end timestamp of this thread (if known). Is
+// null in most cases unless a thread destruction event
+// is enabled (e.g. sched_process_free ftrace event on
+// Linux/Android).
+// @param upid {@joinable process.upid} The process hosting this
+// thread.
+// @param is_main_thread Boolean indicating if this thread is the main thread
+// in the process.
#define PERFETTO_TP_THREAD_TABLE_DEF(NAME, PARENT, C) \
NAME(ThreadTable, "internal_thread") \
PERFETTO_TP_ROOT_TABLE(PARENT, C) \
C(uint32_t, tid) \
- C(StringPool::Id, name) \
+ C(base::Optional<StringPool::Id>, name) \
C(base::Optional<int64_t>, start_ts) \
C(base::Optional<int64_t>, end_ts) \
C(base::Optional<uint32_t>, upid) \
@@ -76,17 +96,40 @@ PERFETTO_TP_TABLE(PERFETTO_TP_METADATA_TABLE_DEF);
PERFETTO_TP_TABLE(PERFETTO_TP_THREAD_TABLE_DEF);
+// Contains information of processes seen during the trace
+//
// @name process
-// @param upid {uint32_t} Unique process id. This is != the OS pid. This is a
-// monotonic number associated to each process. The OS process id (pid)
-// cannot be used as primary key because tids and pids are recycled by
-// most kernels.
-// @param uid The Unix user id of the process {@joinable package_list.uid}.
+// @param upid {uint32_t} Unique process id. This is != the OS pid.
+// This is a monotonic number associated to each process.
+// The OS process id (pid) cannot be used as primary key
+// because tids and pids are recycled by most kernels.
+// @param pid The OS id for this process. Note: this is *not*
+// unique over the lifetime of the trace so cannot be
+// used as a primary key. Use |upid| instead.
+// @param name The name of the process. Can be populated from many
+// sources (e.g. ftrace, /proc scraping, track event
+// etc).
+// @param start_ts The start timestamp of this process (if known). Is
+// null in most cases unless a process creation event is
+// enabled (e.g. task_newtask ftrace event on
+// Linux/Android).
+// @param end_ts The end timestamp of this process (if known). Is
+// null in most cases unless a process destruction event
+// is enabled (e.g. sched_process_free ftrace event on
+// Linux/Android).
+// @param parent_upid {@joinable process.upid} The upid of the process which
+// caused this process to be spawned.
+// @param uid {@joinable package_list.uid} The Unix user id of the
+// process.
+// @param android_appid Android appid of this process.
+// @param cmdline /proc/cmdline for this process.
+// @param arg_set_id {@joinable args.arg_set_id} Extra args for this
+// process.
#define PERFETTO_TP_PROCESS_TABLE_DEF(NAME, PARENT, C) \
NAME(ProcessTable, "internal_process") \
PERFETTO_TP_ROOT_TABLE(PARENT, C) \
C(uint32_t, pid) \
- C(StringPool::Id, name) \
+ C(base::Optional<StringPool::Id>, name) \
C(base::Optional<int64_t>, start_ts) \
C(base::Optional<int64_t>, end_ts) \
C(base::Optional<uint32_t>, parent_upid) \
diff --git a/src/trace_processor/tables/profiler_tables.h b/src/trace_processor/tables/profiler_tables.h
index 419d852b7..08aa9df05 100644
--- a/src/trace_processor/tables/profiler_tables.h
+++ b/src/trace_processor/tables/profiler_tables.h
@@ -233,6 +233,12 @@ PERFETTO_TP_TABLE(PERFETTO_TP_PERF_SAMPLE_DEF);
PERFETTO_TP_TABLE(PERFETTO_TP_SYMBOL_DEF);
// Allocations that happened at a callsite.
+//
+//
+// NOTE: this table is not sorted by timestamp intentionanlly - see b/193757386
+// for details.
+// TODO(b/193757386): readd the sorted flag once this bug is fixed.
+//
// This is generated by heapprofd.
// @param ts the timestamp the allocations happened at. heapprofd batches
// allocations and frees, and all data from a dump will have the same
@@ -250,7 +256,7 @@ PERFETTO_TP_TABLE(PERFETTO_TP_SYMBOL_DEF);
#define PERFETTO_TP_HEAP_PROFILE_ALLOCATION_DEF(NAME, PARENT, C) \
NAME(HeapProfileAllocationTable, "heap_profile_allocation") \
PERFETTO_TP_ROOT_TABLE(PARENT, C) \
- C(int64_t, ts, Column::Flag::kSorted) \
+ C(int64_t, ts) \
C(uint32_t, upid) \
C(StringPool::Id, heap_name) \
C(StackProfileCallsiteTable::Id, callsite_id) \
@@ -282,7 +288,10 @@ PERFETTO_TP_TABLE(PERFETTO_TP_HEAP_PROFILE_ALLOCATION_DEF);
C(int64_t, cumulative_alloc_count) \
C(int64_t, alloc_size) \
C(int64_t, cumulative_alloc_size) \
- C(base::Optional<ExperimentalFlamegraphNodesTable::Id>, parent_id)
+ C(base::Optional<ExperimentalFlamegraphNodesTable::Id>, parent_id) \
+ C(base::Optional<StringPool::Id>, source_file) \
+ C(base::Optional<uint32_t>, line_number) \
+ C(base::Optional<StringPool::Id>, upid_group)
PERFETTO_TP_TABLE(PERFETTO_TP_EXPERIMENTAL_FLAMEGRAPH_NODES);
@@ -313,6 +322,8 @@ PERFETTO_TP_TABLE(PERFETTO_TP_HEAP_GRAPH_CLASS_DEF);
// @param upid UniquePid of the target {@joinable process.upid}.
// @param graph_sample_ts timestamp this dump was taken at.
// @param self_size size this object uses on the Java Heap.
+// @param native_size approximate amount of native memory used by this object,
+// as reported by libcore.util.NativeAllocationRegistry.size.
// @param reference_set_id join key with heap_graph_reference containing all
// objects referred in this object's fields.
// {@joinable heap_graph_reference.reference_set_id}
@@ -327,6 +338,7 @@ PERFETTO_TP_TABLE(PERFETTO_TP_HEAP_GRAPH_CLASS_DEF);
C(uint32_t, upid) \
C(int64_t, graph_sample_ts) \
C(int64_t, self_size) \
+ C(int64_t, native_size) \
C(base::Optional<uint32_t>, reference_set_id, Column::Flag::kDense) \
C(int32_t, reachable) \
C(HeapGraphClassTable::Id, type_id) \
diff --git a/src/trace_processor/tables/slice_tables.h b/src/trace_processor/tables/slice_tables.h
index 54272d85b..9b00bb9ca 100644
--- a/src/trace_processor/tables/slice_tables.h
+++ b/src/trace_processor/tables/slice_tables.h
@@ -26,6 +26,8 @@ namespace tables {
// @name slice
// @tablegroup Events
+// @param ts timestamp of the start of the slice (in nanoseconds)
+// @param dur duration of the slice (in nanoseconds)
// @param arg_set_id {@joinable args.arg_set_id}
#define PERFETTO_TP_SLICE_TABLE_DEF(NAME, PARENT, C) \
NAME(SliceTable, "internal_slice") \
@@ -33,8 +35,8 @@ namespace tables {
C(int64_t, ts, Column::Flag::kSorted) \
C(int64_t, dur) \
C(TrackTable::Id, track_id) \
- C(StringPool::Id, category) \
- C(StringPool::Id, name) \
+ C(base::Optional<StringPool::Id>, category) \
+ C(base::Optional<StringPool::Id>, name) \
C(uint32_t, depth) \
C(int64_t, stack_id) \
C(int64_t, parent_stack_id) \
@@ -44,6 +46,7 @@ namespace tables {
PERFETTO_TP_TABLE(PERFETTO_TP_SLICE_TABLE_DEF);
// @tablegroup Events
+// @param ts timestamp of the start of the slice (in nanoseconds)
// @param arg_set_id {@joinable args.arg_set_id}
#define PERFETTO_TP_INSTANT_TABLE_DEF(NAME, PARENT, C) \
NAME(InstantTable, "instant") \
@@ -57,6 +60,8 @@ PERFETTO_TP_TABLE(PERFETTO_TP_SLICE_TABLE_DEF);
PERFETTO_TP_TABLE(PERFETTO_TP_INSTANT_TABLE_DEF);
// @tablegroup Events
+// @param ts timestamp of the start of the slice (in nanoseconds)
+// @param dur duration of the slice (in nanoseconds)
// @param utid {@joinable thread.utid}
#define PERFETTO_TP_SCHED_SLICE_TABLE_DEF(NAME, PARENT, C) \
NAME(SchedSliceTable, "sched_slice") \
@@ -164,6 +169,21 @@ PERFETTO_TP_TABLE(PERFETTO_TP_ACTUAL_FRAME_TIMELINE_SLICES_DEF);
PERFETTO_TP_TABLE(PERFETTO_TP_THREAD_SLICE_DEF);
+#define PERFETTO_TP_EXPERIMENTAL_FLAT_SLICE_TABLE_DEF(NAME, PARENT, C) \
+ NAME(ExperimentalFlatSliceTable, "experimental_flat_slice") \
+ PERFETTO_TP_ROOT_TABLE(PARENT, C) \
+ C(int64_t, ts) \
+ C(int64_t, dur) \
+ C(TrackTable::Id, track_id) \
+ C(base::Optional<StringPool::Id>, category) \
+ C(base::Optional<StringPool::Id>, name) \
+ C(uint32_t, arg_set_id) \
+ C(base::Optional<SliceTable::Id>, source_id) \
+ C(int64_t, start_bound, Column::Flag::kHidden) \
+ C(int64_t, end_bound, Column::Flag::kHidden)
+
+PERFETTO_TP_TABLE(PERFETTO_TP_EXPERIMENTAL_FLAT_SLICE_TABLE_DEF);
+
} // namespace tables
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/tables/table_destructors.cc b/src/trace_processor/tables/table_destructors.cc
index 34206b9b3..eb9774ebe 100644
--- a/src/trace_processor/tables/table_destructors.cc
+++ b/src/trace_processor/tables/table_destructors.cc
@@ -77,6 +77,7 @@ DescribeSliceTable::~DescribeSliceTable() = default;
ThreadStateTable::~ThreadStateTable() = default;
ExpectedFrameTimelineSliceTable::~ExpectedFrameTimelineSliceTable() = default;
ActualFrameTimelineSliceTable::~ActualFrameTimelineSliceTable() = default;
+ExperimentalFlatSliceTable::~ExperimentalFlatSliceTable() = default;
// track_tables.h
TrackTable::~TrackTable() = default;
diff --git a/src/trace_processor/tables/track_tables.h b/src/trace_processor/tables/track_tables.h
index afcd70882..9ba2b4a22 100644
--- a/src/trace_processor/tables/track_tables.h
+++ b/src/trace_processor/tables/track_tables.h
@@ -121,8 +121,8 @@ PERFETTO_TP_TABLE(PERFETTO_TP_GPU_COUNTER_TRACK_DEF);
// @param perf_session_id id of a distict profiling stream.
// {@joinable perf_sample.perf_session_id}
// @param cpu the core the sample was taken on.
-// @is_timebase if true, this counter was the sampling timebase for this
-// perf_session_id.
+// @param is_timebase if true, this counter was the sampling
+// timebase for this perf_session_id.
// @tablegroup Tracks
#define PERFETTO_TP_PERF_COUNTER_TRACK_DEF(NAME, PARENT, C) \
NAME(PerfCounterTrackTable, "perf_counter_track") \
diff --git a/src/trace_processor/timestamped_trace_piece.h b/src/trace_processor/timestamped_trace_piece.h
index f775443e7..1b1a0f610 100644
--- a/src/trace_processor/timestamped_trace_piece.h
+++ b/src/trace_processor/timestamped_trace_piece.h
@@ -19,7 +19,8 @@
#include "perfetto/base/build_config.h"
#include "perfetto/trace_processor/basic_types.h"
-#include "src/trace_processor/importers/common/trace_blob_view.h"
+#include "perfetto/trace_processor/ref_counted.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
#include "src/trace_processor/importers/fuchsia/fuchsia_record.h"
#include "src/trace_processor/importers/json/json_utils.h"
#include "src/trace_processor/importers/proto/packet_sequence_state.h"
@@ -55,17 +56,17 @@ struct InlineSchedWaking {
struct TracePacketData {
TraceBlobView packet;
- std::shared_ptr<PacketSequenceStateGeneration> sequence_state;
+ RefPtr<PacketSequenceStateGeneration> sequence_state;
};
struct FtraceEventData {
TraceBlobView event;
- std::shared_ptr<PacketSequenceStateGeneration> sequence_state;
+ RefPtr<PacketSequenceStateGeneration> sequence_state;
};
struct TrackEventData : public TracePacketData {
TrackEventData(TraceBlobView pv,
- std::shared_ptr<PacketSequenceStateGeneration> generation)
+ RefPtr<PacketSequenceStateGeneration> generation)
: TracePacketData{std::move(pv), std::move(generation)} {}
static constexpr size_t kMaxNumExtraCounters = 8;
@@ -76,9 +77,19 @@ struct TrackEventData : public TracePacketData {
std::array<double, kMaxNumExtraCounters> extra_counter_values = {};
};
+// On Windows std::aligned_storage was broken before VS 2017 15.8 and the
+// compiler (even clang-cl) requires -D_ENABLE_EXTENDED_ALIGNED_STORAGE. Given
+// the alignment here is purely a performance enhancment with no other
+// functional requirement, disable it on Win.
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#define PERFETTO_TTS_ALIGNMENT alignas(64)
+#else
+#define PERFETTO_TTS_ALIGNMENT
+#endif
+
// A TimestampedTracePiece is (usually a reference to) a piece of a trace that
// is sorted by TraceSorter.
-struct TimestampedTracePiece {
+struct PERFETTO_TTS_ALIGNMENT TimestampedTracePiece {
enum class Type {
kInvalid = 0,
kFtraceEvent,
@@ -91,11 +102,10 @@ struct TimestampedTracePiece {
kSystraceLine,
};
- TimestampedTracePiece(
- int64_t ts,
- uint64_t idx,
- TraceBlobView tbv,
- std::shared_ptr<PacketSequenceStateGeneration> sequence_state)
+ TimestampedTracePiece(int64_t ts,
+ uint64_t idx,
+ TraceBlobView tbv,
+ RefPtr<PacketSequenceStateGeneration> sequence_state)
: packet_data{std::move(tbv), std::move(sequence_state)},
timestamp(ts),
packet_idx(idx),
@@ -242,6 +252,22 @@ struct TimestampedTracePiece {
(timestamp == o.timestamp && packet_idx < o.packet_idx);
}
+ // For std::sort(). Without this the compiler will fall back on invoking
+ // move operators on temporary objects.
+ friend void swap(TimestampedTracePiece& a, TimestampedTracePiece& b) {
+ // We know that TimestampedTracePiece is 64-byte aligned (because of the
+ // alignas(64) in the declaration above). We also know that swapping it is
+ // trivial and we can just swap the memory without invoking move operators.
+ // The cast to aligned_storage below allows the compiler to turn this into
+ // a bunch of movaps with large XMM registers (128/256/512 bit depending on
+ // -mavx).
+ using AS =
+ typename std::aligned_storage<sizeof(TimestampedTracePiece),
+ alignof(TimestampedTracePiece)>::type;
+ using std::swap;
+ swap(reinterpret_cast<AS&>(a), reinterpret_cast<AS&>(b));
+ }
+
// Fields ordered for packing.
// Data for different types of TimestampedTracePiece.
@@ -261,6 +287,14 @@ struct TimestampedTracePiece {
Type type;
};
+// std::sort<TTS> is an extremely hot path in TraceProcessor (in trace_sorter.h)
+// When TTS is 512-bit wide, we can leverage SIMD instructions to swap it by
+// declaring it aligned at its own size, without losing any space in the
+// CircularQueue due to fragmentation. This makes a 6% difference in the
+// ingestion time of a large trace. See the comments above in the swap() above.
+static_assert(sizeof(TimestampedTracePiece) <= 64,
+ "TimestampedTracePiece cannot grow beyond 64 bytes");
+
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/tp_metatrace.h b/src/trace_processor/tp_metatrace.h
index 7245ffc42..7ca1865cd 100644
--- a/src/trace_processor/tp_metatrace.h
+++ b/src/trace_processor/tp_metatrace.h
@@ -48,7 +48,7 @@ struct Record {
uint64_t timestamp_ns;
// Duration of the event.
- uint32_t duration_ns;
+ uint64_t duration_ns;
// The name of the event.
// This is assumed to be a static/long lived string.
@@ -145,7 +145,7 @@ class ScopedEvent {
if (RingBuffer::GetInstance()->HasOverwritten(record_idx_))
return;
auto now = TraceTimeNowNs();
- record_->duration_ns = static_cast<uint32_t>(now - record_->timestamp_ns);
+ record_->duration_ns = now - record_->timestamp_ns;
}
ScopedEvent(ScopedEvent&& value) {
diff --git a/src/trace_processor/trace_blob.cc b/src/trace_processor/trace_blob.cc
new file mode 100644
index 000000000..dfa9ece2e
--- /dev/null
+++ b/src/trace_processor/trace_blob.cc
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/trace_processor/trace_blob.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "perfetto/base/compiler.h"
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/utils.h"
+#include "perfetto/trace_processor/basic_types.h"
+
+#if TRACE_PROCESSOR_HAS_MMAP()
+#include <sys/mman.h>
+#endif
+
+namespace perfetto {
+namespace trace_processor {
+
+// static
+TraceBlob TraceBlob::Allocate(size_t size) {
+ TraceBlob blob(Ownership::kHeapBuf, new uint8_t[size], size);
+ PERFETTO_CHECK(blob.data_);
+ return blob;
+}
+
+// static
+TraceBlob TraceBlob::CopyFrom(const void* src, size_t size) {
+ TraceBlob blob = Allocate(size);
+ memcpy(blob.data_, src, size);
+ return blob;
+}
+
+// static
+TraceBlob TraceBlob::TakeOwnership(std::unique_ptr<uint8_t[]> buf,
+ size_t size) {
+ PERFETTO_CHECK(buf);
+ return TraceBlob(Ownership::kHeapBuf, buf.release(), size);
+}
+
+// static
+TraceBlob TraceBlob::FromMmap(void* data, size_t size) {
+#if TRACE_PROCESSOR_HAS_MMAP()
+ PERFETTO_CHECK(data && data != MAP_FAILED);
+ return TraceBlob(Ownership::kMmaped, static_cast<uint8_t*>(data), size);
+#else
+ base::ignore_result(data);
+ base::ignore_result(size);
+ PERFETTO_FATAL("mmap not supported");
+#endif
+}
+
+TraceBlob::~TraceBlob() {
+ switch (ownership_) {
+ case Ownership::kHeapBuf:
+ delete[] data_;
+ break;
+
+ case Ownership::kMmaped:
+#if TRACE_PROCESSOR_HAS_MMAP()
+ PERFETTO_CHECK(munmap(data_, size_) == 0);
+#else
+ PERFETTO_FATAL("mmap not supported");
+#endif
+ break;
+
+ case Ownership::kNull:
+ // Nothing to do.
+ break;
+ }
+ data_ = nullptr;
+ size_ = 0;
+}
+
+TraceBlob& TraceBlob::operator=(TraceBlob&& other) noexcept {
+ if (this == &other)
+ return *this;
+ static_assert(sizeof(*this) == base::AlignUp<sizeof(void*)>(
+ sizeof(data_) + sizeof(size_) +
+ sizeof(ownership_) + sizeof(RefCounted)),
+ "TraceBlob move operator needs updating");
+ data_ = other.data_;
+ size_ = other.size_;
+ ownership_ = other.ownership_;
+ other.data_ = nullptr;
+ other.size_ = 0;
+ other.ownership_ = Ownership::kNull;
+ RefCounted::operator=(std::move(other));
+ return *this;
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/trace_database_integrationtest.cc b/src/trace_processor/trace_database_integrationtest.cc
index e963b54cb..f70d5936b 100644
--- a/src/trace_processor/trace_database_integrationtest.cc
+++ b/src/trace_processor/trace_database_integrationtest.cc
@@ -35,18 +35,73 @@ namespace {
constexpr size_t kMaxChunkSize = 4 * 1024 * 1024;
+TEST(TraceProcessorCustomConfigTest, SkipInternalMetricsMatchingMountPath) {
+ auto config = Config();
+ config.skip_builtin_metric_paths = {"android/"};
+ auto processor = TraceProcessor::CreateInstance(config);
+ processor->NotifyEndOfFile();
+
+ // Check that andorid metrics have not been loaded.
+ auto it = processor->ExecuteQuery(
+ "select count(*) from trace_metrics "
+ "where name = 'android_cpu';");
+ ASSERT_TRUE(it.Next());
+ ASSERT_EQ(it.Get(0).type, SqlValue::kLong);
+ ASSERT_EQ(it.Get(0).long_value, 0);
+
+ // Check that other metrics have been loaded.
+ it = processor->ExecuteQuery(
+ "select count(*) from trace_metrics "
+ "where name = 'trace_metadata';");
+ ASSERT_TRUE(it.Next());
+ ASSERT_EQ(it.Get(0).type, SqlValue::kLong);
+ ASSERT_EQ(it.Get(0).long_value, 1);
+}
+
+TEST(TraceProcessorCustomConfigTest, EmptyStringSkipsAllMetrics) {
+ auto config = Config();
+ config.skip_builtin_metric_paths = {""};
+ auto processor = TraceProcessor::CreateInstance(config);
+ processor->NotifyEndOfFile();
+
+ // Check that other metrics have been loaded.
+ auto it = processor->ExecuteQuery(
+ "select count(*) from trace_metrics "
+ "where name = 'trace_metadata';");
+ ASSERT_TRUE(it.Next());
+ ASSERT_EQ(it.Get(0).type, SqlValue::kLong);
+ ASSERT_EQ(it.Get(0).long_value, 0);
+}
+
+TEST(TraceProcessorCustomConfigTest, HandlesMalformedMountPath) {
+ auto config = Config();
+ config.skip_builtin_metric_paths = {"androi"};
+ auto processor = TraceProcessor::CreateInstance(config);
+ processor->NotifyEndOfFile();
+
+ // Check that andorid metrics have been loaded.
+ auto it = processor->ExecuteQuery(
+ "select count(*) from trace_metrics "
+ "where name = 'android_cpu';");
+ ASSERT_TRUE(it.Next());
+ ASSERT_EQ(it.Get(0).type, SqlValue::kLong);
+ ASSERT_EQ(it.Get(0).long_value, 1);
+}
+
class TraceProcessorIntegrationTest : public ::testing::Test {
public:
TraceProcessorIntegrationTest()
: processor_(TraceProcessor::CreateInstance(Config())) {}
protected:
- util::Status LoadTrace(const char* name, size_t min_chunk_size = 512) {
- EXPECT_LE(min_chunk_size, kMaxChunkSize);
+ util::Status LoadTrace(const char* name,
+ size_t min_chunk_size = 512,
+ size_t max_chunk_size = kMaxChunkSize) {
+ EXPECT_LE(min_chunk_size, max_chunk_size);
base::ScopedFstream f(fopen(
base::GetTestDataPath(std::string("test/data/") + name).c_str(), "rb"));
std::minstd_rand0 rnd_engine(0);
- std::uniform_int_distribution<size_t> dist(min_chunk_size, kMaxChunkSize);
+ std::uniform_int_distribution<size_t> dist(min_chunk_size, max_chunk_size);
while (!feof(*f)) {
size_t chunk_size = dist(rnd_engine);
std::unique_ptr<uint8_t[]> buf(new uint8_t[chunk_size]);
@@ -124,7 +179,8 @@ TEST_F(TraceProcessorIntegrationTest, Hash) {
ASSERT_EQ(it.Get(0).long_value, static_cast<int64_t>(0xa9cb070fdc15f7a4));
}
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#if !PERFETTO_BUILDFLAG(PERFETTO_LLVM_DEMANGLE) && \
+ !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#define MAYBE_Demangle DISABLED_Demangle
#else
#define MAYBE_Demangle Demangle
@@ -132,15 +188,38 @@ TEST_F(TraceProcessorIntegrationTest, Hash) {
TEST_F(TraceProcessorIntegrationTest, MAYBE_Demangle) {
auto it = Query("select DEMANGLE('_Znwm')");
ASSERT_TRUE(it.Next());
- ASSERT_STRCASEEQ(it.Get(0).string_value, "operator new(unsigned long)");
+ EXPECT_STRCASEEQ(it.Get(0).string_value, "operator new(unsigned long)");
it = Query("select DEMANGLE('_ZN3art6Thread14CreateCallbackEPv')");
ASSERT_TRUE(it.Next());
- ASSERT_STRCASEEQ(it.Get(0).string_value,
+ EXPECT_STRCASEEQ(it.Get(0).string_value,
"art::Thread::CreateCallback(void*)");
it = Query("select DEMANGLE('test')");
ASSERT_TRUE(it.Next());
+ EXPECT_TRUE(it.Get(0).is_null());
+}
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_LLVM_DEMANGLE)
+#define MAYBE_DemangleRust DISABLED_DemangleRust
+#else
+#define MAYBE_DemangleRust DemangleRust
+#endif
+TEST_F(TraceProcessorIntegrationTest, MAYBE_DemangleRust) {
+ auto it = Query(
+ "select DEMANGLE("
+ "'_RNvNvMs0_NtNtNtCsg1Z12QU66Yk_3std3sys4unix6threadNtB7_"
+ "6Thread3new12thread_start')");
+ ASSERT_TRUE(it.Next());
+ EXPECT_STRCASEEQ(it.Get(0).string_value,
+ "<std::sys::unix::thread::Thread>::new::thread_start");
+
+ it = Query("select DEMANGLE('_RNvCsdV139EorvfX_14keystore2_main4main')");
+ ASSERT_TRUE(it.Next());
+ ASSERT_STRCASEEQ(it.Get(0).string_value, "keystore2_main::main");
+
+ it = Query("select DEMANGLE('_R')");
+ ASSERT_TRUE(it.Next());
ASSERT_TRUE(it.Get(0).is_null());
}
@@ -196,18 +275,30 @@ TEST_F(TraceProcessorIntegrationTest, SerializeMetricDescriptors) {
ASSERT_EQ(trace_metrics_count, 1);
}
-TEST_F(TraceProcessorIntegrationTest, ComputeMetricsFormatted) {
+TEST_F(TraceProcessorIntegrationTest, ComputeMetricsFormattedExtension) {
std::string metric_output;
util::Status status = Processor()->ComputeMetricText(
std::vector<std::string>{"test_chrome_metric"},
TraceProcessor::MetricResultFormat::kProtoText, &metric_output);
ASSERT_TRUE(status.ok());
+ // Extension fields are output as [fully.qualified.name].
ASSERT_EQ(metric_output,
- "test_chrome_metric: {\n"
+ "[perfetto.protos.test_chrome_metric] {\n"
" test_value: 1\n"
"}");
}
+TEST_F(TraceProcessorIntegrationTest, ComputeMetricsFormattedNoExtension) {
+ std::string metric_output;
+ util::Status status = Processor()->ComputeMetricText(
+ std::vector<std::string>{"trace_metadata"},
+ TraceProcessor::MetricResultFormat::kProtoText, &metric_output);
+ ASSERT_TRUE(status.ok());
+ // Check that metric result starts with trace_metadata field. Since this is
+ // not an extension field, the field name is not fully qualified.
+ ASSERT_TRUE(metric_output.rfind("trace_metadata {") == 0);
+}
+
// TODO(hjd): Add trace to test_data.
TEST_F(TraceProcessorIntegrationTest, DISABLED_AndroidBuildTrace) {
ASSERT_TRUE(LoadTrace("android_build_trace.json", strlen("[\n{")).ok());
@@ -332,13 +423,13 @@ TEST_F(TraceProcessorIntegrationTest, RestoreInitialTables) {
// with opening the same trace with ninjatracing + chrome://tracing.
TEST_F(TraceProcessorIntegrationTest, NinjaLog) {
ASSERT_TRUE(LoadTrace("ninja_log", 1024).ok());
- auto it = Query("select count(*) from process where name like 'build';");
+ auto it = Query("select count(*) from process where name like 'Build';");
ASSERT_TRUE(it.Next());
ASSERT_EQ(it.Get(0).long_value, 2);
it = Query(
"select count(*) from thread left join process using(upid) where "
- "thread.name like 'worker%' and process.pid=1");
+ "thread.name like 'Worker%' and process.pid=1");
ASSERT_TRUE(it.Next());
ASSERT_EQ(it.Get(0).long_value, 14);
@@ -363,6 +454,39 @@ TEST_F(TraceProcessorIntegrationTest, NinjaLog) {
ASSERT_EQ(it.Get(0).long_value, 276174);
}
+/*
+ * This trace does not have a uuid. The uuid will be generated from the first
+ * 4096 bytes, which will be read in one chunk.
+ */
+TEST_F(TraceProcessorIntegrationTest, TraceWithoutUuidReadInOneChunk) {
+ ASSERT_TRUE(LoadTrace("example_android_trace_30s.pb", kMaxChunkSize).ok());
+ auto it = Query("select str_value from metadata where name = 'trace_uuid'");
+ ASSERT_TRUE(it.Next());
+ EXPECT_STREQ(it.Get(0).string_value, "00000000-0000-0000-8906-ebb53e1d0738");
+}
+
+/*
+ * This trace does not have a uuid. The uuid will be generated from the first
+ * 4096 bytes, which will be read in multiple chunks.
+ */
+TEST_F(TraceProcessorIntegrationTest, TraceWithoutUuidReadInMultipleChuncks) {
+ ASSERT_TRUE(LoadTrace("example_android_trace_30s.pb", 512, 2048).ok());
+ auto it = Query("select str_value from metadata where name = 'trace_uuid'");
+ ASSERT_TRUE(it.Next());
+ EXPECT_STREQ(it.Get(0).string_value, "00000000-0000-0000-8906-ebb53e1d0738");
+}
+
+/*
+ * This trace has a uuid. It will not be overriden by the hash of the first 4096
+ * bytes.
+ */
+TEST_F(TraceProcessorIntegrationTest, TraceWithUuidReadInParts) {
+ ASSERT_TRUE(LoadTrace("trace_with_uuid.pftrace", 512, 2048).ok());
+ auto it = Query("select str_value from metadata where name = 'trace_uuid'");
+ ASSERT_TRUE(it.Next());
+ EXPECT_STREQ(it.Get(0).string_value, "123e4567-e89b-12d3-a456-426655443322");
+}
+
} // namespace
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/trace_processor_context.cc b/src/trace_processor/trace_processor_context.cc
index 412b63a35..a3392f2ed 100644
--- a/src/trace_processor/trace_processor_context.cc
+++ b/src/trace_processor/trace_processor_context.cc
@@ -18,6 +18,7 @@
#include "src/trace_processor/forwarding_trace_parser.h"
#include "src/trace_processor/importers/common/args_tracker.h"
+#include "src/trace_processor/importers/common/args_translation_table.h"
#include "src/trace_processor/importers/common/chunked_trace_reader.h"
#include "src/trace_processor/importers/common/clock_tracker.h"
#include "src/trace_processor/importers/common/event_tracker.h"
@@ -25,6 +26,7 @@
#include "src/trace_processor/importers/common/global_args_tracker.h"
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/importers/common/slice_tracker.h"
+#include "src/trace_processor/importers/common/slice_translation_table.h"
#include "src/trace_processor/importers/common/track_tracker.h"
#include "src/trace_processor/importers/ftrace/ftrace_module.h"
#include "src/trace_processor/importers/proto/async_track_set_tracker.h"
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index 0ca05ead6..db6d099b8 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -16,20 +16,23 @@
#include "src/trace_processor/trace_processor_impl.h"
-#include <inttypes.h>
#include <algorithm>
+#include <memory>
#include "perfetto/base/logging.h"
+#include "perfetto/base/status.h"
#include "perfetto/base/time.h"
#include "perfetto/ext/base/string_splitter.h"
#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/trace_processor/demangle.h"
#include "src/trace_processor/dynamic/ancestor_generator.h"
#include "src/trace_processor/dynamic/connected_flow_generator.h"
-#include "src/trace_processor/dynamic/descendant_slice_generator.h"
+#include "src/trace_processor/dynamic/descendant_generator.h"
#include "src/trace_processor/dynamic/describe_slice_generator.h"
#include "src/trace_processor/dynamic/experimental_annotated_stack_generator.h"
#include "src/trace_processor/dynamic/experimental_counter_dur_generator.h"
#include "src/trace_processor/dynamic/experimental_flamegraph_generator.h"
+#include "src/trace_processor/dynamic/experimental_flat_slice_generator.h"
#include "src/trace_processor/dynamic/experimental_sched_upid_generator.h"
#include "src/trace_processor/dynamic/experimental_slice_layout_generator.h"
#include "src/trace_processor/dynamic/thread_state_generator.h"
@@ -44,6 +47,10 @@
#include "src/trace_processor/importers/proto/metadata_tracker.h"
#include "src/trace_processor/importers/systrace/systrace_trace_parser.h"
#include "src/trace_processor/iterator_impl.h"
+#include "src/trace_processor/sqlite/create_function.h"
+#include "src/trace_processor/sqlite/create_view_function.h"
+#include "src/trace_processor/sqlite/register_function.h"
+#include "src/trace_processor/sqlite/scoped_db.h"
#include "src/trace_processor/sqlite/span_join_operator_table.h"
#include "src/trace_processor/sqlite/sql_stats_table.h"
#include "src/trace_processor/sqlite/sqlite3_str_split.h"
@@ -55,19 +62,17 @@
#include "src/trace_processor/tp_metatrace.h"
#include "src/trace_processor/types/variadic.h"
#include "src/trace_processor/util/protozero_to_text.h"
+#include "src/trace_processor/util/status_macros.h"
#include "protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h"
#include "protos/perfetto/trace/trace.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
-#include "src/trace_processor/metrics/chrome/all_chrome_metrics.descriptor.h"
+#include "src/trace_processor/metrics/all_chrome_metrics.descriptor.h"
#include "src/trace_processor/metrics/metrics.descriptor.h"
#include "src/trace_processor/metrics/metrics.h"
-#include "src/trace_processor/metrics/sql_metrics.h"
+#include "src/trace_processor/metrics/sql/amalgamated_sql_metrics.h"
-#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
-#include <cxxabi.h>
-#endif
// In Android and Chromium tree builds, we don't have the percentile module.
// Just don't include it.
@@ -86,6 +91,18 @@ const char kAllTablesQuery[] =
"SELECT tbl_name, type FROM (SELECT * FROM sqlite_master UNION ALL SELECT "
"* FROM sqlite_temp_master)";
+template <typename SqlFunction, typename Ptr = typename SqlFunction::Context*>
+void RegisterFunction(sqlite3* db,
+ const char* name,
+ int argc,
+ Ptr context = nullptr,
+ bool deterministic = true) {
+ auto status = RegisterSqlFunction<SqlFunction>(
+ db, name, argc, std::move(context), deterministic);
+ if (!status.ok())
+ PERFETTO_ELOG("%s", status.c_message());
+}
+
void InitializeSqlite(sqlite3* db) {
char* error = nullptr;
sqlite3_exec(db, "PRAGMA temp_store=2", 0, 0, &error);
@@ -284,49 +301,82 @@ void CreateBuiltinViews(sqlite3* db) {
PERFETTO_ELOG("Error initializing: %s", error);
sqlite3_free(error);
}
+
+ // This should be kept in sync with GlobalArgsTracker::AddArgSet.
+ sqlite3_exec(db,
+ "CREATE VIEW args AS "
+ "SELECT "
+ "*, "
+ "CASE value_type "
+ " WHEN 'int' THEN CAST(int_value AS text) "
+ " WHEN 'uint' THEN CAST(int_value AS text) "
+ " WHEN 'string' THEN string_value "
+ " WHEN 'real' THEN CAST(real_value AS text) "
+ " WHEN 'pointer' THEN printf('0x%x', int_value) "
+ " WHEN 'bool' THEN ( "
+ " CASE WHEN int_value <> 0 THEN 'true' "
+ " ELSE 'false' END) "
+ " WHEN 'json' THEN string_value "
+ "ELSE NULL END AS display_value "
+ "FROM internal_args;",
+ 0, 0, &error);
+ if (error) {
+ PERFETTO_ELOG("Error initializing: %s", error);
+ sqlite3_free(error);
+ }
}
-void ExportJson(sqlite3_context* ctx, int /*argc*/, sqlite3_value** argv) {
- TraceStorage* storage = static_cast<TraceStorage*>(sqlite3_user_data(ctx));
+struct ExportJson : public SqlFunction {
+ using Context = TraceStorage;
+ static base::Status Run(TraceStorage* storage,
+ size_t /*argc*/,
+ sqlite3_value** argv,
+ SqlValue& /*out*/,
+ Destructors&);
+};
+
+base::Status ExportJson::Run(TraceStorage* storage,
+ size_t /*argc*/,
+ sqlite3_value** argv,
+ SqlValue& /*out*/,
+ Destructors&) {
FILE* output;
if (sqlite3_value_type(argv[0]) == SQLITE_INTEGER) {
// Assume input is an FD.
output = fdopen(sqlite3_value_int(argv[0]), "w");
if (!output) {
- sqlite3_result_error(ctx, "Couldn't open output file from given FD", -1);
- return;
+ return base::ErrStatus(
+ "EXPORT_JSON: Couldn't open output file from given FD");
}
} else {
const char* filename =
reinterpret_cast<const char*>(sqlite3_value_text(argv[0]));
output = fopen(filename, "w");
if (!output) {
- sqlite3_result_error(ctx, "Couldn't open output file", -1);
- return;
+ return base::ErrStatus("EXPORT_JSON: Couldn't open output file");
}
}
-
- util::Status result = json::ExportJson(storage, output);
- if (!result.ok()) {
- sqlite3_result_error(ctx, result.message().c_str(), -1);
- return;
- }
+ return json::ExportJson(storage, output);
}
-void CreateJsonExportFunction(TraceStorage* ts, sqlite3* db) {
- auto ret = sqlite3_create_function_v2(db, "EXPORT_JSON", 1, SQLITE_UTF8, ts,
- ExportJson, nullptr, nullptr,
- sqlite_utils::kSqliteStatic);
- if (ret) {
- PERFETTO_ELOG("Error initializing EXPORT_JSON");
- }
-}
+struct Hash : public SqlFunction {
+ static base::Status Run(void*,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors&);
+};
-void Hash(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
+base::Status Hash::Run(void*,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors&) {
base::Hash hash;
- for (int i = 0; i < argc; ++i) {
+ for (size_t i = 0; i < argc; ++i) {
sqlite3_value* value = argv[i];
- switch (sqlite3_value_type(value)) {
+ int type = sqlite3_value_type(value);
+ switch (type) {
case SQLITE_INTEGER:
hash.Update(sqlite3_value_int64(value));
break;
@@ -337,41 +387,46 @@ void Hash(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
break;
}
default:
- sqlite3_result_error(ctx, "Unsupported type of arg passed to HASH", -1);
- return;
+ return base::ErrStatus("HASH: arg %zu has unknown type %d", i, type);
}
}
- sqlite3_result_int64(ctx, static_cast<int64_t>(hash.digest()));
+ out = SqlValue::Long(static_cast<int64_t>(hash.digest()));
+ return base::OkStatus();
}
-void Demangle(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
- if (argc != 1) {
- sqlite3_result_error(ctx, "Unsupported number of arg passed to DEMANGLE",
- -1);
- return;
- }
+struct Demangle : public SqlFunction {
+ static base::Status Run(void*,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors& destructors);
+};
+
+base::Status Demangle::Run(void*,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors& destructors) {
+ if (argc != 1)
+ return base::ErrStatus("Unsupported number of arg passed to DEMANGLE");
sqlite3_value* value = argv[0];
- if (sqlite3_value_type(value) == SQLITE_NULL) {
- sqlite3_result_null(ctx);
- return;
- }
- if (sqlite3_value_type(value) != SQLITE_TEXT) {
- sqlite3_result_error(ctx, "Unsupported type of arg passed to DEMANGLE", -1);
- return;
- }
- const char* ptr = reinterpret_cast<const char*>(sqlite3_value_text(value));
-#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
- int ignored = 0;
- // This memory was allocated by malloc and will be passed to SQLite to free.
- char* demangled_name = abi::__cxa_demangle(ptr, nullptr, nullptr, &ignored);
- if (!demangled_name) {
- sqlite3_result_null(ctx);
- return;
- }
- sqlite3_result_text(ctx, demangled_name, -1, free);
-#else
- sqlite3_result_text(ctx, ptr, -1, sqlite_utils::kSqliteTransient);
-#endif
+ if (sqlite3_value_type(value) == SQLITE_NULL)
+ return base::OkStatus();
+
+ if (sqlite3_value_type(value) != SQLITE_TEXT)
+ return base::ErrStatus("Unsupported type of arg passed to DEMANGLE");
+
+ const char* mangled =
+ reinterpret_cast<const char*>(sqlite3_value_text(value));
+
+ std::unique_ptr<char, base::FreeDeleter> demangled =
+ demangle::Demangle(mangled);
+ if (!demangled)
+ return base::OkStatus();
+
+ destructors.string_destructor = free;
+ out = SqlValue::String(demangled.release());
+ return base::OkStatus();
}
void LastNonNullStep(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
@@ -422,25 +477,7 @@ void LastNonNullFinal(sqlite3_context* ctx) {
}
}
-void CreateHashFunction(sqlite3* db) {
- auto ret = sqlite3_create_function_v2(
- db, "HASH", -1, SQLITE_UTF8 | SQLITE_DETERMINISTIC, nullptr, &Hash,
- nullptr, nullptr, nullptr);
- if (ret) {
- PERFETTO_ELOG("Error initializing HASH");
- }
-}
-
-void CreateDemangledNameFunction(sqlite3* db) {
- auto ret = sqlite3_create_function_v2(
- db, "DEMANGLE", 1, SQLITE_UTF8 | SQLITE_DETERMINISTIC, nullptr, &Demangle,
- nullptr, nullptr, nullptr);
- if (ret != SQLITE_OK) {
- PERFETTO_ELOG("Error initializing DEMANGLE: %s", sqlite3_errmsg(db));
- }
-}
-
-void CreateLastNonNullFunction(sqlite3* db) {
+void RegisterLastNonNullFunction(sqlite3* db) {
auto ret = sqlite3_create_window_function(
db, "LAST_NON_NULL", 1, SQLITE_UTF8 | SQLITE_DETERMINISTIC, nullptr,
&LastNonNullStep, &LastNonNullFinal, &LastNonNullValue,
@@ -485,6 +522,7 @@ void ValueAtMaxTsStep(sqlite3_context* ctx, int, sqlite3_value** argv) {
return;
}
+ fn_ctx->max_ts = std::numeric_limits<int64_t>::min();
fn_ctx->initialized = true;
}
@@ -503,7 +541,7 @@ void ValueAtMaxTsStep(sqlite3_context* ctx, int, sqlite3_value** argv) {
#endif
int64_t ts_int = sqlite3_value_int64(ts);
- if (PERFETTO_LIKELY(fn_ctx->max_ts < ts_int)) {
+ if (PERFETTO_LIKELY(fn_ctx->max_ts <= ts_int)) {
fn_ctx->max_ts = ts_int;
if (fn_ctx->value_type == SQLITE_INTEGER) {
@@ -528,7 +566,7 @@ void ValueAtMaxTsFinal(sqlite3_context* ctx) {
}
}
-void CreateValueAtMaxTsFunction(sqlite3* db) {
+void RegisterValueAtMaxTsFunction(sqlite3* db) {
auto ret = sqlite3_create_function_v2(
db, "VALUE_AT_MAX_TS", 2, SQLITE_UTF8 | SQLITE_DETERMINISTIC, nullptr,
nullptr, &ValueAtMaxTsStep, &ValueAtMaxTsFinal, nullptr);
@@ -537,116 +575,154 @@ void CreateValueAtMaxTsFunction(sqlite3* db) {
}
}
-void ExtractArg(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
- if (argc != 2) {
- sqlite3_result_error(ctx, "EXTRACT_ARG: 2 args required", -1);
- return;
- }
+struct ExtractArg : public SqlFunction {
+ using Context = TraceStorage;
+ static base::Status Run(TraceStorage* storage,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors& destructors);
+};
+
+base::Status ExtractArg::Run(TraceStorage* storage,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors& destructors) {
+ if (argc != 2)
+ return base::ErrStatus("EXTRACT_ARG: 2 args required");
// If the arg set id is null, just return null as the result.
- if (sqlite3_value_type(argv[0]) == SQLITE_NULL) {
- sqlite3_result_null(ctx);
- return;
- }
- if (sqlite3_value_type(argv[0]) != SQLITE_INTEGER) {
- sqlite3_result_error(ctx, "EXTRACT_ARG: 1st argument should be arg set id",
- -1);
- return;
- }
- if (sqlite3_value_type(argv[1]) != SQLITE_TEXT) {
- sqlite3_result_error(ctx, "EXTRACT_ARG: 2nd argument should be key", -1);
- return;
- }
+ if (sqlite3_value_type(argv[0]) == SQLITE_NULL)
+ return base::OkStatus();
+
+ if (sqlite3_value_type(argv[0]) != SQLITE_INTEGER)
+ return base::ErrStatus("EXTRACT_ARG: 1st argument should be arg set id");
+
+ if (sqlite3_value_type(argv[1]) != SQLITE_TEXT)
+ return base::ErrStatus("EXTRACT_ARG: 2nd argument should be key");
- TraceStorage* storage = static_cast<TraceStorage*>(sqlite3_user_data(ctx));
uint32_t arg_set_id = static_cast<uint32_t>(sqlite3_value_int(argv[0]));
const char* key = reinterpret_cast<const char*>(sqlite3_value_text(argv[1]));
base::Optional<Variadic> opt_value;
- util::Status status = storage->ExtractArg(arg_set_id, key, &opt_value);
- if (!status.ok()) {
- sqlite3_result_error(ctx, status.c_message(), -1);
- return;
- }
+ RETURN_IF_ERROR(storage->ExtractArg(arg_set_id, key, &opt_value));
- if (!opt_value) {
- sqlite3_result_null(ctx);
- return;
- }
+ if (!opt_value)
+ return base::OkStatus();
+
+ // This function always returns static strings (i.e. scoped to lifetime
+ // of the TraceStorage thread pool) so prevent SQLite from making copies.
+ destructors.string_destructor = sqlite_utils::kSqliteStatic;
switch (opt_value->type) {
+ case Variadic::kNull:
+ return base::OkStatus();
case Variadic::kInt:
- sqlite3_result_int64(ctx, opt_value->int_value);
- break;
- case Variadic::kBool:
- sqlite3_result_int64(ctx, opt_value->bool_value);
- break;
+ out = SqlValue::Long(opt_value->int_value);
+ return base::OkStatus();
case Variadic::kUint:
- sqlite3_result_int64(ctx, static_cast<int64_t>(opt_value->uint_value));
- break;
- case Variadic::kPointer:
- sqlite3_result_int64(ctx, static_cast<int64_t>(opt_value->pointer_value));
- break;
- case Variadic::kJson:
- sqlite3_result_text(ctx, storage->GetString(opt_value->json_value).data(),
- -1, nullptr);
- break;
+ out = SqlValue::Long(static_cast<int64_t>(opt_value->uint_value));
+ return base::OkStatus();
case Variadic::kString:
- sqlite3_result_text(
- ctx, storage->GetString(opt_value->string_value).data(), -1, nullptr);
- break;
+ out =
+ SqlValue::String(storage->GetString(opt_value->string_value).data());
+ return base::OkStatus();
case Variadic::kReal:
- sqlite3_result_double(ctx, opt_value->real_value);
- break;
+ out = SqlValue::Double(opt_value->real_value);
+ return base::OkStatus();
+ case Variadic::kBool:
+ out = SqlValue::Long(opt_value->bool_value);
+ return base::OkStatus();
+ case Variadic::kPointer:
+ out = SqlValue::Long(static_cast<int64_t>(opt_value->pointer_value));
+ return base::OkStatus();
+ case Variadic::kJson:
+ out = SqlValue::String(storage->GetString(opt_value->json_value).data());
+ return base::OkStatus();
}
+ PERFETTO_FATAL("For GCC");
}
-void CreateExtractArgFunction(TraceStorage* ts, sqlite3* db) {
- auto ret = sqlite3_create_function_v2(db, "EXTRACT_ARG", 2,
- SQLITE_UTF8 | SQLITE_DETERMINISTIC, ts,
- &ExtractArg, nullptr, nullptr, nullptr);
- if (ret != SQLITE_OK) {
- PERFETTO_FATAL("Error initializing EXTRACT_ARG: %s", sqlite3_errmsg(db));
- }
+std::vector<std::string> SanitizeMetricMountPaths(
+ const std::vector<std::string>& mount_paths) {
+ std::vector<std::string> sanitized;
+ for (const auto& path : mount_paths) {
+ if (path.length() == 0)
+ continue;
+ sanitized.push_back(path);
+ if (path.back() != '/')
+ sanitized.back().append("/");
+ }
+ return sanitized;
}
-void CreateSourceGeqFunction(sqlite3* db) {
- auto fn = [](sqlite3_context* ctx, int, sqlite3_value**) {
- sqlite3_result_error(
- ctx, "SOURCE_GEQ should not be called from the global scope", -1);
- };
- auto ret = sqlite3_create_function_v2(db, "SOURCE_GEQ", -1,
- SQLITE_UTF8 | SQLITE_DETERMINISTIC,
- nullptr, fn, nullptr, nullptr, nullptr);
- if (ret != SQLITE_OK) {
- PERFETTO_FATAL("Error initializing SOURCE_GEQ: %s", sqlite3_errmsg(db));
+struct SourceGeq : public SqlFunction {
+ static base::Status Run(void*,
+ size_t,
+ sqlite3_value**,
+ SqlValue&,
+ Destructors&) {
+ return base::ErrStatus(
+ "SOURCE_GEQ should not be called from the global scope");
}
-}
+};
+
+struct Glob : public SqlFunction {
+ static base::Status Run(void*,
+ size_t,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors&) {
+ const char* pattern =
+ reinterpret_cast<const char*>(sqlite3_value_text(argv[0]));
+ const char* text =
+ reinterpret_cast<const char*>(sqlite3_value_text(argv[1]));
+ if (pattern && text) {
+ out = SqlValue::Long(sqlite3_strglob(pattern, text) == 0);
+ }
+ return base::OkStatus();
+ }
+};
void SetupMetrics(TraceProcessor* tp,
sqlite3* db,
- std::vector<metrics::SqlMetricFile>* sql_metrics) {
- tp->ExtendMetricsProto(kMetricsDescriptor.data(), kMetricsDescriptor.size());
+ std::vector<metrics::SqlMetricFile>* sql_metrics,
+ const std::vector<std::string>& extension_paths) {
+ const std::vector<std::string> sanitized_extension_paths =
+ SanitizeMetricMountPaths(extension_paths);
+ std::vector<std::string> skip_prefixes;
+ skip_prefixes.reserve(sanitized_extension_paths.size());
+ for (const auto& path : sanitized_extension_paths) {
+ skip_prefixes.push_back(kMetricProtoRoot + path);
+ }
+ tp->ExtendMetricsProto(kMetricsDescriptor.data(), kMetricsDescriptor.size(),
+ skip_prefixes);
tp->ExtendMetricsProto(kAllChromeMetricsDescriptor.data(),
- kAllChromeMetricsDescriptor.size());
-
- for (const auto& file_to_sql : metrics::sql_metrics::kFileToSql) {
- tp->RegisterMetric(file_to_sql.path, file_to_sql.sql);
+ kAllChromeMetricsDescriptor.size(), skip_prefixes);
+
+ // TODO(lalitm): remove this special casing and change
+ // SanitizeMetricMountPaths if/when we move all protos for builtin metrics to
+ // match extension protos.
+ bool skip_all_sql = std::find(extension_paths.begin(), extension_paths.end(),
+ "") != extension_paths.end();
+ if (!skip_all_sql) {
+ for (const auto& file_to_sql : metrics::sql_metrics::kFileToSql) {
+ if (base::StartsWithAny(file_to_sql.path, sanitized_extension_paths))
+ continue;
+ tp->RegisterMetric(file_to_sql.path, file_to_sql.sql);
+ }
}
- {
- std::unique_ptr<metrics::RunMetricContext> ctx(
- new metrics::RunMetricContext());
- ctx->tp = tp;
- ctx->metrics = sql_metrics;
- auto ret = sqlite3_create_function_v2(
- db, "RUN_METRIC", -1, SQLITE_UTF8, ctx.release(), metrics::RunMetric,
- nullptr, nullptr,
- [](void* ptr) { delete static_cast<metrics::RunMetricContext*>(ptr); });
- if (ret)
- PERFETTO_FATAL("Error initializing RUN_METRIC");
- }
+ RegisterFunction<metrics::NullIfEmpty>(db, "NULL_IF_EMPTY", 1);
+ RegisterFunction<metrics::UnwrapMetricProto>(db, "UNWRAP_METRIC_PROTO", 2);
+ RegisterFunction<metrics::RunMetric>(
+ db, "RUN_METRIC", -1,
+ std::unique_ptr<metrics::RunMetric::Context>(
+ new metrics::RunMetric::Context{tp, sql_metrics}));
+ // TODO(lalitm): migrate this over to using RegisterFunction once aggregate
+ // functions are supported.
{
auto ret = sqlite3_create_function_v2(
db, "RepeatedField", 1, SQLITE_UTF8, nullptr, nullptr,
@@ -654,14 +730,6 @@ void SetupMetrics(TraceProcessor* tp,
if (ret)
PERFETTO_FATAL("Error initializing RepeatedField");
}
-
- {
- auto ret = sqlite3_create_function_v2(db, "NULL_IF_EMPTY", 1, SQLITE_UTF8,
- nullptr, metrics::NullIfEmpty,
- nullptr, nullptr, nullptr);
- if (ret)
- PERFETTO_FATAL("Error initializing NULL_IF_EMPTY");
- }
}
void EnsureSqliteInitialized() {
@@ -684,6 +752,106 @@ void InsertIntoTraceMetricsTable(sqlite3* db, const std::string& metric_name) {
}
}
+void IncrementCountForStmt(sqlite3_stmt* stmt,
+ IteratorImpl::StmtMetadata* metadata) {
+ metadata->statement_count++;
+
+ // If the stmt is already done, it clearly didn't have any output.
+ if (sqlite_utils::IsStmtDone(stmt))
+ return;
+
+ // If the statement only has a single column and that column is named
+ // "suppress_query_output", treat it as a statement without output for
+ // accounting purposes. This is done so that embedders (e.g. shell) can
+ // strictly check that only the last query produces output while also
+ // providing an escape hatch for SELECT RUN_METRIC() invocations (which
+ // sadly produce output).
+ if (sqlite3_column_count(stmt) == 1 &&
+ strcmp(sqlite3_column_name(stmt, 0), "suppress_query_output") == 0) {
+ return;
+ }
+
+ // Otherwise, the statement has output and so increment the count.
+ metadata->statement_count_with_output++;
+}
+
+base::Status PrepareAndStepUntilLastValidStmt(
+ sqlite3* db,
+ const std::string& sql,
+ ScopedStmt* output_stmt,
+ IteratorImpl::StmtMetadata* metadata) {
+ ScopedStmt prev_stmt;
+ // A sql string can contain several statements. Some of them might be comment
+ // only, e.g. "SELECT 1; /* comment */; SELECT 2;". Here we process one
+ // statement on each iteration. SQLite's sqlite_prepare_v2 (wrapped by
+ // PrepareStmt) returns on each iteration a pointer to the unprocessed string.
+ //
+ // Unfortunately we cannot call PrepareStmt and tokenize all statements
+ // upfront because sqlite_prepare_v2 also semantically checks the statement
+ // against the schema. In some cases statements might depend on the execution
+ // of previous ones (e.e. CREATE VIEW x; SELECT FROM x; DELETE VIEW x;).
+ //
+ // Also, unfortunately, we need to PrepareStmt to find out if a statement is a
+ // comment or a real statement.
+ //
+ // The logic here is the following:
+ // - We invoke PrepareStmt on each statement.
+ // - If the statement is a comment we simply skip it.
+ // - If the statement is valid, we step once to make sure side effects take
+ // effect.
+ // - If we encounter a valid statement afterwards, we step internally through
+ // all rows of the previous one. This ensures that any further side effects
+ // take hold *before* we step into the next statement.
+ // - Once no further non-comment statements are encountered, we return an
+ // iterator to the last valid statement.
+ for (const char* rem_sql = sql.c_str(); rem_sql && rem_sql[0];) {
+ ScopedStmt cur_stmt;
+ {
+ PERFETTO_TP_TRACE("QUERY_PREPARE");
+ const char* tail = nullptr;
+ RETURN_IF_ERROR(sqlite_utils::PrepareStmt(db, rem_sql, &cur_stmt, &tail));
+ rem_sql = tail;
+ }
+
+ // The only situation where we'd have an ok status but also no prepared
+ // statement is if the statement of SQL we parsed was a pure comment. In
+ // this case, just continue to the next statement.
+ if (!cur_stmt)
+ continue;
+
+ // Before stepping into |cur_stmt|, we need to finish iterating through
+ // the previous statement so we don't have two clashing statements (e.g.
+ // SELECT * FROM v and DROP VIEW v) partially stepped into.
+ if (prev_stmt)
+ RETURN_IF_ERROR(sqlite_utils::StepStmtUntilDone(prev_stmt.get()));
+
+ PERFETTO_DLOG("Executing statement: %s", sqlite3_sql(*cur_stmt));
+
+ // Now step once into |cur_stmt| so that when we prepare the next statment
+ // we will have executed any dependent bytecode in this one.
+ int err = sqlite3_step(*cur_stmt);
+ if (err != SQLITE_ROW && err != SQLITE_DONE)
+ return base::ErrStatus("%s (errcode: %d)", sqlite3_errmsg(db), err);
+
+ // Increment the neecessary counts for the statement.
+ IncrementCountForStmt(cur_stmt.get(), metadata);
+
+ // Propogate the current statement to the next iteration.
+ prev_stmt = std::move(cur_stmt);
+ }
+
+ // If we didn't manage to prepare a single statment, that means everything
+ // in the SQL was treated as a comment.
+ if (!prev_stmt)
+ return base::ErrStatus("No valid SQL to run");
+
+ // Update the output statment and column count.
+ *output_stmt = std::move(prev_stmt);
+ metadata->column_count =
+ static_cast<uint32_t>(sqlite3_column_count(output_stmt->get()));
+ return base::OkStatus();
+}
+
} // namespace
TraceProcessorImpl::TraceProcessorImpl(const Config& cfg)
@@ -693,7 +861,7 @@ TraceProcessorImpl::TraceProcessorImpl(const Config& cfg)
context_.systrace_trace_parser.reset(new SystraceTraceParser(&context_));
- if (gzip::IsGzipSupported())
+ if (util::IsGzipSupported())
context_.gzip_trace_parser.reset(new GzipTraceParser(&context_));
if (json::IsJsonSupported()) {
@@ -711,15 +879,30 @@ TraceProcessorImpl::TraceProcessorImpl(const Config& cfg)
CreateBuiltinViews(db);
db_.reset(std::move(db));
- CreateJsonExportFunction(context_.storage.get(), db);
- CreateHashFunction(db);
- CreateDemangledNameFunction(db);
- CreateLastNonNullFunction(db);
- CreateExtractArgFunction(context_.storage.get(), db);
- CreateSourceGeqFunction(db);
- CreateValueAtMaxTsFunction(db);
-
- SetupMetrics(this, *db_, &sql_metrics_);
+ // New style function registration.
+ RegisterFunction<Glob>(db, "glob", 2);
+ RegisterFunction<Hash>(db, "HASH", -1);
+ RegisterFunction<Demangle>(db, "DEMANGLE", 1);
+ RegisterFunction<SourceGeq>(db, "SOURCE_GEQ", -1);
+ RegisterFunction<ExportJson>(db, "EXPORT_JSON", 1, context_.storage.get(),
+ false);
+ RegisterFunction<ExtractArg>(db, "EXTRACT_ARG", 2, context_.storage.get());
+ RegisterFunction<CreateFunction>(
+ db, "CREATE_FUNCTION", 3,
+ std::unique_ptr<CreateFunction::Context>(
+ new CreateFunction::Context{db_.get(), &create_function_state_}));
+ RegisterFunction<CreateViewFunction>(
+ db, "CREATE_VIEW_FUNCTION", 3,
+ std::unique_ptr<CreateViewFunction::Context>(
+ new CreateViewFunction::Context{db_.get()}));
+
+ // Old style function registration.
+ // TODO(lalitm): migrate this over to using RegisterFunction once aggregate
+ // functions are supported.
+ RegisterLastNonNullFunction(db);
+ RegisterValueAtMaxTsFunction(db);
+
+ SetupMetrics(this, *db_, &sql_metrics_, cfg.skip_builtin_metric_paths);
// Setup the query cache.
query_cache_.reset(new QueryCache());
@@ -732,6 +915,7 @@ TraceProcessorImpl::TraceProcessorImpl(const Config& cfg)
// Operator tables.
SpanJoinOperatorTable::RegisterTable(*db_, storage);
WindowOperatorTable::RegisterTable(*db_, storage);
+ CreateViewFunction::RegisterTable(*db_, &create_view_function_state_);
// New style tables but with some custom logic.
SqliteRawTable::RegisterTable(*db_, query_cache_.get(), &context_);
@@ -751,8 +935,14 @@ TraceProcessorImpl::TraceProcessorImpl(const Config& cfg)
new AncestorGenerator(AncestorGenerator::Ancestor::kSlice, &context_)));
RegisterDynamicTable(std::unique_ptr<AncestorGenerator>(new AncestorGenerator(
AncestorGenerator::Ancestor::kStackProfileCallsite, &context_)));
- RegisterDynamicTable(std::unique_ptr<DescendantSliceGenerator>(
- new DescendantSliceGenerator(&context_)));
+ RegisterDynamicTable(std::unique_ptr<AncestorGenerator>(new AncestorGenerator(
+ AncestorGenerator::Ancestor::kSliceByStack, &context_)));
+ RegisterDynamicTable(
+ std::unique_ptr<DescendantGenerator>(new DescendantGenerator(
+ DescendantGenerator::Descendant::kSlice, &context_)));
+ RegisterDynamicTable(
+ std::unique_ptr<DescendantGenerator>(new DescendantGenerator(
+ DescendantGenerator::Descendant::kSliceByStack, &context_)));
RegisterDynamicTable(
std::unique_ptr<ConnectedFlowGenerator>(new ConnectedFlowGenerator(
ConnectedFlowGenerator::Mode::kDirectlyConnectedFlow, &context_)));
@@ -769,6 +959,8 @@ TraceProcessorImpl::TraceProcessorImpl(const Config& cfg)
new ThreadStateGenerator(&context_)));
RegisterDynamicTable(std::unique_ptr<ExperimentalAnnotatedStackGenerator>(
new ExperimentalAnnotatedStackGenerator(&context_)));
+ RegisterDynamicTable(std::unique_ptr<ExperimentalFlatSliceGenerator>(
+ new ExperimentalFlatSliceGenerator(&context_)));
// New style db-backed tables.
RegisterDbTable(storage->arg_table());
@@ -835,10 +1027,9 @@ TraceProcessorImpl::TraceProcessorImpl(const Config& cfg)
TraceProcessorImpl::~TraceProcessorImpl() = default;
-util::Status TraceProcessorImpl::Parse(std::unique_ptr<uint8_t[]> data,
- size_t size) {
- bytes_parsed_ += size;
- return TraceProcessorStorageImpl::Parse(std::move(data), size);
+base::Status TraceProcessorImpl::Parse(TraceBlobView blob) {
+ bytes_parsed_ += blob.size();
+ return TraceProcessorStorageImpl::Parse(std::move(blob));
}
std::string TraceProcessorImpl::GetCurrentTraceName() {
@@ -877,6 +1068,7 @@ void TraceProcessorImpl::NotifyEndOfFile() {
}
size_t TraceProcessorImpl::RestoreInitialTables() {
+ // Step 1: figure out what tables/views/indices we need to delete.
std::vector<std::pair<std::string, std::string>> deletion_list;
std::string msg = "Resetting DB to initial state, deleting table/views:";
for (auto it = ExecuteQuery(kAllTablesQuery); it.Next();) {
@@ -890,6 +1082,8 @@ size_t TraceProcessorImpl::RestoreInitialTables() {
}
PERFETTO_LOG("%s", msg.c_str());
+
+ // Step 2: actually delete those tables/views/indices.
for (const auto& tn : deletion_list) {
std::string query = "DROP " + tn.first + " " + tn.second;
auto it = ExecuteQuery(query);
@@ -905,31 +1099,21 @@ size_t TraceProcessorImpl::RestoreInitialTables() {
return deletion_list.size();
}
-Iterator TraceProcessorImpl::ExecuteQuery(const std::string& sql,
- int64_t time_queued) {
- sqlite3_stmt* raw_stmt;
- int err;
- {
- PERFETTO_TP_TRACE("QUERY_PREPARE");
- err = sqlite3_prepare_v2(*db_, sql.c_str(), static_cast<int>(sql.size()),
- &raw_stmt, nullptr);
- }
-
- util::Status status;
- uint32_t col_count = 0;
- if (err != SQLITE_OK) {
- status = util::ErrStatus("%s", sqlite3_errmsg(*db_));
- } else {
- col_count = static_cast<uint32_t>(sqlite3_column_count(raw_stmt));
- }
+Iterator TraceProcessorImpl::ExecuteQuery(const std::string& sql) {
+ PERFETTO_TP_TRACE("QUERY_EXECUTE");
- base::TimeNanos t_start = base::GetWallTimeNs();
uint32_t sql_stats_row =
- context_.storage->mutable_sql_stats()->RecordQueryBegin(sql, time_queued,
- t_start.count());
+ context_.storage->mutable_sql_stats()->RecordQueryBegin(
+ sql, base::GetWallTimeNs().count());
+
+ ScopedStmt stmt;
+ IteratorImpl::StmtMetadata metadata;
+ base::Status status =
+ PrepareAndStepUntilLastValidStmt(*db_, sql, &stmt, &metadata);
+ PERFETTO_DCHECK((status.ok() && stmt) || (!status.ok() && !stmt));
std::unique_ptr<IteratorImpl> impl(new IteratorImpl(
- this, *db_, ScopedStmt(raw_stmt), col_count, status, sql_stats_row));
+ this, *db_, status, std::move(stmt), std::move(metadata), sql_stats_row));
return Iterator(std::move(impl));
}
@@ -949,7 +1133,7 @@ bool TraceProcessorImpl::IsRootMetricField(const std::string& metric_name) {
return field_idx != nullptr;
}
-util::Status TraceProcessorImpl::RegisterMetric(const std::string& path,
+base::Status TraceProcessorImpl::RegisterMetric(const std::string& path,
const std::string& sql) {
std::string stripped_sql;
for (base::StringSplitter sp(sql, '\n'); sp.Next();) {
@@ -966,7 +1150,7 @@ util::Status TraceProcessorImpl::RegisterMetric(const std::string& path,
[&path](const metrics::SqlMetricFile& m) { return m.path == path; });
if (it != sql_metrics_.end()) {
it->sql = stripped_sql;
- return util::OkStatus();
+ return base::OkStatus();
}
auto sep_idx = path.rfind('/');
@@ -975,7 +1159,7 @@ util::Status TraceProcessorImpl::RegisterMetric(const std::string& path,
auto sql_idx = basename.rfind(".sql");
if (sql_idx == std::string::npos) {
- return util::ErrStatus("Unable to find .sql extension for metric");
+ return base::ErrStatus("Unable to find .sql extension for metric");
}
auto no_ext_name = basename.substr(0, sql_idx);
@@ -986,60 +1170,76 @@ util::Status TraceProcessorImpl::RegisterMetric(const std::string& path,
if (IsRootMetricField(no_ext_name)) {
metric.proto_field_name = no_ext_name;
metric.output_table_name = no_ext_name + "_output";
+
+ auto field_it_and_inserted =
+ proto_field_to_sql_metric_path_.emplace(*metric.proto_field_name, path);
+ if (!field_it_and_inserted.second) {
+ // We already had a metric with this field name in the map. However, if
+ // this was the case, we should have found the metric in
+ // |path_to_sql_metric_file_| above if we are simply overriding the
+ // metric. Return an error since this means we have two different SQL
+ // files which are trying to output the same metric.
+ const auto& prev_path = field_it_and_inserted.first->second;
+ PERFETTO_DCHECK(prev_path != path);
+ return base::ErrStatus(
+ "RegisterMetric Error: Metric paths %s (which is already registered) "
+ "and %s are both trying to output the proto field %s",
+ prev_path.c_str(), path.c_str(), metric.proto_field_name->c_str());
+ }
+
InsertIntoTraceMetricsTable(*db_, no_ext_name);
}
sql_metrics_.emplace_back(metric);
- return util::OkStatus();
+ return base::OkStatus();
}
-util::Status TraceProcessorImpl::ExtendMetricsProto(const uint8_t* data,
+base::Status TraceProcessorImpl::ExtendMetricsProto(const uint8_t* data,
size_t size) {
- util::Status status = pool_.AddFromFileDescriptorSet(data, size);
+ return ExtendMetricsProto(data, size, /*skip_prefixes*/ {});
+}
+
+base::Status TraceProcessorImpl::ExtendMetricsProto(
+ const uint8_t* data,
+ size_t size,
+ const std::vector<std::string>& skip_prefixes) {
+ base::Status status =
+ pool_.AddFromFileDescriptorSet(data, size, skip_prefixes);
if (!status.ok())
return status;
- for (const auto& desc : pool_.descriptors()) {
+ for (uint32_t i = 0; i < pool_.descriptors().size(); ++i) {
// Convert the full name (e.g. .perfetto.protos.TraceMetrics.SubMetric)
// into a function name of the form (TraceMetrics_SubMetric).
+ const auto& desc = pool_.descriptors()[i];
auto fn_name = desc.full_name().substr(desc.package_name().size() + 1);
std::replace(fn_name.begin(), fn_name.end(), '.', '_');
-
- std::unique_ptr<metrics::BuildProtoContext> ctx(
- new metrics::BuildProtoContext());
- ctx->tp = this;
- ctx->pool = &pool_;
- ctx->desc = &desc;
-
- auto ret = sqlite3_create_function_v2(
- *db_, fn_name.c_str(), -1, SQLITE_UTF8, ctx.release(),
- metrics::BuildProto, nullptr, nullptr, [](void* ptr) {
- delete static_cast<metrics::BuildProtoContext*>(ptr);
- });
- if (ret != SQLITE_OK)
- return util::ErrStatus("%s", sqlite3_errmsg(*db_));
+ RegisterFunction<metrics::BuildProto>(
+ db_.get(), fn_name.c_str(), -1,
+ std::unique_ptr<metrics::BuildProto::Context>(
+ new metrics::BuildProto::Context{this, &pool_, i}));
}
- return util::OkStatus();
+ return base::OkStatus();
}
-util::Status TraceProcessorImpl::ComputeMetric(
+base::Status TraceProcessorImpl::ComputeMetric(
const std::vector<std::string>& metric_names,
std::vector<uint8_t>* metrics_proto) {
auto opt_idx = pool_.FindDescriptorIdx(".perfetto.protos.TraceMetrics");
if (!opt_idx.has_value())
- return util::Status("Root metrics proto descriptor not found");
+ return base::Status("Root metrics proto descriptor not found");
const auto& root_descriptor = pool_.descriptors()[opt_idx.value()];
- return metrics::ComputeMetrics(this, metric_names, sql_metrics_,
+ return metrics::ComputeMetrics(this, metric_names, sql_metrics_, pool_,
root_descriptor, metrics_proto);
}
-util::Status TraceProcessorImpl::ComputeMetricText(
+base::Status TraceProcessorImpl::ComputeMetricText(
const std::vector<std::string>& metric_names,
TraceProcessor::MetricResultFormat format,
std::string* metrics_string) {
std::vector<uint8_t> metrics_proto;
- util::Status status = ComputeMetric(metric_names, &metrics_proto);
+ base::Status status = ComputeMetric(metric_names, &metrics_proto);
if (!status.ok())
return status;
switch (format) {
@@ -1065,7 +1265,7 @@ void TraceProcessorImpl::EnableMetatrace() {
metatrace::Enable();
}
-util::Status TraceProcessorImpl::DisableAndReadMetatrace(
+base::Status TraceProcessorImpl::DisableAndReadMetatrace(
std::vector<uint8_t>* trace_proto) {
protozero::HeapBuffered<protos::pbzero::Trace> trace;
metatrace::DisableAndReadBuffer([&trace](metatrace::Record* record) {
@@ -1090,7 +1290,7 @@ util::Status TraceProcessorImpl::DisableAndReadMetatrace(
}
});
*trace_proto = trace.SerializeAsArray();
- return util::OkStatus();
+ return base::OkStatus();
}
} // namespace trace_processor
diff --git a/src/trace_processor/trace_processor_impl.h b/src/trace_processor/trace_processor_impl.h
index cb9ef9f67..4711a0713 100644
--- a/src/trace_processor/trace_processor_impl.h
+++ b/src/trace_processor/trace_processor_impl.h
@@ -21,6 +21,7 @@
#include <atomic>
#include <functional>
+#include <map>
#include <string>
#include <vector>
@@ -28,6 +29,8 @@
#include "perfetto/trace_processor/basic_types.h"
#include "perfetto/trace_processor/status.h"
#include "perfetto/trace_processor/trace_processor.h"
+#include "src/trace_processor/sqlite/create_function.h"
+#include "src/trace_processor/sqlite/create_view_function.h"
#include "src/trace_processor/sqlite/db_sqlite_table.h"
#include "src/trace_processor/sqlite/query_cache.h"
#include "src/trace_processor/sqlite/scoped_db.h"
@@ -46,25 +49,35 @@ class TraceProcessorImpl : public TraceProcessor,
public:
explicit TraceProcessorImpl(const Config&);
+ TraceProcessorImpl(const TraceProcessorImpl&) = delete;
+ TraceProcessorImpl& operator=(const TraceProcessorImpl&) = delete;
+
+ TraceProcessorImpl(TraceProcessorImpl&&) = delete;
+ TraceProcessorImpl& operator=(TraceProcessorImpl&&) = delete;
+
~TraceProcessorImpl() override;
// TraceProcessorStorage implementation:
- util::Status Parse(std::unique_ptr<uint8_t[]>, size_t) override;
+ base::Status Parse(TraceBlobView) override;
void NotifyEndOfFile() override;
// TraceProcessor implementation:
- Iterator ExecuteQuery(const std::string& sql,
- int64_t time_queued = 0) override;
+ Iterator ExecuteQuery(const std::string& sql) override;
- util::Status RegisterMetric(const std::string& path,
+ base::Status RegisterMetric(const std::string& path,
const std::string& sql) override;
- util::Status ExtendMetricsProto(const uint8_t* data, size_t size) override;
+ base::Status ExtendMetricsProto(const uint8_t* data, size_t size) override;
- util::Status ComputeMetric(const std::vector<std::string>& metric_names,
+ base::Status ExtendMetricsProto(
+ const uint8_t* data,
+ size_t size,
+ const std::vector<std::string>& skip_prefixes) override;
+
+ base::Status ComputeMetric(const std::vector<std::string>& metric_names,
std::vector<uint8_t>* metrics) override;
- util::Status ComputeMetricText(const std::vector<std::string>& metric_names,
+ base::Status ComputeMetricText(const std::vector<std::string>& metric_names,
TraceProcessor::MetricResultFormat format,
std::string* metrics_string) override;
@@ -79,7 +92,7 @@ class TraceProcessorImpl : public TraceProcessor,
void EnableMetatrace() override;
- util::Status DisableAndReadMetatrace(
+ base::Status DisableAndReadMetatrace(
std::vector<uint8_t>* trace_proto) override;
private:
@@ -99,11 +112,25 @@ class TraceProcessorImpl : public TraceProcessor,
}
bool IsRootMetricField(const std::string& metric_name);
+
+ // Keep this first: we need this to be destroyed after we clean up
+ // everything else.
ScopedDb db_;
+
+ // State necessary for CREATE_FUNCTION invocations. We store this here as we
+ // need to finalize any prepared statements *before* we destroy the database.
+ CreateFunction::State create_function_state_;
+
+ // State necessary for CREATE_VIEW_FUNCTION invocations. We store this here as
+ // we need to finalize any prepared statements *before* we destroy the
+ // database.
+ CreateViewFunction::State create_view_function_state_;
+
std::unique_ptr<QueryCache> query_cache_;
DescriptorPool pool_;
std::vector<metrics::SqlMetricFile> sql_metrics_;
+ std::unordered_map<std::string, std::string> proto_field_to_sql_metric_path_;
// This is atomic because it is set by the CTRL-C signal handler and we need
// to prevent single-flow compiler optimizations in ExecuteQuery().
@@ -118,7 +145,6 @@ class TraceProcessorImpl : public TraceProcessor,
uint64_t bytes_parsed_ = 0;
};
-
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/trace_processor_shell.cc b/src/trace_processor/trace_processor_shell.cc
index e4fac8b9e..1232a9001 100644
--- a/src/trace_processor/trace_processor_shell.cc
+++ b/src/trace_processor/trace_processor_shell.cc
@@ -15,12 +15,13 @@
*/
#include <errno.h>
#include <fcntl.h>
-#include <inttypes.h>
#include <stdio.h>
#include <sys/stat.h>
+#include <cinttypes>
#include <functional>
#include <iostream>
+#include <unordered_set>
#include <vector>
#include <google/protobuf/compiler/parser.h>
@@ -30,9 +31,11 @@
#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
+#include "perfetto/base/status.h"
#include "perfetto/base/time.h"
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/getopt.h"
+#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/scoped_file.h"
#include "perfetto/ext/base/string_splitter.h"
#include "perfetto/ext/base/string_utils.h"
@@ -40,11 +43,14 @@
#include "perfetto/trace_processor/read_trace.h"
#include "perfetto/trace_processor/trace_processor.h"
-#include "src/trace_processor/metrics/chrome/all_chrome_metrics.descriptor.h"
+#include "src/trace_processor/metrics/all_chrome_metrics.descriptor.h"
#include "src/trace_processor/metrics/metrics.descriptor.h"
+#include "src/trace_processor/metrics/metrics.h"
#include "src/trace_processor/util/proto_to_json.h"
#include "src/trace_processor/util/status_macros.h"
+#include "protos/perfetto/trace_processor/trace_processor.pbzero.h"
+
#if PERFETTO_BUILDFLAG(PERFETTO_TP_HTTPD)
#include "src/trace_processor/rpc/httpd.h"
#endif
@@ -186,13 +192,13 @@ ScopedLine GetLine(const char* prompt) {
#endif // PERFETTO_TP_LINENOISE
-util::Status PrintStats() {
+base::Status PrintStats() {
auto it = g_tp->ExecuteQuery(
"SELECT name, idx, source, value from stats "
"where severity IN ('error', 'data_loss') and value > 0");
bool first = true;
- for (uint32_t rows = 0; it.Next(); rows++) {
+ while (it.Next()) {
if (first) {
fprintf(stderr, "Error stats for this trace:\n");
@@ -231,20 +237,20 @@ util::Status PrintStats() {
fprintf(stderr, "\n");
}
- util::Status status = it.Status();
+ base::Status status = it.Status();
if (!status.ok()) {
- return util::ErrStatus("Error while iterating stats (%s)",
+ return base::ErrStatus("Error while iterating stats (%s)",
status.c_message());
}
- return util::OkStatus();
+ return base::OkStatus();
}
-util::Status ExportTraceToDatabase(const std::string& output_name) {
+base::Status ExportTraceToDatabase(const std::string& output_name) {
PERFETTO_CHECK(output_name.find('\'') == std::string::npos);
{
base::ScopedFile fd(base::OpenFile(output_name, O_CREAT | O_RDWR, 0600));
if (!fd)
- return util::ErrStatus("Failed to create file: %s", output_name.c_str());
+ return base::ErrStatus("Failed to create file: %s", output_name.c_str());
int res = ftruncate(fd.get(), 0);
PERFETTO_CHECK(res == 0);
}
@@ -255,15 +261,15 @@ util::Status ExportTraceToDatabase(const std::string& output_name) {
bool attach_has_more = attach_it.Next();
PERFETTO_DCHECK(!attach_has_more);
- util::Status status = attach_it.Status();
+ base::Status status = attach_it.Status();
if (!status.ok())
- return util::ErrStatus("SQLite error: %s", status.c_message());
+ return base::ErrStatus("SQLite error: %s", status.c_message());
// Export real and virtual tables.
auto tables_it = g_tp->ExecuteQuery(
"SELECT name FROM perfetto_tables UNION "
"SELECT name FROM sqlite_master WHERE type='table'");
- for (uint32_t rows = 0; tables_it.Next(); rows++) {
+ while (tables_it.Next()) {
std::string table_name = tables_it.Get(0).string_value;
PERFETTO_CHECK(!base::Contains(table_name, '\''));
std::string export_sql = "CREATE TABLE perfetto_export." + table_name +
@@ -275,16 +281,16 @@ util::Status ExportTraceToDatabase(const std::string& output_name) {
status = export_it.Status();
if (!status.ok())
- return util::ErrStatus("SQLite error: %s", status.c_message());
+ return base::ErrStatus("SQLite error: %s", status.c_message());
}
status = tables_it.Status();
if (!status.ok())
- return util::ErrStatus("SQLite error: %s", status.c_message());
+ return base::ErrStatus("SQLite error: %s", status.c_message());
// Export views.
auto views_it =
g_tp->ExecuteQuery("SELECT sql FROM sqlite_master WHERE type='view'");
- for (uint32_t rows = 0; views_it.Next(); rows++) {
+ while (views_it.Next()) {
std::string sql = views_it.Get(0).string_value;
// View statements are of the form "CREATE VIEW name AS stmt". We need to
// rewrite name to point to the exported db.
@@ -299,18 +305,18 @@ util::Status ExportTraceToDatabase(const std::string& output_name) {
status = export_it.Status();
if (!status.ok())
- return util::ErrStatus("SQLite error: %s", status.c_message());
+ return base::ErrStatus("SQLite error: %s", status.c_message());
}
status = views_it.Status();
if (!status.ok())
- return util::ErrStatus("SQLite error: %s", status.c_message());
+ return base::ErrStatus("SQLite error: %s", status.c_message());
auto detach_it = g_tp->ExecuteQuery("DETACH DATABASE perfetto_export");
bool detach_has_more = attach_it.Next();
PERFETTO_DCHECK(!detach_has_more);
status = detach_it.Status();
- return status.ok() ? util::OkStatus()
- : util::ErrStatus("SQLite error: %s", status.c_message());
+ return status.ok() ? base::OkStatus()
+ : base::ErrStatus("SQLite error: %s", status.c_message());
}
class ErrorPrinter : public google::protobuf::io::ErrorCollector {
@@ -332,32 +338,36 @@ std::string BaseName(std::string metric_path) {
: metric_path.substr(slash_idx + 1);
}
-util::Status RegisterMetric(const std::string& register_metric) {
+base::Status RegisterMetric(const std::string& register_metric) {
std::string sql;
base::ReadFile(register_metric, &sql);
std::string path = "shell/" + BaseName(register_metric);
-
return g_tp->RegisterMetric(path, sql);
}
-util::Status ExtendMetricsProto(const std::string& extend_metrics_proto,
- google::protobuf::DescriptorPool* pool) {
- google::protobuf::FileDescriptorSet desc_set;
-
- base::ScopedFile file(base::OpenFile(extend_metrics_proto, O_RDONLY));
+base::Status ParseToFileDescriptorProto(
+ const std::string& filename,
+ google::protobuf::FileDescriptorProto* file_desc) {
+ base::ScopedFile file(base::OpenFile(filename, O_RDONLY));
if (file.get() == -1) {
- return util::ErrStatus("Failed to open proto file %s",
- extend_metrics_proto.c_str());
+ return base::ErrStatus("Failed to open proto file %s", filename.c_str());
}
google::protobuf::io::FileInputStream stream(file.get());
ErrorPrinter printer;
google::protobuf::io::Tokenizer tokenizer(&stream, &printer);
- auto* file_desc = desc_set.add_file();
google::protobuf::compiler::Parser parser;
parser.Parse(&tokenizer, file_desc);
+ return base::OkStatus();
+}
+
+base::Status ExtendMetricsProto(const std::string& extend_metrics_proto,
+ google::protobuf::DescriptorPool* pool) {
+ google::protobuf::FileDescriptorSet desc_set;
+ auto* file_desc = desc_set.add_file();
+ RETURN_IF_ERROR(ParseToFileDescriptorProto(extend_metrics_proto, file_desc));
file_desc->set_name(BaseName(extend_metrics_proto));
pool->BuildFile(*file_desc);
@@ -377,62 +387,82 @@ enum OutputFormat {
kNone,
};
-util::Status RunMetrics(const std::vector<std::string>& metric_names,
+struct MetricNameAndPath {
+ std::string name;
+ base::Optional<std::string> no_ext_path;
+};
+
+base::Status RunMetrics(const std::vector<MetricNameAndPath>& metrics,
OutputFormat format,
const google::protobuf::DescriptorPool& pool) {
+ std::vector<std::string> metric_names(metrics.size());
+ for (size_t i = 0; i < metrics.size(); ++i) {
+ metric_names[i] = metrics[i].name;
+ }
+
+ if (format == OutputFormat::kTextProto) {
+ std::string out;
+ base::Status status =
+ g_tp->ComputeMetricText(metric_names, TraceProcessor::kProtoText, &out);
+ if (!status.ok()) {
+ return base::ErrStatus("Error when computing metrics: %s",
+ status.c_message());
+ }
+ out += '\n';
+ fwrite(out.c_str(), sizeof(char), out.size(), stdout);
+ return base::OkStatus();
+ }
+
std::vector<uint8_t> metric_result;
- util::Status status = g_tp->ComputeMetric(metric_names, &metric_result);
+ base::Status status = g_tp->ComputeMetric(metric_names, &metric_result);
if (!status.ok()) {
- return util::ErrStatus("Error when computing metrics: %s",
+ return base::ErrStatus("Error when computing metrics: %s",
status.c_message());
}
- if (format == OutputFormat::kNone) {
- return util::OkStatus();
- }
- if (format == OutputFormat::kBinaryProto) {
- fwrite(metric_result.data(), sizeof(uint8_t), metric_result.size(), stdout);
- return util::OkStatus();
- }
-
- google::protobuf::DynamicMessageFactory factory(&pool);
- auto* descriptor = pool.FindMessageTypeByName("perfetto.protos.TraceMetrics");
- std::unique_ptr<google::protobuf::Message> metrics(
- factory.GetPrototype(descriptor)->New());
- metrics->ParseFromArray(metric_result.data(),
- static_cast<int>(metric_result.size()));
switch (format) {
- case OutputFormat::kTextProto: {
- std::string out;
- google::protobuf::TextFormat::PrintToString(*metrics, &out);
- fwrite(out.c_str(), sizeof(char), out.size(), stdout);
- break;
- }
case OutputFormat::kJson: {
+ // TODO(b/182165266): Handle this using ComputeMetricText.
+ google::protobuf::DynamicMessageFactory factory(&pool);
+ auto* descriptor =
+ pool.FindMessageTypeByName("perfetto.protos.TraceMetrics");
+ std::unique_ptr<google::protobuf::Message> metric_msg(
+ factory.GetPrototype(descriptor)->New());
+ metric_msg->ParseFromArray(metric_result.data(),
+ static_cast<int>(metric_result.size()));
+
// We need to instantiate field options from dynamic message factory
// because otherwise it cannot parse our custom extensions.
const google::protobuf::Message* field_options_prototype =
factory.GetPrototype(
pool.FindMessageTypeByName("google.protobuf.FieldOptions"));
auto out = proto_to_json::MessageToJsonWithAnnotations(
- *metrics, field_options_prototype, 0);
+ *metric_msg, field_options_prototype, 0);
fwrite(out.c_str(), sizeof(char), out.size(), stdout);
break;
}
case OutputFormat::kBinaryProto:
+ fwrite(metric_result.data(), sizeof(uint8_t), metric_result.size(),
+ stdout);
+ break;
case OutputFormat::kNone:
- PERFETTO_FATAL("Unsupported output format.");
+ break;
+ case OutputFormat::kTextProto:
+ PERFETTO_FATAL("This case was already handled.");
}
- return util::OkStatus();
+
+ return base::OkStatus();
}
void PrintQueryResultInteractively(Iterator* it,
base::TimeNanos t_start,
uint32_t column_width) {
- base::TimeNanos t_end = t_start;
+ base::TimeNanos t_end = base::GetWallTimeNs();
for (uint32_t rows = 0; it->Next(); rows++) {
if (rows % 32 == 0) {
- if (rows > 0) {
+ if (rows == 0) {
+ t_end = base::GetWallTimeNs();
+ } else {
fprintf(stderr, "...\nType 'q' to stop, Enter for more records: ");
fflush(stderr);
char input[32];
@@ -440,8 +470,6 @@ void PrintQueryResultInteractively(Iterator* it,
exit(0);
if (input[0] == 'q')
break;
- } else {
- t_end = base::GetWallTimeNs();
}
for (uint32_t i = 0; i < it->ColumnCount(); i++)
printf("%-*.*s ", column_width, column_width,
@@ -479,7 +507,7 @@ void PrintQueryResultInteractively(Iterator* it,
printf("\n");
}
- util::Status status = it->Status();
+ base::Status status = it->Status();
if (!status.ok()) {
PERFETTO_ELOG("SQLite error: %s", status.c_message());
}
@@ -487,7 +515,7 @@ void PrintQueryResultInteractively(Iterator* it,
static_cast<double>((t_end - t_start).count()) / 1E6);
}
-util::Status PrintQueryResultAsCsv(Iterator* it, FILE* output) {
+base::Status PrintQueryResultAsCsv(Iterator* it, bool has_more, FILE* output) {
for (uint32_t c = 0; c < it->ColumnCount(); c++) {
if (c > 0)
fprintf(output, ",");
@@ -495,7 +523,7 @@ util::Status PrintQueryResultAsCsv(Iterator* it, FILE* output) {
}
fprintf(output, "\n");
- for (uint32_t rows = 0; it->Next(); rows++) {
+ for (; has_more; has_more = it->Next()) {
for (uint32_t c = 0; c < it->ColumnCount(); c++) {
if (c > 0)
fprintf(output, ",");
@@ -524,134 +552,105 @@ util::Status PrintQueryResultAsCsv(Iterator* it, FILE* output) {
return it->Status();
}
-bool IsBlankLine(const std::string& buffer) {
- return buffer == "\n" || buffer == "\r\n";
-}
-
-bool IsCommentLine(const std::string& buffer) {
- return base::StartsWith(buffer, "--");
-}
+base::Status RunQueriesWithoutOutput(const std::string& sql_query) {
+ auto it = g_tp->ExecuteQuery(sql_query);
+ if (it.StatementWithOutputCount() > 0)
+ return base::ErrStatus("Unexpected result from a query.");
-bool HasEndOfQueryDelimiter(const std::string& buffer) {
- return base::EndsWith(buffer, ";\n") || base::EndsWith(buffer, ";") ||
- base::EndsWith(buffer, ";\r\n");
+ RETURN_IF_ERROR(it.Status());
+ return it.Next() ? base::ErrStatus("Unexpected result from a query.")
+ : it.Status();
}
-util::Status LoadQueries(FILE* input, std::vector<std::string>* output) {
- char buffer[4096];
- while (!feof(input) && !ferror(input)) {
- std::string sql_query;
- while (fgets(buffer, sizeof(buffer), input)) {
- std::string line = base::TrimLeading(buffer);
- if (IsBlankLine(line))
- break;
-
- if (IsCommentLine(line))
- continue;
-
- sql_query.append(line);
-
- if (HasEndOfQueryDelimiter(line))
- break;
- }
- if (!sql_query.empty() && sql_query.back() == '\n')
- sql_query.resize(sql_query.size() - 1);
-
- // If we have a new line at the end of the file or an extra new line
- // somewhere in the file, we'll end up with an empty query which we should
- // just ignore.
- if (sql_query.empty())
- continue;
-
- output->push_back(sql_query);
+base::Status RunQueriesAndPrintResult(const std::string& sql_query,
+ FILE* output) {
+ PERFETTO_ILOG("Executing query: %s", sql_query.c_str());
+ auto query_start = std::chrono::steady_clock::now();
+
+ auto it = g_tp->ExecuteQuery(sql_query);
+ RETURN_IF_ERROR(it.Status());
+
+ bool has_more = it.Next();
+ RETURN_IF_ERROR(it.Status());
+
+ uint32_t prev_count = it.StatementCount() - 1;
+ uint32_t prev_with_output = has_more ? it.StatementWithOutputCount() - 1
+ : it.StatementWithOutputCount();
+ uint32_t prev_without_output_count = prev_count - prev_with_output;
+ if (prev_with_output > 0) {
+ return base::ErrStatus(
+ "Result rows were returned for multiples queries. Ensure that only the "
+ "final statement is a SELECT statment or use `suppress_query_output` "
+ "to prevent function invocations causing this "
+ "error (see "
+ "https://perfetto.dev/docs/contributing/"
+ "testing#trace-processor-diff-tests).");
}
- if (ferror(input)) {
- return util::ErrStatus("Error reading query file");
+ for (uint32_t i = 0; i < prev_without_output_count; ++i) {
+ fprintf(output, "\n");
}
- return util::OkStatus();
-}
-
-util::Status RunQueriesWithoutOutput(const std::vector<std::string>& queries) {
- for (const auto& sql_query : queries) {
- PERFETTO_DLOG("Executing query: %s", sql_query.c_str());
-
- auto it = g_tp->ExecuteQuery(sql_query);
- RETURN_IF_ERROR(it.Status());
- if (it.Next()) {
- return util::ErrStatus("Unexpected result from a query.");
- }
+ if (it.ColumnCount() == 0) {
+ PERFETTO_DCHECK(!has_more);
+ return base::OkStatus();
}
- return util::OkStatus();
-}
-
-util::Status RunQueriesAndPrintResult(const std::vector<std::string>& queries,
- FILE* output) {
- bool is_first_query = true;
- bool has_output = false;
- for (const auto& sql_query : queries) {
- // Add an extra newline separator between query results.
- if (!is_first_query)
- fprintf(output, "\n");
- is_first_query = false;
-
- PERFETTO_ILOG("Executing query: %s", sql_query.c_str());
-
- auto it = g_tp->ExecuteQuery(sql_query);
- RETURN_IF_ERROR(it.Status());
- if (it.ColumnCount() == 0) {
- bool it_has_more = it.Next();
- PERFETTO_DCHECK(!it_has_more);
- continue;
- }
- // If we have a single column with the name |suppress_query_output| that's
- // a hint to shell that it should not treat the query as having real
- // meaning.
- if (it.ColumnCount() == 1 &&
- it.GetColumnName(0) == "suppress_query_output") {
- // We should only see a single null value as this feature is usually used
- // as SELECT RUN_METRIC(<metric file>) as suppress_query_output and
- // RUN_METRIC returns a single null.
- bool has_next = it.Next();
- RETURN_IF_ERROR(it.Status());
- PERFETTO_DCHECK(has_next);
- PERFETTO_DCHECK(it.Get(0).is_null());
-
- has_next = it.Next();
- RETURN_IF_ERROR(it.Status());
- PERFETTO_DCHECK(!has_next);
- continue;
- }
+ auto query_end = std::chrono::steady_clock::now();
+ RETURN_IF_ERROR(PrintQueryResultAsCsv(&it, has_more, output));
- if (has_output) {
- return util::ErrStatus(
- "More than one query generated result rows. This is unsupported.");
- }
- has_output = true;
- RETURN_IF_ERROR(PrintQueryResultAsCsv(&it, output));
- }
- return util::OkStatus();
+ auto dur = query_end - query_start;
+ PERFETTO_ILOG(
+ "Query execution time: %" PRIi64 " ms",
+ static_cast<int64_t>(
+ std::chrono::duration_cast<std::chrono::milliseconds>(dur).count()));
+ return base::OkStatus();
}
-util::Status PrintPerfFile(const std::string& perf_file_path,
+base::Status PrintPerfFile(const std::string& perf_file_path,
base::TimeNanos t_load,
base::TimeNanos t_run) {
char buf[128];
- int count = snprintf(buf, sizeof(buf), "%" PRId64 ",%" PRId64,
- static_cast<int64_t>(t_load.count()),
- static_cast<int64_t>(t_run.count()));
- if (count < 0) {
- return util::ErrStatus("Failed to write perf data");
+ size_t count = base::SprintfTrunc(buf, sizeof(buf), "%" PRId64 ",%" PRId64,
+ static_cast<int64_t>(t_load.count()),
+ static_cast<int64_t>(t_run.count()));
+ if (count == 0) {
+ return base::ErrStatus("Failed to write perf data");
}
auto fd(base::OpenFile(perf_file_path, O_WRONLY | O_CREAT | O_TRUNC, 0666));
if (!fd) {
- return util::ErrStatus("Failed to open perf file");
+ return base::ErrStatus("Failed to open perf file");
}
- base::WriteAll(fd.get(), buf, static_cast<size_t>(count));
- return util::OkStatus();
+ base::WriteAll(fd.get(), buf, count);
+ return base::OkStatus();
}
+class MetricExtension {
+ public:
+ void SetDiskPath(std::string path) {
+ AddTrailingSlashIfNeeded(path);
+ disk_path_ = std::move(path);
+ }
+ void SetVirtualPath(std::string path) {
+ AddTrailingSlashIfNeeded(path);
+ virtual_path_ = std::move(path);
+ }
+
+ // Disk location. Ends with a trailing slash.
+ const std::string& disk_path() const { return disk_path_; }
+ // Virtual location. Ends with a trailing slash.
+ const std::string& virtual_path() const { return virtual_path_; }
+
+ private:
+ std::string disk_path_;
+ std::string virtual_path_;
+
+ static void AddTrailingSlashIfNeeded(std::string& path) {
+ if (path.length() > 0 && path[path.length() - 1] != '/') {
+ path.push_back('/');
+ }
+ }
+};
+
struct CommandLineOptions {
std::string perf_file_path;
std::string query_file_path;
@@ -661,11 +660,14 @@ struct CommandLineOptions {
std::string metric_output;
std::string trace_file_path;
std::string port_number;
+ std::vector<std::string> raw_metric_extensions;
bool launch_shell = false;
bool enable_httpd = false;
bool wide = false;
bool force_full_sort = false;
std::string metatrace_path;
+ bool dev = false;
+ bool no_ftrace_raw = false;
};
void PrintUsage(char** argv) {
@@ -712,7 +714,22 @@ Options:
writing the resulting trace into FILE.
--full-sort Forces the trace processor into performing
a full sort ignoring any windowing
- logic.)",
+ logic.
+ --metric-extension DISK_PATH@VIRTUAL_PATH
+ Loads metric proto and sql files from
+ DISK_PATH/protos and DISK_PATH/sql
+ respectively, and mounts them onto
+ VIRTUAL_PATH.
+ --dev Enables features which are reserved for
+ local development use only and
+ *should not* be enabled on production
+ builds. The features behind this flag can
+ break at any time without any warning.
+ --no-ftrace-raw Prevents ingestion of typed ftrace events
+ into the raw table. This significantly
+ reduces the memory usage of trace
+ processor when loading traces containing
+ ftrace events.)",
argv[0]);
}
@@ -724,6 +741,9 @@ CommandLineOptions ParseCommandLineOptions(int argc, char** argv) {
OPT_METRICS_OUTPUT,
OPT_FORCE_FULL_SORT,
OPT_HTTP_PORT,
+ OPT_METRIC_EXTENSION,
+ OPT_DEV,
+ OPT_NO_FTRACE_RAW,
};
static const option long_options[] = {
@@ -742,6 +762,9 @@ CommandLineOptions ParseCommandLineOptions(int argc, char** argv) {
{"metrics-output", required_argument, nullptr, OPT_METRICS_OUTPUT},
{"full-sort", no_argument, nullptr, OPT_FORCE_FULL_SORT},
{"http-port", required_argument, nullptr, OPT_HTTP_PORT},
+ {"metric-extension", required_argument, nullptr, OPT_METRIC_EXTENSION},
+ {"dev", no_argument, nullptr, OPT_DEV},
+ {"no-ftrace-raw", no_argument, nullptr, OPT_NO_FTRACE_RAW},
{nullptr, 0, nullptr, 0}};
bool explicit_interactive = false;
@@ -754,6 +777,8 @@ CommandLineOptions ParseCommandLineOptions(int argc, char** argv) {
if (option == 'v') {
printf("%s\n", base::GetVersionString());
+ printf("Trace Processor RPC API version: %d\n",
+ protos::pbzero::TRACE_PROCESSOR_CURRENT_API_VERSION);
exit(0);
}
@@ -826,6 +851,21 @@ CommandLineOptions ParseCommandLineOptions(int argc, char** argv) {
continue;
}
+ if (option == OPT_METRIC_EXTENSION) {
+ command_line_options.raw_metric_extensions.push_back(optarg);
+ continue;
+ }
+
+ if (option == OPT_DEV) {
+ command_line_options.dev = true;
+ continue;
+ }
+
+ if (option == OPT_NO_FTRACE_RAW) {
+ command_line_options.no_ftrace_raw = true;
+ continue;
+ }
+
PrintUsage(argv);
exit(option == 'h' ? 0 : 1);
}
@@ -852,27 +892,31 @@ CommandLineOptions ParseCommandLineOptions(int argc, char** argv) {
PrintUsage(argv);
exit(1);
}
+
return command_line_options;
}
void ExtendPoolWithBinaryDescriptor(google::protobuf::DescriptorPool& pool,
const void* data,
- int size) {
+ int size,
+ std::vector<std::string>& skip_prefixes) {
google::protobuf::FileDescriptorSet desc_set;
- desc_set.ParseFromArray(data, size);
- for (const auto& desc : desc_set.file()) {
- pool.BuildFile(desc);
+ PERFETTO_CHECK(desc_set.ParseFromArray(data, size));
+ for (const auto& file_desc : desc_set.file()) {
+ if (base::StartsWithAny(file_desc.name(), skip_prefixes))
+ continue;
+ pool.BuildFile(file_desc);
}
}
-util::Status LoadTrace(const std::string& trace_file_path, double* size_mb) {
- util::Status read_status =
+base::Status LoadTrace(const std::string& trace_file_path, double* size_mb) {
+ base::Status read_status =
ReadTrace(g_tp, trace_file_path.c_str(), [&size_mb](size_t parsed_size) {
*size_mb = static_cast<double>(parsed_size) / 1E6;
fprintf(stderr, "\rLoading trace: %.2f MB\r", *size_mb);
});
if (!read_status.ok()) {
- return util::ErrStatus("Could not read trace file (path: %s): %s",
+ return base::ErrStatus("Could not read trace file (path: %s): %s",
trace_file_path.c_str(), read_status.c_message());
}
@@ -909,102 +953,281 @@ util::Status LoadTrace(const std::string& trace_file_path, double* size_mb) {
}
});
}
- return util::OkStatus();
+ return base::OkStatus();
}
-util::Status RunQueries(const std::string& query_file_path,
+base::Status RunQueries(const std::string& query_file_path,
bool expect_output) {
- std::vector<std::string> queries;
- base::ScopedFstream file(fopen(query_file_path.c_str(), "r"));
- if (!file) {
- return util::ErrStatus("Could not open query file (path: %s)",
- query_file_path.c_str());
- }
- RETURN_IF_ERROR(LoadQueries(file.get(), &queries));
+ std::string queries;
+ base::ReadFile(query_file_path.c_str(), &queries);
- util::Status status;
+ base::Status status;
if (expect_output) {
status = RunQueriesAndPrintResult(queries, stdout);
} else {
status = RunQueriesWithoutOutput(queries);
}
if (!status.ok()) {
- return util::ErrStatus("Encountered error while running queries: %s",
+ return base::ErrStatus("Encountered error while running queries: %s",
status.c_message());
}
- return util::OkStatus();
+ return base::OkStatus();
}
-util::Status RunMetrics(const CommandLineOptions& options) {
- // Descriptor pool used for printing output as textproto.
- // Building on top of generated pool so default protos in
- // google.protobuf.descriptor.proto are available.
- google::protobuf::DescriptorPool pool(
- google::protobuf::DescriptorPool::generated_pool());
+base::Status ParseSingleMetricExtensionPath(bool dev,
+ const std::string& raw_extension,
+ MetricExtension& parsed_extension) {
+ // We cannot easily use ':' as a path separator because windows paths can have
+ // ':' in them (e.g. C:\foo\bar).
+ std::vector<std::string> parts = base::SplitString(raw_extension, "@");
+ if (parts.size() != 2 || parts[0].length() == 0 || parts[1].length() == 0) {
+ return base::ErrStatus(
+ "--metric-extension-dir must be of format disk_path@virtual_path");
+ }
+
+ parsed_extension.SetDiskPath(std::move(parts[0]));
+ parsed_extension.SetVirtualPath(std::move(parts[1]));
+
+ if (parsed_extension.virtual_path() == "/") {
+ if (!dev) {
+ return base::ErrStatus(
+ "Local development features must be enabled (using the "
+ "--dev flag) to override built-in metrics");
+ }
+ parsed_extension.SetVirtualPath("");
+ }
+
+ if (parsed_extension.virtual_path() == "shell/") {
+ return base::Status(
+ "Cannot have 'shell/' as metric extension virtual path.");
+ }
+ return base::OkStatus();
+}
+
+base::Status CheckForDuplicateMetricExtension(
+ const std::vector<MetricExtension>& metric_extensions) {
+ std::unordered_set<std::string> disk_paths;
+ std::unordered_set<std::string> virtual_paths;
+ for (const auto& extension : metric_extensions) {
+ auto ret = disk_paths.insert(extension.disk_path());
+ if (!ret.second) {
+ return base::ErrStatus(
+ "Another metric extension is already using disk path %s",
+ extension.disk_path().c_str());
+ }
+ ret = virtual_paths.insert(extension.virtual_path());
+ if (!ret.second) {
+ return base::ErrStatus(
+ "Another metric extension is already using virtual path %s",
+ extension.virtual_path().c_str());
+ }
+ }
+ return base::OkStatus();
+}
+
+base::Status ParseMetricExtensionPaths(
+ bool dev,
+ const std::vector<std::string>& raw_metric_extensions,
+ std::vector<MetricExtension>& metric_extensions) {
+ for (const auto& raw_extension : raw_metric_extensions) {
+ metric_extensions.push_back({});
+ RETURN_IF_ERROR(ParseSingleMetricExtensionPath(dev, raw_extension,
+ metric_extensions.back()));
+ }
+ return CheckForDuplicateMetricExtension(metric_extensions);
+}
+
+base::Status LoadMetricExtensionProtos(const std::string& proto_root,
+ const std::string& mount_path) {
+ if (!base::FileExists(proto_root)) {
+ return base::ErrStatus(
+ "Directory %s does not exist. Metric extension directory must contain "
+ "a 'sql/' and 'protos/' subdirectory.",
+ proto_root.c_str());
+ }
+ std::vector<std::string> proto_files;
+ RETURN_IF_ERROR(base::ListFilesRecursive(proto_root, proto_files));
+
+ google::protobuf::FileDescriptorSet parsed_protos;
+ for (const auto& file_path : proto_files) {
+ if (base::GetFileExtension(file_path) != ".proto")
+ continue;
+ auto* file_desc = parsed_protos.add_file();
+ ParseToFileDescriptorProto(proto_root + file_path, file_desc);
+ file_desc->set_name(mount_path + file_path);
+ }
+
+ std::vector<uint8_t> serialized_filedescset;
+ serialized_filedescset.resize(parsed_protos.ByteSizeLong());
+ parsed_protos.SerializeToArray(
+ serialized_filedescset.data(),
+ static_cast<int>(serialized_filedescset.size()));
+
+ RETURN_IF_ERROR(g_tp->ExtendMetricsProto(serialized_filedescset.data(),
+ serialized_filedescset.size()));
+
+ return base::OkStatus();
+}
+
+base::Status LoadMetricExtensionSql(const std::string& sql_root,
+ const std::string& mount_path) {
+ if (!base::FileExists(sql_root)) {
+ return base::ErrStatus(
+ "Directory %s does not exist. Metric extension directory must contain "
+ "a 'sql/' and 'protos/' subdirectory.",
+ sql_root.c_str());
+ }
+
+ std::vector<std::string> sql_files;
+ RETURN_IF_ERROR(base::ListFilesRecursive(sql_root, sql_files));
+ for (const auto& file_path : sql_files) {
+ if (base::GetFileExtension(file_path) != ".sql")
+ continue;
+ std::string file_contents;
+ if (!base::ReadFile(sql_root + file_path, &file_contents)) {
+ return base::ErrStatus("Cannot read file %s", file_path.c_str());
+ }
+ RETURN_IF_ERROR(
+ g_tp->RegisterMetric(mount_path + file_path, file_contents));
+ }
+
+ return base::OkStatus();
+}
+
+base::Status LoadMetricExtension(const MetricExtension& extension) {
+ const std::string& disk_path = extension.disk_path();
+ const std::string& virtual_path = extension.virtual_path();
+
+ if (!base::FileExists(disk_path)) {
+ return base::ErrStatus("Metric extension directory %s does not exist",
+ disk_path.c_str());
+ }
+
+ // Note: Proto files must be loaded first, because we determine whether an SQL
+ // file is a metric or not by checking if the name matches a field of the root
+ // TraceMetrics proto.
+ RETURN_IF_ERROR(LoadMetricExtensionProtos(disk_path + "protos/",
+ kMetricProtoRoot + virtual_path));
+ RETURN_IF_ERROR(LoadMetricExtensionSql(disk_path + "sql/", virtual_path));
+
+ return base::OkStatus();
+}
+
+base::Status PopulateDescriptorPool(
+ google::protobuf::DescriptorPool& pool,
+ const std::vector<MetricExtension>& metric_extensions) {
+ // TODO(b/182165266): There is code duplication here with trace_processor_impl
+ // SetupMetrics. This will be removed when we switch the output formatter to
+ // use internal DescriptorPool.
+ std::vector<std::string> skip_prefixes;
+ skip_prefixes.reserve(metric_extensions.size());
+ for (const auto& ext : metric_extensions) {
+ skip_prefixes.push_back(kMetricProtoRoot + ext.virtual_path());
+ }
ExtendPoolWithBinaryDescriptor(pool, kMetricsDescriptor.data(),
- kMetricsDescriptor.size());
+ kMetricsDescriptor.size(), skip_prefixes);
ExtendPoolWithBinaryDescriptor(pool, kAllChromeMetricsDescriptor.data(),
- kAllChromeMetricsDescriptor.size());
+ kAllChromeMetricsDescriptor.size(),
+ skip_prefixes);
+ return base::OkStatus();
+}
- std::vector<std::string> metrics;
- for (base::StringSplitter ss(options.metric_names, ','); ss.Next();) {
- metrics.emplace_back(ss.cur_token());
+base::Status LoadMetrics(const std::string& raw_metric_names,
+ google::protobuf::DescriptorPool& pool,
+ std::vector<MetricNameAndPath>& name_and_path) {
+ std::vector<std::string> split;
+ for (base::StringSplitter ss(raw_metric_names, ','); ss.Next();) {
+ split.emplace_back(ss.cur_token());
}
// For all metrics which are files, register them and extend the metrics
// proto.
- for (size_t i = 0; i < metrics.size(); ++i) {
- const std::string& metric_or_path = metrics[i];
-
+ for (const std::string& metric_or_path : split) {
// If there is no extension, we assume it is a builtin metric.
auto ext_idx = metric_or_path.rfind('.');
- if (ext_idx == std::string::npos)
+ if (ext_idx == std::string::npos) {
+ name_and_path.emplace_back(
+ MetricNameAndPath{metric_or_path, base::nullopt});
continue;
+ }
- std::string no_ext_name = metric_or_path.substr(0, ext_idx);
+ std::string no_ext_path = metric_or_path.substr(0, ext_idx);
// The proto must be extended before registering the metric.
- util::Status status = ExtendMetricsProto(no_ext_name + ".proto", &pool);
+ base::Status status = ExtendMetricsProto(no_ext_path + ".proto", &pool);
if (!status.ok()) {
- return util::ErrStatus("Unable to extend metrics proto %s: %s",
+ return base::ErrStatus("Unable to extend metrics proto %s: %s",
metric_or_path.c_str(), status.c_message());
}
- status = RegisterMetric(no_ext_name + ".sql");
+ status = RegisterMetric(no_ext_path + ".sql");
if (!status.ok()) {
- return util::ErrStatus("Unable to register metric %s: %s",
+ return base::ErrStatus("Unable to register metric %s: %s",
metric_or_path.c_str(), status.c_message());
}
+ name_and_path.emplace_back(
+ MetricNameAndPath{BaseName(no_ext_path), no_ext_path});
+ }
+ return base::OkStatus();
+}
+
+OutputFormat ParseOutputFormat(const CommandLineOptions& options) {
+ if (!options.query_file_path.empty())
+ return OutputFormat::kNone;
+ if (options.metric_output == "binary")
+ return OutputFormat::kBinaryProto;
+ if (options.metric_output == "json")
+ return OutputFormat::kJson;
+ return OutputFormat::kTextProto;
+}
+
+base::Status LoadMetricsAndExtensionsSql(
+ const std::vector<MetricNameAndPath>& metrics,
+ const std::vector<MetricExtension>& extensions) {
+ for (const MetricExtension& extension : extensions) {
+ const std::string& disk_path = extension.disk_path();
+ const std::string& virtual_path = extension.virtual_path();
- metrics[i] = BaseName(no_ext_name);
+ RETURN_IF_ERROR(LoadMetricExtensionSql(disk_path + "sql/", virtual_path));
}
- OutputFormat format;
- if (!options.query_file_path.empty()) {
- format = OutputFormat::kNone;
- } else if (options.metric_output == "binary") {
- format = OutputFormat::kBinaryProto;
- } else if (options.metric_output == "json") {
- format = OutputFormat::kJson;
- } else {
- format = OutputFormat::kTextProto;
+ for (const MetricNameAndPath& metric : metrics) {
+ // Ignore builtin metrics.
+ if (!metric.no_ext_path.has_value())
+ continue;
+ RETURN_IF_ERROR(RegisterMetric(metric.no_ext_path.value() + ".sql"));
}
- return RunMetrics(std::move(metrics), format, pool);
+ return base::OkStatus();
}
void PrintShellUsage() {
PERFETTO_ELOG(
"Available commands:\n"
- ".quit, .q Exit the shell.\n"
- ".help This text.\n"
- ".dump FILE Export the trace as a sqlite database.\n"
- ".read FILE Executes the queries in the FILE.\n"
- ".reset Destroys all tables/view created by the user.\n");
+ ".quit, .q Exit the shell.\n"
+ ".help This text.\n"
+ ".dump FILE Export the trace as a sqlite database.\n"
+ ".read FILE Executes the queries in the FILE.\n"
+ ".reset Destroys all tables/view created by the user.\n"
+ ".load-metrics-sql Reloads SQL from extension and custom metric paths\n"
+ " specified in command line args.\n"
+ ".run-metrics Runs metrics specified in command line args\n"
+ " and prints the result.\n"
+ ".width WIDTH Changes the column width of interactive query\n"
+ " output.");
}
-util::Status StartInteractiveShell(uint32_t column_width) {
+struct InteractiveOptions {
+ uint32_t column_width;
+ OutputFormat metric_format;
+ std::vector<MetricExtension> extensions;
+ std::vector<MetricNameAndPath> metrics;
+ const google::protobuf::DescriptorPool* pool;
+};
+
+base::Status StartInteractiveShell(const InteractiveOptions& options) {
SetupLineEditor();
+ uint32_t column_width = options.column_width;
for (;;) {
ScopedLine line = GetLine("> ");
if (!line)
@@ -1027,7 +1250,31 @@ util::Status StartInteractiveShell(uint32_t column_width) {
} else if (strcmp(command, "reset") == 0) {
g_tp->RestoreInitialTables();
} else if (strcmp(command, "read") == 0 && strlen(arg)) {
- util::Status status = RunQueries(arg, true);
+ base::Status status = RunQueries(arg, true);
+ if (!status.ok()) {
+ PERFETTO_ELOG("%s", status.c_message());
+ }
+ } else if (strcmp(command, "width") == 0 && strlen(arg)) {
+ base::Optional<uint32_t> width = base::CStringToUInt32(arg);
+ if (!width) {
+ PERFETTO_ELOG("Invalid column width specified");
+ continue;
+ }
+ column_width = *width;
+ } else if (strcmp(command, "load-metrics-sql") == 0) {
+ base::Status status =
+ LoadMetricsAndExtensionsSql(options.metrics, options.extensions);
+ if (!status.ok()) {
+ PERFETTO_ELOG("%s", status.c_message());
+ }
+ } else if (strcmp(command, "run-metrics") == 0) {
+ if (options.metrics.empty()) {
+ PERFETTO_ELOG("No metrics specified on command line");
+ continue;
+ }
+
+ base::Status status =
+ RunMetrics(options.metrics, options.metric_format, *options.pool);
if (!status.ok()) {
PERFETTO_ELOG("%s", status.c_message());
}
@@ -1041,16 +1288,25 @@ util::Status StartInteractiveShell(uint32_t column_width) {
auto it = g_tp->ExecuteQuery(line.get());
PrintQueryResultInteractively(&it, t_start, column_width);
}
- return util::OkStatus();
+ return base::OkStatus();
}
-util::Status TraceProcessorMain(int argc, char** argv) {
+base::Status TraceProcessorMain(int argc, char** argv) {
CommandLineOptions options = ParseCommandLineOptions(argc, argv);
Config config;
config.sorting_mode = options.force_full_sort
? SortingMode::kForceFullSort
: SortingMode::kDefaultHeuristics;
+ config.ingest_ftrace_in_raw_table = !options.no_ftrace_raw;
+
+ std::vector<MetricExtension> metric_extensions;
+ RETURN_IF_ERROR(ParseMetricExtensionPaths(
+ options.dev, options.raw_metric_extensions, metric_extensions));
+
+ for (const auto& extension : metric_extensions) {
+ config.skip_builtin_metric_paths.push_back(extension.virtual_path());
+ }
std::unique_ptr<TraceProcessor> tp = TraceProcessor::CreateInstance(config);
g_tp = tp.get();
@@ -1060,6 +1316,13 @@ util::Status TraceProcessorMain(int argc, char** argv) {
tp->EnableMetatrace();
}
+ // We load all the metric extensions even when --run-metrics arg is not there,
+ // because we want the metrics to be available in interactive mode or when
+ // used in UI using httpd.
+ for (const auto& extension : metric_extensions) {
+ RETURN_IF_ERROR(LoadMetricExtension(extension));
+ }
+
base::TimeNanos t_load{};
if (!options.trace_file_path.empty()) {
base::TimeNanos t_load_start = base::GetWallTimeNs();
@@ -1068,8 +1331,8 @@ util::Status TraceProcessorMain(int argc, char** argv) {
t_load = base::GetWallTimeNs() - t_load_start;
double t_load_s = static_cast<double>(t_load.count()) / 1E9;
- PERFETTO_ILOG("Trace loaded: %.2f MB (%.1f MB/s)", size_mb,
- size_mb / t_load_s);
+ PERFETTO_ILOG("Trace loaded: %.2f MB in %.2fs (%.1f MB/s)", size_mb,
+ t_load_s, size_mb / t_load_s);
RETURN_IF_ERROR(PrintStats());
}
@@ -1090,8 +1353,23 @@ util::Status TraceProcessorMain(int argc, char** argv) {
RETURN_IF_ERROR(RunQueries(options.pre_metrics_path, false));
}
+ // Descriptor pool used for printing output as textproto. Building on top of
+ // generated pool so default protos in google.protobuf.descriptor.proto are
+ // available.
+ // For some insane reason, the descriptor pool is not movable so we need to
+ // create it here so we can create references and pass it everywhere.
+ google::protobuf::DescriptorPool pool(
+ google::protobuf::DescriptorPool::generated_pool());
+ RETURN_IF_ERROR(PopulateDescriptorPool(pool, metric_extensions));
+
+ std::vector<MetricNameAndPath> metrics;
if (!options.metric_names.empty()) {
- RETURN_IF_ERROR(RunMetrics(options));
+ RETURN_IF_ERROR(LoadMetrics(options.metric_names, pool, metrics));
+ }
+
+ OutputFormat metric_format = ParseOutputFormat(options);
+ if (!metrics.empty()) {
+ RETURN_IF_ERROR(RunMetrics(metrics, metric_format, pool));
}
if (!options.query_file_path.empty()) {
@@ -1104,28 +1382,30 @@ util::Status TraceProcessorMain(int argc, char** argv) {
}
if (options.launch_shell) {
- RETURN_IF_ERROR(StartInteractiveShell(options.wide ? 40 : 20));
+ RETURN_IF_ERROR(StartInteractiveShell(
+ InteractiveOptions{options.wide ? 40u : 20u, metric_format,
+ metric_extensions, metrics, &pool}));
} else if (!options.perf_file_path.empty()) {
RETURN_IF_ERROR(PrintPerfFile(options.perf_file_path, t_load, t_query));
}
if (!options.metatrace_path.empty()) {
std::vector<uint8_t> serialized;
- util::Status status = g_tp->DisableAndReadMetatrace(&serialized);
+ base::Status status = g_tp->DisableAndReadMetatrace(&serialized);
if (!status.ok())
return status;
auto file =
base::OpenFile(options.metatrace_path, O_CREAT | O_RDWR | O_TRUNC);
if (!file)
- return util::ErrStatus("Unable to open metatrace file");
+ return base::ErrStatus("Unable to open metatrace file");
ssize_t res = base::WriteAll(*file, serialized.data(), serialized.size());
if (res < 0)
- return util::ErrStatus("Error while writing metatrace file");
+ return base::ErrStatus("Error while writing metatrace file");
}
- return util::OkStatus();
+ return base::OkStatus();
}
} // namespace
diff --git a/src/trace_processor/trace_processor_storage.cc b/src/trace_processor/trace_processor_storage.cc
index f72c2a6e1..36e657974 100644
--- a/src/trace_processor/trace_processor_storage.cc
+++ b/src/trace_processor/trace_processor_storage.cc
@@ -16,6 +16,7 @@
#include "perfetto/trace_processor/trace_processor_storage.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
#include "src/trace_processor/trace_processor_storage_impl.h"
namespace perfetto {
@@ -30,5 +31,10 @@ std::unique_ptr<TraceProcessorStorage> TraceProcessorStorage::CreateInstance(
TraceProcessorStorage::~TraceProcessorStorage() = default;
+util::Status TraceProcessorStorage::Parse(std::unique_ptr<uint8_t[]> buf,
+ size_t size) {
+ return Parse(TraceBlobView(TraceBlob::TakeOwnership(std::move(buf), size)));
+}
+
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/trace_processor_storage_impl.cc b/src/trace_processor/trace_processor_storage_impl.cc
index cca694705..79f96dd2b 100644
--- a/src/trace_processor/trace_processor_storage_impl.cc
+++ b/src/trace_processor/trace_processor_storage_impl.cc
@@ -17,15 +17,17 @@
#include "src/trace_processor/trace_processor_storage_impl.h"
#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/uuid.h"
#include "src/trace_processor/forwarding_trace_parser.h"
#include "src/trace_processor/importers/chrome_track_event.descriptor.h"
#include "src/trace_processor/importers/common/args_tracker.h"
+#include "src/trace_processor/importers/common/args_translation_table.h"
#include "src/trace_processor/importers/common/clock_tracker.h"
#include "src/trace_processor/importers/common/event_tracker.h"
#include "src/trace_processor/importers/common/flow_tracker.h"
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/importers/common/slice_tracker.h"
-#include "src/trace_processor/importers/common/trace_blob_view.h"
+#include "src/trace_processor/importers/common/slice_translation_table.h"
#include "src/trace_processor/importers/common/track_tracker.h"
#include "src/trace_processor/importers/default_modules.h"
#include "src/trace_processor/importers/proto/async_track_set_tracker.h"
@@ -49,7 +51,11 @@ TraceProcessorStorageImpl::TraceProcessorStorageImpl(const Config& cfg) {
context_.track_tracker.reset(new TrackTracker(&context_));
context_.async_track_set_tracker.reset(new AsyncTrackSetTracker(&context_));
context_.args_tracker.reset(new ArgsTracker(&context_));
+ context_.args_translation_table.reset(
+ new ArgsTranslationTable(context_.storage.get()));
context_.slice_tracker.reset(new SliceTracker(&context_));
+ context_.slice_translation_table.reset(
+ new SliceTranslationTable(context_.storage.get()));
context_.flow_tracker.reset(new FlowTracker(&context_));
context_.event_tracker.reset(new EventTracker(&context_));
context_.process_tracker.reset(new ProcessTracker(&context_));
@@ -82,9 +88,8 @@ TraceProcessorStorageImpl::TraceProcessorStorageImpl(const Config& cfg) {
TraceProcessorStorageImpl::~TraceProcessorStorageImpl() {}
-util::Status TraceProcessorStorageImpl::Parse(std::unique_ptr<uint8_t[]> data,
- size_t size) {
- if (size == 0)
+util::Status TraceProcessorStorageImpl::Parse(TraceBlobView blob) {
+ if (blob.size() == 0)
return util::OkStatus();
if (unrecoverable_parse_error_)
return util::ErrStatus(
@@ -94,7 +99,20 @@ util::Status TraceProcessorStorageImpl::Parse(std::unique_ptr<uint8_t[]> data,
auto scoped_trace = context_.storage->TraceExecutionTimeIntoStats(
stats::parse_trace_duration_ns);
- util::Status status = context_.chunk_reader->Parse(std::move(data), size);
+
+ if (hash_input_size_remaining_ > 0 && !context_.uuid_found_in_trace) {
+ const size_t hash_size = std::min(hash_input_size_remaining_, blob.size());
+ hash_input_size_remaining_ -= hash_size;
+
+ trace_hash_.Update(reinterpret_cast<const char*>(blob.data()), hash_size);
+ base::Uuid uuid(static_cast<int64_t>(trace_hash_.digest()), 0);
+ const StringId id_for_uuid =
+ context_.storage->InternString(base::StringView(uuid.ToPrettyString()));
+ context_.metadata_tracker->SetMetadata(metadata::trace_uuid,
+ Variadic::String(id_for_uuid));
+ }
+
+ util::Status status = context_.chunk_reader->Parse(std::move(blob));
unrecoverable_parse_error_ |= !status.ok();
return status;
}
diff --git a/src/trace_processor/trace_processor_storage_impl.h b/src/trace_processor/trace_processor_storage_impl.h
index 1c029c6f9..901256bfc 100644
--- a/src/trace_processor/trace_processor_storage_impl.h
+++ b/src/trace_processor/trace_processor_storage_impl.h
@@ -19,6 +19,7 @@
#include <memory>
+#include "perfetto/ext/base/hash.h"
#include "perfetto/trace_processor/basic_types.h"
#include "perfetto/trace_processor/status.h"
#include "perfetto/trace_processor/trace_processor_storage.h"
@@ -32,14 +33,16 @@ class TraceProcessorStorageImpl : public TraceProcessorStorage {
explicit TraceProcessorStorageImpl(const Config&);
~TraceProcessorStorageImpl() override;
- util::Status Parse(std::unique_ptr<uint8_t[]>, size_t) override;
+ util::Status Parse(TraceBlobView) override;
void NotifyEndOfFile() override;
TraceProcessorContext* context() { return &context_; }
protected:
+ base::Hash trace_hash_;
TraceProcessorContext context_;
bool unrecoverable_parse_error_ = false;
+ size_t hash_input_size_remaining_ = 4096;
};
} // namespace trace_processor
diff --git a/src/trace_processor/trace_sorter.cc b/src/trace_processor/trace_sorter.cc
index 677d31ae3..766508f48 100644
--- a/src/trace_processor/trace_sorter.cc
+++ b/src/trace_processor/trace_sorter.cc
@@ -24,9 +24,12 @@
namespace perfetto {
namespace trace_processor {
-TraceSorter::TraceSorter(std::unique_ptr<TraceParser> parser,
- int64_t window_size_ns)
- : parser_(std::move(parser)), window_size_ns_(window_size_ns) {
+TraceSorter::TraceSorter(TraceProcessorContext* context,
+ std::unique_ptr<TraceParser> parser,
+ SortingMode sorting_mode)
+ : context_(context),
+ parser_(std::move(parser)),
+ sorting_mode_(sorting_mode) {
const char* env = getenv("TRACE_PROCESSOR_SORT_ONLY");
bypass_next_stage_for_testing_ = env && !strcmp(env, "1");
if (bypass_next_stage_for_testing_)
@@ -56,10 +59,10 @@ void TraceSorter::Queue::Sort() {
PERFETTO_DCHECK(std::is_sorted(events_.begin(), events_.end()));
}
-// Removes all the events in |queues_| that are earlier than the given window
-// size and moves them to the next parser stages, respecting global timestamp
-// order. This function is a "extract min from N sorted queues", with some
-// little cleverness: we know that events tend to be bursty, so events are
+// Removes all the events in |queues_| that are earlier than the given
+// packet index and moves them to the next parser stages, respecting global
+// timestamp order. This function is a "extract min from N sorted queues", with
+// some little cleverness: we know that events tend to be bursty, so events are
// not going to be randomly distributed on the N |queues_|.
// Upon each iteration this function finds the first two queues (if any) that
// have the oldest events, and extracts events from the 1st until hitting the
@@ -76,14 +79,9 @@ void TraceSorter::Queue::Sort() {
// to avoid re-scanning all the queues all the times) but doesn't seem worth it.
// With Android traces (that have 8 CPUs) this function accounts for ~1-3% cpu
// time in a profiler.
-void TraceSorter::SortAndExtractEventsBeyondWindow(int64_t window_size_ns) {
- DCHECK_ftrace_batch_cpu(kNoBatch);
-
+void TraceSorter::SortAndExtractEventsUntilPacket(uint64_t limit_packet_idx) {
constexpr int64_t kTsMax = std::numeric_limits<int64_t>::max();
- const bool was_empty = global_min_ts_ == kTsMax && global_max_ts_ == 0;
- int64_t extract_end_ts = global_max_ts_ - window_size_ns;
- size_t iterations = 0;
- for (;; iterations++) {
+ for (;;) {
size_t min_queue_idx = 0; // The index of the queue with the min(ts).
// The top-2 min(ts) among all queues.
@@ -122,27 +120,17 @@ void TraceSorter::SortAndExtractEventsBeyondWindow(int64_t window_size_ns) {
PERFETTO_DCHECK(queue.min_ts_ == global_min_ts_);
// Now that we identified the min-queue, extract all events from it until
- // we hit either: (1) the min-ts of the 2nd queue or (2) the window limit,
- // whichever comes first.
- int64_t extract_until_ts = std::min(extract_end_ts, min_queue_ts[1]);
+ // we hit either: (1) the min-ts of the 2nd queue or (2) the packet index
+ // limit, whichever comes first.
size_t num_extracted = 0;
for (auto& event : events) {
- int64_t timestamp = event.timestamp;
- if (timestamp > extract_until_ts)
+ if (event.packet_idx >= limit_packet_idx ||
+ event.timestamp > min_queue_ts[1]) {
break;
+ }
++num_extracted;
- if (bypass_next_stage_for_testing_)
- continue;
-
- if (min_queue_idx == 0) {
- // queues_[0] is for non-ftrace packets.
- parser_->ParseTracePacket(timestamp, std::move(event));
- } else {
- // Ftrace queues start at offset 1. So queues_[1] = cpu[0] and so on.
- uint32_t cpu = static_cast<uint32_t>(min_queue_idx - 1);
- parser_->ParseFtracePacket(cpu, timestamp, std::move(event));
- }
+ MaybePushEvent(min_queue_idx, std::move(event));
} // for (event: events)
if (!num_extracted) {
@@ -173,12 +161,6 @@ void TraceSorter::SortAndExtractEventsBeyondWindow(int64_t window_size_ns) {
}
} // for(;;)
- // We decide to extract events only when we know (using the global_{min,max}
- // bounds) that there are eligible events. We should never end up in a
- // situation where we call this function but then realize that there was
- // nothing to extract.
- PERFETTO_DCHECK(iterations > 0 || was_empty);
-
#if PERFETTO_DCHECK_IS_ON()
// Check that the global min/max are consistent.
int64_t dbg_min_ts = kTsMax;
@@ -192,5 +174,25 @@ void TraceSorter::SortAndExtractEventsBeyondWindow(int64_t window_size_ns) {
#endif
}
+void TraceSorter::MaybePushEvent(size_t queue_idx, TimestampedTracePiece ttp) {
+ int64_t timestamp = ttp.timestamp;
+ if (timestamp < latest_pushed_event_ts_)
+ context_->storage->IncrementStats(stats::sorter_push_event_out_of_order);
+
+ latest_pushed_event_ts_ = std::max(latest_pushed_event_ts_, timestamp);
+
+ if (PERFETTO_UNLIKELY(bypass_next_stage_for_testing_))
+ return;
+
+ if (queue_idx == 0) {
+ // queues_[0] is for non-ftrace packets.
+ parser_->ParseTracePacket(timestamp, std::move(ttp));
+ } else {
+ // Ftrace queues start at offset 1. So queues_[1] = cpu[0] and so on.
+ uint32_t cpu = static_cast<uint32_t>(queue_idx - 1);
+ parser_->ParseFtracePacket(cpu, timestamp, std::move(ttp));
+ }
+}
+
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/trace_sorter.h b/src/trace_processor/trace_sorter.h
index 614d62730..7df33a631 100644
--- a/src/trace_processor/trace_sorter.h
+++ b/src/trace_processor/trace_sorter.h
@@ -17,43 +17,59 @@
#ifndef SRC_TRACE_PROCESSOR_TRACE_SORTER_H_
#define SRC_TRACE_PROCESSOR_TRACE_SORTER_H_
+#include <algorithm>
+#include <memory>
+#include <utility>
#include <vector>
#include "perfetto/ext/base/circular_queue.h"
#include "perfetto/trace_processor/basic_types.h"
-#include "src/trace_processor/importers/common/trace_blob_view.h"
-#include "src/trace_processor/storage/trace_storage.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
#include "src/trace_processor/timestamped_trace_piece.h"
-namespace Json {
-class Value;
-} // namespace Json
-
namespace perfetto {
namespace trace_processor {
-class FuchsiaProviderView;
class PacketSequenceState;
struct SystraceLine;
// This class takes care of sorting events parsed from the trace stream in
// arbitrary order and pushing them to the next pipeline stages (parsing) in
// order. In order to support streaming use-cases, sorting happens within a
-// max window. Events are held in the TraceSorter staging area (events_) until
-// either (1) the (max - min) timestamp > window_size; (2) trace EOF.
+// window.
+//
+// Events are held in the TraceSorter staging area (events_) until either:
+// 1. We can determine that it's safe to extract events by observing
+// TracingServiceEvent Flush and ReadBuffer events
+// 2. The trace EOF is reached
+//
+// Incremental extraction
+//
+// Incremental extraction happens by using a combination of flush and read
+// buffer events from the tracing service. Note that incremental extraction
+// is only applicable for write_into_file traces; ring-buffer traces will
+// be sorted fully in-memory implicitly because there is only a single read
+// buffer call at the end.
+//
+// The algorithm for incremental extraction is explained in detail at
+// go/trace-sorting-is-complicated.
+//
+// Sorting algorithm
//
-// This class is designed around the assumption that:
+// The sorting algorithm is designed around the assumption that:
// - Most events come from ftrace.
// - Ftrace events are sorted within each cpu most of the times.
//
// Due to this, this class is oprerates as a streaming merge-sort of N+1 queues
// (N = num cpus + 1 for non-ftrace events). Each queue in turn gets sorted (if
// necessary) before proceeding with the global merge-sort-extract.
-// When an event is pushed through, it is just appeneded to the end of one of
+//
+// When an event is pushed through, it is just appended to the end of one of
// the N queues. While appending, we keep track of the fact that the queue
// is still ordered or just lost ordering. When an out-of-order event is
// detected on a queue we keep track of: (1) the offset within the queue where
// the chaos begun, (2) the timestamp that broke the ordering.
+//
// When we decide to extract events from the queues into the next stages of
// the trace processor, we re-sort the events in the queue. Rather than
// re-sorting everything all the times, we use the above knowledge to restrict
@@ -65,116 +81,98 @@ struct SystraceLine;
// from there to the end.
class TraceSorter {
public:
- TraceSorter(std::unique_ptr<TraceParser> parser, int64_t window_size_ns);
+ enum class SortingMode {
+ kDefault,
+ kFullSort,
+ };
+
+ TraceSorter(TraceProcessorContext* context,
+ std::unique_ptr<TraceParser> parser,
+ SortingMode);
inline void PushTracePacket(int64_t timestamp,
PacketSequenceState* state,
TraceBlobView packet) {
- DCHECK_ftrace_batch_cpu(kNoBatch);
- auto* queue = GetQueue(0);
- queue->Append(TimestampedTracePiece(timestamp, packet_idx_++,
- std::move(packet),
- state->current_generation()));
- MaybeExtractEvents(queue);
+ AppendNonFtraceEvent(TimestampedTracePiece(timestamp, packet_idx_++,
+ std::move(packet),
+ state->current_generation()));
}
inline void PushJsonValue(int64_t timestamp, std::string json_value) {
- auto* queue = GetQueue(0);
- queue->Append(
+ AppendNonFtraceEvent(
TimestampedTracePiece(timestamp, packet_idx_++, std::move(json_value)));
- MaybeExtractEvents(queue);
}
inline void PushFuchsiaRecord(int64_t timestamp,
std::unique_ptr<FuchsiaRecord> record) {
- DCHECK_ftrace_batch_cpu(kNoBatch);
- auto* queue = GetQueue(0);
- queue->Append(
+ AppendNonFtraceEvent(
TimestampedTracePiece(timestamp, packet_idx_++, std::move(record)));
- MaybeExtractEvents(queue);
}
inline void PushSystraceLine(std::unique_ptr<SystraceLine> systrace_line) {
- DCHECK_ftrace_batch_cpu(kNoBatch);
- auto* queue = GetQueue(0);
int64_t timestamp = systrace_line->ts;
- queue->Append(TimestampedTracePiece(timestamp, packet_idx_++,
- std::move(systrace_line)));
- MaybeExtractEvents(queue);
+ AppendNonFtraceEvent(TimestampedTracePiece(timestamp, packet_idx_++,
+ std::move(systrace_line)));
+ }
+
+ inline void PushTrackEventPacket(int64_t timestamp,
+ std::unique_ptr<TrackEventData> data) {
+ AppendNonFtraceEvent(
+ TimestampedTracePiece(timestamp, packet_idx_++, std::move(data)));
}
inline void PushFtraceEvent(uint32_t cpu,
int64_t timestamp,
TraceBlobView event,
PacketSequenceState* state) {
- set_ftrace_batch_cpu_for_DCHECK(cpu);
- GetQueue(cpu + 1)->Append(TimestampedTracePiece(
+ auto* queue = GetQueue(cpu + 1);
+ queue->Append(TimestampedTracePiece(
timestamp, packet_idx_++,
FtraceEventData{std::move(event), state->current_generation()}));
-
- // The caller must call FinalizeFtraceEventBatch() after having pushed a
- // batch of ftrace events. This is to amortize the overhead of handling
- // global ordering and doing that in batches only after all ftrace events
- // for a bundle are pushed.
+ UpdateGlobalTs(queue);
}
-
- // As with |PushFtraceEvent|, doesn't immediately sort the affected queues.
- // TODO(rsavitski): if a trace has a mix of normal & "compact" events (being
- // pushed through this function), the ftrace batches will no longer be fully
- // sorted by timestamp. In such situations, we will have to sort at the end of
- // the batch. We can do better as both sub-sequences are sorted however.
- // Consider adding extra queues, or pushing them in a merge-sort fashion
- // instead.
inline void PushInlineFtraceEvent(uint32_t cpu,
int64_t timestamp,
InlineSchedSwitch inline_sched_switch) {
- set_ftrace_batch_cpu_for_DCHECK(cpu);
- GetQueue(cpu + 1)->Append(
+ // TODO(rsavitski): if a trace has a mix of normal & "compact" events (being
+ // pushed through this function), the ftrace batches will no longer be fully
+ // sorted by timestamp. In such situations, we will have to sort at the end
+ // of the batch. We can do better as both sub-sequences are sorted however.
+ // Consider adding extra queues, or pushing them in a merge-sort fashion
+ // instead.
+ auto* queue = GetQueue(cpu + 1);
+ queue->Append(
TimestampedTracePiece(timestamp, packet_idx_++, inline_sched_switch));
+ UpdateGlobalTs(queue);
}
inline void PushInlineFtraceEvent(uint32_t cpu,
int64_t timestamp,
InlineSchedWaking inline_sched_waking) {
- set_ftrace_batch_cpu_for_DCHECK(cpu);
- GetQueue(cpu + 1)->Append(
- TimestampedTracePiece(timestamp, packet_idx_++, inline_sched_waking));
- }
-
- inline void PushTrackEventPacket(int64_t timestamp,
- std::unique_ptr<TrackEventData> data) {
- auto* queue = GetQueue(0);
+ auto* queue = GetQueue(cpu + 1);
queue->Append(
- TimestampedTracePiece(timestamp, packet_idx_++, std::move(data)));
- MaybeExtractEvents(queue);
- }
-
- inline void FinalizeFtraceEventBatch(uint32_t cpu) {
- DCHECK_ftrace_batch_cpu(cpu);
- set_ftrace_batch_cpu_for_DCHECK(kNoBatch);
- MaybeExtractEvents(GetQueue(cpu + 1));
+ TimestampedTracePiece(timestamp, packet_idx_++, inline_sched_waking));
+ UpdateGlobalTs(queue);
}
- // Extract all events ignoring the window.
void ExtractEventsForced() {
- SortAndExtractEventsBeyondWindow(/*window_size_ns=*/0);
+ SortAndExtractEventsUntilPacket(packet_idx_);
queues_.resize(0);
- }
- // Sets the window size to be the size specified (which should be lower than
- // any previous window size specified) and flushes any data beyond
- // this window size.
- // It is undefined to call this function with a window size greater than than
- // the current size.
- void SetWindowSizeNs(int64_t window_size_ns) {
- PERFETTO_DCHECK(window_size_ns <= window_size_ns_);
+ packet_idx_for_extraction_ = packet_idx_;
+ flushes_since_extraction_ = 0;
+ }
- PERFETTO_DLOG("Setting window size to be %" PRId64 " ns", window_size_ns);
- window_size_ns_ = window_size_ns;
+ void NotifyFlushEvent() { flushes_since_extraction_++; }
- // Fast path: if, globally, we are within the window size, then just exit.
- if (global_max_ts_ - global_min_ts_ < window_size_ns)
+ void NotifyReadBufferEvent() {
+ if (sorting_mode_ == SortingMode::kFullSort ||
+ flushes_since_extraction_ < 2) {
return;
- SortAndExtractEventsBeyondWindow(window_size_ns_);
+ }
+
+ SortAndExtractEventsUntilPacket(packet_idx_for_extraction_);
+ packet_idx_for_extraction_ = packet_idx_;
+ flushes_since_extraction_ = 0;
}
int64_t max_timestamp() const { return global_max_ts_; }
@@ -219,9 +217,7 @@ class TraceSorter {
int64_t sort_min_ts_ = std::numeric_limits<int64_t>::max();
};
- // This method passes any events older than window_size_ns to the
- // parser to be parsed and then stored.
- void SortAndExtractEventsBeyondWindow(int64_t windows_size_ns);
+ void SortAndExtractEventsUntilPacket(uint64_t limit_packet_idx);
inline Queue* GetQueue(size_t index) {
if (PERFETTO_UNLIKELY(index >= queues_.size()))
@@ -229,28 +225,40 @@ class TraceSorter {
return &queues_[index];
}
- inline void MaybeExtractEvents(Queue* queue) {
- DCHECK_ftrace_batch_cpu(kNoBatch);
- global_max_ts_ = std::max(global_max_ts_, queue->max_ts_);
- global_min_ts_ = std::min(global_min_ts_, queue->min_ts_);
+ inline void AppendNonFtraceEvent(TimestampedTracePiece ttp) {
+ Queue* queue = GetQueue(0);
+ queue->Append(std::move(ttp));
+ UpdateGlobalTs(queue);
+ }
- // Fast path: if, globally, we are within the window size, then just exit.
- if (global_max_ts_ - global_min_ts_ < window_size_ns_)
- return;
- SortAndExtractEventsBeyondWindow(window_size_ns_);
+ inline void UpdateGlobalTs(Queue* queue) {
+ global_min_ts_ = std::min(global_min_ts_, queue->min_ts_);
+ global_max_ts_ = std::max(global_max_ts_, queue->max_ts_);
}
+ void MaybePushEvent(size_t queue_idx,
+ TimestampedTracePiece ttp) PERFETTO_ALWAYS_INLINE;
+
+ TraceProcessorContext* context_;
std::unique_ptr<TraceParser> parser_;
+ // Whether we should ignore incremental extraction and just wait for
+ // forced extractionn at the end of the trace.
+ SortingMode sorting_mode_ = SortingMode::kDefault;
+
+ // The packet index until which events should be extracted. Set based
+ // on the packet index in |OnReadBuffer|.
+ uint64_t packet_idx_for_extraction_ = 0;
+
+ // The number of flushes which have happened since the last incremental
+ // extraction.
+ uint32_t flushes_since_extraction_ = 0;
+
// queues_[0] is the general (non-ftrace) queue.
// queues_[1] is the ftrace queue for CPU(0).
// queues_[x] is the ftrace queue for CPU(x - 1).
std::vector<Queue> queues_;
- // Events are propagated to the next stage only after (max - min) timestamp
- // is larger than this value.
- int64_t window_size_ns_;
-
// max(e.timestamp for e in queues_).
int64_t global_max_ts_ = 0;
@@ -263,23 +271,8 @@ class TraceSorter {
// Used for performance tests. True when setting TRACE_PROCESSOR_SORT_ONLY=1.
bool bypass_next_stage_for_testing_ = false;
-#if PERFETTO_DCHECK_IS_ON()
- // Used only for DCHECK-ing that FinalizeFtraceEventBatch() is called.
- uint32_t ftrace_batch_cpu_ = kNoBatch;
-
- inline void DCHECK_ftrace_batch_cpu(uint32_t cpu) {
- PERFETTO_DCHECK(ftrace_batch_cpu_ == kNoBatch || ftrace_batch_cpu_ == cpu);
- }
-
- inline void set_ftrace_batch_cpu_for_DCHECK(uint32_t cpu) {
- PERFETTO_DCHECK(ftrace_batch_cpu_ == cpu || ftrace_batch_cpu_ == kNoBatch ||
- cpu == kNoBatch);
- ftrace_batch_cpu_ = cpu;
- }
-#else
- inline void DCHECK_ftrace_batch_cpu(uint32_t) {}
- inline void set_ftrace_batch_cpu_for_DCHECK(uint32_t) {}
-#endif
+ // max(e.ts for e pushed to next stage)
+ int64_t latest_pushed_event_ts_ = std::numeric_limits<int64_t>::min();
};
} // namespace trace_processor
diff --git a/src/trace_processor/trace_sorter_unittest.cc b/src/trace_processor/trace_sorter_unittest.cc
index b49f5152f..342cde938 100644
--- a/src/trace_processor/trace_sorter_unittest.cc
+++ b/src/trace_processor/trace_sorter_unittest.cc
@@ -20,6 +20,7 @@
#include <vector>
#include "perfetto/trace_processor/basic_types.h"
+#include "perfetto/trace_processor/trace_blob.h"
#include "src/trace_processor/timestamped_trace_piece.h"
#include "src/trace_processor/trace_sorter.h"
#include "src/trace_processor/types/trace_processor_context.h"
@@ -72,17 +73,19 @@ class MockTraceStorage : public TraceStorage {
class TraceSorterTest : public ::testing::Test {
public:
- TraceSorterTest()
- : test_buffer_(std::unique_ptr<uint8_t[]>(new uint8_t[8]), 0, 8) {
+ TraceSorterTest() : test_buffer_(TraceBlob::Allocate(8)) {
storage_ = new NiceMock<MockTraceStorage>();
context_.storage.reset(storage_);
+ CreateSorter();
+ }
+ void CreateSorter(bool full_sort = true) {
std::unique_ptr<MockTraceParser> parser(new MockTraceParser(&context_));
parser_ = parser.get();
-
+ auto sorting_mode = full_sort ? TraceSorter::SortingMode::kFullSort
+ : TraceSorter::SortingMode::kDefault;
context_.sorter.reset(
- new TraceSorter(std::move(parser),
- std::numeric_limits<int64_t>::max() /*window_size*/));
+ new TraceSorter(&context_, std::move(parser), sorting_mode));
}
protected:
@@ -94,29 +97,27 @@ class TraceSorterTest : public ::testing::Test {
TEST_F(TraceSorterTest, TestFtrace) {
PacketSequenceState state(&context_);
- TraceBlobView view = test_buffer_.slice(0, 1);
+ TraceBlobView view = test_buffer_.slice_off(0, 1);
EXPECT_CALL(*parser_, MOCK_ParseFtracePacket(0, 1000, view.data(), 1));
context_.sorter->PushFtraceEvent(0 /*cpu*/, 1000 /*timestamp*/,
std::move(view), &state);
- context_.sorter->FinalizeFtraceEventBatch(0);
context_.sorter->ExtractEventsForced();
}
TEST_F(TraceSorterTest, TestTracePacket) {
PacketSequenceState state(&context_);
- TraceBlobView view = test_buffer_.slice(0, 1);
+ TraceBlobView view = test_buffer_.slice_off(0, 1);
EXPECT_CALL(*parser_, MOCK_ParseTracePacket(1000, view.data(), 1));
context_.sorter->PushTracePacket(1000, &state, std::move(view));
- context_.sorter->FinalizeFtraceEventBatch(1000);
context_.sorter->ExtractEventsForced();
}
TEST_F(TraceSorterTest, Ordering) {
PacketSequenceState state(&context_);
- TraceBlobView view_1 = test_buffer_.slice(0, 1);
- TraceBlobView view_2 = test_buffer_.slice(0, 2);
- TraceBlobView view_3 = test_buffer_.slice(0, 3);
- TraceBlobView view_4 = test_buffer_.slice(0, 4);
+ TraceBlobView view_1 = test_buffer_.slice_off(0, 1);
+ TraceBlobView view_2 = test_buffer_.slice_off(0, 2);
+ TraceBlobView view_3 = test_buffer_.slice_off(0, 3);
+ TraceBlobView view_4 = test_buffer_.slice_off(0, 4);
InSequence s;
@@ -125,64 +126,134 @@ TEST_F(TraceSorterTest, Ordering) {
EXPECT_CALL(*parser_, MOCK_ParseTracePacket(1100, view_3.data(), 3));
EXPECT_CALL(*parser_, MOCK_ParseFtracePacket(2, 1200, view_4.data(), 4));
- context_.sorter->SetWindowSizeNs(200);
context_.sorter->PushFtraceEvent(2 /*cpu*/, 1200 /*timestamp*/,
std::move(view_4), &state);
- context_.sorter->FinalizeFtraceEventBatch(2);
context_.sorter->PushTracePacket(1001, &state, std::move(view_2));
context_.sorter->PushTracePacket(1100, &state, std::move(view_3));
context_.sorter->PushFtraceEvent(0 /*cpu*/, 1000 /*timestamp*/,
std::move(view_1), &state);
-
- context_.sorter->FinalizeFtraceEventBatch(0);
context_.sorter->ExtractEventsForced();
}
-TEST_F(TraceSorterTest, SetWindowSize) {
- PacketSequenceState state(&context_);
- TraceBlobView view_1 = test_buffer_.slice(0, 1);
- TraceBlobView view_2 = test_buffer_.slice(0, 2);
- TraceBlobView view_3 = test_buffer_.slice(0, 3);
- TraceBlobView view_4 = test_buffer_.slice(0, 4);
+TEST_F(TraceSorterTest, IncrementalExtraction) {
+ CreateSorter(false);
- MockFunction<void(std::string check_point_name)> check;
+ PacketSequenceState state(&context_);
+ TraceBlobView view_1 = test_buffer_.slice_off(0, 1);
+ TraceBlobView view_2 = test_buffer_.slice_off(0, 2);
+ TraceBlobView view_3 = test_buffer_.slice_off(0, 3);
+ TraceBlobView view_4 = test_buffer_.slice_off(0, 4);
+ TraceBlobView view_5 = test_buffer_.slice_off(0, 5);
+
+ // Flush at the start of packet sequence to match behavior of the
+ // service.
+ context_.sorter->NotifyFlushEvent();
+ context_.sorter->PushTracePacket(1200, &state, std::move(view_2));
+ context_.sorter->PushTracePacket(1100, &state, std::move(view_1));
+
+ // No data should be exttracted at this point because we haven't
+ // seen two flushes yet.
+ context_.sorter->NotifyReadBufferEvent();
+
+ // Now that we've seen two flushes, we should be ready to start extracting
+ // data on the next OnReadBufer call (after two flushes as usual).
+ context_.sorter->NotifyFlushEvent();
+ context_.sorter->NotifyReadBufferEvent();
+
+ context_.sorter->NotifyFlushEvent();
+ context_.sorter->NotifyFlushEvent();
+ context_.sorter->PushTracePacket(1400, &state, std::move(view_4));
+ context_.sorter->PushTracePacket(1300, &state, std::move(view_3));
+
+ // This ReadBuffer call should finally extract until the first OnReadBuffer
+ // call.
{
InSequence s;
-
- EXPECT_CALL(*parser_, MOCK_ParseFtracePacket(0, 1000, view_1.data(), 1));
- EXPECT_CALL(*parser_, MOCK_ParseTracePacket(1001, view_2.data(), 2));
- EXPECT_CALL(check, Call("1"));
- EXPECT_CALL(*parser_, MOCK_ParseTracePacket(1100, view_3.data(), 3));
- EXPECT_CALL(check, Call("2"));
- EXPECT_CALL(*parser_, MOCK_ParseFtracePacket(2, 1200, view_4.data(), 4));
+ EXPECT_CALL(*parser_, MOCK_ParseTracePacket(1100, test_buffer_.data(), 1));
+ EXPECT_CALL(*parser_, MOCK_ParseTracePacket(1200, test_buffer_.data(), 2));
}
+ context_.sorter->NotifyReadBufferEvent();
- context_.sorter->SetWindowSizeNs(200);
- context_.sorter->PushFtraceEvent(2 /*cpu*/, 1200 /*timestamp*/,
- std::move(view_4), &state);
- context_.sorter->FinalizeFtraceEventBatch(2);
- context_.sorter->PushTracePacket(1001, &state, std::move(view_2));
- context_.sorter->PushTracePacket(1100, &state, std::move(view_3));
+ context_.sorter->NotifyFlushEvent();
+ context_.sorter->PushTracePacket(1500, &state, std::move(view_5));
- context_.sorter->PushFtraceEvent(0 /*cpu*/, 1000 /*timestamp*/,
- std::move(view_1), &state);
- context_.sorter->FinalizeFtraceEventBatch(0);
+ // Nothing should be extracted as we haven't seen the second flush.
+ context_.sorter->NotifyReadBufferEvent();
- // At this point, we should just flush the 1000 and 1001 packets.
- context_.sorter->SetWindowSizeNs(101);
+ // Now we've seen the second flush we should extract the next two packets.
+ context_.sorter->NotifyFlushEvent();
+ {
+ InSequence s;
+ EXPECT_CALL(*parser_, MOCK_ParseTracePacket(1300, test_buffer_.data(), 3));
+ EXPECT_CALL(*parser_, MOCK_ParseTracePacket(1400, test_buffer_.data(), 4));
+ }
+ context_.sorter->NotifyReadBufferEvent();
+
+ // The forced extraction should get the last packet.
+ EXPECT_CALL(*parser_, MOCK_ParseTracePacket(1500, test_buffer_.data(), 5));
+ context_.sorter->ExtractEventsForced();
+}
- // Inform the mock about where we are.
- check.Call("1");
+// Simulate a producer bug where the third packet is emitted
+// out of order. Verify that we track the stats correctly.
+TEST_F(TraceSorterTest, OutOfOrder) {
+ CreateSorter(false);
- // Now we should flush the 1100 packet.
- context_.sorter->SetWindowSizeNs(99);
+ PacketSequenceState state(&context_);
+
+ TraceBlobView view_1 = test_buffer_.slice_off(0, 1);
+ TraceBlobView view_2 = test_buffer_.slice_off(0, 2);
+ TraceBlobView view_3 = test_buffer_.slice_off(0, 3);
+ TraceBlobView view_4 = test_buffer_.slice_off(0, 4);
- // Inform the mock about where we are.
- check.Call("2");
+ context_.sorter->NotifyFlushEvent();
+ context_.sorter->NotifyFlushEvent();
+ context_.sorter->PushTracePacket(1200, &state, std::move(view_2));
+ context_.sorter->PushTracePacket(1100, &state, std::move(view_1));
+ context_.sorter->NotifyReadBufferEvent();
- // Now we should flush the 1200 packet.
+ // Both of the packets should have been pushed through.
+ context_.sorter->NotifyFlushEvent();
+ context_.sorter->NotifyFlushEvent();
+ {
+ InSequence s;
+ EXPECT_CALL(*parser_, MOCK_ParseTracePacket(1100, test_buffer_.data(), 1));
+ EXPECT_CALL(*parser_, MOCK_ParseTracePacket(1200, test_buffer_.data(), 2));
+ }
+ context_.sorter->NotifyReadBufferEvent();
+
+ // Now, pass the third packet out of order.
+ context_.sorter->NotifyFlushEvent();
+ context_.sorter->NotifyFlushEvent();
+ context_.sorter->PushTracePacket(1150, &state, std::move(view_3));
+ context_.sorter->NotifyReadBufferEvent();
+
+ // The third packet should still be pushed through.
+ context_.sorter->NotifyFlushEvent();
+ context_.sorter->NotifyFlushEvent();
+ EXPECT_CALL(*parser_, MOCK_ParseTracePacket(1150, test_buffer_.data(), 3));
+ context_.sorter->NotifyReadBufferEvent();
+
+ // But we should also increment the stat that this was out of order.
+ ASSERT_EQ(
+ context_.storage->stats()[stats::sorter_push_event_out_of_order].value,
+ 1);
+
+ // Push the fourth packet also out of order but after third.
+ context_.sorter->NotifyFlushEvent();
+ context_.sorter->NotifyFlushEvent();
+ context_.sorter->PushTracePacket(1170, &state, std::move(view_4));
+ context_.sorter->NotifyReadBufferEvent();
+
+ // The fourt packet should still be pushed through.
+ EXPECT_CALL(*parser_, MOCK_ParseTracePacket(1170, test_buffer_.data(), 4));
context_.sorter->ExtractEventsForced();
+
+ // But we should also increment the stat that this was out of order.
+ ASSERT_EQ(
+ context_.storage->stats()[stats::sorter_push_event_out_of_order].value,
+ 2);
}
// Simulates a random stream of ftrace events happening on random CPUs.
@@ -217,9 +288,7 @@ TEST_F(TraceSorterTest, MultiQueueSorting) {
for (int j = 0; j < num_cpus; j++) {
uint32_t cpu = static_cast<uint32_t>(rnd_engine() % 32);
expectations[ts].push_back(cpu);
- context_.sorter->PushFtraceEvent(cpu, ts, TraceBlobView(nullptr, 0, 0),
- &state);
- context_.sorter->FinalizeFtraceEventBatch(cpu);
+ context_.sorter->PushFtraceEvent(cpu, ts, TraceBlobView(), &state);
}
}
diff --git a/src/trace_processor/types/BUILD.gn b/src/trace_processor/types/BUILD.gn
index 46d16b9c1..ba26e2424 100644
--- a/src/trace_processor/types/BUILD.gn
+++ b/src/trace_processor/types/BUILD.gn
@@ -21,6 +21,7 @@ source_set("types") {
"softirq_action.h",
"task_state.cc",
"task_state.h",
+ "tcp_state.h",
"trace_processor_context.h",
"variadic.cc",
"variadic.h",
diff --git a/src/trace_processor/types/tcp_state.h b/src/trace_processor/types/tcp_state.h
new file mode 100644
index 000000000..5ed58ef50
--- /dev/null
+++ b/src/trace_processor/types/tcp_state.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_TYPES_TCP_STATE_H_
+#define SRC_TRACE_PROCESSOR_TYPES_TCP_STATE_H_
+
+namespace perfetto {
+namespace trace_processor {
+
+// Sock IPV4 Protocol Definition, from include/uapi/linux/in.h.
+constexpr int kAfNet = 2;
+// Sock IPV6 Protocol Definition, from include/uapi/linux/in.h.
+constexpr int kAfNet6 = 10;
+// Sock TCP protocol Definition, from include/uapi/linux/in.h.
+constexpr int kIpprotoTcp = 6;
+// Skb IPV4 Protocol Definition, from include/uapi/linux/if_ether.h.
+constexpr int kEthPIp = 0x800;
+// Skb IPV6 Protocol Definition, from include/uapi/linux/if_ether.h.
+constexpr int kEthPIp6 = 0x86DD;
+// TCP protocol states, from include/net/tcp_states.h.
+enum {
+ TCP_ESTABLISHED = 1,
+ TCP_SYN_SENT,
+ TCP_SYN_RECV,
+ TCP_FIN_WAIT1,
+ TCP_FIN_WAIT2,
+ TCP_TIME_WAIT,
+ TCP_CLOSE,
+ TCP_CLOSE_WAIT,
+ TCP_LAST_ACK,
+ TCP_LISTEN,
+ TCP_CLOSING,
+ TCP_NEW_SYN_RECV,
+ TCP_MAX_STATES
+};
+// TCP protocol state to string mapping.
+static constexpr const char* const kTcpStateNames[] = {
+ "TCP_UNKNOWN", "TCP_ESTABLISHED", "TCP_SYN_SENT", "TCP_SYN_RECV",
+ "TCP_FIN_WAIT1", "TCP_FIN_WAIT2","TCP_TIME_WAIT", "TCP_CLOSE",
+ "TCP_CLOSE_WAIT","TCP_LAST_ACK", "TCP_LISTEN", "TCP_CLOSING",
+ "TCP_NEW_SYN_RECV","TCP_MAX_STATES"};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_TYPES_TCP_STATE_H_
diff --git a/src/trace_processor/types/trace_processor_context.h b/src/trace_processor/types/trace_processor_context.h
index b2c63ba55..7e34e1a35 100644
--- a/src/trace_processor/types/trace_processor_context.h
+++ b/src/trace_processor/types/trace_processor_context.h
@@ -27,6 +27,7 @@ namespace perfetto {
namespace trace_processor {
class ArgsTracker;
+class ArgsTranslationTable;
class AsyncTrackSetTracker;
class AndroidProbesTracker;
class ChunkedTraceReader;
@@ -43,12 +44,12 @@ class MetadataTracker;
class ProtoImporterModule;
class ProcessTracker;
class SliceTracker;
+class SliceTranslationTable;
class FlowTracker;
class TraceParser;
class TraceSorter;
class TraceStorage;
class TrackTracker;
-class JsonTracker;
class DescriptorPool;
class TraceProcessorContext {
@@ -68,10 +69,12 @@ class TraceProcessorContext {
// trackers, as they may own ArgsTrackers themselves.
std::unique_ptr<GlobalArgsTracker> global_args_tracker;
std::unique_ptr<ArgsTracker> args_tracker;
+ std::unique_ptr<ArgsTranslationTable> args_translation_table;
std::unique_ptr<TrackTracker> track_tracker;
std::unique_ptr<AsyncTrackSetTracker> async_track_set_tracker;
std::unique_ptr<SliceTracker> slice_tracker;
+ std::unique_ptr<SliceTranslationTable> slice_translation_table;
std::unique_ptr<FlowTracker> flow_tracker;
std::unique_ptr<ProcessTracker> process_tracker;
std::unique_ptr<EventTracker> event_tracker;
@@ -92,7 +95,6 @@ class TraceProcessorContext {
std::unique_ptr<Destructible> binder_tracker; // BinderTracker
std::unique_ptr<Destructible> systrace_parser; // SystraceParser
std::unique_ptr<Destructible> heap_graph_tracker; // HeapGraphTracker
- std::unique_ptr<Destructible> json_tracker; // JsonTracker
std::unique_ptr<Destructible> system_info_tracker; // SystemInfoTracker
// These fields are trace readers which will be called by |forwarding_parser|
@@ -118,6 +120,11 @@ class TraceProcessorContext {
std::vector<std::vector<ProtoImporterModule*>> modules_by_field;
std::vector<std::unique_ptr<ProtoImporterModule>> modules;
FtraceModule* ftrace_module = nullptr;
+
+ // Marks whether the uuid was read from the trace.
+ // If the uuid was NOT read, the uuid will be made from the hash of the first
+ // 4KB of the trace.
+ bool uuid_found_in_trace = false;
};
} // namespace trace_processor
diff --git a/src/trace_processor/types/variadic.h b/src/trace_processor/types/variadic.h
index 7a929e5f1..8cf7cac06 100644
--- a/src/trace_processor/types/variadic.h
+++ b/src/trace_processor/types/variadic.h
@@ -32,11 +32,12 @@ struct Variadic {
kPointer,
kBool,
kJson,
- kMaxType = kJson,
+ kNull,
+ kMaxType = kNull,
};
static constexpr const char* const kTypeNames[] = {
- "int", "uint", "string", "real", "pointer", "bool", "json"};
+ "int", "uint", "string", "real", "pointer", "bool", "json", "null"};
static Variadic Integer(int64_t int_value) {
Variadic variadic;
@@ -95,6 +96,12 @@ struct Variadic {
return variadic;
}
+ static Variadic Null() {
+ Variadic variadic;
+ variadic.type = Type::kNull;
+ return variadic;
+ }
+
// Used in tests.
bool operator==(const Variadic& other) const {
if (type == other.type) {
@@ -113,6 +120,8 @@ struct Variadic {
return bool_value == other.bool_value;
case kJson:
return json_value == other.json_value;
+ case kNull:
+ return true;
}
}
return false;
diff --git a/src/trace_processor/util/BUILD.gn b/src/trace_processor/util/BUILD.gn
index 02887ac40..07c8d7613 100644
--- a/src/trace_processor/util/BUILD.gn
+++ b/src/trace_processor/util/BUILD.gn
@@ -29,6 +29,22 @@ source_set("util") {
]
}
+source_set("gzip") {
+ sources = [
+ "gzip_utils.cc",
+ "gzip_utils.h",
+ ]
+ deps = [
+ "../../../gn:default_deps",
+ "../../../include/perfetto/base",
+ ]
+
+ # gzip_utils optionally depends on zlib.
+ if (enable_perfetto_zlib) {
+ deps += [ "../../../gn:zlib" ]
+ }
+}
+
source_set("protozero_to_text") {
sources = [
"protozero_to_text.cc",
@@ -45,6 +61,15 @@ source_set("protozero_to_text") {
]
}
+source_set("interned_message_view") {
+ sources = [ "interned_message_view.h" ]
+ public_deps = [ "../../../include/perfetto/trace_processor" ]
+ deps = [
+ "../../../gn:default_deps",
+ "../../base",
+ ]
+}
+
source_set("descriptors") {
sources = [
"descriptors.cc",
@@ -55,14 +80,16 @@ source_set("descriptors") {
"../../../gn:default_deps",
"../../../protos/perfetto/common:zero",
"../../../protos/perfetto/trace_processor:zero",
+ "../../base",
"../../protozero",
"../importers:gen_cc_track_event_descriptor",
]
- public_deps = [ "../../base" ]
}
source_set("proto_to_args_parser") {
sources = [
+ "debug_annotation_parser.cc",
+ "debug_annotation_parser.h",
"proto_to_args_parser.cc",
"proto_to_args_parser.h",
]
@@ -70,6 +97,7 @@ source_set("proto_to_args_parser") {
"../../../gn:default_deps",
"../../../protos/perfetto/common:zero",
"../../../protos/perfetto/trace/interned_data:zero",
+ "../../../protos/perfetto/trace/track_event:zero",
"../../../protos/perfetto/trace_processor:zero",
"../../protozero",
"../importers:gen_cc_track_event_descriptor",
@@ -77,36 +105,35 @@ source_set("proto_to_args_parser") {
public_deps = [
":descriptors",
+ ":interned_message_view",
":util",
"../../base",
-
- # TODO(altimin): Move InternedMessageView and TraceBlobView here and remove
- # this dependency.
- "../importers/common",
]
}
source_set("unittests") {
sources = [
+ "debug_annotation_parser_unittest.cc",
"proto_to_args_parser_unittest.cc",
"protozero_to_text_unittests.cc",
]
+ if (enable_perfetto_zlib) {
+ sources += [ "gzip_utils_unittest.cc" ]
+ }
testonly = true
deps = [
":descriptors",
+ ":gzip",
":proto_to_args_parser",
":protozero_to_text",
"..:gen_cc_test_messages_descriptor",
"../../../gn:default_deps",
"../../../gn:gtest_and_gmock",
"../../../protos/perfetto/common:zero",
+ "../../../protos/perfetto/trace:non_minimal_zero",
"../../../protos/perfetto/trace/track_event:zero",
"../../protozero",
"../../protozero:testing_messages_zero",
"../importers:gen_cc_track_event_descriptor",
-
- # TODO(altimin): Move InternedMessageView and TraceBlobView here and remove
- # this dependency.
- "..:storage_minimal",
]
}
diff --git a/src/trace_processor/util/debug_annotation_parser.cc b/src/trace_processor/util/debug_annotation_parser.cc
new file mode 100644
index 000000000..7b49d2ddc
--- /dev/null
+++ b/src/trace_processor/util/debug_annotation_parser.cc
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/util/debug_annotation_parser.h"
+#include "perfetto/base/build_config.h"
+#include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
+#include "src/trace_processor/util/interned_message_view.h"
+
+namespace perfetto {
+namespace trace_processor {
+namespace util {
+
+namespace {
+
+std::string SanitizeDebugAnnotationName(const std::string& raw_name) {
+ std::string result = raw_name;
+ std::replace(result.begin(), result.end(), '.', '_');
+ std::replace(result.begin(), result.end(), '[', '_');
+ std::replace(result.begin(), result.end(), ']', '_');
+ return result;
+}
+
+bool IsJsonSupported() {
+#if PERFETTO_BUILDFLAG(PERFETTO_TP_JSON)
+ return true;
+#else
+ return false;
+#endif
+}
+
+} // namespace
+
+DebugAnnotationParser::DebugAnnotationParser(ProtoToArgsParser& parser)
+ : proto_to_args_parser_(parser) {}
+
+base::Status DebugAnnotationParser::ParseDebugAnnotationName(
+ protos::pbzero::DebugAnnotation::Decoder& annotation,
+ ProtoToArgsParser::Delegate& delegate,
+ std::string& result) {
+ uint64_t name_iid = annotation.name_iid();
+ if (PERFETTO_LIKELY(name_iid)) {
+ auto* decoder = delegate.GetInternedMessage(
+ protos::pbzero::InternedData::kDebugAnnotationNames, name_iid);
+ if (!decoder)
+ return base::ErrStatus("Debug annotation with invalid name_iid");
+
+ result = SanitizeDebugAnnotationName(decoder->name().ToStdString());
+ } else if (annotation.has_name()) {
+ result = SanitizeDebugAnnotationName(annotation.name().ToStdString());
+ } else {
+ return base::ErrStatus("Debug annotation without name");
+ }
+ return base::OkStatus();
+}
+
+DebugAnnotationParser::ParseResult
+DebugAnnotationParser::ParseDebugAnnotationValue(
+ protos::pbzero::DebugAnnotation::Decoder& annotation,
+ ProtoToArgsParser::Delegate& delegate,
+ const ProtoToArgsParser::Key& context_name) {
+ if (annotation.has_bool_value()) {
+ delegate.AddBoolean(context_name, annotation.bool_value());
+ } else if (annotation.has_uint_value()) {
+ delegate.AddUnsignedInteger(context_name, annotation.uint_value());
+ } else if (annotation.has_int_value()) {
+ delegate.AddInteger(context_name, annotation.int_value());
+ } else if (annotation.has_double_value()) {
+ delegate.AddDouble(context_name, annotation.double_value());
+ } else if (annotation.has_string_value()) {
+ delegate.AddString(context_name, annotation.string_value());
+ } else if (annotation.has_pointer_value()) {
+ delegate.AddPointer(context_name, reinterpret_cast<const void*>(
+ annotation.pointer_value()));
+ } else if (annotation.has_dict_entries()) {
+ bool added_entry = false;
+ for (auto it = annotation.dict_entries(); it; ++it) {
+ protos::pbzero::DebugAnnotation::Decoder key_value(*it);
+ std::string key;
+ base::Status key_parse_result =
+ ParseDebugAnnotationName(key_value, delegate, key);
+ if (!key_parse_result.ok())
+ return {key_parse_result, added_entry};
+
+ auto nested_key = proto_to_args_parser_.EnterDictionary(key);
+ ParseResult value_parse_result =
+ ParseDebugAnnotationValue(key_value, delegate, nested_key.key());
+ added_entry |= value_parse_result.added_entry;
+ if (!value_parse_result.status.ok())
+ return {value_parse_result.status, added_entry};
+ }
+ } else if (annotation.has_array_values()) {
+ size_t index = delegate.GetArrayEntryIndex(context_name.key);
+ bool added_entry = false;
+ for (auto it = annotation.array_values(); it; ++it) {
+ std::string array_key = context_name.key;
+ protos::pbzero::DebugAnnotation::Decoder value(*it);
+
+ auto nested_key = proto_to_args_parser_.EnterArray(index);
+ ParseResult value_parse_result =
+ ParseDebugAnnotationValue(value, delegate, nested_key.key());
+
+ if (value_parse_result.added_entry) {
+ index = delegate.IncrementArrayEntryIndex(array_key);
+ added_entry = true;
+ }
+ if (!value_parse_result.status.ok())
+ return {value_parse_result.status, added_entry};
+ }
+ } else if (annotation.has_legacy_json_value()) {
+ if (!IsJsonSupported())
+ return {base::ErrStatus("Ignoring legacy_json_value (no json support)"),
+ false};
+
+ bool added_entry =
+ delegate.AddJson(context_name, annotation.legacy_json_value());
+ return {base::OkStatus(), added_entry};
+ } else if (annotation.has_nested_value()) {
+ return ParseNestedValueArgs(annotation.nested_value(), context_name,
+ delegate);
+ } else if (annotation.has_proto_value()) {
+ std::string type_name;
+ if (annotation.has_proto_type_name()) {
+ type_name = annotation.proto_type_name().ToStdString();
+ } else if (annotation.has_proto_type_name_iid()) {
+ auto* interned_name = delegate.GetInternedMessage(
+ protos::pbzero::InternedData::kDebugAnnotationValueTypeNames,
+ annotation.proto_type_name_iid());
+ if (!interned_name)
+ return {base::ErrStatus("Interned proto type name not found"), false};
+ type_name = interned_name->name().ToStdString();
+ } else {
+ return {base::ErrStatus("DebugAnnotation has proto_value, but doesn't "
+ "have proto type name"),
+ false};
+ }
+ return {proto_to_args_parser_.ParseMessage(annotation.proto_value(),
+ type_name, nullptr, delegate),
+ true};
+ } else {
+ return {base::OkStatus(), /*added_entry=*/false};
+ }
+
+ return {base::OkStatus(), /*added_entry=*/true};
+}
+
+// static
+base::Status DebugAnnotationParser::Parse(
+ protozero::ConstBytes data,
+ ProtoToArgsParser::Delegate& delegate) {
+ protos::pbzero::DebugAnnotation::Decoder annotation(data);
+
+ std::string name;
+ base::Status name_parse_result =
+ ParseDebugAnnotationName(annotation, delegate, name);
+ if (!name_parse_result.ok())
+ return name_parse_result;
+
+ auto context = proto_to_args_parser_.EnterDictionary(name);
+
+ return ParseDebugAnnotationValue(annotation, delegate, context.key()).status;
+}
+
+DebugAnnotationParser::ParseResult DebugAnnotationParser::ParseNestedValueArgs(
+ protozero::ConstBytes nested_value,
+ const ProtoToArgsParser::Key& context_name,
+ ProtoToArgsParser::Delegate& delegate) {
+ protos::pbzero::DebugAnnotation::NestedValue::Decoder value(nested_value);
+ switch (value.nested_type()) {
+ case protos::pbzero::DebugAnnotation::NestedValue::UNSPECIFIED: {
+ // Leaf value.
+ if (value.has_bool_value()) {
+ delegate.AddBoolean(context_name, value.bool_value());
+ return {base::OkStatus(), true};
+ }
+ if (value.has_int_value()) {
+ delegate.AddInteger(context_name, value.int_value());
+ return {base::OkStatus(), true};
+ }
+ if (value.has_double_value()) {
+ delegate.AddDouble(context_name, value.double_value());
+ return {base::OkStatus(), true};
+ }
+ if (value.has_string_value()) {
+ delegate.AddString(context_name, value.string_value());
+ return {base::OkStatus(), true};
+ }
+ return {base::OkStatus(), false};
+ }
+ case protos::pbzero::DebugAnnotation::NestedValue::DICT: {
+ bool added_entry = false;
+ auto key_it = value.dict_keys();
+ auto value_it = value.dict_values();
+ for (; key_it && value_it; ++key_it, ++value_it) {
+ std::string child_name =
+ SanitizeDebugAnnotationName((*key_it).ToStdString());
+ auto nested_key = proto_to_args_parser_.EnterDictionary(child_name);
+ ParseResult result =
+ ParseNestedValueArgs(*value_it, nested_key.key(), delegate);
+ added_entry |= result.added_entry;
+ if (!result.status.ok())
+ return {result.status, added_entry};
+ }
+ return {base::OkStatus(), true};
+ }
+
+ case protos::pbzero::DebugAnnotation::NestedValue::ARRAY: {
+ std::string array_key = context_name.key;
+ size_t array_index = delegate.GetArrayEntryIndex(context_name.key);
+ bool added_entry = false;
+
+ for (auto value_it = value.array_values(); value_it; ++value_it) {
+ auto nested_key = proto_to_args_parser_.EnterArray(array_index);
+ ParseResult result =
+ ParseNestedValueArgs(*value_it, nested_key.key(), delegate);
+
+ if (result.added_entry) {
+ ++array_index;
+ delegate.IncrementArrayEntryIndex(array_key);
+ added_entry = true;
+ }
+ if (!result.status.ok())
+ return {result.status, added_entry};
+ }
+ return {base::OkStatus(), added_entry};
+ }
+ }
+ return {base::OkStatus(), false};
+}
+
+} // namespace util
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/util/debug_annotation_parser.h b/src/trace_processor/util/debug_annotation_parser.h
new file mode 100644
index 000000000..0e68eec63
--- /dev/null
+++ b/src/trace_processor/util/debug_annotation_parser.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_UTIL_DEBUG_ANNOTATION_PARSER_H_
+#define SRC_TRACE_PROCESSOR_UTIL_DEBUG_ANNOTATION_PARSER_H_
+
+#include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
+#include "src/trace_processor/util/proto_to_args_parser.h"
+
+namespace perfetto {
+namespace trace_processor {
+namespace util {
+
+// |DebugAnnotationParser| is responsible for parsing DebugAnnotation protos
+// and turning it into key-value arg pairs.
+// |DebugAnnotationParser| is a logical extension of |ProtoToArgsParser|:
+// it uses |ProtoToArgsParser::Delegate| for writing the results and uses
+// |ProtoToArgsParser| to parse arbitrary protos nested inside DebugAnnotation.
+class DebugAnnotationParser {
+ public:
+ explicit DebugAnnotationParser(ProtoToArgsParser& proto_to_args_parser);
+
+ base::Status Parse(protozero::ConstBytes data,
+ ProtoToArgsParser::Delegate& delegate);
+
+ private:
+ struct ParseResult {
+ base::Status status;
+ // True if parsing of the annotation added at least one entry to the
+ // |delegate|.
+ bool added_entry;
+ };
+
+ base::Status ParseDebugAnnotationName(
+ protos::pbzero::DebugAnnotation::Decoder& annotation,
+ ProtoToArgsParser::Delegate& delegate,
+ std::string& result);
+ ParseResult ParseDebugAnnotationValue(
+ protos::pbzero::DebugAnnotation::Decoder& annotation,
+ ProtoToArgsParser::Delegate& delegate,
+ const ProtoToArgsParser::Key& context_name);
+ ParseResult ParseNestedValueArgs(protozero::ConstBytes nested_value,
+ const ProtoToArgsParser::Key& context_name,
+ ProtoToArgsParser::Delegate& delegate);
+
+ ProtoToArgsParser& proto_to_args_parser_;
+};
+
+} // namespace util
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_UTIL_DEBUG_ANNOTATION_PARSER_H_
diff --git a/src/trace_processor/util/debug_annotation_parser_unittest.cc b/src/trace_processor/util/debug_annotation_parser_unittest.cc
new file mode 100644
index 000000000..55a614fb6
--- /dev/null
+++ b/src/trace_processor/util/debug_annotation_parser_unittest.cc
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/util/debug_annotation_parser.h"
+
+#include "perfetto/ext/base/string_view.h"
+#include "perfetto/protozero/scattered_heap_buffer.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
+#include "protos/perfetto/common/descriptor.pbzero.h"
+#include "protos/perfetto/trace/test_event.pbzero.h"
+#include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
+#include "protos/perfetto/trace/track_event/source_location.pbzero.h"
+#include "src/protozero/test/example_proto/test_messages.pbzero.h"
+#include "src/trace_processor/test_messages.descriptor.h"
+#include "src/trace_processor/util/interned_message_view.h"
+#include "src/trace_processor/util/proto_to_args_parser.h"
+#include "test/gtest_and_gmock.h"
+
+#include <sstream>
+
+namespace perfetto {
+namespace trace_processor {
+namespace util {
+namespace {
+
+base::Status ParseDebugAnnotation(
+ DebugAnnotationParser& parser,
+ protozero::HeapBuffered<protos::pbzero::DebugAnnotation>& msg,
+ ProtoToArgsParser::Delegate& delegate) {
+ std::vector<uint8_t> data = msg.SerializeAsArray();
+ return parser.Parse(protozero::ConstBytes{data.data(), data.size()},
+ delegate);
+}
+
+class DebugAnnotationParserTest : public ::testing::Test,
+ public ProtoToArgsParser::Delegate {
+ protected:
+ DebugAnnotationParserTest() {}
+
+ const std::vector<std::string>& args() const { return args_; }
+
+ private:
+ using Key = ProtoToArgsParser::Key;
+
+ void AddInteger(const Key& key, int64_t value) override {
+ std::stringstream ss;
+ ss << key.flat_key << " " << key.key << " " << value;
+ args_.push_back(ss.str());
+ }
+
+ void AddUnsignedInteger(const Key& key, uint64_t value) override {
+ std::stringstream ss;
+ ss << key.flat_key << " " << key.key << " " << value;
+ args_.push_back(ss.str());
+ }
+
+ void AddString(const Key& key, const protozero::ConstChars& value) override {
+ std::stringstream ss;
+ ss << key.flat_key << " " << key.key << " " << value.ToStdString();
+ args_.push_back(ss.str());
+ }
+
+ void AddDouble(const Key& key, double value) override {
+ std::stringstream ss;
+ ss << key.flat_key << " " << key.key << " " << value;
+ args_.push_back(ss.str());
+ }
+
+ void AddPointer(const Key& key, const void* value) override {
+ std::stringstream ss;
+ ss << key.flat_key << " " << key.key << " " << std::hex
+ << reinterpret_cast<uintptr_t>(value) << std::dec;
+ args_.push_back(ss.str());
+ }
+
+ void AddBoolean(const Key& key, bool value) override {
+ std::stringstream ss;
+ ss << key.flat_key << " " << key.key << " " << (value ? "true" : "false");
+ args_.push_back(ss.str());
+ }
+
+ bool AddJson(const Key& key, const protozero::ConstChars& value) override {
+ std::stringstream ss;
+ ss << key.flat_key << " " << key.key << " " << std::hex
+ << value.ToStdString() << std::dec;
+ args_.push_back(ss.str());
+ return true;
+ }
+
+ void AddNull(const Key& key) override {
+ std::stringstream ss;
+ ss << key.flat_key << " " << key.key << " [NULL]";
+ args_.push_back(ss.str());
+ }
+
+ size_t GetArrayEntryIndex(const std::string& array_key) final {
+ return array_indices_[array_key];
+ }
+
+ size_t IncrementArrayEntryIndex(const std::string& array_key) final {
+ return ++array_indices_[array_key];
+ }
+
+ InternedMessageView* GetInternedMessageView(uint32_t, uint64_t) override {
+ return nullptr;
+ }
+
+ std::vector<std::string> args_;
+ std::map<std::string, size_t> array_indices_;
+};
+
+// This test checks that in when an array is nested inside a dict which is
+// nested inside an array which is nested inside a dict, flat keys and non-flat
+// keys are parsed correctly.
+TEST_F(DebugAnnotationParserTest, DeeplyNestedDictsAndArrays) {
+ protozero::HeapBuffered<protos::pbzero::DebugAnnotation> msg;
+
+ msg->set_name("root");
+ auto* dict1 = msg->add_dict_entries();
+ dict1->set_name("k1");
+ auto* array1 = dict1->add_array_values();
+ auto* dict2 = array1->add_dict_entries();
+ dict2->set_name("k2");
+ auto* array2 = dict2->add_array_values();
+ array2->set_int_value(42);
+
+ DescriptorPool pool;
+ auto status = pool.AddFromFileDescriptorSet(kTestMessagesDescriptor.data(),
+ kTestMessagesDescriptor.size());
+ EXPECT_TRUE(status.ok()) << "Failed to parse kTestMessagesDescriptor: "
+ << status.message();
+
+ ProtoToArgsParser args_parser(pool);
+ DebugAnnotationParser parser(args_parser);
+
+ status = ParseDebugAnnotation(parser, msg, *this);
+ EXPECT_TRUE(status.ok()) << "DebugAnnotationParser::Parse failed with error: "
+ << status.message();
+
+ EXPECT_THAT(args(), testing::ElementsAre("root.k1.k2 root.k1[0].k2[0] 42"));
+}
+
+// This test checks that array indexes are correctly merged across messages.
+TEST_F(DebugAnnotationParserTest, MergeArrays) {
+ protozero::HeapBuffered<protos::pbzero::DebugAnnotation> msg1;
+ msg1->set_name("root");
+ auto* item1 = msg1->add_array_values();
+ item1->set_int_value(1);
+
+ protozero::HeapBuffered<protos::pbzero::DebugAnnotation> msg2;
+ msg2->set_name("root");
+ auto* item2 = msg1->add_array_values();
+ item2->set_int_value(2);
+
+ DescriptorPool pool;
+ ProtoToArgsParser args_parser(pool);
+ DebugAnnotationParser parser(args_parser);
+
+ base::Status status = ParseDebugAnnotation(parser, msg1, *this);
+ EXPECT_TRUE(status.ok()) << "DebugAnnotationParser::Parse failed with error: "
+ << status.message();
+
+ status = ParseDebugAnnotation(parser, msg2, *this);
+ EXPECT_TRUE(status.ok()) << "DebugAnnotationParser::Parse failed with error: "
+ << status.message();
+
+ EXPECT_THAT(args(), testing::ElementsAre("root root[0] 1", "root root[1] 2"));
+}
+
+// This test checks that nested empty dictionaries / arrays do not cause array
+// index to be incremented.
+TEST_F(DebugAnnotationParserTest, EmptyArrayIndexIsSkipped) {
+ protozero::HeapBuffered<protos::pbzero::DebugAnnotation> msg;
+ msg->set_name("root");
+
+ msg->add_array_values()->set_int_value(1);
+
+ // Empty item.
+ msg->add_array_values();
+
+ msg->add_array_values()->set_int_value(3);
+
+ // Empty dict.
+ msg->add_array_values()->add_dict_entries()->set_name("key1");
+
+ auto* nested_dict_entry = msg->add_array_values()->add_dict_entries();
+ nested_dict_entry->set_name("key2");
+ nested_dict_entry->set_string_value("value");
+
+ msg->add_array_values()->set_int_value(5);
+
+ DescriptorPool pool;
+ ProtoToArgsParser args_parser(pool);
+ DebugAnnotationParser parser(args_parser);
+
+ base::Status status = ParseDebugAnnotation(parser, msg, *this);
+ EXPECT_TRUE(status.ok()) << "DebugAnnotationParser::Parse failed with error: "
+ << status.message();
+
+ EXPECT_THAT(args(), testing::ElementsAre("root root[0] 1", "root root[1] 3",
+ "root.key2 root[3].key2 value",
+ "root root[4] 5"));
+}
+
+TEST_F(DebugAnnotationParserTest, NestedArrays) {
+ protozero::HeapBuffered<protos::pbzero::DebugAnnotation> msg;
+ msg->set_name("root");
+ auto* item1 = msg->add_array_values();
+ item1->add_array_values()->set_int_value(1);
+ item1->add_array_values()->set_int_value(2);
+ auto* item2 = msg->add_array_values();
+ item2->add_array_values()->set_int_value(3);
+ item2->add_array_values()->set_int_value(4);
+
+ DescriptorPool pool;
+ ProtoToArgsParser args_parser(pool);
+ DebugAnnotationParser parser(args_parser);
+
+ base::Status status = ParseDebugAnnotation(parser, msg, *this);
+ EXPECT_TRUE(status.ok()) << "DebugAnnotationParser::Parse failed with error: "
+ << status.message();
+
+ EXPECT_THAT(args(),
+ testing::ElementsAre("root root[0][0] 1", "root root[0][1] 2",
+ "root root[1][0] 3", "root root[1][1] 4"));
+}
+
+TEST_F(DebugAnnotationParserTest, TypedMessageInsideUntyped) {
+ protozero::HeapBuffered<protos::pbzero::DebugAnnotation> msg;
+ msg->set_name("root");
+
+ protozero::HeapBuffered<protozero::test::protos::pbzero::EveryField> message;
+ message->set_field_string("value");
+
+ msg->set_proto_type_name(message->GetName());
+ msg->set_proto_value(message.SerializeAsString());
+
+ DescriptorPool pool;
+ auto status = pool.AddFromFileDescriptorSet(kTestMessagesDescriptor.data(),
+ kTestMessagesDescriptor.size());
+ EXPECT_TRUE(status.ok()) << "Failed to parse kTestMessagesDescriptor: "
+ << status.message();
+
+ ProtoToArgsParser args_parser(pool);
+ DebugAnnotationParser parser(args_parser);
+
+ status = ParseDebugAnnotation(parser, msg, *this);
+ EXPECT_TRUE(status.ok()) << "DebugAnnotationParser::Parse failed with error: "
+ << status.message();
+
+ EXPECT_THAT(args(), testing::ElementsAre(
+ "root.field_string root.field_string value"));
+}
+
+} // namespace
+} // namespace util
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/util/descriptors.cc b/src/trace_processor/util/descriptors.cc
index b5b00e1ad..fb4c213f2 100644
--- a/src/trace_processor/util/descriptors.cc
+++ b/src/trace_processor/util/descriptors.cc
@@ -15,6 +15,8 @@
*/
#include "src/trace_processor/util/descriptors.h"
+
+#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/string_view.h"
#include "perfetto/protozero/field.h"
#include "perfetto/protozero/scattered_heap_buffer.h"
@@ -112,11 +114,10 @@ util::Status DescriptorPool::AddNestedProtoDescriptors(
existing_descriptor.file_name().c_str());
}
if (!prev_idx.has_value()) {
- prev_idx = static_cast<unsigned int>(descriptors_.size());
ProtoDescriptor proto_descriptor(file_name, package_name, full_name,
ProtoDescriptor::Type::kMessage,
parent_idx);
- descriptors_.emplace_back(std::move(proto_descriptor));
+ prev_idx = AddProtoDescriptor(std::move(proto_descriptor));
}
ProtoDescriptor& proto_descriptor = descriptors_[*prev_idx];
if (proto_descriptor.type() != ProtoDescriptor::Type::kMessage) {
@@ -136,20 +137,21 @@ util::Status DescriptorPool::AddNestedProtoDescriptors(
return util::ErrStatus("Field %s is re-introduced with different type",
field.name().c_str());
}
- if (field.type() == FieldDescriptorProto::TYPE_MESSAGE &&
- field.resolved_type_name() != existing_field->resolved_type_name()) {
+ if ((field.type() == FieldDescriptorProto::TYPE_MESSAGE ||
+ field.type() == FieldDescriptorProto::TYPE_ENUM) &&
+ field.raw_type_name() != existing_field->raw_type_name()) {
return util::ErrStatus(
"Field %s is re-introduced with different type %s (was %s)",
- field.name().c_str(), field.resolved_type_name().c_str(),
- existing_field->resolved_type_name().c_str());
+ field.name().c_str(), field.raw_type_name().c_str(),
+ existing_field->raw_type_name().c_str());
}
}
}
auto idx = static_cast<uint32_t>(descriptors_.size()) - 1;
for (auto it = decoder.enum_type(); it; ++it) {
- AddEnumProtoDescriptors(file_name, package_name, idx, *it,
- merge_existing_messages);
+ RETURN_IF_ERROR(AddEnumProtoDescriptors(file_name, package_name, idx, *it,
+ merge_existing_messages));
}
for (auto it = decoder.nested_type(); it; ++it) {
RETURN_IF_ERROR(AddNestedProtoDescriptors(file_name, package_name, idx, *it,
@@ -183,11 +185,10 @@ util::Status DescriptorPool::AddEnumProtoDescriptors(
existing_descriptor.file_name().c_str());
}
if (!prev_idx.has_value()) {
- prev_idx = static_cast<unsigned int>(descriptors_.size());
ProtoDescriptor proto_descriptor(file_name, package_name, full_name,
ProtoDescriptor::Type::kEnum,
base::nullopt);
- descriptors_.emplace_back(std::move(proto_descriptor));
+ prev_idx = AddProtoDescriptor(std::move(proto_descriptor));
}
ProtoDescriptor& proto_descriptor = descriptors_[*prev_idx];
if (proto_descriptor.type() != ProtoDescriptor::Type::kEnum) {
@@ -208,15 +209,16 @@ util::Status DescriptorPool::AddEnumProtoDescriptors(
util::Status DescriptorPool::AddFromFileDescriptorSet(
const uint8_t* file_descriptor_set_proto,
size_t size,
+ const std::vector<std::string>& skip_prefixes,
bool merge_existing_messages) {
- // First pass: extract all the message descriptors from the file and add them
- // to the pool.
protos::pbzero::FileDescriptorSet::Decoder proto(file_descriptor_set_proto,
size);
std::vector<ExtensionInfo> extensions;
for (auto it = proto.file(); it; ++it) {
protos::pbzero::FileDescriptorProto::Decoder file(*it);
- std::string file_name = file.name().ToStdString();
+ const std::string file_name = file.name().ToStdString();
+ if (base::StartsWithAny(file_name, skip_prefixes))
+ continue;
if (processed_files_.find(file_name) != processed_files_.end()) {
// This file has been loaded once already. Skip.
continue;
@@ -229,8 +231,9 @@ util::Status DescriptorPool::AddFromFileDescriptorSet(
merge_existing_messages));
}
for (auto enum_it = file.enum_type(); enum_it; ++enum_it) {
- AddEnumProtoDescriptors(file_name, package, base::nullopt, *enum_it,
- merge_existing_messages);
+ RETURN_IF_ERROR(AddEnumProtoDescriptors(file_name, package, base::nullopt,
+ *enum_it,
+ merge_existing_messages));
}
for (auto ext_it = file.extension(); ext_it; ++ext_it) {
extensions.emplace_back(package, *ext_it);
@@ -271,13 +274,11 @@ util::Status DescriptorPool::AddFromFileDescriptorSet(
base::Optional<uint32_t> DescriptorPool::FindDescriptorIdx(
const std::string& full_name) const {
- auto it = std::find_if(descriptors_.begin(), descriptors_.end(),
- [full_name](const ProtoDescriptor& desc) {
- return desc.full_name() == full_name;
- });
- auto idx = static_cast<uint32_t>(std::distance(descriptors_.begin(), it));
- return idx < descriptors_.size() ? base::Optional<uint32_t>(idx)
- : base::nullopt;
+ auto it = full_name_to_descriptor_index_.find(full_name);
+ if (it == full_name_to_descriptor_index_.end()) {
+ return base::nullopt;
+ }
+ return it->second;
}
std::vector<uint8_t> DescriptorPool::SerializeAsDescriptorSet() {
@@ -306,6 +307,13 @@ std::vector<uint8_t> DescriptorPool::SerializeAsDescriptorSet() {
return descs.SerializeAsArray();
}
+uint32_t DescriptorPool::AddProtoDescriptor(ProtoDescriptor descriptor) {
+ uint32_t idx = static_cast<uint32_t>(descriptors_.size());
+ full_name_to_descriptor_index_[descriptor.full_name()] = idx;
+ descriptors_.emplace_back(std::move(descriptor));
+ return idx;
+}
+
ProtoDescriptor::ProtoDescriptor(std::string file_name,
std::string package_name,
std::string full_name,
diff --git a/src/trace_processor/util/descriptors.h b/src/trace_processor/util/descriptors.h
index 71087817a..71dd5cc02 100644
--- a/src/trace_processor/util/descriptors.h
+++ b/src/trace_processor/util/descriptors.h
@@ -87,16 +87,18 @@ class ProtoDescriptor {
void AddEnumValue(int32_t integer_representation,
std::string string_representation) {
PERFETTO_DCHECK(type_ == Type::kEnum);
- enum_values_[integer_representation] = std::move(string_representation);
+ enum_values_by_name_[string_representation] = integer_representation;
+ enum_names_by_value_[integer_representation] =
+ std::move(string_representation);
}
const FieldDescriptor* FindFieldByName(const std::string& name) const {
PERFETTO_DCHECK(type_ == Type::kMessage);
- auto it =
- std::find_if(fields_.begin(), fields_.end(),
- [name](std::pair<int32_t, const FieldDescriptor&> p) {
- return p.second.name() == name;
- });
+ auto it = std::find_if(
+ fields_.begin(), fields_.end(),
+ [name](const std::pair<const uint32_t, FieldDescriptor>& p) {
+ return p.second.name() == name;
+ });
if (it == fields_.end()) {
return nullptr;
}
@@ -114,9 +116,16 @@ class ProtoDescriptor {
base::Optional<std::string> FindEnumString(const int32_t value) const {
PERFETTO_DCHECK(type_ == Type::kEnum);
- auto it = enum_values_.find(value);
- return it == enum_values_.end() ? base::nullopt
- : base::Optional<std::string>(it->second);
+ auto it = enum_names_by_value_.find(value);
+ return it == enum_names_by_value_.end() ? base::nullopt
+ : base::make_optional(it->second);
+ }
+
+ base::Optional<int32_t> FindEnumValue(const std::string& value) const {
+ PERFETTO_DCHECK(type_ == Type::kEnum);
+ auto it = enum_values_by_name_.find(value);
+ return it == enum_values_by_name_.end() ? base::nullopt
+ : base::make_optional(it->second);
}
const std::string& file_name() const { return file_name_; }
@@ -141,27 +150,35 @@ class ProtoDescriptor {
const Type type_;
base::Optional<uint32_t> parent_id_;
std::unordered_map<uint32_t, FieldDescriptor> fields_;
- std::unordered_map<int32_t, std::string> enum_values_;
+ std::unordered_map<int32_t, std::string> enum_names_by_value_;
+ std::unordered_map<std::string, int32_t> enum_values_by_name_;
};
using ExtensionInfo = std::pair<std::string, protozero::ConstBytes>;
class DescriptorPool {
public:
+ // Adds Descriptors from file_descriptor_set_proto. Ignores any FileDescriptor
+ // with name matching a prefix in |skip_prefixes|.
base::Status AddFromFileDescriptorSet(
const uint8_t* file_descriptor_set_proto,
size_t size,
+ const std::vector<std::string>& skip_prefixes = {},
bool merge_existing_messages = false);
base::Optional<uint32_t> FindDescriptorIdx(
const std::string& full_name) const;
+ std::vector<uint8_t> SerializeAsDescriptorSet();
+
+ void AddProtoDescriptorForTesting(ProtoDescriptor descriptor) {
+ AddProtoDescriptor(std::move(descriptor));
+ }
+
const std::vector<ProtoDescriptor>& descriptors() const {
return descriptors_;
}
- std::vector<uint8_t> SerializeAsDescriptorSet();
-
private:
base::Status AddNestedProtoDescriptors(const std::string& file_name,
const std::string& package_name,
@@ -183,7 +200,13 @@ class DescriptorPool {
base::Optional<uint32_t> ResolveShortType(const std::string& parent_path,
const std::string& short_type);
+ // Adds a new descriptor to the pool and returns its index. There must not be
+ // already a descriptor with the same full_name in the pool.
+ uint32_t AddProtoDescriptor(ProtoDescriptor descriptor);
+
std::vector<ProtoDescriptor> descriptors_;
+ // full_name -> index in the descriptors_ vector.
+ std::unordered_map<std::string, uint32_t> full_name_to_descriptor_index_;
std::set<std::string> processed_files_;
};
diff --git a/src/trace_processor/util/gzip_utils.cc b/src/trace_processor/util/gzip_utils.cc
new file mode 100644
index 000000000..2279b8771
--- /dev/null
+++ b/src/trace_processor/util/gzip_utils.cc
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/util/gzip_utils.h"
+
+// For bazel build.
+#include "perfetto/base/build_config.h"
+#include "perfetto/base/compiler.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
+#include <zlib.h>
+#else
+struct z_stream_s {};
+#endif
+
+namespace perfetto {
+namespace trace_processor {
+namespace util {
+
+bool IsGzipSupported() {
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
+ return true;
+#else
+ return false;
+#endif
+}
+
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB) // Real Implementation
+
+GzipDecompressor::GzipDecompressor() : z_stream_(new z_stream()) {
+ z_stream_->zalloc = nullptr;
+ z_stream_->zfree = nullptr;
+ z_stream_->opaque = nullptr;
+ inflateInit2(z_stream_.get(), 32 + MAX_WBITS);
+}
+
+GzipDecompressor::~GzipDecompressor() {
+ inflateEnd(z_stream_.get());
+}
+
+void GzipDecompressor::Reset() {
+ inflateReset(z_stream_.get());
+}
+
+void GzipDecompressor::Feed(const uint8_t* data, size_t size) {
+ // This const_cast is not harmfull as zlib will not modify the data in this
+ // pointer. This is only necessary because of the build flags we use to be
+ // compatible with other embedders.
+ z_stream_->next_in = const_cast<uint8_t*>(data);
+ z_stream_->avail_in = static_cast<uInt>(size);
+}
+
+GzipDecompressor::Result GzipDecompressor::ExtractOutput(uint8_t* out,
+ size_t out_size) {
+ if (z_stream_->avail_in == 0)
+ return Result{ResultCode::kNeedsMoreInput, 0};
+
+ z_stream_->next_out = out;
+ z_stream_->avail_out = static_cast<uInt>(out_size);
+
+ int ret = inflate(z_stream_.get(), Z_NO_FLUSH);
+ switch (ret) {
+ case Z_NEED_DICT:
+ case Z_DATA_ERROR:
+ case Z_MEM_ERROR:
+ // Ignore inflateEnd error as we will error out anyway.
+ inflateEnd(z_stream_.get());
+ return Result{ResultCode::kError, 0};
+ case Z_STREAM_END:
+ return Result{ResultCode::kEof, out_size - z_stream_->avail_out};
+ case Z_BUF_ERROR:
+ return Result{ResultCode::kNeedsMoreInput, 0};
+ default:
+ return Result{ResultCode::kOk, out_size - z_stream_->avail_out};
+ }
+}
+
+#else // Dummy Implementation
+
+GzipDecompressor::GzipDecompressor() = default;
+GzipDecompressor::~GzipDecompressor() = default;
+void GzipDecompressor::Reset() {}
+void GzipDecompressor::Feed(const uint8_t*, size_t) {}
+GzipDecompressor::Result GzipDecompressor::ExtractOutput(uint8_t*, size_t) {
+ return Result{ResultCode::kError, 0};
+}
+
+#endif // PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
+
+// static
+std::vector<uint8_t> GzipDecompressor::DecompressFully(const uint8_t* data,
+ size_t len) {
+ std::vector<uint8_t> whole_data;
+ GzipDecompressor decompressor;
+ auto decom_output_consumer = [&](const uint8_t* buf, size_t buf_len) {
+ whole_data.insert(whole_data.end(), buf, buf + buf_len);
+ };
+ decompressor.FeedAndExtract(data, len, decom_output_consumer);
+ return whole_data;
+}
+
+} // namespace util
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/util/gzip_utils.h b/src/trace_processor/util/gzip_utils.h
new file mode 100644
index 000000000..711541fc1
--- /dev/null
+++ b/src/trace_processor/util/gzip_utils.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_UTIL_GZIP_UTILS_H_
+#define SRC_TRACE_PROCESSOR_UTIL_GZIP_UTILS_H_
+
+#include <memory>
+#include <vector>
+
+struct z_stream_s;
+
+namespace perfetto {
+namespace trace_processor {
+namespace util {
+
+// Returns whether gzip related functioanlity is supported with the current
+// build flags.
+bool IsGzipSupported();
+
+// Usage: To decompress in a streaming way, there are two ways of using it:
+// 1. [Commonly used] - Feed the sequence of mem-blocks in 'FeedAndExtract' one
+// by one. Output will be produced in given output_consumer, which is simply
+// a callback. On each 'FeedAndExtract', output_consumer could get invoked
+// any number of times, based on how much partial output is available.
+
+// 2. [Uncommon ; Discouraged] - Feed the sequence of mem-blocks one by one, by
+// calling 'Feed'. For each time 'Feed' is called, client should call
+// 'ExtractOutput' again and again to extrat the partially available output,
+// until there in no more output to extract. Also see 'ResultCode' enum.
+class GzipDecompressor {
+ public:
+ enum class ResultCode {
+ // 'kOk' means nothing bad happened so far, but continue doing what you
+ // were doing.
+ kOk,
+ // While calling 'ExtractOutput' repeatedly, if we get 'kEof', it means
+ // we have extracted all the partially available data and we are also
+ // done, i.e. there is no need to feed more input.
+ kEof,
+ // Some error. Possibly invalid compressed stream or corrupted data.
+ kError,
+ // While calling 'ExtractOutput' repeatedly, if we get 'kNeedsMoreInput',
+ // it means we have extracted all the partially available data, but we are
+ // not done yet. We need to call the 'Feed' to feed the next input
+ // mem-block and go through the ExtractOutput loop again.
+ kNeedsMoreInput,
+ };
+ struct Result {
+ // The return code of the decompression.
+ ResultCode ret;
+
+ // The amount of bytes written to output.
+ // Valid in all cases except |ResultCode::kError|.
+ size_t bytes_written;
+ };
+
+ GzipDecompressor();
+ ~GzipDecompressor();
+ GzipDecompressor(const GzipDecompressor&) = delete;
+ GzipDecompressor& operator=(const GzipDecompressor&) = delete;
+
+ // Feed the next mem-block.
+ void Feed(const uint8_t* data, size_t size);
+
+ // Feed the next mem-block and extract output in the callback consumer.
+ // callback can get invoked multiple times if there are multiple
+ // mem-blocks to output.
+ template <typename Callback = void(const uint8_t* ptr, size_t size)>
+ ResultCode FeedAndExtract(const uint8_t* data,
+ size_t size,
+ const Callback& output_consumer) {
+ Feed(data, size);
+ uint8_t buffer[4096];
+ Result result;
+ do {
+ result = ExtractOutput(buffer, sizeof(buffer));
+ if (result.ret != ResultCode::kError && result.bytes_written > 0) {
+ output_consumer(buffer, result.bytes_written);
+ }
+ } while (result.ret == ResultCode::kOk);
+ return result.ret;
+ }
+
+ // Extract the newly available partial output. On each 'Feed', this method
+ // should be called repeatedly until there is no more data to output
+ // i.e. (either 'kEof' or 'kNeedsMoreInput').
+ Result ExtractOutput(uint8_t* out, size_t out_capacity);
+
+ // Sets the state of the decompressor to reuse with other gzip streams.
+ // This is almost like constructing a new 'GzipDecompressor' object
+ // but without paying the cost of internal memory allocation.
+ void Reset();
+
+ // Decompress the entire mem-block and return decompressed mem-block.
+ // This is used for decompressing small strings or small files
+ // which doesn't require streaming decompression.
+ static std::vector<uint8_t> DecompressFully(const uint8_t* data, size_t len);
+
+ private:
+ std::unique_ptr<z_stream_s> z_stream_;
+};
+
+} // namespace util
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_UTIL_GZIP_UTILS_H_
diff --git a/src/trace_processor/util/gzip_utils_unittest.cc b/src/trace_processor/util/gzip_utils_unittest.cc
new file mode 100644
index 000000000..a58332e1c
--- /dev/null
+++ b/src/trace_processor/util/gzip_utils_unittest.cc
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "test/gtest_and_gmock.h"
+
+#include "src/trace_processor/util/gzip_utils.h"
+
+#include <zlib.h>
+#include <fstream>
+#include <iostream>
+#include "perfetto/base/logging.h"
+
+using std::string;
+
+namespace perfetto {
+namespace trace_processor {
+namespace util {
+
+static std::string TrivialGzipCompress(const std::string& input) {
+ constexpr auto buffer_len = 10000;
+ std::unique_ptr<char[]> output_ptr(new char[buffer_len]);
+ char* output = output_ptr.get();
+ z_stream defstream;
+ defstream.zalloc = Z_NULL;
+ defstream.zfree = Z_NULL;
+ defstream.opaque = Z_NULL;
+ defstream.avail_in = uint32_t(input.size());
+ defstream.next_in =
+ const_cast<Bytef*>(reinterpret_cast<const Bytef*>(input.data()));
+ defstream.avail_out = buffer_len;
+ defstream.next_out = reinterpret_cast<Bytef*>(output);
+ deflateInit(&defstream, Z_BEST_COMPRESSION); // GZip decompress
+ deflate(&defstream, Z_FINISH);
+ deflateEnd(&defstream);
+ PERFETTO_CHECK(defstream.avail_out > 0);
+ return std::string(output, buffer_len - defstream.avail_out);
+}
+
+// Trivially decompress using ZlibOnlineDecompress.
+// It's called 'trivial' because we are feeding the entire input in one shot.
+static std::string TrivialDecompress(const std::string& input) {
+ string output;
+ GzipDecompressor decompressor;
+ decompressor.FeedAndExtract(
+ reinterpret_cast<const uint8_t*>(input.data()), uint32_t(input.size()),
+ [&](const uint8_t* data, size_t len) {
+ output.append(reinterpret_cast<const char*>(data), len);
+ });
+ return output;
+}
+
+// Decompress a large GZip file using a in-memory buffer of 4KB, and write the
+// decompressed output in another file.
+static void DecompressGzipFileInFileOut(const std::string& input_file,
+ const std::string& output_file) {
+ std::ofstream output(output_file.c_str(), std::ios::out | std::ios::binary);
+ std::ifstream input(input_file.c_str(), std::ios::binary);
+ GzipDecompressor decompressor;
+ constexpr uint32_t buffer_sizeof = 4096;
+ char buffer[buffer_sizeof];
+ while (!input.eof()) {
+ input.read(buffer, buffer_sizeof);
+ decompressor.FeedAndExtract(
+ reinterpret_cast<const uint8_t*>(buffer), size_t(input.gcount()),
+ [&](const uint8_t* data, size_t len) {
+ output.write(reinterpret_cast<const char*>(data),
+ std::streamsize(len));
+ });
+ }
+ EXPECT_FALSE(input.bad());
+}
+
+TEST(GzipDecompressor, Basic) {
+ string input = "Abc..Def..Ghi";
+ string compressed = TrivialGzipCompress(input);
+ EXPECT_EQ(21u, compressed.size());
+ string decompressed = TrivialDecompress(compressed);
+ EXPECT_EQ(input, decompressed);
+}
+
+TEST(GzipDecompressor, Streaming) {
+ string input = "Abc..Def..Ghi";
+ string compressed = TrivialGzipCompress(input);
+ string decompressed;
+ auto consumer = [&](const uint8_t* data, size_t len) {
+ decompressed.append(reinterpret_cast<const char*>(data), len);
+ };
+ GzipDecompressor decompressor;
+ auto compressed_u8 = reinterpret_cast<const uint8_t*>(compressed.data());
+ ASSERT_GT(compressed.size(), 17u);
+ decompressor.FeedAndExtract(compressed_u8, 7, consumer);
+ decompressor.FeedAndExtract(compressed_u8 + 7, 10, consumer);
+ decompressor.FeedAndExtract(compressed_u8 + 17, compressed.size() - 17,
+ consumer);
+
+ EXPECT_EQ(input, decompressed);
+}
+
+static std::string ReadFile(const std::string& file_name) {
+ std::ifstream fd(file_name, std::ios::binary);
+ std::stringstream buffer;
+ buffer << fd.rdbuf();
+ fd.close();
+ return buffer.str();
+}
+
+static void WriteFile(const std::string& file_name,
+ const std::string& content) {
+ std::ofstream fd(file_name, std::ios::out | std::ios::binary);
+ fd.write(content.data(), std::streamsize(content.size()));
+ fd.close();
+}
+
+TEST(GzipDecompressor, DISABLED_FileInFileOut) {
+ auto big_string = []() {
+ std::string output;
+ for (int i = 0; i < 1000; i++) {
+ output += "Abc..Def..Ghi."; // len = 14
+ }
+ return output;
+ }();
+ constexpr auto gz_file = "/tmp/abc.gz";
+ constexpr auto txt_file = "/tmp/abc.txt";
+ EXPECT_EQ(size_t(1000 * 14), big_string.size());
+ WriteFile(gz_file, TrivialGzipCompress(big_string));
+ DecompressGzipFileInFileOut(gz_file, txt_file);
+ EXPECT_TRUE(ReadFile(txt_file) == big_string);
+}
+
+} // namespace util
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/util/interned_message_view.h b/src/trace_processor/util/interned_message_view.h
new file mode 100644
index 000000000..3422b8bea
--- /dev/null
+++ b/src/trace_processor/util/interned_message_view.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_UTIL_INTERNED_MESSAGE_VIEW_H_
+#define SRC_TRACE_PROCESSOR_UTIL_INTERNED_MESSAGE_VIEW_H_
+
+#include "perfetto/ext/base/flat_hash_map.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+#if PERFETTO_DCHECK_IS_ON()
+// When called from GetOrCreateDecoder(), should include the stringified name of
+// the MessageType.
+#define PERFETTO_TYPE_IDENTIFIER PERFETTO_DEBUG_FUNCTION_IDENTIFIER()
+#else // PERFETTO_DCHECK_IS_ON()
+#define PERFETTO_TYPE_IDENTIFIER nullptr
+#endif // PERFETTO_DCHECK_IS_ON()
+
+// Entry in an interning index, refers to the interned message.
+class InternedMessageView {
+ public:
+ explicit InternedMessageView(TraceBlobView msg) : message_(std::move(msg)) {}
+
+ InternedMessageView(InternedMessageView&&) = default;
+ InternedMessageView& operator=(InternedMessageView&&) = default;
+
+ // Allow copy by cloning the TraceBlobView. This is required for
+ // UpdateTracePacketDefaults().
+ InternedMessageView(const InternedMessageView& view)
+ : message_(view.message_.copy()) {}
+
+ InternedMessageView& operator=(const InternedMessageView& view) {
+ this->message_ = view.message_.copy();
+ this->decoder_ = nullptr;
+ this->decoder_type_ = nullptr;
+ this->submessages_.Clear();
+ return *this;
+ }
+
+ // Lazily initializes and returns the decoder object for the message. The
+ // decoder is stored in the InternedMessageView to avoid having to parse the
+ // message multiple times.
+ template <typename MessageType>
+ typename MessageType::Decoder* GetOrCreateDecoder() {
+ if (!decoder_) {
+ // Lazy init the decoder and save it away, so that we don't have to
+ // reparse the message every time we access the interning entry.
+ decoder_ = std::unique_ptr<void, std::function<void(void*)>>(
+ new typename MessageType::Decoder(message_.data(), message_.length()),
+ [](void* obj) {
+ delete reinterpret_cast<typename MessageType::Decoder*>(obj);
+ });
+ decoder_type_ = PERFETTO_TYPE_IDENTIFIER;
+ }
+ // Verify that the type of the decoder didn't change.
+ if (PERFETTO_TYPE_IDENTIFIER &&
+ strcmp(decoder_type_,
+ // GCC complains if this arg can be null.
+ PERFETTO_TYPE_IDENTIFIER ? PERFETTO_TYPE_IDENTIFIER : "") != 0) {
+ PERFETTO_FATAL(
+ "Interning entry accessed under different types! previous type: "
+ "%s. new type: %s.",
+ decoder_type_, PERFETTO_DEBUG_FUNCTION_IDENTIFIER());
+ }
+ return reinterpret_cast<typename MessageType::Decoder*>(decoder_.get());
+ }
+
+ // Lookup a submessage of the interned message, which is then itself stored
+ // as InternedMessageView, so that we only need to parse it once. Returns
+ // nullptr if the field isn't set.
+ // TODO(eseckler): Support repeated fields.
+ template <typename MessageType, uint32_t FieldId>
+ InternedMessageView* GetOrCreateSubmessageView() {
+ auto it_and_ins = submessages_.Insert(FieldId, nullptr);
+ if (!it_and_ins.second)
+ return it_and_ins.first->get();
+ auto* decoder = GetOrCreateDecoder<MessageType>();
+ // Calls the at() template method on the decoder.
+ auto field = decoder->template at<FieldId>().as_bytes();
+ if (!field.data)
+ return nullptr;
+ TraceBlobView submessage = message_.slice(field.data, field.size);
+ InternedMessageView* submessage_view =
+ new InternedMessageView(std::move(submessage));
+ it_and_ins.first->reset(submessage_view);
+ return submessage_view;
+ }
+
+ const TraceBlobView& message() { return message_; }
+
+ private:
+ using SubMessageViewMap =
+ base::FlatHashMap<uint32_t /*field_id*/,
+ std::unique_ptr<InternedMessageView>>;
+
+ TraceBlobView message_;
+
+ // Stores the decoder for the message_, so that the message does not have to
+ // be re-decoded every time the interned message is looked up. Lazily
+ // initialized in GetOrCreateDecoder(). Since we don't know the type of the
+ // decoder until GetOrCreateDecoder() is called, we store the decoder as a
+ // void* unique_pointer with a destructor function that's supplied in
+ // GetOrCreateDecoder() when the decoder is created.
+ std::unique_ptr<void, std::function<void(void*)>> decoder_;
+
+ // Type identifier for the decoder. Only valid in debug builds and on
+ // supported platforms. Used to verify that GetOrCreateDecoder() is always
+ // called with the same template argument.
+ const char* decoder_type_ = nullptr;
+
+ // Views of submessages of the interned message. Submessages are lazily
+ // added by GetOrCreateSubmessageView(). By storing submessages and their
+ // decoders, we avoid having to decode submessages multiple times if they
+ // looked up often.
+ SubMessageViewMap submessages_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_UTIL_INTERNED_MESSAGE_VIEW_H_
diff --git a/src/trace_processor/util/proto_to_args_parser.cc b/src/trace_processor/util/proto_to_args_parser.cc
index 6fec35ebb..b462d3a19 100644
--- a/src/trace_processor/util/proto_to_args_parser.cc
+++ b/src/trace_processor/util/proto_to_args_parser.cc
@@ -26,34 +26,11 @@ namespace util {
namespace {
-// ScopedStringAppender will add |append| to |dest| when constructed and
-// erases the appended suffix from |dest| when it goes out of scope. Thus
-// |dest| must be valid for the entire lifetime of ScopedStringAppender.
-//
-// This is useful as we descend into a proto since the column names just
-// appended with ".field_name" as we go lower.
-//
-// I.E. message1.message2.field_name1 is a column, but we'll then need to
-// append message1.message2.field_name2 afterwards so we only need to append
-// "field_name1" within some scope.
-class ScopedStringAppender {
- public:
- ScopedStringAppender(const std::string& append, std::string* dest)
- : old_size_(dest->size()), dest_(dest) {
- if (dest->empty()) {
- dest_->reserve(append.size());
- } else {
- dest_->reserve(old_size_ + 1 + append.size());
- dest_->append(".");
- }
- dest_->append(append);
- }
- ~ScopedStringAppender() { dest_->erase(old_size_); }
-
- private:
- size_t old_size_;
- std::string* dest_;
-};
+void AppendProtoType(std::string& target, const std::string& value) {
+ if (!target.empty())
+ target += '.';
+ target += value;
+}
} // namespace
@@ -63,6 +40,33 @@ ProtoToArgsParser::Key::Key(const std::string& fk, const std::string& k)
: flat_key(fk), key(k) {}
ProtoToArgsParser::Key::~Key() = default;
+ProtoToArgsParser::ScopedNestedKeyContext::ScopedNestedKeyContext(Key& key)
+ : key_(key),
+ old_flat_key_length_(key.flat_key.length()),
+ old_key_length_(key.key.length()) {}
+
+ProtoToArgsParser::ScopedNestedKeyContext::ScopedNestedKeyContext(
+ ProtoToArgsParser::ScopedNestedKeyContext&& other)
+ : key_(other.key_),
+ old_flat_key_length_(other.old_flat_key_length_),
+ old_key_length_(other.old_key_length_) {
+ other.old_flat_key_length_ = base::nullopt;
+ other.old_key_length_ = base::nullopt;
+}
+
+ProtoToArgsParser::ScopedNestedKeyContext::~ScopedNestedKeyContext() {
+ RemoveFieldSuffix();
+}
+
+void ProtoToArgsParser::ScopedNestedKeyContext::RemoveFieldSuffix() {
+ if (old_flat_key_length_)
+ key_.flat_key.resize(old_flat_key_length_.value());
+ if (old_key_length_)
+ key_.key.resize(old_key_length_.value());
+ old_flat_key_length_ = base::nullopt;
+ old_key_length_ = base::nullopt;
+}
+
ProtoToArgsParser::Delegate::~Delegate() = default;
ProtoToArgsParser::ProtoToArgsParser(const DescriptorPool& pool) : pool_(pool) {
@@ -75,7 +79,25 @@ base::Status ProtoToArgsParser::ParseMessage(
const protozero::ConstBytes& cb,
const std::string& type,
const std::vector<uint16_t>* allowed_fields,
- Delegate& delegate) {
+ Delegate& delegate,
+ int* unknown_extensions) {
+ ScopedNestedKeyContext key_context(key_prefix_);
+ return ParseMessageInternal(key_context, cb, type, allowed_fields, delegate,
+ unknown_extensions);
+}
+
+base::Status ProtoToArgsParser::ParseMessageInternal(
+ ScopedNestedKeyContext& key_context,
+ const protozero::ConstBytes& cb,
+ const std::string& type,
+ const std::vector<uint16_t>* allowed_fields,
+ Delegate& delegate,
+ int* unknown_extensions) {
+ if (auto override_result =
+ MaybeApplyOverrideForType(type, key_context, cb, delegate)) {
+ return override_result.value();
+ }
+
auto idx = pool_.FindDescriptorIdx(type);
if (!idx) {
return base::Status("Failed to find proto descriptor");
@@ -85,11 +107,17 @@ base::Status ProtoToArgsParser::ParseMessage(
std::unordered_map<size_t, int> repeated_field_index;
+ bool empty_message = true;
+
protozero::ProtoDecoder decoder(cb);
for (protozero::Field f = decoder.ReadField(); f.valid();
f = decoder.ReadField()) {
+ empty_message = false;
auto field = descriptor.FindFieldByTag(f.id());
if (!field) {
+ if (unknown_extensions != nullptr) {
+ (*unknown_extensions)++;
+ }
// Unknown field, possibly an unknown extension.
continue;
}
@@ -105,13 +133,17 @@ base::Status ProtoToArgsParser::ParseMessage(
// reflected.
continue;
}
- RETURN_IF_ERROR(
- ParseField(*field, repeated_field_index[f.id()], f, delegate));
+ RETURN_IF_ERROR(ParseField(*field, repeated_field_index[f.id()], f,
+ delegate, unknown_extensions));
if (field->is_repeated()) {
repeated_field_index[f.id()]++;
}
}
+ if (empty_message) {
+ delegate.AddNull(key_prefix_);
+ }
+
return base::OkStatus();
}
@@ -119,7 +151,8 @@ base::Status ProtoToArgsParser::ParseField(
const FieldDescriptor& field_descriptor,
int repeated_field_number,
protozero::Field field,
- Delegate& delegate) {
+ Delegate& delegate,
+ int* unknown_extensions) {
std::string prefix_part = field_descriptor.name();
if (field_descriptor.is_repeated()) {
std::string number = std::to_string(repeated_field_number);
@@ -132,14 +165,14 @@ base::Status ProtoToArgsParser::ParseField(
// In the args table we build up message1.message2.field1 as the column
// name. This will append the ".field1" suffix to |key_prefix| and then
// remove it when it goes out of scope.
- ScopedStringAppender scoped_prefix(prefix_part, &key_prefix_.key);
- ScopedStringAppender scoped_flat_key_prefix(field_descriptor.name(),
- &key_prefix_.flat_key);
+ ScopedNestedKeyContext key_context(key_prefix_);
+ AppendProtoType(key_prefix_.flat_key, field_descriptor.name());
+ AppendProtoType(key_prefix_.key, prefix_part);
// If we have an override parser then use that instead and move onto the
// next loop.
if (base::Optional<base::Status> status =
- MaybeApplyOverride(field, delegate)) {
+ MaybeApplyOverrideForField(field, delegate)) {
return *status;
}
@@ -148,27 +181,45 @@ base::Status ProtoToArgsParser::ParseField(
// recurse into it.
if (field_descriptor.type() ==
protos::pbzero::FieldDescriptorProto::TYPE_MESSAGE) {
- return ParseMessage(field.as_bytes(), field_descriptor.resolved_type_name(),
- nullptr, delegate);
+ return ParseMessageInternal(key_context, field.as_bytes(),
+ field_descriptor.resolved_type_name(), nullptr,
+ delegate, unknown_extensions);
}
return ParseSimpleField(field_descriptor, field, delegate);
}
-void ProtoToArgsParser::AddParsingOverride(std::string field,
- ParsingOverride func) {
- overrides_[std::move(field)] = std::move(func);
+void ProtoToArgsParser::AddParsingOverrideForField(
+ const std::string& field,
+ ParsingOverrideForField func) {
+ field_overrides_[field] = std::move(func);
}
-base::Optional<base::Status> ProtoToArgsParser::MaybeApplyOverride(
+void ProtoToArgsParser::AddParsingOverrideForType(const std::string& type,
+ ParsingOverrideForType func) {
+ type_overrides_[type] = std::move(func);
+}
+
+base::Optional<base::Status> ProtoToArgsParser::MaybeApplyOverrideForField(
const protozero::Field& field,
Delegate& delegate) {
- auto it = overrides_.find(key_prefix_.flat_key);
- if (it == overrides_.end())
+ auto it = field_overrides_.find(key_prefix_.flat_key);
+ if (it == field_overrides_.end())
return base::nullopt;
return it->second(field, delegate);
}
+base::Optional<base::Status> ProtoToArgsParser::MaybeApplyOverrideForType(
+ const std::string& message_type,
+ ScopedNestedKeyContext& key,
+ const protozero::ConstBytes& data,
+ Delegate& delegate) {
+ auto it = type_overrides_.find(message_type);
+ if (it == type_overrides_.end())
+ return base::nullopt;
+ return it->second(key, data, delegate);
+}
+
base::Status ProtoToArgsParser::ParseSimpleField(
const FieldDescriptor& descriptor,
const protozero::Field& field,
@@ -177,7 +228,6 @@ base::Status ProtoToArgsParser::ParseSimpleField(
switch (descriptor.type()) {
case FieldDescriptorProto::TYPE_INT32:
case FieldDescriptorProto::TYPE_SFIXED32:
- case FieldDescriptorProto::TYPE_FIXED32:
delegate.AddInteger(key_prefix_, field.as_int32());
return base::OkStatus();
case FieldDescriptorProto::TYPE_SINT32:
@@ -185,16 +235,17 @@ base::Status ProtoToArgsParser::ParseSimpleField(
return base::OkStatus();
case FieldDescriptorProto::TYPE_INT64:
case FieldDescriptorProto::TYPE_SFIXED64:
- case FieldDescriptorProto::TYPE_FIXED64:
delegate.AddInteger(key_prefix_, field.as_int64());
return base::OkStatus();
case FieldDescriptorProto::TYPE_SINT64:
delegate.AddInteger(key_prefix_, field.as_sint64());
return base::OkStatus();
case FieldDescriptorProto::TYPE_UINT32:
+ case FieldDescriptorProto::TYPE_FIXED32:
delegate.AddUnsignedInteger(key_prefix_, field.as_uint32());
return base::OkStatus();
case FieldDescriptorProto::TYPE_UINT64:
+ case FieldDescriptorProto::TYPE_FIXED64:
delegate.AddUnsignedInteger(key_prefix_, field.as_uint64());
return base::OkStatus();
case FieldDescriptorProto::TYPE_BOOL:
@@ -238,6 +289,21 @@ base::Status ProtoToArgsParser::ParseSimpleField(
}
}
+ProtoToArgsParser::ScopedNestedKeyContext ProtoToArgsParser::EnterArray(
+ size_t index) {
+ auto context = ScopedNestedKeyContext(key_prefix_);
+ key_prefix_.key += "[" + std::to_string(index) + "]";
+ return context;
+}
+
+ProtoToArgsParser::ScopedNestedKeyContext ProtoToArgsParser::EnterDictionary(
+ const std::string& name) {
+ auto context = ScopedNestedKeyContext(key_prefix_);
+ AppendProtoType(key_prefix_.key, name);
+ AppendProtoType(key_prefix_.flat_key, name);
+ return context;
+}
+
} // namespace util
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/util/proto_to_args_parser.h b/src/trace_processor/util/proto_to_args_parser.h
index f99179cc2..2329edb7c 100644
--- a/src/trace_processor/util/proto_to_args_parser.h
+++ b/src/trace_processor/util/proto_to_args_parser.h
@@ -83,8 +83,13 @@ class ProtoToArgsParser {
virtual void AddDouble(const Key& key, double value) = 0;
virtual void AddPointer(const Key& key, const void* value) = 0;
virtual void AddBoolean(const Key& key, bool value) = 0;
- virtual void AddJson(const Key& key,
+ // Returns whether an entry was added or not.
+ virtual bool AddJson(const Key& key,
const protozero::ConstChars& value) = 0;
+ virtual void AddNull(const Key& key) = 0;
+
+ virtual size_t GetArrayEntryIndex(const std::string& array_key) = 0;
+ virtual size_t IncrementArrayEntryIndex(const std::string& array_key) = 0;
template <typename FieldMetadata>
typename FieldMetadata::cpp_field_type::Decoder* GetInternedMessage(
@@ -96,9 +101,12 @@ class ProtoToArgsParser {
static_assert(std::is_same<typename FieldMetadata::message_type,
protos::pbzero::InternedData>::value,
"Field should belong to InternedData proto");
- return GetInternedMessageView(FieldMetadata::kFieldId, iid)
- ->template GetOrCreateDecoder<
- typename FieldMetadata::cpp_field_type>();
+ auto* interned_message_view =
+ GetInternedMessageView(FieldMetadata::kFieldId, iid);
+ if (!interned_message_view)
+ return nullptr;
+ return interned_message_view->template GetOrCreateDecoder<
+ typename FieldMetadata::cpp_field_type>();
}
protected:
@@ -106,7 +114,65 @@ class ProtoToArgsParser {
uint64_t iid) = 0;
};
- using ParsingOverride =
+ // Given a view of bytes that represent a serialized protozero message of
+ // |type| we will parse each field.
+ //
+ // Returns on any error with a status describing the problem. However any
+ // added values before encountering the error will be parsed and forwarded to
+ // the delegate.
+ //
+ // Fields with ids given in |fields| are parsed using reflection, as well
+ // as known (previously registered) extension fields. If |allowed_fields| is a
+ // nullptr, all fields are going to be parsed.
+ //
+ // Note:
+ // |type| must be the fully qualified name, but with a '.' added to the
+ // beginning. I.E. ".perfetto.protos.TrackEvent". And must match one of the
+ // descriptors already added through |AddProtoFileDescriptor|.
+ //
+ // IMPORTANT: currently bytes fields are not supported.
+ //
+ // TODO(b/145578432): Add support for byte fields.
+ base::Status ParseMessage(const protozero::ConstBytes& cb,
+ const std::string& type,
+ const std::vector<uint16_t>* allowed_fields,
+ Delegate& delegate,
+ int* unknown_extensions = nullptr);
+
+ // This class is responsible for resetting the current key prefix to the old
+ // value when deleted or reset.
+ struct ScopedNestedKeyContext {
+ public:
+ ~ScopedNestedKeyContext();
+ ScopedNestedKeyContext(ScopedNestedKeyContext&&);
+ ScopedNestedKeyContext(const ScopedNestedKeyContext&) = delete;
+ ScopedNestedKeyContext& operator=(const ScopedNestedKeyContext&) = delete;
+
+ const Key& key() const { return key_; }
+
+ // Clear this context, which strips the latest suffix from |key_| and sets
+ // it to the state before the nested context was created.
+ void RemoveFieldSuffix();
+
+ private:
+ friend class ProtoToArgsParser;
+
+ ScopedNestedKeyContext(Key& old_value);
+
+ struct ScopedStringAppender;
+
+ Key& key_;
+ base::Optional<size_t> old_flat_key_length_ = base::nullopt;
+ base::Optional<size_t> old_key_length_ = base::nullopt;
+ };
+
+ // These methods can be called from parsing overrides to enter nested
+ // contexts. The contexts are left when the returned scope is destroyed or
+ // RemoveFieldSuffix() is called.
+ ScopedNestedKeyContext EnterDictionary(const std::string& key);
+ ScopedNestedKeyContext EnterArray(size_t index);
+
+ using ParsingOverrideForField =
std::function<base::Optional<base::Status>(const protozero::Field&,
Delegate& delegate)>;
@@ -132,47 +198,74 @@ class ProtoToArgsParser {
// To override the handling of both SubMessage fields you must add two parsing
// overrides. One with a |field_path| == "field1.field" and another with
// "field2.field".
- void AddParsingOverride(std::string field_path,
- ParsingOverride parsing_override);
+ void AddParsingOverrideForField(const std::string& field_path,
+ ParsingOverrideForField parsing_override);
- // Given a view of bytes that represent a serialized protozero message of
- // |type| we will parse each field.
+ using ParsingOverrideForType = std::function<base::Optional<base::Status>(
+ ScopedNestedKeyContext& key,
+ const protozero::ConstBytes& data,
+ Delegate& delegate)>;
+
+ // Installs an override for all fields with the given type. We will invoke
+ // |parsing_override| when a field with the given message type is encountered.
+ // Note that the path-based overrides take precedence over type overrides.
//
- // Returns on any error with a status describing the problem. However any
- // added values before encountering the error will be parsed and forwarded to
- // the delegate.
+ // The return value of |parsing_override| indicates whether the override
+ // parsed the sub-message and ProtoToArgsParser should skip it (base::nullopt)
+ // or the sub-message should continue to be parsed by ProtoToArgsParser using
+ // the descriptor (base::Status).
//
- // Fields with ids given in |fields| are parsed using reflection, as well
- // as known (previously registered) extension fields. If |allowed_fields| is a
- // nullptr, all fields are going to be parsed.
//
- // Note:
- // |type| must be the fully qualified name, but with a '.' added to the
- // beginning. I.E. ".perfetto.protos.TrackEvent". And must match one of the
- // descriptors already added through |AddProtoFileDescriptor|.
+ // For example, given the following protos and a type override for SubMessage,
+ // all three fields will be parsed using this override.
//
- // IMPORTANT: currently bytes fields are not supported.
+ // message SubMessage {
+ // optional int32 value = 1;
+ // }
//
- // TODO(b/145578432): Add support for byte fields.
- base::Status ParseMessage(const protozero::ConstBytes& cb,
- const std::string& type,
- const std::vector<uint16_t>* allowed_fields,
- Delegate& delegate);
+ // message MainMessage1 {
+ // optional SubMessage field1 = 1;
+ // optional SubMessage field2 = 2;
+ // }
+ //
+ // message MainMessage2 {
+ // optional SubMessage field3 = 1;
+ // }
+ void AddParsingOverrideForType(const std::string& message_type,
+ ParsingOverrideForType parsing_override);
private:
base::Status ParseField(const FieldDescriptor& field_descriptor,
int repeated_field_number,
protozero::Field field,
- Delegate& delegate);
+ Delegate& delegate,
+ int* unknown_extensions);
+
+ base::Optional<base::Status> MaybeApplyOverrideForField(
+ const protozero::Field&,
+ Delegate& delegate);
+
+ base::Optional<base::Status> MaybeApplyOverrideForType(
+ const std::string& message_type,
+ ScopedNestedKeyContext& key,
+ const protozero::ConstBytes& data,
+ Delegate& delegate);
- base::Optional<base::Status> MaybeApplyOverride(const protozero::Field&,
- Delegate& delegate);
+ // A type override can call |key.RemoveFieldSuffix()| if it wants to exclude
+ // the overriden field's name from the parsed args' keys.
+ base::Status ParseMessageInternal(ScopedNestedKeyContext& key,
+ const protozero::ConstBytes& cb,
+ const std::string& type,
+ const std::vector<uint16_t>* fields,
+ Delegate& delegate,
+ int* unknown_extensions);
base::Status ParseSimpleField(const FieldDescriptor& desciptor,
const protozero::Field& field,
Delegate& delegate);
- std::unordered_map<std::string, ParsingOverride> overrides_;
+ std::unordered_map<std::string, ParsingOverrideForField> field_overrides_;
+ std::unordered_map<std::string, ParsingOverrideForType> type_overrides_;
const DescriptorPool& pool_;
Key key_prefix_;
};
diff --git a/src/trace_processor/util/proto_to_args_parser_unittest.cc b/src/trace_processor/util/proto_to_args_parser_unittest.cc
index 89ee9459b..48e5d8131 100644
--- a/src/trace_processor/util/proto_to_args_parser_unittest.cc
+++ b/src/trace_processor/util/proto_to_args_parser_unittest.cc
@@ -18,12 +18,13 @@
#include "perfetto/ext/base/string_view.h"
#include "perfetto/protozero/scattered_heap_buffer.h"
+#include "perfetto/trace_processor/trace_blob.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
#include "protos/perfetto/common/descriptor.pbzero.h"
#include "protos/perfetto/trace/track_event/source_location.pbzero.h"
#include "src/protozero/test/example_proto/test_messages.pbzero.h"
-#include "src/trace_processor/importers/common/trace_blob_view.h"
-#include "src/trace_processor/importers/proto/packet_sequence_state.h"
#include "src/trace_processor/test_messages.descriptor.h"
+#include "src/trace_processor/util/interned_message_view.h"
#include "test/gtest_and_gmock.h"
#include <sstream>
@@ -35,10 +36,9 @@ namespace {
constexpr size_t kChunkSize = 42;
-using ::testing::_;
-using ::testing::Eq;
-using ::testing::Invoke;
-using ::testing::NiceMock;
+protozero::ConstChars ToChars(const char* str) {
+ return protozero::ConstChars{str, strlen(str)};
+}
class ProtoToArgsParserTest : public ::testing::Test,
public ProtoToArgsParser::Delegate {
@@ -92,13 +92,24 @@ class ProtoToArgsParserTest : public ::testing::Test,
args_.push_back(ss.str());
}
- void AddJson(const Key& key, const protozero::ConstChars& value) override {
+ bool AddJson(const Key& key, const protozero::ConstChars& value) override {
std::stringstream ss;
ss << key.flat_key << " " << key.key << " " << std::hex
<< value.ToStdString() << std::dec;
args_.push_back(ss.str());
+ return true;
}
+ void AddNull(const Key& key) override {
+ std::stringstream ss;
+ ss << key.flat_key << " " << key.key << " [NULL]";
+ args_.push_back(ss.str());
+ }
+
+ size_t GetArrayEntryIndex(const std::string&) final { return 0; }
+
+ size_t IncrementArrayEntryIndex(const std::string&) final { return 0; }
+
InternedMessageView* GetInternedMessageView(uint32_t field_id,
uint64_t iid) override {
if (field_id != protos::pbzero::InternedData::kSourceLocationsFieldNumber)
@@ -249,7 +260,7 @@ TEST_F(ProtoToArgsParserTest, NestedProtoParsingOverrideHandled) {
ASSERT_TRUE(status.ok()) << "Failed to parse kTestMessagesDescriptor: "
<< status.message();
- parser.AddParsingOverride(
+ parser.AddParsingOverrideForField(
"super_nested.value_c",
[](const protozero::Field& field, ProtoToArgsParser::Delegate& writer) {
EXPECT_EQ(field.type(), protozero::proto_utils::ProtoWireType::kVarInt);
@@ -285,7 +296,7 @@ TEST_F(ProtoToArgsParserTest, NestedProtoParsingOverrideSkipped) {
ASSERT_TRUE(status.ok()) << "Failed to parse kTestMessagesDescriptor: "
<< status.message();
- parser.AddParsingOverride(
+ parser.AddParsingOverrideForField(
"super_nested.value_c",
[](const protozero::Field& field, ProtoToArgsParser::Delegate&) {
static int val = 0;
@@ -324,8 +335,9 @@ TEST_F(ProtoToArgsParserTest, LookingUpInternedStateParsingOverride) {
for (size_t i = 0; i < binary_data.size(); ++i) {
buffer.get()[i] = binary_data[i];
}
- TraceBlobView blob(std::move(buffer), 0, binary_data.size());
- AddInternedSourceLocation(kIid, std::move(blob));
+ TraceBlob blob =
+ TraceBlob::TakeOwnership(std::move(buffer), binary_data.size());
+ AddInternedSourceLocation(kIid, TraceBlobView(std::move(blob)));
DescriptorPool pool;
auto status = pool.AddFromFileDescriptorSet(kTestMessagesDescriptor.data(),
@@ -336,7 +348,7 @@ TEST_F(ProtoToArgsParserTest, LookingUpInternedStateParsingOverride) {
ProtoToArgsParser parser(pool);
// Now we override the behaviour of |value_c| so we can expand the iid into
// multiple args rows.
- parser.AddParsingOverride(
+ parser.AddParsingOverrideForField(
"super_nested.value_c",
[](const protozero::Field& field, ProtoToArgsParser::Delegate& delegate)
-> base::Optional<base::Status> {
@@ -362,6 +374,152 @@ TEST_F(ProtoToArgsParserTest, LookingUpInternedStateParsingOverride) {
"line_number line_number 2"));
}
+TEST_F(ProtoToArgsParserTest, OverrideForType) {
+ using namespace protozero::test::protos::pbzero;
+ protozero::HeapBuffered<NestedA> msg{kChunkSize, kChunkSize};
+ msg->set_super_nested()->set_value_c(3);
+
+ auto binary_proto = msg.SerializeAsArray();
+
+ DescriptorPool pool;
+ auto status = pool.AddFromFileDescriptorSet(kTestMessagesDescriptor.data(),
+ kTestMessagesDescriptor.size());
+ ASSERT_TRUE(status.ok()) << "Failed to parse kTestMessagesDescriptor: "
+ << status.message();
+
+ ProtoToArgsParser parser(pool);
+
+ parser.AddParsingOverrideForType(
+ ".protozero.test.protos.NestedA.NestedB.NestedC",
+ [](ProtoToArgsParser::ScopedNestedKeyContext&,
+ const protozero::ConstBytes&, Delegate& delegate) {
+ delegate.AddInteger(ProtoToArgsParser::Key("arg"), 42);
+ return base::OkStatus();
+ });
+
+ status = parser.ParseMessage(
+ protozero::ConstBytes{binary_proto.data(), binary_proto.size()},
+ ".protozero.test.protos.NestedA", nullptr, *this);
+ EXPECT_TRUE(status.ok())
+ << "InternProtoFieldsIntoArgsTable failed with error: "
+ << status.message();
+ EXPECT_THAT(args(), testing::ElementsAre("arg arg 42"));
+}
+
+TEST_F(ProtoToArgsParserTest, FieldOverrideTakesPrecedence) {
+ using namespace protozero::test::protos::pbzero;
+ protozero::HeapBuffered<NestedA> msg{kChunkSize, kChunkSize};
+ msg->set_super_nested()->set_value_c(3);
+
+ auto binary_proto = msg.SerializeAsArray();
+
+ DescriptorPool pool;
+ auto status = pool.AddFromFileDescriptorSet(kTestMessagesDescriptor.data(),
+ kTestMessagesDescriptor.size());
+ ASSERT_TRUE(status.ok()) << "Failed to parse kTestMessagesDescriptor: "
+ << status.message();
+
+ ProtoToArgsParser parser(pool);
+
+ parser.AddParsingOverrideForField(
+ "super_nested",
+ [](const protozero::Field&, ProtoToArgsParser::Delegate& writer) {
+ writer.AddString(ProtoToArgsParser::Key("arg"),
+ ToChars("override-for-field"));
+ return base::OkStatus();
+ });
+
+ parser.AddParsingOverrideForType(
+ ".protozero.test.protos.NestedA.NestedB.NestedC",
+ [](ProtoToArgsParser::ScopedNestedKeyContext&,
+ const protozero::ConstBytes&, Delegate& delegate) {
+ delegate.AddString(ProtoToArgsParser::Key("arg"),
+ ToChars("override-for-type"));
+ return base::OkStatus();
+ });
+
+ status = parser.ParseMessage(
+ protozero::ConstBytes{binary_proto.data(), binary_proto.size()},
+ ".protozero.test.protos.NestedA", nullptr, *this);
+ EXPECT_TRUE(status.ok())
+ << "InternProtoFieldsIntoArgsTable failed with error: "
+ << status.message();
+ EXPECT_THAT(args(), testing::ElementsAre("arg arg override-for-field"));
+}
+
+TEST_F(ProtoToArgsParserTest, EmptyMessage) {
+ using namespace protozero::test::protos::pbzero;
+ protozero::HeapBuffered<NestedA> msg{kChunkSize, kChunkSize};
+ msg->set_super_nested();
+
+ auto binary_proto = msg.SerializeAsArray();
+
+ DescriptorPool pool;
+ auto status = pool.AddFromFileDescriptorSet(kTestMessagesDescriptor.data(),
+ kTestMessagesDescriptor.size());
+ ASSERT_TRUE(status.ok()) << "Failed to parse kTestMessagesDescriptor: "
+ << status.message();
+
+ ProtoToArgsParser parser(pool);
+ status = parser.ParseMessage(
+ protozero::ConstBytes{binary_proto.data(), binary_proto.size()},
+ ".protozero.test.protos.NestedA", nullptr, *this);
+ EXPECT_TRUE(status.ok())
+ << "InternProtoFieldsIntoArgsTable failed with error: "
+ << status.message();
+ EXPECT_THAT(args(), testing::ElementsAre("super_nested super_nested [NULL]"));
+}
+
+TEST_F(ProtoToArgsParserTest, WidthAndSignednessOfScalars) {
+ using namespace protozero::test::protos::pbzero;
+ protozero::HeapBuffered<EveryField> msg{kChunkSize, kChunkSize};
+
+ // Set fields to values with the top bit set, and check that the parser
+ // retains the full value with the correct sign.
+ msg->set_field_int32(-0x80000000ll);
+ msg->set_field_sint32(-0x80000000ll);
+ msg->set_field_sfixed32(-0x80000000ll);
+
+ msg->set_field_uint32(0x80000000ull);
+ msg->set_field_fixed32(0x80000000ull);
+
+ msg->set_field_int64(-0x7FFFFFFFFFFFFFFFll - 1);
+ msg->set_field_sint64(-0x7FFFFFFFFFFFFFFFll - 1);
+ msg->set_field_sfixed64(-0x7FFFFFFFFFFFFFFFll - 1);
+
+ msg->set_field_uint64(0x8000000000000000ull);
+ msg->set_field_fixed64(0x8000000000000000ull);
+
+ auto binary_proto = msg.SerializeAsArray();
+
+ DescriptorPool pool;
+ auto status = pool.AddFromFileDescriptorSet(kTestMessagesDescriptor.data(),
+ kTestMessagesDescriptor.size());
+ ProtoToArgsParser parser(pool);
+ ASSERT_TRUE(status.ok()) << "Failed to parse kTestMessagesDescriptor: "
+ << status.message();
+
+ status = parser.ParseMessage(
+ protozero::ConstBytes{binary_proto.data(), binary_proto.size()},
+ ".protozero.test.protos.EveryField", nullptr, *this);
+
+ EXPECT_TRUE(status.ok())
+ << "InternProtoFieldsIntoArgsTable failed with error: "
+ << status.message();
+
+ EXPECT_THAT(args(), testing::ElementsAre(
+ "field_int32 field_int32 -2147483648",
+ "field_sint32 field_sint32 -2147483648",
+ "field_sfixed32 field_sfixed32 -2147483648",
+ "field_uint32 field_uint32 2147483648",
+ "field_fixed32 field_fixed32 2147483648",
+ "field_int64 field_int64 -9223372036854775808",
+ "field_sint64 field_sint64 -9223372036854775808",
+ "field_sfixed64 field_sfixed64 -9223372036854775808",
+ "field_uint64 field_uint64 9223372036854775808",
+ "field_fixed64 field_fixed64 9223372036854775808"));
+}
+
} // namespace
} // namespace util
} // namespace trace_processor
diff --git a/src/trace_processor/util/proto_to_json.cc b/src/trace_processor/util/proto_to_json.cc
index ff430c79f..700357feb 100644
--- a/src/trace_processor/util/proto_to_json.cc
+++ b/src/trace_processor/util/proto_to_json.cc
@@ -30,6 +30,41 @@ namespace proto_to_json {
namespace {
+std::string QuoteAndEscapeJsonString(const std::string& raw) {
+ std::string ret;
+ for (auto it = raw.cbegin(); it != raw.cend(); it++) {
+ char c = *it;
+ switch (c) {
+ case '"':
+ // Double quote needs to be escaped.
+ ret += "\\\"";
+ break;
+ case '\n':
+ // Escape new line specially because it appears often and so is worth
+ // treating specially.
+ ret += "\\n";
+ break;
+ default:
+ if (c < 0x20) {
+ // All 32 ASCII control codes need to be escaped. Instead of using the
+ // short forms, we just always use \u escape sequences instead to make
+ // things simpler.
+ ret += "\\u00";
+
+ // Print |c| as a hex character. We reserve 3 bytes of space: 2 for
+ // the hex code and one for the null terminator.
+ base::StackString<3> buf("%02X", c);
+ ret += buf.c_str();
+ } else {
+ // Everything else can be passed through directly.
+ ret += c;
+ }
+ break;
+ }
+ }
+ return '"' + ret + '"';
+}
+
std::string FieldToJson(const google::protobuf::Message& message,
const google::protobuf::FieldDescriptor* field_desc,
int idx,
@@ -44,7 +79,7 @@ std::string FieldToJson(const google::protobuf::Message& message,
? ref->GetRepeatedBool(message, field_desc, idx)
: ref->GetBool(message, field_desc));
case FieldDescriptor::CppType::CPPTYPE_ENUM:
- return base::QuoteAndEscapeControlCodes(
+ return QuoteAndEscapeJsonString(
is_repeated ? ref->GetRepeatedEnum(message, field_desc, idx)->name()
: ref->GetEnum(message, field_desc)->name());
case FieldDescriptor::CppType::CPPTYPE_FLOAT:
@@ -66,7 +101,7 @@ std::string FieldToJson(const google::protobuf::Message& message,
is_repeated ? ref->GetRepeatedDouble(message, field_desc, idx)
: ref->GetDouble(message, field_desc));
case FieldDescriptor::CppType::CPPTYPE_STRING:
- return base::QuoteAndEscapeControlCodes(
+ return QuoteAndEscapeJsonString(
is_repeated ? ref->GetRepeatedString(message, field_desc, idx)
: ref->GetString(message, field_desc));
case FieldDescriptor::CppType::CPPTYPE_UINT32:
diff --git a/src/trace_processor/util/protozero_to_text.cc b/src/trace_processor/util/protozero_to_text.cc
index 43cf9b5f0..3b774e295 100644
--- a/src/trace_processor/util/protozero_to_text.cc
+++ b/src/trace_processor/util/protozero_to_text.cc
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
#include "src/trace_processor/util/protozero_to_text.h"
#include "perfetto/ext/base/string_utils.h"
@@ -16,146 +32,327 @@ namespace protozero_to_text {
namespace {
-std::string BytesToHexEncodedString(const std::string& bytes) {
- // Each byte becomes four chars 'A' -> "\x41" + 1 for trailing null.
- std::string value(4 * bytes.size() + 1, 'Z');
- for (size_t i = 0; i < bytes.size(); ++i) {
- // snprintf prints 5 characters: '\x', then two hex digits, and finally a
- // null byte. As we write left to right, we keep overwriting the null
- // byte, except for the last call to snprintf.
- snprintf(&(value[4 * i]), 5, "\\x%02hhx", bytes[i]);
- }
- // Trim trailing null.
- value.resize(4 * bytes.size());
- return value;
-}
+using protozero::proto_utils::ProtoWireType;
+using FieldDescriptorProto = protos::pbzero::FieldDescriptorProto;
-// Recursively determine the size of all the string like things passed in the
-// parameter pack |rest|.
-size_t SizeOfStr() {
- return 0;
-}
-template <typename T, typename... Rest>
-size_t SizeOfStr(const T& first, Rest... rest) {
- return base::StringView(first).size() + SizeOfStr(rest...);
+// This function matches the implementation of TextFormatEscaper.escapeBytes
+// from the Java protobuf library.
+std::string QuoteAndEscapeTextProtoString(const std::string& raw) {
+ std::string ret;
+ for (auto it = raw.cbegin(); it != raw.cend(); it++) {
+ switch (*it) {
+ case '\a':
+ ret += "\\a";
+ break;
+ case '\b':
+ ret += "\\b";
+ break;
+ case '\f':
+ ret += "\\f";
+ break;
+ case '\n':
+ ret += "\\n";
+ break;
+ case '\r':
+ ret += "\\r";
+ break;
+ case '\t':
+ ret += "\\t";
+ break;
+ case '\v':
+ ret += "\\v";
+ break;
+ case '\\':
+ ret += "\\\\";
+ break;
+ case '\'':
+ ret += "\\\'";
+ break;
+ case '"':
+ ret += "\\\"";
+ break;
+ default:
+ // Only ASCII characters between 0x20 (space) and 0x7e (tilde) are
+ // printable; other byte values are escaped with 3-character octal
+ // codes.
+ if (*it >= 0x20 && *it <= 0x7e) {
+ ret += *it;
+ } else {
+ ret += '\\';
+
+ // Cast to unsigned char to make the right shift unsigned as well.
+ unsigned char c = static_cast<unsigned char>(*it);
+ ret += ('0' + ((c >> 6) & 3));
+ ret += ('0' + ((c >> 3) & 7));
+ ret += ('0' + (c & 7));
+ }
+ break;
+ }
+ }
+ return '"' + ret + '"';
}
// Append |to_add| which is something string like to |out|.
template <typename T>
-void StrAppendInternal(std::string* out, const T& to_add) {
+void StrAppend(std::string* out, const T& to_add) {
out->append(to_add);
}
template <typename T, typename... strings>
-void StrAppendInternal(std::string* out, const T& first, strings... values) {
- StrAppendInternal(out, first);
- StrAppendInternal(out, values...);
+void StrAppend(std::string* out, const T& first, strings... values) {
+ StrAppend(out, first);
+ StrAppend(out, values...);
}
-// Append |to_add| which is something string like to |out|.
-template <typename T>
-void StrAppend(std::string* out, const T& to_add) {
- out->reserve(out->size() + base::StringView(to_add).size());
- out->append(to_add);
+void IncreaseIndents(std::string* out) {
+ StrAppend(out, " ");
}
-template <typename T, typename... strings>
-void StrAppend(std::string* out, const T& first, strings... values) {
- out->reserve(out->size() + SizeOfStr(values...));
- StrAppendInternal(out, first);
- StrAppendInternal(out, values...);
+void DecreaseIndents(std::string* out) {
+ PERFETTO_DCHECK(out->size() >= 2);
+ out->erase(out->size() - 2);
}
-void ConvertProtoTypeToFieldAndValueString(const FieldDescriptor& fd,
- const protozero::Field& field,
- const std::string& separator,
- const std::string& indent,
- const DescriptorPool& pool,
- std::string* out) {
- using FieldDescriptorProto = protos::pbzero::FieldDescriptorProto;
- switch (fd.type()) {
+std::string FormattedFieldDescriptorName(
+ const FieldDescriptor& field_descriptor) {
+ if (field_descriptor.is_extension()) {
+ // Libprotobuf formatter always formats extension field names as fully
+ // qualified names.
+ // TODO(b/197625974): Assuming for now all our extensions will belong to the
+ // perfetto.protos package. Update this if we ever want to support extendees
+ // in different package.
+ return "[perfetto.protos." + field_descriptor.name() + "]";
+ } else {
+ return field_descriptor.name();
+ }
+}
+
+void PrintVarIntField(const FieldDescriptor* fd,
+ const protozero::Field& field,
+ const DescriptorPool& pool,
+ std::string* out) {
+ uint32_t type = fd ? fd->type() : 0;
+ switch (type) {
case FieldDescriptorProto::TYPE_INT32:
- case FieldDescriptorProto::TYPE_SFIXED32:
- case FieldDescriptorProto::TYPE_FIXED32:
- StrAppend(out, separator, indent, fd.name(), ": ",
- std::to_string(field.as_int32()));
+ StrAppend(out, fd->name(), ": ", std::to_string(field.as_int32()));
return;
case FieldDescriptorProto::TYPE_SINT32:
- StrAppend(out, separator, indent, fd.name(), ": ",
- std::to_string(field.as_sint32()));
+ StrAppend(out, fd->name(), ": ", std::to_string(field.as_sint32()));
+ return;
+ case FieldDescriptorProto::TYPE_UINT32:
+ StrAppend(out, fd->name(), ": ", std::to_string(field.as_uint32()));
return;
case FieldDescriptorProto::TYPE_INT64:
- case FieldDescriptorProto::TYPE_SFIXED64:
- case FieldDescriptorProto::TYPE_FIXED64:
- StrAppend(out, separator, indent, fd.name(), ": ",
- std::to_string(field.as_int64()));
+ StrAppend(out, fd->name(), ": ", std::to_string(field.as_int64()));
return;
case FieldDescriptorProto::TYPE_SINT64:
- StrAppend(out, separator, indent, fd.name(), ": ",
- std::to_string(field.as_sint64()));
- return;
- case FieldDescriptorProto::TYPE_UINT32:
- StrAppend(out, separator, indent, fd.name(), ": ",
- std::to_string(field.as_uint32()));
+ StrAppend(out, fd->name(), ": ", std::to_string(field.as_sint64()));
return;
case FieldDescriptorProto::TYPE_UINT64:
- StrAppend(out, separator, indent, fd.name(), ": ",
- std::to_string(field.as_uint64()));
+ StrAppend(out, fd->name(), ": ", std::to_string(field.as_uint64()));
return;
case FieldDescriptorProto::TYPE_BOOL:
- StrAppend(out, separator, indent, fd.name(), ": ",
- field.as_bool() ? "true" : "false");
+ StrAppend(out, fd->name(), ": ", field.as_bool() ? "true" : "false");
return;
- case FieldDescriptorProto::TYPE_DOUBLE:
- StrAppend(out, separator, indent, fd.name(), ": ",
- std::to_string(field.as_double()));
- return;
- case FieldDescriptorProto::TYPE_FLOAT:
- StrAppend(out, separator, indent, fd.name(), ": ",
- std::to_string(field.as_float()));
- return;
- case FieldDescriptorProto::TYPE_STRING: {
- auto s = base::QuoteAndEscapeControlCodes(field.as_std_string());
- StrAppend(out, separator, indent, fd.name(), ": ", s);
- return;
- }
- case FieldDescriptorProto::TYPE_BYTES: {
- std::string value = BytesToHexEncodedString(field.as_std_string());
- StrAppend(out, separator, indent, fd.name(), ": \"", value, "\"");
- return;
- }
case FieldDescriptorProto::TYPE_ENUM: {
+ // If the enum value is unknown, treat it like a completely unknown field.
auto opt_enum_descriptor_idx =
- pool.FindDescriptorIdx(fd.resolved_type_name());
- PERFETTO_DCHECK(opt_enum_descriptor_idx);
+ pool.FindDescriptorIdx(fd->resolved_type_name());
+ if (!opt_enum_descriptor_idx)
+ break;
auto opt_enum_string =
pool.descriptors()[*opt_enum_descriptor_idx].FindEnumString(
field.as_int32());
- PERFETTO_DCHECK(opt_enum_string);
- StrAppend(out, separator, indent, fd.name(), ": ", *opt_enum_string);
+ if (!opt_enum_string)
+ break;
+ StrAppend(out, fd->name(), ": ", *opt_enum_string);
return;
}
- default: {
- PERFETTO_FATAL(
- "Tried to write value of type field %s (in proto type "
- "%s) which has type enum %d",
- fd.name().c_str(), fd.resolved_type_name().c_str(), fd.type());
- }
+ case 0:
+ default:
+ break;
}
+ StrAppend(out, std::to_string(field.id()), ": ",
+ std::to_string(field.as_uint64()));
}
-void IncreaseIndents(std::string* out) {
- StrAppend(out, " ");
+void PrintFixed32Field(const FieldDescriptor* fd,
+ const protozero::Field& field,
+ std::string* out) {
+ uint32_t type = fd ? fd->type() : 0;
+ switch (type) {
+ case FieldDescriptorProto::TYPE_SFIXED32:
+ StrAppend(out, fd->name(), ": ", std::to_string(field.as_int32()));
+ break;
+ case FieldDescriptorProto::TYPE_FIXED32:
+ StrAppend(out, fd->name(), ": ", std::to_string(field.as_uint32()));
+ break;
+ case FieldDescriptorProto::TYPE_FLOAT:
+ StrAppend(out, fd->name(), ": ", std::to_string(field.as_float()));
+ break;
+ case 0:
+ default:
+ base::StackString<12> padded_hex("0x%08" PRIx32, field.as_uint32());
+ StrAppend(out, std::to_string(field.id()), ": ", padded_hex.c_str());
+ break;
+ }
}
-void DecreaseIndents(std::string* out) {
- PERFETTO_DCHECK(out->size() >= 2);
- out->erase(out->size() - 2);
+void PrintFixed64Field(const FieldDescriptor* fd,
+ const protozero::Field& field,
+ std::string* out) {
+ uint32_t type = fd ? fd->type() : 0;
+ switch (type) {
+ case FieldDescriptorProto::TYPE_SFIXED64:
+ StrAppend(out, fd->name(), ": ", std::to_string(field.as_int64()));
+ break;
+ case FieldDescriptorProto::TYPE_FIXED64:
+ StrAppend(out, fd->name(), ": ", std::to_string(field.as_uint64()));
+ break;
+ case FieldDescriptorProto::TYPE_DOUBLE:
+ StrAppend(out, fd->name(), ": ", std::to_string(field.as_double()));
+ break;
+ case 0:
+ default:
+ base::StackString<20> padded_hex("0x%016" PRIx64, field.as_uint64());
+ StrAppend(out, std::to_string(field.id()), ": ", padded_hex.c_str());
+ break;
+ }
+}
+
+void ProtozeroToTextInternal(const std::string& type,
+ protozero::ConstBytes protobytes,
+ NewLinesMode new_lines_mode,
+ const DescriptorPool& pool,
+ std::string* indents,
+ std::string* output);
+
+template <protozero::proto_utils::ProtoWireType wire_type, typename T>
+void PrintPackedField(const FieldDescriptor& fd,
+ const protozero::Field& field,
+ NewLinesMode new_lines_mode,
+ const std::string& indents,
+ std::string* out) {
+ const bool include_new_lines = new_lines_mode == kIncludeNewLines;
+ bool err = false;
+ bool first_output = true;
+ for (protozero::PackedRepeatedFieldIterator<wire_type, T> it(
+ field.data(), field.size(), &err);
+ it; it++) {
+ T value = *it;
+ if (!first_output) {
+ if (include_new_lines) {
+ StrAppend(out, "\n", indents);
+ } else {
+ StrAppend(out, " ");
+ }
+ }
+ StrAppend(out, fd.name(), ": ", std::to_string(value));
+ first_output = false;
+ }
+
+ if (err) {
+ if (!first_output) {
+ if (include_new_lines) {
+ StrAppend(out, "\n", indents);
+ } else {
+ StrAppend(out, " ");
+ }
+ }
+ StrAppend(out, "# Packed decoding failure for field ", fd.name(), "\n");
+ }
+}
+
+void PrintLengthDelimitedField(const FieldDescriptor* fd,
+ const protozero::Field& field,
+ NewLinesMode new_lines_mode,
+ std::string* indents,
+ const DescriptorPool& pool,
+ std::string* out) {
+ const bool include_new_lines = new_lines_mode == kIncludeNewLines;
+ uint32_t type = fd ? fd->type() : 0;
+ switch (type) {
+ case FieldDescriptorProto::TYPE_BYTES:
+ case FieldDescriptorProto::TYPE_STRING: {
+ std::string value = QuoteAndEscapeTextProtoString(field.as_std_string());
+ StrAppend(out, fd->name(), ": ", value);
+ return;
+ }
+ case FieldDescriptorProto::TYPE_MESSAGE:
+ StrAppend(out, FormattedFieldDescriptorName(*fd), " {");
+ if (include_new_lines) {
+ IncreaseIndents(indents);
+ }
+ ProtozeroToTextInternal(fd->resolved_type_name(), field.as_bytes(),
+ new_lines_mode, pool, indents, out);
+ if (include_new_lines) {
+ DecreaseIndents(indents);
+ StrAppend(out, "\n", *indents, "}");
+ } else {
+ StrAppend(out, " }");
+ }
+ return;
+ case FieldDescriptorProto::TYPE_DOUBLE:
+ PrintPackedField<protozero::proto_utils::ProtoWireType::kFixed64, double>(
+ *fd, field, new_lines_mode, *indents, out);
+ return;
+ case FieldDescriptorProto::TYPE_FLOAT:
+ PrintPackedField<protozero::proto_utils::ProtoWireType::kFixed32, float>(
+ *fd, field, new_lines_mode, *indents, out);
+ return;
+ case FieldDescriptorProto::TYPE_INT64:
+ PrintPackedField<protozero::proto_utils::ProtoWireType::kVarInt, int64_t>(
+ *fd, field, new_lines_mode, *indents, out);
+ return;
+ case FieldDescriptorProto::TYPE_UINT64:
+ PrintPackedField<protozero::proto_utils::ProtoWireType::kVarInt,
+ uint64_t>(*fd, field, new_lines_mode, *indents, out);
+ return;
+ case FieldDescriptorProto::TYPE_INT32:
+ PrintPackedField<protozero::proto_utils::ProtoWireType::kVarInt, int32_t>(
+ *fd, field, new_lines_mode, *indents, out);
+ return;
+ case FieldDescriptorProto::TYPE_FIXED64:
+ PrintPackedField<protozero::proto_utils::ProtoWireType::kFixed64,
+ uint64_t>(*fd, field, new_lines_mode, *indents, out);
+ return;
+ case FieldDescriptorProto::TYPE_FIXED32:
+ PrintPackedField<protozero::proto_utils::ProtoWireType::kFixed32,
+ uint32_t>(*fd, field, new_lines_mode, *indents, out);
+ return;
+ case FieldDescriptorProto::TYPE_UINT32:
+ PrintPackedField<protozero::proto_utils::ProtoWireType::kVarInt,
+ uint32_t>(*fd, field, new_lines_mode, *indents, out);
+ return;
+ case FieldDescriptorProto::TYPE_SFIXED32:
+ PrintPackedField<protozero::proto_utils::ProtoWireType::kFixed32,
+ int32_t>(*fd, field, new_lines_mode, *indents, out);
+ return;
+ case FieldDescriptorProto::TYPE_SFIXED64:
+ PrintPackedField<protozero::proto_utils::ProtoWireType::kFixed64,
+ int64_t>(*fd, field, new_lines_mode, *indents, out);
+ return;
+ // Our protoc plugin cannot generate code for packed repeated fields with
+ // these types. Output a comment and then fall back to the raw field_id:
+ // string representation.
+ case FieldDescriptorProto::TYPE_BOOL:
+ case FieldDescriptorProto::TYPE_ENUM:
+ case FieldDescriptorProto::TYPE_SINT32:
+ case FieldDescriptorProto::TYPE_SINT64:
+ StrAppend(out, "# Packed type ", std::to_string(type),
+ " not supported. Printing raw string.", "\n", *indents);
+ break;
+ case 0:
+ default:
+ break;
+ }
+ std::string value = QuoteAndEscapeTextProtoString(field.as_std_string());
+ StrAppend(out, std::to_string(field.id()), ": ", value);
}
// Recursive case function, Will parse |protobytes| assuming it is a proto of
// |type| and will use |pool| to look up the |type|. All output will be placed
-// in |output| and between fields |separator| will be placed. When called for
+// in |output|, using |new_lines_mode| to separate fields. When called for
// |indents| will be increased by 2 spaces to improve readability.
void ProtozeroToTextInternal(const std::string& type,
protozero::ConstBytes protobytes,
@@ -166,44 +363,35 @@ void ProtozeroToTextInternal(const std::string& type,
auto opt_proto_descriptor_idx = pool.FindDescriptorIdx(type);
PERFETTO_DCHECK(opt_proto_descriptor_idx);
auto& proto_descriptor = pool.descriptors()[*opt_proto_descriptor_idx];
- bool include_new_lines = new_lines_mode == kIncludeNewLines;
+ const bool include_new_lines = new_lines_mode == kIncludeNewLines;
protozero::ProtoDecoder decoder(protobytes.data, protobytes.size);
for (auto field = decoder.ReadField(); field.valid();
field = decoder.ReadField()) {
- auto opt_field_descriptor = proto_descriptor.FindFieldByTag(field.id());
- if (!opt_field_descriptor) {
- StrAppend(
- output, output->empty() ? "" : "\n", *indents,
- "# Ignoring unknown field with id: ", std::to_string(field.id()));
- continue;
- }
- const auto& field_descriptor = *opt_field_descriptor;
-
- if (field_descriptor.type() ==
- protos::pbzero::FieldDescriptorProto::TYPE_MESSAGE) {
+ if (!output->empty()) {
if (include_new_lines) {
- StrAppend(output, output->empty() ? "" : "\n", *indents,
- field_descriptor.name(), ": {");
- IncreaseIndents(indents);
+ StrAppend(output, "\n", *indents);
} else {
- StrAppend(output, output->empty() ? "" : " ", field_descriptor.name(),
- ": {");
- }
- ProtozeroToTextInternal(field_descriptor.resolved_type_name(),
- field.as_bytes(), new_lines_mode, pool, indents,
- output);
- if (include_new_lines) {
- DecreaseIndents(indents);
- StrAppend(output, "\n", *indents, "}");
- } else {
- StrAppend(output, " }");
+ StrAppend(output, " ", *indents);
}
} else {
- ConvertProtoTypeToFieldAndValueString(
- field_descriptor, field,
- output->empty() ? "" : include_new_lines ? "\n" : " ", *indents, pool,
- output);
+ StrAppend(output, *indents);
+ }
+ auto* opt_field_descriptor = proto_descriptor.FindFieldByTag(field.id());
+ switch (field.type()) {
+ case ProtoWireType::kVarInt:
+ PrintVarIntField(opt_field_descriptor, field, pool, output);
+ break;
+ case ProtoWireType::kLengthDelimited:
+ PrintLengthDelimitedField(opt_field_descriptor, field, new_lines_mode,
+ indents, pool, output);
+ break;
+ case ProtoWireType::kFixed32:
+ PrintFixed32Field(opt_field_descriptor, field, output);
+ break;
+ case ProtoWireType::kFixed64:
+ PrintFixed64Field(opt_field_descriptor, field, output);
+ break;
}
}
PERFETTO_DCHECK(decoder.bytes_left() == 0);
@@ -214,8 +402,9 @@ void ProtozeroToTextInternal(const std::string& type,
std::string ProtozeroToText(const DescriptorPool& pool,
const std::string& type,
protozero::ConstBytes protobytes,
- NewLinesMode new_lines_mode) {
- std::string indent = "";
+ NewLinesMode new_lines_mode,
+ uint32_t initial_indent_depth) {
+ std::string indent = std::string(2 * initial_indent_depth, ' ');
std::string final_result;
ProtozeroToTextInternal(type, protobytes, new_lines_mode, pool, &indent,
&final_result);
@@ -269,10 +458,6 @@ std::string ProtozeroToText(const DescriptorPool& pool,
new_lines_mode);
}
-std::string BytesToHexEncodedStringForTesting(const std::string& s) {
- return BytesToHexEncodedString(s);
-}
-
} // namespace protozero_to_text
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/util/protozero_to_text.h b/src/trace_processor/util/protozero_to_text.h
index c2082f983..9a0acf16e 100644
--- a/src/trace_processor/util/protozero_to_text.h
+++ b/src/trace_processor/util/protozero_to_text.h
@@ -28,6 +28,8 @@ class DescriptorPool;
namespace protozero_to_text {
+// If |new_lines_modes| == kIncludeNewLines, new lines will be used between
+// fields, otherwise only a space will be used.
enum NewLinesMode {
kIncludeNewLines = 0,
kSkipNewLines,
@@ -47,13 +49,13 @@ std::string ShortDebugTrackEventProtozeroToText(
// Given a protozero message |protobytes| which is of fully qualified name
// |type|, convert this into a text proto format string. All types used in
-// message definition of |type| must be available in |pool|. If
-// |new_lines_modes| == kIncludeNewLines, new lines will be used between fields,
-// otherwise only a space will be used.
-std::string ProtozeroToText(const DescriptorPool& pool,
- const std::string& type,
- protozero::ConstBytes protobytes,
- NewLinesMode new_lines_mode);
+// message definition of |type| must be available in |pool|.
+std::string ProtozeroToText(
+ const DescriptorPool& pool,
+ const std::string& type,
+ protozero::ConstBytes protobytes,
+ NewLinesMode new_lines_mode = NewLinesMode::kIncludeNewLines,
+ uint32_t initial_indent_depth = 0);
std::string ProtozeroToText(const DescriptorPool& pool,
const std::string& type,
@@ -69,8 +71,6 @@ std::string ProtozeroEnumToText(const std::string& type, Enum enum_value) {
return ProtozeroEnumToText(type, static_cast<int32_t>(enum_value));
}
-std::string BytesToHexEncodedStringForTesting(const std::string&);
-
} // namespace protozero_to_text
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/util/protozero_to_text_unittests.cc b/src/trace_processor/util/protozero_to_text_unittests.cc
index d6390afac..62070559a 100644
--- a/src/trace_processor/util/protozero_to_text_unittests.cc
+++ b/src/trace_processor/util/protozero_to_text_unittests.cc
@@ -16,10 +16,13 @@
#include "src/trace_processor/util/protozero_to_text.h"
+#include "perfetto/ext/base/string_utils.h"
#include "perfetto/protozero/scattered_heap_buffer.h"
#include "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pbzero.h"
#include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+#include "src/protozero/test/example_proto/test_messages.pbzero.h"
#include "src/trace_processor/importers/track_event.descriptor.h"
+#include "src/trace_processor/test_messages.descriptor.h"
#include "src/trace_processor/util/descriptors.h"
#include "test/gtest_and_gmock.h"
@@ -31,8 +34,12 @@ namespace {
constexpr size_t kChunkSize = 42;
+using ::protozero::test::protos::pbzero::EveryField;
+using ::protozero::test::protos::pbzero::PackedRepeatedFields;
using ::testing::_;
+using ::testing::ElementsAre;
using ::testing::Eq;
+using ::testing::StartsWith;
TEST(ProtozeroToTextTest, TrackEventBasic) {
using perfetto::protos::pbzero::TrackEvent;
@@ -67,10 +74,10 @@ TEST(ProtozeroToTextTest, TrackEventNestedMsg) {
EXPECT_EQ(
R"(track_uuid: 4
-cc_scheduler_state: {
+cc_scheduler_state {
deadline_us: 7
- state_machine: {
- minor_state: {
+ state_machine {
+ minor_state {
commit_count: 8
}
}
@@ -82,8 +89,8 @@ timestamp_delta_us: 3)",
protozero::ConstBytes{binary_proto.data(), binary_proto.size()}));
EXPECT_EQ(
- "track_uuid: 4 cc_scheduler_state: { deadline_us: 7 state_machine: { "
- "minor_state: { commit_count: 8 } } observing_begin_frame_source: true } "
+ "track_uuid: 4 cc_scheduler_state { deadline_us: 7 state_machine { "
+ "minor_state { commit_count: 8 } } observing_begin_frame_source: true } "
"timestamp_delta_us: 3",
ShortDebugTrackEventProtozeroToText(
".perfetto.protos.TrackEvent",
@@ -145,10 +152,10 @@ TEST(ProtozeroToTextTest, CustomDescriptorPoolNestedMsg) {
EXPECT_EQ(
R"(track_uuid: 4
-cc_scheduler_state: {
+cc_scheduler_state {
deadline_us: 7
- state_machine: {
- minor_state: {
+ state_machine {
+ minor_state {
commit_count: 8
}
}
@@ -159,58 +166,509 @@ timestamp_delta_us: 3)",
kIncludeNewLines));
EXPECT_EQ(
- "track_uuid: 4 cc_scheduler_state: { deadline_us: 7 state_machine: { "
- "minor_state: { commit_count: 8 } } observing_begin_frame_source: true } "
+ "track_uuid: 4 cc_scheduler_state { deadline_us: 7 state_machine { "
+ "minor_state { commit_count: 8 } } observing_begin_frame_source: true } "
"timestamp_delta_us: 3",
ProtozeroToText(pool, ".perfetto.protos.TrackEvent", binary_proto,
kSkipNewLines));
}
-TEST(ProtozeroToTextTest, EnumToString) {
+TEST(ProtozeroToTextTest, ProtozeroEnumToText) {
using perfetto::protos::pbzero::TrackEvent;
EXPECT_EQ("TYPE_SLICE_END",
ProtozeroEnumToText(".perfetto.protos.TrackEvent.Type",
TrackEvent::TYPE_SLICE_END));
}
-TEST(ProtozeroToTextTest, UnknownField) {
- using perfetto::protos::pbzero::TrackEvent;
- // Wrong type to force unknown field:
- const auto type = ".perfetto.protos.ChromeCompositorSchedulerState";
- protozero::HeapBuffered<TrackEvent> msg{kChunkSize, kChunkSize};
- auto* state = msg->set_cc_scheduler_state();
- state->set_deadline_us(7);
- auto* machine = state->set_state_machine();
- auto* minor_state = machine->set_minor_state();
- minor_state->set_commit_count(8);
- auto bytes = msg.SerializeAsArray();
+// Sets up a descriptor pool with all the messages from
+// "src/protozero/test/example_proto/test_messages.proto"
+class ProtozeroToTextTestMessageTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ auto status = pool_.AddFromFileDescriptorSet(
+ kTestMessagesDescriptor.data(), kTestMessagesDescriptor.size());
+ ASSERT_TRUE(status.ok());
+ }
- DescriptorPool pool;
- auto status = pool.AddFromFileDescriptorSet(kTrackEventDescriptor.data(),
- kTrackEventDescriptor.size());
- ASSERT_TRUE(status.ok());
- ASSERT_EQ(ProtozeroToText(pool, type, bytes, kIncludeNewLines),
- "# Ignoring unknown field with id: 24");
+ DescriptorPool pool_;
+};
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldVarIntInt32) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->set_field_int32(42);
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "field_int32: 42");
}
-TEST(ProtozeroToTextTest, StringField) {
- using perfetto::protos::pbzero::TrackEvent;
- // Wrong type to force unknown field:
- const auto type = ".perfetto.protos.TrackEvent";
- protozero::HeapBuffered<TrackEvent> msg{kChunkSize, kChunkSize};
- msg->add_categories(R"(Hello, "World")");
- auto bytes = msg.SerializeAsArray();
+TEST_F(ProtozeroToTextTestMessageTest, FieldVarIntSint32) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->set_field_sint32(-42);
- DescriptorPool pool;
- auto status = pool.AddFromFileDescriptorSet(kTrackEventDescriptor.data(),
- kTrackEventDescriptor.size());
- ASSERT_TRUE(status.ok());
- ASSERT_EQ(ProtozeroToText(pool, type, bytes, kIncludeNewLines),
- "categories: \"Hello, \\\"World\\\"\"");
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "field_sint32: -42");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldVarIntUint32) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->set_field_uint32(3000000000);
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "field_uint32: 3000000000");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldVarIntInt64) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->set_field_int64(3000000000);
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "field_int64: 3000000000");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldVarIntSint64) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->set_field_sint64(-3000000000);
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "field_sint64: -3000000000");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldVarIntBool) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->set_field_bool(true);
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "field_bool: true");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldVarIntSmallEnum) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->set_small_enum(protozero::test::protos::pbzero::TO_BE);
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "small_enum: TO_BE");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldVarIntSignedEnum) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->set_signed_enum(protozero::test::protos::pbzero::NEGATIVE);
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "signed_enum: NEGATIVE");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldVarIntBigEnum) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->set_big_enum(protozero::test::protos::pbzero::END);
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "big_enum: END");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldVarIntEnumUnknown) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->AppendVarInt(EveryField::kSmallEnumFieldNumber, 42);
+ ASSERT_EQ(EveryField::kSmallEnumFieldNumber, 51);
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "51: 42");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldVarIntUnknown) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->AppendVarInt(/*field_id=*/9999, /*value=*/42);
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "9999: 42");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldVarIntMismatch) {
+ protozero::HeapBuffered<EveryField> msg;
+ ASSERT_EQ(EveryField::kFieldStringFieldNumber, 500);
+ msg->AppendVarInt(EveryField::kFieldStringFieldNumber, 42);
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "500: 42");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldVarIntForPacked) {
+ // Even though field_int32 has [packed = true], it still accepts a non-packed
+ // representation.
+ protozero::HeapBuffered<PackedRepeatedFields> msg;
+ msg->AppendVarInt(PackedRepeatedFields::kFieldInt32FieldNumber, 42);
+
+ EXPECT_EQ(
+ ProtozeroToText(pool_, ".protozero.test.protos.PackedRepeatedFields",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "field_int32: 42");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldFixed32Signed) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->set_field_sfixed32(-42);
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "field_sfixed32: -42");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldFixed32Unsigned) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->set_field_fixed32(3000000000);
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "field_fixed32: 3000000000");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldFixed32Float) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->set_field_float(24.125);
+
+ EXPECT_THAT(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ StartsWith("field_float: 24.125"));
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldFixed32Unknown) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->AppendFixed<uint32_t>(/*field_id=*/9999, /*value=*/0x1);
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "9999: 0x00000001");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldFixed32Mismatch) {
+ protozero::HeapBuffered<EveryField> msg;
+ ASSERT_EQ(EveryField::kFieldStringFieldNumber, 500);
+ msg->AppendFixed<uint32_t>(EveryField::kFieldStringFieldNumber, 0x1);
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "500: 0x00000001");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldFixed64Signed) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->set_field_sfixed64(-42);
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "field_sfixed64: -42");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldFixed64Unsigned) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->set_field_fixed64(3000000000);
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "field_fixed64: 3000000000");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldFixed64Double) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->set_field_double(24.125);
+
+ EXPECT_THAT(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ StartsWith("field_double: 24.125"));
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldFixed64Unknown) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->AppendFixed<uint64_t>(/*field_id=*/9999, /*value=*/0x1);
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "9999: 0x0000000000000001");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldFixed64Mismatch) {
+ protozero::HeapBuffered<EveryField> msg;
+ ASSERT_EQ(EveryField::kFieldStringFieldNumber, 500);
+ msg->AppendFixed<uint64_t>(EveryField::kFieldStringFieldNumber, 0x1);
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "500: 0x0000000000000001");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldLengthLimitedString) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->set_field_string("Hello");
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ R"(field_string: "Hello")");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldLengthLimitedBytes) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->set_field_bytes("Hello");
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ R"(field_bytes: "Hello")");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldLengthLimitedUnknown) {
+ protozero::HeapBuffered<EveryField> msg;
+ msg->AppendString(9999, "Hello");
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ R"(9999: "Hello")");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldLengthLimitedMismatch) {
+ protozero::HeapBuffered<EveryField> msg;
+ ASSERT_EQ(EveryField::kFieldBoolFieldNumber, 13);
+ msg->AppendString(EveryField::kFieldBoolFieldNumber, "Hello");
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "# Packed type 8 not supported. Printing raw string.\n"
+ R"(13: "Hello")");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldLengthLimitedPackedForNonPacked) {
+ // Even though repeated_int32 doesn't have [packed = true], it still accepts a
+ // packed representation.
+ protozero::HeapBuffered<EveryField> msg;
+ protozero::PackedVarInt buf;
+ buf.Append<int32_t>(-42);
+ buf.Append<int32_t>(2147483647);
+ msg->AppendBytes(EveryField::kRepeatedInt32FieldNumber, buf.data(),
+ buf.size());
+
+ EXPECT_EQ(ProtozeroToText(pool_, ".protozero.test.protos.EveryField",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "repeated_int32: -42\nrepeated_int32: 2147483647");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldLengthLimitedPackedVarIntInt32) {
+ protozero::HeapBuffered<PackedRepeatedFields> msg;
+ protozero::PackedVarInt buf;
+ buf.Append<int32_t>(-42);
+ buf.Append<int32_t>(2147483647);
+ msg->set_field_int32(buf);
+
+ EXPECT_EQ(
+ ProtozeroToText(pool_, ".protozero.test.protos.PackedRepeatedFields",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "field_int32: -42\nfield_int32: 2147483647");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldLengthLimitedPackedVarIntInt64) {
+ protozero::HeapBuffered<PackedRepeatedFields> msg;
+ protozero::PackedVarInt buf;
+ buf.Append<int64_t>(-42);
+ buf.Append<int64_t>(3000000000);
+ msg->set_field_int64(buf);
+
+ EXPECT_EQ(
+ ProtozeroToText(pool_, ".protozero.test.protos.PackedRepeatedFields",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "field_int64: -42\nfield_int64: 3000000000");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldLengthLimitedPackedVarIntUint32) {
+ protozero::HeapBuffered<PackedRepeatedFields> msg;
+ protozero::PackedVarInt buf;
+ buf.Append<uint32_t>(42);
+ buf.Append<uint32_t>(3000000000);
+ msg->set_field_uint32(buf);
+
+ EXPECT_EQ(
+ ProtozeroToText(pool_, ".protozero.test.protos.PackedRepeatedFields",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "field_uint32: 42\nfield_uint32: 3000000000");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldLengthLimitedPackedVarIntUint64) {
+ protozero::HeapBuffered<PackedRepeatedFields> msg;
+ protozero::PackedVarInt buf;
+ buf.Append<uint64_t>(42);
+ buf.Append<uint64_t>(3000000000000);
+ msg->set_field_uint64(buf);
+
+ EXPECT_EQ(
+ ProtozeroToText(pool_, ".protozero.test.protos.PackedRepeatedFields",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "field_uint64: 42\nfield_uint64: 3000000000000");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldLengthLimitedPackedFixed32Uint32) {
+ protozero::HeapBuffered<PackedRepeatedFields> msg;
+ protozero::PackedFixedSizeInt<uint32_t> buf;
+ buf.Append(42);
+ buf.Append(3000000000);
+ msg->set_field_fixed32(buf);
+
+ EXPECT_EQ(
+ ProtozeroToText(pool_, ".protozero.test.protos.PackedRepeatedFields",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "field_fixed32: 42\nfield_fixed32: 3000000000");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldLengthLimitedPackedFixed32Int32) {
+ protozero::HeapBuffered<PackedRepeatedFields> msg;
+ protozero::PackedFixedSizeInt<int32_t> buf;
+ buf.Append(-42);
+ buf.Append(42);
+ msg->set_field_sfixed32(buf);
+
+ EXPECT_EQ(
+ ProtozeroToText(pool_, ".protozero.test.protos.PackedRepeatedFields",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "field_sfixed32: -42\nfield_sfixed32: 42");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldLengthLimitedPackedFixed32Float) {
+ protozero::HeapBuffered<PackedRepeatedFields> msg;
+ protozero::PackedFixedSizeInt<float> buf;
+ buf.Append(-42);
+ buf.Append(42.125);
+ msg->set_field_float(buf);
+
+ std::string output =
+ ProtozeroToText(pool_, ".protozero.test.protos.PackedRepeatedFields",
+ msg.SerializeAsArray(), kIncludeNewLines);
+
+ EXPECT_THAT(base::SplitString(output, "\n"),
+ ElementsAre(StartsWith("field_float: -42"),
+ StartsWith("field_float: 42.125")));
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldLengthLimitedPackedFixed64Uint64) {
+ protozero::HeapBuffered<PackedRepeatedFields> msg;
+ protozero::PackedFixedSizeInt<uint64_t> buf;
+ buf.Append(42);
+ buf.Append(3000000000000);
+ msg->set_field_fixed64(buf);
+
+ EXPECT_EQ(
+ ProtozeroToText(pool_, ".protozero.test.protos.PackedRepeatedFields",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "field_fixed64: 42\nfield_fixed64: 3000000000000");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldLengthLimitedPackedFixed64Int64) {
+ protozero::HeapBuffered<PackedRepeatedFields> msg;
+ protozero::PackedFixedSizeInt<int64_t> buf;
+ buf.Append(-42);
+ buf.Append(3000000000000);
+ msg->set_field_sfixed64(buf);
+
+ EXPECT_EQ(
+ ProtozeroToText(pool_, ".protozero.test.protos.PackedRepeatedFields",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "field_sfixed64: -42\nfield_sfixed64: 3000000000000");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldLengthLimitedPackedFixed64Double) {
+ protozero::HeapBuffered<PackedRepeatedFields> msg;
+ protozero::PackedFixedSizeInt<double> buf;
+ buf.Append(-42);
+ buf.Append(42.125);
+ msg->set_field_double(buf);
+
+ EXPECT_THAT(
+ base::SplitString(
+ ProtozeroToText(pool_, ".protozero.test.protos.PackedRepeatedFields",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "\n"),
+ ElementsAre(StartsWith("field_double: -42"),
+ StartsWith("field_double: 42.125")));
}
-TEST(ProtozeroToTextTest, BytesField) {
- EXPECT_EQ(BytesToHexEncodedStringForTesting("abc"), R"(\x61\x62\x63)");
+TEST_F(ProtozeroToTextTestMessageTest, FieldLengthLimitedPackedFixedErrShort) {
+ protozero::HeapBuffered<PackedRepeatedFields> msg;
+ std::string buf;
+ buf = "\x01";
+ // buf does not contain enough data for a fixed 64
+ msg->AppendBytes(PackedRepeatedFields::kFieldFixed64FieldNumber, buf.data(),
+ buf.size());
+
+ // "protoc --decode", instead, returns an error on stderr and doesn't output
+ // anything at all.
+ EXPECT_EQ(
+ ProtozeroToText(pool_, ".protozero.test.protos.PackedRepeatedFields",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "# Packed decoding failure for field field_fixed64\n");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldLengthLimitedPackedFixedGarbage) {
+ protozero::HeapBuffered<PackedRepeatedFields> msg;
+ protozero::PackedFixedSizeInt<uint64_t> buf;
+ buf.Append(42);
+ buf.Append(3000000000000);
+ std::string buf_and_garbage(reinterpret_cast<const char*>(buf.data()),
+ buf.size());
+ buf_and_garbage += "\x01";
+ // buf contains extra garbage
+ msg->AppendBytes(PackedRepeatedFields::kFieldFixed64FieldNumber,
+ buf_and_garbage.data(), buf_and_garbage.size());
+
+ // "protoc --decode", instead, returns an error on stderr and doesn't output
+ // anything at all.
+ EXPECT_EQ(
+ ProtozeroToText(pool_, ".protozero.test.protos.PackedRepeatedFields",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "# Packed decoding failure for field field_fixed64\n");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldLengthLimitedPackedVarIntShort) {
+ protozero::HeapBuffered<PackedRepeatedFields> msg;
+ std::string buf;
+ buf = "\xFF";
+ // for the varint to be valid, buf should contain another byte.
+ msg->AppendBytes(PackedRepeatedFields::kFieldInt32FieldNumber, buf.data(),
+ buf.size());
+
+ // "protoc --decode", instead, returns an error on stderr and doesn't output
+ // anything at all.
+ EXPECT_EQ(
+ ProtozeroToText(pool_, ".protozero.test.protos.PackedRepeatedFields",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "# Packed decoding failure for field field_int32\n");
+}
+
+TEST_F(ProtozeroToTextTestMessageTest, FieldLengthLimitedPackedVarIntGarbage) {
+ protozero::HeapBuffered<PackedRepeatedFields> msg;
+ protozero::PackedVarInt buf;
+ buf.Append(42);
+ buf.Append(105);
+ std::string buf_and_garbage(reinterpret_cast<const char*>(buf.data()),
+ buf.size());
+ buf_and_garbage += "\xFF";
+ // buf contains extra garbage
+ msg->AppendBytes(PackedRepeatedFields::kFieldInt32FieldNumber,
+ buf_and_garbage.data(), buf_and_garbage.size());
+
+ // "protoc --decode", instead:
+ // * doesn't output anything.
+ // * returns an error on stderr.
+ EXPECT_EQ(
+ ProtozeroToText(pool_, ".protozero.test.protos.PackedRepeatedFields",
+ msg.SerializeAsArray(), kIncludeNewLines),
+ "field_int32: 42\n"
+ "field_int32: 105\n"
+ "# Packed decoding failure for field field_int32\n");
}
} // namespace
diff --git a/src/tracebox/BUILD.gn b/src/tracebox/BUILD.gn
new file mode 100644
index 000000000..90007324f
--- /dev/null
+++ b/src/tracebox/BUILD.gn
@@ -0,0 +1,30 @@
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("../../gn/perfetto.gni")
+
+assert(perfetto_build_standalone)
+
+executable("tracebox") {
+ deps = [
+ "../../gn:default_deps",
+ "../base",
+ "../perfetto_cmd",
+ "../perfetto_cmd:trigger_perfetto_cmd",
+ "../traced/probes",
+ "../traced/service",
+ "../websocket_bridge:lib",
+ ]
+ sources = [ "tracebox.cc" ]
+}
diff --git a/src/tracebox/tracebox.cc b/src/tracebox/tracebox.cc
new file mode 100644
index 000000000..a421b97b0
--- /dev/null
+++ b/src/tracebox/tracebox.cc
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/pipe.h"
+#include "perfetto/ext/base/subprocess.h"
+#include "perfetto/ext/base/utils.h"
+#include "perfetto/ext/traced/traced.h"
+#include "src/perfetto_cmd/perfetto_cmd.h"
+#include "src/websocket_bridge/websocket_bridge.h"
+
+#include <stdio.h>
+
+#include <tuple>
+
+namespace perfetto {
+namespace {
+
+struct Applet {
+ using MainFunction = int (*)(int /*argc*/, char** /*argv*/);
+ const char* name;
+ MainFunction entrypoint;
+};
+
+const Applet g_applets[]{
+ {"traced", ServiceMain},
+ {"traced_probes", ProbesMain},
+ {"perfetto", PerfettoCmdMain},
+ {"trigger_perfetto", TriggerPerfettoMain},
+ {"websocket_bridge", WebsocketBridgeMain},
+};
+
+void PrintUsage() {
+ printf(R"(Welcome to Perfetto tracing!
+
+Tracebox is a bundle containing all the tracing services and the perfetto
+cmdline client in one binary. It can be used either to spawn manually the
+various subprocess or in "autostart" mode, which will take care of starting
+and tearing down the services for you.
+
+Usage in autostart mode:
+ tracebox -t 10s -o trace_file.perfetto-trace sched/sched_switch
+ See tracebox --help for more options.
+
+Usage in manual mode:
+ tracebox applet_name [args ...] (e.g. ./tracebox traced --help)
+ Applets:)");
+
+ for (const Applet& applet : g_applets)
+ printf(" %s", applet.name);
+
+ printf(R"(
+
+See also:
+ * https://perfetto.dev/docs/
+ * The config editor in the record page of https://ui.perfetto.dev/
+)");
+}
+
+int TraceboxMain(int argc, char** argv) {
+ // Manual mode: if either the 1st argument (argv[1]) or the exe name (argv[0])
+ // match the name of an applet, directly invoke that without further
+ // modifications.
+
+ // Extract the file name from argv[0].
+ char* slash = strrchr(argv[0], '/');
+ char* argv0 = slash ? slash + 1 : argv[0];
+
+ for (const Applet& applet : g_applets) {
+ if (!strcmp(argv0, applet.name))
+ return applet.entrypoint(argc, argv);
+ if (argc > 1 && !strcmp(argv[1], applet.name))
+ return applet.entrypoint(argc - 1, &argv[1]);
+ }
+
+ // If no matching applet is found, switch to the autostart mode. In this mode
+ // we make tracebox behave like the cmdline client (without needing to prefix
+ // it with "perfetto"), but will also start traced and traced_probes.
+ // As part of this we also use a different namespace for the producer/consumer
+ // sockets, to avoid clashing with the system daemon.
+
+ if (argc <= 1) {
+ PrintUsage();
+ return 1;
+ }
+
+ auto pid_str = std::to_string(static_cast<uint64_t>(base::GetProcessId()));
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+ PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+ // Use an unlinked abstract domain socket on Linux/Android.
+ std::string consumer_socket = "@traced-c-" + pid_str;
+ std::string producer_socket = "@traced-p-" + pid_str;
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+ std::string consumer_socket = "/tmp/traced-c-" + pid_str;
+ std::string producer_socket = "/tmp/traced-p-" + pid_str;
+#else
+ PERFETTO_FATAL("The autostart mode is not supported on this platform");
+#endif
+
+ // If the caller has set the PERFETTO_*_SOCK_NAME, respect those.
+ const char* env;
+ if ((env = getenv("PERFETTO_CONSUMER_SOCK_NAME")))
+ consumer_socket = env;
+ if ((env = getenv("PERFETTO_PRODUCER_SOCK_NAME")))
+ producer_socket = env;
+
+ base::SetEnv("PERFETTO_CONSUMER_SOCK_NAME", consumer_socket);
+ base::SetEnv("PERFETTO_PRODUCER_SOCK_NAME", producer_socket);
+
+ PerfettoCmd perfetto_cmd;
+
+ // If the cmdline parsing fails, stop here, no need to spawn services.
+ // It will daemonize if --background. In that case the subprocesses will be
+ // spawned by the damonized cmdline client, which is what we want so killing
+ // the backgrounded cmdline client will also kill the other services, as they
+ // will live in the same background session.
+ auto opt_res = perfetto_cmd.ParseCmdlineAndMaybeDaemonize(argc, argv);
+ if (opt_res.has_value())
+ return *opt_res;
+
+ std::string self_path = base::GetCurExecutablePath();
+ base::Subprocess traced({self_path, "traced"});
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ // |traced_sync_pipe| is used to synchronize with traced socket creation.
+ // traced will write "1" and close the FD when the IPC socket is listening
+ // (or traced crashed).
+ base::Pipe traced_sync_pipe = base::Pipe::Create();
+ int traced_fd = *traced_sync_pipe.wr;
+ base::SetEnv("TRACED_NOTIFY_FD", std::to_string(traced_fd));
+ traced.args.preserve_fds.emplace_back(traced_fd);
+ // Create a new process group so CTRL-C is delivered only to the cmdline
+ // process (the tracebox one) and not to traced. traced will still exit once
+ // the main process exits, but this allows graceful stopping of the trace
+ // without abruptedly killing traced{,probes} when hitting CTRL+C.
+ traced.args.posix_proc_group_id = 0; // 0 = start a new process group.
+#endif
+ traced.Start();
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ traced_sync_pipe.wr.reset();
+
+ std::string traced_notify_msg;
+ base::ReadPlatformHandle(*traced_sync_pipe.rd, &traced_notify_msg);
+ if (traced_notify_msg != "1")
+ PERFETTO_FATAL("The tracing service failed unexpectedly. Check the logs");
+#endif
+
+ base::Subprocess traced_probes(
+ {self_path, "traced_probes", "--reset-ftrace"});
+ // Put traced_probes in the same process group as traced. Same reason (CTRL+C)
+ // but it's not worth creating a new group.
+ traced_probes.args.posix_proc_group_id = traced.pid();
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ // |traced_probes_sync_pipe| is used to synchronize with traced socket
+ // creation. traced will write "1" and close the FD when the IPC socket is
+ // listening (or traced crashed).
+ base::Pipe traced_probes_sync_pipe = base::Pipe::Create();
+ int traced_probes_fd = *traced_probes_sync_pipe.wr;
+ base::SetEnv("TRACED_PROBES_NOTIFY_FD", std::to_string(traced_probes_fd));
+ traced_probes.args.preserve_fds.emplace_back(traced_probes_fd);
+#endif
+ traced_probes.Start();
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ traced_probes_sync_pipe.wr.reset();
+
+ std::string traced_probes_notify_msg;
+ base::ReadPlatformHandle(*traced_probes_sync_pipe.rd,
+ &traced_probes_notify_msg);
+ if (traced_probes_notify_msg != "1")
+ PERFETTO_FATAL(
+ "The traced_proces service failed unexpectedly. Check the logs");
+#endif
+
+ perfetto_cmd.ConnectToServiceRunAndMaybeNotify();
+ return 0;
+}
+
+} // namespace
+} // namespace perfetto
+
+int main(int argc, char** argv) {
+ return perfetto::TraceboxMain(argc, argv);
+}
diff --git a/src/traced/probes/BUILD.gn b/src/traced/probes/BUILD.gn
index db547fcbf..4c4b65a15 100644
--- a/src/traced/probes/BUILD.gn
+++ b/src/traced/probes/BUILD.gn
@@ -101,6 +101,7 @@ perfetto_unittest_source_set("unittests") {
"filesystem:unittests",
"initial_display_state:unittests",
"packages_list:unittests",
+ "power:unittests",
"ps:unittests",
"sys_stats:unittests",
"system_info:unittests",
diff --git a/src/traced/probes/android_log/android_log_data_source.cc b/src/traced/probes/android_log/android_log_data_source.cc
index 286d1386a..2d4d26475 100644
--- a/src/traced/probes/android_log/android_log_data_source.cc
+++ b/src/traced/probes/android_log/android_log_data_source.cc
@@ -89,6 +89,7 @@ inline bool ReadAndAdvance(const char** ptr, const char* end, T* out) {
const ProbesDataSource::Descriptor AndroidLogDataSource::descriptor = {
/*name*/ "android.log",
/*flags*/ Descriptor::kFlagsNone,
+ /*fill_descriptor_func*/ nullptr,
};
AndroidLogDataSource::AndroidLogDataSource(DataSourceConfig ds_config,
@@ -367,8 +368,6 @@ bool AndroidLogDataSource::ParseBinaryEvent(
if (!ReadAndAdvance(&buf, end, &eid))
return false;
- // TODO test events with 0 arguments. DNS.
-
const EventFormat* fmt = GetEventFormat(eid);
if (!fmt) {
// We got an event which doesn't have a corresponding entry in
diff --git a/src/traced/probes/common/BUILD.gn b/src/traced/probes/common/BUILD.gn
index 4346c4e8c..94e92897a 100644
--- a/src/traced/probes/common/BUILD.gn
+++ b/src/traced/probes/common/BUILD.gn
@@ -42,7 +42,7 @@ perfetto_unittest_source_set("test_support") {
deps = [
":common",
"../../../../gn:default_deps",
- "../../../base",
+ "../../../base:test_support",
]
sources = [
"cpu_freq_info_for_testing.cc",
diff --git a/src/traced/probes/common/cpu_freq_info.cc b/src/traced/probes/common/cpu_freq_info.cc
index 01373694d..2d3c1f946 100644
--- a/src/traced/probes/common/cpu_freq_info.cc
+++ b/src/traced/probes/common/cpu_freq_info.cc
@@ -16,6 +16,8 @@
#include "src/traced/probes/common/cpu_freq_info.h"
+#include <unistd.h>
+
#include <set>
#include "perfetto/ext/base/file_utils.h"
@@ -42,10 +44,11 @@ void ReadAndAppendFreqs(std::set<CpuAndFreq>* freqs,
} // namespace
-CpuFreqInfo::CpuFreqInfo(std::string cpu_dir_path) {
- base::ScopedDir cpu_dir(opendir(cpu_dir_path.c_str()));
+CpuFreqInfo::CpuFreqInfo(std::string sysfs_cpu_path)
+ : sysfs_cpu_path_{sysfs_cpu_path} {
+ base::ScopedDir cpu_dir(opendir(sysfs_cpu_path_.c_str()));
if (!cpu_dir) {
- PERFETTO_PLOG("Failed to opendir(%s)", cpu_dir_path.c_str());
+ PERFETTO_PLOG("Failed to opendir(%s)", sysfs_cpu_path_.c_str());
return;
}
// Accumulate cpu and freqs into a set to ensure stable order.
@@ -64,11 +67,11 @@ CpuFreqInfo::CpuFreqInfo(std::string cpu_dir_path) {
uint32_t cpu_index = maybe_cpu_index.value();
ReadAndAppendFreqs(
&freqs, cpu_index,
- ReadFile(cpu_dir_path + "/cpu" + std::to_string(cpu_index) +
+ ReadFile(sysfs_cpu_path_ + "/cpu" + std::to_string(cpu_index) +
"/cpufreq/scaling_available_frequencies"));
ReadAndAppendFreqs(
&freqs, cpu_index,
- ReadFile(cpu_dir_path + "/cpu" + std::to_string(cpu_index) +
+ ReadFile(sysfs_cpu_path_ + "/cpu" + std::to_string(cpu_index) +
"/cpufreq/scaling_boost_frequencies"));
}
@@ -118,4 +121,28 @@ std::string CpuFreqInfo::ReadFile(std::string path) {
return contents;
}
+const std::vector<uint32_t>& CpuFreqInfo::ReadCpuCurrFreq() {
+ // Check if capacity of cpu_curr_freq_ is enough for all CPUs
+ auto num_cpus = static_cast<size_t>(sysconf(_SC_NPROCESSORS_CONF));
+ if (cpu_curr_freq_.size() < num_cpus)
+ cpu_curr_freq_.resize(num_cpus);
+
+ for (uint32_t i = 0; i < cpu_curr_freq_.size(); i++) {
+ // Read CPU current frequency. Set 0 for offline/disabled cpus.
+ std::string buf(ReadFile(sysfs_cpu_path_ + "/cpu" + std::to_string(i) +
+ "/cpufreq/scaling_cur_freq"));
+ if (buf.empty()) {
+ cpu_curr_freq_[i] = 0;
+ continue;
+ }
+ auto freq = base::StringToUInt32(base::StripSuffix(buf, "\n"));
+ if (!freq.has_value()) {
+ cpu_curr_freq_[i] = 0;
+ continue;
+ }
+ cpu_curr_freq_[i] = freq.value();
+ }
+ return cpu_curr_freq_;
+}
+
} // namespace perfetto
diff --git a/src/traced/probes/common/cpu_freq_info.h b/src/traced/probes/common/cpu_freq_info.h
index 1bcdd79e6..36f7f9c09 100644
--- a/src/traced/probes/common/cpu_freq_info.h
+++ b/src/traced/probes/common/cpu_freq_info.h
@@ -35,13 +35,19 @@ class CpuFreqInfo {
Range GetFreqs(uint32_t cpu);
uint32_t GetCpuFreqIndex(uint32_t cpu, uint32_t freq);
+ const std::vector<uint32_t>& ReadCpuCurrFreq();
+
private:
+ // e.g. /sys/devices/system/cpu
+ std::string sysfs_cpu_path_;
// All frequencies of all CPUs, ordered by CPU and frequency. Includes a guard
// at the end.
std::vector<uint32_t> frequencies_;
// frequencies_index_[cpu] points to first frequency in frequencies_. Includes
// a guard at the end.
std::vector<size_t> frequencies_index_;
+ // Placeholder for CPU current frequency, refresh in ReadCpuCurrFreq()
+ std::vector<uint32_t> cpu_curr_freq_;
std::string ReadFile(std::string path);
};
diff --git a/src/traced/probes/common/cpu_freq_info_for_testing.cc b/src/traced/probes/common/cpu_freq_info_for_testing.cc
index 132f75a4c..2fa163720 100644
--- a/src/traced/probes/common/cpu_freq_info_for_testing.cc
+++ b/src/traced/probes/common/cpu_freq_info_for_testing.cc
@@ -16,13 +16,8 @@
#include "src/traced/probes/common/cpu_freq_info_for_testing.h"
-#include <algorithm>
#include <memory>
-#include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/scoped_file.h"
-#include "perfetto/ext/base/temp_file.h"
-
namespace perfetto {
namespace {
@@ -40,53 +35,29 @@ const char kCpuBoostFrequenciesAndroidBigCore[] = "2803200 \n";
} // namespace
-CpuFreqInfoForTesting::CpuFreqInfoForTesting()
- : fake_cpu_dir_(base::TempDir::Create()) {
+CpuFreqInfoForTesting::CpuFreqInfoForTesting() {
// Create a subset of /sys/devices/system/cpu.
- AddDir("cpuidle");
- AddDir("cpu0");
- AddDir("cpu0/cpufreq");
- AddFile("cpu0/cpufreq/scaling_available_frequencies",
+ tmpdir_.AddDir("cpuidle");
+ tmpdir_.AddDir("cpu0");
+ tmpdir_.AddDir("cpu0/cpufreq");
+ tmpdir_.AddFile("cpu0/cpufreq/scaling_available_frequencies",
kCpuFrequenciesAndroidLittleCore);
- AddFile("cpu0/cpufreq/scaling_boost_frequencies",
+ tmpdir_.AddFile("cpu0/cpufreq/scaling_boost_frequencies",
kCpuBoostFrequenciesAndroidLittleCore);
- AddDir("cpufreq");
- AddDir("cpu1");
- AddDir("cpu1/cpufreq");
- AddFile("cpu1/cpufreq/scaling_available_frequencies",
+ tmpdir_.AddFile("cpu0/cpufreq/scaling_cur_freq", "2650000");
+ tmpdir_.AddDir("cpufreq");
+ tmpdir_.AddDir("cpu1");
+ tmpdir_.AddDir("cpu1/cpufreq");
+ tmpdir_.AddFile("cpu1/cpufreq/scaling_available_frequencies",
kCpuFrequenciesAndroidBigCore);
- AddFile("cpu1/cpufreq/scaling_boost_frequencies",
+ tmpdir_.AddFile("cpu1/cpufreq/scaling_boost_frequencies",
kCpuBoostFrequenciesAndroidBigCore);
- AddDir("power");
-}
-
-CpuFreqInfoForTesting::~CpuFreqInfoForTesting() {
- for (auto path : files_to_remove_)
- PERFETTO_CHECK(remove(AbsolutePath(path).c_str()) == 0);
- std::reverse(dirs_to_remove_.begin(), dirs_to_remove_.end());
- for (auto path : dirs_to_remove_)
- base::Rmdir(AbsolutePath(path));
+ tmpdir_.AddFile("cpu1/cpufreq/scaling_cur_freq", "3698200");
+ tmpdir_.AddDir("power");
}
std::unique_ptr<CpuFreqInfo> CpuFreqInfoForTesting::GetInstance() {
- return std::unique_ptr<CpuFreqInfo>(new CpuFreqInfo(fake_cpu_dir_.path()));
-}
-
-void CpuFreqInfoForTesting::AddDir(std::string path) {
- dirs_to_remove_.push_back(path);
- base::Mkdir(AbsolutePath(path).c_str());
-}
-
-void CpuFreqInfoForTesting::AddFile(std::string path, std::string content) {
- files_to_remove_.push_back(path);
- base::ScopedFile fd(
- base::OpenFile(AbsolutePath(path), O_WRONLY | O_CREAT | O_TRUNC, 0600));
- PERFETTO_CHECK(base::WriteAll(fd.get(), content.c_str(), content.size()) ==
- static_cast<ssize_t>(content.size()));
-}
-
-std::string CpuFreqInfoForTesting::AbsolutePath(std::string path) {
- return fake_cpu_dir_.path() + "/" + path;
+ return std::unique_ptr<CpuFreqInfo>(new CpuFreqInfo(tmpdir_.path()));
}
} // namespace perfetto
diff --git a/src/traced/probes/common/cpu_freq_info_for_testing.h b/src/traced/probes/common/cpu_freq_info_for_testing.h
index e0e57c2f8..3ba3aa5cd 100644
--- a/src/traced/probes/common/cpu_freq_info_for_testing.h
+++ b/src/traced/probes/common/cpu_freq_info_for_testing.h
@@ -20,31 +20,19 @@
#include "src/traced/probes/common/cpu_freq_info.h"
#include <memory>
-#include <string>
-#include <vector>
-#include "perfetto/ext/base/scoped_file.h"
-#include "perfetto/ext/base/temp_file.h"
+#include "src/base/test/tmp_dir_tree.h"
namespace perfetto {
class CpuFreqInfoForTesting {
public:
CpuFreqInfoForTesting();
- ~CpuFreqInfoForTesting();
std::unique_ptr<CpuFreqInfo> GetInstance();
private:
- base::TempDir fake_cpu_dir_;
- std::vector<std::string> dirs_to_remove_;
- std::vector<std::string> files_to_remove_;
-
- void AddDir(std::string path);
- void AddFile(std::string path, std::string content);
- void RmDir(std::string path);
- void RmFile(std::string path);
- std::string AbsolutePath(std::string path);
+ base::TmpDirTree tmpdir_;
};
} // namespace perfetto
diff --git a/src/traced/probes/filesystem/inode_file_data_source.cc b/src/traced/probes/filesystem/inode_file_data_source.cc
index 5362f2c34..8185a6ee6 100644
--- a/src/traced/probes/filesystem/inode_file_data_source.cc
+++ b/src/traced/probes/filesystem/inode_file_data_source.cc
@@ -83,6 +83,7 @@ class StaticMapDelegate : public FileScanner::Delegate {
const ProbesDataSource::Descriptor InodeFileDataSource::descriptor = {
/*name*/ "linux.inode_file_map",
/*flags*/ Descriptor::kFlagsNone,
+ /*fill_descriptor_func*/ nullptr,
};
void CreateStaticDeviceToInodeMap(
@@ -106,7 +107,7 @@ void InodeFileDataSource::FillInodeEntry(InodeFileMap* destination,
}
InodeFileDataSource::InodeFileDataSource(
- DataSourceConfig ds_config,
+ const DataSourceConfig& ds_config,
base::TaskRunner* task_runner,
TracingSessionID session_id,
std::map<BlockDeviceID, std::unordered_map<Inode, InodeMapValue>>*
diff --git a/src/traced/probes/filesystem/inode_file_data_source.h b/src/traced/probes/filesystem/inode_file_data_source.h
index 54a5d4d94..62cc4d7cd 100644
--- a/src/traced/probes/filesystem/inode_file_data_source.h
+++ b/src/traced/probes/filesystem/inode_file_data_source.h
@@ -56,7 +56,7 @@ class InodeFileDataSource : public ProbesDataSource,
static const ProbesDataSource::Descriptor descriptor;
InodeFileDataSource(
- DataSourceConfig,
+ const DataSourceConfig&,
base::TaskRunner*,
TracingSessionID,
std::map<BlockDeviceID, std::unordered_map<Inode, InodeMapValue>>*
diff --git a/src/traced/probes/filesystem/inode_file_data_source_unittest.cc b/src/traced/probes/filesystem/inode_file_data_source_unittest.cc
index edd208b4c..ea62a2951 100644
--- a/src/traced/probes/filesystem/inode_file_data_source_unittest.cc
+++ b/src/traced/probes/filesystem/inode_file_data_source_unittest.cc
@@ -133,7 +133,7 @@ TEST_F(InodeFileDataSourceTest, TestStaticMap) {
EXPECT_CALL(*data_source, FillInodeEntry(_, buf.st_ino, Eq(value)));
data_source->OnInodes({{buf.st_ino, buf.st_dev}});
- // Expect that the found inode is not added the the LRU cache.
+ // Expect that the found inode is not added the LRU cache.
EXPECT_THAT(cache_.Get(std::make_pair(buf.st_dev, buf.st_ino)), IsNull());
}
diff --git a/src/traced/probes/ftrace/BUILD.gn b/src/traced/probes/ftrace/BUILD.gn
index dcc8ca1cc..a047684ef 100644
--- a/src/traced/probes/ftrace/BUILD.gn
+++ b/src/traced/probes/ftrace/BUILD.gn
@@ -113,6 +113,7 @@ source_set("ftrace") {
"..:data_source",
"../../../../gn:default_deps",
"../../../../include/perfetto/ext/traced",
+ "../../../../protos/perfetto/common:zero",
"../../../../protos/perfetto/trace:zero",
"../../../../protos/perfetto/trace/interned_data:zero",
"../../../../protos/perfetto/trace/profiling:zero",
diff --git a/src/traced/probes/ftrace/OWNERS b/src/traced/probes/ftrace/OWNERS
new file mode 100644
index 000000000..66ecb6cb1
--- /dev/null
+++ b/src/traced/probes/ftrace/OWNERS
@@ -0,0 +1,5 @@
+# People knowledgeable with traced_probes <> ftrace integration.
+hjd@google.com
+primiano@google.com
+rsavitski@google.com
+skyostil@google.com
diff --git a/src/traced/probes/ftrace/atrace_wrapper.cc b/src/traced/probes/ftrace/atrace_wrapper.cc
index 2522e472b..632c13137 100644
--- a/src/traced/probes/ftrace/atrace_wrapper.cc
+++ b/src/traced/probes/ftrace/atrace_wrapper.cc
@@ -25,9 +25,13 @@
#include <sys/wait.h>
#include <unistd.h>
+#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
#include "perfetto/base/time.h"
+#include "perfetto/ext/base/android_utils.h"
+#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/pipe.h"
+#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/utils.h"
namespace perfetto {
@@ -35,10 +39,12 @@ namespace perfetto {
namespace {
RunAtraceFunction g_run_atrace_for_testing = nullptr;
+base::Optional<bool> g_is_old_atrace_for_testing{};
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
// Args should include "atrace" for argv[0].
-bool ExecvAtrace(const std::vector<std::string>& args) {
+bool ExecvAtrace(const std::vector<std::string>& args,
+ std::string* atrace_errors) {
int status = 1;
std::vector<char*> argv;
@@ -158,21 +164,22 @@ bool ExecvAtrace(const std::vector<std::string>& args) {
PERFETTO_EINTR(waitpid(pid, &status, 0));
bool ok = WIFEXITED(status) && WEXITSTATUS(status) == 0;
- if (!ok) {
- // TODO(lalitm): use the stderr result from atrace.
+ if (!ok)
PERFETTO_ELOG("%s", error.c_str());
- }
+ if (atrace_errors)
+ atrace_errors->append(error);
return ok;
}
#endif
} // namespace
-bool RunAtrace(const std::vector<std::string>& args) {
+bool RunAtrace(const std::vector<std::string>& args,
+ std::string* atrace_errors) {
if (g_run_atrace_for_testing)
- return g_run_atrace_for_testing(args);
+ return g_run_atrace_for_testing(args, atrace_errors);
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
- return ExecvAtrace(args);
+ return ExecvAtrace(args, atrace_errors);
#else
PERFETTO_LOG("Atrace only supported on Android.");
return false;
@@ -183,4 +190,29 @@ void SetRunAtraceForTesting(RunAtraceFunction f) {
g_run_atrace_for_testing = f;
}
+bool IsOldAtrace() {
+ if (g_is_old_atrace_for_testing.has_value())
+ return *g_is_old_atrace_for_testing;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
+ !PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+ // Sideloaded case. We could be sideloaded on a modern device or an older one.
+ std::string str_value = base::GetAndroidProp("ro.build.version.sdk");
+ if (str_value.empty())
+ return false;
+ auto opt_value = base::CStringToUInt32(str_value.c_str());
+ return opt_value.has_value() && *opt_value < 28; // 28 == Android P.
+#else
+ // In in-tree builds we know that atrace is current, no runtime checks needed.
+ return false;
+#endif
+}
+
+void SetIsOldAtraceForTesting(bool value) {
+ g_is_old_atrace_for_testing = value;
+}
+
+void ClearIsOldAtraceForTesting() {
+ g_is_old_atrace_for_testing.reset();
+}
+
} // namespace perfetto
diff --git a/src/traced/probes/ftrace/atrace_wrapper.h b/src/traced/probes/ftrace/atrace_wrapper.h
index 264cee049..29847aa02 100644
--- a/src/traced/probes/ftrace/atrace_wrapper.h
+++ b/src/traced/probes/ftrace/atrace_wrapper.h
@@ -24,9 +24,20 @@
namespace perfetto {
using RunAtraceFunction =
- std::add_pointer<bool(const std::vector<std::string>& /*args*/)>::type;
+ std::add_pointer<bool(const std::vector<std::string>& /*args*/,
+ std::string* /*atrace_errors*/)>::type;
-bool RunAtrace(const std::vector<std::string>& args);
+// When we are sideloaded on an old version of Android (pre P), we cannot use
+// atrace --only_userspace because that option doesn't exist. In that case we:
+// - Just use atrace --async_start/stop, which will cause atrace to also
+// poke at ftrace.
+// - Suppress the checks for "somebody else enabled ftrace unexpectedly".
+bool IsOldAtrace();
+void SetIsOldAtraceForTesting(bool);
+void ClearIsOldAtraceForTesting();
+
+bool RunAtrace(const std::vector<std::string>& args,
+ std::string* atrace_errors);
void SetRunAtraceForTesting(RunAtraceFunction);
} // namespace perfetto
diff --git a/src/traced/probes/ftrace/cpu_reader.cc b/src/traced/probes/ftrace/cpu_reader.cc
index 9b1d4f878..efcb475c3 100644
--- a/src/traced/probes/ftrace/cpu_reader.cc
+++ b/src/traced/probes/ftrace/cpu_reader.cc
@@ -27,10 +27,13 @@
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/metatrace.h"
#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/string_splitter.h"
+#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/utils.h"
#include "perfetto/ext/tracing/core/trace_writer.h"
#include "src/kallsyms/kernel_symbol_map.h"
#include "src/kallsyms/lazy_kernel_symbolizer.h"
+#include "src/traced/probes/ftrace/cpu_stats_parser.h"
#include "src/traced/probes/ftrace/ftrace_config_muxer.h"
#include "src/traced/probes/ftrace/ftrace_controller.h"
#include "src/traced/probes/ftrace/ftrace_data_source.h"
@@ -49,40 +52,32 @@ namespace {
// If the compact_sched buffer accumulates more unique strings, the reader will
// flush it to reset the interning state (and make it cheap again).
// This is not an exact cap, since we check only at tracing page boundaries.
-// TODO(rsavitski): consider making part of compact_sched config.
constexpr size_t kCompactSchedInternerThreshold = 64;
// For further documentation of these constants see the kernel source:
-// linux/include/linux/ring_buffer.h
-// Some information about the values of these constants are exposed to user
-// space at: /sys/kernel/debug/tracing/events/header_event
+// linux/include/linux/ring_buffer.h
+// Some of this is also available to userspace at runtime via:
+// /sys/kernel/tracing/events/header_event
constexpr uint32_t kTypeDataTypeLengthMax = 28;
constexpr uint32_t kTypePadding = 29;
constexpr uint32_t kTypeTimeExtend = 30;
constexpr uint32_t kTypeTimeStamp = 31;
struct EventHeader {
+ // bottom 5 bits
uint32_t type_or_length : 5;
+ // top 27 bits
uint32_t time_delta : 27;
};
-struct TimeStamp {
- uint64_t tv_nsec;
- uint64_t tv_sec;
-};
-
-bool ReadIntoString(const uint8_t* start,
- const uint8_t* end,
+// Reads a string from `start` until the first '\0' byte or until fixed_len
+// characters have been read. Appends it to `*out` as field `field_id`.
+void ReadIntoString(const uint8_t* start,
+ size_t fixed_len,
uint32_t field_id,
protozero::Message* out) {
- for (const uint8_t* c = start; c < end; c++) {
- if (*c != '\0')
- continue;
- out->AppendBytes(field_id, reinterpret_cast<const char*>(start),
- static_cast<uintptr_t>(c - start));
- return true;
- }
- return false;
+ size_t len = strnlen(reinterpret_cast<const char*>(start), fixed_len);
+ out->AppendBytes(field_id, reinterpret_cast<const char*>(start), len);
}
bool ReadDataLoc(const uint8_t* start,
@@ -91,24 +86,25 @@ bool ReadDataLoc(const uint8_t* start,
const Field& field,
protozero::Message* message) {
PERFETTO_DCHECK(field.ftrace_size == 4);
- // See
- // https://github.com/torvalds/linux/blob/master/include/trace/trace_events.h
+ // See kernel header include/trace/trace_events.h
uint32_t data = 0;
const uint8_t* ptr = field_start;
if (!CpuReader::ReadAndAdvance(&ptr, end, &data)) {
- PERFETTO_DFATAL("Buffer overflowed.");
+ PERFETTO_DFATAL("couldn't read __data_loc value");
return false;
}
const uint16_t offset = data & 0xffff;
const uint16_t len = (data >> 16) & 0xffff;
const uint8_t* const string_start = start + offset;
- const uint8_t* const string_end = string_start + len;
- if (string_start <= start || string_end > end) {
- PERFETTO_DFATAL("Buffer overflowed.");
+
+ if (PERFETTO_UNLIKELY(len == 0))
+ return true;
+ if (PERFETTO_UNLIKELY(string_start < start || string_start + len > end)) {
+ PERFETTO_DFATAL("__data_loc points at invalid location");
return false;
}
- ReadIntoString(string_start, string_end, field.proto_field_id, message);
+ ReadIntoString(string_start, len, field.proto_field_id, message);
return true;
}
@@ -141,6 +137,16 @@ bool SetBlocking(int fd, bool is_blocking) {
return fcntl(fd, F_SETFL, flags) == 0;
}
+void LogInvalidPage(const void* start, size_t size) {
+ PERFETTO_ELOG("Invalid ftrace page");
+ std::string hexdump = base::HexDump(start, size);
+ // Only a single line per log message, because log message size might be
+ // limited.
+ for (base::StringSplitter ss(std::move(hexdump), '\n'); ss.Next();) {
+ PERFETTO_ELOG("%s", ss.cur_token());
+ }
+}
+
} // namespace
using protos::pbzero::GenericFtraceEvent;
@@ -148,10 +154,12 @@ using protos::pbzero::GenericFtraceEvent;
CpuReader::CpuReader(size_t cpu,
const ProtoTranslationTable* table,
LazyKernelSymbolizer* symbolizer,
+ const FtraceClockSnapshot* ftrace_clock_snapshot,
base::ScopedFile trace_fd)
: cpu_(cpu),
table_(table),
symbolizer_(symbolizer),
+ ftrace_clock_snapshot_(ftrace_clock_snapshot),
trace_fd_(std::move(trace_fd)) {
PERFETTO_CHECK(trace_fd_);
PERFETTO_CHECK(SetBlocking(*trace_fd_, false));
@@ -273,18 +281,28 @@ size_t CpuReader::ReadAndProcessBatch(
return pages_read;
for (FtraceDataSource* data_source : started_data_sources) {
- bool success = ProcessPagesForDataSource(
+ size_t pages_parsed_ok = ProcessPagesForDataSource(
data_source->trace_writer(), data_source->mutable_metadata(), cpu_,
data_source->parsing_config(), parsing_buf, pages_read, table_,
- symbolizer_);
- PERFETTO_CHECK(success);
+ symbolizer_, ftrace_clock_snapshot_, ftrace_clock_);
+ // If this happens, it means that we did not know how to parse the kernel
+ // binary format. This is a bug in either perfetto or the kernel, and must
+ // be investigated. Hence we abort instead of recording a bit in the ftrace
+ // stats proto, which is easier to overlook.
+ if (pages_parsed_ok != pages_read) {
+ const size_t first_bad_page_idx = pages_parsed_ok;
+ const uint8_t* curr_page =
+ parsing_buf + (first_bad_page_idx * base::kPageSize);
+ LogInvalidPage(curr_page, base::kPageSize);
+ PERFETTO_FATAL("Failed to parse ftrace page");
+ }
}
return pages_read;
}
// static
-bool CpuReader::ProcessPagesForDataSource(
+size_t CpuReader::ProcessPagesForDataSource(
TraceWriter* trace_writer,
FtraceMetadata* metadata,
size_t cpu,
@@ -292,7 +310,9 @@ bool CpuReader::ProcessPagesForDataSource(
const uint8_t* parsing_buf,
const size_t pages_read,
const ProtoTranslationTable* table,
- LazyKernelSymbolizer* symbolizer) {
+ LazyKernelSymbolizer* symbolizer,
+ const FtraceClockSnapshot* ftrace_clock_snapshot,
+ protos::pbzero::FtraceClock ftrace_clock) {
// Allocate the buffer for compact scheduler events (which will be unused if
// the compact option isn't enabled).
CompactSchedBuffer compact_sched;
@@ -313,7 +333,6 @@ bool CpuReader::ProcessPagesForDataSource(
// Write the kernel symbol index (mangled address) -> name table.
// |metadata| is shared across all cpus, is distinct per |data_source| (i.e.
// tracing session) and is cleared after each FtraceController::ReadTick().
- // const size_t kaddrs_size = metadata->kernel_addrs.size();
if (ds_config->symbolize_ksyms) {
// Symbol indexes are assigned mononically as |kernel_addrs.size()|,
// starting from index 1 (no symbol has index 0). Here we remember the
@@ -374,6 +393,15 @@ bool CpuReader::ProcessPagesForDataSource(
finalize_cur_packet();
packet = trace_writer->NewTracePacket();
bundle = packet->set_ftrace_events();
+ if (ftrace_clock) {
+ bundle->set_ftrace_clock(ftrace_clock);
+
+ if (ftrace_clock_snapshot && ftrace_clock_snapshot->ftrace_clock_ts) {
+ bundle->set_ftrace_timestamp(ftrace_clock_snapshot->ftrace_clock_ts);
+ bundle->set_boot_timestamp(ftrace_clock_snapshot->boot_clock_ts);
+ }
+ }
+
// Note: The fastpath in proto_trace_parser.cc speculates on the fact
// that the cpu field is the first field of the proto message. If this
// changes, change proto_trace_parser.cc accordingly.
@@ -383,8 +411,9 @@ bool CpuReader::ProcessPagesForDataSource(
};
start_new_packet(/*lost_events=*/false);
- for (size_t i = 0; i < pages_read; i++) {
- const uint8_t* curr_page = parsing_buf + (i * base::kPageSize);
+ size_t pages_parsed = 0;
+ for (; pages_parsed < pages_read; pages_parsed++) {
+ const uint8_t* curr_page = parsing_buf + (pages_parsed * base::kPageSize);
const uint8_t* curr_page_end = curr_page + base::kPageSize;
const uint8_t* parse_pos = curr_page;
base::Optional<PageHeader> page_header =
@@ -393,8 +422,7 @@ bool CpuReader::ProcessPagesForDataSource(
if (!page_header.has_value() || page_header->size == 0 ||
parse_pos >= curr_page_end ||
parse_pos + page_header->size > curr_page_end) {
- PERFETTO_DFATAL("invalid page header");
- return false;
+ break;
}
// Start a new bundle if either:
@@ -416,13 +444,13 @@ bool CpuReader::ProcessPagesForDataSource(
ParsePagePayload(parse_pos, &page_header.value(), table, ds_config,
&compact_sched, bundle, metadata);
- // TODO(rsavitski): propagate error to trace processor in release builds.
- // (FtraceMetadata -> FtraceStats in trace).
- PERFETTO_DCHECK(evt_size == page_header->size);
+ if (evt_size != page_header->size) {
+ break;
+ }
}
finalize_cur_packet();
- return true;
+ return pages_parsed;
}
// A page header consists of:
@@ -532,11 +560,11 @@ size_t CpuReader::ParsePagePayload(const uint8_t* start_of_payload,
// size in the process. We assume the newer layout. Parsed the same as
// kTypeTimeExtend, except that the timestamp is interpreted as an
// absolute, instead of a delta on top of the previous state.
- timestamp = event_header.time_delta;
uint32_t time_delta_ext = 0;
if (!ReadAndAdvance<uint32_t>(&ptr, end, &time_delta_ext))
return 0;
- timestamp += (static_cast<uint64_t>(time_delta_ext)) << 27;
+ timestamp = event_header.time_delta +
+ (static_cast<uint64_t>(time_delta_ext) << 27);
break;
}
// Data record:
@@ -647,7 +675,6 @@ bool CpuReader::ParseEvent(uint16_t ftrace_event_id,
for (const Field& field : info.fields) {
auto generic_field = nested->BeginNestedMessage<protozero::Message>(
GenericFtraceEvent::kFieldFieldNumber);
- // TODO(hjd): Avoid outputting field names every time.
generic_field->AppendString(GenericFtraceEvent::Field::kNameFieldNumber,
field.ftrace_name);
success &= ParseField(field, start, end, table, generic_field, metadata);
@@ -720,12 +747,14 @@ bool CpuReader::ParseField(const Field& field,
ReadIntoVarInt<int64_t>(field_start, field_id, message);
return true;
case kFixedCStringToString:
- // TODO(hjd): Add AppendMaxLength string to protozero.
- return ReadIntoString(field_start, field_start + field.ftrace_size,
- field_id, message);
+ // TODO(hjd): Kernel-dive to check this how size:0 char fields work.
+ ReadIntoString(field_start, field.ftrace_size, field_id, message);
+ return true;
case kCStringToString:
// TODO(hjd): Kernel-dive to check this how size:0 char fields work.
- return ReadIntoString(field_start, end, field_id, message);
+ ReadIntoString(field_start, static_cast<size_t>(end - field_start),
+ field_id, message);
+ return true;
case kStringPtrToString: {
uint64_t n = 0;
// The ftrace field may be 8 or 4 bytes and we need to copy it into the
diff --git a/src/traced/probes/ftrace/cpu_reader.h b/src/traced/probes/ftrace/cpu_reader.h
index ba0f9fd55..414da31e7 100644
--- a/src/traced/probes/ftrace/cpu_reader.h
+++ b/src/traced/probes/ftrace/cpu_reader.h
@@ -44,11 +44,13 @@ namespace perfetto {
class FtraceDataSource;
class LazyKernelSymbolizer;
class ProtoTranslationTable;
+struct FtraceClockSnapshot;
struct FtraceDataSourceConfig;
namespace protos {
namespace pbzero {
class FtraceEventBundle;
+enum FtraceClock : int32_t;
} // namespace pbzero
} // namespace protos
@@ -67,6 +69,7 @@ class CpuReader {
CpuReader(size_t cpu,
const ProtoTranslationTable* table,
LazyKernelSymbolizer* symbolizer,
+ const FtraceClockSnapshot*,
base::ScopedFile trace_fd);
~CpuReader();
@@ -231,15 +234,26 @@ class CpuReader {
// Parses & encodes the given range of contiguous tracing pages. Called by
// |ReadAndProcessBatch| for each active data source.
//
+ // Returns the number of correctly processed pages. If the return value is
+ // equal to |pages_read|, there was no error. Otherwise, the return value
+ // points to the first page that contains an error.
+ //
// public and static for testing
- static bool ProcessPagesForDataSource(TraceWriter* trace_writer,
- FtraceMetadata* metadata,
- size_t cpu,
- const FtraceDataSourceConfig* ds_config,
- const uint8_t* parsing_buf,
- const size_t pages_read,
- const ProtoTranslationTable* table,
- LazyKernelSymbolizer* symbolizer);
+ static size_t ProcessPagesForDataSource(
+ TraceWriter* trace_writer,
+ FtraceMetadata* metadata,
+ size_t cpu,
+ const FtraceDataSourceConfig* ds_config,
+ const uint8_t* parsing_buf,
+ const size_t pages_read,
+ const ProtoTranslationTable* table,
+ LazyKernelSymbolizer* symbolizer,
+ const FtraceClockSnapshot*,
+ protos::pbzero::FtraceClock);
+
+ void set_ftrace_clock(protos::pbzero::FtraceClock clock) {
+ ftrace_clock_ = clock;
+ }
private:
CpuReader(const CpuReader&) = delete;
@@ -258,7 +272,9 @@ class CpuReader {
const size_t cpu_;
const ProtoTranslationTable* const table_;
LazyKernelSymbolizer* const symbolizer_;
+ const FtraceClockSnapshot* const ftrace_clock_snapshot_;
base::ScopedFile trace_fd_;
+ protos::pbzero::FtraceClock ftrace_clock_{};
};
} // namespace perfetto
diff --git a/src/traced/probes/ftrace/cpu_reader_benchmark.cc b/src/traced/probes/ftrace/cpu_reader_benchmark.cc
index 6a647a9a1..f6f703831 100644
--- a/src/traced/probes/ftrace/cpu_reader_benchmark.cc
+++ b/src/traced/probes/ftrace/cpu_reader_benchmark.cc
@@ -328,7 +328,8 @@ static void BM_ParsePageFullOfSchedSwitch(benchmark::State& state) {
while (state.KeepRunning()) {
writer.Reset(&stream);
- CompactSchedBuffer compact_buffer;
+ std::unique_ptr<CompactSchedBuffer> compact_buffer(
+ new CompactSchedBuffer());
const uint8_t* parse_pos = page.get();
perfetto::base::Optional<CpuReader::PageHeader> page_header =
CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
@@ -337,7 +338,7 @@ static void BM_ParsePageFullOfSchedSwitch(benchmark::State& state) {
return;
CpuReader::ParsePagePayload(parse_pos, &page_header.value(), table,
- &ds_config, &compact_buffer, &writer,
+ &ds_config, compact_buffer.get(), &writer,
&metadata);
metadata.Clear();
diff --git a/src/traced/probes/ftrace/cpu_reader_fuzzer.cc b/src/traced/probes/ftrace/cpu_reader_fuzzer.cc
index db943a659..84dfda0b0 100644
--- a/src/traced/probes/ftrace/cpu_reader_fuzzer.cc
+++ b/src/traced/probes/ftrace/cpu_reader_fuzzer.cc
@@ -23,12 +23,13 @@
#include "perfetto/ext/base/utils.h"
#include "perfetto/protozero/scattered_stream_null_delegate.h"
#include "perfetto/protozero/scattered_stream_writer.h"
-#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
#include "src/traced/probes/ftrace/cpu_reader.h"
#include "src/traced/probes/ftrace/ftrace_config_muxer.h"
#include "src/traced/probes/ftrace/test/cpu_reader_support.h"
#include "src/tracing/core/null_trace_writer.h"
+#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
+
namespace perfetto {
namespace {
@@ -64,9 +65,10 @@ void FuzzCpuReaderProcessPagesForDataSource(const uint8_t* data, size_t size) {
table->EventToFtraceId(GroupAndName("ftrace", "print")));
NullTraceWriter null_writer;
- CpuReader::ProcessPagesForDataSource(&null_writer, &metadata, /*cpu=*/0,
- &ds_config, g_page, /*pages_read=*/1,
- table, /*symbolizer*/ nullptr);
+ CpuReader::ProcessPagesForDataSource(
+ &null_writer, &metadata, /*cpu=*/0, &ds_config, g_page, /*pages_read=*/1,
+ table, /*symbolizer*/ nullptr, /*ftrace_clock_snapshot=*/nullptr,
+ protos::pbzero::FTRACE_CLOCK_UNSPECIFIED);
}
} // namespace perfetto
diff --git a/src/traced/probes/ftrace/cpu_reader_unittest.cc b/src/traced/probes/ftrace/cpu_reader_unittest.cc
index dd596efc5..a911318fb 100644
--- a/src/traced/probes/ftrace/cpu_reader_unittest.cc
+++ b/src/traced/probes/ftrace/cpu_reader_unittest.cc
@@ -32,6 +32,7 @@
#include "src/tracing/core/trace_writer_for_testing.h"
#include "test/gtest_and_gmock.h"
+#include "protos/perfetto/trace/ftrace/dpu.gen.h"
#include "protos/perfetto/trace/ftrace/ftrace.gen.h"
#include "protos/perfetto/trace/ftrace/ftrace_event.gen.h"
#include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
@@ -39,6 +40,7 @@
#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
#include "protos/perfetto/trace/ftrace/power.gen.h"
#include "protos/perfetto/trace/ftrace/sched.gen.h"
+#include "protos/perfetto/trace/ftrace/task.gen.h"
#include "protos/perfetto/trace/trace_packet.gen.h"
#include "src/traced/probes/ftrace/test/test_messages.gen.h"
#include "src/traced/probes/ftrace/test/test_messages.pbzero.h"
@@ -386,7 +388,7 @@ TEST(CpuReaderTest, ParseSinglePrint) {
table->EventToFtraceId(GroupAndName("ftrace", "print")));
FtraceMetadata metadata{};
- CompactSchedBuffer compact_buffer;
+ std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
const uint8_t* parse_pos = page.get();
base::Optional<CpuReader::PageHeader> page_header =
CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
@@ -399,7 +401,7 @@ TEST(CpuReaderTest, ParseSinglePrint) {
EXPECT_TRUE(parse_pos + page_header->size < page_end);
size_t evt_bytes = CpuReader::ParsePagePayload(
- parse_pos, &page_header.value(), table, &ds_config, &compact_buffer,
+ parse_pos, &page_header.value(), table, &ds_config, compact_buffer.get(),
bundle_provider.writer(), &metadata);
EXPECT_EQ(evt_bytes, 44ul);
@@ -514,7 +516,8 @@ TEST(CpuReaderTest, ReallyLongEvent) {
table->EventToFtraceId(GroupAndName("ftrace", "print")));
FtraceMetadata metadata{};
- CompactSchedBuffer compact_buffer;
+ std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
+
const uint8_t* parse_pos = page.get();
base::Optional<CpuReader::PageHeader> page_header =
CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
@@ -526,7 +529,7 @@ TEST(CpuReaderTest, ReallyLongEvent) {
EXPECT_TRUE(parse_pos + page_header->size < page_end);
CpuReader::ParsePagePayload(parse_pos, &page_header.value(), table,
- &ds_config, &compact_buffer,
+ &ds_config, compact_buffer.get(),
bundle_provider.writer(), &metadata);
auto bundle = bundle_provider.ParseProto();
@@ -539,20 +542,20 @@ TEST(CpuReaderTest, ReallyLongEvent) {
}
// This event is as the event for ParseSinglePrint above except the string
-// is extended to overflow the page size written in the header.
-static ExamplePage g_single_print_malformed{
+// is extended and not null terminated.
+static ExamplePage g_single_print_non_null_terminated{
"synthetic",
R"(
- 00000000: ba12 6a33 c628 0200 2c00 0000 0000 0000 ................
- 00000010: def0 ec67 8d21 0000 0800 0000 0500 0001 ................
- 00000020: 2870 0000 ac5d 1661 86ff ffff 4865 6c6c ................
- 00000030: 6f2c 2077 6f72 6c64 2120 776f 726c 6421 ................
- 00000040: 0a00 ff00 0000 0000 0000 0000 0000 0000 ................
+ 00000000: ba12 6a33 c628 0200 2c00 0000 0000 0000 ..j3.(..,.......
+ 00000010: def0 ec67 8d21 0000 0800 0000 0500 0001 ...g.!..........
+ 00000020: 2870 0000 ac5d 1661 86ff ffff 4865 6c6c (p...].a....Hell
+ 00000030: 6f2c 2077 6f72 6c64 2161 6161 6161 6161 o, world!aaaaaaa
+ 00000040: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa
)",
};
-TEST(CpuReaderTest, ParseSinglePrintMalformed) {
- const ExamplePage* test_case = &g_single_print_malformed;
+TEST(CpuReaderTest, ParseSinglePrintNonNullTerminated) {
+ const ExamplePage* test_case = &g_single_print_non_null_terminated;
BundleProvider bundle_provider(base::kPageSize);
ProtoTranslationTable* table = GetTable(test_case->name);
@@ -563,7 +566,7 @@ TEST(CpuReaderTest, ParseSinglePrintMalformed) {
table->EventToFtraceId(GroupAndName("ftrace", "print")));
FtraceMetadata metadata{};
- CompactSchedBuffer compact_buffer;
+ std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
const uint8_t* parse_pos = page.get();
base::Optional<CpuReader::PageHeader> page_header =
CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
@@ -575,19 +578,67 @@ TEST(CpuReaderTest, ParseSinglePrintMalformed) {
EXPECT_TRUE(parse_pos + page_header->size < page_end);
size_t evt_bytes = CpuReader::ParsePagePayload(
- parse_pos, &page_header.value(), table, &ds_config, &compact_buffer,
+ parse_pos, &page_header.value(), table, &ds_config, compact_buffer.get(),
bundle_provider.writer(), &metadata);
- ASSERT_EQ(0u, evt_bytes);
+ ASSERT_EQ(44u, evt_bytes);
auto bundle = bundle_provider.ParseProto();
ASSERT_TRUE(bundle);
ASSERT_EQ(bundle->event().size(), 1u);
- // Although one field is malformed we still see data for the rest
- // since we write the fields as we parse them for speed.
const protos::gen::FtraceEvent& event = bundle->event()[0];
EXPECT_EQ(event.pid(), 28712ul);
EXPECT_TRUE(WithinOneMicrosecond(event.timestamp(), 608934, 535199));
+ EXPECT_EQ(event.print().buf(), "Hello, world!aaa");
+}
+
+static ExamplePage g_single_print_zero_size{
+ "synthetic",
+ R"(
+ 00000000: ba12 6a33 c628 0200 2c00 0000 0000 0000 ..j3.(..,.......
+ 00000010: def0 ec67 8d21 0000 0800 0000 0500 0001 ...g.!..........
+ 00000020: 2870 0000 ac5d 1661 86ff ffff 0000 0000 (p...].a........
+ 00000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+ 00000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+ )",
+};
+
+TEST(CpuReaderTest, ParseSinglePrintZeroSize) {
+ const ExamplePage* test_case = &g_single_print_zero_size;
+
+ BundleProvider bundle_provider(base::kPageSize);
+ ProtoTranslationTable* table = GetTable(test_case->name);
+ auto page = PageFromXxd(test_case->data);
+
+ FtraceDataSourceConfig ds_config = EmptyConfig();
+ ds_config.event_filter.AddEnabledEvent(
+ table->EventToFtraceId(GroupAndName("ftrace", "print")));
+
+ FtraceMetadata metadata{};
+ std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
+ const uint8_t* parse_pos = page.get();
+ base::Optional<CpuReader::PageHeader> page_header =
+ CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
+
+ const uint8_t* page_end = page.get() + base::kPageSize;
+ ASSERT_TRUE(page_header.has_value());
+ EXPECT_FALSE(page_header->lost_events);
+ EXPECT_TRUE(parse_pos < page_end);
+ EXPECT_TRUE(parse_pos + page_header->size < page_end);
+
+ size_t evt_bytes = CpuReader::ParsePagePayload(
+ parse_pos, &page_header.value(), table, &ds_config, compact_buffer.get(),
+ bundle_provider.writer(), &metadata);
+
+ ASSERT_EQ(44u, evt_bytes);
+
+ auto bundle = bundle_provider.ParseProto();
+ ASSERT_TRUE(bundle);
+ ASSERT_EQ(bundle->event().size(), 1u);
+ const protos::gen::FtraceEvent& event = bundle->event()[0];
+ EXPECT_EQ(event.pid(), 28712ul);
+ EXPECT_TRUE(WithinOneMicrosecond(event.timestamp(), 608934, 535199));
+ EXPECT_TRUE(event.print().has_buf());
EXPECT_EQ(event.print().buf(), "");
}
@@ -601,7 +652,7 @@ TEST(CpuReaderTest, FilterByEvent) {
FtraceDataSourceConfig ds_config = EmptyConfig();
FtraceMetadata metadata{};
- CompactSchedBuffer compact_buffer;
+ std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
const uint8_t* parse_pos = page.get();
base::Optional<CpuReader::PageHeader> page_header =
CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
@@ -610,7 +661,7 @@ TEST(CpuReaderTest, FilterByEvent) {
EXPECT_FALSE(page_header->lost_events);
size_t evt_bytes = CpuReader::ParsePagePayload(
- parse_pos, &page_header.value(), table, &ds_config, &compact_buffer,
+ parse_pos, &page_header.value(), table, &ds_config, compact_buffer.get(),
bundle_provider.writer(), &metadata);
EXPECT_LT(0u, evt_bytes);
@@ -666,7 +717,7 @@ TEST(CpuReaderTest, ParseThreePrint) {
table->EventToFtraceId(GroupAndName("ftrace", "print")));
FtraceMetadata metadata{};
- CompactSchedBuffer compact_buffer;
+ std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
const uint8_t* parse_pos = page.get();
base::Optional<CpuReader::PageHeader> page_header =
CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
@@ -678,7 +729,7 @@ TEST(CpuReaderTest, ParseThreePrint) {
EXPECT_TRUE(parse_pos + page_header->size < page_end);
size_t evt_bytes = CpuReader::ParsePagePayload(
- parse_pos, &page_header.value(), table, &ds_config, &compact_buffer,
+ parse_pos, &page_header.value(), table, &ds_config, compact_buffer.get(),
bundle_provider.writer(), &metadata);
EXPECT_LT(0u, evt_bytes);
@@ -775,7 +826,7 @@ TEST(CpuReaderTest, ParseSixSchedSwitch) {
table->EventToFtraceId(GroupAndName("sched", "sched_switch")));
FtraceMetadata metadata{};
- CompactSchedBuffer compact_buffer;
+ std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
const uint8_t* parse_pos = page.get();
base::Optional<CpuReader::PageHeader> page_header =
CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
@@ -787,7 +838,7 @@ TEST(CpuReaderTest, ParseSixSchedSwitch) {
EXPECT_TRUE(parse_pos + page_header->size < page_end);
size_t evt_bytes = CpuReader::ParsePagePayload(
- parse_pos, &page_header.value(), table, &ds_config, &compact_buffer,
+ parse_pos, &page_header.value(), table, &ds_config, compact_buffer.get(),
bundle_provider.writer(), &metadata);
EXPECT_LT(0u, evt_bytes);
@@ -825,7 +876,7 @@ TEST(CpuReaderTest, ParseSixSchedSwitchCompactFormat) {
table->EventToFtraceId(GroupAndName("sched", "sched_switch")));
FtraceMetadata metadata{};
- CompactSchedBuffer compact_buffer;
+ std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
const uint8_t* parse_pos = page.get();
base::Optional<CpuReader::PageHeader> page_header =
CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
@@ -837,7 +888,7 @@ TEST(CpuReaderTest, ParseSixSchedSwitchCompactFormat) {
EXPECT_TRUE(parse_pos + page_header->size < page_end);
size_t evt_bytes = CpuReader::ParsePagePayload(
- parse_pos, &page_header.value(), table, &ds_config, &compact_buffer,
+ parse_pos, &page_header.value(), table, &ds_config, compact_buffer.get(),
bundle_provider.writer(), &metadata);
EXPECT_LT(0u, evt_bytes);
@@ -850,11 +901,11 @@ TEST(CpuReaderTest, ParseSixSchedSwitchCompactFormat) {
bundle_provider.ResetWriter();
// Instead, sched switch fields were buffered:
- EXPECT_LT(0u, compact_buffer.sched_switch().size());
- EXPECT_LT(0u, compact_buffer.interner().interned_comms_size());
+ EXPECT_LT(0u, compact_buffer->sched_switch().size());
+ EXPECT_LT(0u, compact_buffer->interner().interned_comms_size());
// Write the buffer out & check the serialized format:
- compact_buffer.WriteAndReset(bundle_provider.writer());
+ compact_buffer->WriteAndReset(bundle_provider.writer());
bundle_provider.writer()->Finalize();
bundle = bundle_provider.ParseProto();
ASSERT_TRUE(bundle);
@@ -1069,7 +1120,7 @@ TEST_F(CpuReaderTableTest, ParseAllFields) {
writer.Write<int64_t>(99u); // Inode 64
writer.WriteFixedString(16, "Hello");
writer.Write<uint64_t>(0xffffff8504f51b23ULL); // char* (printk formats)
- writer.Write<uint8_t>(0); // Deliberately mis-aligning.
+ writer.Write<uint8_t>(0); // Deliberately mis-aligning.
writer.Write<uint32_t>(40 | 6 << 16);
writer.WriteFixedString(300, "Goodbye");
@@ -1135,6 +1186,42 @@ TEST(CpuReaderTest, TaskRenameEvent) {
EXPECT_THAT(metadata.pids, Contains(9999));
}
+// Regression test for b/205763418: Kernels without f0a515780393("tracing: Don't
+// make assumptions about length of string on task rename") can output non
+// zero-terminated strings in some cases. Even though it's a kernel bug, there's
+// no point in rejecting that.
+TEST(CpuReaderTest, EventNonZeroTerminated) {
+ BundleProvider bundle_provider(base::kPageSize);
+
+ BinaryWriter writer;
+ ProtoTranslationTable* table = GetTable("android_seed_N2F62_3.10.49");
+
+ constexpr uint32_t kTaskRenameId = 19;
+
+ writer.Write<int32_t>(1001); // Common field.
+ writer.Write<int32_t>(9999); // Common pid
+ writer.Write<int32_t>(9999); // Pid
+ writer.WriteFixedString(16, "Hello"); // Old Comm
+ std::array<char, 16> newcomm;
+ memcpy(&newcomm, "0123456789abcdef", sizeof newcomm);
+ writer.Write(newcomm); // New Comm - not null terminated
+ writer.Write<uint64_t>(10); // flags
+ writer.Write<int16_t>(10); // oom_score_adj
+
+ auto input = writer.GetCopy();
+ auto length = writer.written();
+ FtraceMetadata metadata{};
+
+ ASSERT_TRUE(CpuReader::ParseEvent(
+ kTaskRenameId, input.get(), input.get() + length, table,
+ bundle_provider.writer()->add_event(), &metadata));
+ std::unique_ptr<protos::gen::FtraceEventBundle> a =
+ bundle_provider.ParseProto();
+ ASSERT_NE(a, nullptr);
+ ASSERT_EQ(a->event().size(), 1u);
+ ASSERT_EQ(a->event()[0].task_rename().newcomm(), "0123456789abcdef");
+}
+
// Page with a single sched_switch, no data loss.
static char g_switch_page[] =
R"(
@@ -1157,6 +1244,17 @@ static char g_switch_page_lost_events[] =
00000050: 0000 0000 950e 0000 7800 0000 0000 0000 ................
)";
+// Page with invalid data.
+static char g_invalid_page[] =
+ R"(
+ 00000000: 2b16 c3be 90b6 0300 4b00 0000 0000 0000 ................
+ 00000010: 1e00 0000 0000 0000 1000 0000 2f00 0103 ................
+ 00000020: 0300 0000 6b73 6f66 7469 7271 642f 3000 ................
+ 00000030: 0000 0000 0300 0000 7800 0000 0100 0000 ................
+ 00000040: 0000 0000 736c 6565 7000 722f 3000 0000 ................
+ 00000050: 0000 0000 950e 0000 7800 0000 0000 0000 ................
+ )";
+
TEST(CpuReaderTest, NewPacketOnLostEvents) {
auto page_ok = PageFromXxd(g_switch_page);
auto page_loss = PageFromXxd(g_switch_page_lost_events);
@@ -1167,9 +1265,10 @@ TEST(CpuReaderTest, NewPacketOnLostEvents) {
// Prepare a buffer with 8 contiguous pages, with the above contents.
static constexpr size_t kTestPages = 8;
- uint8_t buf[base::kPageSize * kTestPages] = {};
+
+ std::unique_ptr<uint8_t[]> buf(new uint8_t[base::kPageSize * kTestPages]());
for (size_t i = 0; i < kTestPages; i++) {
- void* dest = buf + (i * base::kPageSize);
+ void* dest = buf.get() + (i * base::kPageSize);
memcpy(dest, static_cast<const void*>(test_page_order[i]), base::kPageSize);
}
@@ -1181,9 +1280,12 @@ TEST(CpuReaderTest, NewPacketOnLostEvents) {
table->EventToFtraceId(GroupAndName("sched", "sched_switch")));
TraceWriterForTesting trace_writer;
- CpuReader::ProcessPagesForDataSource(&trace_writer, &metadata, /*cpu=*/1,
- &ds_config, buf, kTestPages, table,
- /*symbolizer=*/nullptr);
+ size_t processed_pages = CpuReader::ProcessPagesForDataSource(
+ &trace_writer, &metadata, /*cpu=*/1, &ds_config, buf.get(), kTestPages,
+ table, /*symbolizer=*/nullptr, /*ftrace_clock_snapshot=*/nullptr,
+ protos::pbzero::FTRACE_CLOCK_UNSPECIFIED);
+
+ ASSERT_EQ(processed_pages, kTestPages);
// Each packet should contain the parsed contents of a contiguous run of pages
// without data loss.
@@ -1202,6 +1304,39 @@ TEST(CpuReaderTest, NewPacketOnLostEvents) {
EXPECT_EQ(4u, packets[2].ftrace_events().event().size());
}
+TEST(CpuReaderTest, ProcessPagesForDataSourceError) {
+ auto page_ok = PageFromXxd(g_switch_page);
+ auto page_err = PageFromXxd(g_invalid_page);
+
+ std::vector<const void*> test_page_order = {
+ page_ok.get(), page_ok.get(), page_ok.get(), page_err.get(),
+ page_ok.get(), page_ok.get(), page_err.get(), page_ok.get()};
+
+ // Prepare a buffer with 8 contiguous pages, with the above contents.
+ static constexpr size_t kTestPages = 8;
+
+ std::unique_ptr<uint8_t[]> buf(new uint8_t[base::kPageSize * kTestPages]());
+ for (size_t i = 0; i < kTestPages; i++) {
+ void* dest = buf.get() + (i * base::kPageSize);
+ memcpy(dest, static_cast<const void*>(test_page_order[i]), base::kPageSize);
+ }
+
+ BundleProvider bundle_provider(base::kPageSize);
+ ProtoTranslationTable* table = GetTable("synthetic");
+ FtraceMetadata metadata{};
+ FtraceDataSourceConfig ds_config = EmptyConfig();
+ ds_config.event_filter.AddEnabledEvent(
+ table->EventToFtraceId(GroupAndName("sched", "sched_switch")));
+
+ TraceWriterForTesting trace_writer;
+ size_t processed_pages = CpuReader::ProcessPagesForDataSource(
+ &trace_writer, &metadata, /*cpu=*/1, &ds_config, buf.get(), kTestPages,
+ table, /*symbolizer=*/nullptr, /*ftrace_clock_snapshot=*/nullptr,
+ protos::pbzero::FTRACE_CLOCK_UNSPECIFIED);
+
+ EXPECT_EQ(processed_pages, 3u);
+}
+
// Page containing an absolute timestamp (RINGBUF_TYPE_TIME_STAMP).
static char g_abs_timestamp[] =
R"(
@@ -1346,30 +1481,31 @@ TEST(CpuReaderTest, ParseAbsoluteTimestamp) {
SetTranslationStrategy(field->ftrace_type, field->proto_field_type,
&field->strategy);
}
+ using Switch = protos::gen::SchedSwitchFtraceEvent;
Event sched_switch_event{
"sched_switch",
"sched",
{
- {8, 16, FtraceFieldType::kFtraceFixedCString, "prev_comm", 1,
- ProtoSchemaType::kString,
+ {8, 16, FtraceFieldType::kFtraceFixedCString, "prev_comm",
+ Switch::kPrevCommFieldNumber, ProtoSchemaType::kString,
TranslationStrategy::kInvalidTranslationStrategy},
- {24, 4, FtraceFieldType::kFtracePid32, "prev_pid", 2,
- ProtoSchemaType::kInt32,
+ {24, 4, FtraceFieldType::kFtracePid32, "prev_pid",
+ Switch::kPrevPidFieldNumber, ProtoSchemaType::kInt32,
TranslationStrategy::kInvalidTranslationStrategy},
- {28, 4, FtraceFieldType::kFtraceInt32, "prev_prio", 3,
- ProtoSchemaType::kInt32,
+ {28, 4, FtraceFieldType::kFtraceInt32, "prev_prio",
+ Switch::kPrevPrioFieldNumber, ProtoSchemaType::kInt32,
TranslationStrategy::kInvalidTranslationStrategy},
- {32, 8, FtraceFieldType::kFtraceInt64, "prev_state", 4,
- ProtoSchemaType::kInt64,
+ {32, 8, FtraceFieldType::kFtraceInt64, "prev_state",
+ Switch::kPrevStateFieldNumber, ProtoSchemaType::kInt64,
TranslationStrategy::kInvalidTranslationStrategy},
- {40, 16, FtraceFieldType::kFtraceFixedCString, "next_comm", 5,
- ProtoSchemaType::kString,
+ {40, 16, FtraceFieldType::kFtraceFixedCString, "next_comm",
+ Switch::kNextCommFieldNumber, ProtoSchemaType::kString,
TranslationStrategy::kInvalidTranslationStrategy},
- {56, 4, FtraceFieldType::kFtracePid32, "next_pid", 6,
- ProtoSchemaType::kInt32,
+ {56, 4, FtraceFieldType::kFtracePid32, "next_pid",
+ Switch::kNextPidFieldNumber, ProtoSchemaType::kInt32,
TranslationStrategy::kInvalidTranslationStrategy},
- {60, 4, FtraceFieldType::kFtraceInt32, "next_prio", 7,
- ProtoSchemaType::kInt32,
+ {60, 4, FtraceFieldType::kFtraceInt32, "next_prio",
+ Switch::kNextPrioFieldNumber, ProtoSchemaType::kInt32,
TranslationStrategy::kInvalidTranslationStrategy},
},
/*ftrace_event_id=*/315,
@@ -1395,7 +1531,7 @@ TEST(CpuReaderTest, ParseAbsoluteTimestamp) {
table->EventToFtraceId(GroupAndName("sched", "sched_switch")));
FtraceMetadata metadata{};
- CompactSchedBuffer compact_buffer;
+ std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
const uint8_t* parse_pos = page.get();
base::Optional<CpuReader::PageHeader> page_header =
CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
@@ -1407,7 +1543,7 @@ TEST(CpuReaderTest, ParseAbsoluteTimestamp) {
EXPECT_TRUE(parse_pos + page_header->size < page_end);
size_t evt_bytes = CpuReader::ParsePagePayload(
- parse_pos, &page_header.value(), table, &ds_config, &compact_buffer,
+ parse_pos, &page_header.value(), table, &ds_config, compact_buffer.get(),
bundle_provider.writer(), &metadata);
ASSERT_LT(0u, evt_bytes);
@@ -1884,7 +2020,7 @@ TEST(CpuReaderTest, ParseFullPageSchedSwitch) {
table->EventToFtraceId(GroupAndName("sched", "sched_switch")));
FtraceMetadata metadata{};
- CompactSchedBuffer compact_buffer;
+ std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
const uint8_t* parse_pos = page.get();
base::Optional<CpuReader::PageHeader> page_header =
CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
@@ -1896,7 +2032,7 @@ TEST(CpuReaderTest, ParseFullPageSchedSwitch) {
EXPECT_TRUE(parse_pos + page_header->size < page_end);
size_t evt_bytes = CpuReader::ParsePagePayload(
- parse_pos, &page_header.value(), table, &ds_config, &compact_buffer,
+ parse_pos, &page_header.value(), table, &ds_config, compact_buffer.get(),
bundle_provider.writer(), &metadata);
EXPECT_LT(0u, evt_bytes);
@@ -1973,14 +2109,14 @@ TEST(CpuReaderTest, ParseSuspendResume) {
table->EventToFtraceId(GroupAndName("power", "suspend_resume")));
FtraceMetadata metadata{};
- CompactSchedBuffer compact_buffer;
+ std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
const uint8_t* parse_pos = page.get();
base::Optional<CpuReader::PageHeader> page_header =
CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
ASSERT_TRUE(page_header.has_value());
CpuReader::ParsePagePayload(
- parse_pos, &page_header.value(), table, &ds_config, &compact_buffer,
+ parse_pos, &page_header.value(), table, &ds_config, compact_buffer.get(),
bundle_provider.writer(), &metadata);
auto bundle = bundle_provider.ParseProto();
ASSERT_TRUE(bundle);
@@ -2417,7 +2553,7 @@ TEST(CpuReaderTest, ParseExt4WithOverwrite) {
table->EventToFtraceId(GroupAndName("sched", "sched_switch")));
FtraceMetadata metadata{};
- CompactSchedBuffer compact_buffer;
+ std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
const uint8_t* parse_pos = page.get();
base::Optional<CpuReader::PageHeader> page_header =
CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
@@ -2429,7 +2565,7 @@ TEST(CpuReaderTest, ParseExt4WithOverwrite) {
EXPECT_TRUE(parse_pos + page_header->size < page_end);
size_t evt_bytes = CpuReader::ParsePagePayload(
- parse_pos, &page_header.value(), table, &ds_config, &compact_buffer,
+ parse_pos, &page_header.value(), table, &ds_config, compact_buffer.get(),
bundle_provider.writer(), &metadata);
EXPECT_LT(0u, evt_bytes);
@@ -2438,4 +2574,123 @@ TEST(CpuReaderTest, ParseExt4WithOverwrite) {
ASSERT_TRUE(bundle);
}
+// Page with a single event containing a __data_loc entry with value 0x0000
+//
+// [timestamp ] [32 byte payload next ]
+// 00000000: D7 B3 0A 57 CF 02 00 00 20 00 00 00 00 00 00 00 ...W.... .......
+// [evt hdr ] [id ]
+// 00000010: 67 A6 13 00 0F 06 00 00 3D 01 00 00 45 00 00 00 g.......=...E...
+// 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+//
+// name: tracing_mark_write
+// ID: 1551
+// format:
+// field:unsigned short common_type; offset:0; size:2; signed:0;
+// field:unsigned char common_flags; offset:2; size:1; signed:0;
+// field:unsigned char common_preempt_count; offset:3; size:1;
+// signed:0; field:int common_pid; offset:4; size:4; signed:1;
+//
+// field:char type; offset:8; size:1; signed:0;
+// field:int pid; offset:12; size:4; signed:1;
+// field:__data_loc char[] name; offset:16; size:4; signed:0;
+// field:int value; offset:20; size:4; signed:1;
+//
+static char g_zero_data_loc[] =
+ R"(
+00000000: D7B3 0A57 CF02 0000 2000 0000 0000 0000 ...W.... .......
+00000010: 67A6 1300 0F06 0000 3D01 0000 4500 0000 g.......=...E...
+00000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+ )";
+
+TEST(CpuReaderTest, ZeroLengthDataLoc) {
+ BundleProvider bundle_provider(base::kPageSize);
+ auto page = PageFromXxd(g_zero_data_loc);
+
+ // Hand-build a translation table that handles dpu/tracing_mark_write for this
+ // test page.
+ // TODO(rsavitski): look into making these tests less verbose by feeding a
+ // format string through proto_translation_table to get the format.
+ std::vector<Field> common_fields;
+ { // common_pid
+ common_fields.emplace_back(Field{});
+ Field* field = &common_fields.back();
+ field->ftrace_offset = 4;
+ field->ftrace_size = 4;
+ field->ftrace_type = kFtraceCommonPid32;
+ field->proto_field_id = 2;
+ field->proto_field_type = ProtoSchemaType::kInt32;
+ SetTranslationStrategy(field->ftrace_type, field->proto_field_type,
+ &field->strategy);
+ }
+ using Dpu = protos::gen::DpuTracingMarkWriteFtraceEvent;
+ Event evt{"tracing_mark_write",
+ "dpu",
+ {
+ {8, 1, FtraceFieldType::kFtraceUint8, "type",
+ Dpu::kTypeFieldNumber, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {12, 4, FtraceFieldType::kFtraceInt32, "pid",
+ Dpu::kPidFieldNumber, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {16, 4, FtraceFieldType::kFtraceDataLoc, "name",
+ Dpu::kNameFieldNumber, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {20, 4, FtraceFieldType::kFtraceInt32, "value",
+ Dpu::kValueFieldNumber, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ /*ftrace_event_id=*/1551,
+ /*proto_field_id=*/348,
+ /*size=*/24};
+ for (Field& field : evt.fields) {
+ SetTranslationStrategy(field.ftrace_type, field.proto_field_type,
+ &field.strategy);
+ }
+ std::vector<Event> events;
+ events.emplace_back(std::move(evt));
+
+ NiceMock<MockFtraceProcfs> mock_ftrace;
+ PrintkMap printk_formats;
+ ProtoTranslationTable translation_table(
+ &mock_ftrace, events, std::move(common_fields),
+ ProtoTranslationTable::DefaultPageHeaderSpecForTesting(),
+ InvalidCompactSchedEventFormatForTesting(), printk_formats);
+ ProtoTranslationTable* table = &translation_table;
+
+ FtraceDataSourceConfig ds_config = EmptyConfig();
+ ds_config.event_filter.AddEnabledEvent(
+ table->EventToFtraceId(GroupAndName("dpu", "tracing_mark_write")));
+
+ FtraceMetadata metadata{};
+ std::unique_ptr<CompactSchedBuffer> compact_buffer(new CompactSchedBuffer());
+ const uint8_t* parse_pos = page.get();
+ base::Optional<CpuReader::PageHeader> page_header =
+ CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
+
+ const uint8_t* page_end = page.get() + base::kPageSize;
+ ASSERT_TRUE(page_header.has_value());
+ EXPECT_FALSE(page_header->lost_events);
+ EXPECT_TRUE(parse_pos < page_end);
+ EXPECT_TRUE(parse_pos + page_header->size < page_end);
+
+ size_t evt_bytes = CpuReader::ParsePagePayload(
+ parse_pos, &page_header.value(), table, &ds_config, compact_buffer.get(),
+ bundle_provider.writer(), &metadata);
+
+ // successfully parsed the whole 32 byte event
+ ASSERT_EQ(32u, page_header->size);
+ ASSERT_EQ(32u, evt_bytes);
+
+ auto bundle = bundle_provider.ParseProto();
+ ASSERT_TRUE(bundle);
+ EXPECT_EQ(bundle->event().size(), 1u);
+ const protos::gen::FtraceEvent& event = bundle->event()[0];
+ EXPECT_EQ(event.pid(), 317u);
+ EXPECT_EQ(event.dpu_tracing_mark_write().type(), 69u);
+ EXPECT_EQ(event.dpu_tracing_mark_write().pid(), 0);
+ EXPECT_EQ(event.dpu_tracing_mark_write().value(), 0);
+ EXPECT_EQ(event.dpu_tracing_mark_write().name(), "");
+}
+
} // namespace perfetto
diff --git a/src/traced/probes/ftrace/event_info.cc b/src/traced/probes/ftrace/event_info.cc
index b8c23e2b9..e7c83a49b 100644
--- a/src/traced/probes/ftrace/event_info.cc
+++ b/src/traced/probes/ftrace/event_info.cc
@@ -132,6 +132,9 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"offsets_size", 3, ProtoSchemaType::kUint64,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "extra_buffers_size", 4, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
323,
@@ -393,6 +396,9 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"cmd", 6, ProtoSchemaType::kString,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "error", 7, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
125,
@@ -569,6 +575,12 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"cname", 5, ProtoSchemaType::kString,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "dst_level", 6, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "dst_path", 7, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
67,
@@ -585,6 +597,12 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"cname", 3, ProtoSchemaType::kString,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "level", 4, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "path", 5, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
68,
@@ -617,6 +635,12 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"cname", 3, ProtoSchemaType::kString,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "level", 4, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "path", 5, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
70,
@@ -639,6 +663,12 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"cname", 5, ProtoSchemaType::kString,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "dst_level", 6, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "dst_path", 7, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
71,
@@ -671,6 +701,12 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"cname", 3, ProtoSchemaType::kString,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "level", 4, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "path", 5, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
73,
@@ -687,6 +723,12 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"cname", 3, ProtoSchemaType::kString,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "level", 4, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "path", 5, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
74,
@@ -941,6 +983,9 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"classzone_idx", 3, ProtoSchemaType::kUint32,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "highest_zoneidx", 4, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
108,
@@ -989,6 +1034,9 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"mode", 3, ProtoSchemaType::kUint32,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "prio", 4, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
111,
@@ -1005,6 +1053,9 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"classzone_idx", 3, ProtoSchemaType::kUint32,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "highest_zoneidx", 4, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
112,
@@ -1104,6 +1155,126 @@ std::vector<Event> GetStaticEventInfo() {
kUnsetFtraceId,
352,
kUnsetSize},
+ {"cros_ec_sensorhub_data",
+ "cros_ec",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "current_time", 1, ProtoSchemaType::kInt64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "current_timestamp", 2, ProtoSchemaType::kInt64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "delta", 3, ProtoSchemaType::kInt64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "ec_fifo_timestamp", 4, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "ec_sensor_num", 5, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "fifo_timestamp", 6, ProtoSchemaType::kInt64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 364,
+ kUnsetSize},
+ {"dma_fence_init",
+ "dma_fence",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "context", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "driver", 2, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "seqno", 3, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "timeline", 4, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 414,
+ kUnsetSize},
+ {"dma_fence_emit",
+ "dma_fence",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "context", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "driver", 2, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "seqno", 3, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "timeline", 4, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 415,
+ kUnsetSize},
+ {"dma_fence_signaled",
+ "dma_fence",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "context", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "driver", 2, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "seqno", 3, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "timeline", 4, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 416,
+ kUnsetSize},
+ {"dma_fence_wait_start",
+ "dma_fence",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "context", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "driver", 2, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "seqno", 3, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "timeline", 4, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 417,
+ kUnsetSize},
+ {"dma_fence_wait_end",
+ "dma_fence",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "context", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "driver", 2, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "seqno", 3, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "timeline", 4, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 418,
+ kUnsetSize},
{"dma_heap_stat",
"dmabuf_heap",
{
@@ -1145,6 +1316,41 @@ std::vector<Event> GetStaticEventInfo() {
kUnsetFtraceId,
348,
kUnsetSize},
+ {"drm_vblank_event",
+ "drm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "crtc", 1, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "high_prec", 2, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "seq", 3, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "time", 4, ProtoSchemaType::kInt64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 409,
+ kUnsetSize},
+ {"drm_vblank_event_delivered",
+ "drm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "crtc", 1, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "file", 2, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "seq", 3, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 410,
+ kUnsetSize},
{"ext4_da_write_begin",
"ext4",
{
@@ -1561,6 +1767,12 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"ino", 2, ProtoSchemaType::kUint64,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "len", 3, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "needed", 4, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
147,
@@ -2076,6 +2288,15 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"eh_entries", 7, ProtoSchemaType::kUint32,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "pc_lblk", 8, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "pc_pclu", 9, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "pc_state", 10, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
170,
@@ -2120,6 +2341,15 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"ee_len", 7, ProtoSchemaType::kInt32,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "pc_lblk", 8, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "pc_pclu", 9, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "pc_state", 10, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
172,
@@ -2449,6 +2679,9 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"nblocks", 5, ProtoSchemaType::kInt32,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "revoke_creds", 6, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
186,
@@ -2877,6 +3110,9 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"group", 2, ProtoSchemaType::kUint32,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "prefetch", 3, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
206,
@@ -2940,6 +3176,15 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"ee_len", 8, ProtoSchemaType::kUint32,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "pc_lblk", 9, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "pc_pclu", 10, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "pc_state", 11, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
209,
@@ -3410,6 +3655,9 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"free", 10, ProtoSchemaType::kUint32,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "cost", 11, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
247,
@@ -3495,6 +3743,15 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"type", 5, ProtoSchemaType::kInt32,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "dir", 6, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "dirty", 7, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "uptodate", 8, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
251,
@@ -3536,6 +3793,9 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"dirty", 6, ProtoSchemaType::kInt32,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "uptodate", 7, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
253,
@@ -3611,6 +3871,9 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"ret", 5, ProtoSchemaType::kInt32,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "cp_reason", 6, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
256,
@@ -3895,6 +4158,9 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"dirty", 6, ProtoSchemaType::kInt32,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "uptodate", 7, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
270,
@@ -3933,6 +4199,9 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"msg", 3, ProtoSchemaType::kString,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "reason", 4, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
272,
@@ -4140,6 +4409,66 @@ std::vector<Event> GetStaticEventInfo() {
kUnsetFtraceId,
340,
kUnsetSize},
+ {"drm_sched_job",
+ "gpu_scheduler",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "entity", 1, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "fence", 2, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "hw_job_count", 3, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "id", 4, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "job_count", 5, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "name", 6, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 411,
+ kUnsetSize},
+ {"drm_run_job",
+ "gpu_scheduler",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "entity", 1, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "fence", 2, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "hw_job_count", 3, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "id", 4, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "job_count", 5, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "name", 6, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 412,
+ kUnsetSize},
+ {"drm_sched_process_job",
+ "gpu_scheduler",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "fence", 1, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 413,
+ kUnsetSize},
{"i2c_read",
"i2c",
{
@@ -5182,6 +5511,531 @@ std::vector<Event> GetStaticEventInfo() {
kUnsetFtraceId,
337,
kUnsetSize},
+ {"kvm_access_fault",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "ipa", 1, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 368,
+ kUnsetSize},
+ {"kvm_ack_irq",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "irqchip", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "pin", 2, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 369,
+ kUnsetSize},
+ {"kvm_age_hva",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "end", 1, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "start", 2, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 370,
+ kUnsetSize},
+ {"kvm_age_page",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "gfn", 1, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "hva", 2, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "level", 3, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "referenced", 4, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 371,
+ kUnsetSize},
+ {"kvm_arm_clear_debug",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "guest_debug", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 372,
+ kUnsetSize},
+ {"kvm_arm_set_dreg32",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "name", 1, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "value", 2, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 373,
+ kUnsetSize},
+ {"kvm_arm_set_regset",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "len", 1, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "name", 2, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 374,
+ kUnsetSize},
+ {"kvm_arm_setup_debug",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "guest_debug", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "vcpu", 2, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 375,
+ kUnsetSize},
+ {"kvm_entry",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "vcpu_pc", 1, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 376,
+ kUnsetSize},
+ {"kvm_exit",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "esr_ec", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "ret", 2, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "vcpu_pc", 3, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 377,
+ kUnsetSize},
+ {"kvm_fpu",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "load", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 378,
+ kUnsetSize},
+ {"kvm_get_timer_map",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "direct_ptimer", 1, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "direct_vtimer", 2, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "emul_ptimer", 3, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "vcpu_id", 4, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 379,
+ kUnsetSize},
+ {"kvm_guest_fault",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "hsr", 1, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "hxfar", 2, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "ipa", 3, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "vcpu_pc", 4, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 380,
+ kUnsetSize},
+ {"kvm_handle_sys_reg",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "hsr", 1, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 381,
+ kUnsetSize},
+ {"kvm_hvc_arm64",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "imm", 1, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "r0", 2, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "vcpu_pc", 3, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 382,
+ kUnsetSize},
+ {"kvm_irq_line",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "irq_num", 1, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "level", 2, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "type", 3, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "vcpu_idx", 4, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 383,
+ kUnsetSize},
+ {"kvm_mmio",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "gpa", 1, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "len", 2, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "type", 3, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "val", 4, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 384,
+ kUnsetSize},
+ {"kvm_mmio_emulate",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "cpsr", 1, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "instr", 2, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "vcpu_pc", 3, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 385,
+ kUnsetSize},
+ {"kvm_set_guest_debug",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "guest_debug", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "vcpu", 2, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 386,
+ kUnsetSize},
+ {"kvm_set_irq",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "gsi", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "irq_source_id", 2, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "level", 3, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 387,
+ kUnsetSize},
+ {"kvm_set_spte_hva",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "hva", 1, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 388,
+ kUnsetSize},
+ {"kvm_set_way_flush",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "cache", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "vcpu_pc", 2, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 389,
+ kUnsetSize},
+ {"kvm_sys_access",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "CRm", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "CRn", 2, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "Op0", 3, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "Op1", 4, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "Op2", 5, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "is_write", 6, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "name", 7, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "vcpu_pc", 8, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 390,
+ kUnsetSize},
+ {"kvm_test_age_hva",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "hva", 1, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 391,
+ kUnsetSize},
+ {"kvm_timer_emulate",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "should_fire", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "timer_idx", 2, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 392,
+ kUnsetSize},
+ {"kvm_timer_hrtimer_expire",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "timer_idx", 1, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 393,
+ kUnsetSize},
+ {"kvm_timer_restore_state",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "ctl", 1, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "cval", 2, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "timer_idx", 3, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 394,
+ kUnsetSize},
+ {"kvm_timer_save_state",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "ctl", 1, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "cval", 2, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "timer_idx", 3, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 395,
+ kUnsetSize},
+ {"kvm_timer_update_irq",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "irq", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "level", 2, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "vcpu_id", 3, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 396,
+ kUnsetSize},
+ {"kvm_toggle_cache",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "now", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "vcpu_pc", 2, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "was", 3, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 397,
+ kUnsetSize},
+ {"kvm_unmap_hva_range",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "end", 1, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "start", 2, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 398,
+ kUnsetSize},
+ {"kvm_userspace_exit",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "reason", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 399,
+ kUnsetSize},
+ {"kvm_vcpu_wakeup",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "ns", 1, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "valid", 2, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "waited", 3, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 400,
+ kUnsetSize},
+ {"kvm_wfx_arm64",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "is_wfe", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "vcpu_pc", 2, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 401,
+ kUnsetSize},
+ {"trap_reg",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "fn", 1, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "is_write", 2, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "reg", 3, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "write_value", 4, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 402,
+ kUnsetSize},
+ {"vgic_update_irq_pending",
+ "kvm",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "irq", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "level", 2, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "vcpu_id", 3, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 403,
+ kUnsetSize},
{"lowmemory_kill",
"lowmemorykiller",
{
@@ -5704,6 +6558,115 @@ std::vector<Event> GetStaticEventInfo() {
kUnsetFtraceId,
328,
kUnsetSize},
+ {"netif_receive_skb",
+ "net",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "len", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "name", 2, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "skbaddr", 3, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 360,
+ kUnsetSize},
+ {"net_dev_xmit",
+ "net",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "len", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "name", 2, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "rc", 3, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "skbaddr", 4, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 361,
+ kUnsetSize},
+ {"napi_gro_receive_entry",
+ "net",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "data_len", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "gso_size", 2, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "gso_type", 3, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "hash", 4, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "ip_summed", 5, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "l4_hash", 6, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "len", 7, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "mac_header", 8, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "mac_header_valid", 9, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "name", 10, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "napi_id", 11, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "nr_frags", 12, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "protocol", 13, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "queue_mapping", 14, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "skbaddr", 15, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "truesize", 16, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "vlan_proto", 17, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "vlan_tagged", 18, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "vlan_tci", 19, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 365,
+ kUnsetSize},
+ {"napi_gro_receive_exit",
+ "net",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "ret", 1, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 366,
+ kUnsetSize},
{"oom_score_adj_update",
"oom",
{
@@ -5849,6 +6812,42 @@ std::vector<Event> GetStaticEventInfo() {
kUnsetFtraceId,
332,
kUnsetSize},
+ {"wakeup_source_activate",
+ "power",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "name", 1, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "state", 2, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 404,
+ kUnsetSize},
+ {"wakeup_source_deactivate",
+ "power",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "name", 1, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "state", 2, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 405,
+ kUnsetSize},
+ {"console",
+ "printk",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "msg", 1, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 408,
+ kUnsetSize},
{"sys_enter",
"raw_syscalls",
{
@@ -6409,6 +7408,56 @@ std::vector<Event> GetStaticEventInfo() {
kUnsetFtraceId,
325,
kUnsetSize},
+ {"kfree_skb",
+ "skb",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "location", 1, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "protocol", 2, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "skbaddr", 3, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 367,
+ kUnsetSize},
+ {"inet_sock_set_state",
+ "sock",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "daddr", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "dport", 2, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "family", 3, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "newstate", 4, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "oldstate", 5, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "protocol", 6, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "saddr", 7, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "skaddr", 8, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "sport", 9, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 362,
+ kUnsetSize},
{"sync_pt",
"sync",
{
@@ -6451,6 +7500,25 @@ std::vector<Event> GetStaticEventInfo() {
kUnsetFtraceId,
40,
kUnsetSize},
+ {"rss_stat_throttled",
+ "synthetic",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "curr", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "member", 2, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "mm_id", 3, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "size", 4, ProtoSchemaType::kInt64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 359,
+ kUnsetSize},
{"0",
"systrace",
{
@@ -6508,6 +7576,34 @@ std::vector<Event> GetStaticEventInfo() {
kUnsetFtraceId,
236,
kUnsetSize},
+ {"tcp_retransmit_skb",
+ "tcp",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "daddr", 1, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "dport", 2, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "saddr", 3, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "skaddr", 4, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "skbaddr", 5, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "sport", 6, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "state", 7, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 363,
+ kUnsetSize},
{"thermal_temperature",
"thermal",
{
@@ -6540,6 +7636,56 @@ std::vector<Event> GetStaticEventInfo() {
kUnsetFtraceId,
342,
kUnsetSize},
+ {"ufshcd_command",
+ "ufs",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "dev_name", 1, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "doorbell", 2, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "intr", 3, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "lba", 4, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "opcode", 5, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "str", 6, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "tag", 7, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "transfer_len", 8, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "group_id", 9, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "str_t", 10, ProtoSchemaType::kUint32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 406,
+ kUnsetSize},
+ {"ufshcd_clk_gating",
+ "ufs",
+ {
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "dev_name", 1, ProtoSchemaType::kString,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "state", 2, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
+ },
+ kUnsetFtraceId,
+ 407,
+ kUnsetSize},
{"mm_vmscan_direct_reclaim_begin",
"vmscan",
{
@@ -6575,6 +7721,9 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"order", 2, ProtoSchemaType::kInt32,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "zid", 3, ProtoSchemaType::kInt32,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
48,
@@ -6605,6 +7754,9 @@ std::vector<Event> GetStaticEventInfo() {
{kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
"work", 1, ProtoSchemaType::kUint64,
TranslationStrategy::kInvalidTranslationStrategy},
+ {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+ "function", 2, ProtoSchemaType::kUint64,
+ TranslationStrategy::kInvalidTranslationStrategy},
},
kUnsetFtraceId,
57,
diff --git a/src/traced/probes/ftrace/ftrace_config_muxer.cc b/src/traced/probes/ftrace/ftrace_config_muxer.cc
index 24b84b519..69c4176f3 100644
--- a/src/traced/probes/ftrace/ftrace_config_muxer.cc
+++ b/src/traced/probes/ftrace/ftrace_config_muxer.cc
@@ -24,10 +24,13 @@
#include <algorithm>
#include <iterator>
+#include "perfetto/base/compiler.h"
#include "perfetto/ext/base/utils.h"
-#include "protos/perfetto/trace/ftrace/sched.pbzero.h"
#include "src/traced/probes/ftrace/atrace_wrapper.h"
#include "src/traced/probes/ftrace/compact_sched.h"
+#include "src/traced/probes/ftrace/ftrace_stats.h"
+
+#include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
namespace perfetto {
namespace {
@@ -36,6 +39,8 @@ constexpr int kDefaultPerCpuBufferSizeKb = 2 * 1024; // 2mb
constexpr int kMaxPerCpuBufferSizeKb = 64 * 1024; // 64mb
// trace_clocks in preference order.
+// If this list is changed, the FtraceClocks enum in ftrace_event_bundle.proto
+// and FtraceConfigMuxer::SetupClock() should be also changed accordingly.
constexpr const char* kClocks[] = {"boot", "global", "local"};
void AddEventGroup(const ProtoTranslationTable* table,
@@ -90,6 +95,14 @@ void IntersectInPlace(const std::vector<std::string>& unsorted_a,
*out = std::move(v);
}
+// This is just to reduce binary size and stack frame size of the insertions.
+// It effectively undoes STL's set::insert inlining.
+void PERFETTO_NO_INLINE InsertEvent(const char* group,
+ const char* name,
+ std::set<GroupAndName>* dst) {
+ dst->insert(GroupAndName(group, name));
+}
+
} // namespace
std::set<GroupAndName> FtraceConfigMuxer::GetFtraceEvents(
@@ -120,7 +133,7 @@ std::set<GroupAndName> FtraceConfigMuxer::GetFtraceEvents(
}
}
if (RequiresAtrace(request)) {
- events.insert(GroupAndName("ftrace", "print"));
+ InsertEvent("ftrace", "print", &events);
// Ideally we should keep this code in sync with:
// platform/frameworks/native/cmds/atrace/atrace.cpp
@@ -130,53 +143,53 @@ std::set<GroupAndName> FtraceConfigMuxer::GetFtraceEvents(
for (const std::string& category : request.atrace_categories()) {
if (category == "gfx") {
AddEventGroup(table, "mdss", &events);
- events.insert(GroupAndName("mdss", "rotator_bw_ao_as_context"));
- events.insert(GroupAndName("mdss", "mdp_trace_counter"));
- events.insert(GroupAndName("mdss", "tracing_mark_write"));
- events.insert(GroupAndName("mdss", "mdp_cmd_wait_pingpong"));
- events.insert(GroupAndName("mdss", "mdp_cmd_kickoff"));
- events.insert(GroupAndName("mdss", "mdp_cmd_release_bw"));
- events.insert(GroupAndName("mdss", "mdp_cmd_readptr_done"));
- events.insert(GroupAndName("mdss", "mdp_cmd_pingpong_done"));
- events.insert(GroupAndName("mdss", "mdp_misr_crc"));
- events.insert(GroupAndName("mdss", "mdp_compare_bw"));
- events.insert(GroupAndName("mdss", "mdp_perf_update_bus"));
- events.insert(GroupAndName("mdss", "mdp_video_underrun_done"));
- events.insert(GroupAndName("mdss", "mdp_commit"));
- events.insert(GroupAndName("mdss", "mdp_mixer_update"));
- events.insert(GroupAndName("mdss", "mdp_perf_prefill_calc"));
- events.insert(GroupAndName("mdss", "mdp_perf_set_ot"));
- events.insert(GroupAndName("mdss", "mdp_perf_set_wm_levels"));
- events.insert(GroupAndName("mdss", "mdp_perf_set_panic_luts"));
- events.insert(GroupAndName("mdss", "mdp_perf_set_qos_luts"));
- events.insert(GroupAndName("mdss", "mdp_sspp_change"));
- events.insert(GroupAndName("mdss", "mdp_sspp_set"));
+ InsertEvent("mdss", "rotator_bw_ao_as_context", &events);
+ InsertEvent("mdss", "mdp_trace_counter", &events);
+ InsertEvent("mdss", "tracing_mark_write", &events);
+ InsertEvent("mdss", "mdp_cmd_wait_pingpong", &events);
+ InsertEvent("mdss", "mdp_cmd_kickoff", &events);
+ InsertEvent("mdss", "mdp_cmd_release_bw", &events);
+ InsertEvent("mdss", "mdp_cmd_readptr_done", &events);
+ InsertEvent("mdss", "mdp_cmd_pingpong_done", &events);
+ InsertEvent("mdss", "mdp_misr_crc", &events);
+ InsertEvent("mdss", "mdp_compare_bw", &events);
+ InsertEvent("mdss", "mdp_perf_update_bus", &events);
+ InsertEvent("mdss", "mdp_video_underrun_done", &events);
+ InsertEvent("mdss", "mdp_commit", &events);
+ InsertEvent("mdss", "mdp_mixer_update", &events);
+ InsertEvent("mdss", "mdp_perf_prefill_calc", &events);
+ InsertEvent("mdss", "mdp_perf_set_ot", &events);
+ InsertEvent("mdss", "mdp_perf_set_wm_levels", &events);
+ InsertEvent("mdss", "mdp_perf_set_panic_luts", &events);
+ InsertEvent("mdss", "mdp_perf_set_qos_luts", &events);
+ InsertEvent("mdss", "mdp_sspp_change", &events);
+ InsertEvent("mdss", "mdp_sspp_set", &events);
AddEventGroup(table, "mali", &events);
- events.insert(GroupAndName("mali", "tracing_mark_write"));
+ InsertEvent("mali", "tracing_mark_write", &events);
AddEventGroup(table, "sde", &events);
- events.insert(GroupAndName("sde", "tracing_mark_write"));
- events.insert(GroupAndName("sde", "sde_perf_update_bus"));
- events.insert(GroupAndName("sde", "sde_perf_set_qos_luts"));
- events.insert(GroupAndName("sde", "sde_perf_set_ot"));
- events.insert(GroupAndName("sde", "sde_perf_set_danger_luts"));
- events.insert(GroupAndName("sde", "sde_perf_crtc_update"));
- events.insert(GroupAndName("sde", "sde_perf_calc_crtc"));
- events.insert(GroupAndName("sde", "sde_evtlog"));
- events.insert(GroupAndName("sde", "sde_encoder_underrun"));
- events.insert(GroupAndName("sde", "sde_cmd_release_bw"));
+ InsertEvent("sde", "tracing_mark_write", &events);
+ InsertEvent("sde", "sde_perf_update_bus", &events);
+ InsertEvent("sde", "sde_perf_set_qos_luts", &events);
+ InsertEvent("sde", "sde_perf_set_ot", &events);
+ InsertEvent("sde", "sde_perf_set_danger_luts", &events);
+ InsertEvent("sde", "sde_perf_crtc_update", &events);
+ InsertEvent("sde", "sde_perf_calc_crtc", &events);
+ InsertEvent("sde", "sde_evtlog", &events);
+ InsertEvent("sde", "sde_encoder_underrun", &events);
+ InsertEvent("sde", "sde_cmd_release_bw", &events);
AddEventGroup(table, "dpu", &events);
- events.insert(GroupAndName("dpu", "tracing_mark_write"));
+ InsertEvent("dpu", "tracing_mark_write", &events);
AddEventGroup(table, "g2d", &events);
- events.insert(GroupAndName("g2d", "tracing_mark_write"));
- events.insert(GroupAndName("g2d", "g2d_perf_update_qos"));
+ InsertEvent("g2d", "tracing_mark_write", &events);
+ InsertEvent("g2d", "g2d_perf_update_qos", &events);
continue;
}
if (category == "ion") {
- events.insert(GroupAndName("kmem", "ion_alloc_buffer_start"));
+ InsertEvent("kmem", "ion_alloc_buffer_start", &events);
continue;
}
@@ -184,102 +197,102 @@ std::set<GroupAndName> FtraceConfigMuxer::GetFtraceEvents(
// is high-volume, but mostly redundant when sched_waking is also enabled.
// The event can still be enabled explicitly when necessary.
if (category == "sched") {
- events.insert(GroupAndName("sched", "sched_switch"));
- events.insert(GroupAndName("sched", "sched_waking"));
- events.insert(GroupAndName("sched", "sched_blocked_reason"));
- events.insert(GroupAndName("sched", "sched_cpu_hotplug"));
- events.insert(GroupAndName("sched", "sched_pi_setprio"));
- events.insert(GroupAndName("sched", "sched_process_exit"));
+ InsertEvent("sched", "sched_switch", &events);
+ InsertEvent("sched", "sched_waking", &events);
+ InsertEvent("sched", "sched_blocked_reason", &events);
+ InsertEvent("sched", "sched_cpu_hotplug", &events);
+ InsertEvent("sched", "sched_pi_setprio", &events);
+ InsertEvent("sched", "sched_process_exit", &events);
AddEventGroup(table, "cgroup", &events);
- events.insert(GroupAndName("cgroup", "cgroup_transfer_tasks"));
- events.insert(GroupAndName("cgroup", "cgroup_setup_root"));
- events.insert(GroupAndName("cgroup", "cgroup_rmdir"));
- events.insert(GroupAndName("cgroup", "cgroup_rename"));
- events.insert(GroupAndName("cgroup", "cgroup_remount"));
- events.insert(GroupAndName("cgroup", "cgroup_release"));
- events.insert(GroupAndName("cgroup", "cgroup_mkdir"));
- events.insert(GroupAndName("cgroup", "cgroup_destroy_root"));
- events.insert(GroupAndName("cgroup", "cgroup_attach_task"));
- events.insert(GroupAndName("oom", "oom_score_adj_update"));
- events.insert(GroupAndName("task", "task_rename"));
- events.insert(GroupAndName("task", "task_newtask"));
+ InsertEvent("cgroup", "cgroup_transfer_tasks", &events);
+ InsertEvent("cgroup", "cgroup_setup_root", &events);
+ InsertEvent("cgroup", "cgroup_rmdir", &events);
+ InsertEvent("cgroup", "cgroup_rename", &events);
+ InsertEvent("cgroup", "cgroup_remount", &events);
+ InsertEvent("cgroup", "cgroup_release", &events);
+ InsertEvent("cgroup", "cgroup_mkdir", &events);
+ InsertEvent("cgroup", "cgroup_destroy_root", &events);
+ InsertEvent("cgroup", "cgroup_attach_task", &events);
+ InsertEvent("oom", "oom_score_adj_update", &events);
+ InsertEvent("task", "task_rename", &events);
+ InsertEvent("task", "task_newtask", &events);
AddEventGroup(table, "systrace", &events);
- events.insert(GroupAndName("systrace", "0"));
+ InsertEvent("systrace", "0", &events);
AddEventGroup(table, "scm", &events);
- events.insert(GroupAndName("scm", "scm_call_start"));
- events.insert(GroupAndName("scm", "scm_call_end"));
+ InsertEvent("scm", "scm_call_start", &events);
+ InsertEvent("scm", "scm_call_end", &events);
continue;
}
if (category == "irq") {
AddEventGroup(table, "irq", &events);
- events.insert(GroupAndName("irq", "tasklet_hi_exit"));
- events.insert(GroupAndName("irq", "tasklet_hi_entry"));
- events.insert(GroupAndName("irq", "tasklet_exit"));
- events.insert(GroupAndName("irq", "tasklet_entry"));
- events.insert(GroupAndName("irq", "softirq_raise"));
- events.insert(GroupAndName("irq", "softirq_exit"));
- events.insert(GroupAndName("irq", "softirq_entry"));
- events.insert(GroupAndName("irq", "irq_handler_exit"));
- events.insert(GroupAndName("irq", "irq_handler_entry"));
+ InsertEvent("irq", "tasklet_hi_exit", &events);
+ InsertEvent("irq", "tasklet_hi_entry", &events);
+ InsertEvent("irq", "tasklet_exit", &events);
+ InsertEvent("irq", "tasklet_entry", &events);
+ InsertEvent("irq", "softirq_raise", &events);
+ InsertEvent("irq", "softirq_exit", &events);
+ InsertEvent("irq", "softirq_entry", &events);
+ InsertEvent("irq", "irq_handler_exit", &events);
+ InsertEvent("irq", "irq_handler_entry", &events);
AddEventGroup(table, "ipi", &events);
- events.insert(GroupAndName("ipi", "ipi_raise"));
- events.insert(GroupAndName("ipi", "ipi_exit"));
- events.insert(GroupAndName("ipi", "ipi_entry"));
+ InsertEvent("ipi", "ipi_raise", &events);
+ InsertEvent("ipi", "ipi_exit", &events);
+ InsertEvent("ipi", "ipi_entry", &events);
continue;
}
if (category == "irqoff") {
- events.insert(GroupAndName("preemptirq", "irq_enable"));
- events.insert(GroupAndName("preemptirq", "irq_disable"));
+ InsertEvent("preemptirq", "irq_enable", &events);
+ InsertEvent("preemptirq", "irq_disable", &events);
continue;
}
if (category == "preemptoff") {
- events.insert(GroupAndName("preemptirq", "preempt_enable"));
- events.insert(GroupAndName("preemptirq", "preempt_disable"));
+ InsertEvent("preemptirq", "preempt_enable", &events);
+ InsertEvent("preemptirq", "preempt_disable", &events);
continue;
}
if (category == "i2c") {
AddEventGroup(table, "i2c", &events);
- events.insert(GroupAndName("i2c", "i2c_read"));
- events.insert(GroupAndName("i2c", "i2c_write"));
- events.insert(GroupAndName("i2c", "i2c_result"));
- events.insert(GroupAndName("i2c", "i2c_reply"));
- events.insert(GroupAndName("i2c", "smbus_read"));
- events.insert(GroupAndName("i2c", "smbus_write"));
- events.insert(GroupAndName("i2c", "smbus_result"));
- events.insert(GroupAndName("i2c", "smbus_reply"));
+ InsertEvent("i2c", "i2c_read", &events);
+ InsertEvent("i2c", "i2c_write", &events);
+ InsertEvent("i2c", "i2c_result", &events);
+ InsertEvent("i2c", "i2c_reply", &events);
+ InsertEvent("i2c", "smbus_read", &events);
+ InsertEvent("i2c", "smbus_write", &events);
+ InsertEvent("i2c", "smbus_result", &events);
+ InsertEvent("i2c", "smbus_reply", &events);
continue;
}
if (category == "freq") {
- events.insert(GroupAndName("power", "cpu_frequency"));
- events.insert(GroupAndName("power", "gpu_frequency"));
- events.insert(GroupAndName("power", "clock_set_rate"));
- events.insert(GroupAndName("power", "clock_disable"));
- events.insert(GroupAndName("power", "clock_enable"));
- events.insert(GroupAndName("clk", "clk_set_rate"));
- events.insert(GroupAndName("clk", "clk_disable"));
- events.insert(GroupAndName("clk", "clk_enable"));
- events.insert(GroupAndName("power", "cpu_frequency_limits"));
- events.insert(GroupAndName("power", "suspend_resume"));
- events.insert(GroupAndName("cpuhp", "cpuhp_enter"));
- events.insert(GroupAndName("cpuhp", "cpuhp_exit"));
- events.insert(GroupAndName("cpuhp", "cpuhp_pause"));
+ InsertEvent("power", "cpu_frequency", &events);
+ InsertEvent("power", "gpu_frequency", &events);
+ InsertEvent("power", "clock_set_rate", &events);
+ InsertEvent("power", "clock_disable", &events);
+ InsertEvent("power", "clock_enable", &events);
+ InsertEvent("clk", "clk_set_rate", &events);
+ InsertEvent("clk", "clk_disable", &events);
+ InsertEvent("clk", "clk_enable", &events);
+ InsertEvent("power", "cpu_frequency_limits", &events);
+ InsertEvent("power", "suspend_resume", &events);
+ InsertEvent("cpuhp", "cpuhp_enter", &events);
+ InsertEvent("cpuhp", "cpuhp_exit", &events);
+ InsertEvent("cpuhp", "cpuhp_pause", &events);
AddEventGroup(table, "msm_bus", &events);
- events.insert(GroupAndName("msm_bus", "bus_update_request_end"));
- events.insert(GroupAndName("msm_bus", "bus_update_request"));
- events.insert(GroupAndName("msm_bus", "bus_rules_matches"));
- events.insert(GroupAndName("msm_bus", "bus_max_votes"));
- events.insert(GroupAndName("msm_bus", "bus_client_status"));
- events.insert(GroupAndName("msm_bus", "bus_bke_params"));
- events.insert(GroupAndName("msm_bus", "bus_bimc_config_limiter"));
- events.insert(GroupAndName("msm_bus", "bus_avail_bw"));
- events.insert(GroupAndName("msm_bus", "bus_agg_bw"));
+ InsertEvent("msm_bus", "bus_update_request_end", &events);
+ InsertEvent("msm_bus", "bus_update_request", &events);
+ InsertEvent("msm_bus", "bus_rules_matches", &events);
+ InsertEvent("msm_bus", "bus_max_votes", &events);
+ InsertEvent("msm_bus", "bus_client_status", &events);
+ InsertEvent("msm_bus", "bus_bke_params", &events);
+ InsertEvent("msm_bus", "bus_bimc_config_limiter", &events);
+ InsertEvent("msm_bus", "bus_avail_bw", &events);
+ InsertEvent("msm_bus", "bus_agg_bw", &events);
continue;
}
@@ -289,21 +302,21 @@ std::set<GroupAndName> FtraceConfigMuxer::GetFtraceEvents(
}
if (category == "idle") {
- events.insert(GroupAndName("power", "cpu_idle"));
+ InsertEvent("power", "cpu_idle", &events);
continue;
}
if (category == "disk") {
- events.insert(GroupAndName("f2fs", "f2fs_sync_file_enter"));
- events.insert(GroupAndName("f2fs", "f2fs_sync_file_exit"));
- events.insert(GroupAndName("f2fs", "f2fs_write_begin"));
- events.insert(GroupAndName("f2fs", "f2fs_write_end"));
- events.insert(GroupAndName("ext4", "ext4_da_write_begin"));
- events.insert(GroupAndName("ext4", "ext4_da_write_end"));
- events.insert(GroupAndName("ext4", "ext4_sync_file_enter"));
- events.insert(GroupAndName("ext4", "ext4_sync_file_exit"));
- events.insert(GroupAndName("block", "block_rq_issue"));
- events.insert(GroupAndName("block", "block_rq_complete"));
+ InsertEvent("f2fs", "f2fs_sync_file_enter", &events);
+ InsertEvent("f2fs", "f2fs_sync_file_exit", &events);
+ InsertEvent("f2fs", "f2fs_write_begin", &events);
+ InsertEvent("f2fs", "f2fs_write_end", &events);
+ InsertEvent("ext4", "ext4_da_write_begin", &events);
+ InsertEvent("ext4", "ext4_da_write_end", &events);
+ InsertEvent("ext4", "ext4_sync_file_enter", &events);
+ InsertEvent("ext4", "ext4_sync_file_exit", &events);
+ InsertEvent("block", "block_rq_issue", &events);
+ InsertEvent("block", "block_rq_complete", &events);
continue;
}
@@ -320,19 +333,19 @@ std::set<GroupAndName> FtraceConfigMuxer::GetFtraceEvents(
if (category == "sync") {
// linux kernel < 4.9
AddEventGroup(table, "sync", &events);
- events.insert(GroupAndName("sync", "sync_pt"));
- events.insert(GroupAndName("sync", "sync_timeline"));
- events.insert(GroupAndName("sync", "sync_wait"));
+ InsertEvent("sync", "sync_pt", &events);
+ InsertEvent("sync", "sync_timeline", &events);
+ InsertEvent("sync", "sync_wait", &events);
// linux kernel == 4.9.x
AddEventGroup(table, "fence", &events);
- events.insert(GroupAndName("fence", "fence_annotate_wait_on"));
- events.insert(GroupAndName("fence", "fence_destroy"));
- events.insert(GroupAndName("fence", "fence_emit"));
- events.insert(GroupAndName("fence", "fence_enable_signal"));
- events.insert(GroupAndName("fence", "fence_init"));
- events.insert(GroupAndName("fence", "fence_signaled"));
- events.insert(GroupAndName("fence", "fence_wait_end"));
- events.insert(GroupAndName("fence", "fence_wait_start"));
+ InsertEvent("fence", "fence_annotate_wait_on", &events);
+ InsertEvent("fence", "fence_destroy", &events);
+ InsertEvent("fence", "fence_emit", &events);
+ InsertEvent("fence", "fence_enable_signal", &events);
+ InsertEvent("fence", "fence_init", &events);
+ InsertEvent("fence", "fence_signaled", &events);
+ InsertEvent("fence", "fence_wait_end", &events);
+ InsertEvent("fence", "fence_wait_start", &events);
// linux kernel > 4.9
AddEventGroup(table, "dma_fence", &events);
continue;
@@ -340,20 +353,20 @@ std::set<GroupAndName> FtraceConfigMuxer::GetFtraceEvents(
if (category == "workq") {
AddEventGroup(table, "workqueue", &events);
- events.insert(GroupAndName("workqueue", "workqueue_queue_work"));
- events.insert(GroupAndName("workqueue", "workqueue_execute_start"));
- events.insert(GroupAndName("workqueue", "workqueue_execute_end"));
- events.insert(GroupAndName("workqueue", "workqueue_activate_work"));
+ InsertEvent("workqueue", "workqueue_queue_work", &events);
+ InsertEvent("workqueue", "workqueue_execute_start", &events);
+ InsertEvent("workqueue", "workqueue_execute_end", &events);
+ InsertEvent("workqueue", "workqueue_activate_work", &events);
continue;
}
if (category == "memreclaim") {
- events.insert(GroupAndName("vmscan", "mm_vmscan_direct_reclaim_begin"));
- events.insert(GroupAndName("vmscan", "mm_vmscan_direct_reclaim_end"));
- events.insert(GroupAndName("vmscan", "mm_vmscan_kswapd_wake"));
- events.insert(GroupAndName("vmscan", "mm_vmscan_kswapd_sleep"));
+ InsertEvent("vmscan", "mm_vmscan_direct_reclaim_begin", &events);
+ InsertEvent("vmscan", "mm_vmscan_direct_reclaim_end", &events);
+ InsertEvent("vmscan", "mm_vmscan_kswapd_wake", &events);
+ InsertEvent("vmscan", "mm_vmscan_kswapd_sleep", &events);
AddEventGroup(table, "lowmemorykiller", &events);
- events.insert(GroupAndName("lowmemorykiller", "lowmemory_kill"));
+ InsertEvent("lowmemorykiller", "lowmemory_kill", &events);
continue;
}
@@ -361,27 +374,27 @@ std::set<GroupAndName> FtraceConfigMuxer::GetFtraceEvents(
AddEventGroup(table, "regulator", &events);
events.insert(
GroupAndName("regulator", "regulator_set_voltage_complete"));
- events.insert(GroupAndName("regulator", "regulator_set_voltage"));
- events.insert(GroupAndName("regulator", "regulator_enable_delay"));
- events.insert(GroupAndName("regulator", "regulator_enable_complete"));
- events.insert(GroupAndName("regulator", "regulator_enable"));
- events.insert(GroupAndName("regulator", "regulator_disable_complete"));
- events.insert(GroupAndName("regulator", "regulator_disable"));
+ InsertEvent("regulator", "regulator_set_voltage", &events);
+ InsertEvent("regulator", "regulator_enable_delay", &events);
+ InsertEvent("regulator", "regulator_enable_complete", &events);
+ InsertEvent("regulator", "regulator_enable", &events);
+ InsertEvent("regulator", "regulator_disable_complete", &events);
+ InsertEvent("regulator", "regulator_disable", &events);
continue;
}
if (category == "binder_driver") {
- events.insert(GroupAndName("binder", "binder_transaction"));
- events.insert(GroupAndName("binder", "binder_transaction_received"));
- events.insert(GroupAndName("binder", "binder_transaction_alloc_buf"));
- events.insert(GroupAndName("binder", "binder_set_priority"));
+ InsertEvent("binder", "binder_transaction", &events);
+ InsertEvent("binder", "binder_transaction_received", &events);
+ InsertEvent("binder", "binder_transaction_alloc_buf", &events);
+ InsertEvent("binder", "binder_set_priority", &events);
continue;
}
if (category == "binder_lock") {
- events.insert(GroupAndName("binder", "binder_lock"));
- events.insert(GroupAndName("binder", "binder_locked"));
- events.insert(GroupAndName("binder", "binder_unlock"));
+ InsertEvent("binder", "binder_lock", &events);
+ InsertEvent("binder", "binder_locked", &events);
+ InsertEvent("binder", "binder_unlock", &events);
continue;
}
@@ -389,30 +402,50 @@ std::set<GroupAndName> FtraceConfigMuxer::GetFtraceEvents(
AddEventGroup(table, "filemap", &events);
events.insert(
GroupAndName("filemap", "mm_filemap_delete_from_page_cache"));
- events.insert(GroupAndName("filemap", "mm_filemap_add_to_page_cache"));
- events.insert(GroupAndName("filemap", "filemap_set_wb_err"));
- events.insert(GroupAndName("filemap", "file_check_and_advance_wb_err"));
+ InsertEvent("filemap", "mm_filemap_add_to_page_cache", &events);
+ InsertEvent("filemap", "filemap_set_wb_err", &events);
+ InsertEvent("filemap", "file_check_and_advance_wb_err", &events);
continue;
}
if (category == "memory") {
- events.insert(GroupAndName("kmem", "rss_stat"));
- events.insert(GroupAndName("kmem", "ion_heap_grow"));
- events.insert(GroupAndName("kmem", "ion_heap_shrink"));
+ // Use rss_stat_throttled if supported
+ if (ftrace_->SupportsRssStatThrottled()) {
+ InsertEvent("synthetic", "rss_stat_throttled", &events);
+ } else {
+ InsertEvent("kmem", "rss_stat", &events);
+ }
+ InsertEvent("kmem", "ion_heap_grow", &events);
+ InsertEvent("kmem", "ion_heap_shrink", &events);
// ion_stat supersedes ion_heap_grow / shrink for kernel 4.19+
- events.insert(GroupAndName("ion", "ion_stat"));
- events.insert(GroupAndName("mm_event", "mm_event_record"));
- events.insert(GroupAndName("dmabuf_heap", "dma_heap_stat"));
+ InsertEvent("ion", "ion_stat", &events);
+ InsertEvent("mm_event", "mm_event_record", &events);
+ InsertEvent("dmabuf_heap", "dma_heap_stat", &events);
+ InsertEvent("gpu_mem", "gpu_mem_total", &events);
continue;
}
if (category == "thermal") {
- events.insert(GroupAndName("thermal", "thermal_temperature"));
- events.insert(GroupAndName("thermal", "cdev_update"));
+ InsertEvent("thermal", "thermal_temperature", &events);
+ InsertEvent("thermal", "cdev_update", &events);
continue;
}
}
}
+
+ // If throttle_rss_stat: true, use the rss_stat_throttled event if supported
+ if (request.throttle_rss_stat() && ftrace_->SupportsRssStatThrottled()) {
+ auto it = std::find_if(
+ events.begin(), events.end(), [](const GroupAndName& event) {
+ return event.group() == "kmem" && event.name() == "rss_stat";
+ });
+
+ if (it != events.end()) {
+ events.erase(it);
+ InsertEvent("synthetic", "rss_stat_throttled", &events);
+ }
+ }
+
return events;
}
@@ -448,14 +481,15 @@ FtraceConfigMuxer::FtraceConfigMuxer(
vendor_events_(vendor_events) {}
FtraceConfigMuxer::~FtraceConfigMuxer() = default;
-FtraceConfigId FtraceConfigMuxer::SetupConfig(const FtraceConfig& request) {
+FtraceConfigId FtraceConfigMuxer::SetupConfig(const FtraceConfig& request,
+ FtraceSetupErrors* errors) {
EventFilter filter;
bool is_ftrace_enabled = ftrace_->IsTracingEnabled();
if (ds_configs_.empty()) {
PERFETTO_DCHECK(active_configs_.empty());
// If someone outside of perfetto is using ftrace give up now.
- if (is_ftrace_enabled) {
+ if (is_ftrace_enabled && !IsOldAtrace()) {
PERFETTO_ELOG("ftrace in use by non-Perfetto.");
return 0;
}
@@ -466,7 +500,7 @@ FtraceConfigId FtraceConfigMuxer::SetupConfig(const FtraceConfig& request) {
SetupBufferSize(request);
} else {
// Did someone turn ftrace off behind our back? If so give up.
- if (!active_configs_.empty() && !is_ftrace_enabled) {
+ if (!active_configs_.empty() && !is_ftrace_enabled && !IsOldAtrace()) {
PERFETTO_ELOG("ftrace disabled by non-Perfetto.");
return 0;
}
@@ -486,20 +520,39 @@ FtraceConfigId FtraceConfigMuxer::SetupConfig(const FtraceConfig& request) {
}
}
- if (RequiresAtrace(request))
- UpdateAtrace(request);
+ if (RequiresAtrace(request)) {
+ if (IsOldAtrace() && !ds_configs_.empty()) {
+ PERFETTO_ELOG(
+ "Concurrent atrace sessions are not supported before Android P, "
+ "bailing out.");
+ return 0;
+ }
+ UpdateAtrace(request, errors ? &errors->atrace_errors : nullptr);
+ }
for (const auto& group_and_name : events) {
const Event* event = table_->GetOrCreateEvent(group_and_name);
if (!event) {
PERFETTO_DLOG("Can't enable %s, event not known",
group_and_name.ToString().c_str());
+ if (errors)
+ errors->unknown_ftrace_events.push_back(group_and_name.ToString());
+ continue;
+ }
+ // Niche option to skip events that are in the config, but don't have a
+ // dedicated proto for the event in perfetto. Otherwise such events will be
+ // encoded as GenericFtraceEvent.
+ if (request.disable_generic_events() &&
+ event->proto_field_id ==
+ protos::pbzero::FtraceEvent::kGenericFieldNumber) {
+ if (errors)
+ errors->failed_ftrace_events.push_back(group_and_name.ToString());
continue;
}
// Note: ftrace events are always implicitly enabled (and don't have an
// "enable" file). So they aren't tracked by the central event filter (but
- // still need to be added to the per data source event filter to retain the
- // events during parsing).
+ // still need to be added to the per data source event filter to retain
+ // the events during parsing).
if (current_state_.ftrace_events.IsEventEnabled(event->ftrace_event_id) ||
std::string("ftrace") == event->group) {
filter.AddEnabledEvent(event->ftrace_event_id);
@@ -510,6 +563,8 @@ FtraceConfigId FtraceConfigMuxer::SetupConfig(const FtraceConfig& request) {
filter.AddEnabledEvent(event->ftrace_event_id);
} else {
PERFETTO_DPLOG("Failed to enable %s.", group_and_name.ToString().c_str());
+ if (errors)
+ errors->failed_ftrace_events.push_back(group_and_name.ToString());
}
}
@@ -533,7 +588,7 @@ bool FtraceConfigMuxer::ActivateConfig(FtraceConfigId id) {
}
if (active_configs_.empty()) {
- if (ftrace_->IsTracingEnabled()) {
+ if (ftrace_->IsTracingEnabled() && !IsOldAtrace()) {
// If someone outside of perfetto is using ftrace give up now.
PERFETTO_ELOG("ftrace in use by non-Perfetto.");
return false;
@@ -618,7 +673,8 @@ bool FtraceConfigMuxer::RemoveConfig(FtraceConfigId config_id) {
// some categories this won't disable them (e.g. categories that just
// enable ftrace events) for those there is nothing we can do till the
// last ftrace config is removed.
- if (StartAtrace(expected_apps, expected_categories)) {
+ if (StartAtrace(expected_apps, expected_categories,
+ /*atrace_errors=*/nullptr)) {
// Update current_state_ to reflect this change.
current_state_.atrace_apps = expected_apps;
current_state_.atrace_categories = expected_categories;
@@ -647,8 +703,23 @@ void FtraceConfigMuxer::SetupClock(const FtraceConfig&) {
if (current_clock == clock)
break;
ftrace_->SetClock(clock);
+ current_clock = clock;
break;
}
+
+ namespace pb0 = protos::pbzero;
+ if (current_clock == "boot") {
+ // "boot" is the default expectation on modern kernels, which is why we
+ // don't have an explicit FTRACE_CLOCK_BOOT enum and leave it unset.
+ // See comments in ftrace_event_bundle.proto.
+ current_state_.ftrace_clock = pb0::FTRACE_CLOCK_UNSPECIFIED;
+ } else if (current_clock == "global") {
+ current_state_.ftrace_clock = pb0::FTRACE_CLOCK_GLOBAL;
+ } else if (current_clock == "local") {
+ current_state_.ftrace_clock = pb0::FTRACE_CLOCK_LOCAL;
+ } else {
+ current_state_.ftrace_clock = pb0::FTRACE_CLOCK_UNKNOWN;
+ }
}
void FtraceConfigMuxer::SetupBufferSize(const FtraceConfig& request) {
@@ -661,7 +732,8 @@ size_t FtraceConfigMuxer::GetPerCpuBufferSizePages() {
return current_state_.cpu_buffer_size_pages;
}
-void FtraceConfigMuxer::UpdateAtrace(const FtraceConfig& request) {
+void FtraceConfigMuxer::UpdateAtrace(const FtraceConfig& request,
+ std::string* atrace_errors) {
// We want to avoid poisoning current_state_.atrace_{categories, apps}
// if for some reason these args make atrace unhappy so we stash the
// union into temps and only update current_state_ if we successfully
@@ -679,7 +751,7 @@ void FtraceConfigMuxer::UpdateAtrace(const FtraceConfig& request) {
return;
}
- if (StartAtrace(combined_apps, combined_categories)) {
+ if (StartAtrace(combined_apps, combined_categories, atrace_errors)) {
current_state_.atrace_categories = combined_categories;
current_state_.atrace_apps = combined_apps;
current_state_.atrace_on = true;
@@ -687,15 +759,16 @@ void FtraceConfigMuxer::UpdateAtrace(const FtraceConfig& request) {
}
// static
-bool FtraceConfigMuxer::StartAtrace(
- const std::vector<std::string>& apps,
- const std::vector<std::string>& categories) {
+bool FtraceConfigMuxer::StartAtrace(const std::vector<std::string>& apps,
+ const std::vector<std::string>& categories,
+ std::string* atrace_errors) {
PERFETTO_DLOG("Update atrace config...");
std::vector<std::string> args;
args.push_back("atrace"); // argv0 for exec()
args.push_back("--async_start");
- args.push_back("--only_userspace");
+ if (!IsOldAtrace())
+ args.push_back("--only_userspace");
for (const auto& category : categories)
args.push_back(category);
@@ -711,7 +784,7 @@ bool FtraceConfigMuxer::StartAtrace(
args.push_back(arg);
}
- bool result = RunAtrace(args);
+ bool result = RunAtrace(args, atrace_errors);
PERFETTO_DLOG("...done (%s)", result ? "success" : "fail");
return result;
}
@@ -721,7 +794,10 @@ void FtraceConfigMuxer::DisableAtrace() {
PERFETTO_DLOG("Stop atrace...");
- if (RunAtrace({"atrace", "--async_stop", "--only_userspace"})) {
+ std::vector<std::string> args{"atrace", "--async_stop"};
+ if (!IsOldAtrace())
+ args.push_back("--only_userspace");
+ if (RunAtrace(args, /*atrace_errors=*/nullptr)) {
current_state_.atrace_categories.clear();
current_state_.atrace_apps.clear();
current_state_.atrace_on = false;
diff --git a/src/traced/probes/ftrace/ftrace_config_muxer.h b/src/traced/probes/ftrace/ftrace_config_muxer.h
index 39653712a..7b21357ea 100644
--- a/src/traced/probes/ftrace/ftrace_config_muxer.h
+++ b/src/traced/probes/ftrace/ftrace_config_muxer.h
@@ -28,6 +28,14 @@
namespace perfetto {
+namespace protos {
+namespace pbzero {
+enum FtraceClock : int32_t;
+} // namespace pbzero
+} // namespace protos
+
+struct FtraceSetupErrors;
+
// State held by the muxer per data source, used to parse ftrace according to
// that data source's config.
struct FtraceDataSourceConfig {
@@ -53,7 +61,7 @@ struct FtraceDataSourceConfig {
std::vector<std::string> atrace_apps;
std::vector<std::string> atrace_categories;
- // When enabled will turn on the the kallsyms symbolizer in CpuReader.
+ // When enabled will turn on the kallsyms symbolizer in CpuReader.
const bool symbolize_ksyms;
};
@@ -87,7 +95,8 @@ class FtraceConfigMuxer {
// (if you enable an atrace category we try to give you the matching events).
// If someone else is tracing we won't touch atrace (since it resets the
// buffer).
- FtraceConfigId SetupConfig(const FtraceConfig& request);
+ FtraceConfigId SetupConfig(const FtraceConfig& request,
+ FtraceSetupErrors* = nullptr);
// Activate ftrace for the given config (if not already active).
bool ActivateConfig(FtraceConfigId);
@@ -109,6 +118,10 @@ class FtraceConfigMuxer {
SetupClock(request);
}
+ protos::pbzero::FtraceClock ftrace_clock() const {
+ return current_state_.ftrace_clock;
+ }
+
std::set<GroupAndName> GetFtraceEventsForTesting(
const FtraceConfig& request,
const ProtoTranslationTable* table) {
@@ -121,7 +134,8 @@ class FtraceConfigMuxer {
private:
static bool StartAtrace(const std::vector<std::string>& apps,
- const std::vector<std::string>& categories);
+ const std::vector<std::string>& categories,
+ std::string* atrace_errors);
struct FtraceState {
EventFilter ftrace_events;
@@ -130,6 +144,7 @@ class FtraceConfigMuxer {
std::vector<std::string> atrace_categories;
size_t cpu_buffer_size_pages = 0;
bool atrace_on = false;
+ protos::pbzero::FtraceClock ftrace_clock{};
};
FtraceConfigMuxer(const FtraceConfigMuxer&) = delete;
@@ -137,7 +152,7 @@ class FtraceConfigMuxer {
void SetupClock(const FtraceConfig& request);
void SetupBufferSize(const FtraceConfig& request);
- void UpdateAtrace(const FtraceConfig& request);
+ void UpdateAtrace(const FtraceConfig& request, std::string* atrace_errors);
void DisableAtrace();
// This processes the config to get the exact events.
diff --git a/src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc b/src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc
index c3602aaff..40127638d 100644
--- a/src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc
+++ b/src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc
@@ -18,26 +18,34 @@
#include <memory>
+#include "ftrace_config_muxer.h"
#include "src/traced/probes/ftrace/atrace_wrapper.h"
#include "src/traced/probes/ftrace/compact_sched.h"
#include "src/traced/probes/ftrace/ftrace_procfs.h"
+#include "src/traced/probes/ftrace/ftrace_stats.h"
#include "src/traced/probes/ftrace/proto_translation_table.h"
#include "test/gtest_and_gmock.h"
using testing::_;
using testing::AnyNumber;
-using testing::MatchesRegex;
using testing::Contains;
using testing::ElementsAreArray;
using testing::Eq;
+using testing::Invoke;
using testing::IsEmpty;
+using testing::MatchesRegex;
using testing::NiceMock;
using testing::Not;
using testing::Return;
+using testing::UnorderedElementsAre;
namespace perfetto {
namespace {
+constexpr int kFakeSchedSwitchEventId = 1;
+constexpr int kCgroupMkdirEventId = 12;
+constexpr int kFakePrintEventId = 20;
+
class MockFtraceProcfs : public FtraceProcfs {
public:
MockFtraceProcfs() : FtraceProcfs("/root/") {
@@ -57,20 +65,24 @@ class MockFtraceProcfs : public FtraceProcfs {
MOCK_CONST_METHOD0(NumberOfCpus, size_t());
MOCK_CONST_METHOD1(GetEventNamesForGroup,
const std::set<std::string>(const std::string& path));
+ MOCK_CONST_METHOD2(ReadEventFormat,
+ std::string(const std::string& group,
+ const std::string& name));
};
struct MockRunAtrace {
MockRunAtrace() {
static MockRunAtrace* instance;
instance = this;
- SetRunAtraceForTesting([](const std::vector<std::string>& args) {
- return instance->RunAtrace(args);
- });
+ SetRunAtraceForTesting(
+ [](const std::vector<std::string>& args, std::string* atrace_errors) {
+ return instance->RunAtrace(args, atrace_errors);
+ });
}
~MockRunAtrace() { SetRunAtraceForTesting(nullptr); }
- MOCK_METHOD1(RunAtrace, bool(const std::vector<std::string>&));
+ MOCK_METHOD2(RunAtrace, bool(const std::vector<std::string>&, std::string*));
};
class MockProtoTranslationTable : public ProtoTranslationTable {
@@ -93,6 +105,14 @@ class MockProtoTranslationTable : public ProtoTranslationTable {
class FtraceConfigMuxerTest : public ::testing::Test {
protected:
+ void SetUp() override {
+ // Don't probe for older SDK levels, that would relax the atrace-related
+ // checks on older versions of Android (But some tests here test those).
+ // We want the unittests to behave consistently (as if we were on a post P
+ // device) regardless of the Android versions they run on.
+ SetIsOldAtraceForTesting(false);
+ }
+ void TearDown() override { ClearIsOldAtraceForTesting(); }
std::unique_ptr<MockProtoTranslationTable> GetMockTable() {
std::vector<Field> common_fields;
std::vector<Event> events;
@@ -103,17 +123,13 @@ class FtraceConfigMuxerTest : public ::testing::Test {
InvalidCompactSchedEventFormatForTesting()));
}
- static constexpr int kFakeSchedSwitchEventId = 1;
- static constexpr int kCgroupMkdirEventId = 12;
- static constexpr int kFakePrintEventId = 20;
-
std::unique_ptr<ProtoTranslationTable> CreateFakeTable(
CompactSchedEventFormat compact_format =
InvalidCompactSchedEventFormatForTesting()) {
std::vector<Field> common_fields;
std::vector<Event> events;
{
- Event event;
+ Event event = {};
event.name = "sched_switch";
event.group = "sched";
event.ftrace_event_id = kFakeSchedSwitchEventId;
@@ -121,7 +137,7 @@ class FtraceConfigMuxerTest : public ::testing::Test {
}
{
- Event event;
+ Event event = {};
event.name = "sched_wakeup";
event.group = "sched";
event.ftrace_event_id = 10;
@@ -129,7 +145,7 @@ class FtraceConfigMuxerTest : public ::testing::Test {
}
{
- Event event;
+ Event event = {};
event.name = "sched_new";
event.group = "sched";
event.ftrace_event_id = 11;
@@ -137,7 +153,7 @@ class FtraceConfigMuxerTest : public ::testing::Test {
}
{
- Event event;
+ Event event = {};
event.name = "cgroup_mkdir";
event.group = "cgroup";
event.ftrace_event_id = kCgroupMkdirEventId;
@@ -145,7 +161,7 @@ class FtraceConfigMuxerTest : public ::testing::Test {
}
{
- Event event;
+ Event event = {};
event.name = "mm_vmscan_direct_reclaim_begin";
event.group = "vmscan";
event.ftrace_event_id = 13;
@@ -153,7 +169,7 @@ class FtraceConfigMuxerTest : public ::testing::Test {
}
{
- Event event;
+ Event event = {};
event.name = "lowmemory_kill";
event.group = "lowmemorykiller";
event.ftrace_event_id = 14;
@@ -161,7 +177,7 @@ class FtraceConfigMuxerTest : public ::testing::Test {
}
{
- Event event;
+ Event event = {};
event.name = "print";
event.group = "ftrace";
event.ftrace_event_id = kFakePrintEventId;
@@ -418,14 +434,12 @@ TEST_F(FtraceConfigMuxerTest, TurnFtraceOnOff) {
const FtraceDataSourceConfig* ds_config = model.GetDataSourceConfig(id);
ASSERT_TRUE(ds_config);
- ASSERT_THAT(
- ds_config->event_filter.GetEnabledEvents(),
- ElementsAreArray({FtraceConfigMuxerTest::kFakeSchedSwitchEventId}));
+ ASSERT_THAT(ds_config->event_filter.GetEnabledEvents(),
+ ElementsAreArray({kFakeSchedSwitchEventId}));
const EventFilter* central_filter = model.GetCentralEventFilterForTesting();
- ASSERT_THAT(
- central_filter->GetEnabledEvents(),
- ElementsAreArray({FtraceConfigMuxerTest::kFakeSchedSwitchEventId}));
+ ASSERT_THAT(central_filter->GetEnabledEvents(),
+ ElementsAreArray({kFakeSchedSwitchEventId}));
ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(&ftrace));
EXPECT_CALL(ftrace, NumberOfCpus()).Times(AnyNumber());
@@ -466,9 +480,9 @@ TEST_F(FtraceConfigMuxerTest, Atrace) {
EXPECT_CALL(ftrace, ReadOneCharFromFile("/root/tracing_on"))
.WillOnce(Return('0'));
- EXPECT_CALL(atrace,
- RunAtrace(ElementsAreArray(
- {"atrace", "--async_start", "--only_userspace", "sched"})))
+ EXPECT_CALL(atrace, RunAtrace(ElementsAreArray({"atrace", "--async_start",
+ "--only_userspace", "sched"}),
+ _))
.WillOnce(Return(true));
FtraceConfigId id = model.SetupConfig(config);
@@ -480,16 +494,18 @@ TEST_F(FtraceConfigMuxerTest, Atrace) {
const FtraceDataSourceConfig* ds_config = model.GetDataSourceConfig(id);
ASSERT_TRUE(ds_config);
EXPECT_THAT(ds_config->event_filter.GetEnabledEvents(),
- Contains(FtraceConfigMuxerTest::kFakeSchedSwitchEventId));
+ Contains(kFakeSchedSwitchEventId));
EXPECT_THAT(ds_config->event_filter.GetEnabledEvents(),
- Contains(FtraceConfigMuxerTest::kFakePrintEventId));
+ Contains(kFakePrintEventId));
const EventFilter* central_filter = model.GetCentralEventFilterForTesting();
EXPECT_THAT(central_filter->GetEnabledEvents(),
- Contains(FtraceConfigMuxerTest::kFakeSchedSwitchEventId));
+ Contains(kFakeSchedSwitchEventId));
- EXPECT_CALL(atrace, RunAtrace(ElementsAreArray(
- {"atrace", "--async_stop", "--only_userspace"})))
+ EXPECT_CALL(
+ atrace,
+ RunAtrace(
+ ElementsAreArray({"atrace", "--async_stop", "--only_userspace"}), _))
.WillOnce(Return(true));
ASSERT_TRUE(model.RemoveConfig(id));
}
@@ -508,9 +524,11 @@ TEST_F(FtraceConfigMuxerTest, AtraceTwoApps) {
.WillOnce(Return('0'));
EXPECT_CALL(
atrace,
- RunAtrace(ElementsAreArray(
- {"atrace", "--async_start", "--only_userspace", "-a",
- "com.google.android.gms,com.google.android.gms.persistent"})))
+ RunAtrace(
+ ElementsAreArray(
+ {"atrace", "--async_start", "--only_userspace", "-a",
+ "com.google.android.gms,com.google.android.gms.persistent"}),
+ _))
.WillOnce(Return(true));
FtraceConfigId id = model.SetupConfig(config);
@@ -519,10 +537,12 @@ TEST_F(FtraceConfigMuxerTest, AtraceTwoApps) {
const FtraceDataSourceConfig* ds_config = model.GetDataSourceConfig(id);
ASSERT_TRUE(ds_config);
ASSERT_THAT(ds_config->event_filter.GetEnabledEvents(),
- Contains(FtraceConfigMuxerTest::kFakePrintEventId));
+ Contains(kFakePrintEventId));
- EXPECT_CALL(atrace, RunAtrace(ElementsAreArray(
- {"atrace", "--async_stop", "--only_userspace"})))
+ EXPECT_CALL(
+ atrace,
+ RunAtrace(
+ ElementsAreArray({"atrace", "--async_stop", "--only_userspace"}), _))
.WillOnce(Return(true));
ASSERT_TRUE(model.RemoveConfig(id));
}
@@ -547,7 +567,8 @@ TEST_F(FtraceConfigMuxerTest, AtraceMultipleConfigs) {
EXPECT_CALL(atrace, RunAtrace(ElementsAreArray({"atrace", "--async_start",
"--only_userspace", "cat_a",
- "-a", "app_a"})))
+ "-a", "app_a"}),
+ _))
.WillOnce(Return(true));
FtraceConfigId id_a = model.SetupConfig(config_a);
ASSERT_TRUE(id_a);
@@ -555,7 +576,8 @@ TEST_F(FtraceConfigMuxerTest, AtraceMultipleConfigs) {
EXPECT_CALL(
atrace,
RunAtrace(ElementsAreArray({"atrace", "--async_start", "--only_userspace",
- "cat_a", "cat_b", "-a", "app_a,app_b"})))
+ "cat_a", "cat_b", "-a", "app_a,app_b"}),
+ _))
.WillOnce(Return(true));
FtraceConfigId id_b = model.SetupConfig(config_b);
ASSERT_TRUE(id_b);
@@ -563,7 +585,8 @@ TEST_F(FtraceConfigMuxerTest, AtraceMultipleConfigs) {
EXPECT_CALL(atrace,
RunAtrace(ElementsAreArray({"atrace", "--async_start",
"--only_userspace", "cat_a", "cat_b",
- "cat_c", "-a", "app_a,app_b,app_c"})))
+ "cat_c", "-a", "app_a,app_b,app_c"}),
+ _))
.WillOnce(Return(true));
FtraceConfigId id_c = model.SetupConfig(config_c);
ASSERT_TRUE(id_c);
@@ -571,18 +594,22 @@ TEST_F(FtraceConfigMuxerTest, AtraceMultipleConfigs) {
EXPECT_CALL(
atrace,
RunAtrace(ElementsAreArray({"atrace", "--async_start", "--only_userspace",
- "cat_a", "cat_c", "-a", "app_a,app_c"})))
+ "cat_a", "cat_c", "-a", "app_a,app_c"}),
+ _))
.WillOnce(Return(true));
ASSERT_TRUE(model.RemoveConfig(id_b));
EXPECT_CALL(atrace, RunAtrace(ElementsAreArray({"atrace", "--async_start",
"--only_userspace", "cat_c",
- "-a", "app_c"})))
+ "-a", "app_c"}),
+ _))
.WillOnce(Return(true));
ASSERT_TRUE(model.RemoveConfig(id_a));
- EXPECT_CALL(atrace, RunAtrace(ElementsAreArray(
- {"atrace", "--async_stop", "--only_userspace"})))
+ EXPECT_CALL(
+ atrace,
+ RunAtrace(
+ ElementsAreArray({"atrace", "--async_stop", "--only_userspace"}), _))
.WillOnce(Return(true));
ASSERT_TRUE(model.RemoveConfig(id_c));
}
@@ -612,15 +639,17 @@ TEST_F(FtraceConfigMuxerTest, AtraceFailedConfig) {
EXPECT_CALL(
atrace,
RunAtrace(ElementsAreArray({"atrace", "--async_start", "--only_userspace",
- "cat_1", "cat_2", "-a", "app_1,app_2"})))
+ "cat_1", "cat_2", "-a", "app_1,app_2"}),
+ _))
.WillOnce(Return(true));
FtraceConfigId id_a = model.SetupConfig(config_a);
ASSERT_TRUE(id_a);
- EXPECT_CALL(atrace,
- RunAtrace(ElementsAreArray(
- {"atrace", "--async_start", "--only_userspace", "cat_1",
- "cat_2", "cat_fail", "-a", "app_1,app_2,app_fail"})))
+ EXPECT_CALL(atrace, RunAtrace(ElementsAreArray({"atrace", "--async_start",
+ "--only_userspace", "cat_1",
+ "cat_2", "cat_fail", "-a",
+ "app_1,app_2,app_fail"}),
+ _))
.WillOnce(Return(false));
FtraceConfigId id_b = model.SetupConfig(config_b);
ASSERT_TRUE(id_b);
@@ -628,7 +657,8 @@ TEST_F(FtraceConfigMuxerTest, AtraceFailedConfig) {
EXPECT_CALL(atrace,
RunAtrace(ElementsAreArray({"atrace", "--async_start",
"--only_userspace", "cat_1", "cat_2",
- "cat_3", "-a", "app_1,app_2,app_3"})))
+ "cat_3", "-a", "app_1,app_2,app_3"}),
+ _))
.WillOnce(Return(true));
FtraceConfigId id_c = model.SetupConfig(config_c);
ASSERT_TRUE(id_c);
@@ -636,7 +666,8 @@ TEST_F(FtraceConfigMuxerTest, AtraceFailedConfig) {
EXPECT_CALL(
atrace,
RunAtrace(ElementsAreArray({"atrace", "--async_start", "--only_userspace",
- "cat_1", "cat_2", "-a", "app_1,app_2"})))
+ "cat_1", "cat_2", "-a", "app_1,app_2"}),
+ _))
.WillOnce(Return(true));
ASSERT_TRUE(model.RemoveConfig(id_c));
@@ -644,8 +675,10 @@ TEST_F(FtraceConfigMuxerTest, AtraceFailedConfig) {
// so we don't expect a call here.
ASSERT_TRUE(model.RemoveConfig(id_b));
- EXPECT_CALL(atrace, RunAtrace(ElementsAreArray(
- {"atrace", "--async_stop", "--only_userspace"})))
+ EXPECT_CALL(
+ atrace,
+ RunAtrace(
+ ElementsAreArray({"atrace", "--async_stop", "--only_userspace"}), _))
.WillOnce(Return(true));
ASSERT_TRUE(model.RemoveConfig(id_a));
}
@@ -666,7 +699,8 @@ TEST_F(FtraceConfigMuxerTest, AtraceDuplicateConfigs) {
EXPECT_CALL(atrace, RunAtrace(ElementsAreArray({"atrace", "--async_start",
"--only_userspace", "cat_1",
- "-a", "app_1"})))
+ "-a", "app_1"}),
+ _))
.WillOnce(Return(true));
FtraceConfigId id_a = model.SetupConfig(config_a);
ASSERT_TRUE(id_a);
@@ -676,8 +710,10 @@ TEST_F(FtraceConfigMuxerTest, AtraceDuplicateConfigs) {
ASSERT_TRUE(model.RemoveConfig(id_a));
- EXPECT_CALL(atrace, RunAtrace(ElementsAreArray(
- {"atrace", "--async_stop", "--only_userspace"})))
+ EXPECT_CALL(
+ atrace,
+ RunAtrace(
+ ElementsAreArray({"atrace", "--async_stop", "--only_userspace"}), _))
.WillOnce(Return(true));
ASSERT_TRUE(model.RemoveConfig(id_b));
}
@@ -702,7 +738,8 @@ TEST_F(FtraceConfigMuxerTest, AtraceAndFtraceConfigs) {
ASSERT_TRUE(id_a);
EXPECT_CALL(atrace, RunAtrace(ElementsAreArray({"atrace", "--async_start",
- "--only_userspace", "b"})))
+ "--only_userspace", "b"}),
+ _))
.WillOnce(Return(true));
FtraceConfigId id_b = model.SetupConfig(config_b);
ASSERT_TRUE(id_b);
@@ -711,32 +748,67 @@ TEST_F(FtraceConfigMuxerTest, AtraceAndFtraceConfigs) {
ASSERT_TRUE(id_c);
EXPECT_CALL(atrace,
- RunAtrace(ElementsAreArray(
- {"atrace", "--async_start", "--only_userspace", "b", "d"})))
+ RunAtrace(ElementsAreArray({"atrace", "--async_start",
+ "--only_userspace", "b", "d"}),
+ _))
.WillOnce(Return(true));
FtraceConfigId id_d = model.SetupConfig(config_d);
ASSERT_TRUE(id_d);
EXPECT_CALL(atrace, RunAtrace(ElementsAreArray({"atrace", "--async_start",
- "--only_userspace", "b"})))
+ "--only_userspace", "b"}),
+ _))
.WillOnce(Return(true));
ASSERT_TRUE(model.RemoveConfig(id_d));
ASSERT_TRUE(model.RemoveConfig(id_c));
- EXPECT_CALL(atrace, RunAtrace(ElementsAreArray(
- {"atrace", "--async_stop", "--only_userspace"})))
+ EXPECT_CALL(
+ atrace,
+ RunAtrace(
+ ElementsAreArray({"atrace", "--async_stop", "--only_userspace"}), _))
.WillOnce(Return(true));
ASSERT_TRUE(model.RemoveConfig(id_b));
ASSERT_TRUE(model.RemoveConfig(id_a));
}
+TEST_F(FtraceConfigMuxerTest, AtraceErrorsPropagated) {
+ NiceMock<MockFtraceProcfs> ftrace;
+ MockRunAtrace atrace;
+
+ FtraceConfig config = CreateFtraceConfig({});
+ *config.add_atrace_categories() = "cat_1";
+ *config.add_atrace_categories() = "cat_2";
+
+ EXPECT_CALL(ftrace, ReadOneCharFromFile("/root/tracing_on"))
+ .WillRepeatedly(Return('0'));
+
+ FtraceConfigMuxer model(&ftrace, table_.get(), {});
+
+ EXPECT_CALL(atrace, RunAtrace(ElementsAreArray({"atrace", "--async_start",
+ "--only_userspace", "cat_1",
+ "cat_2"}),
+ _))
+ .WillOnce(Invoke([](const std::vector<std::string>&, std::string* err) {
+ EXPECT_NE(err, nullptr);
+ if (err)
+ err->append("foo\nbar\n");
+ return true;
+ }));
+
+ FtraceSetupErrors errors{};
+ FtraceConfigId id_a = model.SetupConfig(config, &errors);
+ ASSERT_TRUE(id_a);
+ EXPECT_EQ(errors.atrace_errors, "foo\nbar\n");
+}
+
TEST_F(FtraceConfigMuxerTest, SetupClockForTesting) {
MockFtraceProcfs ftrace;
FtraceConfig config;
FtraceConfigMuxer model(&ftrace, table_.get(), {});
+ namespace pb0 = protos::pbzero;
EXPECT_CALL(ftrace, ReadFileIntoString("/root/trace_clock"))
.Times(AnyNumber());
@@ -745,19 +817,25 @@ TEST_F(FtraceConfigMuxerTest, SetupClockForTesting) {
.WillByDefault(Return("[local] global boot"));
EXPECT_CALL(ftrace, WriteToFile("/root/trace_clock", "boot"));
model.SetupClockForTesting(config);
+ // unspecified = boot.
+ EXPECT_EQ(model.ftrace_clock(),
+ static_cast<int>(pb0::FTRACE_CLOCK_UNSPECIFIED));
ON_CALL(ftrace, ReadFileIntoString("/root/trace_clock"))
.WillByDefault(Return("[local] global"));
EXPECT_CALL(ftrace, WriteToFile("/root/trace_clock", "global"));
model.SetupClockForTesting(config);
+ EXPECT_EQ(model.ftrace_clock(), static_cast<int>(pb0::FTRACE_CLOCK_GLOBAL));
ON_CALL(ftrace, ReadFileIntoString("/root/trace_clock"))
.WillByDefault(Return(""));
model.SetupClockForTesting(config);
+ EXPECT_EQ(model.ftrace_clock(), static_cast<int>(pb0::FTRACE_CLOCK_UNKNOWN));
ON_CALL(ftrace, ReadFileIntoString("/root/trace_clock"))
.WillByDefault(Return("local [global]"));
model.SetupClockForTesting(config);
+ EXPECT_EQ(model.ftrace_clock(), static_cast<int>(pb0::FTRACE_CLOCK_GLOBAL));
}
TEST_F(FtraceConfigMuxerTest, GetFtraceEvents) {
@@ -839,15 +917,15 @@ TEST_F(FtraceConfigMuxerTest, FallbackOnSetEvent) {
const FtraceDataSourceConfig* ds_config = model.GetDataSourceConfig(id);
ASSERT_TRUE(ds_config);
EXPECT_THAT(ds_config->event_filter.GetEnabledEvents(),
- Contains(FtraceConfigMuxerTest::kFakeSchedSwitchEventId));
+ Contains(kFakeSchedSwitchEventId));
EXPECT_THAT(ds_config->event_filter.GetEnabledEvents(),
- Contains(FtraceConfigMuxerTest::kCgroupMkdirEventId));
+ Contains(kCgroupMkdirEventId));
const EventFilter* central_filter = model.GetCentralEventFilterForTesting();
EXPECT_THAT(central_filter->GetEnabledEvents(),
- Contains(FtraceConfigMuxerTest::kFakeSchedSwitchEventId));
+ Contains(kFakeSchedSwitchEventId));
EXPECT_THAT(central_filter->GetEnabledEvents(),
- Contains(FtraceConfigMuxerTest::kCgroupMkdirEventId));
+ Contains(kCgroupMkdirEventId));
EXPECT_CALL(ftrace, WriteToFile("/root/tracing_on", "0"));
EXPECT_CALL(ftrace, WriteToFile("/root/buffer_size_kb", "4"));
@@ -888,7 +966,7 @@ TEST_F(FtraceConfigMuxerTest, CompactSchedConfig) {
const FtraceDataSourceConfig* ds_config = model.GetDataSourceConfig(id);
ASSERT_TRUE(ds_config);
EXPECT_THAT(ds_config->event_filter.GetEnabledEvents(),
- Contains(FtraceConfigMuxerTest::kFakeSchedSwitchEventId));
+ Contains(kFakeSchedSwitchEventId));
EXPECT_TRUE(ds_config->compact_sched.enabled);
}
{
@@ -897,7 +975,7 @@ TEST_F(FtraceConfigMuxerTest, CompactSchedConfig) {
const FtraceDataSourceConfig* ds_config = model.GetDataSourceConfig(id);
ASSERT_TRUE(ds_config);
EXPECT_THAT(ds_config->event_filter.GetEnabledEvents(),
- Contains(FtraceConfigMuxerTest::kFakeSchedSwitchEventId));
+ Contains(kFakeSchedSwitchEventId));
EXPECT_FALSE(ds_config->compact_sched.enabled);
}
}
@@ -919,9 +997,55 @@ TEST_F(FtraceConfigMuxerTest, CompactSchedConfigWithInvalidFormat) {
const FtraceDataSourceConfig* ds_config = model.GetDataSourceConfig(id);
ASSERT_TRUE(ds_config);
EXPECT_THAT(ds_config->event_filter.GetEnabledEvents(),
- Contains(FtraceConfigMuxerTest::kFakeSchedSwitchEventId));
+ Contains(kFakeSchedSwitchEventId));
EXPECT_FALSE(ds_config->compact_sched.enabled);
}
+TEST_F(FtraceConfigMuxerTest, SkipGenericEventsOption) {
+ NiceMock<MockFtraceProcfs> ftrace;
+ FtraceConfigMuxer model(&ftrace, table_.get(), {});
+
+ static constexpr int kFtraceGenericEventId = 42;
+ ON_CALL(table_procfs_, ReadEventFormat("sched", "generic"))
+ .WillByDefault(Return(R"(name: generic
+ID: 42
+format:
+ field:int common_pid; offset:0; size:4; signed:1;
+
+ field:u32 field_a; offset:4; size:4; signed:0;
+ field:int field_b; offset:8; size:4; signed:1;
+
+print fmt: "unused")"));
+
+ // Data source asking for one known and one generic event.
+ FtraceConfig config_default =
+ CreateFtraceConfig({"sched/sched_switch", "sched/generic"});
+
+ // As above, but with an option to suppress generic events.
+ FtraceConfig config_with_disable =
+ CreateFtraceConfig({"sched/sched_switch", "sched/generic"});
+ config_with_disable.set_disable_generic_events(true);
+
+ {
+ FtraceConfigId id = model.SetupConfig(config_default);
+ ASSERT_TRUE(id);
+ const FtraceDataSourceConfig* ds_config = model.GetDataSourceConfig(id);
+ ASSERT_TRUE(ds_config);
+ // Both events enabled for the data source by default.
+ EXPECT_THAT(
+ ds_config->event_filter.GetEnabledEvents(),
+ UnorderedElementsAre(kFakeSchedSwitchEventId, kFtraceGenericEventId));
+ }
+ {
+ FtraceConfigId id = model.SetupConfig(config_with_disable);
+ ASSERT_TRUE(id);
+ const FtraceDataSourceConfig* ds_config = model.GetDataSourceConfig(id);
+ ASSERT_TRUE(ds_config);
+ // Only the statically known event is enabled.
+ EXPECT_THAT(ds_config->event_filter.GetEnabledEvents(),
+ UnorderedElementsAre(kFakeSchedSwitchEventId));
+ }
+}
+
} // namespace
} // namespace perfetto
diff --git a/src/traced/probes/ftrace/ftrace_controller.cc b/src/traced/probes/ftrace/ftrace_controller.cc
index 53ac1e58f..fc25d3b69 100644
--- a/src/traced/probes/ftrace/ftrace_controller.cc
+++ b/src/traced/probes/ftrace/ftrace_controller.cc
@@ -33,6 +33,7 @@
#include "perfetto/base/time.h"
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/metatrace.h"
+#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/tracing/core/trace_writer.h"
#include "src/kallsyms/kernel_symbol_map.h"
#include "src/kallsyms/lazy_kernel_symbolizer.h"
@@ -84,15 +85,31 @@ uint32_t ClampDrainPeriodMs(uint32_t drain_period_ms) {
return drain_period_ms;
}
-void WriteToFile(const char* path, const char* str) {
+bool WriteToFile(const char* path, const char* str) {
auto fd = base::OpenFile(path, O_WRONLY);
if (!fd)
- return;
- base::ignore_result(base::WriteAll(*fd, str, strlen(str)));
+ return false;
+ const size_t str_len = strlen(str);
+ return base::WriteAll(*fd, str, str_len) == static_cast<ssize_t>(str_len);
}
-void ClearFile(const char* path) {
+bool ClearFile(const char* path) {
auto fd = base::OpenFile(path, O_WRONLY | O_TRUNC);
+ return !!fd;
+}
+
+base::Optional<int64_t> ReadFtraceNowTs(const base::ScopedFile& cpu_stats_fd) {
+ PERFETTO_CHECK(cpu_stats_fd);
+
+ char buf[512];
+ ssize_t res = PERFETTO_EINTR(pread(*cpu_stats_fd, buf, sizeof(buf) - 1, 0));
+ if (res <= 0)
+ return base::nullopt;
+ buf[res] = '\0';
+
+ FtraceCpuStats stats{};
+ DumpCpuStats(buf, &stats);
+ return static_cast<int64_t>(stats.now_ts * 1000 * 1000 * 1000);
}
} // namespace
@@ -100,18 +117,21 @@ void ClearFile(const char* path) {
// Method of last resort to reset ftrace state.
// We don't know what state the rest of the system and process is so as far
// as possible avoid allocations.
-void HardResetFtraceState() {
- PERFETTO_LOG("Hard resetting ftrace state.");
-
- WriteToFile("/sys/kernel/debug/tracing/tracing_on", "0");
- WriteToFile("/sys/kernel/debug/tracing/buffer_size_kb", "4");
- WriteToFile("/sys/kernel/debug/tracing/events/enable", "0");
- ClearFile("/sys/kernel/debug/tracing/trace");
-
- WriteToFile("/sys/kernel/tracing/tracing_on", "0");
- WriteToFile("/sys/kernel/tracing/buffer_size_kb", "4");
- WriteToFile("/sys/kernel/tracing/events/enable", "0");
- ClearFile("/sys/kernel/tracing/trace");
+bool HardResetFtraceState() {
+ for (const char* const* item = FtraceProcfs::kTracingPaths; *item; ++item) {
+ std::string prefix(*item);
+ PERFETTO_CHECK(base::EndsWith(prefix, "/"));
+ bool res = true;
+ res &= WriteToFile((prefix + "tracing_on").c_str(), "0");
+ res &= WriteToFile((prefix + "buffer_size_kb").c_str(), "4");
+ // We deliberately don't check for this as on some older versions of Android
+ // events/enable was not writable by the shell user.
+ WriteToFile((prefix + "events/enable").c_str(), "0");
+ res &= ClearFile((prefix + "trace").c_str());
+ if (res)
+ return true;
+ }
+ return false;
}
// static
@@ -152,6 +172,7 @@ FtraceController::FtraceController(std::unique_ptr<FtraceProcfs> ftrace_procfs,
ftrace_procfs_(std::move(ftrace_procfs)),
table_(std::move(table)),
ftrace_config_muxer_(std::move(model)),
+ ftrace_clock_snapshot_(new FtraceClockSnapshot()),
weak_factory_(this) {}
FtraceController::~FtraceController() {
@@ -167,6 +188,7 @@ uint64_t FtraceController::NowMs() const {
}
void FtraceController::StartIfNeeded() {
+ using FtraceClock = protos::pbzero::FtraceClock;
if (started_data_sources_.size() > 1)
return;
PERFETTO_DCHECK(!started_data_sources_.empty());
@@ -178,13 +200,20 @@ void FtraceController::StartIfNeeded() {
base::PagedMemory::Allocate(base::kPageSize * kParsingBufferSizePages);
}
+ // If we're not using the boot clock, snapshot the ftrace clock.
+ FtraceClock clock = ftrace_config_muxer_->ftrace_clock();
+ if (clock != FtraceClock::FTRACE_CLOCK_UNSPECIFIED) {
+ cpu_zero_stats_fd_ = ftrace_procfs_->OpenCpuStats(0 /* cpu */);
+ MaybeSnapshotFtraceClock();
+ }
+
per_cpu_.clear();
per_cpu_.reserve(ftrace_procfs_->NumberOfCpus());
size_t period_page_quota = ftrace_config_muxer_->GetPerCpuBufferSizePages();
for (size_t cpu = 0; cpu < ftrace_procfs_->NumberOfCpus(); cpu++) {
- auto reader = std::unique_ptr<CpuReader>(
- new CpuReader(cpu, table_.get(), symbolizer_.get(),
- ftrace_procfs_->OpenPipeForCpu(cpu)));
+ auto reader = std::unique_ptr<CpuReader>(new CpuReader(
+ cpu, table_.get(), symbolizer_.get(), ftrace_clock_snapshot_.get(),
+ ftrace_procfs_->OpenPipeForCpu(cpu)));
per_cpu_.emplace_back(std::move(reader), period_page_quota);
}
@@ -243,13 +272,16 @@ void FtraceController::ReadTick(int generation) {
// Read all cpu buffers with remaining per-period quota.
bool all_cpus_done = true;
uint8_t* parsing_buf = reinterpret_cast<uint8_t*>(parsing_mem_.Get());
+ const auto ftrace_clock = ftrace_config_muxer_->ftrace_clock();
for (size_t i = 0; i < per_cpu_.size(); i++) {
size_t orig_quota = per_cpu_[i].period_page_quota;
if (orig_quota == 0)
continue;
size_t max_pages = std::min(orig_quota, kMaxPagesPerCpuPerReadTick);
- size_t pages_read = per_cpu_[i].reader->ReadCycle(
+ CpuReader& cpu_reader = *per_cpu_[i].reader;
+ cpu_reader.set_ftrace_clock(ftrace_clock);
+ size_t pages_read = cpu_reader.ReadCycle(
parsing_buf, kParsingBufferSizePages, max_pages, started_data_sources_);
size_t new_quota = (pages_read >= orig_quota) ? 0 : orig_quota - pages_read;
@@ -282,6 +314,10 @@ void FtraceController::ReadTick(int generation) {
for (auto& per_cpu : per_cpu_)
per_cpu.period_page_quota = period_page_quota;
+ // Snapshot the clock so the data in the next period will be clock synced as
+ // well.
+ MaybeSnapshotFtraceClock();
+
auto drain_period_ms = GetDrainPeriodMs();
task_runner_->PostDelayedTask(
[weak_this, generation] {
@@ -346,6 +382,7 @@ void FtraceController::StopIfNeeded() {
per_cpu_.clear();
symbolizer_->Destroy();
+ cpu_zero_stats_fd_.reset();
if (parsing_mem_.IsValid()) {
parsing_mem_.AdviseDontNeed(parsing_mem_.Get(), parsing_mem_.size());
@@ -356,7 +393,8 @@ bool FtraceController::AddDataSource(FtraceDataSource* data_source) {
if (!ValidConfig(data_source->config()))
return false;
- auto config_id = ftrace_config_muxer_->SetupConfig(data_source->config());
+ auto config_id = ftrace_config_muxer_->SetupConfig(
+ data_source->config(), data_source->mutable_setup_errors());
if (!config_id)
return false;
@@ -419,6 +457,23 @@ void FtraceController::DumpFtraceStats(FtraceStats* stats) {
}
}
+void FtraceController::MaybeSnapshotFtraceClock() {
+ if (!cpu_zero_stats_fd_)
+ return;
+
+ auto ftrace_clock = ftrace_config_muxer_->ftrace_clock();
+ PERFETTO_DCHECK(ftrace_clock != protos::pbzero::FTRACE_CLOCK_UNSPECIFIED);
+
+ // Snapshot the boot clock *before* reading CPU stats so that
+ // two clocks are as close togher as possible (i.e. if it was the
+ // other way round, we'd skew by the const of string parsing).
+ ftrace_clock_snapshot_->boot_clock_ts = base::GetBootTimeNs().count();
+
+ // A value of zero will cause this snapshot to be skipped.
+ ftrace_clock_snapshot_->ftrace_clock_ts =
+ ReadFtraceNowTs(cpu_zero_stats_fd_).value_or(0);
+}
+
FtraceController::Observer::~Observer() = default;
} // namespace perfetto
diff --git a/src/traced/probes/ftrace/ftrace_controller.h b/src/traced/probes/ftrace/ftrace_controller.h
index 3e150a32c..680e5b81c 100644
--- a/src/traced/probes/ftrace/ftrace_controller.h
+++ b/src/traced/probes/ftrace/ftrace_controller.h
@@ -45,7 +45,22 @@ class ProtoTranslationTable;
struct FtraceStats;
// Method of last resort to reset ftrace state.
-void HardResetFtraceState();
+bool HardResetFtraceState();
+
+// Stores the a snapshot of the timestamps from ftrace's trace clock
+// and CLOCK_BOOTITME.
+//
+// This is used when the "boot" (i.e. CLOCK_BOOTITME) is not available
+// for timestamping trace events (on Android O- and 3.x Linux kernels).
+// Trace processor can use this data to sync clocks just as it would
+// with ClockSnapshot packets.
+struct FtraceClockSnapshot {
+ // The timestamp according to the ftrace clock.
+ int64_t ftrace_clock_ts = 0;
+
+ // The timestamp according to CLOCK_BOOTTIME.
+ int64_t boot_clock_ts = 0;
+};
// Utility class for controlling ftrace.
class FtraceController {
@@ -111,13 +126,17 @@ class FtraceController {
void StartIfNeeded();
void StopIfNeeded();
+ void MaybeSnapshotFtraceClock();
+
base::TaskRunner* const task_runner_;
Observer* const observer_;
base::PagedMemory parsing_mem_;
+ base::ScopedFile cpu_zero_stats_fd_;
std::unique_ptr<LazyKernelSymbolizer> symbolizer_;
std::unique_ptr<FtraceProcfs> ftrace_procfs_;
std::unique_ptr<ProtoTranslationTable> table_;
std::unique_ptr<FtraceConfigMuxer> ftrace_config_muxer_;
+ std::unique_ptr<FtraceClockSnapshot> ftrace_clock_snapshot_;
int generation_ = 0;
bool atrace_running_ = false;
std::vector<PerCpuState> per_cpu_; // empty if tracing isn't active
diff --git a/src/traced/probes/ftrace/ftrace_data_source.cc b/src/traced/probes/ftrace/ftrace_data_source.cc
index a801e056f..e5ba1448a 100644
--- a/src/traced/probes/ftrace/ftrace_data_source.cc
+++ b/src/traced/probes/ftrace/ftrace_data_source.cc
@@ -16,19 +16,68 @@
#include "src/traced/probes/ftrace/ftrace_data_source.h"
+#include "perfetto/ext/base/string_splitter.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/string_view.h"
+#include "perfetto/ext/base/subprocess.h"
+#include "perfetto/protozero/scattered_heap_buffer.h"
+#include "perfetto/tracing/core/data_source_descriptor.h"
#include "src/traced/probes/ftrace/cpu_reader.h"
#include "src/traced/probes/ftrace/ftrace_controller.h"
+#include "protos/perfetto/common/ftrace_descriptor.pbzero.h"
#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
#include "protos/perfetto/trace/ftrace/ftrace_stats.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
namespace perfetto {
+namespace {
+
+void FillFtraceDataSourceDescriptor(DataSourceDescriptor* dsd) {
+ protozero::HeapBuffered<protos::pbzero::FtraceDescriptor> ftd;
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+ base::Subprocess p({"/system/bin/atrace", "--list_categories"});
+ p.args.stdin_mode = base::Subprocess::InputMode::kDevNull;
+ p.args.stdout_mode = base::Subprocess::OutputMode::kBuffer;
+ p.args.stderr_mode = base::Subprocess::OutputMode::kBuffer;
+ bool res = p.Call(/*timeout_ms=*/20000);
+ if (res) {
+ for (base::StringSplitter ss(std::move(p.output()), '\n'); ss.Next();) {
+ base::StringView line(ss.cur_token(), ss.cur_token_size());
+ size_t pos = line.find(" - ");
+ if (pos == line.npos) {
+ continue;
+ }
+ base::StringView name = line.substr(0, pos);
+ // Trim initial whitespaces
+ auto it = std::find_if(name.begin(), name.end(),
+ [](char c) { return c != ' '; });
+ name = name.substr(static_cast<size_t>(it - name.begin()));
+
+ base::StringView desc = line.substr(pos + 3);
+
+ protos::pbzero::FtraceDescriptor::AtraceCategory* cat =
+ ftd->add_atrace_categories();
+ cat->set_name(name.data(), name.size());
+ cat->set_description(desc.data(), desc.size());
+ }
+ } else {
+ PERFETTO_ELOG("Failed to run atrace --list_categories code(%d): %s",
+ p.returncode(), p.output().c_str());
+ }
+#endif
+
+ dsd->set_ftrace_descriptor_raw(ftd.SerializeAsString());
+}
+
+} // namespace
// static
const ProbesDataSource::Descriptor FtraceDataSource::descriptor = {
/*name*/ "linux.ftrace",
/*flags*/ Descriptor::kFlagsNone,
+ /*fill_descriptor_func*/ &FillFtraceDataSourceDescriptor,
};
FtraceDataSource::FtraceDataSource(
@@ -62,11 +111,13 @@ void FtraceDataSource::Start() {
if (!ftrace->StartDataSource(this))
return;
DumpFtraceStats(&stats_before_);
+ setup_errors_ = FtraceSetupErrors(); // Dump only on START_OF_TRACE.
}
void FtraceDataSource::DumpFtraceStats(FtraceStats* stats) {
if (controller_weak_)
controller_weak_->DumpFtraceStats(stats);
+ stats->setup_errors = std::move(setup_errors_);
}
void FtraceDataSource::Flush(FlushRequestID flush_request_id,
diff --git a/src/traced/probes/ftrace/ftrace_data_source.h b/src/traced/probes/ftrace/ftrace_data_source.h
index 953476353..b1a1c4589 100644
--- a/src/traced/probes/ftrace/ftrace_data_source.h
+++ b/src/traced/probes/ftrace/ftrace_data_source.h
@@ -81,18 +81,23 @@ class FtraceDataSource : public ProbesDataSource {
}
FtraceMetadata* mutable_metadata() { return &metadata_; }
+ FtraceSetupErrors* mutable_setup_errors() { return &setup_errors_; }
TraceWriter* trace_writer() { return writer_.get(); }
private:
+ // Hands out internal pointers to callbacks.
FtraceDataSource(const FtraceDataSource&) = delete;
FtraceDataSource& operator=(const FtraceDataSource&) = delete;
+ FtraceDataSource(FtraceDataSource&&) = delete;
+ FtraceDataSource& operator=(FtraceDataSource&&) = delete;
void WriteStats();
void DumpFtraceStats(FtraceStats*);
const FtraceConfig config_;
FtraceMetadata metadata_;
- FtraceStats stats_before_ = {};
+ FtraceStats stats_before_{};
+ FtraceSetupErrors setup_errors_{};
std::map<FlushRequestID, std::function<void()>> pending_flushes_;
// -- Fields initialized by the Initialize() call:
diff --git a/src/traced/probes/ftrace/ftrace_metadata.h b/src/traced/probes/ftrace/ftrace_metadata.h
index cdfc138bb..21b0530e4 100644
--- a/src/traced/probes/ftrace/ftrace_metadata.h
+++ b/src/traced/probes/ftrace/ftrace_metadata.h
@@ -33,7 +33,9 @@ using BlockDeviceID = decltype(stat::st_dev);
using Inode = decltype(stat::st_ino);
// Container for tracking miscellaneous information while parsing ftrace events,
-// scoped to an individual data source.
+// scoped to an individual data source. Cleared periodically, after the metadata
+// is processed by the data sources interested in it, see
+// |OnFtraceDataWrittenIntoDataSourceBuffers|.
struct FtraceMetadata {
struct KernelAddr {
KernelAddr(uint64_t _addr, uint32_t _index) : addr(_addr), index(_index) {}
diff --git a/src/traced/probes/ftrace/ftrace_procfs.cc b/src/traced/probes/ftrace/ftrace_procfs.cc
index 9176bae93..55b81b4a4 100644
--- a/src/traced/probes/ftrace/ftrace_procfs.cc
+++ b/src/traced/probes/ftrace/ftrace_procfs.cc
@@ -45,6 +45,12 @@ namespace perfetto {
namespace {
+namespace {
+constexpr char kRssStatThrottledTrigger[] =
+ "hist:keys=mm_id,member:bucket=size/0x80000"
+ ":onchange($bucket).rss_stat_throttled(mm_id,curr,member,size)";
+}
+
void KernelLogWrite(const char* s) {
PERFETTO_DCHECK(*s && s[strlen(s) - 1] == '\n');
if (FtraceProcfs::g_kmesg_fd != -1)
@@ -104,6 +110,11 @@ FtraceProcfs::~FtraceProcfs() = default;
bool FtraceProcfs::EnableEvent(const std::string& group,
const std::string& name) {
std::string path = root_ + "events/" + group + "/" + name + "/enable";
+
+ // Create any required triggers for the ftrace event being enabled.
+ // Some ftrace events (synthetic events) need to set up an event trigger
+ MaybeSetUpEventTriggers(group, name);
+
if (WriteToFile(path, "1"))
return true;
path = root_ + "set_event";
@@ -113,10 +124,17 @@ bool FtraceProcfs::EnableEvent(const std::string& group,
bool FtraceProcfs::DisableEvent(const std::string& group,
const std::string& name) {
std::string path = root_ + "events/" + group + "/" + name + "/enable";
- if (WriteToFile(path, "0"))
- return true;
- path = root_ + "set_event";
- return AppendToFile(path, "!" + group + ":" + name);
+
+ bool ret = WriteToFile(path, "0");
+ if (!ret) {
+ path = root_ + "set_event";
+ ret = AppendToFile(path, "!" + group + ":" + name);
+ }
+
+ // Remove any associated event triggers after disabling the event
+ MaybeTearDownEventTriggers(group, name);
+
+ return ret;
}
bool FtraceProcfs::DisableAllEvents() {
@@ -130,6 +148,112 @@ std::string FtraceProcfs::ReadEventFormat(const std::string& group,
return ReadFileIntoString(path);
}
+std::vector<std::string> FtraceProcfs::ReadEventTriggers(
+ const std::string& group,
+ const std::string& name) const {
+ std::string path = root_ + "events/" + group + "/" + name + "/trigger";
+ std::string s = ReadFileIntoString(path);
+ std::vector<std::string> triggers;
+
+ for (base::StringSplitter ss(s, '\n'); ss.Next();) {
+ std::string trigger = ss.cur_token();
+ if (trigger.empty() || trigger[0] == '#')
+ continue;
+
+ base::StringSplitter ts(trigger, ' ');
+ PERFETTO_CHECK(ts.Next());
+ triggers.push_back(ts.cur_token());
+ }
+
+ return triggers;
+}
+
+bool FtraceProcfs::CreateEventTrigger(const std::string& group,
+ const std::string& name,
+ const std::string& trigger) {
+ std::string path = root_ + "events/" + group + "/" + name + "/trigger";
+ return WriteToFile(path, trigger);
+}
+
+bool FtraceProcfs::RemoveEventTrigger(const std::string& group,
+ const std::string& name,
+ const std::string& trigger) {
+ std::string path = root_ + "events/" + group + "/" + name + "/trigger";
+ return WriteToFile(path, "!" + trigger);
+}
+
+bool FtraceProcfs::RemoveAllEventTriggers(const std::string& group,
+ const std::string& name) {
+ std::vector<std::string> triggers = ReadEventTriggers(group, name);
+
+ // Remove the triggers in reverse order since a trigger can depend
+ // on another trigger created earlier.
+ for (auto it = triggers.rbegin(); it != triggers.rend(); ++it)
+ if (!RemoveEventTrigger(group, name, *it))
+ return false;
+ return true;
+}
+
+bool FtraceProcfs::MaybeSetUpEventTriggers(const std::string& group,
+ const std::string& name) {
+ bool ret = true;
+
+ if (group == "synthetic" && name == "rss_stat_throttled") {
+ ret = RemoveAllEventTriggers("kmem", "rss_stat") &&
+ CreateEventTrigger("kmem", "rss_stat", kRssStatThrottledTrigger);
+ }
+
+ if (!ret) {
+ PERFETTO_PLOG("Failed to setup event triggers for %s:%s", group.c_str(),
+ name.c_str());
+ }
+
+ return ret;
+}
+
+bool FtraceProcfs::MaybeTearDownEventTriggers(const std::string& group,
+ const std::string& name) {
+ bool ret = true;
+
+ if (group == "synthetic" && name == "rss_stat_throttled")
+ ret = RemoveAllEventTriggers("kmem", "rss_stat");
+
+ if (!ret) {
+ PERFETTO_PLOG("Failed to tear down event triggers for: %s:%s",
+ group.c_str(), name.c_str());
+ }
+
+ return ret;
+}
+
+bool FtraceProcfs::SupportsRssStatThrottled() {
+ std::string group = "synthetic";
+ std::string name = "rss_stat_throttled";
+
+ // Check if the trigger already exists. Don't try recreating
+ // or removing the trigger if it is already in use.
+ auto triggers = ReadEventTriggers("kmem", "rss_stat");
+ for (const auto& trigger : triggers) {
+ // The kernel shows all the default values of a trigger
+ // when read from and trace event 'trigger' file.
+ //
+ // Trying to match the complete trigger string is prone
+ // to fail if, in the future, the kernel changes default
+ // fields or values for event triggers.
+ //
+ // Do a partial match on the generated event name
+ // (rss_stat_throttled) to detect if the trigger
+ // is already created.
+ if (trigger.find(name) != std::string::npos)
+ return true;
+ }
+
+ // Attempt to create rss_stat_throttled hist trigger */
+ bool ret = MaybeSetUpEventTriggers(group, name);
+
+ return ret && MaybeTearDownEventTriggers(group, name);
+}
+
std::string FtraceProcfs::ReadPrintkFormats() const {
std::string path = root_ + "printk_formats";
return ReadFileIntoString(path);
@@ -154,6 +278,11 @@ std::string FtraceProcfs::ReadPageHeaderFormat() const {
return ReadFileIntoString(path);
}
+base::ScopedFile FtraceProcfs::OpenCpuStats(size_t cpu) const {
+ std::string path = root_ + "per_cpu/cpu" + std::to_string(cpu) + "/stats";
+ return base::OpenFile(path, O_RDONLY);
+}
+
std::string FtraceProcfs::ReadCpuStats(size_t cpu) const {
std::string path = root_ + "per_cpu/cpu" + std::to_string(cpu) + "/stats";
return ReadFileIntoString(path);
@@ -283,9 +412,7 @@ std::set<std::string> FtraceProcfs::AvailableClocks() {
bool FtraceProcfs::WriteNumberToFile(const std::string& path, size_t value) {
// 2^65 requires 20 digits to write.
char buf[21];
- int res = snprintf(buf, 21, "%zu", value);
- if (res < 0 || res >= 21)
- return false;
+ snprintf(buf, sizeof(buf), "%zu", value);
return WriteToFile(path, std::string(buf));
}
diff --git a/src/traced/probes/ftrace/ftrace_procfs.h b/src/traced/probes/ftrace/ftrace_procfs.h
index fb5d31cd6..b7ddf990b 100644
--- a/src/traced/probes/ftrace/ftrace_procfs.h
+++ b/src/traced/probes/ftrace/ftrace_procfs.h
@@ -58,9 +58,41 @@ class FtraceProcfs {
virtual std::string ReadPageHeaderFormat() const;
+ // Get all triggers for event with the given |group| and |name|.
+ std::vector<std::string> ReadEventTriggers(const std::string& group,
+ const std::string& name) const;
+
+ // Create an event trigger for the given |group| and |name|.
+ bool CreateEventTrigger(const std::string& group,
+ const std::string& name,
+ const std::string& trigger);
+
+ // Remove an event trigger for the given |group| and |name|.
+ bool RemoveEventTrigger(const std::string& group,
+ const std::string& name,
+ const std::string& trigger);
+
+ // Remove all event trigger for the given |group| and |name|.
+ bool RemoveAllEventTriggers(const std::string& group,
+ const std::string& name);
+
+ // Sets up any associated event trigger before enabling the event
+ bool MaybeSetUpEventTriggers(const std::string& group,
+ const std::string& name);
+
+ // Tears down any associated event trigger after disabling the event
+ bool MaybeTearDownEventTriggers(const std::string& group,
+ const std::string& name);
+
+ // Returns true if rss_stat_throttled synthetic event is supported
+ bool SupportsRssStatThrottled();
+
// Read the printk formats file.
std::string ReadPrintkFormats() const;
+ // Opens the "/per_cpu/cpuXX/stats" file for the given |cpu|.
+ base::ScopedFile OpenCpuStats(size_t cpu) const;
+
// Read the "/per_cpu/cpuXX/stats" file for the given |cpu|.
std::string ReadCpuStats(size_t cpu) const;
diff --git a/src/traced/probes/ftrace/ftrace_stats.cc b/src/traced/probes/ftrace/ftrace_stats.cc
index a424cc94c..bba09ac68 100644
--- a/src/traced/probes/ftrace/ftrace_stats.cc
+++ b/src/traced/probes/ftrace/ftrace_stats.cc
@@ -26,6 +26,12 @@ void FtraceStats::Write(protos::pbzero::FtraceStats* writer) const {
}
writer->set_kernel_symbols_parsed(kernel_symbols_parsed);
writer->set_kernel_symbols_mem_kb(kernel_symbols_mem_kb);
+ if (!setup_errors.atrace_errors.empty())
+ writer->set_atrace_errors(setup_errors.atrace_errors);
+ for (const std::string& err : setup_errors.unknown_ftrace_events)
+ writer->add_unknown_ftrace_events(err);
+ for (const std::string& err : setup_errors.failed_ftrace_events)
+ writer->add_failed_ftrace_events(err);
}
void FtraceCpuStats::Write(protos::pbzero::FtraceCpuStats* writer) const {
diff --git a/src/traced/probes/ftrace/ftrace_stats.h b/src/traced/probes/ftrace/ftrace_stats.h
index 1dbcbe929..c7a16d8c4 100644
--- a/src/traced/probes/ftrace/ftrace_stats.h
+++ b/src/traced/probes/ftrace/ftrace_stats.h
@@ -17,8 +17,8 @@
#ifndef SRC_TRACED_PROBES_FTRACE_FTRACE_STATS_H_
#define SRC_TRACED_PROBES_FTRACE_FTRACE_STATS_H_
-#include <inttypes.h>
-
+#include <cinttypes>
+#include <string>
#include <vector>
namespace perfetto {
@@ -44,8 +44,15 @@ struct FtraceCpuStats {
void Write(protos::pbzero::FtraceCpuStats*) const;
};
+struct FtraceSetupErrors {
+ std::string atrace_errors;
+ std::vector<std::string> unknown_ftrace_events;
+ std::vector<std::string> failed_ftrace_events;
+};
+
struct FtraceStats {
std::vector<FtraceCpuStats> cpu_stats;
+ FtraceSetupErrors setup_errors;
uint32_t kernel_symbols_parsed = 0;
uint32_t kernel_symbols_mem_kb = 0;
diff --git a/src/traced/probes/ftrace/printk_formats_parser.cc b/src/traced/probes/ftrace/printk_formats_parser.cc
index 274e98121..9a36daba6 100644
--- a/src/traced/probes/ftrace/printk_formats_parser.cc
+++ b/src/traced/probes/ftrace/printk_formats_parser.cc
@@ -16,9 +16,10 @@
#include "src/traced/probes/ftrace/printk_formats_parser.h"
-#include <inttypes.h>
#include <stdio.h>
+#include <cinttypes>
+
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/optional.h"
diff --git a/src/traced/probes/ftrace/proto_translation_table.cc b/src/traced/probes/ftrace/proto_translation_table.cc
index 9a697459f..90aed246d 100644
--- a/src/traced/probes/ftrace/proto_translation_table.cc
+++ b/src/traced/probes/ftrace/proto_translation_table.cc
@@ -256,12 +256,20 @@ bool InferFtraceType(const std::string& type_and_name,
size_t size,
bool is_signed,
FtraceFieldType* out) {
- // Fixed length strings: e.g. "char foo[16]" we don't care about the number
- // since we get the size as it's own field. Somewhat awkwardly these fields
- // are both fixed size and null terminated meaning that we can't just drop
- // them directly into the protobuf (since if the string is shorter than 15
- // characters we want only the bit up to the null terminator).
- if (Match(type_and_name.c_str(), R"(char [a-zA-Z_]+\[[0-9]+\])")) {
+ // Fixed length strings: e.g. "char foo[16]".
+ //
+ // We don't care about the number, since we get the size as it's own field and
+ // since it can be a string defined elsewhere in a kernel header file.
+ //
+ // Somewhat awkwardly these fields are both fixed size and null terminated
+ // meaning that we can't just drop them directly into the protobuf (since if
+ // the string is shorter than 15 characters we want only the bit up to the
+ // null terminator).
+ //
+ // In some rare cases (e.g. old kernel bugs) these strings might not be null
+ // terminated (b/205763418).
+ if (Match(type_and_name.c_str(),
+ R"(char [a-zA-Z_][a-zA-Z_0-9]*\[[a-zA-Z_0-9]+\])")) {
*out = kFtraceFixedCString;
return true;
}
diff --git a/src/traced/probes/ftrace/proto_translation_table_unittest.cc b/src/traced/probes/ftrace/proto_translation_table_unittest.cc
index 0210f715b..2748ac941 100644
--- a/src/traced/probes/ftrace/proto_translation_table_unittest.cc
+++ b/src/traced/probes/ftrace/proto_translation_table_unittest.cc
@@ -319,6 +319,14 @@ TEST(TranslationTableTest, InferFtraceType) {
ASSERT_TRUE(InferFtraceType("char foo[16]", 16, false, &type));
EXPECT_EQ(type, kFtraceFixedCString);
+ ASSERT_TRUE(InferFtraceType("char comm[TASK_COMM_LEN]", 16, false, &type));
+ EXPECT_EQ(type, kFtraceFixedCString);
+
+ ASSERT_TRUE(InferFtraceType("char identifier22[16]", 16, false, &type));
+ EXPECT_EQ(type, kFtraceFixedCString);
+
+ EXPECT_FALSE(InferFtraceType("char 2invalid[16]", 16, false, &type));
+
ASSERT_TRUE(InferFtraceType("char[] foo", 8, false, &type));
EXPECT_EQ(type, kFtraceStringPtr);
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/available_events b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/available_events
new file mode 100644
index 000000000..fad8c708d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/available_events
@@ -0,0 +1,1533 @@
+mac80211:wake_queue
+mac80211:stop_queue
+mac80211:drv_wake_tx_queue
+mac80211:drv_update_vif_offload
+mac80211:drv_update_tkip_key
+mac80211:drv_unassign_vif_chanctx
+mac80211:drv_tx_last_beacon
+mac80211:drv_tx_frames_pending
+mac80211:drv_tdls_recv_channel_switch
+mac80211:drv_tdls_channel_switch
+mac80211:drv_tdls_cancel_channel_switch
+mac80211:drv_sync_rx_queues
+mac80211:drv_switch_vif_chanctx
+mac80211:drv_sw_scan_start
+mac80211:drv_sw_scan_complete
+mac80211:drv_suspend
+mac80211:drv_stop_nan
+mac80211:drv_stop_ap
+mac80211:drv_stop
+mac80211:drv_start_pmsr
+mac80211:drv_start_nan
+mac80211:drv_start_ap
+mac80211:drv_start
+mac80211:drv_sta_statistics
+mac80211:drv_sta_state
+mac80211:drv_sta_set_txpwr
+mac80211:drv_sta_set_4addr
+mac80211:drv_sta_remove
+mac80211:drv_sta_rc_update
+mac80211:drv_sta_rate_tbl_update
+mac80211:drv_sta_pre_rcu_remove
+mac80211:drv_sta_notify
+mac80211:drv_sta_add
+mac80211:drv_set_wakeup
+mac80211:drv_set_tsf
+mac80211:drv_set_tim
+mac80211:drv_set_rts_threshold
+mac80211:drv_set_ringparam
+mac80211:drv_set_rekey_data
+mac80211:drv_set_key
+mac80211:drv_set_frag_threshold
+mac80211:drv_set_default_unicast_key
+mac80211:drv_set_coverage_class
+mac80211:drv_set_bitrate_mask
+mac80211:drv_set_antenna
+mac80211:drv_sched_scan_stop
+mac80211:drv_sched_scan_start
+mac80211:drv_return_void
+mac80211:drv_return_u64
+mac80211:drv_return_u32
+mac80211:drv_return_int
+mac80211:drv_return_bool
+mac80211:drv_resume
+mac80211:drv_reset_tsf
+mac80211:drv_remove_interface
+mac80211:drv_remove_chanctx
+mac80211:drv_remain_on_channel
+mac80211:drv_release_buffered_frames
+mac80211:drv_reconfig_complete
+mac80211:drv_prepare_multicast
+mac80211:drv_pre_channel_switch
+mac80211:drv_post_channel_switch
+mac80211:drv_offset_tsf
+mac80211:drv_offchannel_tx_cancel_wait
+mac80211:drv_nan_change_conf
+mac80211:drv_mgd_protect_tdls_discover
+mac80211:drv_mgd_prepare_tx
+mac80211:drv_leave_ibss
+mac80211:drv_join_ibss
+mac80211:drv_ipv6_addr_change
+mac80211:drv_hw_scan
+mac80211:drv_get_txpower
+mac80211:drv_get_tsf
+mac80211:drv_get_survey
+mac80211:drv_get_stats
+mac80211:drv_get_ringparam
+mac80211:drv_get_key_seq
+mac80211:drv_get_ftm_responder_stats
+mac80211:drv_get_expected_throughput
+mac80211:drv_get_et_strings
+mac80211:drv_get_et_stats
+mac80211:drv_get_et_sset_count
+mac80211:drv_get_antenna
+mac80211:drv_flush
+mac80211:drv_event_callback
+mac80211:drv_del_nan_func
+mac80211:drv_configure_filter
+mac80211:drv_config_iface_filter
+mac80211:drv_config
+mac80211:drv_conf_tx
+mac80211:drv_channel_switch_rx_beacon
+mac80211:drv_channel_switch_beacon
+mac80211:drv_channel_switch
+mac80211:drv_change_interface
+mac80211:drv_change_chanctx
+mac80211:drv_cancel_remain_on_channel
+mac80211:drv_cancel_hw_scan
+mac80211:drv_bss_info_changed
+mac80211:drv_assign_vif_chanctx
+mac80211:drv_ampdu_action
+mac80211:drv_allow_buffered_frames
+mac80211:drv_add_nan_func
+mac80211:drv_add_interface
+mac80211:drv_add_chanctx
+mac80211:drv_abort_pmsr
+mac80211:drv_abort_channel_switch
+mac80211:api_stop_tx_ba_session
+mac80211:api_stop_tx_ba_cb
+mac80211:api_start_tx_ba_session
+mac80211:api_start_tx_ba_cb
+mac80211:api_sta_set_buffered
+mac80211:api_sta_block_awake
+mac80211:api_send_eosp_nullfunc
+mac80211:api_sched_scan_stopped
+mac80211:api_sched_scan_results
+mac80211:api_scan_completed
+mac80211:api_restart_hw
+mac80211:api_remain_on_channel_expired
+mac80211:api_ready_on_channel
+mac80211:api_radar_detected
+mac80211:api_gtk_rekey_notify
+mac80211:api_eosp
+mac80211:api_enable_rssi_reports
+mac80211:api_cqm_rssi_notify
+mac80211:api_cqm_beacon_loss_notify
+mac80211:api_connection_loss
+mac80211:api_chswitch_done
+mac80211:api_beacon_loss
+cfg80211:rdev_update_owe_info
+cfg80211:rdev_update_mgmt_frame_registrations
+cfg80211:rdev_update_mesh_config
+cfg80211:rdev_update_ft_ies
+cfg80211:rdev_update_connect_params
+cfg80211:rdev_tx_control_port
+cfg80211:rdev_testmode_dump
+cfg80211:rdev_testmode_cmd
+cfg80211:rdev_tdls_oper
+cfg80211:rdev_tdls_mgmt
+cfg80211:rdev_tdls_channel_switch
+cfg80211:rdev_tdls_cancel_channel_switch
+cfg80211:rdev_suspend
+cfg80211:rdev_stop_p2p_device
+cfg80211:rdev_stop_nan
+cfg80211:rdev_stop_ap
+cfg80211:rdev_start_radar_detection
+cfg80211:rdev_start_pmsr
+cfg80211:rdev_start_p2p_device
+cfg80211:rdev_start_nan
+cfg80211:rdev_start_ap
+cfg80211:rdev_set_wiphy_params
+cfg80211:rdev_set_wds_peer
+cfg80211:rdev_set_wakeup
+cfg80211:rdev_set_txq_params
+cfg80211:rdev_set_tx_power
+cfg80211:rdev_set_tid_config
+cfg80211:rdev_set_rekey_data
+cfg80211:rdev_set_qos_map
+cfg80211:rdev_set_power_mgmt
+cfg80211:rdev_set_pmksa
+cfg80211:rdev_set_pmk
+cfg80211:rdev_set_noack_map
+cfg80211:rdev_set_multicast_to_unicast
+cfg80211:rdev_set_monitor_channel
+cfg80211:rdev_set_mcast_rate
+cfg80211:rdev_set_mac_acl
+cfg80211:rdev_set_default_mgmt_key
+cfg80211:rdev_set_default_key
+cfg80211:rdev_set_default_beacon_key
+cfg80211:rdev_set_cqm_txe_config
+cfg80211:rdev_set_cqm_rssi_range_config
+cfg80211:rdev_set_cqm_rssi_config
+cfg80211:rdev_set_coalesce
+cfg80211:rdev_set_bitrate_mask
+cfg80211:rdev_set_ap_chanwidth
+cfg80211:rdev_set_antenna
+cfg80211:rdev_sched_scan_stop
+cfg80211:rdev_sched_scan_start
+cfg80211:rdev_scan
+cfg80211:rdev_rfkill_poll
+cfg80211:rdev_return_wdev
+cfg80211:rdev_return_void_tx_rx
+cfg80211:rdev_return_void
+cfg80211:rdev_return_int_tx_rx
+cfg80211:rdev_return_int_survey_info
+cfg80211:rdev_return_int_station_info
+cfg80211:rdev_return_int_mpath_info
+cfg80211:rdev_return_int_mesh_config
+cfg80211:rdev_return_int_int
+cfg80211:rdev_return_int_cookie
+cfg80211:rdev_return_int
+cfg80211:rdev_return_chandef
+cfg80211:rdev_resume
+cfg80211:rdev_reset_tid_config
+cfg80211:rdev_remain_on_channel
+cfg80211:rdev_probe_mesh_link
+cfg80211:rdev_probe_client
+cfg80211:rdev_nan_change_conf
+cfg80211:rdev_mgmt_tx_cancel_wait
+cfg80211:rdev_mgmt_tx
+cfg80211:rdev_libertas_set_mesh_channel
+cfg80211:rdev_leave_ocb
+cfg80211:rdev_leave_mesh
+cfg80211:rdev_leave_ibss
+cfg80211:rdev_join_ocb
+cfg80211:rdev_join_mesh
+cfg80211:rdev_join_ibss
+cfg80211:rdev_get_txq_stats
+cfg80211:rdev_get_tx_power
+cfg80211:rdev_get_station
+cfg80211:rdev_get_mpp
+cfg80211:rdev_get_mpath
+cfg80211:rdev_get_mesh_config
+cfg80211:rdev_get_key
+cfg80211:rdev_get_ftm_responder_stats
+cfg80211:rdev_get_channel
+cfg80211:rdev_get_antenna
+cfg80211:rdev_flush_pmksa
+cfg80211:rdev_external_auth
+cfg80211:rdev_end_cac
+cfg80211:rdev_dump_survey
+cfg80211:rdev_dump_station
+cfg80211:rdev_dump_mpp
+cfg80211:rdev_dump_mpath
+cfg80211:rdev_disconnect
+cfg80211:rdev_disassoc
+cfg80211:rdev_del_virtual_intf
+cfg80211:rdev_del_tx_ts
+cfg80211:rdev_del_station
+cfg80211:rdev_del_pmksa
+cfg80211:rdev_del_pmk
+cfg80211:rdev_del_nan_func
+cfg80211:rdev_del_mpath
+cfg80211:rdev_del_key
+cfg80211:rdev_deauth
+cfg80211:rdev_crit_proto_stop
+cfg80211:rdev_crit_proto_start
+cfg80211:rdev_connect
+cfg80211:rdev_channel_switch
+cfg80211:rdev_change_virtual_intf
+cfg80211:rdev_change_station
+cfg80211:rdev_change_mpath
+cfg80211:rdev_change_bss
+cfg80211:rdev_change_beacon
+cfg80211:rdev_cancel_remain_on_channel
+cfg80211:rdev_auth
+cfg80211:rdev_assoc
+cfg80211:rdev_add_virtual_intf
+cfg80211:rdev_add_tx_ts
+cfg80211:rdev_add_station
+cfg80211:rdev_add_nan_func
+cfg80211:rdev_add_mpath
+cfg80211:rdev_add_key
+cfg80211:rdev_abort_scan
+cfg80211:rdev_abort_pmsr
+cfg80211:cfg80211_update_owe_info_event
+cfg80211:cfg80211_tx_mlme_mgmt
+cfg80211:cfg80211_tx_mgmt_expired
+cfg80211:cfg80211_tdls_oper_request
+cfg80211:cfg80211_stop_iface
+cfg80211:cfg80211_send_rx_auth
+cfg80211:cfg80211_send_rx_assoc
+cfg80211:cfg80211_send_auth_timeout
+cfg80211:cfg80211_send_assoc_timeout
+cfg80211:cfg80211_sched_scan_stopped
+cfg80211:cfg80211_sched_scan_results
+cfg80211:cfg80211_scan_done
+cfg80211:cfg80211_rx_unprot_mlme_mgmt
+cfg80211:cfg80211_rx_unexpected_4addr_frame
+cfg80211:cfg80211_rx_spurious_frame
+cfg80211:cfg80211_rx_mlme_mgmt
+cfg80211:cfg80211_rx_mgmt
+cfg80211:cfg80211_rx_control_port
+cfg80211:cfg80211_return_uint
+cfg80211:cfg80211_return_u32
+cfg80211:cfg80211_return_bss
+cfg80211:cfg80211_return_bool
+cfg80211:cfg80211_report_wowlan_wakeup
+cfg80211:cfg80211_report_obss_beacon
+cfg80211:cfg80211_reg_can_beacon
+cfg80211:cfg80211_ready_on_channel_expired
+cfg80211:cfg80211_ready_on_channel
+cfg80211:cfg80211_radar_event
+cfg80211:cfg80211_probe_status
+cfg80211:cfg80211_pmsr_report
+cfg80211:cfg80211_pmsr_complete
+cfg80211:cfg80211_pmksa_candidate_notify
+cfg80211:cfg80211_notify_new_peer_candidate
+cfg80211:cfg80211_new_sta
+cfg80211:cfg80211_michael_mic_failure
+cfg80211:cfg80211_mgmt_tx_status
+cfg80211:cfg80211_inform_bss_frame
+cfg80211:cfg80211_ibss_joined
+cfg80211:cfg80211_gtk_rekey_notify
+cfg80211:cfg80211_get_bss
+cfg80211:cfg80211_ft_event
+cfg80211:cfg80211_del_sta
+cfg80211:cfg80211_cqm_rssi_notify
+cfg80211:cfg80211_cqm_pktloss_notify
+cfg80211:cfg80211_control_port_tx_status
+cfg80211:cfg80211_chandef_dfs_required
+cfg80211:cfg80211_ch_switch_started_notify
+cfg80211:cfg80211_ch_switch_notify
+cfg80211:cfg80211_cac_event
+synthetic:rss_stat_throttled
+mcps802154_region_nfcc_coex:nfcc_coex_llhw_vendor_cmd
+mcps802154_region_nfcc_coex:nfcc_coex_llhw_return_int
+mcps802154_region_fira:region_fira_tx_message_type
+mcps802154_region_fira:region_fira_session_params
+mcps802154_region_fira:region_fira_rx_message_type
+mali:gpu_power_state
+power:gpu_frequency
+mali:sysgraph_gpu
+mali:sysgraph
+mali:mali_total_alloc_pages_change
+mali:mali_pm_status
+mali:mali_page_fault_insert_pages
+mali:mali_mmu_page_fault_grow
+mali:mali_job_slots_event
+mali:mali_jit_trim_from_region
+mali:mali_jit_trim
+mali:mali_jit_report_pressure
+mali:mali_jit_report_gpu_mem
+mali:mali_jit_report
+mali:mali_jit_free
+mali:mali_jit_alloc
+dpu:tracing_mark_write
+dw3000:dw3000_wakeup_timer_start
+dw3000:dw3000_wakeup_done
+dw3000:dw3000_wakeup
+dw3000:dw3000_tm_cmd
+dw3000:dw3000_testmode_continuous_tx_stop
+dw3000:dw3000_testmode_continuous_tx_start
+dw3000:dw3000_set_pdoa
+dw3000:dw3000_set_operational_state
+dw3000:dw3000_set_antenna_gpio
+dw3000:dw3000_rx_rssi
+dw3000:dw3000_return_void
+dw3000:dw3000_return_int_u64
+dw3000:dw3000_return_int_u32
+dw3000:dw3000_return_int
+dw3000:dw3000_resync_dtu_sys_time
+dw3000:dw3000_read_rx_timestamp
+dw3000:dw3000_read_pdoa
+dw3000:dw3000_read_clockoffset
+dw3000:dw3000_rctu_convert_tx
+dw3000:dw3000_rctu_convert_synced
+dw3000:dw3000_rctu_convert_rx
+dw3000:dw3000_rctu_convert_align
+dw3000:dw3000_power_stats
+dw3000:dw3000_nfcc_coex_watchdog
+dw3000:dw3000_nfcc_coex_warn
+dw3000:dw3000_nfcc_coex_sleep
+dw3000:dw3000_nfcc_coex_rx_msg_info
+dw3000:dw3000_nfcc_coex_isr
+dw3000:dw3000_nfcc_coex_header_check
+dw3000:dw3000_nfcc_coex_err
+dw3000:dw3000_nfcc_coex_enable
+dw3000:dw3000_nfcc_coex_disable
+dw3000:dw3000_nfcc_coex_clock_sync_payload_put
+dw3000:dw3000_nfcc_coex_clock_offset_payload_put
+dw3000:dw3000_mcps_tx_frame
+dw3000:dw3000_mcps_stop
+dw3000:dw3000_mcps_start
+dw3000:dw3000_mcps_set_sts_params
+dw3000:dw3000_mcps_set_hw_addr_filt
+dw3000:dw3000_mcps_set_channel
+dw3000:dw3000_mcps_rx_get_frame
+dw3000:dw3000_mcps_rx_get_error_frame
+dw3000:dw3000_mcps_rx_enable
+dw3000:dw3000_mcps_rx_disable
+dw3000:dw3000_mcps_reset
+dw3000:dw3000_mcps_idle
+dw3000:dw3000_mcps_get_timestamp
+dw3000:dw3000_isr
+dw3000:dw3000_get_counters_second_part
+dw3000:dw3000_get_counters_first_part
+dw3000:dw3000_deep_sleep_enter
+dw3000:dw3000_deep_sleep
+dw3000:dw3000_coex_gpio_stop
+dw3000:dw3000_coex_gpio_start
+dw3000:dw3000_coex_gpio
+dw3000:dw3000_check_operational_state
+dw3000:dw3000_adjust_tx_power
+mcps802154:schedule_update_done
+mcps802154:schedule_update
+mcps802154:region_get_access
+mcps802154:llhw_tx_frame
+mcps802154:llhw_testmode_cmd
+mcps802154:llhw_stop
+mcps802154:llhw_start
+mcps802154:llhw_set_txpower
+mcps802154:llhw_set_sts_params
+mcps802154:llhw_set_scanning_mode
+mcps802154:llhw_set_promiscuous_mode
+mcps802154:llhw_set_hw_addr_filt
+mcps802154:llhw_set_hrp_uwb_params
+mcps802154:llhw_set_channel
+mcps802154:llhw_set_cca_mode
+mcps802154:llhw_set_cca_ed_level
+mcps802154:llhw_set_calibration
+mcps802154:llhw_rx_get_frame
+mcps802154:llhw_rx_get_error_frame
+mcps802154:llhw_rx_enable
+mcps802154:llhw_rx_disable
+mcps802154:llhw_return_void
+mcps802154:llhw_return_timestamp_rctu
+mcps802154:llhw_return_timestamp_dtu
+mcps802154:llhw_return_rx_frame
+mcps802154:llhw_return_int
+mcps802154:llhw_reset
+mcps802154:llhw_list_calibration
+mcps802154:llhw_idle_timestamp
+mcps802154:llhw_idle
+mcps802154:llhw_get_current_timestamp_dtu
+mcps802154:llhw_get_calibration
+mcps802154:llhw_event_tx_done
+mcps802154:llhw_event_timer_expired
+mcps802154:llhw_event_rx_timeout
+mcps802154:llhw_event_rx_frame
+mcps802154:llhw_event_rx_error
+mcps802154:llhw_event_done
+mcps802154:llhw_event_broken
+mcps802154:ca_set_scheduler_parameters
+mcps802154:ca_set_scheduler
+mcps802154:ca_scheduler_set_region_parameters
+mcps802154:ca_scheduler_call_region
+mcps802154:ca_scheduler_call
+mcps802154:ca_return_int
+mcps802154:ca_get_access
+edgetpu:edgetpu_map_dmabuf_start
+edgetpu:edgetpu_map_dmabuf_end
+edgetpu:edgetpu_map_buffer_start
+edgetpu:edgetpu_map_buffer_end
+power:memlat_dev_update
+power:memlat_dev_meas
+thermal_exynos_gpu:vendor_cdev_update
+thermal_exynos_gpu:thermal_exynos_power_gpu_limit
+thermal_exynos_gpu:thermal_exynos_power_gpu_get_power
+thermal_exynos:vendor_cdev_update
+thermal_exynos:thermal_exynos_tpu_pause
+thermal_exynos:thermal_exynos_power_gpu_limit
+thermal_exynos:thermal_exynos_power_gpu_get_power
+thermal_exynos:thermal_exynos_power_cpu_limit
+thermal_exynos:thermal_exynos_power_cpu_get_power
+thermal_exynos:thermal_exynos_power_allocator_pid
+thermal_exynos:thermal_exynos_power_allocator
+thermal_exynos:thermal_exynos_hard_limit_cdev_update
+thermal_exynos:thermal_exynos_cpu_pause
+thermal_exynos:thermal_exynos_arm_update
+thermal_exynos:thermal_exynos_allow_max_power
+thermal_exynos:thermal_cpu_pressure
+mfc:mfc_node_open
+mfc:mfc_node_close
+mfc:mfc_loadfw_start
+mfc:mfc_loadfw_end
+mfc:mfc_frame_top
+mfc:mfc_frame_start
+mfc:mfc_frame_bottom
+mfc:mfc_dcpp_start
+mfc:mfc_dcpp_end
+ufs_pixel:ufs_stats
+zram:zcomp_decompress_start
+zram:zcomp_decompress_end
+g2d:tracing_mark_write
+g2d:g2d_perf_update_qos
+pt:pt_resize_callback
+pt:pt_enable
+pt:pt_driver_log
+devfreq:dvfs_update_load
+devfreq:dvfs_read_ppc
+preemptirq_long:preempt_disable_long
+preemptirq_long:irq_disable_long
+sched:sugov_util_update
+sched:sugov_next_freq
+sched:schedutil_cpu_util_clamp
+sched:sched_util_est_se
+sched:sched_util_est_cfs
+sched:sched_setscheduler_uclamp
+sched:sched_select_task_rq_rt
+sched:sched_rt_cpu_util
+sched:sched_pelt_se
+sched:sched_pelt_rt
+sched:sched_pelt_irq
+sched:sched_pelt_dl
+sched:sched_pelt_cfs
+sched:sched_overutilized
+sched:sched_find_least_loaded_cpu
+sched:sched_find_energy_efficient_cpu
+sched:sched_find_best_target
+sched:sched_cpu_util
+sched:sched_cpu_capacity
+dmabuf_heap:dma_heap_stat
+systrace:0
+initcall:initcall_finish
+initcall:initcall_level
+initcall:initcall_start
+raw_syscalls:sys_enter
+raw_syscalls:sys_exit
+ipi:ipi_entry
+ipi:ipi_exit
+ipi:ipi_raise
+emulation:instruction_emulation
+kvm:kvm_ack_irq
+kvm:kvm_age_page
+kvm:kvm_fpu
+kvm:kvm_halt_poll_ns
+kvm:kvm_mmio
+kvm:kvm_set_irq
+kvm:kvm_userspace_exit
+kvm:kvm_vcpu_wakeup
+kvm:kvm_access_fault
+kvm:kvm_age_hva
+kvm:kvm_entry
+kvm:kvm_exit
+kvm:kvm_get_timer_map
+kvm:kvm_guest_fault
+kvm:kvm_irq_line
+kvm:kvm_mmio_emulate
+kvm:kvm_set_spte_hva
+kvm:kvm_set_way_flush
+kvm:kvm_test_age_hva
+kvm:kvm_timer_emulate
+kvm:kvm_timer_hrtimer_expire
+kvm:kvm_timer_restore_state
+kvm:kvm_timer_save_state
+kvm:kvm_timer_update_irq
+kvm:kvm_toggle_cache
+kvm:kvm_unmap_hva_range
+kvm:kvm_arm_clear_debug
+kvm:kvm_arm_set_dreg32
+kvm:kvm_arm_set_regset
+kvm:kvm_arm_setup_debug
+kvm:kvm_handle_sys_reg
+kvm:kvm_hvc_arm64
+kvm:kvm_set_guest_debug
+kvm:kvm_sys_access
+kvm:kvm_wfx_arm64
+kvm:trap_reg
+kvm:vgic_update_irq_pending
+task:task_newtask
+task:task_rename
+cpuhp:cpuhp_enter
+cpuhp:cpuhp_exit
+cpuhp:cpuhp_multi_enter
+cpuhp:cpuhp_pause
+irq:irq_handler_entry
+irq:irq_handler_exit
+irq:softirq_entry
+irq:softirq_exit
+irq:softirq_raise
+irq:tasklet_entry
+irq:tasklet_exit
+irq:tasklet_hi_entry
+irq:tasklet_hi_exit
+signal:signal_deliver
+signal:signal_generate
+workqueue:workqueue_activate_work
+workqueue:workqueue_execute_end
+workqueue:workqueue_execute_start
+workqueue:workqueue_queue_work
+sched:sched_blocked_reason
+sched:sched_kthread_stop
+sched:sched_kthread_stop_ret
+sched:sched_migrate_task
+sched:sched_move_numa
+sched:sched_pi_setprio
+sched:sched_process_exec
+sched:sched_process_exit
+sched:sched_process_fork
+sched:sched_process_free
+sched:sched_process_hang
+sched:sched_process_wait
+sched:sched_stat_blocked
+sched:sched_stat_iowait
+sched:sched_stat_runtime
+sched:sched_stat_sleep
+sched:sched_stat_wait
+sched:sched_stick_numa
+sched:sched_swap_numa
+sched:sched_switch
+sched:sched_wait_task
+sched:sched_wake_idle_without_ipi
+sched:sched_wakeup
+sched:sched_wakeup_new
+sched:sched_waking
+printk:console
+rcu:rcu_barrier
+rcu:rcu_batch_end
+rcu:rcu_batch_start
+rcu:rcu_callback
+rcu:rcu_dyntick
+rcu:rcu_exp_funnel_lock
+rcu:rcu_exp_grace_period
+rcu:rcu_fqs
+rcu:rcu_future_grace_period
+rcu:rcu_grace_period
+rcu:rcu_grace_period_init
+rcu:rcu_invoke_callback
+rcu:rcu_invoke_kfree_bulk_callback
+rcu:rcu_invoke_kvfree_callback
+rcu:rcu_kvfree_callback
+rcu:rcu_nocb_wake
+rcu:rcu_preempt_task
+rcu:rcu_quiescent_state_report
+rcu:rcu_stall_warning
+rcu:rcu_torture_read
+rcu:rcu_unlock_preempted_task
+rcu:rcu_utilization
+swiotlb:swiotlb_bounced
+timer:hrtimer_cancel
+timer:hrtimer_expire_entry
+timer:hrtimer_expire_exit
+timer:hrtimer_init
+timer:hrtimer_start
+timer:itimer_expire
+timer:itimer_state
+timer:tick_stop
+timer:timer_cancel
+timer:timer_expire_entry
+timer:timer_expire_exit
+timer:timer_init
+timer:timer_start
+alarmtimer:alarmtimer_cancel
+alarmtimer:alarmtimer_fired
+alarmtimer:alarmtimer_start
+alarmtimer:alarmtimer_suspend
+module:module_free
+module:module_get
+module:module_load
+module:module_put
+module:module_request
+cgroup:cgroup_attach_task
+cgroup:cgroup_destroy_root
+cgroup:cgroup_freeze
+cgroup:cgroup_mkdir
+cgroup:cgroup_notify_frozen
+cgroup:cgroup_notify_populated
+cgroup:cgroup_release
+cgroup:cgroup_remount
+cgroup:cgroup_rename
+cgroup:cgroup_rmdir
+cgroup:cgroup_setup_root
+cgroup:cgroup_transfer_tasks
+cgroup:cgroup_unfreeze
+bpf_trace:bpf_trace_printk
+error_report:error_report_end
+power:clock_disable
+power:clock_enable
+power:clock_set_rate
+power:cpu_frequency
+power:cpu_frequency_limits
+power:cpu_idle
+power:dev_pm_qos_add_request
+power:dev_pm_qos_remove_request
+power:dev_pm_qos_update_request
+power:device_pm_callback_end
+power:device_pm_callback_start
+power:pm_qos_add_request
+power:pm_qos_remove_request
+power:pm_qos_update_flags
+power:pm_qos_update_request
+power:pm_qos_update_target
+power:power_domain_target
+power:powernv_throttle
+power:pstate_sample
+power:suspend_resume
+power:wakeup_source_activate
+power:wakeup_source_deactivate
+rpm:rpm_idle
+rpm:rpm_resume
+rpm:rpm_return_int
+rpm:rpm_suspend
+rpm:rpm_usage
+rwmmio:rwmmio_post_read
+rwmmio:rwmmio_read
+rwmmio:rwmmio_write
+xdp:mem_connect
+xdp:mem_disconnect
+xdp:mem_return_failed
+xdp:xdp_bulk_tx
+xdp:xdp_cpumap_enqueue
+xdp:xdp_cpumap_kthread
+xdp:xdp_devmap_xmit
+xdp:xdp_exception
+xdp:xdp_redirect
+xdp:xdp_redirect_err
+xdp:xdp_redirect_map
+xdp:xdp_redirect_map_err
+filemap:file_check_and_advance_wb_err
+filemap:filemap_set_wb_err
+filemap:mm_filemap_add_to_page_cache
+filemap:mm_filemap_delete_from_page_cache
+oom:compact_retry
+oom:finish_task_reaping
+oom:mark_victim
+oom:oom_score_adj_update
+oom:reclaim_retry_zone
+oom:skip_task_reaping
+oom:start_task_reaping
+oom:wake_reaper
+pagemap:mm_lru_activate
+pagemap:mm_lru_insertion
+vmscan:mm_shrink_slab_end
+vmscan:mm_shrink_slab_start
+vmscan:mm_vmscan_direct_reclaim_begin
+vmscan:mm_vmscan_direct_reclaim_end
+vmscan:mm_vmscan_inactive_list_is_low
+vmscan:mm_vmscan_kswapd_sleep
+vmscan:mm_vmscan_kswapd_wake
+vmscan:mm_vmscan_lru_isolate
+vmscan:mm_vmscan_lru_shrink_active
+vmscan:mm_vmscan_lru_shrink_inactive
+vmscan:mm_vmscan_memcg_reclaim_begin
+vmscan:mm_vmscan_memcg_reclaim_end
+vmscan:mm_vmscan_memcg_softlimit_reclaim_begin
+vmscan:mm_vmscan_memcg_softlimit_reclaim_end
+vmscan:mm_vmscan_node_reclaim_begin
+vmscan:mm_vmscan_node_reclaim_end
+vmscan:mm_vmscan_wakeup_kswapd
+vmscan:mm_vmscan_writepage
+percpu:percpu_alloc_percpu
+percpu:percpu_alloc_percpu_fail
+percpu:percpu_create_chunk
+percpu:percpu_destroy_chunk
+percpu:percpu_free_percpu
+kmem:kfree
+kmem:kmalloc
+kmem:kmalloc_node
+kmem:kmem_cache_alloc
+kmem:kmem_cache_alloc_node
+kmem:kmem_cache_free
+kmem:mm_page_alloc
+kmem:mm_page_alloc_extfrag
+kmem:mm_page_alloc_zone_locked
+kmem:mm_page_free
+kmem:mm_page_free_batched
+kmem:mm_page_pcpu_drain
+kmem:rss_stat
+compaction:mm_compaction_begin
+compaction:mm_compaction_defer_compaction
+compaction:mm_compaction_defer_reset
+compaction:mm_compaction_deferred
+compaction:mm_compaction_end
+compaction:mm_compaction_finished
+compaction:mm_compaction_isolate_freepages
+compaction:mm_compaction_isolate_migratepages
+compaction:mm_compaction_kcompactd_sleep
+compaction:mm_compaction_kcompactd_wake
+compaction:mm_compaction_migratepages
+compaction:mm_compaction_suitable
+compaction:mm_compaction_try_to_compact_pages
+compaction:mm_compaction_wakeup_kcompactd
+pagefault:spf_pmd_changed
+pagefault:spf_pte_lock
+pagefault:spf_vma_access
+pagefault:spf_vma_changed
+pagefault:spf_vma_noanon
+pagefault:spf_vma_notsup
+mmap:vm_unmapped_area
+migrate:mm_migrate_pages
+migrate:mm_migrate_pages_start
+huge_memory:mm_collapse_huge_page
+huge_memory:mm_collapse_huge_page_isolate
+huge_memory:mm_collapse_huge_page_swapin
+huge_memory:mm_khugepaged_scan_pmd
+page_isolation:test_pages_isolated
+cma:cma_alloc_busy_retry
+cma:cma_alloc_finish
+cma:cma_alloc_info
+cma:cma_alloc_start
+cma:cma_release
+namei:inodepath
+writeback:balance_dirty_pages
+writeback:bdi_dirty_ratelimit
+writeback:flush_foreign
+writeback:global_dirty_state
+writeback:inode_foreign_history
+writeback:inode_switch_wbs
+writeback:sb_clear_inode_writeback
+writeback:sb_mark_inode_writeback
+writeback:track_foreign_dirty
+writeback:wait_on_page_writeback
+writeback:wbc_writepage
+writeback:writeback_bdi_register
+writeback:writeback_congestion_wait
+writeback:writeback_dirty_inode
+writeback:writeback_dirty_inode_enqueue
+writeback:writeback_dirty_inode_start
+writeback:writeback_dirty_page
+writeback:writeback_exec
+writeback:writeback_lazytime
+writeback:writeback_lazytime_iput
+writeback:writeback_mark_inode_dirty
+writeback:writeback_pages_written
+writeback:writeback_queue
+writeback:writeback_queue_io
+writeback:writeback_sb_inodes_requeue
+writeback:writeback_single_inode
+writeback:writeback_single_inode_start
+writeback:writeback_start
+writeback:writeback_wait
+writeback:writeback_wait_iff_congested
+writeback:writeback_wake_background
+writeback:writeback_write_inode
+writeback:writeback_write_inode_start
+writeback:writeback_written
+android_fs:android_fs_dataread_end
+android_fs:android_fs_dataread_start
+android_fs:android_fs_datawrite_end
+android_fs:android_fs_datawrite_start
+io_uring:io_uring_complete
+io_uring:io_uring_cqring_wait
+io_uring:io_uring_create
+io_uring:io_uring_defer
+io_uring:io_uring_fail_link
+io_uring:io_uring_file_get
+io_uring:io_uring_link
+io_uring:io_uring_poll_arm
+io_uring:io_uring_poll_wake
+io_uring:io_uring_queue_async_work
+io_uring:io_uring_register
+io_uring:io_uring_submit_sqe
+io_uring:io_uring_task_add
+io_uring:io_uring_task_run
+filelock:break_lease_block
+filelock:break_lease_noblock
+filelock:break_lease_unblock
+filelock:fcntl_setlk
+filelock:flock_lock_inode
+filelock:generic_add_lease
+filelock:generic_delete_lease
+filelock:leases_conflict
+filelock:locks_get_lock_context
+filelock:locks_remove_posix
+filelock:posix_lock_inode
+filelock:time_out_leases
+iomap:iomap_apply
+iomap:iomap_apply_dstmap
+iomap:iomap_apply_srcmap
+iomap:iomap_dio_invalidate_fail
+iomap:iomap_invalidatepage
+iomap:iomap_readahead
+iomap:iomap_readpage
+iomap:iomap_releasepage
+iomap:iomap_writepage
+ext4:ext4_alloc_da_blocks
+ext4:ext4_allocate_blocks
+ext4:ext4_allocate_inode
+ext4:ext4_begin_ordered_truncate
+ext4:ext4_collapse_range
+ext4:ext4_da_release_space
+ext4:ext4_da_reserve_space
+ext4:ext4_da_update_reserve_space
+ext4:ext4_da_write_begin
+ext4:ext4_da_write_end
+ext4:ext4_da_write_pages
+ext4:ext4_da_write_pages_extent
+ext4:ext4_direct_IO_enter
+ext4:ext4_direct_IO_exit
+ext4:ext4_discard_blocks
+ext4:ext4_discard_preallocations
+ext4:ext4_drop_inode
+ext4:ext4_error
+ext4:ext4_es_cache_extent
+ext4:ext4_es_find_extent_range_enter
+ext4:ext4_es_find_extent_range_exit
+ext4:ext4_es_insert_delayed_block
+ext4:ext4_es_insert_extent
+ext4:ext4_es_lookup_extent_enter
+ext4:ext4_es_lookup_extent_exit
+ext4:ext4_es_remove_extent
+ext4:ext4_es_shrink
+ext4:ext4_es_shrink_count
+ext4:ext4_es_shrink_scan_enter
+ext4:ext4_es_shrink_scan_exit
+ext4:ext4_evict_inode
+ext4:ext4_ext_convert_to_initialized_enter
+ext4:ext4_ext_convert_to_initialized_fastpath
+ext4:ext4_ext_handle_unwritten_extents
+ext4:ext4_ext_in_cache
+ext4:ext4_ext_load_extent
+ext4:ext4_ext_map_blocks_enter
+ext4:ext4_ext_map_blocks_exit
+ext4:ext4_ext_put_in_cache
+ext4:ext4_ext_remove_space
+ext4:ext4_ext_remove_space_done
+ext4:ext4_ext_rm_idx
+ext4:ext4_ext_rm_leaf
+ext4:ext4_ext_show_extent
+ext4:ext4_fallocate_enter
+ext4:ext4_fallocate_exit
+ext4:ext4_fc_commit_start
+ext4:ext4_fc_commit_stop
+ext4:ext4_fc_replay
+ext4:ext4_fc_replay_scan
+ext4:ext4_fc_stats
+ext4:ext4_fc_track_create
+ext4:ext4_fc_track_inode
+ext4:ext4_fc_track_link
+ext4:ext4_fc_track_range
+ext4:ext4_fc_track_unlink
+ext4:ext4_find_delalloc_range
+ext4:ext4_forget
+ext4:ext4_free_blocks
+ext4:ext4_free_inode
+ext4:ext4_fsmap_high_key
+ext4:ext4_fsmap_low_key
+ext4:ext4_fsmap_mapping
+ext4:ext4_get_implied_cluster_alloc_exit
+ext4:ext4_get_reserved_cluster_alloc
+ext4:ext4_getfsmap_high_key
+ext4:ext4_getfsmap_low_key
+ext4:ext4_getfsmap_mapping
+ext4:ext4_ind_map_blocks_enter
+ext4:ext4_ind_map_blocks_exit
+ext4:ext4_insert_range
+ext4:ext4_invalidatepage
+ext4:ext4_journal_start
+ext4:ext4_journal_start_reserved
+ext4:ext4_journalled_invalidatepage
+ext4:ext4_journalled_write_end
+ext4:ext4_lazy_itable_init
+ext4:ext4_load_inode
+ext4:ext4_load_inode_bitmap
+ext4:ext4_mark_inode_dirty
+ext4:ext4_mb_bitmap_load
+ext4:ext4_mb_buddy_bitmap_load
+ext4:ext4_mb_discard_preallocations
+ext4:ext4_mb_new_group_pa
+ext4:ext4_mb_new_inode_pa
+ext4:ext4_mb_release_group_pa
+ext4:ext4_mb_release_inode_pa
+ext4:ext4_mballoc_alloc
+ext4:ext4_mballoc_discard
+ext4:ext4_mballoc_free
+ext4:ext4_mballoc_prealloc
+ext4:ext4_nfs_commit_metadata
+ext4:ext4_other_inode_update_time
+ext4:ext4_prefetch_bitmaps
+ext4:ext4_punch_hole
+ext4:ext4_read_block_bitmap_load
+ext4:ext4_readpage
+ext4:ext4_releasepage
+ext4:ext4_remove_blocks
+ext4:ext4_request_blocks
+ext4:ext4_request_inode
+ext4:ext4_shutdown
+ext4:ext4_sync_file_enter
+ext4:ext4_sync_file_exit
+ext4:ext4_sync_fs
+ext4:ext4_trim_all_free
+ext4:ext4_trim_extent
+ext4:ext4_truncate_enter
+ext4:ext4_truncate_exit
+ext4:ext4_unlink_enter
+ext4:ext4_unlink_exit
+ext4:ext4_write_begin
+ext4:ext4_write_end
+ext4:ext4_writepage
+ext4:ext4_writepages
+ext4:ext4_writepages_result
+ext4:ext4_zero_range
+jbd2:jbd2_checkpoint
+jbd2:jbd2_checkpoint_stats
+jbd2:jbd2_commit_flushing
+jbd2:jbd2_commit_locking
+jbd2:jbd2_commit_logging
+jbd2:jbd2_drop_transaction
+jbd2:jbd2_end_commit
+jbd2:jbd2_handle_extend
+jbd2:jbd2_handle_restart
+jbd2:jbd2_handle_start
+jbd2:jbd2_handle_stats
+jbd2:jbd2_lock_buffer_stall
+jbd2:jbd2_run_stats
+jbd2:jbd2_start_commit
+jbd2:jbd2_submit_inode_data
+jbd2:jbd2_update_log_tail
+jbd2:jbd2_write_superblock
+f2fs:f2fs_background_gc
+f2fs:f2fs_bmap
+f2fs:f2fs_commit_inmem_page
+f2fs:f2fs_compress_pages_end
+f2fs:f2fs_compress_pages_start
+f2fs:f2fs_decompress_pages_end
+f2fs:f2fs_decompress_pages_start
+f2fs:f2fs_destroy_extent_tree
+f2fs:f2fs_direct_IO_enter
+f2fs:f2fs_direct_IO_exit
+f2fs:f2fs_do_write_data_page
+f2fs:f2fs_drop_inode
+f2fs:f2fs_evict_inode
+f2fs:f2fs_fallocate
+f2fs:f2fs_fiemap
+f2fs:f2fs_file_write_iter
+f2fs:f2fs_filemap_fault
+f2fs:f2fs_gc_begin
+f2fs:f2fs_gc_end
+f2fs:f2fs_get_victim
+f2fs:f2fs_iget
+f2fs:f2fs_iget_exit
+f2fs:f2fs_iostat
+f2fs:f2fs_issue_discard
+f2fs:f2fs_issue_flush
+f2fs:f2fs_issue_reset_zone
+f2fs:f2fs_lookup_end
+f2fs:f2fs_lookup_extent_tree_end
+f2fs:f2fs_lookup_extent_tree_start
+f2fs:f2fs_lookup_start
+f2fs:f2fs_map_blocks
+f2fs:f2fs_new_inode
+f2fs:f2fs_prepare_read_bio
+f2fs:f2fs_prepare_write_bio
+f2fs:f2fs_queue_discard
+f2fs:f2fs_readdir
+f2fs:f2fs_readpage
+f2fs:f2fs_readpages
+f2fs:f2fs_register_inmem_page
+f2fs:f2fs_remove_discard
+f2fs:f2fs_reserve_new_blocks
+f2fs:f2fs_set_page_dirty
+f2fs:f2fs_shrink_extent_tree
+f2fs:f2fs_shutdown
+f2fs:f2fs_submit_page_bio
+f2fs:f2fs_submit_page_write
+f2fs:f2fs_submit_read_bio
+f2fs:f2fs_submit_write_bio
+f2fs:f2fs_sync_dirty_inodes_enter
+f2fs:f2fs_sync_dirty_inodes_exit
+f2fs:f2fs_sync_file_enter
+f2fs:f2fs_sync_file_exit
+f2fs:f2fs_sync_fs
+f2fs:f2fs_truncate
+f2fs:f2fs_truncate_blocks_enter
+f2fs:f2fs_truncate_blocks_exit
+f2fs:f2fs_truncate_data_blocks_range
+f2fs:f2fs_truncate_inode_blocks_enter
+f2fs:f2fs_truncate_inode_blocks_exit
+f2fs:f2fs_truncate_node
+f2fs:f2fs_truncate_nodes_enter
+f2fs:f2fs_truncate_nodes_exit
+f2fs:f2fs_truncate_partial_nodes
+f2fs:f2fs_unlink_enter
+f2fs:f2fs_unlink_exit
+f2fs:f2fs_update_extent_tree_range
+f2fs:f2fs_vm_page_mkwrite
+f2fs:f2fs_write_begin
+f2fs:f2fs_write_checkpoint
+f2fs:f2fs_write_end
+f2fs:f2fs_writepage
+f2fs:f2fs_writepages
+erofs:erofs_destroy_inode
+erofs:erofs_fill_inode
+erofs:erofs_lookup
+erofs:erofs_map_blocks_flatmode_enter
+erofs:erofs_map_blocks_flatmode_exit
+erofs:erofs_readpage
+erofs:erofs_readpages
+erofs:z_erofs_map_blocks_iter_enter
+erofs:z_erofs_map_blocks_iter_exit
+avc:selinux_audited
+block:block_bio_backmerge
+block:block_bio_bounce
+block:block_bio_complete
+block:block_bio_frontmerge
+block:block_bio_queue
+block:block_bio_remap
+block:block_dirty_buffer
+block:block_getrq
+block:block_plug
+block:block_rq_complete
+block:block_rq_insert
+block:block_rq_issue
+block:block_rq_merge
+block:block_rq_remap
+block:block_rq_requeue
+block:block_sleeprq
+block:block_split
+block:block_touch_buffer
+block:block_unplug
+iocost:iocost_inuse_adjust
+iocost:iocost_inuse_shortage
+iocost:iocost_inuse_transfer
+iocost:iocost_ioc_vrate_adj
+iocost:iocost_iocg_activate
+iocost:iocost_iocg_forgive_debt
+kyber:kyber_adjust
+kyber:kyber_latency
+kyber:kyber_throttled
+gpio:gpio_direction
+gpio:gpio_value
+pwm:pwm_apply
+pwm:pwm_get
+clk:clk_disable
+clk:clk_disable_complete
+clk:clk_enable
+clk:clk_enable_complete
+clk:clk_prepare
+clk:clk_prepare_complete
+clk:clk_set_duty_cycle
+clk:clk_set_duty_cycle_complete
+clk:clk_set_parent
+clk:clk_set_parent_complete
+clk:clk_set_phase
+clk:clk_set_phase_complete
+clk:clk_set_rate
+clk:clk_set_rate_complete
+clk:clk_unprepare
+clk:clk_unprepare_complete
+regulator:regulator_bypass_disable
+regulator:regulator_bypass_disable_complete
+regulator:regulator_bypass_enable
+regulator:regulator_bypass_enable_complete
+regulator:regulator_disable
+regulator:regulator_disable_complete
+regulator:regulator_enable
+regulator:regulator_enable_complete
+regulator:regulator_enable_delay
+regulator:regulator_set_voltage
+regulator:regulator_set_voltage_complete
+random:add_device_randomness
+random:add_disk_randomness
+random:add_input_randomness
+random:credit_entropy_bits
+random:debit_entropy
+random:extract_entropy
+random:extract_entropy_user
+random:get_random_bytes
+random:get_random_bytes_arch
+random:mix_pool_bytes
+random:mix_pool_bytes_nolock
+random:prandom_u32
+random:push_to_pool
+random:random_read
+random:urandom_read
+random:xfer_secondary_pool
+iommu:add_device_to_group
+iommu:attach_device_to_domain
+iommu:detach_device_from_domain
+iommu:io_page_fault
+iommu:map
+iommu:remove_device_from_group
+iommu:unmap
+drm:drm_vblank_event
+drm:drm_vblank_event_delivered
+drm:drm_vblank_event_queued
+gpu_mem:gpu_mem_total
+regmap:regcache_drop_region
+regmap:regcache_sync
+regmap:regmap_async_complete_done
+regmap:regmap_async_complete_start
+regmap:regmap_async_io_complete
+regmap:regmap_async_write_start
+regmap:regmap_cache_bypass
+regmap:regmap_cache_only
+regmap:regmap_hw_read_done
+regmap:regmap_hw_read_start
+regmap:regmap_hw_write_done
+regmap:regmap_hw_write_start
+regmap:regmap_reg_read
+regmap:regmap_reg_read_cache
+regmap:regmap_reg_write
+dma_fence:dma_fence_destroy
+dma_fence:dma_fence_emit
+dma_fence:dma_fence_enable_signal
+dma_fence:dma_fence_init
+dma_fence:dma_fence_signaled
+dma_fence:dma_fence_wait_end
+dma_fence:dma_fence_wait_start
+scsi:scsi_dispatch_cmd_done
+scsi:scsi_dispatch_cmd_error
+scsi:scsi_dispatch_cmd_start
+scsi:scsi_dispatch_cmd_timeout
+scsi:scsi_eh_wakeup
+ufs:ufshcd_auto_bkops_state
+ufs:ufshcd_clk_gating
+ufs:ufshcd_clk_scaling
+ufs:ufshcd_command
+ufs:ufshcd_init
+ufs:ufshcd_profile_clk_gating
+ufs:ufshcd_profile_clk_scaling
+ufs:ufshcd_profile_hibern8
+ufs:ufshcd_runtime_resume
+ufs:ufshcd_runtime_suspend
+ufs:ufshcd_system_resume
+ufs:ufshcd_system_suspend
+ufs:ufshcd_uic_command
+ufs:ufshcd_upiu
+spi:spi_controller_busy
+spi:spi_controller_idle
+spi:spi_message_done
+spi:spi_message_start
+spi:spi_message_submit
+spi:spi_transfer_start
+spi:spi_transfer_stop
+spmi:spmi_cmd
+spmi:spmi_read_begin
+spmi:spmi_read_end
+spmi:spmi_write_begin
+spmi:spmi_write_end
+mdio:mdio_access
+dwc3:dwc3_alloc_request
+dwc3:dwc3_complete_trb
+dwc3:dwc3_ctrl_req
+dwc3:dwc3_ep_dequeue
+dwc3:dwc3_ep_queue
+dwc3:dwc3_event
+dwc3:dwc3_free_request
+dwc3:dwc3_gadget_ep_cmd
+dwc3:dwc3_gadget_ep_disable
+dwc3:dwc3_gadget_ep_enable
+dwc3:dwc3_gadget_generic_cmd
+dwc3:dwc3_gadget_giveback
+dwc3:dwc3_prepare_trb
+dwc3:dwc3_readl
+dwc3:dwc3_writel
+xhci-hcd:xhci_add_endpoint
+xhci-hcd:xhci_address_ctrl_ctx
+xhci-hcd:xhci_address_ctx
+xhci-hcd:xhci_alloc_dev
+xhci-hcd:xhci_alloc_virt_device
+xhci-hcd:xhci_configure_endpoint
+xhci-hcd:xhci_configure_endpoint_ctrl_ctx
+xhci-hcd:xhci_dbc_alloc_request
+xhci-hcd:xhci_dbc_free_request
+xhci-hcd:xhci_dbc_gadget_ep_queue
+xhci-hcd:xhci_dbc_giveback_request
+xhci-hcd:xhci_dbc_handle_event
+xhci-hcd:xhci_dbc_handle_transfer
+xhci-hcd:xhci_dbc_queue_request
+xhci-hcd:xhci_dbg_address
+xhci-hcd:xhci_dbg_cancel_urb
+xhci-hcd:xhci_dbg_context_change
+xhci-hcd:xhci_dbg_init
+xhci-hcd:xhci_dbg_quirks
+xhci-hcd:xhci_dbg_reset_ep
+xhci-hcd:xhci_dbg_ring_expansion
+xhci-hcd:xhci_discover_or_reset_device
+xhci-hcd:xhci_free_dev
+xhci-hcd:xhci_free_virt_device
+xhci-hcd:xhci_get_port_status
+xhci-hcd:xhci_handle_cmd_addr_dev
+xhci-hcd:xhci_handle_cmd_config_ep
+xhci-hcd:xhci_handle_cmd_disable_slot
+xhci-hcd:xhci_handle_cmd_reset_dev
+xhci-hcd:xhci_handle_cmd_reset_ep
+xhci-hcd:xhci_handle_cmd_set_deq
+xhci-hcd:xhci_handle_cmd_set_deq_ep
+xhci-hcd:xhci_handle_cmd_stop_ep
+xhci-hcd:xhci_handle_command
+xhci-hcd:xhci_handle_event
+xhci-hcd:xhci_handle_port_status
+xhci-hcd:xhci_handle_transfer
+xhci-hcd:xhci_hub_status_data
+xhci-hcd:xhci_inc_deq
+xhci-hcd:xhci_inc_enq
+xhci-hcd:xhci_queue_trb
+xhci-hcd:xhci_ring_alloc
+xhci-hcd:xhci_ring_ep_doorbell
+xhci-hcd:xhci_ring_expansion
+xhci-hcd:xhci_ring_free
+xhci-hcd:xhci_ring_host_doorbell
+xhci-hcd:xhci_setup_addressable_virt_device
+xhci-hcd:xhci_setup_device
+xhci-hcd:xhci_setup_device_slot
+xhci-hcd:xhci_stop_device
+xhci-hcd:xhci_urb_dequeue
+xhci-hcd:xhci_urb_enqueue
+xhci-hcd:xhci_urb_giveback
+gadget:usb_ep_alloc_request
+gadget:usb_ep_clear_halt
+gadget:usb_ep_dequeue
+gadget:usb_ep_disable
+gadget:usb_ep_enable
+gadget:usb_ep_fifo_flush
+gadget:usb_ep_fifo_status
+gadget:usb_ep_free_request
+gadget:usb_ep_queue
+gadget:usb_ep_set_halt
+gadget:usb_ep_set_maxpacket_limit
+gadget:usb_ep_set_wedge
+gadget:usb_gadget_activate
+gadget:usb_gadget_clear_selfpowered
+gadget:usb_gadget_connect
+gadget:usb_gadget_deactivate
+gadget:usb_gadget_disconnect
+gadget:usb_gadget_frame_number
+gadget:usb_gadget_giveback_request
+gadget:usb_gadget_set_selfpowered
+gadget:usb_gadget_vbus_connect
+gadget:usb_gadget_vbus_disconnect
+gadget:usb_gadget_vbus_draw
+gadget:usb_gadget_wakeup
+ucsi:ucsi_connector_change
+ucsi:ucsi_register_altmode
+ucsi:ucsi_register_port
+ucsi:ucsi_reset_ppm
+ucsi:ucsi_run_command
+rtc:rtc_alarm_irq_enable
+rtc:rtc_irq_set_freq
+rtc:rtc_irq_set_state
+rtc:rtc_read_alarm
+rtc:rtc_read_offset
+rtc:rtc_read_time
+rtc:rtc_set_alarm
+rtc:rtc_set_offset
+rtc:rtc_set_time
+rtc:rtc_timer_dequeue
+rtc:rtc_timer_enqueue
+rtc:rtc_timer_fired
+i2c:i2c_read
+i2c:i2c_reply
+i2c:i2c_result
+i2c:i2c_write
+smbus:smbus_read
+smbus:smbus_reply
+smbus:smbus_result
+smbus:smbus_write
+v4l2:v4l2_dqbuf
+v4l2:v4l2_qbuf
+v4l2:vb2_v4l2_buf_done
+v4l2:vb2_v4l2_buf_queue
+v4l2:vb2_v4l2_dqbuf
+v4l2:vb2_v4l2_qbuf
+vb2:vb2_buf_done
+vb2:vb2_buf_queue
+vb2:vb2_dqbuf
+vb2:vb2_qbuf
+thermal:cdev_update
+thermal:thermal_power_cpu_get_power
+thermal:thermal_power_cpu_limit
+thermal:thermal_power_devfreq_get_power
+thermal:thermal_power_devfreq_limit
+thermal:thermal_temperature
+thermal:thermal_zone_trip
+thermal_power_allocator:thermal_power_allocator
+thermal_power_allocator:thermal_power_allocator_pid
+mmc:mmc_request_done
+mmc:mmc_request_start
+scmi:scmi_rx_done
+scmi:scmi_xfer_begin
+scmi:scmi_xfer_end
+devfreq:devfreq_monitor
+ras:aer_event
+ras:arm_event
+ras:mc_event
+ras:non_standard_event
+binder:binder_alloc_lru_end
+binder:binder_alloc_lru_start
+binder:binder_alloc_page_end
+binder:binder_alloc_page_start
+binder:binder_command
+binder:binder_free_lru_end
+binder:binder_free_lru_start
+binder:binder_ioctl
+binder:binder_ioctl_done
+binder:binder_lock
+binder:binder_locked
+binder:binder_read_done
+binder:binder_return
+binder:binder_set_priority
+binder:binder_transaction
+binder:binder_transaction_alloc_buf
+binder:binder_transaction_buffer_release
+binder:binder_transaction_failed_buffer_release
+binder:binder_transaction_fd_recv
+binder:binder_transaction_fd_send
+binder:binder_transaction_node_to_ref
+binder:binder_transaction_received
+binder:binder_transaction_ref_to_node
+binder:binder_transaction_ref_to_ref
+binder:binder_unlock
+binder:binder_unmap_kernel_end
+binder:binder_unmap_kernel_start
+binder:binder_unmap_user_end
+binder:binder_unmap_user_start
+binder:binder_update_page_range
+binder:binder_wait_for_work
+binder:binder_write_done
+interconnect:icc_set_bw
+interconnect:icc_set_bw_end
+asoc:snd_soc_bias_level_done
+asoc:snd_soc_bias_level_start
+asoc:snd_soc_dapm_connected
+asoc:snd_soc_dapm_done
+asoc:snd_soc_dapm_path
+asoc:snd_soc_dapm_start
+asoc:snd_soc_dapm_walk_done
+asoc:snd_soc_dapm_widget_event_done
+asoc:snd_soc_dapm_widget_event_start
+asoc:snd_soc_dapm_widget_power
+asoc:snd_soc_jack_irq
+asoc:snd_soc_jack_notify
+asoc:snd_soc_jack_report
+bridge:br_fdb_add
+bridge:br_fdb_external_learn_add
+bridge:br_fdb_update
+skb:consume_skb
+bridge:fdb_delete
+fib:fib_table_lookup
+sock:inet_sock_set_state
+skb:kfree_skb
+net:napi_gro_frags_entry
+net:napi_gro_frags_exit
+net:napi_gro_receive_entry
+net:napi_gro_receive_exit
+napi:napi_poll
+neigh:neigh_cleanup_and_release
+neigh:neigh_create
+neigh:neigh_event_send_dead
+neigh:neigh_event_send_done
+neigh:neigh_timer_handler
+neigh:neigh_update
+neigh:neigh_update_done
+net:net_dev_queue
+net:net_dev_start_xmit
+net:net_dev_xmit
+net:net_dev_xmit_timeout
+net:netif_receive_skb
+net:netif_receive_skb_entry
+net:netif_receive_skb_exit
+net:netif_receive_skb_list_entry
+net:netif_receive_skb_list_exit
+net:netif_rx
+net:netif_rx_entry
+net:netif_rx_exit
+net:netif_rx_ni_entry
+net:netif_rx_ni_exit
+page_pool:page_pool_release
+page_pool:page_pool_state_hold
+page_pool:page_pool_state_release
+page_pool:page_pool_update_nid
+qdisc:qdisc_create
+qdisc:qdisc_dequeue
+qdisc:qdisc_destroy
+qdisc:qdisc_reset
+skb:skb_copy_datagram_iovec
+sock:sock_exceed_buf_limit
+sock:sock_rcvqueue_full
+tcp:tcp_destroy_sock
+tcp:tcp_probe
+tcp:tcp_rcv_space_adjust
+tcp:tcp_receive_reset
+tcp:tcp_retransmit_skb
+tcp:tcp_retransmit_synack
+tcp:tcp_send_reset
+udp:udp_fail_queue_rcv_skb
+bpf_test_run:bpf_test_finish
+fib6:fib6_table_lookup
+l2tp:delete_session
+l2tp:delete_tunnel
+l2tp:free_session
+l2tp:free_tunnel
+l2tp:register_session
+l2tp:register_tunnel
+l2tp:session_pkt_expired
+l2tp:session_pkt_oos
+l2tp:session_pkt_outside_rx_window
+l2tp:session_seqnum_lns_disable
+l2tp:session_seqnum_lns_enable
+l2tp:session_seqnum_reset
+l2tp:session_seqnum_update
+tipc:tipc_l2_device_event
+tipc:tipc_link_bc_ack
+tipc:tipc_link_conges
+tipc:tipc_link_dump
+tipc:tipc_link_fsm
+tipc:tipc_link_reset
+tipc:tipc_link_retrans
+tipc:tipc_link_timeout
+tipc:tipc_link_too_silent
+tipc:tipc_list_dump
+tipc:tipc_node_check_state
+tipc:tipc_node_create
+tipc:tipc_node_delete
+tipc:tipc_node_dump
+tipc:tipc_node_fsm
+tipc:tipc_node_link_down
+tipc:tipc_node_link_up
+tipc:tipc_node_lost_contact
+tipc:tipc_node_reset_links
+tipc:tipc_node_timeout
+tipc:tipc_proto_build
+tipc:tipc_proto_rcv
+tipc:tipc_sk_advance_rx
+tipc:tipc_sk_create
+tipc:tipc_sk_drop_msg
+tipc:tipc_sk_dump
+tipc:tipc_sk_filter_rcv
+tipc:tipc_sk_overlimit1
+tipc:tipc_sk_overlimit2
+tipc:tipc_sk_poll
+tipc:tipc_sk_rej_msg
+tipc:tipc_sk_release
+tipc:tipc_sk_sendmcast
+tipc:tipc_sk_sendmsg
+tipc:tipc_sk_sendstream
+tipc:tipc_sk_shutdown
+tipc:tipc_skb_dump
+cfg802154:802154_rdev_add_virtual_intf
+cfg802154:802154_rdev_del_virtual_intf
+cfg802154:802154_rdev_resume
+cfg802154:802154_rdev_return_int
+cfg802154:802154_rdev_set_ackreq_default
+cfg802154:802154_rdev_set_backoff_exponent
+cfg802154:802154_rdev_set_cca_ed_level
+cfg802154:802154_rdev_set_cca_mode
+cfg802154:802154_rdev_set_channel
+cfg802154:802154_rdev_set_csma_backoffs
+cfg802154:802154_rdev_set_lbt_mode
+cfg802154:802154_rdev_set_max_frame_retries
+cfg802154:802154_rdev_set_pan_id
+cfg802154:802154_rdev_set_short_addr
+cfg802154:802154_rdev_set_tx_power
+cfg802154:802154_rdev_suspend
+mac802154:802154_drv_return_int
+mac802154:802154_drv_return_void
+mac802154:802154_drv_set_cca_ed_level
+mac802154:802154_drv_set_cca_mode
+mac802154:802154_drv_set_channel
+mac802154:802154_drv_set_csma_params
+mac802154:802154_drv_set_extended_addr
+mac802154:802154_drv_set_lbt_mode
+mac802154:802154_drv_set_max_frame_retries
+mac802154:802154_drv_set_pan_coord
+mac802154:802154_drv_set_pan_id
+mac802154:802154_drv_set_promiscuous_mode
+mac802154:802154_drv_set_short_addr
+mac802154:802154_drv_set_tx_power
+mac802154:802154_drv_start
+mac802154:802154_drv_stop
+vsock:virtio_transport_alloc_pkt
+vsock:virtio_transport_recv_pkt
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/alarmtimer/alarmtimer_cancel/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/alarmtimer/alarmtimer_cancel/format
new file mode 100644
index 000000000..60dc020ad
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/alarmtimer/alarmtimer_cancel/format
@@ -0,0 +1,14 @@
+name: alarmtimer_cancel
+ID: 146
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * alarm; offset:8; size:8; signed:0;
+ field:unsigned char alarm_type; offset:16; size:1; signed:0;
+ field:s64 expires; offset:24; size:8; signed:1;
+ field:s64 now; offset:32; size:8; signed:1;
+
+print fmt: "alarmtimer:%p type:%s expires:%llu now:%llu", REC->alarm, __print_flags((1 << REC->alarm_type), " | ", { 1 << 0, "REALTIME" }, { 1 << 1, "BOOTTIME" }, { 1 << 3, "REALTIME Freezer" }, { 1 << 4, "BOOTTIME Freezer" }), REC->expires, REC->now
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/alarmtimer/alarmtimer_fired/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/alarmtimer/alarmtimer_fired/format
new file mode 100644
index 000000000..b71b9acc5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/alarmtimer/alarmtimer_fired/format
@@ -0,0 +1,14 @@
+name: alarmtimer_fired
+ID: 147
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * alarm; offset:8; size:8; signed:0;
+ field:unsigned char alarm_type; offset:16; size:1; signed:0;
+ field:s64 expires; offset:24; size:8; signed:1;
+ field:s64 now; offset:32; size:8; signed:1;
+
+print fmt: "alarmtimer:%p type:%s expires:%llu now:%llu", REC->alarm, __print_flags((1 << REC->alarm_type), " | ", { 1 << 0, "REALTIME" }, { 1 << 1, "BOOTTIME" }, { 1 << 3, "REALTIME Freezer" }, { 1 << 4, "BOOTTIME Freezer" }), REC->expires, REC->now
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/alarmtimer/alarmtimer_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/alarmtimer/alarmtimer_start/format
new file mode 100644
index 000000000..dc6cfdc59
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/alarmtimer/alarmtimer_start/format
@@ -0,0 +1,14 @@
+name: alarmtimer_start
+ID: 148
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * alarm; offset:8; size:8; signed:0;
+ field:unsigned char alarm_type; offset:16; size:1; signed:0;
+ field:s64 expires; offset:24; size:8; signed:1;
+ field:s64 now; offset:32; size:8; signed:1;
+
+print fmt: "alarmtimer:%p type:%s expires:%llu now:%llu", REC->alarm, __print_flags((1 << REC->alarm_type), " | ", { 1 << 0, "REALTIME" }, { 1 << 1, "BOOTTIME" }, { 1 << 3, "REALTIME Freezer" }, { 1 << 4, "BOOTTIME Freezer" }), REC->expires, REC->now
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/alarmtimer/alarmtimer_suspend/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/alarmtimer/alarmtimer_suspend/format
new file mode 100644
index 000000000..16940e375
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/alarmtimer/alarmtimer_suspend/format
@@ -0,0 +1,12 @@
+name: alarmtimer_suspend
+ID: 149
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:s64 expires; offset:8; size:8; signed:1;
+ field:unsigned char alarm_type; offset:16; size:1; signed:0;
+
+print fmt: "alarmtimer type:%s expires:%llu", __print_flags((1 << REC->alarm_type), " | ", { 1 << 0, "REALTIME" }, { 1 << 1, "BOOTTIME" }, { 1 << 3, "REALTIME Freezer" }, { 1 << 4, "BOOTTIME Freezer" }), REC->expires
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/android_fs/android_fs_dataread_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/android_fs/android_fs_dataread_end/format
new file mode 100644
index 000000000..5e10a343b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/android_fs/android_fs_dataread_end/format
@@ -0,0 +1,13 @@
+name: android_fs_dataread_end
+ID: 330
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:ino_t ino; offset:8; size:8; signed:0;
+ field:loff_t offset; offset:16; size:8; signed:1;
+ field:int bytes; offset:24; size:4; signed:1;
+
+print fmt: "ino %lu, offset %llu, bytes %d", (unsigned long) REC->ino, REC->offset, REC->bytes
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/android_fs/android_fs_dataread_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/android_fs/android_fs_dataread_start/format
new file mode 100644
index 000000000..58d69b20f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/android_fs/android_fs_dataread_start/format
@@ -0,0 +1,17 @@
+name: android_fs_dataread_start
+ID: 331
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] pathbuf; offset:8; size:4; signed:0;
+ field:loff_t offset; offset:16; size:8; signed:1;
+ field:int bytes; offset:24; size:4; signed:1;
+ field:loff_t i_size; offset:32; size:8; signed:1;
+ field:__data_loc char[] cmdline; offset:40; size:4; signed:0;
+ field:pid_t pid; offset:44; size:4; signed:1;
+ field:ino_t ino; offset:48; size:8; signed:0;
+
+print fmt: "entry_name %s, offset %llu, bytes %d, cmdline %s, pid %d, i_size %llu, ino %lu", __get_str(pathbuf), REC->offset, REC->bytes, __get_str(cmdline), REC->pid, REC->i_size, (unsigned long) REC->ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/android_fs/android_fs_datawrite_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/android_fs/android_fs_datawrite_end/format
new file mode 100644
index 000000000..0dcdc56e1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/android_fs/android_fs_datawrite_end/format
@@ -0,0 +1,13 @@
+name: android_fs_datawrite_end
+ID: 332
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:ino_t ino; offset:8; size:8; signed:0;
+ field:loff_t offset; offset:16; size:8; signed:1;
+ field:int bytes; offset:24; size:4; signed:1;
+
+print fmt: "ino %lu, offset %llu, bytes %d", (unsigned long) REC->ino, REC->offset, REC->bytes
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/android_fs/android_fs_datawrite_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/android_fs/android_fs_datawrite_start/format
new file mode 100644
index 000000000..208ecfbb6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/android_fs/android_fs_datawrite_start/format
@@ -0,0 +1,17 @@
+name: android_fs_datawrite_start
+ID: 333
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] pathbuf; offset:8; size:4; signed:0;
+ field:loff_t offset; offset:16; size:8; signed:1;
+ field:int bytes; offset:24; size:4; signed:1;
+ field:loff_t i_size; offset:32; size:8; signed:1;
+ field:__data_loc char[] cmdline; offset:40; size:4; signed:0;
+ field:pid_t pid; offset:44; size:4; signed:1;
+ field:ino_t ino; offset:48; size:8; signed:0;
+
+print fmt: "entry_name %s, offset %llu, bytes %d, cmdline %s, pid %d, i_size %llu, ino %lu", __get_str(pathbuf), REC->offset, REC->bytes, __get_str(cmdline), REC->pid, REC->i_size, (unsigned long) REC->ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_bias_level_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_bias_level_done/format
new file mode 100644
index 000000000..4b838b97b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_bias_level_done/format
@@ -0,0 +1,12 @@
+name: snd_soc_bias_level_done
+ID: 905
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:int val; offset:12; size:4; signed:1;
+
+print fmt: "card=%s val=%d", __get_str(name), (int)REC->val
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_bias_level_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_bias_level_start/format
new file mode 100644
index 000000000..d28cf5417
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_bias_level_start/format
@@ -0,0 +1,12 @@
+name: snd_soc_bias_level_start
+ID: 906
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:int val; offset:12; size:4; signed:1;
+
+print fmt: "card=%s val=%d", __get_str(name), (int)REC->val
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_connected/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_connected/format
new file mode 100644
index 000000000..ebd833966
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_connected/format
@@ -0,0 +1,12 @@
+name: snd_soc_dapm_connected
+ID: 907
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int paths; offset:8; size:4; signed:1;
+ field:int stream; offset:12; size:4; signed:1;
+
+print fmt: "%s: found %d paths", REC->stream ? "capture" : "playback", REC->paths
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_done/format
new file mode 100644
index 000000000..f0ce6dff7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_done/format
@@ -0,0 +1,11 @@
+name: snd_soc_dapm_done
+ID: 908
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "card=%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_path/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_path/format
new file mode 100644
index 000000000..53626f99c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_path/format
@@ -0,0 +1,16 @@
+name: snd_soc_dapm_path
+ID: 909
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] wname; offset:8; size:4; signed:0;
+ field:__data_loc char[] pname; offset:12; size:4; signed:0;
+ field:__data_loc char[] pnname; offset:16; size:4; signed:0;
+ field:int path_node; offset:20; size:4; signed:1;
+ field:int path_connect; offset:24; size:4; signed:1;
+ field:int path_dir; offset:28; size:4; signed:1;
+
+print fmt: "%c%s %s %s %s %s", (int) REC->path_node && (int) REC->path_connect ? '*' : ' ', __get_str(wname), (((REC->path_dir) == SND_SOC_DAPM_DIR_OUT) ? "->" : "<-"), __get_str(pname), (((REC->path_dir) == SND_SOC_DAPM_DIR_OUT) ? "->" : "<-"), __get_str(pnname)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_start/format
new file mode 100644
index 000000000..3931848ff
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_start/format
@@ -0,0 +1,11 @@
+name: snd_soc_dapm_start
+ID: 910
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "card=%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_walk_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_walk_done/format
new file mode 100644
index 000000000..c4169e77c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_walk_done/format
@@ -0,0 +1,14 @@
+name: snd_soc_dapm_walk_done
+ID: 911
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:int power_checks; offset:12; size:4; signed:1;
+ field:int path_checks; offset:16; size:4; signed:1;
+ field:int neighbour_checks; offset:20; size:4; signed:1;
+
+print fmt: "%s: checks %d power, %d path, %d neighbour", __get_str(name), (int)REC->power_checks, (int)REC->path_checks, (int)REC->neighbour_checks
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_widget_event_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_widget_event_done/format
new file mode 100644
index 000000000..3e81d1d30
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_widget_event_done/format
@@ -0,0 +1,12 @@
+name: snd_soc_dapm_widget_event_done
+ID: 912
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:int val; offset:12; size:4; signed:1;
+
+print fmt: "widget=%s val=%d", __get_str(name), (int)REC->val
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_widget_event_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_widget_event_start/format
new file mode 100644
index 000000000..e883e09b8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_widget_event_start/format
@@ -0,0 +1,12 @@
+name: snd_soc_dapm_widget_event_start
+ID: 913
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:int val; offset:12; size:4; signed:1;
+
+print fmt: "widget=%s val=%d", __get_str(name), (int)REC->val
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_widget_power/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_widget_power/format
new file mode 100644
index 000000000..7dec55caf
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_dapm_widget_power/format
@@ -0,0 +1,12 @@
+name: snd_soc_dapm_widget_power
+ID: 914
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:int val; offset:12; size:4; signed:1;
+
+print fmt: "widget=%s val=%d", __get_str(name), (int)REC->val
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_jack_irq/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_jack_irq/format
new file mode 100644
index 000000000..7d6d07c61
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_jack_irq/format
@@ -0,0 +1,11 @@
+name: snd_soc_jack_irq
+ID: 915
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_jack_notify/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_jack_notify/format
new file mode 100644
index 000000000..1728997e5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_jack_notify/format
@@ -0,0 +1,12 @@
+name: snd_soc_jack_notify
+ID: 916
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:int val; offset:12; size:4; signed:1;
+
+print fmt: "jack=%s %x", __get_str(name), (int)REC->val
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_jack_report/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_jack_report/format
new file mode 100644
index 000000000..f08239f90
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/asoc/snd_soc_jack_report/format
@@ -0,0 +1,13 @@
+name: snd_soc_jack_report
+ID: 917
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:int mask; offset:12; size:4; signed:1;
+ field:int val; offset:16; size:4; signed:1;
+
+print fmt: "jack=%s %x/%x", __get_str(name), (int)REC->val, (int)REC->mask
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/avc/selinux_audited/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/avc/selinux_audited/format
new file mode 100644
index 000000000..8d6eabb5d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/avc/selinux_audited/format
@@ -0,0 +1,17 @@
+name: selinux_audited
+ID: 584
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 requested; offset:8; size:4; signed:0;
+ field:u32 denied; offset:12; size:4; signed:0;
+ field:u32 audited; offset:16; size:4; signed:0;
+ field:int result; offset:20; size:4; signed:1;
+ field:__data_loc char[] scontext; offset:24; size:4; signed:0;
+ field:__data_loc char[] tcontext; offset:28; size:4; signed:0;
+ field:__data_loc char[] tclass; offset:32; size:4; signed:0;
+
+print fmt: "requested=0x%x denied=0x%x audited=0x%x result=%d scontext=%s tcontext=%s tclass=%s", REC->requested, REC->denied, REC->audited, REC->result, __get_str(scontext), __get_str(tcontext), __get_str(tclass)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_alloc_lru_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_alloc_lru_end/format
new file mode 100644
index 000000000..68e40584d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_alloc_lru_end/format
@@ -0,0 +1,12 @@
+name: binder_alloc_lru_end
+ID: 871
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int proc; offset:8; size:4; signed:1;
+ field:size_t page_index; offset:16; size:8; signed:0;
+
+print fmt: "proc=%d page_index=%zu", REC->proc, REC->page_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_alloc_lru_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_alloc_lru_start/format
new file mode 100644
index 000000000..d3da7ec30
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_alloc_lru_start/format
@@ -0,0 +1,12 @@
+name: binder_alloc_lru_start
+ID: 872
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int proc; offset:8; size:4; signed:1;
+ field:size_t page_index; offset:16; size:8; signed:0;
+
+print fmt: "proc=%d page_index=%zu", REC->proc, REC->page_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_alloc_page_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_alloc_page_end/format
new file mode 100644
index 000000000..1e82de1a6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_alloc_page_end/format
@@ -0,0 +1,12 @@
+name: binder_alloc_page_end
+ID: 873
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int proc; offset:8; size:4; signed:1;
+ field:size_t page_index; offset:16; size:8; signed:0;
+
+print fmt: "proc=%d page_index=%zu", REC->proc, REC->page_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_alloc_page_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_alloc_page_start/format
new file mode 100644
index 000000000..1e5f9cd11
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_alloc_page_start/format
@@ -0,0 +1,12 @@
+name: binder_alloc_page_start
+ID: 874
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int proc; offset:8; size:4; signed:1;
+ field:size_t page_index; offset:16; size:8; signed:0;
+
+print fmt: "proc=%d page_index=%zu", REC->proc, REC->page_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_command/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_command/format
new file mode 100644
index 000000000..0151f46ec
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_command/format
@@ -0,0 +1,11 @@
+name: binder_command
+ID: 875
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:uint32_t cmd; offset:8; size:4; signed:0;
+
+print fmt: "cmd=0x%x %s", REC->cmd, (((REC->cmd) >> 0) & ((1 << 8)-1)) < (sizeof(binder_command_strings) / sizeof((binder_command_strings)[0]) + ((int)(sizeof(struct { int:(-!!(__builtin_types_compatible_p(typeof((binder_command_strings)), typeof(&(binder_command_strings)[0])))); })))) ? binder_command_strings[(((REC->cmd) >> 0) & ((1 << 8)-1))] : "unknown"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_free_lru_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_free_lru_end/format
new file mode 100644
index 000000000..814482f53
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_free_lru_end/format
@@ -0,0 +1,12 @@
+name: binder_free_lru_end
+ID: 876
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int proc; offset:8; size:4; signed:1;
+ field:size_t page_index; offset:16; size:8; signed:0;
+
+print fmt: "proc=%d page_index=%zu", REC->proc, REC->page_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_free_lru_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_free_lru_start/format
new file mode 100644
index 000000000..2dc323f51
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_free_lru_start/format
@@ -0,0 +1,12 @@
+name: binder_free_lru_start
+ID: 877
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int proc; offset:8; size:4; signed:1;
+ field:size_t page_index; offset:16; size:8; signed:0;
+
+print fmt: "proc=%d page_index=%zu", REC->proc, REC->page_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_ioctl/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_ioctl/format
new file mode 100644
index 000000000..d745dcb52
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_ioctl/format
@@ -0,0 +1,12 @@
+name: binder_ioctl
+ID: 878
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int cmd; offset:8; size:4; signed:0;
+ field:unsigned long arg; offset:16; size:8; signed:0;
+
+print fmt: "cmd=0x%x arg=0x%lx", REC->cmd, REC->arg
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_ioctl_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_ioctl_done/format
new file mode 100644
index 000000000..202f06008
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_ioctl_done/format
@@ -0,0 +1,11 @@
+name: binder_ioctl_done
+ID: 879
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ret; offset:8; size:4; signed:1;
+
+print fmt: "ret=%d", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_lock/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_lock/format
new file mode 100644
index 000000000..0c1b2c288
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_lock/format
@@ -0,0 +1,11 @@
+name: binder_lock
+ID: 880
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * tag; offset:8; size:8; signed:0;
+
+print fmt: "tag=%s", REC->tag
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_locked/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_locked/format
new file mode 100644
index 000000000..757cd6cf8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_locked/format
@@ -0,0 +1,11 @@
+name: binder_locked
+ID: 881
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * tag; offset:8; size:8; signed:0;
+
+print fmt: "tag=%s", REC->tag
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_read_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_read_done/format
new file mode 100644
index 000000000..8d574c303
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_read_done/format
@@ -0,0 +1,11 @@
+name: binder_read_done
+ID: 882
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ret; offset:8; size:4; signed:1;
+
+print fmt: "ret=%d", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_return/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_return/format
new file mode 100644
index 000000000..968e0a80e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_return/format
@@ -0,0 +1,11 @@
+name: binder_return
+ID: 883
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:uint32_t cmd; offset:8; size:4; signed:0;
+
+print fmt: "cmd=0x%x %s", REC->cmd, (((REC->cmd) >> 0) & ((1 << 8)-1)) < (sizeof(binder_return_strings) / sizeof((binder_return_strings)[0]) + ((int)(sizeof(struct { int:(-!!(__builtin_types_compatible_p(typeof((binder_return_strings)), typeof(&(binder_return_strings)[0])))); })))) ? binder_return_strings[(((REC->cmd) >> 0) & ((1 << 8)-1))] : "unknown"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_set_priority/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_set_priority/format
new file mode 100644
index 000000000..13c918ba6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_set_priority/format
@@ -0,0 +1,15 @@
+name: binder_set_priority
+ID: 884
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int proc; offset:8; size:4; signed:1;
+ field:int thread; offset:12; size:4; signed:1;
+ field:unsigned int old_prio; offset:16; size:4; signed:0;
+ field:unsigned int new_prio; offset:20; size:4; signed:0;
+ field:unsigned int desired_prio; offset:24; size:4; signed:0;
+
+print fmt: "proc=%d thread=%d old=%d => new=%d desired=%d", REC->proc, REC->thread, REC->old_prio, REC->new_prio, REC->desired_prio
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction/format
new file mode 100644
index 000000000..95ef601d1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction/format
@@ -0,0 +1,17 @@
+name: binder_transaction
+ID: 885
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int debug_id; offset:8; size:4; signed:1;
+ field:int target_node; offset:12; size:4; signed:1;
+ field:int to_proc; offset:16; size:4; signed:1;
+ field:int to_thread; offset:20; size:4; signed:1;
+ field:int reply; offset:24; size:4; signed:1;
+ field:unsigned int code; offset:28; size:4; signed:0;
+ field:unsigned int flags; offset:32; size:4; signed:0;
+
+print fmt: "transaction=%d dest_node=%d dest_proc=%d dest_thread=%d reply=%d flags=0x%x code=0x%x", REC->debug_id, REC->target_node, REC->to_proc, REC->to_thread, REC->reply, REC->flags, REC->code
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_alloc_buf/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_alloc_buf/format
new file mode 100644
index 000000000..39d60683f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_alloc_buf/format
@@ -0,0 +1,14 @@
+name: binder_transaction_alloc_buf
+ID: 886
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int debug_id; offset:8; size:4; signed:1;
+ field:size_t data_size; offset:16; size:8; signed:0;
+ field:size_t offsets_size; offset:24; size:8; signed:0;
+ field:size_t extra_buffers_size; offset:32; size:8; signed:0;
+
+print fmt: "transaction=%d data_size=%zd offsets_size=%zd extra_buffers_size=%zd", REC->debug_id, REC->data_size, REC->offsets_size, REC->extra_buffers_size
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_buffer_release/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_buffer_release/format
new file mode 100644
index 000000000..56f455e25
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_buffer_release/format
@@ -0,0 +1,14 @@
+name: binder_transaction_buffer_release
+ID: 887
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int debug_id; offset:8; size:4; signed:1;
+ field:size_t data_size; offset:16; size:8; signed:0;
+ field:size_t offsets_size; offset:24; size:8; signed:0;
+ field:size_t extra_buffers_size; offset:32; size:8; signed:0;
+
+print fmt: "transaction=%d data_size=%zd offsets_size=%zd extra_buffers_size=%zd", REC->debug_id, REC->data_size, REC->offsets_size, REC->extra_buffers_size
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_failed_buffer_release/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_failed_buffer_release/format
new file mode 100644
index 000000000..d0f98b5f9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_failed_buffer_release/format
@@ -0,0 +1,14 @@
+name: binder_transaction_failed_buffer_release
+ID: 888
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int debug_id; offset:8; size:4; signed:1;
+ field:size_t data_size; offset:16; size:8; signed:0;
+ field:size_t offsets_size; offset:24; size:8; signed:0;
+ field:size_t extra_buffers_size; offset:32; size:8; signed:0;
+
+print fmt: "transaction=%d data_size=%zd offsets_size=%zd extra_buffers_size=%zd", REC->debug_id, REC->data_size, REC->offsets_size, REC->extra_buffers_size
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_fd_recv/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_fd_recv/format
new file mode 100644
index 000000000..a066ff11f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_fd_recv/format
@@ -0,0 +1,13 @@
+name: binder_transaction_fd_recv
+ID: 889
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int debug_id; offset:8; size:4; signed:1;
+ field:int fd; offset:12; size:4; signed:1;
+ field:size_t offset; offset:16; size:8; signed:0;
+
+print fmt: "transaction=%d dest_fd=%d offset=%zu", REC->debug_id, REC->fd, REC->offset
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_fd_send/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_fd_send/format
new file mode 100644
index 000000000..9bbd3f966
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_fd_send/format
@@ -0,0 +1,13 @@
+name: binder_transaction_fd_send
+ID: 890
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int debug_id; offset:8; size:4; signed:1;
+ field:int fd; offset:12; size:4; signed:1;
+ field:size_t offset; offset:16; size:8; signed:0;
+
+print fmt: "transaction=%d src_fd=%d offset=%zu", REC->debug_id, REC->fd, REC->offset
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_node_to_ref/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_node_to_ref/format
new file mode 100644
index 000000000..23c24a59b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_node_to_ref/format
@@ -0,0 +1,15 @@
+name: binder_transaction_node_to_ref
+ID: 891
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int debug_id; offset:8; size:4; signed:1;
+ field:int node_debug_id; offset:12; size:4; signed:1;
+ field:binder_uintptr_t node_ptr; offset:16; size:8; signed:0;
+ field:int ref_debug_id; offset:24; size:4; signed:1;
+ field:uint32_t ref_desc; offset:28; size:4; signed:0;
+
+print fmt: "transaction=%d node=%d src_ptr=0x%016llx ==> dest_ref=%d dest_desc=%d", REC->debug_id, REC->node_debug_id, (u64)REC->node_ptr, REC->ref_debug_id, REC->ref_desc
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_received/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_received/format
new file mode 100644
index 000000000..a0532a986
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_received/format
@@ -0,0 +1,11 @@
+name: binder_transaction_received
+ID: 892
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int debug_id; offset:8; size:4; signed:1;
+
+print fmt: "transaction=%d", REC->debug_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_ref_to_node/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_ref_to_node/format
new file mode 100644
index 000000000..4a234cdae
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_ref_to_node/format
@@ -0,0 +1,15 @@
+name: binder_transaction_ref_to_node
+ID: 893
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int debug_id; offset:8; size:4; signed:1;
+ field:int ref_debug_id; offset:12; size:4; signed:1;
+ field:uint32_t ref_desc; offset:16; size:4; signed:0;
+ field:int node_debug_id; offset:20; size:4; signed:1;
+ field:binder_uintptr_t node_ptr; offset:24; size:8; signed:0;
+
+print fmt: "transaction=%d node=%d src_ref=%d src_desc=%d ==> dest_ptr=0x%016llx", REC->debug_id, REC->node_debug_id, REC->ref_debug_id, REC->ref_desc, (u64)REC->node_ptr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_ref_to_ref/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_ref_to_ref/format
new file mode 100644
index 000000000..2a82ec6ac
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_transaction_ref_to_ref/format
@@ -0,0 +1,16 @@
+name: binder_transaction_ref_to_ref
+ID: 894
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int debug_id; offset:8; size:4; signed:1;
+ field:int node_debug_id; offset:12; size:4; signed:1;
+ field:int src_ref_debug_id; offset:16; size:4; signed:1;
+ field:uint32_t src_ref_desc; offset:20; size:4; signed:0;
+ field:int dest_ref_debug_id; offset:24; size:4; signed:1;
+ field:uint32_t dest_ref_desc; offset:28; size:4; signed:0;
+
+print fmt: "transaction=%d node=%d src_ref=%d src_desc=%d ==> dest_ref=%d dest_desc=%d", REC->debug_id, REC->node_debug_id, REC->src_ref_debug_id, REC->src_ref_desc, REC->dest_ref_debug_id, REC->dest_ref_desc
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_unlock/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_unlock/format
new file mode 100644
index 000000000..0d0db8446
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_unlock/format
@@ -0,0 +1,11 @@
+name: binder_unlock
+ID: 895
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * tag; offset:8; size:8; signed:0;
+
+print fmt: "tag=%s", REC->tag
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_unmap_kernel_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_unmap_kernel_end/format
new file mode 100644
index 000000000..059b436c0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_unmap_kernel_end/format
@@ -0,0 +1,12 @@
+name: binder_unmap_kernel_end
+ID: 896
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int proc; offset:8; size:4; signed:1;
+ field:size_t page_index; offset:16; size:8; signed:0;
+
+print fmt: "proc=%d page_index=%zu", REC->proc, REC->page_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_unmap_kernel_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_unmap_kernel_start/format
new file mode 100644
index 000000000..0627165dd
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_unmap_kernel_start/format
@@ -0,0 +1,12 @@
+name: binder_unmap_kernel_start
+ID: 897
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int proc; offset:8; size:4; signed:1;
+ field:size_t page_index; offset:16; size:8; signed:0;
+
+print fmt: "proc=%d page_index=%zu", REC->proc, REC->page_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_unmap_user_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_unmap_user_end/format
new file mode 100644
index 000000000..602e3533f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_unmap_user_end/format
@@ -0,0 +1,12 @@
+name: binder_unmap_user_end
+ID: 898
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int proc; offset:8; size:4; signed:1;
+ field:size_t page_index; offset:16; size:8; signed:0;
+
+print fmt: "proc=%d page_index=%zu", REC->proc, REC->page_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_unmap_user_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_unmap_user_start/format
new file mode 100644
index 000000000..361e0ccb5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_unmap_user_start/format
@@ -0,0 +1,12 @@
+name: binder_unmap_user_start
+ID: 899
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int proc; offset:8; size:4; signed:1;
+ field:size_t page_index; offset:16; size:8; signed:0;
+
+print fmt: "proc=%d page_index=%zu", REC->proc, REC->page_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_update_page_range/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_update_page_range/format
new file mode 100644
index 000000000..40cb81450
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_update_page_range/format
@@ -0,0 +1,14 @@
+name: binder_update_page_range
+ID: 900
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int proc; offset:8; size:4; signed:1;
+ field:bool allocate; offset:12; size:1; signed:0;
+ field:size_t offset; offset:16; size:8; signed:0;
+ field:size_t size; offset:24; size:8; signed:0;
+
+print fmt: "proc=%d allocate=%d offset=%zu size=%zu", REC->proc, REC->allocate, REC->offset, REC->size
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_wait_for_work/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_wait_for_work/format
new file mode 100644
index 000000000..47430be3b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_wait_for_work/format
@@ -0,0 +1,13 @@
+name: binder_wait_for_work
+ID: 901
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:bool proc_work; offset:8; size:1; signed:0;
+ field:bool transaction_stack; offset:9; size:1; signed:0;
+ field:bool thread_todo; offset:10; size:1; signed:0;
+
+print fmt: "proc_work=%d transaction_stack=%d thread_todo=%d", REC->proc_work, REC->transaction_stack, REC->thread_todo
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_write_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_write_done/format
new file mode 100644
index 000000000..566b62d41
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/binder/binder_write_done/format
@@ -0,0 +1,11 @@
+name: binder_write_done
+ID: 902
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ret; offset:8; size:4; signed:1;
+
+print fmt: "ret=%d", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_backmerge/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_backmerge/format
new file mode 100644
index 000000000..55d276bba
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_backmerge/format
@@ -0,0 +1,15 @@
+name: block_bio_backmerge
+ID: 585
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:sector_t sector; offset:16; size:8; signed:0;
+ field:unsigned int nr_sector; offset:24; size:4; signed:0;
+ field:char rwbs[8]; offset:28; size:8; signed:0;
+ field:char comm[16]; offset:36; size:16; signed:0;
+
+print fmt: "%d,%d %s %llu + %u [%s]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, (unsigned long long)REC->sector, REC->nr_sector, REC->comm
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_bounce/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_bounce/format
new file mode 100644
index 000000000..9ed824fc8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_bounce/format
@@ -0,0 +1,15 @@
+name: block_bio_bounce
+ID: 586
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:sector_t sector; offset:16; size:8; signed:0;
+ field:unsigned int nr_sector; offset:24; size:4; signed:0;
+ field:char rwbs[8]; offset:28; size:8; signed:0;
+ field:char comm[16]; offset:36; size:16; signed:0;
+
+print fmt: "%d,%d %s %llu + %u [%s]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, (unsigned long long)REC->sector, REC->nr_sector, REC->comm
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_complete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_complete/format
new file mode 100644
index 000000000..79c3e778c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_complete/format
@@ -0,0 +1,15 @@
+name: block_bio_complete
+ID: 587
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:sector_t sector; offset:16; size:8; signed:0;
+ field:unsigned nr_sector; offset:24; size:4; signed:0;
+ field:int error; offset:28; size:4; signed:1;
+ field:char rwbs[8]; offset:32; size:8; signed:0;
+
+print fmt: "%d,%d %s %llu + %u [%d]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, (unsigned long long)REC->sector, REC->nr_sector, REC->error
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_frontmerge/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_frontmerge/format
new file mode 100644
index 000000000..35c0c331b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_frontmerge/format
@@ -0,0 +1,15 @@
+name: block_bio_frontmerge
+ID: 588
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:sector_t sector; offset:16; size:8; signed:0;
+ field:unsigned int nr_sector; offset:24; size:4; signed:0;
+ field:char rwbs[8]; offset:28; size:8; signed:0;
+ field:char comm[16]; offset:36; size:16; signed:0;
+
+print fmt: "%d,%d %s %llu + %u [%s]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, (unsigned long long)REC->sector, REC->nr_sector, REC->comm
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_queue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_queue/format
new file mode 100644
index 000000000..8fa0c86ce
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_queue/format
@@ -0,0 +1,15 @@
+name: block_bio_queue
+ID: 589
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:sector_t sector; offset:16; size:8; signed:0;
+ field:unsigned int nr_sector; offset:24; size:4; signed:0;
+ field:char rwbs[8]; offset:28; size:8; signed:0;
+ field:char comm[16]; offset:36; size:16; signed:0;
+
+print fmt: "%d,%d %s %llu + %u [%s]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, (unsigned long long)REC->sector, REC->nr_sector, REC->comm
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_remap/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_remap/format
new file mode 100644
index 000000000..813d9fd54
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_bio_remap/format
@@ -0,0 +1,16 @@
+name: block_bio_remap
+ID: 590
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:sector_t sector; offset:16; size:8; signed:0;
+ field:unsigned int nr_sector; offset:24; size:4; signed:0;
+ field:dev_t old_dev; offset:28; size:4; signed:0;
+ field:sector_t old_sector; offset:32; size:8; signed:0;
+ field:char rwbs[8]; offset:40; size:8; signed:0;
+
+print fmt: "%d,%d %s %llu + %u <- (%d,%d) %llu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, (unsigned long long)REC->sector, REC->nr_sector, ((unsigned int) ((REC->old_dev) >> 20)), ((unsigned int) ((REC->old_dev) & ((1U << 20) - 1))), (unsigned long long)REC->old_sector
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_dirty_buffer/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_dirty_buffer/format
new file mode 100644
index 000000000..9414322bb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_dirty_buffer/format
@@ -0,0 +1,13 @@
+name: block_dirty_buffer
+ID: 591
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:sector_t sector; offset:16; size:8; signed:0;
+ field:size_t size; offset:24; size:8; signed:0;
+
+print fmt: "%d,%d sector=%llu size=%zu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long long)REC->sector, REC->size
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_getrq/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_getrq/format
new file mode 100644
index 000000000..4022f933d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_getrq/format
@@ -0,0 +1,15 @@
+name: block_getrq
+ID: 592
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:sector_t sector; offset:16; size:8; signed:0;
+ field:unsigned int nr_sector; offset:24; size:4; signed:0;
+ field:char rwbs[8]; offset:28; size:8; signed:0;
+ field:char comm[16]; offset:36; size:16; signed:0;
+
+print fmt: "%d,%d %s %llu + %u [%s]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, (unsigned long long)REC->sector, REC->nr_sector, REC->comm
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_plug/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_plug/format
new file mode 100644
index 000000000..fdcf5f1fa
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_plug/format
@@ -0,0 +1,11 @@
+name: block_plug
+ID: 593
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+
+print fmt: "[%s]", REC->comm
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_complete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_complete/format
new file mode 100644
index 000000000..c846b5c07
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_complete/format
@@ -0,0 +1,16 @@
+name: block_rq_complete
+ID: 594
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:sector_t sector; offset:16; size:8; signed:0;
+ field:unsigned int nr_sector; offset:24; size:4; signed:0;
+ field:int error; offset:28; size:4; signed:1;
+ field:char rwbs[8]; offset:32; size:8; signed:0;
+ field:__data_loc char[] cmd; offset:40; size:4; signed:0;
+
+print fmt: "%d,%d %s (%s) %llu + %u [%d]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, __get_str(cmd), (unsigned long long)REC->sector, REC->nr_sector, REC->error
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_insert/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_insert/format
new file mode 100644
index 000000000..5b5a0fb90
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_insert/format
@@ -0,0 +1,17 @@
+name: block_rq_insert
+ID: 595
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:sector_t sector; offset:16; size:8; signed:0;
+ field:unsigned int nr_sector; offset:24; size:4; signed:0;
+ field:unsigned int bytes; offset:28; size:4; signed:0;
+ field:char rwbs[8]; offset:32; size:8; signed:0;
+ field:char comm[16]; offset:40; size:16; signed:0;
+ field:__data_loc char[] cmd; offset:56; size:4; signed:0;
+
+print fmt: "%d,%d %s %u (%s) %llu + %u [%s]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, REC->bytes, __get_str(cmd), (unsigned long long)REC->sector, REC->nr_sector, REC->comm
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_issue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_issue/format
new file mode 100644
index 000000000..e0db503d7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_issue/format
@@ -0,0 +1,17 @@
+name: block_rq_issue
+ID: 596
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:sector_t sector; offset:16; size:8; signed:0;
+ field:unsigned int nr_sector; offset:24; size:4; signed:0;
+ field:unsigned int bytes; offset:28; size:4; signed:0;
+ field:char rwbs[8]; offset:32; size:8; signed:0;
+ field:char comm[16]; offset:40; size:16; signed:0;
+ field:__data_loc char[] cmd; offset:56; size:4; signed:0;
+
+print fmt: "%d,%d %s %u (%s) %llu + %u [%s]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, REC->bytes, __get_str(cmd), (unsigned long long)REC->sector, REC->nr_sector, REC->comm
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_merge/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_merge/format
new file mode 100644
index 000000000..cfff11034
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_merge/format
@@ -0,0 +1,17 @@
+name: block_rq_merge
+ID: 597
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:sector_t sector; offset:16; size:8; signed:0;
+ field:unsigned int nr_sector; offset:24; size:4; signed:0;
+ field:unsigned int bytes; offset:28; size:4; signed:0;
+ field:char rwbs[8]; offset:32; size:8; signed:0;
+ field:char comm[16]; offset:40; size:16; signed:0;
+ field:__data_loc char[] cmd; offset:56; size:4; signed:0;
+
+print fmt: "%d,%d %s %u (%s) %llu + %u [%s]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, REC->bytes, __get_str(cmd), (unsigned long long)REC->sector, REC->nr_sector, REC->comm
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_remap/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_remap/format
new file mode 100644
index 000000000..e1717850d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_remap/format
@@ -0,0 +1,17 @@
+name: block_rq_remap
+ID: 598
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:sector_t sector; offset:16; size:8; signed:0;
+ field:unsigned int nr_sector; offset:24; size:4; signed:0;
+ field:dev_t old_dev; offset:28; size:4; signed:0;
+ field:sector_t old_sector; offset:32; size:8; signed:0;
+ field:unsigned int nr_bios; offset:40; size:4; signed:0;
+ field:char rwbs[8]; offset:44; size:8; signed:0;
+
+print fmt: "%d,%d %s %llu + %u <- (%d,%d) %llu %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, (unsigned long long)REC->sector, REC->nr_sector, ((unsigned int) ((REC->old_dev) >> 20)), ((unsigned int) ((REC->old_dev) & ((1U << 20) - 1))), (unsigned long long)REC->old_sector, REC->nr_bios
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_requeue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_requeue/format
new file mode 100644
index 000000000..954dcb8a6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_rq_requeue/format
@@ -0,0 +1,15 @@
+name: block_rq_requeue
+ID: 599
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:sector_t sector; offset:16; size:8; signed:0;
+ field:unsigned int nr_sector; offset:24; size:4; signed:0;
+ field:char rwbs[8]; offset:28; size:8; signed:0;
+ field:__data_loc char[] cmd; offset:36; size:4; signed:0;
+
+print fmt: "%d,%d %s (%s) %llu + %u [%d]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, __get_str(cmd), (unsigned long long)REC->sector, REC->nr_sector, 0
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_sleeprq/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_sleeprq/format
new file mode 100644
index 000000000..02cdab6a5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_sleeprq/format
@@ -0,0 +1,15 @@
+name: block_sleeprq
+ID: 600
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:sector_t sector; offset:16; size:8; signed:0;
+ field:unsigned int nr_sector; offset:24; size:4; signed:0;
+ field:char rwbs[8]; offset:28; size:8; signed:0;
+ field:char comm[16]; offset:36; size:16; signed:0;
+
+print fmt: "%d,%d %s %llu + %u [%s]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, (unsigned long long)REC->sector, REC->nr_sector, REC->comm
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_split/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_split/format
new file mode 100644
index 000000000..da3d05344
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_split/format
@@ -0,0 +1,15 @@
+name: block_split
+ID: 601
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:sector_t sector; offset:16; size:8; signed:0;
+ field:sector_t new_sector; offset:24; size:8; signed:0;
+ field:char rwbs[8]; offset:32; size:8; signed:0;
+ field:char comm[16]; offset:40; size:16; signed:0;
+
+print fmt: "%d,%d %s %llu / %llu [%s]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, (unsigned long long)REC->sector, (unsigned long long)REC->new_sector, REC->comm
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_touch_buffer/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_touch_buffer/format
new file mode 100644
index 000000000..6b38b9a04
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_touch_buffer/format
@@ -0,0 +1,13 @@
+name: block_touch_buffer
+ID: 602
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:sector_t sector; offset:16; size:8; signed:0;
+ field:size_t size; offset:24; size:8; signed:0;
+
+print fmt: "%d,%d sector=%llu size=%zu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long long)REC->sector, REC->size
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_unplug/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_unplug/format
new file mode 100644
index 000000000..ba38d3b51
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/block/block_unplug/format
@@ -0,0 +1,12 @@
+name: block_unplug
+ID: 603
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int nr_rq; offset:8; size:4; signed:1;
+ field:char comm[16]; offset:12; size:16; signed:0;
+
+print fmt: "[%s] %d", REC->comm, REC->nr_rq
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bpf_test_run/bpf_test_finish/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bpf_test_run/bpf_test_finish/format
new file mode 100644
index 000000000..4abd7e747
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bpf_test_run/bpf_test_finish/format
@@ -0,0 +1,11 @@
+name: bpf_test_finish
+ID: 971
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int err; offset:8; size:4; signed:1;
+
+print fmt: "bpf_test_finish with err=%d", REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bpf_trace/bpf_trace_printk/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bpf_trace/bpf_trace_printk/format
new file mode 100644
index 000000000..4166d9ff9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bpf_trace/bpf_trace_printk/format
@@ -0,0 +1,11 @@
+name: bpf_trace_printk
+ID: 168
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] bpf_string; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(bpf_string)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bridge/br_fdb_add/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bridge/br_fdb_add/format
new file mode 100644
index 000000000..0a61c5889
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bridge/br_fdb_add/format
@@ -0,0 +1,15 @@
+name: br_fdb_add
+ID: 918
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u8 ndm_flags; offset:8; size:1; signed:0;
+ field:__data_loc char[] dev; offset:12; size:4; signed:0;
+ field:unsigned char addr[6]; offset:16; size:6; signed:0;
+ field:u16 vid; offset:22; size:2; signed:0;
+ field:u16 nlh_flags; offset:24; size:2; signed:0;
+
+print fmt: "dev %s addr %02x:%02x:%02x:%02x:%02x:%02x vid %u nlh_flags %04x ndm_flags %02x", __get_str(dev), REC->addr[0], REC->addr[1], REC->addr[2], REC->addr[3], REC->addr[4], REC->addr[5], REC->vid, REC->nlh_flags, REC->ndm_flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bridge/br_fdb_external_learn_add/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bridge/br_fdb_external_learn_add/format
new file mode 100644
index 000000000..4b1fd10c1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bridge/br_fdb_external_learn_add/format
@@ -0,0 +1,14 @@
+name: br_fdb_external_learn_add
+ID: 919
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] br_dev; offset:8; size:4; signed:0;
+ field:__data_loc char[] dev; offset:12; size:4; signed:0;
+ field:unsigned char addr[6]; offset:16; size:6; signed:0;
+ field:u16 vid; offset:22; size:2; signed:0;
+
+print fmt: "br_dev %s port %s addr %02x:%02x:%02x:%02x:%02x:%02x vid %u", __get_str(br_dev), __get_str(dev), REC->addr[0], REC->addr[1], REC->addr[2], REC->addr[3], REC->addr[4], REC->addr[5], REC->vid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bridge/br_fdb_update/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bridge/br_fdb_update/format
new file mode 100644
index 000000000..103300345
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bridge/br_fdb_update/format
@@ -0,0 +1,15 @@
+name: br_fdb_update
+ID: 920
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] br_dev; offset:8; size:4; signed:0;
+ field:__data_loc char[] dev; offset:12; size:4; signed:0;
+ field:unsigned char addr[6]; offset:16; size:6; signed:0;
+ field:u16 vid; offset:22; size:2; signed:0;
+ field:unsigned long flags; offset:24; size:8; signed:0;
+
+print fmt: "br_dev %s source %s addr %02x:%02x:%02x:%02x:%02x:%02x vid %u flags 0x%lx", __get_str(br_dev), __get_str(dev), REC->addr[0], REC->addr[1], REC->addr[2], REC->addr[3], REC->addr[4], REC->addr[5], REC->vid, REC->flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bridge/fdb_delete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bridge/fdb_delete/format
new file mode 100644
index 000000000..b0d47441d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/bridge/fdb_delete/format
@@ -0,0 +1,14 @@
+name: fdb_delete
+ID: 922
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] br_dev; offset:8; size:4; signed:0;
+ field:__data_loc char[] dev; offset:12; size:4; signed:0;
+ field:unsigned char addr[6]; offset:16; size:6; signed:0;
+ field:u16 vid; offset:22; size:2; signed:0;
+
+print fmt: "br_dev %s dev %s addr %02x:%02x:%02x:%02x:%02x:%02x vid %u", __get_str(br_dev), __get_str(dev), REC->addr[0], REC->addr[1], REC->addr[2], REC->addr[3], REC->addr[4], REC->addr[5], REC->vid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_cac_event/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_cac_event/format
new file mode 100644
index 000000000..ccc882e20
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_cac_event/format
@@ -0,0 +1,13 @@
+name: cfg80211_cac_event
+ID: 1247
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:enum nl80211_radar_event evt; offset:28; size:4; signed:0;
+
+print fmt: "netdev:%s(%d), event: %d", REC->name, REC->ifindex, REC->evt
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ch_switch_notify/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ch_switch_notify/format
new file mode 100644
index 000000000..8bd478d3b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ch_switch_notify/format
@@ -0,0 +1,19 @@
+name: cfg80211_ch_switch_notify
+ID: 1248
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:enum nl80211_band band; offset:28; size:4; signed:0;
+ field:u32 control_freq; offset:32; size:4; signed:0;
+ field:u32 freq_offset; offset:36; size:4; signed:0;
+ field:u32 width; offset:40; size:4; signed:0;
+ field:u32 center_freq1; offset:44; size:4; signed:0;
+ field:u32 freq1_offset; offset:48; size:4; signed:0;
+ field:u32 center_freq2; offset:52; size:4; signed:0;
+
+print fmt: "netdev:%s(%d), band: %d, control freq: %u.%03u, width: %d, cf1: %u.%03u, cf2: %u", REC->name, REC->ifindex, REC->band, REC->control_freq, REC->freq_offset, REC->width, REC->center_freq1, REC->freq1_offset, REC->center_freq2
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ch_switch_started_notify/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ch_switch_started_notify/format
new file mode 100644
index 000000000..4510fcc8b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ch_switch_started_notify/format
@@ -0,0 +1,19 @@
+name: cfg80211_ch_switch_started_notify
+ID: 1249
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:enum nl80211_band band; offset:28; size:4; signed:0;
+ field:u32 control_freq; offset:32; size:4; signed:0;
+ field:u32 freq_offset; offset:36; size:4; signed:0;
+ field:u32 width; offset:40; size:4; signed:0;
+ field:u32 center_freq1; offset:44; size:4; signed:0;
+ field:u32 freq1_offset; offset:48; size:4; signed:0;
+ field:u32 center_freq2; offset:52; size:4; signed:0;
+
+print fmt: "netdev:%s(%d), band: %d, control freq: %u.%03u, width: %d, cf1: %u.%03u, cf2: %u", REC->name, REC->ifindex, REC->band, REC->control_freq, REC->freq_offset, REC->width, REC->center_freq1, REC->freq1_offset, REC->center_freq2
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_chandef_dfs_required/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_chandef_dfs_required/format
new file mode 100644
index 000000000..f5d6792eb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_chandef_dfs_required/format
@@ -0,0 +1,18 @@
+name: cfg80211_chandef_dfs_required
+ID: 1250
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_band band; offset:40; size:4; signed:0;
+ field:u32 control_freq; offset:44; size:4; signed:0;
+ field:u32 freq_offset; offset:48; size:4; signed:0;
+ field:u32 width; offset:52; size:4; signed:0;
+ field:u32 center_freq1; offset:56; size:4; signed:0;
+ field:u32 freq1_offset; offset:60; size:4; signed:0;
+ field:u32 center_freq2; offset:64; size:4; signed:0;
+
+print fmt: "%s, band: %d, control freq: %u.%03u, width: %d, cf1: %u.%03u, cf2: %u", REC->wiphy_name, REC->band, REC->control_freq, REC->freq_offset, REC->width, REC->center_freq1, REC->freq1_offset, REC->center_freq2
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_control_port_tx_status/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_control_port_tx_status/format
new file mode 100644
index 000000000..813e1a4e2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_control_port_tx_status/format
@@ -0,0 +1,13 @@
+name: cfg80211_control_port_tx_status
+ID: 1251
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 id; offset:8; size:4; signed:0;
+ field:u64 cookie; offset:16; size:8; signed:0;
+ field:bool ack; offset:24; size:1; signed:0;
+
+print fmt: "wdev(%u), cookie: %llu, ack: %s", (REC->id), REC->cookie, (REC->ack) ? "true" : "false"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_cqm_pktloss_notify/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_cqm_pktloss_notify/format
new file mode 100644
index 000000000..fa42110a3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_cqm_pktloss_notify/format
@@ -0,0 +1,14 @@
+name: cfg80211_cqm_pktloss_notify
+ID: 1252
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:u8 peer[6]; offset:28; size:6; signed:0;
+ field:u32 num_packets; offset:36; size:4; signed:0;
+
+print fmt: "netdev:%s(%d), peer: %pM, num of lost packets: %u", REC->name, REC->ifindex, (REC->peer), REC->num_packets
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_cqm_rssi_notify/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_cqm_rssi_notify/format
new file mode 100644
index 000000000..50a0ad7df
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_cqm_rssi_notify/format
@@ -0,0 +1,14 @@
+name: cfg80211_cqm_rssi_notify
+ID: 1253
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:enum nl80211_cqm_rssi_threshold_event rssi_event; offset:28; size:4; signed:0;
+ field:s32 rssi_level; offset:32; size:4; signed:1;
+
+print fmt: "netdev:%s(%d), rssi event: %d, level: %d", REC->name, REC->ifindex, REC->rssi_event, REC->rssi_level
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_del_sta/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_del_sta/format
new file mode 100644
index 000000000..f7d99bd77
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_del_sta/format
@@ -0,0 +1,13 @@
+name: cfg80211_del_sta
+ID: 1254
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:u8 macaddr[6]; offset:28; size:6; signed:0;
+
+print fmt: "netdev:%s(%d), mac: %pM", REC->name, REC->ifindex, (REC->macaddr)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ft_event/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ft_event/format
new file mode 100644
index 000000000..6bc695357
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ft_event/format
@@ -0,0 +1,16 @@
+name: cfg80211_ft_event
+ID: 1255
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:__data_loc u8[] ies; offset:60; size:4; signed:0;
+ field:u8 target_ap[6]; offset:64; size:6; signed:0;
+ field:__data_loc u8[] ric_ies; offset:72; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), target_ap: %pM", REC->wiphy_name, REC->name, REC->ifindex, (REC->target_ap)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_get_bss/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_get_bss/format
new file mode 100644
index 000000000..0a6454b6a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_get_bss/format
@@ -0,0 +1,18 @@
+name: cfg80211_get_bss
+ID: 1256
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_band band; offset:40; size:4; signed:0;
+ field:u32 center_freq; offset:44; size:4; signed:0;
+ field:u16 freq_offset; offset:48; size:2; signed:0;
+ field:u8 bssid[6]; offset:50; size:6; signed:0;
+ field:__data_loc u8[] ssid; offset:56; size:4; signed:0;
+ field:enum ieee80211_bss_type bss_type; offset:60; size:4; signed:0;
+ field:enum ieee80211_privacy privacy; offset:64; size:4; signed:0;
+
+print fmt: "%s, band: %d, freq: %u.%03u, %pM, buf: %#.2x, bss_type: %d, privacy: %d", REC->wiphy_name, REC->band, REC->center_freq, REC->freq_offset, (REC->bssid), ((u8 *)__get_dynamic_array(ssid))[0], REC->bss_type, REC->privacy
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_gtk_rekey_notify/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_gtk_rekey_notify/format
new file mode 100644
index 000000000..779a3c5f5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_gtk_rekey_notify/format
@@ -0,0 +1,13 @@
+name: cfg80211_gtk_rekey_notify
+ID: 1257
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:u8 macaddr[6]; offset:28; size:6; signed:0;
+
+print fmt: "netdev:%s(%d), mac: %pM", REC->name, REC->ifindex, (REC->macaddr)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ibss_joined/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ibss_joined/format
new file mode 100644
index 000000000..83452852d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ibss_joined/format
@@ -0,0 +1,16 @@
+name: cfg80211_ibss_joined
+ID: 1258
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:u8 bssid[6]; offset:28; size:6; signed:0;
+ field:enum nl80211_band band; offset:36; size:4; signed:0;
+ field:u32 center_freq; offset:40; size:4; signed:0;
+ field:u16 freq_offset; offset:44; size:2; signed:0;
+
+print fmt: "netdev:%s(%d), bssid: %pM, band: %d, freq: %u.%03u", REC->name, REC->ifindex, (REC->bssid), REC->band, REC->center_freq, REC->freq_offset
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_inform_bss_frame/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_inform_bss_frame/format
new file mode 100644
index 000000000..81d9cfca0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_inform_bss_frame/format
@@ -0,0 +1,20 @@
+name: cfg80211_inform_bss_frame
+ID: 1259
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_band band; offset:40; size:4; signed:0;
+ field:u32 center_freq; offset:44; size:4; signed:0;
+ field:u16 freq_offset; offset:48; size:2; signed:0;
+ field:enum nl80211_bss_scan_width scan_width; offset:52; size:4; signed:0;
+ field:__data_loc u8[] mgmt; offset:56; size:4; signed:0;
+ field:s32 signal; offset:60; size:4; signed:1;
+ field:u64 ts_boottime; offset:64; size:8; signed:0;
+ field:u64 parent_tsf; offset:72; size:8; signed:0;
+ field:u8 parent_bssid[6]; offset:80; size:6; signed:0;
+
+print fmt: "%s, band: %d, freq: %u.%03u(scan_width: %d) signal: %d, tsb:%llu, detect_tsf:%llu, tsf_bssid: %pM", REC->wiphy_name, REC->band, REC->center_freq, REC->freq_offset, REC->scan_width, REC->signal, (unsigned long long)REC->ts_boottime, (unsigned long long)REC->parent_tsf, (REC->parent_bssid)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_mgmt_tx_status/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_mgmt_tx_status/format
new file mode 100644
index 000000000..bf3636738
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_mgmt_tx_status/format
@@ -0,0 +1,13 @@
+name: cfg80211_mgmt_tx_status
+ID: 1260
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 id; offset:8; size:4; signed:0;
+ field:u64 cookie; offset:16; size:8; signed:0;
+ field:bool ack; offset:24; size:1; signed:0;
+
+print fmt: "wdev(%u), cookie: %llu, ack: %s", (REC->id), REC->cookie, (REC->ack) ? "true" : "false"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_michael_mic_failure/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_michael_mic_failure/format
new file mode 100644
index 000000000..19ff0b7c5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_michael_mic_failure/format
@@ -0,0 +1,16 @@
+name: cfg80211_michael_mic_failure
+ID: 1261
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:u8 addr[6]; offset:28; size:6; signed:0;
+ field:enum nl80211_key_type key_type; offset:36; size:4; signed:0;
+ field:int key_id; offset:40; size:4; signed:1;
+ field:u8 tsc[6]; offset:44; size:6; signed:0;
+
+print fmt: "netdev:%s(%d), %pM, key type: %d, key id: %d, tsc: %pm", REC->name, REC->ifindex, (REC->addr), REC->key_type, REC->key_id, REC->tsc
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_new_sta/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_new_sta/format
new file mode 100644
index 000000000..d1cd045dc
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_new_sta/format
@@ -0,0 +1,27 @@
+name: cfg80211_new_sta
+ID: 1262
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:u8 mac_addr[6]; offset:28; size:6; signed:0;
+ field:int generation; offset:36; size:4; signed:1;
+ field:u32 connected_time; offset:40; size:4; signed:0;
+ field:u32 inactive_time; offset:44; size:4; signed:0;
+ field:u32 rx_bytes; offset:48; size:4; signed:0;
+ field:u32 tx_bytes; offset:52; size:4; signed:0;
+ field:u32 rx_packets; offset:56; size:4; signed:0;
+ field:u32 tx_packets; offset:60; size:4; signed:0;
+ field:u32 tx_retries; offset:64; size:4; signed:0;
+ field:u32 tx_failed; offset:68; size:4; signed:0;
+ field:u32 rx_dropped_misc; offset:72; size:4; signed:0;
+ field:u32 beacon_loss_count; offset:76; size:4; signed:0;
+ field:u16 llid; offset:80; size:2; signed:0;
+ field:u16 plid; offset:82; size:2; signed:0;
+ field:u8 plink_state; offset:84; size:1; signed:0;
+
+print fmt: "netdev:%s(%d), %pM", REC->name, REC->ifindex, (REC->mac_addr)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_notify_new_peer_candidate/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_notify_new_peer_candidate/format
new file mode 100644
index 000000000..abf253b80
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_notify_new_peer_candidate/format
@@ -0,0 +1,13 @@
+name: cfg80211_notify_new_peer_candidate
+ID: 1263
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:u8 macaddr[6]; offset:28; size:6; signed:0;
+
+print fmt: "netdev:%s(%d), mac: %pM", REC->name, REC->ifindex, (REC->macaddr)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_pmksa_candidate_notify/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_pmksa_candidate_notify/format
new file mode 100644
index 000000000..a0334d6bf
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_pmksa_candidate_notify/format
@@ -0,0 +1,15 @@
+name: cfg80211_pmksa_candidate_notify
+ID: 1264
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:int index; offset:28; size:4; signed:1;
+ field:u8 bssid[6]; offset:32; size:6; signed:0;
+ field:bool preauth; offset:38; size:1; signed:0;
+
+print fmt: "netdev:%s(%d), index:%d, bssid: %pM, pre auth: %s", REC->name, REC->ifindex, REC->index, (REC->bssid), (REC->preauth) ? "true" : "false"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_pmsr_complete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_pmsr_complete/format
new file mode 100644
index 000000000..e96530261
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_pmsr_complete/format
@@ -0,0 +1,13 @@
+name: cfg80211_pmsr_complete
+ID: 1265
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+ field:u64 cookie; offset:48; size:8; signed:0;
+
+print fmt: "%s, wdev(%u), cookie:%lld", REC->wiphy_name, (REC->id), (unsigned long long)REC->cookie
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_pmsr_report/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_pmsr_report/format
new file mode 100644
index 000000000..586d830fe
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_pmsr_report/format
@@ -0,0 +1,14 @@
+name: cfg80211_pmsr_report
+ID: 1266
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+ field:u64 cookie; offset:48; size:8; signed:0;
+ field:u8 addr[6]; offset:56; size:6; signed:0;
+
+print fmt: "%s, wdev(%u), cookie:%lld, %pM", REC->wiphy_name, (REC->id), (unsigned long long)REC->cookie, (REC->addr)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_probe_status/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_probe_status/format
new file mode 100644
index 000000000..dafef5580
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_probe_status/format
@@ -0,0 +1,15 @@
+name: cfg80211_probe_status
+ID: 1267
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:u8 addr[6]; offset:28; size:6; signed:0;
+ field:u64 cookie; offset:40; size:8; signed:0;
+ field:bool acked; offset:48; size:1; signed:0;
+
+print fmt: "netdev:%s(%d) addr:%pM, cookie: %llu, acked: %s", REC->name, REC->ifindex, (REC->addr), REC->cookie, (REC->acked) ? "true" : "false"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_radar_event/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_radar_event/format
new file mode 100644
index 000000000..836cecfc2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_radar_event/format
@@ -0,0 +1,18 @@
+name: cfg80211_radar_event
+ID: 1268
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_band band; offset:40; size:4; signed:0;
+ field:u32 control_freq; offset:44; size:4; signed:0;
+ field:u32 freq_offset; offset:48; size:4; signed:0;
+ field:u32 width; offset:52; size:4; signed:0;
+ field:u32 center_freq1; offset:56; size:4; signed:0;
+ field:u32 freq1_offset; offset:60; size:4; signed:0;
+ field:u32 center_freq2; offset:64; size:4; signed:0;
+
+print fmt: "%s, band: %d, control freq: %u.%03u, width: %d, cf1: %u.%03u, cf2: %u", REC->wiphy_name, REC->band, REC->control_freq, REC->freq_offset, REC->width, REC->center_freq1, REC->freq1_offset, REC->center_freq2
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ready_on_channel/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ready_on_channel/format
new file mode 100644
index 000000000..41e6a9caa
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ready_on_channel/format
@@ -0,0 +1,16 @@
+name: cfg80211_ready_on_channel
+ID: 1269
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 id; offset:8; size:4; signed:0;
+ field:u64 cookie; offset:16; size:8; signed:0;
+ field:enum nl80211_band band; offset:24; size:4; signed:0;
+ field:u32 center_freq; offset:28; size:4; signed:0;
+ field:u16 freq_offset; offset:32; size:2; signed:0;
+ field:unsigned int duration; offset:36; size:4; signed:0;
+
+print fmt: "wdev(%u), cookie: %llu, band: %d, freq: %u.%03u, duration: %u", (REC->id), REC->cookie, REC->band, REC->center_freq, REC->freq_offset, REC->duration
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ready_on_channel_expired/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ready_on_channel_expired/format
new file mode 100644
index 000000000..4f67040b1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_ready_on_channel_expired/format
@@ -0,0 +1,15 @@
+name: cfg80211_ready_on_channel_expired
+ID: 1270
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 id; offset:8; size:4; signed:0;
+ field:u64 cookie; offset:16; size:8; signed:0;
+ field:enum nl80211_band band; offset:24; size:4; signed:0;
+ field:u32 center_freq; offset:28; size:4; signed:0;
+ field:u16 freq_offset; offset:32; size:2; signed:0;
+
+print fmt: "wdev(%u), cookie: %llu, band: %d, freq: %u.%03u", (REC->id), REC->cookie, REC->band, REC->center_freq, REC->freq_offset
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_reg_can_beacon/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_reg_can_beacon/format
new file mode 100644
index 000000000..e44f2197d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_reg_can_beacon/format
@@ -0,0 +1,20 @@
+name: cfg80211_reg_can_beacon
+ID: 1271
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_band band; offset:40; size:4; signed:0;
+ field:u32 control_freq; offset:44; size:4; signed:0;
+ field:u32 freq_offset; offset:48; size:4; signed:0;
+ field:u32 width; offset:52; size:4; signed:0;
+ field:u32 center_freq1; offset:56; size:4; signed:0;
+ field:u32 freq1_offset; offset:60; size:4; signed:0;
+ field:u32 center_freq2; offset:64; size:4; signed:0;
+ field:enum nl80211_iftype iftype; offset:68; size:4; signed:0;
+ field:bool check_no_ir; offset:72; size:1; signed:0;
+
+print fmt: "%s, band: %d, control freq: %u.%03u, width: %d, cf1: %u.%03u, cf2: %u, iftype=%d check_no_ir=%s", REC->wiphy_name, REC->band, REC->control_freq, REC->freq_offset, REC->width, REC->center_freq1, REC->freq1_offset, REC->center_freq2, REC->iftype, (REC->check_no_ir) ? "true" : "false"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_report_obss_beacon/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_report_obss_beacon/format
new file mode 100644
index 000000000..fe201668b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_report_obss_beacon/format
@@ -0,0 +1,13 @@
+name: cfg80211_report_obss_beacon
+ID: 1272
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:int freq; offset:40; size:4; signed:1;
+ field:int sig_dbm; offset:44; size:4; signed:1;
+
+print fmt: "%s, freq: %d.%03d, sig_dbm: %d", REC->wiphy_name, ((REC->freq) / 1000), REC->freq % 1000, REC->sig_dbm
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_report_wowlan_wakeup/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_report_wowlan_wakeup/format
new file mode 100644
index 000000000..7ccced39f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_report_wowlan_wakeup/format
@@ -0,0 +1,22 @@
+name: cfg80211_report_wowlan_wakeup
+ID: 1273
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+ field:bool non_wireless; offset:44; size:1; signed:0;
+ field:bool disconnect; offset:45; size:1; signed:0;
+ field:bool magic_pkt; offset:46; size:1; signed:0;
+ field:bool gtk_rekey_failure; offset:47; size:1; signed:0;
+ field:bool eap_identity_req; offset:48; size:1; signed:0;
+ field:bool four_way_handshake; offset:49; size:1; signed:0;
+ field:bool rfkill_release; offset:50; size:1; signed:0;
+ field:s32 pattern_idx; offset:52; size:4; signed:1;
+ field:u32 packet_len; offset:56; size:4; signed:0;
+ field:__data_loc u8[] packet; offset:60; size:4; signed:0;
+
+print fmt: "%s, wdev(%u)", REC->wiphy_name, (REC->id)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_return_bool/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_return_bool/format
new file mode 100644
index 000000000..737da523e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_return_bool/format
@@ -0,0 +1,11 @@
+name: cfg80211_return_bool
+ID: 1274
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:bool ret; offset:8; size:1; signed:0;
+
+print fmt: "returned %s", (REC->ret) ? "true" : "false"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_return_bss/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_return_bss/format
new file mode 100644
index 000000000..26cd31844
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_return_bss/format
@@ -0,0 +1,14 @@
+name: cfg80211_return_bss
+ID: 1275
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u8 bssid[6]; offset:8; size:6; signed:0;
+ field:enum nl80211_band band; offset:16; size:4; signed:0;
+ field:u32 center_freq; offset:20; size:4; signed:0;
+ field:u16 freq_offset; offset:24; size:2; signed:0;
+
+print fmt: "%pM, band: %d, freq: %u.%03u", (REC->bssid), REC->band, REC->center_freq, REC->freq_offset
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_return_u32/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_return_u32/format
new file mode 100644
index 000000000..88eea69ae
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_return_u32/format
@@ -0,0 +1,11 @@
+name: cfg80211_return_u32
+ID: 1276
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 ret; offset:8; size:4; signed:0;
+
+print fmt: "ret: %u", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_return_uint/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_return_uint/format
new file mode 100644
index 000000000..f5fff3ee1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_return_uint/format
@@ -0,0 +1,11 @@
+name: cfg80211_return_uint
+ID: 1277
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int ret; offset:8; size:4; signed:0;
+
+print fmt: "ret: %d", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_control_port/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_control_port/format
new file mode 100644
index 000000000..a58a2132e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_control_port/format
@@ -0,0 +1,16 @@
+name: cfg80211_rx_control_port
+ID: 1278
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:int len; offset:28; size:4; signed:1;
+ field:u8 from[6]; offset:32; size:6; signed:0;
+ field:u16 proto; offset:38; size:2; signed:0;
+ field:bool unencrypted; offset:40; size:1; signed:0;
+
+print fmt: "netdev:%s(%d), len=%d, %pM, proto: 0x%x, unencrypted: %s", REC->name, REC->ifindex, REC->len, (REC->from), REC->proto, (REC->unencrypted) ? "true" : "false"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_mgmt/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_mgmt/format
new file mode 100644
index 000000000..9610e6fbe
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_mgmt/format
@@ -0,0 +1,13 @@
+name: cfg80211_rx_mgmt
+ID: 1279
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 id; offset:8; size:4; signed:0;
+ field:int freq; offset:12; size:4; signed:1;
+ field:int sig_dbm; offset:16; size:4; signed:1;
+
+print fmt: "wdev(%u), freq: %d.%03d, sig dbm: %d", (REC->id), ((REC->freq) / 1000), REC->freq % 1000, REC->sig_dbm
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_mlme_mgmt/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_mlme_mgmt/format
new file mode 100644
index 000000000..27eed3eab
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_mlme_mgmt/format
@@ -0,0 +1,13 @@
+name: cfg80211_rx_mlme_mgmt
+ID: 1280
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:__data_loc u8[] frame; offset:28; size:4; signed:0;
+
+print fmt: "netdev:%s(%d), ftype:0x%.2x", REC->name, REC->ifindex, __le16_to_cpup((__le16 *)__get_dynamic_array(frame))
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_spurious_frame/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_spurious_frame/format
new file mode 100644
index 000000000..4aa94bdca
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_spurious_frame/format
@@ -0,0 +1,13 @@
+name: cfg80211_rx_spurious_frame
+ID: 1281
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:u8 addr[6]; offset:28; size:6; signed:0;
+
+print fmt: "netdev:%s(%d), %pM", REC->name, REC->ifindex, (REC->addr)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_unexpected_4addr_frame/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_unexpected_4addr_frame/format
new file mode 100644
index 000000000..7b81c4771
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_unexpected_4addr_frame/format
@@ -0,0 +1,13 @@
+name: cfg80211_rx_unexpected_4addr_frame
+ID: 1282
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:u8 addr[6]; offset:28; size:6; signed:0;
+
+print fmt: "netdev:%s(%d), %pM", REC->name, REC->ifindex, (REC->addr)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_unprot_mlme_mgmt/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_unprot_mlme_mgmt/format
new file mode 100644
index 000000000..1eb23717b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_rx_unprot_mlme_mgmt/format
@@ -0,0 +1,13 @@
+name: cfg80211_rx_unprot_mlme_mgmt
+ID: 1283
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:__data_loc u8[] frame; offset:28; size:4; signed:0;
+
+print fmt: "netdev:%s(%d), ftype:0x%.2x", REC->name, REC->ifindex, __le16_to_cpup((__le16 *)__get_dynamic_array(frame))
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_scan_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_scan_done/format
new file mode 100644
index 000000000..d3d0d249d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_scan_done/format
@@ -0,0 +1,19 @@
+name: cfg80211_scan_done
+ID: 1284
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 n_channels; offset:8; size:4; signed:0;
+ field:__data_loc u8[] ie; offset:12; size:4; signed:0;
+ field:u32 rates[NUM_NL80211_BANDS]; offset:16; size:20; signed:0;
+ field:u32 wdev_id; offset:36; size:4; signed:0;
+ field:u8 wiphy_mac[6]; offset:40; size:6; signed:0;
+ field:bool no_cck; offset:46; size:1; signed:0;
+ field:bool aborted; offset:47; size:1; signed:0;
+ field:u64 scan_start_tsf; offset:48; size:8; signed:0;
+ field:u8 tsf_bssid[6]; offset:56; size:6; signed:0;
+
+print fmt: "aborted: %s, scan start (TSF): %llu, tsf_bssid: %pM", (REC->aborted) ? "true" : "false", (unsigned long long)REC->scan_start_tsf, (REC->tsf_bssid)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_sched_scan_results/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_sched_scan_results/format
new file mode 100644
index 000000000..5301c25e2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_sched_scan_results/format
@@ -0,0 +1,12 @@
+name: cfg80211_sched_scan_results
+ID: 1285
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u64 id; offset:40; size:8; signed:0;
+
+print fmt: "%s, id: %llu", REC->wiphy_name, REC->id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_sched_scan_stopped/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_sched_scan_stopped/format
new file mode 100644
index 000000000..4b88b29e6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_sched_scan_stopped/format
@@ -0,0 +1,12 @@
+name: cfg80211_sched_scan_stopped
+ID: 1286
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u64 id; offset:40; size:8; signed:0;
+
+print fmt: "%s, id: %llu", REC->wiphy_name, REC->id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_send_assoc_timeout/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_send_assoc_timeout/format
new file mode 100644
index 000000000..160145221
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_send_assoc_timeout/format
@@ -0,0 +1,13 @@
+name: cfg80211_send_assoc_timeout
+ID: 1287
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:u8 mac[6]; offset:28; size:6; signed:0;
+
+print fmt: "netdev:%s(%d), mac: %pM", REC->name, REC->ifindex, (REC->mac)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_send_auth_timeout/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_send_auth_timeout/format
new file mode 100644
index 000000000..7fbbb6cc1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_send_auth_timeout/format
@@ -0,0 +1,13 @@
+name: cfg80211_send_auth_timeout
+ID: 1288
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:u8 mac[6]; offset:28; size:6; signed:0;
+
+print fmt: "netdev:%s(%d), mac: %pM", REC->name, REC->ifindex, (REC->mac)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_send_rx_assoc/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_send_rx_assoc/format
new file mode 100644
index 000000000..f97316276
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_send_rx_assoc/format
@@ -0,0 +1,16 @@
+name: cfg80211_send_rx_assoc
+ID: 1289
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:u8 bssid[6]; offset:28; size:6; signed:0;
+ field:enum nl80211_band band; offset:36; size:4; signed:0;
+ field:u32 center_freq; offset:40; size:4; signed:0;
+ field:u16 freq_offset; offset:44; size:2; signed:0;
+
+print fmt: "netdev:%s(%d), %pM, band: %d, freq: %u.%03u", REC->name, REC->ifindex, (REC->bssid), REC->band, REC->center_freq, REC->freq_offset
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_send_rx_auth/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_send_rx_auth/format
new file mode 100644
index 000000000..ae385fd84
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_send_rx_auth/format
@@ -0,0 +1,12 @@
+name: cfg80211_send_rx_auth
+ID: 1290
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+
+print fmt: "netdev:%s(%d)", REC->name, REC->ifindex
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_stop_iface/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_stop_iface/format
new file mode 100644
index 000000000..548571869
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_stop_iface/format
@@ -0,0 +1,12 @@
+name: cfg80211_stop_iface
+ID: 1291
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+
+print fmt: "%s, wdev(%u)", REC->wiphy_name, (REC->id)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_tdls_oper_request/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_tdls_oper_request/format
new file mode 100644
index 000000000..c89867cbf
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_tdls_oper_request/format
@@ -0,0 +1,16 @@
+name: cfg80211_tdls_oper_request
+ID: 1292
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 peer[6]; offset:60; size:6; signed:0;
+ field:enum nl80211_tdls_operation oper; offset:68; size:4; signed:0;
+ field:u16 reason_code; offset:72; size:2; signed:0;
+
+print fmt: "%s, netdev:%s(%d), peer: %pM, oper: %d, reason_code %u", REC->wiphy_name, REC->name, REC->ifindex, (REC->peer), REC->oper, REC->reason_code
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_tx_mgmt_expired/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_tx_mgmt_expired/format
new file mode 100644
index 000000000..96fbee433
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_tx_mgmt_expired/format
@@ -0,0 +1,15 @@
+name: cfg80211_tx_mgmt_expired
+ID: 1293
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 id; offset:8; size:4; signed:0;
+ field:u64 cookie; offset:16; size:8; signed:0;
+ field:enum nl80211_band band; offset:24; size:4; signed:0;
+ field:u32 center_freq; offset:28; size:4; signed:0;
+ field:u16 freq_offset; offset:32; size:2; signed:0;
+
+print fmt: "wdev(%u), cookie: %llu, band: %d, freq: %u.%03u", (REC->id), REC->cookie, REC->band, REC->center_freq, REC->freq_offset
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_tx_mlme_mgmt/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_tx_mlme_mgmt/format
new file mode 100644
index 000000000..2a0e11872
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_tx_mlme_mgmt/format
@@ -0,0 +1,13 @@
+name: cfg80211_tx_mlme_mgmt
+ID: 1294
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[16]; offset:8; size:16; signed:0;
+ field:int ifindex; offset:24; size:4; signed:1;
+ field:__data_loc u8[] frame; offset:28; size:4; signed:0;
+
+print fmt: "netdev:%s(%d), ftype:0x%.2x", REC->name, REC->ifindex, __le16_to_cpup((__le16 *)__get_dynamic_array(frame))
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_update_owe_info_event/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_update_owe_info_event/format
new file mode 100644
index 000000000..ad1676f8f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/cfg80211_update_owe_info_event/format
@@ -0,0 +1,15 @@
+name: cfg80211_update_owe_info_event
+ID: 1295
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 peer[6]; offset:60; size:6; signed:0;
+ field:__data_loc u8[] ie; offset:68; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), peer: %pM", REC->wiphy_name, REC->name, REC->ifindex, (REC->peer)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_abort_pmsr/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_abort_pmsr/format
new file mode 100644
index 000000000..73c42c03f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_abort_pmsr/format
@@ -0,0 +1,13 @@
+name: rdev_abort_pmsr
+ID: 1296
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+ field:u64 cookie; offset:48; size:8; signed:0;
+
+print fmt: "%s, wdev(%u), cookie: %lld", REC->wiphy_name, (REC->id), (unsigned long long)REC->cookie
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_abort_scan/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_abort_scan/format
new file mode 100644
index 000000000..45cd30366
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_abort_scan/format
@@ -0,0 +1,12 @@
+name: rdev_abort_scan
+ID: 1297
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+
+print fmt: "%s, wdev(%u)", REC->wiphy_name, (REC->id)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_key/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_key/format
new file mode 100644
index 000000000..972288c79
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_key/format
@@ -0,0 +1,17 @@
+name: rdev_add_key
+ID: 1298
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 mac_addr[6]; offset:60; size:6; signed:0;
+ field:u8 key_index; offset:66; size:1; signed:0;
+ field:bool pairwise; offset:67; size:1; signed:0;
+ field:u8 mode; offset:68; size:1; signed:0;
+
+print fmt: "%s, netdev:%s(%d), key_index: %u, mode: %u, pairwise: %s, mac addr: %pM", REC->wiphy_name, REC->name, REC->ifindex, REC->key_index, REC->mode, (REC->pairwise) ? "true" : "false", (REC->mac_addr)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_mpath/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_mpath/format
new file mode 100644
index 000000000..cff08fd9e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_mpath/format
@@ -0,0 +1,15 @@
+name: rdev_add_mpath
+ID: 1299
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 dst[6]; offset:60; size:6; signed:0;
+ field:u8 next_hop[6]; offset:66; size:6; signed:0;
+
+print fmt: "%s, netdev:%s(%d), destination: %pM, next hop: %pM", REC->wiphy_name, REC->name, REC->ifindex, (REC->dst), (REC->next_hop)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_nan_func/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_nan_func/format
new file mode 100644
index 000000000..3f3188c03
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_nan_func/format
@@ -0,0 +1,14 @@
+name: rdev_add_nan_func
+ID: 1300
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+ field:u8 func_type; offset:44; size:1; signed:0;
+ field:u64 cookie; offset:48; size:8; signed:0;
+
+print fmt: "%s, wdev(%u), type=%u, cookie=%llu", REC->wiphy_name, (REC->id), REC->func_type, REC->cookie
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_station/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_station/format
new file mode 100644
index 000000000..a180c7a8a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_station/format
@@ -0,0 +1,33 @@
+name: rdev_add_station
+ID: 1301
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 sta_mac[6]; offset:60; size:6; signed:0;
+ field:u32 sta_flags_mask; offset:68; size:4; signed:0;
+ field:u32 sta_flags_set; offset:72; size:4; signed:0;
+ field:u32 sta_modify_mask; offset:76; size:4; signed:0;
+ field:int listen_interval; offset:80; size:4; signed:1;
+ field:u16 capability; offset:84; size:2; signed:0;
+ field:u16 aid; offset:86; size:2; signed:0;
+ field:u8 plink_action; offset:88; size:1; signed:0;
+ field:u8 plink_state; offset:89; size:1; signed:0;
+ field:u8 uapsd_queues; offset:90; size:1; signed:0;
+ field:u8 max_sp; offset:91; size:1; signed:0;
+ field:u8 opmode_notif; offset:92; size:1; signed:0;
+ field:bool opmode_notif_used; offset:93; size:1; signed:0;
+ field:u8 ht_capa[(int)sizeof(struct ieee80211_ht_cap)]; offset:94; size:26; signed:0;
+ field:u8 vht_capa[(int)sizeof(struct ieee80211_vht_cap)]; offset:120; size:12; signed:0;
+ field:char vlan[16]; offset:132; size:16; signed:0;
+ field:__data_loc u8[] supported_rates; offset:148; size:4; signed:0;
+ field:__data_loc u8[] ext_capab; offset:152; size:4; signed:0;
+ field:__data_loc u8[] supported_channels; offset:156; size:4; signed:0;
+ field:__data_loc u8[] supported_oper_classes; offset:160; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), station mac: %pM, station flags mask: %u, station flags set: %u, station modify mask: %u, listen interval: %d, aid: %u, plink action: %u, plink state: %u, uapsd queues: %u, vlan:%s", REC->wiphy_name, REC->name, REC->ifindex, (REC->sta_mac), REC->sta_flags_mask, REC->sta_flags_set, REC->sta_modify_mask, REC->listen_interval, REC->aid, REC->plink_action, REC->plink_state, REC->uapsd_queues, REC->vlan
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_tx_ts/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_tx_ts/format
new file mode 100644
index 000000000..09e59446f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_tx_ts/format
@@ -0,0 +1,17 @@
+name: rdev_add_tx_ts
+ID: 1302
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 peer[6]; offset:60; size:6; signed:0;
+ field:u8 tsid; offset:66; size:1; signed:0;
+ field:u8 user_prio; offset:67; size:1; signed:0;
+ field:u16 admitted_time; offset:68; size:2; signed:0;
+
+print fmt: "%s, netdev:%s(%d), %pM, TSID %d, UP %d, time %d", REC->wiphy_name, REC->name, REC->ifindex, (REC->peer), REC->tsid, REC->user_prio, REC->admitted_time
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_virtual_intf/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_virtual_intf/format
new file mode 100644
index 000000000..17c7e572f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_add_virtual_intf/format
@@ -0,0 +1,13 @@
+name: rdev_add_virtual_intf
+ID: 1303
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:__data_loc char[] vir_intf_name; offset:40; size:4; signed:0;
+ field:enum nl80211_iftype type; offset:44; size:4; signed:0;
+
+print fmt: "%s, virtual intf name: %s, type: %d", REC->wiphy_name, __get_str(vir_intf_name), REC->type
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_assoc/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_assoc/format
new file mode 100644
index 000000000..b0d5e0dd8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_assoc/format
@@ -0,0 +1,17 @@
+name: rdev_assoc
+ID: 1304
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 bssid[6]; offset:60; size:6; signed:0;
+ field:u8 prev_bssid[6]; offset:66; size:6; signed:0;
+ field:bool use_mfp; offset:72; size:1; signed:0;
+ field:u32 flags; offset:76; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), bssid: %pM, previous bssid: %pM, use mfp: %s, flags: %u", REC->wiphy_name, REC->name, REC->ifindex, (REC->bssid), (REC->prev_bssid), (REC->use_mfp) ? "true" : "false", REC->flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_auth/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_auth/format
new file mode 100644
index 000000000..c38f70831
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_auth/format
@@ -0,0 +1,15 @@
+name: rdev_auth
+ID: 1305
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 bssid[6]; offset:60; size:6; signed:0;
+ field:enum nl80211_auth_type auth_type; offset:68; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), auth type: %d, bssid: %pM", REC->wiphy_name, REC->name, REC->ifindex, REC->auth_type, (REC->bssid)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_cancel_remain_on_channel/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_cancel_remain_on_channel/format
new file mode 100644
index 000000000..b101b06a5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_cancel_remain_on_channel/format
@@ -0,0 +1,13 @@
+name: rdev_cancel_remain_on_channel
+ID: 1306
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+ field:u64 cookie; offset:48; size:8; signed:0;
+
+print fmt: "%s, wdev(%u), cookie: %llu", REC->wiphy_name, (REC->id), REC->cookie
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_change_beacon/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_change_beacon/format
new file mode 100644
index 000000000..f3cede542
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_change_beacon/format
@@ -0,0 +1,19 @@
+name: rdev_change_beacon
+ID: 1307
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:__data_loc u8[] head; offset:60; size:4; signed:0;
+ field:__data_loc u8[] tail; offset:64; size:4; signed:0;
+ field:__data_loc u8[] beacon_ies; offset:68; size:4; signed:0;
+ field:__data_loc u8[] proberesp_ies; offset:72; size:4; signed:0;
+ field:__data_loc u8[] assocresp_ies; offset:76; size:4; signed:0;
+ field:__data_loc u8[] probe_resp; offset:80; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d)", REC->wiphy_name, REC->name, REC->ifindex
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_change_bss/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_change_bss/format
new file mode 100644
index 000000000..7c966785f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_change_bss/format
@@ -0,0 +1,18 @@
+name: rdev_change_bss
+ID: 1308
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:int use_cts_prot; offset:60; size:4; signed:1;
+ field:int use_short_preamble; offset:64; size:4; signed:1;
+ field:int use_short_slot_time; offset:68; size:4; signed:1;
+ field:int ap_isolate; offset:72; size:4; signed:1;
+ field:int ht_opmode; offset:76; size:4; signed:1;
+
+print fmt: "%s, netdev:%s(%d), use cts prot: %d, use short preamble: %d, use short slot time: %d, ap isolate: %d, ht opmode: %d", REC->wiphy_name, REC->name, REC->ifindex, REC->use_cts_prot, REC->use_short_preamble, REC->use_short_slot_time, REC->ap_isolate, REC->ht_opmode
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_change_mpath/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_change_mpath/format
new file mode 100644
index 000000000..309047d3d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_change_mpath/format
@@ -0,0 +1,15 @@
+name: rdev_change_mpath
+ID: 1309
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 dst[6]; offset:60; size:6; signed:0;
+ field:u8 next_hop[6]; offset:66; size:6; signed:0;
+
+print fmt: "%s, netdev:%s(%d), destination: %pM, next hop: %pM", REC->wiphy_name, REC->name, REC->ifindex, (REC->dst), (REC->next_hop)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_change_station/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_change_station/format
new file mode 100644
index 000000000..1ed39a350
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_change_station/format
@@ -0,0 +1,33 @@
+name: rdev_change_station
+ID: 1310
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 sta_mac[6]; offset:60; size:6; signed:0;
+ field:u32 sta_flags_mask; offset:68; size:4; signed:0;
+ field:u32 sta_flags_set; offset:72; size:4; signed:0;
+ field:u32 sta_modify_mask; offset:76; size:4; signed:0;
+ field:int listen_interval; offset:80; size:4; signed:1;
+ field:u16 capability; offset:84; size:2; signed:0;
+ field:u16 aid; offset:86; size:2; signed:0;
+ field:u8 plink_action; offset:88; size:1; signed:0;
+ field:u8 plink_state; offset:89; size:1; signed:0;
+ field:u8 uapsd_queues; offset:90; size:1; signed:0;
+ field:u8 max_sp; offset:91; size:1; signed:0;
+ field:u8 opmode_notif; offset:92; size:1; signed:0;
+ field:bool opmode_notif_used; offset:93; size:1; signed:0;
+ field:u8 ht_capa[(int)sizeof(struct ieee80211_ht_cap)]; offset:94; size:26; signed:0;
+ field:u8 vht_capa[(int)sizeof(struct ieee80211_vht_cap)]; offset:120; size:12; signed:0;
+ field:char vlan[16]; offset:132; size:16; signed:0;
+ field:__data_loc u8[] supported_rates; offset:148; size:4; signed:0;
+ field:__data_loc u8[] ext_capab; offset:152; size:4; signed:0;
+ field:__data_loc u8[] supported_channels; offset:156; size:4; signed:0;
+ field:__data_loc u8[] supported_oper_classes; offset:160; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), station mac: %pM, station flags mask: %u, station flags set: %u, station modify mask: %u, listen interval: %d, aid: %u, plink action: %u, plink state: %u, uapsd queues: %u, vlan:%s", REC->wiphy_name, REC->name, REC->ifindex, (REC->sta_mac), REC->sta_flags_mask, REC->sta_flags_set, REC->sta_modify_mask, REC->listen_interval, REC->aid, REC->plink_action, REC->plink_state, REC->uapsd_queues, REC->vlan
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_change_virtual_intf/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_change_virtual_intf/format
new file mode 100644
index 000000000..f3da4dc92
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_change_virtual_intf/format
@@ -0,0 +1,14 @@
+name: rdev_change_virtual_intf
+ID: 1311
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:enum nl80211_iftype type; offset:60; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), type: %d", REC->wiphy_name, REC->name, REC->ifindex, REC->type
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_channel_switch/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_channel_switch/format
new file mode 100644
index 000000000..e42a338f3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_channel_switch/format
@@ -0,0 +1,25 @@
+name: rdev_channel_switch
+ID: 1312
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:enum nl80211_band band; offset:60; size:4; signed:0;
+ field:u32 control_freq; offset:64; size:4; signed:0;
+ field:u32 freq_offset; offset:68; size:4; signed:0;
+ field:u32 width; offset:72; size:4; signed:0;
+ field:u32 center_freq1; offset:76; size:4; signed:0;
+ field:u32 freq1_offset; offset:80; size:4; signed:0;
+ field:u32 center_freq2; offset:84; size:4; signed:0;
+ field:bool radar_required; offset:88; size:1; signed:0;
+ field:bool block_tx; offset:89; size:1; signed:0;
+ field:u8 count; offset:90; size:1; signed:0;
+ field:__data_loc u16[] bcn_ofs; offset:92; size:4; signed:0;
+ field:__data_loc u16[] pres_ofs; offset:96; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), band: %d, control freq: %u.%03u, width: %d, cf1: %u.%03u, cf2: %u, block_tx: %d, count: %u, radar_required: %d", REC->wiphy_name, REC->name, REC->ifindex, REC->band, REC->control_freq, REC->freq_offset, REC->width, REC->center_freq1, REC->freq1_offset, REC->center_freq2, REC->block_tx, REC->count, REC->radar_required
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_connect/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_connect/format
new file mode 100644
index 000000000..6fa4c80f1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_connect/format
@@ -0,0 +1,20 @@
+name: rdev_connect
+ID: 1313
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 bssid[6]; offset:60; size:6; signed:0;
+ field:char ssid[32 + 1]; offset:66; size:33; signed:0;
+ field:enum nl80211_auth_type auth_type; offset:100; size:4; signed:0;
+ field:bool privacy; offset:104; size:1; signed:0;
+ field:u32 wpa_versions; offset:108; size:4; signed:0;
+ field:u32 flags; offset:112; size:4; signed:0;
+ field:u8 prev_bssid[6]; offset:116; size:6; signed:0;
+
+print fmt: "%s, netdev:%s(%d), bssid: %pM, ssid: %s, auth type: %d, privacy: %s, wpa versions: %u, flags: %u, previous bssid: %pM", REC->wiphy_name, REC->name, REC->ifindex, (REC->bssid), REC->ssid, REC->auth_type, (REC->privacy) ? "true" : "false", REC->wpa_versions, REC->flags, (REC->prev_bssid)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_crit_proto_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_crit_proto_start/format
new file mode 100644
index 000000000..13cef3e1b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_crit_proto_start/format
@@ -0,0 +1,14 @@
+name: rdev_crit_proto_start
+ID: 1314
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+ field:u16 proto; offset:44; size:2; signed:0;
+ field:u16 duration; offset:46; size:2; signed:0;
+
+print fmt: "%s, wdev(%u), proto=%x, duration=%u", REC->wiphy_name, (REC->id), REC->proto, REC->duration
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_crit_proto_stop/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_crit_proto_stop/format
new file mode 100644
index 000000000..73d8a3ba9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_crit_proto_stop/format
@@ -0,0 +1,12 @@
+name: rdev_crit_proto_stop
+ID: 1315
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+
+print fmt: "%s, wdev(%u)", REC->wiphy_name, (REC->id)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_deauth/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_deauth/format
new file mode 100644
index 000000000..769f921f1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_deauth/format
@@ -0,0 +1,15 @@
+name: rdev_deauth
+ID: 1316
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 bssid[6]; offset:60; size:6; signed:0;
+ field:u16 reason_code; offset:66; size:2; signed:0;
+
+print fmt: "%s, netdev:%s(%d), bssid: %pM, reason: %u", REC->wiphy_name, REC->name, REC->ifindex, (REC->bssid), REC->reason_code
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_key/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_key/format
new file mode 100644
index 000000000..d3f191148
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_key/format
@@ -0,0 +1,16 @@
+name: rdev_del_key
+ID: 1317
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 mac_addr[6]; offset:60; size:6; signed:0;
+ field:u8 key_index; offset:66; size:1; signed:0;
+ field:bool pairwise; offset:67; size:1; signed:0;
+
+print fmt: "%s, netdev:%s(%d), key_index: %u, pairwise: %s, mac addr: %pM", REC->wiphy_name, REC->name, REC->ifindex, REC->key_index, (REC->pairwise) ? "true" : "false", (REC->mac_addr)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_mpath/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_mpath/format
new file mode 100644
index 000000000..e246d6c6b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_mpath/format
@@ -0,0 +1,14 @@
+name: rdev_del_mpath
+ID: 1318
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 sta_mac[6]; offset:60; size:6; signed:0;
+
+print fmt: "%s, netdev:%s(%d), mac: %pM", REC->wiphy_name, REC->name, REC->ifindex, (REC->sta_mac)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_nan_func/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_nan_func/format
new file mode 100644
index 000000000..9e6c51558
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_nan_func/format
@@ -0,0 +1,13 @@
+name: rdev_del_nan_func
+ID: 1319
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+ field:u64 cookie; offset:48; size:8; signed:0;
+
+print fmt: "%s, wdev(%u), cookie=%llu", REC->wiphy_name, (REC->id), REC->cookie
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_pmk/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_pmk/format
new file mode 100644
index 000000000..60f49afd1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_pmk/format
@@ -0,0 +1,14 @@
+name: rdev_del_pmk
+ID: 1320
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 aa[6]; offset:60; size:6; signed:0;
+
+print fmt: "%s, netdev:%s(%d), %pM", REC->wiphy_name, REC->name, REC->ifindex, (REC->aa)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_pmksa/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_pmksa/format
new file mode 100644
index 000000000..40c4d3f62
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_pmksa/format
@@ -0,0 +1,14 @@
+name: rdev_del_pmksa
+ID: 1321
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 bssid[6]; offset:60; size:6; signed:0;
+
+print fmt: "%s, netdev:%s(%d), bssid: %pM", REC->wiphy_name, REC->name, REC->ifindex, (REC->bssid)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_station/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_station/format
new file mode 100644
index 000000000..596d7d210
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_station/format
@@ -0,0 +1,16 @@
+name: rdev_del_station
+ID: 1322
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 sta_mac[6]; offset:60; size:6; signed:0;
+ field:u8 subtype; offset:66; size:1; signed:0;
+ field:u16 reason_code; offset:68; size:2; signed:0;
+
+print fmt: "%s, netdev:%s(%d), station mac: %pM, subtype: %u, reason_code: %u", REC->wiphy_name, REC->name, REC->ifindex, (REC->sta_mac), REC->subtype, REC->reason_code
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_tx_ts/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_tx_ts/format
new file mode 100644
index 000000000..7dc8cfbf3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_tx_ts/format
@@ -0,0 +1,15 @@
+name: rdev_del_tx_ts
+ID: 1323
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 peer[6]; offset:60; size:6; signed:0;
+ field:u8 tsid; offset:66; size:1; signed:0;
+
+print fmt: "%s, netdev:%s(%d), %pM, TSID %d", REC->wiphy_name, REC->name, REC->ifindex, (REC->peer), REC->tsid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_virtual_intf/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_virtual_intf/format
new file mode 100644
index 000000000..7271d5671
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_del_virtual_intf/format
@@ -0,0 +1,12 @@
+name: rdev_del_virtual_intf
+ID: 1324
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+
+print fmt: "%s, wdev(%u)", REC->wiphy_name, (REC->id)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_disassoc/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_disassoc/format
new file mode 100644
index 000000000..2e0e7849a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_disassoc/format
@@ -0,0 +1,16 @@
+name: rdev_disassoc
+ID: 1325
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 bssid[6]; offset:60; size:6; signed:0;
+ field:u16 reason_code; offset:66; size:2; signed:0;
+ field:bool local_state_change; offset:68; size:1; signed:0;
+
+print fmt: "%s, netdev:%s(%d), bssid: %pM, reason: %u, local state change: %s", REC->wiphy_name, REC->name, REC->ifindex, (REC->bssid), REC->reason_code, (REC->local_state_change) ? "true" : "false"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_disconnect/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_disconnect/format
new file mode 100644
index 000000000..4c2a548a2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_disconnect/format
@@ -0,0 +1,14 @@
+name: rdev_disconnect
+ID: 1326
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u16 reason_code; offset:60; size:2; signed:0;
+
+print fmt: "%s, netdev:%s(%d), reason code: %u", REC->wiphy_name, REC->name, REC->ifindex, REC->reason_code
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_dump_mpath/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_dump_mpath/format
new file mode 100644
index 000000000..495cd7b5d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_dump_mpath/format
@@ -0,0 +1,16 @@
+name: rdev_dump_mpath
+ID: 1327
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 dst[6]; offset:60; size:6; signed:0;
+ field:u8 next_hop[6]; offset:66; size:6; signed:0;
+ field:int idx; offset:72; size:4; signed:1;
+
+print fmt: "%s, netdev:%s(%d), index: %d, destination: %pM, next hop: %pM", REC->wiphy_name, REC->name, REC->ifindex, REC->idx, (REC->dst), (REC->next_hop)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_dump_mpp/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_dump_mpp/format
new file mode 100644
index 000000000..0e21f61b9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_dump_mpp/format
@@ -0,0 +1,16 @@
+name: rdev_dump_mpp
+ID: 1328
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 dst[6]; offset:60; size:6; signed:0;
+ field:u8 mpp[6]; offset:66; size:6; signed:0;
+ field:int idx; offset:72; size:4; signed:1;
+
+print fmt: "%s, netdev:%s(%d), index: %d, destination: %pM, mpp: %pM", REC->wiphy_name, REC->name, REC->ifindex, REC->idx, (REC->dst), (REC->mpp)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_dump_station/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_dump_station/format
new file mode 100644
index 000000000..b632d0437
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_dump_station/format
@@ -0,0 +1,15 @@
+name: rdev_dump_station
+ID: 1329
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 sta_mac[6]; offset:60; size:6; signed:0;
+ field:int idx; offset:68; size:4; signed:1;
+
+print fmt: "%s, netdev:%s(%d), station mac: %pM, idx: %d", REC->wiphy_name, REC->name, REC->ifindex, (REC->sta_mac), REC->idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_dump_survey/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_dump_survey/format
new file mode 100644
index 000000000..f3442ae65
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_dump_survey/format
@@ -0,0 +1,14 @@
+name: rdev_dump_survey
+ID: 1330
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:int idx; offset:60; size:4; signed:1;
+
+print fmt: "%s, netdev:%s(%d), index: %d", REC->wiphy_name, REC->name, REC->ifindex, REC->idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_end_cac/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_end_cac/format
new file mode 100644
index 000000000..3fbf932fc
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_end_cac/format
@@ -0,0 +1,13 @@
+name: rdev_end_cac
+ID: 1331
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+
+print fmt: "%s, netdev:%s(%d)", REC->wiphy_name, REC->name, REC->ifindex
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_external_auth/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_external_auth/format
new file mode 100644
index 000000000..d6e238bea
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_external_auth/format
@@ -0,0 +1,16 @@
+name: rdev_external_auth
+ID: 1332
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 bssid[6]; offset:60; size:6; signed:0;
+ field:u8 ssid[32 + 1]; offset:66; size:33; signed:0;
+ field:u16 status; offset:100; size:2; signed:0;
+
+print fmt: "%s, netdev:%s(%d), bssid: %pM, ssid: %s, status: %u", REC->wiphy_name, REC->name, REC->ifindex, REC->bssid, REC->ssid, REC->status
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_flush_pmksa/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_flush_pmksa/format
new file mode 100644
index 000000000..66de6a564
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_flush_pmksa/format
@@ -0,0 +1,13 @@
+name: rdev_flush_pmksa
+ID: 1333
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+
+print fmt: "%s, netdev:%s(%d)", REC->wiphy_name, REC->name, REC->ifindex
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_antenna/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_antenna/format
new file mode 100644
index 000000000..1d8ecfbf9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_antenna/format
@@ -0,0 +1,11 @@
+name: rdev_get_antenna
+ID: 1334
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_channel/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_channel/format
new file mode 100644
index 000000000..a4be7eaa6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_channel/format
@@ -0,0 +1,12 @@
+name: rdev_get_channel
+ID: 1335
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+
+print fmt: "%s, wdev(%u)", REC->wiphy_name, (REC->id)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_ftm_responder_stats/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_ftm_responder_stats/format
new file mode 100644
index 000000000..d5c7d56c3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_ftm_responder_stats/format
@@ -0,0 +1,23 @@
+name: rdev_get_ftm_responder_stats
+ID: 1336
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u64 timestamp; offset:64; size:8; signed:0;
+ field:u32 success_num; offset:72; size:4; signed:0;
+ field:u32 partial_num; offset:76; size:4; signed:0;
+ field:u32 failed_num; offset:80; size:4; signed:0;
+ field:u32 asap_num; offset:84; size:4; signed:0;
+ field:u32 non_asap_num; offset:88; size:4; signed:0;
+ field:u64 duration; offset:96; size:8; signed:0;
+ field:u32 unknown_triggers; offset:104; size:4; signed:0;
+ field:u32 reschedule; offset:108; size:4; signed:0;
+ field:u32 out_of_window; offset:112; size:4; signed:0;
+
+print fmt: "%sFtm responder stats: success %u, partial %u, failed %u, asap %u, non asap %u, total duration %llu, unknown triggers %u, rescheduled %u, out of window %u", REC->wiphy_name, REC->success_num, REC->partial_num, REC->failed_num, REC->asap_num, REC->non_asap_num, REC->duration, REC->unknown_triggers, REC->reschedule, REC->out_of_window
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_key/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_key/format
new file mode 100644
index 000000000..983a99684
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_key/format
@@ -0,0 +1,16 @@
+name: rdev_get_key
+ID: 1337
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 mac_addr[6]; offset:60; size:6; signed:0;
+ field:u8 key_index; offset:66; size:1; signed:0;
+ field:bool pairwise; offset:67; size:1; signed:0;
+
+print fmt: "%s, netdev:%s(%d), key_index: %u, pairwise: %s, mac addr: %pM", REC->wiphy_name, REC->name, REC->ifindex, REC->key_index, (REC->pairwise) ? "true" : "false", (REC->mac_addr)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_mesh_config/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_mesh_config/format
new file mode 100644
index 000000000..ea05559ad
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_mesh_config/format
@@ -0,0 +1,13 @@
+name: rdev_get_mesh_config
+ID: 1338
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+
+print fmt: "%s, netdev:%s(%d)", REC->wiphy_name, REC->name, REC->ifindex
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_mpath/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_mpath/format
new file mode 100644
index 000000000..8df1b87c5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_mpath/format
@@ -0,0 +1,15 @@
+name: rdev_get_mpath
+ID: 1339
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 dst[6]; offset:60; size:6; signed:0;
+ field:u8 next_hop[6]; offset:66; size:6; signed:0;
+
+print fmt: "%s, netdev:%s(%d), destination: %pM, next hop: %pM", REC->wiphy_name, REC->name, REC->ifindex, (REC->dst), (REC->next_hop)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_mpp/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_mpp/format
new file mode 100644
index 000000000..df134b983
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_mpp/format
@@ -0,0 +1,15 @@
+name: rdev_get_mpp
+ID: 1340
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 dst[6]; offset:60; size:6; signed:0;
+ field:u8 mpp[6]; offset:66; size:6; signed:0;
+
+print fmt: "%s, netdev:%s(%d), destination: %pM, mpp: %pM", REC->wiphy_name, REC->name, REC->ifindex, (REC->dst), (REC->mpp)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_station/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_station/format
new file mode 100644
index 000000000..90b29619a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_station/format
@@ -0,0 +1,14 @@
+name: rdev_get_station
+ID: 1341
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 sta_mac[6]; offset:60; size:6; signed:0;
+
+print fmt: "%s, netdev:%s(%d), mac: %pM", REC->wiphy_name, REC->name, REC->ifindex, (REC->sta_mac)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_tx_power/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_tx_power/format
new file mode 100644
index 000000000..b5f3c6418
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_tx_power/format
@@ -0,0 +1,12 @@
+name: rdev_get_tx_power
+ID: 1342
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+
+print fmt: "%s, wdev(%u)", REC->wiphy_name, (REC->id)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_txq_stats/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_txq_stats/format
new file mode 100644
index 000000000..601ea6186
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_get_txq_stats/format
@@ -0,0 +1,12 @@
+name: rdev_get_txq_stats
+ID: 1343
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+
+print fmt: "%s, wdev(%u)", REC->wiphy_name, (REC->id)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_join_ibss/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_join_ibss/format
new file mode 100644
index 000000000..5bddfe37e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_join_ibss/format
@@ -0,0 +1,15 @@
+name: rdev_join_ibss
+ID: 1344
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 bssid[6]; offset:60; size:6; signed:0;
+ field:char ssid[32 + 1]; offset:66; size:33; signed:0;
+
+print fmt: "%s, netdev:%s(%d), bssid: %pM, ssid: %s", REC->wiphy_name, REC->name, REC->ifindex, (REC->bssid), REC->ssid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_join_mesh/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_join_mesh/format
new file mode 100644
index 000000000..38bd93321
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_join_mesh/format
@@ -0,0 +1,39 @@
+name: rdev_join_mesh
+ID: 1345
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u16 dot11MeshRetryTimeout; offset:60; size:2; signed:0;
+ field:u16 dot11MeshConfirmTimeout; offset:62; size:2; signed:0;
+ field:u16 dot11MeshHoldingTimeout; offset:64; size:2; signed:0;
+ field:u16 dot11MeshMaxPeerLinks; offset:66; size:2; signed:0;
+ field:u8 dot11MeshMaxRetries; offset:68; size:1; signed:0;
+ field:u8 dot11MeshTTL; offset:69; size:1; signed:0;
+ field:u8 element_ttl; offset:70; size:1; signed:0;
+ field:bool auto_open_plinks; offset:71; size:1; signed:0;
+ field:u32 dot11MeshNbrOffsetMaxNeighbor; offset:72; size:4; signed:0;
+ field:u8 dot11MeshHWMPmaxPREQretries; offset:76; size:1; signed:0;
+ field:u32 path_refresh_time; offset:80; size:4; signed:0;
+ field:u32 dot11MeshHWMPactivePathTimeout; offset:84; size:4; signed:0;
+ field:u16 min_discovery_timeout; offset:88; size:2; signed:0;
+ field:u16 dot11MeshHWMPpreqMinInterval; offset:90; size:2; signed:0;
+ field:u16 dot11MeshHWMPperrMinInterval; offset:92; size:2; signed:0;
+ field:u16 dot11MeshHWMPnetDiameterTraversalTime; offset:94; size:2; signed:0;
+ field:u8 dot11MeshHWMPRootMode; offset:96; size:1; signed:0;
+ field:u16 dot11MeshHWMPRannInterval; offset:98; size:2; signed:0;
+ field:bool dot11MeshGateAnnouncementProtocol; offset:100; size:1; signed:0;
+ field:bool dot11MeshForwarding; offset:101; size:1; signed:0;
+ field:s32 rssi_threshold; offset:104; size:4; signed:1;
+ field:u16 ht_opmode; offset:108; size:2; signed:0;
+ field:u32 dot11MeshHWMPactivePathToRootTimeout; offset:112; size:4; signed:0;
+ field:u16 dot11MeshHWMProotInterval; offset:116; size:2; signed:0;
+ field:u16 dot11MeshHWMPconfirmationInterval; offset:118; size:2; signed:0;
+ field:bool dot11MeshNolearn; offset:120; size:1; signed:0;
+
+print fmt: "%s, netdev:%s(%d)", REC->wiphy_name, REC->name, REC->ifindex
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_join_ocb/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_join_ocb/format
new file mode 100644
index 000000000..c8b9a0ab4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_join_ocb/format
@@ -0,0 +1,13 @@
+name: rdev_join_ocb
+ID: 1346
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+
+print fmt: "%s, netdev:%s(%d)", REC->wiphy_name, REC->name, REC->ifindex
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_leave_ibss/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_leave_ibss/format
new file mode 100644
index 000000000..54e90b419
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_leave_ibss/format
@@ -0,0 +1,13 @@
+name: rdev_leave_ibss
+ID: 1347
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+
+print fmt: "%s, netdev:%s(%d)", REC->wiphy_name, REC->name, REC->ifindex
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_leave_mesh/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_leave_mesh/format
new file mode 100644
index 000000000..f8d4f08ea
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_leave_mesh/format
@@ -0,0 +1,13 @@
+name: rdev_leave_mesh
+ID: 1348
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+
+print fmt: "%s, netdev:%s(%d)", REC->wiphy_name, REC->name, REC->ifindex
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_leave_ocb/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_leave_ocb/format
new file mode 100644
index 000000000..5d89836d5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_leave_ocb/format
@@ -0,0 +1,13 @@
+name: rdev_leave_ocb
+ID: 1349
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+
+print fmt: "%s, netdev:%s(%d)", REC->wiphy_name, REC->name, REC->ifindex
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_libertas_set_mesh_channel/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_libertas_set_mesh_channel/format
new file mode 100644
index 000000000..1302ac2e3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_libertas_set_mesh_channel/format
@@ -0,0 +1,16 @@
+name: rdev_libertas_set_mesh_channel
+ID: 1350
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:enum nl80211_band band; offset:60; size:4; signed:0;
+ field:u32 center_freq; offset:64; size:4; signed:0;
+ field:u16 freq_offset; offset:68; size:2; signed:0;
+
+print fmt: "%s, netdev:%s(%d), band: %d, freq: %u.%03u", REC->wiphy_name, REC->name, REC->ifindex, REC->band, REC->center_freq, REC->freq_offset
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_mgmt_tx/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_mgmt_tx/format
new file mode 100644
index 000000000..e326c7366
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_mgmt_tx/format
@@ -0,0 +1,19 @@
+name: rdev_mgmt_tx
+ID: 1351
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+ field:enum nl80211_band band; offset:44; size:4; signed:0;
+ field:u32 center_freq; offset:48; size:4; signed:0;
+ field:u16 freq_offset; offset:52; size:2; signed:0;
+ field:bool offchan; offset:54; size:1; signed:0;
+ field:unsigned int wait; offset:56; size:4; signed:0;
+ field:bool no_cck; offset:60; size:1; signed:0;
+ field:bool dont_wait_for_ack; offset:61; size:1; signed:0;
+
+print fmt: "%s, wdev(%u), band: %d, freq: %u.%03u, offchan: %s, wait: %u, no cck: %s, dont wait for ack: %s", REC->wiphy_name, (REC->id), REC->band, REC->center_freq, REC->freq_offset, (REC->offchan) ? "true" : "false", REC->wait, (REC->no_cck) ? "true" : "false", (REC->dont_wait_for_ack) ? "true" : "false"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_mgmt_tx_cancel_wait/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_mgmt_tx_cancel_wait/format
new file mode 100644
index 000000000..bbbcec65e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_mgmt_tx_cancel_wait/format
@@ -0,0 +1,13 @@
+name: rdev_mgmt_tx_cancel_wait
+ID: 1352
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+ field:u64 cookie; offset:48; size:8; signed:0;
+
+print fmt: "%s, wdev(%u), cookie: %llu ", REC->wiphy_name, (REC->id), REC->cookie
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_nan_change_conf/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_nan_change_conf/format
new file mode 100644
index 000000000..7532fdc30
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_nan_change_conf/format
@@ -0,0 +1,15 @@
+name: rdev_nan_change_conf
+ID: 1353
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+ field:u8 master_pref; offset:44; size:1; signed:0;
+ field:u8 bands; offset:45; size:1; signed:0;
+ field:u32 changes; offset:48; size:4; signed:0;
+
+print fmt: "%s, wdev(%u), master preference: %u, bands: 0x%0x, changes: %x", REC->wiphy_name, (REC->id), REC->master_pref, REC->bands, REC->changes
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_probe_client/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_probe_client/format
new file mode 100644
index 000000000..c7b0fee35
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_probe_client/format
@@ -0,0 +1,14 @@
+name: rdev_probe_client
+ID: 1354
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 peer[6]; offset:60; size:6; signed:0;
+
+print fmt: "%s, netdev:%s(%d), %pM", REC->wiphy_name, REC->name, REC->ifindex, (REC->peer)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_probe_mesh_link/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_probe_mesh_link/format
new file mode 100644
index 000000000..7ce46a91f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_probe_mesh_link/format
@@ -0,0 +1,14 @@
+name: rdev_probe_mesh_link
+ID: 1355
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 dest[6]; offset:60; size:6; signed:0;
+
+print fmt: "%s, netdev:%s(%d), %pM", REC->wiphy_name, REC->name, REC->ifindex, (REC->dest)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_remain_on_channel/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_remain_on_channel/format
new file mode 100644
index 000000000..fc5935e47
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_remain_on_channel/format
@@ -0,0 +1,16 @@
+name: rdev_remain_on_channel
+ID: 1356
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+ field:enum nl80211_band band; offset:44; size:4; signed:0;
+ field:u32 center_freq; offset:48; size:4; signed:0;
+ field:u16 freq_offset; offset:52; size:2; signed:0;
+ field:unsigned int duration; offset:56; size:4; signed:0;
+
+print fmt: "%s, wdev(%u), band: %d, freq: %u.%03u, duration: %u", REC->wiphy_name, (REC->id), REC->band, REC->center_freq, REC->freq_offset, REC->duration
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_reset_tid_config/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_reset_tid_config/format
new file mode 100644
index 000000000..5b58269bb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_reset_tid_config/format
@@ -0,0 +1,15 @@
+name: rdev_reset_tid_config
+ID: 1357
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 peer[6]; offset:60; size:6; signed:0;
+ field:u8 tids; offset:66; size:1; signed:0;
+
+print fmt: "%s, netdev:%s(%d), peer: %pM, tids: 0x%x", REC->wiphy_name, REC->name, REC->ifindex, (REC->peer), REC->tids
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_resume/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_resume/format
new file mode 100644
index 000000000..8bba5e5b7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_resume/format
@@ -0,0 +1,11 @@
+name: rdev_resume
+ID: 1358
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_chandef/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_chandef/format
new file mode 100644
index 000000000..e932f3f2a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_chandef/format
@@ -0,0 +1,19 @@
+name: rdev_return_chandef
+ID: 1359
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:int ret; offset:40; size:4; signed:1;
+ field:enum nl80211_band band; offset:44; size:4; signed:0;
+ field:u32 control_freq; offset:48; size:4; signed:0;
+ field:u32 freq_offset; offset:52; size:4; signed:0;
+ field:u32 width; offset:56; size:4; signed:0;
+ field:u32 center_freq1; offset:60; size:4; signed:0;
+ field:u32 freq1_offset; offset:64; size:4; signed:0;
+ field:u32 center_freq2; offset:68; size:4; signed:0;
+
+print fmt: "%s, band: %d, control freq: %u.%03u, width: %d, cf1: %u.%03u, cf2: %u, ret: %d", REC->wiphy_name, REC->band, REC->control_freq, REC->freq_offset, REC->width, REC->center_freq1, REC->freq1_offset, REC->center_freq2, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int/format
new file mode 100644
index 000000000..b820ac5d1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int/format
@@ -0,0 +1,12 @@
+name: rdev_return_int
+ID: 1360
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:int ret; offset:40; size:4; signed:1;
+
+print fmt: "%s, returned: %d", REC->wiphy_name, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_cookie/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_cookie/format
new file mode 100644
index 000000000..7b1d9f6c9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_cookie/format
@@ -0,0 +1,13 @@
+name: rdev_return_int_cookie
+ID: 1361
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:int ret; offset:40; size:4; signed:1;
+ field:u64 cookie; offset:48; size:8; signed:0;
+
+print fmt: "%s, returned %d, cookie: %llu", REC->wiphy_name, REC->ret, REC->cookie
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_int/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_int/format
new file mode 100644
index 000000000..0b5a21782
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_int/format
@@ -0,0 +1,13 @@
+name: rdev_return_int_int
+ID: 1362
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:int func_ret; offset:40; size:4; signed:1;
+ field:int func_fill; offset:44; size:4; signed:1;
+
+print fmt: "%s, function returns: %d, function filled: %d", REC->wiphy_name, REC->func_ret, REC->func_fill
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_mesh_config/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_mesh_config/format
new file mode 100644
index 000000000..ca709e3fe
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_mesh_config/format
@@ -0,0 +1,38 @@
+name: rdev_return_int_mesh_config
+ID: 1363
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u16 dot11MeshRetryTimeout; offset:40; size:2; signed:0;
+ field:u16 dot11MeshConfirmTimeout; offset:42; size:2; signed:0;
+ field:u16 dot11MeshHoldingTimeout; offset:44; size:2; signed:0;
+ field:u16 dot11MeshMaxPeerLinks; offset:46; size:2; signed:0;
+ field:u8 dot11MeshMaxRetries; offset:48; size:1; signed:0;
+ field:u8 dot11MeshTTL; offset:49; size:1; signed:0;
+ field:u8 element_ttl; offset:50; size:1; signed:0;
+ field:bool auto_open_plinks; offset:51; size:1; signed:0;
+ field:u32 dot11MeshNbrOffsetMaxNeighbor; offset:52; size:4; signed:0;
+ field:u8 dot11MeshHWMPmaxPREQretries; offset:56; size:1; signed:0;
+ field:u32 path_refresh_time; offset:60; size:4; signed:0;
+ field:u32 dot11MeshHWMPactivePathTimeout; offset:64; size:4; signed:0;
+ field:u16 min_discovery_timeout; offset:68; size:2; signed:0;
+ field:u16 dot11MeshHWMPpreqMinInterval; offset:70; size:2; signed:0;
+ field:u16 dot11MeshHWMPperrMinInterval; offset:72; size:2; signed:0;
+ field:u16 dot11MeshHWMPnetDiameterTraversalTime; offset:74; size:2; signed:0;
+ field:u8 dot11MeshHWMPRootMode; offset:76; size:1; signed:0;
+ field:u16 dot11MeshHWMPRannInterval; offset:78; size:2; signed:0;
+ field:bool dot11MeshGateAnnouncementProtocol; offset:80; size:1; signed:0;
+ field:bool dot11MeshForwarding; offset:81; size:1; signed:0;
+ field:s32 rssi_threshold; offset:84; size:4; signed:1;
+ field:u16 ht_opmode; offset:88; size:2; signed:0;
+ field:u32 dot11MeshHWMPactivePathToRootTimeout; offset:92; size:4; signed:0;
+ field:u16 dot11MeshHWMProotInterval; offset:96; size:2; signed:0;
+ field:u16 dot11MeshHWMPconfirmationInterval; offset:98; size:2; signed:0;
+ field:bool dot11MeshNolearn; offset:100; size:1; signed:0;
+ field:int ret; offset:104; size:4; signed:1;
+
+print fmt: "%s, returned: %d", REC->wiphy_name, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_mpath_info/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_mpath_info/format
new file mode 100644
index 000000000..153857afc
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_mpath_info/format
@@ -0,0 +1,21 @@
+name: rdev_return_int_mpath_info
+ID: 1364
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:int ret; offset:40; size:4; signed:1;
+ field:int generation; offset:44; size:4; signed:1;
+ field:u32 filled; offset:48; size:4; signed:0;
+ field:u32 frame_qlen; offset:52; size:4; signed:0;
+ field:u32 sn; offset:56; size:4; signed:0;
+ field:u32 metric; offset:60; size:4; signed:0;
+ field:u32 exptime; offset:64; size:4; signed:0;
+ field:u32 discovery_timeout; offset:68; size:4; signed:0;
+ field:u8 discovery_retries; offset:72; size:1; signed:0;
+ field:u8 flags; offset:73; size:1; signed:0;
+
+print fmt: "%s, returned %d. mpath info - generation: %d, filled: %u, frame qlen: %u, sn: %u, metric: %u, exptime: %u, discovery timeout: %u, discovery retries: %u, flags: %u", REC->wiphy_name, REC->ret, REC->generation, REC->filled, REC->frame_qlen, REC->sn, REC->metric, REC->exptime, REC->discovery_timeout, REC->discovery_retries, REC->flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_station_info/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_station_info/format
new file mode 100644
index 000000000..79c6438cd
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_station_info/format
@@ -0,0 +1,26 @@
+name: rdev_return_int_station_info
+ID: 1365
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:int ret; offset:40; size:4; signed:1;
+ field:int generation; offset:44; size:4; signed:1;
+ field:u32 connected_time; offset:48; size:4; signed:0;
+ field:u32 inactive_time; offset:52; size:4; signed:0;
+ field:u32 rx_bytes; offset:56; size:4; signed:0;
+ field:u32 tx_bytes; offset:60; size:4; signed:0;
+ field:u32 rx_packets; offset:64; size:4; signed:0;
+ field:u32 tx_packets; offset:68; size:4; signed:0;
+ field:u32 tx_retries; offset:72; size:4; signed:0;
+ field:u32 tx_failed; offset:76; size:4; signed:0;
+ field:u32 rx_dropped_misc; offset:80; size:4; signed:0;
+ field:u32 beacon_loss_count; offset:84; size:4; signed:0;
+ field:u16 llid; offset:88; size:2; signed:0;
+ field:u16 plid; offset:90; size:2; signed:0;
+ field:u8 plink_state; offset:92; size:1; signed:0;
+
+print fmt: "%s, returned %d", REC->wiphy_name, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_survey_info/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_survey_info/format
new file mode 100644
index 000000000..0b764681f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_survey_info/format
@@ -0,0 +1,23 @@
+name: rdev_return_int_survey_info
+ID: 1366
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_band band; offset:40; size:4; signed:0;
+ field:u32 center_freq; offset:44; size:4; signed:0;
+ field:u16 freq_offset; offset:48; size:2; signed:0;
+ field:int ret; offset:52; size:4; signed:1;
+ field:u64 time; offset:56; size:8; signed:0;
+ field:u64 time_busy; offset:64; size:8; signed:0;
+ field:u64 time_ext_busy; offset:72; size:8; signed:0;
+ field:u64 time_rx; offset:80; size:8; signed:0;
+ field:u64 time_tx; offset:88; size:8; signed:0;
+ field:u64 time_scan; offset:96; size:8; signed:0;
+ field:u32 filled; offset:104; size:4; signed:0;
+ field:s8 noise; offset:108; size:1; signed:1;
+
+print fmt: "%s, returned: %d, band: %d, freq: %u.%03u, channel time: %llu, channel time busy: %llu, channel time extension busy: %llu, channel time rx: %llu, channel time tx: %llu, scan time: %llu, filled: %u, noise: %d", REC->wiphy_name, REC->ret, REC->band, REC->center_freq, REC->freq_offset, REC->time, REC->time_busy, REC->time_ext_busy, REC->time_rx, REC->time_tx, REC->time_scan, REC->filled, REC->noise
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_tx_rx/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_tx_rx/format
new file mode 100644
index 000000000..bfaada51c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_int_tx_rx/format
@@ -0,0 +1,14 @@
+name: rdev_return_int_tx_rx
+ID: 1367
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:int ret; offset:40; size:4; signed:1;
+ field:u32 tx; offset:44; size:4; signed:0;
+ field:u32 rx; offset:48; size:4; signed:0;
+
+print fmt: "%s, returned %d, tx: %u, rx: %u", REC->wiphy_name, REC->ret, REC->tx, REC->rx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_void/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_void/format
new file mode 100644
index 000000000..f91a39f19
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_void/format
@@ -0,0 +1,11 @@
+name: rdev_return_void
+ID: 1368
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_void_tx_rx/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_void_tx_rx/format
new file mode 100644
index 000000000..153d3a74c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_void_tx_rx/format
@@ -0,0 +1,15 @@
+name: rdev_return_void_tx_rx
+ID: 1369
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 tx; offset:40; size:4; signed:0;
+ field:u32 tx_max; offset:44; size:4; signed:0;
+ field:u32 rx; offset:48; size:4; signed:0;
+ field:u32 rx_max; offset:52; size:4; signed:0;
+
+print fmt: "%s, tx: %u, tx_max: %u, rx: %u, rx_max: %u ", REC->wiphy_name, REC->tx, REC->tx_max, REC->rx, REC->rx_max
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_wdev/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_wdev/format
new file mode 100644
index 000000000..2b1bc97b4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_return_wdev/format
@@ -0,0 +1,12 @@
+name: rdev_return_wdev
+ID: 1370
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+
+print fmt: "%s, wdev(%u)", REC->wiphy_name, (REC->id)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_rfkill_poll/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_rfkill_poll/format
new file mode 100644
index 000000000..819faf5aa
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_rfkill_poll/format
@@ -0,0 +1,11 @@
+name: rdev_rfkill_poll
+ID: 1371
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_scan/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_scan/format
new file mode 100644
index 000000000..dfb09261a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_scan/format
@@ -0,0 +1,11 @@
+name: rdev_scan
+ID: 1372
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_sched_scan_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_sched_scan_start/format
new file mode 100644
index 000000000..fd1929e97
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_sched_scan_start/format
@@ -0,0 +1,14 @@
+name: rdev_sched_scan_start
+ID: 1373
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u64 id; offset:64; size:8; signed:0;
+
+print fmt: "%s, netdev:%s(%d), id: %llu", REC->wiphy_name, REC->name, REC->ifindex, REC->id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_sched_scan_stop/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_sched_scan_stop/format
new file mode 100644
index 000000000..3a9e7a616
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_sched_scan_stop/format
@@ -0,0 +1,14 @@
+name: rdev_sched_scan_stop
+ID: 1374
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u64 id; offset:64; size:8; signed:0;
+
+print fmt: "%s, netdev:%s(%d), id: %llu", REC->wiphy_name, REC->name, REC->ifindex, REC->id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_antenna/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_antenna/format
new file mode 100644
index 000000000..16cb2e086
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_antenna/format
@@ -0,0 +1,13 @@
+name: rdev_set_antenna
+ID: 1375
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 tx; offset:40; size:4; signed:0;
+ field:u32 rx; offset:44; size:4; signed:0;
+
+print fmt: "%s, tx: %u, rx: %u ", REC->wiphy_name, REC->tx, REC->rx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_ap_chanwidth/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_ap_chanwidth/format
new file mode 100644
index 000000000..0b9eff475
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_ap_chanwidth/format
@@ -0,0 +1,20 @@
+name: rdev_set_ap_chanwidth
+ID: 1376
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:enum nl80211_band band; offset:60; size:4; signed:0;
+ field:u32 control_freq; offset:64; size:4; signed:0;
+ field:u32 freq_offset; offset:68; size:4; signed:0;
+ field:u32 width; offset:72; size:4; signed:0;
+ field:u32 center_freq1; offset:76; size:4; signed:0;
+ field:u32 freq1_offset; offset:80; size:4; signed:0;
+ field:u32 center_freq2; offset:84; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), band: %d, control freq: %u.%03u, width: %d, cf1: %u.%03u, cf2: %u", REC->wiphy_name, REC->name, REC->ifindex, REC->band, REC->control_freq, REC->freq_offset, REC->width, REC->center_freq1, REC->freq1_offset, REC->center_freq2
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_bitrate_mask/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_bitrate_mask/format
new file mode 100644
index 000000000..8312786a2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_bitrate_mask/format
@@ -0,0 +1,14 @@
+name: rdev_set_bitrate_mask
+ID: 1377
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 peer[6]; offset:60; size:6; signed:0;
+
+print fmt: "%s, netdev:%s(%d), peer: %pM", REC->wiphy_name, REC->name, REC->ifindex, (REC->peer)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_coalesce/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_coalesce/format
new file mode 100644
index 000000000..ce6ca11d5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_coalesce/format
@@ -0,0 +1,12 @@
+name: rdev_set_coalesce
+ID: 1378
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:int n_rules; offset:40; size:4; signed:1;
+
+print fmt: "%s, n_rules=%d", REC->wiphy_name, REC->n_rules
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_cqm_rssi_config/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_cqm_rssi_config/format
new file mode 100644
index 000000000..90c79d887
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_cqm_rssi_config/format
@@ -0,0 +1,15 @@
+name: rdev_set_cqm_rssi_config
+ID: 1379
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:s32 rssi_thold; offset:60; size:4; signed:1;
+ field:u32 rssi_hyst; offset:64; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), rssi_thold: %d, rssi_hyst: %u ", REC->wiphy_name, REC->name, REC->ifindex, REC->rssi_thold, REC->rssi_hyst
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_cqm_rssi_range_config/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_cqm_rssi_range_config/format
new file mode 100644
index 000000000..cace81448
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_cqm_rssi_range_config/format
@@ -0,0 +1,15 @@
+name: rdev_set_cqm_rssi_range_config
+ID: 1380
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:s32 rssi_low; offset:60; size:4; signed:1;
+ field:s32 rssi_high; offset:64; size:4; signed:1;
+
+print fmt: "%s, netdev:%s(%d), range: %d - %d ", REC->wiphy_name, REC->name, REC->ifindex, REC->rssi_low, REC->rssi_high
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_cqm_txe_config/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_cqm_txe_config/format
new file mode 100644
index 000000000..d580d0ee7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_cqm_txe_config/format
@@ -0,0 +1,16 @@
+name: rdev_set_cqm_txe_config
+ID: 1381
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u32 rate; offset:60; size:4; signed:0;
+ field:u32 pkts; offset:64; size:4; signed:0;
+ field:u32 intvl; offset:68; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), rate: %u, packets: %u, interval: %u", REC->wiphy_name, REC->name, REC->ifindex, REC->rate, REC->pkts, REC->intvl
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_default_beacon_key/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_default_beacon_key/format
new file mode 100644
index 000000000..c14e0762c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_default_beacon_key/format
@@ -0,0 +1,14 @@
+name: rdev_set_default_beacon_key
+ID: 1382
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 key_index; offset:60; size:1; signed:0;
+
+print fmt: "%s, netdev:%s(%d), key index: %u", REC->wiphy_name, REC->name, REC->ifindex, REC->key_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_default_key/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_default_key/format
new file mode 100644
index 000000000..98720fa0b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_default_key/format
@@ -0,0 +1,16 @@
+name: rdev_set_default_key
+ID: 1383
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 key_index; offset:60; size:1; signed:0;
+ field:bool unicast; offset:61; size:1; signed:0;
+ field:bool multicast; offset:62; size:1; signed:0;
+
+print fmt: "%s, netdev:%s(%d), key index: %u, unicast: %s, multicast: %s", REC->wiphy_name, REC->name, REC->ifindex, REC->key_index, (REC->unicast) ? "true" : "false", (REC->multicast) ? "true" : "false"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_default_mgmt_key/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_default_mgmt_key/format
new file mode 100644
index 000000000..2665224ba
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_default_mgmt_key/format
@@ -0,0 +1,14 @@
+name: rdev_set_default_mgmt_key
+ID: 1384
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 key_index; offset:60; size:1; signed:0;
+
+print fmt: "%s, netdev:%s(%d), key index: %u", REC->wiphy_name, REC->name, REC->ifindex, REC->key_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_mac_acl/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_mac_acl/format
new file mode 100644
index 000000000..9d31b6014
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_mac_acl/format
@@ -0,0 +1,14 @@
+name: rdev_set_mac_acl
+ID: 1385
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u32 acl_policy; offset:60; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), acl policy: %d", REC->wiphy_name, REC->name, REC->ifindex, REC->acl_policy
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_mcast_rate/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_mcast_rate/format
new file mode 100644
index 000000000..075a62a0a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_mcast_rate/format
@@ -0,0 +1,14 @@
+name: rdev_set_mcast_rate
+ID: 1386
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:int mcast_rate[NUM_NL80211_BANDS]; offset:60; size:20; signed:1;
+
+print fmt: "%s, netdev:%s(%d), mcast_rates [2.4GHz=0x%x, 5.2GHz=0x%x, 6GHz=0x%x, 60GHz=0x%x]", REC->wiphy_name, REC->name, REC->ifindex, REC->mcast_rate[NL80211_BAND_2GHZ], REC->mcast_rate[NL80211_BAND_5GHZ], REC->mcast_rate[NL80211_BAND_6GHZ], REC->mcast_rate[NL80211_BAND_60GHZ]
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_monitor_channel/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_monitor_channel/format
new file mode 100644
index 000000000..ce8f6f30b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_monitor_channel/format
@@ -0,0 +1,18 @@
+name: rdev_set_monitor_channel
+ID: 1387
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_band band; offset:40; size:4; signed:0;
+ field:u32 control_freq; offset:44; size:4; signed:0;
+ field:u32 freq_offset; offset:48; size:4; signed:0;
+ field:u32 width; offset:52; size:4; signed:0;
+ field:u32 center_freq1; offset:56; size:4; signed:0;
+ field:u32 freq1_offset; offset:60; size:4; signed:0;
+ field:u32 center_freq2; offset:64; size:4; signed:0;
+
+print fmt: "%s, band: %d, control freq: %u.%03u, width: %d, cf1: %u.%03u, cf2: %u", REC->wiphy_name, REC->band, REC->control_freq, REC->freq_offset, REC->width, REC->center_freq1, REC->freq1_offset, REC->center_freq2
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_multicast_to_unicast/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_multicast_to_unicast/format
new file mode 100644
index 000000000..50b92c6b1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_multicast_to_unicast/format
@@ -0,0 +1,14 @@
+name: rdev_set_multicast_to_unicast
+ID: 1388
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:bool enabled; offset:60; size:1; signed:0;
+
+print fmt: "%s, netdev:%s(%d), unicast: %s", REC->wiphy_name, REC->name, REC->ifindex, (REC->enabled) ? "true" : "false"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_noack_map/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_noack_map/format
new file mode 100644
index 000000000..0fd7b972d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_noack_map/format
@@ -0,0 +1,14 @@
+name: rdev_set_noack_map
+ID: 1389
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u16 noack_map; offset:60; size:2; signed:0;
+
+print fmt: "%s, netdev:%s(%d), noack_map: %u", REC->wiphy_name, REC->name, REC->ifindex, REC->noack_map
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_pmk/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_pmk/format
new file mode 100644
index 000000000..cdc7c663e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_pmk/format
@@ -0,0 +1,18 @@
+name: rdev_set_pmk
+ID: 1390
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 aa[6]; offset:60; size:6; signed:0;
+ field:u8 pmk_len; offset:66; size:1; signed:0;
+ field:u8 pmk_r0_name_len; offset:67; size:1; signed:0;
+ field:__data_loc u8[] pmk; offset:68; size:4; signed:0;
+ field:__data_loc u8[] pmk_r0_name; offset:72; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), %pMpmk_len=%u, pmk: %s pmk_r0_name: %s", REC->wiphy_name, REC->name, REC->ifindex, (REC->aa), REC->pmk_len, __print_array(__get_dynamic_array(pmk), __get_dynamic_array_len(pmk), 1), REC->pmk_r0_name_len ? __print_array(__get_dynamic_array(pmk_r0_name), __get_dynamic_array_len(pmk_r0_name), 1) : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_pmksa/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_pmksa/format
new file mode 100644
index 000000000..08e9c20cb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_pmksa/format
@@ -0,0 +1,14 @@
+name: rdev_set_pmksa
+ID: 1391
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 bssid[6]; offset:60; size:6; signed:0;
+
+print fmt: "%s, netdev:%s(%d), bssid: %pM", REC->wiphy_name, REC->name, REC->ifindex, (REC->bssid)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_power_mgmt/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_power_mgmt/format
new file mode 100644
index 000000000..e6afe4c45
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_power_mgmt/format
@@ -0,0 +1,15 @@
+name: rdev_set_power_mgmt
+ID: 1392
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:bool enabled; offset:60; size:1; signed:0;
+ field:int timeout; offset:64; size:4; signed:1;
+
+print fmt: "%s, netdev:%s(%d), %senabled, timeout: %d ", REC->wiphy_name, REC->name, REC->ifindex, REC->enabled ? "" : "not ", REC->timeout
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_qos_map/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_qos_map/format
new file mode 100644
index 000000000..aac23afad
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_qos_map/format
@@ -0,0 +1,16 @@
+name: rdev_set_qos_map
+ID: 1393
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 num_des; offset:60; size:1; signed:0;
+ field:u8 dscp_exception[2 * 21]; offset:61; size:42; signed:0;
+ field:u8 up[16]; offset:103; size:16; signed:0;
+
+print fmt: "%s, netdev:%s(%d), num_des: %u", REC->wiphy_name, REC->name, REC->ifindex, REC->num_des
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_rekey_data/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_rekey_data/format
new file mode 100644
index 000000000..1b0daadb1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_rekey_data/format
@@ -0,0 +1,13 @@
+name: rdev_set_rekey_data
+ID: 1394
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+
+print fmt: "%s, netdev:%s(%d)", REC->wiphy_name, REC->name, REC->ifindex
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_tid_config/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_tid_config/format
new file mode 100644
index 000000000..44abc24ba
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_tid_config/format
@@ -0,0 +1,14 @@
+name: rdev_set_tid_config
+ID: 1395
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 peer[6]; offset:60; size:6; signed:0;
+
+print fmt: "%s, netdev:%s(%d), peer: %pM", REC->wiphy_name, REC->name, REC->ifindex, (REC->peer)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_tx_power/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_tx_power/format
new file mode 100644
index 000000000..83a10984d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_tx_power/format
@@ -0,0 +1,14 @@
+name: rdev_set_tx_power
+ID: 1396
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+ field:enum nl80211_tx_power_setting type; offset:44; size:4; signed:0;
+ field:int mbm; offset:48; size:4; signed:1;
+
+print fmt: "%s, wdev(%u), type: %u, mbm: %d", REC->wiphy_name, (REC->id),REC->type, REC->mbm
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_txq_params/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_txq_params/format
new file mode 100644
index 000000000..0d2fe485e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_txq_params/format
@@ -0,0 +1,18 @@
+name: rdev_set_txq_params
+ID: 1397
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:enum nl80211_ac ac; offset:60; size:4; signed:0;
+ field:u16 txop; offset:64; size:2; signed:0;
+ field:u16 cwmin; offset:66; size:2; signed:0;
+ field:u16 cwmax; offset:68; size:2; signed:0;
+ field:u8 aifs; offset:70; size:1; signed:0;
+
+print fmt: "%s, netdev:%s(%d), ac: %d, txop: %u, cwmin: %u, cwmax: %u, aifs: %u", REC->wiphy_name, REC->name, REC->ifindex, REC->ac, REC->txop, REC->cwmin, REC->cwmax, REC->aifs
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_wakeup/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_wakeup/format
new file mode 100644
index 000000000..2579cbf68
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_wakeup/format
@@ -0,0 +1,12 @@
+name: rdev_set_wakeup
+ID: 1398
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:bool enabled; offset:40; size:1; signed:0;
+
+print fmt: "%s, %senabled ", REC->wiphy_name, REC->enabled ? "" : "not "
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_wds_peer/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_wds_peer/format
new file mode 100644
index 000000000..31e471d14
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_wds_peer/format
@@ -0,0 +1,14 @@
+name: rdev_set_wds_peer
+ID: 1399
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 sta_mac[6]; offset:60; size:6; signed:0;
+
+print fmt: "%s, netdev:%s(%d), mac: %pM", REC->wiphy_name, REC->name, REC->ifindex, (REC->sta_mac)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_wiphy_params/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_wiphy_params/format
new file mode 100644
index 000000000..67b212e4c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_set_wiphy_params/format
@@ -0,0 +1,12 @@
+name: rdev_set_wiphy_params
+ID: 1400
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 changed; offset:40; size:4; signed:0;
+
+print fmt: "%s, changed: %u", REC->wiphy_name, REC->changed
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_start_ap/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_start_ap/format
new file mode 100644
index 000000000..f025f263e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_start_ap/format
@@ -0,0 +1,28 @@
+name: rdev_start_ap
+ID: 1401
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:enum nl80211_band band; offset:60; size:4; signed:0;
+ field:u32 control_freq; offset:64; size:4; signed:0;
+ field:u32 freq_offset; offset:68; size:4; signed:0;
+ field:u32 width; offset:72; size:4; signed:0;
+ field:u32 center_freq1; offset:76; size:4; signed:0;
+ field:u32 freq1_offset; offset:80; size:4; signed:0;
+ field:u32 center_freq2; offset:84; size:4; signed:0;
+ field:int beacon_interval; offset:88; size:4; signed:1;
+ field:int dtim_period; offset:92; size:4; signed:1;
+ field:char ssid[32 + 1]; offset:96; size:33; signed:0;
+ field:enum nl80211_hidden_ssid hidden_ssid; offset:132; size:4; signed:0;
+ field:u32 wpa_ver; offset:136; size:4; signed:0;
+ field:bool privacy; offset:140; size:1; signed:0;
+ field:enum nl80211_auth_type auth_type; offset:144; size:4; signed:0;
+ field:int inactivity_timeout; offset:148; size:4; signed:1;
+
+print fmt: "%s, netdev:%s(%d), AP settings - ssid: %s, band: %d, control freq: %u.%03u, width: %d, cf1: %u.%03u, cf2: %u, beacon interval: %d, dtim period: %d, hidden ssid: %d, wpa versions: %u, privacy: %s, auth type: %d, inactivity timeout: %d", REC->wiphy_name, REC->name, REC->ifindex, REC->ssid, REC->band, REC->control_freq, REC->freq_offset, REC->width, REC->center_freq1, REC->freq1_offset, REC->center_freq2, REC->beacon_interval, REC->dtim_period, REC->hidden_ssid, REC->wpa_ver, (REC->privacy) ? "true" : "false", REC->auth_type, REC->inactivity_timeout
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_start_nan/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_start_nan/format
new file mode 100644
index 000000000..812adb097
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_start_nan/format
@@ -0,0 +1,14 @@
+name: rdev_start_nan
+ID: 1402
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+ field:u8 master_pref; offset:44; size:1; signed:0;
+ field:u8 bands; offset:45; size:1; signed:0;
+
+print fmt: "%s, wdev(%u), master preference: %u, bands: 0x%0x", REC->wiphy_name, (REC->id), REC->master_pref, REC->bands
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_start_p2p_device/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_start_p2p_device/format
new file mode 100644
index 000000000..2a2cbeef2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_start_p2p_device/format
@@ -0,0 +1,12 @@
+name: rdev_start_p2p_device
+ID: 1403
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+
+print fmt: "%s, wdev(%u)", REC->wiphy_name, (REC->id)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_start_pmsr/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_start_pmsr/format
new file mode 100644
index 000000000..82c04b60a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_start_pmsr/format
@@ -0,0 +1,13 @@
+name: rdev_start_pmsr
+ID: 1404
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+ field:u64 cookie; offset:48; size:8; signed:0;
+
+print fmt: "%s, wdev(%u), cookie: %lld", REC->wiphy_name, (REC->id), (unsigned long long)REC->cookie
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_start_radar_detection/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_start_radar_detection/format
new file mode 100644
index 000000000..6993dd1f4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_start_radar_detection/format
@@ -0,0 +1,21 @@
+name: rdev_start_radar_detection
+ID: 1405
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:enum nl80211_band band; offset:60; size:4; signed:0;
+ field:u32 control_freq; offset:64; size:4; signed:0;
+ field:u32 freq_offset; offset:68; size:4; signed:0;
+ field:u32 width; offset:72; size:4; signed:0;
+ field:u32 center_freq1; offset:76; size:4; signed:0;
+ field:u32 freq1_offset; offset:80; size:4; signed:0;
+ field:u32 center_freq2; offset:84; size:4; signed:0;
+ field:u32 cac_time_ms; offset:88; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), band: %d, control freq: %u.%03u, width: %d, cf1: %u.%03u, cf2: %u, cac_time_ms=%u", REC->wiphy_name, REC->name, REC->ifindex, REC->band, REC->control_freq, REC->freq_offset, REC->width, REC->center_freq1, REC->freq1_offset, REC->center_freq2, REC->cac_time_ms
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_stop_ap/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_stop_ap/format
new file mode 100644
index 000000000..0a37c0cfd
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_stop_ap/format
@@ -0,0 +1,13 @@
+name: rdev_stop_ap
+ID: 1406
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+
+print fmt: "%s, netdev:%s(%d)", REC->wiphy_name, REC->name, REC->ifindex
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_stop_nan/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_stop_nan/format
new file mode 100644
index 000000000..fe0758573
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_stop_nan/format
@@ -0,0 +1,12 @@
+name: rdev_stop_nan
+ID: 1407
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+
+print fmt: "%s, wdev(%u)", REC->wiphy_name, (REC->id)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_stop_p2p_device/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_stop_p2p_device/format
new file mode 100644
index 000000000..63ed3ee18
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_stop_p2p_device/format
@@ -0,0 +1,12 @@
+name: rdev_stop_p2p_device
+ID: 1408
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+
+print fmt: "%s, wdev(%u)", REC->wiphy_name, (REC->id)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_suspend/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_suspend/format
new file mode 100644
index 000000000..5872fd33c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_suspend/format
@@ -0,0 +1,19 @@
+name: rdev_suspend
+ID: 1409
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:bool any; offset:40; size:1; signed:0;
+ field:bool disconnect; offset:41; size:1; signed:0;
+ field:bool magic_pkt; offset:42; size:1; signed:0;
+ field:bool gtk_rekey_failure; offset:43; size:1; signed:0;
+ field:bool eap_identity_req; offset:44; size:1; signed:0;
+ field:bool four_way_handshake; offset:45; size:1; signed:0;
+ field:bool rfkill_release; offset:46; size:1; signed:0;
+ field:bool valid_wow; offset:47; size:1; signed:0;
+
+print fmt: "%s, wow%s - any: %d, disconnect: %d, magic pkt: %d, gtk rekey failure: %d, eap identify req: %d, four way handshake: %d, rfkill release: %d.", REC->wiphy_name, REC->valid_wow ? "" : "(Not configured!)", REC->any, REC->disconnect, REC->magic_pkt, REC->gtk_rekey_failure, REC->eap_identity_req, REC->four_way_handshake, REC->rfkill_release
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_tdls_cancel_channel_switch/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_tdls_cancel_channel_switch/format
new file mode 100644
index 000000000..1676803fe
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_tdls_cancel_channel_switch/format
@@ -0,0 +1,14 @@
+name: rdev_tdls_cancel_channel_switch
+ID: 1410
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 addr[6]; offset:60; size:6; signed:0;
+
+print fmt: "%s, netdev:%s(%d), %pM", REC->wiphy_name, REC->name, REC->ifindex, (REC->addr)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_tdls_channel_switch/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_tdls_channel_switch/format
new file mode 100644
index 000000000..d46b2aec7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_tdls_channel_switch/format
@@ -0,0 +1,22 @@
+name: rdev_tdls_channel_switch
+ID: 1411
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 addr[6]; offset:60; size:6; signed:0;
+ field:u8 oper_class; offset:66; size:1; signed:0;
+ field:enum nl80211_band band; offset:68; size:4; signed:0;
+ field:u32 control_freq; offset:72; size:4; signed:0;
+ field:u32 freq_offset; offset:76; size:4; signed:0;
+ field:u32 width; offset:80; size:4; signed:0;
+ field:u32 center_freq1; offset:84; size:4; signed:0;
+ field:u32 freq1_offset; offset:88; size:4; signed:0;
+ field:u32 center_freq2; offset:92; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), %pM oper class %d, band: %d, control freq: %u.%03u, width: %d, cf1: %u.%03u, cf2: %u", REC->wiphy_name, REC->name, REC->ifindex, (REC->addr), REC->oper_class, REC->band, REC->control_freq, REC->freq_offset, REC->width, REC->center_freq1, REC->freq1_offset, REC->center_freq2
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_tdls_mgmt/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_tdls_mgmt/format
new file mode 100644
index 000000000..5304bc30e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_tdls_mgmt/format
@@ -0,0 +1,20 @@
+name: rdev_tdls_mgmt
+ID: 1412
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 peer[6]; offset:60; size:6; signed:0;
+ field:u8 action_code; offset:66; size:1; signed:0;
+ field:u8 dialog_token; offset:67; size:1; signed:0;
+ field:u16 status_code; offset:68; size:2; signed:0;
+ field:u32 peer_capability; offset:72; size:4; signed:0;
+ field:bool initiator; offset:76; size:1; signed:0;
+ field:__data_loc u8[] buf; offset:80; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), %pM, action_code: %u, dialog_token: %u, status_code: %u, peer_capability: %u initiator: %s buf: %#.2x ", REC->wiphy_name, REC->name, REC->ifindex, (REC->peer), REC->action_code, REC->dialog_token, REC->status_code, REC->peer_capability, (REC->initiator) ? "true" : "false", ((u8 *)__get_dynamic_array(buf))[0]
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_tdls_oper/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_tdls_oper/format
new file mode 100644
index 000000000..60ae2e923
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_tdls_oper/format
@@ -0,0 +1,15 @@
+name: rdev_tdls_oper
+ID: 1413
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 peer[6]; offset:60; size:6; signed:0;
+ field:enum nl80211_tdls_operation oper; offset:68; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), %pM, oper: %d", REC->wiphy_name, REC->name, REC->ifindex, (REC->peer), REC->oper
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_testmode_cmd/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_testmode_cmd/format
new file mode 100644
index 000000000..7960a675b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_testmode_cmd/format
@@ -0,0 +1,12 @@
+name: rdev_testmode_cmd
+ID: 1414
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+
+print fmt: "%swdev(%u)", REC->wiphy_name, (REC->id)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_testmode_dump/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_testmode_dump/format
new file mode 100644
index 000000000..38f4819cb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_testmode_dump/format
@@ -0,0 +1,11 @@
+name: rdev_testmode_dump
+ID: 1415
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_tx_control_port/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_tx_control_port/format
new file mode 100644
index 000000000..511d2999d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_tx_control_port/format
@@ -0,0 +1,16 @@
+name: rdev_tx_control_port
+ID: 1416
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 dest[6]; offset:60; size:6; signed:0;
+ field:__be16 proto; offset:66; size:2; signed:0;
+ field:bool unencrypted; offset:68; size:1; signed:0;
+
+print fmt: "%s, netdev:%s(%d), %pM, proto: 0x%x, unencrypted: %s", REC->wiphy_name, REC->name, REC->ifindex, (REC->dest), (__builtin_constant_p((__u16)(( __u16)(__be16)(REC->proto))) ? ((__u16)( (((__u16)(( __u16)(__be16)(REC->proto)) & (__u16)0x00ffU) << 8) | (((__u16)(( __u16)(__be16)(REC->proto)) & (__u16)0xff00U) >> 8))) : __fswab16(( __u16)(__be16)(REC->proto))), (REC->unencrypted) ? "true" : "false"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_update_connect_params/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_update_connect_params/format
new file mode 100644
index 000000000..58ca80a84
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_update_connect_params/format
@@ -0,0 +1,14 @@
+name: rdev_update_connect_params
+ID: 1417
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u32 changed; offset:60; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), parameters changed: %u", REC->wiphy_name, REC->name, REC->ifindex, REC->changed
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_update_ft_ies/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_update_ft_ies/format
new file mode 100644
index 000000000..c9cf6c954
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_update_ft_ies/format
@@ -0,0 +1,15 @@
+name: rdev_update_ft_ies
+ID: 1418
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u16 md; offset:60; size:2; signed:0;
+ field:__data_loc u8[] ie; offset:64; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), md: 0x%x", REC->wiphy_name, REC->name, REC->ifindex, REC->md
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_update_mesh_config/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_update_mesh_config/format
new file mode 100644
index 000000000..bb319586d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_update_mesh_config/format
@@ -0,0 +1,40 @@
+name: rdev_update_mesh_config
+ID: 1419
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u16 dot11MeshRetryTimeout; offset:60; size:2; signed:0;
+ field:u16 dot11MeshConfirmTimeout; offset:62; size:2; signed:0;
+ field:u16 dot11MeshHoldingTimeout; offset:64; size:2; signed:0;
+ field:u16 dot11MeshMaxPeerLinks; offset:66; size:2; signed:0;
+ field:u8 dot11MeshMaxRetries; offset:68; size:1; signed:0;
+ field:u8 dot11MeshTTL; offset:69; size:1; signed:0;
+ field:u8 element_ttl; offset:70; size:1; signed:0;
+ field:bool auto_open_plinks; offset:71; size:1; signed:0;
+ field:u32 dot11MeshNbrOffsetMaxNeighbor; offset:72; size:4; signed:0;
+ field:u8 dot11MeshHWMPmaxPREQretries; offset:76; size:1; signed:0;
+ field:u32 path_refresh_time; offset:80; size:4; signed:0;
+ field:u32 dot11MeshHWMPactivePathTimeout; offset:84; size:4; signed:0;
+ field:u16 min_discovery_timeout; offset:88; size:2; signed:0;
+ field:u16 dot11MeshHWMPpreqMinInterval; offset:90; size:2; signed:0;
+ field:u16 dot11MeshHWMPperrMinInterval; offset:92; size:2; signed:0;
+ field:u16 dot11MeshHWMPnetDiameterTraversalTime; offset:94; size:2; signed:0;
+ field:u8 dot11MeshHWMPRootMode; offset:96; size:1; signed:0;
+ field:u16 dot11MeshHWMPRannInterval; offset:98; size:2; signed:0;
+ field:bool dot11MeshGateAnnouncementProtocol; offset:100; size:1; signed:0;
+ field:bool dot11MeshForwarding; offset:101; size:1; signed:0;
+ field:s32 rssi_threshold; offset:104; size:4; signed:1;
+ field:u16 ht_opmode; offset:108; size:2; signed:0;
+ field:u32 dot11MeshHWMPactivePathToRootTimeout; offset:112; size:4; signed:0;
+ field:u16 dot11MeshHWMProotInterval; offset:116; size:2; signed:0;
+ field:u16 dot11MeshHWMPconfirmationInterval; offset:118; size:2; signed:0;
+ field:bool dot11MeshNolearn; offset:120; size:1; signed:0;
+ field:u32 mask; offset:124; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), mask: %u", REC->wiphy_name, REC->name, REC->ifindex, REC->mask
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_update_mgmt_frame_registrations/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_update_mgmt_frame_registrations/format
new file mode 100644
index 000000000..3b37fe709
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_update_mgmt_frame_registrations/format
@@ -0,0 +1,14 @@
+name: rdev_update_mgmt_frame_registrations
+ID: 1420
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 id; offset:40; size:4; signed:0;
+ field:u16 global_stypes; offset:44; size:2; signed:0;
+ field:u16 interface_stypes; offset:46; size:2; signed:0;
+
+print fmt: "%s, wdev(%u), global: 0x%.2x, intf: 0x%.2x", REC->wiphy_name, (REC->id), REC->global_stypes, REC->interface_stypes
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_update_owe_info/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_update_owe_info/format
new file mode 100644
index 000000000..c5c0faa25
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg80211/rdev_update_owe_info/format
@@ -0,0 +1,16 @@
+name: rdev_update_owe_info
+ID: 1421
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char name[16]; offset:40; size:16; signed:0;
+ field:int ifindex; offset:56; size:4; signed:1;
+ field:u8 peer[6]; offset:60; size:6; signed:0;
+ field:u16 status; offset:66; size:2; signed:0;
+ field:__data_loc u8[] ie; offset:68; size:4; signed:0;
+
+print fmt: "%s, netdev:%s(%d), peer: %pM status %d", REC->wiphy_name, REC->name, REC->ifindex, (REC->peer), REC->status
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_add_virtual_intf/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_add_virtual_intf/format
new file mode 100644
index 000000000..fb70676c3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_add_virtual_intf/format
@@ -0,0 +1,14 @@
+name: 802154_rdev_add_virtual_intf
+ID: 1023
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:__data_loc char[] vir_intf_name; offset:40; size:4; signed:0;
+ field:enum nl802154_iftype type; offset:44; size:4; signed:1;
+ field:__le64 extended_addr; offset:48; size:8; signed:0;
+
+print fmt: "%s, virtual intf name: %s, type: %d, extended addr: 0x%llx", REC->wpan_phy_name, __get_str(vir_intf_name), REC->type, (( __u64)(__le64)(REC->extended_addr))
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_del_virtual_intf/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_del_virtual_intf/format
new file mode 100644
index 000000000..b4b0008e8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_del_virtual_intf/format
@@ -0,0 +1,12 @@
+name: 802154_rdev_del_virtual_intf
+ID: 1024
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:u32 identifier; offset:40; size:4; signed:0;
+
+print fmt: "%s, wpan_dev(%u)", REC->wpan_phy_name, (REC->identifier)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_resume/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_resume/format
new file mode 100644
index 000000000..7f70eee17
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_resume/format
@@ -0,0 +1,11 @@
+name: 802154_rdev_resume
+ID: 1025
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wpan_phy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_return_int/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_return_int/format
new file mode 100644
index 000000000..ed9d48d49
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_return_int/format
@@ -0,0 +1,12 @@
+name: 802154_rdev_return_int
+ID: 1026
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:int ret; offset:40; size:4; signed:1;
+
+print fmt: "%s, returned: %d", REC->wpan_phy_name, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_ackreq_default/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_ackreq_default/format
new file mode 100644
index 000000000..f27e52e60
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_ackreq_default/format
@@ -0,0 +1,13 @@
+name: 802154_rdev_set_ackreq_default
+ID: 1027
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:u32 identifier; offset:40; size:4; signed:0;
+ field:bool ackreq; offset:44; size:1; signed:0;
+
+print fmt: "%s, wpan_dev(%u), ackreq default: %s", REC->wpan_phy_name, (REC->identifier), (REC->ackreq) ? "true" : "false"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_backoff_exponent/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_backoff_exponent/format
new file mode 100644
index 000000000..3637c59cb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_backoff_exponent/format
@@ -0,0 +1,14 @@
+name: 802154_rdev_set_backoff_exponent
+ID: 1028
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:u32 identifier; offset:40; size:4; signed:0;
+ field:u8 min_be; offset:44; size:1; signed:0;
+ field:u8 max_be; offset:45; size:1; signed:0;
+
+print fmt: "%s, wpan_dev(%u), min be: %d, max be: %d", REC->wpan_phy_name, (REC->identifier), REC->min_be, REC->max_be
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_cca_ed_level/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_cca_ed_level/format
new file mode 100644
index 000000000..37a9e3e78
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_cca_ed_level/format
@@ -0,0 +1,12 @@
+name: 802154_rdev_set_cca_ed_level
+ID: 1029
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:s32 ed_level; offset:40; size:4; signed:1;
+
+print fmt: "%s, ed level: %d", REC->wpan_phy_name, REC->ed_level
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_cca_mode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_cca_mode/format
new file mode 100644
index 000000000..8d1e799ef
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_cca_mode/format
@@ -0,0 +1,13 @@
+name: 802154_rdev_set_cca_mode
+ID: 1030
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl802154_cca_modes cca_mode; offset:40; size:4; signed:0;
+ field:enum nl802154_cca_opts cca_opt; offset:44; size:4; signed:0;
+
+print fmt: "%s, cca_mode: %d, cca_opt: %d", REC->wpan_phy_name, REC->cca_mode, REC->cca_opt
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_channel/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_channel/format
new file mode 100644
index 000000000..2e9854e7c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_channel/format
@@ -0,0 +1,13 @@
+name: 802154_rdev_set_channel
+ID: 1031
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:u8 page; offset:40; size:1; signed:0;
+ field:u8 channel; offset:41; size:1; signed:0;
+
+print fmt: "%s, page: %d, channel: %d", REC->wpan_phy_name, REC->page, REC->channel
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_csma_backoffs/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_csma_backoffs/format
new file mode 100644
index 000000000..96a5d0b18
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_csma_backoffs/format
@@ -0,0 +1,13 @@
+name: 802154_rdev_set_csma_backoffs
+ID: 1032
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:u32 identifier; offset:40; size:4; signed:0;
+ field:u8 max_csma_backoffs; offset:44; size:1; signed:0;
+
+print fmt: "%s, wpan_dev(%u), max csma backoffs: %d", REC->wpan_phy_name, (REC->identifier), REC->max_csma_backoffs
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_lbt_mode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_lbt_mode/format
new file mode 100644
index 000000000..0d1cf1821
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_lbt_mode/format
@@ -0,0 +1,13 @@
+name: 802154_rdev_set_lbt_mode
+ID: 1033
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:u32 identifier; offset:40; size:4; signed:0;
+ field:bool mode; offset:44; size:1; signed:0;
+
+print fmt: "%s, wpan_dev(%u), lbt mode: %s", REC->wpan_phy_name, (REC->identifier), (REC->mode) ? "true" : "false"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_max_frame_retries/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_max_frame_retries/format
new file mode 100644
index 000000000..187b1d60f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_max_frame_retries/format
@@ -0,0 +1,13 @@
+name: 802154_rdev_set_max_frame_retries
+ID: 1034
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:u32 identifier; offset:40; size:4; signed:0;
+ field:s8 max_frame_retries; offset:44; size:1; signed:1;
+
+print fmt: "%s, wpan_dev(%u), max frame retries: %d", REC->wpan_phy_name, (REC->identifier), REC->max_frame_retries
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_pan_id/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_pan_id/format
new file mode 100644
index 000000000..9cac8ab10
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_pan_id/format
@@ -0,0 +1,13 @@
+name: 802154_rdev_set_pan_id
+ID: 1035
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:u32 identifier; offset:40; size:4; signed:0;
+ field:__le16 le16arg; offset:44; size:2; signed:0;
+
+print fmt: "%s, wpan_dev(%u), pan id: 0x%04x", REC->wpan_phy_name, (REC->identifier), (( __u16)(__le16)(REC->le16arg))
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_short_addr/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_short_addr/format
new file mode 100644
index 000000000..d723e5bde
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_short_addr/format
@@ -0,0 +1,13 @@
+name: 802154_rdev_set_short_addr
+ID: 1036
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:u32 identifier; offset:40; size:4; signed:0;
+ field:__le16 le16arg; offset:44; size:2; signed:0;
+
+print fmt: "%s, wpan_dev(%u), short addr: 0x%04x", REC->wpan_phy_name, (REC->identifier), (( __u16)(__le16)(REC->le16arg))
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_tx_power/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_tx_power/format
new file mode 100644
index 000000000..be804fc3c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_set_tx_power/format
@@ -0,0 +1,12 @@
+name: 802154_rdev_set_tx_power
+ID: 1037
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:s32 power; offset:40; size:4; signed:1;
+
+print fmt: "%s, mbm: %d", REC->wpan_phy_name, REC->power
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_suspend/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_suspend/format
new file mode 100644
index 000000000..0503e9b27
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cfg802154/802154_rdev_suspend/format
@@ -0,0 +1,11 @@
+name: 802154_rdev_suspend
+ID: 1038
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wpan_phy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_attach_task/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_attach_task/format
new file mode 100644
index 000000000..918f93a6f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_attach_task/format
@@ -0,0 +1,16 @@
+name: cgroup_attach_task
+ID: 155
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int dst_root; offset:8; size:4; signed:1;
+ field:int dst_id; offset:12; size:4; signed:1;
+ field:int dst_level; offset:16; size:4; signed:1;
+ field:int pid; offset:20; size:4; signed:1;
+ field:__data_loc char[] dst_path; offset:24; size:4; signed:0;
+ field:__data_loc char[] comm; offset:28; size:4; signed:0;
+
+print fmt: "dst_root=%d dst_id=%d dst_level=%d dst_path=%s pid=%d comm=%s", REC->dst_root, REC->dst_id, REC->dst_level, __get_str(dst_path), REC->pid, __get_str(comm)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_destroy_root/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_destroy_root/format
new file mode 100644
index 000000000..a1b50cb05
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_destroy_root/format
@@ -0,0 +1,13 @@
+name: cgroup_destroy_root
+ID: 156
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int root; offset:8; size:4; signed:1;
+ field:u16 ss_mask; offset:12; size:2; signed:0;
+ field:__data_loc char[] name; offset:16; size:4; signed:0;
+
+print fmt: "root=%d ss_mask=%#x name=%s", REC->root, REC->ss_mask, __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_freeze/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_freeze/format
new file mode 100644
index 000000000..3700e28f9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_freeze/format
@@ -0,0 +1,14 @@
+name: cgroup_freeze
+ID: 157
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int root; offset:8; size:4; signed:1;
+ field:int id; offset:12; size:4; signed:1;
+ field:int level; offset:16; size:4; signed:1;
+ field:__data_loc char[] path; offset:20; size:4; signed:0;
+
+print fmt: "root=%d id=%d level=%d path=%s", REC->root, REC->id, REC->level, __get_str(path)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_mkdir/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_mkdir/format
new file mode 100644
index 000000000..868ec20c6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_mkdir/format
@@ -0,0 +1,14 @@
+name: cgroup_mkdir
+ID: 158
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int root; offset:8; size:4; signed:1;
+ field:int id; offset:12; size:4; signed:1;
+ field:int level; offset:16; size:4; signed:1;
+ field:__data_loc char[] path; offset:20; size:4; signed:0;
+
+print fmt: "root=%d id=%d level=%d path=%s", REC->root, REC->id, REC->level, __get_str(path)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_notify_frozen/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_notify_frozen/format
new file mode 100644
index 000000000..ddc101700
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_notify_frozen/format
@@ -0,0 +1,15 @@
+name: cgroup_notify_frozen
+ID: 159
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int root; offset:8; size:4; signed:1;
+ field:int id; offset:12; size:4; signed:1;
+ field:int level; offset:16; size:4; signed:1;
+ field:__data_loc char[] path; offset:20; size:4; signed:0;
+ field:int val; offset:24; size:4; signed:1;
+
+print fmt: "root=%d id=%d level=%d path=%s val=%d", REC->root, REC->id, REC->level, __get_str(path), REC->val
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_notify_populated/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_notify_populated/format
new file mode 100644
index 000000000..712127938
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_notify_populated/format
@@ -0,0 +1,15 @@
+name: cgroup_notify_populated
+ID: 160
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int root; offset:8; size:4; signed:1;
+ field:int id; offset:12; size:4; signed:1;
+ field:int level; offset:16; size:4; signed:1;
+ field:__data_loc char[] path; offset:20; size:4; signed:0;
+ field:int val; offset:24; size:4; signed:1;
+
+print fmt: "root=%d id=%d level=%d path=%s val=%d", REC->root, REC->id, REC->level, __get_str(path), REC->val
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_release/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_release/format
new file mode 100644
index 000000000..d18234ef3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_release/format
@@ -0,0 +1,14 @@
+name: cgroup_release
+ID: 161
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int root; offset:8; size:4; signed:1;
+ field:int id; offset:12; size:4; signed:1;
+ field:int level; offset:16; size:4; signed:1;
+ field:__data_loc char[] path; offset:20; size:4; signed:0;
+
+print fmt: "root=%d id=%d level=%d path=%s", REC->root, REC->id, REC->level, __get_str(path)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_remount/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_remount/format
new file mode 100644
index 000000000..90c5c561e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_remount/format
@@ -0,0 +1,13 @@
+name: cgroup_remount
+ID: 162
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int root; offset:8; size:4; signed:1;
+ field:u16 ss_mask; offset:12; size:2; signed:0;
+ field:__data_loc char[] name; offset:16; size:4; signed:0;
+
+print fmt: "root=%d ss_mask=%#x name=%s", REC->root, REC->ss_mask, __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_rename/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_rename/format
new file mode 100644
index 000000000..7cb4a6274
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_rename/format
@@ -0,0 +1,14 @@
+name: cgroup_rename
+ID: 163
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int root; offset:8; size:4; signed:1;
+ field:int id; offset:12; size:4; signed:1;
+ field:int level; offset:16; size:4; signed:1;
+ field:__data_loc char[] path; offset:20; size:4; signed:0;
+
+print fmt: "root=%d id=%d level=%d path=%s", REC->root, REC->id, REC->level, __get_str(path)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_rmdir/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_rmdir/format
new file mode 100644
index 000000000..87e01edae
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_rmdir/format
@@ -0,0 +1,14 @@
+name: cgroup_rmdir
+ID: 164
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int root; offset:8; size:4; signed:1;
+ field:int id; offset:12; size:4; signed:1;
+ field:int level; offset:16; size:4; signed:1;
+ field:__data_loc char[] path; offset:20; size:4; signed:0;
+
+print fmt: "root=%d id=%d level=%d path=%s", REC->root, REC->id, REC->level, __get_str(path)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_setup_root/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_setup_root/format
new file mode 100644
index 000000000..bd34e723b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_setup_root/format
@@ -0,0 +1,13 @@
+name: cgroup_setup_root
+ID: 165
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int root; offset:8; size:4; signed:1;
+ field:u16 ss_mask; offset:12; size:2; signed:0;
+ field:__data_loc char[] name; offset:16; size:4; signed:0;
+
+print fmt: "root=%d ss_mask=%#x name=%s", REC->root, REC->ss_mask, __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_transfer_tasks/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_transfer_tasks/format
new file mode 100644
index 000000000..631dba9b6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_transfer_tasks/format
@@ -0,0 +1,16 @@
+name: cgroup_transfer_tasks
+ID: 166
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int dst_root; offset:8; size:4; signed:1;
+ field:int dst_id; offset:12; size:4; signed:1;
+ field:int dst_level; offset:16; size:4; signed:1;
+ field:int pid; offset:20; size:4; signed:1;
+ field:__data_loc char[] dst_path; offset:24; size:4; signed:0;
+ field:__data_loc char[] comm; offset:28; size:4; signed:0;
+
+print fmt: "dst_root=%d dst_id=%d dst_level=%d dst_path=%s pid=%d comm=%s", REC->dst_root, REC->dst_id, REC->dst_level, __get_str(dst_path), REC->pid, __get_str(comm)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_unfreeze/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_unfreeze/format
new file mode 100644
index 000000000..c594bd406
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cgroup/cgroup_unfreeze/format
@@ -0,0 +1,14 @@
+name: cgroup_unfreeze
+ID: 167
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int root; offset:8; size:4; signed:1;
+ field:int id; offset:12; size:4; signed:1;
+ field:int level; offset:16; size:4; signed:1;
+ field:__data_loc char[] path; offset:20; size:4; signed:0;
+
+print fmt: "root=%d id=%d level=%d path=%s", REC->root, REC->id, REC->level, __get_str(path)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_disable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_disable/format
new file mode 100644
index 000000000..41aad01b6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_disable/format
@@ -0,0 +1,11 @@
+name: clk_disable
+ID: 617
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_disable_complete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_disable_complete/format
new file mode 100644
index 000000000..842bfafc4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_disable_complete/format
@@ -0,0 +1,11 @@
+name: clk_disable_complete
+ID: 618
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_enable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_enable/format
new file mode 100644
index 000000000..0c462bde6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_enable/format
@@ -0,0 +1,11 @@
+name: clk_enable
+ID: 619
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_enable_complete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_enable_complete/format
new file mode 100644
index 000000000..c7743b679
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_enable_complete/format
@@ -0,0 +1,11 @@
+name: clk_enable_complete
+ID: 620
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_prepare/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_prepare/format
new file mode 100644
index 000000000..5b4c28b6f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_prepare/format
@@ -0,0 +1,11 @@
+name: clk_prepare
+ID: 621
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_prepare_complete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_prepare_complete/format
new file mode 100644
index 000000000..374a723e7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_prepare_complete/format
@@ -0,0 +1,11 @@
+name: clk_prepare_complete
+ID: 622
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_duty_cycle/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_duty_cycle/format
new file mode 100644
index 000000000..334cbc60d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_duty_cycle/format
@@ -0,0 +1,13 @@
+name: clk_set_duty_cycle
+ID: 623
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int num; offset:12; size:4; signed:0;
+ field:unsigned int den; offset:16; size:4; signed:0;
+
+print fmt: "%s %u/%u", __get_str(name), (unsigned int)REC->num, (unsigned int)REC->den
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_duty_cycle_complete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_duty_cycle_complete/format
new file mode 100644
index 000000000..c3906ab54
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_duty_cycle_complete/format
@@ -0,0 +1,13 @@
+name: clk_set_duty_cycle_complete
+ID: 624
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int num; offset:12; size:4; signed:0;
+ field:unsigned int den; offset:16; size:4; signed:0;
+
+print fmt: "%s %u/%u", __get_str(name), (unsigned int)REC->num, (unsigned int)REC->den
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_parent/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_parent/format
new file mode 100644
index 000000000..2c35de701
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_parent/format
@@ -0,0 +1,12 @@
+name: clk_set_parent
+ID: 625
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:__data_loc char[] pname; offset:12; size:4; signed:0;
+
+print fmt: "%s %s", __get_str(name), __get_str(pname)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_parent_complete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_parent_complete/format
new file mode 100644
index 000000000..fb3bf71e2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_parent_complete/format
@@ -0,0 +1,12 @@
+name: clk_set_parent_complete
+ID: 626
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:__data_loc char[] pname; offset:12; size:4; signed:0;
+
+print fmt: "%s %s", __get_str(name), __get_str(pname)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_phase/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_phase/format
new file mode 100644
index 000000000..a02dec002
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_phase/format
@@ -0,0 +1,12 @@
+name: clk_set_phase
+ID: 627
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:int phase; offset:12; size:4; signed:1;
+
+print fmt: "%s %d", __get_str(name), (int)REC->phase
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_phase_complete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_phase_complete/format
new file mode 100644
index 000000000..dc6ef2518
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_phase_complete/format
@@ -0,0 +1,12 @@
+name: clk_set_phase_complete
+ID: 628
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:int phase; offset:12; size:4; signed:1;
+
+print fmt: "%s %d", __get_str(name), (int)REC->phase
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_rate/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_rate/format
new file mode 100644
index 000000000..5e5bc7c3c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_rate/format
@@ -0,0 +1,12 @@
+name: clk_set_rate
+ID: 629
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned long rate; offset:16; size:8; signed:0;
+
+print fmt: "%s %lu", __get_str(name), (unsigned long)REC->rate
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_rate_complete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_rate_complete/format
new file mode 100644
index 000000000..5a7eac24c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_set_rate_complete/format
@@ -0,0 +1,12 @@
+name: clk_set_rate_complete
+ID: 630
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned long rate; offset:16; size:8; signed:0;
+
+print fmt: "%s %lu", __get_str(name), (unsigned long)REC->rate
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_unprepare/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_unprepare/format
new file mode 100644
index 000000000..3c5d4e246
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_unprepare/format
@@ -0,0 +1,11 @@
+name: clk_unprepare
+ID: 631
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_unprepare_complete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_unprepare_complete/format
new file mode 100644
index 000000000..402d81ab7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/clk/clk_unprepare_complete/format
@@ -0,0 +1,11 @@
+name: clk_unprepare_complete
+ID: 632
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cma/cma_alloc_busy_retry/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cma/cma_alloc_busy_retry/format
new file mode 100644
index 000000000..3bb853b0b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cma/cma_alloc_busy_retry/format
@@ -0,0 +1,15 @@
+name: cma_alloc_busy_retry
+ID: 290
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned long pfn; offset:16; size:8; signed:0;
+ field:const struct page * page; offset:24; size:8; signed:0;
+ field:unsigned int count; offset:32; size:4; signed:0;
+ field:unsigned int align; offset:36; size:4; signed:0;
+
+print fmt: "name=%s pfn=%lx page=%p count=%u align=%u", __get_str(name), REC->pfn, REC->page, REC->count, REC->align
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cma/cma_alloc_finish/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cma/cma_alloc_finish/format
new file mode 100644
index 000000000..e1e66f08d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cma/cma_alloc_finish/format
@@ -0,0 +1,15 @@
+name: cma_alloc_finish
+ID: 291
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned long pfn; offset:16; size:8; signed:0;
+ field:const struct page * page; offset:24; size:8; signed:0;
+ field:unsigned int count; offset:32; size:4; signed:0;
+ field:unsigned int align; offset:36; size:4; signed:0;
+
+print fmt: "name=%s pfn=%lx page=%p count=%u align=%u", __get_str(name), REC->pfn, REC->page, REC->count, REC->align
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cma/cma_alloc_info/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cma/cma_alloc_info/format
new file mode 100644
index 000000000..038d756ba
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cma/cma_alloc_info/format
@@ -0,0 +1,20 @@
+name: cma_alloc_info
+ID: 292
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned long pfn; offset:16; size:8; signed:0;
+ field:unsigned int count; offset:24; size:4; signed:0;
+ field:unsigned int align; offset:28; size:4; signed:0;
+ field:unsigned long nr_migrated; offset:32; size:8; signed:0;
+ field:unsigned long nr_reclaimed; offset:40; size:8; signed:0;
+ field:unsigned long nr_mapped; offset:48; size:8; signed:0;
+ field:unsigned int err_iso; offset:56; size:4; signed:0;
+ field:unsigned int err_mig; offset:60; size:4; signed:0;
+ field:unsigned int err_test; offset:64; size:4; signed:0;
+
+print fmt: "name=%s pfn=0x%lx count=%u align=%u nr_migrated=%lu nr_reclaimed=%lu nr_mapped=%lu err_iso=%u err_mig=%u err_test=%u", __get_str(name), REC->pfn, REC->count, REC->align, REC->nr_migrated, REC->nr_reclaimed, REC->nr_mapped, REC->err_iso, REC->err_mig, REC->err_test
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cma/cma_alloc_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cma/cma_alloc_start/format
new file mode 100644
index 000000000..390f727ab
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cma/cma_alloc_start/format
@@ -0,0 +1,13 @@
+name: cma_alloc_start
+ID: 293
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int count; offset:12; size:4; signed:0;
+ field:unsigned int align; offset:16; size:4; signed:0;
+
+print fmt: "name=%s count=%u align=%u", __get_str(name), REC->count, REC->align
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cma/cma_release/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cma/cma_release/format
new file mode 100644
index 000000000..f22d50fef
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cma/cma_release/format
@@ -0,0 +1,14 @@
+name: cma_release
+ID: 294
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned long pfn; offset:16; size:8; signed:0;
+ field:const struct page * page; offset:24; size:8; signed:0;
+ field:unsigned int count; offset:32; size:4; signed:0;
+
+print fmt: "name=%s pfn=%lx page=%p count=%u", __get_str(name), REC->pfn, REC->page, REC->count
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_begin/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_begin/format
new file mode 100644
index 000000000..1c59963ad
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_begin/format
@@ -0,0 +1,15 @@
+name: mm_compaction_begin
+ID: 262
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long zone_start; offset:8; size:8; signed:0;
+ field:unsigned long migrate_pfn; offset:16; size:8; signed:0;
+ field:unsigned long free_pfn; offset:24; size:8; signed:0;
+ field:unsigned long zone_end; offset:32; size:8; signed:0;
+ field:bool sync; offset:40; size:1; signed:0;
+
+print fmt: "zone_start=0x%lx migrate_pfn=0x%lx free_pfn=0x%lx zone_end=0x%lx, mode=%s", REC->zone_start, REC->migrate_pfn, REC->free_pfn, REC->zone_end, REC->sync ? "sync" : "async"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_defer_compaction/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_defer_compaction/format
new file mode 100644
index 000000000..689144d56
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_defer_compaction/format
@@ -0,0 +1,16 @@
+name: mm_compaction_defer_compaction
+ID: 263
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int nid; offset:8; size:4; signed:1;
+ field:enum zone_type idx; offset:12; size:4; signed:0;
+ field:int order; offset:16; size:4; signed:1;
+ field:unsigned int considered; offset:20; size:4; signed:0;
+ field:unsigned int defer_shift; offset:24; size:4; signed:0;
+ field:int order_failed; offset:28; size:4; signed:1;
+
+print fmt: "node=%d zone=%-8s order=%d order_failed=%d consider=%u limit=%lu", REC->nid, __print_symbolic(REC->idx, {0, "DMA32"}, {1, "Normal"}, {2, "Movable"}), REC->order, REC->order_failed, REC->considered, 1UL << REC->defer_shift
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_defer_reset/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_defer_reset/format
new file mode 100644
index 000000000..80e296d42
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_defer_reset/format
@@ -0,0 +1,16 @@
+name: mm_compaction_defer_reset
+ID: 264
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int nid; offset:8; size:4; signed:1;
+ field:enum zone_type idx; offset:12; size:4; signed:0;
+ field:int order; offset:16; size:4; signed:1;
+ field:unsigned int considered; offset:20; size:4; signed:0;
+ field:unsigned int defer_shift; offset:24; size:4; signed:0;
+ field:int order_failed; offset:28; size:4; signed:1;
+
+print fmt: "node=%d zone=%-8s order=%d order_failed=%d consider=%u limit=%lu", REC->nid, __print_symbolic(REC->idx, {0, "DMA32"}, {1, "Normal"}, {2, "Movable"}), REC->order, REC->order_failed, REC->considered, 1UL << REC->defer_shift
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_deferred/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_deferred/format
new file mode 100644
index 000000000..74256594f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_deferred/format
@@ -0,0 +1,16 @@
+name: mm_compaction_deferred
+ID: 265
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int nid; offset:8; size:4; signed:1;
+ field:enum zone_type idx; offset:12; size:4; signed:0;
+ field:int order; offset:16; size:4; signed:1;
+ field:unsigned int considered; offset:20; size:4; signed:0;
+ field:unsigned int defer_shift; offset:24; size:4; signed:0;
+ field:int order_failed; offset:28; size:4; signed:1;
+
+print fmt: "node=%d zone=%-8s order=%d order_failed=%d consider=%u limit=%lu", REC->nid, __print_symbolic(REC->idx, {0, "DMA32"}, {1, "Normal"}, {2, "Movable"}), REC->order, REC->order_failed, REC->considered, 1UL << REC->defer_shift
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_end/format
new file mode 100644
index 000000000..7d410c432
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_end/format
@@ -0,0 +1,16 @@
+name: mm_compaction_end
+ID: 266
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long zone_start; offset:8; size:8; signed:0;
+ field:unsigned long migrate_pfn; offset:16; size:8; signed:0;
+ field:unsigned long free_pfn; offset:24; size:8; signed:0;
+ field:unsigned long zone_end; offset:32; size:8; signed:0;
+ field:bool sync; offset:40; size:1; signed:0;
+ field:int status; offset:44; size:4; signed:1;
+
+print fmt: "zone_start=0x%lx migrate_pfn=0x%lx free_pfn=0x%lx zone_end=0x%lx, mode=%s status=%s", REC->zone_start, REC->migrate_pfn, REC->free_pfn, REC->zone_end, REC->sync ? "sync" : "async", __print_symbolic(REC->status, {1, "skipped"}, {2, "deferred"}, {4, "continue"}, {8, "success"}, {6, "partial_skipped"}, {5, "complete"}, {3, "no_suitable_page"}, {0, "not_suitable_zone"}, {7, "contended"})
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_finished/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_finished/format
new file mode 100644
index 000000000..305adf5a5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_finished/format
@@ -0,0 +1,14 @@
+name: mm_compaction_finished
+ID: 267
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int nid; offset:8; size:4; signed:1;
+ field:enum zone_type idx; offset:12; size:4; signed:0;
+ field:int order; offset:16; size:4; signed:1;
+ field:int ret; offset:20; size:4; signed:1;
+
+print fmt: "node=%d zone=%-8s order=%d ret=%s", REC->nid, __print_symbolic(REC->idx, {0, "DMA32"}, {1, "Normal"}, {2, "Movable"}), REC->order, __print_symbolic(REC->ret, {1, "skipped"}, {2, "deferred"}, {4, "continue"}, {8, "success"}, {6, "partial_skipped"}, {5, "complete"}, {3, "no_suitable_page"}, {0, "not_suitable_zone"}, {7, "contended"})
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_isolate_freepages/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_isolate_freepages/format
new file mode 100644
index 000000000..2423e3a3a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_isolate_freepages/format
@@ -0,0 +1,14 @@
+name: mm_compaction_isolate_freepages
+ID: 268
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long start_pfn; offset:8; size:8; signed:0;
+ field:unsigned long end_pfn; offset:16; size:8; signed:0;
+ field:unsigned long nr_scanned; offset:24; size:8; signed:0;
+ field:unsigned long nr_taken; offset:32; size:8; signed:0;
+
+print fmt: "range=(0x%lx ~ 0x%lx) nr_scanned=%lu nr_taken=%lu", REC->start_pfn, REC->end_pfn, REC->nr_scanned, REC->nr_taken
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_isolate_migratepages/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_isolate_migratepages/format
new file mode 100644
index 000000000..5e0e79f21
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_isolate_migratepages/format
@@ -0,0 +1,14 @@
+name: mm_compaction_isolate_migratepages
+ID: 269
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long start_pfn; offset:8; size:8; signed:0;
+ field:unsigned long end_pfn; offset:16; size:8; signed:0;
+ field:unsigned long nr_scanned; offset:24; size:8; signed:0;
+ field:unsigned long nr_taken; offset:32; size:8; signed:0;
+
+print fmt: "range=(0x%lx ~ 0x%lx) nr_scanned=%lu nr_taken=%lu", REC->start_pfn, REC->end_pfn, REC->nr_scanned, REC->nr_taken
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_kcompactd_sleep/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_kcompactd_sleep/format
new file mode 100644
index 000000000..4ec70b518
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_kcompactd_sleep/format
@@ -0,0 +1,11 @@
+name: mm_compaction_kcompactd_sleep
+ID: 270
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int nid; offset:8; size:4; signed:1;
+
+print fmt: "nid=%d", REC->nid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_kcompactd_wake/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_kcompactd_wake/format
new file mode 100644
index 000000000..01e28ff94
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_kcompactd_wake/format
@@ -0,0 +1,13 @@
+name: mm_compaction_kcompactd_wake
+ID: 271
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int nid; offset:8; size:4; signed:1;
+ field:int order; offset:12; size:4; signed:1;
+ field:enum zone_type highest_zoneidx; offset:16; size:4; signed:0;
+
+print fmt: "nid=%d order=%d classzone_idx=%-8s", REC->nid, REC->order, __print_symbolic(REC->highest_zoneidx, {0, "DMA32"}, {1, "Normal"}, {2, "Movable"})
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_migratepages/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_migratepages/format
new file mode 100644
index 000000000..80e1c049c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_migratepages/format
@@ -0,0 +1,12 @@
+name: mm_compaction_migratepages
+ID: 272
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long nr_migrated; offset:8; size:8; signed:0;
+ field:unsigned long nr_failed; offset:16; size:8; signed:0;
+
+print fmt: "nr_migrated=%lu nr_failed=%lu", REC->nr_migrated, REC->nr_failed
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_suitable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_suitable/format
new file mode 100644
index 000000000..84f3c75b9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_suitable/format
@@ -0,0 +1,14 @@
+name: mm_compaction_suitable
+ID: 273
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int nid; offset:8; size:4; signed:1;
+ field:enum zone_type idx; offset:12; size:4; signed:0;
+ field:int order; offset:16; size:4; signed:1;
+ field:int ret; offset:20; size:4; signed:1;
+
+print fmt: "node=%d zone=%-8s order=%d ret=%s", REC->nid, __print_symbolic(REC->idx, {0, "DMA32"}, {1, "Normal"}, {2, "Movable"}), REC->order, __print_symbolic(REC->ret, {1, "skipped"}, {2, "deferred"}, {4, "continue"}, {8, "success"}, {6, "partial_skipped"}, {5, "complete"}, {3, "no_suitable_page"}, {0, "not_suitable_zone"}, {7, "contended"})
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_try_to_compact_pages/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_try_to_compact_pages/format
new file mode 100644
index 000000000..1f0da6cc7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_try_to_compact_pages/format
@@ -0,0 +1,13 @@
+name: mm_compaction_try_to_compact_pages
+ID: 274
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int order; offset:8; size:4; signed:1;
+ field:gfp_t gfp_mask; offset:12; size:4; signed:0;
+ field:int prio; offset:16; size:4; signed:1;
+
+print fmt: "order=%d gfp_mask=%s priority=%d", REC->order, (REC->gfp_mask) ? __print_flags(REC->gfp_mask, "|", {(unsigned long)(((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))) | (( gfp_t)0x400u)), "GFP_TRANSHUGE"}, {(unsigned long)((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))), "GFP_TRANSHUGE_LIGHT"}, {(unsigned long)((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)), "GFP_HIGHUSER_MOVABLE"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)), "GFP_HIGHUSER"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)), "GFP_USER"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)) | (( gfp_t)0x400000u)), "GFP_KERNEL_ACCOUNT"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)), "GFP_KERNEL"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u)), "GFP_NOFS"}, {(unsigned long)((( gfp_t)0x20u)|(( gfp_t)0x200u)|(( gfp_t)0x800u)), "GFP_ATOMIC"}, {(unsigned long)((( gfp_t)(0x400u|0x800u))), "GFP_NOIO"}, {(unsigned long)((( gfp_t)0x800u)), "GFP_NOWAIT"}, {(unsigned long)(( gfp_t)0x01u), "GFP_DMA"}, {(unsigned long)(( gfp_t)0x02u), "__GFP_HIGHMEM"}, {(unsigned long)(( gfp_t)0x04u), "GFP_DMA32"}, {(unsigned long)(( gfp_t)0x20u), "__GFP_HIGH"}, {(unsigned long)(( gfp_t)0x200u), "__GFP_ATOMIC"}, {(unsigned long)(( gfp_t)0x40u), "__GFP_IO"}, {(unsigned long)(( gfp_t)0x80u), "__GFP_FS"}, {(unsigned long)(( gfp_t)0x2000u), "__GFP_NOWARN"}, {(unsigned long)(( gfp_t)0x4000u), "__GFP_RETRY_MAYFAIL"}, {(unsigned long)(( gfp_t)0x8000u), "__GFP_NOFAIL"}, {(unsigned long)(( gfp_t)0x10000u), "__GFP_NORETRY"}, {(unsigned long)(( gfp_t)0x40000u), "__GFP_COMP"}, {(unsigned long)(( gfp_t)0x100u), "__GFP_ZERO"}, {(unsigned long)(( gfp_t)0x80000u), "__GFP_NOMEMALLOC"}, {(unsigned long)(( gfp_t)0x20000u), "__GFP_MEMALLOC"}, {(unsigned long)(( gfp_t)0x100000u), "__GFP_HARDWALL"}, {(unsigned long)(( gfp_t)0x200000u), "__GFP_THISNODE"}, {(unsigned long)(( gfp_t)0x10u), "__GFP_RECLAIMABLE"}, {(unsigned long)(( gfp_t)0x08u), "__GFP_MOVABLE"}, {(unsigned long)(( gfp_t)0x400000u), "__GFP_ACCOUNT"}, {(unsigned long)(( gfp_t)0x1000u), "__GFP_WRITE"}, {(unsigned long)(( gfp_t)(0x400u|0x800u)), "__GFP_RECLAIM"}, {(unsigned long)(( gfp_t)0x400u), "__GFP_DIRECT_RECLAIM"}, {(unsigned long)(( gfp_t)0x800u), "__GFP_KSWAPD_RECLAIM"} ) : "none", REC->prio
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_wakeup_kcompactd/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_wakeup_kcompactd/format
new file mode 100644
index 000000000..8936a05df
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/compaction/mm_compaction_wakeup_kcompactd/format
@@ -0,0 +1,13 @@
+name: mm_compaction_wakeup_kcompactd
+ID: 275
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int nid; offset:8; size:4; signed:1;
+ field:int order; offset:12; size:4; signed:1;
+ field:enum zone_type highest_zoneidx; offset:16; size:4; signed:0;
+
+print fmt: "nid=%d order=%d classzone_idx=%-8s", REC->nid, REC->order, __print_symbolic(REC->highest_zoneidx, {0, "DMA32"}, {1, "Normal"}, {2, "Movable"})
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cpuhp/cpuhp_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cpuhp/cpuhp_enter/format
new file mode 100644
index 000000000..a59cdcfe7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cpuhp/cpuhp_enter/format
@@ -0,0 +1,14 @@
+name: cpuhp_enter
+ID: 65
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int cpu; offset:8; size:4; signed:0;
+ field:int target; offset:12; size:4; signed:1;
+ field:int idx; offset:16; size:4; signed:1;
+ field:void * fun; offset:24; size:8; signed:0;
+
+print fmt: "cpu: %04u target: %3d step: %3d (%ps)", REC->cpu, REC->target, REC->idx, REC->fun
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cpuhp/cpuhp_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cpuhp/cpuhp_exit/format
new file mode 100644
index 000000000..e54018959
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cpuhp/cpuhp_exit/format
@@ -0,0 +1,14 @@
+name: cpuhp_exit
+ID: 66
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int cpu; offset:8; size:4; signed:0;
+ field:int state; offset:12; size:4; signed:1;
+ field:int idx; offset:16; size:4; signed:1;
+ field:int ret; offset:20; size:4; signed:1;
+
+print fmt: " cpu: %04u state: %3d step: %3d ret: %d", REC->cpu, REC->state, REC->idx, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cpuhp/cpuhp_multi_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cpuhp/cpuhp_multi_enter/format
new file mode 100644
index 000000000..1ed6bc29b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cpuhp/cpuhp_multi_enter/format
@@ -0,0 +1,14 @@
+name: cpuhp_multi_enter
+ID: 67
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int cpu; offset:8; size:4; signed:0;
+ field:int target; offset:12; size:4; signed:1;
+ field:int idx; offset:16; size:4; signed:1;
+ field:void * fun; offset:24; size:8; signed:0;
+
+print fmt: "cpu: %04u target: %3d step: %3d (%ps)", REC->cpu, REC->target, REC->idx, REC->fun
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cpuhp/cpuhp_pause/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cpuhp/cpuhp_pause/format
new file mode 100644
index 000000000..e0ff5e8c8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/cpuhp/cpuhp_pause/format
@@ -0,0 +1,14 @@
+name: cpuhp_pause
+ID: 68
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int cpus; offset:8; size:4; signed:0;
+ field:unsigned int active_cpus; offset:12; size:4; signed:0;
+ field:unsigned int time; offset:16; size:4; signed:0;
+ field:unsigned char pause; offset:20; size:1; signed:0;
+
+print fmt: "req_cpus=0x%x act_cpus=0x%x time=%u us paused=%d", REC->cpus, REC->active_cpus, REC->time, REC->pause
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/devfreq/devfreq_monitor/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/devfreq/devfreq_monitor/format
new file mode 100644
index 000000000..8519ba1c7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/devfreq/devfreq_monitor/format
@@ -0,0 +1,15 @@
+name: devfreq_monitor
+ID: 866
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long freq; offset:8; size:8; signed:0;
+ field:unsigned long busy_time; offset:16; size:8; signed:0;
+ field:unsigned long total_time; offset:24; size:8; signed:0;
+ field:unsigned int polling_ms; offset:32; size:4; signed:0;
+ field:__data_loc char[] dev_name; offset:36; size:4; signed:0;
+
+print fmt: "dev_name=%s freq=%lu polling_ms=%u load=%lu", __get_str(dev_name), REC->freq, REC->polling_ms, REC->total_time == 0 ? 0 : (100 * REC->busy_time) / REC->total_time
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/devfreq/dvfs_read_ppc/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/devfreq/dvfs_read_ppc/format
new file mode 100644
index 000000000..5d9a65ef8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/devfreq/dvfs_read_ppc/format
@@ -0,0 +1,14 @@
+name: dvfs_read_ppc
+ID: 1080
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long long ccnt; offset:8; size:8; signed:0;
+ field:unsigned long long pmcnt0; offset:16; size:8; signed:0;
+ field:unsigned long long pmcnt1; offset:24; size:8; signed:0;
+ field:unsigned long pa_base; offset:32; size:8; signed:0;
+
+print fmt: "ppc_base=%lx ccnt=%llu pmcnt0=%llu pmcnt1=%llu", REC->pa_base, REC->ccnt, REC->pmcnt0, REC->pmcnt1
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/devfreq/dvfs_update_load/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/devfreq/dvfs_update_load/format
new file mode 100644
index 000000000..f3b5c9def
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/devfreq/dvfs_update_load/format
@@ -0,0 +1,18 @@
+name: dvfs_update_load
+ID: 1081
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int mif_freq; offset:8; size:4; signed:0;
+ field:unsigned long long busy; offset:16; size:8; signed:0;
+ field:unsigned long long total; offset:24; size:8; signed:0;
+ field:unsigned int min_load; offset:32; size:4; signed:0;
+ field:unsigned int max_load; offset:36; size:4; signed:0;
+ field:unsigned int max_spent; offset:40; size:4; signed:0;
+ field:unsigned int idx; offset:44; size:4; signed:0;
+ field:unsigned int int_freq; offset:48; size:4; signed:0;
+
+print fmt: "mif_freq=%u busy=%llu total=%llu min_load=%u max_load=%u max_spent=%u idx=%u int_freq=%u", REC->mif_freq, REC->busy, REC->total, REC->min_load, REC->max_load, REC->max_spent, REC->idx, REC->int_freq
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_destroy/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_destroy/format
new file mode 100644
index 000000000..34e7922b8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_destroy/format
@@ -0,0 +1,14 @@
+name: dma_fence_destroy
+ID: 686
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] driver; offset:8; size:4; signed:0;
+ field:__data_loc char[] timeline; offset:12; size:4; signed:0;
+ field:unsigned int context; offset:16; size:4; signed:0;
+ field:unsigned int seqno; offset:20; size:4; signed:0;
+
+print fmt: "driver=%s timeline=%s context=%u seqno=%u", __get_str(driver), __get_str(timeline), REC->context, REC->seqno
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_emit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_emit/format
new file mode 100644
index 000000000..053549998
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_emit/format
@@ -0,0 +1,14 @@
+name: dma_fence_emit
+ID: 687
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] driver; offset:8; size:4; signed:0;
+ field:__data_loc char[] timeline; offset:12; size:4; signed:0;
+ field:unsigned int context; offset:16; size:4; signed:0;
+ field:unsigned int seqno; offset:20; size:4; signed:0;
+
+print fmt: "driver=%s timeline=%s context=%u seqno=%u", __get_str(driver), __get_str(timeline), REC->context, REC->seqno
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_enable_signal/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_enable_signal/format
new file mode 100644
index 000000000..40346ac09
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_enable_signal/format
@@ -0,0 +1,14 @@
+name: dma_fence_enable_signal
+ID: 688
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] driver; offset:8; size:4; signed:0;
+ field:__data_loc char[] timeline; offset:12; size:4; signed:0;
+ field:unsigned int context; offset:16; size:4; signed:0;
+ field:unsigned int seqno; offset:20; size:4; signed:0;
+
+print fmt: "driver=%s timeline=%s context=%u seqno=%u", __get_str(driver), __get_str(timeline), REC->context, REC->seqno
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_init/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_init/format
new file mode 100644
index 000000000..56e8243de
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_init/format
@@ -0,0 +1,14 @@
+name: dma_fence_init
+ID: 689
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] driver; offset:8; size:4; signed:0;
+ field:__data_loc char[] timeline; offset:12; size:4; signed:0;
+ field:unsigned int context; offset:16; size:4; signed:0;
+ field:unsigned int seqno; offset:20; size:4; signed:0;
+
+print fmt: "driver=%s timeline=%s context=%u seqno=%u", __get_str(driver), __get_str(timeline), REC->context, REC->seqno
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_signaled/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_signaled/format
new file mode 100644
index 000000000..879002171
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_signaled/format
@@ -0,0 +1,14 @@
+name: dma_fence_signaled
+ID: 690
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] driver; offset:8; size:4; signed:0;
+ field:__data_loc char[] timeline; offset:12; size:4; signed:0;
+ field:unsigned int context; offset:16; size:4; signed:0;
+ field:unsigned int seqno; offset:20; size:4; signed:0;
+
+print fmt: "driver=%s timeline=%s context=%u seqno=%u", __get_str(driver), __get_str(timeline), REC->context, REC->seqno
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_wait_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_wait_end/format
new file mode 100644
index 000000000..5d75b981b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_wait_end/format
@@ -0,0 +1,14 @@
+name: dma_fence_wait_end
+ID: 691
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] driver; offset:8; size:4; signed:0;
+ field:__data_loc char[] timeline; offset:12; size:4; signed:0;
+ field:unsigned int context; offset:16; size:4; signed:0;
+ field:unsigned int seqno; offset:20; size:4; signed:0;
+
+print fmt: "driver=%s timeline=%s context=%u seqno=%u", __get_str(driver), __get_str(timeline), REC->context, REC->seqno
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_wait_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_wait_start/format
new file mode 100644
index 000000000..c7c208d04
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dma_fence/dma_fence_wait_start/format
@@ -0,0 +1,14 @@
+name: dma_fence_wait_start
+ID: 692
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] driver; offset:8; size:4; signed:0;
+ field:__data_loc char[] timeline; offset:12; size:4; signed:0;
+ field:unsigned int context; offset:16; size:4; signed:0;
+ field:unsigned int seqno; offset:20; size:4; signed:0;
+
+print fmt: "driver=%s timeline=%s context=%u seqno=%u", __get_str(driver), __get_str(timeline), REC->context, REC->seqno
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dmabuf_heap/dma_heap_stat/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dmabuf_heap/dma_heap_stat/format
new file mode 100644
index 000000000..14c6e10f2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dmabuf_heap/dma_heap_stat/format
@@ -0,0 +1,13 @@
+name: dma_heap_stat
+ID: 1058
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long inode; offset:8; size:8; signed:0;
+ field:long len; offset:16; size:8; signed:1;
+ field:unsigned long total_allocated; offset:24; size:8; signed:0;
+
+print fmt: "inode=%lu len=%ldB total_allocated=%luB", REC->inode, REC->len, REC->total_allocated
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dpu/tracing_mark_write/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dpu/tracing_mark_write/format
new file mode 100644
index 000000000..4b77e29f1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dpu/tracing_mark_write/format
@@ -0,0 +1,14 @@
+name: tracing_mark_write
+ID: 1224
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char type; offset:8; size:1; signed:0;
+ field:int pid; offset:12; size:4; signed:1;
+ field:__data_loc char[] name; offset:16; size:4; signed:0;
+ field:int value; offset:20; size:4; signed:1;
+
+print fmt: "%c|%d|%s|%d", REC->type, REC->pid, __get_str(name), REC->value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/drm/drm_vblank_event/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/drm/drm_vblank_event/format
new file mode 100644
index 000000000..cf1ce931b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/drm/drm_vblank_event/format
@@ -0,0 +1,14 @@
+name: drm_vblank_event
+ID: 667
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int crtc; offset:8; size:4; signed:1;
+ field:unsigned int seq; offset:12; size:4; signed:0;
+ field:ktime_t time; offset:16; size:8; signed:1;
+ field:bool high_prec; offset:24; size:1; signed:0;
+
+print fmt: "crtc=%d, seq=%u, time=%lld, high-prec=%s", REC->crtc, REC->seq, REC->time, REC->high_prec ? "true" : "false"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/drm/drm_vblank_event_delivered/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/drm/drm_vblank_event_delivered/format
new file mode 100644
index 000000000..9bbff43c8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/drm/drm_vblank_event_delivered/format
@@ -0,0 +1,13 @@
+name: drm_vblank_event_delivered
+ID: 668
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct drm_file * file; offset:8; size:8; signed:0;
+ field:int crtc; offset:16; size:4; signed:1;
+ field:unsigned int seq; offset:20; size:4; signed:0;
+
+print fmt: "file=%p, crtc=%d, seq=%u", REC->file, REC->crtc, REC->seq
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/drm/drm_vblank_event_queued/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/drm/drm_vblank_event_queued/format
new file mode 100644
index 000000000..05d7afa84
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/drm/drm_vblank_event_queued/format
@@ -0,0 +1,13 @@
+name: drm_vblank_event_queued
+ID: 669
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct drm_file * file; offset:8; size:8; signed:0;
+ field:int crtc; offset:16; size:4; signed:1;
+ field:unsigned int seq; offset:20; size:4; signed:0;
+
+print fmt: "file=%p, crtc=%d, seq=%u", REC->file, REC->crtc, REC->seq
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_adjust_tx_power/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_adjust_tx_power/format
new file mode 100644
index 000000000..6ba5153d7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_adjust_tx_power/format
@@ -0,0 +1,18 @@
+name: dw3000_adjust_tx_power
+ID: 1167
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u32 base_power; offset:40; size:4; signed:0;
+ field:u32 adjusted_power; offset:44; size:4; signed:0;
+ field:u32 frm_dur; offset:48; size:4; signed:0;
+ field:u16 pl_len; offset:52; size:2; signed:0;
+ field:u8 chan; offset:54; size:1; signed:0;
+ field:u16 th_boost; offset:56; size:2; signed:0;
+ field:u16 app_boost; offset:58; size:2; signed:0;
+
+print fmt: "%s base pwr: 0x%08x, adjusted: 0x%08x (chan: %u,frm_dur: %u, PL_len: %u, th. boost: %u, applied boost: %u)", REC->dw_name, REC->base_power, REC->adjusted_power, REC->chan, REC->frm_dur, REC->pl_len, REC->th_boost, REC->app_boost
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_check_operational_state/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_check_operational_state/format
new file mode 100644
index 000000000..798063331
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_check_operational_state/format
@@ -0,0 +1,14 @@
+name: dw3000_check_operational_state
+ID: 1168
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:int delay_dtu; offset:40; size:4; signed:1;
+ field:enum operational_state current_operational_state; offset:44; size:4; signed:0;
+ field:enum operational_state next_operational_state; offset:48; size:4; signed:0;
+
+print fmt: "%s, delay_dtu: %d, current_operational_state: %s, next_operational_state: %s", REC->dw_name, REC->delay_dtu, __print_symbolic(REC->current_operational_state, { 0, "OFF" }, { 1, "DEEP_SLEEP" }, { 2, "SLEEP" }, { 3, "WAKE_UP" }, { 4, "INIT_RC" }, { 5, "IDLE_RC" }, { 6, "IDLE_PLL" }, { 7, "TX_WAIT" }, { 8, "TX" }, { 9, "RX_WAIT" }, { 10, "RX" }), __print_symbolic(REC->next_operational_state, { 0, "OFF" }, { 1, "DEEP_SLEEP" }, { 2, "SLEEP" }, { 3, "WAKE_UP" }, { 4, "INIT_RC" }, { 5, "IDLE_RC" }, { 6, "IDLE_PLL" }, { 7, "TX_WAIT" }, { 8, "TX" }, { 9, "RX_WAIT" }, { 10, "RX" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_coex_gpio/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_coex_gpio/format
new file mode 100644
index 000000000..50ea161cc
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_coex_gpio/format
@@ -0,0 +1,15 @@
+name: dw3000_coex_gpio
+ID: 1169
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:bool state; offset:40; size:1; signed:0;
+ field:int delay_us; offset:44; size:4; signed:1;
+ field:u32 expire; offset:48; size:4; signed:0;
+ field:bool status; offset:52; size:1; signed:0;
+
+print fmt: "%s, current state: %s, new state: %s, delay_us: %d, expire: %u", REC->dw_name, REC->status ? "ON" : "OFF", REC->state ? "ON" : "OFF", REC->delay_us, (unsigned)REC->expire
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_coex_gpio_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_coex_gpio_start/format
new file mode 100644
index 000000000..fe14326fa
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_coex_gpio_start/format
@@ -0,0 +1,14 @@
+name: dw3000_coex_gpio_start
+ID: 1170
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:int delay_us; offset:40; size:4; signed:1;
+ field:bool status; offset:44; size:1; signed:0;
+ field:int coex_interval_us; offset:48; size:4; signed:1;
+
+print fmt: "%s, delay_us: %d, status: %s, coex_interval_us: %d", REC->dw_name, REC->delay_us, REC->status ? "ON" : "OFF", REC->coex_interval_us
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_coex_gpio_stop/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_coex_gpio_stop/format
new file mode 100644
index 000000000..2395792d8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_coex_gpio_stop/format
@@ -0,0 +1,12 @@
+name: dw3000_coex_gpio_stop
+ID: 1171
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:bool status; offset:40; size:1; signed:0;
+
+print fmt: "%s, status: %s", REC->dw_name, REC->status ? "ON" : "OFF"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_deep_sleep/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_deep_sleep/format
new file mode 100644
index 000000000..896f96666
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_deep_sleep/format
@@ -0,0 +1,12 @@
+name: dw3000_deep_sleep
+ID: 1172
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:int result; offset:40; size:4; signed:1;
+
+print fmt: "%s, result: %d", REC->dw_name, REC->result
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_deep_sleep_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_deep_sleep_enter/format
new file mode 100644
index 000000000..f2047b93d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_deep_sleep_enter/format
@@ -0,0 +1,12 @@
+name: dw3000_deep_sleep_enter
+ID: 1173
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:s64 time_before; offset:40; size:8; signed:1;
+
+print fmt: "%s, time_ns: %lld", REC->dw_name, REC->time_before
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_get_counters_first_part/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_get_counters_first_part/format
new file mode 100644
index 000000000..9933876d2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_get_counters_first_part/format
@@ -0,0 +1,21 @@
+name: dw3000_get_counters_first_part
+ID: 1174
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u16 rxphe; offset:40; size:2; signed:0;
+ field:u16 rxfsl; offset:42; size:2; signed:0;
+ field:u16 rxcfg; offset:44; size:2; signed:0;
+ field:u16 rxovrr; offset:46; size:2; signed:0;
+ field:u16 rxsto; offset:48; size:2; signed:0;
+ field:u16 rxpto; offset:50; size:2; signed:0;
+ field:u16 fwto; offset:52; size:2; signed:0;
+ field:u16 txfrs; offset:54; size:2; signed:0;
+ field:u16 hpwarn; offset:56; size:2; signed:0;
+ field:u16 spicrc; offset:58; size:2; signed:0;
+
+print fmt: "%s rxphe=%d rxfsl=%d rxcfg=%d, rxovrr=%d, rxsto=%d, rxpto=%d, fwto,=%d txfrs=%d, hpwarn=%d, spicrc=%d", REC->dw_name, REC->rxphe, REC->rxfsl, REC->rxcfg, REC->rxovrr, REC->rxsto, REC->rxpto, REC->fwto, REC->txfrs, REC->hpwarn, REC->spicrc
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_get_counters_second_part/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_get_counters_second_part/format
new file mode 100644
index 000000000..2d7efd5a0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_get_counters_second_part/format
@@ -0,0 +1,14 @@
+name: dw3000_get_counters_second_part
+ID: 1175
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u16 rxprej; offset:40; size:2; signed:0;
+ field:u16 cperr; offset:42; size:2; signed:0;
+ field:u16 vwarn; offset:44; size:2; signed:0;
+
+print fmt: "%s rxfce=%d, sts_qual_err=%d, vwarn=%d", REC->dw_name, REC->rxprej, REC->cperr, REC->vwarn
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_isr/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_isr/format
new file mode 100644
index 000000000..b6496d6d8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_isr/format
@@ -0,0 +1,12 @@
+name: dw3000_isr
+ID: 1176
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u64 status; offset:40; size:8; signed:0;
+
+print fmt: "%s, status: %s", REC->dw_name, __print_flags(REC->status, "|", { 0x80000000UL, "TIMER1" }, { 0x40000000UL, "TIMER0" }, { 0x20000000UL, "ARFE" }, { 0x10000000UL, "CPERR" }, { 0x8000000UL, "HPDWARN" }, { 0x4000000UL, "RXSTO" }, { 0x2000000UL, "PLL_HILO" }, { 0x1000000UL, "RCINIT" }, { 0x800000UL, "SPIRDY" }, { 0x400000UL, "LCSSERR" }, { 0x200000UL, "RXPTO" }, { 0x100000UL, "RXOVRR" }, { 0x80000UL, "VWARN" }, { 0x40000UL, "CIAERR" }, { 0x20000UL, "RXFTO" }, { 0x10000UL, "RXFSL" }, { 0x8000U, "RXFCE" }, { 0x4000U, "RXFCG" }, { 0x2000U, "RXFR" }, { 0x1000U, "RXPHE" }, { 0x800U, "RXPHD" }, { 0x400U, "CIA_DONE" }, { 0x200U, "RXSFDD" }, { 0x100U, "RXPRD" }, { 0x80U, "TXFRS" }, { 0x40U, "TXPHS" }, { 0x20U, "TXPRS" }, { 0x10U, "TXFRB" }, { 0x8U, "AAT" }, { 0x4U, "SPICRCERR" }, { 0x2U, "CLK_PLL_LOCK" }, { 0x1U, "IRQS" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_get_timestamp/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_get_timestamp/format
new file mode 100644
index 000000000..c8fad4815
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_get_timestamp/format
@@ -0,0 +1,11 @@
+name: dw3000_mcps_get_timestamp
+ID: 1177
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->dw_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_idle/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_idle/format
new file mode 100644
index 000000000..b252e30e8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_idle/format
@@ -0,0 +1,13 @@
+name: dw3000_mcps_idle
+ID: 1178
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:bool timeout; offset:40; size:1; signed:0;
+ field:u32 timeout_dtu; offset:44; size:4; signed:0;
+
+print fmt: "%s, timeout: %s, timeout_dtu: %#x", REC->dw_name, REC->timeout ? "true" : "false", REC->timeout_dtu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_reset/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_reset/format
new file mode 100644
index 000000000..b3ee69614
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_reset/format
@@ -0,0 +1,11 @@
+name: dw3000_mcps_reset
+ID: 1179
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->dw_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_rx_disable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_rx_disable/format
new file mode 100644
index 000000000..345b025f3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_rx_disable/format
@@ -0,0 +1,11 @@
+name: dw3000_mcps_rx_disable
+ID: 1180
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->dw_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_rx_enable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_rx_enable/format
new file mode 100644
index 000000000..3dbc53379
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_rx_enable/format
@@ -0,0 +1,13 @@
+name: dw3000_mcps_rx_enable
+ID: 1181
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u8 flags; offset:40; size:1; signed:0;
+ field:int timeout; offset:44; size:4; signed:1;
+
+print fmt: "%s, flags: %s, timeout: %d", REC->dw_name, __print_flags(REC->flags, "|", { MCPS802154_RX_INFO_TIMESTAMP_DTU, "TIMESTAMP_DTU" }, { MCPS802154_RX_INFO_AACK, "AACK" }, { MCPS802154_RX_INFO_RANGING, "RANGING" }, { MCPS802154_RX_INFO_KEEP_RANGING_CLOCK, "KEEP_RANGING_CLOCK" }, { MCPS802154_RX_INFO_RANGING_PDOA, "RANGING_PDOA" }, { MCPS802154_RX_INFO_SP3, "SP3" }, { MCPS802154_RX_INFO_SP2, "SP2" }, { MCPS802154_RX_INFO_SP1, "SP1" }, { MCPS802154_RX_INFO_STS_MODE_MASK, "STS_MODE_MASK" }), REC->timeout
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_rx_get_error_frame/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_rx_get_error_frame/format
new file mode 100644
index 000000000..7206bf340
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_rx_get_error_frame/format
@@ -0,0 +1,12 @@
+name: dw3000_mcps_rx_get_error_frame
+ID: 1182
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u16 flags; offset:40; size:2; signed:0;
+
+print fmt: "%s, flags: %s", REC->dw_name, __print_flags(REC->flags, "|", { MCPS802154_RX_FRAME_INFO_TIMESTAMP_DTU, "TIMESTAMP_DTU" }, { MCPS802154_RX_FRAME_INFO_TIMESTAMP_RCTU, "TIMESTAMP_RCTU" }, { MCPS802154_RX_FRAME_INFO_LQI, "LQI" }, { MCPS802154_RX_FRAME_INFO_RSSI, "RSSI" }, { MCPS802154_RX_FRAME_INFO_RANGING_FOM, "RANGING_FOM" }, { MCPS802154_RX_FRAME_INFO_RANGING_OFFSET, "RANGING_OFFSET" }, { MCPS802154_RX_FRAME_INFO_RANGING_PDOA, "RANGING_PDOA" }, { MCPS802154_RX_FRAME_INFO_RANGING_PDOA_FOM, "RANGING_PDOA_FOM" }, { MCPS802154_RX_FRAME_INFO_RANGING_STS_TIMESTAMP_RCTU, "RANGING_STS_TIMESTAMP_RCTU" }, { MCPS802154_RX_FRAME_INFO_RANGING_STS_FOM, "RANGING_STS_FOM" }, { MCPS802154_RX_FRAME_INFO_AACK, "AACK" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_rx_get_frame/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_rx_get_frame/format
new file mode 100644
index 000000000..27e134c84
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_rx_get_frame/format
@@ -0,0 +1,12 @@
+name: dw3000_mcps_rx_get_frame
+ID: 1183
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u16 flags; offset:40; size:2; signed:0;
+
+print fmt: "%s, flags: %s", REC->dw_name, __print_flags(REC->flags, "|", { MCPS802154_RX_FRAME_INFO_TIMESTAMP_DTU, "TIMESTAMP_DTU" }, { MCPS802154_RX_FRAME_INFO_TIMESTAMP_RCTU, "TIMESTAMP_RCTU" }, { MCPS802154_RX_FRAME_INFO_LQI, "LQI" }, { MCPS802154_RX_FRAME_INFO_RSSI, "RSSI" }, { MCPS802154_RX_FRAME_INFO_RANGING_FOM, "RANGING_FOM" }, { MCPS802154_RX_FRAME_INFO_RANGING_OFFSET, "RANGING_OFFSET" }, { MCPS802154_RX_FRAME_INFO_RANGING_PDOA, "RANGING_PDOA" }, { MCPS802154_RX_FRAME_INFO_RANGING_PDOA_FOM, "RANGING_PDOA_FOM" }, { MCPS802154_RX_FRAME_INFO_RANGING_STS_TIMESTAMP_RCTU, "RANGING_STS_TIMESTAMP_RCTU" }, { MCPS802154_RX_FRAME_INFO_RANGING_STS_FOM, "RANGING_STS_FOM" }, { MCPS802154_RX_FRAME_INFO_AACK, "AACK" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_set_channel/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_set_channel/format
new file mode 100644
index 000000000..a2afdbbad
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_set_channel/format
@@ -0,0 +1,14 @@
+name: dw3000_mcps_set_channel
+ID: 1184
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u8 page; offset:40; size:1; signed:0;
+ field:u8 channel; offset:41; size:1; signed:0;
+ field:u8 pcode; offset:42; size:1; signed:0;
+
+print fmt: "%s, page: %u, channel: %u, preamble_code: %u", REC->dw_name, REC->page, REC->channel, REC->pcode
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_set_hw_addr_filt/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_set_hw_addr_filt/format
new file mode 100644
index 000000000..1eff53d6c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_set_hw_addr_filt/format
@@ -0,0 +1,12 @@
+name: dw3000_mcps_set_hw_addr_filt
+ID: 1185
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u8 changed; offset:40; size:1; signed:0;
+
+print fmt: "%s, changed: %#x", REC->dw_name, REC->changed
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_set_sts_params/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_set_sts_params/format
new file mode 100644
index 000000000..c42c15579
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_set_sts_params/format
@@ -0,0 +1,12 @@
+name: dw3000_mcps_set_sts_params
+ID: 1186
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u8 n_segs; offset:40; size:1; signed:0;
+
+print fmt: "%s, n_segs: %u", REC->dw_name, REC->n_segs
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_start/format
new file mode 100644
index 000000000..66bdf3ecc
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_start/format
@@ -0,0 +1,11 @@
+name: dw3000_mcps_start
+ID: 1187
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->dw_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_stop/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_stop/format
new file mode 100644
index 000000000..a47cb8e3d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_stop/format
@@ -0,0 +1,11 @@
+name: dw3000_mcps_stop
+ID: 1188
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->dw_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_tx_frame/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_tx_frame/format
new file mode 100644
index 000000000..e73319449
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_mcps_tx_frame/format
@@ -0,0 +1,13 @@
+name: dw3000_mcps_tx_frame
+ID: 1189
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u8 flags; offset:40; size:1; signed:0;
+ field:u16 len; offset:42; size:2; signed:0;
+
+print fmt: "%s, flags: %s, skb->len: %d", REC->dw_name, __print_flags(REC->flags, "|", { MCPS802154_TX_FRAME_TIMESTAMP_DTU, "TIMESTAMP_DTU" }, { MCPS802154_TX_FRAME_CCA, "CCA" }, { MCPS802154_TX_FRAME_RANGING, "RANGING" }, { MCPS802154_TX_FRAME_KEEP_RANGING_CLOCK, "KEEP_RANGING_CLOCK" }, { MCPS802154_TX_FRAME_SP3, "SP3" }, { MCPS802154_TX_FRAME_SP2, "SP2" }, { MCPS802154_TX_FRAME_SP1, "SP1" }, { MCPS802154_TX_FRAME_STS_MODE_MASK, "STS_MODE_MASK" }),REC->len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_clock_offset_payload_put/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_clock_offset_payload_put/format
new file mode 100644
index 000000000..5d9d7b21c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_clock_offset_payload_put/format
@@ -0,0 +1,12 @@
+name: dw3000_nfcc_coex_clock_offset_payload_put
+ID: 1190
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u32 clock_offset_sys_time; offset:40; size:4; signed:0;
+
+print fmt: "%s, clock_offset_sys_time=%#08x", REC->dw_name, REC->clock_offset_sys_time
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_clock_sync_payload_put/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_clock_sync_payload_put/format
new file mode 100644
index 000000000..bc0fe51d9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_clock_sync_payload_put/format
@@ -0,0 +1,12 @@
+name: dw3000_nfcc_coex_clock_sync_payload_put
+ID: 1191
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u32 session_time0_sys_time; offset:40; size:4; signed:0;
+
+print fmt: "%s, session_time0_sys_time=%#08x", REC->dw_name, REC->session_time0_sys_time
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_disable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_disable/format
new file mode 100644
index 000000000..78ed24c09
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_disable/format
@@ -0,0 +1,11 @@
+name: dw3000_nfcc_coex_disable
+ID: 1192
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->dw_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_enable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_enable/format
new file mode 100644
index 000000000..2a39abf34
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_enable/format
@@ -0,0 +1,12 @@
+name: dw3000_nfcc_coex_enable
+ID: 1193
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:int channel; offset:40; size:4; signed:1;
+
+print fmt: "%s, channel=%d", REC->dw_name, REC->channel
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_err/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_err/format
new file mode 100644
index 000000000..631df0663
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_err/format
@@ -0,0 +1,12 @@
+name: dw3000_nfcc_coex_err
+ID: 1194
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:__data_loc char[] err; offset:40; size:4; signed:0;
+
+print fmt: "%s, err="%s"", REC->dw_name, __get_str(err)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_header_check/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_header_check/format
new file mode 100644
index 000000000..9f8b53a48
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_header_check/format
@@ -0,0 +1,15 @@
+name: dw3000_nfcc_coex_header_check
+ID: 1195
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u8 signature[5]; offset:40; size:5; signed:0;
+ field:u8 ver_id; offset:45; size:1; signed:0;
+ field:u8 seq_num; offset:46; size:1; signed:0;
+ field:u8 nb_tlv; offset:47; size:1; signed:0;
+
+print fmt: "%s, signature=%s, ver_id=%u, seq_num=%u, nb_tlv=%u", REC->dw_name, __print_array(REC->signature, 5, sizeof(u8)), REC->ver_id, REC->seq_num, REC->nb_tlv
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_isr/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_isr/format
new file mode 100644
index 000000000..791455e30
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_isr/format
@@ -0,0 +1,12 @@
+name: dw3000_nfcc_coex_isr
+ID: 1196
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u8 dss_stat; offset:40; size:1; signed:0;
+
+print fmt: "%s, dss_stat=%#x", REC->dw_name, REC->dss_stat
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_rx_msg_info/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_rx_msg_info/format
new file mode 100644
index 000000000..2a716bbdf
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_rx_msg_info/format
@@ -0,0 +1,13 @@
+name: dw3000_nfcc_coex_rx_msg_info
+ID: 1197
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u32 next_timestamp_sys_time; offset:40; size:4; signed:0;
+ field:int next_duration_sys_time; offset:44; size:4; signed:1;
+
+print fmt: "%s, next_timestamp_sys_time=%#08x, next_duration_sys_time=%#08x", REC->dw_name, REC->next_timestamp_sys_time, REC->next_duration_sys_time
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_sleep/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_sleep/format
new file mode 100644
index 000000000..0014f7bad
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_sleep/format
@@ -0,0 +1,12 @@
+name: dw3000_nfcc_coex_sleep
+ID: 1198
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u32 sleep_dtu; offset:40; size:4; signed:0;
+
+print fmt: "%s, sleep_dtu=%u", REC->dw_name, REC->sleep_dtu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_warn/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_warn/format
new file mode 100644
index 000000000..7e229e046
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_warn/format
@@ -0,0 +1,12 @@
+name: dw3000_nfcc_coex_warn
+ID: 1199
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:__data_loc char[] warn; offset:40; size:4; signed:0;
+
+print fmt: "%s, warn="%s"", REC->dw_name, __get_str(warn)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_watchdog/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_watchdog/format
new file mode 100644
index 000000000..6b9dbad5d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_nfcc_coex_watchdog/format
@@ -0,0 +1,11 @@
+name: dw3000_nfcc_coex_watchdog
+ID: 1200
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->dw_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_power_stats/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_power_stats/format
new file mode 100644
index 000000000..2e28e6ffe
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_power_stats/format
@@ -0,0 +1,14 @@
+name: dw3000_power_stats
+ID: 1201
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:int state; offset:40; size:4; signed:1;
+ field:u64 boot_time_ns; offset:48; size:8; signed:0;
+ field:int len_or_date; offset:56; size:4; signed:1;
+
+print fmt: "%s, state: %s, boot_time_ns: %llu, len_or_date: %u", REC->dw_name, __print_symbolic(REC->state, { 0, "OFF" }, { 1, "DEEPSLEEP" }, { 2, "RUN" }, { 3, "IDLE" }, { 4, "RX" }, { 5, "TX" }), REC->boot_time_ns, (unsigned)REC->len_or_date
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_rctu_convert_align/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_rctu_convert_align/format
new file mode 100644
index 000000000..5634039bd
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_rctu_convert_align/format
@@ -0,0 +1,12 @@
+name: dw3000_rctu_convert_align
+ID: 1202
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u32 rmarker_dtu; offset:40; size:4; signed:0;
+
+print fmt: "%s, rmarker_dtu: %#x", REC->dw_name, REC->rmarker_dtu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_rctu_convert_rx/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_rctu_convert_rx/format
new file mode 100644
index 000000000..38833daa1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_rctu_convert_rx/format
@@ -0,0 +1,14 @@
+name: dw3000_rctu_convert_rx
+ID: 1203
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u32 rmarker_dtu; offset:40; size:4; signed:0;
+ field:u64 ts_rctu; offset:48; size:8; signed:0;
+ field:u64 rmarker_rctu; offset:56; size:8; signed:0;
+
+print fmt: "%s, rmarker_dtu: %#x, ts_rctu: %#llx, rmarker_rctu: %#llx", REC->dw_name, REC->rmarker_dtu, REC->ts_rctu, REC->rmarker_rctu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_rctu_convert_synced/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_rctu_convert_synced/format
new file mode 100644
index 000000000..e536d1ac8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_rctu_convert_synced/format
@@ -0,0 +1,12 @@
+name: dw3000_rctu_convert_synced
+ID: 1204
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u64 rmarker_rctu; offset:40; size:8; signed:0;
+
+print fmt: "%s, rmarker_rctu: %#llx", REC->dw_name, REC->rmarker_rctu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_rctu_convert_tx/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_rctu_convert_tx/format
new file mode 100644
index 000000000..bf9acd97c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_rctu_convert_tx/format
@@ -0,0 +1,14 @@
+name: dw3000_rctu_convert_tx
+ID: 1205
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u32 ts_dtu; offset:40; size:4; signed:0;
+ field:u32 ant_offset; offset:44; size:4; signed:0;
+ field:u64 rmarker_rctu; offset:48; size:8; signed:0;
+
+print fmt: "%s, ts_dtu: %#x, ant_offset: %#x, rmarker_rctu: %#llx", REC->dw_name, REC->ts_dtu, REC->ant_offset, REC->rmarker_rctu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_read_clockoffset/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_read_clockoffset/format
new file mode 100644
index 000000000..b722201e4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_read_clockoffset/format
@@ -0,0 +1,12 @@
+name: dw3000_read_clockoffset
+ID: 1206
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:s16 cfo; offset:40; size:2; signed:1;
+
+print fmt: "%s clockoffset=%d", REC->dw_name, REC->cfo
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_read_pdoa/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_read_pdoa/format
new file mode 100644
index 000000000..69ea8a0b8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_read_pdoa/format
@@ -0,0 +1,12 @@
+name: dw3000_read_pdoa
+ID: 1207
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u32 pdoa; offset:40; size:4; signed:0;
+
+print fmt: "%s pdoa=%#08x", REC->dw_name, REC->pdoa
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_read_rx_timestamp/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_read_rx_timestamp/format
new file mode 100644
index 000000000..efd3a2527
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_read_rx_timestamp/format
@@ -0,0 +1,11 @@
+name: dw3000_read_rx_timestamp
+ID: 1208
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->dw_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_resync_dtu_sys_time/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_resync_dtu_sys_time/format
new file mode 100644
index 000000000..1873be240
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_resync_dtu_sys_time/format
@@ -0,0 +1,13 @@
+name: dw3000_resync_dtu_sys_time
+ID: 1209
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u32 sys_time_sync; offset:40; size:4; signed:0;
+ field:u32 dtu_sync; offset:44; size:4; signed:0;
+
+print fmt: "%s, sys_time_sync: %#08x, dtu_sync: %#08x", REC->dw_name, REC->sys_time_sync, REC->dtu_sync
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_return_int/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_return_int/format
new file mode 100644
index 000000000..673ae0aa5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_return_int/format
@@ -0,0 +1,12 @@
+name: dw3000_return_int
+ID: 1210
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:int ret; offset:40; size:4; signed:1;
+
+print fmt: "%s, return %d", REC->dw_name, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_return_int_u32/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_return_int_u32/format
new file mode 100644
index 000000000..8c104b690
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_return_int_u32/format
@@ -0,0 +1,13 @@
+name: dw3000_return_int_u32
+ID: 1211
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:int ret; offset:40; size:4; signed:1;
+ field:u32 val; offset:44; size:4; signed:0;
+
+print fmt: "%s, return %d, value %#x", REC->dw_name, REC->ret, REC->val
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_return_int_u64/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_return_int_u64/format
new file mode 100644
index 000000000..d0c564e5c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_return_int_u64/format
@@ -0,0 +1,13 @@
+name: dw3000_return_int_u64
+ID: 1212
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:int ret; offset:40; size:4; signed:1;
+ field:u64 val; offset:48; size:8; signed:0;
+
+print fmt: "%s, return %d, value %#llx", REC->dw_name, REC->ret, REC->val
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_return_void/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_return_void/format
new file mode 100644
index 000000000..3621ad1eb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_return_void/format
@@ -0,0 +1,11 @@
+name: dw3000_return_void
+ID: 1213
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->dw_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_rx_rssi/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_rx_rssi/format
new file mode 100644
index 000000000..617ec4b4b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_rx_rssi/format
@@ -0,0 +1,17 @@
+name: dw3000_rx_rssi
+ID: 1214
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:const char * chip_name; offset:40; size:8; signed:0;
+ field:bool sts; offset:48; size:1; signed:0;
+ field:u32 cir_pwr; offset:52; size:4; signed:0;
+ field:u16 pacc_cnt; offset:56; size:2; signed:0;
+ field:u8 prf_64mhz; offset:58; size:1; signed:0;
+ field:u8 dgc_dec; offset:59; size:1; signed:0;
+
+print fmt: "%s, chip: %s sts: %u cir_pwr: %u pacc_cnt: %u prf_64mhz: %u dgc_dec: %u", REC->dw_name, REC->chip_name, REC->sts, REC->cir_pwr, REC->pacc_cnt, REC->prf_64mhz, REC->dgc_dec
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_set_antenna_gpio/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_set_antenna_gpio/format
new file mode 100644
index 000000000..dfb385bb8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_set_antenna_gpio/format
@@ -0,0 +1,14 @@
+name: dw3000_set_antenna_gpio
+ID: 1215
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:int res; offset:40; size:4; signed:1;
+ field:u8 gpio; offset:44; size:1; signed:0;
+ field:u8 value; offset:45; size:1; signed:0;
+
+print fmt: "%s, res: %d, gpio: %u, value: %u", REC->dw_name, REC->res, REC->gpio, REC->value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_set_operational_state/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_set_operational_state/format
new file mode 100644
index 000000000..6e560d881
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_set_operational_state/format
@@ -0,0 +1,12 @@
+name: dw3000_set_operational_state
+ID: 1216
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:enum operational_state operational_state; offset:40; size:4; signed:0;
+
+print fmt: "%s, operational_state: %s", REC->dw_name, __print_symbolic(REC->operational_state, { 0, "OFF" }, { 1, "DEEP_SLEEP" }, { 2, "SLEEP" }, { 3, "WAKE_UP" }, { 4, "INIT_RC" }, { 5, "IDLE_RC" }, { 6, "IDLE_PLL" }, { 7, "TX_WAIT" }, { 8, "TX" }, { 9, "RX_WAIT" }, { 10, "RX" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_set_pdoa/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_set_pdoa/format
new file mode 100644
index 000000000..0e1b29331
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_set_pdoa/format
@@ -0,0 +1,12 @@
+name: dw3000_set_pdoa
+ID: 1217
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u32 mode; offset:40; size:4; signed:0;
+
+print fmt: "%s Set PDoA mode to %d", REC->dw_name, REC->mode
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_testmode_continuous_tx_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_testmode_continuous_tx_start/format
new file mode 100644
index 000000000..c1b63b244
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_testmode_continuous_tx_start/format
@@ -0,0 +1,14 @@
+name: dw3000_testmode_continuous_tx_start
+ID: 1218
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u8 chan; offset:40; size:1; signed:0;
+ field:u32 len; offset:44; size:4; signed:0;
+ field:u32 rate; offset:48; size:4; signed:0;
+
+print fmt: "%s chan=%d, len=%d, rate=%d", REC->dw_name, REC->chan, REC->len, REC->rate
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_testmode_continuous_tx_stop/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_testmode_continuous_tx_stop/format
new file mode 100644
index 000000000..4836aa61f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_testmode_continuous_tx_stop/format
@@ -0,0 +1,11 @@
+name: dw3000_testmode_continuous_tx_stop
+ID: 1219
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->dw_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_tm_cmd/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_tm_cmd/format
new file mode 100644
index 000000000..2ec3270a9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_tm_cmd/format
@@ -0,0 +1,12 @@
+name: dw3000_tm_cmd
+ID: 1220
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:u32 cmd; offset:40; size:4; signed:0;
+
+print fmt: "%s, cmd: %s", REC->dw_name, __print_symbolic(REC->cmd, { 1, "START_RX_DIAG" }, { 2, "STOP_RX_DIAG" }, { 3, "GET_RX_DIAG" }, { 4, "CLEAR_RX_DIAG" }, { 7, "START_TX_CWTONE" }, { 8, "STOP_TX_CWTONE" }, { 5, "OTP_READ" }, { 6, "OTP_WRITE" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_wakeup/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_wakeup/format
new file mode 100644
index 000000000..dedbac86a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_wakeup/format
@@ -0,0 +1,11 @@
+name: dw3000_wakeup
+ID: 1221
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->dw_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_wakeup_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_wakeup_done/format
new file mode 100644
index 000000000..0996c66fa
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_wakeup_done/format
@@ -0,0 +1,15 @@
+name: dw3000_wakeup_done
+ID: 1222
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:s64 sleep_time_us; offset:40; size:8; signed:1;
+ field:u32 sleep_enter_dtu; offset:48; size:4; signed:0;
+ field:u32 dtu_next_op; offset:52; size:4; signed:0;
+ field:enum operational_state next_op; offset:56; size:4; signed:0;
+
+print fmt: "%s, sleep_us: %lld, sleep_enter_dtu: %#x, next_op_date: %#x, next_op: %s", REC->dw_name, REC->sleep_time_us, REC->sleep_enter_dtu, REC->dtu_next_op, __print_symbolic(REC->next_op, { 0, "OFF" }, { 1, "DEEP_SLEEP" }, { 2, "SLEEP" }, { 3, "WAKE_UP" }, { 4, "INIT_RC" }, { 5, "IDLE_RC" }, { 6, "IDLE_PLL" }, { 7, "TX_WAIT" }, { 8, "TX" }, { 9, "RX_WAIT" }, { 10, "RX" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_wakeup_timer_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_wakeup_timer_start/format
new file mode 100644
index 000000000..f1ca48137
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dw3000/dw3000_wakeup_timer_start/format
@@ -0,0 +1,12 @@
+name: dw3000_wakeup_timer_start
+ID: 1223
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char dw_name[32]; offset:8; size:32; signed:0;
+ field:int delay_us; offset:40; size:4; signed:1;
+
+print fmt: "%s, delay: %dus", REC->dw_name, REC->delay_us
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_alloc_request/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_alloc_request/format
new file mode 100644
index 000000000..5410d1600
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_alloc_request/format
@@ -0,0 +1,18 @@
+name: dwc3_alloc_request
+ID: 725
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:struct dwc3_request * req; offset:16; size:8; signed:0;
+ field:unsigned int actual; offset:24; size:4; signed:0;
+ field:unsigned int length; offset:28; size:4; signed:0;
+ field:int status; offset:32; size:4; signed:1;
+ field:int zero; offset:36; size:4; signed:1;
+ field:int short_not_ok; offset:40; size:4; signed:1;
+ field:int no_interrupt; offset:44; size:4; signed:1;
+
+print fmt: "%s: req %p length %u/%u %s%s%s ==> %d", __get_str(name), REC->req, REC->actual, REC->length, REC->zero ? "Z" : "z", REC->short_not_ok ? "S" : "s", REC->no_interrupt ? "i" : "I", REC->status
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_complete_trb/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_complete_trb/format
new file mode 100644
index 000000000..87915da30
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_complete_trb/format
@@ -0,0 +1,21 @@
+name: dwc3_complete_trb
+ID: 726
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:struct dwc3_trb * trb; offset:16; size:8; signed:0;
+ field:u32 allocated; offset:24; size:4; signed:0;
+ field:u32 queued; offset:28; size:4; signed:0;
+ field:u32 bpl; offset:32; size:4; signed:0;
+ field:u32 bph; offset:36; size:4; signed:0;
+ field:u32 size; offset:40; size:4; signed:0;
+ field:u32 ctrl; offset:44; size:4; signed:0;
+ field:u32 type; offset:48; size:4; signed:0;
+ field:u32 enqueue; offset:52; size:4; signed:0;
+ field:u32 dequeue; offset:56; size:4; signed:0;
+
+print fmt: "%s: trb %p (E%d:D%d) buf %08x%08x size %s%d ctrl %08x (%c%c%c%c:%c%c:%s)", __get_str(name), REC->trb, REC->enqueue, REC->dequeue, REC->bph, REC->bpl, ({char *s; int pcm = ((REC->size >> 24) & 3) + 1; switch (REC->type) { case 3: case 1: switch (pcm) { case 1: s = "1x "; break; case 2: s = "2x "; break; case 3: default: s = "3x "; break; } break; default: s = ""; } s; }), ((REC->size) & (0x00ffffff)), REC->ctrl, REC->ctrl & ((((1UL))) << (0)) ? 'H' : 'h', REC->ctrl & ((((1UL))) << (1)) ? 'L' : 'l', REC->ctrl & ((((1UL))) << (2)) ? 'C' : 'c', REC->ctrl & ((((1UL))) << (3)) ? 'S' : 's', REC->ctrl & ((((1UL))) << (10)) ? 'S' : 's', REC->ctrl & ((((1UL))) << (11)) ? 'C' : 'c', dwc3_trb_type_string(((REC->ctrl) & (0x3f << 4)))
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_ctrl_req/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_ctrl_req/format
new file mode 100644
index 000000000..f68bc2a78
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_ctrl_req/format
@@ -0,0 +1,16 @@
+name: dwc3_ctrl_req
+ID: 727
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__u8 bRequestType; offset:8; size:1; signed:0;
+ field:__u8 bRequest; offset:9; size:1; signed:0;
+ field:__u16 wValue; offset:10; size:2; signed:0;
+ field:__u16 wIndex; offset:12; size:2; signed:0;
+ field:__u16 wLength; offset:14; size:2; signed:0;
+ field:__data_loc char[] str; offset:16; size:4; signed:0;
+
+print fmt: "%s", usb_decode_ctrl(__get_str(str), 500, REC->bRequestType, REC->bRequest, REC->wValue, REC->wIndex, REC->wLength)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_ep_dequeue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_ep_dequeue/format
new file mode 100644
index 000000000..19fe3ee94
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_ep_dequeue/format
@@ -0,0 +1,18 @@
+name: dwc3_ep_dequeue
+ID: 728
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:struct dwc3_request * req; offset:16; size:8; signed:0;
+ field:unsigned int actual; offset:24; size:4; signed:0;
+ field:unsigned int length; offset:28; size:4; signed:0;
+ field:int status; offset:32; size:4; signed:1;
+ field:int zero; offset:36; size:4; signed:1;
+ field:int short_not_ok; offset:40; size:4; signed:1;
+ field:int no_interrupt; offset:44; size:4; signed:1;
+
+print fmt: "%s: req %p length %u/%u %s%s%s ==> %d", __get_str(name), REC->req, REC->actual, REC->length, REC->zero ? "Z" : "z", REC->short_not_ok ? "S" : "s", REC->no_interrupt ? "i" : "I", REC->status
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_ep_queue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_ep_queue/format
new file mode 100644
index 000000000..cf3fd6c06
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_ep_queue/format
@@ -0,0 +1,18 @@
+name: dwc3_ep_queue
+ID: 729
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:struct dwc3_request * req; offset:16; size:8; signed:0;
+ field:unsigned int actual; offset:24; size:4; signed:0;
+ field:unsigned int length; offset:28; size:4; signed:0;
+ field:int status; offset:32; size:4; signed:1;
+ field:int zero; offset:36; size:4; signed:1;
+ field:int short_not_ok; offset:40; size:4; signed:1;
+ field:int no_interrupt; offset:44; size:4; signed:1;
+
+print fmt: "%s: req %p length %u/%u %s%s%s ==> %d", __get_str(name), REC->req, REC->actual, REC->length, REC->zero ? "Z" : "z", REC->short_not_ok ? "S" : "s", REC->no_interrupt ? "i" : "I", REC->status
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_event/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_event/format
new file mode 100644
index 000000000..50708a31b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_event/format
@@ -0,0 +1,13 @@
+name: dwc3_event
+ID: 730
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 event; offset:8; size:4; signed:0;
+ field:u32 ep0state; offset:12; size:4; signed:0;
+ field:__data_loc char[] str; offset:16; size:4; signed:0;
+
+print fmt: "event (%08x): %s", REC->event, dwc3_decode_event(__get_str(str), 500, REC->event, REC->ep0state)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_free_request/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_free_request/format
new file mode 100644
index 000000000..526e6da8d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_free_request/format
@@ -0,0 +1,18 @@
+name: dwc3_free_request
+ID: 731
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:struct dwc3_request * req; offset:16; size:8; signed:0;
+ field:unsigned int actual; offset:24; size:4; signed:0;
+ field:unsigned int length; offset:28; size:4; signed:0;
+ field:int status; offset:32; size:4; signed:1;
+ field:int zero; offset:36; size:4; signed:1;
+ field:int short_not_ok; offset:40; size:4; signed:1;
+ field:int no_interrupt; offset:44; size:4; signed:1;
+
+print fmt: "%s: req %p length %u/%u %s%s%s ==> %d", __get_str(name), REC->req, REC->actual, REC->length, REC->zero ? "Z" : "z", REC->short_not_ok ? "S" : "s", REC->no_interrupt ? "i" : "I", REC->status
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_gadget_ep_cmd/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_gadget_ep_cmd/format
new file mode 100644
index 000000000..8bd90a98d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_gadget_ep_cmd/format
@@ -0,0 +1,16 @@
+name: dwc3_gadget_ep_cmd
+ID: 732
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int cmd; offset:12; size:4; signed:0;
+ field:u32 param0; offset:16; size:4; signed:0;
+ field:u32 param1; offset:20; size:4; signed:0;
+ field:u32 param2; offset:24; size:4; signed:0;
+ field:int cmd_status; offset:28; size:4; signed:1;
+
+print fmt: "%s: cmd '%s' [%x] params %08x %08x %08x --> status: %s", __get_str(name), dwc3_gadget_ep_cmd_string(REC->cmd), REC->cmd, REC->param0, REC->param1, REC->param2, dwc3_ep_cmd_status_string(REC->cmd_status)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_gadget_ep_disable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_gadget_ep_disable/format
new file mode 100644
index 000000000..d85369332
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_gadget_ep_disable/format
@@ -0,0 +1,19 @@
+name: dwc3_gadget_ep_disable
+ID: 733
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int maxpacket; offset:12; size:4; signed:0;
+ field:unsigned int maxpacket_limit; offset:16; size:4; signed:0;
+ field:unsigned int max_streams; offset:20; size:4; signed:0;
+ field:unsigned int maxburst; offset:24; size:4; signed:0;
+ field:unsigned int flags; offset:28; size:4; signed:0;
+ field:unsigned int direction; offset:32; size:4; signed:0;
+ field:u8 trb_enqueue; offset:36; size:1; signed:0;
+ field:u8 trb_dequeue; offset:37; size:1; signed:0;
+
+print fmt: "%s: mps %d/%d streams %d burst %d ring %d/%d flags %c:%c%c%c%c:%c", __get_str(name), REC->maxpacket, REC->maxpacket_limit, REC->max_streams, REC->maxburst, REC->trb_enqueue, REC->trb_dequeue, REC->flags & ((((1UL))) << (0)) ? 'E' : 'e', REC->flags & ((((1UL))) << (1)) ? 'S' : 's', REC->flags & ((((1UL))) << (2)) ? 'W' : 'w', REC->flags & ((((1UL))) << (3)) ? 'B' : 'b', REC->flags & ((((1UL))) << (5)) ? 'P' : 'p', REC->direction ? '<' : '>'
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_gadget_ep_enable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_gadget_ep_enable/format
new file mode 100644
index 000000000..627f3dbd8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_gadget_ep_enable/format
@@ -0,0 +1,19 @@
+name: dwc3_gadget_ep_enable
+ID: 734
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int maxpacket; offset:12; size:4; signed:0;
+ field:unsigned int maxpacket_limit; offset:16; size:4; signed:0;
+ field:unsigned int max_streams; offset:20; size:4; signed:0;
+ field:unsigned int maxburst; offset:24; size:4; signed:0;
+ field:unsigned int flags; offset:28; size:4; signed:0;
+ field:unsigned int direction; offset:32; size:4; signed:0;
+ field:u8 trb_enqueue; offset:36; size:1; signed:0;
+ field:u8 trb_dequeue; offset:37; size:1; signed:0;
+
+print fmt: "%s: mps %d/%d streams %d burst %d ring %d/%d flags %c:%c%c%c%c:%c", __get_str(name), REC->maxpacket, REC->maxpacket_limit, REC->max_streams, REC->maxburst, REC->trb_enqueue, REC->trb_dequeue, REC->flags & ((((1UL))) << (0)) ? 'E' : 'e', REC->flags & ((((1UL))) << (1)) ? 'S' : 's', REC->flags & ((((1UL))) << (2)) ? 'W' : 'w', REC->flags & ((((1UL))) << (3)) ? 'B' : 'b', REC->flags & ((((1UL))) << (5)) ? 'P' : 'p', REC->direction ? '<' : '>'
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_gadget_generic_cmd/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_gadget_generic_cmd/format
new file mode 100644
index 000000000..4bfbf3087
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_gadget_generic_cmd/format
@@ -0,0 +1,13 @@
+name: dwc3_gadget_generic_cmd
+ID: 735
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int cmd; offset:8; size:4; signed:0;
+ field:u32 param; offset:12; size:4; signed:0;
+ field:int status; offset:16; size:4; signed:1;
+
+print fmt: "cmd '%s' [%x] param %08x --> status: %s", dwc3_gadget_generic_cmd_string(REC->cmd), REC->cmd, REC->param, dwc3_gadget_generic_cmd_status_string(REC->status)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_gadget_giveback/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_gadget_giveback/format
new file mode 100644
index 000000000..0ca80d5bf
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_gadget_giveback/format
@@ -0,0 +1,18 @@
+name: dwc3_gadget_giveback
+ID: 736
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:struct dwc3_request * req; offset:16; size:8; signed:0;
+ field:unsigned int actual; offset:24; size:4; signed:0;
+ field:unsigned int length; offset:28; size:4; signed:0;
+ field:int status; offset:32; size:4; signed:1;
+ field:int zero; offset:36; size:4; signed:1;
+ field:int short_not_ok; offset:40; size:4; signed:1;
+ field:int no_interrupt; offset:44; size:4; signed:1;
+
+print fmt: "%s: req %p length %u/%u %s%s%s ==> %d", __get_str(name), REC->req, REC->actual, REC->length, REC->zero ? "Z" : "z", REC->short_not_ok ? "S" : "s", REC->no_interrupt ? "i" : "I", REC->status
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_prepare_trb/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_prepare_trb/format
new file mode 100644
index 000000000..971036e21
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_prepare_trb/format
@@ -0,0 +1,21 @@
+name: dwc3_prepare_trb
+ID: 737
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:struct dwc3_trb * trb; offset:16; size:8; signed:0;
+ field:u32 allocated; offset:24; size:4; signed:0;
+ field:u32 queued; offset:28; size:4; signed:0;
+ field:u32 bpl; offset:32; size:4; signed:0;
+ field:u32 bph; offset:36; size:4; signed:0;
+ field:u32 size; offset:40; size:4; signed:0;
+ field:u32 ctrl; offset:44; size:4; signed:0;
+ field:u32 type; offset:48; size:4; signed:0;
+ field:u32 enqueue; offset:52; size:4; signed:0;
+ field:u32 dequeue; offset:56; size:4; signed:0;
+
+print fmt: "%s: trb %p (E%d:D%d) buf %08x%08x size %s%d ctrl %08x (%c%c%c%c:%c%c:%s)", __get_str(name), REC->trb, REC->enqueue, REC->dequeue, REC->bph, REC->bpl, ({char *s; int pcm = ((REC->size >> 24) & 3) + 1; switch (REC->type) { case 3: case 1: switch (pcm) { case 1: s = "1x "; break; case 2: s = "2x "; break; case 3: default: s = "3x "; break; } break; default: s = ""; } s; }), ((REC->size) & (0x00ffffff)), REC->ctrl, REC->ctrl & ((((1UL))) << (0)) ? 'H' : 'h', REC->ctrl & ((((1UL))) << (1)) ? 'L' : 'l', REC->ctrl & ((((1UL))) << (2)) ? 'C' : 'c', REC->ctrl & ((((1UL))) << (3)) ? 'S' : 's', REC->ctrl & ((((1UL))) << (10)) ? 'S' : 's', REC->ctrl & ((((1UL))) << (11)) ? 'C' : 'c', dwc3_trb_type_string(((REC->ctrl) & (0x3f << 4)))
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_readl/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_readl/format
new file mode 100644
index 000000000..c8bbb955c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_readl/format
@@ -0,0 +1,13 @@
+name: dwc3_readl
+ID: 738
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * base; offset:8; size:8; signed:0;
+ field:u32 offset; offset:16; size:4; signed:0;
+ field:u32 value; offset:20; size:4; signed:0;
+
+print fmt: "addr %p value %08x", REC->base + REC->offset, REC->value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_writel/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_writel/format
new file mode 100644
index 000000000..64bfc7d15
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/dwc3/dwc3_writel/format
@@ -0,0 +1,13 @@
+name: dwc3_writel
+ID: 739
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * base; offset:8; size:8; signed:0;
+ field:u32 offset; offset:16; size:4; signed:0;
+ field:u32 value; offset:20; size:4; signed:0;
+
+print fmt: "addr %p value %08x", REC->base + REC->offset, REC->value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/edgetpu/edgetpu_map_buffer_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/edgetpu/edgetpu_map_buffer_end/format
new file mode 100644
index 000000000..be941fcbe
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/edgetpu/edgetpu_map_buffer_end/format
@@ -0,0 +1,15 @@
+name: edgetpu_map_buffer_end
+ID: 1117
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__u64 host_address; offset:8; size:8; signed:0;
+ field:__u64 size; offset:16; size:8; signed:0;
+ field:__u64 device_address; offset:24; size:8; signed:0;
+ field:edgetpu_map_flag_t flags; offset:32; size:4; signed:0;
+ field:__u32 die_index; offset:36; size:4; signed:0;
+
+print fmt: "host_address = 0x%llx, size = %llu, device_address = 0x%llx, flags = 0x%x, die_index = %u", REC->host_address, REC->size, REC->device_address, REC->flags, REC->die_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/edgetpu/edgetpu_map_buffer_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/edgetpu/edgetpu_map_buffer_start/format
new file mode 100644
index 000000000..fcabb1e05
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/edgetpu/edgetpu_map_buffer_start/format
@@ -0,0 +1,14 @@
+name: edgetpu_map_buffer_start
+ID: 1118
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__u64 host_address; offset:8; size:8; signed:0;
+ field:__u64 size; offset:16; size:8; signed:0;
+ field:edgetpu_map_flag_t flags; offset:24; size:4; signed:0;
+ field:__u32 die_index; offset:28; size:4; signed:0;
+
+print fmt: "host_address = 0x%llx, size = %llu, flags = 0x%x, die_index = %u", REC->host_address, REC->size, REC->flags, REC->die_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/edgetpu/edgetpu_map_dmabuf_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/edgetpu/edgetpu_map_dmabuf_end/format
new file mode 100644
index 000000000..ddeaffee2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/edgetpu/edgetpu_map_dmabuf_end/format
@@ -0,0 +1,16 @@
+name: edgetpu_map_dmabuf_end
+ID: 1119
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__u64 offset; offset:8; size:8; signed:0;
+ field:__u64 size; offset:16; size:8; signed:0;
+ field:__u64 device_address; offset:24; size:8; signed:0;
+ field:int dmabuf_fd; offset:32; size:4; signed:1;
+ field:edgetpu_map_flag_t flags; offset:36; size:4; signed:0;
+ field:__u32 die_index; offset:40; size:4; signed:0;
+
+print fmt: "offset = 0x%llx, size = %llu, device_address = 0x%llx, dmabuf_fd = %d, flags = 0x%x, die_index = %u", REC->offset, REC->size, REC->device_address, REC->dmabuf_fd, REC->flags, REC->die_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/edgetpu/edgetpu_map_dmabuf_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/edgetpu/edgetpu_map_dmabuf_start/format
new file mode 100644
index 000000000..9c8f0c200
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/edgetpu/edgetpu_map_dmabuf_start/format
@@ -0,0 +1,15 @@
+name: edgetpu_map_dmabuf_start
+ID: 1120
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__u64 offset; offset:8; size:8; signed:0;
+ field:__u64 size; offset:16; size:8; signed:0;
+ field:int dmabuf_fd; offset:24; size:4; signed:1;
+ field:edgetpu_map_flag_t flags; offset:28; size:4; signed:0;
+ field:__u32 die_index; offset:32; size:4; signed:0;
+
+print fmt: "offset = 0x%llx, size = %llu, dmabuf_fd = %d, flags = 0x%x, die_index = %u", REC->offset, REC->size, REC->dmabuf_fd, REC->flags, REC->die_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/emulation/instruction_emulation/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/emulation/instruction_emulation/format
new file mode 100644
index 000000000..848719831
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/emulation/instruction_emulation/format
@@ -0,0 +1,12 @@
+name: instruction_emulation
+ID: 25
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] instr; offset:8; size:4; signed:0;
+ field:u64 addr; offset:16; size:8; signed:0;
+
+print fmt: "instr="%s" addr=0x%llx", __get_str(instr), REC->addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_destroy_inode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_destroy_inode/format
new file mode 100644
index 000000000..b68450296
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_destroy_inode/format
@@ -0,0 +1,12 @@
+name: erofs_destroy_inode
+ID: 575
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:erofs_nid_t nid; offset:16; size:8; signed:0;
+
+print fmt: "dev = (%d,%d), nid = %llu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->nid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_fill_inode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_fill_inode/format
new file mode 100644
index 000000000..10700011d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_fill_inode/format
@@ -0,0 +1,15 @@
+name: erofs_fill_inode
+ID: 576
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:erofs_nid_t nid; offset:16; size:8; signed:0;
+ field:erofs_blk_t blkaddr; offset:24; size:4; signed:0;
+ field:unsigned int ofs; offset:28; size:4; signed:0;
+ field:int isdir; offset:32; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), nid = %llu, blkaddr %u ofs %u, isdir %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->nid, REC->blkaddr, REC->ofs, REC->isdir
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_lookup/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_lookup/format
new file mode 100644
index 000000000..3253cd3d4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_lookup/format
@@ -0,0 +1,14 @@
+name: erofs_lookup
+ID: 577
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:erofs_nid_t nid; offset:16; size:8; signed:0;
+ field:const char * name; offset:24; size:8; signed:0;
+ field:unsigned int flags; offset:32; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), pnid = %llu, name:%s, flags:%x", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->nid, REC->name, REC->flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_map_blocks_flatmode_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_map_blocks_flatmode_enter/format
new file mode 100644
index 000000000..4e8b62eb8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_map_blocks_flatmode_enter/format
@@ -0,0 +1,15 @@
+name: erofs_map_blocks_flatmode_enter
+ID: 578
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:erofs_nid_t nid; offset:16; size:8; signed:0;
+ field:erofs_off_t la; offset:24; size:8; signed:0;
+ field:u64 llen; offset:32; size:8; signed:0;
+ field:unsigned int flags; offset:40; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), nid = %llu, la %llu llen %llu flags %s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->nid, REC->la, REC->llen, REC->flags ? __print_flags(REC->flags, "|", { 0x0001, "RAW" }) : "NULL"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_map_blocks_flatmode_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_map_blocks_flatmode_exit/format
new file mode 100644
index 000000000..1d5151ca7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_map_blocks_flatmode_exit/format
@@ -0,0 +1,19 @@
+name: erofs_map_blocks_flatmode_exit
+ID: 579
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:erofs_nid_t nid; offset:16; size:8; signed:0;
+ field:unsigned int flags; offset:24; size:4; signed:0;
+ field:erofs_off_t la; offset:32; size:8; signed:0;
+ field:erofs_off_t pa; offset:40; size:8; signed:0;
+ field:u64 llen; offset:48; size:8; signed:0;
+ field:u64 plen; offset:56; size:8; signed:0;
+ field:unsigned int mflags; offset:64; size:4; signed:0;
+ field:int ret; offset:68; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), nid = %llu, flags %s la %llu pa %llu llen %llu plen %llu mflags %s ret %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->nid, REC->flags ? __print_flags(REC->flags, "|", { 0x0001, "RAW" }) : "NULL", REC->la, REC->pa, REC->llen, REC->plen, __print_flags(REC->mflags, "", { (1 << BH_Mapped), "M" }, { (1 << BH_Meta), "I" }, { (1 << BH_Zipped), "Z" }), REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_readpage/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_readpage/format
new file mode 100644
index 000000000..ccf5f8a11
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_readpage/format
@@ -0,0 +1,16 @@
+name: erofs_readpage
+ID: 580
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:erofs_nid_t nid; offset:16; size:8; signed:0;
+ field:int dir; offset:24; size:4; signed:1;
+ field:unsigned long index; offset:32; size:8; signed:0;
+ field:int uptodate; offset:40; size:4; signed:1;
+ field:bool raw; offset:44; size:1; signed:0;
+
+print fmt: "dev = (%d,%d), nid = %llu, %s, index = %lu, uptodate = %d raw = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->nid, __print_symbolic(REC->dir, { 0, "FILE" }, { 1, "DIR" }), (unsigned long)REC->index, REC->uptodate, REC->raw
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_readpages/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_readpages/format
new file mode 100644
index 000000000..c4f463ead
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/erofs_readpages/format
@@ -0,0 +1,15 @@
+name: erofs_readpages
+ID: 581
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:erofs_nid_t nid; offset:16; size:8; signed:0;
+ field:unsigned long start; offset:24; size:8; signed:0;
+ field:unsigned int nrpage; offset:32; size:4; signed:0;
+ field:bool raw; offset:36; size:1; signed:0;
+
+print fmt: "dev = (%d,%d), nid = %llu, start = %lu nrpage = %u raw = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->nid, (unsigned long)REC->start, REC->nrpage, REC->raw
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/z_erofs_map_blocks_iter_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/z_erofs_map_blocks_iter_enter/format
new file mode 100644
index 000000000..e27fc0904
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/z_erofs_map_blocks_iter_enter/format
@@ -0,0 +1,15 @@
+name: z_erofs_map_blocks_iter_enter
+ID: 582
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:erofs_nid_t nid; offset:16; size:8; signed:0;
+ field:erofs_off_t la; offset:24; size:8; signed:0;
+ field:u64 llen; offset:32; size:8; signed:0;
+ field:unsigned int flags; offset:40; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), nid = %llu, la %llu llen %llu flags %s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->nid, REC->la, REC->llen, REC->flags ? __print_flags(REC->flags, "|", { 0x0001, "RAW" }) : "NULL"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/z_erofs_map_blocks_iter_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/z_erofs_map_blocks_iter_exit/format
new file mode 100644
index 000000000..f90d0c398
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/erofs/z_erofs_map_blocks_iter_exit/format
@@ -0,0 +1,19 @@
+name: z_erofs_map_blocks_iter_exit
+ID: 583
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:erofs_nid_t nid; offset:16; size:8; signed:0;
+ field:unsigned int flags; offset:24; size:4; signed:0;
+ field:erofs_off_t la; offset:32; size:8; signed:0;
+ field:erofs_off_t pa; offset:40; size:8; signed:0;
+ field:u64 llen; offset:48; size:8; signed:0;
+ field:u64 plen; offset:56; size:8; signed:0;
+ field:unsigned int mflags; offset:64; size:4; signed:0;
+ field:int ret; offset:68; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), nid = %llu, flags %s la %llu pa %llu llen %llu plen %llu mflags %s ret %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->nid, REC->flags ? __print_flags(REC->flags, "|", { 0x0001, "RAW" }) : "NULL", REC->la, REC->pa, REC->llen, REC->plen, __print_flags(REC->mflags, "", { (1 << BH_Mapped), "M" }, { (1 << BH_Meta), "I" }, { (1 << BH_Zipped), "Z" }), REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/error_report/error_report_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/error_report/error_report_end/format
new file mode 100644
index 000000000..408266a88
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/error_report/error_report_end/format
@@ -0,0 +1,12 @@
+name: error_report_end
+ID: 169
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum error_detector error_detector; offset:8; size:4; signed:0;
+ field:unsigned long id; offset:16; size:8; signed:0;
+
+print fmt: "[%s] %lx", __print_symbolic(REC->error_detector, { 0, "kfence" }, { 1, "kasan" }), REC->id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_alloc_da_blocks/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_alloc_da_blocks/format
new file mode 100644
index 000000000..799de346c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_alloc_da_blocks/format
@@ -0,0 +1,13 @@
+name: ext4_alloc_da_blocks
+ID: 369
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned int data_blocks; offset:24; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu reserved_data_blocks %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->data_blocks
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_allocate_blocks/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_allocate_blocks/format
new file mode 100644
index 000000000..9f483069c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_allocate_blocks/format
@@ -0,0 +1,21 @@
+name: ext4_allocate_blocks
+ID: 370
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:__u64 block; offset:24; size:8; signed:0;
+ field:unsigned int len; offset:32; size:4; signed:0;
+ field:__u32 logical; offset:36; size:4; signed:0;
+ field:__u32 lleft; offset:40; size:4; signed:0;
+ field:__u32 lright; offset:44; size:4; signed:0;
+ field:__u64 goal; offset:48; size:8; signed:0;
+ field:__u64 pleft; offset:56; size:8; signed:0;
+ field:__u64 pright; offset:64; size:8; signed:0;
+ field:unsigned int flags; offset:72; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu flags %s len %u block %llu lblk %u goal %llu lleft %u lright %u pleft %llu pright %llu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, __print_flags(REC->flags, "|", { 0x0001, "HINT_MERGE" }, { 0x0002, "HINT_RESV" }, { 0x0004, "HINT_MDATA" }, { 0x0008, "HINT_FIRST" }, { 0x0010, "HINT_BEST" }, { 0x0020, "HINT_DATA" }, { 0x0040, "HINT_NOPREALLOC" }, { 0x0080, "HINT_GRP_ALLOC" }, { 0x0100, "HINT_GOAL_ONLY" }, { 0x0200, "HINT_TRY_GOAL" }, { 0x0400, "DELALLOC_RESV" }, { 0x0800, "STREAM_ALLOC" }, { 0x1000, "USE_ROOT_BLKS" }, { 0x2000, "USE_RESV" }, { 0x4000, "STRICT_CHECK" }), REC->len, REC->block, REC->logical, REC->goal, REC->lleft, REC->lright, REC->pleft, REC->pright
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_allocate_inode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_allocate_inode/format
new file mode 100644
index 000000000..50347cad9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_allocate_inode/format
@@ -0,0 +1,14 @@
+name: ext4_allocate_inode
+ID: 371
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ino_t dir; offset:24; size:8; signed:0;
+ field:__u16 mode; offset:32; size:2; signed:0;
+
+print fmt: "dev %d,%d ino %lu dir %lu mode 0%o", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, (unsigned long) REC->dir, REC->mode
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_begin_ordered_truncate/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_begin_ordered_truncate/format
new file mode 100644
index 000000000..3527cbbd2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_begin_ordered_truncate/format
@@ -0,0 +1,13 @@
+name: ext4_begin_ordered_truncate
+ID: 372
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t new_size; offset:24; size:8; signed:1;
+
+print fmt: "dev %d,%d ino %lu new_size %lld", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->new_size
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_collapse_range/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_collapse_range/format
new file mode 100644
index 000000000..d0bb6e19e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_collapse_range/format
@@ -0,0 +1,14 @@
+name: ext4_collapse_range
+ID: 373
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t offset; offset:24; size:8; signed:1;
+ field:loff_t len; offset:32; size:8; signed:1;
+
+print fmt: "dev %d,%d ino %lu offset %lld len %lld", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->offset, REC->len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_release_space/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_release_space/format
new file mode 100644
index 000000000..97f2f4612
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_release_space/format
@@ -0,0 +1,16 @@
+name: ext4_da_release_space
+ID: 374
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:__u64 i_blocks; offset:24; size:8; signed:0;
+ field:int freed_blocks; offset:32; size:4; signed:1;
+ field:int reserved_data_blocks; offset:36; size:4; signed:1;
+ field:__u16 mode; offset:40; size:2; signed:0;
+
+print fmt: "dev %d,%d ino %lu mode 0%o i_blocks %llu freed_blocks %d reserved_data_blocks %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->mode, REC->i_blocks, REC->freed_blocks, REC->reserved_data_blocks
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_reserve_space/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_reserve_space/format
new file mode 100644
index 000000000..377f9cc44
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_reserve_space/format
@@ -0,0 +1,15 @@
+name: ext4_da_reserve_space
+ID: 375
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:__u64 i_blocks; offset:24; size:8; signed:0;
+ field:int reserved_data_blocks; offset:32; size:4; signed:1;
+ field:__u16 mode; offset:36; size:2; signed:0;
+
+print fmt: "dev %d,%d ino %lu mode 0%o i_blocks %llu reserved_data_blocks %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->mode, REC->i_blocks, REC->reserved_data_blocks
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_update_reserve_space/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_update_reserve_space/format
new file mode 100644
index 000000000..c08b41f08
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_update_reserve_space/format
@@ -0,0 +1,17 @@
+name: ext4_da_update_reserve_space
+ID: 376
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:__u64 i_blocks; offset:24; size:8; signed:0;
+ field:int used_blocks; offset:32; size:4; signed:1;
+ field:int reserved_data_blocks; offset:36; size:4; signed:1;
+ field:int quota_claim; offset:40; size:4; signed:1;
+ field:__u16 mode; offset:44; size:2; signed:0;
+
+print fmt: "dev %d,%d ino %lu mode 0%o i_blocks %llu used_blocks %d reserved_data_blocks %d quota_claim %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->mode, REC->i_blocks, REC->used_blocks, REC->reserved_data_blocks, REC->quota_claim
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_write_begin/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_write_begin/format
new file mode 100644
index 000000000..182a9d363
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_write_begin/format
@@ -0,0 +1,15 @@
+name: ext4_da_write_begin
+ID: 377
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t pos; offset:24; size:8; signed:1;
+ field:unsigned int len; offset:32; size:4; signed:0;
+ field:unsigned int flags; offset:36; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu pos %lld len %u flags %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->pos, REC->len, REC->flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_write_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_write_end/format
new file mode 100644
index 000000000..f620c8c7d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_write_end/format
@@ -0,0 +1,15 @@
+name: ext4_da_write_end
+ID: 378
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t pos; offset:24; size:8; signed:1;
+ field:unsigned int len; offset:32; size:4; signed:0;
+ field:unsigned int copied; offset:36; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu pos %lld len %u copied %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->pos, REC->len, REC->copied
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_write_pages/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_write_pages/format
new file mode 100644
index 000000000..8dbb8e0bb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_write_pages/format
@@ -0,0 +1,15 @@
+name: ext4_da_write_pages
+ID: 379
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long first_page; offset:24; size:8; signed:0;
+ field:long nr_to_write; offset:32; size:8; signed:1;
+ field:int sync_mode; offset:40; size:4; signed:1;
+
+print fmt: "dev %d,%d ino %lu first_page %lu nr_to_write %ld sync_mode %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->first_page, REC->nr_to_write, REC->sync_mode
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_write_pages_extent/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_write_pages_extent/format
new file mode 100644
index 000000000..e7112390f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_da_write_pages_extent/format
@@ -0,0 +1,15 @@
+name: ext4_da_write_pages_extent
+ID: 380
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:__u64 lblk; offset:24; size:8; signed:0;
+ field:__u32 len; offset:32; size:4; signed:0;
+ field:__u32 flags; offset:36; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu lblk %llu len %u flags %s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->lblk, REC->len, __print_flags(REC->flags, "", { ((((1UL))) << (5)), "N" }, { ((((1UL))) << (4)), "M" }, { ((((1UL))) << (11)), "U" }, { ((((1UL))) << (9)), "B" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_direct_IO_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_direct_IO_enter/format
new file mode 100644
index 000000000..05bfe16a7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_direct_IO_enter/format
@@ -0,0 +1,15 @@
+name: ext4_direct_IO_enter
+ID: 381
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t pos; offset:24; size:8; signed:1;
+ field:unsigned long len; offset:32; size:8; signed:0;
+ field:int rw; offset:40; size:4; signed:1;
+
+print fmt: "dev %d,%d ino %lu pos %lld len %lu rw %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->pos, REC->len, REC->rw
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_direct_IO_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_direct_IO_exit/format
new file mode 100644
index 000000000..68d332fd4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_direct_IO_exit/format
@@ -0,0 +1,16 @@
+name: ext4_direct_IO_exit
+ID: 382
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t pos; offset:24; size:8; signed:1;
+ field:unsigned long len; offset:32; size:8; signed:0;
+ field:int rw; offset:40; size:4; signed:1;
+ field:int ret; offset:44; size:4; signed:1;
+
+print fmt: "dev %d,%d ino %lu pos %lld len %lu rw %d ret %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->pos, REC->len, REC->rw, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_discard_blocks/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_discard_blocks/format
new file mode 100644
index 000000000..801fb789b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_discard_blocks/format
@@ -0,0 +1,13 @@
+name: ext4_discard_blocks
+ID: 383
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:__u64 blk; offset:16; size:8; signed:0;
+ field:__u64 count; offset:24; size:8; signed:0;
+
+print fmt: "dev %d,%d blk %llu count %llu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->blk, REC->count
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_discard_preallocations/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_discard_preallocations/format
new file mode 100644
index 000000000..3ba30217c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_discard_preallocations/format
@@ -0,0 +1,14 @@
+name: ext4_discard_preallocations
+ID: 384
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned int len; offset:24; size:4; signed:0;
+ field:unsigned int needed; offset:28; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu len: %u needed %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->len, REC->needed
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_drop_inode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_drop_inode/format
new file mode 100644
index 000000000..1bc360a7d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_drop_inode/format
@@ -0,0 +1,13 @@
+name: ext4_drop_inode
+ID: 385
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int drop; offset:24; size:4; signed:1;
+
+print fmt: "dev %d,%d ino %lu drop %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->drop
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_error/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_error/format
new file mode 100644
index 000000000..7d862e6c9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_error/format
@@ -0,0 +1,13 @@
+name: ext4_error
+ID: 386
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:const char * function; offset:16; size:8; signed:0;
+ field:unsigned line; offset:24; size:4; signed:0;
+
+print fmt: "dev %d,%d function %s line %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->function, REC->line
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_cache_extent/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_cache_extent/format
new file mode 100644
index 000000000..a530e8b89
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_cache_extent/format
@@ -0,0 +1,16 @@
+name: ext4_es_cache_extent
+ID: 387
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_lblk_t lblk; offset:24; size:4; signed:0;
+ field:ext4_lblk_t len; offset:28; size:4; signed:0;
+ field:ext4_fsblk_t pblk; offset:32; size:8; signed:0;
+ field:char status; offset:40; size:1; signed:0;
+
+print fmt: "dev %d,%d ino %lu es [%u/%u) mapped %llu status %s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->lblk, REC->len, REC->pblk, __print_flags(REC->status, "", { (1 << 0), "W" }, { (1 << 1), "U" }, { (1 << 2), "D" }, { (1 << 3), "H" }, { (1 << 4), "R" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_find_extent_range_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_find_extent_range_enter/format
new file mode 100644
index 000000000..4f786be6a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_find_extent_range_enter/format
@@ -0,0 +1,13 @@
+name: ext4_es_find_extent_range_enter
+ID: 388
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_lblk_t lblk; offset:24; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu lblk %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->lblk
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_find_extent_range_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_find_extent_range_exit/format
new file mode 100644
index 000000000..8709f7edb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_find_extent_range_exit/format
@@ -0,0 +1,16 @@
+name: ext4_es_find_extent_range_exit
+ID: 389
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_lblk_t lblk; offset:24; size:4; signed:0;
+ field:ext4_lblk_t len; offset:28; size:4; signed:0;
+ field:ext4_fsblk_t pblk; offset:32; size:8; signed:0;
+ field:char status; offset:40; size:1; signed:0;
+
+print fmt: "dev %d,%d ino %lu es [%u/%u) mapped %llu status %s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->lblk, REC->len, REC->pblk, __print_flags(REC->status, "", { (1 << 0), "W" }, { (1 << 1), "U" }, { (1 << 2), "D" }, { (1 << 3), "H" }, { (1 << 4), "R" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_insert_delayed_block/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_insert_delayed_block/format
new file mode 100644
index 000000000..0daa3966f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_insert_delayed_block/format
@@ -0,0 +1,17 @@
+name: ext4_es_insert_delayed_block
+ID: 390
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_lblk_t lblk; offset:24; size:4; signed:0;
+ field:ext4_lblk_t len; offset:28; size:4; signed:0;
+ field:ext4_fsblk_t pblk; offset:32; size:8; signed:0;
+ field:char status; offset:40; size:1; signed:0;
+ field:bool allocated; offset:41; size:1; signed:0;
+
+print fmt: "dev %d,%d ino %lu es [%u/%u) mapped %llu status %s allocated %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->lblk, REC->len, REC->pblk, __print_flags(REC->status, "", { (1 << 0), "W" }, { (1 << 1), "U" }, { (1 << 2), "D" }, { (1 << 3), "H" }, { (1 << 4), "R" }), REC->allocated
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_insert_extent/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_insert_extent/format
new file mode 100644
index 000000000..96cf7cbb8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_insert_extent/format
@@ -0,0 +1,16 @@
+name: ext4_es_insert_extent
+ID: 391
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_lblk_t lblk; offset:24; size:4; signed:0;
+ field:ext4_lblk_t len; offset:28; size:4; signed:0;
+ field:ext4_fsblk_t pblk; offset:32; size:8; signed:0;
+ field:char status; offset:40; size:1; signed:0;
+
+print fmt: "dev %d,%d ino %lu es [%u/%u) mapped %llu status %s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->lblk, REC->len, REC->pblk, __print_flags(REC->status, "", { (1 << 0), "W" }, { (1 << 1), "U" }, { (1 << 2), "D" }, { (1 << 3), "H" }, { (1 << 4), "R" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_lookup_extent_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_lookup_extent_enter/format
new file mode 100644
index 000000000..fc56633a9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_lookup_extent_enter/format
@@ -0,0 +1,13 @@
+name: ext4_es_lookup_extent_enter
+ID: 392
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_lblk_t lblk; offset:24; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu lblk %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->lblk
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_lookup_extent_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_lookup_extent_exit/format
new file mode 100644
index 000000000..1d7ddb112
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_lookup_extent_exit/format
@@ -0,0 +1,17 @@
+name: ext4_es_lookup_extent_exit
+ID: 393
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_lblk_t lblk; offset:24; size:4; signed:0;
+ field:ext4_lblk_t len; offset:28; size:4; signed:0;
+ field:ext4_fsblk_t pblk; offset:32; size:8; signed:0;
+ field:char status; offset:40; size:1; signed:0;
+ field:int found; offset:44; size:4; signed:1;
+
+print fmt: "dev %d,%d ino %lu found %d [%u/%u) %llu %s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->found, REC->lblk, REC->len, REC->found ? REC->pblk : 0, __print_flags(REC->found ? REC->status : 0, "", { (1 << 0), "W" }, { (1 << 1), "U" }, { (1 << 2), "D" }, { (1 << 3), "H" }, { (1 << 4), "R" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_remove_extent/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_remove_extent/format
new file mode 100644
index 000000000..2c862a56e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_remove_extent/format
@@ -0,0 +1,14 @@
+name: ext4_es_remove_extent
+ID: 394
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t lblk; offset:24; size:8; signed:1;
+ field:loff_t len; offset:32; size:8; signed:1;
+
+print fmt: "dev %d,%d ino %lu es [%lld/%lld)", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->lblk, REC->len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_shrink/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_shrink/format
new file mode 100644
index 000000000..c041ebaf5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_shrink/format
@@ -0,0 +1,15 @@
+name: ext4_es_shrink
+ID: 395
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int nr_shrunk; offset:12; size:4; signed:1;
+ field:unsigned long long scan_time; offset:16; size:8; signed:0;
+ field:int nr_skipped; offset:24; size:4; signed:1;
+ field:int retried; offset:28; size:4; signed:1;
+
+print fmt: "dev %d,%d nr_shrunk %d, scan_time %llu nr_skipped %d retried %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->nr_shrunk, REC->scan_time, REC->nr_skipped, REC->retried
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_shrink_count/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_shrink_count/format
new file mode 100644
index 000000000..560a29140
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_shrink_count/format
@@ -0,0 +1,13 @@
+name: ext4_es_shrink_count
+ID: 396
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int nr_to_scan; offset:12; size:4; signed:1;
+ field:int cache_cnt; offset:16; size:4; signed:1;
+
+print fmt: "dev %d,%d nr_to_scan %d cache_cnt %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->nr_to_scan, REC->cache_cnt
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_shrink_scan_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_shrink_scan_enter/format
new file mode 100644
index 000000000..4b6f2ca00
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_shrink_scan_enter/format
@@ -0,0 +1,13 @@
+name: ext4_es_shrink_scan_enter
+ID: 397
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int nr_to_scan; offset:12; size:4; signed:1;
+ field:int cache_cnt; offset:16; size:4; signed:1;
+
+print fmt: "dev %d,%d nr_to_scan %d cache_cnt %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->nr_to_scan, REC->cache_cnt
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_shrink_scan_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_shrink_scan_exit/format
new file mode 100644
index 000000000..274f22199
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_es_shrink_scan_exit/format
@@ -0,0 +1,13 @@
+name: ext4_es_shrink_scan_exit
+ID: 398
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int nr_shrunk; offset:12; size:4; signed:1;
+ field:int cache_cnt; offset:16; size:4; signed:1;
+
+print fmt: "dev %d,%d nr_shrunk %d cache_cnt %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->nr_shrunk, REC->cache_cnt
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_evict_inode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_evict_inode/format
new file mode 100644
index 000000000..9c5a4abf8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_evict_inode/format
@@ -0,0 +1,13 @@
+name: ext4_evict_inode
+ID: 399
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int nlink; offset:24; size:4; signed:1;
+
+print fmt: "dev %d,%d ino %lu nlink %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->nlink
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_convert_to_initialized_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_convert_to_initialized_enter/format
new file mode 100644
index 000000000..b3df51ca9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_convert_to_initialized_enter/format
@@ -0,0 +1,17 @@
+name: ext4_ext_convert_to_initialized_enter
+ID: 400
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_lblk_t m_lblk; offset:24; size:4; signed:0;
+ field:unsigned m_len; offset:28; size:4; signed:0;
+ field:ext4_lblk_t u_lblk; offset:32; size:4; signed:0;
+ field:unsigned u_len; offset:36; size:4; signed:0;
+ field:ext4_fsblk_t u_pblk; offset:40; size:8; signed:0;
+
+print fmt: "dev %d,%d ino %lu m_lblk %u m_len %u u_lblk %u u_len %u u_pblk %llu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->m_lblk, REC->m_len, REC->u_lblk, REC->u_len, REC->u_pblk
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_convert_to_initialized_fastpath/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_convert_to_initialized_fastpath/format
new file mode 100644
index 000000000..bebb12806
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_convert_to_initialized_fastpath/format
@@ -0,0 +1,20 @@
+name: ext4_ext_convert_to_initialized_fastpath
+ID: 401
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_lblk_t m_lblk; offset:24; size:4; signed:0;
+ field:unsigned m_len; offset:28; size:4; signed:0;
+ field:ext4_lblk_t u_lblk; offset:32; size:4; signed:0;
+ field:unsigned u_len; offset:36; size:4; signed:0;
+ field:ext4_fsblk_t u_pblk; offset:40; size:8; signed:0;
+ field:ext4_lblk_t i_lblk; offset:48; size:4; signed:0;
+ field:unsigned i_len; offset:52; size:4; signed:0;
+ field:ext4_fsblk_t i_pblk; offset:56; size:8; signed:0;
+
+print fmt: "dev %d,%d ino %lu m_lblk %u m_len %u u_lblk %u u_len %u u_pblk %llu i_lblk %u i_len %u i_pblk %llu ", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->m_lblk, REC->m_len, REC->u_lblk, REC->u_len, REC->u_pblk, REC->i_lblk, REC->i_len, REC->i_pblk
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_handle_unwritten_extents/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_handle_unwritten_extents/format
new file mode 100644
index 000000000..2b84695f8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_handle_unwritten_extents/format
@@ -0,0 +1,18 @@
+name: ext4_ext_handle_unwritten_extents
+ID: 402
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int flags; offset:24; size:4; signed:1;
+ field:ext4_lblk_t lblk; offset:28; size:4; signed:0;
+ field:ext4_fsblk_t pblk; offset:32; size:8; signed:0;
+ field:unsigned int len; offset:40; size:4; signed:0;
+ field:unsigned int allocated; offset:44; size:4; signed:0;
+ field:ext4_fsblk_t newblk; offset:48; size:8; signed:0;
+
+print fmt: "dev %d,%d ino %lu m_lblk %u m_pblk %llu m_len %u flags %s allocated %d newblock %llu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, (unsigned) REC->lblk, (unsigned long long) REC->pblk, REC->len, __print_flags(REC->flags, "|", { 0x0001, "CREATE" }, { 0x0002, "UNWRIT" }, { 0x0004, "DELALLOC" }, { 0x0008, "PRE_IO" }, { 0x0010, "CONVERT" }, { 0x0020, "METADATA_NOFAIL" }, { 0x0040, "NO_NORMALIZE" }, { 0x0100, "CONVERT_UNWRITTEN" }, { 0x0200, "ZERO" }, { 0x0400, "IO_SUBMIT" }, { 0x40000000, "EX_NOCACHE" }), (unsigned int) REC->allocated, (unsigned long long) REC->newblk
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_in_cache/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_in_cache/format
new file mode 100644
index 000000000..57e089430
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_in_cache/format
@@ -0,0 +1,14 @@
+name: ext4_ext_in_cache
+ID: 403
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_lblk_t lblk; offset:24; size:4; signed:0;
+ field:int ret; offset:28; size:4; signed:1;
+
+print fmt: "dev %d,%d ino %lu lblk %u ret %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, (unsigned) REC->lblk, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_load_extent/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_load_extent/format
new file mode 100644
index 000000000..b1ebb3f8a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_load_extent/format
@@ -0,0 +1,14 @@
+name: ext4_ext_load_extent
+ID: 404
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_fsblk_t pblk; offset:24; size:8; signed:0;
+ field:ext4_lblk_t lblk; offset:32; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu lblk %u pblk %llu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->lblk, REC->pblk
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_map_blocks_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_map_blocks_enter/format
new file mode 100644
index 000000000..964457adc
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_map_blocks_enter/format
@@ -0,0 +1,15 @@
+name: ext4_ext_map_blocks_enter
+ID: 405
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_lblk_t lblk; offset:24; size:4; signed:0;
+ field:unsigned int len; offset:28; size:4; signed:0;
+ field:unsigned int flags; offset:32; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu lblk %u len %u flags %s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->lblk, REC->len, __print_flags(REC->flags, "|", { 0x0001, "CREATE" }, { 0x0002, "UNWRIT" }, { 0x0004, "DELALLOC" }, { 0x0008, "PRE_IO" }, { 0x0010, "CONVERT" }, { 0x0020, "METADATA_NOFAIL" }, { 0x0040, "NO_NORMALIZE" }, { 0x0100, "CONVERT_UNWRITTEN" }, { 0x0200, "ZERO" }, { 0x0400, "IO_SUBMIT" }, { 0x40000000, "EX_NOCACHE" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_map_blocks_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_map_blocks_exit/format
new file mode 100644
index 000000000..094269aba
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_map_blocks_exit/format
@@ -0,0 +1,18 @@
+name: ext4_ext_map_blocks_exit
+ID: 406
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned int flags; offset:24; size:4; signed:0;
+ field:ext4_fsblk_t pblk; offset:32; size:8; signed:0;
+ field:ext4_lblk_t lblk; offset:40; size:4; signed:0;
+ field:unsigned int len; offset:44; size:4; signed:0;
+ field:unsigned int mflags; offset:48; size:4; signed:0;
+ field:int ret; offset:52; size:4; signed:1;
+
+print fmt: "dev %d,%d ino %lu flags %s lblk %u pblk %llu len %u mflags %s ret %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, __print_flags(REC->flags, "|", { 0x0001, "CREATE" }, { 0x0002, "UNWRIT" }, { 0x0004, "DELALLOC" }, { 0x0008, "PRE_IO" }, { 0x0010, "CONVERT" }, { 0x0020, "METADATA_NOFAIL" }, { 0x0040, "NO_NORMALIZE" }, { 0x0100, "CONVERT_UNWRITTEN" }, { 0x0200, "ZERO" }, { 0x0400, "IO_SUBMIT" }, { 0x40000000, "EX_NOCACHE" }), REC->lblk, REC->pblk, REC->len, __print_flags(REC->mflags, "", { ((((1UL))) << (5)), "N" }, { ((((1UL))) << (4)), "M" }, { ((((1UL))) << (11)), "U" }, { ((((1UL))) << (9)), "B" }), REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_put_in_cache/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_put_in_cache/format
new file mode 100644
index 000000000..ee1bdb639
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_put_in_cache/format
@@ -0,0 +1,15 @@
+name: ext4_ext_put_in_cache
+ID: 407
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_lblk_t lblk; offset:24; size:4; signed:0;
+ field:unsigned int len; offset:28; size:4; signed:0;
+ field:ext4_fsblk_t start; offset:32; size:8; signed:0;
+
+print fmt: "dev %d,%d ino %lu lblk %u len %u start %llu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, (unsigned) REC->lblk, REC->len, (unsigned long long) REC->start
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_remove_space/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_remove_space/format
new file mode 100644
index 000000000..c293b55b7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_remove_space/format
@@ -0,0 +1,15 @@
+name: ext4_ext_remove_space
+ID: 408
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_lblk_t start; offset:24; size:4; signed:0;
+ field:ext4_lblk_t end; offset:28; size:4; signed:0;
+ field:int depth; offset:32; size:4; signed:1;
+
+print fmt: "dev %d,%d ino %lu since %u end %u depth %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, (unsigned) REC->start, (unsigned) REC->end, REC->depth
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_remove_space_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_remove_space_done/format
new file mode 100644
index 000000000..b394315c0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_remove_space_done/format
@@ -0,0 +1,19 @@
+name: ext4_ext_remove_space_done
+ID: 409
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_lblk_t start; offset:24; size:4; signed:0;
+ field:ext4_lblk_t end; offset:28; size:4; signed:0;
+ field:int depth; offset:32; size:4; signed:1;
+ field:ext4_fsblk_t pc_pclu; offset:40; size:8; signed:0;
+ field:ext4_lblk_t pc_lblk; offset:48; size:4; signed:0;
+ field:int pc_state; offset:52; size:4; signed:1;
+ field:unsigned short eh_entries; offset:56; size:2; signed:0;
+
+print fmt: "dev %d,%d ino %lu since %u end %u depth %d partial [pclu %lld lblk %u state %d] remaining_entries %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, (unsigned) REC->start, (unsigned) REC->end, REC->depth, (long long) REC->pc_pclu, (unsigned int) REC->pc_lblk, (int) REC->pc_state, (unsigned short) REC->eh_entries
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_rm_idx/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_rm_idx/format
new file mode 100644
index 000000000..57ba4e3b5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_rm_idx/format
@@ -0,0 +1,13 @@
+name: ext4_ext_rm_idx
+ID: 410
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_fsblk_t pblk; offset:24; size:8; signed:0;
+
+print fmt: "dev %d,%d ino %lu index_pblk %llu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, (unsigned long long) REC->pblk
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_rm_leaf/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_rm_leaf/format
new file mode 100644
index 000000000..4651b44ab
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_rm_leaf/format
@@ -0,0 +1,19 @@
+name: ext4_ext_rm_leaf
+ID: 411
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_lblk_t start; offset:24; size:4; signed:0;
+ field:ext4_lblk_t ee_lblk; offset:28; size:4; signed:0;
+ field:ext4_fsblk_t ee_pblk; offset:32; size:8; signed:0;
+ field:short ee_len; offset:40; size:2; signed:1;
+ field:ext4_fsblk_t pc_pclu; offset:48; size:8; signed:0;
+ field:ext4_lblk_t pc_lblk; offset:56; size:4; signed:0;
+ field:int pc_state; offset:60; size:4; signed:1;
+
+print fmt: "dev %d,%d ino %lu start_lblk %u last_extent [%u(%llu), %u]partial [pclu %lld lblk %u state %d]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, (unsigned) REC->start, (unsigned) REC->ee_lblk, (unsigned long long) REC->ee_pblk, (unsigned short) REC->ee_len, (long long) REC->pc_pclu, (unsigned int) REC->pc_lblk, (int) REC->pc_state
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_show_extent/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_show_extent/format
new file mode 100644
index 000000000..0e9d73ca7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ext_show_extent/format
@@ -0,0 +1,15 @@
+name: ext4_ext_show_extent
+ID: 412
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_fsblk_t pblk; offset:24; size:8; signed:0;
+ field:ext4_lblk_t lblk; offset:32; size:4; signed:0;
+ field:unsigned short len; offset:36; size:2; signed:0;
+
+print fmt: "dev %d,%d ino %lu lblk %u pblk %llu len %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, (unsigned) REC->lblk, (unsigned long long) REC->pblk, (unsigned short) REC->len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fallocate_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fallocate_enter/format
new file mode 100644
index 000000000..db942a9ad
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fallocate_enter/format
@@ -0,0 +1,15 @@
+name: ext4_fallocate_enter
+ID: 413
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t offset; offset:24; size:8; signed:1;
+ field:loff_t len; offset:32; size:8; signed:1;
+ field:int mode; offset:40; size:4; signed:1;
+
+print fmt: "dev %d,%d ino %lu offset %lld len %lld mode %s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->offset, REC->len, __print_flags(REC->mode, "|", { 0x01, "KEEP_SIZE"}, { 0x02, "PUNCH_HOLE"}, { 0x04, "NO_HIDE_STALE"}, { 0x08, "COLLAPSE_RANGE"}, { 0x10, "ZERO_RANGE"})
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fallocate_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fallocate_exit/format
new file mode 100644
index 000000000..62f0df768
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fallocate_exit/format
@@ -0,0 +1,15 @@
+name: ext4_fallocate_exit
+ID: 414
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t pos; offset:24; size:8; signed:1;
+ field:unsigned int blocks; offset:32; size:4; signed:0;
+ field:int ret; offset:36; size:4; signed:1;
+
+print fmt: "dev %d,%d ino %lu pos %lld blocks %u ret %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->pos, REC->blocks, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_commit_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_commit_start/format
new file mode 100644
index 000000000..0b110828e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_commit_start/format
@@ -0,0 +1,11 @@
+name: ext4_fc_commit_start
+ID: 415
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+
+print fmt: "fast_commit started on dev %d,%d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1)))
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_commit_stop/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_commit_stop/format
new file mode 100644
index 000000000..09f4585a3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_commit_stop/format
@@ -0,0 +1,16 @@
+name: ext4_fc_commit_stop
+ID: 416
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int nblks; offset:12; size:4; signed:1;
+ field:int reason; offset:16; size:4; signed:1;
+ field:int num_fc; offset:20; size:4; signed:1;
+ field:int num_fc_ineligible; offset:24; size:4; signed:1;
+ field:int nblks_agg; offset:28; size:4; signed:1;
+
+print fmt: "fc on [%d,%d] nblks %d, reason %d, fc = %d, ineligible = %d, agg_nblks %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->nblks, REC->reason, REC->num_fc, REC->num_fc_ineligible, REC->nblks_agg
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_replay/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_replay/format
new file mode 100644
index 000000000..8159a82af
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_replay/format
@@ -0,0 +1,15 @@
+name: ext4_fc_replay
+ID: 417
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int tag; offset:12; size:4; signed:1;
+ field:int ino; offset:16; size:4; signed:1;
+ field:int priv1; offset:20; size:4; signed:1;
+ field:int priv2; offset:24; size:4; signed:1;
+
+print fmt: "FC Replay %d,%d: tag %d, ino %d, data1 %d, data2 %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->tag, REC->ino, REC->priv1, REC->priv2
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_replay_scan/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_replay_scan/format
new file mode 100644
index 000000000..128df1946
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_replay_scan/format
@@ -0,0 +1,13 @@
+name: ext4_fc_replay_scan
+ID: 418
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int error; offset:12; size:4; signed:1;
+ field:int off; offset:16; size:4; signed:1;
+
+print fmt: "FC scan pass on dev %d,%d: error %d, off %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->error, REC->off
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_stats/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_stats/format
new file mode 100644
index 000000000..259db6a3a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_stats/format
@@ -0,0 +1,14 @@
+name: ext4_fc_stats
+ID: 419
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:struct ext4_sb_info * sbi; offset:16; size:8; signed:0;
+ field:int count; offset:24; size:4; signed:1;
+
+print fmt: "dev %d:%d fc ineligible reasons:
+%s:%d, %s:%d, %s:%d, %s:%d, %s:%d, %s:%d, %s:%d, %s:%d, %s:%d; num_commits:%ld, ineligible: %ld, numblks: %ld", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), __print_symbolic(EXT4_FC_REASON_XATTR, { EXT4_FC_REASON_XATTR, "XATTR"}, { EXT4_FC_REASON_CROSS_RENAME, "CROSS_RENAME"}, { EXT4_FC_REASON_JOURNAL_FLAG_CHANGE, "JOURNAL_FLAG_CHANGE"}, { EXT4_FC_REASON_NOMEM, "NO_MEM"}, { EXT4_FC_REASON_SWAP_BOOT, "SWAP_BOOT"}, { EXT4_FC_REASON_RESIZE, "RESIZE"}, { EXT4_FC_REASON_RENAME_DIR, "RENAME_DIR"}, { EXT4_FC_REASON_FALLOC_RANGE, "FALLOC_RANGE"}, { EXT4_FC_REASON_INODE_JOURNAL_DATA, "INODE_JOURNAL_DATA"}), REC->sbi->s_fc_stats.fc_ineligible_reason_count[EXT4_FC_REASON_XATTR], __print_symbolic(EXT4_FC_REASON_CROSS_RENAME, { EXT4_FC_REASON_XATTR, "XATTR"}, { EXT4_FC_REASON_CROSS_RENAME, "CROSS_RENAME"}, { EXT4_FC_REASON_JOURNAL_FLAG_CHANGE, "JOURNAL_FLAG_CHANGE"}, { EXT4_FC_REASON_NOMEM, "NO_MEM"}, { EXT4_FC_REASON_SWAP_BOOT, "SWAP_BOOT"}, { EXT4_FC_REASON_RESIZE, "RESIZE"}, { EXT4_FC_REASON_RENAME_DIR, "RENAME_DIR"}, { EXT4_FC_REASON_FALLOC_RANGE, "FALLOC_RANGE"}, { EXT4_FC_REASON_INODE_JOURNAL_DATA, "INODE_JOURNAL_DATA"}), REC->sbi->s_fc_stats.fc_ineligible_reason_count[EXT4_FC_REASON_CROSS_RENAME], __print_symbolic(EXT4_FC_REASON_JOURNAL_FLAG_CHANGE, { EXT4_FC_REASON_XATTR, "XATTR"}, { EXT4_FC_REASON_CROSS_RENAME, "CROSS_RENAME"}, { EXT4_FC_REASON_JOURNAL_FLAG_CHANGE, "JOURNAL_FLAG_CHANGE"}, { EXT4_FC_REASON_NOMEM, "NO_MEM"}, { EXT4_FC_REASON_SWAP_BOOT, "SWAP_BOOT"}, { EXT4_FC_REASON_RESIZE, "RESIZE"}, { EXT4_FC_REASON_RENAME_DIR, "RENAME_DIR"}, { EXT4_FC_REASON_FALLOC_RANGE, "FALLOC_RANGE"}, { EXT4_FC_REASON_INODE_JOURNAL_DATA, "INODE_JOURNAL_DATA"}), REC->sbi->s_fc_stats.fc_ineligible_reason_count[EXT4_FC_REASON_JOURNAL_FLAG_CHANGE], __print_symbolic(EXT4_FC_REASON_NOMEM, { EXT4_FC_REASON_XATTR, "XATTR"}, { EXT4_FC_REASON_CROSS_RENAME, "CROSS_RENAME"}, { EXT4_FC_REASON_JOURNAL_FLAG_CHANGE, "JOURNAL_FLAG_CHANGE"}, { EXT4_FC_REASON_NOMEM, "NO_MEM"}, { EXT4_FC_REASON_SWAP_BOOT, "SWAP_BOOT"}, { EXT4_FC_REASON_RESIZE, "RESIZE"}, { EXT4_FC_REASON_RENAME_DIR, "RENAME_DIR"}, { EXT4_FC_REASON_FALLOC_RANGE, "FALLOC_RANGE"}, { EXT4_FC_REASON_INODE_JOURNAL_DATA, "INODE_JOURNAL_DATA"}), REC->sbi->s_fc_stats.fc_ineligible_reason_count[EXT4_FC_REASON_NOMEM], __print_symbolic(EXT4_FC_REASON_SWAP_BOOT, { EXT4_FC_REASON_XATTR, "XATTR"}, { EXT4_FC_REASON_CROSS_RENAME, "CROSS_RENAME"}, { EXT4_FC_REASON_JOURNAL_FLAG_CHANGE, "JOURNAL_FLAG_CHANGE"}, { EXT4_FC_REASON_NOMEM, "NO_MEM"}, { EXT4_FC_REASON_SWAP_BOOT, "SWAP_BOOT"}, { EXT4_FC_REASON_RESIZE, "RESIZE"}, { EXT4_FC_REASON_RENAME_DIR, "RENAME_DIR"}, { EXT4_FC_REASON_FALLOC_RANGE, "FALLOC_RANGE"}, { EXT4_FC_REASON_INODE_JOURNAL_DATA, "INODE_JOURNAL_DATA"}), REC->sbi->s_fc_stats.fc_ineligible_reason_count[EXT4_FC_REASON_SWAP_BOOT], __print_symbolic(EXT4_FC_REASON_RESIZE, { EXT4_FC_REASON_XATTR, "XATTR"}, { EXT4_FC_REASON_CROSS_RENAME, "CROSS_RENAME"}, { EXT4_FC_REASON_JOURNAL_FLAG_CHANGE, "JOURNAL_FLAG_CHANGE"}, { EXT4_FC_REASON_NOMEM, "NO_MEM"}, { EXT4_FC_REASON_SWAP_BOOT, "SWAP_BOOT"}, { EXT4_FC_REASON_RESIZE, "RESIZE"}, { EXT4_FC_REASON_RENAME_DIR, "RENAME_DIR"}, { EXT4_FC_REASON_FALLOC_RANGE, "FALLOC_RANGE"}, { EXT4_FC_REASON_INODE_JOURNAL_DATA, "INODE_JOURNAL_DATA"}), REC->sbi->s_fc_stats.fc_ineligible_reason_count[EXT4_FC_REASON_RESIZE], __print_symbolic(EXT4_FC_REASON_RENAME_DIR, { EXT4_FC_REASON_XATTR, "XATTR"}, { EXT4_FC_REASON_CROSS_RENAME, "CROSS_RENAME"}, { EXT4_FC_REASON_JOURNAL_FLAG_CHANGE, "JOURNAL_FLAG_CHANGE"}, { EXT4_FC_REASON_NOMEM, "NO_MEM"}, { EXT4_FC_REASON_SWAP_BOOT, "SWAP_BOOT"}, { EXT4_FC_REASON_RESIZE, "RESIZE"}, { EXT4_FC_REASON_RENAME_DIR, "RENAME_DIR"}, { EXT4_FC_REASON_FALLOC_RANGE, "FALLOC_RANGE"}, { EXT4_FC_REASON_INODE_JOURNAL_DATA, "INODE_JOURNAL_DATA"}), REC->sbi->s_fc_stats.fc_ineligible_reason_count[EXT4_FC_REASON_RENAME_DIR], __print_symbolic(EXT4_FC_REASON_FALLOC_RANGE, { EXT4_FC_REASON_XATTR, "XATTR"}, { EXT4_FC_REASON_CROSS_RENAME, "CROSS_RENAME"}, { EXT4_FC_REASON_JOURNAL_FLAG_CHANGE, "JOURNAL_FLAG_CHANGE"}, { EXT4_FC_REASON_NOMEM, "NO_MEM"}, { EXT4_FC_REASON_SWAP_BOOT, "SWAP_BOOT"}, { EXT4_FC_REASON_RESIZE, "RESIZE"}, { EXT4_FC_REASON_RENAME_DIR, "RENAME_DIR"}, { EXT4_FC_REASON_FALLOC_RANGE, "FALLOC_RANGE"}, { EXT4_FC_REASON_INODE_JOURNAL_DATA, "INODE_JOURNAL_DATA"}), REC->sbi->s_fc_stats.fc_ineligible_reason_count[EXT4_FC_REASON_FALLOC_RANGE], __print_symbolic(EXT4_FC_REASON_INODE_JOURNAL_DATA, { EXT4_FC_REASON_XATTR, "XATTR"}, { EXT4_FC_REASON_CROSS_RENAME, "CROSS_RENAME"}, { EXT4_FC_REASON_JOURNAL_FLAG_CHANGE, "JOURNAL_FLAG_CHANGE"}, { EXT4_FC_REASON_NOMEM, "NO_MEM"}, { EXT4_FC_REASON_SWAP_BOOT, "SWAP_BOOT"}, { EXT4_FC_REASON_RESIZE, "RESIZE"}, { EXT4_FC_REASON_RENAME_DIR, "RENAME_DIR"}, { EXT4_FC_REASON_FALLOC_RANGE, "FALLOC_RANGE"}, { EXT4_FC_REASON_INODE_JOURNAL_DATA, "INODE_JOURNAL_DATA"}), REC->sbi->s_fc_stats.fc_ineligible_reason_count[EXT4_FC_REASON_INODE_JOURNAL_DATA], REC->sbi->s_fc_stats.fc_num_commits, REC->sbi->s_fc_stats.fc_ineligible_commits, REC->sbi->s_fc_stats.fc_numblks
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_track_create/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_track_create/format
new file mode 100644
index 000000000..9a229b0ef
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_track_create/format
@@ -0,0 +1,13 @@
+name: ext4_fc_track_create
+ID: 420
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int ino; offset:12; size:4; signed:1;
+ field:int error; offset:16; size:4; signed:1;
+
+print fmt: "dev %d:%d, inode %d, error %d, fc_%s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->ino, REC->error, "create"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_track_inode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_track_inode/format
new file mode 100644
index 000000000..fe5e07277
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_track_inode/format
@@ -0,0 +1,13 @@
+name: ext4_fc_track_inode
+ID: 421
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int ino; offset:12; size:4; signed:1;
+ field:int error; offset:16; size:4; signed:1;
+
+print fmt: "dev %d:%d, inode %d, error %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->ino, REC->error
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_track_link/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_track_link/format
new file mode 100644
index 000000000..4736a8ae3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_track_link/format
@@ -0,0 +1,13 @@
+name: ext4_fc_track_link
+ID: 422
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int ino; offset:12; size:4; signed:1;
+ field:int error; offset:16; size:4; signed:1;
+
+print fmt: "dev %d:%d, inode %d, error %d, fc_%s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->ino, REC->error, "link"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_track_range/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_track_range/format
new file mode 100644
index 000000000..7ef747699
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_track_range/format
@@ -0,0 +1,15 @@
+name: ext4_fc_track_range
+ID: 423
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int ino; offset:12; size:4; signed:1;
+ field:long start; offset:16; size:8; signed:1;
+ field:long end; offset:24; size:8; signed:1;
+ field:int error; offset:32; size:4; signed:1;
+
+print fmt: "dev %d:%d, inode %d, error %d, start %ld, end %ld", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->ino, REC->error, REC->start, REC->end
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_track_unlink/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_track_unlink/format
new file mode 100644
index 000000000..55c5cf9c4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fc_track_unlink/format
@@ -0,0 +1,13 @@
+name: ext4_fc_track_unlink
+ID: 424
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int ino; offset:12; size:4; signed:1;
+ field:int error; offset:16; size:4; signed:1;
+
+print fmt: "dev %d:%d, inode %d, error %d, fc_%s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->ino, REC->error, "unlink"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_find_delalloc_range/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_find_delalloc_range/format
new file mode 100644
index 000000000..82a2c64ef
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_find_delalloc_range/format
@@ -0,0 +1,17 @@
+name: ext4_find_delalloc_range
+ID: 425
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_lblk_t from; offset:24; size:4; signed:0;
+ field:ext4_lblk_t to; offset:28; size:4; signed:0;
+ field:int reverse; offset:32; size:4; signed:1;
+ field:int found; offset:36; size:4; signed:1;
+ field:ext4_lblk_t found_blk; offset:40; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu from %u to %u reverse %d found %d (blk = %u)", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, (unsigned) REC->from, (unsigned) REC->to, REC->reverse, REC->found, (unsigned) REC->found_blk
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_forget/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_forget/format
new file mode 100644
index 000000000..ddb11f22c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_forget/format
@@ -0,0 +1,15 @@
+name: ext4_forget
+ID: 426
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:__u64 block; offset:24; size:8; signed:0;
+ field:int is_metadata; offset:32; size:4; signed:1;
+ field:__u16 mode; offset:36; size:2; signed:0;
+
+print fmt: "dev %d,%d ino %lu mode 0%o is_metadata %d block %llu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->mode, REC->is_metadata, REC->block
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_free_blocks/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_free_blocks/format
new file mode 100644
index 000000000..8656ac303
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_free_blocks/format
@@ -0,0 +1,16 @@
+name: ext4_free_blocks
+ID: 427
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:__u64 block; offset:24; size:8; signed:0;
+ field:unsigned long count; offset:32; size:8; signed:0;
+ field:int flags; offset:40; size:4; signed:1;
+ field:__u16 mode; offset:44; size:2; signed:0;
+
+print fmt: "dev %d,%d ino %lu mode 0%o block %llu count %lu flags %s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->mode, REC->block, REC->count, __print_flags(REC->flags, "|", { 0x0001, "METADATA" }, { 0x0002, "FORGET" }, { 0x0004, "VALIDATED" }, { 0x0008, "NO_QUOTA" }, { 0x0010,"1ST_CLUSTER" }, { 0x0020, "LAST_CLUSTER" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_free_inode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_free_inode/format
new file mode 100644
index 000000000..19b3961f9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_free_inode/format
@@ -0,0 +1,16 @@
+name: ext4_free_inode
+ID: 428
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:uid_t uid; offset:24; size:4; signed:0;
+ field:gid_t gid; offset:28; size:4; signed:0;
+ field:__u64 blocks; offset:32; size:8; signed:0;
+ field:__u16 mode; offset:40; size:2; signed:0;
+
+print fmt: "dev %d,%d ino %lu mode 0%o uid %u gid %u blocks %llu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->mode, REC->uid, REC->gid, REC->blocks
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fsmap_high_key/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fsmap_high_key/format
new file mode 100644
index 000000000..a2d101ead
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fsmap_high_key/format
@@ -0,0 +1,17 @@
+name: ext4_fsmap_high_key
+ID: 429
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:dev_t keydev; offset:12; size:4; signed:0;
+ field:u32 agno; offset:16; size:4; signed:0;
+ field:u64 bno; offset:24; size:8; signed:0;
+ field:u64 len; offset:32; size:8; signed:0;
+ field:u64 owner; offset:40; size:8; signed:0;
+
+print fmt: "dev %d:%d keydev %d:%d agno %u bno %llu len %llu owner %lld
+", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), ((unsigned int) ((REC->keydev) >> 20)), ((unsigned int) ((REC->keydev) & ((1U << 20) - 1))), REC->agno, REC->bno, REC->len, REC->owner
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fsmap_low_key/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fsmap_low_key/format
new file mode 100644
index 000000000..1e1714272
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fsmap_low_key/format
@@ -0,0 +1,17 @@
+name: ext4_fsmap_low_key
+ID: 430
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:dev_t keydev; offset:12; size:4; signed:0;
+ field:u32 agno; offset:16; size:4; signed:0;
+ field:u64 bno; offset:24; size:8; signed:0;
+ field:u64 len; offset:32; size:8; signed:0;
+ field:u64 owner; offset:40; size:8; signed:0;
+
+print fmt: "dev %d:%d keydev %d:%d agno %u bno %llu len %llu owner %lld
+", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), ((unsigned int) ((REC->keydev) >> 20)), ((unsigned int) ((REC->keydev) & ((1U << 20) - 1))), REC->agno, REC->bno, REC->len, REC->owner
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fsmap_mapping/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fsmap_mapping/format
new file mode 100644
index 000000000..d3f7c841c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_fsmap_mapping/format
@@ -0,0 +1,17 @@
+name: ext4_fsmap_mapping
+ID: 431
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:dev_t keydev; offset:12; size:4; signed:0;
+ field:u32 agno; offset:16; size:4; signed:0;
+ field:u64 bno; offset:24; size:8; signed:0;
+ field:u64 len; offset:32; size:8; signed:0;
+ field:u64 owner; offset:40; size:8; signed:0;
+
+print fmt: "dev %d:%d keydev %d:%d agno %u bno %llu len %llu owner %lld
+", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), ((unsigned int) ((REC->keydev) >> 20)), ((unsigned int) ((REC->keydev) & ((1U << 20) - 1))), REC->agno, REC->bno, REC->len, REC->owner
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_get_implied_cluster_alloc_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_get_implied_cluster_alloc_exit/format
new file mode 100644
index 000000000..3201ebf09
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_get_implied_cluster_alloc_exit/format
@@ -0,0 +1,16 @@
+name: ext4_get_implied_cluster_alloc_exit
+ID: 432
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:unsigned int flags; offset:12; size:4; signed:0;
+ field:ext4_lblk_t lblk; offset:16; size:4; signed:0;
+ field:ext4_fsblk_t pblk; offset:24; size:8; signed:0;
+ field:unsigned int len; offset:32; size:4; signed:0;
+ field:int ret; offset:36; size:4; signed:1;
+
+print fmt: "dev %d,%d m_lblk %u m_pblk %llu m_len %u m_flags %s ret %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->lblk, (unsigned long long) REC->pblk, REC->len, __print_flags(REC->flags, "", { ((((1UL))) << (5)), "N" }, { ((((1UL))) << (4)), "M" }, { ((((1UL))) << (11)), "U" }, { ((((1UL))) << (9)), "B" }), REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_get_reserved_cluster_alloc/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_get_reserved_cluster_alloc/format
new file mode 100644
index 000000000..1ddbcae62
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_get_reserved_cluster_alloc/format
@@ -0,0 +1,14 @@
+name: ext4_get_reserved_cluster_alloc
+ID: 433
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_lblk_t lblk; offset:24; size:4; signed:0;
+ field:unsigned int len; offset:28; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu lblk %u len %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, (unsigned) REC->lblk, REC->len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_getfsmap_high_key/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_getfsmap_high_key/format
new file mode 100644
index 000000000..b3e89c203
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_getfsmap_high_key/format
@@ -0,0 +1,17 @@
+name: ext4_getfsmap_high_key
+ID: 434
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:dev_t keydev; offset:12; size:4; signed:0;
+ field:u64 block; offset:16; size:8; signed:0;
+ field:u64 len; offset:24; size:8; signed:0;
+ field:u64 owner; offset:32; size:8; signed:0;
+ field:u64 flags; offset:40; size:8; signed:0;
+
+print fmt: "dev %d:%d keydev %d:%d block %llu len %llu owner %lld flags 0x%llx
+", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), ((unsigned int) ((REC->keydev) >> 20)), ((unsigned int) ((REC->keydev) & ((1U << 20) - 1))), REC->block, REC->len, REC->owner, REC->flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_getfsmap_low_key/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_getfsmap_low_key/format
new file mode 100644
index 000000000..d3af1fe99
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_getfsmap_low_key/format
@@ -0,0 +1,17 @@
+name: ext4_getfsmap_low_key
+ID: 435
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:dev_t keydev; offset:12; size:4; signed:0;
+ field:u64 block; offset:16; size:8; signed:0;
+ field:u64 len; offset:24; size:8; signed:0;
+ field:u64 owner; offset:32; size:8; signed:0;
+ field:u64 flags; offset:40; size:8; signed:0;
+
+print fmt: "dev %d:%d keydev %d:%d block %llu len %llu owner %lld flags 0x%llx
+", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), ((unsigned int) ((REC->keydev) >> 20)), ((unsigned int) ((REC->keydev) & ((1U << 20) - 1))), REC->block, REC->len, REC->owner, REC->flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_getfsmap_mapping/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_getfsmap_mapping/format
new file mode 100644
index 000000000..cf9d2464e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_getfsmap_mapping/format
@@ -0,0 +1,17 @@
+name: ext4_getfsmap_mapping
+ID: 436
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:dev_t keydev; offset:12; size:4; signed:0;
+ field:u64 block; offset:16; size:8; signed:0;
+ field:u64 len; offset:24; size:8; signed:0;
+ field:u64 owner; offset:32; size:8; signed:0;
+ field:u64 flags; offset:40; size:8; signed:0;
+
+print fmt: "dev %d:%d keydev %d:%d block %llu len %llu owner %lld flags 0x%llx
+", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), ((unsigned int) ((REC->keydev) >> 20)), ((unsigned int) ((REC->keydev) & ((1U << 20) - 1))), REC->block, REC->len, REC->owner, REC->flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ind_map_blocks_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ind_map_blocks_enter/format
new file mode 100644
index 000000000..efbb7592c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ind_map_blocks_enter/format
@@ -0,0 +1,15 @@
+name: ext4_ind_map_blocks_enter
+ID: 437
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_lblk_t lblk; offset:24; size:4; signed:0;
+ field:unsigned int len; offset:28; size:4; signed:0;
+ field:unsigned int flags; offset:32; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu lblk %u len %u flags %s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->lblk, REC->len, __print_flags(REC->flags, "|", { 0x0001, "CREATE" }, { 0x0002, "UNWRIT" }, { 0x0004, "DELALLOC" }, { 0x0008, "PRE_IO" }, { 0x0010, "CONVERT" }, { 0x0020, "METADATA_NOFAIL" }, { 0x0040, "NO_NORMALIZE" }, { 0x0100, "CONVERT_UNWRITTEN" }, { 0x0200, "ZERO" }, { 0x0400, "IO_SUBMIT" }, { 0x40000000, "EX_NOCACHE" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ind_map_blocks_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ind_map_blocks_exit/format
new file mode 100644
index 000000000..3f5d438d4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_ind_map_blocks_exit/format
@@ -0,0 +1,18 @@
+name: ext4_ind_map_blocks_exit
+ID: 438
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned int flags; offset:24; size:4; signed:0;
+ field:ext4_fsblk_t pblk; offset:32; size:8; signed:0;
+ field:ext4_lblk_t lblk; offset:40; size:4; signed:0;
+ field:unsigned int len; offset:44; size:4; signed:0;
+ field:unsigned int mflags; offset:48; size:4; signed:0;
+ field:int ret; offset:52; size:4; signed:1;
+
+print fmt: "dev %d,%d ino %lu flags %s lblk %u pblk %llu len %u mflags %s ret %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, __print_flags(REC->flags, "|", { 0x0001, "CREATE" }, { 0x0002, "UNWRIT" }, { 0x0004, "DELALLOC" }, { 0x0008, "PRE_IO" }, { 0x0010, "CONVERT" }, { 0x0020, "METADATA_NOFAIL" }, { 0x0040, "NO_NORMALIZE" }, { 0x0100, "CONVERT_UNWRITTEN" }, { 0x0200, "ZERO" }, { 0x0400, "IO_SUBMIT" }, { 0x40000000, "EX_NOCACHE" }), REC->lblk, REC->pblk, REC->len, __print_flags(REC->mflags, "", { ((((1UL))) << (5)), "N" }, { ((((1UL))) << (4)), "M" }, { ((((1UL))) << (11)), "U" }, { ((((1UL))) << (9)), "B" }), REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_insert_range/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_insert_range/format
new file mode 100644
index 000000000..35af75caf
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_insert_range/format
@@ -0,0 +1,14 @@
+name: ext4_insert_range
+ID: 439
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t offset; offset:24; size:8; signed:1;
+ field:loff_t len; offset:32; size:8; signed:1;
+
+print fmt: "dev %d,%d ino %lu offset %lld len %lld", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->offset, REC->len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_invalidatepage/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_invalidatepage/format
new file mode 100644
index 000000000..294ceb2fd
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_invalidatepage/format
@@ -0,0 +1,15 @@
+name: ext4_invalidatepage
+ID: 440
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long index; offset:24; size:8; signed:0;
+ field:unsigned int offset; offset:32; size:4; signed:0;
+ field:unsigned int length; offset:36; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu page_index %lu offset %u length %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, (unsigned long) REC->index, REC->offset, REC->length
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_journal_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_journal_start/format
new file mode 100644
index 000000000..d8a62e26c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_journal_start/format
@@ -0,0 +1,15 @@
+name: ext4_journal_start
+ID: 441
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:unsigned long ip; offset:16; size:8; signed:0;
+ field:int blocks; offset:24; size:4; signed:1;
+ field:int rsv_blocks; offset:28; size:4; signed:1;
+ field:int revoke_creds; offset:32; size:4; signed:1;
+
+print fmt: "dev %d,%d blocks %d, rsv_blocks %d, revoke_creds %d, caller %pS", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->blocks, REC->rsv_blocks, REC->revoke_creds, (void *)REC->ip
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_journal_start_reserved/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_journal_start_reserved/format
new file mode 100644
index 000000000..875e1634a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_journal_start_reserved/format
@@ -0,0 +1,13 @@
+name: ext4_journal_start_reserved
+ID: 442
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:unsigned long ip; offset:16; size:8; signed:0;
+ field:int blocks; offset:24; size:4; signed:1;
+
+print fmt: "dev %d,%d blocks, %d caller %pS", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->blocks, (void *)REC->ip
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_journalled_invalidatepage/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_journalled_invalidatepage/format
new file mode 100644
index 000000000..2cb332f59
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_journalled_invalidatepage/format
@@ -0,0 +1,15 @@
+name: ext4_journalled_invalidatepage
+ID: 443
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long index; offset:24; size:8; signed:0;
+ field:unsigned int offset; offset:32; size:4; signed:0;
+ field:unsigned int length; offset:36; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu page_index %lu offset %u length %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, (unsigned long) REC->index, REC->offset, REC->length
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_journalled_write_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_journalled_write_end/format
new file mode 100644
index 000000000..95a4cae32
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_journalled_write_end/format
@@ -0,0 +1,15 @@
+name: ext4_journalled_write_end
+ID: 444
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t pos; offset:24; size:8; signed:1;
+ field:unsigned int len; offset:32; size:4; signed:0;
+ field:unsigned int copied; offset:36; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu pos %lld len %u copied %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->pos, REC->len, REC->copied
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_lazy_itable_init/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_lazy_itable_init/format
new file mode 100644
index 000000000..54383b1e5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_lazy_itable_init/format
@@ -0,0 +1,12 @@
+name: ext4_lazy_itable_init
+ID: 445
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:__u32 group; offset:12; size:4; signed:0;
+
+print fmt: "dev %d,%d group %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->group
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_load_inode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_load_inode/format
new file mode 100644
index 000000000..edf293fc9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_load_inode/format
@@ -0,0 +1,12 @@
+name: ext4_load_inode
+ID: 446
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+
+print fmt: "dev %d,%d ino %ld", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_load_inode_bitmap/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_load_inode_bitmap/format
new file mode 100644
index 000000000..e520c0a97
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_load_inode_bitmap/format
@@ -0,0 +1,12 @@
+name: ext4_load_inode_bitmap
+ID: 447
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:__u32 group; offset:12; size:4; signed:0;
+
+print fmt: "dev %d,%d group %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->group
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mark_inode_dirty/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mark_inode_dirty/format
new file mode 100644
index 000000000..0eb8f8849
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mark_inode_dirty/format
@@ -0,0 +1,13 @@
+name: ext4_mark_inode_dirty
+ID: 448
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long ip; offset:24; size:8; signed:0;
+
+print fmt: "dev %d,%d ino %lu caller %pS", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, (void *)REC->ip
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_bitmap_load/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_bitmap_load/format
new file mode 100644
index 000000000..08c651e88
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_bitmap_load/format
@@ -0,0 +1,12 @@
+name: ext4_mb_bitmap_load
+ID: 449
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:__u32 group; offset:12; size:4; signed:0;
+
+print fmt: "dev %d,%d group %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->group
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_buddy_bitmap_load/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_buddy_bitmap_load/format
new file mode 100644
index 000000000..c941442b1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_buddy_bitmap_load/format
@@ -0,0 +1,12 @@
+name: ext4_mb_buddy_bitmap_load
+ID: 450
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:__u32 group; offset:12; size:4; signed:0;
+
+print fmt: "dev %d,%d group %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->group
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_discard_preallocations/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_discard_preallocations/format
new file mode 100644
index 000000000..4fbf63800
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_discard_preallocations/format
@@ -0,0 +1,12 @@
+name: ext4_mb_discard_preallocations
+ID: 451
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int needed; offset:12; size:4; signed:1;
+
+print fmt: "dev %d,%d needed %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->needed
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_new_group_pa/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_new_group_pa/format
new file mode 100644
index 000000000..1174f5390
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_new_group_pa/format
@@ -0,0 +1,15 @@
+name: ext4_mb_new_group_pa
+ID: 452
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:__u64 pa_pstart; offset:24; size:8; signed:0;
+ field:__u64 pa_lstart; offset:32; size:8; signed:0;
+ field:__u32 pa_len; offset:40; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu pstart %llu len %u lstart %llu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->pa_pstart, REC->pa_len, REC->pa_lstart
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_new_inode_pa/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_new_inode_pa/format
new file mode 100644
index 000000000..10ba91d0e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_new_inode_pa/format
@@ -0,0 +1,15 @@
+name: ext4_mb_new_inode_pa
+ID: 453
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:__u64 pa_pstart; offset:24; size:8; signed:0;
+ field:__u64 pa_lstart; offset:32; size:8; signed:0;
+ field:__u32 pa_len; offset:40; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu pstart %llu len %u lstart %llu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->pa_pstart, REC->pa_len, REC->pa_lstart
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_release_group_pa/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_release_group_pa/format
new file mode 100644
index 000000000..f9928e3ae
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_release_group_pa/format
@@ -0,0 +1,13 @@
+name: ext4_mb_release_group_pa
+ID: 454
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:__u64 pa_pstart; offset:16; size:8; signed:0;
+ field:__u32 pa_len; offset:24; size:4; signed:0;
+
+print fmt: "dev %d,%d pstart %llu len %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->pa_pstart, REC->pa_len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_release_inode_pa/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_release_inode_pa/format
new file mode 100644
index 000000000..b8fa079ee
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mb_release_inode_pa/format
@@ -0,0 +1,14 @@
+name: ext4_mb_release_inode_pa
+ID: 455
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:__u64 block; offset:24; size:8; signed:0;
+ field:__u32 count; offset:32; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu block %llu count %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->block, REC->count
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mballoc_alloc/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mballoc_alloc/format
new file mode 100644
index 000000000..030372ce3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mballoc_alloc/format
@@ -0,0 +1,30 @@
+name: ext4_mballoc_alloc
+ID: 456
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:__u32 orig_logical; offset:24; size:4; signed:0;
+ field:int orig_start; offset:28; size:4; signed:1;
+ field:__u32 orig_group; offset:32; size:4; signed:0;
+ field:int orig_len; offset:36; size:4; signed:1;
+ field:__u32 goal_logical; offset:40; size:4; signed:0;
+ field:int goal_start; offset:44; size:4; signed:1;
+ field:__u32 goal_group; offset:48; size:4; signed:0;
+ field:int goal_len; offset:52; size:4; signed:1;
+ field:__u32 result_logical; offset:56; size:4; signed:0;
+ field:int result_start; offset:60; size:4; signed:1;
+ field:__u32 result_group; offset:64; size:4; signed:0;
+ field:int result_len; offset:68; size:4; signed:1;
+ field:__u16 found; offset:72; size:2; signed:0;
+ field:__u16 groups; offset:74; size:2; signed:0;
+ field:__u16 buddy; offset:76; size:2; signed:0;
+ field:__u16 flags; offset:78; size:2; signed:0;
+ field:__u16 tail; offset:80; size:2; signed:0;
+ field:__u8 cr; offset:82; size:1; signed:0;
+
+print fmt: "dev %d,%d inode %lu orig %u/%d/%u@%u goal %u/%d/%u@%u result %u/%d/%u@%u blks %u grps %u cr %u flags %s tail %u broken %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->orig_group, REC->orig_start, REC->orig_len, REC->orig_logical, REC->goal_group, REC->goal_start, REC->goal_len, REC->goal_logical, REC->result_group, REC->result_start, REC->result_len, REC->result_logical, REC->found, REC->groups, REC->cr, __print_flags(REC->flags, "|", { 0x0001, "HINT_MERGE" }, { 0x0002, "HINT_RESV" }, { 0x0004, "HINT_MDATA" }, { 0x0008, "HINT_FIRST" }, { 0x0010, "HINT_BEST" }, { 0x0020, "HINT_DATA" }, { 0x0040, "HINT_NOPREALLOC" }, { 0x0080, "HINT_GRP_ALLOC" }, { 0x0100, "HINT_GOAL_ONLY" }, { 0x0200, "HINT_TRY_GOAL" }, { 0x0400, "DELALLOC_RESV" }, { 0x0800, "STREAM_ALLOC" }, { 0x1000, "USE_ROOT_BLKS" }, { 0x2000, "USE_RESV" }, { 0x4000, "STRICT_CHECK" }), REC->tail, REC->buddy ? 1 << REC->buddy : 0
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mballoc_discard/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mballoc_discard/format
new file mode 100644
index 000000000..0773c4bfa
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mballoc_discard/format
@@ -0,0 +1,15 @@
+name: ext4_mballoc_discard
+ID: 457
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int result_start; offset:24; size:4; signed:1;
+ field:__u32 result_group; offset:28; size:4; signed:0;
+ field:int result_len; offset:32; size:4; signed:1;
+
+print fmt: "dev %d,%d inode %lu extent %u/%d/%d ", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->result_group, REC->result_start, REC->result_len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mballoc_free/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mballoc_free/format
new file mode 100644
index 000000000..eefb93cd2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mballoc_free/format
@@ -0,0 +1,15 @@
+name: ext4_mballoc_free
+ID: 458
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int result_start; offset:24; size:4; signed:1;
+ field:__u32 result_group; offset:28; size:4; signed:0;
+ field:int result_len; offset:32; size:4; signed:1;
+
+print fmt: "dev %d,%d inode %lu extent %u/%d/%d ", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->result_group, REC->result_start, REC->result_len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mballoc_prealloc/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mballoc_prealloc/format
new file mode 100644
index 000000000..735d67837
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_mballoc_prealloc/format
@@ -0,0 +1,20 @@
+name: ext4_mballoc_prealloc
+ID: 459
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:__u32 orig_logical; offset:24; size:4; signed:0;
+ field:int orig_start; offset:28; size:4; signed:1;
+ field:__u32 orig_group; offset:32; size:4; signed:0;
+ field:int orig_len; offset:36; size:4; signed:1;
+ field:__u32 result_logical; offset:40; size:4; signed:0;
+ field:int result_start; offset:44; size:4; signed:1;
+ field:__u32 result_group; offset:48; size:4; signed:0;
+ field:int result_len; offset:52; size:4; signed:1;
+
+print fmt: "dev %d,%d inode %lu orig %u/%d/%u@%u result %u/%d/%u@%u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->orig_group, REC->orig_start, REC->orig_len, REC->orig_logical, REC->result_group, REC->result_start, REC->result_len, REC->result_logical
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_nfs_commit_metadata/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_nfs_commit_metadata/format
new file mode 100644
index 000000000..089735b14
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_nfs_commit_metadata/format
@@ -0,0 +1,12 @@
+name: ext4_nfs_commit_metadata
+ID: 460
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+
+print fmt: "dev %d,%d ino %lu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_other_inode_update_time/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_other_inode_update_time/format
new file mode 100644
index 000000000..26ecb6a51
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_other_inode_update_time/format
@@ -0,0 +1,16 @@
+name: ext4_other_inode_update_time
+ID: 461
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ino_t orig_ino; offset:24; size:8; signed:0;
+ field:uid_t uid; offset:32; size:4; signed:0;
+ field:gid_t gid; offset:36; size:4; signed:0;
+ field:__u16 mode; offset:40; size:2; signed:0;
+
+print fmt: "dev %d,%d orig_ino %lu ino %lu mode 0%o uid %u gid %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->orig_ino, (unsigned long) REC->ino, REC->mode, REC->uid, REC->gid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_prefetch_bitmaps/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_prefetch_bitmaps/format
new file mode 100644
index 000000000..76806ad59
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_prefetch_bitmaps/format
@@ -0,0 +1,14 @@
+name: ext4_prefetch_bitmaps
+ID: 462
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:__u32 group; offset:12; size:4; signed:0;
+ field:__u32 next; offset:16; size:4; signed:0;
+ field:__u32 ios; offset:20; size:4; signed:0;
+
+print fmt: "dev %d,%d group %u next %u ios %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->group, REC->next, REC->ios
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_punch_hole/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_punch_hole/format
new file mode 100644
index 000000000..644b3ea7f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_punch_hole/format
@@ -0,0 +1,15 @@
+name: ext4_punch_hole
+ID: 463
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t offset; offset:24; size:8; signed:1;
+ field:loff_t len; offset:32; size:8; signed:1;
+ field:int mode; offset:40; size:4; signed:1;
+
+print fmt: "dev %d,%d ino %lu offset %lld len %lld mode %s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->offset, REC->len, __print_flags(REC->mode, "|", { 0x01, "KEEP_SIZE"}, { 0x02, "PUNCH_HOLE"}, { 0x04, "NO_HIDE_STALE"}, { 0x08, "COLLAPSE_RANGE"}, { 0x10, "ZERO_RANGE"})
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_read_block_bitmap_load/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_read_block_bitmap_load/format
new file mode 100644
index 000000000..e3db7057e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_read_block_bitmap_load/format
@@ -0,0 +1,13 @@
+name: ext4_read_block_bitmap_load
+ID: 464
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:__u32 group; offset:12; size:4; signed:0;
+ field:bool prefetch; offset:16; size:1; signed:0;
+
+print fmt: "dev %d,%d group %u prefetch %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->group, REC->prefetch
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_readpage/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_readpage/format
new file mode 100644
index 000000000..90a4e280c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_readpage/format
@@ -0,0 +1,13 @@
+name: ext4_readpage
+ID: 465
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long index; offset:24; size:8; signed:0;
+
+print fmt: "dev %d,%d ino %lu page_index %lu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, (unsigned long) REC->index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_releasepage/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_releasepage/format
new file mode 100644
index 000000000..b4852d8a1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_releasepage/format
@@ -0,0 +1,13 @@
+name: ext4_releasepage
+ID: 466
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long index; offset:24; size:8; signed:0;
+
+print fmt: "dev %d,%d ino %lu page_index %lu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, (unsigned long) REC->index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_remove_blocks/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_remove_blocks/format
new file mode 100644
index 000000000..6a6c23d9f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_remove_blocks/format
@@ -0,0 +1,20 @@
+name: ext4_remove_blocks
+ID: 467
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ext4_lblk_t from; offset:24; size:4; signed:0;
+ field:ext4_lblk_t to; offset:28; size:4; signed:0;
+ field:ext4_fsblk_t ee_pblk; offset:32; size:8; signed:0;
+ field:ext4_lblk_t ee_lblk; offset:40; size:4; signed:0;
+ field:unsigned short ee_len; offset:44; size:2; signed:0;
+ field:ext4_fsblk_t pc_pclu; offset:48; size:8; signed:0;
+ field:ext4_lblk_t pc_lblk; offset:56; size:4; signed:0;
+ field:int pc_state; offset:60; size:4; signed:1;
+
+print fmt: "dev %d,%d ino %lu extent [%u(%llu), %u]from %u to %u partial [pclu %lld lblk %u state %d]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, (unsigned) REC->ee_lblk, (unsigned long long) REC->ee_pblk, (unsigned short) REC->ee_len, (unsigned) REC->from, (unsigned) REC->to, (long long) REC->pc_pclu, (unsigned int) REC->pc_lblk, (int) REC->pc_state
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_request_blocks/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_request_blocks/format
new file mode 100644
index 000000000..3f67026e2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_request_blocks/format
@@ -0,0 +1,20 @@
+name: ext4_request_blocks
+ID: 468
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned int len; offset:24; size:4; signed:0;
+ field:__u32 logical; offset:28; size:4; signed:0;
+ field:__u32 lleft; offset:32; size:4; signed:0;
+ field:__u32 lright; offset:36; size:4; signed:0;
+ field:__u64 goal; offset:40; size:8; signed:0;
+ field:__u64 pleft; offset:48; size:8; signed:0;
+ field:__u64 pright; offset:56; size:8; signed:0;
+ field:unsigned int flags; offset:64; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu flags %s len %u lblk %u goal %llu lleft %u lright %u pleft %llu pright %llu ", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, __print_flags(REC->flags, "|", { 0x0001, "HINT_MERGE" }, { 0x0002, "HINT_RESV" }, { 0x0004, "HINT_MDATA" }, { 0x0008, "HINT_FIRST" }, { 0x0010, "HINT_BEST" }, { 0x0020, "HINT_DATA" }, { 0x0040, "HINT_NOPREALLOC" }, { 0x0080, "HINT_GRP_ALLOC" }, { 0x0100, "HINT_GOAL_ONLY" }, { 0x0200, "HINT_TRY_GOAL" }, { 0x0400, "DELALLOC_RESV" }, { 0x0800, "STREAM_ALLOC" }, { 0x1000, "USE_ROOT_BLKS" }, { 0x2000, "USE_RESV" }, { 0x4000, "STRICT_CHECK" }), REC->len, REC->logical, REC->goal, REC->lleft, REC->lright, REC->pleft, REC->pright
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_request_inode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_request_inode/format
new file mode 100644
index 000000000..983ffa91d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_request_inode/format
@@ -0,0 +1,13 @@
+name: ext4_request_inode
+ID: 469
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t dir; offset:16; size:8; signed:0;
+ field:__u16 mode; offset:24; size:2; signed:0;
+
+print fmt: "dev %d,%d dir %lu mode 0%o", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->dir, REC->mode
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_shutdown/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_shutdown/format
new file mode 100644
index 000000000..b4c75711b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_shutdown/format
@@ -0,0 +1,12 @@
+name: ext4_shutdown
+ID: 470
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:unsigned flags; offset:12; size:4; signed:0;
+
+print fmt: "dev %d,%d flags %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_sync_file_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_sync_file_enter/format
new file mode 100644
index 000000000..417049766
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_sync_file_enter/format
@@ -0,0 +1,14 @@
+name: ext4_sync_file_enter
+ID: 471
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ino_t parent; offset:24; size:8; signed:0;
+ field:int datasync; offset:32; size:4; signed:1;
+
+print fmt: "dev %d,%d ino %lu parent %lu datasync %d ", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, (unsigned long) REC->parent, REC->datasync
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_sync_file_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_sync_file_exit/format
new file mode 100644
index 000000000..bb0f8ae1d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_sync_file_exit/format
@@ -0,0 +1,13 @@
+name: ext4_sync_file_exit
+ID: 472
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int ret; offset:24; size:4; signed:1;
+
+print fmt: "dev %d,%d ino %lu ret %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_sync_fs/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_sync_fs/format
new file mode 100644
index 000000000..d2d7872f2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_sync_fs/format
@@ -0,0 +1,12 @@
+name: ext4_sync_fs
+ID: 473
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int wait; offset:12; size:4; signed:1;
+
+print fmt: "dev %d,%d wait %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->wait
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_trim_all_free/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_trim_all_free/format
new file mode 100644
index 000000000..0c146d2f8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_trim_all_free/format
@@ -0,0 +1,15 @@
+name: ext4_trim_all_free
+ID: 474
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int dev_major; offset:8; size:4; signed:1;
+ field:int dev_minor; offset:12; size:4; signed:1;
+ field:__u32 group; offset:16; size:4; signed:0;
+ field:int start; offset:20; size:4; signed:1;
+ field:int len; offset:24; size:4; signed:1;
+
+print fmt: "dev %d,%d group %u, start %d, len %d", REC->dev_major, REC->dev_minor, REC->group, REC->start, REC->len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_trim_extent/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_trim_extent/format
new file mode 100644
index 000000000..23801f99e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_trim_extent/format
@@ -0,0 +1,15 @@
+name: ext4_trim_extent
+ID: 475
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int dev_major; offset:8; size:4; signed:1;
+ field:int dev_minor; offset:12; size:4; signed:1;
+ field:__u32 group; offset:16; size:4; signed:0;
+ field:int start; offset:20; size:4; signed:1;
+ field:int len; offset:24; size:4; signed:1;
+
+print fmt: "dev %d,%d group %u, start %d, len %d", REC->dev_major, REC->dev_minor, REC->group, REC->start, REC->len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_truncate_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_truncate_enter/format
new file mode 100644
index 000000000..f41090010
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_truncate_enter/format
@@ -0,0 +1,13 @@
+name: ext4_truncate_enter
+ID: 476
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:__u64 blocks; offset:24; size:8; signed:0;
+
+print fmt: "dev %d,%d ino %lu blocks %llu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->blocks
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_truncate_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_truncate_exit/format
new file mode 100644
index 000000000..ba7833ce9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_truncate_exit/format
@@ -0,0 +1,13 @@
+name: ext4_truncate_exit
+ID: 477
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:__u64 blocks; offset:24; size:8; signed:0;
+
+print fmt: "dev %d,%d ino %lu blocks %llu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->blocks
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_unlink_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_unlink_enter/format
new file mode 100644
index 000000000..1dc238850
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_unlink_enter/format
@@ -0,0 +1,14 @@
+name: ext4_unlink_enter
+ID: 478
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ino_t parent; offset:24; size:8; signed:0;
+ field:loff_t size; offset:32; size:8; signed:1;
+
+print fmt: "dev %d,%d ino %lu size %lld parent %lu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->size, (unsigned long) REC->parent
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_unlink_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_unlink_exit/format
new file mode 100644
index 000000000..4ce3e446c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_unlink_exit/format
@@ -0,0 +1,13 @@
+name: ext4_unlink_exit
+ID: 479
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int ret; offset:24; size:4; signed:1;
+
+print fmt: "dev %d,%d ino %lu ret %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_write_begin/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_write_begin/format
new file mode 100644
index 000000000..84a7fab55
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_write_begin/format
@@ -0,0 +1,15 @@
+name: ext4_write_begin
+ID: 480
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t pos; offset:24; size:8; signed:1;
+ field:unsigned int len; offset:32; size:4; signed:0;
+ field:unsigned int flags; offset:36; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu pos %lld len %u flags %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->pos, REC->len, REC->flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_write_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_write_end/format
new file mode 100644
index 000000000..fa090938f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_write_end/format
@@ -0,0 +1,15 @@
+name: ext4_write_end
+ID: 481
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t pos; offset:24; size:8; signed:1;
+ field:unsigned int len; offset:32; size:4; signed:0;
+ field:unsigned int copied; offset:36; size:4; signed:0;
+
+print fmt: "dev %d,%d ino %lu pos %lld len %u copied %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->pos, REC->len, REC->copied
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_writepage/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_writepage/format
new file mode 100644
index 000000000..049c7d0f3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_writepage/format
@@ -0,0 +1,13 @@
+name: ext4_writepage
+ID: 482
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long index; offset:24; size:8; signed:0;
+
+print fmt: "dev %d,%d ino %lu page_index %lu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, (unsigned long) REC->index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_writepages/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_writepages/format
new file mode 100644
index 000000000..08739e298
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_writepages/format
@@ -0,0 +1,20 @@
+name: ext4_writepages
+ID: 483
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:long nr_to_write; offset:24; size:8; signed:1;
+ field:long pages_skipped; offset:32; size:8; signed:1;
+ field:loff_t range_start; offset:40; size:8; signed:1;
+ field:loff_t range_end; offset:48; size:8; signed:1;
+ field:unsigned long writeback_index; offset:56; size:8; signed:0;
+ field:int sync_mode; offset:64; size:4; signed:1;
+ field:char for_kupdate; offset:68; size:1; signed:0;
+ field:char range_cyclic; offset:69; size:1; signed:0;
+
+print fmt: "dev %d,%d ino %lu nr_to_write %ld pages_skipped %ld range_start %lld range_end %lld sync_mode %d for_kupdate %d range_cyclic %d writeback_index %lu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->nr_to_write, REC->pages_skipped, REC->range_start, REC->range_end, REC->sync_mode, REC->for_kupdate, REC->range_cyclic, (unsigned long) REC->writeback_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_writepages_result/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_writepages_result/format
new file mode 100644
index 000000000..1318b9add
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_writepages_result/format
@@ -0,0 +1,17 @@
+name: ext4_writepages_result
+ID: 484
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int ret; offset:24; size:4; signed:1;
+ field:int pages_written; offset:28; size:4; signed:1;
+ field:long pages_skipped; offset:32; size:8; signed:1;
+ field:unsigned long writeback_index; offset:40; size:8; signed:0;
+ field:int sync_mode; offset:48; size:4; signed:1;
+
+print fmt: "dev %d,%d ino %lu ret %d pages_written %d pages_skipped %ld sync_mode %d writeback_index %lu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->ret, REC->pages_written, REC->pages_skipped, REC->sync_mode, (unsigned long) REC->writeback_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_zero_range/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_zero_range/format
new file mode 100644
index 000000000..68803247b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ext4/ext4_zero_range/format
@@ -0,0 +1,15 @@
+name: ext4_zero_range
+ID: 485
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t offset; offset:24; size:8; signed:1;
+ field:loff_t len; offset:32; size:8; signed:1;
+ field:int mode; offset:40; size:4; signed:1;
+
+print fmt: "dev %d,%d ino %lu offset %lld len %lld mode %s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, REC->offset, REC->len, __print_flags(REC->mode, "|", { 0x01, "KEEP_SIZE"}, { 0x02, "PUNCH_HOLE"}, { 0x04, "NO_HIDE_STALE"}, { 0x08, "COLLAPSE_RANGE"}, { 0x10, "ZERO_RANGE"})
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_background_gc/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_background_gc/format
new file mode 100644
index 000000000..e7b188ae0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_background_gc/format
@@ -0,0 +1,14 @@
+name: f2fs_background_gc
+ID: 503
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:unsigned int wait_ms; offset:12; size:4; signed:0;
+ field:unsigned int prefree; offset:16; size:4; signed:0;
+ field:unsigned int free; offset:20; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), wait_ms = %u, prefree = %u, free = %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->wait_ms, REC->prefree, REC->free
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_bmap/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_bmap/format
new file mode 100644
index 000000000..003eae2a9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_bmap/format
@@ -0,0 +1,14 @@
+name: f2fs_bmap
+ID: 504
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:sector_t lblock; offset:24; size:8; signed:0;
+ field:sector_t pblock; offset:32; size:8; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, lblock:%lld, pblock:%lld", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, (unsigned long long)REC->lblock, (unsigned long long)REC->pblock
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_commit_inmem_page/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_commit_inmem_page/format
new file mode 100644
index 000000000..0cc487e1b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_commit_inmem_page/format
@@ -0,0 +1,17 @@
+name: f2fs_commit_inmem_page
+ID: 505
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int type; offset:24; size:4; signed:1;
+ field:int dir; offset:28; size:4; signed:1;
+ field:unsigned long index; offset:32; size:8; signed:0;
+ field:int dirty; offset:40; size:4; signed:1;
+ field:int uptodate; offset:44; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, %s, %s, index = %lu, dirty = %d, uptodate = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, __print_symbolic(REC->type, { 1, "NODE" }, { 0, "DATA" }, { 2, "META" }, { 4, "META_FLUSH" }, { 5, "INMEM" }, { 6, "INMEM_DROP" }, { 7, "INMEM_INVALIDATE" }, { 8, "INMEM_REVOKE" }, { 9, "IN-PLACE" }, { 10, "OUT-OF-PLACE" }), __print_symbolic(REC->dir, { 0, "FILE" }, { 1, "DIR" }), (unsigned long)REC->index, REC->dirty, REC->uptodate
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_compress_pages_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_compress_pages_end/format
new file mode 100644
index 000000000..97955a056
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_compress_pages_end/format
@@ -0,0 +1,15 @@
+name: f2fs_compress_pages_end
+ID: 506
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long idx; offset:24; size:8; signed:0;
+ field:unsigned int size; offset:32; size:4; signed:0;
+ field:unsigned int ret; offset:36; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, cluster_idx:%lu, compressed_size = %u, ret = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->idx, REC->size, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_compress_pages_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_compress_pages_start/format
new file mode 100644
index 000000000..0ab7e6b43
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_compress_pages_start/format
@@ -0,0 +1,15 @@
+name: f2fs_compress_pages_start
+ID: 507
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long idx; offset:24; size:8; signed:0;
+ field:unsigned int size; offset:32; size:4; signed:0;
+ field:unsigned int algtype; offset:36; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, cluster_idx:%lu, cluster_size = %u, algorithm = %s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->idx, REC->size, __print_symbolic(REC->algtype, { COMPRESS_LZO, "LZO" }, { COMPRESS_LZ4, "LZ4" }, { COMPRESS_ZSTD, "ZSTD" }, { COMPRESS_LZORLE, "LZO-RLE" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_decompress_pages_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_decompress_pages_end/format
new file mode 100644
index 000000000..6f9992f7c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_decompress_pages_end/format
@@ -0,0 +1,15 @@
+name: f2fs_decompress_pages_end
+ID: 508
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long idx; offset:24; size:8; signed:0;
+ field:unsigned int size; offset:32; size:4; signed:0;
+ field:unsigned int ret; offset:36; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, cluster_idx:%lu, compressed_size = %u, ret = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->idx, REC->size, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_decompress_pages_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_decompress_pages_start/format
new file mode 100644
index 000000000..14d73f7f6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_decompress_pages_start/format
@@ -0,0 +1,15 @@
+name: f2fs_decompress_pages_start
+ID: 509
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long idx; offset:24; size:8; signed:0;
+ field:unsigned int size; offset:32; size:4; signed:0;
+ field:unsigned int algtype; offset:36; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, cluster_idx:%lu, cluster_size = %u, algorithm = %s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->idx, REC->size, __print_symbolic(REC->algtype, { COMPRESS_LZO, "LZO" }, { COMPRESS_LZ4, "LZ4" }, { COMPRESS_ZSTD, "ZSTD" }, { COMPRESS_LZORLE, "LZO-RLE" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_destroy_extent_tree/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_destroy_extent_tree/format
new file mode 100644
index 000000000..77d739c2e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_destroy_extent_tree/format
@@ -0,0 +1,13 @@
+name: f2fs_destroy_extent_tree
+ID: 510
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned int node_cnt; offset:24; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, destroyed: node_cnt = %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->node_cnt
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_direct_IO_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_direct_IO_enter/format
new file mode 100644
index 000000000..5da013b04
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_direct_IO_enter/format
@@ -0,0 +1,15 @@
+name: f2fs_direct_IO_enter
+ID: 511
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t pos; offset:24; size:8; signed:1;
+ field:unsigned long len; offset:32; size:8; signed:0;
+ field:int rw; offset:40; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu pos = %lld len = %lu rw = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->pos, REC->len, REC->rw
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_direct_IO_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_direct_IO_exit/format
new file mode 100644
index 000000000..c21027239
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_direct_IO_exit/format
@@ -0,0 +1,16 @@
+name: f2fs_direct_IO_exit
+ID: 512
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t pos; offset:24; size:8; signed:1;
+ field:unsigned long len; offset:32; size:8; signed:0;
+ field:int rw; offset:40; size:4; signed:1;
+ field:int ret; offset:44; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu pos = %lld len = %lu rw = %d ret = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->pos, REC->len, REC->rw, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_do_write_data_page/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_do_write_data_page/format
new file mode 100644
index 000000000..11399a9ce
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_do_write_data_page/format
@@ -0,0 +1,17 @@
+name: f2fs_do_write_data_page
+ID: 513
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int type; offset:24; size:4; signed:1;
+ field:int dir; offset:28; size:4; signed:1;
+ field:unsigned long index; offset:32; size:8; signed:0;
+ field:int dirty; offset:40; size:4; signed:1;
+ field:int uptodate; offset:44; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, %s, %s, index = %lu, dirty = %d, uptodate = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, __print_symbolic(REC->type, { 1, "NODE" }, { 0, "DATA" }, { 2, "META" }, { 4, "META_FLUSH" }, { 5, "INMEM" }, { 6, "INMEM_DROP" }, { 7, "INMEM_INVALIDATE" }, { 8, "INMEM_REVOKE" }, { 9, "IN-PLACE" }, { 10, "OUT-OF-PLACE" }), __print_symbolic(REC->dir, { 0, "FILE" }, { 1, "DIR" }), (unsigned long)REC->index, REC->dirty, REC->uptodate
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_drop_inode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_drop_inode/format
new file mode 100644
index 000000000..0dc31bd2c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_drop_inode/format
@@ -0,0 +1,13 @@
+name: f2fs_drop_inode
+ID: 514
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int ret; offset:24; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, ret = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_evict_inode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_evict_inode/format
new file mode 100644
index 000000000..da11ef9b0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_evict_inode/format
@@ -0,0 +1,18 @@
+name: f2fs_evict_inode
+ID: 515
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ino_t pino; offset:24; size:8; signed:0;
+ field:umode_t mode; offset:32; size:2; signed:0;
+ field:loff_t size; offset:40; size:8; signed:1;
+ field:unsigned int nlink; offset:48; size:4; signed:0;
+ field:blkcnt_t blocks; offset:56; size:8; signed:0;
+ field:__u8 advise; offset:64; size:1; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, pino = %lu, i_mode = 0x%hx, i_size = %lld, i_nlink = %u, i_blocks = %llu, i_advise = 0x%x", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, (unsigned long)REC->pino, REC->mode, REC->size, (unsigned int)REC->nlink, (unsigned long long)REC->blocks, (unsigned char)REC->advise
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_fallocate/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_fallocate/format
new file mode 100644
index 000000000..f32609453
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_fallocate/format
@@ -0,0 +1,18 @@
+name: f2fs_fallocate
+ID: 516
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int mode; offset:24; size:4; signed:1;
+ field:loff_t offset; offset:32; size:8; signed:1;
+ field:loff_t len; offset:40; size:8; signed:1;
+ field:loff_t size; offset:48; size:8; signed:1;
+ field:blkcnt_t blocks; offset:56; size:8; signed:0;
+ field:int ret; offset:64; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, mode = %x, offset = %lld, len = %lld, i_size = %lld, i_blocks = %llu, ret = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->mode, (unsigned long long)REC->offset, (unsigned long long)REC->len, (unsigned long long)REC->size, (unsigned long long)REC->blocks, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_fiemap/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_fiemap/format
new file mode 100644
index 000000000..894f98701
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_fiemap/format
@@ -0,0 +1,17 @@
+name: f2fs_fiemap
+ID: 517
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:sector_t lblock; offset:24; size:8; signed:0;
+ field:sector_t pblock; offset:32; size:8; signed:0;
+ field:unsigned long long len; offset:40; size:8; signed:0;
+ field:unsigned int flags; offset:48; size:4; signed:0;
+ field:int ret; offset:52; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, lblock:%lld, pblock:%lld, len:%llu, flags:%u, ret:%d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, (unsigned long long)REC->lblock, (unsigned long long)REC->pblock, REC->len, REC->flags, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_file_write_iter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_file_write_iter/format
new file mode 100644
index 000000000..1c5232312
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_file_write_iter/format
@@ -0,0 +1,15 @@
+name: f2fs_file_write_iter
+ID: 518
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long offset; offset:24; size:8; signed:0;
+ field:unsigned long length; offset:32; size:8; signed:0;
+ field:int ret; offset:40; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, offset = %lu, length = %lu, written(err) = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->offset, REC->length, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_filemap_fault/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_filemap_fault/format
new file mode 100644
index 000000000..b74800257
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_filemap_fault/format
@@ -0,0 +1,14 @@
+name: f2fs_filemap_fault
+ID: 519
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long index; offset:24; size:8; signed:0;
+ field:unsigned long ret; offset:32; size:8; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, index = %lu, ret = %lx", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, (unsigned long)REC->index, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_gc_begin/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_gc_begin/format
new file mode 100644
index 000000000..a4936699b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_gc_begin/format
@@ -0,0 +1,20 @@
+name: f2fs_gc_begin
+ID: 520
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:bool sync; offset:12; size:1; signed:0;
+ field:bool background; offset:13; size:1; signed:0;
+ field:long long dirty_nodes; offset:16; size:8; signed:1;
+ field:long long dirty_dents; offset:24; size:8; signed:1;
+ field:long long dirty_imeta; offset:32; size:8; signed:1;
+ field:unsigned int free_sec; offset:40; size:4; signed:0;
+ field:unsigned int free_seg; offset:44; size:4; signed:0;
+ field:int reserved_seg; offset:48; size:4; signed:1;
+ field:unsigned int prefree_seg; offset:52; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), sync = %d, background = %d, nodes = %lld, dents = %lld, imeta = %lld, free_sec:%u, free_seg:%u, rsv_seg:%d, prefree_seg:%u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->sync, REC->background, REC->dirty_nodes, REC->dirty_dents, REC->dirty_imeta, REC->free_sec, REC->free_seg, REC->reserved_seg, REC->prefree_seg
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_gc_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_gc_end/format
new file mode 100644
index 000000000..14870b345
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_gc_end/format
@@ -0,0 +1,21 @@
+name: f2fs_gc_end
+ID: 521
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int ret; offset:12; size:4; signed:1;
+ field:int seg_freed; offset:16; size:4; signed:1;
+ field:int sec_freed; offset:20; size:4; signed:1;
+ field:long long dirty_nodes; offset:24; size:8; signed:1;
+ field:long long dirty_dents; offset:32; size:8; signed:1;
+ field:long long dirty_imeta; offset:40; size:8; signed:1;
+ field:unsigned int free_sec; offset:48; size:4; signed:0;
+ field:unsigned int free_seg; offset:52; size:4; signed:0;
+ field:int reserved_seg; offset:56; size:4; signed:1;
+ field:unsigned int prefree_seg; offset:60; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), ret = %d, seg_freed = %d, sec_freed = %d, nodes = %lld, dents = %lld, imeta = %lld, free_sec:%u, free_seg:%u, rsv_seg:%d, prefree_seg:%u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->ret, REC->seg_freed, REC->sec_freed, REC->dirty_nodes, REC->dirty_dents, REC->dirty_imeta, REC->free_sec, REC->free_seg, REC->reserved_seg, REC->prefree_seg
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_get_victim/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_get_victim/format
new file mode 100644
index 000000000..eb88b172d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_get_victim/format
@@ -0,0 +1,21 @@
+name: f2fs_get_victim
+ID: 522
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int type; offset:12; size:4; signed:1;
+ field:int gc_type; offset:16; size:4; signed:1;
+ field:int alloc_mode; offset:20; size:4; signed:1;
+ field:int gc_mode; offset:24; size:4; signed:1;
+ field:unsigned int victim; offset:28; size:4; signed:0;
+ field:unsigned int cost; offset:32; size:4; signed:0;
+ field:unsigned int ofs_unit; offset:36; size:4; signed:0;
+ field:unsigned int pre_victim; offset:40; size:4; signed:0;
+ field:unsigned int prefree; offset:44; size:4; signed:0;
+ field:unsigned int free; offset:48; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), type = %s, policy = (%s, %s, %s), victim = %u, cost = %u, ofs_unit = %u, pre_victim_secno = %d, prefree = %u, free = %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), __print_symbolic(REC->type, { 0, "Hot DATA" }, { 1, "Warm DATA" }, { 2, "Cold DATA" }, { 3, "Hot NODE" }, { 4, "Warm NODE" }, { 5, "Cold NODE" }, { 8, "No TYPE" }), __print_symbolic(REC->gc_type, { 1, "Foreground GC" }, { 0, "Background GC" }), __print_symbolic(REC->alloc_mode, { 0, "LFS-mode" }, { 1, "SSR-mode" }, { AT_SSR, "AT_SSR-mode" }), __print_symbolic(REC->gc_mode, { 1, "Greedy" }, { 0, "Cost-Benefit" }, { GC_AT, "Age-threshold" }), REC->victim, REC->cost, REC->ofs_unit, (int)REC->pre_victim, REC->prefree, REC->free
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_iget/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_iget/format
new file mode 100644
index 000000000..623b974c0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_iget/format
@@ -0,0 +1,18 @@
+name: f2fs_iget
+ID: 523
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ino_t pino; offset:24; size:8; signed:0;
+ field:umode_t mode; offset:32; size:2; signed:0;
+ field:loff_t size; offset:40; size:8; signed:1;
+ field:unsigned int nlink; offset:48; size:4; signed:0;
+ field:blkcnt_t blocks; offset:56; size:8; signed:0;
+ field:__u8 advise; offset:64; size:1; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, pino = %lu, i_mode = 0x%hx, i_size = %lld, i_nlink = %u, i_blocks = %llu, i_advise = 0x%x", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, (unsigned long)REC->pino, REC->mode, REC->size, (unsigned int)REC->nlink, (unsigned long long)REC->blocks, (unsigned char)REC->advise
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_iget_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_iget_exit/format
new file mode 100644
index 000000000..54a035961
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_iget_exit/format
@@ -0,0 +1,13 @@
+name: f2fs_iget_exit
+ID: 524
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int ret; offset:24; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, ret = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_iostat/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_iostat/format
new file mode 100644
index 000000000..7df90423c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_iostat/format
@@ -0,0 +1,33 @@
+name: f2fs_iostat
+ID: 525
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:unsigned long long app_dio; offset:16; size:8; signed:0;
+ field:unsigned long long app_bio; offset:24; size:8; signed:0;
+ field:unsigned long long app_wio; offset:32; size:8; signed:0;
+ field:unsigned long long app_mio; offset:40; size:8; signed:0;
+ field:unsigned long long fs_dio; offset:48; size:8; signed:0;
+ field:unsigned long long fs_nio; offset:56; size:8; signed:0;
+ field:unsigned long long fs_mio; offset:64; size:8; signed:0;
+ field:unsigned long long fs_gc_dio; offset:72; size:8; signed:0;
+ field:unsigned long long fs_gc_nio; offset:80; size:8; signed:0;
+ field:unsigned long long fs_cp_dio; offset:88; size:8; signed:0;
+ field:unsigned long long fs_cp_nio; offset:96; size:8; signed:0;
+ field:unsigned long long fs_cp_mio; offset:104; size:8; signed:0;
+ field:unsigned long long app_drio; offset:112; size:8; signed:0;
+ field:unsigned long long app_brio; offset:120; size:8; signed:0;
+ field:unsigned long long app_rio; offset:128; size:8; signed:0;
+ field:unsigned long long app_mrio; offset:136; size:8; signed:0;
+ field:unsigned long long fs_drio; offset:144; size:8; signed:0;
+ field:unsigned long long fs_gdrio; offset:152; size:8; signed:0;
+ field:unsigned long long fs_cdrio; offset:160; size:8; signed:0;
+ field:unsigned long long fs_nrio; offset:168; size:8; signed:0;
+ field:unsigned long long fs_mrio; offset:176; size:8; signed:0;
+ field:unsigned long long fs_discard; offset:184; size:8; signed:0;
+
+print fmt: "dev = (%d,%d), app [write=%llu (direct=%llu, buffered=%llu), mapped=%llu], fs [data=%llu, node=%llu, meta=%llu, discard=%llu], gc [data=%llu, node=%llu], cp [data=%llu, node=%llu, meta=%llu], app [read=%llu (direct=%llu, buffered=%llu), mapped=%llu], fs [data=%llu, (gc_data=%llu, compr_data=%llu), node=%llu, meta=%llu]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->app_wio, REC->app_dio, REC->app_bio, REC->app_mio, REC->fs_dio, REC->fs_nio, REC->fs_mio, REC->fs_discard, REC->fs_gc_dio, REC->fs_gc_nio, REC->fs_cp_dio, REC->fs_cp_nio, REC->fs_cp_mio, REC->app_rio, REC->app_drio, REC->app_brio, REC->app_mrio, REC->fs_drio, REC->fs_gdrio, REC->fs_cdrio, REC->fs_nrio, REC->fs_mrio
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_issue_discard/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_issue_discard/format
new file mode 100644
index 000000000..a0e4dd50a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_issue_discard/format
@@ -0,0 +1,13 @@
+name: f2fs_issue_discard
+ID: 526
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:block_t blkstart; offset:12; size:4; signed:0;
+ field:block_t blklen; offset:16; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), blkstart = 0x%llx, blklen = 0x%llx", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long long)REC->blkstart, (unsigned long long)REC->blklen
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_issue_flush/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_issue_flush/format
new file mode 100644
index 000000000..93c2d22fb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_issue_flush/format
@@ -0,0 +1,14 @@
+name: f2fs_issue_flush
+ID: 527
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:unsigned int nobarrier; offset:12; size:4; signed:0;
+ field:unsigned int flush_merge; offset:16; size:4; signed:0;
+ field:int ret; offset:20; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), %s %s, ret = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->nobarrier ? "skip (nobarrier)" : "issue", REC->flush_merge ? " with flush_merge" : "", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_issue_reset_zone/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_issue_reset_zone/format
new file mode 100644
index 000000000..5ce63d63a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_issue_reset_zone/format
@@ -0,0 +1,12 @@
+name: f2fs_issue_reset_zone
+ID: 528
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:block_t blkstart; offset:12; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), reset zone at block = 0x%llx", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long long)REC->blkstart
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_lookup_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_lookup_end/format
new file mode 100644
index 000000000..0050023e3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_lookup_end/format
@@ -0,0 +1,15 @@
+name: f2fs_lookup_end
+ID: 529
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:const char * name; offset:24; size:8; signed:0;
+ field:nid_t cino; offset:32; size:4; signed:0;
+ field:int err; offset:36; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), pino = %lu, name:%s, ino:%u, err:%d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->name, REC->cino, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_lookup_extent_tree_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_lookup_extent_tree_end/format
new file mode 100644
index 000000000..c6f404fa4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_lookup_extent_tree_end/format
@@ -0,0 +1,16 @@
+name: f2fs_lookup_extent_tree_end
+ID: 530
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned int pgofs; offset:24; size:4; signed:0;
+ field:unsigned int fofs; offset:28; size:4; signed:0;
+ field:u32 blk; offset:32; size:4; signed:0;
+ field:unsigned int len; offset:36; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, pgofs = %u, ext_info(fofs: %u, blk: %u, len: %u)", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->pgofs, REC->fofs, REC->blk, REC->len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_lookup_extent_tree_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_lookup_extent_tree_start/format
new file mode 100644
index 000000000..568ac8413
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_lookup_extent_tree_start/format
@@ -0,0 +1,13 @@
+name: f2fs_lookup_extent_tree_start
+ID: 531
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned int pgofs; offset:24; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, pgofs = %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->pgofs
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_lookup_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_lookup_start/format
new file mode 100644
index 000000000..df46f7b12
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_lookup_start/format
@@ -0,0 +1,14 @@
+name: f2fs_lookup_start
+ID: 532
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:const char * name; offset:24; size:8; signed:0;
+ field:unsigned int flags; offset:32; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), pino = %lu, name:%s, flags:%u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->name, REC->flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_map_blocks/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_map_blocks/format
new file mode 100644
index 000000000..51403e865
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_map_blocks/format
@@ -0,0 +1,19 @@
+name: f2fs_map_blocks
+ID: 533
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:block_t m_lblk; offset:24; size:4; signed:0;
+ field:block_t m_pblk; offset:28; size:4; signed:0;
+ field:unsigned int m_len; offset:32; size:4; signed:0;
+ field:unsigned int m_flags; offset:36; size:4; signed:0;
+ field:int m_seg_type; offset:40; size:4; signed:1;
+ field:bool m_may_create; offset:44; size:1; signed:0;
+ field:int ret; offset:48; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, file offset = %llu, start blkaddr = 0x%llx, len = 0x%llx, flags = %u,seg_type = %d, may_create = %d, err = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, (unsigned long long)REC->m_lblk, (unsigned long long)REC->m_pblk, (unsigned long long)REC->m_len, REC->m_flags, REC->m_seg_type, REC->m_may_create, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_new_inode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_new_inode/format
new file mode 100644
index 000000000..e4be163e2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_new_inode/format
@@ -0,0 +1,13 @@
+name: f2fs_new_inode
+ID: 534
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int ret; offset:24; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, ret = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_prepare_read_bio/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_prepare_read_bio/format
new file mode 100644
index 000000000..e3e7cf7eb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_prepare_read_bio/format
@@ -0,0 +1,17 @@
+name: f2fs_prepare_read_bio
+ID: 535
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:dev_t target; offset:12; size:4; signed:0;
+ field:int op; offset:16; size:4; signed:1;
+ field:int op_flags; offset:20; size:4; signed:1;
+ field:int type; offset:24; size:4; signed:1;
+ field:sector_t sector; offset:32; size:8; signed:0;
+ field:unsigned int size; offset:40; size:4; signed:0;
+
+print fmt: "dev = (%d,%d)/(%d,%d), rw = %s(%s), %s, sector = %lld, size = %u", ((unsigned int) ((REC->target) >> 20)), ((unsigned int) ((REC->target) & ((1U << 20) - 1))), ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), blk_op_str(REC->op), __print_flags((REC->op_flags & ((1ULL << 19) | (1ULL << 11) | (1ULL << 12) | (1ULL << 13) | (1ULL << 18) | (1ULL << 17))), "|", { (1ULL << 19), "R" }, { (1ULL << 11), "S" }, { (1ULL << 12), "M" }, { (1ULL << 13), "P" }, { (1ULL << 18), "PF" }, { (1ULL << 17), "FUA" }), __print_symbolic(REC->type, { 1, "NODE" }, { 0, "DATA" }, { 2, "META" }, { 4, "META_FLUSH" }, { 5, "INMEM" }, { 6, "INMEM_DROP" }, { 7, "INMEM_INVALIDATE" }, { 8, "INMEM_REVOKE" }, { 9, "IN-PLACE" }, { 10, "OUT-OF-PLACE" }), (unsigned long long)REC->sector, REC->size
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_prepare_write_bio/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_prepare_write_bio/format
new file mode 100644
index 000000000..001a3f03d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_prepare_write_bio/format
@@ -0,0 +1,17 @@
+name: f2fs_prepare_write_bio
+ID: 536
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:dev_t target; offset:12; size:4; signed:0;
+ field:int op; offset:16; size:4; signed:1;
+ field:int op_flags; offset:20; size:4; signed:1;
+ field:int type; offset:24; size:4; signed:1;
+ field:sector_t sector; offset:32; size:8; signed:0;
+ field:unsigned int size; offset:40; size:4; signed:0;
+
+print fmt: "dev = (%d,%d)/(%d,%d), rw = %s(%s), %s, sector = %lld, size = %u", ((unsigned int) ((REC->target) >> 20)), ((unsigned int) ((REC->target) & ((1U << 20) - 1))), ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), blk_op_str(REC->op), __print_flags((REC->op_flags & ((1ULL << 19) | (1ULL << 11) | (1ULL << 12) | (1ULL << 13) | (1ULL << 18) | (1ULL << 17))), "|", { (1ULL << 19), "R" }, { (1ULL << 11), "S" }, { (1ULL << 12), "M" }, { (1ULL << 13), "P" }, { (1ULL << 18), "PF" }, { (1ULL << 17), "FUA" }), __print_symbolic(REC->type, { 1, "NODE" }, { 0, "DATA" }, { 2, "META" }, { 4, "META_FLUSH" }, { 5, "INMEM" }, { 6, "INMEM_DROP" }, { 7, "INMEM_INVALIDATE" }, { 8, "INMEM_REVOKE" }, { 9, "IN-PLACE" }, { 10, "OUT-OF-PLACE" }), (unsigned long long)REC->sector, REC->size
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_queue_discard/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_queue_discard/format
new file mode 100644
index 000000000..99d56af44
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_queue_discard/format
@@ -0,0 +1,13 @@
+name: f2fs_queue_discard
+ID: 537
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:block_t blkstart; offset:12; size:4; signed:0;
+ field:block_t blklen; offset:16; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), blkstart = 0x%llx, blklen = 0x%llx", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long long)REC->blkstart, (unsigned long long)REC->blklen
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_readdir/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_readdir/format
new file mode 100644
index 000000000..0fc453473
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_readdir/format
@@ -0,0 +1,15 @@
+name: f2fs_readdir
+ID: 538
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t start; offset:24; size:8; signed:1;
+ field:loff_t end; offset:32; size:8; signed:1;
+ field:int err; offset:40; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, start_pos:%llu, end_pos:%llu, err:%d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->start, REC->end, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_readpage/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_readpage/format
new file mode 100644
index 000000000..996b38775
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_readpage/format
@@ -0,0 +1,17 @@
+name: f2fs_readpage
+ID: 539
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int type; offset:24; size:4; signed:1;
+ field:int dir; offset:28; size:4; signed:1;
+ field:unsigned long index; offset:32; size:8; signed:0;
+ field:int dirty; offset:40; size:4; signed:1;
+ field:int uptodate; offset:44; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, %s, %s, index = %lu, dirty = %d, uptodate = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, __print_symbolic(REC->type, { 1, "NODE" }, { 0, "DATA" }, { 2, "META" }, { 4, "META_FLUSH" }, { 5, "INMEM" }, { 6, "INMEM_DROP" }, { 7, "INMEM_INVALIDATE" }, { 8, "INMEM_REVOKE" }, { 9, "IN-PLACE" }, { 10, "OUT-OF-PLACE" }), __print_symbolic(REC->dir, { 0, "FILE" }, { 1, "DIR" }), (unsigned long)REC->index, REC->dirty, REC->uptodate
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_readpages/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_readpages/format
new file mode 100644
index 000000000..719b9d81d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_readpages/format
@@ -0,0 +1,14 @@
+name: f2fs_readpages
+ID: 540
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long start; offset:24; size:8; signed:0;
+ field:unsigned int nrpage; offset:32; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, start = %lu nrpage = %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, (unsigned long)REC->start, REC->nrpage
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_register_inmem_page/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_register_inmem_page/format
new file mode 100644
index 000000000..c0e11a757
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_register_inmem_page/format
@@ -0,0 +1,17 @@
+name: f2fs_register_inmem_page
+ID: 541
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int type; offset:24; size:4; signed:1;
+ field:int dir; offset:28; size:4; signed:1;
+ field:unsigned long index; offset:32; size:8; signed:0;
+ field:int dirty; offset:40; size:4; signed:1;
+ field:int uptodate; offset:44; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, %s, %s, index = %lu, dirty = %d, uptodate = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, __print_symbolic(REC->type, { 1, "NODE" }, { 0, "DATA" }, { 2, "META" }, { 4, "META_FLUSH" }, { 5, "INMEM" }, { 6, "INMEM_DROP" }, { 7, "INMEM_INVALIDATE" }, { 8, "INMEM_REVOKE" }, { 9, "IN-PLACE" }, { 10, "OUT-OF-PLACE" }), __print_symbolic(REC->dir, { 0, "FILE" }, { 1, "DIR" }), (unsigned long)REC->index, REC->dirty, REC->uptodate
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_remove_discard/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_remove_discard/format
new file mode 100644
index 000000000..1ead780f5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_remove_discard/format
@@ -0,0 +1,13 @@
+name: f2fs_remove_discard
+ID: 542
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:block_t blkstart; offset:12; size:4; signed:0;
+ field:block_t blklen; offset:16; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), blkstart = 0x%llx, blklen = 0x%llx", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long long)REC->blkstart, (unsigned long long)REC->blklen
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_reserve_new_blocks/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_reserve_new_blocks/format
new file mode 100644
index 000000000..346b06a60
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_reserve_new_blocks/format
@@ -0,0 +1,14 @@
+name: f2fs_reserve_new_blocks
+ID: 543
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:nid_t nid; offset:12; size:4; signed:0;
+ field:unsigned int ofs_in_node; offset:16; size:4; signed:0;
+ field:blkcnt_t count; offset:24; size:8; signed:0;
+
+print fmt: "dev = (%d,%d), nid = %u, ofs_in_node = %u, count = %llu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned int)REC->nid, REC->ofs_in_node, (unsigned long long)REC->count
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_set_page_dirty/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_set_page_dirty/format
new file mode 100644
index 000000000..574820489
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_set_page_dirty/format
@@ -0,0 +1,17 @@
+name: f2fs_set_page_dirty
+ID: 544
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int type; offset:24; size:4; signed:1;
+ field:int dir; offset:28; size:4; signed:1;
+ field:unsigned long index; offset:32; size:8; signed:0;
+ field:int dirty; offset:40; size:4; signed:1;
+ field:int uptodate; offset:44; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, %s, %s, index = %lu, dirty = %d, uptodate = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, __print_symbolic(REC->type, { 1, "NODE" }, { 0, "DATA" }, { 2, "META" }, { 4, "META_FLUSH" }, { 5, "INMEM" }, { 6, "INMEM_DROP" }, { 7, "INMEM_INVALIDATE" }, { 8, "INMEM_REVOKE" }, { 9, "IN-PLACE" }, { 10, "OUT-OF-PLACE" }), __print_symbolic(REC->dir, { 0, "FILE" }, { 1, "DIR" }), (unsigned long)REC->index, REC->dirty, REC->uptodate
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_shrink_extent_tree/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_shrink_extent_tree/format
new file mode 100644
index 000000000..6c4f6ec33
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_shrink_extent_tree/format
@@ -0,0 +1,13 @@
+name: f2fs_shrink_extent_tree
+ID: 545
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:unsigned int node_cnt; offset:12; size:4; signed:0;
+ field:unsigned int tree_cnt; offset:16; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), shrunk: node_cnt = %u, tree_cnt = %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->node_cnt, REC->tree_cnt
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_shutdown/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_shutdown/format
new file mode 100644
index 000000000..ab971a548
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_shutdown/format
@@ -0,0 +1,13 @@
+name: f2fs_shutdown
+ID: 546
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:unsigned int mode; offset:12; size:4; signed:0;
+ field:int ret; offset:16; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), mode: %s, ret:%d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), __print_symbolic(REC->mode, { 0x0, "full sync" }, { 0x1, "meta sync" }, { 0x2, "no sync" }, { 0x3, "meta flush" }, { 0x4, "need fsck" }), REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_submit_page_bio/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_submit_page_bio/format
new file mode 100644
index 000000000..82b3a94de
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_submit_page_bio/format
@@ -0,0 +1,19 @@
+name: f2fs_submit_page_bio
+ID: 547
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long index; offset:24; size:8; signed:0;
+ field:block_t old_blkaddr; offset:32; size:4; signed:0;
+ field:block_t new_blkaddr; offset:36; size:4; signed:0;
+ field:int op; offset:40; size:4; signed:1;
+ field:int op_flags; offset:44; size:4; signed:1;
+ field:int temp; offset:48; size:4; signed:1;
+ field:int type; offset:52; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, page_index = 0x%lx, oldaddr = 0x%llx, newaddr = 0x%llx, rw = %s(%s), type = %s_%s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, (unsigned long)REC->index, (unsigned long long)REC->old_blkaddr, (unsigned long long)REC->new_blkaddr, blk_op_str(REC->op), __print_flags((REC->op_flags & ((1ULL << 19) | (1ULL << 11) | (1ULL << 12) | (1ULL << 13) | (1ULL << 18) | (1ULL << 17))), "|", { (1ULL << 19), "R" }, { (1ULL << 11), "S" }, { (1ULL << 12), "M" }, { (1ULL << 13), "P" }, { (1ULL << 18), "PF" }, { (1ULL << 17), "FUA" }), __print_symbolic(REC->temp, { 0, "HOT" }, { 1, "WARM" }, { 2, "COLD" }), __print_symbolic(REC->type, { 1, "NODE" }, { 0, "DATA" }, { 2, "META" }, { 4, "META_FLUSH" }, { 5, "INMEM" }, { 6, "INMEM_DROP" }, { 7, "INMEM_INVALIDATE" }, { 8, "INMEM_REVOKE" }, { 9, "IN-PLACE" }, { 10, "OUT-OF-PLACE" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_submit_page_write/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_submit_page_write/format
new file mode 100644
index 000000000..614cc711a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_submit_page_write/format
@@ -0,0 +1,19 @@
+name: f2fs_submit_page_write
+ID: 548
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long index; offset:24; size:8; signed:0;
+ field:block_t old_blkaddr; offset:32; size:4; signed:0;
+ field:block_t new_blkaddr; offset:36; size:4; signed:0;
+ field:int op; offset:40; size:4; signed:1;
+ field:int op_flags; offset:44; size:4; signed:1;
+ field:int temp; offset:48; size:4; signed:1;
+ field:int type; offset:52; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, page_index = 0x%lx, oldaddr = 0x%llx, newaddr = 0x%llx, rw = %s(%s), type = %s_%s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, (unsigned long)REC->index, (unsigned long long)REC->old_blkaddr, (unsigned long long)REC->new_blkaddr, blk_op_str(REC->op), __print_flags((REC->op_flags & ((1ULL << 19) | (1ULL << 11) | (1ULL << 12) | (1ULL << 13) | (1ULL << 18) | (1ULL << 17))), "|", { (1ULL << 19), "R" }, { (1ULL << 11), "S" }, { (1ULL << 12), "M" }, { (1ULL << 13), "P" }, { (1ULL << 18), "PF" }, { (1ULL << 17), "FUA" }), __print_symbolic(REC->temp, { 0, "HOT" }, { 1, "WARM" }, { 2, "COLD" }), __print_symbolic(REC->type, { 1, "NODE" }, { 0, "DATA" }, { 2, "META" }, { 4, "META_FLUSH" }, { 5, "INMEM" }, { 6, "INMEM_DROP" }, { 7, "INMEM_INVALIDATE" }, { 8, "INMEM_REVOKE" }, { 9, "IN-PLACE" }, { 10, "OUT-OF-PLACE" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_submit_read_bio/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_submit_read_bio/format
new file mode 100644
index 000000000..bb3950ff3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_submit_read_bio/format
@@ -0,0 +1,17 @@
+name: f2fs_submit_read_bio
+ID: 549
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:dev_t target; offset:12; size:4; signed:0;
+ field:int op; offset:16; size:4; signed:1;
+ field:int op_flags; offset:20; size:4; signed:1;
+ field:int type; offset:24; size:4; signed:1;
+ field:sector_t sector; offset:32; size:8; signed:0;
+ field:unsigned int size; offset:40; size:4; signed:0;
+
+print fmt: "dev = (%d,%d)/(%d,%d), rw = %s(%s), %s, sector = %lld, size = %u", ((unsigned int) ((REC->target) >> 20)), ((unsigned int) ((REC->target) & ((1U << 20) - 1))), ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), blk_op_str(REC->op), __print_flags((REC->op_flags & ((1ULL << 19) | (1ULL << 11) | (1ULL << 12) | (1ULL << 13) | (1ULL << 18) | (1ULL << 17))), "|", { (1ULL << 19), "R" }, { (1ULL << 11), "S" }, { (1ULL << 12), "M" }, { (1ULL << 13), "P" }, { (1ULL << 18), "PF" }, { (1ULL << 17), "FUA" }), __print_symbolic(REC->type, { 1, "NODE" }, { 0, "DATA" }, { 2, "META" }, { 4, "META_FLUSH" }, { 5, "INMEM" }, { 6, "INMEM_DROP" }, { 7, "INMEM_INVALIDATE" }, { 8, "INMEM_REVOKE" }, { 9, "IN-PLACE" }, { 10, "OUT-OF-PLACE" }), (unsigned long long)REC->sector, REC->size
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_submit_write_bio/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_submit_write_bio/format
new file mode 100644
index 000000000..927fa9335
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_submit_write_bio/format
@@ -0,0 +1,17 @@
+name: f2fs_submit_write_bio
+ID: 550
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:dev_t target; offset:12; size:4; signed:0;
+ field:int op; offset:16; size:4; signed:1;
+ field:int op_flags; offset:20; size:4; signed:1;
+ field:int type; offset:24; size:4; signed:1;
+ field:sector_t sector; offset:32; size:8; signed:0;
+ field:unsigned int size; offset:40; size:4; signed:0;
+
+print fmt: "dev = (%d,%d)/(%d,%d), rw = %s(%s), %s, sector = %lld, size = %u", ((unsigned int) ((REC->target) >> 20)), ((unsigned int) ((REC->target) & ((1U << 20) - 1))), ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), blk_op_str(REC->op), __print_flags((REC->op_flags & ((1ULL << 19) | (1ULL << 11) | (1ULL << 12) | (1ULL << 13) | (1ULL << 18) | (1ULL << 17))), "|", { (1ULL << 19), "R" }, { (1ULL << 11), "S" }, { (1ULL << 12), "M" }, { (1ULL << 13), "P" }, { (1ULL << 18), "PF" }, { (1ULL << 17), "FUA" }), __print_symbolic(REC->type, { 1, "NODE" }, { 0, "DATA" }, { 2, "META" }, { 4, "META_FLUSH" }, { 5, "INMEM" }, { 6, "INMEM_DROP" }, { 7, "INMEM_INVALIDATE" }, { 8, "INMEM_REVOKE" }, { 9, "IN-PLACE" }, { 10, "OUT-OF-PLACE" }), (unsigned long long)REC->sector, REC->size
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_sync_dirty_inodes_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_sync_dirty_inodes_enter/format
new file mode 100644
index 000000000..ee2c6c486
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_sync_dirty_inodes_enter/format
@@ -0,0 +1,13 @@
+name: f2fs_sync_dirty_inodes_enter
+ID: 551
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int type; offset:12; size:4; signed:1;
+ field:s64 count; offset:16; size:8; signed:1;
+
+print fmt: "dev = (%d,%d), %s, dirty count = %lld", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), __print_symbolic(REC->type, { 0, "FILE" }, { 1, "DIR" }), REC->count
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_sync_dirty_inodes_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_sync_dirty_inodes_exit/format
new file mode 100644
index 000000000..17e796b97
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_sync_dirty_inodes_exit/format
@@ -0,0 +1,13 @@
+name: f2fs_sync_dirty_inodes_exit
+ID: 552
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int type; offset:12; size:4; signed:1;
+ field:s64 count; offset:16; size:8; signed:1;
+
+print fmt: "dev = (%d,%d), %s, dirty count = %lld", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), __print_symbolic(REC->type, { 0, "FILE" }, { 1, "DIR" }), REC->count
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_sync_file_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_sync_file_enter/format
new file mode 100644
index 000000000..401d69f4c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_sync_file_enter/format
@@ -0,0 +1,18 @@
+name: f2fs_sync_file_enter
+ID: 553
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ino_t pino; offset:24; size:8; signed:0;
+ field:umode_t mode; offset:32; size:2; signed:0;
+ field:loff_t size; offset:40; size:8; signed:1;
+ field:unsigned int nlink; offset:48; size:4; signed:0;
+ field:blkcnt_t blocks; offset:56; size:8; signed:0;
+ field:__u8 advise; offset:64; size:1; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, pino = %lu, i_mode = 0x%hx, i_size = %lld, i_nlink = %u, i_blocks = %llu, i_advise = 0x%x", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, (unsigned long)REC->pino, REC->mode, REC->size, (unsigned int)REC->nlink, (unsigned long long)REC->blocks, (unsigned char)REC->advise
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_sync_file_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_sync_file_exit/format
new file mode 100644
index 000000000..983fb5422
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_sync_file_exit/format
@@ -0,0 +1,15 @@
+name: f2fs_sync_file_exit
+ID: 554
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int cp_reason; offset:24; size:4; signed:1;
+ field:int datasync; offset:28; size:4; signed:1;
+ field:int ret; offset:32; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, cp_reason: %s, datasync = %d, ret = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, __print_symbolic(REC->cp_reason, { CP_NO_NEEDED, "no needed" }, { CP_NON_REGULAR, "non regular" }, { CP_COMPRESSED, "compressed" }, { CP_HARDLINK, "hardlink" }, { CP_SB_NEED_CP, "sb needs cp" }, { CP_WRONG_PINO, "wrong pino" }, { CP_NO_SPC_ROLL, "no space roll forward" }, { CP_NODE_NEED_CP, "node needs cp" }, { CP_FASTBOOT_MODE, "fastboot mode" }, { CP_SPEC_LOG_NUM, "log type is 2" }, { CP_RECOVER_DIR, "dir needs recovery" }), REC->datasync, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_sync_fs/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_sync_fs/format
new file mode 100644
index 000000000..246078ed7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_sync_fs/format
@@ -0,0 +1,13 @@
+name: f2fs_sync_fs
+ID: 555
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int dirty; offset:12; size:4; signed:1;
+ field:int wait; offset:16; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), superblock is %s, wait = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->dirty ? "dirty" : "not dirty", REC->wait
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate/format
new file mode 100644
index 000000000..5ee23735e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate/format
@@ -0,0 +1,18 @@
+name: f2fs_truncate
+ID: 556
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:ino_t pino; offset:24; size:8; signed:0;
+ field:umode_t mode; offset:32; size:2; signed:0;
+ field:loff_t size; offset:40; size:8; signed:1;
+ field:unsigned int nlink; offset:48; size:4; signed:0;
+ field:blkcnt_t blocks; offset:56; size:8; signed:0;
+ field:__u8 advise; offset:64; size:1; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, pino = %lu, i_mode = 0x%hx, i_size = %lld, i_nlink = %u, i_blocks = %llu, i_advise = 0x%x", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, (unsigned long)REC->pino, REC->mode, REC->size, (unsigned int)REC->nlink, (unsigned long long)REC->blocks, (unsigned char)REC->advise
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_blocks_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_blocks_enter/format
new file mode 100644
index 000000000..55ee00d05
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_blocks_enter/format
@@ -0,0 +1,15 @@
+name: f2fs_truncate_blocks_enter
+ID: 557
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t size; offset:24; size:8; signed:1;
+ field:blkcnt_t blocks; offset:32; size:8; signed:0;
+ field:u64 from; offset:40; size:8; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, i_size = %lld, i_blocks = %llu, start file offset = %llu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->size, (unsigned long long)REC->blocks, (unsigned long long)REC->from
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_blocks_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_blocks_exit/format
new file mode 100644
index 000000000..5db0ac5f3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_blocks_exit/format
@@ -0,0 +1,13 @@
+name: f2fs_truncate_blocks_exit
+ID: 558
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int ret; offset:24; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, ret = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_data_blocks_range/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_data_blocks_range/format
new file mode 100644
index 000000000..a4b641811
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_data_blocks_range/format
@@ -0,0 +1,15 @@
+name: f2fs_truncate_data_blocks_range
+ID: 559
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:nid_t nid; offset:24; size:4; signed:0;
+ field:unsigned int ofs; offset:28; size:4; signed:0;
+ field:int free; offset:32; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, nid = %u, offset = %u, freed = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, (unsigned int)REC->nid, REC->ofs, REC->free
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_inode_blocks_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_inode_blocks_enter/format
new file mode 100644
index 000000000..d2199cc30
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_inode_blocks_enter/format
@@ -0,0 +1,15 @@
+name: f2fs_truncate_inode_blocks_enter
+ID: 560
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t size; offset:24; size:8; signed:1;
+ field:blkcnt_t blocks; offset:32; size:8; signed:0;
+ field:u64 from; offset:40; size:8; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, i_size = %lld, i_blocks = %llu, start file offset = %llu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->size, (unsigned long long)REC->blocks, (unsigned long long)REC->from
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_inode_blocks_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_inode_blocks_exit/format
new file mode 100644
index 000000000..4deb9cc28
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_inode_blocks_exit/format
@@ -0,0 +1,13 @@
+name: f2fs_truncate_inode_blocks_exit
+ID: 561
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int ret; offset:24; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, ret = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_node/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_node/format
new file mode 100644
index 000000000..ca0acc74b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_node/format
@@ -0,0 +1,14 @@
+name: f2fs_truncate_node
+ID: 562
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:nid_t nid; offset:24; size:4; signed:0;
+ field:block_t blk_addr; offset:28; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, nid = %u, block_address = 0x%llx", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, (unsigned int)REC->nid, (unsigned long long)REC->blk_addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_nodes_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_nodes_enter/format
new file mode 100644
index 000000000..63e3e4f5b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_nodes_enter/format
@@ -0,0 +1,14 @@
+name: f2fs_truncate_nodes_enter
+ID: 563
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:nid_t nid; offset:24; size:4; signed:0;
+ field:block_t blk_addr; offset:28; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, nid = %u, block_address = 0x%llx", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, (unsigned int)REC->nid, (unsigned long long)REC->blk_addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_nodes_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_nodes_exit/format
new file mode 100644
index 000000000..a9bceaaf3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_nodes_exit/format
@@ -0,0 +1,13 @@
+name: f2fs_truncate_nodes_exit
+ID: 564
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int ret; offset:24; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, ret = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_partial_nodes/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_partial_nodes/format
new file mode 100644
index 000000000..32fd9b80b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_truncate_partial_nodes/format
@@ -0,0 +1,15 @@
+name: f2fs_truncate_partial_nodes
+ID: 565
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:nid_t nid[3]; offset:24; size:4; signed:0;
+ field:int depth; offset:28; size:4; signed:1;
+ field:int err; offset:32; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, nid[0] = %u, nid[1] = %u, nid[2] = %u, depth = %d, err = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, (unsigned int)REC->nid[0], (unsigned int)REC->nid[1], (unsigned int)REC->nid[2], REC->depth, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_unlink_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_unlink_enter/format
new file mode 100644
index 000000000..0aef34170
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_unlink_enter/format
@@ -0,0 +1,15 @@
+name: f2fs_unlink_enter
+ID: 566
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t size; offset:24; size:8; signed:1;
+ field:blkcnt_t blocks; offset:32; size:8; signed:0;
+ field:const char * name; offset:40; size:8; signed:0;
+
+print fmt: "dev = (%d,%d), dir ino = %lu, i_size = %lld, i_blocks = %llu, name = %s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->size, (unsigned long long)REC->blocks, REC->name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_unlink_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_unlink_exit/format
new file mode 100644
index 000000000..b6fc9cf8d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_unlink_exit/format
@@ -0,0 +1,13 @@
+name: f2fs_unlink_exit
+ID: 567
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int ret; offset:24; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, ret = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_update_extent_tree_range/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_update_extent_tree_range/format
new file mode 100644
index 000000000..a7a10c78c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_update_extent_tree_range/format
@@ -0,0 +1,15 @@
+name: f2fs_update_extent_tree_range
+ID: 568
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned int pgofs; offset:24; size:4; signed:0;
+ field:u32 blk; offset:28; size:4; signed:0;
+ field:unsigned int len; offset:32; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, pgofs = %u, blkaddr = %u, len = %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->pgofs, REC->blk, REC->len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_vm_page_mkwrite/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_vm_page_mkwrite/format
new file mode 100644
index 000000000..bf52b45b2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_vm_page_mkwrite/format
@@ -0,0 +1,17 @@
+name: f2fs_vm_page_mkwrite
+ID: 569
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int type; offset:24; size:4; signed:1;
+ field:int dir; offset:28; size:4; signed:1;
+ field:unsigned long index; offset:32; size:8; signed:0;
+ field:int dirty; offset:40; size:4; signed:1;
+ field:int uptodate; offset:44; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, %s, %s, index = %lu, dirty = %d, uptodate = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, __print_symbolic(REC->type, { 1, "NODE" }, { 0, "DATA" }, { 2, "META" }, { 4, "META_FLUSH" }, { 5, "INMEM" }, { 6, "INMEM_DROP" }, { 7, "INMEM_INVALIDATE" }, { 8, "INMEM_REVOKE" }, { 9, "IN-PLACE" }, { 10, "OUT-OF-PLACE" }), __print_symbolic(REC->dir, { 0, "FILE" }, { 1, "DIR" }), (unsigned long)REC->index, REC->dirty, REC->uptodate
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_write_begin/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_write_begin/format
new file mode 100644
index 000000000..fc022a99f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_write_begin/format
@@ -0,0 +1,15 @@
+name: f2fs_write_begin
+ID: 570
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t pos; offset:24; size:8; signed:1;
+ field:unsigned int len; offset:32; size:4; signed:0;
+ field:unsigned int flags; offset:36; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, pos = %llu, len = %u, flags = %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, (unsigned long long)REC->pos, REC->len, REC->flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_write_checkpoint/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_write_checkpoint/format
new file mode 100644
index 000000000..7228a2b60
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_write_checkpoint/format
@@ -0,0 +1,13 @@
+name: f2fs_write_checkpoint
+ID: 571
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int reason; offset:12; size:4; signed:1;
+ field:char * msg; offset:16; size:8; signed:0;
+
+print fmt: "dev = (%d,%d), checkpoint for %s, state = %s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), __print_flags(REC->reason, "|", { 0x00000001, "Umount" }, { 0x00000002, "Fastboot" }, { 0x00000004, "Sync" }, { 0x00000008, "Recovery" }, { 0x00000010, "Discard" }, { 0x00000040, "Pause" }, { 0x00000020, "Trimmed" }, { 0x00000080, "Resize" }), REC->msg
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_write_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_write_end/format
new file mode 100644
index 000000000..986a8b24d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_write_end/format
@@ -0,0 +1,15 @@
+name: f2fs_write_end
+ID: 572
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:loff_t pos; offset:24; size:8; signed:1;
+ field:unsigned int len; offset:32; size:4; signed:0;
+ field:unsigned int copied; offset:36; size:4; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, pos = %llu, len = %u, copied = %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, (unsigned long long)REC->pos, REC->len, REC->copied
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_writepage/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_writepage/format
new file mode 100644
index 000000000..77d784d5e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_writepage/format
@@ -0,0 +1,17 @@
+name: f2fs_writepage
+ID: 573
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int type; offset:24; size:4; signed:1;
+ field:int dir; offset:28; size:4; signed:1;
+ field:unsigned long index; offset:32; size:8; signed:0;
+ field:int dirty; offset:40; size:4; signed:1;
+ field:int uptodate; offset:44; size:4; signed:1;
+
+print fmt: "dev = (%d,%d), ino = %lu, %s, %s, index = %lu, dirty = %d, uptodate = %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, __print_symbolic(REC->type, { 1, "NODE" }, { 0, "DATA" }, { 2, "META" }, { 4, "META_FLUSH" }, { 5, "INMEM" }, { 6, "INMEM_DROP" }, { 7, "INMEM_INVALIDATE" }, { 8, "INMEM_REVOKE" }, { 9, "IN-PLACE" }, { 10, "OUT-OF-PLACE" }), __print_symbolic(REC->dir, { 0, "FILE" }, { 1, "DIR" }), (unsigned long)REC->index, REC->dirty, REC->uptodate
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_writepages/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_writepages/format
new file mode 100644
index 000000000..478ace22d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/f2fs/f2fs_writepages/format
@@ -0,0 +1,26 @@
+name: f2fs_writepages
+ID: 574
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:int type; offset:24; size:4; signed:1;
+ field:int dir; offset:28; size:4; signed:1;
+ field:long nr_to_write; offset:32; size:8; signed:1;
+ field:long pages_skipped; offset:40; size:8; signed:1;
+ field:loff_t range_start; offset:48; size:8; signed:1;
+ field:loff_t range_end; offset:56; size:8; signed:1;
+ field:unsigned long writeback_index; offset:64; size:8; signed:0;
+ field:int sync_mode; offset:72; size:4; signed:1;
+ field:char for_kupdate; offset:76; size:1; signed:0;
+ field:char for_background; offset:77; size:1; signed:0;
+ field:char tagged_writepages; offset:78; size:1; signed:0;
+ field:char for_reclaim; offset:79; size:1; signed:0;
+ field:char range_cyclic; offset:80; size:1; signed:0;
+ field:char for_sync; offset:81; size:1; signed:0;
+
+print fmt: "dev = (%d,%d), ino = %lu, %s, %s, nr_to_write %ld, skipped %ld, start %lld, end %lld, wb_idx %lu, sync_mode %d, kupdate %u background %u tagged %u reclaim %u cyclic %u sync %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, __print_symbolic(REC->type, { 1, "NODE" }, { 0, "DATA" }, { 2, "META" }, { 4, "META_FLUSH" }, { 5, "INMEM" }, { 6, "INMEM_DROP" }, { 7, "INMEM_INVALIDATE" }, { 8, "INMEM_REVOKE" }, { 9, "IN-PLACE" }, { 10, "OUT-OF-PLACE" }), __print_symbolic(REC->dir, { 0, "FILE" }, { 1, "DIR" }), REC->nr_to_write, REC->pages_skipped, REC->range_start, REC->range_end, (unsigned long)REC->writeback_index, REC->sync_mode, REC->for_kupdate, REC->for_background, REC->tagged_writepages, REC->for_reclaim, REC->range_cyclic, REC->for_sync
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/fib/fib_table_lookup/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/fib/fib_table_lookup/format
new file mode 100644
index 000000000..0020328f2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/fib/fib_table_lookup/format
@@ -0,0 +1,25 @@
+name: fib_table_lookup
+ID: 923
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 tb_id; offset:8; size:4; signed:0;
+ field:int err; offset:12; size:4; signed:1;
+ field:int oif; offset:16; size:4; signed:1;
+ field:int iif; offset:20; size:4; signed:1;
+ field:u8 proto; offset:24; size:1; signed:0;
+ field:__u8 tos; offset:25; size:1; signed:0;
+ field:__u8 scope; offset:26; size:1; signed:0;
+ field:__u8 flags; offset:27; size:1; signed:0;
+ field:__u8 src[4]; offset:28; size:4; signed:0;
+ field:__u8 dst[4]; offset:32; size:4; signed:0;
+ field:__u8 gw4[4]; offset:36; size:4; signed:0;
+ field:__u8 gw6[16]; offset:40; size:16; signed:0;
+ field:u16 sport; offset:56; size:2; signed:0;
+ field:u16 dport; offset:58; size:2; signed:0;
+ field:__data_loc char[] name; offset:60; size:4; signed:0;
+
+print fmt: "table %u oif %d iif %d proto %u %pI4/%u -> %pI4/%u tos %d scope %d flags %x ==> dev %s gw %pI4/%pI6c err %d", REC->tb_id, REC->oif, REC->iif, REC->proto, REC->src, REC->sport, REC->dst, REC->dport, REC->tos, REC->scope, REC->flags, __get_str(name), REC->gw4, REC->gw6, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/fib6/fib6_table_lookup/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/fib6/fib6_table_lookup/format
new file mode 100644
index 000000000..cbfbb86bd
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/fib6/fib6_table_lookup/format
@@ -0,0 +1,25 @@
+name: fib6_table_lookup
+ID: 972
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 tb_id; offset:8; size:4; signed:0;
+ field:int err; offset:12; size:4; signed:1;
+ field:int oif; offset:16; size:4; signed:1;
+ field:int iif; offset:20; size:4; signed:1;
+ field:__u8 tos; offset:24; size:1; signed:0;
+ field:__u8 scope; offset:25; size:1; signed:0;
+ field:__u8 flags; offset:26; size:1; signed:0;
+ field:__u8 src[16]; offset:27; size:16; signed:0;
+ field:__u8 dst[16]; offset:43; size:16; signed:0;
+ field:u16 sport; offset:60; size:2; signed:0;
+ field:u16 dport; offset:62; size:2; signed:0;
+ field:u8 proto; offset:64; size:1; signed:0;
+ field:u8 rt_type; offset:65; size:1; signed:0;
+ field:__data_loc char[] name; offset:68; size:4; signed:0;
+ field:__u8 gw[16]; offset:72; size:16; signed:0;
+
+print fmt: "table %3u oif %d iif %d proto %u %pI6c/%u -> %pI6c/%u tos %d scope %d flags %x ==> dev %s gw %pI6c err %d", REC->tb_id, REC->oif, REC->iif, REC->proto, REC->src, REC->sport, REC->dst, REC->dport, REC->tos, REC->scope, REC->flags, __get_str(name), REC->gw, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/break_lease_block/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/break_lease_block/format
new file mode 100644
index 000000000..07abfdbcf
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/break_lease_block/format
@@ -0,0 +1,19 @@
+name: break_lease_block
+ID: 348
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct file_lock * fl; offset:8; size:8; signed:0;
+ field:unsigned long i_ino; offset:16; size:8; signed:0;
+ field:dev_t s_dev; offset:24; size:4; signed:0;
+ field:struct file_lock * fl_blocker; offset:32; size:8; signed:0;
+ field:fl_owner_t fl_owner; offset:40; size:8; signed:0;
+ field:unsigned int fl_flags; offset:48; size:4; signed:0;
+ field:unsigned char fl_type; offset:52; size:1; signed:0;
+ field:unsigned long fl_break_time; offset:56; size:8; signed:0;
+ field:unsigned long fl_downgrade_time; offset:64; size:8; signed:0;
+
+print fmt: "fl=%p dev=0x%x:0x%x ino=0x%lx fl_blocker=%p fl_owner=%p fl_flags=%s fl_type=%s fl_break_time=%lu fl_downgrade_time=%lu", REC->fl, ((unsigned int) ((REC->s_dev) >> 20)), ((unsigned int) ((REC->s_dev) & ((1U << 20) - 1))), REC->i_ino, REC->fl_blocker, REC->fl_owner, __print_flags(REC->fl_flags, "|", { 1, "FL_POSIX" }, { 2, "FL_FLOCK" }, { 4, "FL_DELEG" }, { 8, "FL_ACCESS" }, { 16, "FL_EXISTS" }, { 32, "FL_LEASE" }, { 64, "FL_CLOSE" }, { 128, "FL_SLEEP" }, { 256, "FL_DOWNGRADE_PENDING" }, { 512, "FL_UNLOCK_PENDING" }, { 1024, "FL_OFDLCK" }), __print_symbolic(REC->fl_type, { 0, "F_RDLCK" }, { 1, "F_WRLCK" }, { 2, "F_UNLCK" }), REC->fl_break_time, REC->fl_downgrade_time
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/break_lease_noblock/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/break_lease_noblock/format
new file mode 100644
index 000000000..aa7b4c836
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/break_lease_noblock/format
@@ -0,0 +1,19 @@
+name: break_lease_noblock
+ID: 349
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct file_lock * fl; offset:8; size:8; signed:0;
+ field:unsigned long i_ino; offset:16; size:8; signed:0;
+ field:dev_t s_dev; offset:24; size:4; signed:0;
+ field:struct file_lock * fl_blocker; offset:32; size:8; signed:0;
+ field:fl_owner_t fl_owner; offset:40; size:8; signed:0;
+ field:unsigned int fl_flags; offset:48; size:4; signed:0;
+ field:unsigned char fl_type; offset:52; size:1; signed:0;
+ field:unsigned long fl_break_time; offset:56; size:8; signed:0;
+ field:unsigned long fl_downgrade_time; offset:64; size:8; signed:0;
+
+print fmt: "fl=%p dev=0x%x:0x%x ino=0x%lx fl_blocker=%p fl_owner=%p fl_flags=%s fl_type=%s fl_break_time=%lu fl_downgrade_time=%lu", REC->fl, ((unsigned int) ((REC->s_dev) >> 20)), ((unsigned int) ((REC->s_dev) & ((1U << 20) - 1))), REC->i_ino, REC->fl_blocker, REC->fl_owner, __print_flags(REC->fl_flags, "|", { 1, "FL_POSIX" }, { 2, "FL_FLOCK" }, { 4, "FL_DELEG" }, { 8, "FL_ACCESS" }, { 16, "FL_EXISTS" }, { 32, "FL_LEASE" }, { 64, "FL_CLOSE" }, { 128, "FL_SLEEP" }, { 256, "FL_DOWNGRADE_PENDING" }, { 512, "FL_UNLOCK_PENDING" }, { 1024, "FL_OFDLCK" }), __print_symbolic(REC->fl_type, { 0, "F_RDLCK" }, { 1, "F_WRLCK" }, { 2, "F_UNLCK" }), REC->fl_break_time, REC->fl_downgrade_time
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/break_lease_unblock/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/break_lease_unblock/format
new file mode 100644
index 000000000..7548c1b5a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/break_lease_unblock/format
@@ -0,0 +1,19 @@
+name: break_lease_unblock
+ID: 350
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct file_lock * fl; offset:8; size:8; signed:0;
+ field:unsigned long i_ino; offset:16; size:8; signed:0;
+ field:dev_t s_dev; offset:24; size:4; signed:0;
+ field:struct file_lock * fl_blocker; offset:32; size:8; signed:0;
+ field:fl_owner_t fl_owner; offset:40; size:8; signed:0;
+ field:unsigned int fl_flags; offset:48; size:4; signed:0;
+ field:unsigned char fl_type; offset:52; size:1; signed:0;
+ field:unsigned long fl_break_time; offset:56; size:8; signed:0;
+ field:unsigned long fl_downgrade_time; offset:64; size:8; signed:0;
+
+print fmt: "fl=%p dev=0x%x:0x%x ino=0x%lx fl_blocker=%p fl_owner=%p fl_flags=%s fl_type=%s fl_break_time=%lu fl_downgrade_time=%lu", REC->fl, ((unsigned int) ((REC->s_dev) >> 20)), ((unsigned int) ((REC->s_dev) & ((1U << 20) - 1))), REC->i_ino, REC->fl_blocker, REC->fl_owner, __print_flags(REC->fl_flags, "|", { 1, "FL_POSIX" }, { 2, "FL_FLOCK" }, { 4, "FL_DELEG" }, { 8, "FL_ACCESS" }, { 16, "FL_EXISTS" }, { 32, "FL_LEASE" }, { 64, "FL_CLOSE" }, { 128, "FL_SLEEP" }, { 256, "FL_DOWNGRADE_PENDING" }, { 512, "FL_UNLOCK_PENDING" }, { 1024, "FL_OFDLCK" }), __print_symbolic(REC->fl_type, { 0, "F_RDLCK" }, { 1, "F_WRLCK" }, { 2, "F_UNLCK" }), REC->fl_break_time, REC->fl_downgrade_time
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/fcntl_setlk/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/fcntl_setlk/format
new file mode 100644
index 000000000..21e34d0c1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/fcntl_setlk/format
@@ -0,0 +1,21 @@
+name: fcntl_setlk
+ID: 351
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct file_lock * fl; offset:8; size:8; signed:0;
+ field:unsigned long i_ino; offset:16; size:8; signed:0;
+ field:dev_t s_dev; offset:24; size:4; signed:0;
+ field:struct file_lock * fl_blocker; offset:32; size:8; signed:0;
+ field:fl_owner_t fl_owner; offset:40; size:8; signed:0;
+ field:unsigned int fl_pid; offset:48; size:4; signed:0;
+ field:unsigned int fl_flags; offset:52; size:4; signed:0;
+ field:unsigned char fl_type; offset:56; size:1; signed:0;
+ field:loff_t fl_start; offset:64; size:8; signed:1;
+ field:loff_t fl_end; offset:72; size:8; signed:1;
+ field:int ret; offset:80; size:4; signed:1;
+
+print fmt: "fl=%p dev=0x%x:0x%x ino=0x%lx fl_blocker=%p fl_owner=%p fl_pid=%u fl_flags=%s fl_type=%s fl_start=%lld fl_end=%lld ret=%d", REC->fl, ((unsigned int) ((REC->s_dev) >> 20)), ((unsigned int) ((REC->s_dev) & ((1U << 20) - 1))), REC->i_ino, REC->fl_blocker, REC->fl_owner, REC->fl_pid, __print_flags(REC->fl_flags, "|", { 1, "FL_POSIX" }, { 2, "FL_FLOCK" }, { 4, "FL_DELEG" }, { 8, "FL_ACCESS" }, { 16, "FL_EXISTS" }, { 32, "FL_LEASE" }, { 64, "FL_CLOSE" }, { 128, "FL_SLEEP" }, { 256, "FL_DOWNGRADE_PENDING" }, { 512, "FL_UNLOCK_PENDING" }, { 1024, "FL_OFDLCK" }), __print_symbolic(REC->fl_type, { 0, "F_RDLCK" }, { 1, "F_WRLCK" }, { 2, "F_UNLCK" }), REC->fl_start, REC->fl_end, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/flock_lock_inode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/flock_lock_inode/format
new file mode 100644
index 000000000..7b20c1788
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/flock_lock_inode/format
@@ -0,0 +1,21 @@
+name: flock_lock_inode
+ID: 352
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct file_lock * fl; offset:8; size:8; signed:0;
+ field:unsigned long i_ino; offset:16; size:8; signed:0;
+ field:dev_t s_dev; offset:24; size:4; signed:0;
+ field:struct file_lock * fl_blocker; offset:32; size:8; signed:0;
+ field:fl_owner_t fl_owner; offset:40; size:8; signed:0;
+ field:unsigned int fl_pid; offset:48; size:4; signed:0;
+ field:unsigned int fl_flags; offset:52; size:4; signed:0;
+ field:unsigned char fl_type; offset:56; size:1; signed:0;
+ field:loff_t fl_start; offset:64; size:8; signed:1;
+ field:loff_t fl_end; offset:72; size:8; signed:1;
+ field:int ret; offset:80; size:4; signed:1;
+
+print fmt: "fl=%p dev=0x%x:0x%x ino=0x%lx fl_blocker=%p fl_owner=%p fl_pid=%u fl_flags=%s fl_type=%s fl_start=%lld fl_end=%lld ret=%d", REC->fl, ((unsigned int) ((REC->s_dev) >> 20)), ((unsigned int) ((REC->s_dev) & ((1U << 20) - 1))), REC->i_ino, REC->fl_blocker, REC->fl_owner, REC->fl_pid, __print_flags(REC->fl_flags, "|", { 1, "FL_POSIX" }, { 2, "FL_FLOCK" }, { 4, "FL_DELEG" }, { 8, "FL_ACCESS" }, { 16, "FL_EXISTS" }, { 32, "FL_LEASE" }, { 64, "FL_CLOSE" }, { 128, "FL_SLEEP" }, { 256, "FL_DOWNGRADE_PENDING" }, { 512, "FL_UNLOCK_PENDING" }, { 1024, "FL_OFDLCK" }), __print_symbolic(REC->fl_type, { 0, "F_RDLCK" }, { 1, "F_WRLCK" }, { 2, "F_UNLCK" }), REC->fl_start, REC->fl_end, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/generic_add_lease/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/generic_add_lease/format
new file mode 100644
index 000000000..10db2ba01
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/generic_add_lease/format
@@ -0,0 +1,18 @@
+name: generic_add_lease
+ID: 353
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long i_ino; offset:8; size:8; signed:0;
+ field:int wcount; offset:16; size:4; signed:1;
+ field:int rcount; offset:20; size:4; signed:1;
+ field:int icount; offset:24; size:4; signed:1;
+ field:dev_t s_dev; offset:28; size:4; signed:0;
+ field:fl_owner_t fl_owner; offset:32; size:8; signed:0;
+ field:unsigned int fl_flags; offset:40; size:4; signed:0;
+ field:unsigned char fl_type; offset:44; size:1; signed:0;
+
+print fmt: "dev=0x%x:0x%x ino=0x%lx wcount=%d rcount=%d icount=%d fl_owner=%p fl_flags=%s fl_type=%s", ((unsigned int) ((REC->s_dev) >> 20)), ((unsigned int) ((REC->s_dev) & ((1U << 20) - 1))), REC->i_ino, REC->wcount, REC->rcount, REC->icount, REC->fl_owner, __print_flags(REC->fl_flags, "|", { 1, "FL_POSIX" }, { 2, "FL_FLOCK" }, { 4, "FL_DELEG" }, { 8, "FL_ACCESS" }, { 16, "FL_EXISTS" }, { 32, "FL_LEASE" }, { 64, "FL_CLOSE" }, { 128, "FL_SLEEP" }, { 256, "FL_DOWNGRADE_PENDING" }, { 512, "FL_UNLOCK_PENDING" }, { 1024, "FL_OFDLCK" }), __print_symbolic(REC->fl_type, { 0, "F_RDLCK" }, { 1, "F_WRLCK" }, { 2, "F_UNLCK" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/generic_delete_lease/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/generic_delete_lease/format
new file mode 100644
index 000000000..9561b0a1e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/generic_delete_lease/format
@@ -0,0 +1,19 @@
+name: generic_delete_lease
+ID: 354
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct file_lock * fl; offset:8; size:8; signed:0;
+ field:unsigned long i_ino; offset:16; size:8; signed:0;
+ field:dev_t s_dev; offset:24; size:4; signed:0;
+ field:struct file_lock * fl_blocker; offset:32; size:8; signed:0;
+ field:fl_owner_t fl_owner; offset:40; size:8; signed:0;
+ field:unsigned int fl_flags; offset:48; size:4; signed:0;
+ field:unsigned char fl_type; offset:52; size:1; signed:0;
+ field:unsigned long fl_break_time; offset:56; size:8; signed:0;
+ field:unsigned long fl_downgrade_time; offset:64; size:8; signed:0;
+
+print fmt: "fl=%p dev=0x%x:0x%x ino=0x%lx fl_blocker=%p fl_owner=%p fl_flags=%s fl_type=%s fl_break_time=%lu fl_downgrade_time=%lu", REC->fl, ((unsigned int) ((REC->s_dev) >> 20)), ((unsigned int) ((REC->s_dev) & ((1U << 20) - 1))), REC->i_ino, REC->fl_blocker, REC->fl_owner, __print_flags(REC->fl_flags, "|", { 1, "FL_POSIX" }, { 2, "FL_FLOCK" }, { 4, "FL_DELEG" }, { 8, "FL_ACCESS" }, { 16, "FL_EXISTS" }, { 32, "FL_LEASE" }, { 64, "FL_CLOSE" }, { 128, "FL_SLEEP" }, { 256, "FL_DOWNGRADE_PENDING" }, { 512, "FL_UNLOCK_PENDING" }, { 1024, "FL_OFDLCK" }), __print_symbolic(REC->fl_type, { 0, "F_RDLCK" }, { 1, "F_WRLCK" }, { 2, "F_UNLCK" }), REC->fl_break_time, REC->fl_downgrade_time
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/leases_conflict/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/leases_conflict/format
new file mode 100644
index 000000000..c0ff5b22b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/leases_conflict/format
@@ -0,0 +1,17 @@
+name: leases_conflict
+ID: 355
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * lease; offset:8; size:8; signed:0;
+ field:void * breaker; offset:16; size:8; signed:0;
+ field:unsigned int l_fl_flags; offset:24; size:4; signed:0;
+ field:unsigned int b_fl_flags; offset:28; size:4; signed:0;
+ field:unsigned char l_fl_type; offset:32; size:1; signed:0;
+ field:unsigned char b_fl_type; offset:33; size:1; signed:0;
+ field:bool conflict; offset:34; size:1; signed:0;
+
+print fmt: "conflict %d: lease=%p fl_flags=%s fl_type=%s; breaker=%p fl_flags=%s fl_type=%s", REC->conflict, REC->lease, __print_flags(REC->l_fl_flags, "|", { 1, "FL_POSIX" }, { 2, "FL_FLOCK" }, { 4, "FL_DELEG" }, { 8, "FL_ACCESS" }, { 16, "FL_EXISTS" }, { 32, "FL_LEASE" }, { 64, "FL_CLOSE" }, { 128, "FL_SLEEP" }, { 256, "FL_DOWNGRADE_PENDING" }, { 512, "FL_UNLOCK_PENDING" }, { 1024, "FL_OFDLCK" }), __print_symbolic(REC->l_fl_type, { 0, "F_RDLCK" }, { 1, "F_WRLCK" }, { 2, "F_UNLCK" }), REC->breaker, __print_flags(REC->b_fl_flags, "|", { 1, "FL_POSIX" }, { 2, "FL_FLOCK" }, { 4, "FL_DELEG" }, { 8, "FL_ACCESS" }, { 16, "FL_EXISTS" }, { 32, "FL_LEASE" }, { 64, "FL_CLOSE" }, { 128, "FL_SLEEP" }, { 256, "FL_DOWNGRADE_PENDING" }, { 512, "FL_UNLOCK_PENDING" }, { 1024, "FL_OFDLCK" }), __print_symbolic(REC->b_fl_type, { 0, "F_RDLCK" }, { 1, "F_WRLCK" }, { 2, "F_UNLCK" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/locks_get_lock_context/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/locks_get_lock_context/format
new file mode 100644
index 000000000..b363abd30
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/locks_get_lock_context/format
@@ -0,0 +1,14 @@
+name: locks_get_lock_context
+ID: 356
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long i_ino; offset:8; size:8; signed:0;
+ field:dev_t s_dev; offset:16; size:4; signed:0;
+ field:unsigned char type; offset:20; size:1; signed:0;
+ field:struct file_lock_context * ctx; offset:24; size:8; signed:0;
+
+print fmt: "dev=0x%x:0x%x ino=0x%lx type=%s ctx=%p", ((unsigned int) ((REC->s_dev) >> 20)), ((unsigned int) ((REC->s_dev) & ((1U << 20) - 1))), REC->i_ino, __print_symbolic(REC->type, { 0, "F_RDLCK" }, { 1, "F_WRLCK" }, { 2, "F_UNLCK" }), REC->ctx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/locks_remove_posix/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/locks_remove_posix/format
new file mode 100644
index 000000000..6ae468410
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/locks_remove_posix/format
@@ -0,0 +1,21 @@
+name: locks_remove_posix
+ID: 357
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct file_lock * fl; offset:8; size:8; signed:0;
+ field:unsigned long i_ino; offset:16; size:8; signed:0;
+ field:dev_t s_dev; offset:24; size:4; signed:0;
+ field:struct file_lock * fl_blocker; offset:32; size:8; signed:0;
+ field:fl_owner_t fl_owner; offset:40; size:8; signed:0;
+ field:unsigned int fl_pid; offset:48; size:4; signed:0;
+ field:unsigned int fl_flags; offset:52; size:4; signed:0;
+ field:unsigned char fl_type; offset:56; size:1; signed:0;
+ field:loff_t fl_start; offset:64; size:8; signed:1;
+ field:loff_t fl_end; offset:72; size:8; signed:1;
+ field:int ret; offset:80; size:4; signed:1;
+
+print fmt: "fl=%p dev=0x%x:0x%x ino=0x%lx fl_blocker=%p fl_owner=%p fl_pid=%u fl_flags=%s fl_type=%s fl_start=%lld fl_end=%lld ret=%d", REC->fl, ((unsigned int) ((REC->s_dev) >> 20)), ((unsigned int) ((REC->s_dev) & ((1U << 20) - 1))), REC->i_ino, REC->fl_blocker, REC->fl_owner, REC->fl_pid, __print_flags(REC->fl_flags, "|", { 1, "FL_POSIX" }, { 2, "FL_FLOCK" }, { 4, "FL_DELEG" }, { 8, "FL_ACCESS" }, { 16, "FL_EXISTS" }, { 32, "FL_LEASE" }, { 64, "FL_CLOSE" }, { 128, "FL_SLEEP" }, { 256, "FL_DOWNGRADE_PENDING" }, { 512, "FL_UNLOCK_PENDING" }, { 1024, "FL_OFDLCK" }), __print_symbolic(REC->fl_type, { 0, "F_RDLCK" }, { 1, "F_WRLCK" }, { 2, "F_UNLCK" }), REC->fl_start, REC->fl_end, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/posix_lock_inode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/posix_lock_inode/format
new file mode 100644
index 000000000..54e951f5b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/posix_lock_inode/format
@@ -0,0 +1,21 @@
+name: posix_lock_inode
+ID: 358
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct file_lock * fl; offset:8; size:8; signed:0;
+ field:unsigned long i_ino; offset:16; size:8; signed:0;
+ field:dev_t s_dev; offset:24; size:4; signed:0;
+ field:struct file_lock * fl_blocker; offset:32; size:8; signed:0;
+ field:fl_owner_t fl_owner; offset:40; size:8; signed:0;
+ field:unsigned int fl_pid; offset:48; size:4; signed:0;
+ field:unsigned int fl_flags; offset:52; size:4; signed:0;
+ field:unsigned char fl_type; offset:56; size:1; signed:0;
+ field:loff_t fl_start; offset:64; size:8; signed:1;
+ field:loff_t fl_end; offset:72; size:8; signed:1;
+ field:int ret; offset:80; size:4; signed:1;
+
+print fmt: "fl=%p dev=0x%x:0x%x ino=0x%lx fl_blocker=%p fl_owner=%p fl_pid=%u fl_flags=%s fl_type=%s fl_start=%lld fl_end=%lld ret=%d", REC->fl, ((unsigned int) ((REC->s_dev) >> 20)), ((unsigned int) ((REC->s_dev) & ((1U << 20) - 1))), REC->i_ino, REC->fl_blocker, REC->fl_owner, REC->fl_pid, __print_flags(REC->fl_flags, "|", { 1, "FL_POSIX" }, { 2, "FL_FLOCK" }, { 4, "FL_DELEG" }, { 8, "FL_ACCESS" }, { 16, "FL_EXISTS" }, { 32, "FL_LEASE" }, { 64, "FL_CLOSE" }, { 128, "FL_SLEEP" }, { 256, "FL_DOWNGRADE_PENDING" }, { 512, "FL_UNLOCK_PENDING" }, { 1024, "FL_OFDLCK" }), __print_symbolic(REC->fl_type, { 0, "F_RDLCK" }, { 1, "F_WRLCK" }, { 2, "F_UNLCK" }), REC->fl_start, REC->fl_end, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/time_out_leases/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/time_out_leases/format
new file mode 100644
index 000000000..52cde3b0d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filelock/time_out_leases/format
@@ -0,0 +1,19 @@
+name: time_out_leases
+ID: 359
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct file_lock * fl; offset:8; size:8; signed:0;
+ field:unsigned long i_ino; offset:16; size:8; signed:0;
+ field:dev_t s_dev; offset:24; size:4; signed:0;
+ field:struct file_lock * fl_blocker; offset:32; size:8; signed:0;
+ field:fl_owner_t fl_owner; offset:40; size:8; signed:0;
+ field:unsigned int fl_flags; offset:48; size:4; signed:0;
+ field:unsigned char fl_type; offset:52; size:1; signed:0;
+ field:unsigned long fl_break_time; offset:56; size:8; signed:0;
+ field:unsigned long fl_downgrade_time; offset:64; size:8; signed:0;
+
+print fmt: "fl=%p dev=0x%x:0x%x ino=0x%lx fl_blocker=%p fl_owner=%p fl_flags=%s fl_type=%s fl_break_time=%lu fl_downgrade_time=%lu", REC->fl, ((unsigned int) ((REC->s_dev) >> 20)), ((unsigned int) ((REC->s_dev) & ((1U << 20) - 1))), REC->i_ino, REC->fl_blocker, REC->fl_owner, __print_flags(REC->fl_flags, "|", { 1, "FL_POSIX" }, { 2, "FL_FLOCK" }, { 4, "FL_DELEG" }, { 8, "FL_ACCESS" }, { 16, "FL_EXISTS" }, { 32, "FL_LEASE" }, { 64, "FL_CLOSE" }, { 128, "FL_SLEEP" }, { 256, "FL_DOWNGRADE_PENDING" }, { 512, "FL_UNLOCK_PENDING" }, { 1024, "FL_OFDLCK" }), __print_symbolic(REC->fl_type, { 0, "F_RDLCK" }, { 1, "F_WRLCK" }, { 2, "F_UNLCK" }), REC->fl_break_time, REC->fl_downgrade_time
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filemap/file_check_and_advance_wb_err/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filemap/file_check_and_advance_wb_err/format
new file mode 100644
index 000000000..88ffe4a49
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filemap/file_check_and_advance_wb_err/format
@@ -0,0 +1,15 @@
+name: file_check_and_advance_wb_err
+ID: 212
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct file * file; offset:8; size:8; signed:0;
+ field:unsigned long i_ino; offset:16; size:8; signed:0;
+ field:dev_t s_dev; offset:24; size:4; signed:0;
+ field:errseq_t old; offset:28; size:4; signed:0;
+ field:errseq_t new; offset:32; size:4; signed:0;
+
+print fmt: "file=%p dev=%d:%d ino=0x%lx old=0x%x new=0x%x", REC->file, ((unsigned int) ((REC->s_dev) >> 20)), ((unsigned int) ((REC->s_dev) & ((1U << 20) - 1))), REC->i_ino, REC->old, REC->new
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filemap/filemap_set_wb_err/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filemap/filemap_set_wb_err/format
new file mode 100644
index 000000000..3eae78cb7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filemap/filemap_set_wb_err/format
@@ -0,0 +1,13 @@
+name: filemap_set_wb_err
+ID: 213
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long i_ino; offset:8; size:8; signed:0;
+ field:dev_t s_dev; offset:16; size:4; signed:0;
+ field:errseq_t errseq; offset:20; size:4; signed:0;
+
+print fmt: "dev=%d:%d ino=0x%lx errseq=0x%x", ((unsigned int) ((REC->s_dev) >> 20)), ((unsigned int) ((REC->s_dev) & ((1U << 20) - 1))), REC->i_ino, REC->errseq
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filemap/mm_filemap_add_to_page_cache/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filemap/mm_filemap_add_to_page_cache/format
new file mode 100644
index 000000000..ef7a5952b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filemap/mm_filemap_add_to_page_cache/format
@@ -0,0 +1,14 @@
+name: mm_filemap_add_to_page_cache
+ID: 214
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long pfn; offset:8; size:8; signed:0;
+ field:unsigned long i_ino; offset:16; size:8; signed:0;
+ field:unsigned long index; offset:24; size:8; signed:0;
+ field:dev_t s_dev; offset:32; size:4; signed:0;
+
+print fmt: "dev %d:%d ino %lx page=%p pfn=%lu ofs=%lu", ((unsigned int) ((REC->s_dev) >> 20)), ((unsigned int) ((REC->s_dev) & ((1U << 20) - 1))), REC->i_ino, (((struct page *)(-(((-((((1UL))) << ((((39))) - 1))) - ((-((((1UL))) << ((39)))))) >> (12 - (( __builtin_constant_p(sizeof(struct page)) ? ( ((sizeof(struct page)) == 0 || (sizeof(struct page)) == 1) ? 0 : ( __builtin_constant_p((sizeof(struct page)) - 1) ? ( __builtin_constant_p((sizeof(struct page)) - 1) ? ( ((sizeof(struct page)) - 1) < 2 ? 0 : ((sizeof(struct page)) - 1) & (1ULL << 63) ? 63 : ((sizeof(struct page)) - 1) & (1ULL << 62) ? 62 : ((sizeof(struct page)) - 1) & (1ULL << 61) ? 61 : ((sizeof(struct page)) - 1) & (1ULL << 60) ? 60 : ((sizeof(struct page)) - 1) & (1ULL << 59) ? 59 : ((sizeof(struct page)) - 1) & (1ULL << 58) ? 58 : ((sizeof(struct page)) - 1) & (1ULL << 57) ? 57 : ((sizeof(struct page)) - 1) & (1ULL << 56) ? 56 : ((sizeof(struct page)) - 1) & (1ULL << 55) ? 55 : ((sizeof(struct page)) - 1) & (1ULL << 54) ? 54 : ((sizeof(struct page)) - 1) & (1ULL << 53) ? 53 : ((sizeof(struct page)) - 1) & (1ULL << 52) ? 52 : ((sizeof(struct page)) - 1) & (1ULL << 51) ? 51 : ((sizeof(struct page)) - 1) & (1ULL << 50) ? 50 : ((sizeof(struct page)) - 1) & (1ULL << 49) ? 49 : ((sizeof(struct page)) - 1) & (1ULL << 48) ? 48 : ((sizeof(struct page)) - 1) & (1ULL << 47) ? 47 : ((sizeof(struct page)) - 1) & (1ULL << 46) ? 46 : ((sizeof(struct page)) - 1) & (1ULL << 45) ? 45 : ((sizeof(struct page)) - 1) & (1ULL << 44) ? 44 : ((sizeof(struct page)) - 1) & (1ULL << 43) ? 43 : ((sizeof(struct page)) - 1) & (1ULL << 42) ? 42 : ((sizeof(struct page)) - 1) & (1ULL << 41) ? 41 : ((sizeof(struct page)) - 1) & (1ULL << 40) ? 40 : ((sizeof(struct page)) - 1) & (1ULL << 39) ? 39 : ((sizeof(struct page)) - 1) & (1ULL << 38) ? 38 : ((sizeof(struct page)) - 1) & (1ULL << 37) ? 37 : ((sizeof(struct page)) - 1) & (1ULL << 36) ? 36 : ((sizeof(struct page)) - 1) & (1ULL << 35) ? 35 : ((sizeof(struct page)) - 1) & (1ULL << 34) ? 34 : ((sizeof(struct page)) - 1) & (1ULL << 33) ? 33 : ((sizeof(struct page)) - 1) & (1ULL << 32) ? 32 : ((sizeof(struct page)) - 1) & (1ULL << 31) ? 31 : ((sizeof(struct page)) - 1) & (1ULL << 30) ? 30 : ((sizeof(struct page)) - 1) & (1ULL << 29) ? 29 : ((sizeof(struct page)) - 1) & (1ULL << 28) ? 28 : ((sizeof(struct page)) - 1) & (1ULL << 27) ? 27 : ((sizeof(struct page)) - 1) & (1ULL << 26) ? 26 : ((sizeof(struct page)) - 1) & (1ULL << 25) ? 25 : ((sizeof(struct page)) - 1) & (1ULL << 24) ? 24 : ((sizeof(struct page)) - 1) & (1ULL << 23) ? 23 : ((sizeof(struct page)) - 1) & (1ULL << 22) ? 22 : ((sizeof(struct page)) - 1) & (1ULL << 21) ? 21 : ((sizeof(struct page)) - 1) & (1ULL << 20) ? 20 : ((sizeof(struct page)) - 1) & (1ULL << 19) ? 19 : ((sizeof(struct page)) - 1) & (1ULL << 18) ? 18 : ((sizeof(struct page)) - 1) & (1ULL << 17) ? 17 : ((sizeof(struct page)) - 1) & (1ULL << 16) ? 16 : ((sizeof(struct page)) - 1) & (1ULL << 15) ? 15 : ((sizeof(struct page)) - 1) & (1ULL << 14) ? 14 : ((sizeof(struct page)) - 1) & (1ULL << 13) ? 13 : ((sizeof(struct page)) - 1) & (1ULL << 12) ? 12 : ((sizeof(struct page)) - 1) & (1ULL << 11) ? 11 : ((sizeof(struct page)) - 1) & (1ULL << 10) ? 10 : ((sizeof(struct page)) - 1) & (1ULL << 9) ? 9 : ((sizeof(struct page)) - 1) & (1ULL << 8) ? 8 : ((sizeof(struct page)) - 1) & (1ULL << 7) ? 7 : ((sizeof(struct page)) - 1) & (1ULL << 6) ? 6 : ((sizeof(struct page)) - 1) & (1ULL << 5) ? 5 : ((sizeof(struct page)) - 1) & (1ULL << 4) ? 4 : ((sizeof(struct page)) - 1) & (1ULL << 3) ? 3 : ((sizeof(struct page)) - 1) & (1ULL << 2) ? 2 : 1) : -1) : (sizeof((sizeof(struct page)) - 1) <= 4) ? __ilog2_u32((sizeof(struct page)) - 1) : __ilog2_u64((sizeof(struct page)) - 1) ) + 1) : __order_base_2(sizeof(struct page)) )))) - 0x00200000) - (memstart_addr >> 12)) + (REC->pfn)), REC->pfn, REC->index << 12
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filemap/mm_filemap_delete_from_page_cache/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filemap/mm_filemap_delete_from_page_cache/format
new file mode 100644
index 000000000..f7d138344
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/filemap/mm_filemap_delete_from_page_cache/format
@@ -0,0 +1,14 @@
+name: mm_filemap_delete_from_page_cache
+ID: 215
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long pfn; offset:8; size:8; signed:0;
+ field:unsigned long i_ino; offset:16; size:8; signed:0;
+ field:unsigned long index; offset:24; size:8; signed:0;
+ field:dev_t s_dev; offset:32; size:4; signed:0;
+
+print fmt: "dev %d:%d ino %lx page=%p pfn=%lu ofs=%lu", ((unsigned int) ((REC->s_dev) >> 20)), ((unsigned int) ((REC->s_dev) & ((1U << 20) - 1))), REC->i_ino, (((struct page *)(-(((-((((1UL))) << ((((39))) - 1))) - ((-((((1UL))) << ((39)))))) >> (12 - (( __builtin_constant_p(sizeof(struct page)) ? ( ((sizeof(struct page)) == 0 || (sizeof(struct page)) == 1) ? 0 : ( __builtin_constant_p((sizeof(struct page)) - 1) ? ( __builtin_constant_p((sizeof(struct page)) - 1) ? ( ((sizeof(struct page)) - 1) < 2 ? 0 : ((sizeof(struct page)) - 1) & (1ULL << 63) ? 63 : ((sizeof(struct page)) - 1) & (1ULL << 62) ? 62 : ((sizeof(struct page)) - 1) & (1ULL << 61) ? 61 : ((sizeof(struct page)) - 1) & (1ULL << 60) ? 60 : ((sizeof(struct page)) - 1) & (1ULL << 59) ? 59 : ((sizeof(struct page)) - 1) & (1ULL << 58) ? 58 : ((sizeof(struct page)) - 1) & (1ULL << 57) ? 57 : ((sizeof(struct page)) - 1) & (1ULL << 56) ? 56 : ((sizeof(struct page)) - 1) & (1ULL << 55) ? 55 : ((sizeof(struct page)) - 1) & (1ULL << 54) ? 54 : ((sizeof(struct page)) - 1) & (1ULL << 53) ? 53 : ((sizeof(struct page)) - 1) & (1ULL << 52) ? 52 : ((sizeof(struct page)) - 1) & (1ULL << 51) ? 51 : ((sizeof(struct page)) - 1) & (1ULL << 50) ? 50 : ((sizeof(struct page)) - 1) & (1ULL << 49) ? 49 : ((sizeof(struct page)) - 1) & (1ULL << 48) ? 48 : ((sizeof(struct page)) - 1) & (1ULL << 47) ? 47 : ((sizeof(struct page)) - 1) & (1ULL << 46) ? 46 : ((sizeof(struct page)) - 1) & (1ULL << 45) ? 45 : ((sizeof(struct page)) - 1) & (1ULL << 44) ? 44 : ((sizeof(struct page)) - 1) & (1ULL << 43) ? 43 : ((sizeof(struct page)) - 1) & (1ULL << 42) ? 42 : ((sizeof(struct page)) - 1) & (1ULL << 41) ? 41 : ((sizeof(struct page)) - 1) & (1ULL << 40) ? 40 : ((sizeof(struct page)) - 1) & (1ULL << 39) ? 39 : ((sizeof(struct page)) - 1) & (1ULL << 38) ? 38 : ((sizeof(struct page)) - 1) & (1ULL << 37) ? 37 : ((sizeof(struct page)) - 1) & (1ULL << 36) ? 36 : ((sizeof(struct page)) - 1) & (1ULL << 35) ? 35 : ((sizeof(struct page)) - 1) & (1ULL << 34) ? 34 : ((sizeof(struct page)) - 1) & (1ULL << 33) ? 33 : ((sizeof(struct page)) - 1) & (1ULL << 32) ? 32 : ((sizeof(struct page)) - 1) & (1ULL << 31) ? 31 : ((sizeof(struct page)) - 1) & (1ULL << 30) ? 30 : ((sizeof(struct page)) - 1) & (1ULL << 29) ? 29 : ((sizeof(struct page)) - 1) & (1ULL << 28) ? 28 : ((sizeof(struct page)) - 1) & (1ULL << 27) ? 27 : ((sizeof(struct page)) - 1) & (1ULL << 26) ? 26 : ((sizeof(struct page)) - 1) & (1ULL << 25) ? 25 : ((sizeof(struct page)) - 1) & (1ULL << 24) ? 24 : ((sizeof(struct page)) - 1) & (1ULL << 23) ? 23 : ((sizeof(struct page)) - 1) & (1ULL << 22) ? 22 : ((sizeof(struct page)) - 1) & (1ULL << 21) ? 21 : ((sizeof(struct page)) - 1) & (1ULL << 20) ? 20 : ((sizeof(struct page)) - 1) & (1ULL << 19) ? 19 : ((sizeof(struct page)) - 1) & (1ULL << 18) ? 18 : ((sizeof(struct page)) - 1) & (1ULL << 17) ? 17 : ((sizeof(struct page)) - 1) & (1ULL << 16) ? 16 : ((sizeof(struct page)) - 1) & (1ULL << 15) ? 15 : ((sizeof(struct page)) - 1) & (1ULL << 14) ? 14 : ((sizeof(struct page)) - 1) & (1ULL << 13) ? 13 : ((sizeof(struct page)) - 1) & (1ULL << 12) ? 12 : ((sizeof(struct page)) - 1) & (1ULL << 11) ? 11 : ((sizeof(struct page)) - 1) & (1ULL << 10) ? 10 : ((sizeof(struct page)) - 1) & (1ULL << 9) ? 9 : ((sizeof(struct page)) - 1) & (1ULL << 8) ? 8 : ((sizeof(struct page)) - 1) & (1ULL << 7) ? 7 : ((sizeof(struct page)) - 1) & (1ULL << 6) ? 6 : ((sizeof(struct page)) - 1) & (1ULL << 5) ? 5 : ((sizeof(struct page)) - 1) & (1ULL << 4) ? 4 : ((sizeof(struct page)) - 1) & (1ULL << 3) ? 3 : ((sizeof(struct page)) - 1) & (1ULL << 2) ? 2 : 1) : -1) : (sizeof((sizeof(struct page)) - 1) <= 4) ? __ilog2_u32((sizeof(struct page)) - 1) : __ilog2_u64((sizeof(struct page)) - 1) ) + 1) : __order_base_2(sizeof(struct page)) )))) - 0x00200000) - (memstart_addr >> 12)) + (REC->pfn)), REC->pfn, REC->index << 12
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/bprint/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/bprint/format
new file mode 100644
index 000000000..074382f8e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/bprint/format
@@ -0,0 +1,13 @@
+name: bprint
+ID: 6
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long ip; offset:8; size:8; signed:0;
+ field:const char * fmt; offset:16; size:8; signed:0;
+ field:u32 buf[]; offset:24; size:0; signed:0;
+
+print fmt: "%ps: %s", (void *)REC->ip, REC->fmt
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/bputs/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/bputs/format
new file mode 100644
index 000000000..7704ec775
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/bputs/format
@@ -0,0 +1,12 @@
+name: bputs
+ID: 14
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long ip; offset:8; size:8; signed:0;
+ field:const char * str; offset:16; size:8; signed:0;
+
+print fmt: "%ps: %s", (void *)REC->ip, REC->str
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/branch/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/branch/format
new file mode 100644
index 000000000..ed995fb38
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/branch/format
@@ -0,0 +1,15 @@
+name: branch
+ID: 9
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int line; offset:8; size:4; signed:0;
+ field:char func[30+1]; offset:12; size:31; signed:0;
+ field:char file[20+1]; offset:43; size:21; signed:0;
+ field:char correct; offset:64; size:1; signed:0;
+ field:char constant; offset:65; size:1; signed:0;
+
+print fmt: "%u:%s:%s (%u)%s", REC->line, REC->func, REC->file, REC->correct, REC->constant ? " CONSTANT" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/context_switch/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/context_switch/format
new file mode 100644
index 000000000..d7b4432dd
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/context_switch/format
@@ -0,0 +1,17 @@
+name: context_switch
+ID: 2
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int prev_pid; offset:8; size:4; signed:0;
+ field:unsigned int next_pid; offset:12; size:4; signed:0;
+ field:unsigned int next_cpu; offset:16; size:4; signed:0;
+ field:unsigned char prev_prio; offset:20; size:1; signed:0;
+ field:unsigned char prev_state; offset:21; size:1; signed:0;
+ field:unsigned char next_prio; offset:22; size:1; signed:0;
+ field:unsigned char next_state; offset:23; size:1; signed:0;
+
+print fmt: "%u:%u:%u ==> %u:%u:%u [%03u]", REC->prev_pid, REC->prev_prio, REC->prev_state, REC->next_pid, REC->next_prio, REC->next_state, REC->next_cpu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/funcgraph_entry/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/funcgraph_entry/format
new file mode 100644
index 000000000..6c17b8df6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/funcgraph_entry/format
@@ -0,0 +1,12 @@
+name: funcgraph_entry
+ID: 11
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long func; offset:8; size:8; signed:0;
+ field:int depth; offset:16; size:4; signed:1;
+
+print fmt: "--> %ps (%d)", (void *)REC->func, REC->depth
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/funcgraph_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/funcgraph_exit/format
new file mode 100644
index 000000000..31d447b61
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/funcgraph_exit/format
@@ -0,0 +1,15 @@
+name: funcgraph_exit
+ID: 10
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long func; offset:8; size:8; signed:0;
+ field:unsigned long overrun; offset:16; size:8; signed:0;
+ field:unsigned long long calltime; offset:24; size:8; signed:0;
+ field:unsigned long long rettime; offset:32; size:8; signed:0;
+ field:int depth; offset:40; size:4; signed:1;
+
+print fmt: "<-- %ps (%d) (start: %llx end: %llx) over: %d", (void *)REC->func, REC->depth, REC->calltime, REC->rettime, REC->depth
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/function/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/function/format
new file mode 100644
index 000000000..c98c2163e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/function/format
@@ -0,0 +1,12 @@
+name: function
+ID: 1
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long ip; offset:8; size:8; signed:0;
+ field:unsigned long parent_ip; offset:16; size:8; signed:0;
+
+print fmt: " %ps <-- %ps", (void *)REC->ip, (void *)REC->parent_ip
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/hwlat/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/hwlat/format
new file mode 100644
index 000000000..dee081096
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/hwlat/format
@@ -0,0 +1,18 @@
+name: hwlat
+ID: 15
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 duration; offset:8; size:8; signed:0;
+ field:u64 outer_duration; offset:16; size:8; signed:0;
+ field:u64 nmi_total_ts; offset:24; size:8; signed:0;
+ field:s64 tv_sec; offset:32; size:8; signed:1;
+ field:long tv_nsec; offset:40; size:8; signed:1;
+ field:unsigned int nmi_count; offset:48; size:4; signed:0;
+ field:unsigned int seqnum; offset:52; size:4; signed:0;
+ field:unsigned int count; offset:56; size:4; signed:0;
+
+print fmt: "cnt:%u\tts:%010llu.%010lu\tinner:%llu\touter:%llu\tcount:%d\tnmi-ts:%llu\tnmi-count:%u\n", REC->seqnum, REC->tv_sec, REC->tv_nsec, REC->duration, REC->outer_duration, REC->count, REC->nmi_total_ts, REC->nmi_count
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/kernel_stack/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/kernel_stack/format
new file mode 100644
index 000000000..1af875346
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/kernel_stack/format
@@ -0,0 +1,12 @@
+name: kernel_stack
+ID: 4
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int size; offset:8; size:4; signed:1;
+ field:unsigned long caller[8]; offset:16; size:64; signed:0;
+
+print fmt: "\t=> %ps\n\t=> %ps\n\t=> %ps\n" "\t=> %ps\n\t=> %ps\n\t=> %ps\n" "\t=> %ps\n\t=> %ps\n", (void *)REC->caller[0], (void *)REC->caller[1], (void *)REC->caller[2], (void *)REC->caller[3], (void *)REC->caller[4], (void *)REC->caller[5], (void *)REC->caller[6], (void *)REC->caller[7]
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/mmiotrace_map/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/mmiotrace_map/format
new file mode 100644
index 000000000..4ff80e7cd
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/mmiotrace_map/format
@@ -0,0 +1,15 @@
+name: mmiotrace_map
+ID: 8
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:resource_size_t phys; offset:8; size:8; signed:0;
+ field:unsigned long virt; offset:16; size:8; signed:0;
+ field:unsigned long len; offset:24; size:8; signed:0;
+ field:int map_id; offset:32; size:4; signed:1;
+ field:unsigned char opcode; offset:36; size:1; signed:0;
+
+print fmt: "%lx %lx %lx %d %x", (unsigned long)REC->phys, REC->virt, REC->len, REC->map_id, REC->opcode
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/mmiotrace_rw/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/mmiotrace_rw/format
new file mode 100644
index 000000000..2ce7282f4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/mmiotrace_rw/format
@@ -0,0 +1,16 @@
+name: mmiotrace_rw
+ID: 7
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:resource_size_t phys; offset:8; size:8; signed:0;
+ field:unsigned long value; offset:16; size:8; signed:0;
+ field:unsigned long pc; offset:24; size:8; signed:0;
+ field:int map_id; offset:32; size:4; signed:1;
+ field:unsigned char opcode; offset:36; size:1; signed:0;
+ field:unsigned char width; offset:37; size:1; signed:0;
+
+print fmt: "%lx %lx %lx %d %x %x", (unsigned long)REC->phys, REC->value, REC->pc, REC->map_id, REC->opcode, REC->width
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/print/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/print/format
new file mode 100644
index 000000000..7d554bf11
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/print/format
@@ -0,0 +1,12 @@
+name: print
+ID: 5
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long ip; offset:8; size:8; signed:0;
+ field:char buf[]; offset:16; size:0; signed:0;
+
+print fmt: "%ps: %s", (void *)REC->ip, REC->buf
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/raw_data/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/raw_data/format
new file mode 100644
index 000000000..e23a28686
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/raw_data/format
@@ -0,0 +1,12 @@
+name: raw_data
+ID: 16
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int id; offset:8; size:4; signed:0;
+ field:char buf[]; offset:12; size:0; signed:0;
+
+print fmt: "id:%04x %08x", REC->id, (int)REC->buf[0]
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/user_stack/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/user_stack/format
new file mode 100644
index 000000000..00d6dfe46
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/user_stack/format
@@ -0,0 +1,12 @@
+name: user_stack
+ID: 12
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int tgid; offset:8; size:4; signed:0;
+ field:unsigned long caller[8]; offset:16; size:64; signed:0;
+
+print fmt: "\t=> %ps\n\t=> %ps\n\t=> %ps\n" "\t=> %ps\n\t=> %ps\n\t=> %ps\n" "\t=> %ps\n\t=> %ps\n", (void *)REC->caller[0], (void *)REC->caller[1], (void *)REC->caller[2], (void *)REC->caller[3], (void *)REC->caller[4], (void *)REC->caller[5], (void *)REC->caller[6], (void *)REC->caller[7]
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/wakeup/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/wakeup/format
new file mode 100644
index 000000000..6091527ef
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ftrace/wakeup/format
@@ -0,0 +1,17 @@
+name: wakeup
+ID: 3
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int prev_pid; offset:8; size:4; signed:0;
+ field:unsigned int next_pid; offset:12; size:4; signed:0;
+ field:unsigned int next_cpu; offset:16; size:4; signed:0;
+ field:unsigned char prev_prio; offset:20; size:1; signed:0;
+ field:unsigned char prev_state; offset:21; size:1; signed:0;
+ field:unsigned char next_prio; offset:22; size:1; signed:0;
+ field:unsigned char next_state; offset:23; size:1; signed:0;
+
+print fmt: "%u:%u:%u ==+ %u:%u:%u [%03u]", REC->prev_pid, REC->prev_prio, REC->prev_state, REC->next_pid, REC->next_prio, REC->next_state, REC->next_cpu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/g2d/g2d_perf_update_qos/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/g2d/g2d_perf_update_qos/format
new file mode 100644
index 000000000..2871d893b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/g2d/g2d_perf_update_qos/format
@@ -0,0 +1,13 @@
+name: g2d_perf_update_qos
+ID: 1085
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 rbw; offset:8; size:8; signed:0;
+ field:u64 wbw; offset:16; size:8; signed:0;
+ field:u32 devfreq; offset:24; size:4; signed:0;
+
+print fmt: "rbw=%lld wbw=%lld devfreq=%d", REC->rbw, REC->wbw, REC->devfreq
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/g2d/tracing_mark_write/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/g2d/tracing_mark_write/format
new file mode 100644
index 000000000..ee24f8e85
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/g2d/tracing_mark_write/format
@@ -0,0 +1,14 @@
+name: tracing_mark_write
+ID: 1086
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char type; offset:8; size:1; signed:0;
+ field:int pid; offset:12; size:4; signed:1;
+ field:__data_loc char[] name; offset:16; size:4; signed:0;
+ field:int value; offset:20; size:4; signed:1;
+
+print fmt: "%c|%d|%s|%d", REC->type, REC->pid, __get_str(name), REC->value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_alloc_request/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_alloc_request/format
new file mode 100644
index 000000000..2d6dd27ad
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_alloc_request/format
@@ -0,0 +1,22 @@
+name: usb_ep_alloc_request
+ID: 793
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned length; offset:12; size:4; signed:0;
+ field:unsigned actual; offset:16; size:4; signed:0;
+ field:unsigned num_sgs; offset:20; size:4; signed:0;
+ field:unsigned num_mapped_sgs; offset:24; size:4; signed:0;
+ field:unsigned stream_id; offset:28; size:4; signed:0;
+ field:unsigned no_interrupt; offset:32; size:4; signed:0;
+ field:unsigned zero; offset:36; size:4; signed:0;
+ field:unsigned short_not_ok; offset:40; size:4; signed:0;
+ field:int status; offset:44; size:4; signed:1;
+ field:int ret; offset:48; size:4; signed:1;
+ field:struct usb_request * req; offset:56; size:8; signed:0;
+
+print fmt: "%s: req %p length %d/%d sgs %d/%d stream %d %s%s%s status %d --> %d", __get_str(name),REC->req, REC->actual, REC->length, REC->num_mapped_sgs, REC->num_sgs, REC->stream_id, REC->zero ? "Z" : "z", REC->short_not_ok ? "S" : "s", REC->no_interrupt ? "i" : "I", REC->status, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_clear_halt/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_clear_halt/format
new file mode 100644
index 000000000..31b943c0d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_clear_halt/format
@@ -0,0 +1,20 @@
+name: usb_ep_clear_halt
+ID: 794
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned maxpacket; offset:12; size:4; signed:0;
+ field:unsigned maxpacket_limit; offset:16; size:4; signed:0;
+ field:unsigned max_streams; offset:20; size:4; signed:0;
+ field:unsigned mult; offset:24; size:4; signed:0;
+ field:unsigned maxburst; offset:28; size:4; signed:0;
+ field:u8 address; offset:32; size:1; signed:0;
+ field:bool claimed; offset:33; size:1; signed:0;
+ field:bool enabled; offset:34; size:1; signed:0;
+ field:int ret; offset:36; size:4; signed:1;
+
+print fmt: "%s: mps %d/%d streams %d mult %d burst %d addr %02x %s%s --> %d", __get_str(name), REC->maxpacket, REC->maxpacket_limit, REC->max_streams, REC->mult, REC->maxburst, REC->address, REC->claimed ? "claimed:" : "released:", REC->enabled ? "enabled" : "disabled", ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_dequeue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_dequeue/format
new file mode 100644
index 000000000..cad1b2415
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_dequeue/format
@@ -0,0 +1,22 @@
+name: usb_ep_dequeue
+ID: 795
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned length; offset:12; size:4; signed:0;
+ field:unsigned actual; offset:16; size:4; signed:0;
+ field:unsigned num_sgs; offset:20; size:4; signed:0;
+ field:unsigned num_mapped_sgs; offset:24; size:4; signed:0;
+ field:unsigned stream_id; offset:28; size:4; signed:0;
+ field:unsigned no_interrupt; offset:32; size:4; signed:0;
+ field:unsigned zero; offset:36; size:4; signed:0;
+ field:unsigned short_not_ok; offset:40; size:4; signed:0;
+ field:int status; offset:44; size:4; signed:1;
+ field:int ret; offset:48; size:4; signed:1;
+ field:struct usb_request * req; offset:56; size:8; signed:0;
+
+print fmt: "%s: req %p length %d/%d sgs %d/%d stream %d %s%s%s status %d --> %d", __get_str(name),REC->req, REC->actual, REC->length, REC->num_mapped_sgs, REC->num_sgs, REC->stream_id, REC->zero ? "Z" : "z", REC->short_not_ok ? "S" : "s", REC->no_interrupt ? "i" : "I", REC->status, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_disable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_disable/format
new file mode 100644
index 000000000..881ae09ce
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_disable/format
@@ -0,0 +1,20 @@
+name: usb_ep_disable
+ID: 796
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned maxpacket; offset:12; size:4; signed:0;
+ field:unsigned maxpacket_limit; offset:16; size:4; signed:0;
+ field:unsigned max_streams; offset:20; size:4; signed:0;
+ field:unsigned mult; offset:24; size:4; signed:0;
+ field:unsigned maxburst; offset:28; size:4; signed:0;
+ field:u8 address; offset:32; size:1; signed:0;
+ field:bool claimed; offset:33; size:1; signed:0;
+ field:bool enabled; offset:34; size:1; signed:0;
+ field:int ret; offset:36; size:4; signed:1;
+
+print fmt: "%s: mps %d/%d streams %d mult %d burst %d addr %02x %s%s --> %d", __get_str(name), REC->maxpacket, REC->maxpacket_limit, REC->max_streams, REC->mult, REC->maxburst, REC->address, REC->claimed ? "claimed:" : "released:", REC->enabled ? "enabled" : "disabled", ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_enable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_enable/format
new file mode 100644
index 000000000..cbf1106e2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_enable/format
@@ -0,0 +1,20 @@
+name: usb_ep_enable
+ID: 797
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned maxpacket; offset:12; size:4; signed:0;
+ field:unsigned maxpacket_limit; offset:16; size:4; signed:0;
+ field:unsigned max_streams; offset:20; size:4; signed:0;
+ field:unsigned mult; offset:24; size:4; signed:0;
+ field:unsigned maxburst; offset:28; size:4; signed:0;
+ field:u8 address; offset:32; size:1; signed:0;
+ field:bool claimed; offset:33; size:1; signed:0;
+ field:bool enabled; offset:34; size:1; signed:0;
+ field:int ret; offset:36; size:4; signed:1;
+
+print fmt: "%s: mps %d/%d streams %d mult %d burst %d addr %02x %s%s --> %d", __get_str(name), REC->maxpacket, REC->maxpacket_limit, REC->max_streams, REC->mult, REC->maxburst, REC->address, REC->claimed ? "claimed:" : "released:", REC->enabled ? "enabled" : "disabled", ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_fifo_flush/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_fifo_flush/format
new file mode 100644
index 000000000..360e5503a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_fifo_flush/format
@@ -0,0 +1,20 @@
+name: usb_ep_fifo_flush
+ID: 798
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned maxpacket; offset:12; size:4; signed:0;
+ field:unsigned maxpacket_limit; offset:16; size:4; signed:0;
+ field:unsigned max_streams; offset:20; size:4; signed:0;
+ field:unsigned mult; offset:24; size:4; signed:0;
+ field:unsigned maxburst; offset:28; size:4; signed:0;
+ field:u8 address; offset:32; size:1; signed:0;
+ field:bool claimed; offset:33; size:1; signed:0;
+ field:bool enabled; offset:34; size:1; signed:0;
+ field:int ret; offset:36; size:4; signed:1;
+
+print fmt: "%s: mps %d/%d streams %d mult %d burst %d addr %02x %s%s --> %d", __get_str(name), REC->maxpacket, REC->maxpacket_limit, REC->max_streams, REC->mult, REC->maxburst, REC->address, REC->claimed ? "claimed:" : "released:", REC->enabled ? "enabled" : "disabled", ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_fifo_status/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_fifo_status/format
new file mode 100644
index 000000000..86942f424
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_fifo_status/format
@@ -0,0 +1,20 @@
+name: usb_ep_fifo_status
+ID: 799
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned maxpacket; offset:12; size:4; signed:0;
+ field:unsigned maxpacket_limit; offset:16; size:4; signed:0;
+ field:unsigned max_streams; offset:20; size:4; signed:0;
+ field:unsigned mult; offset:24; size:4; signed:0;
+ field:unsigned maxburst; offset:28; size:4; signed:0;
+ field:u8 address; offset:32; size:1; signed:0;
+ field:bool claimed; offset:33; size:1; signed:0;
+ field:bool enabled; offset:34; size:1; signed:0;
+ field:int ret; offset:36; size:4; signed:1;
+
+print fmt: "%s: mps %d/%d streams %d mult %d burst %d addr %02x %s%s --> %d", __get_str(name), REC->maxpacket, REC->maxpacket_limit, REC->max_streams, REC->mult, REC->maxburst, REC->address, REC->claimed ? "claimed:" : "released:", REC->enabled ? "enabled" : "disabled", ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_free_request/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_free_request/format
new file mode 100644
index 000000000..11a17be1c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_free_request/format
@@ -0,0 +1,22 @@
+name: usb_ep_free_request
+ID: 800
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned length; offset:12; size:4; signed:0;
+ field:unsigned actual; offset:16; size:4; signed:0;
+ field:unsigned num_sgs; offset:20; size:4; signed:0;
+ field:unsigned num_mapped_sgs; offset:24; size:4; signed:0;
+ field:unsigned stream_id; offset:28; size:4; signed:0;
+ field:unsigned no_interrupt; offset:32; size:4; signed:0;
+ field:unsigned zero; offset:36; size:4; signed:0;
+ field:unsigned short_not_ok; offset:40; size:4; signed:0;
+ field:int status; offset:44; size:4; signed:1;
+ field:int ret; offset:48; size:4; signed:1;
+ field:struct usb_request * req; offset:56; size:8; signed:0;
+
+print fmt: "%s: req %p length %d/%d sgs %d/%d stream %d %s%s%s status %d --> %d", __get_str(name),REC->req, REC->actual, REC->length, REC->num_mapped_sgs, REC->num_sgs, REC->stream_id, REC->zero ? "Z" : "z", REC->short_not_ok ? "S" : "s", REC->no_interrupt ? "i" : "I", REC->status, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_queue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_queue/format
new file mode 100644
index 000000000..838dde00f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_queue/format
@@ -0,0 +1,22 @@
+name: usb_ep_queue
+ID: 801
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned length; offset:12; size:4; signed:0;
+ field:unsigned actual; offset:16; size:4; signed:0;
+ field:unsigned num_sgs; offset:20; size:4; signed:0;
+ field:unsigned num_mapped_sgs; offset:24; size:4; signed:0;
+ field:unsigned stream_id; offset:28; size:4; signed:0;
+ field:unsigned no_interrupt; offset:32; size:4; signed:0;
+ field:unsigned zero; offset:36; size:4; signed:0;
+ field:unsigned short_not_ok; offset:40; size:4; signed:0;
+ field:int status; offset:44; size:4; signed:1;
+ field:int ret; offset:48; size:4; signed:1;
+ field:struct usb_request * req; offset:56; size:8; signed:0;
+
+print fmt: "%s: req %p length %d/%d sgs %d/%d stream %d %s%s%s status %d --> %d", __get_str(name),REC->req, REC->actual, REC->length, REC->num_mapped_sgs, REC->num_sgs, REC->stream_id, REC->zero ? "Z" : "z", REC->short_not_ok ? "S" : "s", REC->no_interrupt ? "i" : "I", REC->status, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_set_halt/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_set_halt/format
new file mode 100644
index 000000000..38bc80958
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_set_halt/format
@@ -0,0 +1,20 @@
+name: usb_ep_set_halt
+ID: 802
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned maxpacket; offset:12; size:4; signed:0;
+ field:unsigned maxpacket_limit; offset:16; size:4; signed:0;
+ field:unsigned max_streams; offset:20; size:4; signed:0;
+ field:unsigned mult; offset:24; size:4; signed:0;
+ field:unsigned maxburst; offset:28; size:4; signed:0;
+ field:u8 address; offset:32; size:1; signed:0;
+ field:bool claimed; offset:33; size:1; signed:0;
+ field:bool enabled; offset:34; size:1; signed:0;
+ field:int ret; offset:36; size:4; signed:1;
+
+print fmt: "%s: mps %d/%d streams %d mult %d burst %d addr %02x %s%s --> %d", __get_str(name), REC->maxpacket, REC->maxpacket_limit, REC->max_streams, REC->mult, REC->maxburst, REC->address, REC->claimed ? "claimed:" : "released:", REC->enabled ? "enabled" : "disabled", ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_set_maxpacket_limit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_set_maxpacket_limit/format
new file mode 100644
index 000000000..20eec1c19
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_set_maxpacket_limit/format
@@ -0,0 +1,20 @@
+name: usb_ep_set_maxpacket_limit
+ID: 803
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned maxpacket; offset:12; size:4; signed:0;
+ field:unsigned maxpacket_limit; offset:16; size:4; signed:0;
+ field:unsigned max_streams; offset:20; size:4; signed:0;
+ field:unsigned mult; offset:24; size:4; signed:0;
+ field:unsigned maxburst; offset:28; size:4; signed:0;
+ field:u8 address; offset:32; size:1; signed:0;
+ field:bool claimed; offset:33; size:1; signed:0;
+ field:bool enabled; offset:34; size:1; signed:0;
+ field:int ret; offset:36; size:4; signed:1;
+
+print fmt: "%s: mps %d/%d streams %d mult %d burst %d addr %02x %s%s --> %d", __get_str(name), REC->maxpacket, REC->maxpacket_limit, REC->max_streams, REC->mult, REC->maxburst, REC->address, REC->claimed ? "claimed:" : "released:", REC->enabled ? "enabled" : "disabled", ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_set_wedge/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_set_wedge/format
new file mode 100644
index 000000000..01d7f4392
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_ep_set_wedge/format
@@ -0,0 +1,20 @@
+name: usb_ep_set_wedge
+ID: 804
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned maxpacket; offset:12; size:4; signed:0;
+ field:unsigned maxpacket_limit; offset:16; size:4; signed:0;
+ field:unsigned max_streams; offset:20; size:4; signed:0;
+ field:unsigned mult; offset:24; size:4; signed:0;
+ field:unsigned maxburst; offset:28; size:4; signed:0;
+ field:u8 address; offset:32; size:1; signed:0;
+ field:bool claimed; offset:33; size:1; signed:0;
+ field:bool enabled; offset:34; size:1; signed:0;
+ field:int ret; offset:36; size:4; signed:1;
+
+print fmt: "%s: mps %d/%d streams %d mult %d burst %d addr %02x %s%s --> %d", __get_str(name), REC->maxpacket, REC->maxpacket_limit, REC->max_streams, REC->mult, REC->maxburst, REC->address, REC->claimed ? "claimed:" : "released:", REC->enabled ? "enabled" : "disabled", ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_activate/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_activate/format
new file mode 100644
index 000000000..44c273c8d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_activate/format
@@ -0,0 +1,29 @@
+name: usb_gadget_activate
+ID: 805
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum usb_device_speed speed; offset:8; size:4; signed:0;
+ field:enum usb_device_speed max_speed; offset:12; size:4; signed:0;
+ field:enum usb_device_state state; offset:16; size:4; signed:0;
+ field:unsigned mA; offset:20; size:4; signed:0;
+ field:unsigned sg_supported; offset:24; size:4; signed:0;
+ field:unsigned is_otg; offset:28; size:4; signed:0;
+ field:unsigned is_a_peripheral; offset:32; size:4; signed:0;
+ field:unsigned b_hnp_enable; offset:36; size:4; signed:0;
+ field:unsigned a_hnp_support; offset:40; size:4; signed:0;
+ field:unsigned hnp_polling_support; offset:44; size:4; signed:0;
+ field:unsigned host_request_flag; offset:48; size:4; signed:0;
+ field:unsigned quirk_ep_out_aligned_size; offset:52; size:4; signed:0;
+ field:unsigned quirk_altset_not_supp; offset:56; size:4; signed:0;
+ field:unsigned quirk_stall_not_supp; offset:60; size:4; signed:0;
+ field:unsigned quirk_zlp_not_supp; offset:64; size:4; signed:0;
+ field:unsigned is_selfpowered; offset:68; size:4; signed:0;
+ field:unsigned deactivated; offset:72; size:4; signed:0;
+ field:unsigned connected; offset:76; size:4; signed:0;
+ field:int ret; offset:80; size:4; signed:1;
+
+print fmt: "speed %d/%d state %d %dmA [%s%s%s%s%s%s%s%s%s%s%s%s%s%s] --> %d", REC->speed, REC->max_speed, REC->state, REC->mA, REC->sg_supported ? "sg:" : "", REC->is_otg ? "OTG:" : "", REC->is_a_peripheral ? "a_peripheral:" : "", REC->b_hnp_enable ? "b_hnp:" : "", REC->a_hnp_support ? "a_hnp:" : "", REC->hnp_polling_support ? "hnp_poll:" : "", REC->host_request_flag ? "hostreq:" : "", REC->quirk_ep_out_aligned_size ? "out_aligned:" : "", REC->quirk_altset_not_supp ? "no_altset:" : "", REC->quirk_stall_not_supp ? "no_stall:" : "", REC->quirk_zlp_not_supp ? "no_zlp" : "", REC->is_selfpowered ? "self-powered:" : "bus-powered:", REC->deactivated ? "deactivated:" : "activated:", REC->connected ? "connected" : "disconnected", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_clear_selfpowered/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_clear_selfpowered/format
new file mode 100644
index 000000000..fc246eb0b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_clear_selfpowered/format
@@ -0,0 +1,29 @@
+name: usb_gadget_clear_selfpowered
+ID: 806
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum usb_device_speed speed; offset:8; size:4; signed:0;
+ field:enum usb_device_speed max_speed; offset:12; size:4; signed:0;
+ field:enum usb_device_state state; offset:16; size:4; signed:0;
+ field:unsigned mA; offset:20; size:4; signed:0;
+ field:unsigned sg_supported; offset:24; size:4; signed:0;
+ field:unsigned is_otg; offset:28; size:4; signed:0;
+ field:unsigned is_a_peripheral; offset:32; size:4; signed:0;
+ field:unsigned b_hnp_enable; offset:36; size:4; signed:0;
+ field:unsigned a_hnp_support; offset:40; size:4; signed:0;
+ field:unsigned hnp_polling_support; offset:44; size:4; signed:0;
+ field:unsigned host_request_flag; offset:48; size:4; signed:0;
+ field:unsigned quirk_ep_out_aligned_size; offset:52; size:4; signed:0;
+ field:unsigned quirk_altset_not_supp; offset:56; size:4; signed:0;
+ field:unsigned quirk_stall_not_supp; offset:60; size:4; signed:0;
+ field:unsigned quirk_zlp_not_supp; offset:64; size:4; signed:0;
+ field:unsigned is_selfpowered; offset:68; size:4; signed:0;
+ field:unsigned deactivated; offset:72; size:4; signed:0;
+ field:unsigned connected; offset:76; size:4; signed:0;
+ field:int ret; offset:80; size:4; signed:1;
+
+print fmt: "speed %d/%d state %d %dmA [%s%s%s%s%s%s%s%s%s%s%s%s%s%s] --> %d", REC->speed, REC->max_speed, REC->state, REC->mA, REC->sg_supported ? "sg:" : "", REC->is_otg ? "OTG:" : "", REC->is_a_peripheral ? "a_peripheral:" : "", REC->b_hnp_enable ? "b_hnp:" : "", REC->a_hnp_support ? "a_hnp:" : "", REC->hnp_polling_support ? "hnp_poll:" : "", REC->host_request_flag ? "hostreq:" : "", REC->quirk_ep_out_aligned_size ? "out_aligned:" : "", REC->quirk_altset_not_supp ? "no_altset:" : "", REC->quirk_stall_not_supp ? "no_stall:" : "", REC->quirk_zlp_not_supp ? "no_zlp" : "", REC->is_selfpowered ? "self-powered:" : "bus-powered:", REC->deactivated ? "deactivated:" : "activated:", REC->connected ? "connected" : "disconnected", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_connect/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_connect/format
new file mode 100644
index 000000000..3b65f23c4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_connect/format
@@ -0,0 +1,29 @@
+name: usb_gadget_connect
+ID: 807
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum usb_device_speed speed; offset:8; size:4; signed:0;
+ field:enum usb_device_speed max_speed; offset:12; size:4; signed:0;
+ field:enum usb_device_state state; offset:16; size:4; signed:0;
+ field:unsigned mA; offset:20; size:4; signed:0;
+ field:unsigned sg_supported; offset:24; size:4; signed:0;
+ field:unsigned is_otg; offset:28; size:4; signed:0;
+ field:unsigned is_a_peripheral; offset:32; size:4; signed:0;
+ field:unsigned b_hnp_enable; offset:36; size:4; signed:0;
+ field:unsigned a_hnp_support; offset:40; size:4; signed:0;
+ field:unsigned hnp_polling_support; offset:44; size:4; signed:0;
+ field:unsigned host_request_flag; offset:48; size:4; signed:0;
+ field:unsigned quirk_ep_out_aligned_size; offset:52; size:4; signed:0;
+ field:unsigned quirk_altset_not_supp; offset:56; size:4; signed:0;
+ field:unsigned quirk_stall_not_supp; offset:60; size:4; signed:0;
+ field:unsigned quirk_zlp_not_supp; offset:64; size:4; signed:0;
+ field:unsigned is_selfpowered; offset:68; size:4; signed:0;
+ field:unsigned deactivated; offset:72; size:4; signed:0;
+ field:unsigned connected; offset:76; size:4; signed:0;
+ field:int ret; offset:80; size:4; signed:1;
+
+print fmt: "speed %d/%d state %d %dmA [%s%s%s%s%s%s%s%s%s%s%s%s%s%s] --> %d", REC->speed, REC->max_speed, REC->state, REC->mA, REC->sg_supported ? "sg:" : "", REC->is_otg ? "OTG:" : "", REC->is_a_peripheral ? "a_peripheral:" : "", REC->b_hnp_enable ? "b_hnp:" : "", REC->a_hnp_support ? "a_hnp:" : "", REC->hnp_polling_support ? "hnp_poll:" : "", REC->host_request_flag ? "hostreq:" : "", REC->quirk_ep_out_aligned_size ? "out_aligned:" : "", REC->quirk_altset_not_supp ? "no_altset:" : "", REC->quirk_stall_not_supp ? "no_stall:" : "", REC->quirk_zlp_not_supp ? "no_zlp" : "", REC->is_selfpowered ? "self-powered:" : "bus-powered:", REC->deactivated ? "deactivated:" : "activated:", REC->connected ? "connected" : "disconnected", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_deactivate/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_deactivate/format
new file mode 100644
index 000000000..80e0d7a1e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_deactivate/format
@@ -0,0 +1,29 @@
+name: usb_gadget_deactivate
+ID: 808
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum usb_device_speed speed; offset:8; size:4; signed:0;
+ field:enum usb_device_speed max_speed; offset:12; size:4; signed:0;
+ field:enum usb_device_state state; offset:16; size:4; signed:0;
+ field:unsigned mA; offset:20; size:4; signed:0;
+ field:unsigned sg_supported; offset:24; size:4; signed:0;
+ field:unsigned is_otg; offset:28; size:4; signed:0;
+ field:unsigned is_a_peripheral; offset:32; size:4; signed:0;
+ field:unsigned b_hnp_enable; offset:36; size:4; signed:0;
+ field:unsigned a_hnp_support; offset:40; size:4; signed:0;
+ field:unsigned hnp_polling_support; offset:44; size:4; signed:0;
+ field:unsigned host_request_flag; offset:48; size:4; signed:0;
+ field:unsigned quirk_ep_out_aligned_size; offset:52; size:4; signed:0;
+ field:unsigned quirk_altset_not_supp; offset:56; size:4; signed:0;
+ field:unsigned quirk_stall_not_supp; offset:60; size:4; signed:0;
+ field:unsigned quirk_zlp_not_supp; offset:64; size:4; signed:0;
+ field:unsigned is_selfpowered; offset:68; size:4; signed:0;
+ field:unsigned deactivated; offset:72; size:4; signed:0;
+ field:unsigned connected; offset:76; size:4; signed:0;
+ field:int ret; offset:80; size:4; signed:1;
+
+print fmt: "speed %d/%d state %d %dmA [%s%s%s%s%s%s%s%s%s%s%s%s%s%s] --> %d", REC->speed, REC->max_speed, REC->state, REC->mA, REC->sg_supported ? "sg:" : "", REC->is_otg ? "OTG:" : "", REC->is_a_peripheral ? "a_peripheral:" : "", REC->b_hnp_enable ? "b_hnp:" : "", REC->a_hnp_support ? "a_hnp:" : "", REC->hnp_polling_support ? "hnp_poll:" : "", REC->host_request_flag ? "hostreq:" : "", REC->quirk_ep_out_aligned_size ? "out_aligned:" : "", REC->quirk_altset_not_supp ? "no_altset:" : "", REC->quirk_stall_not_supp ? "no_stall:" : "", REC->quirk_zlp_not_supp ? "no_zlp" : "", REC->is_selfpowered ? "self-powered:" : "bus-powered:", REC->deactivated ? "deactivated:" : "activated:", REC->connected ? "connected" : "disconnected", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_disconnect/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_disconnect/format
new file mode 100644
index 000000000..8a3714987
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_disconnect/format
@@ -0,0 +1,29 @@
+name: usb_gadget_disconnect
+ID: 809
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum usb_device_speed speed; offset:8; size:4; signed:0;
+ field:enum usb_device_speed max_speed; offset:12; size:4; signed:0;
+ field:enum usb_device_state state; offset:16; size:4; signed:0;
+ field:unsigned mA; offset:20; size:4; signed:0;
+ field:unsigned sg_supported; offset:24; size:4; signed:0;
+ field:unsigned is_otg; offset:28; size:4; signed:0;
+ field:unsigned is_a_peripheral; offset:32; size:4; signed:0;
+ field:unsigned b_hnp_enable; offset:36; size:4; signed:0;
+ field:unsigned a_hnp_support; offset:40; size:4; signed:0;
+ field:unsigned hnp_polling_support; offset:44; size:4; signed:0;
+ field:unsigned host_request_flag; offset:48; size:4; signed:0;
+ field:unsigned quirk_ep_out_aligned_size; offset:52; size:4; signed:0;
+ field:unsigned quirk_altset_not_supp; offset:56; size:4; signed:0;
+ field:unsigned quirk_stall_not_supp; offset:60; size:4; signed:0;
+ field:unsigned quirk_zlp_not_supp; offset:64; size:4; signed:0;
+ field:unsigned is_selfpowered; offset:68; size:4; signed:0;
+ field:unsigned deactivated; offset:72; size:4; signed:0;
+ field:unsigned connected; offset:76; size:4; signed:0;
+ field:int ret; offset:80; size:4; signed:1;
+
+print fmt: "speed %d/%d state %d %dmA [%s%s%s%s%s%s%s%s%s%s%s%s%s%s] --> %d", REC->speed, REC->max_speed, REC->state, REC->mA, REC->sg_supported ? "sg:" : "", REC->is_otg ? "OTG:" : "", REC->is_a_peripheral ? "a_peripheral:" : "", REC->b_hnp_enable ? "b_hnp:" : "", REC->a_hnp_support ? "a_hnp:" : "", REC->hnp_polling_support ? "hnp_poll:" : "", REC->host_request_flag ? "hostreq:" : "", REC->quirk_ep_out_aligned_size ? "out_aligned:" : "", REC->quirk_altset_not_supp ? "no_altset:" : "", REC->quirk_stall_not_supp ? "no_stall:" : "", REC->quirk_zlp_not_supp ? "no_zlp" : "", REC->is_selfpowered ? "self-powered:" : "bus-powered:", REC->deactivated ? "deactivated:" : "activated:", REC->connected ? "connected" : "disconnected", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_frame_number/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_frame_number/format
new file mode 100644
index 000000000..977ba48ed
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_frame_number/format
@@ -0,0 +1,29 @@
+name: usb_gadget_frame_number
+ID: 810
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum usb_device_speed speed; offset:8; size:4; signed:0;
+ field:enum usb_device_speed max_speed; offset:12; size:4; signed:0;
+ field:enum usb_device_state state; offset:16; size:4; signed:0;
+ field:unsigned mA; offset:20; size:4; signed:0;
+ field:unsigned sg_supported; offset:24; size:4; signed:0;
+ field:unsigned is_otg; offset:28; size:4; signed:0;
+ field:unsigned is_a_peripheral; offset:32; size:4; signed:0;
+ field:unsigned b_hnp_enable; offset:36; size:4; signed:0;
+ field:unsigned a_hnp_support; offset:40; size:4; signed:0;
+ field:unsigned hnp_polling_support; offset:44; size:4; signed:0;
+ field:unsigned host_request_flag; offset:48; size:4; signed:0;
+ field:unsigned quirk_ep_out_aligned_size; offset:52; size:4; signed:0;
+ field:unsigned quirk_altset_not_supp; offset:56; size:4; signed:0;
+ field:unsigned quirk_stall_not_supp; offset:60; size:4; signed:0;
+ field:unsigned quirk_zlp_not_supp; offset:64; size:4; signed:0;
+ field:unsigned is_selfpowered; offset:68; size:4; signed:0;
+ field:unsigned deactivated; offset:72; size:4; signed:0;
+ field:unsigned connected; offset:76; size:4; signed:0;
+ field:int ret; offset:80; size:4; signed:1;
+
+print fmt: "speed %d/%d state %d %dmA [%s%s%s%s%s%s%s%s%s%s%s%s%s%s] --> %d", REC->speed, REC->max_speed, REC->state, REC->mA, REC->sg_supported ? "sg:" : "", REC->is_otg ? "OTG:" : "", REC->is_a_peripheral ? "a_peripheral:" : "", REC->b_hnp_enable ? "b_hnp:" : "", REC->a_hnp_support ? "a_hnp:" : "", REC->hnp_polling_support ? "hnp_poll:" : "", REC->host_request_flag ? "hostreq:" : "", REC->quirk_ep_out_aligned_size ? "out_aligned:" : "", REC->quirk_altset_not_supp ? "no_altset:" : "", REC->quirk_stall_not_supp ? "no_stall:" : "", REC->quirk_zlp_not_supp ? "no_zlp" : "", REC->is_selfpowered ? "self-powered:" : "bus-powered:", REC->deactivated ? "deactivated:" : "activated:", REC->connected ? "connected" : "disconnected", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_giveback_request/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_giveback_request/format
new file mode 100644
index 000000000..f43abe387
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_giveback_request/format
@@ -0,0 +1,22 @@
+name: usb_gadget_giveback_request
+ID: 811
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned length; offset:12; size:4; signed:0;
+ field:unsigned actual; offset:16; size:4; signed:0;
+ field:unsigned num_sgs; offset:20; size:4; signed:0;
+ field:unsigned num_mapped_sgs; offset:24; size:4; signed:0;
+ field:unsigned stream_id; offset:28; size:4; signed:0;
+ field:unsigned no_interrupt; offset:32; size:4; signed:0;
+ field:unsigned zero; offset:36; size:4; signed:0;
+ field:unsigned short_not_ok; offset:40; size:4; signed:0;
+ field:int status; offset:44; size:4; signed:1;
+ field:int ret; offset:48; size:4; signed:1;
+ field:struct usb_request * req; offset:56; size:8; signed:0;
+
+print fmt: "%s: req %p length %d/%d sgs %d/%d stream %d %s%s%s status %d --> %d", __get_str(name),REC->req, REC->actual, REC->length, REC->num_mapped_sgs, REC->num_sgs, REC->stream_id, REC->zero ? "Z" : "z", REC->short_not_ok ? "S" : "s", REC->no_interrupt ? "i" : "I", REC->status, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_set_selfpowered/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_set_selfpowered/format
new file mode 100644
index 000000000..bebdc5cf2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_set_selfpowered/format
@@ -0,0 +1,29 @@
+name: usb_gadget_set_selfpowered
+ID: 812
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum usb_device_speed speed; offset:8; size:4; signed:0;
+ field:enum usb_device_speed max_speed; offset:12; size:4; signed:0;
+ field:enum usb_device_state state; offset:16; size:4; signed:0;
+ field:unsigned mA; offset:20; size:4; signed:0;
+ field:unsigned sg_supported; offset:24; size:4; signed:0;
+ field:unsigned is_otg; offset:28; size:4; signed:0;
+ field:unsigned is_a_peripheral; offset:32; size:4; signed:0;
+ field:unsigned b_hnp_enable; offset:36; size:4; signed:0;
+ field:unsigned a_hnp_support; offset:40; size:4; signed:0;
+ field:unsigned hnp_polling_support; offset:44; size:4; signed:0;
+ field:unsigned host_request_flag; offset:48; size:4; signed:0;
+ field:unsigned quirk_ep_out_aligned_size; offset:52; size:4; signed:0;
+ field:unsigned quirk_altset_not_supp; offset:56; size:4; signed:0;
+ field:unsigned quirk_stall_not_supp; offset:60; size:4; signed:0;
+ field:unsigned quirk_zlp_not_supp; offset:64; size:4; signed:0;
+ field:unsigned is_selfpowered; offset:68; size:4; signed:0;
+ field:unsigned deactivated; offset:72; size:4; signed:0;
+ field:unsigned connected; offset:76; size:4; signed:0;
+ field:int ret; offset:80; size:4; signed:1;
+
+print fmt: "speed %d/%d state %d %dmA [%s%s%s%s%s%s%s%s%s%s%s%s%s%s] --> %d", REC->speed, REC->max_speed, REC->state, REC->mA, REC->sg_supported ? "sg:" : "", REC->is_otg ? "OTG:" : "", REC->is_a_peripheral ? "a_peripheral:" : "", REC->b_hnp_enable ? "b_hnp:" : "", REC->a_hnp_support ? "a_hnp:" : "", REC->hnp_polling_support ? "hnp_poll:" : "", REC->host_request_flag ? "hostreq:" : "", REC->quirk_ep_out_aligned_size ? "out_aligned:" : "", REC->quirk_altset_not_supp ? "no_altset:" : "", REC->quirk_stall_not_supp ? "no_stall:" : "", REC->quirk_zlp_not_supp ? "no_zlp" : "", REC->is_selfpowered ? "self-powered:" : "bus-powered:", REC->deactivated ? "deactivated:" : "activated:", REC->connected ? "connected" : "disconnected", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_vbus_connect/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_vbus_connect/format
new file mode 100644
index 000000000..2f04046fc
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_vbus_connect/format
@@ -0,0 +1,29 @@
+name: usb_gadget_vbus_connect
+ID: 813
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum usb_device_speed speed; offset:8; size:4; signed:0;
+ field:enum usb_device_speed max_speed; offset:12; size:4; signed:0;
+ field:enum usb_device_state state; offset:16; size:4; signed:0;
+ field:unsigned mA; offset:20; size:4; signed:0;
+ field:unsigned sg_supported; offset:24; size:4; signed:0;
+ field:unsigned is_otg; offset:28; size:4; signed:0;
+ field:unsigned is_a_peripheral; offset:32; size:4; signed:0;
+ field:unsigned b_hnp_enable; offset:36; size:4; signed:0;
+ field:unsigned a_hnp_support; offset:40; size:4; signed:0;
+ field:unsigned hnp_polling_support; offset:44; size:4; signed:0;
+ field:unsigned host_request_flag; offset:48; size:4; signed:0;
+ field:unsigned quirk_ep_out_aligned_size; offset:52; size:4; signed:0;
+ field:unsigned quirk_altset_not_supp; offset:56; size:4; signed:0;
+ field:unsigned quirk_stall_not_supp; offset:60; size:4; signed:0;
+ field:unsigned quirk_zlp_not_supp; offset:64; size:4; signed:0;
+ field:unsigned is_selfpowered; offset:68; size:4; signed:0;
+ field:unsigned deactivated; offset:72; size:4; signed:0;
+ field:unsigned connected; offset:76; size:4; signed:0;
+ field:int ret; offset:80; size:4; signed:1;
+
+print fmt: "speed %d/%d state %d %dmA [%s%s%s%s%s%s%s%s%s%s%s%s%s%s] --> %d", REC->speed, REC->max_speed, REC->state, REC->mA, REC->sg_supported ? "sg:" : "", REC->is_otg ? "OTG:" : "", REC->is_a_peripheral ? "a_peripheral:" : "", REC->b_hnp_enable ? "b_hnp:" : "", REC->a_hnp_support ? "a_hnp:" : "", REC->hnp_polling_support ? "hnp_poll:" : "", REC->host_request_flag ? "hostreq:" : "", REC->quirk_ep_out_aligned_size ? "out_aligned:" : "", REC->quirk_altset_not_supp ? "no_altset:" : "", REC->quirk_stall_not_supp ? "no_stall:" : "", REC->quirk_zlp_not_supp ? "no_zlp" : "", REC->is_selfpowered ? "self-powered:" : "bus-powered:", REC->deactivated ? "deactivated:" : "activated:", REC->connected ? "connected" : "disconnected", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_vbus_disconnect/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_vbus_disconnect/format
new file mode 100644
index 000000000..979cf918b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_vbus_disconnect/format
@@ -0,0 +1,29 @@
+name: usb_gadget_vbus_disconnect
+ID: 814
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum usb_device_speed speed; offset:8; size:4; signed:0;
+ field:enum usb_device_speed max_speed; offset:12; size:4; signed:0;
+ field:enum usb_device_state state; offset:16; size:4; signed:0;
+ field:unsigned mA; offset:20; size:4; signed:0;
+ field:unsigned sg_supported; offset:24; size:4; signed:0;
+ field:unsigned is_otg; offset:28; size:4; signed:0;
+ field:unsigned is_a_peripheral; offset:32; size:4; signed:0;
+ field:unsigned b_hnp_enable; offset:36; size:4; signed:0;
+ field:unsigned a_hnp_support; offset:40; size:4; signed:0;
+ field:unsigned hnp_polling_support; offset:44; size:4; signed:0;
+ field:unsigned host_request_flag; offset:48; size:4; signed:0;
+ field:unsigned quirk_ep_out_aligned_size; offset:52; size:4; signed:0;
+ field:unsigned quirk_altset_not_supp; offset:56; size:4; signed:0;
+ field:unsigned quirk_stall_not_supp; offset:60; size:4; signed:0;
+ field:unsigned quirk_zlp_not_supp; offset:64; size:4; signed:0;
+ field:unsigned is_selfpowered; offset:68; size:4; signed:0;
+ field:unsigned deactivated; offset:72; size:4; signed:0;
+ field:unsigned connected; offset:76; size:4; signed:0;
+ field:int ret; offset:80; size:4; signed:1;
+
+print fmt: "speed %d/%d state %d %dmA [%s%s%s%s%s%s%s%s%s%s%s%s%s%s] --> %d", REC->speed, REC->max_speed, REC->state, REC->mA, REC->sg_supported ? "sg:" : "", REC->is_otg ? "OTG:" : "", REC->is_a_peripheral ? "a_peripheral:" : "", REC->b_hnp_enable ? "b_hnp:" : "", REC->a_hnp_support ? "a_hnp:" : "", REC->hnp_polling_support ? "hnp_poll:" : "", REC->host_request_flag ? "hostreq:" : "", REC->quirk_ep_out_aligned_size ? "out_aligned:" : "", REC->quirk_altset_not_supp ? "no_altset:" : "", REC->quirk_stall_not_supp ? "no_stall:" : "", REC->quirk_zlp_not_supp ? "no_zlp" : "", REC->is_selfpowered ? "self-powered:" : "bus-powered:", REC->deactivated ? "deactivated:" : "activated:", REC->connected ? "connected" : "disconnected", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_vbus_draw/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_vbus_draw/format
new file mode 100644
index 000000000..4e03d29fb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_vbus_draw/format
@@ -0,0 +1,29 @@
+name: usb_gadget_vbus_draw
+ID: 815
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum usb_device_speed speed; offset:8; size:4; signed:0;
+ field:enum usb_device_speed max_speed; offset:12; size:4; signed:0;
+ field:enum usb_device_state state; offset:16; size:4; signed:0;
+ field:unsigned mA; offset:20; size:4; signed:0;
+ field:unsigned sg_supported; offset:24; size:4; signed:0;
+ field:unsigned is_otg; offset:28; size:4; signed:0;
+ field:unsigned is_a_peripheral; offset:32; size:4; signed:0;
+ field:unsigned b_hnp_enable; offset:36; size:4; signed:0;
+ field:unsigned a_hnp_support; offset:40; size:4; signed:0;
+ field:unsigned hnp_polling_support; offset:44; size:4; signed:0;
+ field:unsigned host_request_flag; offset:48; size:4; signed:0;
+ field:unsigned quirk_ep_out_aligned_size; offset:52; size:4; signed:0;
+ field:unsigned quirk_altset_not_supp; offset:56; size:4; signed:0;
+ field:unsigned quirk_stall_not_supp; offset:60; size:4; signed:0;
+ field:unsigned quirk_zlp_not_supp; offset:64; size:4; signed:0;
+ field:unsigned is_selfpowered; offset:68; size:4; signed:0;
+ field:unsigned deactivated; offset:72; size:4; signed:0;
+ field:unsigned connected; offset:76; size:4; signed:0;
+ field:int ret; offset:80; size:4; signed:1;
+
+print fmt: "speed %d/%d state %d %dmA [%s%s%s%s%s%s%s%s%s%s%s%s%s%s] --> %d", REC->speed, REC->max_speed, REC->state, REC->mA, REC->sg_supported ? "sg:" : "", REC->is_otg ? "OTG:" : "", REC->is_a_peripheral ? "a_peripheral:" : "", REC->b_hnp_enable ? "b_hnp:" : "", REC->a_hnp_support ? "a_hnp:" : "", REC->hnp_polling_support ? "hnp_poll:" : "", REC->host_request_flag ? "hostreq:" : "", REC->quirk_ep_out_aligned_size ? "out_aligned:" : "", REC->quirk_altset_not_supp ? "no_altset:" : "", REC->quirk_stall_not_supp ? "no_stall:" : "", REC->quirk_zlp_not_supp ? "no_zlp" : "", REC->is_selfpowered ? "self-powered:" : "bus-powered:", REC->deactivated ? "deactivated:" : "activated:", REC->connected ? "connected" : "disconnected", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_wakeup/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_wakeup/format
new file mode 100644
index 000000000..788fb22ad
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gadget/usb_gadget_wakeup/format
@@ -0,0 +1,29 @@
+name: usb_gadget_wakeup
+ID: 816
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum usb_device_speed speed; offset:8; size:4; signed:0;
+ field:enum usb_device_speed max_speed; offset:12; size:4; signed:0;
+ field:enum usb_device_state state; offset:16; size:4; signed:0;
+ field:unsigned mA; offset:20; size:4; signed:0;
+ field:unsigned sg_supported; offset:24; size:4; signed:0;
+ field:unsigned is_otg; offset:28; size:4; signed:0;
+ field:unsigned is_a_peripheral; offset:32; size:4; signed:0;
+ field:unsigned b_hnp_enable; offset:36; size:4; signed:0;
+ field:unsigned a_hnp_support; offset:40; size:4; signed:0;
+ field:unsigned hnp_polling_support; offset:44; size:4; signed:0;
+ field:unsigned host_request_flag; offset:48; size:4; signed:0;
+ field:unsigned quirk_ep_out_aligned_size; offset:52; size:4; signed:0;
+ field:unsigned quirk_altset_not_supp; offset:56; size:4; signed:0;
+ field:unsigned quirk_stall_not_supp; offset:60; size:4; signed:0;
+ field:unsigned quirk_zlp_not_supp; offset:64; size:4; signed:0;
+ field:unsigned is_selfpowered; offset:68; size:4; signed:0;
+ field:unsigned deactivated; offset:72; size:4; signed:0;
+ field:unsigned connected; offset:76; size:4; signed:0;
+ field:int ret; offset:80; size:4; signed:1;
+
+print fmt: "speed %d/%d state %d %dmA [%s%s%s%s%s%s%s%s%s%s%s%s%s%s] --> %d", REC->speed, REC->max_speed, REC->state, REC->mA, REC->sg_supported ? "sg:" : "", REC->is_otg ? "OTG:" : "", REC->is_a_peripheral ? "a_peripheral:" : "", REC->b_hnp_enable ? "b_hnp:" : "", REC->a_hnp_support ? "a_hnp:" : "", REC->hnp_polling_support ? "hnp_poll:" : "", REC->host_request_flag ? "hostreq:" : "", REC->quirk_ep_out_aligned_size ? "out_aligned:" : "", REC->quirk_altset_not_supp ? "no_altset:" : "", REC->quirk_stall_not_supp ? "no_stall:" : "", REC->quirk_zlp_not_supp ? "no_zlp" : "", REC->is_selfpowered ? "self-powered:" : "bus-powered:", REC->deactivated ? "deactivated:" : "activated:", REC->connected ? "connected" : "disconnected", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gpio/gpio_direction/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gpio/gpio_direction/format
new file mode 100644
index 000000000..ee94e2bac
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gpio/gpio_direction/format
@@ -0,0 +1,13 @@
+name: gpio_direction
+ID: 613
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned gpio; offset:8; size:4; signed:0;
+ field:int in; offset:12; size:4; signed:1;
+ field:int err; offset:16; size:4; signed:1;
+
+print fmt: "%u %3s (%d)", REC->gpio, REC->in ? "in" : "out", REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gpio/gpio_value/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gpio/gpio_value/format
new file mode 100644
index 000000000..dfd1fa497
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gpio/gpio_value/format
@@ -0,0 +1,13 @@
+name: gpio_value
+ID: 614
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned gpio; offset:8; size:4; signed:0;
+ field:int get; offset:12; size:4; signed:1;
+ field:int value; offset:16; size:4; signed:1;
+
+print fmt: "%u %3s %d", REC->gpio, REC->get ? "get" : "set", REC->value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gpu_mem/gpu_mem_total/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gpu_mem/gpu_mem_total/format
new file mode 100644
index 000000000..895317edf
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/gpu_mem/gpu_mem_total/format
@@ -0,0 +1,13 @@
+name: gpu_mem_total
+ID: 670
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:uint32_t gpu_id; offset:8; size:4; signed:0;
+ field:uint32_t pid; offset:12; size:4; signed:0;
+ field:uint64_t size; offset:16; size:8; signed:0;
+
+print fmt: "gpu_id=%u pid=%u size=%llu", REC->gpu_id, REC->pid, REC->size
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/header_event b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/header_event
new file mode 100644
index 000000000..615ec1ceb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/header_event
@@ -0,0 +1,9 @@
+# compressed entry header
+ type_len : 5 bits
+ time_delta : 27 bits
+ array : 32 bits
+
+ padding : type == 29
+ time_extend : type == 30
+ time_stamp : type == 31
+ data max type_len == 28
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/header_page b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/header_page
new file mode 100644
index 000000000..d569267bc
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/header_page
@@ -0,0 +1,4 @@
+ field: u64 timestamp; offset:0; size:8; signed:0;
+ field: local_t commit; offset:8; size:8; signed:1;
+ field: int overwrite; offset:8; size:1; signed:1;
+ field: char data; offset:16; size:4080; signed:0;
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/huge_memory/mm_collapse_huge_page/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/huge_memory/mm_collapse_huge_page/format
new file mode 100644
index 000000000..e36b1401a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/huge_memory/mm_collapse_huge_page/format
@@ -0,0 +1,13 @@
+name: mm_collapse_huge_page
+ID: 285
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct mm_struct * mm; offset:8; size:8; signed:0;
+ field:int isolated; offset:16; size:4; signed:1;
+ field:int status; offset:20; size:4; signed:1;
+
+print fmt: "mm=%p, isolated=%d, status=%s", REC->mm, REC->isolated, __print_symbolic(REC->status, {0, "failed"}, {1, "succeeded"}, {2, "pmd_null"}, {3, "exceed_none_pte"}, {4, "exceed_swap_pte"}, {5, "exceed_shared_pte"}, {6, "pte_non_present"}, {7, "pte_uffd_wp"}, {8, "no_writable_page"}, {9, "lack_referenced_page"}, {10, "page_null"}, {11, "scan_aborted"}, {12, "not_suitable_page_count"}, {13, "page_not_in_lru"}, {14, "page_locked"}, {15, "page_not_anon"}, {16, "page_compound"}, {17, "no_process_for_page"}, {18, "vma_null"}, {19, "vma_check_failed"}, {20, "not_suitable_address_range"}, {21, "page_swap_cache"}, {22, "could_not_delete_page_from_lru"}, {23, "alloc_huge_page_failed"}, {24, "ccgroup_charge_failed"}, {25, "truncated"}, {26, "page_has_private"})
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/huge_memory/mm_collapse_huge_page_isolate/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/huge_memory/mm_collapse_huge_page_isolate/format
new file mode 100644
index 000000000..e18c5db83
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/huge_memory/mm_collapse_huge_page_isolate/format
@@ -0,0 +1,15 @@
+name: mm_collapse_huge_page_isolate
+ID: 286
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long pfn; offset:8; size:8; signed:0;
+ field:int none_or_zero; offset:16; size:4; signed:1;
+ field:int referenced; offset:20; size:4; signed:1;
+ field:bool writable; offset:24; size:1; signed:0;
+ field:int status; offset:28; size:4; signed:1;
+
+print fmt: "scan_pfn=0x%lx, none_or_zero=%d, referenced=%d, writable=%d, status=%s", REC->pfn, REC->none_or_zero, REC->referenced, REC->writable, __print_symbolic(REC->status, {0, "failed"}, {1, "succeeded"}, {2, "pmd_null"}, {3, "exceed_none_pte"}, {4, "exceed_swap_pte"}, {5, "exceed_shared_pte"}, {6, "pte_non_present"}, {7, "pte_uffd_wp"}, {8, "no_writable_page"}, {9, "lack_referenced_page"}, {10, "page_null"}, {11, "scan_aborted"}, {12, "not_suitable_page_count"}, {13, "page_not_in_lru"}, {14, "page_locked"}, {15, "page_not_anon"}, {16, "page_compound"}, {17, "no_process_for_page"}, {18, "vma_null"}, {19, "vma_check_failed"}, {20, "not_suitable_address_range"}, {21, "page_swap_cache"}, {22, "could_not_delete_page_from_lru"}, {23, "alloc_huge_page_failed"}, {24, "ccgroup_charge_failed"}, {25, "truncated"}, {26, "page_has_private"})
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/huge_memory/mm_collapse_huge_page_swapin/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/huge_memory/mm_collapse_huge_page_swapin/format
new file mode 100644
index 000000000..53c88a782
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/huge_memory/mm_collapse_huge_page_swapin/format
@@ -0,0 +1,14 @@
+name: mm_collapse_huge_page_swapin
+ID: 287
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct mm_struct * mm; offset:8; size:8; signed:0;
+ field:int swapped_in; offset:16; size:4; signed:1;
+ field:int referenced; offset:20; size:4; signed:1;
+ field:int ret; offset:24; size:4; signed:1;
+
+print fmt: "mm=%p, swapped_in=%d, referenced=%d, ret=%d", REC->mm, REC->swapped_in, REC->referenced, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/huge_memory/mm_khugepaged_scan_pmd/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/huge_memory/mm_khugepaged_scan_pmd/format
new file mode 100644
index 000000000..607e026f1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/huge_memory/mm_khugepaged_scan_pmd/format
@@ -0,0 +1,17 @@
+name: mm_khugepaged_scan_pmd
+ID: 288
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct mm_struct * mm; offset:8; size:8; signed:0;
+ field:unsigned long pfn; offset:16; size:8; signed:0;
+ field:bool writable; offset:24; size:1; signed:0;
+ field:int referenced; offset:28; size:4; signed:1;
+ field:int none_or_zero; offset:32; size:4; signed:1;
+ field:int status; offset:36; size:4; signed:1;
+ field:int unmapped; offset:40; size:4; signed:1;
+
+print fmt: "mm=%p, scan_pfn=0x%lx, writable=%d, referenced=%d, none_or_zero=%d, status=%s, unmapped=%d", REC->mm, REC->pfn, REC->writable, REC->referenced, REC->none_or_zero, __print_symbolic(REC->status, {0, "failed"}, {1, "succeeded"}, {2, "pmd_null"}, {3, "exceed_none_pte"}, {4, "exceed_swap_pte"}, {5, "exceed_shared_pte"}, {6, "pte_non_present"}, {7, "pte_uffd_wp"}, {8, "no_writable_page"}, {9, "lack_referenced_page"}, {10, "page_null"}, {11, "scan_aborted"}, {12, "not_suitable_page_count"}, {13, "page_not_in_lru"}, {14, "page_locked"}, {15, "page_not_anon"}, {16, "page_compound"}, {17, "no_process_for_page"}, {18, "vma_null"}, {19, "vma_check_failed"}, {20, "not_suitable_address_range"}, {21, "page_swap_cache"}, {22, "could_not_delete_page_from_lru"}, {23, "alloc_huge_page_failed"}, {24, "ccgroup_charge_failed"}, {25, "truncated"}, {26, "page_has_private"}), REC->unmapped
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/i2c/i2c_read/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/i2c/i2c_read/format
new file mode 100644
index 000000000..33e385e00
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/i2c/i2c_read/format
@@ -0,0 +1,15 @@
+name: i2c_read
+ID: 834
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int adapter_nr; offset:8; size:4; signed:1;
+ field:__u16 msg_nr; offset:12; size:2; signed:0;
+ field:__u16 addr; offset:14; size:2; signed:0;
+ field:__u16 flags; offset:16; size:2; signed:0;
+ field:__u16 len; offset:18; size:2; signed:0;
+
+print fmt: "i2c-%d #%u a=%03x f=%04x l=%u", REC->adapter_nr, REC->msg_nr, REC->addr, REC->flags, REC->len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/i2c/i2c_reply/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/i2c/i2c_reply/format
new file mode 100644
index 000000000..a493fb8e1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/i2c/i2c_reply/format
@@ -0,0 +1,16 @@
+name: i2c_reply
+ID: 835
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int adapter_nr; offset:8; size:4; signed:1;
+ field:__u16 msg_nr; offset:12; size:2; signed:0;
+ field:__u16 addr; offset:14; size:2; signed:0;
+ field:__u16 flags; offset:16; size:2; signed:0;
+ field:__u16 len; offset:18; size:2; signed:0;
+ field:__data_loc __u8[] buf; offset:20; size:4; signed:0;
+
+print fmt: "i2c-%d #%u a=%03x f=%04x l=%u [%*phD]", REC->adapter_nr, REC->msg_nr, REC->addr, REC->flags, REC->len, REC->len, __get_dynamic_array(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/i2c/i2c_result/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/i2c/i2c_result/format
new file mode 100644
index 000000000..1be3de3f1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/i2c/i2c_result/format
@@ -0,0 +1,13 @@
+name: i2c_result
+ID: 836
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int adapter_nr; offset:8; size:4; signed:1;
+ field:__u16 nr_msgs; offset:12; size:2; signed:0;
+ field:__s16 ret; offset:14; size:2; signed:1;
+
+print fmt: "i2c-%d n=%u ret=%d", REC->adapter_nr, REC->nr_msgs, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/i2c/i2c_write/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/i2c/i2c_write/format
new file mode 100644
index 000000000..58174e5d8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/i2c/i2c_write/format
@@ -0,0 +1,16 @@
+name: i2c_write
+ID: 837
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int adapter_nr; offset:8; size:4; signed:1;
+ field:__u16 msg_nr; offset:12; size:2; signed:0;
+ field:__u16 addr; offset:14; size:2; signed:0;
+ field:__u16 flags; offset:16; size:2; signed:0;
+ field:__u16 len; offset:18; size:2; signed:0;
+ field:__data_loc __u8[] buf; offset:20; size:4; signed:0;
+
+print fmt: "i2c-%d #%u a=%03x f=%04x l=%u [%*phD]", REC->adapter_nr, REC->msg_nr, REC->addr, REC->flags, REC->len, REC->len, __get_dynamic_array(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/initcall/initcall_finish/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/initcall/initcall_finish/format
new file mode 100644
index 000000000..17b0fbaac
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/initcall/initcall_finish/format
@@ -0,0 +1,12 @@
+name: initcall_finish
+ID: 17
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:initcall_t func; offset:8; size:8; signed:0;
+ field:int ret; offset:16; size:4; signed:1;
+
+print fmt: "func=%pS ret=%d", REC->func, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/initcall/initcall_level/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/initcall/initcall_level/format
new file mode 100644
index 000000000..63d9c88a1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/initcall/initcall_level/format
@@ -0,0 +1,11 @@
+name: initcall_level
+ID: 18
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] level; offset:8; size:4; signed:0;
+
+print fmt: "level=%s", __get_str(level)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/initcall/initcall_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/initcall/initcall_start/format
new file mode 100644
index 000000000..706713550
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/initcall/initcall_start/format
@@ -0,0 +1,11 @@
+name: initcall_start
+ID: 19
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:initcall_t func; offset:8; size:8; signed:0;
+
+print fmt: "func=%pS", REC->func
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/interconnect/icc_set_bw/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/interconnect/icc_set_bw/format
new file mode 100644
index 000000000..024a6490d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/interconnect/icc_set_bw/format
@@ -0,0 +1,17 @@
+name: icc_set_bw
+ID: 903
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] path_name; offset:8; size:4; signed:0;
+ field:__data_loc char[] dev; offset:12; size:4; signed:0;
+ field:__data_loc char[] node_name; offset:16; size:4; signed:0;
+ field:u32 avg_bw; offset:20; size:4; signed:0;
+ field:u32 peak_bw; offset:24; size:4; signed:0;
+ field:u32 node_avg_bw; offset:28; size:4; signed:0;
+ field:u32 node_peak_bw; offset:32; size:4; signed:0;
+
+print fmt: "path=%s dev=%s node=%s avg_bw=%u peak_bw=%u agg_avg=%u agg_peak=%u", __get_str(path_name), __get_str(dev), __get_str(node_name), REC->avg_bw, REC->peak_bw, REC->node_avg_bw, REC->node_peak_bw
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/interconnect/icc_set_bw_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/interconnect/icc_set_bw_end/format
new file mode 100644
index 000000000..116c499ca
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/interconnect/icc_set_bw_end/format
@@ -0,0 +1,13 @@
+name: icc_set_bw_end
+ID: 904
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] path_name; offset:8; size:4; signed:0;
+ field:__data_loc char[] dev; offset:12; size:4; signed:0;
+ field:int ret; offset:16; size:4; signed:1;
+
+print fmt: "path=%s dev=%s ret=%d", __get_str(path_name), __get_str(dev), REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_complete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_complete/format
new file mode 100644
index 000000000..8d6ab912c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_complete/format
@@ -0,0 +1,13 @@
+name: io_uring_complete
+ID: 334
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * ctx; offset:8; size:8; signed:0;
+ field:u64 user_data; offset:16; size:8; signed:0;
+ field:long res; offset:24; size:8; signed:1;
+
+print fmt: "ring %p, user_data 0x%llx, result %ld", REC->ctx, (unsigned long long)REC->user_data, REC->res
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_cqring_wait/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_cqring_wait/format
new file mode 100644
index 000000000..7d2dedda2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_cqring_wait/format
@@ -0,0 +1,12 @@
+name: io_uring_cqring_wait
+ID: 335
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * ctx; offset:8; size:8; signed:0;
+ field:int min_events; offset:16; size:4; signed:1;
+
+print fmt: "ring %p, min_events %d", REC->ctx, REC->min_events
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_create/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_create/format
new file mode 100644
index 000000000..df7ce67b3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_create/format
@@ -0,0 +1,15 @@
+name: io_uring_create
+ID: 336
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int fd; offset:8; size:4; signed:1;
+ field:void * ctx; offset:16; size:8; signed:0;
+ field:u32 sq_entries; offset:24; size:4; signed:0;
+ field:u32 cq_entries; offset:28; size:4; signed:0;
+ field:u32 flags; offset:32; size:4; signed:0;
+
+print fmt: "ring %p, fd %d sq size %d, cq size %d, flags %d", REC->ctx, REC->fd, REC->sq_entries, REC->cq_entries, REC->flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_defer/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_defer/format
new file mode 100644
index 000000000..788d1e690
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_defer/format
@@ -0,0 +1,13 @@
+name: io_uring_defer
+ID: 337
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * ctx; offset:8; size:8; signed:0;
+ field:void * req; offset:16; size:8; signed:0;
+ field:unsigned long long data; offset:24; size:8; signed:0;
+
+print fmt: "ring %p, request %p user_data %llu", REC->ctx, REC->req, REC->data
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_fail_link/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_fail_link/format
new file mode 100644
index 000000000..dfd416eaa
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_fail_link/format
@@ -0,0 +1,12 @@
+name: io_uring_fail_link
+ID: 338
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * req; offset:8; size:8; signed:0;
+ field:void * link; offset:16; size:8; signed:0;
+
+print fmt: "request %p, link %p", REC->req, REC->link
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_file_get/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_file_get/format
new file mode 100644
index 000000000..1aca74a78
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_file_get/format
@@ -0,0 +1,12 @@
+name: io_uring_file_get
+ID: 339
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * ctx; offset:8; size:8; signed:0;
+ field:int fd; offset:16; size:4; signed:1;
+
+print fmt: "ring %p, fd %d", REC->ctx, REC->fd
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_link/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_link/format
new file mode 100644
index 000000000..8c7f7cd55
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_link/format
@@ -0,0 +1,13 @@
+name: io_uring_link
+ID: 340
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * ctx; offset:8; size:8; signed:0;
+ field:void * req; offset:16; size:8; signed:0;
+ field:void * target_req; offset:24; size:8; signed:0;
+
+print fmt: "ring %p, request %p linked after %p", REC->ctx, REC->req, REC->target_req
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_poll_arm/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_poll_arm/format
new file mode 100644
index 000000000..5829c6fe1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_poll_arm/format
@@ -0,0 +1,15 @@
+name: io_uring_poll_arm
+ID: 341
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * ctx; offset:8; size:8; signed:0;
+ field:u8 opcode; offset:16; size:1; signed:0;
+ field:u64 user_data; offset:24; size:8; signed:0;
+ field:int mask; offset:32; size:4; signed:1;
+ field:int events; offset:36; size:4; signed:1;
+
+print fmt: "ring %p, op %d, data 0x%llx, mask 0x%x, events 0x%x", REC->ctx, REC->opcode, (unsigned long long) REC->user_data, REC->mask, REC->events
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_poll_wake/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_poll_wake/format
new file mode 100644
index 000000000..f522d488c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_poll_wake/format
@@ -0,0 +1,14 @@
+name: io_uring_poll_wake
+ID: 342
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * ctx; offset:8; size:8; signed:0;
+ field:u8 opcode; offset:16; size:1; signed:0;
+ field:u64 user_data; offset:24; size:8; signed:0;
+ field:int mask; offset:32; size:4; signed:1;
+
+print fmt: "ring %p, op %d, data 0x%llx, mask 0x%x", REC->ctx, REC->opcode, (unsigned long long) REC->user_data, REC->mask
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_queue_async_work/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_queue_async_work/format
new file mode 100644
index 000000000..58b681da9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_queue_async_work/format
@@ -0,0 +1,15 @@
+name: io_uring_queue_async_work
+ID: 343
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * ctx; offset:8; size:8; signed:0;
+ field:int rw; offset:16; size:4; signed:1;
+ field:void * req; offset:24; size:8; signed:0;
+ field:struct io_wq_work * work; offset:32; size:8; signed:0;
+ field:unsigned int flags; offset:40; size:4; signed:0;
+
+print fmt: "ring %p, request %p, flags %d, %s queue, work %p", REC->ctx, REC->req, REC->flags, REC->rw ? "hashed" : "normal", REC->work
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_register/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_register/format
new file mode 100644
index 000000000..232d408c7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_register/format
@@ -0,0 +1,16 @@
+name: io_uring_register
+ID: 344
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * ctx; offset:8; size:8; signed:0;
+ field:unsigned opcode; offset:16; size:4; signed:0;
+ field:unsigned nr_files; offset:20; size:4; signed:0;
+ field:unsigned nr_bufs; offset:24; size:4; signed:0;
+ field:bool eventfd; offset:28; size:1; signed:0;
+ field:long ret; offset:32; size:8; signed:1;
+
+print fmt: "ring %p, opcode %d, nr_user_files %d, nr_user_bufs %d, eventfd %d, ret %ld", REC->ctx, REC->opcode, REC->nr_files, REC->nr_bufs, REC->eventfd, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_submit_sqe/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_submit_sqe/format
new file mode 100644
index 000000000..f15f12908
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_submit_sqe/format
@@ -0,0 +1,15 @@
+name: io_uring_submit_sqe
+ID: 345
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * ctx; offset:8; size:8; signed:0;
+ field:u8 opcode; offset:16; size:1; signed:0;
+ field:u64 user_data; offset:24; size:8; signed:0;
+ field:bool force_nonblock; offset:32; size:1; signed:0;
+ field:bool sq_thread; offset:33; size:1; signed:0;
+
+print fmt: "ring %p, op %d, data 0x%llx, non block %d, sq_thread %d", REC->ctx, REC->opcode, (unsigned long long) REC->user_data, REC->force_nonblock, REC->sq_thread
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_task_add/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_task_add/format
new file mode 100644
index 000000000..0a539755e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_task_add/format
@@ -0,0 +1,14 @@
+name: io_uring_task_add
+ID: 346
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * ctx; offset:8; size:8; signed:0;
+ field:u8 opcode; offset:16; size:1; signed:0;
+ field:u64 user_data; offset:24; size:8; signed:0;
+ field:int mask; offset:32; size:4; signed:1;
+
+print fmt: "ring %p, op %d, data 0x%llx, mask %x", REC->ctx, REC->opcode, (unsigned long long) REC->user_data, REC->mask
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_task_run/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_task_run/format
new file mode 100644
index 000000000..af3848727
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/io_uring/io_uring_task_run/format
@@ -0,0 +1,13 @@
+name: io_uring_task_run
+ID: 347
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * ctx; offset:8; size:8; signed:0;
+ field:u8 opcode; offset:16; size:1; signed:0;
+ field:u64 user_data; offset:24; size:8; signed:0;
+
+print fmt: "ring %p, op %d, data 0x%llx", REC->ctx, REC->opcode, (unsigned long long) REC->user_data
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_inuse_adjust/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_inuse_adjust/format
new file mode 100644
index 000000000..506aef3d9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_inuse_adjust/format
@@ -0,0 +1,17 @@
+name: iocost_inuse_adjust
+ID: 604
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] devname; offset:8; size:4; signed:0;
+ field:__data_loc char[] cgroup; offset:12; size:4; signed:0;
+ field:u64 now; offset:16; size:8; signed:0;
+ field:u32 old_inuse; offset:24; size:4; signed:0;
+ field:u32 new_inuse; offset:28; size:4; signed:0;
+ field:u64 old_hweight_inuse; offset:32; size:8; signed:0;
+ field:u64 new_hweight_inuse; offset:40; size:8; signed:0;
+
+print fmt: "[%s:%s] now=%llu inuse=%u->%u hw_inuse=%llu->%llu", __get_str(devname), __get_str(cgroup), REC->now, REC->old_inuse, REC->new_inuse, REC->old_hweight_inuse, REC->new_hweight_inuse
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_inuse_shortage/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_inuse_shortage/format
new file mode 100644
index 000000000..c06c5bd7b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_inuse_shortage/format
@@ -0,0 +1,17 @@
+name: iocost_inuse_shortage
+ID: 605
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] devname; offset:8; size:4; signed:0;
+ field:__data_loc char[] cgroup; offset:12; size:4; signed:0;
+ field:u64 now; offset:16; size:8; signed:0;
+ field:u32 old_inuse; offset:24; size:4; signed:0;
+ field:u32 new_inuse; offset:28; size:4; signed:0;
+ field:u64 old_hweight_inuse; offset:32; size:8; signed:0;
+ field:u64 new_hweight_inuse; offset:40; size:8; signed:0;
+
+print fmt: "[%s:%s] now=%llu inuse=%u->%u hw_inuse=%llu->%llu", __get_str(devname), __get_str(cgroup), REC->now, REC->old_inuse, REC->new_inuse, REC->old_hweight_inuse, REC->new_hweight_inuse
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_inuse_transfer/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_inuse_transfer/format
new file mode 100644
index 000000000..123e8dd5c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_inuse_transfer/format
@@ -0,0 +1,17 @@
+name: iocost_inuse_transfer
+ID: 606
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] devname; offset:8; size:4; signed:0;
+ field:__data_loc char[] cgroup; offset:12; size:4; signed:0;
+ field:u64 now; offset:16; size:8; signed:0;
+ field:u32 old_inuse; offset:24; size:4; signed:0;
+ field:u32 new_inuse; offset:28; size:4; signed:0;
+ field:u64 old_hweight_inuse; offset:32; size:8; signed:0;
+ field:u64 new_hweight_inuse; offset:40; size:8; signed:0;
+
+print fmt: "[%s:%s] now=%llu inuse=%u->%u hw_inuse=%llu->%llu", __get_str(devname), __get_str(cgroup), REC->now, REC->old_inuse, REC->new_inuse, REC->old_hweight_inuse, REC->new_hweight_inuse
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_ioc_vrate_adj/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_ioc_vrate_adj/format
new file mode 100644
index 000000000..e6f487c48
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_ioc_vrate_adj/format
@@ -0,0 +1,19 @@
+name: iocost_ioc_vrate_adj
+ID: 607
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] devname; offset:8; size:4; signed:0;
+ field:u64 old_vrate; offset:16; size:8; signed:0;
+ field:u64 new_vrate; offset:24; size:8; signed:0;
+ field:int busy_level; offset:32; size:4; signed:1;
+ field:u32 read_missed_ppm; offset:36; size:4; signed:0;
+ field:u32 write_missed_ppm; offset:40; size:4; signed:0;
+ field:u32 rq_wait_pct; offset:44; size:4; signed:0;
+ field:int nr_lagging; offset:48; size:4; signed:1;
+ field:int nr_shortages; offset:52; size:4; signed:1;
+
+print fmt: "[%s] vrate=%llu->%llu busy=%d missed_ppm=%u:%u rq_wait_pct=%u lagging=%d shortages=%d", __get_str(devname), REC->old_vrate, REC->new_vrate, REC->busy_level, REC->read_missed_ppm, REC->write_missed_ppm, REC->rq_wait_pct, REC->nr_lagging, REC->nr_shortages
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_iocg_activate/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_iocg_activate/format
new file mode 100644
index 000000000..e77c0f3af
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_iocg_activate/format
@@ -0,0 +1,22 @@
+name: iocost_iocg_activate
+ID: 608
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] devname; offset:8; size:4; signed:0;
+ field:__data_loc char[] cgroup; offset:12; size:4; signed:0;
+ field:u64 now; offset:16; size:8; signed:0;
+ field:u64 vnow; offset:24; size:8; signed:0;
+ field:u64 vrate; offset:32; size:8; signed:0;
+ field:u64 last_period; offset:40; size:8; signed:0;
+ field:u64 cur_period; offset:48; size:8; signed:0;
+ field:u64 vtime; offset:56; size:8; signed:0;
+ field:u32 weight; offset:64; size:4; signed:0;
+ field:u32 inuse; offset:68; size:4; signed:0;
+ field:u64 hweight_active; offset:72; size:8; signed:0;
+ field:u64 hweight_inuse; offset:80; size:8; signed:0;
+
+print fmt: "[%s:%s] now=%llu:%llu vrate=%llu period=%llu->%llu vtime=%llu weight=%u/%u hweight=%llu/%llu", __get_str(devname), __get_str(cgroup), REC->now, REC->vnow, REC->vrate, REC->last_period, REC->cur_period, REC->vtime, REC->inuse, REC->weight, REC->hweight_inuse, REC->hweight_active
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_iocg_forgive_debt/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_iocg_forgive_debt/format
new file mode 100644
index 000000000..08407905c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iocost/iocost_iocg_forgive_debt/format
@@ -0,0 +1,19 @@
+name: iocost_iocg_forgive_debt
+ID: 609
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] devname; offset:8; size:4; signed:0;
+ field:__data_loc char[] cgroup; offset:12; size:4; signed:0;
+ field:u64 now; offset:16; size:8; signed:0;
+ field:u64 vnow; offset:24; size:8; signed:0;
+ field:u32 usage_pct; offset:32; size:4; signed:0;
+ field:u64 old_debt; offset:40; size:8; signed:0;
+ field:u64 new_debt; offset:48; size:8; signed:0;
+ field:u64 old_delay; offset:56; size:8; signed:0;
+ field:u64 new_delay; offset:64; size:8; signed:0;
+
+print fmt: "[%s:%s] now=%llu:%llu usage=%u debt=%llu->%llu delay=%llu->%llu", __get_str(devname), __get_str(cgroup), REC->now, REC->vnow, REC->usage_pct, REC->old_debt, REC->new_debt, REC->old_delay, REC->new_delay
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_apply/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_apply/format
new file mode 100644
index 000000000..38496d964
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_apply/format
@@ -0,0 +1,18 @@
+name: iomap_apply
+ID: 360
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:u64 ino; offset:16; size:8; signed:0;
+ field:loff_t pos; offset:24; size:8; signed:1;
+ field:loff_t length; offset:32; size:8; signed:1;
+ field:unsigned int flags; offset:40; size:4; signed:0;
+ field:const void * ops; offset:48; size:8; signed:0;
+ field:void * actor; offset:56; size:8; signed:0;
+ field:unsigned long caller; offset:64; size:8; signed:0;
+
+print fmt: "dev %d:%d ino 0x%llx pos %lld length %lld flags %s (0x%x) ops %ps caller %pS actor %ps", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->ino, REC->pos, REC->length, __print_flags(REC->flags, "|", { (1 << 0), "WRITE" }, { (1 << 1), "ZERO" }, { (1 << 2), "REPORT" }, { (1 << 3), "FAULT" }, { (1 << 4), "DIRECT" }, { (1 << 5), "NOWAIT" }), REC->flags, REC->ops, (void *)REC->caller, REC->actor
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_apply_dstmap/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_apply_dstmap/format
new file mode 100644
index 000000000..b10255234
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_apply_dstmap/format
@@ -0,0 +1,18 @@
+name: iomap_apply_dstmap
+ID: 361
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:u64 ino; offset:16; size:8; signed:0;
+ field:u64 addr; offset:24; size:8; signed:0;
+ field:loff_t offset; offset:32; size:8; signed:1;
+ field:u64 length; offset:40; size:8; signed:0;
+ field:u16 type; offset:48; size:2; signed:0;
+ field:u16 flags; offset:50; size:2; signed:0;
+ field:dev_t bdev; offset:52; size:4; signed:0;
+
+print fmt: "dev %d:%d ino 0x%llx bdev %d:%d addr %lld offset %lld length %llu type %s flags %s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->ino, ((unsigned int) ((REC->bdev) >> 20)), ((unsigned int) ((REC->bdev) & ((1U << 20) - 1))), REC->addr, REC->offset, REC->length, __print_symbolic(REC->type, { 0, "HOLE" }, { 1, "DELALLOC" }, { 2, "MAPPED" }, { 3, "UNWRITTEN" }, { 4, "INLINE" }), __print_flags(REC->flags, "|", { 0x01, "NEW" }, { 0x02, "DIRTY" }, { 0x04, "SHARED" }, { 0x08, "MERGED" }, { 0x10, "BH" }, { 0x100, "SIZE_CHANGED" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_apply_srcmap/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_apply_srcmap/format
new file mode 100644
index 000000000..7b3665105
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_apply_srcmap/format
@@ -0,0 +1,18 @@
+name: iomap_apply_srcmap
+ID: 362
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:u64 ino; offset:16; size:8; signed:0;
+ field:u64 addr; offset:24; size:8; signed:0;
+ field:loff_t offset; offset:32; size:8; signed:1;
+ field:u64 length; offset:40; size:8; signed:0;
+ field:u16 type; offset:48; size:2; signed:0;
+ field:u16 flags; offset:50; size:2; signed:0;
+ field:dev_t bdev; offset:52; size:4; signed:0;
+
+print fmt: "dev %d:%d ino 0x%llx bdev %d:%d addr %lld offset %lld length %llu type %s flags %s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->ino, ((unsigned int) ((REC->bdev) >> 20)), ((unsigned int) ((REC->bdev) & ((1U << 20) - 1))), REC->addr, REC->offset, REC->length, __print_symbolic(REC->type, { 0, "HOLE" }, { 1, "DELALLOC" }, { 2, "MAPPED" }, { 3, "UNWRITTEN" }, { 4, "INLINE" }), __print_flags(REC->flags, "|", { 0x01, "NEW" }, { 0x02, "DIRTY" }, { 0x04, "SHARED" }, { 0x08, "MERGED" }, { 0x10, "BH" }, { 0x100, "SIZE_CHANGED" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_dio_invalidate_fail/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_dio_invalidate_fail/format
new file mode 100644
index 000000000..84f01879f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_dio_invalidate_fail/format
@@ -0,0 +1,15 @@
+name: iomap_dio_invalidate_fail
+ID: 363
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:u64 ino; offset:16; size:8; signed:0;
+ field:loff_t size; offset:24; size:8; signed:1;
+ field:unsigned long offset; offset:32; size:8; signed:0;
+ field:unsigned int length; offset:40; size:4; signed:0;
+
+print fmt: "dev %d:%d ino 0x%llx size 0x%llx offset %lx length %x", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->ino, REC->size, REC->offset, REC->length
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_invalidatepage/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_invalidatepage/format
new file mode 100644
index 000000000..e03b304d1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_invalidatepage/format
@@ -0,0 +1,15 @@
+name: iomap_invalidatepage
+ID: 364
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:u64 ino; offset:16; size:8; signed:0;
+ field:loff_t size; offset:24; size:8; signed:1;
+ field:unsigned long offset; offset:32; size:8; signed:0;
+ field:unsigned int length; offset:40; size:4; signed:0;
+
+print fmt: "dev %d:%d ino 0x%llx size 0x%llx offset %lx length %x", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->ino, REC->size, REC->offset, REC->length
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_readahead/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_readahead/format
new file mode 100644
index 000000000..09a77a09d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_readahead/format
@@ -0,0 +1,13 @@
+name: iomap_readahead
+ID: 365
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:u64 ino; offset:16; size:8; signed:0;
+ field:int nr_pages; offset:24; size:4; signed:1;
+
+print fmt: "dev %d:%d ino 0x%llx nr_pages %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->ino, REC->nr_pages
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_readpage/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_readpage/format
new file mode 100644
index 000000000..2734bf5a1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_readpage/format
@@ -0,0 +1,13 @@
+name: iomap_readpage
+ID: 366
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:u64 ino; offset:16; size:8; signed:0;
+ field:int nr_pages; offset:24; size:4; signed:1;
+
+print fmt: "dev %d:%d ino 0x%llx nr_pages %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->ino, REC->nr_pages
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_releasepage/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_releasepage/format
new file mode 100644
index 000000000..691c4985b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_releasepage/format
@@ -0,0 +1,15 @@
+name: iomap_releasepage
+ID: 367
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:u64 ino; offset:16; size:8; signed:0;
+ field:loff_t size; offset:24; size:8; signed:1;
+ field:unsigned long offset; offset:32; size:8; signed:0;
+ field:unsigned int length; offset:40; size:4; signed:0;
+
+print fmt: "dev %d:%d ino 0x%llx size 0x%llx offset %lx length %x", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->ino, REC->size, REC->offset, REC->length
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_writepage/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_writepage/format
new file mode 100644
index 000000000..0ec7eb3c3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iomap/iomap_writepage/format
@@ -0,0 +1,15 @@
+name: iomap_writepage
+ID: 368
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:u64 ino; offset:16; size:8; signed:0;
+ field:loff_t size; offset:24; size:8; signed:1;
+ field:unsigned long offset; offset:32; size:8; signed:0;
+ field:unsigned int length; offset:40; size:4; signed:0;
+
+print fmt: "dev %d:%d ino 0x%llx size 0x%llx offset %lx length %x", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->ino, REC->size, REC->offset, REC->length
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/add_device_to_group/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/add_device_to_group/format
new file mode 100644
index 000000000..abf9d5662
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/add_device_to_group/format
@@ -0,0 +1,12 @@
+name: add_device_to_group
+ID: 660
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int gid; offset:8; size:4; signed:1;
+ field:__data_loc char[] device; offset:12; size:4; signed:0;
+
+print fmt: "IOMMU: groupID=%d device=%s", REC->gid, __get_str(device)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/attach_device_to_domain/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/attach_device_to_domain/format
new file mode 100644
index 000000000..edced81f2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/attach_device_to_domain/format
@@ -0,0 +1,11 @@
+name: attach_device_to_domain
+ID: 661
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] device; offset:8; size:4; signed:0;
+
+print fmt: "IOMMU: device=%s", __get_str(device)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/detach_device_from_domain/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/detach_device_from_domain/format
new file mode 100644
index 000000000..7e85dc7b8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/detach_device_from_domain/format
@@ -0,0 +1,11 @@
+name: detach_device_from_domain
+ID: 662
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] device; offset:8; size:4; signed:0;
+
+print fmt: "IOMMU: device=%s", __get_str(device)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/io_page_fault/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/io_page_fault/format
new file mode 100644
index 000000000..e14dc4958
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/io_page_fault/format
@@ -0,0 +1,14 @@
+name: io_page_fault
+ID: 663
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] device; offset:8; size:4; signed:0;
+ field:__data_loc char[] driver; offset:12; size:4; signed:0;
+ field:u64 iova; offset:16; size:8; signed:0;
+ field:int flags; offset:24; size:4; signed:1;
+
+print fmt: "IOMMU:%s %s iova=0x%016llx flags=0x%04x", __get_str(driver), __get_str(device), REC->iova, REC->flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/map/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/map/format
new file mode 100644
index 000000000..c290ee1c4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/map/format
@@ -0,0 +1,13 @@
+name: map
+ID: 664
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 iova; offset:8; size:8; signed:0;
+ field:u64 paddr; offset:16; size:8; signed:0;
+ field:size_t size; offset:24; size:8; signed:0;
+
+print fmt: "IOMMU: iova=0x%016llx paddr=0x%016llx size=%zu", REC->iova, REC->paddr, REC->size
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/remove_device_from_group/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/remove_device_from_group/format
new file mode 100644
index 000000000..b873fc051
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/remove_device_from_group/format
@@ -0,0 +1,12 @@
+name: remove_device_from_group
+ID: 665
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int gid; offset:8; size:4; signed:1;
+ field:__data_loc char[] device; offset:12; size:4; signed:0;
+
+print fmt: "IOMMU: groupID=%d device=%s", REC->gid, __get_str(device)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/unmap/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/unmap/format
new file mode 100644
index 000000000..7d2ebd1e7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/iommu/unmap/format
@@ -0,0 +1,13 @@
+name: unmap
+ID: 666
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 iova; offset:8; size:8; signed:0;
+ field:size_t size; offset:16; size:8; signed:0;
+ field:size_t unmapped_size; offset:24; size:8; signed:0;
+
+print fmt: "IOMMU: iova=0x%016llx size=%zu unmapped_size=%zu", REC->iova, REC->size, REC->unmapped_size
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ipi/ipi_entry/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ipi/ipi_entry/format
new file mode 100644
index 000000000..688c9c318
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ipi/ipi_entry/format
@@ -0,0 +1,11 @@
+name: ipi_entry
+ID: 22
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * reason; offset:8; size:8; signed:0;
+
+print fmt: "(%s)", REC->reason
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ipi/ipi_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ipi/ipi_exit/format
new file mode 100644
index 000000000..918af8fdd
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ipi/ipi_exit/format
@@ -0,0 +1,11 @@
+name: ipi_exit
+ID: 23
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * reason; offset:8; size:8; signed:0;
+
+print fmt: "(%s)", REC->reason
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ipi/ipi_raise/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ipi/ipi_raise/format
new file mode 100644
index 000000000..4c7689f53
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ipi/ipi_raise/format
@@ -0,0 +1,12 @@
+name: ipi_raise
+ID: 24
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc unsigned long[] target_cpus; offset:8; size:4; signed:0;
+ field:const char * reason; offset:16; size:8; signed:0;
+
+print fmt: "target_mask=%s (%s)", __get_bitmask(target_cpus), REC->reason
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/irq_handler_entry/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/irq_handler_entry/format
new file mode 100644
index 000000000..12c237644
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/irq_handler_entry/format
@@ -0,0 +1,12 @@
+name: irq_handler_entry
+ID: 69
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int irq; offset:8; size:4; signed:1;
+ field:__data_loc char[] name; offset:12; size:4; signed:0;
+
+print fmt: "irq=%d name=%s", REC->irq, __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/irq_handler_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/irq_handler_exit/format
new file mode 100644
index 000000000..aff6f1393
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/irq_handler_exit/format
@@ -0,0 +1,12 @@
+name: irq_handler_exit
+ID: 70
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int irq; offset:8; size:4; signed:1;
+ field:int ret; offset:12; size:4; signed:1;
+
+print fmt: "irq=%d ret=%s", REC->irq, REC->ret ? "handled" : "unhandled"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/softirq_entry/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/softirq_entry/format
new file mode 100644
index 000000000..94033fd5b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/softirq_entry/format
@@ -0,0 +1,11 @@
+name: softirq_entry
+ID: 71
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int vec; offset:8; size:4; signed:0;
+
+print fmt: "vec=%u [action=%s]", REC->vec, __print_symbolic(REC->vec, { 0, "HI" }, { 1, "TIMER" }, { 2, "NET_TX" }, { 3, "NET_RX" }, { 4, "BLOCK" }, { 5, "IRQ_POLL" }, { 6, "TASKLET" }, { 7, "SCHED" }, { 8, "HRTIMER" }, { 9, "RCU" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/softirq_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/softirq_exit/format
new file mode 100644
index 000000000..fad7a3e82
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/softirq_exit/format
@@ -0,0 +1,11 @@
+name: softirq_exit
+ID: 72
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int vec; offset:8; size:4; signed:0;
+
+print fmt: "vec=%u [action=%s]", REC->vec, __print_symbolic(REC->vec, { 0, "HI" }, { 1, "TIMER" }, { 2, "NET_TX" }, { 3, "NET_RX" }, { 4, "BLOCK" }, { 5, "IRQ_POLL" }, { 6, "TASKLET" }, { 7, "SCHED" }, { 8, "HRTIMER" }, { 9, "RCU" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/softirq_raise/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/softirq_raise/format
new file mode 100644
index 000000000..11e878a52
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/softirq_raise/format
@@ -0,0 +1,11 @@
+name: softirq_raise
+ID: 73
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int vec; offset:8; size:4; signed:0;
+
+print fmt: "vec=%u [action=%s]", REC->vec, __print_symbolic(REC->vec, { 0, "HI" }, { 1, "TIMER" }, { 2, "NET_TX" }, { 3, "NET_RX" }, { 4, "BLOCK" }, { 5, "IRQ_POLL" }, { 6, "TASKLET" }, { 7, "SCHED" }, { 8, "HRTIMER" }, { 9, "RCU" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/tasklet_entry/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/tasklet_entry/format
new file mode 100644
index 000000000..f81b50def
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/tasklet_entry/format
@@ -0,0 +1,11 @@
+name: tasklet_entry
+ID: 74
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * func; offset:8; size:8; signed:0;
+
+print fmt: "function=%ps", REC->func
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/tasklet_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/tasklet_exit/format
new file mode 100644
index 000000000..79ad8c837
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/tasklet_exit/format
@@ -0,0 +1,11 @@
+name: tasklet_exit
+ID: 75
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * func; offset:8; size:8; signed:0;
+
+print fmt: "function=%ps", REC->func
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/tasklet_hi_entry/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/tasklet_hi_entry/format
new file mode 100644
index 000000000..91e701fd3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/tasklet_hi_entry/format
@@ -0,0 +1,11 @@
+name: tasklet_hi_entry
+ID: 76
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * func; offset:8; size:8; signed:0;
+
+print fmt: "function=%ps", REC->func
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/tasklet_hi_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/tasklet_hi_exit/format
new file mode 100644
index 000000000..7b946fe1c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/irq/tasklet_hi_exit/format
@@ -0,0 +1,11 @@
+name: tasklet_hi_exit
+ID: 77
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * func; offset:8; size:8; signed:0;
+
+print fmt: "function=%ps", REC->func
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_checkpoint/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_checkpoint/format
new file mode 100644
index 000000000..11eb40136
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_checkpoint/format
@@ -0,0 +1,12 @@
+name: jbd2_checkpoint
+ID: 486
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int result; offset:12; size:4; signed:1;
+
+print fmt: "dev %d,%d result %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->result
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_checkpoint_stats/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_checkpoint_stats/format
new file mode 100644
index 000000000..7fd091e7f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_checkpoint_stats/format
@@ -0,0 +1,16 @@
+name: jbd2_checkpoint_stats
+ID: 487
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:unsigned long tid; offset:16; size:8; signed:0;
+ field:unsigned long chp_time; offset:24; size:8; signed:0;
+ field:__u32 forced_to_close; offset:32; size:4; signed:0;
+ field:__u32 written; offset:36; size:4; signed:0;
+ field:__u32 dropped; offset:40; size:4; signed:0;
+
+print fmt: "dev %d,%d tid %lu chp_time %u forced_to_close %u written %u dropped %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->tid, jiffies_to_msecs(REC->chp_time), REC->forced_to_close, REC->written, REC->dropped
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_commit_flushing/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_commit_flushing/format
new file mode 100644
index 000000000..45601997f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_commit_flushing/format
@@ -0,0 +1,13 @@
+name: jbd2_commit_flushing
+ID: 488
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:char sync_commit; offset:12; size:1; signed:0;
+ field:int transaction; offset:16; size:4; signed:1;
+
+print fmt: "dev %d,%d transaction %d sync %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->transaction, REC->sync_commit
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_commit_locking/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_commit_locking/format
new file mode 100644
index 000000000..3608655a3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_commit_locking/format
@@ -0,0 +1,13 @@
+name: jbd2_commit_locking
+ID: 489
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:char sync_commit; offset:12; size:1; signed:0;
+ field:int transaction; offset:16; size:4; signed:1;
+
+print fmt: "dev %d,%d transaction %d sync %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->transaction, REC->sync_commit
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_commit_logging/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_commit_logging/format
new file mode 100644
index 000000000..92ad72051
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_commit_logging/format
@@ -0,0 +1,13 @@
+name: jbd2_commit_logging
+ID: 490
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:char sync_commit; offset:12; size:1; signed:0;
+ field:int transaction; offset:16; size:4; signed:1;
+
+print fmt: "dev %d,%d transaction %d sync %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->transaction, REC->sync_commit
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_drop_transaction/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_drop_transaction/format
new file mode 100644
index 000000000..fdca1fcee
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_drop_transaction/format
@@ -0,0 +1,13 @@
+name: jbd2_drop_transaction
+ID: 491
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:char sync_commit; offset:12; size:1; signed:0;
+ field:int transaction; offset:16; size:4; signed:1;
+
+print fmt: "dev %d,%d transaction %d sync %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->transaction, REC->sync_commit
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_end_commit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_end_commit/format
new file mode 100644
index 000000000..b97c64ed3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_end_commit/format
@@ -0,0 +1,14 @@
+name: jbd2_end_commit
+ID: 492
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:char sync_commit; offset:12; size:1; signed:0;
+ field:int transaction; offset:16; size:4; signed:1;
+ field:int head; offset:20; size:4; signed:1;
+
+print fmt: "dev %d,%d transaction %d sync %d head %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->transaction, REC->sync_commit, REC->head
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_handle_extend/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_handle_extend/format
new file mode 100644
index 000000000..f182b029f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_handle_extend/format
@@ -0,0 +1,16 @@
+name: jbd2_handle_extend
+ID: 493
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:unsigned long tid; offset:16; size:8; signed:0;
+ field:unsigned int type; offset:24; size:4; signed:0;
+ field:unsigned int line_no; offset:28; size:4; signed:0;
+ field:int buffer_credits; offset:32; size:4; signed:1;
+ field:int requested_blocks; offset:36; size:4; signed:1;
+
+print fmt: "dev %d,%d tid %lu type %u line_no %u buffer_credits %d requested_blocks %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->tid, REC->type, REC->line_no, REC->buffer_credits, REC->requested_blocks
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_handle_restart/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_handle_restart/format
new file mode 100644
index 000000000..2733262de
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_handle_restart/format
@@ -0,0 +1,15 @@
+name: jbd2_handle_restart
+ID: 494
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:unsigned long tid; offset:16; size:8; signed:0;
+ field:unsigned int type; offset:24; size:4; signed:0;
+ field:unsigned int line_no; offset:28; size:4; signed:0;
+ field:int requested_blocks; offset:32; size:4; signed:1;
+
+print fmt: "dev %d,%d tid %lu type %u line_no %u requested_blocks %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->tid, REC->type, REC->line_no, REC->requested_blocks
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_handle_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_handle_start/format
new file mode 100644
index 000000000..63b297656
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_handle_start/format
@@ -0,0 +1,15 @@
+name: jbd2_handle_start
+ID: 495
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:unsigned long tid; offset:16; size:8; signed:0;
+ field:unsigned int type; offset:24; size:4; signed:0;
+ field:unsigned int line_no; offset:28; size:4; signed:0;
+ field:int requested_blocks; offset:32; size:4; signed:1;
+
+print fmt: "dev %d,%d tid %lu type %u line_no %u requested_blocks %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->tid, REC->type, REC->line_no, REC->requested_blocks
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_handle_stats/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_handle_stats/format
new file mode 100644
index 000000000..718d15479
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_handle_stats/format
@@ -0,0 +1,18 @@
+name: jbd2_handle_stats
+ID: 496
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:unsigned long tid; offset:16; size:8; signed:0;
+ field:unsigned int type; offset:24; size:4; signed:0;
+ field:unsigned int line_no; offset:28; size:4; signed:0;
+ field:int interval; offset:32; size:4; signed:1;
+ field:int sync; offset:36; size:4; signed:1;
+ field:int requested_blocks; offset:40; size:4; signed:1;
+ field:int dirtied_blocks; offset:44; size:4; signed:1;
+
+print fmt: "dev %d,%d tid %lu type %u line_no %u interval %d sync %d requested_blocks %d dirtied_blocks %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->tid, REC->type, REC->line_no, REC->interval, REC->sync, REC->requested_blocks, REC->dirtied_blocks
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_lock_buffer_stall/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_lock_buffer_stall/format
new file mode 100644
index 000000000..03c50e707
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_lock_buffer_stall/format
@@ -0,0 +1,12 @@
+name: jbd2_lock_buffer_stall
+ID: 497
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:unsigned long stall_ms; offset:16; size:8; signed:0;
+
+print fmt: "dev %d,%d stall_ms %lu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->stall_ms
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_run_stats/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_run_stats/format
new file mode 100644
index 000000000..ef50ba8ab
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_run_stats/format
@@ -0,0 +1,21 @@
+name: jbd2_run_stats
+ID: 498
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:unsigned long tid; offset:16; size:8; signed:0;
+ field:unsigned long wait; offset:24; size:8; signed:0;
+ field:unsigned long request_delay; offset:32; size:8; signed:0;
+ field:unsigned long running; offset:40; size:8; signed:0;
+ field:unsigned long locked; offset:48; size:8; signed:0;
+ field:unsigned long flushing; offset:56; size:8; signed:0;
+ field:unsigned long logging; offset:64; size:8; signed:0;
+ field:__u32 handle_count; offset:72; size:4; signed:0;
+ field:__u32 blocks; offset:76; size:4; signed:0;
+ field:__u32 blocks_logged; offset:80; size:4; signed:0;
+
+print fmt: "dev %d,%d tid %lu wait %u request_delay %u running %u locked %u flushing %u logging %u handle_count %u blocks %u blocks_logged %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->tid, jiffies_to_msecs(REC->wait), jiffies_to_msecs(REC->request_delay), jiffies_to_msecs(REC->running), jiffies_to_msecs(REC->locked), jiffies_to_msecs(REC->flushing), jiffies_to_msecs(REC->logging), REC->handle_count, REC->blocks, REC->blocks_logged
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_start_commit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_start_commit/format
new file mode 100644
index 000000000..c8f41f6bf
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_start_commit/format
@@ -0,0 +1,13 @@
+name: jbd2_start_commit
+ID: 499
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:char sync_commit; offset:12; size:1; signed:0;
+ field:int transaction; offset:16; size:4; signed:1;
+
+print fmt: "dev %d,%d transaction %d sync %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->transaction, REC->sync_commit
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_submit_inode_data/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_submit_inode_data/format
new file mode 100644
index 000000000..3b1f539a5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_submit_inode_data/format
@@ -0,0 +1,12 @@
+name: jbd2_submit_inode_data
+ID: 500
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+
+print fmt: "dev %d,%d ino %lu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_update_log_tail/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_update_log_tail/format
new file mode 100644
index 000000000..eda6b084e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_update_log_tail/format
@@ -0,0 +1,15 @@
+name: jbd2_update_log_tail
+ID: 501
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:tid_t tail_sequence; offset:12; size:4; signed:0;
+ field:tid_t first_tid; offset:16; size:4; signed:0;
+ field:unsigned long block_nr; offset:24; size:8; signed:0;
+ field:unsigned long freed; offset:32; size:8; signed:0;
+
+print fmt: "dev %d,%d from %u to %u offset %lu freed %lu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->tail_sequence, REC->first_tid, REC->block_nr, REC->freed
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_write_superblock/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_write_superblock/format
new file mode 100644
index 000000000..ee038e6cc
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/jbd2/jbd2_write_superblock/format
@@ -0,0 +1,12 @@
+name: jbd2_write_superblock
+ID: 502
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int write_op; offset:12; size:4; signed:1;
+
+print fmt: "dev %d,%d write_op %x", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->write_op
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kfree/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kfree/format
new file mode 100644
index 000000000..e0fdcda00
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kfree/format
@@ -0,0 +1,12 @@
+name: kfree
+ID: 249
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long call_site; offset:8; size:8; signed:0;
+ field:const void * ptr; offset:16; size:8; signed:0;
+
+print fmt: "call_site=%pS ptr=%p", (void *)REC->call_site, REC->ptr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kmalloc/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kmalloc/format
new file mode 100644
index 000000000..71a31a9b5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kmalloc/format
@@ -0,0 +1,15 @@
+name: kmalloc
+ID: 250
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long call_site; offset:8; size:8; signed:0;
+ field:const void * ptr; offset:16; size:8; signed:0;
+ field:size_t bytes_req; offset:24; size:8; signed:0;
+ field:size_t bytes_alloc; offset:32; size:8; signed:0;
+ field:gfp_t gfp_flags; offset:40; size:4; signed:0;
+
+print fmt: "call_site=%pS ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s", (void *)REC->call_site, REC->ptr, REC->bytes_req, REC->bytes_alloc, (REC->gfp_flags) ? __print_flags(REC->gfp_flags, "|", {(unsigned long)(((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))) | (( gfp_t)0x400u)), "GFP_TRANSHUGE"}, {(unsigned long)((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))), "GFP_TRANSHUGE_LIGHT"}, {(unsigned long)((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)), "GFP_HIGHUSER_MOVABLE"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)), "GFP_HIGHUSER"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)), "GFP_USER"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)) | (( gfp_t)0x400000u)), "GFP_KERNEL_ACCOUNT"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)), "GFP_KERNEL"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u)), "GFP_NOFS"}, {(unsigned long)((( gfp_t)0x20u)|(( gfp_t)0x200u)|(( gfp_t)0x800u)), "GFP_ATOMIC"}, {(unsigned long)((( gfp_t)(0x400u|0x800u))), "GFP_NOIO"}, {(unsigned long)((( gfp_t)0x800u)), "GFP_NOWAIT"}, {(unsigned long)(( gfp_t)0x01u), "GFP_DMA"}, {(unsigned long)(( gfp_t)0x02u), "__GFP_HIGHMEM"}, {(unsigned long)(( gfp_t)0x04u), "GFP_DMA32"}, {(unsigned long)(( gfp_t)0x20u), "__GFP_HIGH"}, {(unsigned long)(( gfp_t)0x200u), "__GFP_ATOMIC"}, {(unsigned long)(( gfp_t)0x40u), "__GFP_IO"}, {(unsigned long)(( gfp_t)0x80u), "__GFP_FS"}, {(unsigned long)(( gfp_t)0x2000u), "__GFP_NOWARN"}, {(unsigned long)(( gfp_t)0x4000u), "__GFP_RETRY_MAYFAIL"}, {(unsigned long)(( gfp_t)0x8000u), "__GFP_NOFAIL"}, {(unsigned long)(( gfp_t)0x10000u), "__GFP_NORETRY"}, {(unsigned long)(( gfp_t)0x40000u), "__GFP_COMP"}, {(unsigned long)(( gfp_t)0x100u), "__GFP_ZERO"}, {(unsigned long)(( gfp_t)0x80000u), "__GFP_NOMEMALLOC"}, {(unsigned long)(( gfp_t)0x20000u), "__GFP_MEMALLOC"}, {(unsigned long)(( gfp_t)0x100000u), "__GFP_HARDWALL"}, {(unsigned long)(( gfp_t)0x200000u), "__GFP_THISNODE"}, {(unsigned long)(( gfp_t)0x10u), "__GFP_RECLAIMABLE"}, {(unsigned long)(( gfp_t)0x08u), "__GFP_MOVABLE"}, {(unsigned long)(( gfp_t)0x400000u), "__GFP_ACCOUNT"}, {(unsigned long)(( gfp_t)0x1000u), "__GFP_WRITE"}, {(unsigned long)(( gfp_t)(0x400u|0x800u)), "__GFP_RECLAIM"}, {(unsigned long)(( gfp_t)0x400u), "__GFP_DIRECT_RECLAIM"}, {(unsigned long)(( gfp_t)0x800u), "__GFP_KSWAPD_RECLAIM"} ) : "none"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kmalloc_node/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kmalloc_node/format
new file mode 100644
index 000000000..62703c980
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kmalloc_node/format
@@ -0,0 +1,16 @@
+name: kmalloc_node
+ID: 251
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long call_site; offset:8; size:8; signed:0;
+ field:const void * ptr; offset:16; size:8; signed:0;
+ field:size_t bytes_req; offset:24; size:8; signed:0;
+ field:size_t bytes_alloc; offset:32; size:8; signed:0;
+ field:gfp_t gfp_flags; offset:40; size:4; signed:0;
+ field:int node; offset:44; size:4; signed:1;
+
+print fmt: "call_site=%pS ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d", (void *)REC->call_site, REC->ptr, REC->bytes_req, REC->bytes_alloc, (REC->gfp_flags) ? __print_flags(REC->gfp_flags, "|", {(unsigned long)(((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))) | (( gfp_t)0x400u)), "GFP_TRANSHUGE"}, {(unsigned long)((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))), "GFP_TRANSHUGE_LIGHT"}, {(unsigned long)((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)), "GFP_HIGHUSER_MOVABLE"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)), "GFP_HIGHUSER"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)), "GFP_USER"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)) | (( gfp_t)0x400000u)), "GFP_KERNEL_ACCOUNT"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)), "GFP_KERNEL"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u)), "GFP_NOFS"}, {(unsigned long)((( gfp_t)0x20u)|(( gfp_t)0x200u)|(( gfp_t)0x800u)), "GFP_ATOMIC"}, {(unsigned long)((( gfp_t)(0x400u|0x800u))), "GFP_NOIO"}, {(unsigned long)((( gfp_t)0x800u)), "GFP_NOWAIT"}, {(unsigned long)(( gfp_t)0x01u), "GFP_DMA"}, {(unsigned long)(( gfp_t)0x02u), "__GFP_HIGHMEM"}, {(unsigned long)(( gfp_t)0x04u), "GFP_DMA32"}, {(unsigned long)(( gfp_t)0x20u), "__GFP_HIGH"}, {(unsigned long)(( gfp_t)0x200u), "__GFP_ATOMIC"}, {(unsigned long)(( gfp_t)0x40u), "__GFP_IO"}, {(unsigned long)(( gfp_t)0x80u), "__GFP_FS"}, {(unsigned long)(( gfp_t)0x2000u), "__GFP_NOWARN"}, {(unsigned long)(( gfp_t)0x4000u), "__GFP_RETRY_MAYFAIL"}, {(unsigned long)(( gfp_t)0x8000u), "__GFP_NOFAIL"}, {(unsigned long)(( gfp_t)0x10000u), "__GFP_NORETRY"}, {(unsigned long)(( gfp_t)0x40000u), "__GFP_COMP"}, {(unsigned long)(( gfp_t)0x100u), "__GFP_ZERO"}, {(unsigned long)(( gfp_t)0x80000u), "__GFP_NOMEMALLOC"}, {(unsigned long)(( gfp_t)0x20000u), "__GFP_MEMALLOC"}, {(unsigned long)(( gfp_t)0x100000u), "__GFP_HARDWALL"}, {(unsigned long)(( gfp_t)0x200000u), "__GFP_THISNODE"}, {(unsigned long)(( gfp_t)0x10u), "__GFP_RECLAIMABLE"}, {(unsigned long)(( gfp_t)0x08u), "__GFP_MOVABLE"}, {(unsigned long)(( gfp_t)0x400000u), "__GFP_ACCOUNT"}, {(unsigned long)(( gfp_t)0x1000u), "__GFP_WRITE"}, {(unsigned long)(( gfp_t)(0x400u|0x800u)), "__GFP_RECLAIM"}, {(unsigned long)(( gfp_t)0x400u), "__GFP_DIRECT_RECLAIM"}, {(unsigned long)(( gfp_t)0x800u), "__GFP_KSWAPD_RECLAIM"} ) : "none", REC->node
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kmem_cache_alloc/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kmem_cache_alloc/format
new file mode 100644
index 000000000..13f765f43
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kmem_cache_alloc/format
@@ -0,0 +1,15 @@
+name: kmem_cache_alloc
+ID: 252
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long call_site; offset:8; size:8; signed:0;
+ field:const void * ptr; offset:16; size:8; signed:0;
+ field:size_t bytes_req; offset:24; size:8; signed:0;
+ field:size_t bytes_alloc; offset:32; size:8; signed:0;
+ field:gfp_t gfp_flags; offset:40; size:4; signed:0;
+
+print fmt: "call_site=%pS ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s", (void *)REC->call_site, REC->ptr, REC->bytes_req, REC->bytes_alloc, (REC->gfp_flags) ? __print_flags(REC->gfp_flags, "|", {(unsigned long)(((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))) | (( gfp_t)0x400u)), "GFP_TRANSHUGE"}, {(unsigned long)((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))), "GFP_TRANSHUGE_LIGHT"}, {(unsigned long)((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)), "GFP_HIGHUSER_MOVABLE"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)), "GFP_HIGHUSER"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)), "GFP_USER"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)) | (( gfp_t)0x400000u)), "GFP_KERNEL_ACCOUNT"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)), "GFP_KERNEL"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u)), "GFP_NOFS"}, {(unsigned long)((( gfp_t)0x20u)|(( gfp_t)0x200u)|(( gfp_t)0x800u)), "GFP_ATOMIC"}, {(unsigned long)((( gfp_t)(0x400u|0x800u))), "GFP_NOIO"}, {(unsigned long)((( gfp_t)0x800u)), "GFP_NOWAIT"}, {(unsigned long)(( gfp_t)0x01u), "GFP_DMA"}, {(unsigned long)(( gfp_t)0x02u), "__GFP_HIGHMEM"}, {(unsigned long)(( gfp_t)0x04u), "GFP_DMA32"}, {(unsigned long)(( gfp_t)0x20u), "__GFP_HIGH"}, {(unsigned long)(( gfp_t)0x200u), "__GFP_ATOMIC"}, {(unsigned long)(( gfp_t)0x40u), "__GFP_IO"}, {(unsigned long)(( gfp_t)0x80u), "__GFP_FS"}, {(unsigned long)(( gfp_t)0x2000u), "__GFP_NOWARN"}, {(unsigned long)(( gfp_t)0x4000u), "__GFP_RETRY_MAYFAIL"}, {(unsigned long)(( gfp_t)0x8000u), "__GFP_NOFAIL"}, {(unsigned long)(( gfp_t)0x10000u), "__GFP_NORETRY"}, {(unsigned long)(( gfp_t)0x40000u), "__GFP_COMP"}, {(unsigned long)(( gfp_t)0x100u), "__GFP_ZERO"}, {(unsigned long)(( gfp_t)0x80000u), "__GFP_NOMEMALLOC"}, {(unsigned long)(( gfp_t)0x20000u), "__GFP_MEMALLOC"}, {(unsigned long)(( gfp_t)0x100000u), "__GFP_HARDWALL"}, {(unsigned long)(( gfp_t)0x200000u), "__GFP_THISNODE"}, {(unsigned long)(( gfp_t)0x10u), "__GFP_RECLAIMABLE"}, {(unsigned long)(( gfp_t)0x08u), "__GFP_MOVABLE"}, {(unsigned long)(( gfp_t)0x400000u), "__GFP_ACCOUNT"}, {(unsigned long)(( gfp_t)0x1000u), "__GFP_WRITE"}, {(unsigned long)(( gfp_t)(0x400u|0x800u)), "__GFP_RECLAIM"}, {(unsigned long)(( gfp_t)0x400u), "__GFP_DIRECT_RECLAIM"}, {(unsigned long)(( gfp_t)0x800u), "__GFP_KSWAPD_RECLAIM"} ) : "none"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kmem_cache_alloc_node/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kmem_cache_alloc_node/format
new file mode 100644
index 000000000..ebcd6c0d1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kmem_cache_alloc_node/format
@@ -0,0 +1,16 @@
+name: kmem_cache_alloc_node
+ID: 253
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long call_site; offset:8; size:8; signed:0;
+ field:const void * ptr; offset:16; size:8; signed:0;
+ field:size_t bytes_req; offset:24; size:8; signed:0;
+ field:size_t bytes_alloc; offset:32; size:8; signed:0;
+ field:gfp_t gfp_flags; offset:40; size:4; signed:0;
+ field:int node; offset:44; size:4; signed:1;
+
+print fmt: "call_site=%pS ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d", (void *)REC->call_site, REC->ptr, REC->bytes_req, REC->bytes_alloc, (REC->gfp_flags) ? __print_flags(REC->gfp_flags, "|", {(unsigned long)(((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))) | (( gfp_t)0x400u)), "GFP_TRANSHUGE"}, {(unsigned long)((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))), "GFP_TRANSHUGE_LIGHT"}, {(unsigned long)((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)), "GFP_HIGHUSER_MOVABLE"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)), "GFP_HIGHUSER"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)), "GFP_USER"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)) | (( gfp_t)0x400000u)), "GFP_KERNEL_ACCOUNT"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)), "GFP_KERNEL"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u)), "GFP_NOFS"}, {(unsigned long)((( gfp_t)0x20u)|(( gfp_t)0x200u)|(( gfp_t)0x800u)), "GFP_ATOMIC"}, {(unsigned long)((( gfp_t)(0x400u|0x800u))), "GFP_NOIO"}, {(unsigned long)((( gfp_t)0x800u)), "GFP_NOWAIT"}, {(unsigned long)(( gfp_t)0x01u), "GFP_DMA"}, {(unsigned long)(( gfp_t)0x02u), "__GFP_HIGHMEM"}, {(unsigned long)(( gfp_t)0x04u), "GFP_DMA32"}, {(unsigned long)(( gfp_t)0x20u), "__GFP_HIGH"}, {(unsigned long)(( gfp_t)0x200u), "__GFP_ATOMIC"}, {(unsigned long)(( gfp_t)0x40u), "__GFP_IO"}, {(unsigned long)(( gfp_t)0x80u), "__GFP_FS"}, {(unsigned long)(( gfp_t)0x2000u), "__GFP_NOWARN"}, {(unsigned long)(( gfp_t)0x4000u), "__GFP_RETRY_MAYFAIL"}, {(unsigned long)(( gfp_t)0x8000u), "__GFP_NOFAIL"}, {(unsigned long)(( gfp_t)0x10000u), "__GFP_NORETRY"}, {(unsigned long)(( gfp_t)0x40000u), "__GFP_COMP"}, {(unsigned long)(( gfp_t)0x100u), "__GFP_ZERO"}, {(unsigned long)(( gfp_t)0x80000u), "__GFP_NOMEMALLOC"}, {(unsigned long)(( gfp_t)0x20000u), "__GFP_MEMALLOC"}, {(unsigned long)(( gfp_t)0x100000u), "__GFP_HARDWALL"}, {(unsigned long)(( gfp_t)0x200000u), "__GFP_THISNODE"}, {(unsigned long)(( gfp_t)0x10u), "__GFP_RECLAIMABLE"}, {(unsigned long)(( gfp_t)0x08u), "__GFP_MOVABLE"}, {(unsigned long)(( gfp_t)0x400000u), "__GFP_ACCOUNT"}, {(unsigned long)(( gfp_t)0x1000u), "__GFP_WRITE"}, {(unsigned long)(( gfp_t)(0x400u|0x800u)), "__GFP_RECLAIM"}, {(unsigned long)(( gfp_t)0x400u), "__GFP_DIRECT_RECLAIM"}, {(unsigned long)(( gfp_t)0x800u), "__GFP_KSWAPD_RECLAIM"} ) : "none", REC->node
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kmem_cache_free/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kmem_cache_free/format
new file mode 100644
index 000000000..d8d31b9fd
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/kmem_cache_free/format
@@ -0,0 +1,12 @@
+name: kmem_cache_free
+ID: 254
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long call_site; offset:8; size:8; signed:0;
+ field:const void * ptr; offset:16; size:8; signed:0;
+
+print fmt: "call_site=%pS ptr=%p", (void *)REC->call_site, REC->ptr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_alloc/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_alloc/format
new file mode 100644
index 000000000..a3004b423
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_alloc/format
@@ -0,0 +1,14 @@
+name: mm_page_alloc
+ID: 255
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long pfn; offset:8; size:8; signed:0;
+ field:unsigned int order; offset:16; size:4; signed:0;
+ field:gfp_t gfp_flags; offset:20; size:4; signed:0;
+ field:int migratetype; offset:24; size:4; signed:1;
+
+print fmt: "page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s", REC->pfn != -1UL ? (((struct page *)(-(((-((((1UL))) << ((((39))) - 1))) - ((-((((1UL))) << ((39)))))) >> (12 - (( __builtin_constant_p(sizeof(struct page)) ? ( ((sizeof(struct page)) == 0 || (sizeof(struct page)) == 1) ? 0 : ( __builtin_constant_p((sizeof(struct page)) - 1) ? ( __builtin_constant_p((sizeof(struct page)) - 1) ? ( ((sizeof(struct page)) - 1) < 2 ? 0 : ((sizeof(struct page)) - 1) & (1ULL << 63) ? 63 : ((sizeof(struct page)) - 1) & (1ULL << 62) ? 62 : ((sizeof(struct page)) - 1) & (1ULL << 61) ? 61 : ((sizeof(struct page)) - 1) & (1ULL << 60) ? 60 : ((sizeof(struct page)) - 1) & (1ULL << 59) ? 59 : ((sizeof(struct page)) - 1) & (1ULL << 58) ? 58 : ((sizeof(struct page)) - 1) & (1ULL << 57) ? 57 : ((sizeof(struct page)) - 1) & (1ULL << 56) ? 56 : ((sizeof(struct page)) - 1) & (1ULL << 55) ? 55 : ((sizeof(struct page)) - 1) & (1ULL << 54) ? 54 : ((sizeof(struct page)) - 1) & (1ULL << 53) ? 53 : ((sizeof(struct page)) - 1) & (1ULL << 52) ? 52 : ((sizeof(struct page)) - 1) & (1ULL << 51) ? 51 : ((sizeof(struct page)) - 1) & (1ULL << 50) ? 50 : ((sizeof(struct page)) - 1) & (1ULL << 49) ? 49 : ((sizeof(struct page)) - 1) & (1ULL << 48) ? 48 : ((sizeof(struct page)) - 1) & (1ULL << 47) ? 47 : ((sizeof(struct page)) - 1) & (1ULL << 46) ? 46 : ((sizeof(struct page)) - 1) & (1ULL << 45) ? 45 : ((sizeof(struct page)) - 1) & (1ULL << 44) ? 44 : ((sizeof(struct page)) - 1) & (1ULL << 43) ? 43 : ((sizeof(struct page)) - 1) & (1ULL << 42) ? 42 : ((sizeof(struct page)) - 1) & (1ULL << 41) ? 41 : ((sizeof(struct page)) - 1) & (1ULL << 40) ? 40 : ((sizeof(struct page)) - 1) & (1ULL << 39) ? 39 : ((sizeof(struct page)) - 1) & (1ULL << 38) ? 38 : ((sizeof(struct page)) - 1) & (1ULL << 37) ? 37 : ((sizeof(struct page)) - 1) & (1ULL << 36) ? 36 : ((sizeof(struct page)) - 1) & (1ULL << 35) ? 35 : ((sizeof(struct page)) - 1) & (1ULL << 34) ? 34 : ((sizeof(struct page)) - 1) & (1ULL << 33) ? 33 : ((sizeof(struct page)) - 1) & (1ULL << 32) ? 32 : ((sizeof(struct page)) - 1) & (1ULL << 31) ? 31 : ((sizeof(struct page)) - 1) & (1ULL << 30) ? 30 : ((sizeof(struct page)) - 1) & (1ULL << 29) ? 29 : ((sizeof(struct page)) - 1) & (1ULL << 28) ? 28 : ((sizeof(struct page)) - 1) & (1ULL << 27) ? 27 : ((sizeof(struct page)) - 1) & (1ULL << 26) ? 26 : ((sizeof(struct page)) - 1) & (1ULL << 25) ? 25 : ((sizeof(struct page)) - 1) & (1ULL << 24) ? 24 : ((sizeof(struct page)) - 1) & (1ULL << 23) ? 23 : ((sizeof(struct page)) - 1) & (1ULL << 22) ? 22 : ((sizeof(struct page)) - 1) & (1ULL << 21) ? 21 : ((sizeof(struct page)) - 1) & (1ULL << 20) ? 20 : ((sizeof(struct page)) - 1) & (1ULL << 19) ? 19 : ((sizeof(struct page)) - 1) & (1ULL << 18) ? 18 : ((sizeof(struct page)) - 1) & (1ULL << 17) ? 17 : ((sizeof(struct page)) - 1) & (1ULL << 16) ? 16 : ((sizeof(struct page)) - 1) & (1ULL << 15) ? 15 : ((sizeof(struct page)) - 1) & (1ULL << 14) ? 14 : ((sizeof(struct page)) - 1) & (1ULL << 13) ? 13 : ((sizeof(struct page)) - 1) & (1ULL << 12) ? 12 : ((sizeof(struct page)) - 1) & (1ULL << 11) ? 11 : ((sizeof(struct page)) - 1) & (1ULL << 10) ? 10 : ((sizeof(struct page)) - 1) & (1ULL << 9) ? 9 : ((sizeof(struct page)) - 1) & (1ULL << 8) ? 8 : ((sizeof(struct page)) - 1) & (1ULL << 7) ? 7 : ((sizeof(struct page)) - 1) & (1ULL << 6) ? 6 : ((sizeof(struct page)) - 1) & (1ULL << 5) ? 5 : ((sizeof(struct page)) - 1) & (1ULL << 4) ? 4 : ((sizeof(struct page)) - 1) & (1ULL << 3) ? 3 : ((sizeof(struct page)) - 1) & (1ULL << 2) ? 2 : 1) : -1) : (sizeof((sizeof(struct page)) - 1) <= 4) ? __ilog2_u32((sizeof(struct page)) - 1) : __ilog2_u64((sizeof(struct page)) - 1) ) + 1) : __order_base_2(sizeof(struct page)) )))) - 0x00200000) - (memstart_addr >> 12)) + (REC->pfn)) : ((void *)0), REC->pfn != -1UL ? REC->pfn : 0, REC->order, REC->migratetype, (REC->gfp_flags) ? __print_flags(REC->gfp_flags, "|", {(unsigned long)(((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))) | (( gfp_t)0x400u)), "GFP_TRANSHUGE"}, {(unsigned long)((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))), "GFP_TRANSHUGE_LIGHT"}, {(unsigned long)((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)), "GFP_HIGHUSER_MOVABLE"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)), "GFP_HIGHUSER"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)), "GFP_USER"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)) | (( gfp_t)0x400000u)), "GFP_KERNEL_ACCOUNT"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)), "GFP_KERNEL"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u)), "GFP_NOFS"}, {(unsigned long)((( gfp_t)0x20u)|(( gfp_t)0x200u)|(( gfp_t)0x800u)), "GFP_ATOMIC"}, {(unsigned long)((( gfp_t)(0x400u|0x800u))), "GFP_NOIO"}, {(unsigned long)((( gfp_t)0x800u)), "GFP_NOWAIT"}, {(unsigned long)(( gfp_t)0x01u), "GFP_DMA"}, {(unsigned long)(( gfp_t)0x02u), "__GFP_HIGHMEM"}, {(unsigned long)(( gfp_t)0x04u), "GFP_DMA32"}, {(unsigned long)(( gfp_t)0x20u), "__GFP_HIGH"}, {(unsigned long)(( gfp_t)0x200u), "__GFP_ATOMIC"}, {(unsigned long)(( gfp_t)0x40u), "__GFP_IO"}, {(unsigned long)(( gfp_t)0x80u), "__GFP_FS"}, {(unsigned long)(( gfp_t)0x2000u), "__GFP_NOWARN"}, {(unsigned long)(( gfp_t)0x4000u), "__GFP_RETRY_MAYFAIL"}, {(unsigned long)(( gfp_t)0x8000u), "__GFP_NOFAIL"}, {(unsigned long)(( gfp_t)0x10000u), "__GFP_NORETRY"}, {(unsigned long)(( gfp_t)0x40000u), "__GFP_COMP"}, {(unsigned long)(( gfp_t)0x100u), "__GFP_ZERO"}, {(unsigned long)(( gfp_t)0x80000u), "__GFP_NOMEMALLOC"}, {(unsigned long)(( gfp_t)0x20000u), "__GFP_MEMALLOC"}, {(unsigned long)(( gfp_t)0x100000u), "__GFP_HARDWALL"}, {(unsigned long)(( gfp_t)0x200000u), "__GFP_THISNODE"}, {(unsigned long)(( gfp_t)0x10u), "__GFP_RECLAIMABLE"}, {(unsigned long)(( gfp_t)0x08u), "__GFP_MOVABLE"}, {(unsigned long)(( gfp_t)0x400000u), "__GFP_ACCOUNT"}, {(unsigned long)(( gfp_t)0x1000u), "__GFP_WRITE"}, {(unsigned long)(( gfp_t)(0x400u|0x800u)), "__GFP_RECLAIM"}, {(unsigned long)(( gfp_t)0x400u), "__GFP_DIRECT_RECLAIM"}, {(unsigned long)(( gfp_t)0x800u), "__GFP_KSWAPD_RECLAIM"} ) : "none"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_alloc_extfrag/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_alloc_extfrag/format
new file mode 100644
index 000000000..c07e07490
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_alloc_extfrag/format
@@ -0,0 +1,16 @@
+name: mm_page_alloc_extfrag
+ID: 256
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long pfn; offset:8; size:8; signed:0;
+ field:int alloc_order; offset:16; size:4; signed:1;
+ field:int fallback_order; offset:20; size:4; signed:1;
+ field:int alloc_migratetype; offset:24; size:4; signed:1;
+ field:int fallback_migratetype; offset:28; size:4; signed:1;
+ field:int change_ownership; offset:32; size:4; signed:1;
+
+print fmt: "page=%p pfn=%lu alloc_order=%d fallback_order=%d pageblock_order=%d alloc_migratetype=%d fallback_migratetype=%d fragmenting=%d change_ownership=%d", (((struct page *)(-(((-((((1UL))) << ((((39))) - 1))) - ((-((((1UL))) << ((39)))))) >> (12 - (( __builtin_constant_p(sizeof(struct page)) ? ( ((sizeof(struct page)) == 0 || (sizeof(struct page)) == 1) ? 0 : ( __builtin_constant_p((sizeof(struct page)) - 1) ? ( __builtin_constant_p((sizeof(struct page)) - 1) ? ( ((sizeof(struct page)) - 1) < 2 ? 0 : ((sizeof(struct page)) - 1) & (1ULL << 63) ? 63 : ((sizeof(struct page)) - 1) & (1ULL << 62) ? 62 : ((sizeof(struct page)) - 1) & (1ULL << 61) ? 61 : ((sizeof(struct page)) - 1) & (1ULL << 60) ? 60 : ((sizeof(struct page)) - 1) & (1ULL << 59) ? 59 : ((sizeof(struct page)) - 1) & (1ULL << 58) ? 58 : ((sizeof(struct page)) - 1) & (1ULL << 57) ? 57 : ((sizeof(struct page)) - 1) & (1ULL << 56) ? 56 : ((sizeof(struct page)) - 1) & (1ULL << 55) ? 55 : ((sizeof(struct page)) - 1) & (1ULL << 54) ? 54 : ((sizeof(struct page)) - 1) & (1ULL << 53) ? 53 : ((sizeof(struct page)) - 1) & (1ULL << 52) ? 52 : ((sizeof(struct page)) - 1) & (1ULL << 51) ? 51 : ((sizeof(struct page)) - 1) & (1ULL << 50) ? 50 : ((sizeof(struct page)) - 1) & (1ULL << 49) ? 49 : ((sizeof(struct page)) - 1) & (1ULL << 48) ? 48 : ((sizeof(struct page)) - 1) & (1ULL << 47) ? 47 : ((sizeof(struct page)) - 1) & (1ULL << 46) ? 46 : ((sizeof(struct page)) - 1) & (1ULL << 45) ? 45 : ((sizeof(struct page)) - 1) & (1ULL << 44) ? 44 : ((sizeof(struct page)) - 1) & (1ULL << 43) ? 43 : ((sizeof(struct page)) - 1) & (1ULL << 42) ? 42 : ((sizeof(struct page)) - 1) & (1ULL << 41) ? 41 : ((sizeof(struct page)) - 1) & (1ULL << 40) ? 40 : ((sizeof(struct page)) - 1) & (1ULL << 39) ? 39 : ((sizeof(struct page)) - 1) & (1ULL << 38) ? 38 : ((sizeof(struct page)) - 1) & (1ULL << 37) ? 37 : ((sizeof(struct page)) - 1) & (1ULL << 36) ? 36 : ((sizeof(struct page)) - 1) & (1ULL << 35) ? 35 : ((sizeof(struct page)) - 1) & (1ULL << 34) ? 34 : ((sizeof(struct page)) - 1) & (1ULL << 33) ? 33 : ((sizeof(struct page)) - 1) & (1ULL << 32) ? 32 : ((sizeof(struct page)) - 1) & (1ULL << 31) ? 31 : ((sizeof(struct page)) - 1) & (1ULL << 30) ? 30 : ((sizeof(struct page)) - 1) & (1ULL << 29) ? 29 : ((sizeof(struct page)) - 1) & (1ULL << 28) ? 28 : ((sizeof(struct page)) - 1) & (1ULL << 27) ? 27 : ((sizeof(struct page)) - 1) & (1ULL << 26) ? 26 : ((sizeof(struct page)) - 1) & (1ULL << 25) ? 25 : ((sizeof(struct page)) - 1) & (1ULL << 24) ? 24 : ((sizeof(struct page)) - 1) & (1ULL << 23) ? 23 : ((sizeof(struct page)) - 1) & (1ULL << 22) ? 22 : ((sizeof(struct page)) - 1) & (1ULL << 21) ? 21 : ((sizeof(struct page)) - 1) & (1ULL << 20) ? 20 : ((sizeof(struct page)) - 1) & (1ULL << 19) ? 19 : ((sizeof(struct page)) - 1) & (1ULL << 18) ? 18 : ((sizeof(struct page)) - 1) & (1ULL << 17) ? 17 : ((sizeof(struct page)) - 1) & (1ULL << 16) ? 16 : ((sizeof(struct page)) - 1) & (1ULL << 15) ? 15 : ((sizeof(struct page)) - 1) & (1ULL << 14) ? 14 : ((sizeof(struct page)) - 1) & (1ULL << 13) ? 13 : ((sizeof(struct page)) - 1) & (1ULL << 12) ? 12 : ((sizeof(struct page)) - 1) & (1ULL << 11) ? 11 : ((sizeof(struct page)) - 1) & (1ULL << 10) ? 10 : ((sizeof(struct page)) - 1) & (1ULL << 9) ? 9 : ((sizeof(struct page)) - 1) & (1ULL << 8) ? 8 : ((sizeof(struct page)) - 1) & (1ULL << 7) ? 7 : ((sizeof(struct page)) - 1) & (1ULL << 6) ? 6 : ((sizeof(struct page)) - 1) & (1ULL << 5) ? 5 : ((sizeof(struct page)) - 1) & (1ULL << 4) ? 4 : ((sizeof(struct page)) - 1) & (1ULL << 3) ? 3 : ((sizeof(struct page)) - 1) & (1ULL << 2) ? 2 : 1) : -1) : (sizeof((sizeof(struct page)) - 1) <= 4) ? __ilog2_u32((sizeof(struct page)) - 1) : __ilog2_u64((sizeof(struct page)) - 1) ) + 1) : __order_base_2(sizeof(struct page)) )))) - 0x00200000) - (memstart_addr >> 12)) + (REC->pfn)), REC->pfn, REC->alloc_order, REC->fallback_order, (11-1), REC->alloc_migratetype, REC->fallback_migratetype, REC->fallback_order < (11-1), REC->change_ownership
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_alloc_zone_locked/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_alloc_zone_locked/format
new file mode 100644
index 000000000..0a4b16c9c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_alloc_zone_locked/format
@@ -0,0 +1,13 @@
+name: mm_page_alloc_zone_locked
+ID: 257
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long pfn; offset:8; size:8; signed:0;
+ field:unsigned int order; offset:16; size:4; signed:0;
+ field:int migratetype; offset:20; size:4; signed:1;
+
+print fmt: "page=%p pfn=%lu order=%u migratetype=%d percpu_refill=%d", REC->pfn != -1UL ? (((struct page *)(-(((-((((1UL))) << ((((39))) - 1))) - ((-((((1UL))) << ((39)))))) >> (12 - (( __builtin_constant_p(sizeof(struct page)) ? ( ((sizeof(struct page)) == 0 || (sizeof(struct page)) == 1) ? 0 : ( __builtin_constant_p((sizeof(struct page)) - 1) ? ( __builtin_constant_p((sizeof(struct page)) - 1) ? ( ((sizeof(struct page)) - 1) < 2 ? 0 : ((sizeof(struct page)) - 1) & (1ULL << 63) ? 63 : ((sizeof(struct page)) - 1) & (1ULL << 62) ? 62 : ((sizeof(struct page)) - 1) & (1ULL << 61) ? 61 : ((sizeof(struct page)) - 1) & (1ULL << 60) ? 60 : ((sizeof(struct page)) - 1) & (1ULL << 59) ? 59 : ((sizeof(struct page)) - 1) & (1ULL << 58) ? 58 : ((sizeof(struct page)) - 1) & (1ULL << 57) ? 57 : ((sizeof(struct page)) - 1) & (1ULL << 56) ? 56 : ((sizeof(struct page)) - 1) & (1ULL << 55) ? 55 : ((sizeof(struct page)) - 1) & (1ULL << 54) ? 54 : ((sizeof(struct page)) - 1) & (1ULL << 53) ? 53 : ((sizeof(struct page)) - 1) & (1ULL << 52) ? 52 : ((sizeof(struct page)) - 1) & (1ULL << 51) ? 51 : ((sizeof(struct page)) - 1) & (1ULL << 50) ? 50 : ((sizeof(struct page)) - 1) & (1ULL << 49) ? 49 : ((sizeof(struct page)) - 1) & (1ULL << 48) ? 48 : ((sizeof(struct page)) - 1) & (1ULL << 47) ? 47 : ((sizeof(struct page)) - 1) & (1ULL << 46) ? 46 : ((sizeof(struct page)) - 1) & (1ULL << 45) ? 45 : ((sizeof(struct page)) - 1) & (1ULL << 44) ? 44 : ((sizeof(struct page)) - 1) & (1ULL << 43) ? 43 : ((sizeof(struct page)) - 1) & (1ULL << 42) ? 42 : ((sizeof(struct page)) - 1) & (1ULL << 41) ? 41 : ((sizeof(struct page)) - 1) & (1ULL << 40) ? 40 : ((sizeof(struct page)) - 1) & (1ULL << 39) ? 39 : ((sizeof(struct page)) - 1) & (1ULL << 38) ? 38 : ((sizeof(struct page)) - 1) & (1ULL << 37) ? 37 : ((sizeof(struct page)) - 1) & (1ULL << 36) ? 36 : ((sizeof(struct page)) - 1) & (1ULL << 35) ? 35 : ((sizeof(struct page)) - 1) & (1ULL << 34) ? 34 : ((sizeof(struct page)) - 1) & (1ULL << 33) ? 33 : ((sizeof(struct page)) - 1) & (1ULL << 32) ? 32 : ((sizeof(struct page)) - 1) & (1ULL << 31) ? 31 : ((sizeof(struct page)) - 1) & (1ULL << 30) ? 30 : ((sizeof(struct page)) - 1) & (1ULL << 29) ? 29 : ((sizeof(struct page)) - 1) & (1ULL << 28) ? 28 : ((sizeof(struct page)) - 1) & (1ULL << 27) ? 27 : ((sizeof(struct page)) - 1) & (1ULL << 26) ? 26 : ((sizeof(struct page)) - 1) & (1ULL << 25) ? 25 : ((sizeof(struct page)) - 1) & (1ULL << 24) ? 24 : ((sizeof(struct page)) - 1) & (1ULL << 23) ? 23 : ((sizeof(struct page)) - 1) & (1ULL << 22) ? 22 : ((sizeof(struct page)) - 1) & (1ULL << 21) ? 21 : ((sizeof(struct page)) - 1) & (1ULL << 20) ? 20 : ((sizeof(struct page)) - 1) & (1ULL << 19) ? 19 : ((sizeof(struct page)) - 1) & (1ULL << 18) ? 18 : ((sizeof(struct page)) - 1) & (1ULL << 17) ? 17 : ((sizeof(struct page)) - 1) & (1ULL << 16) ? 16 : ((sizeof(struct page)) - 1) & (1ULL << 15) ? 15 : ((sizeof(struct page)) - 1) & (1ULL << 14) ? 14 : ((sizeof(struct page)) - 1) & (1ULL << 13) ? 13 : ((sizeof(struct page)) - 1) & (1ULL << 12) ? 12 : ((sizeof(struct page)) - 1) & (1ULL << 11) ? 11 : ((sizeof(struct page)) - 1) & (1ULL << 10) ? 10 : ((sizeof(struct page)) - 1) & (1ULL << 9) ? 9 : ((sizeof(struct page)) - 1) & (1ULL << 8) ? 8 : ((sizeof(struct page)) - 1) & (1ULL << 7) ? 7 : ((sizeof(struct page)) - 1) & (1ULL << 6) ? 6 : ((sizeof(struct page)) - 1) & (1ULL << 5) ? 5 : ((sizeof(struct page)) - 1) & (1ULL << 4) ? 4 : ((sizeof(struct page)) - 1) & (1ULL << 3) ? 3 : ((sizeof(struct page)) - 1) & (1ULL << 2) ? 2 : 1) : -1) : (sizeof((sizeof(struct page)) - 1) <= 4) ? __ilog2_u32((sizeof(struct page)) - 1) : __ilog2_u64((sizeof(struct page)) - 1) ) + 1) : __order_base_2(sizeof(struct page)) )))) - 0x00200000) - (memstart_addr >> 12)) + (REC->pfn)) : ((void *)0), REC->pfn != -1UL ? REC->pfn : 0, REC->order, REC->migratetype, REC->order == 0
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_free/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_free/format
new file mode 100644
index 000000000..ffec50d6d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_free/format
@@ -0,0 +1,12 @@
+name: mm_page_free
+ID: 258
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long pfn; offset:8; size:8; signed:0;
+ field:unsigned int order; offset:16; size:4; signed:0;
+
+print fmt: "page=%p pfn=%lu order=%d", (((struct page *)(-(((-((((1UL))) << ((((39))) - 1))) - ((-((((1UL))) << ((39)))))) >> (12 - (( __builtin_constant_p(sizeof(struct page)) ? ( ((sizeof(struct page)) == 0 || (sizeof(struct page)) == 1) ? 0 : ( __builtin_constant_p((sizeof(struct page)) - 1) ? ( __builtin_constant_p((sizeof(struct page)) - 1) ? ( ((sizeof(struct page)) - 1) < 2 ? 0 : ((sizeof(struct page)) - 1) & (1ULL << 63) ? 63 : ((sizeof(struct page)) - 1) & (1ULL << 62) ? 62 : ((sizeof(struct page)) - 1) & (1ULL << 61) ? 61 : ((sizeof(struct page)) - 1) & (1ULL << 60) ? 60 : ((sizeof(struct page)) - 1) & (1ULL << 59) ? 59 : ((sizeof(struct page)) - 1) & (1ULL << 58) ? 58 : ((sizeof(struct page)) - 1) & (1ULL << 57) ? 57 : ((sizeof(struct page)) - 1) & (1ULL << 56) ? 56 : ((sizeof(struct page)) - 1) & (1ULL << 55) ? 55 : ((sizeof(struct page)) - 1) & (1ULL << 54) ? 54 : ((sizeof(struct page)) - 1) & (1ULL << 53) ? 53 : ((sizeof(struct page)) - 1) & (1ULL << 52) ? 52 : ((sizeof(struct page)) - 1) & (1ULL << 51) ? 51 : ((sizeof(struct page)) - 1) & (1ULL << 50) ? 50 : ((sizeof(struct page)) - 1) & (1ULL << 49) ? 49 : ((sizeof(struct page)) - 1) & (1ULL << 48) ? 48 : ((sizeof(struct page)) - 1) & (1ULL << 47) ? 47 : ((sizeof(struct page)) - 1) & (1ULL << 46) ? 46 : ((sizeof(struct page)) - 1) & (1ULL << 45) ? 45 : ((sizeof(struct page)) - 1) & (1ULL << 44) ? 44 : ((sizeof(struct page)) - 1) & (1ULL << 43) ? 43 : ((sizeof(struct page)) - 1) & (1ULL << 42) ? 42 : ((sizeof(struct page)) - 1) & (1ULL << 41) ? 41 : ((sizeof(struct page)) - 1) & (1ULL << 40) ? 40 : ((sizeof(struct page)) - 1) & (1ULL << 39) ? 39 : ((sizeof(struct page)) - 1) & (1ULL << 38) ? 38 : ((sizeof(struct page)) - 1) & (1ULL << 37) ? 37 : ((sizeof(struct page)) - 1) & (1ULL << 36) ? 36 : ((sizeof(struct page)) - 1) & (1ULL << 35) ? 35 : ((sizeof(struct page)) - 1) & (1ULL << 34) ? 34 : ((sizeof(struct page)) - 1) & (1ULL << 33) ? 33 : ((sizeof(struct page)) - 1) & (1ULL << 32) ? 32 : ((sizeof(struct page)) - 1) & (1ULL << 31) ? 31 : ((sizeof(struct page)) - 1) & (1ULL << 30) ? 30 : ((sizeof(struct page)) - 1) & (1ULL << 29) ? 29 : ((sizeof(struct page)) - 1) & (1ULL << 28) ? 28 : ((sizeof(struct page)) - 1) & (1ULL << 27) ? 27 : ((sizeof(struct page)) - 1) & (1ULL << 26) ? 26 : ((sizeof(struct page)) - 1) & (1ULL << 25) ? 25 : ((sizeof(struct page)) - 1) & (1ULL << 24) ? 24 : ((sizeof(struct page)) - 1) & (1ULL << 23) ? 23 : ((sizeof(struct page)) - 1) & (1ULL << 22) ? 22 : ((sizeof(struct page)) - 1) & (1ULL << 21) ? 21 : ((sizeof(struct page)) - 1) & (1ULL << 20) ? 20 : ((sizeof(struct page)) - 1) & (1ULL << 19) ? 19 : ((sizeof(struct page)) - 1) & (1ULL << 18) ? 18 : ((sizeof(struct page)) - 1) & (1ULL << 17) ? 17 : ((sizeof(struct page)) - 1) & (1ULL << 16) ? 16 : ((sizeof(struct page)) - 1) & (1ULL << 15) ? 15 : ((sizeof(struct page)) - 1) & (1ULL << 14) ? 14 : ((sizeof(struct page)) - 1) & (1ULL << 13) ? 13 : ((sizeof(struct page)) - 1) & (1ULL << 12) ? 12 : ((sizeof(struct page)) - 1) & (1ULL << 11) ? 11 : ((sizeof(struct page)) - 1) & (1ULL << 10) ? 10 : ((sizeof(struct page)) - 1) & (1ULL << 9) ? 9 : ((sizeof(struct page)) - 1) & (1ULL << 8) ? 8 : ((sizeof(struct page)) - 1) & (1ULL << 7) ? 7 : ((sizeof(struct page)) - 1) & (1ULL << 6) ? 6 : ((sizeof(struct page)) - 1) & (1ULL << 5) ? 5 : ((sizeof(struct page)) - 1) & (1ULL << 4) ? 4 : ((sizeof(struct page)) - 1) & (1ULL << 3) ? 3 : ((sizeof(struct page)) - 1) & (1ULL << 2) ? 2 : 1) : -1) : (sizeof((sizeof(struct page)) - 1) <= 4) ? __ilog2_u32((sizeof(struct page)) - 1) : __ilog2_u64((sizeof(struct page)) - 1) ) + 1) : __order_base_2(sizeof(struct page)) )))) - 0x00200000) - (memstart_addr >> 12)) + (REC->pfn)), REC->pfn, REC->order
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_free_batched/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_free_batched/format
new file mode 100644
index 000000000..4941f7cae
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_free_batched/format
@@ -0,0 +1,11 @@
+name: mm_page_free_batched
+ID: 259
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long pfn; offset:8; size:8; signed:0;
+
+print fmt: "page=%p pfn=%lu order=0", (((struct page *)(-(((-((((1UL))) << ((((39))) - 1))) - ((-((((1UL))) << ((39)))))) >> (12 - (( __builtin_constant_p(sizeof(struct page)) ? ( ((sizeof(struct page)) == 0 || (sizeof(struct page)) == 1) ? 0 : ( __builtin_constant_p((sizeof(struct page)) - 1) ? ( __builtin_constant_p((sizeof(struct page)) - 1) ? ( ((sizeof(struct page)) - 1) < 2 ? 0 : ((sizeof(struct page)) - 1) & (1ULL << 63) ? 63 : ((sizeof(struct page)) - 1) & (1ULL << 62) ? 62 : ((sizeof(struct page)) - 1) & (1ULL << 61) ? 61 : ((sizeof(struct page)) - 1) & (1ULL << 60) ? 60 : ((sizeof(struct page)) - 1) & (1ULL << 59) ? 59 : ((sizeof(struct page)) - 1) & (1ULL << 58) ? 58 : ((sizeof(struct page)) - 1) & (1ULL << 57) ? 57 : ((sizeof(struct page)) - 1) & (1ULL << 56) ? 56 : ((sizeof(struct page)) - 1) & (1ULL << 55) ? 55 : ((sizeof(struct page)) - 1) & (1ULL << 54) ? 54 : ((sizeof(struct page)) - 1) & (1ULL << 53) ? 53 : ((sizeof(struct page)) - 1) & (1ULL << 52) ? 52 : ((sizeof(struct page)) - 1) & (1ULL << 51) ? 51 : ((sizeof(struct page)) - 1) & (1ULL << 50) ? 50 : ((sizeof(struct page)) - 1) & (1ULL << 49) ? 49 : ((sizeof(struct page)) - 1) & (1ULL << 48) ? 48 : ((sizeof(struct page)) - 1) & (1ULL << 47) ? 47 : ((sizeof(struct page)) - 1) & (1ULL << 46) ? 46 : ((sizeof(struct page)) - 1) & (1ULL << 45) ? 45 : ((sizeof(struct page)) - 1) & (1ULL << 44) ? 44 : ((sizeof(struct page)) - 1) & (1ULL << 43) ? 43 : ((sizeof(struct page)) - 1) & (1ULL << 42) ? 42 : ((sizeof(struct page)) - 1) & (1ULL << 41) ? 41 : ((sizeof(struct page)) - 1) & (1ULL << 40) ? 40 : ((sizeof(struct page)) - 1) & (1ULL << 39) ? 39 : ((sizeof(struct page)) - 1) & (1ULL << 38) ? 38 : ((sizeof(struct page)) - 1) & (1ULL << 37) ? 37 : ((sizeof(struct page)) - 1) & (1ULL << 36) ? 36 : ((sizeof(struct page)) - 1) & (1ULL << 35) ? 35 : ((sizeof(struct page)) - 1) & (1ULL << 34) ? 34 : ((sizeof(struct page)) - 1) & (1ULL << 33) ? 33 : ((sizeof(struct page)) - 1) & (1ULL << 32) ? 32 : ((sizeof(struct page)) - 1) & (1ULL << 31) ? 31 : ((sizeof(struct page)) - 1) & (1ULL << 30) ? 30 : ((sizeof(struct page)) - 1) & (1ULL << 29) ? 29 : ((sizeof(struct page)) - 1) & (1ULL << 28) ? 28 : ((sizeof(struct page)) - 1) & (1ULL << 27) ? 27 : ((sizeof(struct page)) - 1) & (1ULL << 26) ? 26 : ((sizeof(struct page)) - 1) & (1ULL << 25) ? 25 : ((sizeof(struct page)) - 1) & (1ULL << 24) ? 24 : ((sizeof(struct page)) - 1) & (1ULL << 23) ? 23 : ((sizeof(struct page)) - 1) & (1ULL << 22) ? 22 : ((sizeof(struct page)) - 1) & (1ULL << 21) ? 21 : ((sizeof(struct page)) - 1) & (1ULL << 20) ? 20 : ((sizeof(struct page)) - 1) & (1ULL << 19) ? 19 : ((sizeof(struct page)) - 1) & (1ULL << 18) ? 18 : ((sizeof(struct page)) - 1) & (1ULL << 17) ? 17 : ((sizeof(struct page)) - 1) & (1ULL << 16) ? 16 : ((sizeof(struct page)) - 1) & (1ULL << 15) ? 15 : ((sizeof(struct page)) - 1) & (1ULL << 14) ? 14 : ((sizeof(struct page)) - 1) & (1ULL << 13) ? 13 : ((sizeof(struct page)) - 1) & (1ULL << 12) ? 12 : ((sizeof(struct page)) - 1) & (1ULL << 11) ? 11 : ((sizeof(struct page)) - 1) & (1ULL << 10) ? 10 : ((sizeof(struct page)) - 1) & (1ULL << 9) ? 9 : ((sizeof(struct page)) - 1) & (1ULL << 8) ? 8 : ((sizeof(struct page)) - 1) & (1ULL << 7) ? 7 : ((sizeof(struct page)) - 1) & (1ULL << 6) ? 6 : ((sizeof(struct page)) - 1) & (1ULL << 5) ? 5 : ((sizeof(struct page)) - 1) & (1ULL << 4) ? 4 : ((sizeof(struct page)) - 1) & (1ULL << 3) ? 3 : ((sizeof(struct page)) - 1) & (1ULL << 2) ? 2 : 1) : -1) : (sizeof((sizeof(struct page)) - 1) <= 4) ? __ilog2_u32((sizeof(struct page)) - 1) : __ilog2_u64((sizeof(struct page)) - 1) ) + 1) : __order_base_2(sizeof(struct page)) )))) - 0x00200000) - (memstart_addr >> 12)) + (REC->pfn)), REC->pfn
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_pcpu_drain/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_pcpu_drain/format
new file mode 100644
index 000000000..bf8a5535c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/mm_page_pcpu_drain/format
@@ -0,0 +1,13 @@
+name: mm_page_pcpu_drain
+ID: 260
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long pfn; offset:8; size:8; signed:0;
+ field:unsigned int order; offset:16; size:4; signed:0;
+ field:int migratetype; offset:20; size:4; signed:1;
+
+print fmt: "page=%p pfn=%lu order=%d migratetype=%d", (((struct page *)(-(((-((((1UL))) << ((((39))) - 1))) - ((-((((1UL))) << ((39)))))) >> (12 - (( __builtin_constant_p(sizeof(struct page)) ? ( ((sizeof(struct page)) == 0 || (sizeof(struct page)) == 1) ? 0 : ( __builtin_constant_p((sizeof(struct page)) - 1) ? ( __builtin_constant_p((sizeof(struct page)) - 1) ? ( ((sizeof(struct page)) - 1) < 2 ? 0 : ((sizeof(struct page)) - 1) & (1ULL << 63) ? 63 : ((sizeof(struct page)) - 1) & (1ULL << 62) ? 62 : ((sizeof(struct page)) - 1) & (1ULL << 61) ? 61 : ((sizeof(struct page)) - 1) & (1ULL << 60) ? 60 : ((sizeof(struct page)) - 1) & (1ULL << 59) ? 59 : ((sizeof(struct page)) - 1) & (1ULL << 58) ? 58 : ((sizeof(struct page)) - 1) & (1ULL << 57) ? 57 : ((sizeof(struct page)) - 1) & (1ULL << 56) ? 56 : ((sizeof(struct page)) - 1) & (1ULL << 55) ? 55 : ((sizeof(struct page)) - 1) & (1ULL << 54) ? 54 : ((sizeof(struct page)) - 1) & (1ULL << 53) ? 53 : ((sizeof(struct page)) - 1) & (1ULL << 52) ? 52 : ((sizeof(struct page)) - 1) & (1ULL << 51) ? 51 : ((sizeof(struct page)) - 1) & (1ULL << 50) ? 50 : ((sizeof(struct page)) - 1) & (1ULL << 49) ? 49 : ((sizeof(struct page)) - 1) & (1ULL << 48) ? 48 : ((sizeof(struct page)) - 1) & (1ULL << 47) ? 47 : ((sizeof(struct page)) - 1) & (1ULL << 46) ? 46 : ((sizeof(struct page)) - 1) & (1ULL << 45) ? 45 : ((sizeof(struct page)) - 1) & (1ULL << 44) ? 44 : ((sizeof(struct page)) - 1) & (1ULL << 43) ? 43 : ((sizeof(struct page)) - 1) & (1ULL << 42) ? 42 : ((sizeof(struct page)) - 1) & (1ULL << 41) ? 41 : ((sizeof(struct page)) - 1) & (1ULL << 40) ? 40 : ((sizeof(struct page)) - 1) & (1ULL << 39) ? 39 : ((sizeof(struct page)) - 1) & (1ULL << 38) ? 38 : ((sizeof(struct page)) - 1) & (1ULL << 37) ? 37 : ((sizeof(struct page)) - 1) & (1ULL << 36) ? 36 : ((sizeof(struct page)) - 1) & (1ULL << 35) ? 35 : ((sizeof(struct page)) - 1) & (1ULL << 34) ? 34 : ((sizeof(struct page)) - 1) & (1ULL << 33) ? 33 : ((sizeof(struct page)) - 1) & (1ULL << 32) ? 32 : ((sizeof(struct page)) - 1) & (1ULL << 31) ? 31 : ((sizeof(struct page)) - 1) & (1ULL << 30) ? 30 : ((sizeof(struct page)) - 1) & (1ULL << 29) ? 29 : ((sizeof(struct page)) - 1) & (1ULL << 28) ? 28 : ((sizeof(struct page)) - 1) & (1ULL << 27) ? 27 : ((sizeof(struct page)) - 1) & (1ULL << 26) ? 26 : ((sizeof(struct page)) - 1) & (1ULL << 25) ? 25 : ((sizeof(struct page)) - 1) & (1ULL << 24) ? 24 : ((sizeof(struct page)) - 1) & (1ULL << 23) ? 23 : ((sizeof(struct page)) - 1) & (1ULL << 22) ? 22 : ((sizeof(struct page)) - 1) & (1ULL << 21) ? 21 : ((sizeof(struct page)) - 1) & (1ULL << 20) ? 20 : ((sizeof(struct page)) - 1) & (1ULL << 19) ? 19 : ((sizeof(struct page)) - 1) & (1ULL << 18) ? 18 : ((sizeof(struct page)) - 1) & (1ULL << 17) ? 17 : ((sizeof(struct page)) - 1) & (1ULL << 16) ? 16 : ((sizeof(struct page)) - 1) & (1ULL << 15) ? 15 : ((sizeof(struct page)) - 1) & (1ULL << 14) ? 14 : ((sizeof(struct page)) - 1) & (1ULL << 13) ? 13 : ((sizeof(struct page)) - 1) & (1ULL << 12) ? 12 : ((sizeof(struct page)) - 1) & (1ULL << 11) ? 11 : ((sizeof(struct page)) - 1) & (1ULL << 10) ? 10 : ((sizeof(struct page)) - 1) & (1ULL << 9) ? 9 : ((sizeof(struct page)) - 1) & (1ULL << 8) ? 8 : ((sizeof(struct page)) - 1) & (1ULL << 7) ? 7 : ((sizeof(struct page)) - 1) & (1ULL << 6) ? 6 : ((sizeof(struct page)) - 1) & (1ULL << 5) ? 5 : ((sizeof(struct page)) - 1) & (1ULL << 4) ? 4 : ((sizeof(struct page)) - 1) & (1ULL << 3) ? 3 : ((sizeof(struct page)) - 1) & (1ULL << 2) ? 2 : 1) : -1) : (sizeof((sizeof(struct page)) - 1) <= 4) ? __ilog2_u32((sizeof(struct page)) - 1) : __ilog2_u64((sizeof(struct page)) - 1) ) + 1) : __order_base_2(sizeof(struct page)) )))) - 0x00200000) - (memstart_addr >> 12)) + (REC->pfn)), REC->pfn, REC->order, REC->migratetype
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/rss_stat/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/rss_stat/format
new file mode 100644
index 000000000..8a9addec0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kmem/rss_stat/format
@@ -0,0 +1,14 @@
+name: rss_stat
+ID: 261
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int mm_id; offset:8; size:4; signed:0;
+ field:unsigned int curr; offset:12; size:4; signed:0;
+ field:int member; offset:16; size:4; signed:1;
+ field:long size; offset:24; size:8; signed:1;
+
+print fmt: "mm_id=%u curr=%d member=%d size=%ldB", REC->mm_id, REC->curr, REC->member, REC->size
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_access_fault/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_access_fault/format
new file mode 100644
index 000000000..357736a2d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_access_fault/format
@@ -0,0 +1,11 @@
+name: kvm_access_fault
+ID: 34
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long ipa; offset:8; size:8; signed:0;
+
+print fmt: "IPA: %lx", REC->ipa
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_ack_irq/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_ack_irq/format
new file mode 100644
index 000000000..fe2b3e20a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_ack_irq/format
@@ -0,0 +1,12 @@
+name: kvm_ack_irq
+ID: 26
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int irqchip; offset:8; size:4; signed:0;
+ field:unsigned int pin; offset:12; size:4; signed:0;
+
+print fmt: "irqchip %d pin %u", REC->irqchip, REC->pin
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_age_hva/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_age_hva/format
new file mode 100644
index 000000000..16382f630
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_age_hva/format
@@ -0,0 +1,12 @@
+name: kvm_age_hva
+ID: 35
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long start; offset:8; size:8; signed:0;
+ field:unsigned long end; offset:16; size:8; signed:0;
+
+print fmt: "mmu notifier age hva: %#016lx -- %#016lx", REC->start, REC->end
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_age_page/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_age_page/format
new file mode 100644
index 000000000..4fddd2c90
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_age_page/format
@@ -0,0 +1,14 @@
+name: kvm_age_page
+ID: 27
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 hva; offset:8; size:8; signed:0;
+ field:u64 gfn; offset:16; size:8; signed:0;
+ field:u8 level; offset:24; size:1; signed:0;
+ field:u8 referenced; offset:25; size:1; signed:0;
+
+print fmt: "hva %llx gfn %llx level %u %s", REC->hva, REC->gfn, REC->level, REC->referenced ? "YOUNG" : "OLD"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_arm_clear_debug/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_arm_clear_debug/format
new file mode 100644
index 000000000..c76435d50
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_arm_clear_debug/format
@@ -0,0 +1,11 @@
+name: kvm_arm_clear_debug
+ID: 52
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__u32 guest_debug; offset:8; size:4; signed:0;
+
+print fmt: "flags: 0x%08x", REC->guest_debug
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_arm_set_dreg32/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_arm_set_dreg32/format
new file mode 100644
index 000000000..cf0216098
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_arm_set_dreg32/format
@@ -0,0 +1,12 @@
+name: kvm_arm_set_dreg32
+ID: 53
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * name; offset:8; size:8; signed:0;
+ field:__u32 value; offset:16; size:4; signed:0;
+
+print fmt: "%s: 0x%08x", REC->name, REC->value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_arm_set_regset/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_arm_set_regset/format
new file mode 100644
index 000000000..053f7f823
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_arm_set_regset/format
@@ -0,0 +1,14 @@
+name: kvm_arm_set_regset
+ID: 54
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * name; offset:8; size:8; signed:0;
+ field:int len; offset:16; size:4; signed:1;
+ field:u64 ctrls[16]; offset:24; size:128; signed:0;
+ field:u64 values[16]; offset:152; size:128; signed:0;
+
+print fmt: "%d %s CTRL:%s VALUE:%s", REC->len, REC->name, __print_array(REC->ctrls, REC->len, 8), __print_array(REC->values, REC->len, 8)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_arm_setup_debug/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_arm_setup_debug/format
new file mode 100644
index 000000000..465d35096
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_arm_setup_debug/format
@@ -0,0 +1,12 @@
+name: kvm_arm_setup_debug
+ID: 55
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct kvm_vcpu * vcpu; offset:8; size:8; signed:0;
+ field:__u32 guest_debug; offset:16; size:4; signed:0;
+
+print fmt: "vcpu: %p, flags: 0x%08x", REC->vcpu, REC->guest_debug
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_entry/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_entry/format
new file mode 100644
index 000000000..0f4680c72
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_entry/format
@@ -0,0 +1,11 @@
+name: kvm_entry
+ID: 36
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long vcpu_pc; offset:8; size:8; signed:0;
+
+print fmt: "PC: 0x%016lx", REC->vcpu_pc
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_exit/format
new file mode 100644
index 000000000..20380902d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_exit/format
@@ -0,0 +1,13 @@
+name: kvm_exit
+ID: 37
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ret; offset:8; size:4; signed:1;
+ field:unsigned int esr_ec; offset:12; size:4; signed:0;
+ field:unsigned long vcpu_pc; offset:16; size:8; signed:0;
+
+print fmt: "%s: HSR_EC: 0x%04x (%s), PC: 0x%016lx", __print_symbolic(REC->ret, {0, "IRQ" }, {1, "SERROR" }, {2, "TRAP" }, {0xbadca11, "HYP_GONE" }), REC->esr_ec, __print_symbolic(REC->esr_ec, { (0x00), "UNKNOWN" }, { (0x01), "WFx" }, { (0x03), "CP15_32" }, { (0x04), "CP15_64" }, { (0x05), "CP14_MR" }, { (0x06), "CP14_LS" }, { (0x07), "FP_ASIMD" }, { (0x08), "CP10_ID" }, { (0x09), "PAC" }, { (0x0C), "CP14_64" }, { (0x15), "SVC64" }, { (0x16), "HVC64" }, { (0x17), "SMC64" }, { (0x18), "SYS64" }, { (0x19), "SVE" }, { (0x1f), "IMP_DEF" }, { (0x20), "IABT_LOW" }, { (0x21), "IABT_CUR" }, { (0x22), "PC_ALIGN" }, { (0x24), "DABT_LOW" }, { (0x25), "DABT_CUR" }, { (0x26), "SP_ALIGN" }, { (0x28), "FP_EXC32" }, { (0x2C), "FP_EXC64" }, { (0x2F), "SERROR" }, { (0x30), "BREAKPT_LOW" }, { (0x31), "BREAKPT_CUR" }, { (0x32), "SOFTSTP_LOW" }, { (0x33), "SOFTSTP_CUR" }, { (0x34), "WATCHPT_LOW" }, { (0x35), "WATCHPT_CUR" }, { (0x38), "BKPT32" }, { (0x3A), "VECTOR32" }, { (0x3C), "BRK64" }), REC->vcpu_pc
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_fpu/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_fpu/format
new file mode 100644
index 000000000..885107b66
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_fpu/format
@@ -0,0 +1,11 @@
+name: kvm_fpu
+ID: 28
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 load; offset:8; size:4; signed:0;
+
+print fmt: "%s", __print_symbolic(REC->load, {0, "unload"}, {1, "load"})
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_get_timer_map/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_get_timer_map/format
new file mode 100644
index 000000000..07a183a7d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_get_timer_map/format
@@ -0,0 +1,14 @@
+name: kvm_get_timer_map
+ID: 38
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long vcpu_id; offset:8; size:8; signed:0;
+ field:int direct_vtimer; offset:16; size:4; signed:1;
+ field:int direct_ptimer; offset:20; size:4; signed:1;
+ field:int emul_ptimer; offset:24; size:4; signed:1;
+
+print fmt: "VCPU: %ld, dv: %d, dp: %d, ep: %d", REC->vcpu_id, REC->direct_vtimer, REC->direct_ptimer, REC->emul_ptimer
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_guest_fault/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_guest_fault/format
new file mode 100644
index 000000000..655061921
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_guest_fault/format
@@ -0,0 +1,14 @@
+name: kvm_guest_fault
+ID: 39
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long vcpu_pc; offset:8; size:8; signed:0;
+ field:unsigned long hsr; offset:16; size:8; signed:0;
+ field:unsigned long hxfar; offset:24; size:8; signed:0;
+ field:unsigned long long ipa; offset:32; size:8; signed:0;
+
+print fmt: "ipa %#llx, hsr %#08lx, hxfar %#08lx, pc %#016lx", REC->ipa, REC->hsr, REC->hxfar, REC->vcpu_pc
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_halt_poll_ns/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_halt_poll_ns/format
new file mode 100644
index 000000000..07695f84b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_halt_poll_ns/format
@@ -0,0 +1,14 @@
+name: kvm_halt_poll_ns
+ID: 29
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:bool grow; offset:8; size:1; signed:0;
+ field:unsigned int vcpu_id; offset:12; size:4; signed:0;
+ field:unsigned int new; offset:16; size:4; signed:0;
+ field:unsigned int old; offset:20; size:4; signed:0;
+
+print fmt: "vcpu %u: halt_poll_ns %u (%s %u)", REC->vcpu_id, REC->new, REC->grow ? "grow" : "shrink", REC->old
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_handle_sys_reg/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_handle_sys_reg/format
new file mode 100644
index 000000000..3a5e388ea
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_handle_sys_reg/format
@@ -0,0 +1,11 @@
+name: kvm_handle_sys_reg
+ID: 56
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long hsr; offset:8; size:8; signed:0;
+
+print fmt: "HSR 0x%08lx", REC->hsr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_hvc_arm64/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_hvc_arm64/format
new file mode 100644
index 000000000..c08706ad0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_hvc_arm64/format
@@ -0,0 +1,13 @@
+name: kvm_hvc_arm64
+ID: 57
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long vcpu_pc; offset:8; size:8; signed:0;
+ field:unsigned long r0; offset:16; size:8; signed:0;
+ field:unsigned long imm; offset:24; size:8; signed:0;
+
+print fmt: "HVC at 0x%016lx (r0: 0x%016lx, imm: 0x%lx)", REC->vcpu_pc, REC->r0, REC->imm
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_irq_line/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_irq_line/format
new file mode 100644
index 000000000..e7b21cde3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_irq_line/format
@@ -0,0 +1,14 @@
+name: kvm_irq_line
+ID: 40
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int type; offset:8; size:4; signed:0;
+ field:int vcpu_idx; offset:12; size:4; signed:1;
+ field:int irq_num; offset:16; size:4; signed:1;
+ field:int level; offset:20; size:4; signed:1;
+
+print fmt: "Inject %s interrupt (%d), vcpu->idx: %d, num: %d, level: %d", (REC->type == 0) ? "CPU" : (REC->type == 2) ? "VGIC PPI" : (REC->type == 1) ? "VGIC SPI" : "UNKNOWN", REC->type, REC->vcpu_idx, REC->irq_num, REC->level
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_mmio/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_mmio/format
new file mode 100644
index 000000000..1343bde35
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_mmio/format
@@ -0,0 +1,14 @@
+name: kvm_mmio
+ID: 30
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 type; offset:8; size:4; signed:0;
+ field:u32 len; offset:12; size:4; signed:0;
+ field:u64 gpa; offset:16; size:8; signed:0;
+ field:u64 val; offset:24; size:8; signed:0;
+
+print fmt: "mmio %s len %u gpa 0x%llx val 0x%llx", __print_symbolic(REC->type, { 0, "unsatisfied-read" }, { 1, "read" }, { 2, "write" }), REC->len, REC->gpa, REC->val
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_mmio_emulate/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_mmio_emulate/format
new file mode 100644
index 000000000..fc89bc6f5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_mmio_emulate/format
@@ -0,0 +1,13 @@
+name: kvm_mmio_emulate
+ID: 41
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long vcpu_pc; offset:8; size:8; signed:0;
+ field:unsigned long instr; offset:16; size:8; signed:0;
+ field:unsigned long cpsr; offset:24; size:8; signed:0;
+
+print fmt: "Emulate MMIO at: 0x%016lx (instr: %08lx, cpsr: %08lx)", REC->vcpu_pc, REC->instr, REC->cpsr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_set_guest_debug/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_set_guest_debug/format
new file mode 100644
index 000000000..b85e70d0c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_set_guest_debug/format
@@ -0,0 +1,12 @@
+name: kvm_set_guest_debug
+ID: 58
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct kvm_vcpu * vcpu; offset:8; size:8; signed:0;
+ field:__u32 guest_debug; offset:16; size:4; signed:0;
+
+print fmt: "vcpu: %p, flags: 0x%08x", REC->vcpu, REC->guest_debug
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_set_irq/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_set_irq/format
new file mode 100644
index 000000000..002a01176
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_set_irq/format
@@ -0,0 +1,13 @@
+name: kvm_set_irq
+ID: 31
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int gsi; offset:8; size:4; signed:0;
+ field:int level; offset:12; size:4; signed:1;
+ field:int irq_source_id; offset:16; size:4; signed:1;
+
+print fmt: "gsi %u level %d source %d", REC->gsi, REC->level, REC->irq_source_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_set_spte_hva/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_set_spte_hva/format
new file mode 100644
index 000000000..6851c2c81
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_set_spte_hva/format
@@ -0,0 +1,11 @@
+name: kvm_set_spte_hva
+ID: 42
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long hva; offset:8; size:8; signed:0;
+
+print fmt: "mmu notifier set pte hva: %#016lx", REC->hva
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_set_way_flush/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_set_way_flush/format
new file mode 100644
index 000000000..3b0d873d4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_set_way_flush/format
@@ -0,0 +1,12 @@
+name: kvm_set_way_flush
+ID: 43
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long vcpu_pc; offset:8; size:8; signed:0;
+ field:bool cache; offset:16; size:1; signed:0;
+
+print fmt: "S/W flush at 0x%016lx (cache %s)", REC->vcpu_pc, REC->cache ? "on" : "off"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_sys_access/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_sys_access/format
new file mode 100644
index 000000000..2e10f2772
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_sys_access/format
@@ -0,0 +1,18 @@
+name: kvm_sys_access
+ID: 59
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long vcpu_pc; offset:8; size:8; signed:0;
+ field:bool is_write; offset:16; size:1; signed:0;
+ field:const char * name; offset:24; size:8; signed:0;
+ field:u8 Op0; offset:32; size:1; signed:0;
+ field:u8 Op1; offset:33; size:1; signed:0;
+ field:u8 CRn; offset:34; size:1; signed:0;
+ field:u8 CRm; offset:35; size:1; signed:0;
+ field:u8 Op2; offset:36; size:1; signed:0;
+
+print fmt: "PC: %lx %s (%d,%d,%d,%d,%d) %s", REC->vcpu_pc, REC->name ?: "UNKN", REC->Op0, REC->Op1, REC->CRn, REC->CRm, REC->Op2, REC->is_write ? "write" : "read"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_test_age_hva/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_test_age_hva/format
new file mode 100644
index 000000000..e259c1ca1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_test_age_hva/format
@@ -0,0 +1,11 @@
+name: kvm_test_age_hva
+ID: 44
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long hva; offset:8; size:8; signed:0;
+
+print fmt: "mmu notifier test age hva: %#016lx", REC->hva
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_timer_emulate/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_timer_emulate/format
new file mode 100644
index 000000000..f56676c33
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_timer_emulate/format
@@ -0,0 +1,12 @@
+name: kvm_timer_emulate
+ID: 45
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int timer_idx; offset:8; size:4; signed:1;
+ field:bool should_fire; offset:12; size:1; signed:0;
+
+print fmt: "arch_timer_ctx_index: %d (should_fire: %d)", REC->timer_idx, REC->should_fire
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_timer_hrtimer_expire/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_timer_hrtimer_expire/format
new file mode 100644
index 000000000..1874d57ec
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_timer_hrtimer_expire/format
@@ -0,0 +1,11 @@
+name: kvm_timer_hrtimer_expire
+ID: 46
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int timer_idx; offset:8; size:4; signed:1;
+
+print fmt: "arch_timer_ctx_index: %d", REC->timer_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_timer_restore_state/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_timer_restore_state/format
new file mode 100644
index 000000000..b8b4e338d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_timer_restore_state/format
@@ -0,0 +1,13 @@
+name: kvm_timer_restore_state
+ID: 47
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long ctl; offset:8; size:8; signed:0;
+ field:unsigned long long cval; offset:16; size:8; signed:0;
+ field:int timer_idx; offset:24; size:4; signed:1;
+
+print fmt: "CTL: %#08lx CVAL: %#16llx arch_timer_ctx_index: %d", REC->ctl, REC->cval, REC->timer_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_timer_save_state/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_timer_save_state/format
new file mode 100644
index 000000000..9e48332c0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_timer_save_state/format
@@ -0,0 +1,13 @@
+name: kvm_timer_save_state
+ID: 48
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long ctl; offset:8; size:8; signed:0;
+ field:unsigned long long cval; offset:16; size:8; signed:0;
+ field:int timer_idx; offset:24; size:4; signed:1;
+
+print fmt: " CTL: %#08lx CVAL: %#16llx arch_timer_ctx_index: %d", REC->ctl, REC->cval, REC->timer_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_timer_update_irq/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_timer_update_irq/format
new file mode 100644
index 000000000..211b220ec
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_timer_update_irq/format
@@ -0,0 +1,13 @@
+name: kvm_timer_update_irq
+ID: 49
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long vcpu_id; offset:8; size:8; signed:0;
+ field:__u32 irq; offset:16; size:4; signed:0;
+ field:int level; offset:20; size:4; signed:1;
+
+print fmt: "VCPU: %ld, IRQ %d, level %d", REC->vcpu_id, REC->irq, REC->level
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_toggle_cache/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_toggle_cache/format
new file mode 100644
index 000000000..388af79df
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_toggle_cache/format
@@ -0,0 +1,13 @@
+name: kvm_toggle_cache
+ID: 50
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long vcpu_pc; offset:8; size:8; signed:0;
+ field:bool was; offset:16; size:1; signed:0;
+ field:bool now; offset:17; size:1; signed:0;
+
+print fmt: "VM op at 0x%016lx (cache was %s, now %s)", REC->vcpu_pc, REC->was ? "on" : "off", REC->now ? "on" : "off"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_unmap_hva_range/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_unmap_hva_range/format
new file mode 100644
index 000000000..cb31a50a3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_unmap_hva_range/format
@@ -0,0 +1,12 @@
+name: kvm_unmap_hva_range
+ID: 51
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long start; offset:8; size:8; signed:0;
+ field:unsigned long end; offset:16; size:8; signed:0;
+
+print fmt: "mmu notifier unmap range: %#016lx -- %#016lx", REC->start, REC->end
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_userspace_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_userspace_exit/format
new file mode 100644
index 000000000..b1569935c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_userspace_exit/format
@@ -0,0 +1,12 @@
+name: kvm_userspace_exit
+ID: 32
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__u32 reason; offset:8; size:4; signed:0;
+ field:int errno; offset:12; size:4; signed:1;
+
+print fmt: "reason %s (%d)", REC->errno < 0 ? (REC->errno == -4 ? "restart" : "error") : __print_symbolic(REC->reason, { 0, "KVM_EXIT_" "UNKNOWN" }, { 1, "KVM_EXIT_" "EXCEPTION" }, { 2, "KVM_EXIT_" "IO" }, { 3, "KVM_EXIT_" "HYPERCALL" }, { 4, "KVM_EXIT_" "DEBUG" }, { 5, "KVM_EXIT_" "HLT" }, { 6, "KVM_EXIT_" "MMIO" }, { 7, "KVM_EXIT_" "IRQ_WINDOW_OPEN" }, { 8, "KVM_EXIT_" "SHUTDOWN" }, { 9, "KVM_EXIT_" "FAIL_ENTRY" }, { 10, "KVM_EXIT_" "INTR" }, { 11, "KVM_EXIT_" "SET_TPR" }, { 12, "KVM_EXIT_" "TPR_ACCESS" }, { 13, "KVM_EXIT_" "S390_SIEIC" }, { 14, "KVM_EXIT_" "S390_RESET" }, { 15, "KVM_EXIT_" "DCR" }, { 16, "KVM_EXIT_" "NMI" }, { 17, "KVM_EXIT_" "INTERNAL_ERROR" }, { 18, "KVM_EXIT_" "OSI" }, { 19, "KVM_EXIT_" "PAPR_HCALL" }, { 20, "KVM_EXIT_" "S390_UCONTROL" }, { 21, "KVM_EXIT_" "WATCHDOG" }, { 22, "KVM_EXIT_" "S390_TSCH" }, { 23, "KVM_EXIT_" "EPR" }, { 24, "KVM_EXIT_" "SYSTEM_EVENT" }, { 25, "KVM_EXIT_" "S390_STSI" }, { 26, "KVM_EXIT_" "IOAPIC_EOI" }, { 27, "KVM_EXIT_" "HYPERV" }, { 28, "KVM_EXIT_" "ARM_NISV" }, { 29, "KVM_EXIT_" "X86_RDMSR" }, { 30, "KVM_EXIT_" "X86_WRMSR" }), REC->errno < 0 ? -REC->errno : REC->reason
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_vcpu_wakeup/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_vcpu_wakeup/format
new file mode 100644
index 000000000..66073cec4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_vcpu_wakeup/format
@@ -0,0 +1,13 @@
+name: kvm_vcpu_wakeup
+ID: 33
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__u64 ns; offset:8; size:8; signed:0;
+ field:bool waited; offset:16; size:1; signed:0;
+ field:bool valid; offset:17; size:1; signed:0;
+
+print fmt: "%s time %lld ns, polling %s", REC->waited ? "wait" : "poll", REC->ns, REC->valid ? "valid" : "invalid"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_wfx_arm64/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_wfx_arm64/format
new file mode 100644
index 000000000..cde7c0e82
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/kvm_wfx_arm64/format
@@ -0,0 +1,12 @@
+name: kvm_wfx_arm64
+ID: 60
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long vcpu_pc; offset:8; size:8; signed:0;
+ field:bool is_wfe; offset:16; size:1; signed:0;
+
+print fmt: "guest executed wf%c at: 0x%016lx", REC->is_wfe ? 'e' : 'i', REC->vcpu_pc
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/trap_reg/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/trap_reg/format
new file mode 100644
index 000000000..478555862
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/trap_reg/format
@@ -0,0 +1,14 @@
+name: trap_reg
+ID: 61
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * fn; offset:8; size:8; signed:0;
+ field:int reg; offset:16; size:4; signed:1;
+ field:bool is_write; offset:20; size:1; signed:0;
+ field:u64 write_value; offset:24; size:8; signed:0;
+
+print fmt: "%s %s reg %d (0x%016llx)", REC->fn, REC->is_write?"write to":"read from", REC->reg, REC->write_value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/vgic_update_irq_pending/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/vgic_update_irq_pending/format
new file mode 100644
index 000000000..d0b0ecbc2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kvm/vgic_update_irq_pending/format
@@ -0,0 +1,13 @@
+name: vgic_update_irq_pending
+ID: 62
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long vcpu_id; offset:8; size:8; signed:0;
+ field:__u32 irq; offset:16; size:4; signed:0;
+ field:bool level; offset:20; size:1; signed:0;
+
+print fmt: "VCPU: %ld, IRQ %d, level: %d", REC->vcpu_id, REC->irq, REC->level
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kyber/kyber_adjust/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kyber/kyber_adjust/format
new file mode 100644
index 000000000..916cf1e70
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kyber/kyber_adjust/format
@@ -0,0 +1,13 @@
+name: kyber_adjust
+ID: 610
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:char domain[16]; offset:12; size:16; signed:0;
+ field:unsigned int depth; offset:28; size:4; signed:0;
+
+print fmt: "%d,%d %s %u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->domain, REC->depth
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kyber/kyber_latency/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kyber/kyber_latency/format
new file mode 100644
index 000000000..e8f5a8adf
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kyber/kyber_latency/format
@@ -0,0 +1,17 @@
+name: kyber_latency
+ID: 611
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:char domain[16]; offset:12; size:16; signed:0;
+ field:char type[8]; offset:28; size:8; signed:0;
+ field:u8 percentile; offset:36; size:1; signed:0;
+ field:u8 numerator; offset:37; size:1; signed:0;
+ field:u8 denominator; offset:38; size:1; signed:0;
+ field:unsigned int samples; offset:40; size:4; signed:0;
+
+print fmt: "%d,%d %s %s p%u %u/%u samples=%u", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->domain, REC->type, REC->percentile, REC->numerator, REC->denominator, REC->samples
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kyber/kyber_throttled/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kyber/kyber_throttled/format
new file mode 100644
index 000000000..79e21fdde
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/kyber/kyber_throttled/format
@@ -0,0 +1,12 @@
+name: kyber_throttled
+ID: 612
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:char domain[16]; offset:12; size:16; signed:0;
+
+print fmt: "%d,%d %s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->domain
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/delete_session/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/delete_session/format
new file mode 100644
index 000000000..5e0f6a5b9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/delete_session/format
@@ -0,0 +1,11 @@
+name: delete_session
+ID: 973
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/delete_tunnel/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/delete_tunnel/format
new file mode 100644
index 000000000..e246aee9a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/delete_tunnel/format
@@ -0,0 +1,11 @@
+name: delete_tunnel
+ID: 974
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[20]; offset:8; size:20; signed:0;
+
+print fmt: "%s", REC->name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/free_session/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/free_session/format
new file mode 100644
index 000000000..ccca2c88e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/free_session/format
@@ -0,0 +1,11 @@
+name: free_session
+ID: 975
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/free_tunnel/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/free_tunnel/format
new file mode 100644
index 000000000..17e8415d0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/free_tunnel/format
@@ -0,0 +1,11 @@
+name: free_tunnel
+ID: 976
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[20]; offset:8; size:20; signed:0;
+
+print fmt: "%s", REC->name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/register_session/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/register_session/format
new file mode 100644
index 000000000..77863176b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/register_session/format
@@ -0,0 +1,16 @@
+name: register_session
+ID: 977
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:u32 tid; offset:40; size:4; signed:0;
+ field:u32 ptid; offset:44; size:4; signed:0;
+ field:u32 sid; offset:48; size:4; signed:0;
+ field:u32 psid; offset:52; size:4; signed:0;
+ field:enum l2tp_pwtype pwtype; offset:56; size:4; signed:0;
+
+print fmt: "%s: pseudowire=%s sid=%u psid=%u tid=%u ptid=%u", REC->name, __print_symbolic(REC->pwtype, { L2TP_PWTYPE_ETH_VLAN, "ETH_VLAN" }, { L2TP_PWTYPE_ETH, "ETH" }, { L2TP_PWTYPE_PPP, "PPP" }, { L2TP_PWTYPE_PPP_AC, "PPP_AC" }, { L2TP_PWTYPE_IP, "IP" }), REC->sid, REC->psid, REC->sid, REC->psid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/register_tunnel/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/register_tunnel/format
new file mode 100644
index 000000000..a4a8937cc
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/register_tunnel/format
@@ -0,0 +1,16 @@
+name: register_tunnel
+ID: 978
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[20]; offset:8; size:20; signed:0;
+ field:int fd; offset:28; size:4; signed:1;
+ field:u32 tid; offset:32; size:4; signed:0;
+ field:u32 ptid; offset:36; size:4; signed:0;
+ field:int version; offset:40; size:4; signed:1;
+ field:enum l2tp_encap_type encap; offset:44; size:4; signed:0;
+
+print fmt: "%s: type=%s encap=%s version=L2TPv%d tid=%u ptid=%u fd=%d", REC->name, REC->fd > 0 ? "managed" : "unmanaged", __print_symbolic(REC->encap, { L2TP_ENCAPTYPE_UDP, "UDP" }, { L2TP_ENCAPTYPE_IP, "IP" }), REC->version, REC->tid, REC->ptid, REC->fd
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_pkt_expired/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_pkt_expired/format
new file mode 100644
index 000000000..4f36c14a6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_pkt_expired/format
@@ -0,0 +1,14 @@
+name: session_pkt_expired
+ID: 979
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:u32 pkt_ns; offset:40; size:4; signed:0;
+ field:u32 my_nr; offset:44; size:4; signed:0;
+ field:u32 reorder_q_len; offset:48; size:4; signed:0;
+
+print fmt: "%s: pkt_ns=%u my_nr=%u reorder_q_len=%u", REC->name, REC->pkt_ns, REC->my_nr, REC->reorder_q_len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_pkt_oos/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_pkt_oos/format
new file mode 100644
index 000000000..3db2418d6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_pkt_oos/format
@@ -0,0 +1,14 @@
+name: session_pkt_oos
+ID: 980
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:u32 pkt_ns; offset:40; size:4; signed:0;
+ field:u32 my_nr; offset:44; size:4; signed:0;
+ field:u32 reorder_q_len; offset:48; size:4; signed:0;
+
+print fmt: "%s: pkt_ns=%u my_nr=%u reorder_q_len=%u", REC->name, REC->pkt_ns, REC->my_nr, REC->reorder_q_len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_pkt_outside_rx_window/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_pkt_outside_rx_window/format
new file mode 100644
index 000000000..5a9df6103
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_pkt_outside_rx_window/format
@@ -0,0 +1,14 @@
+name: session_pkt_outside_rx_window
+ID: 981
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:u32 pkt_ns; offset:40; size:4; signed:0;
+ field:u32 my_nr; offset:44; size:4; signed:0;
+ field:u32 reorder_q_len; offset:48; size:4; signed:0;
+
+print fmt: "%s: pkt_ns=%u my_nr=%u reorder_q_len=%u", REC->name, REC->pkt_ns, REC->my_nr, REC->reorder_q_len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_seqnum_lns_disable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_seqnum_lns_disable/format
new file mode 100644
index 000000000..44302aad2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_seqnum_lns_disable/format
@@ -0,0 +1,11 @@
+name: session_seqnum_lns_disable
+ID: 982
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_seqnum_lns_enable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_seqnum_lns_enable/format
new file mode 100644
index 000000000..d98998929
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_seqnum_lns_enable/format
@@ -0,0 +1,11 @@
+name: session_seqnum_lns_enable
+ID: 983
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_seqnum_reset/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_seqnum_reset/format
new file mode 100644
index 000000000..3e1d98812
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_seqnum_reset/format
@@ -0,0 +1,13 @@
+name: session_seqnum_reset
+ID: 984
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:u32 ns; offset:40; size:4; signed:0;
+ field:u32 nr; offset:44; size:4; signed:0;
+
+print fmt: "%s: ns=%u nr=%u", REC->name, REC->ns, REC->nr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_seqnum_update/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_seqnum_update/format
new file mode 100644
index 000000000..e6016f9e2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/l2tp/session_seqnum_update/format
@@ -0,0 +1,13 @@
+name: session_seqnum_update
+ID: 985
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:u32 ns; offset:40; size:4; signed:0;
+ field:u32 nr; offset:44; size:4; signed:0;
+
+print fmt: "%s: ns=%u nr=%u", REC->name, REC->ns, REC->nr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_beacon_loss/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_beacon_loss/format
new file mode 100644
index 000000000..5137e5b5a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_beacon_loss/format
@@ -0,0 +1,14 @@
+name: api_beacon_loss
+ID: 1422
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum nl80211_iftype vif_type; offset:8; size:4; signed:0;
+ field:void * sdata; offset:16; size:8; signed:0;
+ field:bool p2p; offset:24; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:28; size:4; signed:0;
+
+print fmt: " vif:%s(%d%s)", __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_chswitch_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_chswitch_done/format
new file mode 100644
index 000000000..b3ca7481b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_chswitch_done/format
@@ -0,0 +1,15 @@
+name: api_chswitch_done
+ID: 1423
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum nl80211_iftype vif_type; offset:8; size:4; signed:0;
+ field:void * sdata; offset:16; size:8; signed:0;
+ field:bool p2p; offset:24; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:28; size:4; signed:0;
+ field:bool success; offset:32; size:1; signed:0;
+
+print fmt: " vif:%s(%d%s) success=%d", __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->success
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_connection_loss/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_connection_loss/format
new file mode 100644
index 000000000..8747f1615
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_connection_loss/format
@@ -0,0 +1,14 @@
+name: api_connection_loss
+ID: 1424
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum nl80211_iftype vif_type; offset:8; size:4; signed:0;
+ field:void * sdata; offset:16; size:8; signed:0;
+ field:bool p2p; offset:24; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:28; size:4; signed:0;
+
+print fmt: " vif:%s(%d%s)", __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_cqm_beacon_loss_notify/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_cqm_beacon_loss_notify/format
new file mode 100644
index 000000000..0e1a78570
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_cqm_beacon_loss_notify/format
@@ -0,0 +1,15 @@
+name: api_cqm_beacon_loss_notify
+ID: 1425
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_cqm_rssi_notify/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_cqm_rssi_notify/format
new file mode 100644
index 000000000..8545eccea
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_cqm_rssi_notify/format
@@ -0,0 +1,16 @@
+name: api_cqm_rssi_notify
+ID: 1426
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum nl80211_iftype vif_type; offset:8; size:4; signed:0;
+ field:void * sdata; offset:16; size:8; signed:0;
+ field:bool p2p; offset:24; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:28; size:4; signed:0;
+ field:u32 rssi_event; offset:32; size:4; signed:0;
+ field:s32 rssi_level; offset:36; size:4; signed:1;
+
+print fmt: " vif:%s(%d%s) event:%d rssi:%d", __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->rssi_event, REC->rssi_level
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_enable_rssi_reports/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_enable_rssi_reports/format
new file mode 100644
index 000000000..1ca1c6237
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_enable_rssi_reports/format
@@ -0,0 +1,16 @@
+name: api_enable_rssi_reports
+ID: 1427
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum nl80211_iftype vif_type; offset:8; size:4; signed:0;
+ field:void * sdata; offset:16; size:8; signed:0;
+ field:bool p2p; offset:24; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:28; size:4; signed:0;
+ field:int rssi_min_thold; offset:32; size:4; signed:1;
+ field:int rssi_max_thold; offset:36; size:4; signed:1;
+
+print fmt: " vif:%s(%d%s) rssi_min_thold =%d, rssi_max_thold = %d", __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->rssi_min_thold, REC->rssi_max_thold
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_eosp/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_eosp/format
new file mode 100644
index 000000000..973326cb3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_eosp/format
@@ -0,0 +1,12 @@
+name: api_eosp
+ID: 1428
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char sta_addr[6]; offset:40; size:6; signed:0;
+
+print fmt: "%s sta:%pM", REC->wiphy_name, REC->sta_addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_gtk_rekey_notify/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_gtk_rekey_notify/format
new file mode 100644
index 000000000..6db285a8e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_gtk_rekey_notify/format
@@ -0,0 +1,16 @@
+name: api_gtk_rekey_notify
+ID: 1429
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum nl80211_iftype vif_type; offset:8; size:4; signed:0;
+ field:void * sdata; offset:16; size:8; signed:0;
+ field:bool p2p; offset:24; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:28; size:4; signed:0;
+ field:u8 bssid[6]; offset:32; size:6; signed:0;
+ field:u8 replay_ctr[8]; offset:38; size:8; signed:0;
+
+print fmt: " vif:%s(%d%s)", __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_radar_detected/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_radar_detected/format
new file mode 100644
index 000000000..7c5321d2b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_radar_detected/format
@@ -0,0 +1,11 @@
+name: api_radar_detected
+ID: 1430
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s radar detected", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_ready_on_channel/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_ready_on_channel/format
new file mode 100644
index 000000000..8a8be04fd
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_ready_on_channel/format
@@ -0,0 +1,11 @@
+name: api_ready_on_channel
+ID: 1431
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_remain_on_channel_expired/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_remain_on_channel_expired/format
new file mode 100644
index 000000000..bdec61dac
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_remain_on_channel_expired/format
@@ -0,0 +1,11 @@
+name: api_remain_on_channel_expired
+ID: 1432
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_restart_hw/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_restart_hw/format
new file mode 100644
index 000000000..8992ee03b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_restart_hw/format
@@ -0,0 +1,11 @@
+name: api_restart_hw
+ID: 1433
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_scan_completed/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_scan_completed/format
new file mode 100644
index 000000000..cb68c957a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_scan_completed/format
@@ -0,0 +1,12 @@
+name: api_scan_completed
+ID: 1434
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:bool aborted; offset:40; size:1; signed:0;
+
+print fmt: "%s aborted:%d", REC->wiphy_name, REC->aborted
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_sched_scan_results/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_sched_scan_results/format
new file mode 100644
index 000000000..a2d06a82c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_sched_scan_results/format
@@ -0,0 +1,11 @@
+name: api_sched_scan_results
+ID: 1435
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_sched_scan_stopped/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_sched_scan_stopped/format
new file mode 100644
index 000000000..ed510d8ba
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_sched_scan_stopped/format
@@ -0,0 +1,11 @@
+name: api_sched_scan_stopped
+ID: 1436
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_send_eosp_nullfunc/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_send_eosp_nullfunc/format
new file mode 100644
index 000000000..308b88623
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_send_eosp_nullfunc/format
@@ -0,0 +1,13 @@
+name: api_send_eosp_nullfunc
+ID: 1437
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char sta_addr[6]; offset:40; size:6; signed:0;
+ field:u8 tid; offset:46; size:1; signed:0;
+
+print fmt: "%s sta:%pM tid:%d", REC->wiphy_name, REC->sta_addr, REC->tid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_sta_block_awake/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_sta_block_awake/format
new file mode 100644
index 000000000..812a82ecc
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_sta_block_awake/format
@@ -0,0 +1,13 @@
+name: api_sta_block_awake
+ID: 1438
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char sta_addr[6]; offset:40; size:6; signed:0;
+ field:bool block; offset:46; size:1; signed:0;
+
+print fmt: "%s sta:%pM block:%d", REC->wiphy_name, REC->sta_addr, REC->block
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_sta_set_buffered/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_sta_set_buffered/format
new file mode 100644
index 000000000..c527c1f94
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_sta_set_buffered/format
@@ -0,0 +1,14 @@
+name: api_sta_set_buffered
+ID: 1439
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char sta_addr[6]; offset:40; size:6; signed:0;
+ field:u8 tid; offset:46; size:1; signed:0;
+ field:bool buffered; offset:47; size:1; signed:0;
+
+print fmt: "%s sta:%pM tid:%d buffered:%d", REC->wiphy_name, REC->sta_addr, REC->tid, REC->buffered
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_start_tx_ba_cb/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_start_tx_ba_cb/format
new file mode 100644
index 000000000..323658924
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_start_tx_ba_cb/format
@@ -0,0 +1,16 @@
+name: api_start_tx_ba_cb
+ID: 1440
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum nl80211_iftype vif_type; offset:8; size:4; signed:0;
+ field:void * sdata; offset:16; size:8; signed:0;
+ field:bool p2p; offset:24; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:28; size:4; signed:0;
+ field:u8 ra[6]; offset:32; size:6; signed:0;
+ field:u16 tid; offset:38; size:2; signed:0;
+
+print fmt: " vif:%s(%d%s) ra:%pM tid:%d", __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->ra, REC->tid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_start_tx_ba_session/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_start_tx_ba_session/format
new file mode 100644
index 000000000..aa280ae13
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_start_tx_ba_session/format
@@ -0,0 +1,12 @@
+name: api_start_tx_ba_session
+ID: 1441
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char sta_addr[6]; offset:8; size:6; signed:0;
+ field:u16 tid; offset:14; size:2; signed:0;
+
+print fmt: " sta:%pM tid:%d", REC->sta_addr, REC->tid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_stop_tx_ba_cb/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_stop_tx_ba_cb/format
new file mode 100644
index 000000000..4c75a1d31
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_stop_tx_ba_cb/format
@@ -0,0 +1,16 @@
+name: api_stop_tx_ba_cb
+ID: 1442
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum nl80211_iftype vif_type; offset:8; size:4; signed:0;
+ field:void * sdata; offset:16; size:8; signed:0;
+ field:bool p2p; offset:24; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:28; size:4; signed:0;
+ field:u8 ra[6]; offset:32; size:6; signed:0;
+ field:u16 tid; offset:38; size:2; signed:0;
+
+print fmt: " vif:%s(%d%s) ra:%pM tid:%d", __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->ra, REC->tid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_stop_tx_ba_session/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_stop_tx_ba_session/format
new file mode 100644
index 000000000..e7167ef1c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/api_stop_tx_ba_session/format
@@ -0,0 +1,12 @@
+name: api_stop_tx_ba_session
+ID: 1443
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char sta_addr[6]; offset:8; size:6; signed:0;
+ field:u16 tid; offset:14; size:2; signed:0;
+
+print fmt: " sta:%pM tid:%d", REC->sta_addr, REC->tid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_abort_channel_switch/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_abort_channel_switch/format
new file mode 100644
index 000000000..e84f5a5f8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_abort_channel_switch/format
@@ -0,0 +1,15 @@
+name: drv_abort_channel_switch
+ID: 1444
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_abort_pmsr/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_abort_pmsr/format
new file mode 100644
index 000000000..b7af72444
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_abort_pmsr/format
@@ -0,0 +1,15 @@
+name: drv_abort_pmsr
+ID: 1445
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_add_chanctx/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_add_chanctx/format
new file mode 100644
index 000000000..c7abf81b6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_add_chanctx/format
@@ -0,0 +1,25 @@
+name: drv_add_chanctx
+ID: 1446
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 control_freq; offset:40; size:4; signed:0;
+ field:u32 freq_offset; offset:44; size:4; signed:0;
+ field:u32 chan_width; offset:48; size:4; signed:0;
+ field:u32 center_freq1; offset:52; size:4; signed:0;
+ field:u32 freq1_offset; offset:56; size:4; signed:0;
+ field:u32 center_freq2; offset:60; size:4; signed:0;
+ field:u32 min_control_freq; offset:64; size:4; signed:0;
+ field:u32 min_freq_offset; offset:68; size:4; signed:0;
+ field:u32 min_chan_width; offset:72; size:4; signed:0;
+ field:u32 min_center_freq1; offset:76; size:4; signed:0;
+ field:u32 min_freq1_offset; offset:80; size:4; signed:0;
+ field:u32 min_center_freq2; offset:84; size:4; signed:0;
+ field:u8 rx_chains_static; offset:88; size:1; signed:0;
+ field:u8 rx_chains_dynamic; offset:89; size:1; signed:0;
+
+print fmt: "%s control:%d.%03d MHz width:%d center: %d.%03d/%d MHz min_control:%d.%03d MHz min_width:%d min_center: %d.%03d/%d MHz chains:%d/%d", REC->wiphy_name, REC->control_freq, REC->freq_offset, REC->chan_width, REC->center_freq1, REC->freq1_offset, REC->center_freq2, REC->min_control_freq, REC->min_freq_offset, REC->min_chan_width, REC->min_center_freq1, REC->min_freq1_offset, REC->min_center_freq2, REC->rx_chains_static, REC->rx_chains_dynamic
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_add_interface/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_add_interface/format
new file mode 100644
index 000000000..7de690487
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_add_interface/format
@@ -0,0 +1,16 @@
+name: drv_add_interface
+ID: 1447
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:char addr[6]; offset:64; size:6; signed:0;
+
+print fmt: "%s vif:%s(%d%s) addr:%pM", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_add_nan_func/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_add_nan_func/format
new file mode 100644
index 000000000..cae5d0f67
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_add_nan_func/format
@@ -0,0 +1,17 @@
+name: drv_add_nan_func
+ID: 1448
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u8 type; offset:64; size:1; signed:0;
+ field:u8 inst_id; offset:65; size:1; signed:0;
+
+print fmt: "%s vif:%s(%d%s), type: %u, inst_id: %u", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->type, REC->inst_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_allow_buffered_frames/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_allow_buffered_frames/format
new file mode 100644
index 000000000..ae26c6b60
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_allow_buffered_frames/format
@@ -0,0 +1,16 @@
+name: drv_allow_buffered_frames
+ID: 1449
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char sta_addr[6]; offset:40; size:6; signed:0;
+ field:u16 tids; offset:46; size:2; signed:0;
+ field:int num_frames; offset:48; size:4; signed:1;
+ field:int reason; offset:52; size:4; signed:1;
+ field:bool more_data; offset:56; size:1; signed:0;
+
+print fmt: "%s sta:%pM TIDs:0x%.4x frames:%d reason:%d more:%d", REC->wiphy_name, REC->sta_addr, REC->tids, REC->num_frames, REC->reason, REC->more_data
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_ampdu_action/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_ampdu_action/format
new file mode 100644
index 000000000..6ad4bfe25
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_ampdu_action/format
@@ -0,0 +1,23 @@
+name: drv_ampdu_action
+ID: 1450
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:enum ieee80211_ampdu_mlme_action ieee80211_ampdu_mlme_action; offset:64; size:4; signed:0;
+ field:char sta_addr[6]; offset:68; size:6; signed:0;
+ field:u16 tid; offset:74; size:2; signed:0;
+ field:u16 ssn; offset:76; size:2; signed:0;
+ field:u16 buf_size; offset:78; size:2; signed:0;
+ field:bool amsdu; offset:80; size:1; signed:0;
+ field:u16 timeout; offset:82; size:2; signed:0;
+ field:u16 action; offset:84; size:2; signed:0;
+
+print fmt: "%s vif:%s(%d%s) sta:%pM tid %d, ssn %d, buf_size %u, amsdu %d, timeout %d action %d", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->sta_addr, REC->tid, REC->ssn, REC->buf_size, REC->amsdu, REC->timeout, REC->action
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_assign_vif_chanctx/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_assign_vif_chanctx/format
new file mode 100644
index 000000000..f25ac8ce7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_assign_vif_chanctx/format
@@ -0,0 +1,29 @@
+name: drv_assign_vif_chanctx
+ID: 1451
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u32 control_freq; offset:64; size:4; signed:0;
+ field:u32 freq_offset; offset:68; size:4; signed:0;
+ field:u32 chan_width; offset:72; size:4; signed:0;
+ field:u32 center_freq1; offset:76; size:4; signed:0;
+ field:u32 freq1_offset; offset:80; size:4; signed:0;
+ field:u32 center_freq2; offset:84; size:4; signed:0;
+ field:u32 min_control_freq; offset:88; size:4; signed:0;
+ field:u32 min_freq_offset; offset:92; size:4; signed:0;
+ field:u32 min_chan_width; offset:96; size:4; signed:0;
+ field:u32 min_center_freq1; offset:100; size:4; signed:0;
+ field:u32 min_freq1_offset; offset:104; size:4; signed:0;
+ field:u32 min_center_freq2; offset:108; size:4; signed:0;
+ field:u8 rx_chains_static; offset:112; size:1; signed:0;
+ field:u8 rx_chains_dynamic; offset:113; size:1; signed:0;
+
+print fmt: "%s vif:%s(%d%s) control:%d.%03d MHz width:%d center: %d.%03d/%d MHz min_control:%d.%03d MHz min_width:%d min_center: %d.%03d/%d MHz chains:%d/%d", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->control_freq, REC->freq_offset, REC->chan_width, REC->center_freq1, REC->freq1_offset, REC->center_freq2, REC->min_control_freq, REC->min_freq_offset, REC->min_chan_width, REC->min_center_freq1, REC->min_freq1_offset, REC->min_center_freq2, REC->rx_chains_static, REC->rx_chains_dynamic
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_bss_info_changed/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_bss_info_changed/format
new file mode 100644
index 000000000..dcd07166d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_bss_info_changed/format
@@ -0,0 +1,47 @@
+name: drv_bss_info_changed
+ID: 1452
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u32 changed; offset:64; size:4; signed:0;
+ field:bool assoc; offset:68; size:1; signed:0;
+ field:bool ibss_joined; offset:69; size:1; signed:0;
+ field:bool ibss_creator; offset:70; size:1; signed:0;
+ field:u16 aid; offset:72; size:2; signed:0;
+ field:bool cts; offset:74; size:1; signed:0;
+ field:bool shortpre; offset:75; size:1; signed:0;
+ field:bool shortslot; offset:76; size:1; signed:0;
+ field:bool enable_beacon; offset:77; size:1; signed:0;
+ field:u8 dtimper; offset:78; size:1; signed:0;
+ field:u16 bcnint; offset:80; size:2; signed:0;
+ field:u16 assoc_cap; offset:82; size:2; signed:0;
+ field:u64 sync_tsf; offset:88; size:8; signed:0;
+ field:u32 sync_device_ts; offset:96; size:4; signed:0;
+ field:u8 sync_dtim_count; offset:100; size:1; signed:0;
+ field:u32 basic_rates; offset:104; size:4; signed:0;
+ field:int mcast_rate[NUM_NL80211_BANDS]; offset:108; size:20; signed:1;
+ field:u16 ht_operation_mode; offset:128; size:2; signed:0;
+ field:s32 cqm_rssi_thold; offset:132; size:4; signed:1;
+ field:s32 cqm_rssi_hyst; offset:136; size:4; signed:1;
+ field:u32 channel_width; offset:140; size:4; signed:0;
+ field:u32 channel_cfreq1; offset:144; size:4; signed:0;
+ field:u32 channel_cfreq1_offset; offset:148; size:4; signed:0;
+ field:__data_loc u32[] arp_addr_list; offset:152; size:4; signed:0;
+ field:int arp_addr_cnt; offset:156; size:4; signed:1;
+ field:bool qos; offset:160; size:1; signed:0;
+ field:bool idle; offset:161; size:1; signed:0;
+ field:bool ps; offset:162; size:1; signed:0;
+ field:__data_loc u8[] ssid; offset:164; size:4; signed:0;
+ field:bool hidden_ssid; offset:168; size:1; signed:0;
+ field:int txpower; offset:172; size:4; signed:1;
+ field:u8 p2p_oppps_ctwindow; offset:176; size:1; signed:0;
+
+print fmt: "%s vif:%s(%d%s) changed:%#x", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->changed
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_cancel_hw_scan/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_cancel_hw_scan/format
new file mode 100644
index 000000000..4cb78cb61
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_cancel_hw_scan/format
@@ -0,0 +1,15 @@
+name: drv_cancel_hw_scan
+ID: 1453
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_cancel_remain_on_channel/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_cancel_remain_on_channel/format
new file mode 100644
index 000000000..9be84e159
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_cancel_remain_on_channel/format
@@ -0,0 +1,15 @@
+name: drv_cancel_remain_on_channel
+ID: 1454
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_change_chanctx/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_change_chanctx/format
new file mode 100644
index 000000000..4a7977de6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_change_chanctx/format
@@ -0,0 +1,26 @@
+name: drv_change_chanctx
+ID: 1455
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 control_freq; offset:40; size:4; signed:0;
+ field:u32 freq_offset; offset:44; size:4; signed:0;
+ field:u32 chan_width; offset:48; size:4; signed:0;
+ field:u32 center_freq1; offset:52; size:4; signed:0;
+ field:u32 freq1_offset; offset:56; size:4; signed:0;
+ field:u32 center_freq2; offset:60; size:4; signed:0;
+ field:u32 min_control_freq; offset:64; size:4; signed:0;
+ field:u32 min_freq_offset; offset:68; size:4; signed:0;
+ field:u32 min_chan_width; offset:72; size:4; signed:0;
+ field:u32 min_center_freq1; offset:76; size:4; signed:0;
+ field:u32 min_freq1_offset; offset:80; size:4; signed:0;
+ field:u32 min_center_freq2; offset:84; size:4; signed:0;
+ field:u8 rx_chains_static; offset:88; size:1; signed:0;
+ field:u8 rx_chains_dynamic; offset:89; size:1; signed:0;
+ field:u32 changed; offset:92; size:4; signed:0;
+
+print fmt: "%s control:%d.%03d MHz width:%d center: %d.%03d/%d MHz min_control:%d.%03d MHz min_width:%d min_center: %d.%03d/%d MHz chains:%d/%d changed:%#x", REC->wiphy_name, REC->control_freq, REC->freq_offset, REC->chan_width, REC->center_freq1, REC->freq1_offset, REC->center_freq2, REC->min_control_freq, REC->min_freq_offset, REC->min_chan_width, REC->min_center_freq1, REC->min_freq1_offset, REC->min_center_freq2, REC->rx_chains_static, REC->rx_chains_dynamic, REC->changed
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_change_interface/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_change_interface/format
new file mode 100644
index 000000000..ce060eecb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_change_interface/format
@@ -0,0 +1,17 @@
+name: drv_change_interface
+ID: 1456
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u32 new_type; offset:64; size:4; signed:0;
+ field:bool new_p2p; offset:68; size:1; signed:0;
+
+print fmt: "%s vif:%s(%d%s) new type:%d%s", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->new_type, REC->new_p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_channel_switch/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_channel_switch/format
new file mode 100644
index 000000000..3e6523051
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_channel_switch/format
@@ -0,0 +1,25 @@
+name: drv_channel_switch
+ID: 1457
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u32 control_freq; offset:64; size:4; signed:0;
+ field:u32 freq_offset; offset:68; size:4; signed:0;
+ field:u32 chan_width; offset:72; size:4; signed:0;
+ field:u32 center_freq1; offset:76; size:4; signed:0;
+ field:u32 freq1_offset; offset:80; size:4; signed:0;
+ field:u32 center_freq2; offset:84; size:4; signed:0;
+ field:u64 timestamp; offset:88; size:8; signed:0;
+ field:u32 device_timestamp; offset:96; size:4; signed:0;
+ field:bool block_tx; offset:100; size:1; signed:0;
+ field:u8 count; offset:101; size:1; signed:0;
+
+print fmt: "%s vif:%s(%d%s) new control:%d.%03d MHz width:%d center: %d.%03d/%d MHz count:%d", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->control_freq, REC->freq_offset, REC->chan_width, REC->center_freq1, REC->freq1_offset, REC->center_freq2, REC->count
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_channel_switch_beacon/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_channel_switch_beacon/format
new file mode 100644
index 000000000..0c6a2c883
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_channel_switch_beacon/format
@@ -0,0 +1,21 @@
+name: drv_channel_switch_beacon
+ID: 1458
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u32 control_freq; offset:64; size:4; signed:0;
+ field:u32 freq_offset; offset:68; size:4; signed:0;
+ field:u32 chan_width; offset:72; size:4; signed:0;
+ field:u32 center_freq1; offset:76; size:4; signed:0;
+ field:u32 freq1_offset; offset:80; size:4; signed:0;
+ field:u32 center_freq2; offset:84; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s) channel switch to control:%d.%03d MHz width:%d center: %d.%03d/%d MHz", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->control_freq, REC->freq_offset, REC->chan_width, REC->center_freq1, REC->freq1_offset, REC->center_freq2
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_channel_switch_rx_beacon/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_channel_switch_rx_beacon/format
new file mode 100644
index 000000000..2e9471ad6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_channel_switch_rx_beacon/format
@@ -0,0 +1,25 @@
+name: drv_channel_switch_rx_beacon
+ID: 1459
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u32 control_freq; offset:64; size:4; signed:0;
+ field:u32 freq_offset; offset:68; size:4; signed:0;
+ field:u32 chan_width; offset:72; size:4; signed:0;
+ field:u32 center_freq1; offset:76; size:4; signed:0;
+ field:u32 freq1_offset; offset:80; size:4; signed:0;
+ field:u32 center_freq2; offset:84; size:4; signed:0;
+ field:u64 timestamp; offset:88; size:8; signed:0;
+ field:u32 device_timestamp; offset:96; size:4; signed:0;
+ field:bool block_tx; offset:100; size:1; signed:0;
+ field:u8 count; offset:101; size:1; signed:0;
+
+print fmt: "%s vif:%s(%d%s) received a channel switch beacon to control:%d.%03d MHz width:%d center: %d.%03d/%d MHz count:%d block_tx:%d timestamp:%llu", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->control_freq, REC->freq_offset, REC->chan_width, REC->center_freq1, REC->freq1_offset, REC->center_freq2, REC->count, REC->block_tx, REC->timestamp
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_conf_tx/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_conf_tx/format
new file mode 100644
index 000000000..cede1bc99
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_conf_tx/format
@@ -0,0 +1,21 @@
+name: drv_conf_tx
+ID: 1460
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u16 ac; offset:64; size:2; signed:0;
+ field:u16 txop; offset:66; size:2; signed:0;
+ field:u16 cw_min; offset:68; size:2; signed:0;
+ field:u16 cw_max; offset:70; size:2; signed:0;
+ field:u8 aifs; offset:72; size:1; signed:0;
+ field:bool uapsd; offset:73; size:1; signed:0;
+
+print fmt: "%s vif:%s(%d%s) AC:%d", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->ac
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_config/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_config/format
new file mode 100644
index 000000000..c5c941645
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_config/format
@@ -0,0 +1,25 @@
+name: drv_config
+ID: 1461
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 changed; offset:40; size:4; signed:0;
+ field:u32 flags; offset:44; size:4; signed:0;
+ field:int power_level; offset:48; size:4; signed:1;
+ field:int dynamic_ps_timeout; offset:52; size:4; signed:1;
+ field:u16 listen_interval; offset:56; size:2; signed:0;
+ field:u8 long_frame_max_tx_count; offset:58; size:1; signed:0;
+ field:u8 short_frame_max_tx_count; offset:59; size:1; signed:0;
+ field:u32 control_freq; offset:60; size:4; signed:0;
+ field:u32 freq_offset; offset:64; size:4; signed:0;
+ field:u32 chan_width; offset:68; size:4; signed:0;
+ field:u32 center_freq1; offset:72; size:4; signed:0;
+ field:u32 freq1_offset; offset:76; size:4; signed:0;
+ field:u32 center_freq2; offset:80; size:4; signed:0;
+ field:int smps; offset:84; size:4; signed:1;
+
+print fmt: "%s ch:%#x control:%d.%03d MHz width:%d center: %d.%03d/%d MHz", REC->wiphy_name, REC->changed, REC->control_freq, REC->freq_offset, REC->chan_width, REC->center_freq1, REC->freq1_offset, REC->center_freq2
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_config_iface_filter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_config_iface_filter/format
new file mode 100644
index 000000000..3c238f628
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_config_iface_filter/format
@@ -0,0 +1,17 @@
+name: drv_config_iface_filter
+ID: 1462
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:unsigned int filter_flags; offset:64; size:4; signed:0;
+ field:unsigned int changed_flags; offset:68; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s) filter_flags: %#x changed_flags: %#x", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->filter_flags, REC->changed_flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_configure_filter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_configure_filter/format
new file mode 100644
index 000000000..6c45ca485
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_configure_filter/format
@@ -0,0 +1,14 @@
+name: drv_configure_filter
+ID: 1463
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:unsigned int changed; offset:40; size:4; signed:0;
+ field:unsigned int total; offset:44; size:4; signed:0;
+ field:u64 multicast; offset:48; size:8; signed:0;
+
+print fmt: "%s changed:%#x total:%#x", REC->wiphy_name, REC->changed, REC->total
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_del_nan_func/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_del_nan_func/format
new file mode 100644
index 000000000..9a753cd8c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_del_nan_func/format
@@ -0,0 +1,16 @@
+name: drv_del_nan_func
+ID: 1464
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u8 instance_id; offset:64; size:1; signed:0;
+
+print fmt: "%s vif:%s(%d%s), instance_id: %u", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->instance_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_event_callback/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_event_callback/format
new file mode 100644
index 000000000..29a9910f7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_event_callback/format
@@ -0,0 +1,16 @@
+name: drv_event_callback
+ID: 1465
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u32 type; offset:64; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s) event:%d", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->type
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_flush/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_flush/format
new file mode 100644
index 000000000..70328f880
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_flush/format
@@ -0,0 +1,13 @@
+name: drv_flush
+ID: 1466
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:bool drop; offset:40; size:1; signed:0;
+ field:u32 queues; offset:44; size:4; signed:0;
+
+print fmt: "%s queues:0x%x drop:%d", REC->wiphy_name, REC->queues, REC->drop
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_antenna/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_antenna/format
new file mode 100644
index 000000000..00415fb1e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_antenna/format
@@ -0,0 +1,14 @@
+name: drv_get_antenna
+ID: 1467
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 tx_ant; offset:40; size:4; signed:0;
+ field:u32 rx_ant; offset:44; size:4; signed:0;
+ field:int ret; offset:48; size:4; signed:1;
+
+print fmt: "%s tx_ant:%d rx_ant:%d ret:%d", REC->wiphy_name, REC->tx_ant, REC->rx_ant, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_et_sset_count/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_et_sset_count/format
new file mode 100644
index 000000000..221805ac8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_et_sset_count/format
@@ -0,0 +1,12 @@
+name: drv_get_et_sset_count
+ID: 1468
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 value; offset:40; size:4; signed:0;
+
+print fmt: "%s value:%d", REC->wiphy_name, REC->value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_et_stats/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_et_stats/format
new file mode 100644
index 000000000..1e9edef6e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_et_stats/format
@@ -0,0 +1,11 @@
+name: drv_get_et_stats
+ID: 1469
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_et_strings/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_et_strings/format
new file mode 100644
index 000000000..298a815a1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_et_strings/format
@@ -0,0 +1,12 @@
+name: drv_get_et_strings
+ID: 1470
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 value; offset:40; size:4; signed:0;
+
+print fmt: "%s value:%d", REC->wiphy_name, REC->value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_expected_throughput/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_expected_throughput/format
new file mode 100644
index 000000000..7ec2bb08f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_expected_throughput/format
@@ -0,0 +1,11 @@
+name: drv_get_expected_throughput
+ID: 1471
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char sta_addr[6]; offset:8; size:6; signed:0;
+
+print fmt: " sta:%pM", REC->sta_addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_ftm_responder_stats/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_ftm_responder_stats/format
new file mode 100644
index 000000000..5797dcc9c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_ftm_responder_stats/format
@@ -0,0 +1,15 @@
+name: drv_get_ftm_responder_stats
+ID: 1472
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_key_seq/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_key_seq/format
new file mode 100644
index 000000000..d85633ccf
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_key_seq/format
@@ -0,0 +1,15 @@
+name: drv_get_key_seq
+ID: 1473
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 cipher; offset:40; size:4; signed:0;
+ field:u8 hw_key_idx; offset:44; size:1; signed:0;
+ field:u8 flags; offset:45; size:1; signed:0;
+ field:s8 keyidx; offset:46; size:1; signed:1;
+
+print fmt: "%s cipher:0x%x, flags=%#x, keyidx=%d, hw_key_idx=%d", REC->wiphy_name, REC->cipher, REC->flags, REC->keyidx, REC->hw_key_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_ringparam/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_ringparam/format
new file mode 100644
index 000000000..63faa552f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_ringparam/format
@@ -0,0 +1,15 @@
+name: drv_get_ringparam
+ID: 1474
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 tx; offset:40; size:4; signed:0;
+ field:u32 tx_max; offset:44; size:4; signed:0;
+ field:u32 rx; offset:48; size:4; signed:0;
+ field:u32 rx_max; offset:52; size:4; signed:0;
+
+print fmt: "%s tx:%d tx_max %d rx %d rx_max %d", REC->wiphy_name, REC->tx, REC->tx_max, REC->rx, REC->rx_max
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_stats/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_stats/format
new file mode 100644
index 000000000..5ad7f8c34
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_stats/format
@@ -0,0 +1,16 @@
+name: drv_get_stats
+ID: 1475
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:int ret; offset:40; size:4; signed:1;
+ field:unsigned int ackfail; offset:44; size:4; signed:0;
+ field:unsigned int rtsfail; offset:48; size:4; signed:0;
+ field:unsigned int fcserr; offset:52; size:4; signed:0;
+ field:unsigned int rtssucc; offset:56; size:4; signed:0;
+
+print fmt: "%s ret:%d", REC->wiphy_name, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_survey/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_survey/format
new file mode 100644
index 000000000..c0b4f7d8d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_survey/format
@@ -0,0 +1,12 @@
+name: drv_get_survey
+ID: 1476
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:int idx; offset:40; size:4; signed:1;
+
+print fmt: "%s idx:%d", REC->wiphy_name, REC->idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_tsf/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_tsf/format
new file mode 100644
index 000000000..768f76453
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_tsf/format
@@ -0,0 +1,15 @@
+name: drv_get_tsf
+ID: 1477
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_txpower/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_txpower/format
new file mode 100644
index 000000000..34f2072c0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_get_txpower/format
@@ -0,0 +1,17 @@
+name: drv_get_txpower
+ID: 1478
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:int dbm; offset:64; size:4; signed:1;
+ field:int ret; offset:68; size:4; signed:1;
+
+print fmt: "%s vif:%s(%d%s) dbm:%d ret:%d", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->dbm, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_hw_scan/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_hw_scan/format
new file mode 100644
index 000000000..c1d81b256
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_hw_scan/format
@@ -0,0 +1,15 @@
+name: drv_hw_scan
+ID: 1479
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_ipv6_addr_change/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_ipv6_addr_change/format
new file mode 100644
index 000000000..630f1efb2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_ipv6_addr_change/format
@@ -0,0 +1,15 @@
+name: drv_ipv6_addr_change
+ID: 1480
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_join_ibss/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_join_ibss/format
new file mode 100644
index 000000000..7f55c5546
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_join_ibss/format
@@ -0,0 +1,18 @@
+name: drv_join_ibss
+ID: 1481
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u8 dtimper; offset:64; size:1; signed:0;
+ field:u16 bcnint; offset:66; size:2; signed:0;
+ field:__data_loc u8[] ssid; offset:68; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_leave_ibss/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_leave_ibss/format
new file mode 100644
index 000000000..3076a92e9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_leave_ibss/format
@@ -0,0 +1,15 @@
+name: drv_leave_ibss
+ID: 1482
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_mgd_prepare_tx/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_mgd_prepare_tx/format
new file mode 100644
index 000000000..af1ddc773
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_mgd_prepare_tx/format
@@ -0,0 +1,16 @@
+name: drv_mgd_prepare_tx
+ID: 1483
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u32 duration; offset:64; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s) duration: %u", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->duration
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_mgd_protect_tdls_discover/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_mgd_protect_tdls_discover/format
new file mode 100644
index 000000000..ee7e27628
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_mgd_protect_tdls_discover/format
@@ -0,0 +1,15 @@
+name: drv_mgd_protect_tdls_discover
+ID: 1484
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_nan_change_conf/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_nan_change_conf/format
new file mode 100644
index 000000000..bb2b0f5b9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_nan_change_conf/format
@@ -0,0 +1,18 @@
+name: drv_nan_change_conf
+ID: 1485
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u8 master_pref; offset:64; size:1; signed:0;
+ field:u8 bands; offset:65; size:1; signed:0;
+ field:u32 changes; offset:68; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s), master preference: %u, bands: 0x%0x, changes: 0x%x", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->master_pref, REC->bands, REC->changes
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_offchannel_tx_cancel_wait/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_offchannel_tx_cancel_wait/format
new file mode 100644
index 000000000..f33fb3a5f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_offchannel_tx_cancel_wait/format
@@ -0,0 +1,11 @@
+name: drv_offchannel_tx_cancel_wait
+ID: 1486
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_offset_tsf/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_offset_tsf/format
new file mode 100644
index 000000000..d591fea90
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_offset_tsf/format
@@ -0,0 +1,16 @@
+name: drv_offset_tsf
+ID: 1487
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:s64 tsf_offset; offset:64; size:8; signed:1;
+
+print fmt: "%s vif:%s(%d%s) tsf offset:%lld", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", (unsigned long long)REC->tsf_offset
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_post_channel_switch/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_post_channel_switch/format
new file mode 100644
index 000000000..8754c9981
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_post_channel_switch/format
@@ -0,0 +1,15 @@
+name: drv_post_channel_switch
+ID: 1488
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_pre_channel_switch/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_pre_channel_switch/format
new file mode 100644
index 000000000..c606607b4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_pre_channel_switch/format
@@ -0,0 +1,25 @@
+name: drv_pre_channel_switch
+ID: 1489
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u32 control_freq; offset:64; size:4; signed:0;
+ field:u32 freq_offset; offset:68; size:4; signed:0;
+ field:u32 chan_width; offset:72; size:4; signed:0;
+ field:u32 center_freq1; offset:76; size:4; signed:0;
+ field:u32 freq1_offset; offset:80; size:4; signed:0;
+ field:u32 center_freq2; offset:84; size:4; signed:0;
+ field:u64 timestamp; offset:88; size:8; signed:0;
+ field:u32 device_timestamp; offset:96; size:4; signed:0;
+ field:bool block_tx; offset:100; size:1; signed:0;
+ field:u8 count; offset:101; size:1; signed:0;
+
+print fmt: "%s vif:%s(%d%s) prepare channel switch to control:%d.%03d MHz width:%d center: %d.%03d/%d MHz count:%d block_tx:%d timestamp:%llu", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->control_freq, REC->freq_offset, REC->chan_width, REC->center_freq1, REC->freq1_offset, REC->center_freq2, REC->count, REC->block_tx, REC->timestamp
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_prepare_multicast/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_prepare_multicast/format
new file mode 100644
index 000000000..aca854cc4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_prepare_multicast/format
@@ -0,0 +1,12 @@
+name: drv_prepare_multicast
+ID: 1490
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:int mc_count; offset:40; size:4; signed:1;
+
+print fmt: "%s prepare mc (%d)", REC->wiphy_name, REC->mc_count
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_reconfig_complete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_reconfig_complete/format
new file mode 100644
index 000000000..7e83fb5dc
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_reconfig_complete/format
@@ -0,0 +1,12 @@
+name: drv_reconfig_complete
+ID: 1491
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u8 reconfig_type; offset:40; size:1; signed:0;
+
+print fmt: "%s reconfig_type:%d", REC->wiphy_name, REC->reconfig_type
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_release_buffered_frames/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_release_buffered_frames/format
new file mode 100644
index 000000000..7624400d9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_release_buffered_frames/format
@@ -0,0 +1,16 @@
+name: drv_release_buffered_frames
+ID: 1492
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char sta_addr[6]; offset:40; size:6; signed:0;
+ field:u16 tids; offset:46; size:2; signed:0;
+ field:int num_frames; offset:48; size:4; signed:1;
+ field:int reason; offset:52; size:4; signed:1;
+ field:bool more_data; offset:56; size:1; signed:0;
+
+print fmt: "%s sta:%pM TIDs:0x%.4x frames:%d reason:%d more:%d", REC->wiphy_name, REC->sta_addr, REC->tids, REC->num_frames, REC->reason, REC->more_data
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_remain_on_channel/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_remain_on_channel/format
new file mode 100644
index 000000000..9ea51b953
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_remain_on_channel/format
@@ -0,0 +1,19 @@
+name: drv_remain_on_channel
+ID: 1493
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:int center_freq; offset:64; size:4; signed:1;
+ field:int freq_offset; offset:68; size:4; signed:1;
+ field:unsigned int duration; offset:72; size:4; signed:0;
+ field:u32 type; offset:76; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s) freq:%d.%03dMHz duration:%dms type=%d", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->center_freq, REC->freq_offset, REC->duration, REC->type
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_remove_chanctx/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_remove_chanctx/format
new file mode 100644
index 000000000..2032c1f7f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_remove_chanctx/format
@@ -0,0 +1,25 @@
+name: drv_remove_chanctx
+ID: 1494
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 control_freq; offset:40; size:4; signed:0;
+ field:u32 freq_offset; offset:44; size:4; signed:0;
+ field:u32 chan_width; offset:48; size:4; signed:0;
+ field:u32 center_freq1; offset:52; size:4; signed:0;
+ field:u32 freq1_offset; offset:56; size:4; signed:0;
+ field:u32 center_freq2; offset:60; size:4; signed:0;
+ field:u32 min_control_freq; offset:64; size:4; signed:0;
+ field:u32 min_freq_offset; offset:68; size:4; signed:0;
+ field:u32 min_chan_width; offset:72; size:4; signed:0;
+ field:u32 min_center_freq1; offset:76; size:4; signed:0;
+ field:u32 min_freq1_offset; offset:80; size:4; signed:0;
+ field:u32 min_center_freq2; offset:84; size:4; signed:0;
+ field:u8 rx_chains_static; offset:88; size:1; signed:0;
+ field:u8 rx_chains_dynamic; offset:89; size:1; signed:0;
+
+print fmt: "%s control:%d.%03d MHz width:%d center: %d.%03d/%d MHz min_control:%d.%03d MHz min_width:%d min_center: %d.%03d/%d MHz chains:%d/%d", REC->wiphy_name, REC->control_freq, REC->freq_offset, REC->chan_width, REC->center_freq1, REC->freq1_offset, REC->center_freq2, REC->min_control_freq, REC->min_freq_offset, REC->min_chan_width, REC->min_center_freq1, REC->min_freq1_offset, REC->min_center_freq2, REC->rx_chains_static, REC->rx_chains_dynamic
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_remove_interface/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_remove_interface/format
new file mode 100644
index 000000000..1b18b3368
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_remove_interface/format
@@ -0,0 +1,16 @@
+name: drv_remove_interface
+ID: 1495
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:char addr[6]; offset:64; size:6; signed:0;
+
+print fmt: "%s vif:%s(%d%s) addr:%pM", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_reset_tsf/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_reset_tsf/format
new file mode 100644
index 000000000..abe8b7ff9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_reset_tsf/format
@@ -0,0 +1,15 @@
+name: drv_reset_tsf
+ID: 1496
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_resume/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_resume/format
new file mode 100644
index 000000000..0932b3c97
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_resume/format
@@ -0,0 +1,11 @@
+name: drv_resume
+ID: 1497
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_return_bool/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_return_bool/format
new file mode 100644
index 000000000..84a1b17b6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_return_bool/format
@@ -0,0 +1,12 @@
+name: drv_return_bool
+ID: 1498
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:bool ret; offset:40; size:1; signed:0;
+
+print fmt: "%s - %s", REC->wiphy_name, (REC->ret) ? "true" : "false"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_return_int/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_return_int/format
new file mode 100644
index 000000000..2aa0dd335
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_return_int/format
@@ -0,0 +1,12 @@
+name: drv_return_int
+ID: 1499
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:int ret; offset:40; size:4; signed:1;
+
+print fmt: "%s - %d", REC->wiphy_name, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_return_u32/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_return_u32/format
new file mode 100644
index 000000000..cd8ae0f89
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_return_u32/format
@@ -0,0 +1,12 @@
+name: drv_return_u32
+ID: 1500
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 ret; offset:40; size:4; signed:0;
+
+print fmt: "%s - %u", REC->wiphy_name, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_return_u64/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_return_u64/format
new file mode 100644
index 000000000..ecffbef7d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_return_u64/format
@@ -0,0 +1,12 @@
+name: drv_return_u64
+ID: 1501
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u64 ret; offset:40; size:8; signed:0;
+
+print fmt: "%s - %llu", REC->wiphy_name, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_return_void/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_return_void/format
new file mode 100644
index 000000000..5055c1893
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_return_void/format
@@ -0,0 +1,11 @@
+name: drv_return_void
+ID: 1502
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sched_scan_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sched_scan_start/format
new file mode 100644
index 000000000..107c9297f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sched_scan_start/format
@@ -0,0 +1,15 @@
+name: drv_sched_scan_start
+ID: 1503
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sched_scan_stop/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sched_scan_stop/format
new file mode 100644
index 000000000..c1ff9362e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sched_scan_stop/format
@@ -0,0 +1,15 @@
+name: drv_sched_scan_stop
+ID: 1504
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_antenna/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_antenna/format
new file mode 100644
index 000000000..710083d7a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_antenna/format
@@ -0,0 +1,14 @@
+name: drv_set_antenna
+ID: 1505
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 tx_ant; offset:40; size:4; signed:0;
+ field:u32 rx_ant; offset:44; size:4; signed:0;
+ field:int ret; offset:48; size:4; signed:1;
+
+print fmt: "%s tx_ant:%d rx_ant:%d ret:%d", REC->wiphy_name, REC->tx_ant, REC->rx_ant, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_bitrate_mask/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_bitrate_mask/format
new file mode 100644
index 000000000..bc6802a51
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_bitrate_mask/format
@@ -0,0 +1,17 @@
+name: drv_set_bitrate_mask
+ID: 1506
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u32 legacy_2g; offset:64; size:4; signed:0;
+ field:u32 legacy_5g; offset:68; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s) 2G Mask:0x%x 5G Mask:0x%x", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->legacy_2g, REC->legacy_5g
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_coverage_class/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_coverage_class/format
new file mode 100644
index 000000000..f7d70f10e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_coverage_class/format
@@ -0,0 +1,12 @@
+name: drv_set_coverage_class
+ID: 1507
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:s16 value; offset:40; size:2; signed:1;
+
+print fmt: "%s value:%d", REC->wiphy_name, REC->value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_default_unicast_key/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_default_unicast_key/format
new file mode 100644
index 000000000..2495fb35f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_default_unicast_key/format
@@ -0,0 +1,16 @@
+name: drv_set_default_unicast_key
+ID: 1508
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:int key_idx; offset:64; size:4; signed:1;
+
+print fmt: "%s vif:%s(%d%s) key_idx:%d", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->key_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_frag_threshold/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_frag_threshold/format
new file mode 100644
index 000000000..2ad7acc42
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_frag_threshold/format
@@ -0,0 +1,12 @@
+name: drv_set_frag_threshold
+ID: 1509
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 value; offset:40; size:4; signed:0;
+
+print fmt: "%s value:%d", REC->wiphy_name, REC->value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_key/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_key/format
new file mode 100644
index 000000000..460f148a5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_key/format
@@ -0,0 +1,20 @@
+name: drv_set_key
+ID: 1510
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:char sta_addr[6]; offset:64; size:6; signed:0;
+ field:u32 cipher; offset:72; size:4; signed:0;
+ field:u8 hw_key_idx; offset:76; size:1; signed:0;
+ field:u8 flags; offset:77; size:1; signed:0;
+ field:s8 keyidx; offset:78; size:1; signed:1;
+
+print fmt: "%s vif:%s(%d%s) sta:%pM cipher:0x%x, flags=%#x, keyidx=%d, hw_key_idx=%d", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->sta_addr, REC->cipher, REC->flags, REC->keyidx, REC->hw_key_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_rekey_data/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_rekey_data/format
new file mode 100644
index 000000000..231af95a4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_rekey_data/format
@@ -0,0 +1,18 @@
+name: drv_set_rekey_data
+ID: 1511
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u8 kek[16]; offset:64; size:16; signed:0;
+ field:u8 kck[16]; offset:80; size:16; signed:0;
+ field:u8 replay_ctr[8]; offset:96; size:8; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_ringparam/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_ringparam/format
new file mode 100644
index 000000000..ff7c0c361
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_ringparam/format
@@ -0,0 +1,13 @@
+name: drv_set_ringparam
+ID: 1512
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 tx; offset:40; size:4; signed:0;
+ field:u32 rx; offset:44; size:4; signed:0;
+
+print fmt: "%s tx:%d rx %d", REC->wiphy_name, REC->tx, REC->rx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_rts_threshold/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_rts_threshold/format
new file mode 100644
index 000000000..ede26540d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_rts_threshold/format
@@ -0,0 +1,12 @@
+name: drv_set_rts_threshold
+ID: 1513
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u32 value; offset:40; size:4; signed:0;
+
+print fmt: "%s value:%d", REC->wiphy_name, REC->value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_tim/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_tim/format
new file mode 100644
index 000000000..a5c1c88b6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_tim/format
@@ -0,0 +1,13 @@
+name: drv_set_tim
+ID: 1514
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:char sta_addr[6]; offset:40; size:6; signed:0;
+ field:bool set; offset:46; size:1; signed:0;
+
+print fmt: "%s sta:%pM set:%d", REC->wiphy_name, REC->sta_addr, REC->set
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_tsf/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_tsf/format
new file mode 100644
index 000000000..e6049bd4c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_tsf/format
@@ -0,0 +1,16 @@
+name: drv_set_tsf
+ID: 1515
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u64 tsf; offset:64; size:8; signed:0;
+
+print fmt: "%s vif:%s(%d%s) tsf:%llu", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", (unsigned long long)REC->tsf
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_wakeup/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_wakeup/format
new file mode 100644
index 000000000..a1026566c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_set_wakeup/format
@@ -0,0 +1,12 @@
+name: drv_set_wakeup
+ID: 1516
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:bool enabled; offset:40; size:1; signed:0;
+
+print fmt: "%s enabled:%d", REC->wiphy_name, REC->enabled
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_add/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_add/format
new file mode 100644
index 000000000..71403e42e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_add/format
@@ -0,0 +1,16 @@
+name: drv_sta_add
+ID: 1517
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:char sta_addr[6]; offset:64; size:6; signed:0;
+
+print fmt: "%s vif:%s(%d%s) sta:%pM", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->sta_addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_notify/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_notify/format
new file mode 100644
index 000000000..1f385d853
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_notify/format
@@ -0,0 +1,17 @@
+name: drv_sta_notify
+ID: 1518
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:char sta_addr[6]; offset:64; size:6; signed:0;
+ field:u32 cmd; offset:72; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s) sta:%pM cmd:%d", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->sta_addr, REC->cmd
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_pre_rcu_remove/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_pre_rcu_remove/format
new file mode 100644
index 000000000..3b15b6d4c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_pre_rcu_remove/format
@@ -0,0 +1,16 @@
+name: drv_sta_pre_rcu_remove
+ID: 1519
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:char sta_addr[6]; offset:64; size:6; signed:0;
+
+print fmt: "%s vif:%s(%d%s) sta:%pM", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->sta_addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_rate_tbl_update/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_rate_tbl_update/format
new file mode 100644
index 000000000..cf9c27e78
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_rate_tbl_update/format
@@ -0,0 +1,16 @@
+name: drv_sta_rate_tbl_update
+ID: 1520
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:char sta_addr[6]; offset:64; size:6; signed:0;
+
+print fmt: "%s vif:%s(%d%s) sta:%pM", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->sta_addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_rc_update/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_rc_update/format
new file mode 100644
index 000000000..69f4f955c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_rc_update/format
@@ -0,0 +1,17 @@
+name: drv_sta_rc_update
+ID: 1521
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:char sta_addr[6]; offset:64; size:6; signed:0;
+ field:u32 changed; offset:72; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s) sta:%pM changed: 0x%x", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->sta_addr, REC->changed
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_remove/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_remove/format
new file mode 100644
index 000000000..80c09011b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_remove/format
@@ -0,0 +1,16 @@
+name: drv_sta_remove
+ID: 1522
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:char sta_addr[6]; offset:64; size:6; signed:0;
+
+print fmt: "%s vif:%s(%d%s) sta:%pM", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->sta_addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_set_4addr/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_set_4addr/format
new file mode 100644
index 000000000..52e219e6a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_set_4addr/format
@@ -0,0 +1,17 @@
+name: drv_sta_set_4addr
+ID: 1523
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:char sta_addr[6]; offset:64; size:6; signed:0;
+ field:bool enabled; offset:70; size:1; signed:0;
+
+print fmt: "%s vif:%s(%d%s) sta:%pM enabled:%d", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->sta_addr, REC->enabled
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_set_txpwr/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_set_txpwr/format
new file mode 100644
index 000000000..b29e246a4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_set_txpwr/format
@@ -0,0 +1,18 @@
+name: drv_sta_set_txpwr
+ID: 1524
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:char sta_addr[6]; offset:64; size:6; signed:0;
+ field:s16 txpwr; offset:70; size:2; signed:1;
+ field:u8 type; offset:72; size:1; signed:0;
+
+print fmt: "%s vif:%s(%d%s) sta:%pM txpwr: %d type %d", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->sta_addr, REC->txpwr, REC->type
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_state/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_state/format
new file mode 100644
index 000000000..d7b7fca03
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_state/format
@@ -0,0 +1,18 @@
+name: drv_sta_state
+ID: 1525
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:char sta_addr[6]; offset:64; size:6; signed:0;
+ field:u32 old_state; offset:72; size:4; signed:0;
+ field:u32 new_state; offset:76; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s) sta:%pM state: %d->%d", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->sta_addr, REC->old_state, REC->new_state
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_statistics/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_statistics/format
new file mode 100644
index 000000000..27a1cdb64
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sta_statistics/format
@@ -0,0 +1,16 @@
+name: drv_sta_statistics
+ID: 1526
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:char sta_addr[6]; offset:64; size:6; signed:0;
+
+print fmt: "%s vif:%s(%d%s) sta:%pM", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->sta_addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_start/format
new file mode 100644
index 000000000..427012f7b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_start/format
@@ -0,0 +1,11 @@
+name: drv_start
+ID: 1527
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_start_ap/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_start_ap/format
new file mode 100644
index 000000000..efb87703e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_start_ap/format
@@ -0,0 +1,19 @@
+name: drv_start_ap
+ID: 1528
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u8 dtimper; offset:64; size:1; signed:0;
+ field:u16 bcnint; offset:66; size:2; signed:0;
+ field:__data_loc u8[] ssid; offset:68; size:4; signed:0;
+ field:bool hidden_ssid; offset:72; size:1; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_start_nan/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_start_nan/format
new file mode 100644
index 000000000..93db22f81
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_start_nan/format
@@ -0,0 +1,17 @@
+name: drv_start_nan
+ID: 1529
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u8 master_pref; offset:64; size:1; signed:0;
+ field:u8 bands; offset:65; size:1; signed:0;
+
+print fmt: "%s vif:%s(%d%s), master preference: %u, bands: 0x%0x", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->master_pref, REC->bands
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_start_pmsr/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_start_pmsr/format
new file mode 100644
index 000000000..15e3bfb15
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_start_pmsr/format
@@ -0,0 +1,15 @@
+name: drv_start_pmsr
+ID: 1530
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_stop/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_stop/format
new file mode 100644
index 000000000..b5a66ae56
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_stop/format
@@ -0,0 +1,11 @@
+name: drv_stop
+ID: 1531
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_stop_ap/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_stop_ap/format
new file mode 100644
index 000000000..3cf62ab1a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_stop_ap/format
@@ -0,0 +1,15 @@
+name: drv_stop_ap
+ID: 1532
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_stop_nan/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_stop_nan/format
new file mode 100644
index 000000000..3e7507810
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_stop_nan/format
@@ -0,0 +1,15 @@
+name: drv_stop_nan
+ID: 1533
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_suspend/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_suspend/format
new file mode 100644
index 000000000..25ac4fb87
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_suspend/format
@@ -0,0 +1,11 @@
+name: drv_suspend
+ID: 1534
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sw_scan_complete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sw_scan_complete/format
new file mode 100644
index 000000000..4b92159b1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sw_scan_complete/format
@@ -0,0 +1,15 @@
+name: drv_sw_scan_complete
+ID: 1535
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s)", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : ""
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sw_scan_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sw_scan_start/format
new file mode 100644
index 000000000..4be704c48
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sw_scan_start/format
@@ -0,0 +1,16 @@
+name: drv_sw_scan_start
+ID: 1536
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:char mac_addr[6]; offset:64; size:6; signed:0;
+
+print fmt: "%s, vif:%s(%d%s), addr:%pM", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->mac_addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_switch_vif_chanctx/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_switch_vif_chanctx/format
new file mode 100644
index 000000000..6e1b9bd8c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_switch_vif_chanctx/format
@@ -0,0 +1,14 @@
+name: drv_switch_vif_chanctx
+ID: 1537
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:int n_vifs; offset:40; size:4; signed:1;
+ field:u32 mode; offset:44; size:4; signed:0;
+ field:__data_loc u8[] vifs; offset:48; size:4; signed:0;
+
+print fmt: "%s n_vifs:%d mode:%d", REC->wiphy_name, REC->n_vifs, REC->mode
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sync_rx_queues/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sync_rx_queues/format
new file mode 100644
index 000000000..d2eb58db5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_sync_rx_queues/format
@@ -0,0 +1,16 @@
+name: drv_sync_rx_queues
+ID: 1538
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:char sta_addr[6]; offset:64; size:6; signed:0;
+
+print fmt: "%s vif:%s(%d%s) sta:%pM", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->sta_addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_tdls_cancel_channel_switch/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_tdls_cancel_channel_switch/format
new file mode 100644
index 000000000..5d0def728
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_tdls_cancel_channel_switch/format
@@ -0,0 +1,16 @@
+name: drv_tdls_cancel_channel_switch
+ID: 1539
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:char sta_addr[6]; offset:64; size:6; signed:0;
+
+print fmt: "%s vif:%s(%d%s) tdls cancel channel switch with sta:%pM", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->sta_addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_tdls_channel_switch/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_tdls_channel_switch/format
new file mode 100644
index 000000000..4277acd9a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_tdls_channel_switch/format
@@ -0,0 +1,23 @@
+name: drv_tdls_channel_switch
+ID: 1540
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:char sta_addr[6]; offset:64; size:6; signed:0;
+ field:u8 oper_class; offset:70; size:1; signed:0;
+ field:u32 control_freq; offset:72; size:4; signed:0;
+ field:u32 freq_offset; offset:76; size:4; signed:0;
+ field:u32 chan_width; offset:80; size:4; signed:0;
+ field:u32 center_freq1; offset:84; size:4; signed:0;
+ field:u32 freq1_offset; offset:88; size:4; signed:0;
+ field:u32 center_freq2; offset:92; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s) tdls channel switch to control:%d.%03d MHz width:%d center: %d.%03d/%d MHz oper_class:%d sta:%pM", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->control_freq, REC->freq_offset, REC->chan_width, REC->center_freq1, REC->freq1_offset, REC->center_freq2, REC->oper_class, REC->sta_addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_tdls_recv_channel_switch/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_tdls_recv_channel_switch/format
new file mode 100644
index 000000000..81dd88a07
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_tdls_recv_channel_switch/format
@@ -0,0 +1,28 @@
+name: drv_tdls_recv_channel_switch
+ID: 1541
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u8 action_code; offset:64; size:1; signed:0;
+ field:char sta_addr[6]; offset:65; size:6; signed:0;
+ field:u32 control_freq; offset:72; size:4; signed:0;
+ field:u32 freq_offset; offset:76; size:4; signed:0;
+ field:u32 chan_width; offset:80; size:4; signed:0;
+ field:u32 center_freq1; offset:84; size:4; signed:0;
+ field:u32 freq1_offset; offset:88; size:4; signed:0;
+ field:u32 center_freq2; offset:92; size:4; signed:0;
+ field:u32 status; offset:96; size:4; signed:0;
+ field:bool peer_initiator; offset:100; size:1; signed:0;
+ field:u32 timestamp; offset:104; size:4; signed:0;
+ field:u16 switch_time; offset:108; size:2; signed:0;
+ field:u16 switch_timeout; offset:110; size:2; signed:0;
+
+print fmt: "%s vif:%s(%d%s) received tdls channel switch packet action:%d status:%d time:%d switch time:%d switch timeout:%d initiator: %d chan: control:%d.%03d MHz width:%d center: %d.%03d/%d MHz sta:%pM", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->action_code, REC->status, REC->timestamp, REC->switch_time, REC->switch_timeout, REC->peer_initiator, REC->control_freq, REC->freq_offset, REC->chan_width, REC->center_freq1, REC->freq1_offset, REC->center_freq2, REC->sta_addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_tx_frames_pending/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_tx_frames_pending/format
new file mode 100644
index 000000000..6004bd7a1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_tx_frames_pending/format
@@ -0,0 +1,11 @@
+name: drv_tx_frames_pending
+ID: 1542
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_tx_last_beacon/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_tx_last_beacon/format
new file mode 100644
index 000000000..0e929176f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_tx_last_beacon/format
@@ -0,0 +1,11 @@
+name: drv_tx_last_beacon
+ID: 1543
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wiphy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_unassign_vif_chanctx/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_unassign_vif_chanctx/format
new file mode 100644
index 000000000..76ad527d7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_unassign_vif_chanctx/format
@@ -0,0 +1,29 @@
+name: drv_unassign_vif_chanctx
+ID: 1544
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:u32 control_freq; offset:64; size:4; signed:0;
+ field:u32 freq_offset; offset:68; size:4; signed:0;
+ field:u32 chan_width; offset:72; size:4; signed:0;
+ field:u32 center_freq1; offset:76; size:4; signed:0;
+ field:u32 freq1_offset; offset:80; size:4; signed:0;
+ field:u32 center_freq2; offset:84; size:4; signed:0;
+ field:u32 min_control_freq; offset:88; size:4; signed:0;
+ field:u32 min_freq_offset; offset:92; size:4; signed:0;
+ field:u32 min_chan_width; offset:96; size:4; signed:0;
+ field:u32 min_center_freq1; offset:100; size:4; signed:0;
+ field:u32 min_freq1_offset; offset:104; size:4; signed:0;
+ field:u32 min_center_freq2; offset:108; size:4; signed:0;
+ field:u8 rx_chains_static; offset:112; size:1; signed:0;
+ field:u8 rx_chains_dynamic; offset:113; size:1; signed:0;
+
+print fmt: "%s vif:%s(%d%s) control:%d.%03d MHz width:%d center: %d.%03d/%d MHz min_control:%d.%03d MHz min_width:%d min_center: %d.%03d/%d MHz chains:%d/%d", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->control_freq, REC->freq_offset, REC->chan_width, REC->center_freq1, REC->freq1_offset, REC->center_freq2, REC->min_control_freq, REC->min_freq_offset, REC->min_chan_width, REC->min_center_freq1, REC->min_freq1_offset, REC->min_center_freq2, REC->rx_chains_static, REC->rx_chains_dynamic
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_update_tkip_key/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_update_tkip_key/format
new file mode 100644
index 000000000..acd922957
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_update_tkip_key/format
@@ -0,0 +1,17 @@
+name: drv_update_tkip_key
+ID: 1545
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:char sta_addr[6]; offset:64; size:6; signed:0;
+ field:u32 iv32; offset:72; size:4; signed:0;
+
+print fmt: "%s vif:%s(%d%s) sta:%pM iv32:%#x", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->sta_addr, REC->iv32
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_update_vif_offload/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_update_vif_offload/format
new file mode 100644
index 000000000..6d5de8e48
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_update_vif_offload/format
@@ -0,0 +1,16 @@
+name: drv_update_vif_offload
+ID: 1546
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:char addr[6]; offset:64; size:6; signed:0;
+
+print fmt: "%s vif:%s(%d%s) addr:%pM", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_wake_tx_queue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_wake_tx_queue/format
new file mode 100644
index 000000000..6d0934f1f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/drv_wake_tx_queue/format
@@ -0,0 +1,18 @@
+name: drv_wake_tx_queue
+ID: 1547
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl80211_iftype vif_type; offset:40; size:4; signed:0;
+ field:void * sdata; offset:48; size:8; signed:0;
+ field:bool p2p; offset:56; size:1; signed:0;
+ field:__data_loc char[] vif_name; offset:60; size:4; signed:0;
+ field:char sta_addr[6]; offset:64; size:6; signed:0;
+ field:u8 ac; offset:70; size:1; signed:0;
+ field:u8 tid; offset:71; size:1; signed:0;
+
+print fmt: "%s vif:%s(%d%s) sta:%pM ac:%d tid:%d", REC->wiphy_name, __get_str(vif_name), REC->vif_type, REC->p2p ? "/p2p" : "", REC->sta_addr, REC->ac, REC->tid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/stop_queue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/stop_queue/format
new file mode 100644
index 000000000..600665f41
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/stop_queue/format
@@ -0,0 +1,13 @@
+name: stop_queue
+ID: 1548
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u16 queue; offset:40; size:2; signed:0;
+ field:u32 reason; offset:44; size:4; signed:0;
+
+print fmt: "%s queue:%d, reason:%d", REC->wiphy_name, REC->queue, REC->reason
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/wake_queue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/wake_queue/format
new file mode 100644
index 000000000..f24538dfc
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac80211/wake_queue/format
@@ -0,0 +1,13 @@
+name: wake_queue
+ID: 1549
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wiphy_name[32]; offset:8; size:32; signed:0;
+ field:u16 queue; offset:40; size:2; signed:0;
+ field:u32 reason; offset:44; size:4; signed:0;
+
+print fmt: "%s queue:%d, reason:%d", REC->wiphy_name, REC->queue, REC->reason
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_return_int/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_return_int/format
new file mode 100644
index 000000000..d792a7db8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_return_int/format
@@ -0,0 +1,12 @@
+name: 802154_drv_return_int
+ID: 1039
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:int ret; offset:40; size:4; signed:1;
+
+print fmt: "%s, returned: %d", REC->wpan_phy_name, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_return_void/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_return_void/format
new file mode 100644
index 000000000..1323d8c9a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_return_void/format
@@ -0,0 +1,11 @@
+name: 802154_drv_return_void
+ID: 1040
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wpan_phy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_cca_ed_level/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_cca_ed_level/format
new file mode 100644
index 000000000..b768a5c22
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_cca_ed_level/format
@@ -0,0 +1,12 @@
+name: 802154_drv_set_cca_ed_level
+ID: 1041
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:s32 mbm; offset:40; size:4; signed:1;
+
+print fmt: "%s, ed level: %d", REC->wpan_phy_name, REC->mbm
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_cca_mode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_cca_mode/format
new file mode 100644
index 000000000..c8e28bef3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_cca_mode/format
@@ -0,0 +1,13 @@
+name: 802154_drv_set_cca_mode
+ID: 1042
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:enum nl802154_cca_modes cca_mode; offset:40; size:4; signed:0;
+ field:enum nl802154_cca_opts cca_opt; offset:44; size:4; signed:0;
+
+print fmt: "%s, cca_mode: %d, cca_opt: %d", REC->wpan_phy_name, REC->cca_mode, REC->cca_opt
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_channel/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_channel/format
new file mode 100644
index 000000000..e44cc3a51
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_channel/format
@@ -0,0 +1,13 @@
+name: 802154_drv_set_channel
+ID: 1043
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:u8 page; offset:40; size:1; signed:0;
+ field:u8 channel; offset:41; size:1; signed:0;
+
+print fmt: "%s, page: %d, channel: %d", REC->wpan_phy_name, REC->page, REC->channel
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_csma_params/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_csma_params/format
new file mode 100644
index 000000000..df3d79194
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_csma_params/format
@@ -0,0 +1,14 @@
+name: 802154_drv_set_csma_params
+ID: 1044
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:u8 min_be; offset:40; size:1; signed:0;
+ field:u8 max_be; offset:41; size:1; signed:0;
+ field:u8 max_csma_backoffs; offset:42; size:1; signed:0;
+
+print fmt: "%s, min be: %d, max be: %d, max csma backoffs: %d", REC->wpan_phy_name, REC->min_be, REC->max_be, REC->max_csma_backoffs
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_extended_addr/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_extended_addr/format
new file mode 100644
index 000000000..257b68616
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_extended_addr/format
@@ -0,0 +1,12 @@
+name: 802154_drv_set_extended_addr
+ID: 1045
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:__le64 extended_addr; offset:40; size:8; signed:0;
+
+print fmt: "%s, extended addr: 0x%llx", REC->wpan_phy_name, (( __u64)(__le64)(REC->extended_addr))
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_lbt_mode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_lbt_mode/format
new file mode 100644
index 000000000..b6e826f18
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_lbt_mode/format
@@ -0,0 +1,12 @@
+name: 802154_drv_set_lbt_mode
+ID: 1046
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:bool mode; offset:40; size:1; signed:0;
+
+print fmt: "%s, lbt mode: %s", REC->wpan_phy_name, (REC->mode) ? "true" : "false"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_max_frame_retries/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_max_frame_retries/format
new file mode 100644
index 000000000..83c09acf0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_max_frame_retries/format
@@ -0,0 +1,12 @@
+name: 802154_drv_set_max_frame_retries
+ID: 1047
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:s8 max_frame_retries; offset:40; size:1; signed:1;
+
+print fmt: "%s, max frame retries: %d", REC->wpan_phy_name, REC->max_frame_retries
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_pan_coord/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_pan_coord/format
new file mode 100644
index 000000000..a277beacb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_pan_coord/format
@@ -0,0 +1,12 @@
+name: 802154_drv_set_pan_coord
+ID: 1048
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:bool is_coord; offset:40; size:1; signed:0;
+
+print fmt: "%s, is_coord: %s", REC->wpan_phy_name, (REC->is_coord) ? "true" : "false"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_pan_id/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_pan_id/format
new file mode 100644
index 000000000..650b16435
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_pan_id/format
@@ -0,0 +1,12 @@
+name: 802154_drv_set_pan_id
+ID: 1049
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:__le16 pan_id; offset:40; size:2; signed:0;
+
+print fmt: "%s, pan id: 0x%04x", REC->wpan_phy_name, (( __u16)(__le16)(REC->pan_id))
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_promiscuous_mode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_promiscuous_mode/format
new file mode 100644
index 000000000..564bffa1e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_promiscuous_mode/format
@@ -0,0 +1,12 @@
+name: 802154_drv_set_promiscuous_mode
+ID: 1050
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:bool on; offset:40; size:1; signed:0;
+
+print fmt: "%s, promiscuous mode: %s", REC->wpan_phy_name, (REC->on) ? "true" : "false"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_short_addr/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_short_addr/format
new file mode 100644
index 000000000..3136b2577
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_short_addr/format
@@ -0,0 +1,12 @@
+name: 802154_drv_set_short_addr
+ID: 1051
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:__le16 short_addr; offset:40; size:2; signed:0;
+
+print fmt: "%s, short addr: 0x%04x", REC->wpan_phy_name, (( __u16)(__le16)(REC->short_addr))
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_tx_power/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_tx_power/format
new file mode 100644
index 000000000..e1ea9967e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_set_tx_power/format
@@ -0,0 +1,12 @@
+name: 802154_drv_set_tx_power
+ID: 1052
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+ field:s32 power; offset:40; size:4; signed:1;
+
+print fmt: "%s, mbm: %d", REC->wpan_phy_name, REC->power
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_start/format
new file mode 100644
index 000000000..47708aa35
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_start/format
@@ -0,0 +1,11 @@
+name: 802154_drv_start
+ID: 1053
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wpan_phy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_stop/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_stop/format
new file mode 100644
index 000000000..ed9d63236
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mac802154/802154_drv_stop/format
@@ -0,0 +1,11 @@
+name: 802154_drv_stop
+ID: 1054
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char wpan_phy_name[32]; offset:8; size:32; signed:0;
+
+print fmt: "%s", REC->wpan_phy_name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/gpu_power_state/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/gpu_power_state/format
new file mode 100644
index 000000000..ecab55138
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/gpu_power_state/format
@@ -0,0 +1,13 @@
+name: gpu_power_state
+ID: 1240
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 change_ns; offset:8; size:8; signed:0;
+ field:int from_state; offset:16; size:4; signed:1;
+ field:int to_state; offset:20; size:4; signed:1;
+
+print fmt: "from=%s to=%s ns=%llu", __print_symbolic(REC->from_state, {GPU_POWER_LEVEL_STACKS, "STACKS"}, {GPU_POWER_LEVEL_COREGROUP, "COREGROUP"}, {GPU_POWER_LEVEL_GLOBAL, "GLOBAL"}, {GPU_POWER_LEVEL_OFF, "OFF"}), __print_symbolic(REC->to_state, {GPU_POWER_LEVEL_STACKS, "STACKS"}, {GPU_POWER_LEVEL_COREGROUP, "COREGROUP"}, {GPU_POWER_LEVEL_GLOBAL, "GLOBAL"}, {GPU_POWER_LEVEL_OFF, "OFF"}), REC->change_ns
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_alloc/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_alloc/format
new file mode 100644
index 000000000..935351610
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_alloc/format
@@ -0,0 +1,14 @@
+name: mali_jit_alloc
+ID: 1225
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 start_addr; offset:8; size:8; signed:0;
+ field:size_t nr_pages; offset:16; size:8; signed:0;
+ field:size_t backed_pages; offset:24; size:8; signed:0;
+ field:u8 jit_id; offset:32; size:1; signed:0;
+
+print fmt: "jit_id=%u start=0x%llx va_pages=0x%zx backed_size=0x%zx", REC->jit_id, REC->start_addr, REC->nr_pages, REC->backed_pages
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_free/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_free/format
new file mode 100644
index 000000000..bbac14a28
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_free/format
@@ -0,0 +1,14 @@
+name: mali_jit_free
+ID: 1226
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 start_addr; offset:8; size:8; signed:0;
+ field:size_t nr_pages; offset:16; size:8; signed:0;
+ field:size_t backed_pages; offset:24; size:8; signed:0;
+ field:u8 jit_id; offset:32; size:1; signed:0;
+
+print fmt: "start=0x%llx va_pages=0x%zx backed_size=0x%zx", REC->start_addr, REC->nr_pages, REC->backed_pages
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_report/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_report/format
new file mode 100644
index 000000000..8aa42ae0e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_report/format
@@ -0,0 +1,16 @@
+name: mali_jit_report
+ID: 1227
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 start_addr; offset:8; size:8; signed:0;
+ field:u64 read_val; offset:16; size:8; signed:0;
+ field:u64 used_pages; offset:24; size:8; signed:0;
+ field:unsigned long flags; offset:32; size:8; signed:0;
+ field:u8 id_idx; offset:40; size:1; signed:0;
+ field:u8 jit_id; offset:41; size:1; signed:0;
+
+print fmt: "start=0x%llx jit_ids[%u]=%u read_type='%s' read_val=0x%llx used_pages=%llu", REC->start_addr, REC->id_idx, REC->jit_id, __print_symbolic(REC->flags, { 0, "address"}, { (1ul << 23), "address with align" }, { (1ul << 27), "size" }, { (1ul << 27) | (1ul << 23), "size with align (invalid)" } ), REC->read_val, REC->used_pages
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_report_gpu_mem/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_report_gpu_mem/format
new file mode 100644
index 000000000..175358670
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_report_gpu_mem/format
@@ -0,0 +1,14 @@
+name: mali_jit_report_gpu_mem
+ID: 1228
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 base_addr; offset:8; size:8; signed:0;
+ field:u64 reg_addr; offset:16; size:8; signed:0;
+ field:u64 mem_values[(4 * sizeof(u64)) / sizeof(u64)]; offset:24; size:32; signed:0;
+ field:unsigned int flags; offset:56; size:4; signed:0;
+
+print fmt: "start=0x%llx read GPU memory base=0x%llx values=%s report_flags=%s", REC->reg_addr, REC->base_addr, __print_array(REC->mem_values, (sizeof(REC->mem_values) / sizeof((REC->mem_values)[0]) + ((int)(sizeof(struct { int:(-!!(__builtin_types_compatible_p(typeof((REC->mem_values)), typeof(&(REC->mem_values)[0])))); })))), sizeof(u64)), __print_flags(REC->flags, "|", { 1, "HAPPENED_ON_ALLOC_OR_FREE" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_report_pressure/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_report_pressure/format
new file mode 100644
index 000000000..b4674a72f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_report_pressure/format
@@ -0,0 +1,15 @@
+name: mali_jit_report_pressure
+ID: 1229
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 start_addr; offset:8; size:8; signed:0;
+ field:u64 used_pages; offset:16; size:8; signed:0;
+ field:u64 new_used_pages; offset:24; size:8; signed:0;
+ field:u64 new_pressure; offset:32; size:8; signed:0;
+ field:unsigned int flags; offset:40; size:4; signed:0;
+
+print fmt: "start=0x%llx old_used_pages=%llu new_used_pages=%llu new_pressure=%llu report_flags=%s", REC->start_addr, REC->used_pages, REC->new_used_pages, REC->new_pressure, __print_flags(REC->flags, "|", { 1, "HAPPENED_ON_ALLOC_OR_FREE" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_trim/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_trim/format
new file mode 100644
index 000000000..a2c1f4aa7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_trim/format
@@ -0,0 +1,11 @@
+name: mali_jit_trim
+ID: 1230
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:size_t freed_pages; offset:8; size:8; signed:0;
+
+print fmt: "freed_pages=%zu", REC->freed_pages
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_trim_from_region/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_trim_from_region/format
new file mode 100644
index 000000000..29db4ecd2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_jit_trim_from_region/format
@@ -0,0 +1,15 @@
+name: mali_jit_trim_from_region
+ID: 1231
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 start_addr; offset:8; size:8; signed:0;
+ field:size_t freed_pages; offset:16; size:8; signed:0;
+ field:size_t old_pages; offset:24; size:8; signed:0;
+ field:size_t available_pages; offset:32; size:8; signed:0;
+ field:size_t new_pages; offset:40; size:8; signed:0;
+
+print fmt: "start=0x%llx freed_pages=%zu old_pages=%zu available_pages=%zu new_pages=%zu", REC->start_addr, REC->freed_pages, REC->old_pages, REC->available_pages, REC->new_pages
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_job_slots_event/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_job_slots_event/format
new file mode 100644
index 000000000..77edbac61
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_job_slots_event/format
@@ -0,0 +1,15 @@
+name: mali_job_slots_event
+ID: 1232
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 gpu_id; offset:8; size:4; signed:0;
+ field:u32 event_id; offset:12; size:4; signed:0;
+ field:u32 tgid; offset:16; size:4; signed:0;
+ field:u32 pid; offset:20; size:4; signed:0;
+ field:u8 job_id; offset:24; size:1; signed:0;
+
+print fmt: "gpu=%u event=%u tgid=%u pid=%u job_id=%u", REC->gpu_id, REC->event_id, REC->tgid, REC->pid, REC->job_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_mmu_page_fault_grow/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_mmu_page_fault_grow/format
new file mode 100644
index 000000000..6cce6cebe
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_mmu_page_fault_grow/format
@@ -0,0 +1,15 @@
+name: mali_mmu_page_fault_grow
+ID: 1233
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 start_addr; offset:8; size:8; signed:0;
+ field:u64 fault_addr; offset:16; size:8; signed:0;
+ field:u64 fault_extra_addr; offset:24; size:8; signed:0;
+ field:size_t new_pages; offset:32; size:8; signed:0;
+ field:u32 status; offset:40; size:4; signed:0;
+
+print fmt: "start=0x%llx fault_addr=0x%llx fault_extra_addr=0x%llx new_pages=%zu raw_fault_status=0x%x decoded_faultstatus=%s exception_type=0x%x,%s%u access_type=0x%x,%s source_id=0x%x", REC->start_addr, REC->fault_addr, REC->fault_extra_addr, REC->new_pages, REC->status, (((REC->status) & (1u << 10)) ? "DECODER_FAULT" : "SLAVE_FAULT"), ((REC->status) & 0xFFu), (!((((REC->status) & 0xFFu) >= 0xC0 && ((REC->status) & 0xFFu) <= 0xEF) && (!(((REC->status) & 0xFFu) >= 0xC5 && ((REC->status) & 0xFFu) <= 0xC6)) && (!(((REC->status) & 0xFFu) >= 0xCC && ((REC->status) & 0xFFu) <= 0xCF)) && (!(((REC->status) & 0xFFu) >= 0xD4 && ((REC->status) & 0xFFu) <= 0xD7)) && (!(((REC->status) & 0xFFu) >= 0xDC && ((REC->status) & 0xFFu) <= 0xDF))) ? "UNKNOWN,level=" : __print_symbolic(((((REC->status) & 0xFFu)) & ~3u), {0xC0, "TRANSLATION_FAULT_" }, {0xC4, "TRANSLATION_FAULT(_7==_IDENTITY)_" }, {0xC8, "PERMISSION_FAULT_" }, {0xD0, "TRANSTAB_BUS_FAULT_" }, {0xD8, "ACCESS_FLAG_" }, {0xE0, "ADDRESS_SIZE_FAULT_IN" }, {0xE4, "ADDRESS_SIZE_FAULT_OUT" }, {0xE8, "MEMORY_ATTRIBUTES_FAULT_" }, {0xEC, "MEMORY_ATTRIBUTES_NONCACHEABLE_" })), (((((((REC->status) & 0xFFu)) & ~0x3u) == 0xC4) ? 4 : 0) + ((((REC->status) & 0xFFu)) & 0x3u)), ((REC->status) & (0x3 << 8)) >> 8, __print_symbolic(((REC->status) & (0x3 << 8)), {(0x0), "ATOMIC" }, {(0x1), "EXECUTE"}, {(0x2), "READ" }, {(0x3), "WRITE" }), REC->status >> 16
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_page_fault_insert_pages/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_page_fault_insert_pages/format
new file mode 100644
index 000000000..a3300cb2b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_page_fault_insert_pages/format
@@ -0,0 +1,13 @@
+name: mali_page_fault_insert_pages
+ID: 1234
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 gpu_id; offset:8; size:4; signed:0;
+ field:s32 event_id; offset:12; size:4; signed:1;
+ field:u64 value; offset:16; size:8; signed:0;
+
+print fmt: "gpu=%u event %d = %llu", REC->gpu_id, REC->event_id, REC->value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_pm_status/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_pm_status/format
new file mode 100644
index 000000000..12dd24373
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_pm_status/format
@@ -0,0 +1,13 @@
+name: mali_pm_status
+ID: 1235
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 gpu_id; offset:8; size:4; signed:0;
+ field:u32 event_id; offset:12; size:4; signed:0;
+ field:u64 value; offset:16; size:8; signed:0;
+
+print fmt: "gpu=%u event %u = %llu", REC->gpu_id, REC->event_id, REC->value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_total_alloc_pages_change/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_total_alloc_pages_change/format
new file mode 100644
index 000000000..107b853a5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/mali_total_alloc_pages_change/format
@@ -0,0 +1,12 @@
+name: mali_total_alloc_pages_change
+ID: 1236
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 gpu_id; offset:8; size:4; signed:0;
+ field:s64 event_id; offset:16; size:8; signed:1;
+
+print fmt: "gpu=%u event=%lld", REC->gpu_id, REC->event_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/sysgraph/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/sysgraph/format
new file mode 100644
index 000000000..0bb1d69c7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/sysgraph/format
@@ -0,0 +1,13 @@
+name: sysgraph
+ID: 1237
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int proc_id; offset:8; size:4; signed:0;
+ field:enum sysgraph_msg message; offset:12; size:4; signed:0;
+ field:unsigned int atom_id; offset:16; size:4; signed:0;
+
+print fmt: "msg=%u proc_id=%u, param1=%d", REC->message, REC->proc_id, REC->atom_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/sysgraph_gpu/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/sysgraph_gpu/format
new file mode 100644
index 000000000..0594fb272
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mali/sysgraph_gpu/format
@@ -0,0 +1,14 @@
+name: sysgraph_gpu
+ID: 1238
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int proc_id; offset:8; size:4; signed:0;
+ field:enum sysgraph_msg message; offset:12; size:4; signed:0;
+ field:unsigned int atom_id; offset:16; size:4; signed:0;
+ field:unsigned int js; offset:20; size:4; signed:0;
+
+print fmt: "msg=%u proc_id=%u, param1=%d, param2=%d", REC->message, REC->proc_id, REC->atom_id, REC->js
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_get_access/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_get_access/format
new file mode 100644
index 000000000..d1772b8c6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_get_access/format
@@ -0,0 +1,12 @@
+name: ca_get_access
+ID: 1121
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:u32 next_timestamp_dtu; offset:12; size:4; signed:0;
+
+print fmt: "hw%d next_timestamp_dtu=%#08x", REC->hw_idx, REC->next_timestamp_dtu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_return_int/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_return_int/format
new file mode 100644
index 000000000..9ea0defdf
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_return_int/format
@@ -0,0 +1,12 @@
+name: ca_return_int
+ID: 1122
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:int r; offset:12; size:4; signed:1;
+
+print fmt: "hw%d r=%d", REC->hw_idx, REC->r
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_scheduler_call/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_scheduler_call/format
new file mode 100644
index 000000000..ac3c37c3c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_scheduler_call/format
@@ -0,0 +1,13 @@
+name: ca_scheduler_call
+ID: 1123
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:__data_loc char[] scheduler_name; offset:12; size:4; signed:0;
+ field:u32 call_id; offset:16; size:4; signed:0;
+
+print fmt: "hw%d scheduler=%s call_id=%#x", REC->hw_idx, __get_str(scheduler_name), REC->call_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_scheduler_call_region/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_scheduler_call_region/format
new file mode 100644
index 000000000..ccd2151e9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_scheduler_call_region/format
@@ -0,0 +1,15 @@
+name: ca_scheduler_call_region
+ID: 1124
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:__data_loc char[] scheduler_name; offset:12; size:4; signed:0;
+ field:u32 region_id; offset:16; size:4; signed:0;
+ field:__data_loc char[] region_name; offset:20; size:4; signed:0;
+ field:u32 call_id; offset:24; size:4; signed:0;
+
+print fmt: "hw%d scheduler=%s region_id=%u region_name=%s call_id=%#x", REC->hw_idx, __get_str(scheduler_name), REC->region_id, __get_str(region_name), REC->call_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_scheduler_set_region_parameters/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_scheduler_set_region_parameters/format
new file mode 100644
index 000000000..5fe1a4fd7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_scheduler_set_region_parameters/format
@@ -0,0 +1,14 @@
+name: ca_scheduler_set_region_parameters
+ID: 1125
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:__data_loc char[] scheduler_name; offset:12; size:4; signed:0;
+ field:u32 region_id; offset:16; size:4; signed:0;
+ field:__data_loc char[] region_name; offset:20; size:4; signed:0;
+
+print fmt: "hw%d scheduler=%s region_id=%u region_name=%s", REC->hw_idx, __get_str(scheduler_name), REC->region_id, __get_str(region_name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_set_scheduler/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_set_scheduler/format
new file mode 100644
index 000000000..96fd84f7e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_set_scheduler/format
@@ -0,0 +1,12 @@
+name: ca_set_scheduler
+ID: 1126
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:__data_loc char[] name; offset:12; size:4; signed:0;
+
+print fmt: "hw%d name=%s", REC->hw_idx, __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_set_scheduler_parameters/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_set_scheduler_parameters/format
new file mode 100644
index 000000000..3cda19e69
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/ca_set_scheduler_parameters/format
@@ -0,0 +1,12 @@
+name: ca_set_scheduler_parameters
+ID: 1127
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:__data_loc char[] name; offset:12; size:4; signed:0;
+
+print fmt: "hw%d name=%s", REC->hw_idx, __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_broken/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_broken/format
new file mode 100644
index 000000000..38380f960
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_broken/format
@@ -0,0 +1,11 @@
+name: llhw_event_broken
+ID: 1128
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+
+print fmt: "hw%d", REC->hw_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_done/format
new file mode 100644
index 000000000..bcc048946
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_done/format
@@ -0,0 +1,11 @@
+name: llhw_event_done
+ID: 1129
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+
+print fmt: "hw%d", REC->hw_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_rx_error/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_rx_error/format
new file mode 100644
index 000000000..6a6b9cf7d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_rx_error/format
@@ -0,0 +1,12 @@
+name: llhw_event_rx_error
+ID: 1130
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:enum mcps802154_rx_error_type error; offset:12; size:4; signed:0;
+
+print fmt: "hw%d error=%s", REC->hw_idx, __print_symbolic(REC->error, { 2, "BAD_CKSUM" }, { 3, "UNCORRECTABLE" }, { 4, "FILTERED" }, { 5, "SFD_TIMEOUT" }, { 6, "OTHER" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_rx_frame/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_rx_frame/format
new file mode 100644
index 000000000..c3109f43e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_rx_frame/format
@@ -0,0 +1,11 @@
+name: llhw_event_rx_frame
+ID: 1131
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+
+print fmt: "hw%d", REC->hw_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_rx_timeout/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_rx_timeout/format
new file mode 100644
index 000000000..d0c0ef1d5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_rx_timeout/format
@@ -0,0 +1,11 @@
+name: llhw_event_rx_timeout
+ID: 1132
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+
+print fmt: "hw%d", REC->hw_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_timer_expired/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_timer_expired/format
new file mode 100644
index 000000000..e6c23a4ea
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_timer_expired/format
@@ -0,0 +1,11 @@
+name: llhw_event_timer_expired
+ID: 1133
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+
+print fmt: "hw%d", REC->hw_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_tx_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_tx_done/format
new file mode 100644
index 000000000..fff1f6ae6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_event_tx_done/format
@@ -0,0 +1,11 @@
+name: llhw_event_tx_done
+ID: 1134
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+
+print fmt: "hw%d", REC->hw_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_get_calibration/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_get_calibration/format
new file mode 100644
index 000000000..35c37919e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_get_calibration/format
@@ -0,0 +1,12 @@
+name: llhw_get_calibration
+ID: 1135
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:__data_loc char[] key; offset:12; size:4; signed:0;
+
+print fmt: "hw%d key=%s", REC->hw_idx, __get_str(key)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_get_current_timestamp_dtu/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_get_current_timestamp_dtu/format
new file mode 100644
index 000000000..0924ce80e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_get_current_timestamp_dtu/format
@@ -0,0 +1,11 @@
+name: llhw_get_current_timestamp_dtu
+ID: 1136
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+
+print fmt: "hw%d", REC->hw_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_idle/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_idle/format
new file mode 100644
index 000000000..8453ceeb7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_idle/format
@@ -0,0 +1,11 @@
+name: llhw_idle
+ID: 1137
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+
+print fmt: "hw%d", REC->hw_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_idle_timestamp/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_idle_timestamp/format
new file mode 100644
index 000000000..73ff23446
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_idle_timestamp/format
@@ -0,0 +1,12 @@
+name: llhw_idle_timestamp
+ID: 1138
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:u32 timestamp_dtu; offset:12; size:4; signed:0;
+
+print fmt: "hw%d timestamp_dtu=%#08x", REC->hw_idx, REC->timestamp_dtu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_list_calibration/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_list_calibration/format
new file mode 100644
index 000000000..726d1aa53
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_list_calibration/format
@@ -0,0 +1,11 @@
+name: llhw_list_calibration
+ID: 1139
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+
+print fmt: "hw%d", REC->hw_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_reset/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_reset/format
new file mode 100644
index 000000000..789c77be6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_reset/format
@@ -0,0 +1,11 @@
+name: llhw_reset
+ID: 1140
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+
+print fmt: "hw%d", REC->hw_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_return_int/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_return_int/format
new file mode 100644
index 000000000..00ca62b1b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_return_int/format
@@ -0,0 +1,12 @@
+name: llhw_return_int
+ID: 1141
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:int ret; offset:12; size:4; signed:1;
+
+print fmt: "hw%d returned=%d", REC->hw_idx, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_return_rx_frame/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_return_rx_frame/format
new file mode 100644
index 000000000..f076251e5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_return_rx_frame/format
@@ -0,0 +1,17 @@
+name: llhw_return_rx_frame
+ID: 1142
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:int ret; offset:12; size:4; signed:1;
+ field:u32 timestamp_dtu; offset:16; size:4; signed:0;
+ field:u64 timestamp_rctu; offset:24; size:8; signed:0;
+ field:int frame_duration_dtu; offset:32; size:4; signed:1;
+ field:u8 ranging_sts_fom0; offset:36; size:1; signed:0;
+ field:u16 flags; offset:38; size:2; signed:0;
+
+print fmt: "hw%d returned=%d timestamp_dtu=0x%08x timestamp_rctu=%#llx frame_duration_dtu=%d ranging_sts_fom[0]=%#02x flags=%s", REC->hw_idx, REC->ret, REC->timestamp_dtu, REC->timestamp_rctu, REC->frame_duration_dtu, REC->ranging_sts_fom0, __print_flags(REC->flags, "|", { 1, "TIMESTAMP_DTU" }, { 2, "TIMESTAMP_RCTU" }, { 4, "LQI" }, { 8, "RSSI" }, { 16, "RANGING_FOM" }, { 32, "RANGING_OFFSET" }, { 64, "RANGING_PDOA" }, { 128, "RANGING_PDOA_FOM" }, { 256, "RANGING_STS_TIMESTAMP_RCTU" }, { 512, "RANGING_STS_FOM" }, { 1024, "AACK" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_return_timestamp_dtu/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_return_timestamp_dtu/format
new file mode 100644
index 000000000..db7cd9558
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_return_timestamp_dtu/format
@@ -0,0 +1,13 @@
+name: llhw_return_timestamp_dtu
+ID: 1143
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:int ret; offset:12; size:4; signed:1;
+ field:u32 timestamp_dtu; offset:16; size:4; signed:0;
+
+print fmt: "hw%d returned=%d timestamp_dtu=%#08x", REC->hw_idx, REC->ret, REC->timestamp_dtu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_return_timestamp_rctu/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_return_timestamp_rctu/format
new file mode 100644
index 000000000..cfe05597d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_return_timestamp_rctu/format
@@ -0,0 +1,13 @@
+name: llhw_return_timestamp_rctu
+ID: 1144
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:int ret; offset:12; size:4; signed:1;
+ field:u64 timestamp_rctu; offset:16; size:8; signed:0;
+
+print fmt: "hw%d returned=%d timestamp_rctu=%#llx", REC->hw_idx, REC->ret, REC->timestamp_rctu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_return_void/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_return_void/format
new file mode 100644
index 000000000..1da5117ad
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_return_void/format
@@ -0,0 +1,11 @@
+name: llhw_return_void
+ID: 1145
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+
+print fmt: "hw%d", REC->hw_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_rx_disable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_rx_disable/format
new file mode 100644
index 000000000..7fb4633a1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_rx_disable/format
@@ -0,0 +1,11 @@
+name: llhw_rx_disable
+ID: 1146
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+
+print fmt: "hw%d", REC->hw_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_rx_enable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_rx_enable/format
new file mode 100644
index 000000000..988672265
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_rx_enable/format
@@ -0,0 +1,17 @@
+name: llhw_rx_enable
+ID: 1147
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:u32 timestamp_dtu; offset:12; size:4; signed:0;
+ field:int timeout_dtu; offset:16; size:4; signed:1;
+ field:u8 flags; offset:20; size:1; signed:0;
+ field:u8 ant_pair_id; offset:21; size:1; signed:0;
+ field:int frame_idx; offset:24; size:4; signed:1;
+ field:int next_delay_dtu; offset:28; size:4; signed:1;
+
+print fmt: "hw%d timestamp_dtu=%#08x timeout_dtu=%d ant_pair_id=%d flags=%s frame_idx=%d next_delay_dtu=%d", REC->hw_idx, REC->timestamp_dtu, REC->timeout_dtu, REC->ant_pair_id, __print_flags(REC->flags, "|", { 1, "TIMESTAMP_DTU" }, { 2, "AACK" }, { 4, "RANGING" }, { 8, "KEEP_RANGING_CLOCK" }, { 16, "RANGING_PDOA" }, { 96, "SP3" }, { 64, "SP2" }, { 32, "SP1" }), REC->frame_idx, REC->next_delay_dtu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_rx_get_error_frame/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_rx_get_error_frame/format
new file mode 100644
index 000000000..3db71a07e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_rx_get_error_frame/format
@@ -0,0 +1,12 @@
+name: llhw_rx_get_error_frame
+ID: 1148
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:u16 flags; offset:12; size:2; signed:0;
+
+print fmt: "hw%d flags=%s", REC->hw_idx, __print_flags(REC->flags, "|", { 1, "TIMESTAMP_DTU" }, { 2, "TIMESTAMP_RCTU" }, { 4, "LQI" }, { 8, "RSSI" }, { 16, "RANGING_FOM" }, { 32, "RANGING_OFFSET" }, { 64, "RANGING_PDOA" }, { 128, "RANGING_PDOA_FOM" }, { 256, "RANGING_STS_TIMESTAMP_RCTU" }, { 512, "RANGING_STS_FOM" }, { 1024, "AACK" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_rx_get_frame/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_rx_get_frame/format
new file mode 100644
index 000000000..28cc3df4f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_rx_get_frame/format
@@ -0,0 +1,12 @@
+name: llhw_rx_get_frame
+ID: 1149
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:u16 flags; offset:12; size:2; signed:0;
+
+print fmt: "hw%d flags=%s", REC->hw_idx, __print_flags(REC->flags, "|", { 1, "TIMESTAMP_DTU" }, { 2, "TIMESTAMP_RCTU" }, { 4, "LQI" }, { 8, "RSSI" }, { 16, "RANGING_FOM" }, { 32, "RANGING_OFFSET" }, { 64, "RANGING_PDOA" }, { 128, "RANGING_PDOA_FOM" }, { 256, "RANGING_STS_TIMESTAMP_RCTU" }, { 512, "RANGING_STS_FOM" }, { 1024, "AACK" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_calibration/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_calibration/format
new file mode 100644
index 000000000..f7827fa75
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_calibration/format
@@ -0,0 +1,12 @@
+name: llhw_set_calibration
+ID: 1150
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:__data_loc char[] key; offset:12; size:4; signed:0;
+
+print fmt: "hw%d key=%s", REC->hw_idx, __get_str(key)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_cca_ed_level/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_cca_ed_level/format
new file mode 100644
index 000000000..e61dafa27
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_cca_ed_level/format
@@ -0,0 +1,12 @@
+name: llhw_set_cca_ed_level
+ID: 1151
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:s32 mbm; offset:12; size:4; signed:1;
+
+print fmt: "hw%d mbm=%d", REC->hw_idx, REC->mbm
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_cca_mode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_cca_mode/format
new file mode 100644
index 000000000..0096d0943
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_cca_mode/format
@@ -0,0 +1,13 @@
+name: llhw_set_cca_mode
+ID: 1152
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:enum nl802154_cca_modes cca_mode; offset:12; size:4; signed:0;
+ field:enum nl802154_cca_opts cca_opt; offset:16; size:4; signed:0;
+
+print fmt: "hw%d cca_mode=%d cca_opt=%d", REC->hw_idx, REC->cca_mode, REC->cca_opt
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_channel/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_channel/format
new file mode 100644
index 000000000..5b1840f07
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_channel/format
@@ -0,0 +1,14 @@
+name: llhw_set_channel
+ID: 1153
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:u8 page; offset:12; size:1; signed:0;
+ field:u8 channel; offset:13; size:1; signed:0;
+ field:u8 preamble_code; offset:14; size:1; signed:0;
+
+print fmt: "hw%d page=%d channel=%d preamble_code=%d", REC->hw_idx, REC->page, REC->channel, REC->preamble_code
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_hrp_uwb_params/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_hrp_uwb_params/format
new file mode 100644
index 000000000..8e881e246
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_hrp_uwb_params/format
@@ -0,0 +1,16 @@
+name: llhw_set_hrp_uwb_params
+ID: 1154
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:int prf; offset:12; size:4; signed:1;
+ field:int psr; offset:16; size:4; signed:1;
+ field:int sfd_selector; offset:20; size:4; signed:1;
+ field:int phr_rate; offset:24; size:4; signed:1;
+ field:int data_rate; offset:28; size:4; signed:1;
+
+print fmt: "hw%d prf=%d psr=%d sfd_selector=%d phr_rate=%d data_rate=%d", REC->hw_idx, REC->prf, REC->psr, REC->sfd_selector, REC->phr_rate, REC->data_rate
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_hw_addr_filt/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_hw_addr_filt/format
new file mode 100644
index 000000000..dd5dd6cba
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_hw_addr_filt/format
@@ -0,0 +1,16 @@
+name: llhw_set_hw_addr_filt
+ID: 1155
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:__le16 pan_id; offset:12; size:2; signed:0;
+ field:__le16 short_addr; offset:14; size:2; signed:0;
+ field:__le64 extended_addr; offset:16; size:8; signed:0;
+ field:bool pan_coord; offset:24; size:1; signed:0;
+ field:unsigned long changed; offset:32; size:8; signed:0;
+
+print fmt: "hw%d pan_id=%#04x short_addr=%#04x extended_addr=%#016llx pan_coord=%s changed=%s", REC->hw_idx, REC->pan_id, REC->short_addr, REC->extended_addr, REC->pan_coord ? "true" : "false", __print_flags(REC->changed, "|", { 1, "SHORT_ADDR" }, { 2, "EXTENDED_ADDR" }, { 4, "PAN_ID" }, { 8, "PAN_COORD" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_promiscuous_mode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_promiscuous_mode/format
new file mode 100644
index 000000000..6bfb09d9a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_promiscuous_mode/format
@@ -0,0 +1,12 @@
+name: llhw_set_promiscuous_mode
+ID: 1156
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:bool on; offset:12; size:1; signed:0;
+
+print fmt: "hw%d %s", REC->hw_idx, REC->on ? "on" : "off"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_scanning_mode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_scanning_mode/format
new file mode 100644
index 000000000..2749334f5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_scanning_mode/format
@@ -0,0 +1,12 @@
+name: llhw_set_scanning_mode
+ID: 1157
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:bool on; offset:12; size:1; signed:0;
+
+print fmt: "hw%d %s", REC->hw_idx, REC->on ? "on" : "off"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_sts_params/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_sts_params/format
new file mode 100644
index 000000000..5456cca92
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_sts_params/format
@@ -0,0 +1,15 @@
+name: llhw_set_sts_params
+ID: 1158
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:int n_segs; offset:12; size:4; signed:1;
+ field:int seg_len; offset:16; size:4; signed:1;
+ field:int sp2_tx_gap_4chips; offset:20; size:4; signed:1;
+ field:int sp2_rx_gap_4chips[4]; offset:24; size:16; signed:1;
+
+print fmt: "hw%d n_segs=%d seg_len=%d sp2_tx_gap_4chips=%d sp2_rx_gap_4chips=%d,%d,%d,%d", REC->hw_idx, REC->n_segs, REC->seg_len, REC->sp2_tx_gap_4chips, REC->sp2_rx_gap_4chips[0], REC->sp2_rx_gap_4chips[1], REC->sp2_rx_gap_4chips[2], REC->sp2_rx_gap_4chips[3]
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_txpower/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_txpower/format
new file mode 100644
index 000000000..53ff00166
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_set_txpower/format
@@ -0,0 +1,12 @@
+name: llhw_set_txpower
+ID: 1159
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:s32 mbm; offset:12; size:4; signed:1;
+
+print fmt: "hw%d mbm=%d", REC->hw_idx, REC->mbm
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_start/format
new file mode 100644
index 000000000..d39dabf64
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_start/format
@@ -0,0 +1,11 @@
+name: llhw_start
+ID: 1160
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+
+print fmt: "hw%d", REC->hw_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_stop/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_stop/format
new file mode 100644
index 000000000..7689bda94
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_stop/format
@@ -0,0 +1,11 @@
+name: llhw_stop
+ID: 1161
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+
+print fmt: "hw%d", REC->hw_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_testmode_cmd/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_testmode_cmd/format
new file mode 100644
index 000000000..e2dcccaec
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_testmode_cmd/format
@@ -0,0 +1,11 @@
+name: llhw_testmode_cmd
+ID: 1162
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+
+print fmt: "hw%d", REC->hw_idx
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_tx_frame/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_tx_frame/format
new file mode 100644
index 000000000..05ab81aa0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/llhw_tx_frame/format
@@ -0,0 +1,18 @@
+name: llhw_tx_frame
+ID: 1163
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:u32 timestamp_dtu; offset:12; size:4; signed:0;
+ field:int rx_enable_after_tx_dtu; offset:16; size:4; signed:1;
+ field:int rx_enable_after_tx_timeout_dtu; offset:20; size:4; signed:1;
+ field:int ant_id; offset:24; size:4; signed:1;
+ field:u8 flags; offset:28; size:1; signed:0;
+ field:int frame_idx; offset:32; size:4; signed:1;
+ field:int next_delay_dtu; offset:36; size:4; signed:1;
+
+print fmt: "hw%d timestamp_dtu=%#08x rx_enable_after_tx_dtu=%d rx_enable_after_tx_timeout_dtu=%d ant_id=%d flags=%s frame_idx=%d next_delay_dtu=%d", REC->hw_idx, REC->timestamp_dtu, REC->rx_enable_after_tx_dtu, REC->rx_enable_after_tx_timeout_dtu, REC->ant_id, __print_flags(REC->flags, "|", { 1, "TIMESTAMP_DTU" }, { 2, "CCA" }, { 4, "RANGING" }, { 8, "KEEP_RANGING_CLOCK" }, { 16, "RANGING_PDOA" }, { 96, "SP3" }, { 64, "SP2" }, { 32, "SP1" }), REC->frame_idx, REC->next_delay_dtu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/region_get_access/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/region_get_access/format
new file mode 100644
index 000000000..a614a56cf
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/region_get_access/format
@@ -0,0 +1,15 @@
+name: region_get_access
+ID: 1164
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:__data_loc char[] region_name; offset:12; size:4; signed:0;
+ field:u32 next_timestamp_dtu; offset:16; size:4; signed:0;
+ field:int next_in_region_dtu; offset:20; size:4; signed:1;
+ field:int region_duration_dtu; offset:24; size:4; signed:1;
+
+print fmt: "hw%d region=%s next_timestamp_dtu=%#08x next_in_region_dtu=%d region_duration_dtu=%d", REC->hw_idx, __get_str(region_name), REC->next_timestamp_dtu, REC->next_in_region_dtu, REC->region_duration_dtu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/schedule_update/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/schedule_update/format
new file mode 100644
index 000000000..45d39189f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/schedule_update/format
@@ -0,0 +1,12 @@
+name: schedule_update
+ID: 1165
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:u32 next_timestamp_dtu; offset:12; size:4; signed:0;
+
+print fmt: "hw%d next_timestamp_dtu=%#08x", REC->hw_idx, REC->next_timestamp_dtu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/schedule_update_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/schedule_update_done/format
new file mode 100644
index 000000000..3f9c887fe
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154/schedule_update_done/format
@@ -0,0 +1,14 @@
+name: schedule_update_done
+ID: 1166
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:u32 start_timestamp_dtu; offset:12; size:4; signed:0;
+ field:int duration_dtu; offset:16; size:4; signed:1;
+ field:size_t n_regions; offset:24; size:8; signed:0;
+
+print fmt: "hw%d start_timestamp_dtu=%#08x duration_dtu=%d n_regions=%lu", REC->hw_idx, REC->start_timestamp_dtu, REC->duration_dtu, REC->n_regions
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154_region_fira/region_fira_rx_message_type/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154_region_fira/region_fira_rx_message_type/format
new file mode 100644
index 000000000..42076ddcb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154_region_fira/region_fira_rx_message_type/format
@@ -0,0 +1,13 @@
+name: region_fira_rx_message_type
+ID: 1241
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 session_id; offset:8; size:4; signed:0;
+ field:enum fira_message_id msg_id; offset:12; size:4; signed:0;
+ field:enum fira_ranging_status status; offset:16; size:4; signed:1;
+
+print fmt: "session_id=%d message_type=%s status=%s", REC->session_id, __print_symbolic(REC->msg_id, { FIRA_MESSAGE_ID_RANGING_INITIATION, "RIM" }, { FIRA_MESSAGE_ID_RANGING_RESPONSE, "RRM" }, { FIRA_MESSAGE_ID_RANGING_FINAL, "RFM" }, { FIRA_MESSAGE_ID_CONTROL, "RCM" }, { FIRA_MESSAGE_ID_MEASUREMENT_REPORT, "MRM" }, { FIRA_MESSAGE_ID_RESULT_REPORT, "RRRM" }, { FIRA_MESSAGE_ID_CONTROL_UPDATE, "CMU" }), __print_symbolic(REC->status, { FIRA_STATUS_RANGING_SUCCESS, "success" }, { FIRA_STATUS_RANGING_TX_FAILED, "tx_failed" }, { FIRA_STATUS_RANGING_RX_TIMEOUT, "rx_timeout" }, { FIRA_STATUS_RANGING_RX_PHY_DEC_FAILED, "rx_phy_dec_failed" }, { FIRA_STATUS_RANGING_RX_PHY_TOA_FAILED, "rx_phy_toa_failed" }, { FIRA_STATUS_RANGING_RX_PHY_STS_FAILED, "rx_phy_sts_failed" }, { FIRA_STATUS_RANGING_RX_MAC_DEC_FAILED, "rx_mac_dec_failed" }, { FIRA_STATUS_RANGING_RX_MAC_IE_DEC_FAILED, "rx_mac_ie_dec_failed" }, { FIRA_STATUS_RANGING_RX_MAC_IE_MISSING, "rx_mac_ie_missing" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154_region_fira/region_fira_session_params/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154_region_fira/region_fira_session_params/format
new file mode 100644
index 000000000..e3f005e53
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154_region_fira/region_fira_session_params/format
@@ -0,0 +1,40 @@
+name: region_fira_session_params
+ID: 1242
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 session_id; offset:8; size:4; signed:0;
+ field:enum fira_device_type device_type; offset:12; size:4; signed:0;
+ field:enum fira_ranging_round_usage ranging_round_usage; offset:16; size:4; signed:0;
+ field:enum fira_multi_node_mode multi_node_mode; offset:20; size:4; signed:0;
+ field:__le16 controller_short_addr; offset:24; size:2; signed:0;
+ field:int initiation_time_ms; offset:28; size:4; signed:1;
+ field:int slot_duration_dtu; offset:32; size:4; signed:1;
+ field:int block_duration_dtu; offset:36; size:4; signed:1;
+ field:int round_duration_slots; offset:40; size:4; signed:1;
+ field:bool round_hopping; offset:44; size:1; signed:0;
+ field:int priority; offset:48; size:4; signed:1;
+ field:int channel_number; offset:52; size:4; signed:1;
+ field:int preamble_code_index; offset:56; size:4; signed:1;
+ field:enum fira_rframe_config rframe_config; offset:60; size:4; signed:0;
+ field:enum fira_preambule_duration preamble_duration; offset:64; size:4; signed:0;
+ field:enum fira_sfd_id sfd_id; offset:68; size:4; signed:0;
+ field:enum fira_psdu_data_rate psdu_data_rate; offset:72; size:4; signed:0;
+ field:enum fira_mac_fcs_type mac_fcs_type; offset:76; size:4; signed:0;
+ field:enum fira_sts_config sts_config; offset:80; size:4; signed:0;
+ field:u8 vupper64[8]; offset:84; size:8; signed:0;
+ field:bool aoa_result_req; offset:92; size:1; signed:0;
+ field:bool report_tof; offset:93; size:1; signed:0;
+ field:bool report_aoa_azimuth; offset:94; size:1; signed:0;
+ field:bool report_aoa_elevation; offset:95; size:1; signed:0;
+ field:bool report_aoa_fom; offset:96; size:1; signed:0;
+ field:u8 rx_antenna_selection; offset:97; size:1; signed:0;
+ field:u8 rx_antenna_pair_azimuth; offset:98; size:1; signed:0;
+ field:u8 rx_antenna_pair_elevation; offset:99; size:1; signed:0;
+ field:u8 tx_antenna_selection; offset:100; size:1; signed:0;
+ field:u8 rx_antenna_switch; offset:101; size:1; signed:0;
+
+print fmt: "session_id=%d device_type=%s ranging_round_usage=%s multi_node_mode=%s controller_short_addr=0x%x initiation_time_ms=%d slot_duration_dtu=%d block_duration_dtu=%d round_duration_slots=%d round_hopping=%d priority=%d channel_number=%d preamble_code_index=%d rframe_config=%s preamble_duration=%s sfd_id=%d psdu_data_rate=%s mac_fcs_type=%s sts_config=%s vupper64=%s aoa_result_req=%d report_tof=%d report_aoa_azimuth=%d report_aoa_elevation=%d report_aoa_fom=%d rx_antenna_selection=0x%x rx_antenna_pair_azimuth=%d rx_antenna_pair_elevation=%d tx_antenna_selection=%d rx_antenna_switch=%s", REC->session_id, __print_symbolic(REC->device_type, { FIRA_DEVICE_TYPE_CONTROLEE, "controlee" }, { FIRA_DEVICE_TYPE_CONTROLLER, "controller" }), __print_symbolic(REC->ranging_round_usage, { FIRA_RANGING_ROUND_USAGE_OWR, "OWR" }, { FIRA_RANGING_ROUND_USAGE_SSTWR, "SSTWR" }, { FIRA_RANGING_ROUND_USAGE_DSTWR, "DSTWR" }), __print_symbolic(REC->multi_node_mode, { FIRA_MULTI_NODE_MODE_UNICAST, "UNICAST" }, { FIRA_MULTI_NODE_MODE_ONE_TO_MANY, "ONE_TO_MANY" }, { FIRA_MULTI_NODE_MODE_MANY_TO_MANY, "MANY_TO_MANY" }), REC->controller_short_addr, REC->initiation_time_ms, REC->slot_duration_dtu, REC->block_duration_dtu, REC->round_duration_slots, REC->round_hopping, REC->priority, REC->channel_number, REC->preamble_code_index, __print_symbolic(REC->rframe_config, { FIRA_RFRAME_CONFIG_SP0, "SP0" }, { FIRA_RFRAME_CONFIG_SP1, "SP1" }, { FIRA_RFRAME_CONFIG_SP2, "SP2" }, { FIRA_RFRAME_CONFIG_SP3, "SP3" }), __print_symbolic(REC->preamble_duration, { FIRA_PREAMBULE_DURATION_32, "32" }, { FIRA_PREAMBULE_DURATION_64, "64" }), REC->sfd_id, __print_symbolic(REC->psdu_data_rate, { FIRA_PSDU_DATA_RATE_6M81, "6M81" }, { FIRA_PSDU_DATA_RATE_7M80, "7M80" }, { FIRA_PSDU_DATA_RATE_27M2, "27M2" }, { FIRA_PSDU_DATA_RATE_31M2, "31M2" }), __print_symbolic(REC->mac_fcs_type, { FIRA_MAC_FCS_TYPE_CRC_16, "16" }, { FIRA_MAC_FCS_TYPE_CRC_32, "32" }), __print_symbolic(REC->sts_config, { FIRA_STS_CONFIG_STATIC, "static" }, { FIRA_STS_CONFIG_DYNAMIC, "dynamic" }, { FIRA_STS_CONFIG_DYNAMIC_INDIVIDUAL_KEY, "dynamic_individual_key" }), __print_hex(REC->vupper64, 8), REC->aoa_result_req, REC->report_tof, REC->report_aoa_azimuth, REC->report_aoa_elevation, REC->report_aoa_fom, REC->rx_antenna_selection, REC->rx_antenna_pair_azimuth, REC->rx_antenna_pair_elevation, REC->tx_antenna_selection, __print_symbolic(REC->rx_antenna_switch, { FIRA_RX_ANTENNA_SWITCH_BETWEEN_ROUND, "between_round" }, { FIRA_RX_ANTENNA_SWITCH_DURING_ROUND, "during_round" }, { FIRA_RX_ANTENNA_SWITCH_TWO_RANGING, "two_ranging" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154_region_fira/region_fira_tx_message_type/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154_region_fira/region_fira_tx_message_type/format
new file mode 100644
index 000000000..3641d0560
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154_region_fira/region_fira_tx_message_type/format
@@ -0,0 +1,12 @@
+name: region_fira_tx_message_type
+ID: 1243
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 session_id; offset:8; size:4; signed:0;
+ field:enum fira_message_id msg_id; offset:12; size:4; signed:0;
+
+print fmt: "session_id=%d message_type=%s", REC->session_id, __print_symbolic(REC->msg_id, { FIRA_MESSAGE_ID_RANGING_INITIATION, "RIM" }, { FIRA_MESSAGE_ID_RANGING_RESPONSE, "RRM" }, { FIRA_MESSAGE_ID_RANGING_FINAL, "RFM" }, { FIRA_MESSAGE_ID_CONTROL, "RCM" }, { FIRA_MESSAGE_ID_MEASUREMENT_REPORT, "MRM" }, { FIRA_MESSAGE_ID_RESULT_REPORT, "RRRM" }, { FIRA_MESSAGE_ID_CONTROL_UPDATE, "CMU" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154_region_nfcc_coex/nfcc_coex_llhw_return_int/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154_region_nfcc_coex/nfcc_coex_llhw_return_int/format
new file mode 100644
index 000000000..bdd1f034b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154_region_nfcc_coex/nfcc_coex_llhw_return_int/format
@@ -0,0 +1,12 @@
+name: nfcc_coex_llhw_return_int
+ID: 1244
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:int ret; offset:12; size:4; signed:1;
+
+print fmt: "hw%d returned=%d", REC->hw_idx, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154_region_nfcc_coex/nfcc_coex_llhw_vendor_cmd/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154_region_nfcc_coex/nfcc_coex_llhw_vendor_cmd/format
new file mode 100644
index 000000000..d4832cc25
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mcps802154_region_nfcc_coex/nfcc_coex_llhw_vendor_cmd/format
@@ -0,0 +1,13 @@
+name: nfcc_coex_llhw_vendor_cmd
+ID: 1245
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int hw_idx; offset:8; size:4; signed:1;
+ field:u32 vendor_id; offset:12; size:4; signed:0;
+ field:u32 subcmd; offset:16; size:4; signed:0;
+
+print fmt: "hw%d vendor_id=%06x subcmd=%s", REC->hw_idx, REC->vendor_id, __print_symbolic(REC->subcmd, { DW3000_VENDOR_CMD_NFCC_COEX_HANDLE_ACCESS, "HANDLE_ACCESS"}, { DW3000_VENDOR_CMD_NFCC_COEX_GET_ACCESS_INFORMATION, "GET_ACCESS_INFORMATION"}, { DW3000_VENDOR_CMD_NFCC_COEX_STOP, "STOP"})
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mdio/mdio_access/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mdio/mdio_access/format
new file mode 100644
index 000000000..cfdcfd960
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mdio/mdio_access/format
@@ -0,0 +1,15 @@
+name: mdio_access
+ID: 724
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char busid[61]; offset:8; size:61; signed:0;
+ field:char read; offset:69; size:1; signed:0;
+ field:u8 addr; offset:70; size:1; signed:0;
+ field:u16 val; offset:72; size:2; signed:0;
+ field:unsigned regnum; offset:76; size:4; signed:0;
+
+print fmt: "%s %-5s phy:0x%02hhx reg:0x%02x val:0x%04hx", REC->busid, REC->read ? "read" : "write", REC->addr, REC->regnum, REC->val
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_dcpp_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_dcpp_end/format
new file mode 100644
index 000000000..111dc7e31
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_dcpp_end/format
@@ -0,0 +1,13 @@
+name: mfc_dcpp_end
+ID: 1090
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ctx_num; offset:8; size:4; signed:1;
+ field:int is_support_smc; offset:12; size:4; signed:1;
+ field:int drm_fw_status; offset:16; size:4; signed:1;
+
+print fmt: "ctx[%d] support drm=%d, drm fw %s", REC->ctx_num, REC->is_support_smc, REC->drm_fw_status ? "loaded" : "not-loaded"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_dcpp_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_dcpp_start/format
new file mode 100644
index 000000000..5e9f0cd02
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_dcpp_start/format
@@ -0,0 +1,13 @@
+name: mfc_dcpp_start
+ID: 1091
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ctx_num; offset:8; size:4; signed:1;
+ field:int is_support_smc; offset:12; size:4; signed:1;
+ field:int drm_fw_status; offset:16; size:4; signed:1;
+
+print fmt: "ctx[%d] support drm=%d, drm fw %s", REC->ctx_num, REC->is_support_smc, REC->drm_fw_status ? "loaded" : "not-loaded"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_frame_bottom/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_frame_bottom/format
new file mode 100644
index 000000000..89b50fcf1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_frame_bottom/format
@@ -0,0 +1,14 @@
+name: mfc_frame_bottom
+ID: 1092
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ctx_num; offset:8; size:4; signed:1;
+ field:int reason; offset:12; size:4; signed:1;
+ field:int type; offset:16; size:4; signed:1;
+ field:int is_drm; offset:20; size:4; signed:1;
+
+print fmt: "ctx[%d] reason=%d, type=%d, %s", REC->ctx_num, REC->reason, REC->type, REC->is_drm ? "drm" : "normal"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_frame_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_frame_start/format
new file mode 100644
index 000000000..5fa99af22
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_frame_start/format
@@ -0,0 +1,14 @@
+name: mfc_frame_start
+ID: 1093
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ctx_num; offset:8; size:4; signed:1;
+ field:int reason; offset:12; size:4; signed:1;
+ field:int type; offset:16; size:4; signed:1;
+ field:int is_drm; offset:20; size:4; signed:1;
+
+print fmt: "ctx[%d] reason=%d, type=%d, %s", REC->ctx_num, REC->reason, REC->type, REC->is_drm ? "drm" : "normal"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_frame_top/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_frame_top/format
new file mode 100644
index 000000000..9d9675742
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_frame_top/format
@@ -0,0 +1,14 @@
+name: mfc_frame_top
+ID: 1094
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ctx_num; offset:8; size:4; signed:1;
+ field:int reason; offset:12; size:4; signed:1;
+ field:int type; offset:16; size:4; signed:1;
+ field:int is_drm; offset:20; size:4; signed:1;
+
+print fmt: "ctx[%d] reason=%d, type=%d, %s", REC->ctx_num, REC->reason, REC->type, REC->is_drm ? "drm" : "normal"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_loadfw_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_loadfw_end/format
new file mode 100644
index 000000000..089be6360
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_loadfw_end/format
@@ -0,0 +1,12 @@
+name: mfc_loadfw_end
+ID: 1095
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:size_t fw_region_size; offset:8; size:8; signed:0;
+ field:size_t fw_size; offset:16; size:8; signed:0;
+
+print fmt: "FW region: %ld, size: %ld", REC->fw_region_size, REC->fw_size
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_loadfw_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_loadfw_start/format
new file mode 100644
index 000000000..256ecdce1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_loadfw_start/format
@@ -0,0 +1,12 @@
+name: mfc_loadfw_start
+ID: 1096
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:size_t fw_region_size; offset:8; size:8; signed:0;
+ field:size_t fw_size; offset:16; size:8; signed:0;
+
+print fmt: "FW region: %ld, size: %ld", REC->fw_region_size, REC->fw_size
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_node_close/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_node_close/format
new file mode 100644
index 000000000..7f30af5f7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_node_close/format
@@ -0,0 +1,14 @@
+name: mfc_node_close
+ID: 1097
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ctx_num; offset:8; size:4; signed:1;
+ field:int num_inst; offset:12; size:4; signed:1;
+ field:unsigned int type; offset:16; size:4; signed:0;
+ field:int is_drm; offset:20; size:4; signed:1;
+
+print fmt: "ctx[%d] total inst=%d, type=%d, %s", REC->ctx_num, REC->num_inst, REC->type, REC->is_drm ? "drm" : "normal"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_node_open/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_node_open/format
new file mode 100644
index 000000000..8dd088ba4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mfc/mfc_node_open/format
@@ -0,0 +1,14 @@
+name: mfc_node_open
+ID: 1098
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ctx_num; offset:8; size:4; signed:1;
+ field:int num_inst; offset:12; size:4; signed:1;
+ field:unsigned int type; offset:16; size:4; signed:0;
+ field:int is_drm; offset:20; size:4; signed:1;
+
+print fmt: "ctx[%d] total inst=%d, type=%d, %s", REC->ctx_num, REC->num_inst, REC->type, REC->is_drm ? "drm" : "normal"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/migrate/mm_migrate_pages/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/migrate/mm_migrate_pages/format
new file mode 100644
index 000000000..b16efc5d0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/migrate/mm_migrate_pages/format
@@ -0,0 +1,17 @@
+name: mm_migrate_pages
+ID: 283
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long succeeded; offset:8; size:8; signed:0;
+ field:unsigned long failed; offset:16; size:8; signed:0;
+ field:unsigned long thp_succeeded; offset:24; size:8; signed:0;
+ field:unsigned long thp_failed; offset:32; size:8; signed:0;
+ field:unsigned long thp_split; offset:40; size:8; signed:0;
+ field:enum migrate_mode mode; offset:48; size:4; signed:0;
+ field:int reason; offset:52; size:4; signed:1;
+
+print fmt: "nr_succeeded=%lu nr_failed=%lu nr_thp_succeeded=%lu nr_thp_failed=%lu nr_thp_split=%lu mode=%s reason=%s", REC->succeeded, REC->failed, REC->thp_succeeded, REC->thp_failed, REC->thp_split, __print_symbolic(REC->mode, {0, "MIGRATE_ASYNC"}, {1, "MIGRATE_SYNC_LIGHT"}, {2, "MIGRATE_SYNC"}), __print_symbolic(REC->reason, {0, "compaction"}, {1, "memory_failure"}, {2, "memory_hotplug"}, {3, "syscall_or_cpuset"}, {4, "mempolicy_mbind"}, {5, "numa_misplaced"}, {6, "contig_range"})
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/migrate/mm_migrate_pages_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/migrate/mm_migrate_pages_start/format
new file mode 100644
index 000000000..b9b8d9b02
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/migrate/mm_migrate_pages_start/format
@@ -0,0 +1,12 @@
+name: mm_migrate_pages_start
+ID: 284
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum migrate_mode mode; offset:8; size:4; signed:0;
+ field:int reason; offset:12; size:4; signed:1;
+
+print fmt: "mode=%s reason=%s", __print_symbolic(REC->mode, {0, "MIGRATE_ASYNC"}, {1, "MIGRATE_SYNC_LIGHT"}, {2, "MIGRATE_SYNC"}), __print_symbolic(REC->reason, {0, "compaction"}, {1, "memory_failure"}, {2, "memory_hotplug"}, {3, "syscall_or_cpuset"}, {4, "mempolicy_mbind"}, {5, "numa_misplaced"}, {6, "contig_range"})
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mmap/vm_unmapped_area/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mmap/vm_unmapped_area/format
new file mode 100644
index 000000000..35dd246c8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mmap/vm_unmapped_area/format
@@ -0,0 +1,19 @@
+name: vm_unmapped_area
+ID: 282
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long addr; offset:8; size:8; signed:0;
+ field:unsigned long total_vm; offset:16; size:8; signed:0;
+ field:unsigned long flags; offset:24; size:8; signed:0;
+ field:unsigned long length; offset:32; size:8; signed:0;
+ field:unsigned long low_limit; offset:40; size:8; signed:0;
+ field:unsigned long high_limit; offset:48; size:8; signed:0;
+ field:unsigned long align_mask; offset:56; size:8; signed:0;
+ field:unsigned long align_offset; offset:64; size:8; signed:0;
+
+print fmt: "addr=0x%lx err=%ld total_vm=0x%lx flags=0x%lx len=0x%lx lo=0x%lx hi=0x%lx mask=0x%lx ofs=0x%lx
+", __builtin_expect(!!((unsigned long)(void *)(REC->addr) >= (unsigned long)-4095), 0) ? 0 : REC->addr, __builtin_expect(!!((unsigned long)(void *)(REC->addr) >= (unsigned long)-4095), 0) ? REC->addr : 0, REC->total_vm, REC->flags, REC->length, REC->low_limit, REC->high_limit, REC->align_mask, REC->align_offset
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mmc/mmc_request_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mmc/mmc_request_done/format
new file mode 100644
index 000000000..7bb4d4788
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mmc/mmc_request_done/format
@@ -0,0 +1,33 @@
+name: mmc_request_done
+ID: 861
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 cmd_opcode; offset:8; size:4; signed:0;
+ field:int cmd_err; offset:12; size:4; signed:1;
+ field:u32 cmd_resp[4]; offset:16; size:16; signed:0;
+ field:unsigned int cmd_retries; offset:32; size:4; signed:0;
+ field:u32 stop_opcode; offset:36; size:4; signed:0;
+ field:int stop_err; offset:40; size:4; signed:1;
+ field:u32 stop_resp[4]; offset:44; size:16; signed:0;
+ field:unsigned int stop_retries; offset:60; size:4; signed:0;
+ field:u32 sbc_opcode; offset:64; size:4; signed:0;
+ field:int sbc_err; offset:68; size:4; signed:1;
+ field:u32 sbc_resp[4]; offset:72; size:16; signed:0;
+ field:unsigned int sbc_retries; offset:88; size:4; signed:0;
+ field:unsigned int bytes_xfered; offset:92; size:4; signed:0;
+ field:int data_err; offset:96; size:4; signed:1;
+ field:int tag; offset:100; size:4; signed:1;
+ field:unsigned int can_retune; offset:104; size:4; signed:0;
+ field:unsigned int doing_retune; offset:108; size:4; signed:0;
+ field:unsigned int retune_now; offset:112; size:4; signed:0;
+ field:int need_retune; offset:116; size:4; signed:1;
+ field:int hold_retune; offset:120; size:4; signed:1;
+ field:unsigned int retune_period; offset:124; size:4; signed:0;
+ field:struct mmc_request * mrq; offset:128; size:8; signed:0;
+ field:__data_loc char[] name; offset:136; size:4; signed:0;
+
+print fmt: "%s: end struct mmc_request[%p]: cmd_opcode=%u cmd_err=%d cmd_resp=0x%x 0x%x 0x%x 0x%x cmd_retries=%u stop_opcode=%u stop_err=%d stop_resp=0x%x 0x%x 0x%x 0x%x stop_retries=%u sbc_opcode=%u sbc_err=%d sbc_resp=0x%x 0x%x 0x%x 0x%x sbc_retries=%u bytes_xfered=%u data_err=%d tag=%d can_retune=%u doing_retune=%u retune_now=%u need_retune=%d hold_retune=%d retune_period=%u", __get_str(name), REC->mrq, REC->cmd_opcode, REC->cmd_err, REC->cmd_resp[0], REC->cmd_resp[1], REC->cmd_resp[2], REC->cmd_resp[3], REC->cmd_retries, REC->stop_opcode, REC->stop_err, REC->stop_resp[0], REC->stop_resp[1], REC->stop_resp[2], REC->stop_resp[3], REC->stop_retries, REC->sbc_opcode, REC->sbc_err, REC->sbc_resp[0], REC->sbc_resp[1], REC->sbc_resp[2], REC->sbc_resp[3], REC->sbc_retries, REC->bytes_xfered, REC->data_err, REC->tag, REC->can_retune, REC->doing_retune, REC->retune_now, REC->need_retune, REC->hold_retune, REC->retune_period
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mmc/mmc_request_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mmc/mmc_request_start/format
new file mode 100644
index 000000000..b4c27fc13
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/mmc/mmc_request_start/format
@@ -0,0 +1,35 @@
+name: mmc_request_start
+ID: 862
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 cmd_opcode; offset:8; size:4; signed:0;
+ field:u32 cmd_arg; offset:12; size:4; signed:0;
+ field:unsigned int cmd_flags; offset:16; size:4; signed:0;
+ field:unsigned int cmd_retries; offset:20; size:4; signed:0;
+ field:u32 stop_opcode; offset:24; size:4; signed:0;
+ field:u32 stop_arg; offset:28; size:4; signed:0;
+ field:unsigned int stop_flags; offset:32; size:4; signed:0;
+ field:unsigned int stop_retries; offset:36; size:4; signed:0;
+ field:u32 sbc_opcode; offset:40; size:4; signed:0;
+ field:u32 sbc_arg; offset:44; size:4; signed:0;
+ field:unsigned int sbc_flags; offset:48; size:4; signed:0;
+ field:unsigned int sbc_retries; offset:52; size:4; signed:0;
+ field:unsigned int blocks; offset:56; size:4; signed:0;
+ field:unsigned int blk_addr; offset:60; size:4; signed:0;
+ field:unsigned int blksz; offset:64; size:4; signed:0;
+ field:unsigned int data_flags; offset:68; size:4; signed:0;
+ field:int tag; offset:72; size:4; signed:1;
+ field:unsigned int can_retune; offset:76; size:4; signed:0;
+ field:unsigned int doing_retune; offset:80; size:4; signed:0;
+ field:unsigned int retune_now; offset:84; size:4; signed:0;
+ field:int need_retune; offset:88; size:4; signed:1;
+ field:int hold_retune; offset:92; size:4; signed:1;
+ field:unsigned int retune_period; offset:96; size:4; signed:0;
+ field:struct mmc_request * mrq; offset:104; size:8; signed:0;
+ field:__data_loc char[] name; offset:112; size:4; signed:0;
+
+print fmt: "%s: start struct mmc_request[%p]: cmd_opcode=%u cmd_arg=0x%x cmd_flags=0x%x cmd_retries=%u stop_opcode=%u stop_arg=0x%x stop_flags=0x%x stop_retries=%u sbc_opcode=%u sbc_arg=0x%x sbc_flags=0x%x sbc_retires=%u blocks=%u block_size=%u blk_addr=%u data_flags=0x%x tag=%d can_retune=%u doing_retune=%u retune_now=%u need_retune=%d hold_retune=%d retune_period=%u", __get_str(name), REC->mrq, REC->cmd_opcode, REC->cmd_arg, REC->cmd_flags, REC->cmd_retries, REC->stop_opcode, REC->stop_arg, REC->stop_flags, REC->stop_retries, REC->sbc_opcode, REC->sbc_arg, REC->sbc_flags, REC->sbc_retries, REC->blocks, REC->blksz, REC->blk_addr, REC->data_flags, REC->tag, REC->can_retune, REC->doing_retune, REC->retune_now, REC->need_retune, REC->hold_retune, REC->retune_period
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/module/module_free/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/module/module_free/format
new file mode 100644
index 000000000..2a1e28c2b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/module/module_free/format
@@ -0,0 +1,11 @@
+name: module_free
+ID: 150
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/module/module_get/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/module/module_get/format
new file mode 100644
index 000000000..16538bf43
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/module/module_get/format
@@ -0,0 +1,13 @@
+name: module_get
+ID: 151
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long ip; offset:8; size:8; signed:0;
+ field:int refcnt; offset:16; size:4; signed:1;
+ field:__data_loc char[] name; offset:20; size:4; signed:0;
+
+print fmt: "%s call_site=%ps refcnt=%d", __get_str(name), (void *)REC->ip, REC->refcnt
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/module/module_load/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/module/module_load/format
new file mode 100644
index 000000000..0052c5a0c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/module/module_load/format
@@ -0,0 +1,12 @@
+name: module_load
+ID: 152
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int taints; offset:8; size:4; signed:0;
+ field:__data_loc char[] name; offset:12; size:4; signed:0;
+
+print fmt: "%s %s", __get_str(name), __print_flags(REC->taints, "", { (1UL << 0), "P" }, { (1UL << 12), "O" }, { (1UL << 1), "F" }, { (1UL << 10), "C" }, { (1UL << 13), "E" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/module/module_put/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/module/module_put/format
new file mode 100644
index 000000000..0a145c82e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/module/module_put/format
@@ -0,0 +1,13 @@
+name: module_put
+ID: 153
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long ip; offset:8; size:8; signed:0;
+ field:int refcnt; offset:16; size:4; signed:1;
+ field:__data_loc char[] name; offset:20; size:4; signed:0;
+
+print fmt: "%s call_site=%ps refcnt=%d", __get_str(name), (void *)REC->ip, REC->refcnt
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/module/module_request/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/module/module_request/format
new file mode 100644
index 000000000..54261ccad
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/module/module_request/format
@@ -0,0 +1,13 @@
+name: module_request
+ID: 154
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long ip; offset:8; size:8; signed:0;
+ field:bool wait; offset:16; size:1; signed:0;
+ field:__data_loc char[] name; offset:20; size:4; signed:0;
+
+print fmt: "%s wait=%d call_site=%ps", __get_str(name), (int)REC->wait, (void *)REC->ip
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/namei/inodepath/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/namei/inodepath/format
new file mode 100644
index 000000000..2b924d6ae
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/namei/inodepath/format
@@ -0,0 +1,13 @@
+name: inodepath
+ID: 295
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long ino; offset:8; size:8; signed:0;
+ field:unsigned long dev; offset:16; size:8; signed:0;
+ field:__data_loc char[] path; offset:24; size:4; signed:0;
+
+print fmt: "dev %d:%d ino=%lu path=%s", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->ino, __get_str(path)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/napi/napi_poll/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/napi/napi_poll/format
new file mode 100644
index 000000000..fcf8fb504
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/napi/napi_poll/format
@@ -0,0 +1,14 @@
+name: napi_poll
+ID: 930
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct napi_struct * napi; offset:8; size:8; signed:0;
+ field:__data_loc char[] dev_name; offset:16; size:4; signed:0;
+ field:int work; offset:20; size:4; signed:1;
+ field:int budget; offset:24; size:4; signed:1;
+
+print fmt: "napi poll on napi struct %p for device %s work %d budget %d", REC->napi, __get_str(dev_name), REC->work, REC->budget
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_cleanup_and_release/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_cleanup_and_release/format
new file mode 100644
index 000000000..6dd183123
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_cleanup_and_release/format
@@ -0,0 +1,25 @@
+name: neigh_cleanup_and_release
+ID: 931
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 family; offset:8; size:4; signed:0;
+ field:__data_loc char[] dev; offset:12; size:4; signed:0;
+ field:u8 lladdr[32]; offset:16; size:32; signed:0;
+ field:u8 lladdr_len; offset:48; size:1; signed:0;
+ field:u8 flags; offset:49; size:1; signed:0;
+ field:u8 nud_state; offset:50; size:1; signed:0;
+ field:u8 type; offset:51; size:1; signed:0;
+ field:u8 dead; offset:52; size:1; signed:0;
+ field:int refcnt; offset:56; size:4; signed:1;
+ field:__u8 primary_key4[4]; offset:60; size:4; signed:0;
+ field:__u8 primary_key6[16]; offset:64; size:16; signed:0;
+ field:unsigned long confirmed; offset:80; size:8; signed:0;
+ field:unsigned long updated; offset:88; size:8; signed:0;
+ field:unsigned long used; offset:96; size:8; signed:0;
+ field:u32 err; offset:104; size:4; signed:0;
+
+print fmt: "family %d dev %s lladdr %s flags %02x nud_state %s type %02x dead %d refcnt %d primary_key4 %pI4 primary_key6 %pI6c confirmed %lu updated %lu used %lu err %d", REC->family, __get_str(dev), __print_hex_str(REC->lladdr, REC->lladdr_len), REC->flags, __print_symbolic(REC->nud_state, { 0x01, "incomplete" }, { 0x02, "reachable" }, { 0x04, "stale" }, { 0x08, "delay" }, { 0x10, "probe" }, { 0x20, "failed" }, { 0x40, "noarp" }, { 0x80, "permanent"}), REC->type, REC->dead, REC->refcnt, REC->primary_key4, REC->primary_key6, REC->confirmed, REC->updated, REC->used, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_create/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_create/format
new file mode 100644
index 000000000..b94d87ea6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_create/format
@@ -0,0 +1,17 @@
+name: neigh_create
+ID: 932
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 family; offset:8; size:4; signed:0;
+ field:__data_loc char[] dev; offset:12; size:4; signed:0;
+ field:int entries; offset:16; size:4; signed:1;
+ field:u8 created; offset:20; size:1; signed:0;
+ field:u8 gc_exempt; offset:21; size:1; signed:0;
+ field:u8 primary_key4[4]; offset:22; size:4; signed:0;
+ field:u8 primary_key6[16]; offset:26; size:16; signed:0;
+
+print fmt: "family %d dev %s entries %d primary_key4 %pI4 primary_key6 %pI6c created %d gc_exempt %d", REC->family, __get_str(dev), REC->entries, REC->primary_key4, REC->primary_key6, REC->created, REC->gc_exempt
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_event_send_dead/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_event_send_dead/format
new file mode 100644
index 000000000..28a0ed636
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_event_send_dead/format
@@ -0,0 +1,25 @@
+name: neigh_event_send_dead
+ID: 933
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 family; offset:8; size:4; signed:0;
+ field:__data_loc char[] dev; offset:12; size:4; signed:0;
+ field:u8 lladdr[32]; offset:16; size:32; signed:0;
+ field:u8 lladdr_len; offset:48; size:1; signed:0;
+ field:u8 flags; offset:49; size:1; signed:0;
+ field:u8 nud_state; offset:50; size:1; signed:0;
+ field:u8 type; offset:51; size:1; signed:0;
+ field:u8 dead; offset:52; size:1; signed:0;
+ field:int refcnt; offset:56; size:4; signed:1;
+ field:__u8 primary_key4[4]; offset:60; size:4; signed:0;
+ field:__u8 primary_key6[16]; offset:64; size:16; signed:0;
+ field:unsigned long confirmed; offset:80; size:8; signed:0;
+ field:unsigned long updated; offset:88; size:8; signed:0;
+ field:unsigned long used; offset:96; size:8; signed:0;
+ field:u32 err; offset:104; size:4; signed:0;
+
+print fmt: "family %d dev %s lladdr %s flags %02x nud_state %s type %02x dead %d refcnt %d primary_key4 %pI4 primary_key6 %pI6c confirmed %lu updated %lu used %lu err %d", REC->family, __get_str(dev), __print_hex_str(REC->lladdr, REC->lladdr_len), REC->flags, __print_symbolic(REC->nud_state, { 0x01, "incomplete" }, { 0x02, "reachable" }, { 0x04, "stale" }, { 0x08, "delay" }, { 0x10, "probe" }, { 0x20, "failed" }, { 0x40, "noarp" }, { 0x80, "permanent"}), REC->type, REC->dead, REC->refcnt, REC->primary_key4, REC->primary_key6, REC->confirmed, REC->updated, REC->used, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_event_send_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_event_send_done/format
new file mode 100644
index 000000000..089ac0c2a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_event_send_done/format
@@ -0,0 +1,25 @@
+name: neigh_event_send_done
+ID: 934
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 family; offset:8; size:4; signed:0;
+ field:__data_loc char[] dev; offset:12; size:4; signed:0;
+ field:u8 lladdr[32]; offset:16; size:32; signed:0;
+ field:u8 lladdr_len; offset:48; size:1; signed:0;
+ field:u8 flags; offset:49; size:1; signed:0;
+ field:u8 nud_state; offset:50; size:1; signed:0;
+ field:u8 type; offset:51; size:1; signed:0;
+ field:u8 dead; offset:52; size:1; signed:0;
+ field:int refcnt; offset:56; size:4; signed:1;
+ field:__u8 primary_key4[4]; offset:60; size:4; signed:0;
+ field:__u8 primary_key6[16]; offset:64; size:16; signed:0;
+ field:unsigned long confirmed; offset:80; size:8; signed:0;
+ field:unsigned long updated; offset:88; size:8; signed:0;
+ field:unsigned long used; offset:96; size:8; signed:0;
+ field:u32 err; offset:104; size:4; signed:0;
+
+print fmt: "family %d dev %s lladdr %s flags %02x nud_state %s type %02x dead %d refcnt %d primary_key4 %pI4 primary_key6 %pI6c confirmed %lu updated %lu used %lu err %d", REC->family, __get_str(dev), __print_hex_str(REC->lladdr, REC->lladdr_len), REC->flags, __print_symbolic(REC->nud_state, { 0x01, "incomplete" }, { 0x02, "reachable" }, { 0x04, "stale" }, { 0x08, "delay" }, { 0x10, "probe" }, { 0x20, "failed" }, { 0x40, "noarp" }, { 0x80, "permanent"}), REC->type, REC->dead, REC->refcnt, REC->primary_key4, REC->primary_key6, REC->confirmed, REC->updated, REC->used, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_timer_handler/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_timer_handler/format
new file mode 100644
index 000000000..1c0c05250
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_timer_handler/format
@@ -0,0 +1,25 @@
+name: neigh_timer_handler
+ID: 935
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 family; offset:8; size:4; signed:0;
+ field:__data_loc char[] dev; offset:12; size:4; signed:0;
+ field:u8 lladdr[32]; offset:16; size:32; signed:0;
+ field:u8 lladdr_len; offset:48; size:1; signed:0;
+ field:u8 flags; offset:49; size:1; signed:0;
+ field:u8 nud_state; offset:50; size:1; signed:0;
+ field:u8 type; offset:51; size:1; signed:0;
+ field:u8 dead; offset:52; size:1; signed:0;
+ field:int refcnt; offset:56; size:4; signed:1;
+ field:__u8 primary_key4[4]; offset:60; size:4; signed:0;
+ field:__u8 primary_key6[16]; offset:64; size:16; signed:0;
+ field:unsigned long confirmed; offset:80; size:8; signed:0;
+ field:unsigned long updated; offset:88; size:8; signed:0;
+ field:unsigned long used; offset:96; size:8; signed:0;
+ field:u32 err; offset:104; size:4; signed:0;
+
+print fmt: "family %d dev %s lladdr %s flags %02x nud_state %s type %02x dead %d refcnt %d primary_key4 %pI4 primary_key6 %pI6c confirmed %lu updated %lu used %lu err %d", REC->family, __get_str(dev), __print_hex_str(REC->lladdr, REC->lladdr_len), REC->flags, __print_symbolic(REC->nud_state, { 0x01, "incomplete" }, { 0x02, "reachable" }, { 0x04, "stale" }, { 0x08, "delay" }, { 0x10, "probe" }, { 0x20, "failed" }, { 0x40, "noarp" }, { 0x80, "permanent"}), REC->type, REC->dead, REC->refcnt, REC->primary_key4, REC->primary_key6, REC->confirmed, REC->updated, REC->used, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_update/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_update/format
new file mode 100644
index 000000000..e7c6c46cb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_update/format
@@ -0,0 +1,28 @@
+name: neigh_update
+ID: 936
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 family; offset:8; size:4; signed:0;
+ field:__data_loc char[] dev; offset:12; size:4; signed:0;
+ field:u8 lladdr[32]; offset:16; size:32; signed:0;
+ field:u8 lladdr_len; offset:48; size:1; signed:0;
+ field:u8 flags; offset:49; size:1; signed:0;
+ field:u8 nud_state; offset:50; size:1; signed:0;
+ field:u8 type; offset:51; size:1; signed:0;
+ field:u8 dead; offset:52; size:1; signed:0;
+ field:int refcnt; offset:56; size:4; signed:1;
+ field:__u8 primary_key4[4]; offset:60; size:4; signed:0;
+ field:__u8 primary_key6[16]; offset:64; size:16; signed:0;
+ field:unsigned long confirmed; offset:80; size:8; signed:0;
+ field:unsigned long updated; offset:88; size:8; signed:0;
+ field:unsigned long used; offset:96; size:8; signed:0;
+ field:u8 new_lladdr[32]; offset:104; size:32; signed:0;
+ field:u8 new_state; offset:136; size:1; signed:0;
+ field:u32 update_flags; offset:140; size:4; signed:0;
+ field:u32 pid; offset:144; size:4; signed:0;
+
+print fmt: "family %d dev %s lladdr %s flags %02x nud_state %s type %02x dead %d refcnt %d primary_key4 %pI4 primary_key6 %pI6c confirmed %lu updated %lu used %lu new_lladdr %s new_state %s update_flags %02x pid %d", REC->family, __get_str(dev), __print_hex_str(REC->lladdr, REC->lladdr_len), REC->flags, __print_symbolic(REC->nud_state, { 0x01, "incomplete" }, { 0x02, "reachable" }, { 0x04, "stale" }, { 0x08, "delay" }, { 0x10, "probe" }, { 0x20, "failed" }, { 0x40, "noarp" }, { 0x80, "permanent"}), REC->type, REC->dead, REC->refcnt, REC->primary_key4, REC->primary_key6, REC->confirmed, REC->updated, REC->used, __print_hex_str(REC->new_lladdr, REC->lladdr_len), __print_symbolic(REC->new_state, { 0x01, "incomplete" }, { 0x02, "reachable" }, { 0x04, "stale" }, { 0x08, "delay" }, { 0x10, "probe" }, { 0x20, "failed" }, { 0x40, "noarp" }, { 0x80, "permanent"}), REC->update_flags, REC->pid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_update_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_update_done/format
new file mode 100644
index 000000000..cca8b11a3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/neigh/neigh_update_done/format
@@ -0,0 +1,25 @@
+name: neigh_update_done
+ID: 937
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 family; offset:8; size:4; signed:0;
+ field:__data_loc char[] dev; offset:12; size:4; signed:0;
+ field:u8 lladdr[32]; offset:16; size:32; signed:0;
+ field:u8 lladdr_len; offset:48; size:1; signed:0;
+ field:u8 flags; offset:49; size:1; signed:0;
+ field:u8 nud_state; offset:50; size:1; signed:0;
+ field:u8 type; offset:51; size:1; signed:0;
+ field:u8 dead; offset:52; size:1; signed:0;
+ field:int refcnt; offset:56; size:4; signed:1;
+ field:__u8 primary_key4[4]; offset:60; size:4; signed:0;
+ field:__u8 primary_key6[16]; offset:64; size:16; signed:0;
+ field:unsigned long confirmed; offset:80; size:8; signed:0;
+ field:unsigned long updated; offset:88; size:8; signed:0;
+ field:unsigned long used; offset:96; size:8; signed:0;
+ field:u32 err; offset:104; size:4; signed:0;
+
+print fmt: "family %d dev %s lladdr %s flags %02x nud_state %s type %02x dead %d refcnt %d primary_key4 %pI4 primary_key6 %pI6c confirmed %lu updated %lu used %lu err %d", REC->family, __get_str(dev), __print_hex_str(REC->lladdr, REC->lladdr_len), REC->flags, __print_symbolic(REC->nud_state, { 0x01, "incomplete" }, { 0x02, "reachable" }, { 0x04, "stale" }, { 0x08, "delay" }, { 0x10, "probe" }, { 0x20, "failed" }, { 0x40, "noarp" }, { 0x80, "permanent"}), REC->type, REC->dead, REC->refcnt, REC->primary_key4, REC->primary_key6, REC->confirmed, REC->updated, REC->used, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/napi_gro_frags_entry/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/napi_gro_frags_entry/format
new file mode 100644
index 000000000..135549e23
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/napi_gro_frags_entry/format
@@ -0,0 +1,29 @@
+name: napi_gro_frags_entry
+ID: 926
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int napi_id; offset:12; size:4; signed:0;
+ field:u16 queue_mapping; offset:16; size:2; signed:0;
+ field:const void * skbaddr; offset:24; size:8; signed:0;
+ field:bool vlan_tagged; offset:32; size:1; signed:0;
+ field:u16 vlan_proto; offset:34; size:2; signed:0;
+ field:u16 vlan_tci; offset:36; size:2; signed:0;
+ field:u16 protocol; offset:38; size:2; signed:0;
+ field:u8 ip_summed; offset:40; size:1; signed:0;
+ field:u32 hash; offset:44; size:4; signed:0;
+ field:bool l4_hash; offset:48; size:1; signed:0;
+ field:unsigned int len; offset:52; size:4; signed:0;
+ field:unsigned int data_len; offset:56; size:4; signed:0;
+ field:unsigned int truesize; offset:60; size:4; signed:0;
+ field:bool mac_header_valid; offset:64; size:1; signed:0;
+ field:int mac_header; offset:68; size:4; signed:1;
+ field:unsigned char nr_frags; offset:72; size:1; signed:0;
+ field:u16 gso_size; offset:74; size:2; signed:0;
+ field:u16 gso_type; offset:76; size:2; signed:0;
+
+print fmt: "dev=%s napi_id=%#x queue_mapping=%u skbaddr=%p vlan_tagged=%d vlan_proto=0x%04x vlan_tci=0x%04x protocol=0x%04x ip_summed=%d hash=0x%08x l4_hash=%d len=%u data_len=%u truesize=%u mac_header_valid=%d mac_header=%d nr_frags=%d gso_size=%d gso_type=%#x", __get_str(name), REC->napi_id, REC->queue_mapping, REC->skbaddr, REC->vlan_tagged, REC->vlan_proto, REC->vlan_tci, REC->protocol, REC->ip_summed, REC->hash, REC->l4_hash, REC->len, REC->data_len, REC->truesize, REC->mac_header_valid, REC->mac_header, REC->nr_frags, REC->gso_size, REC->gso_type
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/napi_gro_frags_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/napi_gro_frags_exit/format
new file mode 100644
index 000000000..e0d8513da
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/napi_gro_frags_exit/format
@@ -0,0 +1,11 @@
+name: napi_gro_frags_exit
+ID: 927
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ret; offset:8; size:4; signed:1;
+
+print fmt: "ret=%d", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/napi_gro_receive_entry/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/napi_gro_receive_entry/format
new file mode 100644
index 000000000..1d8d55723
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/napi_gro_receive_entry/format
@@ -0,0 +1,29 @@
+name: napi_gro_receive_entry
+ID: 928
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int napi_id; offset:12; size:4; signed:0;
+ field:u16 queue_mapping; offset:16; size:2; signed:0;
+ field:const void * skbaddr; offset:24; size:8; signed:0;
+ field:bool vlan_tagged; offset:32; size:1; signed:0;
+ field:u16 vlan_proto; offset:34; size:2; signed:0;
+ field:u16 vlan_tci; offset:36; size:2; signed:0;
+ field:u16 protocol; offset:38; size:2; signed:0;
+ field:u8 ip_summed; offset:40; size:1; signed:0;
+ field:u32 hash; offset:44; size:4; signed:0;
+ field:bool l4_hash; offset:48; size:1; signed:0;
+ field:unsigned int len; offset:52; size:4; signed:0;
+ field:unsigned int data_len; offset:56; size:4; signed:0;
+ field:unsigned int truesize; offset:60; size:4; signed:0;
+ field:bool mac_header_valid; offset:64; size:1; signed:0;
+ field:int mac_header; offset:68; size:4; signed:1;
+ field:unsigned char nr_frags; offset:72; size:1; signed:0;
+ field:u16 gso_size; offset:74; size:2; signed:0;
+ field:u16 gso_type; offset:76; size:2; signed:0;
+
+print fmt: "dev=%s napi_id=%#x queue_mapping=%u skbaddr=%p vlan_tagged=%d vlan_proto=0x%04x vlan_tci=0x%04x protocol=0x%04x ip_summed=%d hash=0x%08x l4_hash=%d len=%u data_len=%u truesize=%u mac_header_valid=%d mac_header=%d nr_frags=%d gso_size=%d gso_type=%#x", __get_str(name), REC->napi_id, REC->queue_mapping, REC->skbaddr, REC->vlan_tagged, REC->vlan_proto, REC->vlan_tci, REC->protocol, REC->ip_summed, REC->hash, REC->l4_hash, REC->len, REC->data_len, REC->truesize, REC->mac_header_valid, REC->mac_header, REC->nr_frags, REC->gso_size, REC->gso_type
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/napi_gro_receive_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/napi_gro_receive_exit/format
new file mode 100644
index 000000000..2eb347d76
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/napi_gro_receive_exit/format
@@ -0,0 +1,11 @@
+name: napi_gro_receive_exit
+ID: 929
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ret; offset:8; size:4; signed:1;
+
+print fmt: "ret=%d", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/net_dev_queue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/net_dev_queue/format
new file mode 100644
index 000000000..43a99e0eb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/net_dev_queue/format
@@ -0,0 +1,13 @@
+name: net_dev_queue
+ID: 938
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * skbaddr; offset:8; size:8; signed:0;
+ field:unsigned int len; offset:16; size:4; signed:0;
+ field:__data_loc char[] name; offset:20; size:4; signed:0;
+
+print fmt: "dev=%s skbaddr=%p len=%u", __get_str(name), REC->skbaddr, REC->len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/net_dev_start_xmit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/net_dev_start_xmit/format
new file mode 100644
index 000000000..5fb235753
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/net_dev_start_xmit/format
@@ -0,0 +1,27 @@
+name: net_dev_start_xmit
+ID: 939
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:u16 queue_mapping; offset:12; size:2; signed:0;
+ field:const void * skbaddr; offset:16; size:8; signed:0;
+ field:bool vlan_tagged; offset:24; size:1; signed:0;
+ field:u16 vlan_proto; offset:26; size:2; signed:0;
+ field:u16 vlan_tci; offset:28; size:2; signed:0;
+ field:u16 protocol; offset:30; size:2; signed:0;
+ field:u8 ip_summed; offset:32; size:1; signed:0;
+ field:unsigned int len; offset:36; size:4; signed:0;
+ field:unsigned int data_len; offset:40; size:4; signed:0;
+ field:int network_offset; offset:44; size:4; signed:1;
+ field:bool transport_offset_valid; offset:48; size:1; signed:0;
+ field:int transport_offset; offset:52; size:4; signed:1;
+ field:u8 tx_flags; offset:56; size:1; signed:0;
+ field:u16 gso_size; offset:58; size:2; signed:0;
+ field:u16 gso_segs; offset:60; size:2; signed:0;
+ field:u16 gso_type; offset:62; size:2; signed:0;
+
+print fmt: "dev=%s queue_mapping=%u skbaddr=%p vlan_tagged=%d vlan_proto=0x%04x vlan_tci=0x%04x protocol=0x%04x ip_summed=%d len=%u data_len=%u network_offset=%d transport_offset_valid=%d transport_offset=%d tx_flags=%d gso_size=%d gso_segs=%d gso_type=%#x", __get_str(name), REC->queue_mapping, REC->skbaddr, REC->vlan_tagged, REC->vlan_proto, REC->vlan_tci, REC->protocol, REC->ip_summed, REC->len, REC->data_len, REC->network_offset, REC->transport_offset_valid, REC->transport_offset, REC->tx_flags, REC->gso_size, REC->gso_segs, REC->gso_type
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/net_dev_xmit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/net_dev_xmit/format
new file mode 100644
index 000000000..e7482891d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/net_dev_xmit/format
@@ -0,0 +1,14 @@
+name: net_dev_xmit
+ID: 940
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * skbaddr; offset:8; size:8; signed:0;
+ field:unsigned int len; offset:16; size:4; signed:0;
+ field:int rc; offset:20; size:4; signed:1;
+ field:__data_loc char[] name; offset:24; size:4; signed:0;
+
+print fmt: "dev=%s skbaddr=%p len=%u rc=%d", __get_str(name), REC->skbaddr, REC->len, REC->rc
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/net_dev_xmit_timeout/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/net_dev_xmit_timeout/format
new file mode 100644
index 000000000..4510b71eb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/net_dev_xmit_timeout/format
@@ -0,0 +1,13 @@
+name: net_dev_xmit_timeout
+ID: 941
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:__data_loc char[] driver; offset:12; size:4; signed:0;
+ field:int queue_index; offset:16; size:4; signed:1;
+
+print fmt: "dev=%s driver=%s queue=%d", __get_str(name), __get_str(driver), REC->queue_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_receive_skb/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_receive_skb/format
new file mode 100644
index 000000000..9be89b6b5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_receive_skb/format
@@ -0,0 +1,13 @@
+name: netif_receive_skb
+ID: 942
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * skbaddr; offset:8; size:8; signed:0;
+ field:unsigned int len; offset:16; size:4; signed:0;
+ field:__data_loc char[] name; offset:20; size:4; signed:0;
+
+print fmt: "dev=%s skbaddr=%p len=%u", __get_str(name), REC->skbaddr, REC->len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_receive_skb_entry/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_receive_skb_entry/format
new file mode 100644
index 000000000..bbcd776bb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_receive_skb_entry/format
@@ -0,0 +1,29 @@
+name: netif_receive_skb_entry
+ID: 943
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int napi_id; offset:12; size:4; signed:0;
+ field:u16 queue_mapping; offset:16; size:2; signed:0;
+ field:const void * skbaddr; offset:24; size:8; signed:0;
+ field:bool vlan_tagged; offset:32; size:1; signed:0;
+ field:u16 vlan_proto; offset:34; size:2; signed:0;
+ field:u16 vlan_tci; offset:36; size:2; signed:0;
+ field:u16 protocol; offset:38; size:2; signed:0;
+ field:u8 ip_summed; offset:40; size:1; signed:0;
+ field:u32 hash; offset:44; size:4; signed:0;
+ field:bool l4_hash; offset:48; size:1; signed:0;
+ field:unsigned int len; offset:52; size:4; signed:0;
+ field:unsigned int data_len; offset:56; size:4; signed:0;
+ field:unsigned int truesize; offset:60; size:4; signed:0;
+ field:bool mac_header_valid; offset:64; size:1; signed:0;
+ field:int mac_header; offset:68; size:4; signed:1;
+ field:unsigned char nr_frags; offset:72; size:1; signed:0;
+ field:u16 gso_size; offset:74; size:2; signed:0;
+ field:u16 gso_type; offset:76; size:2; signed:0;
+
+print fmt: "dev=%s napi_id=%#x queue_mapping=%u skbaddr=%p vlan_tagged=%d vlan_proto=0x%04x vlan_tci=0x%04x protocol=0x%04x ip_summed=%d hash=0x%08x l4_hash=%d len=%u data_len=%u truesize=%u mac_header_valid=%d mac_header=%d nr_frags=%d gso_size=%d gso_type=%#x", __get_str(name), REC->napi_id, REC->queue_mapping, REC->skbaddr, REC->vlan_tagged, REC->vlan_proto, REC->vlan_tci, REC->protocol, REC->ip_summed, REC->hash, REC->l4_hash, REC->len, REC->data_len, REC->truesize, REC->mac_header_valid, REC->mac_header, REC->nr_frags, REC->gso_size, REC->gso_type
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_receive_skb_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_receive_skb_exit/format
new file mode 100644
index 000000000..34a40e847
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_receive_skb_exit/format
@@ -0,0 +1,11 @@
+name: netif_receive_skb_exit
+ID: 944
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ret; offset:8; size:4; signed:1;
+
+print fmt: "ret=%d", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_receive_skb_list_entry/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_receive_skb_list_entry/format
new file mode 100644
index 000000000..f6e0afa20
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_receive_skb_list_entry/format
@@ -0,0 +1,29 @@
+name: netif_receive_skb_list_entry
+ID: 945
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int napi_id; offset:12; size:4; signed:0;
+ field:u16 queue_mapping; offset:16; size:2; signed:0;
+ field:const void * skbaddr; offset:24; size:8; signed:0;
+ field:bool vlan_tagged; offset:32; size:1; signed:0;
+ field:u16 vlan_proto; offset:34; size:2; signed:0;
+ field:u16 vlan_tci; offset:36; size:2; signed:0;
+ field:u16 protocol; offset:38; size:2; signed:0;
+ field:u8 ip_summed; offset:40; size:1; signed:0;
+ field:u32 hash; offset:44; size:4; signed:0;
+ field:bool l4_hash; offset:48; size:1; signed:0;
+ field:unsigned int len; offset:52; size:4; signed:0;
+ field:unsigned int data_len; offset:56; size:4; signed:0;
+ field:unsigned int truesize; offset:60; size:4; signed:0;
+ field:bool mac_header_valid; offset:64; size:1; signed:0;
+ field:int mac_header; offset:68; size:4; signed:1;
+ field:unsigned char nr_frags; offset:72; size:1; signed:0;
+ field:u16 gso_size; offset:74; size:2; signed:0;
+ field:u16 gso_type; offset:76; size:2; signed:0;
+
+print fmt: "dev=%s napi_id=%#x queue_mapping=%u skbaddr=%p vlan_tagged=%d vlan_proto=0x%04x vlan_tci=0x%04x protocol=0x%04x ip_summed=%d hash=0x%08x l4_hash=%d len=%u data_len=%u truesize=%u mac_header_valid=%d mac_header=%d nr_frags=%d gso_size=%d gso_type=%#x", __get_str(name), REC->napi_id, REC->queue_mapping, REC->skbaddr, REC->vlan_tagged, REC->vlan_proto, REC->vlan_tci, REC->protocol, REC->ip_summed, REC->hash, REC->l4_hash, REC->len, REC->data_len, REC->truesize, REC->mac_header_valid, REC->mac_header, REC->nr_frags, REC->gso_size, REC->gso_type
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_receive_skb_list_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_receive_skb_list_exit/format
new file mode 100644
index 000000000..b0913f4b6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_receive_skb_list_exit/format
@@ -0,0 +1,11 @@
+name: netif_receive_skb_list_exit
+ID: 946
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ret; offset:8; size:4; signed:1;
+
+print fmt: "ret=%d", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_rx/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_rx/format
new file mode 100644
index 000000000..f402bfb70
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_rx/format
@@ -0,0 +1,13 @@
+name: netif_rx
+ID: 947
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * skbaddr; offset:8; size:8; signed:0;
+ field:unsigned int len; offset:16; size:4; signed:0;
+ field:__data_loc char[] name; offset:20; size:4; signed:0;
+
+print fmt: "dev=%s skbaddr=%p len=%u", __get_str(name), REC->skbaddr, REC->len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_rx_entry/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_rx_entry/format
new file mode 100644
index 000000000..2e0c19373
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_rx_entry/format
@@ -0,0 +1,29 @@
+name: netif_rx_entry
+ID: 948
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int napi_id; offset:12; size:4; signed:0;
+ field:u16 queue_mapping; offset:16; size:2; signed:0;
+ field:const void * skbaddr; offset:24; size:8; signed:0;
+ field:bool vlan_tagged; offset:32; size:1; signed:0;
+ field:u16 vlan_proto; offset:34; size:2; signed:0;
+ field:u16 vlan_tci; offset:36; size:2; signed:0;
+ field:u16 protocol; offset:38; size:2; signed:0;
+ field:u8 ip_summed; offset:40; size:1; signed:0;
+ field:u32 hash; offset:44; size:4; signed:0;
+ field:bool l4_hash; offset:48; size:1; signed:0;
+ field:unsigned int len; offset:52; size:4; signed:0;
+ field:unsigned int data_len; offset:56; size:4; signed:0;
+ field:unsigned int truesize; offset:60; size:4; signed:0;
+ field:bool mac_header_valid; offset:64; size:1; signed:0;
+ field:int mac_header; offset:68; size:4; signed:1;
+ field:unsigned char nr_frags; offset:72; size:1; signed:0;
+ field:u16 gso_size; offset:74; size:2; signed:0;
+ field:u16 gso_type; offset:76; size:2; signed:0;
+
+print fmt: "dev=%s napi_id=%#x queue_mapping=%u skbaddr=%p vlan_tagged=%d vlan_proto=0x%04x vlan_tci=0x%04x protocol=0x%04x ip_summed=%d hash=0x%08x l4_hash=%d len=%u data_len=%u truesize=%u mac_header_valid=%d mac_header=%d nr_frags=%d gso_size=%d gso_type=%#x", __get_str(name), REC->napi_id, REC->queue_mapping, REC->skbaddr, REC->vlan_tagged, REC->vlan_proto, REC->vlan_tci, REC->protocol, REC->ip_summed, REC->hash, REC->l4_hash, REC->len, REC->data_len, REC->truesize, REC->mac_header_valid, REC->mac_header, REC->nr_frags, REC->gso_size, REC->gso_type
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_rx_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_rx_exit/format
new file mode 100644
index 000000000..f77e11891
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_rx_exit/format
@@ -0,0 +1,11 @@
+name: netif_rx_exit
+ID: 949
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ret; offset:8; size:4; signed:1;
+
+print fmt: "ret=%d", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_rx_ni_entry/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_rx_ni_entry/format
new file mode 100644
index 000000000..41c4f3e81
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_rx_ni_entry/format
@@ -0,0 +1,29 @@
+name: netif_rx_ni_entry
+ID: 950
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int napi_id; offset:12; size:4; signed:0;
+ field:u16 queue_mapping; offset:16; size:2; signed:0;
+ field:const void * skbaddr; offset:24; size:8; signed:0;
+ field:bool vlan_tagged; offset:32; size:1; signed:0;
+ field:u16 vlan_proto; offset:34; size:2; signed:0;
+ field:u16 vlan_tci; offset:36; size:2; signed:0;
+ field:u16 protocol; offset:38; size:2; signed:0;
+ field:u8 ip_summed; offset:40; size:1; signed:0;
+ field:u32 hash; offset:44; size:4; signed:0;
+ field:bool l4_hash; offset:48; size:1; signed:0;
+ field:unsigned int len; offset:52; size:4; signed:0;
+ field:unsigned int data_len; offset:56; size:4; signed:0;
+ field:unsigned int truesize; offset:60; size:4; signed:0;
+ field:bool mac_header_valid; offset:64; size:1; signed:0;
+ field:int mac_header; offset:68; size:4; signed:1;
+ field:unsigned char nr_frags; offset:72; size:1; signed:0;
+ field:u16 gso_size; offset:74; size:2; signed:0;
+ field:u16 gso_type; offset:76; size:2; signed:0;
+
+print fmt: "dev=%s napi_id=%#x queue_mapping=%u skbaddr=%p vlan_tagged=%d vlan_proto=0x%04x vlan_tci=0x%04x protocol=0x%04x ip_summed=%d hash=0x%08x l4_hash=%d len=%u data_len=%u truesize=%u mac_header_valid=%d mac_header=%d nr_frags=%d gso_size=%d gso_type=%#x", __get_str(name), REC->napi_id, REC->queue_mapping, REC->skbaddr, REC->vlan_tagged, REC->vlan_proto, REC->vlan_tci, REC->protocol, REC->ip_summed, REC->hash, REC->l4_hash, REC->len, REC->data_len, REC->truesize, REC->mac_header_valid, REC->mac_header, REC->nr_frags, REC->gso_size, REC->gso_type
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_rx_ni_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_rx_ni_exit/format
new file mode 100644
index 000000000..cc3c3a965
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/net/netif_rx_ni_exit/format
@@ -0,0 +1,11 @@
+name: netif_rx_ni_exit
+ID: 951
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ret; offset:8; size:4; signed:1;
+
+print fmt: "ret=%d", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/compact_retry/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/compact_retry/format
new file mode 100644
index 000000000..2c58b6a85
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/compact_retry/format
@@ -0,0 +1,16 @@
+name: compact_retry
+ID: 216
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int order; offset:8; size:4; signed:1;
+ field:int priority; offset:12; size:4; signed:1;
+ field:int result; offset:16; size:4; signed:1;
+ field:int retries; offset:20; size:4; signed:1;
+ field:int max_retries; offset:24; size:4; signed:1;
+ field:bool ret; offset:28; size:1; signed:0;
+
+print fmt: "order=%d priority=%s compaction_result=%s retries=%d max_retries=%d should_retry=%d", REC->order, __print_symbolic(REC->priority, {0, "COMPACT_PRIO_SYNC_FULL"}, {1, "COMPACT_PRIO_SYNC_LIGHT"}, {2, "COMPACT_PRIO_ASYNC"}), __print_symbolic(REC->result, {1, "failed"}, {2, "withdrawn"}, {3, "progress"}), REC->retries, REC->max_retries, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/finish_task_reaping/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/finish_task_reaping/format
new file mode 100644
index 000000000..b1609b72f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/finish_task_reaping/format
@@ -0,0 +1,11 @@
+name: finish_task_reaping
+ID: 217
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int pid; offset:8; size:4; signed:1;
+
+print fmt: "pid=%d", REC->pid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/mark_victim/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/mark_victim/format
new file mode 100644
index 000000000..fee2859da
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/mark_victim/format
@@ -0,0 +1,11 @@
+name: mark_victim
+ID: 218
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int pid; offset:8; size:4; signed:1;
+
+print fmt: "pid=%d", REC->pid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/oom_score_adj_update/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/oom_score_adj_update/format
new file mode 100644
index 000000000..a1cc19a39
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/oom_score_adj_update/format
@@ -0,0 +1,13 @@
+name: oom_score_adj_update
+ID: 219
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:pid_t pid; offset:8; size:4; signed:1;
+ field:char comm[16]; offset:12; size:16; signed:0;
+ field:short oom_score_adj; offset:28; size:2; signed:1;
+
+print fmt: "pid=%d comm=%s oom_score_adj=%hd", REC->pid, REC->comm, REC->oom_score_adj
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/reclaim_retry_zone/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/reclaim_retry_zone/format
new file mode 100644
index 000000000..c679eed24
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/reclaim_retry_zone/format
@@ -0,0 +1,18 @@
+name: reclaim_retry_zone
+ID: 220
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int node; offset:8; size:4; signed:1;
+ field:int zone_idx; offset:12; size:4; signed:1;
+ field:int order; offset:16; size:4; signed:1;
+ field:unsigned long reclaimable; offset:24; size:8; signed:0;
+ field:unsigned long available; offset:32; size:8; signed:0;
+ field:unsigned long min_wmark; offset:40; size:8; signed:0;
+ field:int no_progress_loops; offset:48; size:4; signed:1;
+ field:bool wmark_check; offset:52; size:1; signed:0;
+
+print fmt: "node=%d zone=%-8s order=%d reclaimable=%lu available=%lu min_wmark=%lu no_progress_loops=%d wmark_check=%d", REC->node, __print_symbolic(REC->zone_idx, {0, "DMA32"}, {1, "Normal"}, {2, "Movable"}), REC->order, REC->reclaimable, REC->available, REC->min_wmark, REC->no_progress_loops, REC->wmark_check
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/skip_task_reaping/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/skip_task_reaping/format
new file mode 100644
index 000000000..4832adb56
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/skip_task_reaping/format
@@ -0,0 +1,11 @@
+name: skip_task_reaping
+ID: 221
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int pid; offset:8; size:4; signed:1;
+
+print fmt: "pid=%d", REC->pid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/start_task_reaping/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/start_task_reaping/format
new file mode 100644
index 000000000..28669cde2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/start_task_reaping/format
@@ -0,0 +1,11 @@
+name: start_task_reaping
+ID: 222
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int pid; offset:8; size:4; signed:1;
+
+print fmt: "pid=%d", REC->pid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/wake_reaper/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/wake_reaper/format
new file mode 100644
index 000000000..a06796df4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/oom/wake_reaper/format
@@ -0,0 +1,11 @@
+name: wake_reaper
+ID: 223
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int pid; offset:8; size:4; signed:1;
+
+print fmt: "pid=%d", REC->pid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/page_isolation/test_pages_isolated/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/page_isolation/test_pages_isolated/format
new file mode 100644
index 000000000..4778c139e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/page_isolation/test_pages_isolated/format
@@ -0,0 +1,13 @@
+name: test_pages_isolated
+ID: 289
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long start_pfn; offset:8; size:8; signed:0;
+ field:unsigned long end_pfn; offset:16; size:8; signed:0;
+ field:unsigned long fin_pfn; offset:24; size:8; signed:0;
+
+print fmt: "start_pfn=0x%lx end_pfn=0x%lx fin_pfn=0x%lx ret=%s", REC->start_pfn, REC->end_pfn, REC->fin_pfn, REC->end_pfn <= REC->fin_pfn ? "success" : "fail"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/page_pool/page_pool_release/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/page_pool/page_pool_release/format
new file mode 100644
index 000000000..16364ed89
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/page_pool/page_pool_release/format
@@ -0,0 +1,15 @@
+name: page_pool_release
+ID: 952
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const struct page_pool * pool; offset:8; size:8; signed:0;
+ field:s32 inflight; offset:16; size:4; signed:1;
+ field:u32 hold; offset:20; size:4; signed:0;
+ field:u32 release; offset:24; size:4; signed:0;
+ field:u64 cnt; offset:32; size:8; signed:0;
+
+print fmt: "page_pool=%p inflight=%d hold=%u release=%u cnt=%llu", REC->pool, REC->inflight, REC->hold, REC->release, REC->cnt
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/page_pool/page_pool_state_hold/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/page_pool/page_pool_state_hold/format
new file mode 100644
index 000000000..44794dd2b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/page_pool/page_pool_state_hold/format
@@ -0,0 +1,14 @@
+name: page_pool_state_hold
+ID: 953
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const struct page_pool * pool; offset:8; size:8; signed:0;
+ field:const struct page * page; offset:16; size:8; signed:0;
+ field:u32 hold; offset:24; size:4; signed:0;
+ field:unsigned long pfn; offset:32; size:8; signed:0;
+
+print fmt: "page_pool=%p page=%p pfn=%lu hold=%u", REC->pool, REC->page, REC->pfn, REC->hold
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/page_pool/page_pool_state_release/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/page_pool/page_pool_state_release/format
new file mode 100644
index 000000000..7449103b6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/page_pool/page_pool_state_release/format
@@ -0,0 +1,14 @@
+name: page_pool_state_release
+ID: 954
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const struct page_pool * pool; offset:8; size:8; signed:0;
+ field:const struct page * page; offset:16; size:8; signed:0;
+ field:u32 release; offset:24; size:4; signed:0;
+ field:unsigned long pfn; offset:32; size:8; signed:0;
+
+print fmt: "page_pool=%p page=%p pfn=%lu release=%u", REC->pool, REC->page, REC->pfn, REC->release
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/page_pool/page_pool_update_nid/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/page_pool/page_pool_update_nid/format
new file mode 100644
index 000000000..6f54fe499
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/page_pool/page_pool_update_nid/format
@@ -0,0 +1,13 @@
+name: page_pool_update_nid
+ID: 955
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const struct page_pool * pool; offset:8; size:8; signed:0;
+ field:int pool_nid; offset:16; size:4; signed:1;
+ field:int new_nid; offset:20; size:4; signed:1;
+
+print fmt: "page_pool=%p pool_nid=%d new_nid=%d", REC->pool, REC->pool_nid, REC->new_nid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_pmd_changed/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_pmd_changed/format
new file mode 100644
index 000000000..a9034da8a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_pmd_changed/format
@@ -0,0 +1,14 @@
+name: spf_pmd_changed
+ID: 276
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long caller; offset:8; size:8; signed:0;
+ field:unsigned long vm_start; offset:16; size:8; signed:0;
+ field:unsigned long vm_end; offset:24; size:8; signed:0;
+ field:unsigned long address; offset:32; size:8; signed:0;
+
+print fmt: "ip:%lx vma:%lx-%lx address:%lx", REC->caller, REC->vm_start, REC->vm_end, REC->address
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_pte_lock/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_pte_lock/format
new file mode 100644
index 000000000..370a65bff
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_pte_lock/format
@@ -0,0 +1,14 @@
+name: spf_pte_lock
+ID: 277
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long caller; offset:8; size:8; signed:0;
+ field:unsigned long vm_start; offset:16; size:8; signed:0;
+ field:unsigned long vm_end; offset:24; size:8; signed:0;
+ field:unsigned long address; offset:32; size:8; signed:0;
+
+print fmt: "ip:%lx vma:%lx-%lx address:%lx", REC->caller, REC->vm_start, REC->vm_end, REC->address
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_vma_access/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_vma_access/format
new file mode 100644
index 000000000..0dbc0d533
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_vma_access/format
@@ -0,0 +1,14 @@
+name: spf_vma_access
+ID: 278
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long caller; offset:8; size:8; signed:0;
+ field:unsigned long vm_start; offset:16; size:8; signed:0;
+ field:unsigned long vm_end; offset:24; size:8; signed:0;
+ field:unsigned long address; offset:32; size:8; signed:0;
+
+print fmt: "ip:%lx vma:%lx-%lx address:%lx", REC->caller, REC->vm_start, REC->vm_end, REC->address
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_vma_changed/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_vma_changed/format
new file mode 100644
index 000000000..9da19b6f9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_vma_changed/format
@@ -0,0 +1,14 @@
+name: spf_vma_changed
+ID: 279
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long caller; offset:8; size:8; signed:0;
+ field:unsigned long vm_start; offset:16; size:8; signed:0;
+ field:unsigned long vm_end; offset:24; size:8; signed:0;
+ field:unsigned long address; offset:32; size:8; signed:0;
+
+print fmt: "ip:%lx vma:%lx-%lx address:%lx", REC->caller, REC->vm_start, REC->vm_end, REC->address
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_vma_noanon/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_vma_noanon/format
new file mode 100644
index 000000000..2c5c08c01
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_vma_noanon/format
@@ -0,0 +1,14 @@
+name: spf_vma_noanon
+ID: 280
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long caller; offset:8; size:8; signed:0;
+ field:unsigned long vm_start; offset:16; size:8; signed:0;
+ field:unsigned long vm_end; offset:24; size:8; signed:0;
+ field:unsigned long address; offset:32; size:8; signed:0;
+
+print fmt: "ip:%lx vma:%lx-%lx address:%lx", REC->caller, REC->vm_start, REC->vm_end, REC->address
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_vma_notsup/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_vma_notsup/format
new file mode 100644
index 000000000..81c882eb9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagefault/spf_vma_notsup/format
@@ -0,0 +1,14 @@
+name: spf_vma_notsup
+ID: 281
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long caller; offset:8; size:8; signed:0;
+ field:unsigned long vm_start; offset:16; size:8; signed:0;
+ field:unsigned long vm_end; offset:24; size:8; signed:0;
+ field:unsigned long address; offset:32; size:8; signed:0;
+
+print fmt: "ip:%lx vma:%lx-%lx address:%lx", REC->caller, REC->vm_start, REC->vm_end, REC->address
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagemap/mm_lru_activate/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagemap/mm_lru_activate/format
new file mode 100644
index 000000000..32c7f277e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagemap/mm_lru_activate/format
@@ -0,0 +1,12 @@
+name: mm_lru_activate
+ID: 224
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct page * page; offset:8; size:8; signed:0;
+ field:unsigned long pfn; offset:16; size:8; signed:0;
+
+print fmt: "page=%p pfn=%lu", REC->page, REC->pfn
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagemap/mm_lru_insertion/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagemap/mm_lru_insertion/format
new file mode 100644
index 000000000..aa340d56c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pagemap/mm_lru_insertion/format
@@ -0,0 +1,14 @@
+name: mm_lru_insertion
+ID: 225
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct page * page; offset:8; size:8; signed:0;
+ field:unsigned long pfn; offset:16; size:8; signed:0;
+ field:int lru; offset:24; size:4; signed:1;
+ field:unsigned long flags; offset:32; size:8; signed:0;
+
+print fmt: "page=%p pfn=%lu lru=%d flags=%s%s%s%s%s%s", REC->page, REC->pfn, REC->lru, REC->flags & 0x0001u ? "M" : " ", REC->flags & 0x0002u ? "a" : "f", REC->flags & 0x0008u ? "s" : " ", REC->flags & 0x0010u ? "b" : " ", REC->flags & 0x0020u ? "d" : " ", REC->flags & 0x0040u ? "B" : " "
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/percpu/percpu_alloc_percpu/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/percpu/percpu_alloc_percpu/format
new file mode 100644
index 000000000..e39417d36
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/percpu/percpu_alloc_percpu/format
@@ -0,0 +1,17 @@
+name: percpu_alloc_percpu
+ID: 244
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:bool reserved; offset:8; size:1; signed:0;
+ field:bool is_atomic; offset:9; size:1; signed:0;
+ field:size_t size; offset:16; size:8; signed:0;
+ field:size_t align; offset:24; size:8; signed:0;
+ field:void * base_addr; offset:32; size:8; signed:0;
+ field:int off; offset:40; size:4; signed:1;
+ field:void * ptr; offset:48; size:8; signed:0;
+
+print fmt: "reserved=%d is_atomic=%d size=%zu align=%zu base_addr=%p off=%d ptr=%p", REC->reserved, REC->is_atomic, REC->size, REC->align, REC->base_addr, REC->off, REC->ptr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/percpu/percpu_alloc_percpu_fail/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/percpu/percpu_alloc_percpu_fail/format
new file mode 100644
index 000000000..71e934d03
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/percpu/percpu_alloc_percpu_fail/format
@@ -0,0 +1,14 @@
+name: percpu_alloc_percpu_fail
+ID: 245
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:bool reserved; offset:8; size:1; signed:0;
+ field:bool is_atomic; offset:9; size:1; signed:0;
+ field:size_t size; offset:16; size:8; signed:0;
+ field:size_t align; offset:24; size:8; signed:0;
+
+print fmt: "reserved=%d is_atomic=%d size=%zu align=%zu", REC->reserved, REC->is_atomic, REC->size, REC->align
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/percpu/percpu_create_chunk/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/percpu/percpu_create_chunk/format
new file mode 100644
index 000000000..2142eb363
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/percpu/percpu_create_chunk/format
@@ -0,0 +1,11 @@
+name: percpu_create_chunk
+ID: 246
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * base_addr; offset:8; size:8; signed:0;
+
+print fmt: "base_addr=%p", REC->base_addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/percpu/percpu_destroy_chunk/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/percpu/percpu_destroy_chunk/format
new file mode 100644
index 000000000..2bf8e4c71
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/percpu/percpu_destroy_chunk/format
@@ -0,0 +1,11 @@
+name: percpu_destroy_chunk
+ID: 247
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * base_addr; offset:8; size:8; signed:0;
+
+print fmt: "base_addr=%p", REC->base_addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/percpu/percpu_free_percpu/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/percpu/percpu_free_percpu/format
new file mode 100644
index 000000000..e88fcc7f3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/percpu/percpu_free_percpu/format
@@ -0,0 +1,13 @@
+name: percpu_free_percpu
+ID: 248
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * base_addr; offset:8; size:8; signed:0;
+ field:int off; offset:16; size:4; signed:1;
+ field:void * ptr; offset:24; size:8; signed:0;
+
+print fmt: "base_addr=%p off=%d ptr=%p", REC->base_addr, REC->off, REC->ptr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/clock_disable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/clock_disable/format
new file mode 100644
index 000000000..042204c86
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/clock_disable/format
@@ -0,0 +1,13 @@
+name: clock_disable
+ID: 170
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:u64 state; offset:16; size:8; signed:0;
+ field:u64 cpu_id; offset:24; size:8; signed:0;
+
+print fmt: "%s state=%lu cpu_id=%lu", __get_str(name), (unsigned long)REC->state, (unsigned long)REC->cpu_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/clock_enable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/clock_enable/format
new file mode 100644
index 000000000..7924d26c6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/clock_enable/format
@@ -0,0 +1,13 @@
+name: clock_enable
+ID: 171
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:u64 state; offset:16; size:8; signed:0;
+ field:u64 cpu_id; offset:24; size:8; signed:0;
+
+print fmt: "%s state=%lu cpu_id=%lu", __get_str(name), (unsigned long)REC->state, (unsigned long)REC->cpu_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/clock_set_rate/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/clock_set_rate/format
new file mode 100644
index 000000000..43547546f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/clock_set_rate/format
@@ -0,0 +1,13 @@
+name: clock_set_rate
+ID: 172
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:u64 state; offset:16; size:8; signed:0;
+ field:u64 cpu_id; offset:24; size:8; signed:0;
+
+print fmt: "%s state=%lu cpu_id=%lu", __get_str(name), (unsigned long)REC->state, (unsigned long)REC->cpu_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/cpu_frequency/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/cpu_frequency/format
new file mode 100644
index 000000000..bf0da8cc0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/cpu_frequency/format
@@ -0,0 +1,12 @@
+name: cpu_frequency
+ID: 173
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 state; offset:8; size:4; signed:0;
+ field:u32 cpu_id; offset:12; size:4; signed:0;
+
+print fmt: "state=%lu cpu_id=%lu", (unsigned long)REC->state, (unsigned long)REC->cpu_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/cpu_frequency_limits/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/cpu_frequency_limits/format
new file mode 100644
index 000000000..15a45b0f5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/cpu_frequency_limits/format
@@ -0,0 +1,13 @@
+name: cpu_frequency_limits
+ID: 174
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 min_freq; offset:8; size:4; signed:0;
+ field:u32 max_freq; offset:12; size:4; signed:0;
+ field:u32 cpu_id; offset:16; size:4; signed:0;
+
+print fmt: "min=%lu max=%lu cpu_id=%lu", (unsigned long)REC->min_freq, (unsigned long)REC->max_freq, (unsigned long)REC->cpu_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/cpu_idle/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/cpu_idle/format
new file mode 100644
index 000000000..440667200
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/cpu_idle/format
@@ -0,0 +1,12 @@
+name: cpu_idle
+ID: 175
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 state; offset:8; size:4; signed:0;
+ field:u32 cpu_id; offset:12; size:4; signed:0;
+
+print fmt: "state=%lu cpu_id=%lu", (unsigned long)REC->state, (unsigned long)REC->cpu_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/dev_pm_qos_add_request/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/dev_pm_qos_add_request/format
new file mode 100644
index 000000000..e9073b468
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/dev_pm_qos_add_request/format
@@ -0,0 +1,13 @@
+name: dev_pm_qos_add_request
+ID: 176
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:enum dev_pm_qos_req_type type; offset:12; size:4; signed:0;
+ field:s32 new_value; offset:16; size:4; signed:1;
+
+print fmt: "device=%s type=%s new_value=%d", __get_str(name), __print_symbolic(REC->type, { DEV_PM_QOS_RESUME_LATENCY, "DEV_PM_QOS_RESUME_LATENCY" }, { DEV_PM_QOS_FLAGS, "DEV_PM_QOS_FLAGS" }), REC->new_value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/dev_pm_qos_remove_request/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/dev_pm_qos_remove_request/format
new file mode 100644
index 000000000..6e027ef45
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/dev_pm_qos_remove_request/format
@@ -0,0 +1,13 @@
+name: dev_pm_qos_remove_request
+ID: 177
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:enum dev_pm_qos_req_type type; offset:12; size:4; signed:0;
+ field:s32 new_value; offset:16; size:4; signed:1;
+
+print fmt: "device=%s type=%s new_value=%d", __get_str(name), __print_symbolic(REC->type, { DEV_PM_QOS_RESUME_LATENCY, "DEV_PM_QOS_RESUME_LATENCY" }, { DEV_PM_QOS_FLAGS, "DEV_PM_QOS_FLAGS" }), REC->new_value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/dev_pm_qos_update_request/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/dev_pm_qos_update_request/format
new file mode 100644
index 000000000..c1a5a92ae
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/dev_pm_qos_update_request/format
@@ -0,0 +1,13 @@
+name: dev_pm_qos_update_request
+ID: 178
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:enum dev_pm_qos_req_type type; offset:12; size:4; signed:0;
+ field:s32 new_value; offset:16; size:4; signed:1;
+
+print fmt: "device=%s type=%s new_value=%d", __get_str(name), __print_symbolic(REC->type, { DEV_PM_QOS_RESUME_LATENCY, "DEV_PM_QOS_RESUME_LATENCY" }, { DEV_PM_QOS_FLAGS, "DEV_PM_QOS_FLAGS" }), REC->new_value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/device_pm_callback_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/device_pm_callback_end/format
new file mode 100644
index 000000000..ee35b2312
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/device_pm_callback_end/format
@@ -0,0 +1,13 @@
+name: device_pm_callback_end
+ID: 179
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] device; offset:8; size:4; signed:0;
+ field:__data_loc char[] driver; offset:12; size:4; signed:0;
+ field:int error; offset:16; size:4; signed:1;
+
+print fmt: "%s %s, err=%d", __get_str(driver), __get_str(device), REC->error
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/device_pm_callback_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/device_pm_callback_start/format
new file mode 100644
index 000000000..d37af3697
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/device_pm_callback_start/format
@@ -0,0 +1,15 @@
+name: device_pm_callback_start
+ID: 180
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] device; offset:8; size:4; signed:0;
+ field:__data_loc char[] driver; offset:12; size:4; signed:0;
+ field:__data_loc char[] parent; offset:16; size:4; signed:0;
+ field:__data_loc char[] pm_ops; offset:20; size:4; signed:0;
+ field:int event; offset:24; size:4; signed:1;
+
+print fmt: "%s %s, parent: %s, %s[%s]", __get_str(driver), __get_str(device), __get_str(parent), __get_str(pm_ops), __print_symbolic(REC->event, { 0x0002, "suspend" }, { 0x0010, "resume" }, { 0x0001, "freeze" }, { 0x0008, "quiesce" }, { 0x0004, "hibernate" }, { 0x0020, "thaw" }, { 0x0040, "restore" }, { 0x0080, "recover" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/gpu_frequency/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/gpu_frequency/format
new file mode 100644
index 000000000..3f6225c16
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/gpu_frequency/format
@@ -0,0 +1,12 @@
+name: gpu_frequency
+ID: 1239
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 state; offset:8; size:4; signed:0;
+ field:u32 gpu_id; offset:12; size:4; signed:0;
+
+print fmt: "state=%lu gpu_id=%lu", (unsigned long)REC->state, (unsigned long)REC->gpu_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/memlat_dev_meas/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/memlat_dev_meas/format
new file mode 100644
index 000000000..e4a57e785
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/memlat_dev_meas/format
@@ -0,0 +1,17 @@
+name: memlat_dev_meas
+ID: 1115
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int dev_id; offset:12; size:4; signed:0;
+ field:unsigned long inst; offset:16; size:8; signed:0;
+ field:unsigned long mem; offset:24; size:8; signed:0;
+ field:unsigned long freq; offset:32; size:8; signed:0;
+ field:unsigned int stall; offset:40; size:4; signed:0;
+ field:unsigned int ratio; offset:44; size:4; signed:0;
+
+print fmt: "dev: %s, id=%u, inst=%lu, mem=%lu, freq=%lu, stall=%u, ratio=%u", __get_str(name), REC->dev_id, REC->inst, REC->mem, REC->freq, REC->stall, REC->ratio
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/memlat_dev_update/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/memlat_dev_update/format
new file mode 100644
index 000000000..cd46dc196
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/memlat_dev_update/format
@@ -0,0 +1,16 @@
+name: memlat_dev_update
+ID: 1116
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int dev_id; offset:12; size:4; signed:0;
+ field:unsigned long inst; offset:16; size:8; signed:0;
+ field:unsigned long mem; offset:24; size:8; signed:0;
+ field:unsigned long freq; offset:32; size:8; signed:0;
+ field:unsigned long vote; offset:40; size:8; signed:0;
+
+print fmt: "dev: %s, id=%u, inst=%lu, mem=%lu, freq=%lu, vote=%lu", __get_str(name), REC->dev_id, REC->inst, REC->mem, REC->freq, REC->vote
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pm_qos_add_request/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pm_qos_add_request/format
new file mode 100644
index 000000000..6da2cb71b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pm_qos_add_request/format
@@ -0,0 +1,11 @@
+name: pm_qos_add_request
+ID: 181
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:s32 value; offset:8; size:4; signed:1;
+
+print fmt: "CPU_DMA_LATENCY value=%d", REC->value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pm_qos_remove_request/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pm_qos_remove_request/format
new file mode 100644
index 000000000..e07d1149a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pm_qos_remove_request/format
@@ -0,0 +1,11 @@
+name: pm_qos_remove_request
+ID: 182
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:s32 value; offset:8; size:4; signed:1;
+
+print fmt: "CPU_DMA_LATENCY value=%d", REC->value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pm_qos_update_flags/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pm_qos_update_flags/format
new file mode 100644
index 000000000..2011627b5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pm_qos_update_flags/format
@@ -0,0 +1,13 @@
+name: pm_qos_update_flags
+ID: 183
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum pm_qos_req_action action; offset:8; size:4; signed:0;
+ field:int prev_value; offset:12; size:4; signed:1;
+ field:int curr_value; offset:16; size:4; signed:1;
+
+print fmt: "action=%s prev_value=0x%x curr_value=0x%x", __print_symbolic(REC->action, { PM_QOS_ADD_REQ, "ADD_REQ" }, { PM_QOS_UPDATE_REQ, "UPDATE_REQ" }, { PM_QOS_REMOVE_REQ, "REMOVE_REQ" }), REC->prev_value, REC->curr_value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pm_qos_update_request/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pm_qos_update_request/format
new file mode 100644
index 000000000..e27fa99d6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pm_qos_update_request/format
@@ -0,0 +1,11 @@
+name: pm_qos_update_request
+ID: 184
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:s32 value; offset:8; size:4; signed:1;
+
+print fmt: "CPU_DMA_LATENCY value=%d", REC->value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pm_qos_update_target/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pm_qos_update_target/format
new file mode 100644
index 000000000..c0924c6bd
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pm_qos_update_target/format
@@ -0,0 +1,13 @@
+name: pm_qos_update_target
+ID: 185
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:enum pm_qos_req_action action; offset:8; size:4; signed:0;
+ field:int prev_value; offset:12; size:4; signed:1;
+ field:int curr_value; offset:16; size:4; signed:1;
+
+print fmt: "action=%s prev_value=%d curr_value=%d", __print_symbolic(REC->action, { PM_QOS_ADD_REQ, "ADD_REQ" }, { PM_QOS_UPDATE_REQ, "UPDATE_REQ" }, { PM_QOS_REMOVE_REQ, "REMOVE_REQ" }), REC->prev_value, REC->curr_value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/power_domain_target/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/power_domain_target/format
new file mode 100644
index 000000000..a33688a90
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/power_domain_target/format
@@ -0,0 +1,13 @@
+name: power_domain_target
+ID: 186
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:u64 state; offset:16; size:8; signed:0;
+ field:u64 cpu_id; offset:24; size:8; signed:0;
+
+print fmt: "%s state=%lu cpu_id=%lu", __get_str(name), (unsigned long)REC->state, (unsigned long)REC->cpu_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/powernv_throttle/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/powernv_throttle/format
new file mode 100644
index 000000000..699b67d16
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/powernv_throttle/format
@@ -0,0 +1,13 @@
+name: powernv_throttle
+ID: 187
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int chip_id; offset:8; size:4; signed:1;
+ field:__data_loc char[] reason; offset:12; size:4; signed:0;
+ field:int pmax; offset:16; size:4; signed:1;
+
+print fmt: "Chip %d Pmax %d %s", REC->chip_id, REC->pmax, __get_str(reason)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pstate_sample/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pstate_sample/format
new file mode 100644
index 000000000..ed3bb8c08
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/pstate_sample/format
@@ -0,0 +1,19 @@
+name: pstate_sample
+ID: 188
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 core_busy; offset:8; size:4; signed:0;
+ field:u32 scaled_busy; offset:12; size:4; signed:0;
+ field:u32 from; offset:16; size:4; signed:0;
+ field:u32 to; offset:20; size:4; signed:0;
+ field:u64 mperf; offset:24; size:8; signed:0;
+ field:u64 aperf; offset:32; size:8; signed:0;
+ field:u64 tsc; offset:40; size:8; signed:0;
+ field:u32 freq; offset:48; size:4; signed:0;
+ field:u32 io_boost; offset:52; size:4; signed:0;
+
+print fmt: "core_busy=%lu scaled=%lu from=%lu to=%lu mperf=%llu aperf=%llu tsc=%llu freq=%lu io_boost=%lu", (unsigned long)REC->core_busy, (unsigned long)REC->scaled_busy, (unsigned long)REC->from, (unsigned long)REC->to, (unsigned long long)REC->mperf, (unsigned long long)REC->aperf, (unsigned long long)REC->tsc, (unsigned long)REC->freq, (unsigned long)REC->io_boost
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/suspend_resume/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/suspend_resume/format
new file mode 100644
index 000000000..0fadf5f90
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/suspend_resume/format
@@ -0,0 +1,13 @@
+name: suspend_resume
+ID: 189
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * action; offset:8; size:8; signed:0;
+ field:int val; offset:16; size:4; signed:1;
+ field:bool start; offset:20; size:1; signed:0;
+
+print fmt: "%s[%u] %s", REC->action, (unsigned int)REC->val, (REC->start)?"begin":"end"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/wakeup_source_activate/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/wakeup_source_activate/format
new file mode 100644
index 000000000..c31a981ba
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/wakeup_source_activate/format
@@ -0,0 +1,12 @@
+name: wakeup_source_activate
+ID: 190
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:u64 state; offset:16; size:8; signed:0;
+
+print fmt: "%s state=0x%lx", __get_str(name), (unsigned long)REC->state
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/wakeup_source_deactivate/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/wakeup_source_deactivate/format
new file mode 100644
index 000000000..e1eb9cc57
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/power/wakeup_source_deactivate/format
@@ -0,0 +1,12 @@
+name: wakeup_source_deactivate
+ID: 191
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:u64 state; offset:16; size:8; signed:0;
+
+print fmt: "%s state=0x%lx", __get_str(name), (unsigned long)REC->state
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/preemptirq_long/irq_disable_long/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/preemptirq_long/irq_disable_long/format
new file mode 100644
index 000000000..9ce687f83
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/preemptirq_long/irq_disable_long/format
@@ -0,0 +1,11 @@
+name: irq_disable_long
+ID: 1078
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 delta; offset:8; size:8; signed:0;
+
+print fmt: "delta=%llu(ns)", REC->delta
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/preemptirq_long/preempt_disable_long/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/preemptirq_long/preempt_disable_long/format
new file mode 100644
index 000000000..27b6eb836
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/preemptirq_long/preempt_disable_long/format
@@ -0,0 +1,11 @@
+name: preempt_disable_long
+ID: 1079
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 delta; offset:8; size:8; signed:0;
+
+print fmt: "delta=%llu(ns)", REC->delta
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/printk/console/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/printk/console/format
new file mode 100644
index 000000000..303a8cb90
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/printk/console/format
@@ -0,0 +1,11 @@
+name: console
+ID: 109
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] msg; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(msg)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pt/pt_driver_log/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pt/pt_driver_log/format
new file mode 100644
index 000000000..d68e13a5b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pt/pt_driver_log/format
@@ -0,0 +1,20 @@
+name: pt_driver_log
+ID: 1082
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * driver_name; offset:8; size:8; signed:0;
+ field:const char * fn_name; offset:16; size:8; signed:0;
+ field:u64 arg0; offset:24; size:8; signed:0;
+ field:u64 arg1; offset:32; size:8; signed:0;
+ field:u64 arg2; offset:40; size:8; signed:0;
+ field:u64 arg3; offset:48; size:8; signed:0;
+ field:int ret; offset:56; size:4; signed:1;
+ field:u64 sec_ret0; offset:64; size:8; signed:0;
+ field:u64 sec_ret1; offset:72; size:8; signed:0;
+ field:u64 sec_ret2; offset:80; size:8; signed:0;
+
+print fmt: "PT: %s %s 0x%llx 0x%llx 0x%llx 0x%llx ret: 0x%x, sec_ret0: 0x%llx, sec_ret1: 0x%llx, sec_ret2: 0x%llx", REC->driver_name, REC->fn_name, REC->arg0, REC->arg1, REC->arg2, REC->arg3, REC->ret, REC->sec_ret0, REC->sec_ret1, REC->sec_ret2
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pt/pt_enable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pt/pt_enable/format
new file mode 100644
index 000000000..2de0d17bf
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pt/pt_enable/format
@@ -0,0 +1,14 @@
+name: pt_enable
+ID: 1083
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * node_name; offset:8; size:8; signed:0;
+ field:const char * id_name; offset:16; size:8; signed:0;
+ field:bool enable; offset:24; size:1; signed:0;
+ field:u32 ptid; offset:28; size:4; signed:0;
+
+print fmt: "Node %s %s %s %d", REC->node_name, REC->id_name, REC->enable?"ENABLE":"DISABLE", (int)REC->ptid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pt/pt_resize_callback/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pt/pt_resize_callback/format
new file mode 100644
index 000000000..929684243
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pt/pt_resize_callback/format
@@ -0,0 +1,15 @@
+name: pt_resize_callback
+ID: 1084
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * node_name; offset:8; size:8; signed:0;
+ field:const char * id_name; offset:16; size:8; signed:0;
+ field:bool enter; offset:24; size:1; signed:0;
+ field:u64 size; offset:32; size:8; signed:0;
+ field:u32 ptid; offset:40; size:4; signed:0;
+
+print fmt: "Node %s %s %s 0x%llx ptid %d", REC->node_name, REC->id_name, REC->enter?"ENTER":"EXIT", REC->size, (int)REC->ptid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pwm/pwm_apply/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pwm/pwm_apply/format
new file mode 100644
index 000000000..284fddde3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pwm/pwm_apply/format
@@ -0,0 +1,15 @@
+name: pwm_apply
+ID: 615
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct pwm_device * pwm; offset:8; size:8; signed:0;
+ field:u64 period; offset:16; size:8; signed:0;
+ field:u64 duty_cycle; offset:24; size:8; signed:0;
+ field:enum pwm_polarity polarity; offset:32; size:4; signed:0;
+ field:bool enabled; offset:36; size:1; signed:0;
+
+print fmt: "%p: period=%llu duty_cycle=%llu polarity=%d enabled=%d", REC->pwm, REC->period, REC->duty_cycle, REC->polarity, REC->enabled
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pwm/pwm_get/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pwm/pwm_get/format
new file mode 100644
index 000000000..5a49491ee
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/pwm/pwm_get/format
@@ -0,0 +1,15 @@
+name: pwm_get
+ID: 616
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct pwm_device * pwm; offset:8; size:8; signed:0;
+ field:u64 period; offset:16; size:8; signed:0;
+ field:u64 duty_cycle; offset:24; size:8; signed:0;
+ field:enum pwm_polarity polarity; offset:32; size:4; signed:0;
+ field:bool enabled; offset:36; size:1; signed:0;
+
+print fmt: "%p: period=%llu duty_cycle=%llu polarity=%d enabled=%d", REC->pwm, REC->period, REC->duty_cycle, REC->polarity, REC->enabled
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/qdisc/qdisc_create/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/qdisc/qdisc_create/format
new file mode 100644
index 000000000..1e7e657f6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/qdisc/qdisc_create/format
@@ -0,0 +1,13 @@
+name: qdisc_create
+ID: 956
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] dev; offset:8; size:4; signed:0;
+ field:__data_loc char[] kind; offset:12; size:4; signed:0;
+ field:u32 parent; offset:16; size:4; signed:0;
+
+print fmt: "dev=%s kind=%s parent=%x:%x", __get_str(dev), __get_str(kind), ((REC->parent)&(0xFFFF0000U)) >> 16, ((REC->parent)&(0x0000FFFFU))
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/qdisc/qdisc_dequeue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/qdisc/qdisc_dequeue/format
new file mode 100644
index 000000000..06a1345fe
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/qdisc/qdisc_dequeue/format
@@ -0,0 +1,18 @@
+name: qdisc_dequeue
+ID: 957
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct Qdisc * qdisc; offset:8; size:8; signed:0;
+ field:const struct netdev_queue * txq; offset:16; size:8; signed:0;
+ field:int packets; offset:24; size:4; signed:1;
+ field:void * skbaddr; offset:32; size:8; signed:0;
+ field:int ifindex; offset:40; size:4; signed:1;
+ field:u32 handle; offset:44; size:4; signed:0;
+ field:u32 parent; offset:48; size:4; signed:0;
+ field:unsigned long txq_state; offset:56; size:8; signed:0;
+
+print fmt: "dequeue ifindex=%d qdisc handle=0x%X parent=0x%X txq_state=0x%lX packets=%d skbaddr=%p", REC->ifindex, REC->handle, REC->parent, REC->txq_state, REC->packets, REC->skbaddr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/qdisc/qdisc_destroy/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/qdisc/qdisc_destroy/format
new file mode 100644
index 000000000..983469b39
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/qdisc/qdisc_destroy/format
@@ -0,0 +1,14 @@
+name: qdisc_destroy
+ID: 958
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] dev; offset:8; size:4; signed:0;
+ field:__data_loc char[] kind; offset:12; size:4; signed:0;
+ field:u32 parent; offset:16; size:4; signed:0;
+ field:u32 handle; offset:20; size:4; signed:0;
+
+print fmt: "dev=%s kind=%s parent=%x:%x handle=%x:%x", __get_str(dev), __get_str(kind), ((REC->parent)&(0xFFFF0000U)) >> 16, ((REC->parent)&(0x0000FFFFU)), ((REC->handle)&(0xFFFF0000U)) >> 16, ((REC->handle)&(0x0000FFFFU))
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/qdisc/qdisc_reset/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/qdisc/qdisc_reset/format
new file mode 100644
index 000000000..07618435b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/qdisc/qdisc_reset/format
@@ -0,0 +1,14 @@
+name: qdisc_reset
+ID: 959
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] dev; offset:8; size:4; signed:0;
+ field:__data_loc char[] kind; offset:12; size:4; signed:0;
+ field:u32 parent; offset:16; size:4; signed:0;
+ field:u32 handle; offset:20; size:4; signed:0;
+
+print fmt: "dev=%s kind=%s parent=%x:%x handle=%x:%x", __get_str(dev), __get_str(kind), ((REC->parent)&(0xFFFF0000U)) >> 16, ((REC->parent)&(0x0000FFFFU)), ((REC->handle)&(0xFFFF0000U)) >> 16, ((REC->handle)&(0x0000FFFFU))
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/add_device_randomness/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/add_device_randomness/format
new file mode 100644
index 000000000..7a7583e8b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/add_device_randomness/format
@@ -0,0 +1,12 @@
+name: add_device_randomness
+ID: 644
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int bytes; offset:8; size:4; signed:1;
+ field:unsigned long IP; offset:16; size:8; signed:0;
+
+print fmt: "bytes %d caller %pS", REC->bytes, (void *)REC->IP
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/add_disk_randomness/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/add_disk_randomness/format
new file mode 100644
index 000000000..6717f048f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/add_disk_randomness/format
@@ -0,0 +1,12 @@
+name: add_disk_randomness
+ID: 645
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:int input_bits; offset:12; size:4; signed:1;
+
+print fmt: "dev %d,%d input_pool_bits %d", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->input_bits
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/add_input_randomness/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/add_input_randomness/format
new file mode 100644
index 000000000..e5e2a698a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/add_input_randomness/format
@@ -0,0 +1,11 @@
+name: add_input_randomness
+ID: 646
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int input_bits; offset:8; size:4; signed:1;
+
+print fmt: "input_pool_bits %d", REC->input_bits
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/credit_entropy_bits/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/credit_entropy_bits/format
new file mode 100644
index 000000000..e49d18b35
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/credit_entropy_bits/format
@@ -0,0 +1,14 @@
+name: credit_entropy_bits
+ID: 647
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * pool_name; offset:8; size:8; signed:0;
+ field:int bits; offset:16; size:4; signed:1;
+ field:int entropy_count; offset:20; size:4; signed:1;
+ field:unsigned long IP; offset:24; size:8; signed:0;
+
+print fmt: "%s pool: bits %d entropy_count %d caller %pS", REC->pool_name, REC->bits, REC->entropy_count, (void *)REC->IP
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/debit_entropy/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/debit_entropy/format
new file mode 100644
index 000000000..c8bc8def1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/debit_entropy/format
@@ -0,0 +1,12 @@
+name: debit_entropy
+ID: 648
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * pool_name; offset:8; size:8; signed:0;
+ field:int debit_bits; offset:16; size:4; signed:1;
+
+print fmt: "%s: debit_bits %d", REC->pool_name, REC->debit_bits
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/extract_entropy/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/extract_entropy/format
new file mode 100644
index 000000000..da69521a6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/extract_entropy/format
@@ -0,0 +1,14 @@
+name: extract_entropy
+ID: 649
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * pool_name; offset:8; size:8; signed:0;
+ field:int nbytes; offset:16; size:4; signed:1;
+ field:int entropy_count; offset:20; size:4; signed:1;
+ field:unsigned long IP; offset:24; size:8; signed:0;
+
+print fmt: "%s pool: nbytes %d entropy_count %d caller %pS", REC->pool_name, REC->nbytes, REC->entropy_count, (void *)REC->IP
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/extract_entropy_user/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/extract_entropy_user/format
new file mode 100644
index 000000000..41018101f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/extract_entropy_user/format
@@ -0,0 +1,14 @@
+name: extract_entropy_user
+ID: 650
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * pool_name; offset:8; size:8; signed:0;
+ field:int nbytes; offset:16; size:4; signed:1;
+ field:int entropy_count; offset:20; size:4; signed:1;
+ field:unsigned long IP; offset:24; size:8; signed:0;
+
+print fmt: "%s pool: nbytes %d entropy_count %d caller %pS", REC->pool_name, REC->nbytes, REC->entropy_count, (void *)REC->IP
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/get_random_bytes/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/get_random_bytes/format
new file mode 100644
index 000000000..30ef01827
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/get_random_bytes/format
@@ -0,0 +1,12 @@
+name: get_random_bytes
+ID: 651
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int nbytes; offset:8; size:4; signed:1;
+ field:unsigned long IP; offset:16; size:8; signed:0;
+
+print fmt: "nbytes %d caller %pS", REC->nbytes, (void *)REC->IP
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/get_random_bytes_arch/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/get_random_bytes_arch/format
new file mode 100644
index 000000000..67215652a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/get_random_bytes_arch/format
@@ -0,0 +1,12 @@
+name: get_random_bytes_arch
+ID: 652
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int nbytes; offset:8; size:4; signed:1;
+ field:unsigned long IP; offset:16; size:8; signed:0;
+
+print fmt: "nbytes %d caller %pS", REC->nbytes, (void *)REC->IP
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/mix_pool_bytes/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/mix_pool_bytes/format
new file mode 100644
index 000000000..1c8c9ffa6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/mix_pool_bytes/format
@@ -0,0 +1,13 @@
+name: mix_pool_bytes
+ID: 653
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * pool_name; offset:8; size:8; signed:0;
+ field:int bytes; offset:16; size:4; signed:1;
+ field:unsigned long IP; offset:24; size:8; signed:0;
+
+print fmt: "%s pool: bytes %d caller %pS", REC->pool_name, REC->bytes, (void *)REC->IP
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/mix_pool_bytes_nolock/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/mix_pool_bytes_nolock/format
new file mode 100644
index 000000000..97d0b4334
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/mix_pool_bytes_nolock/format
@@ -0,0 +1,13 @@
+name: mix_pool_bytes_nolock
+ID: 654
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * pool_name; offset:8; size:8; signed:0;
+ field:int bytes; offset:16; size:4; signed:1;
+ field:unsigned long IP; offset:24; size:8; signed:0;
+
+print fmt: "%s pool: bytes %d caller %pS", REC->pool_name, REC->bytes, (void *)REC->IP
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/prandom_u32/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/prandom_u32/format
new file mode 100644
index 000000000..9831719b2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/prandom_u32/format
@@ -0,0 +1,11 @@
+name: prandom_u32
+ID: 655
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int ret; offset:8; size:4; signed:0;
+
+print fmt: "ret=%u", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/push_to_pool/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/push_to_pool/format
new file mode 100644
index 000000000..b6d38aa41
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/push_to_pool/format
@@ -0,0 +1,13 @@
+name: push_to_pool
+ID: 656
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * pool_name; offset:8; size:8; signed:0;
+ field:int pool_bits; offset:16; size:4; signed:1;
+ field:int input_bits; offset:20; size:4; signed:1;
+
+print fmt: "%s: pool_bits %d input_pool_bits %d", REC->pool_name, REC->pool_bits, REC->input_bits
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/random_read/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/random_read/format
new file mode 100644
index 000000000..45d67dcde
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/random_read/format
@@ -0,0 +1,14 @@
+name: random_read
+ID: 657
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int got_bits; offset:8; size:4; signed:1;
+ field:int need_bits; offset:12; size:4; signed:1;
+ field:int pool_left; offset:16; size:4; signed:1;
+ field:int input_left; offset:20; size:4; signed:1;
+
+print fmt: "got_bits %d still_needed_bits %d blocking_pool_entropy_left %d input_entropy_left %d", REC->got_bits, REC->got_bits, REC->pool_left, REC->input_left
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/urandom_read/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/urandom_read/format
new file mode 100644
index 000000000..34d70d42b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/urandom_read/format
@@ -0,0 +1,13 @@
+name: urandom_read
+ID: 658
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int got_bits; offset:8; size:4; signed:1;
+ field:int pool_left; offset:12; size:4; signed:1;
+ field:int input_left; offset:16; size:4; signed:1;
+
+print fmt: "got_bits %d nonblocking_pool_entropy_left %d input_entropy_left %d", REC->got_bits, REC->pool_left, REC->input_left
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/xfer_secondary_pool/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/xfer_secondary_pool/format
new file mode 100644
index 000000000..fdaef938e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/random/xfer_secondary_pool/format
@@ -0,0 +1,15 @@
+name: xfer_secondary_pool
+ID: 659
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * pool_name; offset:8; size:8; signed:0;
+ field:int xfer_bits; offset:16; size:4; signed:1;
+ field:int request_bits; offset:20; size:4; signed:1;
+ field:int pool_entropy; offset:24; size:4; signed:1;
+ field:int input_entropy; offset:28; size:4; signed:1;
+
+print fmt: "pool %s xfer_bits %d request_bits %d pool_entropy %d input_entropy %d", REC->pool_name, REC->xfer_bits, REC->request_bits, REC->pool_entropy, REC->input_entropy
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ras/aer_event/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ras/aer_event/format
new file mode 100644
index 000000000..fcd53e2d5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ras/aer_event/format
@@ -0,0 +1,16 @@
+name: aer_event
+ID: 867
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] dev_name; offset:8; size:4; signed:0;
+ field:u32 status; offset:12; size:4; signed:0;
+ field:u8 severity; offset:16; size:1; signed:0;
+ field:u8 tlp_header_valid; offset:17; size:1; signed:0;
+ field:u32 tlp_header[4]; offset:20; size:16; signed:0;
+
+print fmt: "%s PCIe Bus Error: severity=%s, %s, TLP Header=%s
+", __get_str(dev_name), REC->severity == 2 ? "Corrected" : REC->severity == 1 ? "Fatal" : "Uncorrected, non-fatal", REC->severity == 2 ? __print_flags(REC->status, "|", {0x00000001, "Receiver Error"}, {0x00000040, "Bad TLP"}, {0x00000080, "Bad DLLP"}, {0x00000100, "RELAY_NUM Rollover"}, {0x00001000, "Replay Timer Timeout"}, {0x00002000, "Advisory Non-Fatal Error"}, {0x00004000, "Corrected Internal Error"}, {0x00008000, "Header Log Overflow"}) : __print_flags(REC->status, "|", {0x00000001, "Undefined"}, {0x00000010, "Data Link Protocol Error"}, {0x00000020, "Surprise Down Error"}, {0x00001000,"Poisoned TLP"}, {0x00002000, "Flow Control Protocol Error"}, {0x00004000, "Completion Timeout"}, {0x00008000,"Completer Abort"}, {0x00010000, "Unexpected Completion"}, {0x00020000, "Receiver Overflow"}, {0x00040000, "Malformed TLP"}, {0x00080000, "ECRC Error"}, {0x00100000, "Unsupported Request Error"}, {0x00200000, "ACS Violation"}, {0x00400000, "Uncorrectable Internal Error"}, {0x00800000, "MC Blocked TLP"}, {0x01000000, "AtomicOp Egress Blocked"}, {0x02000000, "TLP Prefix Blocked Error"}), REC->tlp_header_valid ? __print_array(REC->tlp_header, 4, 4) : "Not available"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ras/arm_event/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ras/arm_event/format
new file mode 100644
index 000000000..66540923c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ras/arm_event/format
@@ -0,0 +1,15 @@
+name: arm_event
+ID: 868
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 mpidr; offset:8; size:8; signed:0;
+ field:u64 midr; offset:16; size:8; signed:0;
+ field:u32 running_state; offset:24; size:4; signed:0;
+ field:u32 psci_state; offset:28; size:4; signed:0;
+ field:u8 affinity; offset:32; size:1; signed:0;
+
+print fmt: "affinity level: %d; MPIDR: %016llx; MIDR: %016llx; running state: %d; PSCI state: %d", REC->affinity, REC->mpidr, REC->midr, REC->running_state, REC->psci_state
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ras/mc_event/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ras/mc_event/format
new file mode 100644
index 000000000..1fc7d91b4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ras/mc_event/format
@@ -0,0 +1,22 @@
+name: mc_event
+ID: 869
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int error_type; offset:8; size:4; signed:0;
+ field:__data_loc char[] msg; offset:12; size:4; signed:0;
+ field:__data_loc char[] label; offset:16; size:4; signed:0;
+ field:u16 error_count; offset:20; size:2; signed:0;
+ field:u8 mc_index; offset:22; size:1; signed:0;
+ field:s8 top_layer; offset:23; size:1; signed:1;
+ field:s8 middle_layer; offset:24; size:1; signed:1;
+ field:s8 lower_layer; offset:25; size:1; signed:1;
+ field:long address; offset:32; size:8; signed:1;
+ field:u8 grain_bits; offset:40; size:1; signed:0;
+ field:long syndrome; offset:48; size:8; signed:1;
+ field:__data_loc char[] driver_detail; offset:56; size:4; signed:0;
+
+print fmt: "%d %s error%s:%s%s on %s (mc:%d location:%d:%d:%d address:0x%08lx grain:%d syndrome:0x%08lx%s%s)", REC->error_count, mc_event_error_type(REC->error_type), REC->error_count > 1 ? "s" : "", __get_str(msg)[0] ? " " : "", __get_str(msg), __get_str(label), REC->mc_index, REC->top_layer, REC->middle_layer, REC->lower_layer, REC->address, 1 << REC->grain_bits, REC->syndrome, __get_str(driver_detail)[0] ? " " : "", __get_str(driver_detail)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ras/non_standard_event/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ras/non_standard_event/format
new file mode 100644
index 000000000..057887e93
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ras/non_standard_event/format
@@ -0,0 +1,16 @@
+name: non_standard_event
+ID: 870
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char sec_type[16]; offset:8; size:16; signed:0;
+ field:char fru_id[16]; offset:24; size:16; signed:0;
+ field:__data_loc char[] fru_text; offset:40; size:4; signed:0;
+ field:u8 sev; offset:44; size:1; signed:0;
+ field:u32 len; offset:48; size:4; signed:0;
+ field:__data_loc u8[] buf; offset:52; size:4; signed:0;
+
+print fmt: "severity: %d; sec type:%pU; FRU: %pU %s; data len:%d; raw data:%s", REC->sev, REC->sec_type, REC->fru_id, __get_str(fru_text), REC->len, __print_hex(__get_dynamic_array(buf), REC->len)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/raw_syscalls/sys_enter/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/raw_syscalls/sys_enter/format
new file mode 100644
index 000000000..eacec9835
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/raw_syscalls/sys_enter/format
@@ -0,0 +1,12 @@
+name: sys_enter
+ID: 20
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:long id; offset:8; size:8; signed:1;
+ field:unsigned long args[6]; offset:16; size:48; signed:0;
+
+print fmt: "NR %ld (%lx, %lx, %lx, %lx, %lx, %lx)", REC->id, REC->args[0], REC->args[1], REC->args[2], REC->args[3], REC->args[4], REC->args[5]
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/raw_syscalls/sys_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/raw_syscalls/sys_exit/format
new file mode 100644
index 000000000..94b6d8542
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/raw_syscalls/sys_exit/format
@@ -0,0 +1,12 @@
+name: sys_exit
+ID: 21
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:long id; offset:8; size:8; signed:1;
+ field:long ret; offset:16; size:8; signed:1;
+
+print fmt: "NR %ld = %ld", REC->id, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_barrier/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_barrier/format
new file mode 100644
index 000000000..04ce46d99
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_barrier/format
@@ -0,0 +1,15 @@
+name: rcu_barrier
+ID: 110
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * rcuname; offset:8; size:8; signed:0;
+ field:const char * s; offset:16; size:8; signed:0;
+ field:int cpu; offset:24; size:4; signed:1;
+ field:int cnt; offset:28; size:4; signed:1;
+ field:unsigned long done; offset:32; size:8; signed:0;
+
+print fmt: "%s %s cpu %d remaining %d # %lu", REC->rcuname, REC->s, REC->cpu, REC->cnt, REC->done
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_batch_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_batch_end/format
new file mode 100644
index 000000000..dc55ff938
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_batch_end/format
@@ -0,0 +1,16 @@
+name: rcu_batch_end
+ID: 111
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * rcuname; offset:8; size:8; signed:0;
+ field:int callbacks_invoked; offset:16; size:4; signed:1;
+ field:char cb; offset:20; size:1; signed:0;
+ field:char nr; offset:21; size:1; signed:0;
+ field:char iit; offset:22; size:1; signed:0;
+ field:char risk; offset:23; size:1; signed:0;
+
+print fmt: "%s CBs-invoked=%d idle=%c%c%c%c", REC->rcuname, REC->callbacks_invoked, REC->cb ? 'C' : '.', REC->nr ? 'S' : '.', REC->iit ? 'I' : '.', REC->risk ? 'R' : '.'
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_batch_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_batch_start/format
new file mode 100644
index 000000000..ab61db16c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_batch_start/format
@@ -0,0 +1,13 @@
+name: rcu_batch_start
+ID: 112
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * rcuname; offset:8; size:8; signed:0;
+ field:long qlen; offset:16; size:8; signed:1;
+ field:long blimit; offset:24; size:8; signed:1;
+
+print fmt: "%s CBs=%ld bl=%ld", REC->rcuname, REC->qlen, REC->blimit
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_callback/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_callback/format
new file mode 100644
index 000000000..96f6ff84d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_callback/format
@@ -0,0 +1,14 @@
+name: rcu_callback
+ID: 113
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * rcuname; offset:8; size:8; signed:0;
+ field:void * rhp; offset:16; size:8; signed:0;
+ field:void * func; offset:24; size:8; signed:0;
+ field:long qlen; offset:32; size:8; signed:1;
+
+print fmt: "%s rhp=%p func=%ps %ld", REC->rcuname, REC->rhp, REC->func, REC->qlen
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_dyntick/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_dyntick/format
new file mode 100644
index 000000000..83128280d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_dyntick/format
@@ -0,0 +1,14 @@
+name: rcu_dyntick
+ID: 114
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * polarity; offset:8; size:8; signed:0;
+ field:long oldnesting; offset:16; size:8; signed:1;
+ field:long newnesting; offset:24; size:8; signed:1;
+ field:int dynticks; offset:32; size:4; signed:1;
+
+print fmt: "%s %lx %lx %#3x", REC->polarity, REC->oldnesting, REC->newnesting, REC->dynticks & 0xfff
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_exp_funnel_lock/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_exp_funnel_lock/format
new file mode 100644
index 000000000..0db175a27
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_exp_funnel_lock/format
@@ -0,0 +1,15 @@
+name: rcu_exp_funnel_lock
+ID: 115
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * rcuname; offset:8; size:8; signed:0;
+ field:u8 level; offset:16; size:1; signed:0;
+ field:int grplo; offset:20; size:4; signed:1;
+ field:int grphi; offset:24; size:4; signed:1;
+ field:const char * gpevent; offset:32; size:8; signed:0;
+
+print fmt: "%s %d %d %d %s", REC->rcuname, REC->level, REC->grplo, REC->grphi, REC->gpevent
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_exp_grace_period/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_exp_grace_period/format
new file mode 100644
index 000000000..428865520
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_exp_grace_period/format
@@ -0,0 +1,13 @@
+name: rcu_exp_grace_period
+ID: 116
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * rcuname; offset:8; size:8; signed:0;
+ field:long gpseq; offset:16; size:8; signed:1;
+ field:const char * gpevent; offset:24; size:8; signed:0;
+
+print fmt: "%s %ld %s", REC->rcuname, REC->gpseq, REC->gpevent
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_fqs/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_fqs/format
new file mode 100644
index 000000000..b3db01fc5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_fqs/format
@@ -0,0 +1,14 @@
+name: rcu_fqs
+ID: 117
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * rcuname; offset:8; size:8; signed:0;
+ field:long gp_seq; offset:16; size:8; signed:1;
+ field:int cpu; offset:24; size:4; signed:1;
+ field:const char * qsevent; offset:32; size:8; signed:0;
+
+print fmt: "%s %ld %d %s", REC->rcuname, REC->gp_seq, REC->cpu, REC->qsevent
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_future_grace_period/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_future_grace_period/format
new file mode 100644
index 000000000..133918a68
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_future_grace_period/format
@@ -0,0 +1,17 @@
+name: rcu_future_grace_period
+ID: 118
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * rcuname; offset:8; size:8; signed:0;
+ field:long gp_seq; offset:16; size:8; signed:1;
+ field:long gp_seq_req; offset:24; size:8; signed:1;
+ field:u8 level; offset:32; size:1; signed:0;
+ field:int grplo; offset:36; size:4; signed:1;
+ field:int grphi; offset:40; size:4; signed:1;
+ field:const char * gpevent; offset:48; size:8; signed:0;
+
+print fmt: "%s %ld %ld %u %d %d %s", REC->rcuname, (long)REC->gp_seq, (long)REC->gp_seq_req, REC->level, REC->grplo, REC->grphi, REC->gpevent
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_grace_period/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_grace_period/format
new file mode 100644
index 000000000..7f627fde4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_grace_period/format
@@ -0,0 +1,13 @@
+name: rcu_grace_period
+ID: 119
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * rcuname; offset:8; size:8; signed:0;
+ field:long gp_seq; offset:16; size:8; signed:1;
+ field:const char * gpevent; offset:24; size:8; signed:0;
+
+print fmt: "%s %ld %s", REC->rcuname, REC->gp_seq, REC->gpevent
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_grace_period_init/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_grace_period_init/format
new file mode 100644
index 000000000..ed917c8bf
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_grace_period_init/format
@@ -0,0 +1,16 @@
+name: rcu_grace_period_init
+ID: 120
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * rcuname; offset:8; size:8; signed:0;
+ field:long gp_seq; offset:16; size:8; signed:1;
+ field:u8 level; offset:24; size:1; signed:0;
+ field:int grplo; offset:28; size:4; signed:1;
+ field:int grphi; offset:32; size:4; signed:1;
+ field:unsigned long qsmask; offset:40; size:8; signed:0;
+
+print fmt: "%s %ld %u %d %d %lx", REC->rcuname, REC->gp_seq, REC->level, REC->grplo, REC->grphi, REC->qsmask
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_invoke_callback/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_invoke_callback/format
new file mode 100644
index 000000000..4cb4a47ea
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_invoke_callback/format
@@ -0,0 +1,13 @@
+name: rcu_invoke_callback
+ID: 121
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * rcuname; offset:8; size:8; signed:0;
+ field:void * rhp; offset:16; size:8; signed:0;
+ field:void * func; offset:24; size:8; signed:0;
+
+print fmt: "%s rhp=%p func=%ps", REC->rcuname, REC->rhp, REC->func
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_invoke_kfree_bulk_callback/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_invoke_kfree_bulk_callback/format
new file mode 100644
index 000000000..6eab32407
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_invoke_kfree_bulk_callback/format
@@ -0,0 +1,13 @@
+name: rcu_invoke_kfree_bulk_callback
+ID: 122
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * rcuname; offset:8; size:8; signed:0;
+ field:unsigned long nr_records; offset:16; size:8; signed:0;
+ field:void ** p; offset:24; size:8; signed:0;
+
+print fmt: "%s bulk=0x%p nr_records=%lu", REC->rcuname, REC->p, REC->nr_records
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_invoke_kvfree_callback/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_invoke_kvfree_callback/format
new file mode 100644
index 000000000..bb7ed9634
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_invoke_kvfree_callback/format
@@ -0,0 +1,13 @@
+name: rcu_invoke_kvfree_callback
+ID: 123
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * rcuname; offset:8; size:8; signed:0;
+ field:void * rhp; offset:16; size:8; signed:0;
+ field:unsigned long offset; offset:24; size:8; signed:0;
+
+print fmt: "%s rhp=%p func=%ld", REC->rcuname, REC->rhp, REC->offset
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_kvfree_callback/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_kvfree_callback/format
new file mode 100644
index 000000000..3dc6c4302
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_kvfree_callback/format
@@ -0,0 +1,14 @@
+name: rcu_kvfree_callback
+ID: 124
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * rcuname; offset:8; size:8; signed:0;
+ field:void * rhp; offset:16; size:8; signed:0;
+ field:unsigned long offset; offset:24; size:8; signed:0;
+ field:long qlen; offset:32; size:8; signed:1;
+
+print fmt: "%s rhp=%p func=%ld %ld", REC->rcuname, REC->rhp, REC->offset, REC->qlen
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_nocb_wake/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_nocb_wake/format
new file mode 100644
index 000000000..76dd397be
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_nocb_wake/format
@@ -0,0 +1,13 @@
+name: rcu_nocb_wake
+ID: 125
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * rcuname; offset:8; size:8; signed:0;
+ field:int cpu; offset:16; size:4; signed:1;
+ field:const char * reason; offset:24; size:8; signed:0;
+
+print fmt: "%s %d %s", REC->rcuname, REC->cpu, REC->reason
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_preempt_task/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_preempt_task/format
new file mode 100644
index 000000000..21fd275e6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_preempt_task/format
@@ -0,0 +1,13 @@
+name: rcu_preempt_task
+ID: 126
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * rcuname; offset:8; size:8; signed:0;
+ field:long gp_seq; offset:16; size:8; signed:1;
+ field:int pid; offset:24; size:4; signed:1;
+
+print fmt: "%s %ld %d", REC->rcuname, REC->gp_seq, REC->pid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_quiescent_state_report/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_quiescent_state_report/format
new file mode 100644
index 000000000..9aa1a7419
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_quiescent_state_report/format
@@ -0,0 +1,18 @@
+name: rcu_quiescent_state_report
+ID: 127
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * rcuname; offset:8; size:8; signed:0;
+ field:long gp_seq; offset:16; size:8; signed:1;
+ field:unsigned long mask; offset:24; size:8; signed:0;
+ field:unsigned long qsmask; offset:32; size:8; signed:0;
+ field:u8 level; offset:40; size:1; signed:0;
+ field:int grplo; offset:44; size:4; signed:1;
+ field:int grphi; offset:48; size:4; signed:1;
+ field:u8 gp_tasks; offset:52; size:1; signed:0;
+
+print fmt: "%s %ld %lx>%lx %u %d %d %u", REC->rcuname, REC->gp_seq, REC->mask, REC->qsmask, REC->level, REC->grplo, REC->grphi, REC->gp_tasks
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_stall_warning/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_stall_warning/format
new file mode 100644
index 000000000..0cc9be613
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_stall_warning/format
@@ -0,0 +1,12 @@
+name: rcu_stall_warning
+ID: 128
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * rcuname; offset:8; size:8; signed:0;
+ field:const char * msg; offset:16; size:8; signed:0;
+
+print fmt: "%s %s", REC->rcuname, REC->msg
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_torture_read/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_torture_read/format
new file mode 100644
index 000000000..efee31c4e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_torture_read/format
@@ -0,0 +1,15 @@
+name: rcu_torture_read
+ID: 129
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char rcutorturename[8]; offset:8; size:1; signed:0;
+ field:struct callback_head * rhp; offset:16; size:8; signed:0;
+ field:unsigned long secs; offset:24; size:8; signed:0;
+ field:unsigned long c_old; offset:32; size:8; signed:0;
+ field:unsigned long c; offset:40; size:8; signed:0;
+
+print fmt: "%s torture read %p %luus c: %lu %lu", REC->rcutorturename, REC->rhp, REC->secs, REC->c_old, REC->c
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_unlock_preempted_task/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_unlock_preempted_task/format
new file mode 100644
index 000000000..a6614f59a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_unlock_preempted_task/format
@@ -0,0 +1,13 @@
+name: rcu_unlock_preempted_task
+ID: 130
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * rcuname; offset:8; size:8; signed:0;
+ field:long gp_seq; offset:16; size:8; signed:1;
+ field:int pid; offset:24; size:4; signed:1;
+
+print fmt: "%s %ld %d", REC->rcuname, REC->gp_seq, REC->pid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_utilization/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_utilization/format
new file mode 100644
index 000000000..c5ee511b1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rcu/rcu_utilization/format
@@ -0,0 +1,11 @@
+name: rcu_utilization
+ID: 131
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * s; offset:8; size:8; signed:0;
+
+print fmt: "%s", REC->s
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regcache_drop_region/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regcache_drop_region/format
new file mode 100644
index 000000000..b3d60d970
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regcache_drop_region/format
@@ -0,0 +1,13 @@
+name: regcache_drop_region
+ID: 671
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int from; offset:12; size:4; signed:0;
+ field:unsigned int to; offset:16; size:4; signed:0;
+
+print fmt: "%s %u-%u", __get_str(name), (unsigned int)REC->from, (unsigned int)REC->to
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regcache_sync/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regcache_sync/format
new file mode 100644
index 000000000..bca46b4e2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regcache_sync/format
@@ -0,0 +1,14 @@
+name: regcache_sync
+ID: 672
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:__data_loc char[] status; offset:12; size:4; signed:0;
+ field:__data_loc char[] type; offset:16; size:4; signed:0;
+ field:int type; offset:20; size:4; signed:1;
+
+print fmt: "%s type=%s status=%s", __get_str(name), __get_str(type), __get_str(status)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_async_complete_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_async_complete_done/format
new file mode 100644
index 000000000..a69fe1d81
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_async_complete_done/format
@@ -0,0 +1,11 @@
+name: regmap_async_complete_done
+ID: 673
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_async_complete_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_async_complete_start/format
new file mode 100644
index 000000000..51fdb0c63
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_async_complete_start/format
@@ -0,0 +1,11 @@
+name: regmap_async_complete_start
+ID: 674
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_async_io_complete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_async_io_complete/format
new file mode 100644
index 000000000..b2b46f744
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_async_io_complete/format
@@ -0,0 +1,11 @@
+name: regmap_async_io_complete
+ID: 675
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_async_write_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_async_write_start/format
new file mode 100644
index 000000000..a3af3d038
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_async_write_start/format
@@ -0,0 +1,13 @@
+name: regmap_async_write_start
+ID: 676
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int reg; offset:12; size:4; signed:0;
+ field:int count; offset:16; size:4; signed:1;
+
+print fmt: "%s reg=%x count=%d", __get_str(name), (unsigned int)REC->reg, (int)REC->count
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_cache_bypass/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_cache_bypass/format
new file mode 100644
index 000000000..c131f1d17
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_cache_bypass/format
@@ -0,0 +1,12 @@
+name: regmap_cache_bypass
+ID: 677
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:int flag; offset:12; size:4; signed:1;
+
+print fmt: "%s flag=%d", __get_str(name), (int)REC->flag
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_cache_only/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_cache_only/format
new file mode 100644
index 000000000..3eab9569a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_cache_only/format
@@ -0,0 +1,12 @@
+name: regmap_cache_only
+ID: 678
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:int flag; offset:12; size:4; signed:1;
+
+print fmt: "%s flag=%d", __get_str(name), (int)REC->flag
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_hw_read_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_hw_read_done/format
new file mode 100644
index 000000000..201cf2116
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_hw_read_done/format
@@ -0,0 +1,13 @@
+name: regmap_hw_read_done
+ID: 679
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int reg; offset:12; size:4; signed:0;
+ field:int count; offset:16; size:4; signed:1;
+
+print fmt: "%s reg=%x count=%d", __get_str(name), (unsigned int)REC->reg, (int)REC->count
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_hw_read_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_hw_read_start/format
new file mode 100644
index 000000000..1c578647f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_hw_read_start/format
@@ -0,0 +1,13 @@
+name: regmap_hw_read_start
+ID: 680
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int reg; offset:12; size:4; signed:0;
+ field:int count; offset:16; size:4; signed:1;
+
+print fmt: "%s reg=%x count=%d", __get_str(name), (unsigned int)REC->reg, (int)REC->count
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_hw_write_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_hw_write_done/format
new file mode 100644
index 000000000..3a4aa7a84
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_hw_write_done/format
@@ -0,0 +1,13 @@
+name: regmap_hw_write_done
+ID: 681
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int reg; offset:12; size:4; signed:0;
+ field:int count; offset:16; size:4; signed:1;
+
+print fmt: "%s reg=%x count=%d", __get_str(name), (unsigned int)REC->reg, (int)REC->count
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_hw_write_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_hw_write_start/format
new file mode 100644
index 000000000..0d6a84f82
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_hw_write_start/format
@@ -0,0 +1,13 @@
+name: regmap_hw_write_start
+ID: 682
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int reg; offset:12; size:4; signed:0;
+ field:int count; offset:16; size:4; signed:1;
+
+print fmt: "%s reg=%x count=%d", __get_str(name), (unsigned int)REC->reg, (int)REC->count
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_reg_read/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_reg_read/format
new file mode 100644
index 000000000..a29590e92
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_reg_read/format
@@ -0,0 +1,13 @@
+name: regmap_reg_read
+ID: 683
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int reg; offset:12; size:4; signed:0;
+ field:unsigned int val; offset:16; size:4; signed:0;
+
+print fmt: "%s reg=%x val=%x", __get_str(name), (unsigned int)REC->reg, (unsigned int)REC->val
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_reg_read_cache/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_reg_read_cache/format
new file mode 100644
index 000000000..7724bef18
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_reg_read_cache/format
@@ -0,0 +1,13 @@
+name: regmap_reg_read_cache
+ID: 684
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int reg; offset:12; size:4; signed:0;
+ field:unsigned int val; offset:16; size:4; signed:0;
+
+print fmt: "%s reg=%x val=%x", __get_str(name), (unsigned int)REC->reg, (unsigned int)REC->val
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_reg_write/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_reg_write/format
new file mode 100644
index 000000000..a53efbf07
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regmap/regmap_reg_write/format
@@ -0,0 +1,13 @@
+name: regmap_reg_write
+ID: 685
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int reg; offset:12; size:4; signed:0;
+ field:unsigned int val; offset:16; size:4; signed:0;
+
+print fmt: "%s reg=%x val=%x", __get_str(name), (unsigned int)REC->reg, (unsigned int)REC->val
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_bypass_disable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_bypass_disable/format
new file mode 100644
index 000000000..63fc9df29
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_bypass_disable/format
@@ -0,0 +1,11 @@
+name: regulator_bypass_disable
+ID: 633
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "name=%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_bypass_disable_complete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_bypass_disable_complete/format
new file mode 100644
index 000000000..768015166
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_bypass_disable_complete/format
@@ -0,0 +1,11 @@
+name: regulator_bypass_disable_complete
+ID: 634
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "name=%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_bypass_enable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_bypass_enable/format
new file mode 100644
index 000000000..0402edc14
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_bypass_enable/format
@@ -0,0 +1,11 @@
+name: regulator_bypass_enable
+ID: 635
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "name=%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_bypass_enable_complete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_bypass_enable_complete/format
new file mode 100644
index 000000000..f7e75620a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_bypass_enable_complete/format
@@ -0,0 +1,11 @@
+name: regulator_bypass_enable_complete
+ID: 636
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "name=%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_disable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_disable/format
new file mode 100644
index 000000000..01f3091f2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_disable/format
@@ -0,0 +1,11 @@
+name: regulator_disable
+ID: 637
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "name=%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_disable_complete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_disable_complete/format
new file mode 100644
index 000000000..8c0bbf44b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_disable_complete/format
@@ -0,0 +1,11 @@
+name: regulator_disable_complete
+ID: 638
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "name=%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_enable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_enable/format
new file mode 100644
index 000000000..daf12fe51
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_enable/format
@@ -0,0 +1,11 @@
+name: regulator_enable
+ID: 639
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "name=%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_enable_complete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_enable_complete/format
new file mode 100644
index 000000000..509458818
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_enable_complete/format
@@ -0,0 +1,11 @@
+name: regulator_enable_complete
+ID: 640
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "name=%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_enable_delay/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_enable_delay/format
new file mode 100644
index 000000000..45b9fab48
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_enable_delay/format
@@ -0,0 +1,11 @@
+name: regulator_enable_delay
+ID: 641
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+
+print fmt: "name=%s", __get_str(name)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_set_voltage/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_set_voltage/format
new file mode 100644
index 000000000..94e8dee5e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_set_voltage/format
@@ -0,0 +1,13 @@
+name: regulator_set_voltage
+ID: 642
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:int min; offset:12; size:4; signed:1;
+ field:int max; offset:16; size:4; signed:1;
+
+print fmt: "name=%s (%d-%d)", __get_str(name), (int)REC->min, (int)REC->max
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_set_voltage_complete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_set_voltage_complete/format
new file mode 100644
index 000000000..097c1e6f5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/regulator/regulator_set_voltage_complete/format
@@ -0,0 +1,12 @@
+name: regulator_set_voltage_complete
+ID: 643
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int val; offset:12; size:4; signed:0;
+
+print fmt: "name=%s, val=%u", __get_str(name), (int)REC->val
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rpm/rpm_idle/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rpm/rpm_idle/format
new file mode 100644
index 000000000..ef448614f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rpm/rpm_idle/format
@@ -0,0 +1,18 @@
+name: rpm_idle
+ID: 192
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:int flags; offset:12; size:4; signed:1;
+ field:int usage_count; offset:16; size:4; signed:1;
+ field:int disable_depth; offset:20; size:4; signed:1;
+ field:int runtime_auto; offset:24; size:4; signed:1;
+ field:int request_pending; offset:28; size:4; signed:1;
+ field:int irq_safe; offset:32; size:4; signed:1;
+ field:int child_count; offset:36; size:4; signed:1;
+
+print fmt: "%s flags-%x cnt-%-2d dep-%-2d auto-%-1d p-%-1d irq-%-1d child-%d", __get_str(name), REC->flags, REC->usage_count, REC->disable_depth, REC->runtime_auto, REC->request_pending, REC->irq_safe, REC->child_count
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rpm/rpm_resume/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rpm/rpm_resume/format
new file mode 100644
index 000000000..1f8807246
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rpm/rpm_resume/format
@@ -0,0 +1,18 @@
+name: rpm_resume
+ID: 193
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:int flags; offset:12; size:4; signed:1;
+ field:int usage_count; offset:16; size:4; signed:1;
+ field:int disable_depth; offset:20; size:4; signed:1;
+ field:int runtime_auto; offset:24; size:4; signed:1;
+ field:int request_pending; offset:28; size:4; signed:1;
+ field:int irq_safe; offset:32; size:4; signed:1;
+ field:int child_count; offset:36; size:4; signed:1;
+
+print fmt: "%s flags-%x cnt-%-2d dep-%-2d auto-%-1d p-%-1d irq-%-1d child-%d", __get_str(name), REC->flags, REC->usage_count, REC->disable_depth, REC->runtime_auto, REC->request_pending, REC->irq_safe, REC->child_count
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rpm/rpm_return_int/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rpm/rpm_return_int/format
new file mode 100644
index 000000000..72c225538
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rpm/rpm_return_int/format
@@ -0,0 +1,13 @@
+name: rpm_return_int
+ID: 194
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned long ip; offset:16; size:8; signed:0;
+ field:int ret; offset:24; size:4; signed:1;
+
+print fmt: "%pS:%s ret=%d", (void *)REC->ip, __get_str(name), REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rpm/rpm_suspend/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rpm/rpm_suspend/format
new file mode 100644
index 000000000..09e82f341
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rpm/rpm_suspend/format
@@ -0,0 +1,18 @@
+name: rpm_suspend
+ID: 195
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:int flags; offset:12; size:4; signed:1;
+ field:int usage_count; offset:16; size:4; signed:1;
+ field:int disable_depth; offset:20; size:4; signed:1;
+ field:int runtime_auto; offset:24; size:4; signed:1;
+ field:int request_pending; offset:28; size:4; signed:1;
+ field:int irq_safe; offset:32; size:4; signed:1;
+ field:int child_count; offset:36; size:4; signed:1;
+
+print fmt: "%s flags-%x cnt-%-2d dep-%-2d auto-%-1d p-%-1d irq-%-1d child-%d", __get_str(name), REC->flags, REC->usage_count, REC->disable_depth, REC->runtime_auto, REC->request_pending, REC->irq_safe, REC->child_count
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rpm/rpm_usage/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rpm/rpm_usage/format
new file mode 100644
index 000000000..234971654
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rpm/rpm_usage/format
@@ -0,0 +1,18 @@
+name: rpm_usage
+ID: 196
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:int flags; offset:12; size:4; signed:1;
+ field:int usage_count; offset:16; size:4; signed:1;
+ field:int disable_depth; offset:20; size:4; signed:1;
+ field:int runtime_auto; offset:24; size:4; signed:1;
+ field:int request_pending; offset:28; size:4; signed:1;
+ field:int irq_safe; offset:32; size:4; signed:1;
+ field:int child_count; offset:36; size:4; signed:1;
+
+print fmt: "%s flags-%x cnt-%-2d dep-%-2d auto-%-1d p-%-1d irq-%-1d child-%d", __get_str(name), REC->flags, REC->usage_count, REC->disable_depth, REC->runtime_auto, REC->request_pending, REC->irq_safe, REC->child_count
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_alarm_irq_enable/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_alarm_irq_enable/format
new file mode 100644
index 000000000..4de7840a4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_alarm_irq_enable/format
@@ -0,0 +1,12 @@
+name: rtc_alarm_irq_enable
+ID: 822
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int enabled; offset:8; size:4; signed:0;
+ field:int err; offset:12; size:4; signed:1;
+
+print fmt: "%s RTC alarm IRQ (%d)", REC->enabled ? "enable" : "disable", REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_irq_set_freq/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_irq_set_freq/format
new file mode 100644
index 000000000..ce0be9a68
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_irq_set_freq/format
@@ -0,0 +1,12 @@
+name: rtc_irq_set_freq
+ID: 823
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int freq; offset:8; size:4; signed:1;
+ field:int err; offset:12; size:4; signed:1;
+
+print fmt: "set RTC periodic IRQ frequency:%u (%d)", REC->freq, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_irq_set_state/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_irq_set_state/format
new file mode 100644
index 000000000..ada4e3d62
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_irq_set_state/format
@@ -0,0 +1,12 @@
+name: rtc_irq_set_state
+ID: 824
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int enabled; offset:8; size:4; signed:1;
+ field:int err; offset:12; size:4; signed:1;
+
+print fmt: "%s RTC 2^N Hz periodic IRQs (%d)", REC->enabled ? "enable" : "disable", REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_read_alarm/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_read_alarm/format
new file mode 100644
index 000000000..97ac56546
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_read_alarm/format
@@ -0,0 +1,12 @@
+name: rtc_read_alarm
+ID: 825
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:time64_t secs; offset:8; size:8; signed:1;
+ field:int err; offset:16; size:4; signed:1;
+
+print fmt: "UTC (%lld) (%d)", REC->secs, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_read_offset/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_read_offset/format
new file mode 100644
index 000000000..7f534a03b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_read_offset/format
@@ -0,0 +1,12 @@
+name: rtc_read_offset
+ID: 826
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:long offset; offset:8; size:8; signed:1;
+ field:int err; offset:16; size:4; signed:1;
+
+print fmt: "RTC offset: %ld (%d)", REC->offset, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_read_time/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_read_time/format
new file mode 100644
index 000000000..00fde875f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_read_time/format
@@ -0,0 +1,12 @@
+name: rtc_read_time
+ID: 827
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:time64_t secs; offset:8; size:8; signed:1;
+ field:int err; offset:16; size:4; signed:1;
+
+print fmt: "UTC (%lld) (%d)", REC->secs, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_set_alarm/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_set_alarm/format
new file mode 100644
index 000000000..e03e80cdc
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_set_alarm/format
@@ -0,0 +1,12 @@
+name: rtc_set_alarm
+ID: 828
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:time64_t secs; offset:8; size:8; signed:1;
+ field:int err; offset:16; size:4; signed:1;
+
+print fmt: "UTC (%lld) (%d)", REC->secs, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_set_offset/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_set_offset/format
new file mode 100644
index 000000000..037df883e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_set_offset/format
@@ -0,0 +1,12 @@
+name: rtc_set_offset
+ID: 829
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:long offset; offset:8; size:8; signed:1;
+ field:int err; offset:16; size:4; signed:1;
+
+print fmt: "RTC offset: %ld (%d)", REC->offset, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_set_time/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_set_time/format
new file mode 100644
index 000000000..f980700cf
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_set_time/format
@@ -0,0 +1,12 @@
+name: rtc_set_time
+ID: 830
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:time64_t secs; offset:8; size:8; signed:1;
+ field:int err; offset:16; size:4; signed:1;
+
+print fmt: "UTC (%lld) (%d)", REC->secs, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_timer_dequeue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_timer_dequeue/format
new file mode 100644
index 000000000..0e69674f9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_timer_dequeue/format
@@ -0,0 +1,13 @@
+name: rtc_timer_dequeue
+ID: 831
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct rtc_timer * timer; offset:8; size:8; signed:0;
+ field:ktime_t expires; offset:16; size:8; signed:1;
+ field:ktime_t period; offset:24; size:8; signed:1;
+
+print fmt: "RTC timer:(%p) expires:%lld period:%lld", REC->timer, REC->expires, REC->period
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_timer_enqueue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_timer_enqueue/format
new file mode 100644
index 000000000..f24615e04
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_timer_enqueue/format
@@ -0,0 +1,13 @@
+name: rtc_timer_enqueue
+ID: 832
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct rtc_timer * timer; offset:8; size:8; signed:0;
+ field:ktime_t expires; offset:16; size:8; signed:1;
+ field:ktime_t period; offset:24; size:8; signed:1;
+
+print fmt: "RTC timer:(%p) expires:%lld period:%lld", REC->timer, REC->expires, REC->period
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_timer_fired/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_timer_fired/format
new file mode 100644
index 000000000..f8304962c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rtc/rtc_timer_fired/format
@@ -0,0 +1,13 @@
+name: rtc_timer_fired
+ID: 833
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct rtc_timer * timer; offset:8; size:8; signed:0;
+ field:ktime_t expires; offset:16; size:8; signed:1;
+ field:ktime_t period; offset:24; size:8; signed:1;
+
+print fmt: "RTC timer:(%p) expires:%lld period:%lld", REC->timer, REC->expires, REC->period
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rwmmio/rwmmio_post_read/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rwmmio/rwmmio_post_read/format
new file mode 100644
index 000000000..1a2d5a063
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rwmmio/rwmmio_post_read/format
@@ -0,0 +1,15 @@
+name: rwmmio_post_read
+ID: 197
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 fn; offset:8; size:8; signed:0;
+ field:u64 val; offset:16; size:8; signed:0;
+ field:u8 width; offset:24; size:1; signed:0;
+ field:u64 addr; offset:32; size:8; signed:0;
+
+print fmt: "%llxS read addr=%llx of width=%x val=0x%llx
+", REC->fn, REC->addr, REC->width, REC->val
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rwmmio/rwmmio_read/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rwmmio/rwmmio_read/format
new file mode 100644
index 000000000..db62d440f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rwmmio/rwmmio_read/format
@@ -0,0 +1,14 @@
+name: rwmmio_read
+ID: 198
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 fn; offset:8; size:8; signed:0;
+ field:u8 width; offset:16; size:1; signed:0;
+ field:u64 addr; offset:24; size:8; signed:0;
+
+print fmt: "%llxS read addr=%llx of width=%x
+", REC->fn, REC->addr, REC->width
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rwmmio/rwmmio_write/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rwmmio/rwmmio_write/format
new file mode 100644
index 000000000..8147584dd
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/rwmmio/rwmmio_write/format
@@ -0,0 +1,15 @@
+name: rwmmio_write
+ID: 199
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 fn; offset:8; size:8; signed:0;
+ field:u64 val; offset:16; size:8; signed:0;
+ field:u8 width; offset:24; size:1; signed:0;
+ field:u64 addr; offset:32; size:8; signed:0;
+
+print fmt: "%llxS write addr=%llx of width=%x val=0x%llx
+", REC->fn, REC->addr, REC->width, REC->val
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_blocked_reason/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_blocked_reason/format
new file mode 100644
index 000000000..b269fd68a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_blocked_reason/format
@@ -0,0 +1,13 @@
+name: sched_blocked_reason
+ID: 84
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:pid_t pid; offset:8; size:4; signed:1;
+ field:void* caller; offset:16; size:8; signed:0;
+ field:bool io_wait; offset:24; size:1; signed:0;
+
+print fmt: "pid=%d iowait=%d caller=%pS", REC->pid, REC->io_wait, REC->caller
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_cpu_capacity/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_cpu_capacity/format
new file mode 100644
index 000000000..a87454018
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_cpu_capacity/format
@@ -0,0 +1,13 @@
+name: sched_cpu_capacity
+ID: 1059
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int cpu; offset:8; size:4; signed:1;
+ field:unsigned long capacity; offset:16; size:8; signed:0;
+ field:unsigned long capacity_orig; offset:24; size:8; signed:0;
+
+print fmt: "cpu=%d capacity=%lu, capacity_orig=%lu", REC->cpu, REC->capacity, REC->capacity_orig
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_cpu_util/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_cpu_util/format
new file mode 100644
index 000000000..9254f69e8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_cpu_util/format
@@ -0,0 +1,25 @@
+name: sched_cpu_util
+ID: 1060
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int cpu; offset:8; size:4; signed:0;
+ field:unsigned int nr_running; offset:12; size:4; signed:0;
+ field:unsigned long cpu_util; offset:16; size:8; signed:0;
+ field:unsigned long capacity_curr; offset:24; size:8; signed:0;
+ field:unsigned long capacity; offset:32; size:8; signed:0;
+ field:unsigned long wake_util; offset:40; size:8; signed:0;
+ field:unsigned long capacity_orig; offset:48; size:8; signed:0;
+ field:int active; offset:56; size:4; signed:1;
+ field:bool idle_cpu; offset:60; size:1; signed:0;
+ field:unsigned long cpu_importance; offset:64; size:8; signed:0;
+ field:unsigned long group_capacity; offset:72; size:8; signed:0;
+ field:unsigned long wake_group_util; offset:80; size:8; signed:0;
+ field:long spare_cap; offset:88; size:8; signed:1;
+ field:unsigned long group_util; offset:96; size:8; signed:0;
+ field:bool grp_overutilized; offset:104; size:1; signed:0;
+
+print fmt: "cpu=%d nr_running=%d cpu_util=%llu capacity_curr=%llu capacity=%llu wake_util=%llu capacity_orig=%u active=%u idle_cpu=%d cpu_importance=%llu group_capacity=%llu wake_group_util=%llu spare_cap=%ld group_util=%lu grp_overutilized=%d", REC->cpu, REC->nr_running, REC->cpu_util, REC->capacity_curr, REC->capacity, REC->wake_util, REC->capacity_orig, REC->active, REC->idle_cpu, REC->cpu_importance, REC->group_capacity, REC->wake_group_util, REC->spare_cap, REC->group_util, REC->grp_overutilized
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_find_best_target/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_find_best_target/format
new file mode 100644
index 000000000..4280f7f91
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_find_best_target/format
@@ -0,0 +1,23 @@
+name: sched_find_best_target
+ID: 1061
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+ field:unsigned long task_util; offset:32; size:8; signed:0;
+ field:bool prefer_idle; offset:40; size:1; signed:0;
+ field:bool prefer_high_cap; offset:41; size:1; signed:0;
+ field:bool prefer_prev; offset:42; size:1; signed:0;
+ field:bool sync_boost; offset:43; size:1; signed:0;
+ field:int start_cpu; offset:44; size:4; signed:1;
+ field:int best_idle; offset:48; size:4; signed:1;
+ field:int best_active; offset:52; size:4; signed:1;
+ field:int best_importance; offset:56; size:4; signed:1;
+ field:int backup; offset:60; size:4; signed:1;
+ field:int target; offset:64; size:4; signed:1;
+
+print fmt: "pid=%d comm=%s task_util=%lu prefer_idle=%d prefer_high_cap=%d prefer_prev=%d sync_boost=%d start_cpu=%d best_idle=%d best_active=%d best_importance=%d backup=%d target=%d", REC->pid, REC->comm, REC->task_util, REC->prefer_idle, REC->prefer_high_cap, REC->prefer_prev, REC->sync_boost, REC->start_cpu, REC->best_idle, REC->best_active, REC->best_importance, REC->backup, REC->target
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_find_energy_efficient_cpu/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_find_energy_efficient_cpu/format
new file mode 100644
index 000000000..9dd791fd4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_find_energy_efficient_cpu/format
@@ -0,0 +1,19 @@
+name: sched_find_energy_efficient_cpu
+ID: 1062
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+ field:bool sync_wakeup; offset:28; size:1; signed:0;
+ field:int new_cpu; offset:32; size:4; signed:1;
+ field:int best_energy_cpu; offset:36; size:4; signed:1;
+ field:int prev_cpu; offset:40; size:4; signed:1;
+ field:int group; offset:44; size:4; signed:1;
+ field:int uclamp_min; offset:48; size:4; signed:1;
+ field:int uclamp_max; offset:52; size:4; signed:1;
+
+print fmt: "pid=%d comm=%s sync_wakeup=%d new_cpu=%d best_energy_cpu=%d prev_cpu=%d group=%d uclamp.min=%d uclamp.max=%d", REC->pid, REC->comm, REC->sync_wakeup, REC->new_cpu, REC->best_energy_cpu, REC->prev_cpu, REC->group, REC->uclamp_min, REC->uclamp_max
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_find_least_loaded_cpu/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_find_least_loaded_cpu/format
new file mode 100644
index 000000000..729a7d170
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_find_least_loaded_cpu/format
@@ -0,0 +1,23 @@
+name: sched_find_least_loaded_cpu
+ID: 1063
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+ field:int group; offset:28; size:4; signed:1;
+ field:unsigned long uclamp_min; offset:32; size:8; signed:0;
+ field:unsigned long uclamp_max; offset:40; size:8; signed:0;
+ field:bool check_cpu_overutilized; offset:48; size:1; signed:0;
+ field:unsigned long min_cpu_util; offset:56; size:8; signed:0;
+ field:unsigned long min_cpu_capacity; offset:64; size:8; signed:0;
+ field:unsigned int min_exit_lat; offset:72; size:4; signed:0;
+ field:int prev_cpu; offset:76; size:4; signed:1;
+ field:int best_cpu; offset:80; size:4; signed:1;
+ field:unsigned long lowest_mask; offset:88; size:8; signed:0;
+ field:unsigned long backup_mask; offset:96; size:8; signed:0;
+
+print fmt: "pid=%d comm=%s group=%d uclamp_min=%llu uclamp_max=%llu check_cpu_overutilized=%d min_cpu_util=%llu min_cpu_capacity=%llu min_exit_lat=%u prev_cpu=%d best_cpu=%d lowest_mask=0x%x backup_mask=0x%x", REC->pid, REC->comm, REC->group, REC->uclamp_min, REC->uclamp_max, REC->check_cpu_overutilized, REC->min_cpu_util, REC->min_cpu_capacity, REC->min_exit_lat, REC->prev_cpu, REC->best_cpu, REC->lowest_mask, REC->backup_mask
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_kthread_stop/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_kthread_stop/format
new file mode 100644
index 000000000..10d40778c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_kthread_stop/format
@@ -0,0 +1,12 @@
+name: sched_kthread_stop
+ID: 85
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+
+print fmt: "comm=%s pid=%d", REC->comm, REC->pid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_kthread_stop_ret/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_kthread_stop_ret/format
new file mode 100644
index 000000000..389277edd
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_kthread_stop_ret/format
@@ -0,0 +1,11 @@
+name: sched_kthread_stop_ret
+ID: 86
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ret; offset:8; size:4; signed:1;
+
+print fmt: "ret=%d", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_migrate_task/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_migrate_task/format
new file mode 100644
index 000000000..5c2b973bc
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_migrate_task/format
@@ -0,0 +1,16 @@
+name: sched_migrate_task
+ID: 87
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+ field:int prio; offset:28; size:4; signed:1;
+ field:int orig_cpu; offset:32; size:4; signed:1;
+ field:int dest_cpu; offset:36; size:4; signed:1;
+ field:int running; offset:40; size:4; signed:1;
+
+print fmt: "comm=%s pid=%d prio=%d orig_cpu=%d dest_cpu=%d running=%d", REC->comm, REC->pid, REC->prio, REC->orig_cpu, REC->dest_cpu, REC->running
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_move_numa/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_move_numa/format
new file mode 100644
index 000000000..34418fbca
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_move_numa/format
@@ -0,0 +1,17 @@
+name: sched_move_numa
+ID: 88
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:pid_t pid; offset:8; size:4; signed:1;
+ field:pid_t tgid; offset:12; size:4; signed:1;
+ field:pid_t ngid; offset:16; size:4; signed:1;
+ field:int src_cpu; offset:20; size:4; signed:1;
+ field:int src_nid; offset:24; size:4; signed:1;
+ field:int dst_cpu; offset:28; size:4; signed:1;
+ field:int dst_nid; offset:32; size:4; signed:1;
+
+print fmt: "pid=%d tgid=%d ngid=%d src_cpu=%d src_nid=%d dst_cpu=%d dst_nid=%d", REC->pid, REC->tgid, REC->ngid, REC->src_cpu, REC->src_nid, REC->dst_cpu, REC->dst_nid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_overutilized/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_overutilized/format
new file mode 100644
index 000000000..e5139421f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_overutilized/format
@@ -0,0 +1,12 @@
+name: sched_overutilized
+ID: 1064
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int overutilized; offset:8; size:4; signed:1;
+ field:char span[((((((32)-1) | ((__typeof__(32))((4)-1)))+1)/4) > 128 ? 128 : (((((32)-1) | ((__typeof__(32))((4)-1)))+1)/4))]; offset:12; size:8; signed:0;
+
+print fmt: "overutilized=%d span=0x%s", REC->overutilized, REC->span
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pelt_cfs/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pelt_cfs/format
new file mode 100644
index 000000000..9ff5dad90
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pelt_cfs/format
@@ -0,0 +1,15 @@
+name: sched_pelt_cfs
+ID: 1065
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int cpu; offset:8; size:4; signed:1;
+ field:char path[64]; offset:12; size:64; signed:0;
+ field:unsigned long load; offset:80; size:8; signed:0;
+ field:unsigned long runnable; offset:88; size:8; signed:0;
+ field:unsigned long util; offset:96; size:8; signed:0;
+
+print fmt: "cpu=%d path=%s load=%lu runnable=%lu util=%lu", REC->cpu, REC->path, REC->load, REC->runnable,REC->util
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pelt_dl/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pelt_dl/format
new file mode 100644
index 000000000..4f258e7af
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pelt_dl/format
@@ -0,0 +1,14 @@
+name: sched_pelt_dl
+ID: 1066
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int cpu; offset:8; size:4; signed:1;
+ field:unsigned long load; offset:16; size:8; signed:0;
+ field:unsigned long runnable; offset:24; size:8; signed:0;
+ field:unsigned long util; offset:32; size:8; signed:0;
+
+print fmt: "cpu=%d load=%lu runnable=%lu util=%lu", REC->cpu, REC->load, REC->runnable,REC->util
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pelt_irq/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pelt_irq/format
new file mode 100644
index 000000000..297096f22
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pelt_irq/format
@@ -0,0 +1,14 @@
+name: sched_pelt_irq
+ID: 1067
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int cpu; offset:8; size:4; signed:1;
+ field:unsigned long load; offset:16; size:8; signed:0;
+ field:unsigned long runnable; offset:24; size:8; signed:0;
+ field:unsigned long util; offset:32; size:8; signed:0;
+
+print fmt: "cpu=%d load=%lu runnable=%lu util=%lu", REC->cpu, REC->load, REC->runnable,REC->util
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pelt_rt/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pelt_rt/format
new file mode 100644
index 000000000..6f66313be
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pelt_rt/format
@@ -0,0 +1,14 @@
+name: sched_pelt_rt
+ID: 1068
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int cpu; offset:8; size:4; signed:1;
+ field:unsigned long load; offset:16; size:8; signed:0;
+ field:unsigned long runnable; offset:24; size:8; signed:0;
+ field:unsigned long util; offset:32; size:8; signed:0;
+
+print fmt: "cpu=%d load=%lu runnable=%lu util=%lu", REC->cpu, REC->load, REC->runnable,REC->util
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pelt_se/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pelt_se/format
new file mode 100644
index 000000000..adc82958a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pelt_se/format
@@ -0,0 +1,18 @@
+name: sched_pelt_se
+ID: 1069
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int cpu; offset:8; size:4; signed:1;
+ field:char path[64]; offset:12; size:64; signed:0;
+ field:char comm[16]; offset:76; size:16; signed:0;
+ field:int pid; offset:92; size:4; signed:1;
+ field:unsigned long load; offset:96; size:8; signed:0;
+ field:unsigned long runnable; offset:104; size:8; signed:0;
+ field:unsigned long util; offset:112; size:8; signed:0;
+ field:unsigned long long update_time; offset:120; size:8; signed:0;
+
+print fmt: "cpu=%d path=%s comm=%s pid=%d load=%lu runnable=%lu util=%lu update_time=%llu", REC->cpu, REC->path, REC->comm, REC->pid, REC->load, REC->runnable,REC->util, REC->update_time
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pi_setprio/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pi_setprio/format
new file mode 100644
index 000000000..00407e081
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_pi_setprio/format
@@ -0,0 +1,14 @@
+name: sched_pi_setprio
+ID: 89
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+ field:int oldprio; offset:28; size:4; signed:1;
+ field:int newprio; offset:32; size:4; signed:1;
+
+print fmt: "comm=%s pid=%d oldprio=%d newprio=%d", REC->comm, REC->pid, REC->oldprio, REC->newprio
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_exec/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_exec/format
new file mode 100644
index 000000000..2e39bacf7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_exec/format
@@ -0,0 +1,13 @@
+name: sched_process_exec
+ID: 90
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] filename; offset:8; size:4; signed:0;
+ field:pid_t pid; offset:12; size:4; signed:1;
+ field:pid_t old_pid; offset:16; size:4; signed:1;
+
+print fmt: "filename=%s pid=%d old_pid=%d", __get_str(filename), REC->pid, REC->old_pid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_exit/format
new file mode 100644
index 000000000..cc391301d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_exit/format
@@ -0,0 +1,13 @@
+name: sched_process_exit
+ID: 91
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+ field:int prio; offset:28; size:4; signed:1;
+
+print fmt: "comm=%s pid=%d prio=%d", REC->comm, REC->pid, REC->prio
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_fork/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_fork/format
new file mode 100644
index 000000000..9290061ab
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_fork/format
@@ -0,0 +1,14 @@
+name: sched_process_fork
+ID: 92
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char parent_comm[16]; offset:8; size:16; signed:0;
+ field:pid_t parent_pid; offset:24; size:4; signed:1;
+ field:char child_comm[16]; offset:28; size:16; signed:0;
+ field:pid_t child_pid; offset:44; size:4; signed:1;
+
+print fmt: "comm=%s pid=%d child_comm=%s child_pid=%d", REC->parent_comm, REC->parent_pid, REC->child_comm, REC->child_pid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_free/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_free/format
new file mode 100644
index 000000000..d2496e9d8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_free/format
@@ -0,0 +1,13 @@
+name: sched_process_free
+ID: 93
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+ field:int prio; offset:28; size:4; signed:1;
+
+print fmt: "comm=%s pid=%d prio=%d", REC->comm, REC->pid, REC->prio
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_hang/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_hang/format
new file mode 100644
index 000000000..88f48c210
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_hang/format
@@ -0,0 +1,12 @@
+name: sched_process_hang
+ID: 94
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+
+print fmt: "comm=%s pid=%d", REC->comm, REC->pid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_wait/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_wait/format
new file mode 100644
index 000000000..73efadff7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_process_wait/format
@@ -0,0 +1,13 @@
+name: sched_process_wait
+ID: 95
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+ field:int prio; offset:28; size:4; signed:1;
+
+print fmt: "comm=%s pid=%d prio=%d", REC->comm, REC->pid, REC->prio
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_rt_cpu_util/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_rt_cpu_util/format
new file mode 100644
index 000000000..ecde84c0a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_rt_cpu_util/format
@@ -0,0 +1,15 @@
+name: sched_rt_cpu_util
+ID: 1070
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int cpu; offset:8; size:4; signed:1;
+ field:unsigned long capacity; offset:16; size:8; signed:0;
+ field:unsigned long util; offset:24; size:8; signed:0;
+ field:unsigned long exit_lat; offset:32; size:8; signed:0;
+ field:unsigned long cpu_importance; offset:40; size:8; signed:0;
+
+print fmt: "cpu=%d capacity=%llu util=%llu exit_lat=%llu cpu_importance=%llu", REC->cpu, REC->capacity, REC->util, REC->exit_lat, REC->cpu_importance
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_select_task_rq_rt/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_select_task_rq_rt/format
new file mode 100644
index 000000000..d54042763
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_select_task_rq_rt/format
@@ -0,0 +1,16 @@
+name: sched_select_task_rq_rt
+ID: 1071
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+ field:int prev_cpu; offset:28; size:4; signed:1;
+ field:int target; offset:32; size:4; signed:1;
+ field:int new_cpu; offset:36; size:4; signed:1;
+ field:bool sync_wakeup; offset:40; size:1; signed:0;
+
+print fmt: "pid=%d comm=%s prev_cpu=%d target=%d new_cpu=%d sync_wakeup=%d", REC->pid, REC->comm, REC->prev_cpu, REC->target, REC->new_cpu, REC->sync_wakeup
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_setscheduler_uclamp/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_setscheduler_uclamp/format
new file mode 100644
index 000000000..9a4787b96
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_setscheduler_uclamp/format
@@ -0,0 +1,14 @@
+name: sched_setscheduler_uclamp
+ID: 1072
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+ field:int clamp_id; offset:28; size:4; signed:1;
+ field:unsigned int value; offset:32; size:4; signed:0;
+
+print fmt: "pid=%d comm=%s clamp_id=%d, value=%u", REC->pid, REC->comm, REC->clamp_id, REC->value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stat_blocked/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stat_blocked/format
new file mode 100644
index 000000000..df5174c35
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stat_blocked/format
@@ -0,0 +1,13 @@
+name: sched_stat_blocked
+ID: 96
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+ field:u64 delay; offset:32; size:8; signed:0;
+
+print fmt: "comm=%s pid=%d delay=%Lu [ns]", REC->comm, REC->pid, (unsigned long long)REC->delay
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stat_iowait/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stat_iowait/format
new file mode 100644
index 000000000..785c214a1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stat_iowait/format
@@ -0,0 +1,13 @@
+name: sched_stat_iowait
+ID: 97
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+ field:u64 delay; offset:32; size:8; signed:0;
+
+print fmt: "comm=%s pid=%d delay=%Lu [ns]", REC->comm, REC->pid, (unsigned long long)REC->delay
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stat_runtime/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stat_runtime/format
new file mode 100644
index 000000000..b36db4613
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stat_runtime/format
@@ -0,0 +1,14 @@
+name: sched_stat_runtime
+ID: 98
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+ field:u64 runtime; offset:32; size:8; signed:0;
+ field:u64 vruntime; offset:40; size:8; signed:0;
+
+print fmt: "comm=%s pid=%d runtime=%Lu [ns] vruntime=%Lu [ns]", REC->comm, REC->pid, (unsigned long long)REC->runtime, (unsigned long long)REC->vruntime
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stat_sleep/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stat_sleep/format
new file mode 100644
index 000000000..2083810a1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stat_sleep/format
@@ -0,0 +1,13 @@
+name: sched_stat_sleep
+ID: 99
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+ field:u64 delay; offset:32; size:8; signed:0;
+
+print fmt: "comm=%s pid=%d delay=%Lu [ns]", REC->comm, REC->pid, (unsigned long long)REC->delay
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stat_wait/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stat_wait/format
new file mode 100644
index 000000000..5497bd1e0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stat_wait/format
@@ -0,0 +1,13 @@
+name: sched_stat_wait
+ID: 100
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+ field:u64 delay; offset:32; size:8; signed:0;
+
+print fmt: "comm=%s pid=%d delay=%Lu [ns]", REC->comm, REC->pid, (unsigned long long)REC->delay
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stick_numa/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stick_numa/format
new file mode 100644
index 000000000..747a276e5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_stick_numa/format
@@ -0,0 +1,20 @@
+name: sched_stick_numa
+ID: 101
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:pid_t src_pid; offset:8; size:4; signed:1;
+ field:pid_t src_tgid; offset:12; size:4; signed:1;
+ field:pid_t src_ngid; offset:16; size:4; signed:1;
+ field:int src_cpu; offset:20; size:4; signed:1;
+ field:int src_nid; offset:24; size:4; signed:1;
+ field:pid_t dst_pid; offset:28; size:4; signed:1;
+ field:pid_t dst_tgid; offset:32; size:4; signed:1;
+ field:pid_t dst_ngid; offset:36; size:4; signed:1;
+ field:int dst_cpu; offset:40; size:4; signed:1;
+ field:int dst_nid; offset:44; size:4; signed:1;
+
+print fmt: "src_pid=%d src_tgid=%d src_ngid=%d src_cpu=%d src_nid=%d dst_pid=%d dst_tgid=%d dst_ngid=%d dst_cpu=%d dst_nid=%d", REC->src_pid, REC->src_tgid, REC->src_ngid, REC->src_cpu, REC->src_nid, REC->dst_pid, REC->dst_tgid, REC->dst_ngid, REC->dst_cpu, REC->dst_nid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_swap_numa/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_swap_numa/format
new file mode 100644
index 000000000..ac88bc209
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_swap_numa/format
@@ -0,0 +1,20 @@
+name: sched_swap_numa
+ID: 102
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:pid_t src_pid; offset:8; size:4; signed:1;
+ field:pid_t src_tgid; offset:12; size:4; signed:1;
+ field:pid_t src_ngid; offset:16; size:4; signed:1;
+ field:int src_cpu; offset:20; size:4; signed:1;
+ field:int src_nid; offset:24; size:4; signed:1;
+ field:pid_t dst_pid; offset:28; size:4; signed:1;
+ field:pid_t dst_tgid; offset:32; size:4; signed:1;
+ field:pid_t dst_ngid; offset:36; size:4; signed:1;
+ field:int dst_cpu; offset:40; size:4; signed:1;
+ field:int dst_nid; offset:44; size:4; signed:1;
+
+print fmt: "src_pid=%d src_tgid=%d src_ngid=%d src_cpu=%d src_nid=%d dst_pid=%d dst_tgid=%d dst_ngid=%d dst_cpu=%d dst_nid=%d", REC->src_pid, REC->src_tgid, REC->src_ngid, REC->src_cpu, REC->src_nid, REC->dst_pid, REC->dst_tgid, REC->dst_ngid, REC->dst_cpu, REC->dst_nid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_switch/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_switch/format
new file mode 100644
index 000000000..571c4f945
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_switch/format
@@ -0,0 +1,17 @@
+name: sched_switch
+ID: 103
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char prev_comm[16]; offset:8; size:16; signed:0;
+ field:pid_t prev_pid; offset:24; size:4; signed:1;
+ field:int prev_prio; offset:28; size:4; signed:1;
+ field:long prev_state; offset:32; size:8; signed:1;
+ field:char next_comm[16]; offset:40; size:16; signed:0;
+ field:pid_t next_pid; offset:56; size:4; signed:1;
+ field:int next_prio; offset:60; size:4; signed:1;
+
+print fmt: "prev_comm=%s prev_pid=%d prev_prio=%d prev_state=%s%s ==> next_comm=%s next_pid=%d next_prio=%d", REC->prev_comm, REC->prev_pid, REC->prev_prio, (REC->prev_state & ((((0x0000 | 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040) + 1) << 1) - 1)) ? __print_flags(REC->prev_state & ((((0x0000 | 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040) + 1) << 1) - 1), "|", { 0x0001, "S" }, { 0x0002, "D" }, { 0x0004, "T" }, { 0x0008, "t" }, { 0x0010, "X" }, { 0x0020, "Z" }, { 0x0040, "P" }, { 0x0080, "I" }) : "R", REC->prev_state & (((0x0000 | 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040) + 1) << 1) ? "+" : "", REC->next_comm, REC->next_pid, REC->next_prio
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_util_est_cfs/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_util_est_cfs/format
new file mode 100644
index 000000000..29d0bb893
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_util_est_cfs/format
@@ -0,0 +1,15 @@
+name: sched_util_est_cfs
+ID: 1073
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int cpu; offset:8; size:4; signed:1;
+ field:char path[64]; offset:12; size:64; signed:0;
+ field:unsigned int enqueued; offset:76; size:4; signed:0;
+ field:unsigned int ewma; offset:80; size:4; signed:0;
+ field:unsigned long util; offset:88; size:8; signed:0;
+
+print fmt: "cpu=%d path=%s enqueued=%u ewma=%u util=%lu", REC->cpu, REC->path, REC->enqueued, REC->ewma, REC->util
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_util_est_se/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_util_est_se/format
new file mode 100644
index 000000000..b3babd579
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_util_est_se/format
@@ -0,0 +1,17 @@
+name: sched_util_est_se
+ID: 1074
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int cpu; offset:8; size:4; signed:1;
+ field:char path[64]; offset:12; size:64; signed:0;
+ field:char comm[16]; offset:76; size:16; signed:0;
+ field:int pid; offset:92; size:4; signed:1;
+ field:unsigned int enqueued; offset:96; size:4; signed:0;
+ field:unsigned int ewma; offset:100; size:4; signed:0;
+ field:unsigned long util; offset:104; size:8; signed:0;
+
+print fmt: "cpu=%d path=%s comm=%s pid=%d enqueued=%u ewma=%u util=%lu", REC->cpu, REC->path, REC->comm, REC->pid, REC->enqueued, REC->ewma, REC->util
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_wait_task/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_wait_task/format
new file mode 100644
index 000000000..a4695efc4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_wait_task/format
@@ -0,0 +1,13 @@
+name: sched_wait_task
+ID: 104
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+ field:int prio; offset:28; size:4; signed:1;
+
+print fmt: "comm=%s pid=%d prio=%d", REC->comm, REC->pid, REC->prio
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_wake_idle_without_ipi/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_wake_idle_without_ipi/format
new file mode 100644
index 000000000..00fd41683
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_wake_idle_without_ipi/format
@@ -0,0 +1,11 @@
+name: sched_wake_idle_without_ipi
+ID: 105
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int cpu; offset:8; size:4; signed:1;
+
+print fmt: "cpu=%d", REC->cpu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_wakeup/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_wakeup/format
new file mode 100644
index 000000000..64990c1d8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_wakeup/format
@@ -0,0 +1,15 @@
+name: sched_wakeup
+ID: 106
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+ field:int prio; offset:28; size:4; signed:1;
+ field:int success; offset:32; size:4; signed:1;
+ field:int target_cpu; offset:36; size:4; signed:1;
+
+print fmt: "comm=%s pid=%d prio=%d target_cpu=%03d", REC->comm, REC->pid, REC->prio, REC->target_cpu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_wakeup_new/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_wakeup_new/format
new file mode 100644
index 000000000..e98f5d4bd
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_wakeup_new/format
@@ -0,0 +1,15 @@
+name: sched_wakeup_new
+ID: 107
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+ field:int prio; offset:28; size:4; signed:1;
+ field:int success; offset:32; size:4; signed:1;
+ field:int target_cpu; offset:36; size:4; signed:1;
+
+print fmt: "comm=%s pid=%d prio=%d target_cpu=%03d", REC->comm, REC->pid, REC->prio, REC->target_cpu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_waking/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_waking/format
new file mode 100644
index 000000000..9eee914f5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sched_waking/format
@@ -0,0 +1,15 @@
+name: sched_waking
+ID: 108
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char comm[16]; offset:8; size:16; signed:0;
+ field:pid_t pid; offset:24; size:4; signed:1;
+ field:int prio; offset:28; size:4; signed:1;
+ field:int success; offset:32; size:4; signed:1;
+ field:int target_cpu; offset:36; size:4; signed:1;
+
+print fmt: "comm=%s pid=%d prio=%d target_cpu=%03d", REC->comm, REC->pid, REC->prio, REC->target_cpu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/schedutil_cpu_util_clamp/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/schedutil_cpu_util_clamp/format
new file mode 100644
index 000000000..0e0eca7df
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/schedutil_cpu_util_clamp/format
@@ -0,0 +1,15 @@
+name: schedutil_cpu_util_clamp
+ID: 1075
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int cpu; offset:8; size:4; signed:1;
+ field:unsigned long util_cfs; offset:16; size:8; signed:0;
+ field:unsigned long util_rt; offset:24; size:8; signed:0;
+ field:unsigned long util_clamp; offset:32; size:8; signed:0;
+ field:unsigned long util_max; offset:40; size:8; signed:0;
+
+print fmt: "cpu=%d util_cfs=%ld util_rt=%ld util_clamp=%ld util_max=%ld", REC->cpu, REC->util_cfs, REC->util_rt, REC->util_clamp, REC->util_max
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sugov_next_freq/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sugov_next_freq/format
new file mode 100644
index 000000000..09566a61d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sugov_next_freq/format
@@ -0,0 +1,14 @@
+name: sugov_next_freq
+ID: 1076
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int cpu; offset:8; size:4; signed:0;
+ field:unsigned long util; offset:16; size:8; signed:0;
+ field:unsigned long max; offset:24; size:8; signed:0;
+ field:unsigned int freq; offset:32; size:4; signed:0;
+
+print fmt: "cpu=%u util=%lu max=%lu freq=%u", REC->cpu, REC->util, REC->max, REC->freq
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sugov_util_update/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sugov_util_update/format
new file mode 100644
index 000000000..936e18676
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sched/sugov_util_update/format
@@ -0,0 +1,14 @@
+name: sugov_util_update
+ID: 1077
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int cpu; offset:8; size:4; signed:0;
+ field:unsigned long util; offset:16; size:8; signed:0;
+ field:unsigned long max_cap; offset:24; size:8; signed:0;
+ field:unsigned int flags; offset:32; size:4; signed:0;
+
+print fmt: "cpu=%u util=%lu max_cap=%lu flags=0x%x", REC->cpu, REC->util, REC->max_cap, REC->flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scmi/scmi_rx_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scmi/scmi_rx_done/format
new file mode 100644
index 000000000..01d432105
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scmi/scmi_rx_done/format
@@ -0,0 +1,15 @@
+name: scmi_rx_done
+ID: 863
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int transfer_id; offset:8; size:4; signed:1;
+ field:u8 msg_id; offset:12; size:1; signed:0;
+ field:u8 protocol_id; offset:13; size:1; signed:0;
+ field:u16 seq; offset:14; size:2; signed:0;
+ field:u8 msg_type; offset:16; size:1; signed:0;
+
+print fmt: "transfer_id=%d msg_id=%u protocol_id=%u seq=%u msg_type=%u", REC->transfer_id, REC->msg_id, REC->protocol_id, REC->seq, REC->msg_type
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scmi/scmi_xfer_begin/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scmi/scmi_xfer_begin/format
new file mode 100644
index 000000000..9e5d0ec1a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scmi/scmi_xfer_begin/format
@@ -0,0 +1,15 @@
+name: scmi_xfer_begin
+ID: 864
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int transfer_id; offset:8; size:4; signed:1;
+ field:u8 msg_id; offset:12; size:1; signed:0;
+ field:u8 protocol_id; offset:13; size:1; signed:0;
+ field:u16 seq; offset:14; size:2; signed:0;
+ field:bool poll; offset:16; size:1; signed:0;
+
+print fmt: "transfer_id=%d msg_id=%u protocol_id=%u seq=%u poll=%u", REC->transfer_id, REC->msg_id, REC->protocol_id, REC->seq, REC->poll
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scmi/scmi_xfer_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scmi/scmi_xfer_end/format
new file mode 100644
index 000000000..cb60a6805
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scmi/scmi_xfer_end/format
@@ -0,0 +1,15 @@
+name: scmi_xfer_end
+ID: 865
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int transfer_id; offset:8; size:4; signed:1;
+ field:u8 msg_id; offset:12; size:1; signed:0;
+ field:u8 protocol_id; offset:13; size:1; signed:0;
+ field:u16 seq; offset:14; size:2; signed:0;
+ field:int status; offset:16; size:4; signed:1;
+
+print fmt: "transfer_id=%d msg_id=%u protocol_id=%u seq=%u status=%d", REC->transfer_id, REC->msg_id, REC->protocol_id, REC->seq, REC->status
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scsi/scsi_dispatch_cmd_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scsi/scsi_dispatch_cmd_done/format
new file mode 100644
index 000000000..dbd9669e0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scsi/scsi_dispatch_cmd_done/format
@@ -0,0 +1,21 @@
+name: scsi_dispatch_cmd_done
+ID: 693
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int host_no; offset:8; size:4; signed:0;
+ field:unsigned int channel; offset:12; size:4; signed:0;
+ field:unsigned int id; offset:16; size:4; signed:0;
+ field:unsigned int lun; offset:20; size:4; signed:0;
+ field:int result; offset:24; size:4; signed:1;
+ field:unsigned int opcode; offset:28; size:4; signed:0;
+ field:unsigned int cmd_len; offset:32; size:4; signed:0;
+ field:unsigned int data_sglen; offset:36; size:4; signed:0;
+ field:unsigned int prot_sglen; offset:40; size:4; signed:0;
+ field:unsigned char prot_op; offset:44; size:1; signed:0;
+ field:__data_loc unsigned char[] cmnd; offset:48; size:4; signed:0;
+
+print fmt: "host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u prot_op=%s cmnd=(%s %s raw=%s) result=(driver=%s host=%s message=%s status=%s)", REC->host_no, REC->channel, REC->id, REC->lun, REC->data_sglen, REC->prot_sglen, __print_symbolic(REC->prot_op, { SCSI_PROT_NORMAL, "SCSI_PROT_NORMAL" }, { SCSI_PROT_READ_INSERT, "SCSI_PROT_READ_INSERT" }, { SCSI_PROT_WRITE_STRIP, "SCSI_PROT_WRITE_STRIP" }, { SCSI_PROT_READ_STRIP, "SCSI_PROT_READ_STRIP" }, { SCSI_PROT_WRITE_INSERT, "SCSI_PROT_WRITE_INSERT" }, { SCSI_PROT_READ_PASS, "SCSI_PROT_READ_PASS" }, { SCSI_PROT_WRITE_PASS, "SCSI_PROT_WRITE_PASS" }), __print_symbolic(REC->opcode, { 0x00, "TEST_UNIT_READY" }, { 0x01, "REZERO_UNIT" }, { 0x03, "REQUEST_SENSE" }, { 0x04, "FORMAT_UNIT" }, { 0x05, "READ_BLOCK_LIMITS" }, { 0x07, "REASSIGN_BLOCKS" }, { 0x07, "INITIALIZE_ELEMENT_STATUS" }, { 0x08, "READ_6" }, { 0x0a, "WRITE_6" }, { 0x0b, "SEEK_6" }, { 0x0f, "READ_REVERSE" }, { 0x10, "WRITE_FILEMARKS" }, { 0x11, "SPACE" }, { 0x12, "INQUIRY" }, { 0x14, "RECOVER_BUFFERED_DATA" }, { 0x15, "MODE_SELECT" }, { 0x16, "RESERVE" }, { 0x17, "RELEASE" }, { 0x18, "COPY" }, { 0x19, "ERASE" }, { 0x1a, "MODE_SENSE" }, { 0x1b, "START_STOP" }, { 0x1c, "RECEIVE_DIAGNOSTIC" }, { 0x1d, "SEND_DIAGNOSTIC" }, { 0x1e, "ALLOW_MEDIUM_REMOVAL" }, { 0x24, "SET_WINDOW" }, { 0x25, "READ_CAPACITY" }, { 0x28, "READ_10" }, { 0x2a, "WRITE_10" }, { 0x2b, "SEEK_10" }, { 0x2b, "POSITION_TO_ELEMENT" }, { 0x2e, "WRITE_VERIFY" }, { 0x2f, "VERIFY" }, { 0x30, "SEARCH_HIGH" }, { 0x31, "SEARCH_EQUAL" }, { 0x32, "SEARCH_LOW" }, { 0x33, "SET_LIMITS" }, { 0x34, "PRE_FETCH" }, { 0x34, "READ_POSITION" }, { 0x35, "SYNCHRONIZE_CACHE" }, { 0x36, "LOCK_UNLOCK_CACHE" }, { 0x37, "READ_DEFECT_DATA" }, { 0x38, "MEDIUM_SCAN" }, { 0x39, "COMPARE" }, { 0x3a, "COPY_VERIFY" }, { 0x3b, "WRITE_BUFFER" }, { 0x3c, "READ_BUFFER" }, { 0x3d, "UPDATE_BLOCK" }, { 0x3e, "READ_LONG" }, { 0x3f, "WRITE_LONG" }, { 0x40, "CHANGE_DEFINITION" }, { 0x41, "WRITE_SAME" }, { 0x42, "UNMAP" }, { 0x43, "READ_TOC" }, { 0x4c, "LOG_SELECT" }, { 0x4d, "LOG_SENSE" }, { 0x53, "XDWRITEREAD_10" }, { 0x55, "MODE_SELECT_10" }, { 0x56, "RESERVE_10" }, { 0x57, "RELEASE_10" }, { 0x5a, "MODE_SENSE_10" }, { 0x5e, "PERSISTENT_RESERVE_IN" }, { 0x5f, "PERSISTENT_RESERVE_OUT" }, { 0x7f, "VARIABLE_LENGTH_CMD" }, { 0xa0, "REPORT_LUNS" }, { 0xa3, "MAINTENANCE_IN" }, { 0xa4, "MAINTENANCE_OUT" }, { 0xa5, "MOVE_MEDIUM" }, { 0xa6, "EXCHANGE_MEDIUM" }, { 0xa8, "READ_12" }, { 0xaa, "WRITE_12" }, { 0xae, "WRITE_VERIFY_12" }, { 0xb0, "SEARCH_HIGH_12" }, { 0xb1, "SEARCH_EQUAL_12" }, { 0xb2, "SEARCH_LOW_12" }, { 0xb8, "READ_ELEMENT_STATUS" }, { 0xb6, "SEND_VOLUME_TAG" }, { 0xea, "WRITE_LONG_2" }, { 0x88, "READ_16" }, { 0x8a, "WRITE_16" }, { 0x8f, "VERIFY_16" }, { 0x93, "WRITE_SAME_16" }, { 0x94, "ZBC_OUT" }, { 0x95, "ZBC_IN" }, { 0x9e, "SERVICE_ACTION_IN_16" }, { 0x09, "READ_32" }, { 0x0b, "WRITE_32" }, { 0x0d, "WRITE_SAME_32" }, { 0x85, "ATA_16" }, { 0xa1, "ATA_12" }), scsi_trace_parse_cdb(p, __get_dynamic_array(cmnd), REC->cmd_len), __print_hex(__get_dynamic_array(cmnd), REC->cmd_len), __print_symbolic(((REC->result) >> 24) & 0xff, { 0x00, "DRIVER_OK" }, { 0x01, "DRIVER_BUSY" }, { 0x02, "DRIVER_SOFT" }, { 0x03, "DRIVER_MEDIA" }, { 0x04, "DRIVER_ERROR" }, { 0x05, "DRIVER_INVALID" }, { 0x06, "DRIVER_TIMEOUT" }, { 0x07, "DRIVER_HARD" }, { 0x08, "DRIVER_SENSE" }), __print_symbolic(((REC->result) >> 16) & 0xff, { 0x00, "DID_OK" }, { 0x01, "DID_NO_CONNECT" }, { 0x02, "DID_BUS_BUSY" }, { 0x03, "DID_TIME_OUT" }, { 0x04, "DID_BAD_TARGET" }, { 0x05, "DID_ABORT" }, { 0x06, "DID_PARITY" }, { 0x07, "DID_ERROR" }, { 0x08, "DID_RESET" }, { 0x09, "DID_BAD_INTR" }, { 0x0a, "DID_PASSTHROUGH" }, { 0x0b, "DID_SOFT_ERROR" }, { 0x0c, "DID_IMM_RETRY" }, { 0x0d, "DID_REQUEUE" }, { 0x0e, "DID_TRANSPORT_DISRUPTED" }, { 0x0f, "DID_TRANSPORT_FAILFAST" }), __print_symbolic(((REC->result) >> 8) & 0xff, { 0x00, "COMMAND_COMPLETE" }, { 0x01, "EXTENDED_MESSAGE" }, { 0x02, "SAVE_POINTERS" }, { 0x03, "RESTORE_POINTERS" }, { 0x04, "DISCONNECT" }, { 0x05, "INITIATOR_ERROR" }, { 0x06, "ABORT_TASK_SET" }, { 0x07, "MESSAGE_REJECT" }, { 0x08, "NOP" }, { 0x09, "MSG_PARITY_ERROR" }, { 0x0a, "LINKED_CMD_COMPLETE" }, { 0x0b, "LINKED_FLG_CMD_COMPLETE" }, { 0x0c, "TARGET_RESET" }, { 0x0d, "ABORT_TASK" }, { 0x0e, "CLEAR_TASK_SET" }, { 0x0f, "INITIATE_RECOVERY" }, { 0x10, "RELEASE_RECOVERY" }, { 0x16, "CLEAR_ACA" }, { 0x17, "LOGICAL_UNIT_RESET" }, { 0x20, "SIMPLE_QUEUE_TAG" }, { 0x21, "HEAD_OF_QUEUE_TAG" }, { 0x22, "ORDERED_QUEUE_TAG" }, { 0x23, "IGNORE_WIDE_RESIDUE" }, { 0x24, "ACA" }, { 0x55, "QAS_REQUEST" }, { 0x0c, "BUS_DEVICE_RESET" }, { 0x06, "ABORT" }), __print_symbolic(REC->result & 0xff, { 0x00, "SAM_STAT_GOOD" }, { 0x02, "SAM_STAT_CHECK_CONDITION" }, { 0x04, "SAM_STAT_CONDITION_MET" }, { 0x08, "SAM_STAT_BUSY" }, { 0x10, "SAM_STAT_INTERMEDIATE" }, { 0x14, "SAM_STAT_INTERMEDIATE_CONDITION_MET" }, { 0x18, "SAM_STAT_RESERVATION_CONFLICT" }, { 0x22, "SAM_STAT_COMMAND_TERMINATED" }, { 0x28, "SAM_STAT_TASK_SET_FULL" }, { 0x30, "SAM_STAT_ACA_ACTIVE" }, { 0x40, "SAM_STAT_TASK_ABORTED" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scsi/scsi_dispatch_cmd_error/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scsi/scsi_dispatch_cmd_error/format
new file mode 100644
index 000000000..2d8e79b45
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scsi/scsi_dispatch_cmd_error/format
@@ -0,0 +1,21 @@
+name: scsi_dispatch_cmd_error
+ID: 694
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int host_no; offset:8; size:4; signed:0;
+ field:unsigned int channel; offset:12; size:4; signed:0;
+ field:unsigned int id; offset:16; size:4; signed:0;
+ field:unsigned int lun; offset:20; size:4; signed:0;
+ field:int rtn; offset:24; size:4; signed:1;
+ field:unsigned int opcode; offset:28; size:4; signed:0;
+ field:unsigned int cmd_len; offset:32; size:4; signed:0;
+ field:unsigned int data_sglen; offset:36; size:4; signed:0;
+ field:unsigned int prot_sglen; offset:40; size:4; signed:0;
+ field:unsigned char prot_op; offset:44; size:1; signed:0;
+ field:__data_loc unsigned char[] cmnd; offset:48; size:4; signed:0;
+
+print fmt: "host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u prot_op=%s cmnd=(%s %s raw=%s) rtn=%d", REC->host_no, REC->channel, REC->id, REC->lun, REC->data_sglen, REC->prot_sglen, __print_symbolic(REC->prot_op, { SCSI_PROT_NORMAL, "SCSI_PROT_NORMAL" }, { SCSI_PROT_READ_INSERT, "SCSI_PROT_READ_INSERT" }, { SCSI_PROT_WRITE_STRIP, "SCSI_PROT_WRITE_STRIP" }, { SCSI_PROT_READ_STRIP, "SCSI_PROT_READ_STRIP" }, { SCSI_PROT_WRITE_INSERT, "SCSI_PROT_WRITE_INSERT" }, { SCSI_PROT_READ_PASS, "SCSI_PROT_READ_PASS" }, { SCSI_PROT_WRITE_PASS, "SCSI_PROT_WRITE_PASS" }), __print_symbolic(REC->opcode, { 0x00, "TEST_UNIT_READY" }, { 0x01, "REZERO_UNIT" }, { 0x03, "REQUEST_SENSE" }, { 0x04, "FORMAT_UNIT" }, { 0x05, "READ_BLOCK_LIMITS" }, { 0x07, "REASSIGN_BLOCKS" }, { 0x07, "INITIALIZE_ELEMENT_STATUS" }, { 0x08, "READ_6" }, { 0x0a, "WRITE_6" }, { 0x0b, "SEEK_6" }, { 0x0f, "READ_REVERSE" }, { 0x10, "WRITE_FILEMARKS" }, { 0x11, "SPACE" }, { 0x12, "INQUIRY" }, { 0x14, "RECOVER_BUFFERED_DATA" }, { 0x15, "MODE_SELECT" }, { 0x16, "RESERVE" }, { 0x17, "RELEASE" }, { 0x18, "COPY" }, { 0x19, "ERASE" }, { 0x1a, "MODE_SENSE" }, { 0x1b, "START_STOP" }, { 0x1c, "RECEIVE_DIAGNOSTIC" }, { 0x1d, "SEND_DIAGNOSTIC" }, { 0x1e, "ALLOW_MEDIUM_REMOVAL" }, { 0x24, "SET_WINDOW" }, { 0x25, "READ_CAPACITY" }, { 0x28, "READ_10" }, { 0x2a, "WRITE_10" }, { 0x2b, "SEEK_10" }, { 0x2b, "POSITION_TO_ELEMENT" }, { 0x2e, "WRITE_VERIFY" }, { 0x2f, "VERIFY" }, { 0x30, "SEARCH_HIGH" }, { 0x31, "SEARCH_EQUAL" }, { 0x32, "SEARCH_LOW" }, { 0x33, "SET_LIMITS" }, { 0x34, "PRE_FETCH" }, { 0x34, "READ_POSITION" }, { 0x35, "SYNCHRONIZE_CACHE" }, { 0x36, "LOCK_UNLOCK_CACHE" }, { 0x37, "READ_DEFECT_DATA" }, { 0x38, "MEDIUM_SCAN" }, { 0x39, "COMPARE" }, { 0x3a, "COPY_VERIFY" }, { 0x3b, "WRITE_BUFFER" }, { 0x3c, "READ_BUFFER" }, { 0x3d, "UPDATE_BLOCK" }, { 0x3e, "READ_LONG" }, { 0x3f, "WRITE_LONG" }, { 0x40, "CHANGE_DEFINITION" }, { 0x41, "WRITE_SAME" }, { 0x42, "UNMAP" }, { 0x43, "READ_TOC" }, { 0x4c, "LOG_SELECT" }, { 0x4d, "LOG_SENSE" }, { 0x53, "XDWRITEREAD_10" }, { 0x55, "MODE_SELECT_10" }, { 0x56, "RESERVE_10" }, { 0x57, "RELEASE_10" }, { 0x5a, "MODE_SENSE_10" }, { 0x5e, "PERSISTENT_RESERVE_IN" }, { 0x5f, "PERSISTENT_RESERVE_OUT" }, { 0x7f, "VARIABLE_LENGTH_CMD" }, { 0xa0, "REPORT_LUNS" }, { 0xa3, "MAINTENANCE_IN" }, { 0xa4, "MAINTENANCE_OUT" }, { 0xa5, "MOVE_MEDIUM" }, { 0xa6, "EXCHANGE_MEDIUM" }, { 0xa8, "READ_12" }, { 0xaa, "WRITE_12" }, { 0xae, "WRITE_VERIFY_12" }, { 0xb0, "SEARCH_HIGH_12" }, { 0xb1, "SEARCH_EQUAL_12" }, { 0xb2, "SEARCH_LOW_12" }, { 0xb8, "READ_ELEMENT_STATUS" }, { 0xb6, "SEND_VOLUME_TAG" }, { 0xea, "WRITE_LONG_2" }, { 0x88, "READ_16" }, { 0x8a, "WRITE_16" }, { 0x8f, "VERIFY_16" }, { 0x93, "WRITE_SAME_16" }, { 0x94, "ZBC_OUT" }, { 0x95, "ZBC_IN" }, { 0x9e, "SERVICE_ACTION_IN_16" }, { 0x09, "READ_32" }, { 0x0b, "WRITE_32" }, { 0x0d, "WRITE_SAME_32" }, { 0x85, "ATA_16" }, { 0xa1, "ATA_12" }), scsi_trace_parse_cdb(p, __get_dynamic_array(cmnd), REC->cmd_len), __print_hex(__get_dynamic_array(cmnd), REC->cmd_len), REC->rtn
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scsi/scsi_dispatch_cmd_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scsi/scsi_dispatch_cmd_start/format
new file mode 100644
index 000000000..3d04b658b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scsi/scsi_dispatch_cmd_start/format
@@ -0,0 +1,20 @@
+name: scsi_dispatch_cmd_start
+ID: 695
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int host_no; offset:8; size:4; signed:0;
+ field:unsigned int channel; offset:12; size:4; signed:0;
+ field:unsigned int id; offset:16; size:4; signed:0;
+ field:unsigned int lun; offset:20; size:4; signed:0;
+ field:unsigned int opcode; offset:24; size:4; signed:0;
+ field:unsigned int cmd_len; offset:28; size:4; signed:0;
+ field:unsigned int data_sglen; offset:32; size:4; signed:0;
+ field:unsigned int prot_sglen; offset:36; size:4; signed:0;
+ field:unsigned char prot_op; offset:40; size:1; signed:0;
+ field:__data_loc unsigned char[] cmnd; offset:44; size:4; signed:0;
+
+print fmt: "host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u prot_op=%s cmnd=(%s %s raw=%s)", REC->host_no, REC->channel, REC->id, REC->lun, REC->data_sglen, REC->prot_sglen, __print_symbolic(REC->prot_op, { SCSI_PROT_NORMAL, "SCSI_PROT_NORMAL" }, { SCSI_PROT_READ_INSERT, "SCSI_PROT_READ_INSERT" }, { SCSI_PROT_WRITE_STRIP, "SCSI_PROT_WRITE_STRIP" }, { SCSI_PROT_READ_STRIP, "SCSI_PROT_READ_STRIP" }, { SCSI_PROT_WRITE_INSERT, "SCSI_PROT_WRITE_INSERT" }, { SCSI_PROT_READ_PASS, "SCSI_PROT_READ_PASS" }, { SCSI_PROT_WRITE_PASS, "SCSI_PROT_WRITE_PASS" }), __print_symbolic(REC->opcode, { 0x00, "TEST_UNIT_READY" }, { 0x01, "REZERO_UNIT" }, { 0x03, "REQUEST_SENSE" }, { 0x04, "FORMAT_UNIT" }, { 0x05, "READ_BLOCK_LIMITS" }, { 0x07, "REASSIGN_BLOCKS" }, { 0x07, "INITIALIZE_ELEMENT_STATUS" }, { 0x08, "READ_6" }, { 0x0a, "WRITE_6" }, { 0x0b, "SEEK_6" }, { 0x0f, "READ_REVERSE" }, { 0x10, "WRITE_FILEMARKS" }, { 0x11, "SPACE" }, { 0x12, "INQUIRY" }, { 0x14, "RECOVER_BUFFERED_DATA" }, { 0x15, "MODE_SELECT" }, { 0x16, "RESERVE" }, { 0x17, "RELEASE" }, { 0x18, "COPY" }, { 0x19, "ERASE" }, { 0x1a, "MODE_SENSE" }, { 0x1b, "START_STOP" }, { 0x1c, "RECEIVE_DIAGNOSTIC" }, { 0x1d, "SEND_DIAGNOSTIC" }, { 0x1e, "ALLOW_MEDIUM_REMOVAL" }, { 0x24, "SET_WINDOW" }, { 0x25, "READ_CAPACITY" }, { 0x28, "READ_10" }, { 0x2a, "WRITE_10" }, { 0x2b, "SEEK_10" }, { 0x2b, "POSITION_TO_ELEMENT" }, { 0x2e, "WRITE_VERIFY" }, { 0x2f, "VERIFY" }, { 0x30, "SEARCH_HIGH" }, { 0x31, "SEARCH_EQUAL" }, { 0x32, "SEARCH_LOW" }, { 0x33, "SET_LIMITS" }, { 0x34, "PRE_FETCH" }, { 0x34, "READ_POSITION" }, { 0x35, "SYNCHRONIZE_CACHE" }, { 0x36, "LOCK_UNLOCK_CACHE" }, { 0x37, "READ_DEFECT_DATA" }, { 0x38, "MEDIUM_SCAN" }, { 0x39, "COMPARE" }, { 0x3a, "COPY_VERIFY" }, { 0x3b, "WRITE_BUFFER" }, { 0x3c, "READ_BUFFER" }, { 0x3d, "UPDATE_BLOCK" }, { 0x3e, "READ_LONG" }, { 0x3f, "WRITE_LONG" }, { 0x40, "CHANGE_DEFINITION" }, { 0x41, "WRITE_SAME" }, { 0x42, "UNMAP" }, { 0x43, "READ_TOC" }, { 0x4c, "LOG_SELECT" }, { 0x4d, "LOG_SENSE" }, { 0x53, "XDWRITEREAD_10" }, { 0x55, "MODE_SELECT_10" }, { 0x56, "RESERVE_10" }, { 0x57, "RELEASE_10" }, { 0x5a, "MODE_SENSE_10" }, { 0x5e, "PERSISTENT_RESERVE_IN" }, { 0x5f, "PERSISTENT_RESERVE_OUT" }, { 0x7f, "VARIABLE_LENGTH_CMD" }, { 0xa0, "REPORT_LUNS" }, { 0xa3, "MAINTENANCE_IN" }, { 0xa4, "MAINTENANCE_OUT" }, { 0xa5, "MOVE_MEDIUM" }, { 0xa6, "EXCHANGE_MEDIUM" }, { 0xa8, "READ_12" }, { 0xaa, "WRITE_12" }, { 0xae, "WRITE_VERIFY_12" }, { 0xb0, "SEARCH_HIGH_12" }, { 0xb1, "SEARCH_EQUAL_12" }, { 0xb2, "SEARCH_LOW_12" }, { 0xb8, "READ_ELEMENT_STATUS" }, { 0xb6, "SEND_VOLUME_TAG" }, { 0xea, "WRITE_LONG_2" }, { 0x88, "READ_16" }, { 0x8a, "WRITE_16" }, { 0x8f, "VERIFY_16" }, { 0x93, "WRITE_SAME_16" }, { 0x94, "ZBC_OUT" }, { 0x95, "ZBC_IN" }, { 0x9e, "SERVICE_ACTION_IN_16" }, { 0x09, "READ_32" }, { 0x0b, "WRITE_32" }, { 0x0d, "WRITE_SAME_32" }, { 0x85, "ATA_16" }, { 0xa1, "ATA_12" }), scsi_trace_parse_cdb(p, __get_dynamic_array(cmnd), REC->cmd_len), __print_hex(__get_dynamic_array(cmnd), REC->cmd_len)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scsi/scsi_dispatch_cmd_timeout/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scsi/scsi_dispatch_cmd_timeout/format
new file mode 100644
index 000000000..9fa450b0e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scsi/scsi_dispatch_cmd_timeout/format
@@ -0,0 +1,21 @@
+name: scsi_dispatch_cmd_timeout
+ID: 696
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int host_no; offset:8; size:4; signed:0;
+ field:unsigned int channel; offset:12; size:4; signed:0;
+ field:unsigned int id; offset:16; size:4; signed:0;
+ field:unsigned int lun; offset:20; size:4; signed:0;
+ field:int result; offset:24; size:4; signed:1;
+ field:unsigned int opcode; offset:28; size:4; signed:0;
+ field:unsigned int cmd_len; offset:32; size:4; signed:0;
+ field:unsigned int data_sglen; offset:36; size:4; signed:0;
+ field:unsigned int prot_sglen; offset:40; size:4; signed:0;
+ field:unsigned char prot_op; offset:44; size:1; signed:0;
+ field:__data_loc unsigned char[] cmnd; offset:48; size:4; signed:0;
+
+print fmt: "host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u prot_op=%s cmnd=(%s %s raw=%s) result=(driver=%s host=%s message=%s status=%s)", REC->host_no, REC->channel, REC->id, REC->lun, REC->data_sglen, REC->prot_sglen, __print_symbolic(REC->prot_op, { SCSI_PROT_NORMAL, "SCSI_PROT_NORMAL" }, { SCSI_PROT_READ_INSERT, "SCSI_PROT_READ_INSERT" }, { SCSI_PROT_WRITE_STRIP, "SCSI_PROT_WRITE_STRIP" }, { SCSI_PROT_READ_STRIP, "SCSI_PROT_READ_STRIP" }, { SCSI_PROT_WRITE_INSERT, "SCSI_PROT_WRITE_INSERT" }, { SCSI_PROT_READ_PASS, "SCSI_PROT_READ_PASS" }, { SCSI_PROT_WRITE_PASS, "SCSI_PROT_WRITE_PASS" }), __print_symbolic(REC->opcode, { 0x00, "TEST_UNIT_READY" }, { 0x01, "REZERO_UNIT" }, { 0x03, "REQUEST_SENSE" }, { 0x04, "FORMAT_UNIT" }, { 0x05, "READ_BLOCK_LIMITS" }, { 0x07, "REASSIGN_BLOCKS" }, { 0x07, "INITIALIZE_ELEMENT_STATUS" }, { 0x08, "READ_6" }, { 0x0a, "WRITE_6" }, { 0x0b, "SEEK_6" }, { 0x0f, "READ_REVERSE" }, { 0x10, "WRITE_FILEMARKS" }, { 0x11, "SPACE" }, { 0x12, "INQUIRY" }, { 0x14, "RECOVER_BUFFERED_DATA" }, { 0x15, "MODE_SELECT" }, { 0x16, "RESERVE" }, { 0x17, "RELEASE" }, { 0x18, "COPY" }, { 0x19, "ERASE" }, { 0x1a, "MODE_SENSE" }, { 0x1b, "START_STOP" }, { 0x1c, "RECEIVE_DIAGNOSTIC" }, { 0x1d, "SEND_DIAGNOSTIC" }, { 0x1e, "ALLOW_MEDIUM_REMOVAL" }, { 0x24, "SET_WINDOW" }, { 0x25, "READ_CAPACITY" }, { 0x28, "READ_10" }, { 0x2a, "WRITE_10" }, { 0x2b, "SEEK_10" }, { 0x2b, "POSITION_TO_ELEMENT" }, { 0x2e, "WRITE_VERIFY" }, { 0x2f, "VERIFY" }, { 0x30, "SEARCH_HIGH" }, { 0x31, "SEARCH_EQUAL" }, { 0x32, "SEARCH_LOW" }, { 0x33, "SET_LIMITS" }, { 0x34, "PRE_FETCH" }, { 0x34, "READ_POSITION" }, { 0x35, "SYNCHRONIZE_CACHE" }, { 0x36, "LOCK_UNLOCK_CACHE" }, { 0x37, "READ_DEFECT_DATA" }, { 0x38, "MEDIUM_SCAN" }, { 0x39, "COMPARE" }, { 0x3a, "COPY_VERIFY" }, { 0x3b, "WRITE_BUFFER" }, { 0x3c, "READ_BUFFER" }, { 0x3d, "UPDATE_BLOCK" }, { 0x3e, "READ_LONG" }, { 0x3f, "WRITE_LONG" }, { 0x40, "CHANGE_DEFINITION" }, { 0x41, "WRITE_SAME" }, { 0x42, "UNMAP" }, { 0x43, "READ_TOC" }, { 0x4c, "LOG_SELECT" }, { 0x4d, "LOG_SENSE" }, { 0x53, "XDWRITEREAD_10" }, { 0x55, "MODE_SELECT_10" }, { 0x56, "RESERVE_10" }, { 0x57, "RELEASE_10" }, { 0x5a, "MODE_SENSE_10" }, { 0x5e, "PERSISTENT_RESERVE_IN" }, { 0x5f, "PERSISTENT_RESERVE_OUT" }, { 0x7f, "VARIABLE_LENGTH_CMD" }, { 0xa0, "REPORT_LUNS" }, { 0xa3, "MAINTENANCE_IN" }, { 0xa4, "MAINTENANCE_OUT" }, { 0xa5, "MOVE_MEDIUM" }, { 0xa6, "EXCHANGE_MEDIUM" }, { 0xa8, "READ_12" }, { 0xaa, "WRITE_12" }, { 0xae, "WRITE_VERIFY_12" }, { 0xb0, "SEARCH_HIGH_12" }, { 0xb1, "SEARCH_EQUAL_12" }, { 0xb2, "SEARCH_LOW_12" }, { 0xb8, "READ_ELEMENT_STATUS" }, { 0xb6, "SEND_VOLUME_TAG" }, { 0xea, "WRITE_LONG_2" }, { 0x88, "READ_16" }, { 0x8a, "WRITE_16" }, { 0x8f, "VERIFY_16" }, { 0x93, "WRITE_SAME_16" }, { 0x94, "ZBC_OUT" }, { 0x95, "ZBC_IN" }, { 0x9e, "SERVICE_ACTION_IN_16" }, { 0x09, "READ_32" }, { 0x0b, "WRITE_32" }, { 0x0d, "WRITE_SAME_32" }, { 0x85, "ATA_16" }, { 0xa1, "ATA_12" }), scsi_trace_parse_cdb(p, __get_dynamic_array(cmnd), REC->cmd_len), __print_hex(__get_dynamic_array(cmnd), REC->cmd_len), __print_symbolic(((REC->result) >> 24) & 0xff, { 0x00, "DRIVER_OK" }, { 0x01, "DRIVER_BUSY" }, { 0x02, "DRIVER_SOFT" }, { 0x03, "DRIVER_MEDIA" }, { 0x04, "DRIVER_ERROR" }, { 0x05, "DRIVER_INVALID" }, { 0x06, "DRIVER_TIMEOUT" }, { 0x07, "DRIVER_HARD" }, { 0x08, "DRIVER_SENSE" }), __print_symbolic(((REC->result) >> 16) & 0xff, { 0x00, "DID_OK" }, { 0x01, "DID_NO_CONNECT" }, { 0x02, "DID_BUS_BUSY" }, { 0x03, "DID_TIME_OUT" }, { 0x04, "DID_BAD_TARGET" }, { 0x05, "DID_ABORT" }, { 0x06, "DID_PARITY" }, { 0x07, "DID_ERROR" }, { 0x08, "DID_RESET" }, { 0x09, "DID_BAD_INTR" }, { 0x0a, "DID_PASSTHROUGH" }, { 0x0b, "DID_SOFT_ERROR" }, { 0x0c, "DID_IMM_RETRY" }, { 0x0d, "DID_REQUEUE" }, { 0x0e, "DID_TRANSPORT_DISRUPTED" }, { 0x0f, "DID_TRANSPORT_FAILFAST" }), __print_symbolic(((REC->result) >> 8) & 0xff, { 0x00, "COMMAND_COMPLETE" }, { 0x01, "EXTENDED_MESSAGE" }, { 0x02, "SAVE_POINTERS" }, { 0x03, "RESTORE_POINTERS" }, { 0x04, "DISCONNECT" }, { 0x05, "INITIATOR_ERROR" }, { 0x06, "ABORT_TASK_SET" }, { 0x07, "MESSAGE_REJECT" }, { 0x08, "NOP" }, { 0x09, "MSG_PARITY_ERROR" }, { 0x0a, "LINKED_CMD_COMPLETE" }, { 0x0b, "LINKED_FLG_CMD_COMPLETE" }, { 0x0c, "TARGET_RESET" }, { 0x0d, "ABORT_TASK" }, { 0x0e, "CLEAR_TASK_SET" }, { 0x0f, "INITIATE_RECOVERY" }, { 0x10, "RELEASE_RECOVERY" }, { 0x16, "CLEAR_ACA" }, { 0x17, "LOGICAL_UNIT_RESET" }, { 0x20, "SIMPLE_QUEUE_TAG" }, { 0x21, "HEAD_OF_QUEUE_TAG" }, { 0x22, "ORDERED_QUEUE_TAG" }, { 0x23, "IGNORE_WIDE_RESIDUE" }, { 0x24, "ACA" }, { 0x55, "QAS_REQUEST" }, { 0x0c, "BUS_DEVICE_RESET" }, { 0x06, "ABORT" }), __print_symbolic(REC->result & 0xff, { 0x00, "SAM_STAT_GOOD" }, { 0x02, "SAM_STAT_CHECK_CONDITION" }, { 0x04, "SAM_STAT_CONDITION_MET" }, { 0x08, "SAM_STAT_BUSY" }, { 0x10, "SAM_STAT_INTERMEDIATE" }, { 0x14, "SAM_STAT_INTERMEDIATE_CONDITION_MET" }, { 0x18, "SAM_STAT_RESERVATION_CONFLICT" }, { 0x22, "SAM_STAT_COMMAND_TERMINATED" }, { 0x28, "SAM_STAT_TASK_SET_FULL" }, { 0x30, "SAM_STAT_ACA_ACTIVE" }, { 0x40, "SAM_STAT_TASK_ABORTED" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scsi/scsi_eh_wakeup/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scsi/scsi_eh_wakeup/format
new file mode 100644
index 000000000..d5c4fed36
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/scsi/scsi_eh_wakeup/format
@@ -0,0 +1,11 @@
+name: scsi_eh_wakeup
+ID: 697
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int host_no; offset:8; size:4; signed:0;
+
+print fmt: "host_no=%u", REC->host_no
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/signal/signal_deliver/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/signal/signal_deliver/format
new file mode 100644
index 000000000..15b4ab470
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/signal/signal_deliver/format
@@ -0,0 +1,15 @@
+name: signal_deliver
+ID: 78
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int sig; offset:8; size:4; signed:1;
+ field:int errno; offset:12; size:4; signed:1;
+ field:int code; offset:16; size:4; signed:1;
+ field:unsigned long sa_handler; offset:24; size:8; signed:0;
+ field:unsigned long sa_flags; offset:32; size:8; signed:0;
+
+print fmt: "sig=%d errno=%d code=%d sa_handler=%lx sa_flags=%lx", REC->sig, REC->errno, REC->code, REC->sa_handler, REC->sa_flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/signal/signal_generate/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/signal/signal_generate/format
new file mode 100644
index 000000000..5770ae33e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/signal/signal_generate/format
@@ -0,0 +1,17 @@
+name: signal_generate
+ID: 79
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int sig; offset:8; size:4; signed:1;
+ field:int errno; offset:12; size:4; signed:1;
+ field:int code; offset:16; size:4; signed:1;
+ field:char comm[16]; offset:20; size:16; signed:0;
+ field:pid_t pid; offset:36; size:4; signed:1;
+ field:int group; offset:40; size:4; signed:1;
+ field:int result; offset:44; size:4; signed:1;
+
+print fmt: "sig=%d errno=%d code=%d comm=%s pid=%d grp=%d res=%d", REC->sig, REC->errno, REC->code, REC->comm, REC->pid, REC->group, REC->result
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/skb/consume_skb/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/skb/consume_skb/format
new file mode 100644
index 000000000..bd2725084
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/skb/consume_skb/format
@@ -0,0 +1,11 @@
+name: consume_skb
+ID: 921
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * skbaddr; offset:8; size:8; signed:0;
+
+print fmt: "skbaddr=%p", REC->skbaddr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/skb/kfree_skb/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/skb/kfree_skb/format
new file mode 100644
index 000000000..5f55e2062
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/skb/kfree_skb/format
@@ -0,0 +1,13 @@
+name: kfree_skb
+ID: 925
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * skbaddr; offset:8; size:8; signed:0;
+ field:void * location; offset:16; size:8; signed:0;
+ field:unsigned short protocol; offset:24; size:2; signed:0;
+
+print fmt: "skbaddr=%p protocol=%u location=%p", REC->skbaddr, REC->protocol, REC->location
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/skb/skb_copy_datagram_iovec/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/skb/skb_copy_datagram_iovec/format
new file mode 100644
index 000000000..17c2a59cb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/skb/skb_copy_datagram_iovec/format
@@ -0,0 +1,12 @@
+name: skb_copy_datagram_iovec
+ID: 960
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const void * skbaddr; offset:8; size:8; signed:0;
+ field:int len; offset:16; size:4; signed:1;
+
+print fmt: "skbaddr=%p len=%d", REC->skbaddr, REC->len
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/smbus/smbus_read/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/smbus/smbus_read/format
new file mode 100644
index 000000000..97a3c4519
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/smbus/smbus_read/format
@@ -0,0 +1,16 @@
+name: smbus_read
+ID: 838
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int adapter_nr; offset:8; size:4; signed:1;
+ field:__u16 flags; offset:12; size:2; signed:0;
+ field:__u16 addr; offset:14; size:2; signed:0;
+ field:__u8 command; offset:16; size:1; signed:0;
+ field:__u32 protocol; offset:20; size:4; signed:0;
+ field:__u8 buf[32 + 2]; offset:24; size:34; signed:0;
+
+print fmt: "i2c-%d a=%03x f=%04x c=%x %s", REC->adapter_nr, REC->addr, REC->flags, REC->command, __print_symbolic(REC->protocol, { 0, "QUICK" }, { 1, "BYTE" }, { 2, "BYTE_DATA" }, { 3, "WORD_DATA" }, { 4, "PROC_CALL" }, { 5, "BLOCK_DATA" }, { 6, "I2C_BLOCK_BROKEN" }, { 7, "BLOCK_PROC_CALL" }, { 8, "I2C_BLOCK_DATA" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/smbus/smbus_reply/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/smbus/smbus_reply/format
new file mode 100644
index 000000000..8738b9fd6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/smbus/smbus_reply/format
@@ -0,0 +1,17 @@
+name: smbus_reply
+ID: 839
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int adapter_nr; offset:8; size:4; signed:1;
+ field:__u16 addr; offset:12; size:2; signed:0;
+ field:__u16 flags; offset:14; size:2; signed:0;
+ field:__u8 command; offset:16; size:1; signed:0;
+ field:__u8 len; offset:17; size:1; signed:0;
+ field:__u32 protocol; offset:20; size:4; signed:0;
+ field:__u8 buf[32 + 2]; offset:24; size:34; signed:0;
+
+print fmt: "i2c-%d a=%03x f=%04x c=%x %s l=%u [%*phD]", REC->adapter_nr, REC->addr, REC->flags, REC->command, __print_symbolic(REC->protocol, { 0, "QUICK" }, { 1, "BYTE" }, { 2, "BYTE_DATA" }, { 3, "WORD_DATA" }, { 4, "PROC_CALL" }, { 5, "BLOCK_DATA" }, { 6, "I2C_BLOCK_BROKEN" }, { 7, "BLOCK_PROC_CALL" }, { 8, "I2C_BLOCK_DATA" }), REC->len, REC->len, REC->buf
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/smbus/smbus_result/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/smbus/smbus_result/format
new file mode 100644
index 000000000..d581d82c0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/smbus/smbus_result/format
@@ -0,0 +1,17 @@
+name: smbus_result
+ID: 840
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int adapter_nr; offset:8; size:4; signed:1;
+ field:__u16 addr; offset:12; size:2; signed:0;
+ field:__u16 flags; offset:14; size:2; signed:0;
+ field:__u8 read_write; offset:16; size:1; signed:0;
+ field:__u8 command; offset:17; size:1; signed:0;
+ field:__s16 res; offset:18; size:2; signed:1;
+ field:__u32 protocol; offset:20; size:4; signed:0;
+
+print fmt: "i2c-%d a=%03x f=%04x c=%x %s %s res=%d", REC->adapter_nr, REC->addr, REC->flags, REC->command, __print_symbolic(REC->protocol, { 0, "QUICK" }, { 1, "BYTE" }, { 2, "BYTE_DATA" }, { 3, "WORD_DATA" }, { 4, "PROC_CALL" }, { 5, "BLOCK_DATA" }, { 6, "I2C_BLOCK_BROKEN" }, { 7, "BLOCK_PROC_CALL" }, { 8, "I2C_BLOCK_DATA" }), REC->read_write == 0 ? "wr" : "rd", REC->res
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/smbus/smbus_write/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/smbus/smbus_write/format
new file mode 100644
index 000000000..6964b6e58
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/smbus/smbus_write/format
@@ -0,0 +1,17 @@
+name: smbus_write
+ID: 841
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int adapter_nr; offset:8; size:4; signed:1;
+ field:__u16 addr; offset:12; size:2; signed:0;
+ field:__u16 flags; offset:14; size:2; signed:0;
+ field:__u8 command; offset:16; size:1; signed:0;
+ field:__u8 len; offset:17; size:1; signed:0;
+ field:__u32 protocol; offset:20; size:4; signed:0;
+ field:__u8 buf[32 + 2]; offset:24; size:34; signed:0;
+
+print fmt: "i2c-%d a=%03x f=%04x c=%x %s l=%u [%*phD]", REC->adapter_nr, REC->addr, REC->flags, REC->command, __print_symbolic(REC->protocol, { 0, "QUICK" }, { 1, "BYTE" }, { 2, "BYTE_DATA" }, { 3, "WORD_DATA" }, { 4, "PROC_CALL" }, { 5, "BLOCK_DATA" }, { 6, "I2C_BLOCK_BROKEN" }, { 7, "BLOCK_PROC_CALL" }, { 8, "I2C_BLOCK_DATA" }), REC->len, REC->len, REC->buf
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sock/inet_sock_set_state/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sock/inet_sock_set_state/format
new file mode 100644
index 000000000..d7c36c7c1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sock/inet_sock_set_state/format
@@ -0,0 +1,21 @@
+name: inet_sock_set_state
+ID: 924
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const void * skaddr; offset:8; size:8; signed:0;
+ field:int oldstate; offset:16; size:4; signed:1;
+ field:int newstate; offset:20; size:4; signed:1;
+ field:__u16 sport; offset:24; size:2; signed:0;
+ field:__u16 dport; offset:26; size:2; signed:0;
+ field:__u16 family; offset:28; size:2; signed:0;
+ field:__u16 protocol; offset:30; size:2; signed:0;
+ field:__u8 saddr[4]; offset:32; size:4; signed:0;
+ field:__u8 daddr[4]; offset:36; size:4; signed:0;
+ field:__u8 saddr_v6[16]; offset:40; size:16; signed:0;
+ field:__u8 daddr_v6[16]; offset:56; size:16; signed:0;
+
+print fmt: "family=%s protocol=%s sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c oldstate=%s newstate=%s", __print_symbolic(REC->family, { 2, "AF_INET" }, { 10, "AF_INET6" }), __print_symbolic(REC->protocol, { 6, "IPPROTO_TCP" }, { 33, "IPPROTO_DCCP" }, { 132, "IPPROTO_SCTP" }, { 262, "IPPROTO_MPTCP" }), REC->sport, REC->dport, REC->saddr, REC->daddr, REC->saddr_v6, REC->daddr_v6, __print_symbolic(REC->oldstate, { 1, "TCP_ESTABLISHED" }, { 2, "TCP_SYN_SENT" }, { 3, "TCP_SYN_RECV" }, { 4, "TCP_FIN_WAIT1" }, { 5, "TCP_FIN_WAIT2" }, { 6, "TCP_TIME_WAIT" }, { 7, "TCP_CLOSE" }, { 8, "TCP_CLOSE_WAIT" }, { 9, "TCP_LAST_ACK" }, { 10, "TCP_LISTEN" }, { 11, "TCP_CLOSING" }, { 12, "TCP_NEW_SYN_RECV" }), __print_symbolic(REC->newstate, { 1, "TCP_ESTABLISHED" }, { 2, "TCP_SYN_SENT" }, { 3, "TCP_SYN_RECV" }, { 4, "TCP_FIN_WAIT1" }, { 5, "TCP_FIN_WAIT2" }, { 6, "TCP_TIME_WAIT" }, { 7, "TCP_CLOSE" }, { 8, "TCP_CLOSE_WAIT" }, { 9, "TCP_LAST_ACK" }, { 10, "TCP_LISTEN" }, { 11, "TCP_CLOSING" }, { 12, "TCP_NEW_SYN_RECV" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sock/sock_exceed_buf_limit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sock/sock_exceed_buf_limit/format
new file mode 100644
index 000000000..bcee4fff6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sock/sock_exceed_buf_limit/format
@@ -0,0 +1,19 @@
+name: sock_exceed_buf_limit
+ID: 961
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:long * sysctl_mem; offset:40; size:8; signed:0;
+ field:long allocated; offset:48; size:8; signed:1;
+ field:int sysctl_rmem; offset:56; size:4; signed:1;
+ field:int rmem_alloc; offset:60; size:4; signed:1;
+ field:int sysctl_wmem; offset:64; size:4; signed:1;
+ field:int wmem_alloc; offset:68; size:4; signed:1;
+ field:int wmem_queued; offset:72; size:4; signed:1;
+ field:int kind; offset:76; size:4; signed:1;
+
+print fmt: "proto:%s sysctl_mem=%ld,%ld,%ld allocated=%ld sysctl_rmem=%d rmem_alloc=%d sysctl_wmem=%d wmem_alloc=%d wmem_queued=%d kind=%s", REC->name, REC->sysctl_mem[0], REC->sysctl_mem[1], REC->sysctl_mem[2], REC->allocated, REC->sysctl_rmem, REC->rmem_alloc, REC->sysctl_wmem, REC->wmem_alloc, REC->wmem_queued, __print_symbolic(REC->kind, { 0, "SK_MEM_SEND" }, { 1, "SK_MEM_RECV" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sock/sock_rcvqueue_full/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sock/sock_rcvqueue_full/format
new file mode 100644
index 000000000..33f573fc8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/sock/sock_rcvqueue_full/format
@@ -0,0 +1,13 @@
+name: sock_rcvqueue_full
+ID: 962
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int rmem_alloc; offset:8; size:4; signed:1;
+ field:unsigned int truesize; offset:12; size:4; signed:0;
+ field:int sk_rcvbuf; offset:16; size:4; signed:1;
+
+print fmt: "rmem_alloc=%d truesize=%u sk_rcvbuf=%d", REC->rmem_alloc, REC->truesize, REC->sk_rcvbuf
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_controller_busy/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_controller_busy/format
new file mode 100644
index 000000000..f09f089ba
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_controller_busy/format
@@ -0,0 +1,11 @@
+name: spi_controller_busy
+ID: 712
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int bus_num; offset:8; size:4; signed:1;
+
+print fmt: "spi%d", (int)REC->bus_num
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_controller_idle/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_controller_idle/format
new file mode 100644
index 000000000..2c080c6b4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_controller_idle/format
@@ -0,0 +1,11 @@
+name: spi_controller_idle
+ID: 713
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int bus_num; offset:8; size:4; signed:1;
+
+print fmt: "spi%d", (int)REC->bus_num
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_message_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_message_done/format
new file mode 100644
index 000000000..3a5f1c48e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_message_done/format
@@ -0,0 +1,15 @@
+name: spi_message_done
+ID: 714
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int bus_num; offset:8; size:4; signed:1;
+ field:int chip_select; offset:12; size:4; signed:1;
+ field:struct spi_message * msg; offset:16; size:8; signed:0;
+ field:unsigned frame; offset:24; size:4; signed:0;
+ field:unsigned actual; offset:28; size:4; signed:0;
+
+print fmt: "spi%d.%d %p len=%u/%u", (int)REC->bus_num, (int)REC->chip_select, (struct spi_message *)REC->msg, (unsigned)REC->actual, (unsigned)REC->frame
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_message_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_message_start/format
new file mode 100644
index 000000000..23dcdf41a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_message_start/format
@@ -0,0 +1,13 @@
+name: spi_message_start
+ID: 715
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int bus_num; offset:8; size:4; signed:1;
+ field:int chip_select; offset:12; size:4; signed:1;
+ field:struct spi_message * msg; offset:16; size:8; signed:0;
+
+print fmt: "spi%d.%d %p", (int)REC->bus_num, (int)REC->chip_select, (struct spi_message *)REC->msg
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_message_submit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_message_submit/format
new file mode 100644
index 000000000..9685c4732
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_message_submit/format
@@ -0,0 +1,13 @@
+name: spi_message_submit
+ID: 716
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int bus_num; offset:8; size:4; signed:1;
+ field:int chip_select; offset:12; size:4; signed:1;
+ field:struct spi_message * msg; offset:16; size:8; signed:0;
+
+print fmt: "spi%d.%d %p", (int)REC->bus_num, (int)REC->chip_select, (struct spi_message *)REC->msg
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_transfer_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_transfer_start/format
new file mode 100644
index 000000000..3d646a094
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_transfer_start/format
@@ -0,0 +1,16 @@
+name: spi_transfer_start
+ID: 717
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int bus_num; offset:8; size:4; signed:1;
+ field:int chip_select; offset:12; size:4; signed:1;
+ field:struct spi_transfer * xfer; offset:16; size:8; signed:0;
+ field:int len; offset:24; size:4; signed:1;
+ field:__data_loc u8[] rx_buf; offset:28; size:4; signed:0;
+ field:__data_loc u8[] tx_buf; offset:32; size:4; signed:0;
+
+print fmt: "spi%d.%d %p len=%d tx=[%*phD] rx=[%*phD]", REC->bus_num, REC->chip_select, REC->xfer, REC->len, __get_dynamic_array_len(tx_buf), __get_dynamic_array(tx_buf), __get_dynamic_array_len(rx_buf), __get_dynamic_array(rx_buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_transfer_stop/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_transfer_stop/format
new file mode 100644
index 000000000..c0075f511
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spi/spi_transfer_stop/format
@@ -0,0 +1,16 @@
+name: spi_transfer_stop
+ID: 718
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int bus_num; offset:8; size:4; signed:1;
+ field:int chip_select; offset:12; size:4; signed:1;
+ field:struct spi_transfer * xfer; offset:16; size:8; signed:0;
+ field:int len; offset:24; size:4; signed:1;
+ field:__data_loc u8[] rx_buf; offset:28; size:4; signed:0;
+ field:__data_loc u8[] tx_buf; offset:32; size:4; signed:0;
+
+print fmt: "spi%d.%d %p len=%d tx=[%*phD] rx=[%*phD]", REC->bus_num, REC->chip_select, REC->xfer, REC->len, __get_dynamic_array_len(tx_buf), __get_dynamic_array(tx_buf), __get_dynamic_array_len(rx_buf), __get_dynamic_array(rx_buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spmi/spmi_cmd/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spmi/spmi_cmd/format
new file mode 100644
index 000000000..caebc24c4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spmi/spmi_cmd/format
@@ -0,0 +1,13 @@
+name: spmi_cmd
+ID: 719
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u8 opcode; offset:8; size:1; signed:0;
+ field:u8 sid; offset:9; size:1; signed:0;
+ field:int ret; offset:12; size:4; signed:1;
+
+print fmt: "opc=%d sid=%02d ret=%d", (int)REC->opcode, (int)REC->sid, ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spmi/spmi_read_begin/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spmi/spmi_read_begin/format
new file mode 100644
index 000000000..ed52f96a5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spmi/spmi_read_begin/format
@@ -0,0 +1,13 @@
+name: spmi_read_begin
+ID: 720
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u8 opcode; offset:8; size:1; signed:0;
+ field:u8 sid; offset:9; size:1; signed:0;
+ field:u16 addr; offset:10; size:2; signed:0;
+
+print fmt: "opc=%d sid=%02d addr=0x%04x", (int)REC->opcode, (int)REC->sid, (int)REC->addr
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spmi/spmi_read_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spmi/spmi_read_end/format
new file mode 100644
index 000000000..d849679fd
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spmi/spmi_read_end/format
@@ -0,0 +1,16 @@
+name: spmi_read_end
+ID: 721
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u8 opcode; offset:8; size:1; signed:0;
+ field:u8 sid; offset:9; size:1; signed:0;
+ field:u16 addr; offset:10; size:2; signed:0;
+ field:int ret; offset:12; size:4; signed:1;
+ field:u8 len; offset:16; size:1; signed:0;
+ field:__data_loc u8[] buf; offset:20; size:4; signed:0;
+
+print fmt: "opc=%d sid=%02d addr=0x%04x ret=%d len=%02d buf=0x[%*phD]", (int)REC->opcode, (int)REC->sid, (int)REC->addr, REC->ret, (int)REC->len, (int)REC->len, __get_dynamic_array(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spmi/spmi_write_begin/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spmi/spmi_write_begin/format
new file mode 100644
index 000000000..9ebdff324
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spmi/spmi_write_begin/format
@@ -0,0 +1,15 @@
+name: spmi_write_begin
+ID: 722
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u8 opcode; offset:8; size:1; signed:0;
+ field:u8 sid; offset:9; size:1; signed:0;
+ field:u16 addr; offset:10; size:2; signed:0;
+ field:u8 len; offset:12; size:1; signed:0;
+ field:__data_loc u8[] buf; offset:16; size:4; signed:0;
+
+print fmt: "opc=%d sid=%02d addr=0x%04x len=%d buf=0x[%*phD]", (int)REC->opcode, (int)REC->sid, (int)REC->addr, (int)REC->len, (int)REC->len, __get_dynamic_array(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spmi/spmi_write_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spmi/spmi_write_end/format
new file mode 100644
index 000000000..5f307336b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/spmi/spmi_write_end/format
@@ -0,0 +1,14 @@
+name: spmi_write_end
+ID: 723
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u8 opcode; offset:8; size:1; signed:0;
+ field:u8 sid; offset:9; size:1; signed:0;
+ field:u16 addr; offset:10; size:2; signed:0;
+ field:int ret; offset:12; size:4; signed:1;
+
+print fmt: "opc=%d sid=%02d addr=0x%04x ret=%d", (int)REC->opcode, (int)REC->sid, (int)REC->addr, REC->ret
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/swiotlb/swiotlb_bounced/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/swiotlb/swiotlb_bounced/format
new file mode 100644
index 000000000..382551254
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/swiotlb/swiotlb_bounced/format
@@ -0,0 +1,15 @@
+name: swiotlb_bounced
+ID: 132
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] dev_name; offset:8; size:4; signed:0;
+ field:u64 dma_mask; offset:16; size:8; signed:0;
+ field:dma_addr_t dev_addr; offset:24; size:8; signed:0;
+ field:size_t size; offset:32; size:8; signed:0;
+ field:enum swiotlb_force swiotlb_force; offset:40; size:4; signed:0;
+
+print fmt: "dev_name: %s dma_mask=%llx dev_addr=%llx size=%zu %s", __get_str(dev_name), REC->dma_mask, (unsigned long long)REC->dev_addr, REC->size, __print_symbolic(REC->swiotlb_force, { SWIOTLB_NORMAL, "NORMAL" }, { SWIOTLB_FORCE, "FORCE" }, { SWIOTLB_NO_FORCE, "NO_FORCE" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/synthetic/rss_stat_throttled/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/synthetic/rss_stat_throttled/format
new file mode 100644
index 000000000..fd6282219
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/synthetic/rss_stat_throttled/format
@@ -0,0 +1,14 @@
+name: rss_stat_throttled
+ID: 1246
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int mm_id; offset:8; size:4; signed:0;
+ field:unsigned int curr; offset:16; size:4; signed:0;
+ field:int member; offset:24; size:4; signed:1;
+ field:long size; offset:32; size:8; signed:1;
+
+print fmt: "mm_id=%u, curr=%u, member=%d, size=%ld", REC->mm_id, REC->curr, REC->member, REC->size
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/systrace/0/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/systrace/0/format
new file mode 100644
index 000000000..1f6e4db55
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/systrace/0/format
@@ -0,0 +1,14 @@
+name: 0
+ID: 1057
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int flag; offset:8; size:4; signed:1;
+ field:int pid; offset:12; size:4; signed:1;
+ field:__data_loc char[] name; offset:16; size:4; signed:0;
+ field:int64_t value; offset:24; size:8; signed:1;
+
+print fmt: "%s|%d|%s|%lld", __print_flags(REC->flag, "", { SYSTRACE_EVENT_BEGIN, "B" }, { SYSTRACE_EVENT_END, "E" }, { SYSTRACE_EVENT_INT64, "C" }), REC->pid, __get_str(name), REC->value
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/task/task_newtask/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/task/task_newtask/format
new file mode 100644
index 000000000..ac7042bf3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/task/task_newtask/format
@@ -0,0 +1,14 @@
+name: task_newtask
+ID: 63
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:pid_t pid; offset:8; size:4; signed:1;
+ field:char comm[16]; offset:12; size:16; signed:0;
+ field:unsigned long clone_flags; offset:32; size:8; signed:0;
+ field:short oom_score_adj; offset:40; size:2; signed:1;
+
+print fmt: "pid=%d comm=%s clone_flags=%lx oom_score_adj=%hd", REC->pid, REC->comm, REC->clone_flags, REC->oom_score_adj
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/task/task_rename/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/task/task_rename/format
new file mode 100644
index 000000000..cce6d4385
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/task/task_rename/format
@@ -0,0 +1,14 @@
+name: task_rename
+ID: 64
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:pid_t pid; offset:8; size:4; signed:1;
+ field:char oldcomm[16]; offset:12; size:16; signed:0;
+ field:char newcomm[16]; offset:28; size:16; signed:0;
+ field:short oom_score_adj; offset:44; size:2; signed:1;
+
+print fmt: "pid=%d oldcomm=%s newcomm=%s oom_score_adj=%hd", REC->pid, REC->oldcomm, REC->newcomm, REC->oom_score_adj
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_destroy_sock/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_destroy_sock/format
new file mode 100644
index 000000000..c06dc6c86
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_destroy_sock/format
@@ -0,0 +1,18 @@
+name: tcp_destroy_sock
+ID: 963
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const void * skaddr; offset:8; size:8; signed:0;
+ field:__u16 sport; offset:16; size:2; signed:0;
+ field:__u16 dport; offset:18; size:2; signed:0;
+ field:__u8 saddr[4]; offset:20; size:4; signed:0;
+ field:__u8 daddr[4]; offset:24; size:4; signed:0;
+ field:__u8 saddr_v6[16]; offset:28; size:16; signed:0;
+ field:__u8 daddr_v6[16]; offset:44; size:16; signed:0;
+ field:__u64 sock_cookie; offset:64; size:8; signed:0;
+
+print fmt: "sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c sock_cookie=%llx", REC->sport, REC->dport, REC->saddr, REC->daddr, REC->saddr_v6, REC->daddr_v6, REC->sock_cookie
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_probe/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_probe/format
new file mode 100644
index 000000000..6e93855eb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_probe/format
@@ -0,0 +1,24 @@
+name: tcp_probe
+ID: 964
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__u8 saddr[sizeof(struct sockaddr_in6)]; offset:8; size:28; signed:0;
+ field:__u8 daddr[sizeof(struct sockaddr_in6)]; offset:36; size:28; signed:0;
+ field:__u16 sport; offset:64; size:2; signed:0;
+ field:__u16 dport; offset:66; size:2; signed:0;
+ field:__u32 mark; offset:68; size:4; signed:0;
+ field:__u16 data_len; offset:72; size:2; signed:0;
+ field:__u32 snd_nxt; offset:76; size:4; signed:0;
+ field:__u32 snd_una; offset:80; size:4; signed:0;
+ field:__u32 snd_cwnd; offset:84; size:4; signed:0;
+ field:__u32 ssthresh; offset:88; size:4; signed:0;
+ field:__u32 snd_wnd; offset:92; size:4; signed:0;
+ field:__u32 srtt; offset:96; size:4; signed:0;
+ field:__u32 rcv_wnd; offset:100; size:4; signed:0;
+ field:__u64 sock_cookie; offset:104; size:8; signed:0;
+
+print fmt: "src=%pISpc dest=%pISpc mark=%#x data_len=%d snd_nxt=%#x snd_una=%#x snd_cwnd=%u ssthresh=%u snd_wnd=%u srtt=%u rcv_wnd=%u sock_cookie=%llx", REC->saddr, REC->daddr, REC->mark, REC->data_len, REC->snd_nxt, REC->snd_una, REC->snd_cwnd, REC->ssthresh, REC->snd_wnd, REC->srtt, REC->rcv_wnd, REC->sock_cookie
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_rcv_space_adjust/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_rcv_space_adjust/format
new file mode 100644
index 000000000..feda161eb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_rcv_space_adjust/format
@@ -0,0 +1,18 @@
+name: tcp_rcv_space_adjust
+ID: 965
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const void * skaddr; offset:8; size:8; signed:0;
+ field:__u16 sport; offset:16; size:2; signed:0;
+ field:__u16 dport; offset:18; size:2; signed:0;
+ field:__u8 saddr[4]; offset:20; size:4; signed:0;
+ field:__u8 daddr[4]; offset:24; size:4; signed:0;
+ field:__u8 saddr_v6[16]; offset:28; size:16; signed:0;
+ field:__u8 daddr_v6[16]; offset:44; size:16; signed:0;
+ field:__u64 sock_cookie; offset:64; size:8; signed:0;
+
+print fmt: "sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c sock_cookie=%llx", REC->sport, REC->dport, REC->saddr, REC->daddr, REC->saddr_v6, REC->daddr_v6, REC->sock_cookie
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_receive_reset/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_receive_reset/format
new file mode 100644
index 000000000..61a7597b1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_receive_reset/format
@@ -0,0 +1,18 @@
+name: tcp_receive_reset
+ID: 966
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const void * skaddr; offset:8; size:8; signed:0;
+ field:__u16 sport; offset:16; size:2; signed:0;
+ field:__u16 dport; offset:18; size:2; signed:0;
+ field:__u8 saddr[4]; offset:20; size:4; signed:0;
+ field:__u8 daddr[4]; offset:24; size:4; signed:0;
+ field:__u8 saddr_v6[16]; offset:28; size:16; signed:0;
+ field:__u8 daddr_v6[16]; offset:44; size:16; signed:0;
+ field:__u64 sock_cookie; offset:64; size:8; signed:0;
+
+print fmt: "sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c sock_cookie=%llx", REC->sport, REC->dport, REC->saddr, REC->daddr, REC->saddr_v6, REC->daddr_v6, REC->sock_cookie
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_retransmit_skb/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_retransmit_skb/format
new file mode 100644
index 000000000..a73ee0e3b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_retransmit_skb/format
@@ -0,0 +1,19 @@
+name: tcp_retransmit_skb
+ID: 967
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const void * skbaddr; offset:8; size:8; signed:0;
+ field:const void * skaddr; offset:16; size:8; signed:0;
+ field:int state; offset:24; size:4; signed:1;
+ field:__u16 sport; offset:28; size:2; signed:0;
+ field:__u16 dport; offset:30; size:2; signed:0;
+ field:__u8 saddr[4]; offset:32; size:4; signed:0;
+ field:__u8 daddr[4]; offset:36; size:4; signed:0;
+ field:__u8 saddr_v6[16]; offset:40; size:16; signed:0;
+ field:__u8 daddr_v6[16]; offset:56; size:16; signed:0;
+
+print fmt: "sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c state=%s", REC->sport, REC->dport, REC->saddr, REC->daddr, REC->saddr_v6, REC->daddr_v6, __print_symbolic(REC->state, { TCP_ESTABLISHED, "TCP_ESTABLISHED" }, { TCP_SYN_SENT, "TCP_SYN_SENT" }, { TCP_SYN_RECV, "TCP_SYN_RECV" }, { TCP_FIN_WAIT1, "TCP_FIN_WAIT1" }, { TCP_FIN_WAIT2, "TCP_FIN_WAIT2" }, { TCP_TIME_WAIT, "TCP_TIME_WAIT" }, { TCP_CLOSE, "TCP_CLOSE" }, { TCP_CLOSE_WAIT, "TCP_CLOSE_WAIT" }, { TCP_LAST_ACK, "TCP_LAST_ACK" }, { TCP_LISTEN, "TCP_LISTEN" }, { TCP_CLOSING, "TCP_CLOSING" }, { TCP_NEW_SYN_RECV, "TCP_NEW_SYN_RECV" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_retransmit_synack/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_retransmit_synack/format
new file mode 100644
index 000000000..33515018c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_retransmit_synack/format
@@ -0,0 +1,18 @@
+name: tcp_retransmit_synack
+ID: 968
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const void * skaddr; offset:8; size:8; signed:0;
+ field:const void * req; offset:16; size:8; signed:0;
+ field:__u16 sport; offset:24; size:2; signed:0;
+ field:__u16 dport; offset:26; size:2; signed:0;
+ field:__u8 saddr[4]; offset:28; size:4; signed:0;
+ field:__u8 daddr[4]; offset:32; size:4; signed:0;
+ field:__u8 saddr_v6[16]; offset:36; size:16; signed:0;
+ field:__u8 daddr_v6[16]; offset:52; size:16; signed:0;
+
+print fmt: "sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c", REC->sport, REC->dport, REC->saddr, REC->daddr, REC->saddr_v6, REC->daddr_v6
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_send_reset/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_send_reset/format
new file mode 100644
index 000000000..a11e09ecf
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tcp/tcp_send_reset/format
@@ -0,0 +1,19 @@
+name: tcp_send_reset
+ID: 969
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const void * skbaddr; offset:8; size:8; signed:0;
+ field:const void * skaddr; offset:16; size:8; signed:0;
+ field:int state; offset:24; size:4; signed:1;
+ field:__u16 sport; offset:28; size:2; signed:0;
+ field:__u16 dport; offset:30; size:2; signed:0;
+ field:__u8 saddr[4]; offset:32; size:4; signed:0;
+ field:__u8 daddr[4]; offset:36; size:4; signed:0;
+ field:__u8 saddr_v6[16]; offset:40; size:16; signed:0;
+ field:__u8 daddr_v6[16]; offset:56; size:16; signed:0;
+
+print fmt: "sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c state=%s", REC->sport, REC->dport, REC->saddr, REC->daddr, REC->saddr_v6, REC->daddr_v6, __print_symbolic(REC->state, { TCP_ESTABLISHED, "TCP_ESTABLISHED" }, { TCP_SYN_SENT, "TCP_SYN_SENT" }, { TCP_SYN_RECV, "TCP_SYN_RECV" }, { TCP_FIN_WAIT1, "TCP_FIN_WAIT1" }, { TCP_FIN_WAIT2, "TCP_FIN_WAIT2" }, { TCP_TIME_WAIT, "TCP_TIME_WAIT" }, { TCP_CLOSE, "TCP_CLOSE" }, { TCP_CLOSE_WAIT, "TCP_CLOSE_WAIT" }, { TCP_LAST_ACK, "TCP_LAST_ACK" }, { TCP_LISTEN, "TCP_LISTEN" }, { TCP_CLOSING, "TCP_CLOSING" }, { TCP_NEW_SYN_RECV, "TCP_NEW_SYN_RECV" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/cdev_update/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/cdev_update/format
new file mode 100644
index 000000000..d44decc8e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/cdev_update/format
@@ -0,0 +1,12 @@
+name: cdev_update
+ID: 852
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] type; offset:8; size:4; signed:0;
+ field:unsigned long target; offset:16; size:8; signed:0;
+
+print fmt: "type=%s target=%lu", __get_str(type), REC->target
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_power_cpu_get_power/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_power_cpu_get_power/format
new file mode 100644
index 000000000..3436c8678
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_power_cpu_get_power/format
@@ -0,0 +1,15 @@
+name: thermal_power_cpu_get_power
+ID: 853
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc unsigned long[] cpumask; offset:8; size:4; signed:0;
+ field:unsigned long freq; offset:16; size:8; signed:0;
+ field:__data_loc u32[] load; offset:24; size:4; signed:0;
+ field:size_t load_len; offset:32; size:8; signed:0;
+ field:u32 dynamic_power; offset:40; size:4; signed:0;
+
+print fmt: "cpus=%s freq=%lu load={%s} dynamic_power=%d", __get_bitmask(cpumask), REC->freq, __print_array(__get_dynamic_array(load), REC->load_len, 4), REC->dynamic_power
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_power_cpu_limit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_power_cpu_limit/format
new file mode 100644
index 000000000..440797a07
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_power_cpu_limit/format
@@ -0,0 +1,14 @@
+name: thermal_power_cpu_limit
+ID: 854
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc unsigned long[] cpumask; offset:8; size:4; signed:0;
+ field:unsigned int freq; offset:12; size:4; signed:0;
+ field:unsigned long cdev_state; offset:16; size:8; signed:0;
+ field:u32 power; offset:24; size:4; signed:0;
+
+print fmt: "cpus=%s freq=%u cdev_state=%lu power=%u", __get_bitmask(cpumask), REC->freq, REC->cdev_state, REC->power
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_power_devfreq_get_power/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_power_devfreq_get_power/format
new file mode 100644
index 000000000..2e61ab625
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_power_devfreq_get_power/format
@@ -0,0 +1,16 @@
+name: thermal_power_devfreq_get_power
+ID: 855
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] type; offset:8; size:4; signed:0;
+ field:unsigned long freq; offset:16; size:8; signed:0;
+ field:u32 load; offset:24; size:4; signed:0;
+ field:u32 dynamic_power; offset:28; size:4; signed:0;
+ field:u32 static_power; offset:32; size:4; signed:0;
+ field:u32 power; offset:36; size:4; signed:0;
+
+print fmt: "type=%s freq=%lu load=%u dynamic_power=%u static_power=%u power=%u", __get_str(type), REC->freq, REC->load, REC->dynamic_power, REC->static_power, REC->power
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_power_devfreq_limit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_power_devfreq_limit/format
new file mode 100644
index 000000000..b68ae3b04
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_power_devfreq_limit/format
@@ -0,0 +1,14 @@
+name: thermal_power_devfreq_limit
+ID: 856
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] type; offset:8; size:4; signed:0;
+ field:unsigned int freq; offset:12; size:4; signed:0;
+ field:unsigned long cdev_state; offset:16; size:8; signed:0;
+ field:u32 power; offset:24; size:4; signed:0;
+
+print fmt: "type=%s freq=%u cdev_state=%lu power=%u", __get_str(type), REC->freq, REC->cdev_state, REC->power
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_temperature/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_temperature/format
new file mode 100644
index 000000000..6e23e591a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_temperature/format
@@ -0,0 +1,14 @@
+name: thermal_temperature
+ID: 857
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] thermal_zone; offset:8; size:4; signed:0;
+ field:int id; offset:12; size:4; signed:1;
+ field:int temp_prev; offset:16; size:4; signed:1;
+ field:int temp; offset:20; size:4; signed:1;
+
+print fmt: "thermal_zone=%s id=%d temp_prev=%d temp=%d", __get_str(thermal_zone), REC->id, REC->temp_prev, REC->temp
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_zone_trip/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_zone_trip/format
new file mode 100644
index 000000000..7d5635019
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal/thermal_zone_trip/format
@@ -0,0 +1,14 @@
+name: thermal_zone_trip
+ID: 858
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] thermal_zone; offset:8; size:4; signed:0;
+ field:int id; offset:12; size:4; signed:1;
+ field:int trip; offset:16; size:4; signed:1;
+ field:enum thermal_trip_type trip_type; offset:20; size:4; signed:0;
+
+print fmt: "thermal_zone=%s id=%d trip=%d trip_type=%s", __get_str(thermal_zone), REC->id, REC->trip, __print_symbolic(REC->trip_type, { 3, "CRITICAL"}, { 2, "HOT"}, { 1, "PASSIVE"}, { 0, "ACTIVE"})
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_cpu_pressure/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_cpu_pressure/format
new file mode 100644
index 000000000..e333cf4c7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_cpu_pressure/format
@@ -0,0 +1,12 @@
+name: thermal_cpu_pressure
+ID: 1099
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long pressure; offset:8; size:8; signed:0;
+ field:int cpu; offset:16; size:4; signed:1;
+
+print fmt: "pressure=%lu cpu=%d", REC->pressure, REC->cpu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_allow_max_power/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_allow_max_power/format
new file mode 100644
index 000000000..ad7b93c31
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_allow_max_power/format
@@ -0,0 +1,14 @@
+name: thermal_exynos_allow_max_power
+ID: 1100
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * tmu_name; offset:8; size:8; signed:0;
+ field:bool is_hardlimited; offset:16; size:1; signed:0;
+ field:const char * cdev_type; offset:24; size:8; signed:0;
+ field:unsigned long state; offset:32; size:8; signed:0;
+
+print fmt: "tmu_name:%s, is_hardlimited=%d, cdev:%s, target=%lu", REC->tmu_name, REC->is_hardlimited, REC->cdev_type, REC->state
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_arm_update/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_arm_update/format
new file mode 100644
index 000000000..fefabebe9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_arm_update/format
@@ -0,0 +1,16 @@
+name: thermal_exynos_arm_update
+ID: 1101
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * tmu_name; offset:8; size:8; signed:0;
+ field:bool is_cpu_hw_throttled; offset:16; size:1; signed:0;
+ field:int ppm_throttle_level; offset:20; size:4; signed:1;
+ field:int ppm_clr_level; offset:24; size:4; signed:1;
+ field:int mpmm_throttle_level; offset:28; size:4; signed:1;
+ field:int mpmm_clr_level; offset:32; size:4; signed:1;
+
+print fmt: "tmu_name:%s is_cpu_hw_throttled=%d, ppm_throttle_lvl=0x%x, ppm_clr_lvl=0x%x, mpmm_throttle_lvl=0x%x, mpmm_clr_lvl=0x%x", REC->tmu_name, REC->is_cpu_hw_throttled, REC->ppm_throttle_level, REC->ppm_clr_level, REC->mpmm_throttle_level, REC->mpmm_clr_level
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_cpu_pause/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_cpu_pause/format
new file mode 100644
index 000000000..0ee8def93
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_cpu_pause/format
@@ -0,0 +1,13 @@
+name: thermal_exynos_cpu_pause
+ID: 1102
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * tmu_name; offset:8; size:8; signed:0;
+ field:__data_loc unsigned long[] cpumask; offset:16; size:4; signed:0;
+ field:bool is_cpu_paused; offset:20; size:1; signed:0;
+
+print fmt: "tmu_name:%s cpus=%s, is_cpu_paused=%d", REC->tmu_name, __get_bitmask(cpumask), REC->is_cpu_paused
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_hard_limit_cdev_update/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_hard_limit_cdev_update/format
new file mode 100644
index 000000000..36c88b5be
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_hard_limit_cdev_update/format
@@ -0,0 +1,16 @@
+name: thermal_exynos_hard_limit_cdev_update
+ID: 1103
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * tmu_name; offset:8; size:8; signed:0;
+ field:const char * cdev_type; offset:16; size:8; signed:0;
+ field:bool is_hardlimited; offset:24; size:1; signed:0;
+ field:bool pid_switch_on; offset:25; size:1; signed:0;
+ field:unsigned long prev_max_state; offset:32; size:8; signed:0;
+ field:unsigned long state; offset:40; size:8; signed:0;
+
+print fmt: "tmu_name:%s cdev:%s, is_hardlimited=%d, pid_switch_on=%d, prev_max_state=%lu, state=%lu", REC->tmu_name, REC->cdev_type, REC->is_hardlimited, REC->pid_switch_on, REC->prev_max_state, REC->state
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_allocator/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_allocator/format
new file mode 100644
index 000000000..a059f1b27
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_allocator/format
@@ -0,0 +1,17 @@
+name: thermal_exynos_power_allocator
+ID: 1104
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int tz_id; offset:8; size:4; signed:1;
+ field:u32 power_range; offset:12; size:4; signed:0;
+ field:u32 max_allocatable_power; offset:16; size:4; signed:0;
+ field:int current_temp; offset:20; size:4; signed:1;
+ field:s32 delta_temp; offset:24; size:4; signed:1;
+ field:unsigned long cdev_state; offset:32; size:8; signed:0;
+ field:bool is_hardlimited; offset:40; size:1; signed:0;
+
+print fmt: "thermal_zone_id=%d power_range=%u max_allocatable_power=%u current_temperature=%d delta_temperature=%d cdev_state=%lu is_hardlimited=%d", REC->tz_id, REC->power_range, REC->max_allocatable_power, REC->current_temp, REC->delta_temp, REC->cdev_state, REC->is_hardlimited
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_allocator_pid/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_allocator_pid/format
new file mode 100644
index 000000000..dcfefc38a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_allocator_pid/format
@@ -0,0 +1,16 @@
+name: thermal_exynos_power_allocator_pid
+ID: 1105
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int tz_id; offset:8; size:4; signed:1;
+ field:s32 err; offset:12; size:4; signed:1;
+ field:s32 err_integral; offset:16; size:4; signed:1;
+ field:s64 p; offset:24; size:8; signed:1;
+ field:s64 i; offset:32; size:8; signed:1;
+ field:s32 output; offset:40; size:4; signed:1;
+
+print fmt: "thermal_zone_id=%d err=%d err_integral=%d p=%lld i=%lld output=%d", REC->tz_id, REC->err, REC->err_integral, REC->p, REC->i, REC->output
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_cpu_get_power/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_cpu_get_power/format
new file mode 100644
index 000000000..6719d269f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_cpu_get_power/format
@@ -0,0 +1,17 @@
+name: thermal_exynos_power_cpu_get_power
+ID: 1106
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int tzid; offset:8; size:4; signed:1;
+ field:int cpu; offset:12; size:4; signed:1;
+ field:unsigned long freq; offset:16; size:8; signed:0;
+ field:__data_loc u32[] load; offset:24; size:4; signed:0;
+ field:size_t load_len; offset:32; size:8; signed:0;
+ field:u32 dynamic_power; offset:40; size:4; signed:0;
+ field:u32 static_power; offset:44; size:4; signed:0;
+
+print fmt: "thermal_zone_id=%d cpu=%d freq=%lu load={%s} dynamic_power=%d static_power=%d", REC->tzid, REC->cpu, REC->freq, __print_array(__get_dynamic_array(load), REC->load_len, 4), REC->dynamic_power, REC->static_power
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_cpu_limit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_cpu_limit/format
new file mode 100644
index 000000000..615312461
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_cpu_limit/format
@@ -0,0 +1,15 @@
+name: thermal_exynos_power_cpu_limit
+ID: 1107
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int tzid; offset:8; size:4; signed:1;
+ field:int cpu; offset:12; size:4; signed:1;
+ field:unsigned int freq; offset:16; size:4; signed:0;
+ field:unsigned long cdev_state; offset:24; size:8; signed:0;
+ field:u32 power; offset:32; size:4; signed:0;
+
+print fmt: "thermal_zone_id=%d cpu=%d freq=%u cdev_state=%lu power=%u", REC->tzid, REC->cpu, REC->freq, REC->cdev_state, REC->power
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_gpu_get_power/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_gpu_get_power/format
new file mode 100644
index 000000000..af9336456
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_gpu_get_power/format
@@ -0,0 +1,14 @@
+name: thermal_exynos_power_gpu_get_power
+ID: 1108
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long freq; offset:8; size:8; signed:0;
+ field:u32 load; offset:16; size:4; signed:0;
+ field:u32 dynamic_power; offset:20; size:4; signed:0;
+ field:u32 static_power; offset:24; size:4; signed:0;
+
+print fmt: "freq=%lu load=%d dynamic_power=%d static_power=%d", REC->freq, REC->load, REC->dynamic_power, REC->static_power
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_gpu_limit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_gpu_limit/format
new file mode 100644
index 000000000..351022ea8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_power_gpu_limit/format
@@ -0,0 +1,13 @@
+name: thermal_exynos_power_gpu_limit
+ID: 1109
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int freq; offset:8; size:4; signed:0;
+ field:unsigned long cdev_state; offset:16; size:8; signed:0;
+ field:u32 power; offset:24; size:4; signed:0;
+
+print fmt: "freq=%u cdev_state=%lu power=%u", REC->freq, REC->cdev_state, REC->power
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_tpu_pause/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_tpu_pause/format
new file mode 100644
index 000000000..de63e7cd2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/thermal_exynos_tpu_pause/format
@@ -0,0 +1,12 @@
+name: thermal_exynos_tpu_pause
+ID: 1110
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * tmu_name; offset:8; size:8; signed:0;
+ field:bool is_paused; offset:16; size:1; signed:0;
+
+print fmt: "tmu_name:%s is_paused=%d", REC->tmu_name, REC->is_paused
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/vendor_cdev_update/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/vendor_cdev_update/format
new file mode 100644
index 000000000..46a37df22
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos/vendor_cdev_update/format
@@ -0,0 +1,13 @@
+name: vendor_cdev_update
+ID: 1111
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * cdev_type; offset:8; size:8; signed:0;
+ field:unsigned long sysfs_req; offset:16; size:8; signed:0;
+ field:unsigned long state; offset:24; size:8; signed:0;
+
+print fmt: "cdev:%s sysfs_req=%lu, state=%lu", REC->cdev_type, REC->sysfs_req, REC->state
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos_gpu/thermal_exynos_power_gpu_get_power/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos_gpu/thermal_exynos_power_gpu_get_power/format
new file mode 100644
index 000000000..99e25c2ff
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos_gpu/thermal_exynos_power_gpu_get_power/format
@@ -0,0 +1,14 @@
+name: thermal_exynos_power_gpu_get_power
+ID: 1112
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long freq; offset:8; size:8; signed:0;
+ field:u32 load; offset:16; size:4; signed:0;
+ field:u32 dynamic_power; offset:20; size:4; signed:0;
+ field:u32 static_power; offset:24; size:4; signed:0;
+
+print fmt: "freq=%lu load=%d dynamic_power=%d static_power=%d", REC->freq, REC->load, REC->dynamic_power, REC->static_power
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos_gpu/thermal_exynos_power_gpu_limit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos_gpu/thermal_exynos_power_gpu_limit/format
new file mode 100644
index 000000000..2099c24ff
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos_gpu/thermal_exynos_power_gpu_limit/format
@@ -0,0 +1,13 @@
+name: thermal_exynos_power_gpu_limit
+ID: 1113
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int freq; offset:8; size:4; signed:0;
+ field:unsigned long cdev_state; offset:16; size:8; signed:0;
+ field:u32 power; offset:24; size:4; signed:0;
+
+print fmt: "freq=%u cdev_state=%lu power=%u", REC->freq, REC->cdev_state, REC->power
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos_gpu/vendor_cdev_update/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos_gpu/vendor_cdev_update/format
new file mode 100644
index 000000000..04883fb97
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_exynos_gpu/vendor_cdev_update/format
@@ -0,0 +1,13 @@
+name: vendor_cdev_update
+ID: 1114
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const char * cdev_type; offset:8; size:8; signed:0;
+ field:unsigned long sysfs_req; offset:16; size:8; signed:0;
+ field:unsigned long state; offset:24; size:8; signed:0;
+
+print fmt: "cdev:%s sysfs_req=%lu, state=%lu", REC->cdev_type, REC->sysfs_req, REC->state
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_power_allocator/thermal_power_allocator/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_power_allocator/thermal_power_allocator/format
new file mode 100644
index 000000000..f7280bc08
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_power_allocator/thermal_power_allocator/format
@@ -0,0 +1,20 @@
+name: thermal_power_allocator
+ID: 859
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int tz_id; offset:8; size:4; signed:1;
+ field:__data_loc u32[] req_power; offset:12; size:4; signed:0;
+ field:u32 total_req_power; offset:16; size:4; signed:0;
+ field:__data_loc u32[] granted_power; offset:20; size:4; signed:0;
+ field:u32 total_granted_power; offset:24; size:4; signed:0;
+ field:size_t num_actors; offset:32; size:8; signed:0;
+ field:u32 power_range; offset:40; size:4; signed:0;
+ field:u32 max_allocatable_power; offset:44; size:4; signed:0;
+ field:int current_temp; offset:48; size:4; signed:1;
+ field:s32 delta_temp; offset:52; size:4; signed:1;
+
+print fmt: "thermal_zone_id=%d req_power={%s} total_req_power=%u granted_power={%s} total_granted_power=%u power_range=%u max_allocatable_power=%u current_temperature=%d delta_temperature=%d", REC->tz_id, __print_array(__get_dynamic_array(req_power), REC->num_actors, 4), REC->total_req_power, __print_array(__get_dynamic_array(granted_power), REC->num_actors, 4), REC->total_granted_power, REC->power_range, REC->max_allocatable_power, REC->current_temp, REC->delta_temp
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_power_allocator/thermal_power_allocator_pid/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_power_allocator/thermal_power_allocator_pid/format
new file mode 100644
index 000000000..35429d158
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/thermal_power_allocator/thermal_power_allocator_pid/format
@@ -0,0 +1,17 @@
+name: thermal_power_allocator_pid
+ID: 860
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int tz_id; offset:8; size:4; signed:1;
+ field:s32 err; offset:12; size:4; signed:1;
+ field:s32 err_integral; offset:16; size:4; signed:1;
+ field:s64 p; offset:24; size:8; signed:1;
+ field:s64 i; offset:32; size:8; signed:1;
+ field:s64 d; offset:40; size:8; signed:1;
+ field:s32 output; offset:48; size:4; signed:1;
+
+print fmt: "thermal_zone_id=%d err=%d err_integral=%d p=%lld i=%lld d=%lld output=%d", REC->tz_id, REC->err, REC->err_integral, REC->p, REC->i, REC->d, REC->output
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/hrtimer_cancel/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/hrtimer_cancel/format
new file mode 100644
index 000000000..df854726c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/hrtimer_cancel/format
@@ -0,0 +1,11 @@
+name: hrtimer_cancel
+ID: 133
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * hrtimer; offset:8; size:8; signed:0;
+
+print fmt: "hrtimer=%p", REC->hrtimer
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/hrtimer_expire_entry/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/hrtimer_expire_entry/format
new file mode 100644
index 000000000..b25737b10
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/hrtimer_expire_entry/format
@@ -0,0 +1,13 @@
+name: hrtimer_expire_entry
+ID: 134
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * hrtimer; offset:8; size:8; signed:0;
+ field:s64 now; offset:16; size:8; signed:1;
+ field:void * function; offset:24; size:8; signed:0;
+
+print fmt: "hrtimer=%p function=%ps now=%llu", REC->hrtimer, REC->function, (unsigned long long) REC->now
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/hrtimer_expire_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/hrtimer_expire_exit/format
new file mode 100644
index 000000000..1b39e18ba
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/hrtimer_expire_exit/format
@@ -0,0 +1,11 @@
+name: hrtimer_expire_exit
+ID: 135
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * hrtimer; offset:8; size:8; signed:0;
+
+print fmt: "hrtimer=%p", REC->hrtimer
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/hrtimer_init/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/hrtimer_init/format
new file mode 100644
index 000000000..e012d2fe7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/hrtimer_init/format
@@ -0,0 +1,13 @@
+name: hrtimer_init
+ID: 136
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * hrtimer; offset:8; size:8; signed:0;
+ field:clockid_t clockid; offset:16; size:4; signed:1;
+ field:enum hrtimer_mode mode; offset:20; size:4; signed:0;
+
+print fmt: "hrtimer=%p clockid=%s mode=%s", REC->hrtimer, __print_symbolic(REC->clockid, { 0, "CLOCK_REALTIME" }, { 1, "CLOCK_MONOTONIC" }, { 7, "CLOCK_BOOTTIME" }, { 11, "CLOCK_TAI" }), __print_symbolic(REC->mode, { HRTIMER_MODE_ABS, "ABS" }, { HRTIMER_MODE_REL, "REL" }, { HRTIMER_MODE_ABS_PINNED, "ABS|PINNED" }, { HRTIMER_MODE_REL_PINNED, "REL|PINNED" }, { HRTIMER_MODE_ABS_SOFT, "ABS|SOFT" }, { HRTIMER_MODE_REL_SOFT, "REL|SOFT" }, { HRTIMER_MODE_ABS_PINNED_SOFT, "ABS|PINNED|SOFT" }, { HRTIMER_MODE_REL_PINNED_SOFT, "REL|PINNED|SOFT" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/hrtimer_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/hrtimer_start/format
new file mode 100644
index 000000000..21cf94f68
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/hrtimer_start/format
@@ -0,0 +1,15 @@
+name: hrtimer_start
+ID: 137
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * hrtimer; offset:8; size:8; signed:0;
+ field:void * function; offset:16; size:8; signed:0;
+ field:s64 expires; offset:24; size:8; signed:1;
+ field:s64 softexpires; offset:32; size:8; signed:1;
+ field:enum hrtimer_mode mode; offset:40; size:4; signed:0;
+
+print fmt: "hrtimer=%p function=%ps expires=%llu softexpires=%llu mode=%s", REC->hrtimer, REC->function, (unsigned long long) REC->expires, (unsigned long long) REC->softexpires, __print_symbolic(REC->mode, { HRTIMER_MODE_ABS, "ABS" }, { HRTIMER_MODE_REL, "REL" }, { HRTIMER_MODE_ABS_PINNED, "ABS|PINNED" }, { HRTIMER_MODE_REL_PINNED, "REL|PINNED" }, { HRTIMER_MODE_ABS_SOFT, "ABS|SOFT" }, { HRTIMER_MODE_REL_SOFT, "REL|SOFT" }, { HRTIMER_MODE_ABS_PINNED_SOFT, "ABS|PINNED|SOFT" }, { HRTIMER_MODE_REL_PINNED_SOFT, "REL|PINNED|SOFT" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/itimer_expire/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/itimer_expire/format
new file mode 100644
index 000000000..c0dfd68d1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/itimer_expire/format
@@ -0,0 +1,13 @@
+name: itimer_expire
+ID: 138
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int which; offset:8; size:4; signed:1;
+ field:pid_t pid; offset:12; size:4; signed:1;
+ field:unsigned long long now; offset:16; size:8; signed:0;
+
+print fmt: "which=%d pid=%d now=%llu", REC->which, (int) REC->pid, REC->now
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/itimer_state/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/itimer_state/format
new file mode 100644
index 000000000..ac2e08aed
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/itimer_state/format
@@ -0,0 +1,16 @@
+name: itimer_state
+ID: 139
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int which; offset:8; size:4; signed:1;
+ field:unsigned long long expires; offset:16; size:8; signed:0;
+ field:long value_sec; offset:24; size:8; signed:1;
+ field:long value_nsec; offset:32; size:8; signed:1;
+ field:long interval_sec; offset:40; size:8; signed:1;
+ field:long interval_nsec; offset:48; size:8; signed:1;
+
+print fmt: "which=%d expires=%llu it_value=%ld.%06ld it_interval=%ld.%06ld", REC->which, REC->expires, REC->value_sec, REC->value_nsec / 1000L, REC->interval_sec, REC->interval_nsec / 1000L
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/tick_stop/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/tick_stop/format
new file mode 100644
index 000000000..551f2b87d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/tick_stop/format
@@ -0,0 +1,12 @@
+name: tick_stop
+ID: 140
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int success; offset:8; size:4; signed:1;
+ field:int dependency; offset:12; size:4; signed:1;
+
+print fmt: "success=%d dependency=%s", REC->success, __print_symbolic(REC->dependency, { 0, "NONE" }, { (1 << 0), "POSIX_TIMER" }, { (1 << 1), "PERF_EVENTS" }, { (1 << 2), "SCHED" }, { (1 << 3), "CLOCK_UNSTABLE" }, { (1 << 4), "RCU" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/timer_cancel/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/timer_cancel/format
new file mode 100644
index 000000000..68cd85f42
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/timer_cancel/format
@@ -0,0 +1,11 @@
+name: timer_cancel
+ID: 141
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * timer; offset:8; size:8; signed:0;
+
+print fmt: "timer=%p", REC->timer
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/timer_expire_entry/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/timer_expire_entry/format
new file mode 100644
index 000000000..21eac283e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/timer_expire_entry/format
@@ -0,0 +1,14 @@
+name: timer_expire_entry
+ID: 142
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * timer; offset:8; size:8; signed:0;
+ field:unsigned long now; offset:16; size:8; signed:0;
+ field:void * function; offset:24; size:8; signed:0;
+ field:unsigned long baseclk; offset:32; size:8; signed:0;
+
+print fmt: "timer=%p function=%ps now=%lu baseclk=%lu", REC->timer, REC->function, REC->now, REC->baseclk
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/timer_expire_exit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/timer_expire_exit/format
new file mode 100644
index 000000000..a50d9e42d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/timer_expire_exit/format
@@ -0,0 +1,11 @@
+name: timer_expire_exit
+ID: 143
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * timer; offset:8; size:8; signed:0;
+
+print fmt: "timer=%p", REC->timer
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/timer_init/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/timer_init/format
new file mode 100644
index 000000000..124d1a4a6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/timer_init/format
@@ -0,0 +1,11 @@
+name: timer_init
+ID: 144
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * timer; offset:8; size:8; signed:0;
+
+print fmt: "timer=%p", REC->timer
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/timer_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/timer_start/format
new file mode 100644
index 000000000..1b8f84c37
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/timer/timer_start/format
@@ -0,0 +1,15 @@
+name: timer_start
+ID: 145
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * timer; offset:8; size:8; signed:0;
+ field:void * function; offset:16; size:8; signed:0;
+ field:unsigned long expires; offset:24; size:8; signed:0;
+ field:unsigned long now; offset:32; size:8; signed:0;
+ field:unsigned int flags; offset:40; size:4; signed:0;
+
+print fmt: "timer=%p function=%ps expires=%lu [timeout=%ld] cpu=%u idx=%u flags=%s", REC->timer, REC->function, REC->expires, (long)REC->expires - REC->now, REC->flags & 0x0003FFFF, REC->flags >> 22, __print_flags(REC->flags & (0x00040000 | 0x00080000 | 0x00100000 | 0x00200000), "|", { 0x00040000, "M" }, { 0x00080000, "D" }, { 0x00100000, "P" }, { 0x00200000, "I" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_l2_device_event/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_l2_device_event/format
new file mode 100644
index 000000000..b05350a89
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_l2_device_event/format
@@ -0,0 +1,17 @@
+name: tipc_l2_device_event
+ID: 986
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] dev_name; offset:8; size:4; signed:0;
+ field:__data_loc char[] b_name; offset:12; size:4; signed:0;
+ field:unsigned long evt; offset:16; size:8; signed:0;
+ field:u8 b_up; offset:24; size:1; signed:0;
+ field:u8 carrier; offset:25; size:1; signed:0;
+ field:u8 oper; offset:26; size:1; signed:0;
+
+print fmt: "%s on: <%s>/<%s> oper: %s carrier: %s bearer: %s
+", __print_symbolic(REC->evt, {(NETDEV_CHANGE), "NETDEV_CHANGE" }, {(NETDEV_GOING_DOWN), "NETDEV_GOING_DOWN" }, {(NETDEV_UP), "NETDEV_UP" }, {(NETDEV_CHANGEMTU), "NETDEV_CHANGEMTU" }, {(NETDEV_CHANGEADDR), "NETDEV_CHANGEADDR" }, {(NETDEV_UNREGISTER), "NETDEV_UNREGISTER" }, {(NETDEV_CHANGENAME), "NETDEV_CHANGENAME" }), __get_str(dev_name), __get_str(b_name), (REC->oper) ? "up" : "down", (REC->carrier) ? "ok" : "notok", (REC->b_up) ? "up" : "down"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_bc_ack/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_bc_ack/format
new file mode 100644
index 000000000..53207032f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_bc_ack/format
@@ -0,0 +1,17 @@
+name: tipc_link_bc_ack
+ID: 987
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[68]; offset:8; size:68; signed:0;
+ field:u16 from; offset:76; size:2; signed:0;
+ field:u16 to; offset:78; size:2; signed:0;
+ field:u32 len; offset:80; size:4; signed:0;
+ field:u16 fseqno; offset:84; size:2; signed:0;
+ field:u16 lseqno; offset:86; size:2; signed:0;
+
+print fmt: "<%s> acked: %u gap: %u transmq: %u [%u-%u]
+", REC->name, REC->from, REC->to, REC->len, REC->fseqno, REC->lseqno
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_conges/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_conges/format
new file mode 100644
index 000000000..b1db76a30
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_conges/format
@@ -0,0 +1,14 @@
+name: tipc_link_conges
+ID: 988
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:char name[68]; offset:12; size:68; signed:0;
+ field:__data_loc char[] buf; offset:80; size:4; signed:0;
+
+print fmt: "<%s> %s
+%s", REC->name, __get_str(header), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_dump/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_dump/format
new file mode 100644
index 000000000..d09acc89f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_dump/format
@@ -0,0 +1,14 @@
+name: tipc_link_dump
+ID: 989
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:char name[68]; offset:12; size:68; signed:0;
+ field:__data_loc char[] buf; offset:80; size:4; signed:0;
+
+print fmt: "<%s> %s
+%s", REC->name, __get_str(header), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_fsm/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_fsm/format
new file mode 100644
index 000000000..8dc2ac096
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_fsm/format
@@ -0,0 +1,15 @@
+name: tipc_link_fsm
+ID: 990
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:u32 os; offset:12; size:4; signed:0;
+ field:u32 ns; offset:16; size:4; signed:0;
+ field:u32 evt; offset:20; size:4; signed:0;
+
+print fmt: "<%s> %s--(%s)->%s
+", __get_str(name), __print_symbolic(REC->os, {(0xe), "ESTABLISHED" }, {(0xe << 4), "ESTABLISHING" }, {(0x1 << 8), "RESET" }, {(0x2 << 12), "RESETTING" }, {(0xd << 16), "PEER_RESET" }, {(0xf << 20), "FAILINGOVER" }, {(0xc << 24), "SYNCHING" }, {(0xdd), "SELF_DOWN_PEER_DOWN" }, {(0xaa), "SELF_UP_PEER_UP" }, {(0xd1), "SELF_DOWN_PEER_LEAVING" }, {(0xac), "SELF_UP_PEER_COMING" }, {(0xca), "SELF_COMING_PEER_UP" }, {(0x1d), "SELF_LEAVING_PEER_DOWN" }, {(0xf0), "FAILINGOVER" }, {(0xcc), "SYNCHING" }), __print_symbolic(REC->evt, {(0xec1ab1e), "ESTABLISH_EVT" }, {(0x9eed0e), "PEER_RESET_EVT" }, {(0xfa110e), "FAILURE_EVT" }, {(0x10ca1d0e), "RESET_EVT" }, {(0xfa110bee), "FAILOVER_BEGIN_EVT" }, {(0xfa110ede), "FAILOVER_END_EVT" }, {(0xc1ccbee), "SYNCH_BEGIN_EVT" }, {(0xc1ccede), "SYNCH_END_EVT" }, {(0xece), "SELF_ESTABL_CONTACT_EVT" }, {(0x1ce), "SELF_LOST_CONTACT_EVT" }, {(0x9ece), "PEER_ESTABL_CONTACT_EVT" }, {(0x91ce), "PEER_LOST_CONTACT_EVT" }, {(0xfbe), "FAILOVER_BEGIN_EVT" }, {(0xfee), "FAILOVER_END_EVT" }, {(0xcbe), "SYNCH_BEGIN_EVT" }, {(0xcee), "SYNCH_END_EVT" }), __print_symbolic(REC->ns, {(0xe), "ESTABLISHED" }, {(0xe << 4), "ESTABLISHING" }, {(0x1 << 8), "RESET" }, {(0x2 << 12), "RESETTING" }, {(0xd << 16), "PEER_RESET" }, {(0xf << 20), "FAILINGOVER" }, {(0xc << 24), "SYNCHING" }, {(0xdd), "SELF_DOWN_PEER_DOWN" }, {(0xaa), "SELF_UP_PEER_UP" }, {(0xd1), "SELF_DOWN_PEER_LEAVING" }, {(0xac), "SELF_UP_PEER_COMING" }, {(0xca), "SELF_COMING_PEER_UP" }, {(0x1d), "SELF_LEAVING_PEER_DOWN" }, {(0xf0), "FAILINGOVER" }, {(0xcc), "SYNCHING" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_reset/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_reset/format
new file mode 100644
index 000000000..4dc87ade2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_reset/format
@@ -0,0 +1,14 @@
+name: tipc_link_reset
+ID: 991
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:char name[68]; offset:12; size:68; signed:0;
+ field:__data_loc char[] buf; offset:80; size:4; signed:0;
+
+print fmt: "<%s> %s
+%s", REC->name, __get_str(header), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_retrans/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_retrans/format
new file mode 100644
index 000000000..a9a461c26
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_retrans/format
@@ -0,0 +1,17 @@
+name: tipc_link_retrans
+ID: 992
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[68]; offset:8; size:68; signed:0;
+ field:u16 from; offset:76; size:2; signed:0;
+ field:u16 to; offset:78; size:2; signed:0;
+ field:u32 len; offset:80; size:4; signed:0;
+ field:u16 fseqno; offset:84; size:2; signed:0;
+ field:u16 lseqno; offset:86; size:2; signed:0;
+
+print fmt: "<%s> retrans req: [%u-%u] transmq: %u [%u-%u]
+", REC->name, REC->from, REC->to, REC->len, REC->fseqno, REC->lseqno
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_timeout/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_timeout/format
new file mode 100644
index 000000000..d0b4adc33
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_timeout/format
@@ -0,0 +1,14 @@
+name: tipc_link_timeout
+ID: 993
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:char name[68]; offset:12; size:68; signed:0;
+ field:__data_loc char[] buf; offset:80; size:4; signed:0;
+
+print fmt: "<%s> %s
+%s", REC->name, __get_str(header), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_too_silent/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_too_silent/format
new file mode 100644
index 000000000..cab54131f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_link_too_silent/format
@@ -0,0 +1,14 @@
+name: tipc_link_too_silent
+ID: 994
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:char name[68]; offset:12; size:68; signed:0;
+ field:__data_loc char[] buf; offset:80; size:4; signed:0;
+
+print fmt: "<%s> %s
+%s", REC->name, __get_str(header), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_list_dump/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_list_dump/format
new file mode 100644
index 000000000..3fd873c36
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_list_dump/format
@@ -0,0 +1,13 @@
+name: tipc_list_dump
+ID: 995
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:__data_loc char[] buf; offset:12; size:4; signed:0;
+
+print fmt: "%s
+%s", __get_str(header), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_check_state/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_check_state/format
new file mode 100644
index 000000000..1f8186c69
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_check_state/format
@@ -0,0 +1,14 @@
+name: tipc_node_check_state
+ID: 996
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 addr; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+
+print fmt: "<%x> %s
+%s", REC->addr, __get_str(header), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_create/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_create/format
new file mode 100644
index 000000000..28bee5d85
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_create/format
@@ -0,0 +1,14 @@
+name: tipc_node_create
+ID: 997
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 addr; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+
+print fmt: "<%x> %s
+%s", REC->addr, __get_str(header), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_delete/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_delete/format
new file mode 100644
index 000000000..0dd9a2df3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_delete/format
@@ -0,0 +1,14 @@
+name: tipc_node_delete
+ID: 998
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 addr; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+
+print fmt: "<%x> %s
+%s", REC->addr, __get_str(header), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_dump/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_dump/format
new file mode 100644
index 000000000..b1556d6a5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_dump/format
@@ -0,0 +1,14 @@
+name: tipc_node_dump
+ID: 999
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 addr; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+
+print fmt: "<%x> %s
+%s", REC->addr, __get_str(header), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_fsm/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_fsm/format
new file mode 100644
index 000000000..3443538ef
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_fsm/format
@@ -0,0 +1,15 @@
+name: tipc_node_fsm
+ID: 1000
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:u32 os; offset:12; size:4; signed:0;
+ field:u32 ns; offset:16; size:4; signed:0;
+ field:u32 evt; offset:20; size:4; signed:0;
+
+print fmt: "<%s> %s--(%s)->%s
+", __get_str(name), __print_symbolic(REC->os, {(0xe), "ESTABLISHED" }, {(0xe << 4), "ESTABLISHING" }, {(0x1 << 8), "RESET" }, {(0x2 << 12), "RESETTING" }, {(0xd << 16), "PEER_RESET" }, {(0xf << 20), "FAILINGOVER" }, {(0xc << 24), "SYNCHING" }, {(0xdd), "SELF_DOWN_PEER_DOWN" }, {(0xaa), "SELF_UP_PEER_UP" }, {(0xd1), "SELF_DOWN_PEER_LEAVING" }, {(0xac), "SELF_UP_PEER_COMING" }, {(0xca), "SELF_COMING_PEER_UP" }, {(0x1d), "SELF_LEAVING_PEER_DOWN" }, {(0xf0), "FAILINGOVER" }, {(0xcc), "SYNCHING" }), __print_symbolic(REC->evt, {(0xec1ab1e), "ESTABLISH_EVT" }, {(0x9eed0e), "PEER_RESET_EVT" }, {(0xfa110e), "FAILURE_EVT" }, {(0x10ca1d0e), "RESET_EVT" }, {(0xfa110bee), "FAILOVER_BEGIN_EVT" }, {(0xfa110ede), "FAILOVER_END_EVT" }, {(0xc1ccbee), "SYNCH_BEGIN_EVT" }, {(0xc1ccede), "SYNCH_END_EVT" }, {(0xece), "SELF_ESTABL_CONTACT_EVT" }, {(0x1ce), "SELF_LOST_CONTACT_EVT" }, {(0x9ece), "PEER_ESTABL_CONTACT_EVT" }, {(0x91ce), "PEER_LOST_CONTACT_EVT" }, {(0xfbe), "FAILOVER_BEGIN_EVT" }, {(0xfee), "FAILOVER_END_EVT" }, {(0xcbe), "SYNCH_BEGIN_EVT" }, {(0xcee), "SYNCH_END_EVT" }), __print_symbolic(REC->ns, {(0xe), "ESTABLISHED" }, {(0xe << 4), "ESTABLISHING" }, {(0x1 << 8), "RESET" }, {(0x2 << 12), "RESETTING" }, {(0xd << 16), "PEER_RESET" }, {(0xf << 20), "FAILINGOVER" }, {(0xc << 24), "SYNCHING" }, {(0xdd), "SELF_DOWN_PEER_DOWN" }, {(0xaa), "SELF_UP_PEER_UP" }, {(0xd1), "SELF_DOWN_PEER_LEAVING" }, {(0xac), "SELF_UP_PEER_COMING" }, {(0xca), "SELF_COMING_PEER_UP" }, {(0x1d), "SELF_LEAVING_PEER_DOWN" }, {(0xf0), "FAILINGOVER" }, {(0xcc), "SYNCHING" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_link_down/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_link_down/format
new file mode 100644
index 000000000..0333fee25
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_link_down/format
@@ -0,0 +1,14 @@
+name: tipc_node_link_down
+ID: 1001
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 addr; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+
+print fmt: "<%x> %s
+%s", REC->addr, __get_str(header), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_link_up/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_link_up/format
new file mode 100644
index 000000000..e2e655cfc
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_link_up/format
@@ -0,0 +1,14 @@
+name: tipc_node_link_up
+ID: 1002
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 addr; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+
+print fmt: "<%x> %s
+%s", REC->addr, __get_str(header), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_lost_contact/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_lost_contact/format
new file mode 100644
index 000000000..6afc86cca
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_lost_contact/format
@@ -0,0 +1,14 @@
+name: tipc_node_lost_contact
+ID: 1003
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 addr; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+
+print fmt: "<%x> %s
+%s", REC->addr, __get_str(header), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_reset_links/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_reset_links/format
new file mode 100644
index 000000000..7962032e0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_reset_links/format
@@ -0,0 +1,14 @@
+name: tipc_node_reset_links
+ID: 1004
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 addr; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+
+print fmt: "<%x> %s
+%s", REC->addr, __get_str(header), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_timeout/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_timeout/format
new file mode 100644
index 000000000..9017a1595
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_node_timeout/format
@@ -0,0 +1,14 @@
+name: tipc_node_timeout
+ID: 1005
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 addr; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+
+print fmt: "<%x> %s
+%s", REC->addr, __get_str(header), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_proto_build/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_proto_build/format
new file mode 100644
index 000000000..b17e2adac
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_proto_build/format
@@ -0,0 +1,13 @@
+name: tipc_proto_build
+ID: 1006
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:__data_loc char[] buf; offset:12; size:4; signed:0;
+
+print fmt: "%s
+%s", __get_str(header), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_proto_rcv/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_proto_rcv/format
new file mode 100644
index 000000000..f1ae3a06f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_proto_rcv/format
@@ -0,0 +1,13 @@
+name: tipc_proto_rcv
+ID: 1007
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:__data_loc char[] buf; offset:12; size:4; signed:0;
+
+print fmt: "%s
+%s", __get_str(header), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_advance_rx/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_advance_rx/format
new file mode 100644
index 000000000..1546efae1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_advance_rx/format
@@ -0,0 +1,15 @@
+name: tipc_sk_advance_rx
+ID: 1008
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 portid; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+ field:__data_loc char[] skb_buf; offset:20; size:4; signed:0;
+
+print fmt: "<%u> %s
+%s%s", REC->portid, __get_str(header), __get_str(skb_buf), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_create/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_create/format
new file mode 100644
index 000000000..629fb1f00
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_create/format
@@ -0,0 +1,15 @@
+name: tipc_sk_create
+ID: 1009
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 portid; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+ field:__data_loc char[] skb_buf; offset:20; size:4; signed:0;
+
+print fmt: "<%u> %s
+%s%s", REC->portid, __get_str(header), __get_str(skb_buf), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_drop_msg/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_drop_msg/format
new file mode 100644
index 000000000..7fff3b177
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_drop_msg/format
@@ -0,0 +1,15 @@
+name: tipc_sk_drop_msg
+ID: 1010
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 portid; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+ field:__data_loc char[] skb_buf; offset:20; size:4; signed:0;
+
+print fmt: "<%u> %s
+%s%s", REC->portid, __get_str(header), __get_str(skb_buf), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_dump/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_dump/format
new file mode 100644
index 000000000..3ecb0f0b2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_dump/format
@@ -0,0 +1,15 @@
+name: tipc_sk_dump
+ID: 1011
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 portid; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+ field:__data_loc char[] skb_buf; offset:20; size:4; signed:0;
+
+print fmt: "<%u> %s
+%s%s", REC->portid, __get_str(header), __get_str(skb_buf), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_filter_rcv/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_filter_rcv/format
new file mode 100644
index 000000000..8c72dd5bb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_filter_rcv/format
@@ -0,0 +1,15 @@
+name: tipc_sk_filter_rcv
+ID: 1012
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 portid; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+ field:__data_loc char[] skb_buf; offset:20; size:4; signed:0;
+
+print fmt: "<%u> %s
+%s%s", REC->portid, __get_str(header), __get_str(skb_buf), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_overlimit1/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_overlimit1/format
new file mode 100644
index 000000000..684d3d73e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_overlimit1/format
@@ -0,0 +1,15 @@
+name: tipc_sk_overlimit1
+ID: 1013
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 portid; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+ field:__data_loc char[] skb_buf; offset:20; size:4; signed:0;
+
+print fmt: "<%u> %s
+%s%s", REC->portid, __get_str(header), __get_str(skb_buf), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_overlimit2/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_overlimit2/format
new file mode 100644
index 000000000..4ad70efa8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_overlimit2/format
@@ -0,0 +1,15 @@
+name: tipc_sk_overlimit2
+ID: 1014
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 portid; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+ field:__data_loc char[] skb_buf; offset:20; size:4; signed:0;
+
+print fmt: "<%u> %s
+%s%s", REC->portid, __get_str(header), __get_str(skb_buf), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_poll/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_poll/format
new file mode 100644
index 000000000..907b31eed
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_poll/format
@@ -0,0 +1,15 @@
+name: tipc_sk_poll
+ID: 1015
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 portid; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+ field:__data_loc char[] skb_buf; offset:20; size:4; signed:0;
+
+print fmt: "<%u> %s
+%s%s", REC->portid, __get_str(header), __get_str(skb_buf), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_rej_msg/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_rej_msg/format
new file mode 100644
index 000000000..0e85eac97
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_rej_msg/format
@@ -0,0 +1,15 @@
+name: tipc_sk_rej_msg
+ID: 1016
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 portid; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+ field:__data_loc char[] skb_buf; offset:20; size:4; signed:0;
+
+print fmt: "<%u> %s
+%s%s", REC->portid, __get_str(header), __get_str(skb_buf), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_release/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_release/format
new file mode 100644
index 000000000..c8688b6e1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_release/format
@@ -0,0 +1,15 @@
+name: tipc_sk_release
+ID: 1017
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 portid; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+ field:__data_loc char[] skb_buf; offset:20; size:4; signed:0;
+
+print fmt: "<%u> %s
+%s%s", REC->portid, __get_str(header), __get_str(skb_buf), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_sendmcast/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_sendmcast/format
new file mode 100644
index 000000000..a257a8f3b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_sendmcast/format
@@ -0,0 +1,15 @@
+name: tipc_sk_sendmcast
+ID: 1018
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 portid; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+ field:__data_loc char[] skb_buf; offset:20; size:4; signed:0;
+
+print fmt: "<%u> %s
+%s%s", REC->portid, __get_str(header), __get_str(skb_buf), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_sendmsg/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_sendmsg/format
new file mode 100644
index 000000000..b2defbeb3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_sendmsg/format
@@ -0,0 +1,15 @@
+name: tipc_sk_sendmsg
+ID: 1019
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 portid; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+ field:__data_loc char[] skb_buf; offset:20; size:4; signed:0;
+
+print fmt: "<%u> %s
+%s%s", REC->portid, __get_str(header), __get_str(skb_buf), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_sendstream/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_sendstream/format
new file mode 100644
index 000000000..0fbb8001a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_sendstream/format
@@ -0,0 +1,15 @@
+name: tipc_sk_sendstream
+ID: 1020
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 portid; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+ field:__data_loc char[] skb_buf; offset:20; size:4; signed:0;
+
+print fmt: "<%u> %s
+%s%s", REC->portid, __get_str(header), __get_str(skb_buf), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_shutdown/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_shutdown/format
new file mode 100644
index 000000000..bda871b38
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_sk_shutdown/format
@@ -0,0 +1,15 @@
+name: tipc_sk_shutdown
+ID: 1021
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:u32 portid; offset:12; size:4; signed:0;
+ field:__data_loc char[] buf; offset:16; size:4; signed:0;
+ field:__data_loc char[] skb_buf; offset:20; size:4; signed:0;
+
+print fmt: "<%u> %s
+%s%s", REC->portid, __get_str(header), __get_str(skb_buf), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_skb_dump/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_skb_dump/format
new file mode 100644
index 000000000..ea6bce814
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/tipc/tipc_skb_dump/format
@@ -0,0 +1,13 @@
+name: tipc_skb_dump
+ID: 1022
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] header; offset:8; size:4; signed:0;
+ field:__data_loc char[] buf; offset:12; size:4; signed:0;
+
+print fmt: "%s
+%s", __get_str(header), __get_str(buf)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ucsi/ucsi_connector_change/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ucsi/ucsi_connector_change/format
new file mode 100644
index 000000000..2e3c06575
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ucsi/ucsi_connector_change/format
@@ -0,0 +1,19 @@
+name: ucsi_connector_change
+ID: 817
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int port; offset:8; size:4; signed:1;
+ field:u16 change; offset:12; size:2; signed:0;
+ field:u8 opmode; offset:14; size:1; signed:0;
+ field:u8 connected; offset:15; size:1; signed:0;
+ field:u8 pwr_dir; offset:16; size:1; signed:0;
+ field:u8 partner_flags; offset:17; size:1; signed:0;
+ field:u8 partner_type; offset:18; size:1; signed:0;
+ field:u32 request_data_obj; offset:20; size:4; signed:0;
+ field:u8 bc_status; offset:24; size:1; signed:0;
+
+print fmt: "port%d status: change=%04x, opmode=%x, connected=%d, sourcing=%d, partner_flags=%x, partner_type=%x, request_data_obj=%08x, BC status=%x", REC->port, REC->change, REC->opmode, REC->connected, REC->pwr_dir, REC->partner_flags, REC->partner_type, REC->request_data_obj, REC->bc_status
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ucsi/ucsi_register_altmode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ucsi/ucsi_register_altmode/format
new file mode 100644
index 000000000..19e975579
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ucsi/ucsi_register_altmode/format
@@ -0,0 +1,14 @@
+name: ucsi_register_altmode
+ID: 818
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u8 recipient; offset:8; size:1; signed:0;
+ field:u16 svid; offset:10; size:2; signed:0;
+ field:u8 mode; offset:12; size:1; signed:0;
+ field:u32 vdo; offset:16; size:4; signed:0;
+
+print fmt: "%s alt mode: svid %04x, mode %d vdo %x", ucsi_recipient_str(REC->recipient), REC->svid, REC->mode, REC->vdo
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ucsi/ucsi_register_port/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ucsi/ucsi_register_port/format
new file mode 100644
index 000000000..0a51d899e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ucsi/ucsi_register_port/format
@@ -0,0 +1,19 @@
+name: ucsi_register_port
+ID: 819
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int port; offset:8; size:4; signed:1;
+ field:u16 change; offset:12; size:2; signed:0;
+ field:u8 opmode; offset:14; size:1; signed:0;
+ field:u8 connected; offset:15; size:1; signed:0;
+ field:u8 pwr_dir; offset:16; size:1; signed:0;
+ field:u8 partner_flags; offset:17; size:1; signed:0;
+ field:u8 partner_type; offset:18; size:1; signed:0;
+ field:u32 request_data_obj; offset:20; size:4; signed:0;
+ field:u8 bc_status; offset:24; size:1; signed:0;
+
+print fmt: "port%d status: change=%04x, opmode=%x, connected=%d, sourcing=%d, partner_flags=%x, partner_type=%x, request_data_obj=%08x, BC status=%x", REC->port, REC->change, REC->opmode, REC->connected, REC->pwr_dir, REC->partner_flags, REC->partner_type, REC->request_data_obj, REC->bc_status
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ucsi/ucsi_reset_ppm/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ucsi/ucsi_reset_ppm/format
new file mode 100644
index 000000000..216fd9480
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ucsi/ucsi_reset_ppm/format
@@ -0,0 +1,12 @@
+name: ucsi_reset_ppm
+ID: 820
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 ctrl; offset:8; size:8; signed:0;
+ field:int ret; offset:16; size:4; signed:1;
+
+print fmt: "%s -> %s (err=%d)", ucsi_cmd_str(REC->ctrl), REC->ret < 0 ? "FAIL" : "OK", REC->ret < 0 ? REC->ret : 0
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ucsi/ucsi_run_command/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ucsi/ucsi_run_command/format
new file mode 100644
index 000000000..cfd7d0df3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ucsi/ucsi_run_command/format
@@ -0,0 +1,12 @@
+name: ucsi_run_command
+ID: 821
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 ctrl; offset:8; size:8; signed:0;
+ field:int ret; offset:16; size:4; signed:1;
+
+print fmt: "%s -> %s (err=%d)", ucsi_cmd_str(REC->ctrl), REC->ret < 0 ? "FAIL" : "OK", REC->ret < 0 ? REC->ret : 0
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/udp/udp_fail_queue_rcv_skb/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/udp/udp_fail_queue_rcv_skb/format
new file mode 100644
index 000000000..4166a7f46
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/udp/udp_fail_queue_rcv_skb/format
@@ -0,0 +1,12 @@
+name: udp_fail_queue_rcv_skb
+ID: 970
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int rc; offset:8; size:4; signed:1;
+ field:__u16 lport; offset:12; size:2; signed:0;
+
+print fmt: "rc=%d port=%hu", REC->rc, REC->lport
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_auto_bkops_state/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_auto_bkops_state/format
new file mode 100644
index 000000000..196006340
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_auto_bkops_state/format
@@ -0,0 +1,12 @@
+name: ufshcd_auto_bkops_state
+ID: 698
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] dev_name; offset:8; size:4; signed:0;
+ field:__data_loc char[] state; offset:12; size:4; signed:0;
+
+print fmt: "%s: auto bkops - %s", __get_str(dev_name), __get_str(state)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_clk_gating/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_clk_gating/format
new file mode 100644
index 000000000..32d556201
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_clk_gating/format
@@ -0,0 +1,12 @@
+name: ufshcd_clk_gating
+ID: 699
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] dev_name; offset:8; size:4; signed:0;
+ field:int state; offset:12; size:4; signed:1;
+
+print fmt: "%s: gating state changed to %s", __get_str(dev_name), __print_symbolic(REC->state, { 0, "CLKS_OFF" }, { 1, "CLKS_ON" }, { 2, "REQ_CLKS_OFF" }, { 3, "REQ_CLKS_ON" })
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_clk_scaling/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_clk_scaling/format
new file mode 100644
index 000000000..1b0da3dc6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_clk_scaling/format
@@ -0,0 +1,15 @@
+name: ufshcd_clk_scaling
+ID: 700
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] dev_name; offset:8; size:4; signed:0;
+ field:__data_loc char[] state; offset:12; size:4; signed:0;
+ field:__data_loc char[] clk; offset:16; size:4; signed:0;
+ field:u32 prev_state; offset:20; size:4; signed:0;
+ field:u32 curr_state; offset:24; size:4; signed:0;
+
+print fmt: "%s: %s %s from %u to %u Hz", __get_str(dev_name), __get_str(state), __get_str(clk), REC->prev_state, REC->curr_state
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_command/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_command/format
new file mode 100644
index 000000000..bda88bd6b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_command/format
@@ -0,0 +1,19 @@
+name: ufshcd_command
+ID: 701
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] dev_name; offset:8; size:4; signed:0;
+ field:__data_loc char[] str; offset:12; size:4; signed:0;
+ field:unsigned int tag; offset:16; size:4; signed:0;
+ field:u32 doorbell; offset:20; size:4; signed:0;
+ field:int transfer_len; offset:24; size:4; signed:1;
+ field:u32 intr; offset:28; size:4; signed:0;
+ field:u64 lba; offset:32; size:8; signed:0;
+ field:u8 opcode; offset:40; size:1; signed:0;
+ field:u8 group_id; offset:41; size:1; signed:0;
+
+print fmt: "%s: %s: tag: %u, DB: 0x%x, size: %d, IS: %u, LBA: %llu, opcode: 0x%x (%s), group_id: 0x%x", __get_str(str), __get_str(dev_name), REC->tag, REC->doorbell, REC->transfer_len, REC->intr, REC->lba, (u32)REC->opcode, __print_symbolic(REC->opcode, { 0x8a, "WRITE_16" }, { 0x2a, "WRITE_10" }, { 0x88, "READ_16" }, { 0x28, "READ_10" }, { 0x35, "SYNC" }, { 0x42, "UNMAP" }), (u32)REC->group_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_init/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_init/format
new file mode 100644
index 000000000..80808be12
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_init/format
@@ -0,0 +1,15 @@
+name: ufshcd_init
+ID: 702
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:s64 usecs; offset:8; size:8; signed:1;
+ field:int err; offset:16; size:4; signed:1;
+ field:__data_loc char[] dev_name; offset:20; size:4; signed:0;
+ field:int dev_state; offset:24; size:4; signed:1;
+ field:int link_state; offset:28; size:4; signed:1;
+
+print fmt: "%s: took %lld usecs, dev_state: %s, link_state: %s, err %d", __get_str(dev_name), REC->usecs, __print_symbolic(REC->dev_state, { 1, "UFS_ACTIVE_PWR_MODE" }, { 2, "UFS_SLEEP_PWR_MODE" }, { 3, "UFS_POWERDOWN_PWR_MODE" }), __print_symbolic(REC->link_state, { 0, "UIC_LINK_OFF_STATE" }, { 1, "UIC_LINK_ACTIVE_STATE" }, { 2, "UIC_LINK_HIBERN8_STATE" }), REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_profile_clk_gating/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_profile_clk_gating/format
new file mode 100644
index 000000000..7f6f8e741
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_profile_clk_gating/format
@@ -0,0 +1,14 @@
+name: ufshcd_profile_clk_gating
+ID: 703
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] dev_name; offset:8; size:4; signed:0;
+ field:__data_loc char[] profile_info; offset:12; size:4; signed:0;
+ field:s64 time_us; offset:16; size:8; signed:1;
+ field:int err; offset:24; size:4; signed:1;
+
+print fmt: "%s: %s: took %lld usecs, err %d", __get_str(dev_name), __get_str(profile_info), REC->time_us, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_profile_clk_scaling/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_profile_clk_scaling/format
new file mode 100644
index 000000000..be4182f01
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_profile_clk_scaling/format
@@ -0,0 +1,14 @@
+name: ufshcd_profile_clk_scaling
+ID: 704
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] dev_name; offset:8; size:4; signed:0;
+ field:__data_loc char[] profile_info; offset:12; size:4; signed:0;
+ field:s64 time_us; offset:16; size:8; signed:1;
+ field:int err; offset:24; size:4; signed:1;
+
+print fmt: "%s: %s: took %lld usecs, err %d", __get_str(dev_name), __get_str(profile_info), REC->time_us, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_profile_hibern8/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_profile_hibern8/format
new file mode 100644
index 000000000..606fcd0aa
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_profile_hibern8/format
@@ -0,0 +1,14 @@
+name: ufshcd_profile_hibern8
+ID: 705
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] dev_name; offset:8; size:4; signed:0;
+ field:__data_loc char[] profile_info; offset:12; size:4; signed:0;
+ field:s64 time_us; offset:16; size:8; signed:1;
+ field:int err; offset:24; size:4; signed:1;
+
+print fmt: "%s: %s: took %lld usecs, err %d", __get_str(dev_name), __get_str(profile_info), REC->time_us, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_runtime_resume/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_runtime_resume/format
new file mode 100644
index 000000000..62cf2034f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_runtime_resume/format
@@ -0,0 +1,15 @@
+name: ufshcd_runtime_resume
+ID: 706
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:s64 usecs; offset:8; size:8; signed:1;
+ field:int err; offset:16; size:4; signed:1;
+ field:__data_loc char[] dev_name; offset:20; size:4; signed:0;
+ field:int dev_state; offset:24; size:4; signed:1;
+ field:int link_state; offset:28; size:4; signed:1;
+
+print fmt: "%s: took %lld usecs, dev_state: %s, link_state: %s, err %d", __get_str(dev_name), REC->usecs, __print_symbolic(REC->dev_state, { 1, "UFS_ACTIVE_PWR_MODE" }, { 2, "UFS_SLEEP_PWR_MODE" }, { 3, "UFS_POWERDOWN_PWR_MODE" }), __print_symbolic(REC->link_state, { 0, "UIC_LINK_OFF_STATE" }, { 1, "UIC_LINK_ACTIVE_STATE" }, { 2, "UIC_LINK_HIBERN8_STATE" }), REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_runtime_suspend/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_runtime_suspend/format
new file mode 100644
index 000000000..3c851ced9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_runtime_suspend/format
@@ -0,0 +1,15 @@
+name: ufshcd_runtime_suspend
+ID: 707
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:s64 usecs; offset:8; size:8; signed:1;
+ field:int err; offset:16; size:4; signed:1;
+ field:__data_loc char[] dev_name; offset:20; size:4; signed:0;
+ field:int dev_state; offset:24; size:4; signed:1;
+ field:int link_state; offset:28; size:4; signed:1;
+
+print fmt: "%s: took %lld usecs, dev_state: %s, link_state: %s, err %d", __get_str(dev_name), REC->usecs, __print_symbolic(REC->dev_state, { 1, "UFS_ACTIVE_PWR_MODE" }, { 2, "UFS_SLEEP_PWR_MODE" }, { 3, "UFS_POWERDOWN_PWR_MODE" }), __print_symbolic(REC->link_state, { 0, "UIC_LINK_OFF_STATE" }, { 1, "UIC_LINK_ACTIVE_STATE" }, { 2, "UIC_LINK_HIBERN8_STATE" }), REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_system_resume/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_system_resume/format
new file mode 100644
index 000000000..a45e35e11
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_system_resume/format
@@ -0,0 +1,15 @@
+name: ufshcd_system_resume
+ID: 708
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:s64 usecs; offset:8; size:8; signed:1;
+ field:int err; offset:16; size:4; signed:1;
+ field:__data_loc char[] dev_name; offset:20; size:4; signed:0;
+ field:int dev_state; offset:24; size:4; signed:1;
+ field:int link_state; offset:28; size:4; signed:1;
+
+print fmt: "%s: took %lld usecs, dev_state: %s, link_state: %s, err %d", __get_str(dev_name), REC->usecs, __print_symbolic(REC->dev_state, { 1, "UFS_ACTIVE_PWR_MODE" }, { 2, "UFS_SLEEP_PWR_MODE" }, { 3, "UFS_POWERDOWN_PWR_MODE" }), __print_symbolic(REC->link_state, { 0, "UIC_LINK_OFF_STATE" }, { 1, "UIC_LINK_ACTIVE_STATE" }, { 2, "UIC_LINK_HIBERN8_STATE" }), REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_system_suspend/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_system_suspend/format
new file mode 100644
index 000000000..4ae7b08ea
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_system_suspend/format
@@ -0,0 +1,15 @@
+name: ufshcd_system_suspend
+ID: 709
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:s64 usecs; offset:8; size:8; signed:1;
+ field:int err; offset:16; size:4; signed:1;
+ field:__data_loc char[] dev_name; offset:20; size:4; signed:0;
+ field:int dev_state; offset:24; size:4; signed:1;
+ field:int link_state; offset:28; size:4; signed:1;
+
+print fmt: "%s: took %lld usecs, dev_state: %s, link_state: %s, err %d", __get_str(dev_name), REC->usecs, __print_symbolic(REC->dev_state, { 1, "UFS_ACTIVE_PWR_MODE" }, { 2, "UFS_SLEEP_PWR_MODE" }, { 3, "UFS_POWERDOWN_PWR_MODE" }), __print_symbolic(REC->link_state, { 0, "UIC_LINK_OFF_STATE" }, { 1, "UIC_LINK_ACTIVE_STATE" }, { 2, "UIC_LINK_HIBERN8_STATE" }), REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_uic_command/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_uic_command/format
new file mode 100644
index 000000000..f1e27a6a9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_uic_command/format
@@ -0,0 +1,16 @@
+name: ufshcd_uic_command
+ID: 710
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] dev_name; offset:8; size:4; signed:0;
+ field:__data_loc char[] str; offset:12; size:4; signed:0;
+ field:u32 cmd; offset:16; size:4; signed:0;
+ field:u32 arg1; offset:20; size:4; signed:0;
+ field:u32 arg2; offset:24; size:4; signed:0;
+ field:u32 arg3; offset:28; size:4; signed:0;
+
+print fmt: "%s: %s: cmd: 0x%x, arg1: 0x%x, arg2: 0x%x, arg3: 0x%x", __get_str(str), __get_str(dev_name), REC->cmd, REC->arg1, REC->arg2, REC->arg3
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_upiu/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_upiu/format
new file mode 100644
index 000000000..f82f11c9f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs/ufshcd_upiu/format
@@ -0,0 +1,14 @@
+name: ufshcd_upiu
+ID: 711
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] dev_name; offset:8; size:4; signed:0;
+ field:__data_loc char[] str; offset:12; size:4; signed:0;
+ field:unsigned char hdr[12]; offset:16; size:12; signed:0;
+ field:unsigned char tsf[16]; offset:28; size:16; signed:0;
+
+print fmt: "%s: %s: HDR:%s, CDB:%s", __get_str(str), __get_str(dev_name), __print_hex(REC->hdr, sizeof(REC->hdr)), __print_hex(REC->tsf, sizeof(REC->tsf))
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs_pixel/ufs_stats/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs_pixel/ufs_stats/format
new file mode 100644
index 000000000..370ee9aab
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/ufs_pixel/ufs_stats/format
@@ -0,0 +1,29 @@
+name: ufs_stats
+ID: 1089
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u64 peak_read; offset:8; size:8; signed:0;
+ field:u64 peak_write; offset:16; size:8; signed:0;
+ field:u64 peak_flush; offset:24; size:8; signed:0;
+ field:u64 peak_discard; offset:32; size:8; signed:0;
+ field:u64 peak_qdepth; offset:40; size:8; signed:0;
+ field:u64 avg_read; offset:48; size:8; signed:0;
+ field:u64 avg_write; offset:56; size:8; signed:0;
+ field:u64 avg_flush; offset:64; size:8; signed:0;
+ field:u64 avg_discard; offset:72; size:8; signed:0;
+ field:u64 r_rc_s; offset:80; size:8; signed:0;
+ field:u64 r_tb_s; offset:88; size:8; signed:0;
+ field:u64 w_rc_s; offset:96; size:8; signed:0;
+ field:u64 w_tb_s; offset:104; size:8; signed:0;
+ field:u64 r_rc_c; offset:112; size:8; signed:0;
+ field:u64 r_tb_c; offset:120; size:8; signed:0;
+ field:u64 w_rc_c; offset:128; size:8; signed:0;
+ field:u64 w_tb_c; offset:136; size:8; signed:0;
+ field:u64 r_rem; offset:144; size:8; signed:0;
+ field:u64 w_rem; offset:152; size:8; signed:0;
+
+print fmt: "avg/max(us): read(%llu/%llu) write(%llu/%llu) flush(%llu/%llu) discard(%llu/%llu), started_bytes/count: read(%llu/%llu) write(%llu/%llu), completed_bytes/count: read(%llu/%llu) write(%llu/%llu), in-flight_read/write: %llu/%llu, peak_queue_depth: %llu", REC->avg_read, REC->peak_read, REC->avg_write, REC->peak_write, REC->avg_flush, REC->peak_flush, REC->avg_discard, REC->peak_discard, REC->r_tb_s, REC->r_rc_s, REC->w_tb_s, REC->w_rc_s, REC->r_tb_c, REC->r_rc_c, REC->w_tb_c, REC->w_rc_c, REC->r_rem, REC->w_rem, REC->peak_qdepth
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/v4l2_dqbuf/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/v4l2_dqbuf/format
new file mode 100644
index 000000000..9a6d25031
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/v4l2_dqbuf/format
@@ -0,0 +1,28 @@
+name: v4l2_dqbuf
+ID: 842
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int minor; offset:8; size:4; signed:1;
+ field:u32 index; offset:12; size:4; signed:0;
+ field:u32 type; offset:16; size:4; signed:0;
+ field:u32 bytesused; offset:20; size:4; signed:0;
+ field:u32 flags; offset:24; size:4; signed:0;
+ field:u32 field; offset:28; size:4; signed:0;
+ field:s64 timestamp; offset:32; size:8; signed:1;
+ field:u32 timecode_type; offset:40; size:4; signed:0;
+ field:u32 timecode_flags; offset:44; size:4; signed:0;
+ field:u8 timecode_frames; offset:48; size:1; signed:0;
+ field:u8 timecode_seconds; offset:49; size:1; signed:0;
+ field:u8 timecode_minutes; offset:50; size:1; signed:0;
+ field:u8 timecode_hours; offset:51; size:1; signed:0;
+ field:u8 timecode_userbits0; offset:52; size:1; signed:0;
+ field:u8 timecode_userbits1; offset:53; size:1; signed:0;
+ field:u8 timecode_userbits2; offset:54; size:1; signed:0;
+ field:u8 timecode_userbits3; offset:55; size:1; signed:0;
+ field:u32 sequence; offset:56; size:4; signed:0;
+
+print fmt: "minor = %d, index = %u, type = %s, bytesused = %u, flags = %s, field = %s, timestamp = %llu, timecode = { type = %s, flags = %s, frames = %u, seconds = %u, minutes = %u, hours = %u, userbits = { %u %u %u %u } }, sequence = %u", REC->minor, REC->index, __print_symbolic(REC->type, {1, "VIDEO_CAPTURE"}, {2, "VIDEO_OUTPUT"}, {3, "VIDEO_OVERLAY"}, {4, "VBI_CAPTURE"}, {5, "VBI_OUTPUT"}, {6, "SLICED_VBI_CAPTURE"}, {7, "SLICED_VBI_OUTPUT"}, {8, "VIDEO_OUTPUT_OVERLAY"}, {9, "VIDEO_CAPTURE_MPLANE"}, {10, "VIDEO_OUTPUT_MPLANE"}, {11, "SDR_CAPTURE"}, {12, "SDR_OUTPUT"}, {13, "META_CAPTURE"}, {128, "PRIVATE"}), REC->bytesused, __print_flags(REC->flags, "|", { 0x00000001, "MAPPED" }, { 0x00000002, "QUEUED" }, { 0x00000004, "DONE" }, { 0x00000008, "KEYFRAME" }, { 0x00000010, "PFRAME" }, { 0x00000020, "BFRAME" }, { 0x00000040, "ERROR" }, { 0x00000100, "TIMECODE" }, { 0x00000400, "PREPARED" }, { 0x00000800, "NO_CACHE_INVALIDATE" }, { 0x00001000, "NO_CACHE_CLEAN" }, { 0x0000e000, "TIMESTAMP_MASK" }, { 0x00000000, "TIMESTAMP_UNKNOWN" }, { 0x00002000, "TIMESTAMP_MONOTONIC" }, { 0x00004000, "TIMESTAMP_COPY" }, { 0x00100000, "LAST" }), __print_symbolic(REC->field, {0, "ANY"}, {1, "NONE"}, {2, "TOP"}, {3, "BOTTOM"}, {4, "INTERLACED"}, {5, "SEQ_TB"}, {6, "SEQ_BT"}, {7, "ALTERNATE"}, {8, "INTERLACED_TB"}, {9, "INTERLACED_BT"}), REC->timestamp, __print_symbolic(REC->timecode_type, { 1, "24FPS" }, { 2, "25FPS" }, { 3, "30FPS" }, { 4, "50FPS" }, { 5, "60FPS" }), __print_flags(REC->timecode_flags, "|", { 0x0001, "DROPFRAME" }, { 0x0002, "COLORFRAME" }, { 0x0000, "USERBITS_USERDEFINED" }, { 0x0008, "USERBITS_8BITCHARS" }), REC->timecode_frames, REC->timecode_seconds, REC->timecode_minutes, REC->timecode_hours, REC->timecode_userbits0, REC->timecode_userbits1, REC->timecode_userbits2, REC->timecode_userbits3, REC->sequence
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/v4l2_qbuf/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/v4l2_qbuf/format
new file mode 100644
index 000000000..3e619ebdd
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/v4l2_qbuf/format
@@ -0,0 +1,28 @@
+name: v4l2_qbuf
+ID: 843
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int minor; offset:8; size:4; signed:1;
+ field:u32 index; offset:12; size:4; signed:0;
+ field:u32 type; offset:16; size:4; signed:0;
+ field:u32 bytesused; offset:20; size:4; signed:0;
+ field:u32 flags; offset:24; size:4; signed:0;
+ field:u32 field; offset:28; size:4; signed:0;
+ field:s64 timestamp; offset:32; size:8; signed:1;
+ field:u32 timecode_type; offset:40; size:4; signed:0;
+ field:u32 timecode_flags; offset:44; size:4; signed:0;
+ field:u8 timecode_frames; offset:48; size:1; signed:0;
+ field:u8 timecode_seconds; offset:49; size:1; signed:0;
+ field:u8 timecode_minutes; offset:50; size:1; signed:0;
+ field:u8 timecode_hours; offset:51; size:1; signed:0;
+ field:u8 timecode_userbits0; offset:52; size:1; signed:0;
+ field:u8 timecode_userbits1; offset:53; size:1; signed:0;
+ field:u8 timecode_userbits2; offset:54; size:1; signed:0;
+ field:u8 timecode_userbits3; offset:55; size:1; signed:0;
+ field:u32 sequence; offset:56; size:4; signed:0;
+
+print fmt: "minor = %d, index = %u, type = %s, bytesused = %u, flags = %s, field = %s, timestamp = %llu, timecode = { type = %s, flags = %s, frames = %u, seconds = %u, minutes = %u, hours = %u, userbits = { %u %u %u %u } }, sequence = %u", REC->minor, REC->index, __print_symbolic(REC->type, {1, "VIDEO_CAPTURE"}, {2, "VIDEO_OUTPUT"}, {3, "VIDEO_OVERLAY"}, {4, "VBI_CAPTURE"}, {5, "VBI_OUTPUT"}, {6, "SLICED_VBI_CAPTURE"}, {7, "SLICED_VBI_OUTPUT"}, {8, "VIDEO_OUTPUT_OVERLAY"}, {9, "VIDEO_CAPTURE_MPLANE"}, {10, "VIDEO_OUTPUT_MPLANE"}, {11, "SDR_CAPTURE"}, {12, "SDR_OUTPUT"}, {13, "META_CAPTURE"}, {128, "PRIVATE"}), REC->bytesused, __print_flags(REC->flags, "|", { 0x00000001, "MAPPED" }, { 0x00000002, "QUEUED" }, { 0x00000004, "DONE" }, { 0x00000008, "KEYFRAME" }, { 0x00000010, "PFRAME" }, { 0x00000020, "BFRAME" }, { 0x00000040, "ERROR" }, { 0x00000100, "TIMECODE" }, { 0x00000400, "PREPARED" }, { 0x00000800, "NO_CACHE_INVALIDATE" }, { 0x00001000, "NO_CACHE_CLEAN" }, { 0x0000e000, "TIMESTAMP_MASK" }, { 0x00000000, "TIMESTAMP_UNKNOWN" }, { 0x00002000, "TIMESTAMP_MONOTONIC" }, { 0x00004000, "TIMESTAMP_COPY" }, { 0x00100000, "LAST" }), __print_symbolic(REC->field, {0, "ANY"}, {1, "NONE"}, {2, "TOP"}, {3, "BOTTOM"}, {4, "INTERLACED"}, {5, "SEQ_TB"}, {6, "SEQ_BT"}, {7, "ALTERNATE"}, {8, "INTERLACED_TB"}, {9, "INTERLACED_BT"}), REC->timestamp, __print_symbolic(REC->timecode_type, { 1, "24FPS" }, { 2, "25FPS" }, { 3, "30FPS" }, { 4, "50FPS" }, { 5, "60FPS" }), __print_flags(REC->timecode_flags, "|", { 0x0001, "DROPFRAME" }, { 0x0002, "COLORFRAME" }, { 0x0000, "USERBITS_USERDEFINED" }, { 0x0008, "USERBITS_8BITCHARS" }), REC->timecode_frames, REC->timecode_seconds, REC->timecode_minutes, REC->timecode_hours, REC->timecode_userbits0, REC->timecode_userbits1, REC->timecode_userbits2, REC->timecode_userbits3, REC->sequence
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/vb2_v4l2_buf_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/vb2_v4l2_buf_done/format
new file mode 100644
index 000000000..a1fe2aed4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/vb2_v4l2_buf_done/format
@@ -0,0 +1,25 @@
+name: vb2_v4l2_buf_done
+ID: 844
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int minor; offset:8; size:4; signed:1;
+ field:u32 flags; offset:12; size:4; signed:0;
+ field:u32 field; offset:16; size:4; signed:0;
+ field:u64 timestamp; offset:24; size:8; signed:0;
+ field:u32 timecode_type; offset:32; size:4; signed:0;
+ field:u32 timecode_flags; offset:36; size:4; signed:0;
+ field:u8 timecode_frames; offset:40; size:1; signed:0;
+ field:u8 timecode_seconds; offset:41; size:1; signed:0;
+ field:u8 timecode_minutes; offset:42; size:1; signed:0;
+ field:u8 timecode_hours; offset:43; size:1; signed:0;
+ field:u8 timecode_userbits0; offset:44; size:1; signed:0;
+ field:u8 timecode_userbits1; offset:45; size:1; signed:0;
+ field:u8 timecode_userbits2; offset:46; size:1; signed:0;
+ field:u8 timecode_userbits3; offset:47; size:1; signed:0;
+ field:u32 sequence; offset:48; size:4; signed:0;
+
+print fmt: "minor=%d flags = %s, field = %s, timestamp = %llu, timecode = { type = %s, flags = %s, frames = %u, seconds = %u, minutes = %u, hours = %u, userbits = { %u %u %u %u } }, sequence = %u", REC->minor, __print_flags(REC->flags, "|", { 0x00000001, "MAPPED" }, { 0x00000002, "QUEUED" }, { 0x00000004, "DONE" }, { 0x00000008, "KEYFRAME" }, { 0x00000010, "PFRAME" }, { 0x00000020, "BFRAME" }, { 0x00000040, "ERROR" }, { 0x00000100, "TIMECODE" }, { 0x00000400, "PREPARED" }, { 0x00000800, "NO_CACHE_INVALIDATE" }, { 0x00001000, "NO_CACHE_CLEAN" }, { 0x0000e000, "TIMESTAMP_MASK" }, { 0x00000000, "TIMESTAMP_UNKNOWN" }, { 0x00002000, "TIMESTAMP_MONOTONIC" }, { 0x00004000, "TIMESTAMP_COPY" }, { 0x00100000, "LAST" }), __print_symbolic(REC->field, {0, "ANY"}, {1, "NONE"}, {2, "TOP"}, {3, "BOTTOM"}, {4, "INTERLACED"}, {5, "SEQ_TB"}, {6, "SEQ_BT"}, {7, "ALTERNATE"}, {8, "INTERLACED_TB"}, {9, "INTERLACED_BT"}), REC->timestamp, __print_symbolic(REC->timecode_type, { 1, "24FPS" }, { 2, "25FPS" }, { 3, "30FPS" }, { 4, "50FPS" }, { 5, "60FPS" }), __print_flags(REC->timecode_flags, "|", { 0x0001, "DROPFRAME" }, { 0x0002, "COLORFRAME" }, { 0x0000, "USERBITS_USERDEFINED" }, { 0x0008, "USERBITS_8BITCHARS" }), REC->timecode_frames, REC->timecode_seconds, REC->timecode_minutes, REC->timecode_hours, REC->timecode_userbits0, REC->timecode_userbits1, REC->timecode_userbits2, REC->timecode_userbits3, REC->sequence
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/vb2_v4l2_buf_queue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/vb2_v4l2_buf_queue/format
new file mode 100644
index 000000000..5ffd505cc
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/vb2_v4l2_buf_queue/format
@@ -0,0 +1,25 @@
+name: vb2_v4l2_buf_queue
+ID: 845
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int minor; offset:8; size:4; signed:1;
+ field:u32 flags; offset:12; size:4; signed:0;
+ field:u32 field; offset:16; size:4; signed:0;
+ field:u64 timestamp; offset:24; size:8; signed:0;
+ field:u32 timecode_type; offset:32; size:4; signed:0;
+ field:u32 timecode_flags; offset:36; size:4; signed:0;
+ field:u8 timecode_frames; offset:40; size:1; signed:0;
+ field:u8 timecode_seconds; offset:41; size:1; signed:0;
+ field:u8 timecode_minutes; offset:42; size:1; signed:0;
+ field:u8 timecode_hours; offset:43; size:1; signed:0;
+ field:u8 timecode_userbits0; offset:44; size:1; signed:0;
+ field:u8 timecode_userbits1; offset:45; size:1; signed:0;
+ field:u8 timecode_userbits2; offset:46; size:1; signed:0;
+ field:u8 timecode_userbits3; offset:47; size:1; signed:0;
+ field:u32 sequence; offset:48; size:4; signed:0;
+
+print fmt: "minor=%d flags = %s, field = %s, timestamp = %llu, timecode = { type = %s, flags = %s, frames = %u, seconds = %u, minutes = %u, hours = %u, userbits = { %u %u %u %u } }, sequence = %u", REC->minor, __print_flags(REC->flags, "|", { 0x00000001, "MAPPED" }, { 0x00000002, "QUEUED" }, { 0x00000004, "DONE" }, { 0x00000008, "KEYFRAME" }, { 0x00000010, "PFRAME" }, { 0x00000020, "BFRAME" }, { 0x00000040, "ERROR" }, { 0x00000100, "TIMECODE" }, { 0x00000400, "PREPARED" }, { 0x00000800, "NO_CACHE_INVALIDATE" }, { 0x00001000, "NO_CACHE_CLEAN" }, { 0x0000e000, "TIMESTAMP_MASK" }, { 0x00000000, "TIMESTAMP_UNKNOWN" }, { 0x00002000, "TIMESTAMP_MONOTONIC" }, { 0x00004000, "TIMESTAMP_COPY" }, { 0x00100000, "LAST" }), __print_symbolic(REC->field, {0, "ANY"}, {1, "NONE"}, {2, "TOP"}, {3, "BOTTOM"}, {4, "INTERLACED"}, {5, "SEQ_TB"}, {6, "SEQ_BT"}, {7, "ALTERNATE"}, {8, "INTERLACED_TB"}, {9, "INTERLACED_BT"}), REC->timestamp, __print_symbolic(REC->timecode_type, { 1, "24FPS" }, { 2, "25FPS" }, { 3, "30FPS" }, { 4, "50FPS" }, { 5, "60FPS" }), __print_flags(REC->timecode_flags, "|", { 0x0001, "DROPFRAME" }, { 0x0002, "COLORFRAME" }, { 0x0000, "USERBITS_USERDEFINED" }, { 0x0008, "USERBITS_8BITCHARS" }), REC->timecode_frames, REC->timecode_seconds, REC->timecode_minutes, REC->timecode_hours, REC->timecode_userbits0, REC->timecode_userbits1, REC->timecode_userbits2, REC->timecode_userbits3, REC->sequence
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/vb2_v4l2_dqbuf/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/vb2_v4l2_dqbuf/format
new file mode 100644
index 000000000..badabc9ea
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/vb2_v4l2_dqbuf/format
@@ -0,0 +1,25 @@
+name: vb2_v4l2_dqbuf
+ID: 846
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int minor; offset:8; size:4; signed:1;
+ field:u32 flags; offset:12; size:4; signed:0;
+ field:u32 field; offset:16; size:4; signed:0;
+ field:u64 timestamp; offset:24; size:8; signed:0;
+ field:u32 timecode_type; offset:32; size:4; signed:0;
+ field:u32 timecode_flags; offset:36; size:4; signed:0;
+ field:u8 timecode_frames; offset:40; size:1; signed:0;
+ field:u8 timecode_seconds; offset:41; size:1; signed:0;
+ field:u8 timecode_minutes; offset:42; size:1; signed:0;
+ field:u8 timecode_hours; offset:43; size:1; signed:0;
+ field:u8 timecode_userbits0; offset:44; size:1; signed:0;
+ field:u8 timecode_userbits1; offset:45; size:1; signed:0;
+ field:u8 timecode_userbits2; offset:46; size:1; signed:0;
+ field:u8 timecode_userbits3; offset:47; size:1; signed:0;
+ field:u32 sequence; offset:48; size:4; signed:0;
+
+print fmt: "minor=%d flags = %s, field = %s, timestamp = %llu, timecode = { type = %s, flags = %s, frames = %u, seconds = %u, minutes = %u, hours = %u, userbits = { %u %u %u %u } }, sequence = %u", REC->minor, __print_flags(REC->flags, "|", { 0x00000001, "MAPPED" }, { 0x00000002, "QUEUED" }, { 0x00000004, "DONE" }, { 0x00000008, "KEYFRAME" }, { 0x00000010, "PFRAME" }, { 0x00000020, "BFRAME" }, { 0x00000040, "ERROR" }, { 0x00000100, "TIMECODE" }, { 0x00000400, "PREPARED" }, { 0x00000800, "NO_CACHE_INVALIDATE" }, { 0x00001000, "NO_CACHE_CLEAN" }, { 0x0000e000, "TIMESTAMP_MASK" }, { 0x00000000, "TIMESTAMP_UNKNOWN" }, { 0x00002000, "TIMESTAMP_MONOTONIC" }, { 0x00004000, "TIMESTAMP_COPY" }, { 0x00100000, "LAST" }), __print_symbolic(REC->field, {0, "ANY"}, {1, "NONE"}, {2, "TOP"}, {3, "BOTTOM"}, {4, "INTERLACED"}, {5, "SEQ_TB"}, {6, "SEQ_BT"}, {7, "ALTERNATE"}, {8, "INTERLACED_TB"}, {9, "INTERLACED_BT"}), REC->timestamp, __print_symbolic(REC->timecode_type, { 1, "24FPS" }, { 2, "25FPS" }, { 3, "30FPS" }, { 4, "50FPS" }, { 5, "60FPS" }), __print_flags(REC->timecode_flags, "|", { 0x0001, "DROPFRAME" }, { 0x0002, "COLORFRAME" }, { 0x0000, "USERBITS_USERDEFINED" }, { 0x0008, "USERBITS_8BITCHARS" }), REC->timecode_frames, REC->timecode_seconds, REC->timecode_minutes, REC->timecode_hours, REC->timecode_userbits0, REC->timecode_userbits1, REC->timecode_userbits2, REC->timecode_userbits3, REC->sequence
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/vb2_v4l2_qbuf/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/vb2_v4l2_qbuf/format
new file mode 100644
index 000000000..0568fc0e1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/v4l2/vb2_v4l2_qbuf/format
@@ -0,0 +1,25 @@
+name: vb2_v4l2_qbuf
+ID: 847
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int minor; offset:8; size:4; signed:1;
+ field:u32 flags; offset:12; size:4; signed:0;
+ field:u32 field; offset:16; size:4; signed:0;
+ field:u64 timestamp; offset:24; size:8; signed:0;
+ field:u32 timecode_type; offset:32; size:4; signed:0;
+ field:u32 timecode_flags; offset:36; size:4; signed:0;
+ field:u8 timecode_frames; offset:40; size:1; signed:0;
+ field:u8 timecode_seconds; offset:41; size:1; signed:0;
+ field:u8 timecode_minutes; offset:42; size:1; signed:0;
+ field:u8 timecode_hours; offset:43; size:1; signed:0;
+ field:u8 timecode_userbits0; offset:44; size:1; signed:0;
+ field:u8 timecode_userbits1; offset:45; size:1; signed:0;
+ field:u8 timecode_userbits2; offset:46; size:1; signed:0;
+ field:u8 timecode_userbits3; offset:47; size:1; signed:0;
+ field:u32 sequence; offset:48; size:4; signed:0;
+
+print fmt: "minor=%d flags = %s, field = %s, timestamp = %llu, timecode = { type = %s, flags = %s, frames = %u, seconds = %u, minutes = %u, hours = %u, userbits = { %u %u %u %u } }, sequence = %u", REC->minor, __print_flags(REC->flags, "|", { 0x00000001, "MAPPED" }, { 0x00000002, "QUEUED" }, { 0x00000004, "DONE" }, { 0x00000008, "KEYFRAME" }, { 0x00000010, "PFRAME" }, { 0x00000020, "BFRAME" }, { 0x00000040, "ERROR" }, { 0x00000100, "TIMECODE" }, { 0x00000400, "PREPARED" }, { 0x00000800, "NO_CACHE_INVALIDATE" }, { 0x00001000, "NO_CACHE_CLEAN" }, { 0x0000e000, "TIMESTAMP_MASK" }, { 0x00000000, "TIMESTAMP_UNKNOWN" }, { 0x00002000, "TIMESTAMP_MONOTONIC" }, { 0x00004000, "TIMESTAMP_COPY" }, { 0x00100000, "LAST" }), __print_symbolic(REC->field, {0, "ANY"}, {1, "NONE"}, {2, "TOP"}, {3, "BOTTOM"}, {4, "INTERLACED"}, {5, "SEQ_TB"}, {6, "SEQ_BT"}, {7, "ALTERNATE"}, {8, "INTERLACED_TB"}, {9, "INTERLACED_BT"}), REC->timestamp, __print_symbolic(REC->timecode_type, { 1, "24FPS" }, { 2, "25FPS" }, { 3, "30FPS" }, { 4, "50FPS" }, { 5, "60FPS" }), __print_flags(REC->timecode_flags, "|", { 0x0001, "DROPFRAME" }, { 0x0002, "COLORFRAME" }, { 0x0000, "USERBITS_USERDEFINED" }, { 0x0008, "USERBITS_8BITCHARS" }), REC->timecode_frames, REC->timecode_seconds, REC->timecode_minutes, REC->timecode_hours, REC->timecode_userbits0, REC->timecode_userbits1, REC->timecode_userbits2, REC->timecode_userbits3, REC->sequence
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vb2/vb2_buf_done/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vb2/vb2_buf_done/format
new file mode 100644
index 000000000..347c5f075
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vb2/vb2_buf_done/format
@@ -0,0 +1,17 @@
+name: vb2_buf_done
+ID: 848
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * owner; offset:8; size:8; signed:0;
+ field:u32 queued_count; offset:16; size:4; signed:0;
+ field:int owned_by_drv_count; offset:20; size:4; signed:1;
+ field:u32 index; offset:24; size:4; signed:0;
+ field:u32 type; offset:28; size:4; signed:0;
+ field:u32 bytesused; offset:32; size:4; signed:0;
+ field:u64 timestamp; offset:40; size:8; signed:0;
+
+print fmt: "owner = %p, queued = %u, owned_by_drv = %d, index = %u, type = %u, bytesused = %u, timestamp = %llu", REC->owner, REC->queued_count, REC->owned_by_drv_count, REC->index, REC->type, REC->bytesused, REC->timestamp
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vb2/vb2_buf_queue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vb2/vb2_buf_queue/format
new file mode 100644
index 000000000..3e863cd63
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vb2/vb2_buf_queue/format
@@ -0,0 +1,17 @@
+name: vb2_buf_queue
+ID: 849
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * owner; offset:8; size:8; signed:0;
+ field:u32 queued_count; offset:16; size:4; signed:0;
+ field:int owned_by_drv_count; offset:20; size:4; signed:1;
+ field:u32 index; offset:24; size:4; signed:0;
+ field:u32 type; offset:28; size:4; signed:0;
+ field:u32 bytesused; offset:32; size:4; signed:0;
+ field:u64 timestamp; offset:40; size:8; signed:0;
+
+print fmt: "owner = %p, queued = %u, owned_by_drv = %d, index = %u, type = %u, bytesused = %u, timestamp = %llu", REC->owner, REC->queued_count, REC->owned_by_drv_count, REC->index, REC->type, REC->bytesused, REC->timestamp
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vb2/vb2_dqbuf/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vb2/vb2_dqbuf/format
new file mode 100644
index 000000000..cbff569d4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vb2/vb2_dqbuf/format
@@ -0,0 +1,17 @@
+name: vb2_dqbuf
+ID: 850
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * owner; offset:8; size:8; signed:0;
+ field:u32 queued_count; offset:16; size:4; signed:0;
+ field:int owned_by_drv_count; offset:20; size:4; signed:1;
+ field:u32 index; offset:24; size:4; signed:0;
+ field:u32 type; offset:28; size:4; signed:0;
+ field:u32 bytesused; offset:32; size:4; signed:0;
+ field:u64 timestamp; offset:40; size:8; signed:0;
+
+print fmt: "owner = %p, queued = %u, owned_by_drv = %d, index = %u, type = %u, bytesused = %u, timestamp = %llu", REC->owner, REC->queued_count, REC->owned_by_drv_count, REC->index, REC->type, REC->bytesused, REC->timestamp
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vb2/vb2_qbuf/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vb2/vb2_qbuf/format
new file mode 100644
index 000000000..d14a2b225
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vb2/vb2_qbuf/format
@@ -0,0 +1,17 @@
+name: vb2_qbuf
+ID: 851
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * owner; offset:8; size:8; signed:0;
+ field:u32 queued_count; offset:16; size:4; signed:0;
+ field:int owned_by_drv_count; offset:20; size:4; signed:1;
+ field:u32 index; offset:24; size:4; signed:0;
+ field:u32 type; offset:28; size:4; signed:0;
+ field:u32 bytesused; offset:32; size:4; signed:0;
+ field:u64 timestamp; offset:40; size:8; signed:0;
+
+print fmt: "owner = %p, queued = %u, owned_by_drv = %d, index = %u, type = %u, bytesused = %u, timestamp = %llu", REC->owner, REC->queued_count, REC->owned_by_drv_count, REC->index, REC->type, REC->bytesused, REC->timestamp
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_shrink_slab_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_shrink_slab_end/format
new file mode 100644
index 000000000..42ec9a671
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_shrink_slab_end/format
@@ -0,0 +1,17 @@
+name: mm_shrink_slab_end
+ID: 226
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct shrinker * shr; offset:8; size:8; signed:0;
+ field:int nid; offset:16; size:4; signed:1;
+ field:void * shrink; offset:24; size:8; signed:0;
+ field:long unused_scan; offset:32; size:8; signed:1;
+ field:long new_scan; offset:40; size:8; signed:1;
+ field:int retval; offset:48; size:4; signed:1;
+ field:long total_scan; offset:56; size:8; signed:1;
+
+print fmt: "%pS %p: nid: %d unused scan count %ld new scan count %ld total_scan %ld last shrinker return val %d", REC->shrink, REC->shr, REC->nid, REC->unused_scan, REC->new_scan, REC->total_scan, REC->retval
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_shrink_slab_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_shrink_slab_start/format
new file mode 100644
index 000000000..9a4d83a16
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_shrink_slab_start/format
@@ -0,0 +1,19 @@
+name: mm_shrink_slab_start
+ID: 227
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct shrinker * shr; offset:8; size:8; signed:0;
+ field:void * shrink; offset:16; size:8; signed:0;
+ field:int nid; offset:24; size:4; signed:1;
+ field:long nr_objects_to_shrink; offset:32; size:8; signed:1;
+ field:gfp_t gfp_flags; offset:40; size:4; signed:0;
+ field:unsigned long cache_items; offset:48; size:8; signed:0;
+ field:unsigned long long delta; offset:56; size:8; signed:0;
+ field:unsigned long total_scan; offset:64; size:8; signed:0;
+ field:int priority; offset:72; size:4; signed:1;
+
+print fmt: "%pS %p: nid: %d objects to shrink %ld gfp_flags %s cache items %ld delta %lld total_scan %ld priority %d", REC->shrink, REC->shr, REC->nid, REC->nr_objects_to_shrink, (REC->gfp_flags) ? __print_flags(REC->gfp_flags, "|", {(unsigned long)(((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))) | (( gfp_t)0x400u)), "GFP_TRANSHUGE"}, {(unsigned long)((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))), "GFP_TRANSHUGE_LIGHT"}, {(unsigned long)((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)), "GFP_HIGHUSER_MOVABLE"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)), "GFP_HIGHUSER"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)), "GFP_USER"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)) | (( gfp_t)0x400000u)), "GFP_KERNEL_ACCOUNT"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)), "GFP_KERNEL"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u)), "GFP_NOFS"}, {(unsigned long)((( gfp_t)0x20u)|(( gfp_t)0x200u)|(( gfp_t)0x800u)), "GFP_ATOMIC"}, {(unsigned long)((( gfp_t)(0x400u|0x800u))), "GFP_NOIO"}, {(unsigned long)((( gfp_t)0x800u)), "GFP_NOWAIT"}, {(unsigned long)(( gfp_t)0x01u), "GFP_DMA"}, {(unsigned long)(( gfp_t)0x02u), "__GFP_HIGHMEM"}, {(unsigned long)(( gfp_t)0x04u), "GFP_DMA32"}, {(unsigned long)(( gfp_t)0x20u), "__GFP_HIGH"}, {(unsigned long)(( gfp_t)0x200u), "__GFP_ATOMIC"}, {(unsigned long)(( gfp_t)0x40u), "__GFP_IO"}, {(unsigned long)(( gfp_t)0x80u), "__GFP_FS"}, {(unsigned long)(( gfp_t)0x2000u), "__GFP_NOWARN"}, {(unsigned long)(( gfp_t)0x4000u), "__GFP_RETRY_MAYFAIL"}, {(unsigned long)(( gfp_t)0x8000u), "__GFP_NOFAIL"}, {(unsigned long)(( gfp_t)0x10000u), "__GFP_NORETRY"}, {(unsigned long)(( gfp_t)0x40000u), "__GFP_COMP"}, {(unsigned long)(( gfp_t)0x100u), "__GFP_ZERO"}, {(unsigned long)(( gfp_t)0x80000u), "__GFP_NOMEMALLOC"}, {(unsigned long)(( gfp_t)0x20000u), "__GFP_MEMALLOC"}, {(unsigned long)(( gfp_t)0x100000u), "__GFP_HARDWALL"}, {(unsigned long)(( gfp_t)0x200000u), "__GFP_THISNODE"}, {(unsigned long)(( gfp_t)0x10u), "__GFP_RECLAIMABLE"}, {(unsigned long)(( gfp_t)0x08u), "__GFP_MOVABLE"}, {(unsigned long)(( gfp_t)0x400000u), "__GFP_ACCOUNT"}, {(unsigned long)(( gfp_t)0x1000u), "__GFP_WRITE"}, {(unsigned long)(( gfp_t)(0x400u|0x800u)), "__GFP_RECLAIM"}, {(unsigned long)(( gfp_t)0x400u), "__GFP_DIRECT_RECLAIM"}, {(unsigned long)(( gfp_t)0x800u), "__GFP_KSWAPD_RECLAIM"} ) : "none", REC->cache_items, REC->delta, REC->total_scan, REC->priority
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_direct_reclaim_begin/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_direct_reclaim_begin/format
new file mode 100644
index 000000000..9bc8d1fe6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_direct_reclaim_begin/format
@@ -0,0 +1,12 @@
+name: mm_vmscan_direct_reclaim_begin
+ID: 228
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int order; offset:8; size:4; signed:1;
+ field:gfp_t gfp_flags; offset:12; size:4; signed:0;
+
+print fmt: "order=%d gfp_flags=%s", REC->order, (REC->gfp_flags) ? __print_flags(REC->gfp_flags, "|", {(unsigned long)(((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))) | (( gfp_t)0x400u)), "GFP_TRANSHUGE"}, {(unsigned long)((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))), "GFP_TRANSHUGE_LIGHT"}, {(unsigned long)((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)), "GFP_HIGHUSER_MOVABLE"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)), "GFP_HIGHUSER"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)), "GFP_USER"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)) | (( gfp_t)0x400000u)), "GFP_KERNEL_ACCOUNT"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)), "GFP_KERNEL"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u)), "GFP_NOFS"}, {(unsigned long)((( gfp_t)0x20u)|(( gfp_t)0x200u)|(( gfp_t)0x800u)), "GFP_ATOMIC"}, {(unsigned long)((( gfp_t)(0x400u|0x800u))), "GFP_NOIO"}, {(unsigned long)((( gfp_t)0x800u)), "GFP_NOWAIT"}, {(unsigned long)(( gfp_t)0x01u), "GFP_DMA"}, {(unsigned long)(( gfp_t)0x02u), "__GFP_HIGHMEM"}, {(unsigned long)(( gfp_t)0x04u), "GFP_DMA32"}, {(unsigned long)(( gfp_t)0x20u), "__GFP_HIGH"}, {(unsigned long)(( gfp_t)0x200u), "__GFP_ATOMIC"}, {(unsigned long)(( gfp_t)0x40u), "__GFP_IO"}, {(unsigned long)(( gfp_t)0x80u), "__GFP_FS"}, {(unsigned long)(( gfp_t)0x2000u), "__GFP_NOWARN"}, {(unsigned long)(( gfp_t)0x4000u), "__GFP_RETRY_MAYFAIL"}, {(unsigned long)(( gfp_t)0x8000u), "__GFP_NOFAIL"}, {(unsigned long)(( gfp_t)0x10000u), "__GFP_NORETRY"}, {(unsigned long)(( gfp_t)0x40000u), "__GFP_COMP"}, {(unsigned long)(( gfp_t)0x100u), "__GFP_ZERO"}, {(unsigned long)(( gfp_t)0x80000u), "__GFP_NOMEMALLOC"}, {(unsigned long)(( gfp_t)0x20000u), "__GFP_MEMALLOC"}, {(unsigned long)(( gfp_t)0x100000u), "__GFP_HARDWALL"}, {(unsigned long)(( gfp_t)0x200000u), "__GFP_THISNODE"}, {(unsigned long)(( gfp_t)0x10u), "__GFP_RECLAIMABLE"}, {(unsigned long)(( gfp_t)0x08u), "__GFP_MOVABLE"}, {(unsigned long)(( gfp_t)0x400000u), "__GFP_ACCOUNT"}, {(unsigned long)(( gfp_t)0x1000u), "__GFP_WRITE"}, {(unsigned long)(( gfp_t)(0x400u|0x800u)), "__GFP_RECLAIM"}, {(unsigned long)(( gfp_t)0x400u), "__GFP_DIRECT_RECLAIM"}, {(unsigned long)(( gfp_t)0x800u), "__GFP_KSWAPD_RECLAIM"} ) : "none"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_direct_reclaim_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_direct_reclaim_end/format
new file mode 100644
index 000000000..2fda67116
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_direct_reclaim_end/format
@@ -0,0 +1,11 @@
+name: mm_vmscan_direct_reclaim_end
+ID: 229
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long nr_reclaimed; offset:8; size:8; signed:0;
+
+print fmt: "nr_reclaimed=%lu", REC->nr_reclaimed
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_inactive_list_is_low/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_inactive_list_is_low/format
new file mode 100644
index 000000000..a0c777c2f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_inactive_list_is_low/format
@@ -0,0 +1,18 @@
+name: mm_vmscan_inactive_list_is_low
+ID: 230
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int nid; offset:8; size:4; signed:1;
+ field:int reclaim_idx; offset:12; size:4; signed:1;
+ field:unsigned long total_inactive; offset:16; size:8; signed:0;
+ field:unsigned long inactive; offset:24; size:8; signed:0;
+ field:unsigned long total_active; offset:32; size:8; signed:0;
+ field:unsigned long active; offset:40; size:8; signed:0;
+ field:unsigned long ratio; offset:48; size:8; signed:0;
+ field:int reclaim_flags; offset:56; size:4; signed:1;
+
+print fmt: "nid=%d reclaim_idx=%d total_inactive=%ld inactive=%ld total_active=%ld active=%ld ratio=%ld flags=%s", REC->nid, REC->reclaim_idx, REC->total_inactive, REC->inactive, REC->total_active, REC->active, REC->ratio, (REC->reclaim_flags) ? __print_flags(REC->reclaim_flags, "|", {0x0001u, "RECLAIM_WB_ANON"}, {0x0002u, "RECLAIM_WB_FILE"}, {0x0010u, "RECLAIM_WB_MIXED"}, {0x0004u, "RECLAIM_WB_SYNC"}, {0x0008u, "RECLAIM_WB_ASYNC"} ) : "RECLAIM_WB_NONE"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_kswapd_sleep/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_kswapd_sleep/format
new file mode 100644
index 000000000..d2bc828f9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_kswapd_sleep/format
@@ -0,0 +1,11 @@
+name: mm_vmscan_kswapd_sleep
+ID: 231
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int nid; offset:8; size:4; signed:1;
+
+print fmt: "nid=%d", REC->nid
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_kswapd_wake/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_kswapd_wake/format
new file mode 100644
index 000000000..4be0e7959
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_kswapd_wake/format
@@ -0,0 +1,13 @@
+name: mm_vmscan_kswapd_wake
+ID: 232
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int nid; offset:8; size:4; signed:1;
+ field:int zid; offset:12; size:4; signed:1;
+ field:int order; offset:16; size:4; signed:1;
+
+print fmt: "nid=%d order=%d", REC->nid, REC->order
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_lru_isolate/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_lru_isolate/format
new file mode 100644
index 000000000..85d0e37c4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_lru_isolate/format
@@ -0,0 +1,18 @@
+name: mm_vmscan_lru_isolate
+ID: 233
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int highest_zoneidx; offset:8; size:4; signed:1;
+ field:int order; offset:12; size:4; signed:1;
+ field:unsigned long nr_requested; offset:16; size:8; signed:0;
+ field:unsigned long nr_scanned; offset:24; size:8; signed:0;
+ field:unsigned long nr_skipped; offset:32; size:8; signed:0;
+ field:unsigned long nr_taken; offset:40; size:8; signed:0;
+ field:isolate_mode_t isolate_mode; offset:48; size:4; signed:0;
+ field:int lru; offset:52; size:4; signed:1;
+
+print fmt: "isolate_mode=%d classzone=%d order=%d nr_requested=%lu nr_scanned=%lu nr_skipped=%lu nr_taken=%lu lru=%s", REC->isolate_mode, REC->highest_zoneidx, REC->order, REC->nr_requested, REC->nr_scanned, REC->nr_skipped, REC->nr_taken, __print_symbolic(REC->lru, {0, "inactive_anon"}, {1, "active_anon"}, {2, "inactive_file"}, {3, "active_file"}, {4, "unevictable"})
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_lru_shrink_active/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_lru_shrink_active/format
new file mode 100644
index 000000000..cb9ebee5d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_lru_shrink_active/format
@@ -0,0 +1,17 @@
+name: mm_vmscan_lru_shrink_active
+ID: 234
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int nid; offset:8; size:4; signed:1;
+ field:unsigned long nr_taken; offset:16; size:8; signed:0;
+ field:unsigned long nr_active; offset:24; size:8; signed:0;
+ field:unsigned long nr_deactivated; offset:32; size:8; signed:0;
+ field:unsigned long nr_referenced; offset:40; size:8; signed:0;
+ field:int priority; offset:48; size:4; signed:1;
+ field:int reclaim_flags; offset:52; size:4; signed:1;
+
+print fmt: "nid=%d nr_taken=%ld nr_active=%ld nr_deactivated=%ld nr_referenced=%ld priority=%d flags=%s", REC->nid, REC->nr_taken, REC->nr_active, REC->nr_deactivated, REC->nr_referenced, REC->priority, (REC->reclaim_flags) ? __print_flags(REC->reclaim_flags, "|", {0x0001u, "RECLAIM_WB_ANON"}, {0x0002u, "RECLAIM_WB_FILE"}, {0x0010u, "RECLAIM_WB_MIXED"}, {0x0004u, "RECLAIM_WB_SYNC"}, {0x0008u, "RECLAIM_WB_ASYNC"} ) : "RECLAIM_WB_NONE"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_lru_shrink_inactive/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_lru_shrink_inactive/format
new file mode 100644
index 000000000..7e11e0fcc
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_lru_shrink_inactive/format
@@ -0,0 +1,23 @@
+name: mm_vmscan_lru_shrink_inactive
+ID: 235
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int nid; offset:8; size:4; signed:1;
+ field:unsigned long nr_scanned; offset:16; size:8; signed:0;
+ field:unsigned long nr_reclaimed; offset:24; size:8; signed:0;
+ field:unsigned long nr_dirty; offset:32; size:8; signed:0;
+ field:unsigned long nr_writeback; offset:40; size:8; signed:0;
+ field:unsigned long nr_congested; offset:48; size:8; signed:0;
+ field:unsigned long nr_immediate; offset:56; size:8; signed:0;
+ field:unsigned int nr_activate0; offset:64; size:4; signed:0;
+ field:unsigned int nr_activate1; offset:68; size:4; signed:0;
+ field:unsigned long nr_ref_keep; offset:72; size:8; signed:0;
+ field:unsigned long nr_unmap_fail; offset:80; size:8; signed:0;
+ field:int priority; offset:88; size:4; signed:1;
+ field:int reclaim_flags; offset:92; size:4; signed:1;
+
+print fmt: "nid=%d nr_scanned=%ld nr_reclaimed=%ld nr_dirty=%ld nr_writeback=%ld nr_congested=%ld nr_immediate=%ld nr_activate_anon=%d nr_activate_file=%d nr_ref_keep=%ld nr_unmap_fail=%ld priority=%d flags=%s", REC->nid, REC->nr_scanned, REC->nr_reclaimed, REC->nr_dirty, REC->nr_writeback, REC->nr_congested, REC->nr_immediate, REC->nr_activate0, REC->nr_activate1, REC->nr_ref_keep, REC->nr_unmap_fail, REC->priority, (REC->reclaim_flags) ? __print_flags(REC->reclaim_flags, "|", {0x0001u, "RECLAIM_WB_ANON"}, {0x0002u, "RECLAIM_WB_FILE"}, {0x0010u, "RECLAIM_WB_MIXED"}, {0x0004u, "RECLAIM_WB_SYNC"}, {0x0008u, "RECLAIM_WB_ASYNC"} ) : "RECLAIM_WB_NONE"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_memcg_reclaim_begin/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_memcg_reclaim_begin/format
new file mode 100644
index 000000000..b9f4538dc
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_memcg_reclaim_begin/format
@@ -0,0 +1,12 @@
+name: mm_vmscan_memcg_reclaim_begin
+ID: 236
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int order; offset:8; size:4; signed:1;
+ field:gfp_t gfp_flags; offset:12; size:4; signed:0;
+
+print fmt: "order=%d gfp_flags=%s", REC->order, (REC->gfp_flags) ? __print_flags(REC->gfp_flags, "|", {(unsigned long)(((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))) | (( gfp_t)0x400u)), "GFP_TRANSHUGE"}, {(unsigned long)((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))), "GFP_TRANSHUGE_LIGHT"}, {(unsigned long)((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)), "GFP_HIGHUSER_MOVABLE"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)), "GFP_HIGHUSER"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)), "GFP_USER"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)) | (( gfp_t)0x400000u)), "GFP_KERNEL_ACCOUNT"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)), "GFP_KERNEL"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u)), "GFP_NOFS"}, {(unsigned long)((( gfp_t)0x20u)|(( gfp_t)0x200u)|(( gfp_t)0x800u)), "GFP_ATOMIC"}, {(unsigned long)((( gfp_t)(0x400u|0x800u))), "GFP_NOIO"}, {(unsigned long)((( gfp_t)0x800u)), "GFP_NOWAIT"}, {(unsigned long)(( gfp_t)0x01u), "GFP_DMA"}, {(unsigned long)(( gfp_t)0x02u), "__GFP_HIGHMEM"}, {(unsigned long)(( gfp_t)0x04u), "GFP_DMA32"}, {(unsigned long)(( gfp_t)0x20u), "__GFP_HIGH"}, {(unsigned long)(( gfp_t)0x200u), "__GFP_ATOMIC"}, {(unsigned long)(( gfp_t)0x40u), "__GFP_IO"}, {(unsigned long)(( gfp_t)0x80u), "__GFP_FS"}, {(unsigned long)(( gfp_t)0x2000u), "__GFP_NOWARN"}, {(unsigned long)(( gfp_t)0x4000u), "__GFP_RETRY_MAYFAIL"}, {(unsigned long)(( gfp_t)0x8000u), "__GFP_NOFAIL"}, {(unsigned long)(( gfp_t)0x10000u), "__GFP_NORETRY"}, {(unsigned long)(( gfp_t)0x40000u), "__GFP_COMP"}, {(unsigned long)(( gfp_t)0x100u), "__GFP_ZERO"}, {(unsigned long)(( gfp_t)0x80000u), "__GFP_NOMEMALLOC"}, {(unsigned long)(( gfp_t)0x20000u), "__GFP_MEMALLOC"}, {(unsigned long)(( gfp_t)0x100000u), "__GFP_HARDWALL"}, {(unsigned long)(( gfp_t)0x200000u), "__GFP_THISNODE"}, {(unsigned long)(( gfp_t)0x10u), "__GFP_RECLAIMABLE"}, {(unsigned long)(( gfp_t)0x08u), "__GFP_MOVABLE"}, {(unsigned long)(( gfp_t)0x400000u), "__GFP_ACCOUNT"}, {(unsigned long)(( gfp_t)0x1000u), "__GFP_WRITE"}, {(unsigned long)(( gfp_t)(0x400u|0x800u)), "__GFP_RECLAIM"}, {(unsigned long)(( gfp_t)0x400u), "__GFP_DIRECT_RECLAIM"}, {(unsigned long)(( gfp_t)0x800u), "__GFP_KSWAPD_RECLAIM"} ) : "none"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_memcg_reclaim_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_memcg_reclaim_end/format
new file mode 100644
index 000000000..77f9af9c5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_memcg_reclaim_end/format
@@ -0,0 +1,11 @@
+name: mm_vmscan_memcg_reclaim_end
+ID: 237
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long nr_reclaimed; offset:8; size:8; signed:0;
+
+print fmt: "nr_reclaimed=%lu", REC->nr_reclaimed
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_memcg_softlimit_reclaim_begin/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_memcg_softlimit_reclaim_begin/format
new file mode 100644
index 000000000..7ae928bc5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_memcg_softlimit_reclaim_begin/format
@@ -0,0 +1,12 @@
+name: mm_vmscan_memcg_softlimit_reclaim_begin
+ID: 238
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int order; offset:8; size:4; signed:1;
+ field:gfp_t gfp_flags; offset:12; size:4; signed:0;
+
+print fmt: "order=%d gfp_flags=%s", REC->order, (REC->gfp_flags) ? __print_flags(REC->gfp_flags, "|", {(unsigned long)(((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))) | (( gfp_t)0x400u)), "GFP_TRANSHUGE"}, {(unsigned long)((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))), "GFP_TRANSHUGE_LIGHT"}, {(unsigned long)((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)), "GFP_HIGHUSER_MOVABLE"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)), "GFP_HIGHUSER"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)), "GFP_USER"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)) | (( gfp_t)0x400000u)), "GFP_KERNEL_ACCOUNT"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)), "GFP_KERNEL"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u)), "GFP_NOFS"}, {(unsigned long)((( gfp_t)0x20u)|(( gfp_t)0x200u)|(( gfp_t)0x800u)), "GFP_ATOMIC"}, {(unsigned long)((( gfp_t)(0x400u|0x800u))), "GFP_NOIO"}, {(unsigned long)((( gfp_t)0x800u)), "GFP_NOWAIT"}, {(unsigned long)(( gfp_t)0x01u), "GFP_DMA"}, {(unsigned long)(( gfp_t)0x02u), "__GFP_HIGHMEM"}, {(unsigned long)(( gfp_t)0x04u), "GFP_DMA32"}, {(unsigned long)(( gfp_t)0x20u), "__GFP_HIGH"}, {(unsigned long)(( gfp_t)0x200u), "__GFP_ATOMIC"}, {(unsigned long)(( gfp_t)0x40u), "__GFP_IO"}, {(unsigned long)(( gfp_t)0x80u), "__GFP_FS"}, {(unsigned long)(( gfp_t)0x2000u), "__GFP_NOWARN"}, {(unsigned long)(( gfp_t)0x4000u), "__GFP_RETRY_MAYFAIL"}, {(unsigned long)(( gfp_t)0x8000u), "__GFP_NOFAIL"}, {(unsigned long)(( gfp_t)0x10000u), "__GFP_NORETRY"}, {(unsigned long)(( gfp_t)0x40000u), "__GFP_COMP"}, {(unsigned long)(( gfp_t)0x100u), "__GFP_ZERO"}, {(unsigned long)(( gfp_t)0x80000u), "__GFP_NOMEMALLOC"}, {(unsigned long)(( gfp_t)0x20000u), "__GFP_MEMALLOC"}, {(unsigned long)(( gfp_t)0x100000u), "__GFP_HARDWALL"}, {(unsigned long)(( gfp_t)0x200000u), "__GFP_THISNODE"}, {(unsigned long)(( gfp_t)0x10u), "__GFP_RECLAIMABLE"}, {(unsigned long)(( gfp_t)0x08u), "__GFP_MOVABLE"}, {(unsigned long)(( gfp_t)0x400000u), "__GFP_ACCOUNT"}, {(unsigned long)(( gfp_t)0x1000u), "__GFP_WRITE"}, {(unsigned long)(( gfp_t)(0x400u|0x800u)), "__GFP_RECLAIM"}, {(unsigned long)(( gfp_t)0x400u), "__GFP_DIRECT_RECLAIM"}, {(unsigned long)(( gfp_t)0x800u), "__GFP_KSWAPD_RECLAIM"} ) : "none"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_memcg_softlimit_reclaim_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_memcg_softlimit_reclaim_end/format
new file mode 100644
index 000000000..9f8257aea
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_memcg_softlimit_reclaim_end/format
@@ -0,0 +1,11 @@
+name: mm_vmscan_memcg_softlimit_reclaim_end
+ID: 239
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long nr_reclaimed; offset:8; size:8; signed:0;
+
+print fmt: "nr_reclaimed=%lu", REC->nr_reclaimed
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_node_reclaim_begin/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_node_reclaim_begin/format
new file mode 100644
index 000000000..2c6809919
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_node_reclaim_begin/format
@@ -0,0 +1,13 @@
+name: mm_vmscan_node_reclaim_begin
+ID: 240
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int nid; offset:8; size:4; signed:1;
+ field:int order; offset:12; size:4; signed:1;
+ field:gfp_t gfp_flags; offset:16; size:4; signed:0;
+
+print fmt: "nid=%d order=%d gfp_flags=%s", REC->nid, REC->order, (REC->gfp_flags) ? __print_flags(REC->gfp_flags, "|", {(unsigned long)(((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))) | (( gfp_t)0x400u)), "GFP_TRANSHUGE"}, {(unsigned long)((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))), "GFP_TRANSHUGE_LIGHT"}, {(unsigned long)((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)), "GFP_HIGHUSER_MOVABLE"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)), "GFP_HIGHUSER"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)), "GFP_USER"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)) | (( gfp_t)0x400000u)), "GFP_KERNEL_ACCOUNT"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)), "GFP_KERNEL"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u)), "GFP_NOFS"}, {(unsigned long)((( gfp_t)0x20u)|(( gfp_t)0x200u)|(( gfp_t)0x800u)), "GFP_ATOMIC"}, {(unsigned long)((( gfp_t)(0x400u|0x800u))), "GFP_NOIO"}, {(unsigned long)((( gfp_t)0x800u)), "GFP_NOWAIT"}, {(unsigned long)(( gfp_t)0x01u), "GFP_DMA"}, {(unsigned long)(( gfp_t)0x02u), "__GFP_HIGHMEM"}, {(unsigned long)(( gfp_t)0x04u), "GFP_DMA32"}, {(unsigned long)(( gfp_t)0x20u), "__GFP_HIGH"}, {(unsigned long)(( gfp_t)0x200u), "__GFP_ATOMIC"}, {(unsigned long)(( gfp_t)0x40u), "__GFP_IO"}, {(unsigned long)(( gfp_t)0x80u), "__GFP_FS"}, {(unsigned long)(( gfp_t)0x2000u), "__GFP_NOWARN"}, {(unsigned long)(( gfp_t)0x4000u), "__GFP_RETRY_MAYFAIL"}, {(unsigned long)(( gfp_t)0x8000u), "__GFP_NOFAIL"}, {(unsigned long)(( gfp_t)0x10000u), "__GFP_NORETRY"}, {(unsigned long)(( gfp_t)0x40000u), "__GFP_COMP"}, {(unsigned long)(( gfp_t)0x100u), "__GFP_ZERO"}, {(unsigned long)(( gfp_t)0x80000u), "__GFP_NOMEMALLOC"}, {(unsigned long)(( gfp_t)0x20000u), "__GFP_MEMALLOC"}, {(unsigned long)(( gfp_t)0x100000u), "__GFP_HARDWALL"}, {(unsigned long)(( gfp_t)0x200000u), "__GFP_THISNODE"}, {(unsigned long)(( gfp_t)0x10u), "__GFP_RECLAIMABLE"}, {(unsigned long)(( gfp_t)0x08u), "__GFP_MOVABLE"}, {(unsigned long)(( gfp_t)0x400000u), "__GFP_ACCOUNT"}, {(unsigned long)(( gfp_t)0x1000u), "__GFP_WRITE"}, {(unsigned long)(( gfp_t)(0x400u|0x800u)), "__GFP_RECLAIM"}, {(unsigned long)(( gfp_t)0x400u), "__GFP_DIRECT_RECLAIM"}, {(unsigned long)(( gfp_t)0x800u), "__GFP_KSWAPD_RECLAIM"} ) : "none"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_node_reclaim_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_node_reclaim_end/format
new file mode 100644
index 000000000..367125478
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_node_reclaim_end/format
@@ -0,0 +1,11 @@
+name: mm_vmscan_node_reclaim_end
+ID: 241
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long nr_reclaimed; offset:8; size:8; signed:0;
+
+print fmt: "nr_reclaimed=%lu", REC->nr_reclaimed
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_wakeup_kswapd/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_wakeup_kswapd/format
new file mode 100644
index 000000000..a7a260f3d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_wakeup_kswapd/format
@@ -0,0 +1,14 @@
+name: mm_vmscan_wakeup_kswapd
+ID: 242
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int nid; offset:8; size:4; signed:1;
+ field:int zid; offset:12; size:4; signed:1;
+ field:int order; offset:16; size:4; signed:1;
+ field:gfp_t gfp_flags; offset:20; size:4; signed:0;
+
+print fmt: "nid=%d order=%d gfp_flags=%s", REC->nid, REC->order, (REC->gfp_flags) ? __print_flags(REC->gfp_flags, "|", {(unsigned long)(((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))) | (( gfp_t)0x400u)), "GFP_TRANSHUGE"}, {(unsigned long)((((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)) | (( gfp_t)0x40000u) | (( gfp_t)0x80000u) | (( gfp_t)0x2000u)) & ~(( gfp_t)(0x400u|0x800u))), "GFP_TRANSHUGE_LIGHT"}, {(unsigned long)((((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)) | (( gfp_t)0x08u) | (( gfp_t)0x1000000u)), "GFP_HIGHUSER_MOVABLE"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)) | (( gfp_t)0x02u)), "GFP_HIGHUSER"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u) | (( gfp_t)0x100000u)), "GFP_USER"}, {(unsigned long)(((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)) | (( gfp_t)0x400000u)), "GFP_KERNEL_ACCOUNT"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u) | (( gfp_t)0x80u)), "GFP_KERNEL"}, {(unsigned long)((( gfp_t)(0x400u|0x800u)) | (( gfp_t)0x40u)), "GFP_NOFS"}, {(unsigned long)((( gfp_t)0x20u)|(( gfp_t)0x200u)|(( gfp_t)0x800u)), "GFP_ATOMIC"}, {(unsigned long)((( gfp_t)(0x400u|0x800u))), "GFP_NOIO"}, {(unsigned long)((( gfp_t)0x800u)), "GFP_NOWAIT"}, {(unsigned long)(( gfp_t)0x01u), "GFP_DMA"}, {(unsigned long)(( gfp_t)0x02u), "__GFP_HIGHMEM"}, {(unsigned long)(( gfp_t)0x04u), "GFP_DMA32"}, {(unsigned long)(( gfp_t)0x20u), "__GFP_HIGH"}, {(unsigned long)(( gfp_t)0x200u), "__GFP_ATOMIC"}, {(unsigned long)(( gfp_t)0x40u), "__GFP_IO"}, {(unsigned long)(( gfp_t)0x80u), "__GFP_FS"}, {(unsigned long)(( gfp_t)0x2000u), "__GFP_NOWARN"}, {(unsigned long)(( gfp_t)0x4000u), "__GFP_RETRY_MAYFAIL"}, {(unsigned long)(( gfp_t)0x8000u), "__GFP_NOFAIL"}, {(unsigned long)(( gfp_t)0x10000u), "__GFP_NORETRY"}, {(unsigned long)(( gfp_t)0x40000u), "__GFP_COMP"}, {(unsigned long)(( gfp_t)0x100u), "__GFP_ZERO"}, {(unsigned long)(( gfp_t)0x80000u), "__GFP_NOMEMALLOC"}, {(unsigned long)(( gfp_t)0x20000u), "__GFP_MEMALLOC"}, {(unsigned long)(( gfp_t)0x100000u), "__GFP_HARDWALL"}, {(unsigned long)(( gfp_t)0x200000u), "__GFP_THISNODE"}, {(unsigned long)(( gfp_t)0x10u), "__GFP_RECLAIMABLE"}, {(unsigned long)(( gfp_t)0x08u), "__GFP_MOVABLE"}, {(unsigned long)(( gfp_t)0x400000u), "__GFP_ACCOUNT"}, {(unsigned long)(( gfp_t)0x1000u), "__GFP_WRITE"}, {(unsigned long)(( gfp_t)(0x400u|0x800u)), "__GFP_RECLAIM"}, {(unsigned long)(( gfp_t)0x400u), "__GFP_DIRECT_RECLAIM"}, {(unsigned long)(( gfp_t)0x800u), "__GFP_KSWAPD_RECLAIM"} ) : "none"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_writepage/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_writepage/format
new file mode 100644
index 000000000..6581f10ed
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vmscan/mm_vmscan_writepage/format
@@ -0,0 +1,12 @@
+name: mm_vmscan_writepage
+ID: 243
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long pfn; offset:8; size:8; signed:0;
+ field:int reclaim_flags; offset:16; size:4; signed:1;
+
+print fmt: "page=%p pfn=%lu flags=%s", (((struct page *)(-(((-((((1UL))) << ((((39))) - 1))) - ((-((((1UL))) << ((39)))))) >> (12 - (( __builtin_constant_p(sizeof(struct page)) ? ( ((sizeof(struct page)) == 0 || (sizeof(struct page)) == 1) ? 0 : ( __builtin_constant_p((sizeof(struct page)) - 1) ? ( __builtin_constant_p((sizeof(struct page)) - 1) ? ( ((sizeof(struct page)) - 1) < 2 ? 0 : ((sizeof(struct page)) - 1) & (1ULL << 63) ? 63 : ((sizeof(struct page)) - 1) & (1ULL << 62) ? 62 : ((sizeof(struct page)) - 1) & (1ULL << 61) ? 61 : ((sizeof(struct page)) - 1) & (1ULL << 60) ? 60 : ((sizeof(struct page)) - 1) & (1ULL << 59) ? 59 : ((sizeof(struct page)) - 1) & (1ULL << 58) ? 58 : ((sizeof(struct page)) - 1) & (1ULL << 57) ? 57 : ((sizeof(struct page)) - 1) & (1ULL << 56) ? 56 : ((sizeof(struct page)) - 1) & (1ULL << 55) ? 55 : ((sizeof(struct page)) - 1) & (1ULL << 54) ? 54 : ((sizeof(struct page)) - 1) & (1ULL << 53) ? 53 : ((sizeof(struct page)) - 1) & (1ULL << 52) ? 52 : ((sizeof(struct page)) - 1) & (1ULL << 51) ? 51 : ((sizeof(struct page)) - 1) & (1ULL << 50) ? 50 : ((sizeof(struct page)) - 1) & (1ULL << 49) ? 49 : ((sizeof(struct page)) - 1) & (1ULL << 48) ? 48 : ((sizeof(struct page)) - 1) & (1ULL << 47) ? 47 : ((sizeof(struct page)) - 1) & (1ULL << 46) ? 46 : ((sizeof(struct page)) - 1) & (1ULL << 45) ? 45 : ((sizeof(struct page)) - 1) & (1ULL << 44) ? 44 : ((sizeof(struct page)) - 1) & (1ULL << 43) ? 43 : ((sizeof(struct page)) - 1) & (1ULL << 42) ? 42 : ((sizeof(struct page)) - 1) & (1ULL << 41) ? 41 : ((sizeof(struct page)) - 1) & (1ULL << 40) ? 40 : ((sizeof(struct page)) - 1) & (1ULL << 39) ? 39 : ((sizeof(struct page)) - 1) & (1ULL << 38) ? 38 : ((sizeof(struct page)) - 1) & (1ULL << 37) ? 37 : ((sizeof(struct page)) - 1) & (1ULL << 36) ? 36 : ((sizeof(struct page)) - 1) & (1ULL << 35) ? 35 : ((sizeof(struct page)) - 1) & (1ULL << 34) ? 34 : ((sizeof(struct page)) - 1) & (1ULL << 33) ? 33 : ((sizeof(struct page)) - 1) & (1ULL << 32) ? 32 : ((sizeof(struct page)) - 1) & (1ULL << 31) ? 31 : ((sizeof(struct page)) - 1) & (1ULL << 30) ? 30 : ((sizeof(struct page)) - 1) & (1ULL << 29) ? 29 : ((sizeof(struct page)) - 1) & (1ULL << 28) ? 28 : ((sizeof(struct page)) - 1) & (1ULL << 27) ? 27 : ((sizeof(struct page)) - 1) & (1ULL << 26) ? 26 : ((sizeof(struct page)) - 1) & (1ULL << 25) ? 25 : ((sizeof(struct page)) - 1) & (1ULL << 24) ? 24 : ((sizeof(struct page)) - 1) & (1ULL << 23) ? 23 : ((sizeof(struct page)) - 1) & (1ULL << 22) ? 22 : ((sizeof(struct page)) - 1) & (1ULL << 21) ? 21 : ((sizeof(struct page)) - 1) & (1ULL << 20) ? 20 : ((sizeof(struct page)) - 1) & (1ULL << 19) ? 19 : ((sizeof(struct page)) - 1) & (1ULL << 18) ? 18 : ((sizeof(struct page)) - 1) & (1ULL << 17) ? 17 : ((sizeof(struct page)) - 1) & (1ULL << 16) ? 16 : ((sizeof(struct page)) - 1) & (1ULL << 15) ? 15 : ((sizeof(struct page)) - 1) & (1ULL << 14) ? 14 : ((sizeof(struct page)) - 1) & (1ULL << 13) ? 13 : ((sizeof(struct page)) - 1) & (1ULL << 12) ? 12 : ((sizeof(struct page)) - 1) & (1ULL << 11) ? 11 : ((sizeof(struct page)) - 1) & (1ULL << 10) ? 10 : ((sizeof(struct page)) - 1) & (1ULL << 9) ? 9 : ((sizeof(struct page)) - 1) & (1ULL << 8) ? 8 : ((sizeof(struct page)) - 1) & (1ULL << 7) ? 7 : ((sizeof(struct page)) - 1) & (1ULL << 6) ? 6 : ((sizeof(struct page)) - 1) & (1ULL << 5) ? 5 : ((sizeof(struct page)) - 1) & (1ULL << 4) ? 4 : ((sizeof(struct page)) - 1) & (1ULL << 3) ? 3 : ((sizeof(struct page)) - 1) & (1ULL << 2) ? 2 : 1) : -1) : (sizeof((sizeof(struct page)) - 1) <= 4) ? __ilog2_u32((sizeof(struct page)) - 1) : __ilog2_u64((sizeof(struct page)) - 1) ) + 1) : __order_base_2(sizeof(struct page)) )))) - 0x00200000) - (memstart_addr >> 12)) + (REC->pfn)), REC->pfn, (REC->reclaim_flags) ? __print_flags(REC->reclaim_flags, "|", {0x0001u, "RECLAIM_WB_ANON"}, {0x0002u, "RECLAIM_WB_FILE"}, {0x0010u, "RECLAIM_WB_MIXED"}, {0x0004u, "RECLAIM_WB_SYNC"}, {0x0008u, "RECLAIM_WB_ASYNC"} ) : "RECLAIM_WB_NONE"
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vsock/virtio_transport_alloc_pkt/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vsock/virtio_transport_alloc_pkt/format
new file mode 100644
index 000000000..a19621c09
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vsock/virtio_transport_alloc_pkt/format
@@ -0,0 +1,18 @@
+name: virtio_transport_alloc_pkt
+ID: 1055
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__u32 src_cid; offset:8; size:4; signed:0;
+ field:__u32 src_port; offset:12; size:4; signed:0;
+ field:__u32 dst_cid; offset:16; size:4; signed:0;
+ field:__u32 dst_port; offset:20; size:4; signed:0;
+ field:__u32 len; offset:24; size:4; signed:0;
+ field:__u16 type; offset:28; size:2; signed:0;
+ field:__u16 op; offset:30; size:2; signed:0;
+ field:__u32 flags; offset:32; size:4; signed:0;
+
+print fmt: "%u:%u -> %u:%u len=%u type=%s op=%s flags=%#x", REC->src_cid, REC->src_port, REC->dst_cid, REC->dst_port, REC->len, __print_symbolic(REC->type, { 1, "STREAM" }), __print_symbolic(REC->op, { 0, "INVALID" }, { 1, "REQUEST" }, { 2, "RESPONSE" }, { 3, "RST" }, { 4, "SHUTDOWN" }, { 5, "RW" }, { 6, "CREDIT_UPDATE" }, { 7, "CREDIT_REQUEST" }), REC->flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vsock/virtio_transport_recv_pkt/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vsock/virtio_transport_recv_pkt/format
new file mode 100644
index 000000000..426acfc3d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/vsock/virtio_transport_recv_pkt/format
@@ -0,0 +1,20 @@
+name: virtio_transport_recv_pkt
+ID: 1056
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__u32 src_cid; offset:8; size:4; signed:0;
+ field:__u32 src_port; offset:12; size:4; signed:0;
+ field:__u32 dst_cid; offset:16; size:4; signed:0;
+ field:__u32 dst_port; offset:20; size:4; signed:0;
+ field:__u32 len; offset:24; size:4; signed:0;
+ field:__u16 type; offset:28; size:2; signed:0;
+ field:__u16 op; offset:30; size:2; signed:0;
+ field:__u32 flags; offset:32; size:4; signed:0;
+ field:__u32 buf_alloc; offset:36; size:4; signed:0;
+ field:__u32 fwd_cnt; offset:40; size:4; signed:0;
+
+print fmt: "%u:%u -> %u:%u len=%u type=%s op=%s flags=%#x buf_alloc=%u fwd_cnt=%u", REC->src_cid, REC->src_port, REC->dst_cid, REC->dst_port, REC->len, __print_symbolic(REC->type, { 1, "STREAM" }), __print_symbolic(REC->op, { 0, "INVALID" }, { 1, "REQUEST" }, { 2, "RESPONSE" }, { 3, "RST" }, { 4, "SHUTDOWN" }, { 5, "RW" }, { 6, "CREDIT_UPDATE" }, { 7, "CREDIT_REQUEST" }), REC->flags, REC->buf_alloc, REC->fwd_cnt
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/workqueue/workqueue_activate_work/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/workqueue/workqueue_activate_work/format
new file mode 100644
index 000000000..43c4931f5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/workqueue/workqueue_activate_work/format
@@ -0,0 +1,11 @@
+name: workqueue_activate_work
+ID: 80
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * work; offset:8; size:8; signed:0;
+
+print fmt: "work struct %p", REC->work
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/workqueue/workqueue_execute_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/workqueue/workqueue_execute_end/format
new file mode 100644
index 000000000..54fd03a3a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/workqueue/workqueue_execute_end/format
@@ -0,0 +1,12 @@
+name: workqueue_execute_end
+ID: 81
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * work; offset:8; size:8; signed:0;
+ field:void * function; offset:16; size:8; signed:0;
+
+print fmt: "work struct %p: function %ps", REC->work, REC->function
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/workqueue/workqueue_execute_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/workqueue/workqueue_execute_start/format
new file mode 100644
index 000000000..690a0d669
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/workqueue/workqueue_execute_start/format
@@ -0,0 +1,12 @@
+name: workqueue_execute_start
+ID: 82
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * work; offset:8; size:8; signed:0;
+ field:void * function; offset:16; size:8; signed:0;
+
+print fmt: "work struct %p: function %ps", REC->work, REC->function
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/workqueue/workqueue_queue_work/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/workqueue/workqueue_queue_work/format
new file mode 100644
index 000000000..136581f60
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/workqueue/workqueue_queue_work/format
@@ -0,0 +1,15 @@
+name: workqueue_queue_work
+ID: 83
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * work; offset:8; size:8; signed:0;
+ field:void * function; offset:16; size:8; signed:0;
+ field:void * workqueue; offset:24; size:8; signed:0;
+ field:unsigned int req_cpu; offset:32; size:4; signed:0;
+ field:unsigned int cpu; offset:36; size:4; signed:0;
+
+print fmt: "work struct=%p function=%ps workqueue=%p req_cpu=%u cpu=%u", REC->work, REC->function, REC->workqueue, REC->req_cpu, REC->cpu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/balance_dirty_pages/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/balance_dirty_pages/format
new file mode 100644
index 000000000..be3226277
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/balance_dirty_pages/format
@@ -0,0 +1,25 @@
+name: balance_dirty_pages
+ID: 296
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char bdi[32]; offset:8; size:32; signed:0;
+ field:unsigned long limit; offset:40; size:8; signed:0;
+ field:unsigned long setpoint; offset:48; size:8; signed:0;
+ field:unsigned long dirty; offset:56; size:8; signed:0;
+ field:unsigned long bdi_setpoint; offset:64; size:8; signed:0;
+ field:unsigned long bdi_dirty; offset:72; size:8; signed:0;
+ field:unsigned long dirty_ratelimit; offset:80; size:8; signed:0;
+ field:unsigned long task_ratelimit; offset:88; size:8; signed:0;
+ field:unsigned int dirtied; offset:96; size:4; signed:0;
+ field:unsigned int dirtied_pause; offset:100; size:4; signed:0;
+ field:unsigned long paused; offset:104; size:8; signed:0;
+ field:long pause; offset:112; size:8; signed:1;
+ field:unsigned long period; offset:120; size:8; signed:0;
+ field:long think; offset:128; size:8; signed:1;
+ field:ino_t cgroup_ino; offset:136; size:8; signed:0;
+
+print fmt: "bdi %s: limit=%lu setpoint=%lu dirty=%lu bdi_setpoint=%lu bdi_dirty=%lu dirty_ratelimit=%lu task_ratelimit=%lu dirtied=%u dirtied_pause=%u paused=%lu pause=%ld period=%lu think=%ld cgroup_ino=%lu", REC->bdi, REC->limit, REC->setpoint, REC->dirty, REC->bdi_setpoint, REC->bdi_dirty, REC->dirty_ratelimit, REC->task_ratelimit, REC->dirtied, REC->dirtied_pause, REC->paused, REC->pause, REC->period, REC->think, (unsigned long)REC->cgroup_ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/bdi_dirty_ratelimit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/bdi_dirty_ratelimit/format
new file mode 100644
index 000000000..a651e47d5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/bdi_dirty_ratelimit/format
@@ -0,0 +1,18 @@
+name: bdi_dirty_ratelimit
+ID: 297
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char bdi[32]; offset:8; size:32; signed:0;
+ field:unsigned long write_bw; offset:40; size:8; signed:0;
+ field:unsigned long avg_write_bw; offset:48; size:8; signed:0;
+ field:unsigned long dirty_rate; offset:56; size:8; signed:0;
+ field:unsigned long dirty_ratelimit; offset:64; size:8; signed:0;
+ field:unsigned long task_ratelimit; offset:72; size:8; signed:0;
+ field:unsigned long balanced_dirty_ratelimit; offset:80; size:8; signed:0;
+ field:ino_t cgroup_ino; offset:88; size:8; signed:0;
+
+print fmt: "bdi %s: write_bw=%lu awrite_bw=%lu dirty_rate=%lu dirty_ratelimit=%lu task_ratelimit=%lu balanced_dirty_ratelimit=%lu cgroup_ino=%lu", REC->bdi, REC->write_bw, REC->avg_write_bw, REC->dirty_rate, REC->dirty_ratelimit, REC->task_ratelimit, REC->balanced_dirty_ratelimit, (unsigned long)REC->cgroup_ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/flush_foreign/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/flush_foreign/format
new file mode 100644
index 000000000..48cb604ef
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/flush_foreign/format
@@ -0,0 +1,14 @@
+name: flush_foreign
+ID: 298
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:ino_t cgroup_ino; offset:40; size:8; signed:0;
+ field:unsigned int frn_bdi_id; offset:48; size:4; signed:0;
+ field:unsigned int frn_memcg_id; offset:52; size:4; signed:0;
+
+print fmt: "bdi %s: cgroup_ino=%lu frn_bdi_id=%u frn_memcg_id=%u", REC->name, (unsigned long)REC->cgroup_ino, REC->frn_bdi_id, REC->frn_memcg_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/global_dirty_state/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/global_dirty_state/format
new file mode 100644
index 000000000..69287e61f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/global_dirty_state/format
@@ -0,0 +1,17 @@
+name: global_dirty_state
+ID: 299
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long nr_dirty; offset:8; size:8; signed:0;
+ field:unsigned long nr_writeback; offset:16; size:8; signed:0;
+ field:unsigned long background_thresh; offset:24; size:8; signed:0;
+ field:unsigned long dirty_thresh; offset:32; size:8; signed:0;
+ field:unsigned long dirty_limit; offset:40; size:8; signed:0;
+ field:unsigned long nr_dirtied; offset:48; size:8; signed:0;
+ field:unsigned long nr_written; offset:56; size:8; signed:0;
+
+print fmt: "dirty=%lu writeback=%lu bg_thresh=%lu thresh=%lu limit=%lu dirtied=%lu written=%lu", REC->nr_dirty, REC->nr_writeback, REC->background_thresh, REC->dirty_thresh, REC->dirty_limit, REC->nr_dirtied, REC->nr_written
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/inode_foreign_history/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/inode_foreign_history/format
new file mode 100644
index 000000000..59bd6acbf
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/inode_foreign_history/format
@@ -0,0 +1,14 @@
+name: inode_foreign_history
+ID: 300
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:ino_t ino; offset:40; size:8; signed:0;
+ field:ino_t cgroup_ino; offset:48; size:8; signed:0;
+ field:unsigned int history; offset:56; size:4; signed:0;
+
+print fmt: "bdi %s: ino=%lu cgroup_ino=%lu history=0x%x", REC->name, (unsigned long)REC->ino, (unsigned long)REC->cgroup_ino, REC->history
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/inode_switch_wbs/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/inode_switch_wbs/format
new file mode 100644
index 000000000..c9fa68544
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/inode_switch_wbs/format
@@ -0,0 +1,14 @@
+name: inode_switch_wbs
+ID: 301
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:ino_t ino; offset:40; size:8; signed:0;
+ field:ino_t old_cgroup_ino; offset:48; size:8; signed:0;
+ field:ino_t new_cgroup_ino; offset:56; size:8; signed:0;
+
+print fmt: "bdi %s: ino=%lu old_cgroup_ino=%lu new_cgroup_ino=%lu", REC->name, (unsigned long)REC->ino, (unsigned long)REC->old_cgroup_ino, (unsigned long)REC->new_cgroup_ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/sb_clear_inode_writeback/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/sb_clear_inode_writeback/format
new file mode 100644
index 000000000..7615f308e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/sb_clear_inode_writeback/format
@@ -0,0 +1,15 @@
+name: sb_clear_inode_writeback
+ID: 302
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long state; offset:24; size:8; signed:0;
+ field:__u16 mode; offset:32; size:2; signed:0;
+ field:unsigned long dirtied_when; offset:40; size:8; signed:0;
+
+print fmt: "dev %d,%d ino %lu dirtied %lu state %s mode 0%o", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->dirtied_when, __print_flags(REC->state, "|", {(1 << 0), "I_DIRTY_SYNC"}, {(1 << 1), "I_DIRTY_DATASYNC"}, {(1 << 2), "I_DIRTY_PAGES"}, {(1 << 3), "I_NEW"}, {(1 << 4), "I_WILL_FREE"}, {(1 << 5), "I_FREEING"}, {(1 << 6), "I_CLEAR"}, {(1 << 7), "I_SYNC"}, {(1 << 11), "I_DIRTY_TIME"}, {(1 << 8), "I_REFERENCED"} ), REC->mode
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/sb_mark_inode_writeback/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/sb_mark_inode_writeback/format
new file mode 100644
index 000000000..30e103add
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/sb_mark_inode_writeback/format
@@ -0,0 +1,15 @@
+name: sb_mark_inode_writeback
+ID: 303
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long state; offset:24; size:8; signed:0;
+ field:__u16 mode; offset:32; size:2; signed:0;
+ field:unsigned long dirtied_when; offset:40; size:8; signed:0;
+
+print fmt: "dev %d,%d ino %lu dirtied %lu state %s mode 0%o", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->dirtied_when, __print_flags(REC->state, "|", {(1 << 0), "I_DIRTY_SYNC"}, {(1 << 1), "I_DIRTY_DATASYNC"}, {(1 << 2), "I_DIRTY_PAGES"}, {(1 << 3), "I_NEW"}, {(1 << 4), "I_WILL_FREE"}, {(1 << 5), "I_FREEING"}, {(1 << 6), "I_CLEAR"}, {(1 << 7), "I_SYNC"}, {(1 << 11), "I_DIRTY_TIME"}, {(1 << 8), "I_REFERENCED"} ), REC->mode
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/track_foreign_dirty/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/track_foreign_dirty/format
new file mode 100644
index 000000000..adc6cce94
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/track_foreign_dirty/format
@@ -0,0 +1,16 @@
+name: track_foreign_dirty
+ID: 304
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:u64 bdi_id; offset:40; size:8; signed:0;
+ field:ino_t ino; offset:48; size:8; signed:0;
+ field:unsigned int memcg_id; offset:56; size:4; signed:0;
+ field:ino_t cgroup_ino; offset:64; size:8; signed:0;
+ field:ino_t page_cgroup_ino; offset:72; size:8; signed:0;
+
+print fmt: "bdi %s[%llu]: ino=%lu memcg_id=%u cgroup_ino=%lu page_cgroup_ino=%lu", REC->name, REC->bdi_id, (unsigned long)REC->ino, REC->memcg_id, (unsigned long)REC->cgroup_ino, (unsigned long)REC->page_cgroup_ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/wait_on_page_writeback/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/wait_on_page_writeback/format
new file mode 100644
index 000000000..fe890f313
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/wait_on_page_writeback/format
@@ -0,0 +1,13 @@
+name: wait_on_page_writeback
+ID: 305
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:ino_t ino; offset:40; size:8; signed:0;
+ field:unsigned long index; offset:48; size:8; signed:0;
+
+print fmt: "bdi %s: ino=%lu index=%lu", REC->name, (unsigned long)REC->ino, REC->index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/wbc_writepage/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/wbc_writepage/format
new file mode 100644
index 000000000..85c4b0e23
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/wbc_writepage/format
@@ -0,0 +1,21 @@
+name: wbc_writepage
+ID: 306
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:long nr_to_write; offset:40; size:8; signed:1;
+ field:long pages_skipped; offset:48; size:8; signed:1;
+ field:int sync_mode; offset:56; size:4; signed:1;
+ field:int for_kupdate; offset:60; size:4; signed:1;
+ field:int for_background; offset:64; size:4; signed:1;
+ field:int for_reclaim; offset:68; size:4; signed:1;
+ field:int range_cyclic; offset:72; size:4; signed:1;
+ field:long range_start; offset:80; size:8; signed:1;
+ field:long range_end; offset:88; size:8; signed:1;
+ field:ino_t cgroup_ino; offset:96; size:8; signed:0;
+
+print fmt: "bdi %s: towrt=%ld skip=%ld mode=%d kupd=%d bgrd=%d reclm=%d cyclic=%d start=0x%lx end=0x%lx cgroup_ino=%lu", REC->name, REC->nr_to_write, REC->pages_skipped, REC->sync_mode, REC->for_kupdate, REC->for_background, REC->for_reclaim, REC->range_cyclic, REC->range_start, REC->range_end, (unsigned long)REC->cgroup_ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_bdi_register/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_bdi_register/format
new file mode 100644
index 000000000..fe04fe7bb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_bdi_register/format
@@ -0,0 +1,11 @@
+name: writeback_bdi_register
+ID: 307
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+
+print fmt: "bdi %s", REC->name
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_congestion_wait/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_congestion_wait/format
new file mode 100644
index 000000000..d16ee8817
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_congestion_wait/format
@@ -0,0 +1,12 @@
+name: writeback_congestion_wait
+ID: 308
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int usec_timeout; offset:8; size:4; signed:0;
+ field:unsigned int usec_delayed; offset:12; size:4; signed:0;
+
+print fmt: "usec_timeout=%u usec_delayed=%u", REC->usec_timeout, REC->usec_delayed
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_dirty_inode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_dirty_inode/format
new file mode 100644
index 000000000..21a3c9501
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_dirty_inode/format
@@ -0,0 +1,14 @@
+name: writeback_dirty_inode
+ID: 309
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:ino_t ino; offset:40; size:8; signed:0;
+ field:unsigned long state; offset:48; size:8; signed:0;
+ field:unsigned long flags; offset:56; size:8; signed:0;
+
+print fmt: "bdi %s: ino=%lu state=%s flags=%s", REC->name, (unsigned long)REC->ino, __print_flags(REC->state, "|", {(1 << 0), "I_DIRTY_SYNC"}, {(1 << 1), "I_DIRTY_DATASYNC"}, {(1 << 2), "I_DIRTY_PAGES"}, {(1 << 3), "I_NEW"}, {(1 << 4), "I_WILL_FREE"}, {(1 << 5), "I_FREEING"}, {(1 << 6), "I_CLEAR"}, {(1 << 7), "I_SYNC"}, {(1 << 11), "I_DIRTY_TIME"}, {(1 << 8), "I_REFERENCED"} ), __print_flags(REC->flags, "|", {(1 << 0), "I_DIRTY_SYNC"}, {(1 << 1), "I_DIRTY_DATASYNC"}, {(1 << 2), "I_DIRTY_PAGES"}, {(1 << 3), "I_NEW"}, {(1 << 4), "I_WILL_FREE"}, {(1 << 5), "I_FREEING"}, {(1 << 6), "I_CLEAR"}, {(1 << 7), "I_SYNC"}, {(1 << 11), "I_DIRTY_TIME"}, {(1 << 8), "I_REFERENCED"} )
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_dirty_inode_enqueue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_dirty_inode_enqueue/format
new file mode 100644
index 000000000..0ffee1849
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_dirty_inode_enqueue/format
@@ -0,0 +1,15 @@
+name: writeback_dirty_inode_enqueue
+ID: 310
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long state; offset:24; size:8; signed:0;
+ field:__u16 mode; offset:32; size:2; signed:0;
+ field:unsigned long dirtied_when; offset:40; size:8; signed:0;
+
+print fmt: "dev %d,%d ino %lu dirtied %lu state %s mode 0%o", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->dirtied_when, __print_flags(REC->state, "|", {(1 << 0), "I_DIRTY_SYNC"}, {(1 << 1), "I_DIRTY_DATASYNC"}, {(1 << 2), "I_DIRTY_PAGES"}, {(1 << 3), "I_NEW"}, {(1 << 4), "I_WILL_FREE"}, {(1 << 5), "I_FREEING"}, {(1 << 6), "I_CLEAR"}, {(1 << 7), "I_SYNC"}, {(1 << 11), "I_DIRTY_TIME"}, {(1 << 8), "I_REFERENCED"} ), REC->mode
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_dirty_inode_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_dirty_inode_start/format
new file mode 100644
index 000000000..11864937a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_dirty_inode_start/format
@@ -0,0 +1,14 @@
+name: writeback_dirty_inode_start
+ID: 311
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:ino_t ino; offset:40; size:8; signed:0;
+ field:unsigned long state; offset:48; size:8; signed:0;
+ field:unsigned long flags; offset:56; size:8; signed:0;
+
+print fmt: "bdi %s: ino=%lu state=%s flags=%s", REC->name, (unsigned long)REC->ino, __print_flags(REC->state, "|", {(1 << 0), "I_DIRTY_SYNC"}, {(1 << 1), "I_DIRTY_DATASYNC"}, {(1 << 2), "I_DIRTY_PAGES"}, {(1 << 3), "I_NEW"}, {(1 << 4), "I_WILL_FREE"}, {(1 << 5), "I_FREEING"}, {(1 << 6), "I_CLEAR"}, {(1 << 7), "I_SYNC"}, {(1 << 11), "I_DIRTY_TIME"}, {(1 << 8), "I_REFERENCED"} ), __print_flags(REC->flags, "|", {(1 << 0), "I_DIRTY_SYNC"}, {(1 << 1), "I_DIRTY_DATASYNC"}, {(1 << 2), "I_DIRTY_PAGES"}, {(1 << 3), "I_NEW"}, {(1 << 4), "I_WILL_FREE"}, {(1 << 5), "I_FREEING"}, {(1 << 6), "I_CLEAR"}, {(1 << 7), "I_SYNC"}, {(1 << 11), "I_DIRTY_TIME"}, {(1 << 8), "I_REFERENCED"} )
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_dirty_page/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_dirty_page/format
new file mode 100644
index 000000000..5af2c7015
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_dirty_page/format
@@ -0,0 +1,13 @@
+name: writeback_dirty_page
+ID: 312
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:ino_t ino; offset:40; size:8; signed:0;
+ field:unsigned long index; offset:48; size:8; signed:0;
+
+print fmt: "bdi %s: ino=%lu index=%lu", REC->name, (unsigned long)REC->ino, REC->index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_exec/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_exec/format
new file mode 100644
index 000000000..91d9d5541
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_exec/format
@@ -0,0 +1,19 @@
+name: writeback_exec
+ID: 313
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:long nr_pages; offset:40; size:8; signed:1;
+ field:dev_t sb_dev; offset:48; size:4; signed:0;
+ field:int sync_mode; offset:52; size:4; signed:1;
+ field:int for_kupdate; offset:56; size:4; signed:1;
+ field:int range_cyclic; offset:60; size:4; signed:1;
+ field:int for_background; offset:64; size:4; signed:1;
+ field:int reason; offset:68; size:4; signed:1;
+ field:ino_t cgroup_ino; offset:72; size:8; signed:0;
+
+print fmt: "bdi %s: sb_dev %d:%d nr_pages=%ld sync_mode=%d kupdate=%d range_cyclic=%d background=%d reason=%s cgroup_ino=%lu", REC->name, ((unsigned int) ((REC->sb_dev) >> 20)), ((unsigned int) ((REC->sb_dev) & ((1U << 20) - 1))), REC->nr_pages, REC->sync_mode, REC->for_kupdate, REC->range_cyclic, REC->for_background, __print_symbolic(REC->reason, { 0, "background" }, { 1, "vmscan" }, { 2, "sync" }, { 3, "periodic" }, { 4, "laptop_timer" }, { 5, "fs_free_space" }, { 6, "forker_thread" }), (unsigned long)REC->cgroup_ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_lazytime/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_lazytime/format
new file mode 100644
index 000000000..c98b1f2a9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_lazytime/format
@@ -0,0 +1,15 @@
+name: writeback_lazytime
+ID: 314
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long state; offset:24; size:8; signed:0;
+ field:__u16 mode; offset:32; size:2; signed:0;
+ field:unsigned long dirtied_when; offset:40; size:8; signed:0;
+
+print fmt: "dev %d,%d ino %lu dirtied %lu state %s mode 0%o", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->dirtied_when, __print_flags(REC->state, "|", {(1 << 0), "I_DIRTY_SYNC"}, {(1 << 1), "I_DIRTY_DATASYNC"}, {(1 << 2), "I_DIRTY_PAGES"}, {(1 << 3), "I_NEW"}, {(1 << 4), "I_WILL_FREE"}, {(1 << 5), "I_FREEING"}, {(1 << 6), "I_CLEAR"}, {(1 << 7), "I_SYNC"}, {(1 << 11), "I_DIRTY_TIME"}, {(1 << 8), "I_REFERENCED"} ), REC->mode
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_lazytime_iput/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_lazytime_iput/format
new file mode 100644
index 000000000..e56af3a3d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_lazytime_iput/format
@@ -0,0 +1,15 @@
+name: writeback_lazytime_iput
+ID: 315
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:dev_t dev; offset:8; size:4; signed:0;
+ field:ino_t ino; offset:16; size:8; signed:0;
+ field:unsigned long state; offset:24; size:8; signed:0;
+ field:__u16 mode; offset:32; size:2; signed:0;
+ field:unsigned long dirtied_when; offset:40; size:8; signed:0;
+
+print fmt: "dev %d,%d ino %lu dirtied %lu state %s mode 0%o", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long)REC->ino, REC->dirtied_when, __print_flags(REC->state, "|", {(1 << 0), "I_DIRTY_SYNC"}, {(1 << 1), "I_DIRTY_DATASYNC"}, {(1 << 2), "I_DIRTY_PAGES"}, {(1 << 3), "I_NEW"}, {(1 << 4), "I_WILL_FREE"}, {(1 << 5), "I_FREEING"}, {(1 << 6), "I_CLEAR"}, {(1 << 7), "I_SYNC"}, {(1 << 11), "I_DIRTY_TIME"}, {(1 << 8), "I_REFERENCED"} ), REC->mode
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_mark_inode_dirty/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_mark_inode_dirty/format
new file mode 100644
index 000000000..d7572935e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_mark_inode_dirty/format
@@ -0,0 +1,14 @@
+name: writeback_mark_inode_dirty
+ID: 316
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:ino_t ino; offset:40; size:8; signed:0;
+ field:unsigned long state; offset:48; size:8; signed:0;
+ field:unsigned long flags; offset:56; size:8; signed:0;
+
+print fmt: "bdi %s: ino=%lu state=%s flags=%s", REC->name, (unsigned long)REC->ino, __print_flags(REC->state, "|", {(1 << 0), "I_DIRTY_SYNC"}, {(1 << 1), "I_DIRTY_DATASYNC"}, {(1 << 2), "I_DIRTY_PAGES"}, {(1 << 3), "I_NEW"}, {(1 << 4), "I_WILL_FREE"}, {(1 << 5), "I_FREEING"}, {(1 << 6), "I_CLEAR"}, {(1 << 7), "I_SYNC"}, {(1 << 11), "I_DIRTY_TIME"}, {(1 << 8), "I_REFERENCED"} ), __print_flags(REC->flags, "|", {(1 << 0), "I_DIRTY_SYNC"}, {(1 << 1), "I_DIRTY_DATASYNC"}, {(1 << 2), "I_DIRTY_PAGES"}, {(1 << 3), "I_NEW"}, {(1 << 4), "I_WILL_FREE"}, {(1 << 5), "I_FREEING"}, {(1 << 6), "I_CLEAR"}, {(1 << 7), "I_SYNC"}, {(1 << 11), "I_DIRTY_TIME"}, {(1 << 8), "I_REFERENCED"} )
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_pages_written/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_pages_written/format
new file mode 100644
index 000000000..3780c881b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_pages_written/format
@@ -0,0 +1,11 @@
+name: writeback_pages_written
+ID: 317
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:long pages; offset:8; size:8; signed:1;
+
+print fmt: "%ld", REC->pages
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_queue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_queue/format
new file mode 100644
index 000000000..cf32eaa1e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_queue/format
@@ -0,0 +1,19 @@
+name: writeback_queue
+ID: 318
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:long nr_pages; offset:40; size:8; signed:1;
+ field:dev_t sb_dev; offset:48; size:4; signed:0;
+ field:int sync_mode; offset:52; size:4; signed:1;
+ field:int for_kupdate; offset:56; size:4; signed:1;
+ field:int range_cyclic; offset:60; size:4; signed:1;
+ field:int for_background; offset:64; size:4; signed:1;
+ field:int reason; offset:68; size:4; signed:1;
+ field:ino_t cgroup_ino; offset:72; size:8; signed:0;
+
+print fmt: "bdi %s: sb_dev %d:%d nr_pages=%ld sync_mode=%d kupdate=%d range_cyclic=%d background=%d reason=%s cgroup_ino=%lu", REC->name, ((unsigned int) ((REC->sb_dev) >> 20)), ((unsigned int) ((REC->sb_dev) & ((1U << 20) - 1))), REC->nr_pages, REC->sync_mode, REC->for_kupdate, REC->range_cyclic, REC->for_background, __print_symbolic(REC->reason, { 0, "background" }, { 1, "vmscan" }, { 2, "sync" }, { 3, "periodic" }, { 4, "laptop_timer" }, { 5, "fs_free_space" }, { 6, "forker_thread" }), (unsigned long)REC->cgroup_ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_queue_io/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_queue_io/format
new file mode 100644
index 000000000..e2e7d06f2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_queue_io/format
@@ -0,0 +1,16 @@
+name: writeback_queue_io
+ID: 319
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:unsigned long older; offset:40; size:8; signed:0;
+ field:long age; offset:48; size:8; signed:1;
+ field:int moved; offset:56; size:4; signed:1;
+ field:int reason; offset:60; size:4; signed:1;
+ field:ino_t cgroup_ino; offset:64; size:8; signed:0;
+
+print fmt: "bdi %s: older=%lu age=%ld enqueue=%d reason=%s cgroup_ino=%lu", REC->name, REC->older, REC->age, REC->moved, __print_symbolic(REC->reason, { 0, "background" }, { 1, "vmscan" }, { 2, "sync" }, { 3, "periodic" }, { 4, "laptop_timer" }, { 5, "fs_free_space" }, { 6, "forker_thread" }), (unsigned long)REC->cgroup_ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_sb_inodes_requeue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_sb_inodes_requeue/format
new file mode 100644
index 000000000..83fab337b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_sb_inodes_requeue/format
@@ -0,0 +1,15 @@
+name: writeback_sb_inodes_requeue
+ID: 320
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:ino_t ino; offset:40; size:8; signed:0;
+ field:unsigned long state; offset:48; size:8; signed:0;
+ field:unsigned long dirtied_when; offset:56; size:8; signed:0;
+ field:ino_t cgroup_ino; offset:64; size:8; signed:0;
+
+print fmt: "bdi %s: ino=%lu state=%s dirtied_when=%lu age=%lu cgroup_ino=%lu", REC->name, (unsigned long)REC->ino, __print_flags(REC->state, "|", {(1 << 0), "I_DIRTY_SYNC"}, {(1 << 1), "I_DIRTY_DATASYNC"}, {(1 << 2), "I_DIRTY_PAGES"}, {(1 << 3), "I_NEW"}, {(1 << 4), "I_WILL_FREE"}, {(1 << 5), "I_FREEING"}, {(1 << 6), "I_CLEAR"}, {(1 << 7), "I_SYNC"}, {(1 << 11), "I_DIRTY_TIME"}, {(1 << 8), "I_REFERENCED"} ), REC->dirtied_when, (jiffies - REC->dirtied_when) / 250, (unsigned long)REC->cgroup_ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_single_inode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_single_inode/format
new file mode 100644
index 000000000..652e44b4f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_single_inode/format
@@ -0,0 +1,18 @@
+name: writeback_single_inode
+ID: 321
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:ino_t ino; offset:40; size:8; signed:0;
+ field:unsigned long state; offset:48; size:8; signed:0;
+ field:unsigned long dirtied_when; offset:56; size:8; signed:0;
+ field:unsigned long writeback_index; offset:64; size:8; signed:0;
+ field:long nr_to_write; offset:72; size:8; signed:1;
+ field:unsigned long wrote; offset:80; size:8; signed:0;
+ field:ino_t cgroup_ino; offset:88; size:8; signed:0;
+
+print fmt: "bdi %s: ino=%lu state=%s dirtied_when=%lu age=%lu index=%lu to_write=%ld wrote=%lu cgroup_ino=%lu", REC->name, (unsigned long)REC->ino, __print_flags(REC->state, "|", {(1 << 0), "I_DIRTY_SYNC"}, {(1 << 1), "I_DIRTY_DATASYNC"}, {(1 << 2), "I_DIRTY_PAGES"}, {(1 << 3), "I_NEW"}, {(1 << 4), "I_WILL_FREE"}, {(1 << 5), "I_FREEING"}, {(1 << 6), "I_CLEAR"}, {(1 << 7), "I_SYNC"}, {(1 << 11), "I_DIRTY_TIME"}, {(1 << 8), "I_REFERENCED"} ), REC->dirtied_when, (jiffies - REC->dirtied_when) / 250, REC->writeback_index, REC->nr_to_write, REC->wrote, (unsigned long)REC->cgroup_ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_single_inode_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_single_inode_start/format
new file mode 100644
index 000000000..aed328069
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_single_inode_start/format
@@ -0,0 +1,18 @@
+name: writeback_single_inode_start
+ID: 322
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:ino_t ino; offset:40; size:8; signed:0;
+ field:unsigned long state; offset:48; size:8; signed:0;
+ field:unsigned long dirtied_when; offset:56; size:8; signed:0;
+ field:unsigned long writeback_index; offset:64; size:8; signed:0;
+ field:long nr_to_write; offset:72; size:8; signed:1;
+ field:unsigned long wrote; offset:80; size:8; signed:0;
+ field:ino_t cgroup_ino; offset:88; size:8; signed:0;
+
+print fmt: "bdi %s: ino=%lu state=%s dirtied_when=%lu age=%lu index=%lu to_write=%ld wrote=%lu cgroup_ino=%lu", REC->name, (unsigned long)REC->ino, __print_flags(REC->state, "|", {(1 << 0), "I_DIRTY_SYNC"}, {(1 << 1), "I_DIRTY_DATASYNC"}, {(1 << 2), "I_DIRTY_PAGES"}, {(1 << 3), "I_NEW"}, {(1 << 4), "I_WILL_FREE"}, {(1 << 5), "I_FREEING"}, {(1 << 6), "I_CLEAR"}, {(1 << 7), "I_SYNC"}, {(1 << 11), "I_DIRTY_TIME"}, {(1 << 8), "I_REFERENCED"} ), REC->dirtied_when, (jiffies - REC->dirtied_when) / 250, REC->writeback_index, REC->nr_to_write, REC->wrote, (unsigned long)REC->cgroup_ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_start/format
new file mode 100644
index 000000000..833f08ae2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_start/format
@@ -0,0 +1,19 @@
+name: writeback_start
+ID: 323
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:long nr_pages; offset:40; size:8; signed:1;
+ field:dev_t sb_dev; offset:48; size:4; signed:0;
+ field:int sync_mode; offset:52; size:4; signed:1;
+ field:int for_kupdate; offset:56; size:4; signed:1;
+ field:int range_cyclic; offset:60; size:4; signed:1;
+ field:int for_background; offset:64; size:4; signed:1;
+ field:int reason; offset:68; size:4; signed:1;
+ field:ino_t cgroup_ino; offset:72; size:8; signed:0;
+
+print fmt: "bdi %s: sb_dev %d:%d nr_pages=%ld sync_mode=%d kupdate=%d range_cyclic=%d background=%d reason=%s cgroup_ino=%lu", REC->name, ((unsigned int) ((REC->sb_dev) >> 20)), ((unsigned int) ((REC->sb_dev) & ((1U << 20) - 1))), REC->nr_pages, REC->sync_mode, REC->for_kupdate, REC->range_cyclic, REC->for_background, __print_symbolic(REC->reason, { 0, "background" }, { 1, "vmscan" }, { 2, "sync" }, { 3, "periodic" }, { 4, "laptop_timer" }, { 5, "fs_free_space" }, { 6, "forker_thread" }), (unsigned long)REC->cgroup_ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_wait/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_wait/format
new file mode 100644
index 000000000..898ecce42
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_wait/format
@@ -0,0 +1,19 @@
+name: writeback_wait
+ID: 324
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:long nr_pages; offset:40; size:8; signed:1;
+ field:dev_t sb_dev; offset:48; size:4; signed:0;
+ field:int sync_mode; offset:52; size:4; signed:1;
+ field:int for_kupdate; offset:56; size:4; signed:1;
+ field:int range_cyclic; offset:60; size:4; signed:1;
+ field:int for_background; offset:64; size:4; signed:1;
+ field:int reason; offset:68; size:4; signed:1;
+ field:ino_t cgroup_ino; offset:72; size:8; signed:0;
+
+print fmt: "bdi %s: sb_dev %d:%d nr_pages=%ld sync_mode=%d kupdate=%d range_cyclic=%d background=%d reason=%s cgroup_ino=%lu", REC->name, ((unsigned int) ((REC->sb_dev) >> 20)), ((unsigned int) ((REC->sb_dev) & ((1U << 20) - 1))), REC->nr_pages, REC->sync_mode, REC->for_kupdate, REC->range_cyclic, REC->for_background, __print_symbolic(REC->reason, { 0, "background" }, { 1, "vmscan" }, { 2, "sync" }, { 3, "periodic" }, { 4, "laptop_timer" }, { 5, "fs_free_space" }, { 6, "forker_thread" }), (unsigned long)REC->cgroup_ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_wait_iff_congested/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_wait_iff_congested/format
new file mode 100644
index 000000000..b5b26edea
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_wait_iff_congested/format
@@ -0,0 +1,12 @@
+name: writeback_wait_iff_congested
+ID: 325
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int usec_timeout; offset:8; size:4; signed:0;
+ field:unsigned int usec_delayed; offset:12; size:4; signed:0;
+
+print fmt: "usec_timeout=%u usec_delayed=%u", REC->usec_timeout, REC->usec_delayed
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_wake_background/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_wake_background/format
new file mode 100644
index 000000000..193fb9505
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_wake_background/format
@@ -0,0 +1,12 @@
+name: writeback_wake_background
+ID: 326
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:ino_t cgroup_ino; offset:40; size:8; signed:0;
+
+print fmt: "bdi %s: cgroup_ino=%lu", REC->name, (unsigned long)REC->cgroup_ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_write_inode/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_write_inode/format
new file mode 100644
index 000000000..faa1af079
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_write_inode/format
@@ -0,0 +1,14 @@
+name: writeback_write_inode
+ID: 327
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:ino_t ino; offset:40; size:8; signed:0;
+ field:int sync_mode; offset:48; size:4; signed:1;
+ field:ino_t cgroup_ino; offset:56; size:8; signed:0;
+
+print fmt: "bdi %s: ino=%lu sync_mode=%d cgroup_ino=%lu", REC->name, (unsigned long)REC->ino, REC->sync_mode, (unsigned long)REC->cgroup_ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_write_inode_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_write_inode_start/format
new file mode 100644
index 000000000..4b5e6c93d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_write_inode_start/format
@@ -0,0 +1,14 @@
+name: writeback_write_inode_start
+ID: 328
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:ino_t ino; offset:40; size:8; signed:0;
+ field:int sync_mode; offset:48; size:4; signed:1;
+ field:ino_t cgroup_ino; offset:56; size:8; signed:0;
+
+print fmt: "bdi %s: ino=%lu sync_mode=%d cgroup_ino=%lu", REC->name, (unsigned long)REC->ino, REC->sync_mode, (unsigned long)REC->cgroup_ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_written/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_written/format
new file mode 100644
index 000000000..887d191a9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/writeback/writeback_written/format
@@ -0,0 +1,19 @@
+name: writeback_written
+ID: 329
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:char name[32]; offset:8; size:32; signed:0;
+ field:long nr_pages; offset:40; size:8; signed:1;
+ field:dev_t sb_dev; offset:48; size:4; signed:0;
+ field:int sync_mode; offset:52; size:4; signed:1;
+ field:int for_kupdate; offset:56; size:4; signed:1;
+ field:int range_cyclic; offset:60; size:4; signed:1;
+ field:int for_background; offset:64; size:4; signed:1;
+ field:int reason; offset:68; size:4; signed:1;
+ field:ino_t cgroup_ino; offset:72; size:8; signed:0;
+
+print fmt: "bdi %s: sb_dev %d:%d nr_pages=%ld sync_mode=%d kupdate=%d range_cyclic=%d background=%d reason=%s cgroup_ino=%lu", REC->name, ((unsigned int) ((REC->sb_dev) >> 20)), ((unsigned int) ((REC->sb_dev) & ((1U << 20) - 1))), REC->nr_pages, REC->sync_mode, REC->for_kupdate, REC->range_cyclic, REC->for_background, __print_symbolic(REC->reason, { 0, "background" }, { 1, "vmscan" }, { 2, "sync" }, { 3, "periodic" }, { 4, "laptop_timer" }, { 5, "fs_free_space" }, { 6, "forker_thread" }), (unsigned long)REC->cgroup_ino
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/mem_connect/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/mem_connect/format
new file mode 100644
index 000000000..638bdebfd
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/mem_connect/format
@@ -0,0 +1,16 @@
+name: mem_connect
+ID: 200
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const struct xdp_mem_allocator * xa; offset:8; size:8; signed:0;
+ field:u32 mem_id; offset:16; size:4; signed:0;
+ field:u32 mem_type; offset:20; size:4; signed:0;
+ field:const void * allocator; offset:24; size:8; signed:0;
+ field:const struct xdp_rxq_info * rxq; offset:32; size:8; signed:0;
+ field:int ifindex; offset:40; size:4; signed:1;
+
+print fmt: "mem_id=%d mem_type=%s allocator=%p ifindex=%d", REC->mem_id, __print_symbolic(REC->mem_type, { 0, "PAGE_SHARED" }, { 1, "PAGE_ORDER0" }, { 2, "PAGE_POOL" }, { 3, "XSK_BUFF_POOL" }, { -1, 0 }), REC->allocator, REC->ifindex
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/mem_disconnect/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/mem_disconnect/format
new file mode 100644
index 000000000..913e4b5cb
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/mem_disconnect/format
@@ -0,0 +1,14 @@
+name: mem_disconnect
+ID: 201
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const struct xdp_mem_allocator * xa; offset:8; size:8; signed:0;
+ field:u32 mem_id; offset:16; size:4; signed:0;
+ field:u32 mem_type; offset:20; size:4; signed:0;
+ field:const void * allocator; offset:24; size:8; signed:0;
+
+print fmt: "mem_id=%d mem_type=%s allocator=%p", REC->mem_id, __print_symbolic(REC->mem_type, { 0, "PAGE_SHARED" }, { 1, "PAGE_ORDER0" }, { 2, "PAGE_POOL" }, { 3, "XSK_BUFF_POOL" }, { -1, 0 }), REC->allocator
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/mem_return_failed/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/mem_return_failed/format
new file mode 100644
index 000000000..3359991d7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/mem_return_failed/format
@@ -0,0 +1,13 @@
+name: mem_return_failed
+ID: 202
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const struct page * page; offset:8; size:8; signed:0;
+ field:u32 mem_id; offset:16; size:4; signed:0;
+ field:u32 mem_type; offset:20; size:4; signed:0;
+
+print fmt: "mem_id=%d mem_type=%s page=%p", REC->mem_id, __print_symbolic(REC->mem_type, { 0, "PAGE_SHARED" }, { 1, "PAGE_ORDER0" }, { 2, "PAGE_POOL" }, { 3, "XSK_BUFF_POOL" }, { -1, 0 }), REC->page
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_bulk_tx/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_bulk_tx/format
new file mode 100644
index 000000000..703a91474
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_bulk_tx/format
@@ -0,0 +1,15 @@
+name: xdp_bulk_tx
+ID: 203
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ifindex; offset:8; size:4; signed:1;
+ field:u32 act; offset:12; size:4; signed:0;
+ field:int drops; offset:16; size:4; signed:1;
+ field:int sent; offset:20; size:4; signed:1;
+ field:int err; offset:24; size:4; signed:1;
+
+print fmt: "ifindex=%d action=%s sent=%d drops=%d err=%d", REC->ifindex, __print_symbolic(REC->act, { 0, "ABORTED" }, { 1, "DROP" }, { 2, "PASS" }, { 3, "TX" }, { 4, "REDIRECT" }, { -1, ((void *)0) }), REC->sent, REC->drops, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_cpumap_enqueue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_cpumap_enqueue/format
new file mode 100644
index 000000000..ea1206f53
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_cpumap_enqueue/format
@@ -0,0 +1,16 @@
+name: xdp_cpumap_enqueue
+ID: 204
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int map_id; offset:8; size:4; signed:1;
+ field:u32 act; offset:12; size:4; signed:0;
+ field:int cpu; offset:16; size:4; signed:1;
+ field:unsigned int drops; offset:20; size:4; signed:0;
+ field:unsigned int processed; offset:24; size:4; signed:0;
+ field:int to_cpu; offset:28; size:4; signed:1;
+
+print fmt: "enqueue cpu=%d map_id=%d action=%s processed=%u drops=%u to_cpu=%d", REC->cpu, REC->map_id, __print_symbolic(REC->act, { 0, "ABORTED" }, { 1, "DROP" }, { 2, "PASS" }, { 3, "TX" }, { 4, "REDIRECT" }, { -1, ((void *)0) }), REC->processed, REC->drops, REC->to_cpu
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_cpumap_kthread/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_cpumap_kthread/format
new file mode 100644
index 000000000..67abb27c6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_cpumap_kthread/format
@@ -0,0 +1,19 @@
+name: xdp_cpumap_kthread
+ID: 205
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int map_id; offset:8; size:4; signed:1;
+ field:u32 act; offset:12; size:4; signed:0;
+ field:int cpu; offset:16; size:4; signed:1;
+ field:unsigned int drops; offset:20; size:4; signed:0;
+ field:unsigned int processed; offset:24; size:4; signed:0;
+ field:int sched; offset:28; size:4; signed:1;
+ field:unsigned int xdp_pass; offset:32; size:4; signed:0;
+ field:unsigned int xdp_drop; offset:36; size:4; signed:0;
+ field:unsigned int xdp_redirect; offset:40; size:4; signed:0;
+
+print fmt: "kthread cpu=%d map_id=%d action=%s processed=%u drops=%u sched=%d xdp_pass=%u xdp_drop=%u xdp_redirect=%u", REC->cpu, REC->map_id, __print_symbolic(REC->act, { 0, "ABORTED" }, { 1, "DROP" }, { 2, "PASS" }, { 3, "TX" }, { 4, "REDIRECT" }, { -1, ((void *)0) }), REC->processed, REC->drops, REC->sched, REC->xdp_pass, REC->xdp_drop, REC->xdp_redirect
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_devmap_xmit/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_devmap_xmit/format
new file mode 100644
index 000000000..21172982f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_devmap_xmit/format
@@ -0,0 +1,16 @@
+name: xdp_devmap_xmit
+ID: 206
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int from_ifindex; offset:8; size:4; signed:1;
+ field:u32 act; offset:12; size:4; signed:0;
+ field:int to_ifindex; offset:16; size:4; signed:1;
+ field:int drops; offset:20; size:4; signed:1;
+ field:int sent; offset:24; size:4; signed:1;
+ field:int err; offset:28; size:4; signed:1;
+
+print fmt: "ndo_xdp_xmit from_ifindex=%d to_ifindex=%d action=%s sent=%d drops=%d err=%d", REC->from_ifindex, REC->to_ifindex, __print_symbolic(REC->act, { 0, "ABORTED" }, { 1, "DROP" }, { 2, "PASS" }, { 3, "TX" }, { 4, "REDIRECT" }, { -1, ((void *)0) }), REC->sent, REC->drops, REC->err
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_exception/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_exception/format
new file mode 100644
index 000000000..23fdde6c2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_exception/format
@@ -0,0 +1,13 @@
+name: xdp_exception
+ID: 207
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int prog_id; offset:8; size:4; signed:1;
+ field:u32 act; offset:12; size:4; signed:0;
+ field:int ifindex; offset:16; size:4; signed:1;
+
+print fmt: "prog_id=%d action=%s ifindex=%d", REC->prog_id, __print_symbolic(REC->act, { 0, "ABORTED" }, { 1, "DROP" }, { 2, "PASS" }, { 3, "TX" }, { 4, "REDIRECT" }, { -1, ((void *)0) }), REC->ifindex
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_redirect/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_redirect/format
new file mode 100644
index 000000000..85589add5
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_redirect/format
@@ -0,0 +1,17 @@
+name: xdp_redirect
+ID: 208
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int prog_id; offset:8; size:4; signed:1;
+ field:u32 act; offset:12; size:4; signed:0;
+ field:int ifindex; offset:16; size:4; signed:1;
+ field:int err; offset:20; size:4; signed:1;
+ field:int to_ifindex; offset:24; size:4; signed:1;
+ field:u32 map_id; offset:28; size:4; signed:0;
+ field:int map_index; offset:32; size:4; signed:1;
+
+print fmt: "prog_id=%d action=%s ifindex=%d to_ifindex=%d err=%d map_id=%d map_index=%d", REC->prog_id, __print_symbolic(REC->act, { 0, "ABORTED" }, { 1, "DROP" }, { 2, "PASS" }, { 3, "TX" }, { 4, "REDIRECT" }, { -1, ((void *)0) }), REC->ifindex, REC->to_ifindex, REC->err, REC->map_id, REC->map_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_redirect_err/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_redirect_err/format
new file mode 100644
index 000000000..5a8751832
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_redirect_err/format
@@ -0,0 +1,17 @@
+name: xdp_redirect_err
+ID: 209
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int prog_id; offset:8; size:4; signed:1;
+ field:u32 act; offset:12; size:4; signed:0;
+ field:int ifindex; offset:16; size:4; signed:1;
+ field:int err; offset:20; size:4; signed:1;
+ field:int to_ifindex; offset:24; size:4; signed:1;
+ field:u32 map_id; offset:28; size:4; signed:0;
+ field:int map_index; offset:32; size:4; signed:1;
+
+print fmt: "prog_id=%d action=%s ifindex=%d to_ifindex=%d err=%d map_id=%d map_index=%d", REC->prog_id, __print_symbolic(REC->act, { 0, "ABORTED" }, { 1, "DROP" }, { 2, "PASS" }, { 3, "TX" }, { 4, "REDIRECT" }, { -1, ((void *)0) }), REC->ifindex, REC->to_ifindex, REC->err, REC->map_id, REC->map_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_redirect_map/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_redirect_map/format
new file mode 100644
index 000000000..555e4f2e6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_redirect_map/format
@@ -0,0 +1,17 @@
+name: xdp_redirect_map
+ID: 210
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int prog_id; offset:8; size:4; signed:1;
+ field:u32 act; offset:12; size:4; signed:0;
+ field:int ifindex; offset:16; size:4; signed:1;
+ field:int err; offset:20; size:4; signed:1;
+ field:int to_ifindex; offset:24; size:4; signed:1;
+ field:u32 map_id; offset:28; size:4; signed:0;
+ field:int map_index; offset:32; size:4; signed:1;
+
+print fmt: "prog_id=%d action=%s ifindex=%d to_ifindex=%d err=%d map_id=%d map_index=%d", REC->prog_id, __print_symbolic(REC->act, { 0, "ABORTED" }, { 1, "DROP" }, { 2, "PASS" }, { 3, "TX" }, { 4, "REDIRECT" }, { -1, ((void *)0) }), REC->ifindex, REC->to_ifindex, REC->err, REC->map_id, REC->map_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_redirect_map_err/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_redirect_map_err/format
new file mode 100644
index 000000000..3b8222d1e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xdp/xdp_redirect_map_err/format
@@ -0,0 +1,17 @@
+name: xdp_redirect_map_err
+ID: 211
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int prog_id; offset:8; size:4; signed:1;
+ field:u32 act; offset:12; size:4; signed:0;
+ field:int ifindex; offset:16; size:4; signed:1;
+ field:int err; offset:20; size:4; signed:1;
+ field:int to_ifindex; offset:24; size:4; signed:1;
+ field:u32 map_id; offset:28; size:4; signed:0;
+ field:int map_index; offset:32; size:4; signed:1;
+
+print fmt: "prog_id=%d action=%s ifindex=%d to_ifindex=%d err=%d map_id=%d map_index=%d", REC->prog_id, __print_symbolic(REC->act, { 0, "ABORTED" }, { 1, "DROP" }, { 2, "PASS" }, { 3, "TX" }, { 4, "REDIRECT" }, { -1, ((void *)0) }), REC->ifindex, REC->to_ifindex, REC->err, REC->map_id, REC->map_index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_add_endpoint/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_add_endpoint/format
new file mode 100644
index 000000000..598cb0c55
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_add_endpoint/format
@@ -0,0 +1,14 @@
+name: xhci_add_endpoint
+ID: 740
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 info; offset:8; size:4; signed:0;
+ field:u32 info2; offset:12; size:4; signed:0;
+ field:u64 deq; offset:16; size:8; signed:0;
+ field:u32 tx_info; offset:24; size:4; signed:0;
+
+print fmt: "%s", xhci_decode_ep_context(REC->info, REC->info2, REC->deq, REC->tx_info)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_address_ctrl_ctx/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_address_ctrl_ctx/format
new file mode 100644
index 000000000..79887f504
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_address_ctrl_ctx/format
@@ -0,0 +1,12 @@
+name: xhci_address_ctrl_ctx
+ID: 741
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 drop; offset:8; size:4; signed:0;
+ field:u32 add; offset:12; size:4; signed:0;
+
+print fmt: "%s", xhci_decode_ctrl_ctx(REC->drop, REC->add)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_address_ctx/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_address_ctx/format
new file mode 100644
index 000000000..b7f6c4385
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_address_ctx/format
@@ -0,0 +1,17 @@
+name: xhci_address_ctx
+ID: 742
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ctx_64; offset:8; size:4; signed:1;
+ field:unsigned ctx_type; offset:12; size:4; signed:0;
+ field:dma_addr_t ctx_dma; offset:16; size:8; signed:0;
+ field:u8 * ctx_va; offset:24; size:8; signed:0;
+ field:unsigned ctx_ep_num; offset:32; size:4; signed:0;
+ field:int slot_id; offset:36; size:4; signed:1;
+ field:__data_loc u32[] ctx_data; offset:40; size:4; signed:0;
+
+print fmt: "ctx_64=%d, ctx_type=%u, ctx_dma=@%llx, ctx_va=@%p", REC->ctx_64, REC->ctx_type, (unsigned long long) REC->ctx_dma, REC->ctx_va
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_alloc_dev/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_alloc_dev/format
new file mode 100644
index 000000000..8833aedce
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_alloc_dev/format
@@ -0,0 +1,14 @@
+name: xhci_alloc_dev
+ID: 743
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 info; offset:8; size:4; signed:0;
+ field:u32 info2; offset:12; size:4; signed:0;
+ field:u32 tt_info; offset:16; size:4; signed:0;
+ field:u32 state; offset:20; size:4; signed:0;
+
+print fmt: "%s", xhci_decode_slot_context(REC->info, REC->info2, REC->tt_info, REC->state)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_alloc_virt_device/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_alloc_virt_device/format
new file mode 100644
index 000000000..1ad02047c
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_alloc_virt_device/format
@@ -0,0 +1,19 @@
+name: xhci_alloc_virt_device
+ID: 744
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * vdev; offset:8; size:8; signed:0;
+ field:unsigned long long out_ctx; offset:16; size:8; signed:0;
+ field:unsigned long long in_ctx; offset:24; size:8; signed:0;
+ field:int devnum; offset:32; size:4; signed:1;
+ field:int state; offset:36; size:4; signed:1;
+ field:int speed; offset:40; size:4; signed:1;
+ field:u8 portnum; offset:44; size:1; signed:0;
+ field:u8 level; offset:45; size:1; signed:0;
+ field:int slot_id; offset:48; size:4; signed:1;
+
+print fmt: "vdev %p ctx %llx | %llx num %d state %d speed %d port %d level %d slot %d", REC->vdev, REC->in_ctx, REC->out_ctx, REC->devnum, REC->state, REC->speed, REC->portnum, REC->level, REC->slot_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_configure_endpoint/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_configure_endpoint/format
new file mode 100644
index 000000000..1edee0f28
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_configure_endpoint/format
@@ -0,0 +1,14 @@
+name: xhci_configure_endpoint
+ID: 745
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 info; offset:8; size:4; signed:0;
+ field:u32 info2; offset:12; size:4; signed:0;
+ field:u32 tt_info; offset:16; size:4; signed:0;
+ field:u32 state; offset:20; size:4; signed:0;
+
+print fmt: "%s", xhci_decode_slot_context(REC->info, REC->info2, REC->tt_info, REC->state)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_configure_endpoint_ctrl_ctx/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_configure_endpoint_ctrl_ctx/format
new file mode 100644
index 000000000..9fa7799c2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_configure_endpoint_ctrl_ctx/format
@@ -0,0 +1,12 @@
+name: xhci_configure_endpoint_ctrl_ctx
+ID: 746
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 drop; offset:8; size:4; signed:0;
+ field:u32 add; offset:12; size:4; signed:0;
+
+print fmt: "%s", xhci_decode_ctrl_ctx(REC->drop, REC->add)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_alloc_request/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_alloc_request/format
new file mode 100644
index 000000000..e900c6b35
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_alloc_request/format
@@ -0,0 +1,15 @@
+name: xhci_dbc_alloc_request
+ID: 747
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct dbc_request * req; offset:8; size:8; signed:0;
+ field:bool dir; offset:16; size:1; signed:0;
+ field:unsigned int actual; offset:20; size:4; signed:0;
+ field:unsigned int length; offset:24; size:4; signed:0;
+ field:int status; offset:28; size:4; signed:1;
+
+print fmt: "%s: req %p length %u/%u ==> %d", REC->dir ? "bulk-in" : "bulk-out", REC->req, REC->actual, REC->length, REC->status
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_free_request/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_free_request/format
new file mode 100644
index 000000000..14956fc69
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_free_request/format
@@ -0,0 +1,15 @@
+name: xhci_dbc_free_request
+ID: 748
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct dbc_request * req; offset:8; size:8; signed:0;
+ field:bool dir; offset:16; size:1; signed:0;
+ field:unsigned int actual; offset:20; size:4; signed:0;
+ field:unsigned int length; offset:24; size:4; signed:0;
+ field:int status; offset:28; size:4; signed:1;
+
+print fmt: "%s: req %p length %u/%u ==> %d", REC->dir ? "bulk-in" : "bulk-out", REC->req, REC->actual, REC->length, REC->status
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_gadget_ep_queue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_gadget_ep_queue/format
new file mode 100644
index 000000000..a95f81151
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_gadget_ep_queue/format
@@ -0,0 +1,15 @@
+name: xhci_dbc_gadget_ep_queue
+ID: 749
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 type; offset:8; size:4; signed:0;
+ field:u32 field0; offset:12; size:4; signed:0;
+ field:u32 field1; offset:16; size:4; signed:0;
+ field:u32 field2; offset:20; size:4; signed:0;
+ field:u32 field3; offset:24; size:4; signed:0;
+
+print fmt: "%s: %s", xhci_ring_type_string(REC->type), xhci_decode_trb(REC->field0, REC->field1, REC->field2, REC->field3)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_giveback_request/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_giveback_request/format
new file mode 100644
index 000000000..e02afa05d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_giveback_request/format
@@ -0,0 +1,15 @@
+name: xhci_dbc_giveback_request
+ID: 750
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct dbc_request * req; offset:8; size:8; signed:0;
+ field:bool dir; offset:16; size:1; signed:0;
+ field:unsigned int actual; offset:20; size:4; signed:0;
+ field:unsigned int length; offset:24; size:4; signed:0;
+ field:int status; offset:28; size:4; signed:1;
+
+print fmt: "%s: req %p length %u/%u ==> %d", REC->dir ? "bulk-in" : "bulk-out", REC->req, REC->actual, REC->length, REC->status
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_handle_event/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_handle_event/format
new file mode 100644
index 000000000..60ef97758
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_handle_event/format
@@ -0,0 +1,15 @@
+name: xhci_dbc_handle_event
+ID: 751
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 type; offset:8; size:4; signed:0;
+ field:u32 field0; offset:12; size:4; signed:0;
+ field:u32 field1; offset:16; size:4; signed:0;
+ field:u32 field2; offset:20; size:4; signed:0;
+ field:u32 field3; offset:24; size:4; signed:0;
+
+print fmt: "%s: %s", xhci_ring_type_string(REC->type), xhci_decode_trb(REC->field0, REC->field1, REC->field2, REC->field3)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_handle_transfer/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_handle_transfer/format
new file mode 100644
index 000000000..88a91941f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_handle_transfer/format
@@ -0,0 +1,15 @@
+name: xhci_dbc_handle_transfer
+ID: 752
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 type; offset:8; size:4; signed:0;
+ field:u32 field0; offset:12; size:4; signed:0;
+ field:u32 field1; offset:16; size:4; signed:0;
+ field:u32 field2; offset:20; size:4; signed:0;
+ field:u32 field3; offset:24; size:4; signed:0;
+
+print fmt: "%s: %s", xhci_ring_type_string(REC->type), xhci_decode_trb(REC->field0, REC->field1, REC->field2, REC->field3)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_queue_request/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_queue_request/format
new file mode 100644
index 000000000..9325dff8e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbc_queue_request/format
@@ -0,0 +1,15 @@
+name: xhci_dbc_queue_request
+ID: 753
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct dbc_request * req; offset:8; size:8; signed:0;
+ field:bool dir; offset:16; size:1; signed:0;
+ field:unsigned int actual; offset:20; size:4; signed:0;
+ field:unsigned int length; offset:24; size:4; signed:0;
+ field:int status; offset:28; size:4; signed:1;
+
+print fmt: "%s: req %p length %u/%u ==> %d", REC->dir ? "bulk-in" : "bulk-out", REC->req, REC->actual, REC->length, REC->status
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_address/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_address/format
new file mode 100644
index 000000000..e4878b9a1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_address/format
@@ -0,0 +1,11 @@
+name: xhci_dbg_address
+ID: 754
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] msg; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(msg)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_cancel_urb/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_cancel_urb/format
new file mode 100644
index 000000000..645988bb9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_cancel_urb/format
@@ -0,0 +1,11 @@
+name: xhci_dbg_cancel_urb
+ID: 755
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] msg; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(msg)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_context_change/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_context_change/format
new file mode 100644
index 000000000..2feccf715
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_context_change/format
@@ -0,0 +1,11 @@
+name: xhci_dbg_context_change
+ID: 756
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] msg; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(msg)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_init/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_init/format
new file mode 100644
index 000000000..f219f790d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_init/format
@@ -0,0 +1,11 @@
+name: xhci_dbg_init
+ID: 757
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] msg; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(msg)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_quirks/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_quirks/format
new file mode 100644
index 000000000..cb5188ff4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_quirks/format
@@ -0,0 +1,11 @@
+name: xhci_dbg_quirks
+ID: 758
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] msg; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(msg)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_reset_ep/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_reset_ep/format
new file mode 100644
index 000000000..aa0b8aa59
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_reset_ep/format
@@ -0,0 +1,11 @@
+name: xhci_dbg_reset_ep
+ID: 759
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] msg; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(msg)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_ring_expansion/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_ring_expansion/format
new file mode 100644
index 000000000..e8325110b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_dbg_ring_expansion/format
@@ -0,0 +1,11 @@
+name: xhci_dbg_ring_expansion
+ID: 760
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] msg; offset:8; size:4; signed:0;
+
+print fmt: "%s", __get_str(msg)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_discover_or_reset_device/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_discover_or_reset_device/format
new file mode 100644
index 000000000..aed1add22
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_discover_or_reset_device/format
@@ -0,0 +1,14 @@
+name: xhci_discover_or_reset_device
+ID: 761
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 info; offset:8; size:4; signed:0;
+ field:u32 info2; offset:12; size:4; signed:0;
+ field:u32 tt_info; offset:16; size:4; signed:0;
+ field:u32 state; offset:20; size:4; signed:0;
+
+print fmt: "%s", xhci_decode_slot_context(REC->info, REC->info2, REC->tt_info, REC->state)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_free_dev/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_free_dev/format
new file mode 100644
index 000000000..c1082edd3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_free_dev/format
@@ -0,0 +1,14 @@
+name: xhci_free_dev
+ID: 762
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 info; offset:8; size:4; signed:0;
+ field:u32 info2; offset:12; size:4; signed:0;
+ field:u32 tt_info; offset:16; size:4; signed:0;
+ field:u32 state; offset:20; size:4; signed:0;
+
+print fmt: "%s", xhci_decode_slot_context(REC->info, REC->info2, REC->tt_info, REC->state)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_free_virt_device/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_free_virt_device/format
new file mode 100644
index 000000000..c91d2cbc8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_free_virt_device/format
@@ -0,0 +1,16 @@
+name: xhci_free_virt_device
+ID: 763
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * vdev; offset:8; size:8; signed:0;
+ field:unsigned long long out_ctx; offset:16; size:8; signed:0;
+ field:unsigned long long in_ctx; offset:24; size:8; signed:0;
+ field:u8 fake_port; offset:32; size:1; signed:0;
+ field:u8 real_port; offset:33; size:1; signed:0;
+ field:u16 current_mel; offset:34; size:2; signed:0;
+
+print fmt: "vdev %p ctx %llx | %llx fake_port %d real_port %d current_mel %d", REC->vdev, REC->in_ctx, REC->out_ctx, REC->fake_port, REC->real_port, REC->current_mel
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_get_port_status/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_get_port_status/format
new file mode 100644
index 000000000..dd5669d16
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_get_port_status/format
@@ -0,0 +1,12 @@
+name: xhci_get_port_status
+ID: 764
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 portnum; offset:8; size:4; signed:0;
+ field:u32 portsc; offset:12; size:4; signed:0;
+
+print fmt: "port-%d: %s", REC->portnum, xhci_decode_portsc(REC->portsc)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_addr_dev/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_addr_dev/format
new file mode 100644
index 000000000..3753ddd0e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_addr_dev/format
@@ -0,0 +1,14 @@
+name: xhci_handle_cmd_addr_dev
+ID: 765
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 info; offset:8; size:4; signed:0;
+ field:u32 info2; offset:12; size:4; signed:0;
+ field:u32 tt_info; offset:16; size:4; signed:0;
+ field:u32 state; offset:20; size:4; signed:0;
+
+print fmt: "%s", xhci_decode_slot_context(REC->info, REC->info2, REC->tt_info, REC->state)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_config_ep/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_config_ep/format
new file mode 100644
index 000000000..8fb144ad0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_config_ep/format
@@ -0,0 +1,14 @@
+name: xhci_handle_cmd_config_ep
+ID: 766
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 info; offset:8; size:4; signed:0;
+ field:u32 info2; offset:12; size:4; signed:0;
+ field:u64 deq; offset:16; size:8; signed:0;
+ field:u32 tx_info; offset:24; size:4; signed:0;
+
+print fmt: "%s", xhci_decode_ep_context(REC->info, REC->info2, REC->deq, REC->tx_info)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_disable_slot/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_disable_slot/format
new file mode 100644
index 000000000..6eb0c4fd6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_disable_slot/format
@@ -0,0 +1,14 @@
+name: xhci_handle_cmd_disable_slot
+ID: 767
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 info; offset:8; size:4; signed:0;
+ field:u32 info2; offset:12; size:4; signed:0;
+ field:u32 tt_info; offset:16; size:4; signed:0;
+ field:u32 state; offset:20; size:4; signed:0;
+
+print fmt: "%s", xhci_decode_slot_context(REC->info, REC->info2, REC->tt_info, REC->state)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_reset_dev/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_reset_dev/format
new file mode 100644
index 000000000..3f3311d27
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_reset_dev/format
@@ -0,0 +1,14 @@
+name: xhci_handle_cmd_reset_dev
+ID: 768
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 info; offset:8; size:4; signed:0;
+ field:u32 info2; offset:12; size:4; signed:0;
+ field:u32 tt_info; offset:16; size:4; signed:0;
+ field:u32 state; offset:20; size:4; signed:0;
+
+print fmt: "%s", xhci_decode_slot_context(REC->info, REC->info2, REC->tt_info, REC->state)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_reset_ep/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_reset_ep/format
new file mode 100644
index 000000000..645bf24ae
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_reset_ep/format
@@ -0,0 +1,14 @@
+name: xhci_handle_cmd_reset_ep
+ID: 769
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 info; offset:8; size:4; signed:0;
+ field:u32 info2; offset:12; size:4; signed:0;
+ field:u64 deq; offset:16; size:8; signed:0;
+ field:u32 tx_info; offset:24; size:4; signed:0;
+
+print fmt: "%s", xhci_decode_ep_context(REC->info, REC->info2, REC->deq, REC->tx_info)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_set_deq/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_set_deq/format
new file mode 100644
index 000000000..a4ce7f087
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_set_deq/format
@@ -0,0 +1,14 @@
+name: xhci_handle_cmd_set_deq
+ID: 770
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 info; offset:8; size:4; signed:0;
+ field:u32 info2; offset:12; size:4; signed:0;
+ field:u32 tt_info; offset:16; size:4; signed:0;
+ field:u32 state; offset:20; size:4; signed:0;
+
+print fmt: "%s", xhci_decode_slot_context(REC->info, REC->info2, REC->tt_info, REC->state)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_set_deq_ep/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_set_deq_ep/format
new file mode 100644
index 000000000..8c1c24af3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_set_deq_ep/format
@@ -0,0 +1,14 @@
+name: xhci_handle_cmd_set_deq_ep
+ID: 771
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 info; offset:8; size:4; signed:0;
+ field:u32 info2; offset:12; size:4; signed:0;
+ field:u64 deq; offset:16; size:8; signed:0;
+ field:u32 tx_info; offset:24; size:4; signed:0;
+
+print fmt: "%s", xhci_decode_ep_context(REC->info, REC->info2, REC->deq, REC->tx_info)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_stop_ep/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_stop_ep/format
new file mode 100644
index 000000000..8be6e6c0d
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_cmd_stop_ep/format
@@ -0,0 +1,14 @@
+name: xhci_handle_cmd_stop_ep
+ID: 772
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 info; offset:8; size:4; signed:0;
+ field:u32 info2; offset:12; size:4; signed:0;
+ field:u64 deq; offset:16; size:8; signed:0;
+ field:u32 tx_info; offset:24; size:4; signed:0;
+
+print fmt: "%s", xhci_decode_ep_context(REC->info, REC->info2, REC->deq, REC->tx_info)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_command/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_command/format
new file mode 100644
index 000000000..2fb42f7d3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_command/format
@@ -0,0 +1,15 @@
+name: xhci_handle_command
+ID: 773
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 type; offset:8; size:4; signed:0;
+ field:u32 field0; offset:12; size:4; signed:0;
+ field:u32 field1; offset:16; size:4; signed:0;
+ field:u32 field2; offset:20; size:4; signed:0;
+ field:u32 field3; offset:24; size:4; signed:0;
+
+print fmt: "%s: %s", xhci_ring_type_string(REC->type), xhci_decode_trb(REC->field0, REC->field1, REC->field2, REC->field3)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_event/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_event/format
new file mode 100644
index 000000000..06bdf69c9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_event/format
@@ -0,0 +1,15 @@
+name: xhci_handle_event
+ID: 774
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 type; offset:8; size:4; signed:0;
+ field:u32 field0; offset:12; size:4; signed:0;
+ field:u32 field1; offset:16; size:4; signed:0;
+ field:u32 field2; offset:20; size:4; signed:0;
+ field:u32 field3; offset:24; size:4; signed:0;
+
+print fmt: "%s: %s", xhci_ring_type_string(REC->type), xhci_decode_trb(REC->field0, REC->field1, REC->field2, REC->field3)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_port_status/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_port_status/format
new file mode 100644
index 000000000..c9f829fb2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_port_status/format
@@ -0,0 +1,12 @@
+name: xhci_handle_port_status
+ID: 775
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 portnum; offset:8; size:4; signed:0;
+ field:u32 portsc; offset:12; size:4; signed:0;
+
+print fmt: "port-%d: %s", REC->portnum, xhci_decode_portsc(REC->portsc)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_transfer/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_transfer/format
new file mode 100644
index 000000000..8ea688935
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_handle_transfer/format
@@ -0,0 +1,15 @@
+name: xhci_handle_transfer
+ID: 776
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 type; offset:8; size:4; signed:0;
+ field:u32 field0; offset:12; size:4; signed:0;
+ field:u32 field1; offset:16; size:4; signed:0;
+ field:u32 field2; offset:20; size:4; signed:0;
+ field:u32 field3; offset:24; size:4; signed:0;
+
+print fmt: "%s: %s", xhci_ring_type_string(REC->type), xhci_decode_trb(REC->field0, REC->field1, REC->field2, REC->field3)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_hub_status_data/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_hub_status_data/format
new file mode 100644
index 000000000..fef9142a0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_hub_status_data/format
@@ -0,0 +1,12 @@
+name: xhci_hub_status_data
+ID: 777
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 portnum; offset:8; size:4; signed:0;
+ field:u32 portsc; offset:12; size:4; signed:0;
+
+print fmt: "port-%d: %s", REC->portnum, xhci_decode_portsc(REC->portsc)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_inc_deq/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_inc_deq/format
new file mode 100644
index 000000000..f29400754
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_inc_deq/format
@@ -0,0 +1,21 @@
+name: xhci_inc_deq
+ID: 778
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 type; offset:8; size:4; signed:0;
+ field:void * ring; offset:16; size:8; signed:0;
+ field:dma_addr_t enq; offset:24; size:8; signed:0;
+ field:dma_addr_t deq; offset:32; size:8; signed:0;
+ field:dma_addr_t enq_seg; offset:40; size:8; signed:0;
+ field:dma_addr_t deq_seg; offset:48; size:8; signed:0;
+ field:unsigned int num_segs; offset:56; size:4; signed:0;
+ field:unsigned int stream_id; offset:60; size:4; signed:0;
+ field:unsigned int cycle_state; offset:64; size:4; signed:0;
+ field:unsigned int num_trbs_free; offset:68; size:4; signed:0;
+ field:unsigned int bounce_buf_len; offset:72; size:4; signed:0;
+
+print fmt: "%s %p: enq %pad(%pad) deq %pad(%pad) segs %d stream %d free_trbs %d bounce %d cycle %d", xhci_ring_type_string(REC->type), REC->ring, &REC->enq, &REC->enq_seg, &REC->deq, &REC->deq_seg, REC->num_segs, REC->stream_id, REC->num_trbs_free, REC->bounce_buf_len, REC->cycle_state
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_inc_enq/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_inc_enq/format
new file mode 100644
index 000000000..c7fc22eb8
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_inc_enq/format
@@ -0,0 +1,21 @@
+name: xhci_inc_enq
+ID: 779
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 type; offset:8; size:4; signed:0;
+ field:void * ring; offset:16; size:8; signed:0;
+ field:dma_addr_t enq; offset:24; size:8; signed:0;
+ field:dma_addr_t deq; offset:32; size:8; signed:0;
+ field:dma_addr_t enq_seg; offset:40; size:8; signed:0;
+ field:dma_addr_t deq_seg; offset:48; size:8; signed:0;
+ field:unsigned int num_segs; offset:56; size:4; signed:0;
+ field:unsigned int stream_id; offset:60; size:4; signed:0;
+ field:unsigned int cycle_state; offset:64; size:4; signed:0;
+ field:unsigned int num_trbs_free; offset:68; size:4; signed:0;
+ field:unsigned int bounce_buf_len; offset:72; size:4; signed:0;
+
+print fmt: "%s %p: enq %pad(%pad) deq %pad(%pad) segs %d stream %d free_trbs %d bounce %d cycle %d", xhci_ring_type_string(REC->type), REC->ring, &REC->enq, &REC->enq_seg, &REC->deq, &REC->deq_seg, REC->num_segs, REC->stream_id, REC->num_trbs_free, REC->bounce_buf_len, REC->cycle_state
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_queue_trb/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_queue_trb/format
new file mode 100644
index 000000000..b3fce75e2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_queue_trb/format
@@ -0,0 +1,15 @@
+name: xhci_queue_trb
+ID: 780
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 type; offset:8; size:4; signed:0;
+ field:u32 field0; offset:12; size:4; signed:0;
+ field:u32 field1; offset:16; size:4; signed:0;
+ field:u32 field2; offset:20; size:4; signed:0;
+ field:u32 field3; offset:24; size:4; signed:0;
+
+print fmt: "%s: %s", xhci_ring_type_string(REC->type), xhci_decode_trb(REC->field0, REC->field1, REC->field2, REC->field3)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_ring_alloc/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_ring_alloc/format
new file mode 100644
index 000000000..3593f28b1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_ring_alloc/format
@@ -0,0 +1,21 @@
+name: xhci_ring_alloc
+ID: 781
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 type; offset:8; size:4; signed:0;
+ field:void * ring; offset:16; size:8; signed:0;
+ field:dma_addr_t enq; offset:24; size:8; signed:0;
+ field:dma_addr_t deq; offset:32; size:8; signed:0;
+ field:dma_addr_t enq_seg; offset:40; size:8; signed:0;
+ field:dma_addr_t deq_seg; offset:48; size:8; signed:0;
+ field:unsigned int num_segs; offset:56; size:4; signed:0;
+ field:unsigned int stream_id; offset:60; size:4; signed:0;
+ field:unsigned int cycle_state; offset:64; size:4; signed:0;
+ field:unsigned int num_trbs_free; offset:68; size:4; signed:0;
+ field:unsigned int bounce_buf_len; offset:72; size:4; signed:0;
+
+print fmt: "%s %p: enq %pad(%pad) deq %pad(%pad) segs %d stream %d free_trbs %d bounce %d cycle %d", xhci_ring_type_string(REC->type), REC->ring, &REC->enq, &REC->enq_seg, &REC->deq, &REC->deq_seg, REC->num_segs, REC->stream_id, REC->num_trbs_free, REC->bounce_buf_len, REC->cycle_state
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_ring_ep_doorbell/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_ring_ep_doorbell/format
new file mode 100644
index 000000000..e0db9070e
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_ring_ep_doorbell/format
@@ -0,0 +1,12 @@
+name: xhci_ring_ep_doorbell
+ID: 782
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 slot; offset:8; size:4; signed:0;
+ field:u32 doorbell; offset:12; size:4; signed:0;
+
+print fmt: "Ring doorbell for %s", xhci_decode_doorbell(REC->slot, REC->doorbell)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_ring_expansion/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_ring_expansion/format
new file mode 100644
index 000000000..ed4cd67a0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_ring_expansion/format
@@ -0,0 +1,21 @@
+name: xhci_ring_expansion
+ID: 783
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 type; offset:8; size:4; signed:0;
+ field:void * ring; offset:16; size:8; signed:0;
+ field:dma_addr_t enq; offset:24; size:8; signed:0;
+ field:dma_addr_t deq; offset:32; size:8; signed:0;
+ field:dma_addr_t enq_seg; offset:40; size:8; signed:0;
+ field:dma_addr_t deq_seg; offset:48; size:8; signed:0;
+ field:unsigned int num_segs; offset:56; size:4; signed:0;
+ field:unsigned int stream_id; offset:60; size:4; signed:0;
+ field:unsigned int cycle_state; offset:64; size:4; signed:0;
+ field:unsigned int num_trbs_free; offset:68; size:4; signed:0;
+ field:unsigned int bounce_buf_len; offset:72; size:4; signed:0;
+
+print fmt: "%s %p: enq %pad(%pad) deq %pad(%pad) segs %d stream %d free_trbs %d bounce %d cycle %d", xhci_ring_type_string(REC->type), REC->ring, &REC->enq, &REC->enq_seg, &REC->deq, &REC->deq_seg, REC->num_segs, REC->stream_id, REC->num_trbs_free, REC->bounce_buf_len, REC->cycle_state
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_ring_free/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_ring_free/format
new file mode 100644
index 000000000..da10805f4
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_ring_free/format
@@ -0,0 +1,21 @@
+name: xhci_ring_free
+ID: 784
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 type; offset:8; size:4; signed:0;
+ field:void * ring; offset:16; size:8; signed:0;
+ field:dma_addr_t enq; offset:24; size:8; signed:0;
+ field:dma_addr_t deq; offset:32; size:8; signed:0;
+ field:dma_addr_t enq_seg; offset:40; size:8; signed:0;
+ field:dma_addr_t deq_seg; offset:48; size:8; signed:0;
+ field:unsigned int num_segs; offset:56; size:4; signed:0;
+ field:unsigned int stream_id; offset:60; size:4; signed:0;
+ field:unsigned int cycle_state; offset:64; size:4; signed:0;
+ field:unsigned int num_trbs_free; offset:68; size:4; signed:0;
+ field:unsigned int bounce_buf_len; offset:72; size:4; signed:0;
+
+print fmt: "%s %p: enq %pad(%pad) deq %pad(%pad) segs %d stream %d free_trbs %d bounce %d cycle %d", xhci_ring_type_string(REC->type), REC->ring, &REC->enq, &REC->enq_seg, &REC->deq, &REC->deq_seg, REC->num_segs, REC->stream_id, REC->num_trbs_free, REC->bounce_buf_len, REC->cycle_state
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_ring_host_doorbell/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_ring_host_doorbell/format
new file mode 100644
index 000000000..31a0e4406
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_ring_host_doorbell/format
@@ -0,0 +1,12 @@
+name: xhci_ring_host_doorbell
+ID: 785
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 slot; offset:8; size:4; signed:0;
+ field:u32 doorbell; offset:12; size:4; signed:0;
+
+print fmt: "Ring doorbell for %s", xhci_decode_doorbell(REC->slot, REC->doorbell)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_setup_addressable_virt_device/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_setup_addressable_virt_device/format
new file mode 100644
index 000000000..0fca6c27a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_setup_addressable_virt_device/format
@@ -0,0 +1,19 @@
+name: xhci_setup_addressable_virt_device
+ID: 786
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * vdev; offset:8; size:8; signed:0;
+ field:unsigned long long out_ctx; offset:16; size:8; signed:0;
+ field:unsigned long long in_ctx; offset:24; size:8; signed:0;
+ field:int devnum; offset:32; size:4; signed:1;
+ field:int state; offset:36; size:4; signed:1;
+ field:int speed; offset:40; size:4; signed:1;
+ field:u8 portnum; offset:44; size:1; signed:0;
+ field:u8 level; offset:45; size:1; signed:0;
+ field:int slot_id; offset:48; size:4; signed:1;
+
+print fmt: "vdev %p ctx %llx | %llx num %d state %d speed %d port %d level %d slot %d", REC->vdev, REC->in_ctx, REC->out_ctx, REC->devnum, REC->state, REC->speed, REC->portnum, REC->level, REC->slot_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_setup_device/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_setup_device/format
new file mode 100644
index 000000000..529e1d61a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_setup_device/format
@@ -0,0 +1,19 @@
+name: xhci_setup_device
+ID: 787
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * vdev; offset:8; size:8; signed:0;
+ field:unsigned long long out_ctx; offset:16; size:8; signed:0;
+ field:unsigned long long in_ctx; offset:24; size:8; signed:0;
+ field:int devnum; offset:32; size:4; signed:1;
+ field:int state; offset:36; size:4; signed:1;
+ field:int speed; offset:40; size:4; signed:1;
+ field:u8 portnum; offset:44; size:1; signed:0;
+ field:u8 level; offset:45; size:1; signed:0;
+ field:int slot_id; offset:48; size:4; signed:1;
+
+print fmt: "vdev %p ctx %llx | %llx num %d state %d speed %d port %d level %d slot %d", REC->vdev, REC->in_ctx, REC->out_ctx, REC->devnum, REC->state, REC->speed, REC->portnum, REC->level, REC->slot_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_setup_device_slot/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_setup_device_slot/format
new file mode 100644
index 000000000..f3dbbef64
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_setup_device_slot/format
@@ -0,0 +1,14 @@
+name: xhci_setup_device_slot
+ID: 788
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 info; offset:8; size:4; signed:0;
+ field:u32 info2; offset:12; size:4; signed:0;
+ field:u32 tt_info; offset:16; size:4; signed:0;
+ field:u32 state; offset:20; size:4; signed:0;
+
+print fmt: "%s", xhci_decode_slot_context(REC->info, REC->info2, REC->tt_info, REC->state)
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_stop_device/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_stop_device/format
new file mode 100644
index 000000000..652ab4028
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_stop_device/format
@@ -0,0 +1,19 @@
+name: xhci_stop_device
+ID: 789
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * vdev; offset:8; size:8; signed:0;
+ field:unsigned long long out_ctx; offset:16; size:8; signed:0;
+ field:unsigned long long in_ctx; offset:24; size:8; signed:0;
+ field:int devnum; offset:32; size:4; signed:1;
+ field:int state; offset:36; size:4; signed:1;
+ field:int speed; offset:40; size:4; signed:1;
+ field:u8 portnum; offset:44; size:1; signed:0;
+ field:u8 level; offset:45; size:1; signed:0;
+ field:int slot_id; offset:48; size:4; signed:1;
+
+print fmt: "vdev %p ctx %llx | %llx num %d state %d speed %d port %d level %d slot %d", REC->vdev, REC->in_ctx, REC->out_ctx, REC->devnum, REC->state, REC->speed, REC->portnum, REC->level, REC->slot_id
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_urb_dequeue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_urb_dequeue/format
new file mode 100644
index 000000000..1318a22b3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_urb_dequeue/format
@@ -0,0 +1,23 @@
+name: xhci_urb_dequeue
+ID: 790
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * urb; offset:8; size:8; signed:0;
+ field:unsigned int pipe; offset:16; size:4; signed:0;
+ field:unsigned int stream; offset:20; size:4; signed:0;
+ field:int status; offset:24; size:4; signed:1;
+ field:unsigned int flags; offset:28; size:4; signed:0;
+ field:int num_mapped_sgs; offset:32; size:4; signed:1;
+ field:int num_sgs; offset:36; size:4; signed:1;
+ field:int length; offset:40; size:4; signed:1;
+ field:int actual; offset:44; size:4; signed:1;
+ field:int epnum; offset:48; size:4; signed:1;
+ field:int dir_in; offset:52; size:4; signed:1;
+ field:int type; offset:56; size:4; signed:1;
+ field:int slot_id; offset:60; size:4; signed:1;
+
+print fmt: "ep%d%s-%s: urb %p pipe %u slot %d length %d/%d sgs %d/%d stream %d flags %08x", REC->epnum, REC->dir_in ? "in" : "out", __print_symbolic(REC->type, { 3, "intr" }, { 0, "control" }, { 2, "bulk" }, { 1, "isoc" }), REC->urb, REC->pipe, REC->slot_id, REC->actual, REC->length, REC->num_mapped_sgs, REC->num_sgs, REC->stream, REC->flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_urb_enqueue/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_urb_enqueue/format
new file mode 100644
index 000000000..c2b546e4f
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_urb_enqueue/format
@@ -0,0 +1,23 @@
+name: xhci_urb_enqueue
+ID: 791
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * urb; offset:8; size:8; signed:0;
+ field:unsigned int pipe; offset:16; size:4; signed:0;
+ field:unsigned int stream; offset:20; size:4; signed:0;
+ field:int status; offset:24; size:4; signed:1;
+ field:unsigned int flags; offset:28; size:4; signed:0;
+ field:int num_mapped_sgs; offset:32; size:4; signed:1;
+ field:int num_sgs; offset:36; size:4; signed:1;
+ field:int length; offset:40; size:4; signed:1;
+ field:int actual; offset:44; size:4; signed:1;
+ field:int epnum; offset:48; size:4; signed:1;
+ field:int dir_in; offset:52; size:4; signed:1;
+ field:int type; offset:56; size:4; signed:1;
+ field:int slot_id; offset:60; size:4; signed:1;
+
+print fmt: "ep%d%s-%s: urb %p pipe %u slot %d length %d/%d sgs %d/%d stream %d flags %08x", REC->epnum, REC->dir_in ? "in" : "out", __print_symbolic(REC->type, { 3, "intr" }, { 0, "control" }, { 2, "bulk" }, { 1, "isoc" }), REC->urb, REC->pipe, REC->slot_id, REC->actual, REC->length, REC->num_mapped_sgs, REC->num_sgs, REC->stream, REC->flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_urb_giveback/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_urb_giveback/format
new file mode 100644
index 000000000..4d6a362ce
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/xhci-hcd/xhci_urb_giveback/format
@@ -0,0 +1,23 @@
+name: xhci_urb_giveback
+ID: 792
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * urb; offset:8; size:8; signed:0;
+ field:unsigned int pipe; offset:16; size:4; signed:0;
+ field:unsigned int stream; offset:20; size:4; signed:0;
+ field:int status; offset:24; size:4; signed:1;
+ field:unsigned int flags; offset:28; size:4; signed:0;
+ field:int num_mapped_sgs; offset:32; size:4; signed:1;
+ field:int num_sgs; offset:36; size:4; signed:1;
+ field:int length; offset:40; size:4; signed:1;
+ field:int actual; offset:44; size:4; signed:1;
+ field:int epnum; offset:48; size:4; signed:1;
+ field:int dir_in; offset:52; size:4; signed:1;
+ field:int type; offset:56; size:4; signed:1;
+ field:int slot_id; offset:60; size:4; signed:1;
+
+print fmt: "ep%d%s-%s: urb %p pipe %u slot %d length %d/%d sgs %d/%d stream %d flags %08x", REC->epnum, REC->dir_in ? "in" : "out", __print_symbolic(REC->type, { 3, "intr" }, { 0, "control" }, { 2, "bulk" }, { 1, "isoc" }), REC->urb, REC->pipe, REC->slot_id, REC->actual, REC->length, REC->num_mapped_sgs, REC->num_sgs, REC->stream, REC->flags
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/zram/zcomp_decompress_end/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/zram/zcomp_decompress_end/format
new file mode 100644
index 000000000..e4fd5702a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/zram/zcomp_decompress_end/format
@@ -0,0 +1,12 @@
+name: zcomp_decompress_end
+ID: 1087
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long pfn; offset:8; size:8; signed:0;
+ field:u32 index; offset:16; size:4; signed:0;
+
+print fmt: "pfn=%lu index=%d", REC->pfn, REC->index
diff --git a/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/zram/zcomp_decompress_start/format b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/zram/zcomp_decompress_start/format
new file mode 100644
index 000000000..c329bb49b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/android_raven_AOSP.MASTER_5.10.43/events/zram/zcomp_decompress_start/format
@@ -0,0 +1,12 @@
+name: zcomp_decompress_start
+ID: 1088
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned long pfn; offset:8; size:8; signed:0;
+ field:u32 index; offset:16; size:4; signed:0;
+
+print fmt: "pfn=%lu index=%d", REC->pfn, REC->index
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/cgroup/cgroup_attach_task/format b/src/traced/probes/ftrace/test/data/synthetic/events/cgroup/cgroup_attach_task/format
new file mode 100644
index 000000000..a0c51a813
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/cgroup/cgroup_attach_task/format
@@ -0,0 +1,16 @@
+name: cgroup_attach_task
+ID: 129
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int dst_root; offset:8; size:4; signed:1;
+ field:int dst_id; offset:12; size:4; signed:1;
+ field:int dst_level; offset:16; size:4; signed:1;
+ field:__data_loc char[] dst_path; offset:20; size:4; signed:0;
+ field:int pid; offset:24; size:4; signed:1;
+ field:__data_loc char[] comm; offset:28; size:4; signed:0;
+
+print fmt: "dst_root=%d dst_id=%d dst_level=%d dst_path=%s pid=%d comm=%s", REC->dst_root, REC->dst_id, REC->dst_level, __get_str(dst_path), REC->pid, __get_str(comm) \ No newline at end of file
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/cros_ec/cros_ec_sensorhub_data/format b/src/traced/probes/ftrace/test/data/synthetic/events/cros_ec/cros_ec_sensorhub_data/format
new file mode 100644
index 000000000..d578512d2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/cros_ec/cros_ec_sensorhub_data/format
@@ -0,0 +1,17 @@
+name: cros_ec_sensorhub_data
+ID: 1195
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:u32 ec_sensor_num; offset:8; size:4; signed:0;
+ field:u32 ec_fifo_timestamp; offset:12; size:4; signed:0;
+ field:s64 fifo_timestamp; offset:16; size:8; signed:1;
+ field:s64 current_timestamp; offset:24; size:8; signed:1;
+ field:s64 current_time; offset:32; size:8; signed:1;
+ field:s64 delta; offset:40; size:8; signed:1;
+
+print fmt: "ec_num: %4u, ec_fifo_ts: %9u, fifo_ts: %12lld, curr_ts: %12lld, curr_time: %12lld, delta %12lld", REC->ec_sensor_num, REC->ec_fifo_timestamp, REC->fifo_timestamp, REC->current_timestamp, REC->current_time, REC->delta
+
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/dma_fence/dma_fence_emit/format b/src/traced/probes/ftrace/test/data/synthetic/events/dma_fence/dma_fence_emit/format
new file mode 100644
index 000000000..d730843b3
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/dma_fence/dma_fence_emit/format
@@ -0,0 +1,14 @@
+name: dma_fence_emit
+ID: 1092
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] driver; offset:8; size:4; signed:0;
+ field:__data_loc char[] timeline; offset:12; size:4; signed:0;
+ field:unsigned int context; offset:16; size:4; signed:0;
+ field:unsigned int seqno; offset:20; size:4; signed:0;
+
+print fmt: "driver=%s timeline=%s context=%u seqno=%u", __get_str(driver), __get_str(timeline), REC->context, REC->seqno
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/dma_fence/dma_fence_init/format b/src/traced/probes/ftrace/test/data/synthetic/events/dma_fence/dma_fence_init/format
new file mode 100644
index 000000000..b25f8e799
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/dma_fence/dma_fence_init/format
@@ -0,0 +1,14 @@
+name: dma_fence_init
+ID: 1091
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] driver; offset:8; size:4; signed:0;
+ field:__data_loc char[] timeline; offset:12; size:4; signed:0;
+ field:unsigned int context; offset:16; size:4; signed:0;
+ field:unsigned int seqno; offset:20; size:4; signed:0;
+
+print fmt: "driver=%s timeline=%s context=%u seqno=%u", __get_str(driver), __get_str(timeline), REC->context, REC->seqno
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/dma_fence/dma_fence_signaled/format b/src/traced/probes/ftrace/test/data/synthetic/events/dma_fence/dma_fence_signaled/format
new file mode 100644
index 000000000..e56cc0719
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/dma_fence/dma_fence_signaled/format
@@ -0,0 +1,14 @@
+name: dma_fence_signaled
+ID: 1088
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] driver; offset:8; size:4; signed:0;
+ field:__data_loc char[] timeline; offset:12; size:4; signed:0;
+ field:unsigned int context; offset:16; size:4; signed:0;
+ field:unsigned int seqno; offset:20; size:4; signed:0;
+
+print fmt: "driver=%s timeline=%s context=%u seqno=%u", __get_str(driver), __get_str(timeline), REC->context, REC->seqno
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/dma_fence/dma_fence_wait_end/format b/src/traced/probes/ftrace/test/data/synthetic/events/dma_fence/dma_fence_wait_end/format
new file mode 100644
index 000000000..d61248753
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/dma_fence/dma_fence_wait_end/format
@@ -0,0 +1,14 @@
+name: dma_fence_wait_end
+ID: 1086
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] driver; offset:8; size:4; signed:0;
+ field:__data_loc char[] timeline; offset:12; size:4; signed:0;
+ field:unsigned int context; offset:16; size:4; signed:0;
+ field:unsigned int seqno; offset:20; size:4; signed:0;
+
+print fmt: "driver=%s timeline=%s context=%u seqno=%u", __get_str(driver), __get_str(timeline), REC->context, REC->seqno
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/dma_fence/dma_fence_wait_start/format b/src/traced/probes/ftrace/test/data/synthetic/events/dma_fence/dma_fence_wait_start/format
new file mode 100644
index 000000000..f835d83f6
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/dma_fence/dma_fence_wait_start/format
@@ -0,0 +1,14 @@
+name: dma_fence_wait_start
+ID: 1087
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] driver; offset:8; size:4; signed:0;
+ field:__data_loc char[] timeline; offset:12; size:4; signed:0;
+ field:unsigned int context; offset:16; size:4; signed:0;
+ field:unsigned int seqno; offset:20; size:4; signed:0;
+
+print fmt: "driver=%s timeline=%s context=%u seqno=%u", __get_str(driver), __get_str(timeline), REC->context, REC->seqno
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/drm/drm_vblank_event/format b/src/traced/probes/ftrace/test/data/synthetic/events/drm/drm_vblank_event/format
new file mode 100644
index 000000000..f2c33c3c9
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/drm/drm_vblank_event/format
@@ -0,0 +1,14 @@
+name: drm_vblank_event
+ID: 980
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int crtc; offset:8; size:4; signed:1;
+ field:unsigned int seq; offset:12; size:4; signed:0;
+ field:ktime_t time; offset:16; size:8; signed:1;
+ field:bool high_prec; offset:24; size:1; signed:0;
+
+print fmt: "crtc=%d, seq=%u, time=%lld, high-prec=%s", REC->crtc, REC->seq, REC->time, REC->high_prec ? "true" : "false"
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/drm/drm_vblank_event_delivered/format b/src/traced/probes/ftrace/test/data/synthetic/events/drm/drm_vblank_event_delivered/format
new file mode 100644
index 000000000..04dee60fa
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/drm/drm_vblank_event_delivered/format
@@ -0,0 +1,13 @@
+name: drm_vblank_event_delivered
+ID: 978
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct drm_file * file; offset:8; size:8; signed:0;
+ field:int crtc; offset:16; size:4; signed:1;
+ field:unsigned int seq; offset:20; size:4; signed:0;
+
+print fmt: "file=%p, crtc=%d, seq=%u", REC->file, REC->crtc, REC->seq
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/gpu_scheduler/drm_run_job/format b/src/traced/probes/ftrace/test/data/synthetic/events/gpu_scheduler/drm_run_job/format
new file mode 100644
index 000000000..59c9f62a2
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/gpu_scheduler/drm_run_job/format
@@ -0,0 +1,16 @@
+name: drm_run_job
+ID: 983
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct drm_sched_entity * entity; offset:8; size:8; signed:0;
+ field:struct dma_fence * fence; offset:16; size:8; signed:0;
+ field:__data_loc char[] name; offset:24; size:4; signed:0;
+ field:uint64_t id; offset:32; size:8; signed:0;
+ field:u32 job_count; offset:40; size:4; signed:0;
+ field:int hw_job_count; offset:44; size:4; signed:1;
+
+print fmt: "entity=%p, id=%llu, fence=%p, ring=%s, job count:%u, hw job count:%d", REC->entity, REC->id, REC->fence, __get_str(name), REC->job_count, REC->hw_job_count
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/gpu_scheduler/drm_sched_job/format b/src/traced/probes/ftrace/test/data/synthetic/events/gpu_scheduler/drm_sched_job/format
new file mode 100644
index 000000000..0122bc416
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/gpu_scheduler/drm_sched_job/format
@@ -0,0 +1,16 @@
+name: drm_sched_job
+ID: 984
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct drm_sched_entity * entity; offset:8; size:8; signed:0;
+ field:struct dma_fence * fence; offset:16; size:8; signed:0;
+ field:__data_loc char[] name; offset:24; size:4; signed:0;
+ field:uint64_t id; offset:32; size:8; signed:0;
+ field:u32 job_count; offset:40; size:4; signed:0;
+ field:int hw_job_count; offset:44; size:4; signed:1;
+
+print fmt: "entity=%p, id=%llu, fence=%p, ring=%s, job count:%u, hw job count:%d", REC->entity, REC->id, REC->fence, __get_str(name), REC->job_count, REC->hw_job_count
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/gpu_scheduler/drm_sched_process_job/format b/src/traced/probes/ftrace/test/data/synthetic/events/gpu_scheduler/drm_sched_process_job/format
new file mode 100644
index 000000000..4234ed4c0
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/gpu_scheduler/drm_sched_process_job/format
@@ -0,0 +1,11 @@
+name: drm_sched_process_job
+ID: 982
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:struct dma_fence * fence; offset:8; size:8; signed:0;
+
+print fmt: "fence=%p signaled", REC->fence
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/net/napi_gro_receive_entry/format b/src/traced/probes/ftrace/test/data/synthetic/events/net/napi_gro_receive_entry/format
new file mode 100644
index 000000000..1d8d55723
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/net/napi_gro_receive_entry/format
@@ -0,0 +1,29 @@
+name: napi_gro_receive_entry
+ID: 928
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:unsigned int napi_id; offset:12; size:4; signed:0;
+ field:u16 queue_mapping; offset:16; size:2; signed:0;
+ field:const void * skbaddr; offset:24; size:8; signed:0;
+ field:bool vlan_tagged; offset:32; size:1; signed:0;
+ field:u16 vlan_proto; offset:34; size:2; signed:0;
+ field:u16 vlan_tci; offset:36; size:2; signed:0;
+ field:u16 protocol; offset:38; size:2; signed:0;
+ field:u8 ip_summed; offset:40; size:1; signed:0;
+ field:u32 hash; offset:44; size:4; signed:0;
+ field:bool l4_hash; offset:48; size:1; signed:0;
+ field:unsigned int len; offset:52; size:4; signed:0;
+ field:unsigned int data_len; offset:56; size:4; signed:0;
+ field:unsigned int truesize; offset:60; size:4; signed:0;
+ field:bool mac_header_valid; offset:64; size:1; signed:0;
+ field:int mac_header; offset:68; size:4; signed:1;
+ field:unsigned char nr_frags; offset:72; size:1; signed:0;
+ field:u16 gso_size; offset:74; size:2; signed:0;
+ field:u16 gso_type; offset:76; size:2; signed:0;
+
+print fmt: "dev=%s napi_id=%#x queue_mapping=%u skbaddr=%p vlan_tagged=%d vlan_proto=0x%04x vlan_tci=0x%04x protocol=0x%04x ip_summed=%d hash=0x%08x l4_hash=%d len=%u data_len=%u truesize=%u mac_header_valid=%d mac_header=%d nr_frags=%d gso_size=%d gso_type=%#x", __get_str(name), REC->napi_id, REC->queue_mapping, REC->skbaddr, REC->vlan_tagged, REC->vlan_proto, REC->vlan_tci, REC->protocol, REC->ip_summed, REC->hash, REC->l4_hash, REC->len, REC->data_len, REC->truesize, REC->mac_header_valid, REC->mac_header, REC->nr_frags, REC->gso_size, REC->gso_type
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/net/napi_gro_receive_exit/format b/src/traced/probes/ftrace/test/data/synthetic/events/net/napi_gro_receive_exit/format
new file mode 100644
index 000000000..2eb347d76
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/net/napi_gro_receive_exit/format
@@ -0,0 +1,11 @@
+name: napi_gro_receive_exit
+ID: 929
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:int ret; offset:8; size:4; signed:1;
+
+print fmt: "ret=%d", REC->ret
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/net/net_dev_xmit/format b/src/traced/probes/ftrace/test/data/synthetic/events/net/net_dev_xmit/format
new file mode 100644
index 000000000..1691830d1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/net/net_dev_xmit/format
@@ -0,0 +1,14 @@
+name: net_dev_xmit
+ID: 930
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * skbaddr; offset:8; size:8; signed:0;
+ field:unsigned int len; offset:16; size:4; signed:0;
+ field:int rc; offset:20; size:4; signed:1;
+ field:__data_loc char[] name; offset:24; size:4; signed:0;
+
+print fmt: "dev=%s skbaddr=%p len=%u rc=%d", __get_str(name), REC->skbaddr, REC->len, REC->rc
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/net/netif_receive_skb/format b/src/traced/probes/ftrace/test/data/synthetic/events/net/netif_receive_skb/format
new file mode 100644
index 000000000..8eb8cb3ee
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/net/netif_receive_skb/format
@@ -0,0 +1,13 @@
+name: netif_receive_skb
+ID: 931
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * skbaddr; offset:8; size:8; signed:0;
+ field:unsigned int len; offset:16; size:4; signed:0;
+ field:__data_loc char[] name; offset:20; size:4; signed:0;
+
+print fmt: "dev=%s skbaddr=%p len=%u", __get_str(name), REC->skbaddr, REC->len
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/power/wakeup_source_activate/format b/src/traced/probes/ftrace/test/data/synthetic/events/power/wakeup_source_activate/format
new file mode 100644
index 000000000..b8b39d85a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/power/wakeup_source_activate/format
@@ -0,0 +1,12 @@
+name: wakeup_source_activate
+ID: 123
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:u64 state; offset:16; size:8; signed:0;
+
+print fmt: "%s state=0x%lx", __get_str(name), (unsigned long)REC->state
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/power/wakeup_source_deactivate/format b/src/traced/probes/ftrace/test/data/synthetic/events/power/wakeup_source_deactivate/format
new file mode 100644
index 000000000..03e9b3966
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/power/wakeup_source_deactivate/format
@@ -0,0 +1,12 @@
+name: wakeup_source_deactivate
+ID: 124
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] name; offset:8; size:4; signed:0;
+ field:u64 state; offset:16; size:8; signed:0;
+
+print fmt: "%s state=0x%lx", __get_str(name), (unsigned long)REC->state
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/skb/kfree_skb/format b/src/traced/probes/ftrace/test/data/synthetic/events/skb/kfree_skb/format
new file mode 100644
index 000000000..5f55e2062
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/skb/kfree_skb/format
@@ -0,0 +1,13 @@
+name: kfree_skb
+ID: 925
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:void * skbaddr; offset:8; size:8; signed:0;
+ field:void * location; offset:16; size:8; signed:0;
+ field:unsigned short protocol; offset:24; size:2; signed:0;
+
+print fmt: "skbaddr=%p protocol=%u location=%p", REC->skbaddr, REC->protocol, REC->location
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/sock/inet_sock_set_state/format b/src/traced/probes/ftrace/test/data/synthetic/events/sock/inet_sock_set_state/format
new file mode 100644
index 000000000..d7c36c7c1
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/sock/inet_sock_set_state/format
@@ -0,0 +1,21 @@
+name: inet_sock_set_state
+ID: 924
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const void * skaddr; offset:8; size:8; signed:0;
+ field:int oldstate; offset:16; size:4; signed:1;
+ field:int newstate; offset:20; size:4; signed:1;
+ field:__u16 sport; offset:24; size:2; signed:0;
+ field:__u16 dport; offset:26; size:2; signed:0;
+ field:__u16 family; offset:28; size:2; signed:0;
+ field:__u16 protocol; offset:30; size:2; signed:0;
+ field:__u8 saddr[4]; offset:32; size:4; signed:0;
+ field:__u8 daddr[4]; offset:36; size:4; signed:0;
+ field:__u8 saddr_v6[16]; offset:40; size:16; signed:0;
+ field:__u8 daddr_v6[16]; offset:56; size:16; signed:0;
+
+print fmt: "family=%s protocol=%s sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c oldstate=%s newstate=%s", __print_symbolic(REC->family, { 2, "AF_INET" }, { 10, "AF_INET6" }), __print_symbolic(REC->protocol, { 6, "IPPROTO_TCP" }, { 33, "IPPROTO_DCCP" }, { 132, "IPPROTO_SCTP" }, { 262, "IPPROTO_MPTCP" }), REC->sport, REC->dport, REC->saddr, REC->daddr, REC->saddr_v6, REC->daddr_v6, __print_symbolic(REC->oldstate, { 1, "TCP_ESTABLISHED" }, { 2, "TCP_SYN_SENT" }, { 3, "TCP_SYN_RECV" }, { 4, "TCP_FIN_WAIT1" }, { 5, "TCP_FIN_WAIT2" }, { 6, "TCP_TIME_WAIT" }, { 7, "TCP_CLOSE" }, { 8, "TCP_CLOSE_WAIT" }, { 9, "TCP_LAST_ACK" }, { 10, "TCP_LISTEN" }, { 11, "TCP_CLOSING" }, { 12, "TCP_NEW_SYN_RECV" }), __print_symbolic(REC->newstate, { 1, "TCP_ESTABLISHED" }, { 2, "TCP_SYN_SENT" }, { 3, "TCP_SYN_RECV" }, { 4, "TCP_FIN_WAIT1" }, { 5, "TCP_FIN_WAIT2" }, { 6, "TCP_TIME_WAIT" }, { 7, "TCP_CLOSE" }, { 8, "TCP_CLOSE_WAIT" }, { 9, "TCP_LAST_ACK" }, { 10, "TCP_LISTEN" }, { 11, "TCP_CLOSING" }, { 12, "TCP_NEW_SYN_RECV" })
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/synthetic/rss_stat_throttled/format b/src/traced/probes/ftrace/test/data/synthetic/events/synthetic/rss_stat_throttled/format
new file mode 100644
index 000000000..1b8185f0a
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/synthetic/rss_stat_throttled/format
@@ -0,0 +1,14 @@
+name: rss_stat_throttled
+ID: 1471
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:unsigned int mm_id; offset:8; size:4; signed:0;
+ field:unsigned int curr; offset:16; size:4; signed:0;
+ field:int member; offset:24; size:4; signed:1;
+ field:long size; offset:32; size:8; signed:1;
+
+print fmt: "mm_id=%u, curr=%u, member=%d, size=%ld", REC->mm_id, REC->curr, REC->member, REC->size
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/tcp/tcp_retransmit_skb/format b/src/traced/probes/ftrace/test/data/synthetic/events/tcp/tcp_retransmit_skb/format
new file mode 100644
index 000000000..a73ee0e3b
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/tcp/tcp_retransmit_skb/format
@@ -0,0 +1,19 @@
+name: tcp_retransmit_skb
+ID: 967
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:const void * skbaddr; offset:8; size:8; signed:0;
+ field:const void * skaddr; offset:16; size:8; signed:0;
+ field:int state; offset:24; size:4; signed:1;
+ field:__u16 sport; offset:28; size:2; signed:0;
+ field:__u16 dport; offset:30; size:2; signed:0;
+ field:__u8 saddr[4]; offset:32; size:4; signed:0;
+ field:__u8 daddr[4]; offset:36; size:4; signed:0;
+ field:__u8 saddr_v6[16]; offset:40; size:16; signed:0;
+ field:__u8 daddr_v6[16]; offset:56; size:16; signed:0;
+
+print fmt: "sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c state=%s", REC->sport, REC->dport, REC->saddr, REC->daddr, REC->saddr_v6, REC->daddr_v6, __print_symbolic(REC->state, { TCP_ESTABLISHED, "TCP_ESTABLISHED" }, { TCP_SYN_SENT, "TCP_SYN_SENT" }, { TCP_SYN_RECV, "TCP_SYN_RECV" }, { TCP_FIN_WAIT1, "TCP_FIN_WAIT1" }, { TCP_FIN_WAIT2, "TCP_FIN_WAIT2" }, { TCP_TIME_WAIT, "TCP_TIME_WAIT" }, { TCP_CLOSE, "TCP_CLOSE" }, { TCP_CLOSE_WAIT, "TCP_CLOSE_WAIT" }, { TCP_LAST_ACK, "TCP_LAST_ACK" }, { TCP_LISTEN, "TCP_LISTEN" }, { TCP_CLOSING, "TCP_CLOSING" }, { TCP_NEW_SYN_RECV, "TCP_NEW_SYN_RECV" })
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/ufs/ufshcd_clk_gating/format b/src/traced/probes/ftrace/test/data/synthetic/events/ufs/ufshcd_clk_gating/format
new file mode 100644
index 000000000..b9f5bdf86
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/ufs/ufshcd_clk_gating/format
@@ -0,0 +1,12 @@
+name: ufshcd_clk_gating
+ID: 699
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] dev_name; offset:8; size:4; signed:0;
+ field:int state; offset:12; size:4; signed:1;
+
+print fmt: "%s: gating state changed to %s", __get_str(dev_name), __print_symbolic(REC->state, {0, "CLKS_OFF"}, {1, "CLKS_ON"}, {2, "REQ_CLKS_OFF"}, {3, "REQ_CLKS_ON"})
diff --git a/src/traced/probes/ftrace/test/data/synthetic/events/ufs/ufshcd_command/format b/src/traced/probes/ftrace/test/data/synthetic/events/ufs/ufshcd_command/format
new file mode 100644
index 000000000..b80b353a7
--- /dev/null
+++ b/src/traced/probes/ftrace/test/data/synthetic/events/ufs/ufshcd_command/format
@@ -0,0 +1,19 @@
+name: ufshcd_command
+ID: 714
+format:
+ field:unsigned short common_type; offset:0; size:2; signed:0;
+ field:unsigned char common_flags; offset:2; size:1; signed:0;
+ field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
+ field:int common_pid; offset:4; size:4; signed:1;
+
+ field:__data_loc char[] dev_name; offset:8; size:4; signed:0;
+ field:enum ufs_trace_str_t str_t; offset:12; size:4; signed:0;
+ field:unsigned int tag; offset:16; size:4; signed:0;
+ field:u32 doorbell; offset:20; size:4; signed:0;
+ field:int transfer_len; offset:24; size:4; signed:1;
+ field:u32 intr; offset:28; size:4; signed:0;
+ field:u64 lba; offset:32; size:8; signed:0;
+ field:u8 opcode; offset:40; size:1; signed:0;
+ field:u8 group_id; offset:41; size:1; signed:0;
+
+print fmt: "%s: %s: tag: %u, DB: 0x%x, size: %d, IS: %u, LBA: %llu, opcode: 0x%x (%s), group_id: 0x%x", __print_symbolic(REC->str_t, {0, "send_req"}, {1, "complete_rsp"}, {2, "dev_complete"}, {3, "query_send"}, {4, "query_complete"}, {5, "query_complete_err"}, {6, "tm_send"}, {7, "tm_complete"}, {8, "tm_complete_err"}), __get_str(dev_name), REC->tag, REC->doorbell, REC->transfer_len, REC->intr, REC->lba, (u32)REC->opcode, __print_symbolic(REC->opcode, { 0x8a, "WRITE_16" }, { 0x2a, "WRITE_10" }, { 0x88, "READ_16" }, { 0x28, "READ_10" }, { 0x35, "SYNC" }, { 0x42, "UNMAP" }), (u32)REC->group_id
diff --git a/src/traced/probes/initial_display_state/initial_display_state_data_source.cc b/src/traced/probes/initial_display_state/initial_display_state_data_source.cc
index f5b9583f3..85ea6062f 100644
--- a/src/traced/probes/initial_display_state/initial_display_state_data_source.cc
+++ b/src/traced/probes/initial_display_state/initial_display_state_data_source.cc
@@ -18,6 +18,7 @@
#include "perfetto/base/task_runner.h"
#include "perfetto/base/time.h"
+#include "perfetto/ext/base/android_utils.h"
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/string_utils.h"
#include "perfetto/tracing/core/data_source_config.h"
@@ -26,10 +27,6 @@
#include "protos/perfetto/trace/android/initial_display_state.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-#include <sys/system_properties.h>
-#endif
-
namespace perfetto {
// static
@@ -37,6 +34,7 @@ const InitialDisplayStateDataSource::Descriptor
InitialDisplayStateDataSource::descriptor = {
/* name */ "android.polled_state",
/* flags */ Descriptor::kFlagsNone,
+ /*fill_descriptor_func*/ nullptr,
};
InitialDisplayStateDataSource::InitialDisplayStateDataSource(
@@ -114,13 +112,12 @@ void InitialDisplayStateDataSource::WriteState() {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
const base::Optional<std::string> InitialDisplayStateDataSource::ReadProperty(
const std::string name) {
- char value[PROP_VALUE_MAX];
- if (__system_property_get(name.c_str(), value)) {
- return base::make_optional(value);
- } else {
+ std::string value = base::GetAndroidProp(name.c_str());
+ if (value.empty()) {
PERFETTO_ELOG("Unable to read %s", name.c_str());
return base::nullopt;
}
+ return base::make_optional(value);
}
#else
const base::Optional<std::string> InitialDisplayStateDataSource::ReadProperty(
diff --git a/src/traced/probes/metatrace/metatrace_data_source.cc b/src/traced/probes/metatrace/metatrace_data_source.cc
index 1c5a2a72b..6849579d3 100644
--- a/src/traced/probes/metatrace/metatrace_data_source.cc
+++ b/src/traced/probes/metatrace/metatrace_data_source.cc
@@ -32,6 +32,7 @@ namespace perfetto {
const ProbesDataSource::Descriptor MetatraceDataSource::descriptor = {
/*name*/ MetatraceWriter::kDataSourceName,
/*flags*/ Descriptor::kFlagsNone,
+ /*fill_descriptor_func*/ nullptr,
};
MetatraceDataSource::MetatraceDataSource(base::TaskRunner* task_runner,
diff --git a/src/traced/probes/packages_list/packages_list_data_source.cc b/src/traced/probes/packages_list/packages_list_data_source.cc
index f9919b8d3..8276f62cb 100644
--- a/src/traced/probes/packages_list/packages_list_data_source.cc
+++ b/src/traced/probes/packages_list/packages_list_data_source.cc
@@ -32,6 +32,7 @@ namespace perfetto {
const ProbesDataSource::Descriptor PackagesListDataSource::descriptor = {
/*name*/ "android.packages_list",
/*flags*/ Descriptor::kFlagsNone,
+ /*fill_descriptor_func*/ nullptr,
};
bool ParsePackagesListStream(protos::pbzero::PackagesList* packages_list_packet,
diff --git a/src/traced/probes/packages_list/packages_list_parser.h b/src/traced/probes/packages_list/packages_list_parser.h
index 9cbecd160..c294ad7af 100644
--- a/src/traced/probes/packages_list/packages_list_parser.h
+++ b/src/traced/probes/packages_list/packages_list_parser.h
@@ -17,7 +17,7 @@
#ifndef SRC_TRACED_PROBES_PACKAGES_LIST_PACKAGES_LIST_PARSER_H_
#define SRC_TRACED_PROBES_PACKAGES_LIST_PACKAGES_LIST_PARSER_H_
-#include <inttypes.h>
+#include <cinttypes>
#include <string>
namespace perfetto {
diff --git a/src/traced/probes/power/BUILD.gn b/src/traced/probes/power/BUILD.gn
index fc28f6731..0131a92fc 100644
--- a/src/traced/probes/power/BUILD.gn
+++ b/src/traced/probes/power/BUILD.gn
@@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import("../../../../gn/test.gni")
+
source_set("power") {
public_deps = [ "../../../tracing/core" ]
deps = [
@@ -28,5 +30,19 @@ source_set("power") {
sources = [
"android_power_data_source.cc",
"android_power_data_source.h",
+ "linux_power_sysfs_data_source.cc",
+ "linux_power_sysfs_data_source.h",
+ ]
+}
+
+perfetto_unittest_source_set("unittests") {
+ testonly = true
+ deps = [
+ ":power",
+ "../../../../gn:default_deps",
+ "../../../../gn:gtest_and_gmock",
+ "../../../../src/tracing/test:test_support",
+ "../../../base:test_support",
]
+ sources = [ "linux_power_sysfs_data_source_unittest.cc" ]
}
diff --git a/src/traced/probes/power/android_power_data_source.cc b/src/traced/probes/power/android_power_data_source.cc
index 1dccb1a2a..9d2d9a57d 100644
--- a/src/traced/probes/power/android_power_data_source.cc
+++ b/src/traced/probes/power/android_power_data_source.cc
@@ -50,7 +50,8 @@ constexpr size_t kMaxNumPowerEntities = 256;
// static
const ProbesDataSource::Descriptor AndroidPowerDataSource::descriptor = {
/*name*/ "android.power",
- /*flags*/ Descriptor::kFlagsNone,
+ /*flags*/ Descriptor::kHandlesIncrementalState,
+ /*fill_descriptor_func*/ nullptr,
};
// Dynamically loads the libperfetto_android_internal.so library which
@@ -140,8 +141,6 @@ AndroidPowerDataSource::AndroidPowerDataSource(
std::unique_ptr<TraceWriter> writer)
: ProbesDataSource(session_id, &descriptor),
task_runner_(task_runner),
- rail_descriptors_logged_(false),
- energy_consumer_loggged_(false),
writer_(std::move(writer)),
weak_factory_(this) {
using protos::pbzero::AndroidPowerConfig;
@@ -201,9 +200,19 @@ void AndroidPowerDataSource::Tick() {
},
poll_interval_ms_ - static_cast<uint32_t>(now_ms % poll_interval_ms_));
+ if (should_emit_descriptors_) {
+ // We write incremental state cleared in its own packet to avoid the subtle
+ // code we'd need if we were to set this on the first enabled data source.
+ auto packet = writer_->NewTracePacket();
+ packet->set_sequence_flags(
+ protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED);
+ }
+
WriteBatteryCounters();
WritePowerRailsData();
WriteEnergyEstimationBreakdown();
+
+ should_emit_descriptors_ = false;
}
void AndroidPowerDataSource::WriteBatteryCounters() {
@@ -252,15 +261,14 @@ void AndroidPowerDataSource::WritePowerRailsData() {
auto packet = writer_->NewTracePacket();
packet->set_timestamp(static_cast<uint64_t>(base::GetBootTimeNs().count()));
- auto* rails_proto = packet->set_power_rails();
+ packet->set_sequence_flags(
+ protos::pbzero::TracePacket::SEQ_NEEDS_INCREMENTAL_STATE);
- if (!rail_descriptors_logged_) {
- // We only add the rail descriptors to the first package, to avoid logging
- // all rail names etc. on each one.
- rail_descriptors_logged_ = true;
+ auto* rails_proto = packet->set_power_rails();
+ if (should_emit_descriptors_) {
auto rail_descriptors = lib_->GetRailDescriptors();
if (rail_descriptors.empty()) {
- // No rails to collect data for. Don't try again in the next iteration.
+ // No rails to collect data for. Don't try again.
rails_collection_enabled_ = false;
return;
}
@@ -291,8 +299,7 @@ void AndroidPowerDataSource::WriteEnergyEstimationBreakdown() {
protos::pbzero::AndroidEnergyEstimationBreakdown* energy_estimation_proto =
nullptr;
- if (!energy_consumer_loggged_) {
- energy_consumer_loggged_ = true;
+ if (should_emit_descriptors_) {
packet = writer_->NewTracePacket();
energy_estimation_proto = packet->set_android_energy_estimation_breakdown();
auto* descriptor_proto =
@@ -316,6 +323,9 @@ void AndroidPowerDataSource::WriteEnergyEstimationBreakdown() {
}
packet = writer_->NewTracePacket();
packet->set_timestamp(timestamp);
+ packet->set_sequence_flags(
+ protos::pbzero::TracePacket::SEQ_NEEDS_INCREMENTAL_STATE);
+
energy_estimation_proto =
packet->set_android_energy_estimation_breakdown();
energy_estimation_proto->set_energy_consumer_id(
@@ -336,4 +346,8 @@ void AndroidPowerDataSource::Flush(FlushRequestID,
writer_->Flush(callback);
}
+void AndroidPowerDataSource::ClearIncrementalState() {
+ should_emit_descriptors_ = true;
+}
+
} // namespace perfetto
diff --git a/src/traced/probes/power/android_power_data_source.h b/src/traced/probes/power/android_power_data_source.h
index 4fecfda0b..56b02f6ca 100644
--- a/src/traced/probes/power/android_power_data_source.h
+++ b/src/traced/probes/power/android_power_data_source.h
@@ -48,6 +48,7 @@ class AndroidPowerDataSource : public ProbesDataSource {
// ProbesDataSource implementation.
void Start() override;
void Flush(FlushRequestID, std::function<void()> callback) override;
+ void ClearIncrementalState() override;
private:
struct DynamicLibLoader;
@@ -57,13 +58,19 @@ class AndroidPowerDataSource : public ProbesDataSource {
void WritePowerRailsData();
void WriteEnergyEstimationBreakdown();
- base::TaskRunner* const task_runner_;
- uint32_t poll_interval_ms_ = 0;
+ // Battery counters.
std::bitset<8> counters_enabled_;
- bool rails_collection_enabled_;
- bool rail_descriptors_logged_;
- bool energy_consumer_loggged_;
- bool energy_breakdown_collection_enabled_;
+
+ // Power rails.
+ bool rails_collection_enabled_ = false;
+
+ // Energy estimation.
+ bool energy_breakdown_collection_enabled_ = false;
+
+ uint32_t poll_interval_ms_ = 0;
+ bool should_emit_descriptors_ = true;
+
+ base::TaskRunner* const task_runner_;
std::unique_ptr<TraceWriter> writer_;
std::unique_ptr<DynamicLibLoader> lib_;
base::WeakPtrFactory<AndroidPowerDataSource> weak_factory_; // Keep last.
diff --git a/src/traced/probes/power/linux_power_sysfs_data_source.cc b/src/traced/probes/power/linux_power_sysfs_data_source.cc
new file mode 100644
index 000000000..2e7d66e17
--- /dev/null
+++ b/src/traced/probes/power/linux_power_sysfs_data_source.cc
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/traced/probes/power/linux_power_sysfs_data_source.h"
+
+#include <dirent.h>
+#include <sys/types.h>
+
+#include "perfetto/base/logging.h"
+#include "perfetto/base/task_runner.h"
+#include "perfetto/base/time.h"
+#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/tracing/core/trace_packet.h"
+#include "perfetto/ext/tracing/core/trace_writer.h"
+#include "perfetto/tracing/core/data_source_config.h"
+
+#include "protos/perfetto/trace/power/battery_counters.pbzero.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+
+namespace {
+constexpr uint32_t kDefaultPollIntervalMs = 1000;
+
+base::Optional<int64_t> ReadFileAsInt64(std::string path) {
+ std::string buf;
+ if (!base::ReadFile(path, &buf))
+ return base::nullopt;
+ return base::StringToInt64(base::StripSuffix(buf, "\n"));
+}
+} // namespace
+
+LinuxPowerSysfsDataSource::BatteryInfo::BatteryInfo(
+ const char* power_supply_dir_path) {
+ base::ScopedDir power_supply_dir(opendir(power_supply_dir_path));
+ if (!power_supply_dir)
+ return;
+
+ for (auto* ent = readdir(power_supply_dir.get()); ent;
+ ent = readdir(power_supply_dir.get())) {
+ if (ent->d_name[0] == '.')
+ continue;
+ std::string dir_name =
+ std::string(power_supply_dir_path) + "/" + ent->d_name;
+ std::string buf;
+ if (!base::ReadFile(dir_name + "/type", &buf) ||
+ base::StripSuffix(buf, "\n") != "Battery")
+ continue;
+ buf.clear();
+ if (!base::ReadFile(dir_name + "/present", &buf) ||
+ base::StripSuffix(buf, "\n") != "1")
+ continue;
+ sysfs_battery_dirs_.push_back(dir_name);
+ }
+}
+LinuxPowerSysfsDataSource::BatteryInfo::~BatteryInfo() = default;
+
+size_t LinuxPowerSysfsDataSource::BatteryInfo::num_batteries() const {
+ return sysfs_battery_dirs_.size();
+}
+
+base::Optional<int64_t>
+LinuxPowerSysfsDataSource::BatteryInfo::GetChargeCounterUah(
+ size_t battery_idx) {
+ PERFETTO_CHECK(battery_idx < sysfs_battery_dirs_.size());
+ return ReadFileAsInt64(sysfs_battery_dirs_[battery_idx] + "/charge_now");
+}
+
+base::Optional<int64_t>
+LinuxPowerSysfsDataSource::BatteryInfo::GetCapacityPercent(size_t battery_idx) {
+ PERFETTO_CHECK(battery_idx < sysfs_battery_dirs_.size());
+ return ReadFileAsInt64(sysfs_battery_dirs_[battery_idx] + "/capacity");
+}
+
+base::Optional<int64_t> LinuxPowerSysfsDataSource::BatteryInfo::GetCurrentNowUa(
+ size_t battery_idx) {
+ PERFETTO_CHECK(battery_idx < sysfs_battery_dirs_.size());
+ return ReadFileAsInt64(sysfs_battery_dirs_[battery_idx] + "/current_now");
+}
+
+base::Optional<int64_t>
+LinuxPowerSysfsDataSource::BatteryInfo::GetAverageCurrentUa(
+ size_t battery_idx) {
+ PERFETTO_CHECK(battery_idx < sysfs_battery_dirs_.size());
+ return ReadFileAsInt64(sysfs_battery_dirs_[battery_idx] + "/current_avg");
+}
+
+// static
+const ProbesDataSource::Descriptor LinuxPowerSysfsDataSource::descriptor = {
+ /*name*/ "linux.sysfs_power",
+ /*flags*/ Descriptor::kFlagsNone,
+ /*fill_descriptor_func*/ nullptr,
+};
+
+LinuxPowerSysfsDataSource::LinuxPowerSysfsDataSource(
+ DataSourceConfig cfg,
+ base::TaskRunner* task_runner,
+ TracingSessionID session_id,
+ std::unique_ptr<TraceWriter> writer)
+ : ProbesDataSource(session_id, &descriptor),
+ poll_interval_ms_(kDefaultPollIntervalMs),
+ task_runner_(task_runner),
+ writer_(std::move(writer)),
+ weak_factory_(this) {
+ base::ignore_result(cfg); // The data source doesn't need any config yet.
+}
+
+LinuxPowerSysfsDataSource::~LinuxPowerSysfsDataSource() = default;
+
+void LinuxPowerSysfsDataSource::Start() {
+ battery_info_.reset(new BatteryInfo());
+ Tick();
+}
+
+void LinuxPowerSysfsDataSource::Tick() {
+ // Post next task.
+ auto now_ms = base::GetWallTimeMs().count();
+ auto weak_this = weak_factory_.GetWeakPtr();
+ task_runner_->PostDelayedTask(
+ [weak_this] {
+ if (weak_this)
+ weak_this->Tick();
+ },
+ poll_interval_ms_ - static_cast<uint32_t>(now_ms % poll_interval_ms_));
+
+ WriteBatteryCounters();
+}
+
+void LinuxPowerSysfsDataSource::WriteBatteryCounters() {
+ auto packet = writer_->NewTracePacket();
+ packet->set_timestamp(static_cast<uint64_t>(base::GetBootTimeNs().count()));
+
+ // Query battery counters from sysfs. Report the battery counters for each
+ // battery.
+ for (size_t battery_idx = 0; battery_idx < battery_info_->num_batteries();
+ battery_idx++) {
+ auto* counters_proto = packet->set_battery();
+ auto value = battery_info_->GetChargeCounterUah(battery_idx);
+ if (value)
+ counters_proto->set_charge_counter_uah(*value);
+ value = battery_info_->GetCapacityPercent(battery_idx);
+ if (value)
+ counters_proto->set_capacity_percent(static_cast<float>(*value));
+ value = battery_info_->GetCurrentNowUa(battery_idx);
+ if (value)
+ counters_proto->set_current_ua(*value);
+ value = battery_info_->GetAverageCurrentUa(battery_idx);
+ if (value)
+ counters_proto->set_current_ua(*value);
+ }
+}
+
+void LinuxPowerSysfsDataSource::Flush(FlushRequestID,
+ std::function<void()> callback) {
+ writer_->Flush(callback);
+}
+
+} // namespace perfetto
diff --git a/src/traced/probes/power/linux_power_sysfs_data_source.h b/src/traced/probes/power/linux_power_sysfs_data_source.h
new file mode 100644
index 000000000..9838a15a0
--- /dev/null
+++ b/src/traced/probes/power/linux_power_sysfs_data_source.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACED_PROBES_POWER_LINUX_POWER_SYSFS_DATA_SOURCE_H_
+#define SRC_TRACED_PROBES_POWER_LINUX_POWER_SYSFS_DATA_SOURCE_H_
+
+#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/weak_ptr.h"
+#include "perfetto/tracing/core/data_source_config.h"
+#include "src/traced/probes/probes_data_source.h"
+
+namespace perfetto {
+class BatteryInfo;
+class TraceWriter;
+
+namespace base {
+class TaskRunner;
+}
+
+class LinuxPowerSysfsDataSource : public ProbesDataSource {
+ public:
+ class BatteryInfo {
+ public:
+ explicit BatteryInfo(
+ const char* power_supply_dir_path = "/sys/class/power_supply");
+ ~BatteryInfo();
+
+ // The current coloumb counter value in µAh.
+ base::Optional<int64_t> GetChargeCounterUah(size_t battery_idx);
+
+ // The battery capacity in percent.
+ base::Optional<int64_t> GetCapacityPercent(size_t battery_idx);
+
+ // The current reading of the battery in µA.
+ base::Optional<int64_t> GetCurrentNowUa(size_t battery_idx);
+
+ // The smoothed current reading of the battery in µA.
+ base::Optional<int64_t> GetAverageCurrentUa(size_t battery_idx);
+
+ size_t num_batteries() const;
+
+ private:
+ // The subdirectories that contain info of a battery power supply, not
+ // USBPD, AC or other types of power supplies.
+ std::vector<std::string> sysfs_battery_dirs_;
+ };
+ static const ProbesDataSource::Descriptor descriptor;
+
+ LinuxPowerSysfsDataSource(DataSourceConfig,
+ base::TaskRunner*,
+ TracingSessionID,
+ std::unique_ptr<TraceWriter> writer);
+
+ ~LinuxPowerSysfsDataSource() override;
+
+ base::WeakPtr<LinuxPowerSysfsDataSource> GetWeakPtr() const;
+
+ // ProbesDataSource implementation.
+ void Start() override;
+ void Flush(FlushRequestID, std::function<void()> callback) override;
+ // Use the default ClearIncrementalState() implementation: this data source
+ // doesn't have any incremental state.
+
+ private:
+ void Tick();
+ void WriteBatteryCounters();
+
+ uint32_t poll_interval_ms_ = 0;
+
+ base::TaskRunner* const task_runner_;
+ std::unique_ptr<TraceWriter> writer_;
+ std::unique_ptr<BatteryInfo> battery_info_;
+ base::WeakPtrFactory<LinuxPowerSysfsDataSource> weak_factory_; // Keep last.
+};
+
+} // namespace perfetto
+
+#endif // SRC_TRACED_PROBES_POWER_LINUX_POWER_SYSFS_DATA_SOURCE_H_
diff --git a/src/traced/probes/power/linux_power_sysfs_data_source_unittest.cc b/src/traced/probes/power/linux_power_sysfs_data_source_unittest.cc
new file mode 100644
index 000000000..590c9263e
--- /dev/null
+++ b/src/traced/probes/power/linux_power_sysfs_data_source_unittest.cc
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/traced/probes/power/linux_power_sysfs_data_source.h"
+#include "src/base/test/tmp_dir_tree.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace {
+
+TEST(LinuxPowerSysfsDataSourceTest, BatteryCounters) {
+ base::TmpDirTree tmpdir;
+ std::unique_ptr<LinuxPowerSysfsDataSource::BatteryInfo> battery_info_;
+
+ tmpdir.AddDir("BAT0");
+ tmpdir.AddFile("BAT0/type", "Battery\n");
+ tmpdir.AddFile("BAT0/present", "1\n");
+ tmpdir.AddFile("BAT0/capacity", "95\n"); // 95 percent.
+ tmpdir.AddFile("BAT0/charge_now", "3074000\n"); // 3074000 µAh.
+ tmpdir.AddFile("BAT0/current_now", "245000\n"); // 245000 µA.
+ tmpdir.AddFile("BAT0/current_avg", "240000\n"); // 240000 µA.
+
+ battery_info_.reset(
+ new LinuxPowerSysfsDataSource::BatteryInfo(tmpdir.path().c_str()));
+
+ EXPECT_EQ(battery_info_->num_batteries(), 1u);
+ EXPECT_EQ(*battery_info_->GetCapacityPercent(0), 95);
+ EXPECT_EQ(*battery_info_->GetCurrentNowUa(0), 245000);
+ EXPECT_EQ(*battery_info_->GetAverageCurrentUa(0), 240000);
+ EXPECT_EQ(*battery_info_->GetChargeCounterUah(0), 3074000);
+}
+
+TEST(LinuxPowerSysfsDataSourceTest, HidDeviceCounters) {
+ base::TmpDirTree tmpdir;
+ std::unique_ptr<LinuxPowerSysfsDataSource::BatteryInfo> battery_info_;
+
+ // Some HID devices (e.g. stylus) can also report battery info.
+ tmpdir.AddDir("hid-0001-battery");
+ tmpdir.AddFile("hid-0001-battery/type", "Battery\n");
+ tmpdir.AddFile("hid-0001-battery/present", "1\n");
+ tmpdir.AddFile("hid-0001-battery/capacity", "88\n"); // 88 percent.
+ // The HID device only reports the battery capacity in percent.
+
+ battery_info_.reset(
+ new LinuxPowerSysfsDataSource::BatteryInfo(tmpdir.path().c_str()));
+
+ EXPECT_EQ(battery_info_->num_batteries(), 1u);
+ EXPECT_EQ(*battery_info_->GetCapacityPercent(0), 88);
+ EXPECT_EQ(battery_info_->GetCurrentNowUa(0), base::nullopt);
+ EXPECT_EQ(battery_info_->GetAverageCurrentUa(0), base::nullopt);
+ EXPECT_EQ(battery_info_->GetChargeCounterUah(0), base::nullopt);
+}
+
+} // namespace
+} // namespace perfetto
diff --git a/src/traced/probes/probes.cc b/src/traced/probes/probes.cc
index b02b6d5cd..e13e56b22 100644
--- a/src/traced/probes/probes.cc
+++ b/src/traced/probes/probes.cc
@@ -20,6 +20,7 @@
#include <unistd.h>
#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/getopt.h"
#include "perfetto/ext/base/unix_task_runner.h"
#include "perfetto/ext/base/utils.h"
@@ -38,13 +39,16 @@ int PERFETTO_EXPORT_ENTRYPOINT ProbesMain(int argc, char** argv) {
OPT_CLEANUP_AFTER_CRASH = 1000,
OPT_VERSION,
OPT_BACKGROUND,
+ OPT_RESET_FTRACE,
};
bool background = false;
+ bool reset_ftrace = false;
static const option long_options[] = {
{"background", no_argument, nullptr, OPT_BACKGROUND},
{"cleanup-after-crash", no_argument, nullptr, OPT_CLEANUP_AFTER_CRASH},
+ {"reset-ftrace", no_argument, nullptr, OPT_RESET_FTRACE},
{"version", no_argument, nullptr, OPT_VERSION},
{nullptr, 0, nullptr, 0}};
@@ -57,19 +61,35 @@ int PERFETTO_EXPORT_ENTRYPOINT ProbesMain(int argc, char** argv) {
background = true;
break;
case OPT_CLEANUP_AFTER_CRASH:
+ // Used by perfetto.rc in Android.
+ PERFETTO_LOG("Hard resetting ftrace state.");
HardResetFtraceState();
return 0;
+ case OPT_RESET_FTRACE:
+ // This is like --cleanup-after-crash but doesn't quit.
+ reset_ftrace = true;
+ break;
case OPT_VERSION:
printf("%s\n", base::GetVersionString());
return 0;
default:
- PERFETTO_ELOG("Usage: %s [--background|--cleanup-after-crash|--version]", argv[0]);
+ fprintf(
+ stderr,
+ "Usage: %s [--background] [--reset-ftrace] [--cleanup-after-crash] "
+ "[--version]\n",
+ argv[0]);
return 1;
}
}
+ if (reset_ftrace && !HardResetFtraceState()) {
+ PERFETTO_ELOG(
+ "Failed to reset ftrace. Either run this as root or run "
+ "`sudo chown -R $USER /sys/kernel/tracing`");
+ }
+
if (background) {
- base::Daemonize();
+ base::Daemonize([] { return 0; });
}
base::Watchdog* watchdog = base::Watchdog::GetInstance();
@@ -97,6 +117,18 @@ int PERFETTO_EXPORT_ENTRYPOINT ProbesMain(int argc, char** argv) {
base::UnixTaskRunner task_runner;
ProbesProducer producer;
+ // If the TRACED_PROBES_NOTIFY_FD env var is set, write 1 and close the FD,
+ // when all data sources have been registered. This is used for //src/tracebox
+ // --background-wait, to make sure that the data sources are registered before
+ // waiting for them to be started.
+ const char* env_notif = getenv("TRACED_PROBES_NOTIFY_FD");
+ if (env_notif) {
+ int notif_fd = atoi(env_notif);
+ producer.SetAllDataSourcesRegisteredCb([notif_fd] {
+ PERFETTO_CHECK(base::WriteAll(notif_fd, "1", 1) == 1);
+ PERFETTO_CHECK(base::CloseFile(notif_fd) == 0);
+ });
+ }
producer.ConnectWithRetries(GetProducerSocket(), &task_runner);
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
diff --git a/src/traced/probes/probes_data_source.h b/src/traced/probes/probes_data_source.h
index 6ceef56b5..902504699 100644
--- a/src/traced/probes/probes_data_source.h
+++ b/src/traced/probes/probes_data_source.h
@@ -31,12 +31,16 @@ class ProbesDataSource {
// Static properties for a data source. Needs to be available before
// instantiating each data source. It must have static lifetime.
struct Descriptor {
+ using FillDescriptorFunc = void (*)(DataSourceDescriptor*);
enum Flags : uint32_t {
kFlagsNone = 0,
kHandlesIncrementalState = 1 << 0,
};
const char* const name;
uint32_t flags;
+ // If not nullptr, called to fill data source specific fields in
+ // DataSourceDescriptor.
+ FillDescriptorFunc fill_descriptor_func;
};
ProbesDataSource(TracingSessionID, const Descriptor*);
diff --git a/src/traced/probes/probes_producer.cc b/src/traced/probes/probes_producer.cc
index 9907a73de..8b9fc46c5 100644
--- a/src/traced/probes/probes_producer.cc
+++ b/src/traced/probes/probes_producer.cc
@@ -32,6 +32,7 @@
#include "perfetto/ext/tracing/ipc/producer_ipc_client.h"
#include "perfetto/tracing/core/data_source_config.h"
#include "perfetto/tracing/core/data_source_descriptor.h"
+#include "perfetto/tracing/core/forward_decls.h"
#include "perfetto/tracing/core/trace_config.h"
#include "src/android_stats/statsd_logging_helper.h"
#include "src/traced/probes/android_log/android_log_data_source.h"
@@ -42,6 +43,7 @@
#include "src/traced/probes/metatrace/metatrace_data_source.h"
#include "src/traced/probes/packages_list/packages_list_data_source.h"
#include "src/traced/probes/power/android_power_data_source.h"
+#include "src/traced/probes/power/linux_power_sysfs_data_source.h"
#include "src/traced/probes/probes_data_source.h"
#include "src/traced/probes/ps/process_stats_data_source.h"
#include "src/traced/probes/sys_stats/sys_stats_data_source.h"
@@ -65,18 +67,6 @@ constexpr uint32_t kFlushTimeoutMs = 1000;
constexpr size_t kTracingSharedMemSizeHintBytes = 1024 * 1024;
constexpr size_t kTracingSharedMemPageSizeHintBytes = 32 * 1024;
-ProbesDataSource::Descriptor const* const kAllDataSources[]{
- &FtraceDataSource::descriptor, //
- &ProcessStatsDataSource::descriptor, //
- &InodeFileDataSource::descriptor, //
- &SysStatsDataSource::descriptor, //
- &AndroidPowerDataSource::descriptor, //
- &AndroidLogDataSource::descriptor, //
- &PackagesListDataSource::descriptor, //
- &MetatraceDataSource::descriptor, //
- &SystemInfoDataSource::descriptor, //
- &InitialDisplayStateDataSource::descriptor, //
-};
} // namespace
// State transition diagram:
@@ -105,37 +95,6 @@ ProbesProducer::~ProbesProducer() {
ftrace_.reset();
}
-void ProbesProducer::OnConnect() {
- PERFETTO_DCHECK(state_ == kConnecting);
- state_ = kConnected;
- ResetConnectionBackoff();
- PERFETTO_LOG("Connected to the service");
-
- // Register all the data sources.
- for (const FtraceDataSource::Descriptor* desc : kAllDataSources) {
- DataSourceDescriptor proto_desc;
- proto_desc.set_name(desc->name);
- proto_desc.set_will_notify_on_start(true);
- proto_desc.set_will_notify_on_stop(true);
- using Flags = ProbesDataSource::Descriptor::Flags;
- if (desc->flags & Flags::kHandlesIncrementalState)
- proto_desc.set_handles_incremental_state_clear(true);
- endpoint_->RegisterDataSource(proto_desc);
- }
-}
-
-void ProbesProducer::OnDisconnect() {
- PERFETTO_DCHECK(state_ == kConnected || state_ == kConnecting);
- PERFETTO_LOG("Disconnected from tracing service");
- if (state_ == kConnected)
- return task_runner_->PostTask([this] { this->Restart(); });
-
- state_ = kNotConnected;
- IncreaseConnectionBackoff();
- task_runner_->PostDelayedTask([this] { this->Connect(); },
- connection_backoff_ms_);
-}
-
void ProbesProducer::Restart() {
// We lost the connection with the tracing service. At this point we need
// to reset all the data sources. Trying to handle that manually is going to
@@ -152,70 +111,9 @@ void ProbesProducer::Restart() {
ConnectWithRetries(socket_name, task_runner);
}
-void ProbesProducer::SetupDataSource(DataSourceInstanceID instance_id,
- const DataSourceConfig& config) {
- PERFETTO_DLOG("SetupDataSource(id=%" PRIu64 ", name=%s)", instance_id,
- config.name().c_str());
- PERFETTO_DCHECK(data_sources_.count(instance_id) == 0);
- TracingSessionID session_id = config.tracing_session_id();
- PERFETTO_CHECK(session_id > 0);
-
- std::unique_ptr<ProbesDataSource> data_source;
- if (config.name() == FtraceDataSource::descriptor.name) {
- data_source = CreateFtraceDataSource(session_id, config);
- } else if (config.name() == InodeFileDataSource::descriptor.name) {
- data_source = CreateInodeFileDataSource(session_id, config);
- } else if (config.name() == ProcessStatsDataSource::descriptor.name) {
- data_source = CreateProcessStatsDataSource(session_id, config);
- } else if (config.name() == SysStatsDataSource::descriptor.name) {
- data_source = CreateSysStatsDataSource(session_id, config);
- } else if (config.name() == AndroidPowerDataSource::descriptor.name) {
- data_source = CreateAndroidPowerDataSource(session_id, config);
- } else if (config.name() == AndroidLogDataSource::descriptor.name) {
- data_source = CreateAndroidLogDataSource(session_id, config);
- } else if (config.name() == PackagesListDataSource::descriptor.name) {
- data_source = CreatePackagesListDataSource(session_id, config);
- } else if (config.name() == MetatraceDataSource::descriptor.name) {
- data_source = CreateMetatraceDataSource(session_id, config);
- } else if (config.name() == SystemInfoDataSource::descriptor.name) {
- data_source = CreateSystemInfoDataSource(session_id, config);
- } else if (config.name() == InitialDisplayStateDataSource::descriptor.name) {
- data_source = CreateInitialDisplayStateDataSource(session_id, config);
- }
-
- if (!data_source) {
- PERFETTO_ELOG("Failed to create data source '%s'", config.name().c_str());
- return;
- }
-
- session_data_sources_.emplace(session_id, data_source.get());
- data_sources_[instance_id] = std::move(data_source);
-}
-
-void ProbesProducer::StartDataSource(DataSourceInstanceID instance_id,
- const DataSourceConfig& config) {
- PERFETTO_DLOG("StartDataSource(id=%" PRIu64 ", name=%s)", instance_id,
- config.name().c_str());
- auto it = data_sources_.find(instance_id);
- if (it == data_sources_.end()) {
- // Can happen if SetupDataSource() failed (e.g. ftrace was busy).
- PERFETTO_ELOG("Data source id=%" PRIu64 " not found", instance_id);
- return;
- }
- ProbesDataSource* data_source = it->second.get();
- if (data_source->started)
- return;
- if (config.trace_duration_ms() != 0) {
- uint32_t timeout = 5000 + 2 * config.trace_duration_ms();
- watchdogs_.emplace(
- instance_id, base::Watchdog::GetInstance()->CreateFatalTimer(timeout));
- }
- data_source->started = true;
- data_source->Start();
- endpoint_->NotifyDataSourceStarted(instance_id);
-}
-
-std::unique_ptr<ProbesDataSource> ProbesProducer::CreateFtraceDataSource(
+template <>
+std::unique_ptr<ProbesDataSource>
+ProbesProducer::CreateDSInstance<FtraceDataSource>(
TracingSessionID session_id,
const DataSourceConfig& config) {
// Don't retry if FtraceController::Create() failed once.
@@ -252,20 +150,24 @@ std::unique_ptr<ProbesDataSource> ProbesProducer::CreateFtraceDataSource(
return std::unique_ptr<ProbesDataSource>(std::move(data_source));
}
-std::unique_ptr<ProbesDataSource> ProbesProducer::CreateInodeFileDataSource(
+template <>
+std::unique_ptr<ProbesDataSource>
+ProbesProducer::CreateDSInstance<InodeFileDataSource>(
TracingSessionID session_id,
- DataSourceConfig source_config) {
+ const DataSourceConfig& source_config) {
PERFETTO_LOG("Inode file map setup (target_buf=%" PRIu32 ")",
source_config.target_buffer());
auto buffer_id = static_cast<BufferID>(source_config.target_buffer());
if (system_inodes_.empty())
CreateStaticDeviceToInodeMap("/system", &system_inodes_);
return std::unique_ptr<InodeFileDataSource>(new InodeFileDataSource(
- std::move(source_config), task_runner_, session_id, &system_inodes_,
- &cache_, endpoint_->CreateTraceWriter(buffer_id)));
+ source_config, task_runner_, session_id, &system_inodes_, &cache_,
+ endpoint_->CreateTraceWriter(buffer_id)));
}
-std::unique_ptr<ProbesDataSource> ProbesProducer::CreateProcessStatsDataSource(
+template <>
+std::unique_ptr<ProbesDataSource>
+ProbesProducer::CreateDSInstance<ProcessStatsDataSource>(
TracingSessionID session_id,
const DataSourceConfig& config) {
auto buffer_id = static_cast<BufferID>(config.target_buffer());
@@ -274,7 +176,9 @@ std::unique_ptr<ProbesDataSource> ProbesProducer::CreateProcessStatsDataSource(
std::unique_ptr<CpuFreqInfo>(new CpuFreqInfo())));
}
-std::unique_ptr<ProbesDataSource> ProbesProducer::CreateAndroidPowerDataSource(
+template <>
+std::unique_ptr<ProbesDataSource>
+ProbesProducer::CreateDSInstance<AndroidPowerDataSource>(
TracingSessionID session_id,
const DataSourceConfig& config) {
auto buffer_id = static_cast<BufferID>(config.target_buffer());
@@ -283,7 +187,20 @@ std::unique_ptr<ProbesDataSource> ProbesProducer::CreateAndroidPowerDataSource(
endpoint_->CreateTraceWriter(buffer_id)));
}
-std::unique_ptr<ProbesDataSource> ProbesProducer::CreateAndroidLogDataSource(
+template <>
+std::unique_ptr<ProbesDataSource>
+ProbesProducer::CreateDSInstance<LinuxPowerSysfsDataSource>(
+ TracingSessionID session_id,
+ const DataSourceConfig& config) {
+ auto buffer_id = static_cast<BufferID>(config.target_buffer());
+ return std::unique_ptr<ProbesDataSource>(
+ new LinuxPowerSysfsDataSource(config, task_runner_, session_id,
+ endpoint_->CreateTraceWriter(buffer_id)));
+}
+
+template <>
+std::unique_ptr<ProbesDataSource>
+ProbesProducer::CreateDSInstance<AndroidLogDataSource>(
TracingSessionID session_id,
const DataSourceConfig& config) {
auto buffer_id = static_cast<BufferID>(config.target_buffer());
@@ -292,7 +209,9 @@ std::unique_ptr<ProbesDataSource> ProbesProducer::CreateAndroidLogDataSource(
endpoint_->CreateTraceWriter(buffer_id)));
}
-std::unique_ptr<ProbesDataSource> ProbesProducer::CreatePackagesListDataSource(
+template <>
+std::unique_ptr<ProbesDataSource>
+ProbesProducer::CreateDSInstance<PackagesListDataSource>(
TracingSessionID session_id,
const DataSourceConfig& config) {
auto buffer_id = static_cast<BufferID>(config.target_buffer());
@@ -300,16 +219,20 @@ std::unique_ptr<ProbesDataSource> ProbesProducer::CreatePackagesListDataSource(
config, session_id, endpoint_->CreateTraceWriter(buffer_id)));
}
-std::unique_ptr<ProbesDataSource> ProbesProducer::CreateSysStatsDataSource(
+template <>
+std::unique_ptr<ProbesDataSource>
+ProbesProducer::CreateDSInstance<SysStatsDataSource>(
TracingSessionID session_id,
const DataSourceConfig& config) {
auto buffer_id = static_cast<BufferID>(config.target_buffer());
- return std::unique_ptr<SysStatsDataSource>(
- new SysStatsDataSource(task_runner_, session_id,
- endpoint_->CreateTraceWriter(buffer_id), config));
+ return std::unique_ptr<SysStatsDataSource>(new SysStatsDataSource(
+ task_runner_, session_id, endpoint_->CreateTraceWriter(buffer_id), config,
+ std::unique_ptr<CpuFreqInfo>(new CpuFreqInfo())));
}
-std::unique_ptr<ProbesDataSource> ProbesProducer::CreateMetatraceDataSource(
+template <>
+std::unique_ptr<ProbesDataSource>
+ProbesProducer::CreateDSInstance<MetatraceDataSource>(
TracingSessionID session_id,
const DataSourceConfig& config) {
auto buffer_id = static_cast<BufferID>(config.target_buffer());
@@ -317,7 +240,9 @@ std::unique_ptr<ProbesDataSource> ProbesProducer::CreateMetatraceDataSource(
task_runner_, session_id, endpoint_->CreateTraceWriter(buffer_id)));
}
-std::unique_ptr<ProbesDataSource> ProbesProducer::CreateSystemInfoDataSource(
+template <>
+std::unique_ptr<ProbesDataSource>
+ProbesProducer::CreateDSInstance<SystemInfoDataSource>(
TracingSessionID session_id,
const DataSourceConfig& config) {
auto buffer_id = static_cast<BufferID>(config.target_buffer());
@@ -326,8 +251,9 @@ std::unique_ptr<ProbesDataSource> ProbesProducer::CreateSystemInfoDataSource(
std::unique_ptr<CpuFreqInfo>(new CpuFreqInfo())));
}
+template <>
std::unique_ptr<ProbesDataSource>
-ProbesProducer::CreateInitialDisplayStateDataSource(
+ProbesProducer::CreateDSInstance<InitialDisplayStateDataSource>(
TracingSessionID session_id,
const DataSourceConfig& config) {
auto buffer_id = static_cast<BufferID>(config.target_buffer());
@@ -336,6 +262,136 @@ ProbesProducer::CreateInitialDisplayStateDataSource(
endpoint_->CreateTraceWriter(buffer_id)));
}
+// Another anonymous namespace. This cannot be moved into the anonymous
+// namespace on top (it would fail to compile), because the CreateDSInstance
+// methods need to be fully declared before.
+namespace {
+
+using ProbesDataSourceFactoryFunc = std::unique_ptr<ProbesDataSource> (
+ ProbesProducer::*)(TracingSessionID, const DataSourceConfig&);
+
+struct DataSourceTraits {
+ const ProbesDataSource::Descriptor* descriptor;
+ ProbesDataSourceFactoryFunc factory_func;
+};
+
+template <typename T>
+constexpr DataSourceTraits Ds() {
+ return DataSourceTraits{&T::descriptor, &ProbesProducer::CreateDSInstance<T>};
+}
+
+const DataSourceTraits kAllDataSources[] = {
+ Ds<AndroidLogDataSource>(), Ds<AndroidPowerDataSource>(),
+ Ds<FtraceDataSource>(), Ds<InitialDisplayStateDataSource>(),
+ Ds<InodeFileDataSource>(), Ds<LinuxPowerSysfsDataSource>(),
+ Ds<MetatraceDataSource>(), Ds<PackagesListDataSource>(),
+ Ds<ProcessStatsDataSource>(), Ds<SysStatsDataSource>(),
+ Ds<SystemInfoDataSource>(),
+};
+
+} // namespace
+
+void ProbesProducer::OnConnect() {
+ PERFETTO_DCHECK(state_ == kConnecting);
+ state_ = kConnected;
+ ResetConnectionBackoff();
+ PERFETTO_LOG("Connected to the service");
+
+ std::array<DataSourceDescriptor, base::ArraySize(kAllDataSources)>
+ proto_descs;
+ // Generate all data source descriptors.
+ for (size_t i = 0; i < proto_descs.size(); i++) {
+ DataSourceDescriptor& proto_desc = proto_descs[i];
+ const ProbesDataSource::Descriptor* desc = kAllDataSources[i].descriptor;
+
+ proto_desc.set_name(desc->name);
+ proto_desc.set_will_notify_on_start(true);
+ proto_desc.set_will_notify_on_stop(true);
+ using Flags = ProbesDataSource::Descriptor::Flags;
+ if (desc->flags & Flags::kHandlesIncrementalState)
+ proto_desc.set_handles_incremental_state_clear(true);
+ if (desc->fill_descriptor_func) {
+ desc->fill_descriptor_func(&proto_desc);
+ }
+ }
+
+ // Register all the data sources. Separate from the above loop because, if
+ // generating a data source descriptor takes too long, we don't want to be in
+ // a state where only some data sources are registered.
+ for (const DataSourceDescriptor& proto_desc : proto_descs) {
+ endpoint_->RegisterDataSource(proto_desc);
+ }
+
+ // Used by tracebox to synchronize with traced_probes being registered.
+ if (all_data_sources_registered_cb_) {
+ endpoint_->Sync(all_data_sources_registered_cb_);
+ }
+}
+
+void ProbesProducer::OnDisconnect() {
+ PERFETTO_DCHECK(state_ == kConnected || state_ == kConnecting);
+ PERFETTO_LOG("Disconnected from tracing service");
+ if (state_ == kConnected)
+ return task_runner_->PostTask([this] { this->Restart(); });
+
+ state_ = kNotConnected;
+ IncreaseConnectionBackoff();
+ task_runner_->PostDelayedTask([this] { this->Connect(); },
+ connection_backoff_ms_);
+}
+
+void ProbesProducer::SetupDataSource(DataSourceInstanceID instance_id,
+ const DataSourceConfig& config) {
+ PERFETTO_DLOG("SetupDataSource(id=%" PRIu64 ", name=%s)", instance_id,
+ config.name().c_str());
+ PERFETTO_DCHECK(data_sources_.count(instance_id) == 0);
+ TracingSessionID session_id = config.tracing_session_id();
+ PERFETTO_CHECK(session_id > 0);
+
+ std::unique_ptr<ProbesDataSource> data_source;
+
+ for (const DataSourceTraits& rds : kAllDataSources) {
+ if (rds.descriptor->name != config.name()) {
+ continue;
+ }
+ data_source = (this->*(rds.factory_func))(session_id, config);
+ break;
+ }
+
+ if (!data_source) {
+ PERFETTO_ELOG("Failed to create data source '%s'", config.name().c_str());
+ return;
+ }
+
+ session_data_sources_[session_id].emplace(data_source->descriptor,
+ data_source.get());
+ data_sources_[instance_id] = std::move(data_source);
+}
+
+void ProbesProducer::StartDataSource(DataSourceInstanceID instance_id,
+ const DataSourceConfig& config) {
+ PERFETTO_DLOG("StartDataSource(id=%" PRIu64 ", name=%s)", instance_id,
+ config.name().c_str());
+ auto it = data_sources_.find(instance_id);
+ if (it == data_sources_.end()) {
+ // Can happen if SetupDataSource() failed (e.g. ftrace was busy).
+ PERFETTO_ELOG("Data source id=%" PRIu64 " not found", instance_id);
+ return;
+ }
+ ProbesDataSource* data_source = it->second.get();
+ if (data_source->started)
+ return;
+ if (config.trace_duration_ms() != 0) {
+ uint32_t timeout = 5000 + 2 * config.trace_duration_ms();
+ watchdogs_.emplace(
+ instance_id, base::Watchdog::GetInstance()->CreateFatalTimer(
+ timeout, base::WatchdogCrashReason::kTraceDidntStop));
+ }
+ data_source->started = true;
+ data_source->Start();
+ endpoint_->NotifyDataSourceStarted(instance_id);
+}
+
void ProbesProducer::StopDataSource(DataSourceInstanceID id) {
PERFETTO_LOG("Producer stop (id=%" PRIu64 ")", id);
auto it = data_sources_.find(id);
@@ -354,12 +410,19 @@ void ProbesProducer::StopDataSource(DataSourceInstanceID id) {
endpoint_->NotifyDataSourceStopped(id);
TracingSessionID session_id = data_source->tracing_session_id;
- auto range = session_data_sources_.equal_range(session_id);
- for (auto kv = range.first; kv != range.second; kv++) {
- if (kv->second != data_source)
- continue;
- session_data_sources_.erase(kv);
- break;
+
+ auto session_it = session_data_sources_.find(session_id);
+ if (session_it != session_data_sources_.end()) {
+ auto desc_range = session_it->second.equal_range(data_source->descriptor);
+ for (auto ds_it = desc_range.first; ds_it != desc_range.second; ds_it++) {
+ if (ds_it->second == data_source) {
+ session_it->second.erase(ds_it);
+ if (session_it->second.empty()) {
+ session_data_sources_.erase(session_it);
+ }
+ break;
+ }
+ }
}
data_sources_.erase(it);
watchdogs_.erase(id);
@@ -456,56 +519,44 @@ void ProbesProducer::ClearIncrementalState(
// userspace tracing buffer. If more than one ftrace data sources are active,
// this call typically happens after writing for all session has been handled.
void ProbesProducer::OnFtraceDataWrittenIntoDataSourceBuffers() {
- TracingSessionID last_session_id = 0;
- FtraceMetadata* metadata = nullptr;
- InodeFileDataSource* inode_data_source = nullptr;
- ProcessStatsDataSource* ps_data_source = nullptr;
-
- // unordered_multimap guarantees that entries with the same key are contiguous
- // in the iteration.
- for (auto it = session_data_sources_.begin(); /* check below*/; it++) {
- // If this is the last iteration or the session id has changed,
- // dispatch the metadata update to the linked data sources, if any.
- if (it == session_data_sources_.end() || it->first != last_session_id) {
- bool has_inodes = metadata && !metadata->inode_and_device.empty();
- bool has_pids = metadata && !metadata->pids.empty();
- bool has_rename_pids = metadata && !metadata->rename_pids.empty();
- if (has_inodes && inode_data_source)
- inode_data_source->OnInodes(metadata->inode_and_device);
- // Ordering the rename pids before the seen pids is important so that any
- // renamed processes get scraped in the OnPids call.
- if (has_rename_pids && ps_data_source)
- ps_data_source->OnRenamePids(metadata->rename_pids);
- if (has_pids && ps_data_source)
- ps_data_source->OnPids(metadata->pids);
- if (metadata)
- metadata->Clear();
- metadata = nullptr;
- inode_data_source = nullptr;
- ps_data_source = nullptr;
- if (it == session_data_sources_.end())
- break;
- last_session_id = it->first;
- }
- ProbesDataSource* ds = it->second;
- if (!ds->started)
- continue;
-
- if (ds->descriptor == &FtraceDataSource::descriptor) {
- metadata = static_cast<FtraceDataSource*>(ds)->mutable_metadata();
- } else if (ds->descriptor == &InodeFileDataSource::descriptor) {
- inode_data_source = static_cast<InodeFileDataSource*>(ds);
- } else if (ds->descriptor == &ProcessStatsDataSource::descriptor) {
- // A trace session might have declared more than one ps data source.
- // In those cases we often use one for a full dump on startup (
- // targeting a dedicated buffer) and another one for on-demand dumps
- // targeting the main buffer.
- // Only use the one that has on-demand dumps enabled, if any.
- auto ps = static_cast<ProcessStatsDataSource*>(ds);
- if (ps->on_demand_dumps_enabled())
- ps_data_source = ps;
- }
- } // for (session_data_sources_)
+ for (const auto& tracing_session : session_data_sources_) {
+ // Take the metadata (e.g. new pids) collected from ftrace and pass it to
+ // other interested data sources (e.g. the process scraper to get command
+ // lines on new pids and tgid<>tid mappings). Note: there can be more than
+ // one ftrace data source per session. All of them should be considered
+ // (b/169226092).
+ const std::unordered_multimap<const ProbesDataSource::Descriptor*,
+ ProbesDataSource*>& ds_by_type =
+ tracing_session.second;
+ auto ft_range = ds_by_type.equal_range(&FtraceDataSource::descriptor);
+
+ auto ino_range = ds_by_type.equal_range(&InodeFileDataSource::descriptor);
+ auto ps_range = ds_by_type.equal_range(&ProcessStatsDataSource::descriptor);
+ for (auto ft_it = ft_range.first; ft_it != ft_range.second; ft_it++) {
+ auto* ftrace_ds = static_cast<FtraceDataSource*>(ft_it->second);
+ if (!ftrace_ds->started)
+ continue;
+ auto* metadata = ftrace_ds->mutable_metadata();
+ for (auto ps_it = ps_range.first; ps_it != ps_range.second; ps_it++) {
+ auto* ps_ds = static_cast<ProcessStatsDataSource*>(ps_it->second);
+ if (!ps_ds->started || !ps_ds->on_demand_dumps_enabled())
+ continue;
+ // Ordering the rename pids before the seen pids is important so that
+ // any renamed processes get scraped in the OnPids call.
+ if (!metadata->rename_pids.empty())
+ ps_ds->OnRenamePids(metadata->rename_pids);
+ if (!metadata->pids.empty())
+ ps_ds->OnPids(metadata->pids);
+ }
+ for (auto in_it = ino_range.first; in_it != ino_range.second; in_it++) {
+ auto* inode_ds = static_cast<InodeFileDataSource*>(in_it->second);
+ if (!inode_ds->started)
+ continue;
+ inode_ds->OnInodes(metadata->inode_and_device);
+ }
+ metadata->Clear();
+ } // for (FtraceDataSource)
+ } // for (tracing_session)
}
void ProbesProducer::ConnectWithRetries(const char* socket_name,
diff --git a/src/traced/probes/probes_producer.h b/src/traced/probes/probes_producer.h
index eb4df63e0..b021ee5c4 100644
--- a/src/traced/probes/probes_producer.h
+++ b/src/traced/probes/probes_producer.h
@@ -17,6 +17,7 @@
#ifndef SRC_TRACED_PROBES_PROBES_PRODUCER_H_
#define SRC_TRACED_PROBES_PROBES_PRODUCER_H_
+#include <functional>
#include <memory>
#include <unordered_map>
#include <utility>
@@ -65,41 +66,20 @@ class ProbesProducer : public Producer, public FtraceController::Observer {
// Our Impl
void ConnectWithRetries(const char* socket_name,
base::TaskRunner* task_runner);
- std::unique_ptr<ProbesDataSource> CreateFtraceDataSource(
- TracingSessionID session_id,
- const DataSourceConfig& config);
- std::unique_ptr<ProbesDataSource> CreateProcessStatsDataSource(
- TracingSessionID session_id,
- const DataSourceConfig& config);
- std::unique_ptr<ProbesDataSource> CreateInodeFileDataSource(
- TracingSessionID session_id,
- DataSourceConfig config);
- std::unique_ptr<ProbesDataSource> CreateSysStatsDataSource(
- TracingSessionID session_id,
- const DataSourceConfig& config);
- std::unique_ptr<ProbesDataSource> CreateAndroidPowerDataSource(
- TracingSessionID session_id,
- const DataSourceConfig& config);
- std::unique_ptr<ProbesDataSource> CreateAndroidPowerStatsDataSource(
- TracingSessionID session_id,
- const DataSourceConfig& config);
- std::unique_ptr<ProbesDataSource> CreateAndroidLogDataSource(
- TracingSessionID session_id,
- const DataSourceConfig& config);
- std::unique_ptr<ProbesDataSource> CreatePackagesListDataSource(
- TracingSessionID session_id,
- const DataSourceConfig& config);
- std::unique_ptr<ProbesDataSource> CreateMetatraceDataSource(
- TracingSessionID session_id,
- const DataSourceConfig& config);
- std::unique_ptr<ProbesDataSource> CreateSystemInfoDataSource(
- TracingSessionID session_id,
- const DataSourceConfig& config);
- std::unique_ptr<ProbesDataSource> CreateInitialDisplayStateDataSource(
+
+ // Constructs an instance of a data source of type T.
+ template <typename T>
+ std::unique_ptr<ProbesDataSource> CreateDSInstance(
TracingSessionID session_id,
const DataSourceConfig& config);
+
void ActivateTrigger(std::string trigger);
+ // Calls `cb` when all data sources have been registered.
+ void SetAllDataSourcesRegisteredCb(std::function<void()> cb) {
+ all_data_sources_registered_cb_ = cb;
+ }
+
private:
static ProbesProducer* instance_;
@@ -132,13 +112,24 @@ class ProbesProducer : public Producer, public FtraceController::Observer {
std::unordered_map<DataSourceInstanceID, std::unique_ptr<ProbesDataSource>>
data_sources_;
- // Keeps (pointers to) data sources ordered by session id.
- std::unordered_multimap<TracingSessionID, ProbesDataSource*>
+ // Keeps (pointers to) data sources grouped by session id and data source
+ // type. The pointers do not own the data sources (they're owned by
+ // data_sources_).
+ //
+ // const ProbesDataSource::Descriptor* identifies the type.
+ //
+ // Used by OnFtraceDataWrittenIntoDataSourceBuffers().
+ std::unordered_map<
+ TracingSessionID,
+ std::unordered_multimap<const ProbesDataSource::Descriptor*,
+ ProbesDataSource*>>
session_data_sources_;
std::unordered_multimap<FlushRequestID, DataSourceInstanceID>
pending_flushes_;
+ std::function<void()> all_data_sources_registered_cb_;
+
std::unordered_map<DataSourceInstanceID, base::Watchdog::Timer> watchdogs_;
LRUInodeCache cache_{kLRUInodeCacheSize};
std::map<BlockDeviceID, std::unordered_map<Inode, InodeMapValue>>
diff --git a/src/traced/probes/ps/process_stats_data_source.cc b/src/traced/probes/ps/process_stats_data_source.cc
index 9dafa729f..665a350bd 100644
--- a/src/traced/probes/ps/process_stats_data_source.cc
+++ b/src/traced/probes/ps/process_stats_data_source.cc
@@ -79,6 +79,7 @@ inline uint32_t ToU32(const char* str) {
const ProbesDataSource::Descriptor ProcessStatsDataSource::descriptor = {
/*name*/ "linux.process_stats",
/*flags*/ Descriptor::kHandlesIncrementalState,
+ /*fill_descriptor_func*/ nullptr,
};
ProcessStatsDataSource::ProcessStatsDataSource(
@@ -152,9 +153,8 @@ void ProcessStatsDataSource::WriteAllProcesses() {
return;
while (int32_t pid = ReadNextNumericDir(*proc_dir)) {
WriteProcessOrThread(pid);
- char task_path[255];
- sprintf(task_path, "/proc/%d/task", pid);
- base::ScopedDir task_dir(opendir(task_path));
+ base::StackString<128> task_path("/proc/%d/task", pid);
+ base::ScopedDir task_dir(opendir(task_path.c_str()));
if (!task_dir)
continue;
@@ -166,8 +166,10 @@ void ProcessStatsDataSource::WriteAllProcesses() {
} else {
// If we are not interested in thread names, there is no need to open
// a proc file for each thread. We can save time and directly write the
- // thread record.
- WriteThread(tid, pid, /*optional_name=*/nullptr);
+ // thread record. Note that we still read proc_status for recording
+ // NSpid entries.
+ std::string proc_status = ReadProcPidFile(tid, "status");
+ WriteThread(tid, pid, /*optional_name=*/nullptr, proc_status);
}
}
}
@@ -221,28 +223,75 @@ void ProcessStatsDataSource::WriteProcessOrThread(int32_t pid) {
if (proc_status.empty())
return;
int tgid = ToInt(ReadProcStatusEntry(proc_status, "Tgid:"));
- if (tgid <= 0)
+ int tid = ToInt(ReadProcStatusEntry(proc_status, "Pid:"));
+ if (tgid <= 0 || tid <= 0)
return;
- if (!seen_pids_.count(tgid))
- WriteProcess(tgid, proc_status);
+
+ if (!seen_pids_.count(tgid)) {
+ // We need to read the status file if |pid| is non-main thread.
+ const std::string& proc_status_tgid =
+ (tgid == tid ? proc_status : ReadProcPidFile(tgid, "status"));
+ WriteProcess(tgid, proc_status_tgid);
+ }
if (pid != tgid) {
PERFETTO_DCHECK(!seen_pids_.count(pid));
std::string thread_name;
if (record_thread_names_)
thread_name = ReadProcStatusEntry(proc_status, "Name:");
- WriteThread(pid, tgid, thread_name.empty() ? nullptr : thread_name.c_str());
+ WriteThread(pid, tgid, thread_name.empty() ? nullptr : thread_name.c_str(),
+ proc_status);
+ }
+}
+
+void ProcessStatsDataSource::ReadNamespacedTids(int32_t tid,
+ const std::string& proc_status,
+ TidArray& out) {
+ // If a process has entered a PID namespace, NSpid shows the mapping in
+ // the status file like: NSpid: 28971 2
+ // NStgid: 28971 2
+ // which denotes that the thread (or process) 28971 in the root PID namespace
+ // has PID = 2 in the child PID namespace. This information can be read from
+ // the NSpid entry in /proc/<tid>/status.
+ if (proc_status.empty())
+ return;
+ std::string nspid = ReadProcStatusEntry(proc_status, "NSpid:");
+ if (nspid.empty())
+ return;
+
+ out.fill(0); // Zero-initialize the array in case the caller doesn't.
+ auto it = out.begin();
+
+ base::StringSplitter ss(std::move(nspid), '\t');
+ ss.Next(); // Skip the 1st element.
+ PERFETTO_DCHECK(base::CStringToInt32(ss.cur_token()) == tid);
+ while (ss.Next()) {
+ PERFETTO_CHECK(it < out.end());
+ auto maybe_int32 = base::CStringToInt32(ss.cur_token());
+ PERFETTO_DCHECK(maybe_int32.has_value());
+ *it++ = *maybe_int32;
}
}
void ProcessStatsDataSource::WriteProcess(int32_t pid,
const std::string& proc_status) {
PERFETTO_DCHECK(ToInt(ReadProcStatusEntry(proc_status, "Tgid:")) == pid);
+ // Assert that |proc_status| is not for a non-main thread.
+ PERFETTO_DCHECK(ToInt(ReadProcStatusEntry(proc_status, "Pid:")) == pid);
auto* proc = GetOrCreatePsTree()->add_processes();
proc->set_pid(pid);
proc->set_ppid(ToInt(ReadProcStatusEntry(proc_status, "PPid:")));
// Uid will have multiple entries, only return first (real uid).
proc->set_uid(ToInt(ReadProcStatusEntry(proc_status, "Uid:")));
+ // Optionally write namespace-local PIDs.
+ TidArray nspids = {};
+ ReadNamespacedTids(pid, proc_status, nspids);
+ for (auto nspid : nspids) {
+ if (nspid == 0) // No more elements.
+ break;
+ proc->add_nspid(nspid);
+ }
+
std::string cmdline = ReadProcPidFile(pid, "cmdline");
if (!cmdline.empty()) {
if (cmdline.back() != '\0') {
@@ -261,12 +310,22 @@ void ProcessStatsDataSource::WriteProcess(int32_t pid,
void ProcessStatsDataSource::WriteThread(int32_t tid,
int32_t tgid,
- const char* optional_name) {
+ const char* optional_name,
+ const std::string& proc_status) {
auto* thread = GetOrCreatePsTree()->add_threads();
thread->set_tid(tid);
thread->set_tgid(tgid);
if (optional_name)
thread->set_name(optional_name);
+
+ // Optionally write namespace-local TIDs.
+ TidArray nstids = {};
+ ReadNamespacedTids(tid, proc_status, nstids);
+ for (auto nstid : nstids) {
+ if (nstid == 0) // No more elements.
+ break;
+ thread->add_nstid(nstid);
+ }
seen_pids_.insert(tid);
}
@@ -279,17 +338,17 @@ base::ScopedDir ProcessStatsDataSource::OpenProcDir() {
std::string ProcessStatsDataSource::ReadProcPidFile(int32_t pid,
const std::string& file) {
+ base::StackString<128> path("/proc/%" PRId32 "/%s", pid, file.c_str());
std::string contents;
contents.reserve(4096);
- if (!base::ReadFile("/proc/" + std::to_string(pid) + "/" + file, &contents))
+ if (!base::ReadFile(path.c_str(), &contents))
return "";
return contents;
}
base::ScopedDir ProcessStatsDataSource::OpenProcTaskDir(int32_t pid) {
- char task_path[255];
- sprintf(task_path, "/proc/%d/task", pid);
- return base::ScopedDir(opendir(task_path));
+ base::StackString<128> task_path("/proc/%d/task", pid);
+ return base::ScopedDir(opendir(task_path.c_str()));
}
std::string ProcessStatsDataSource::ReadProcStatusEntry(const std::string& buf,
diff --git a/src/traced/probes/ps/process_stats_data_source.h b/src/traced/probes/ps/process_stats_data_source.h
index 9d5640ae9..70ddd8eb1 100644
--- a/src/traced/probes/ps/process_stats_data_source.h
+++ b/src/traced/probes/ps/process_stats_data_source.h
@@ -17,6 +17,7 @@
#ifndef SRC_TRACED_PROBES_PS_PROCESS_STATS_DATA_SOURCE_H_
#define SRC_TRACED_PROBES_PS_PROCESS_STATS_DATA_SOURCE_H_
+#include <array>
#include <limits>
#include <memory>
#include <set>
@@ -103,10 +104,21 @@ class ProcessStatsDataSource : public ProbesDataSource {
// Functions for snapshotting process/thread long-term info and relationships.
void WriteProcess(int32_t pid, const std::string& proc_status);
- void WriteThread(int32_t tid, int32_t tgid, const char* optional_name);
+ void WriteThread(int32_t tid,
+ int32_t tgid,
+ const char* optional_name,
+ const std::string& proc_status);
void WriteProcessOrThread(int32_t pid);
std::string ReadProcStatusEntry(const std::string& buf, const char* key);
+ constexpr static size_t kMaxNamespacedTidSize = 8;
+ using TidArray = std::array<int32_t, kMaxNamespacedTidSize>;
+ // Reads the thread IDs in each non-root level of PID namespace from
+ // /proc/tid/status.
+ void ReadNamespacedTids(int32_t tid,
+ const std::string& proc_status,
+ TidArray& out);
+
// Functions for periodically sampling process stats/counters.
static void Tick(base::WeakPtr<ProcessStatsDataSource>);
void WriteAllProcessStats();
diff --git a/src/traced/probes/ps/process_stats_data_source_unittest.cc b/src/traced/probes/ps/process_stats_data_source_unittest.cc
index bb123d1bf..0fa7d546b 100644
--- a/src/traced/probes/ps/process_stats_data_source_unittest.cc
+++ b/src/traced/probes/ps/process_stats_data_source_unittest.cc
@@ -653,5 +653,41 @@ TEST_F(ProcessStatsDataSourceTest, ThreadTimeInState) {
base::Rmdir(path);
}
+TEST_F(ProcessStatsDataSourceTest, NamespacedProcess) {
+ auto data_source = GetProcessStatsDataSource(DataSourceConfig());
+ EXPECT_CALL(*data_source, ReadProcPidFile(42, "status"))
+ .WillOnce(Return(
+ "Name: foo\nTgid:\t42\nPid: 42\nPPid: 17\nNSpid:\t42\t2\n"));
+ EXPECT_CALL(*data_source, ReadProcPidFile(42, "cmdline"))
+ .WillOnce(Return(std::string("foo\0bar\0baz\0", 12)));
+
+ EXPECT_CALL(*data_source, ReadProcPidFile(43, "status"))
+ .WillOnce(Return(
+ "Name: foo\nTgid:\t42\nPid: 43\nPPid: 17\nNSpid:\t43\t3\n"));
+
+ // It's possible that OnPids() is called with a non-main thread is seen before
+ // the main thread for a process. When this happens, the data source
+ // will WriteProcess(42) first and then WriteThread(43).
+ data_source->OnPids({43});
+ data_source->OnPids({42}); // This will be a no-op.
+
+ auto trace = writer_raw_->GetAllTracePackets();
+ ASSERT_EQ(trace.size(), 1u);
+ auto ps_tree = trace[0].process_tree();
+ ASSERT_EQ(ps_tree.processes_size(), 1);
+ auto first_process = ps_tree.processes()[0];
+ ASSERT_EQ(first_process.pid(), 42);
+ ASSERT_EQ(first_process.ppid(), 17);
+ auto nspid = first_process.nspid();
+ EXPECT_THAT(nspid, ElementsAre(2));
+
+ ASSERT_EQ(ps_tree.threads_size(), 1);
+ auto first_thread = ps_tree.threads()[0];
+ ASSERT_EQ(first_thread.tid(), 43);
+ ASSERT_EQ(first_thread.tgid(), 42);
+ auto nstid = first_thread.nstid();
+ EXPECT_THAT(nstid, ElementsAre(3));
+}
+
} // namespace
} // namespace perfetto
diff --git a/src/traced/probes/sys_stats/BUILD.gn b/src/traced/probes/sys_stats/BUILD.gn
index 9c02da80b..ceeaaf587 100644
--- a/src/traced/probes/sys_stats/BUILD.gn
+++ b/src/traced/probes/sys_stats/BUILD.gn
@@ -26,6 +26,7 @@ source_set("sys_stats") {
"../../../../protos/perfetto/trace:zero",
"../../../../protos/perfetto/trace/sys_stats:zero",
"../../../base",
+ "../common",
]
sources = [
"sys_stats_data_source.cc",
@@ -43,6 +44,7 @@ perfetto_unittest_source_set("unittests") {
"../../../../protos/perfetto/trace/sys_stats:cpp",
"../../../../src/base:test_support",
"../../../../src/tracing/test:test_support",
+ "../common:test_support",
]
sources = [ "sys_stats_data_source_unittest.cc" ]
}
diff --git a/src/traced/probes/sys_stats/sys_stats_data_source.cc b/src/traced/probes/sys_stats/sys_stats_data_source.cc
index 3d75ff2ff..9f2875fc1 100644
--- a/src/traced/probes/sys_stats/sys_stats_data_source.cc
+++ b/src/traced/probes/sys_stats/sys_stats_data_source.cc
@@ -31,6 +31,7 @@
#include "perfetto/ext/base/metatrace.h"
#include "perfetto/ext/base/scoped_file.h"
#include "perfetto/ext/base/string_splitter.h"
+#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/utils.h"
#include "perfetto/ext/traced/sys_stats_counters.h"
@@ -69,16 +70,20 @@ uint32_t ClampTo10Ms(uint32_t period_ms, const char* counter_name) {
const ProbesDataSource::Descriptor SysStatsDataSource::descriptor = {
/*name*/ "linux.sys_stats",
/*flags*/ Descriptor::kFlagsNone,
+ /*fill_descriptor_func*/ nullptr,
};
-SysStatsDataSource::SysStatsDataSource(base::TaskRunner* task_runner,
- TracingSessionID session_id,
- std::unique_ptr<TraceWriter> writer,
- const DataSourceConfig& ds_config,
- OpenFunction open_fn)
+SysStatsDataSource::SysStatsDataSource(
+ base::TaskRunner* task_runner,
+ TracingSessionID session_id,
+ std::unique_ptr<TraceWriter> writer,
+ const DataSourceConfig& ds_config,
+ std::unique_ptr<CpuFreqInfo> cpu_freq_info,
+ OpenFunction open_fn)
: ProbesDataSource(session_id, &descriptor),
task_runner_(task_runner),
writer_(std::move(writer)),
+ cpu_freq_info_(std::move(cpu_freq_info)),
weak_factory_(this) {
ns_per_user_hz_ = 1000000000ull / static_cast<uint64_t>(sysconf(_SC_CLK_TCK));
@@ -138,14 +143,15 @@ SysStatsDataSource::SysStatsDataSource(base::TaskRunner* task_runner,
stat_enabled_fields_ |= 1ul << static_cast<uint32_t>(*counter);
}
- std::array<uint32_t, 4> periods_ms{};
- std::array<uint32_t, 4> ticks{};
+ std::array<uint32_t, 5> periods_ms{};
+ std::array<uint32_t, 5> ticks{};
static_assert(periods_ms.size() == ticks.size(), "must have same size");
periods_ms[0] = ClampTo10Ms(cfg.meminfo_period_ms(), "meminfo_period_ms");
periods_ms[1] = ClampTo10Ms(cfg.vmstat_period_ms(), "vmstat_period_ms");
periods_ms[2] = ClampTo10Ms(cfg.stat_period_ms(), "stat_period_ms");
periods_ms[3] = ClampTo10Ms(cfg.devfreq_period_ms(), "devfreq_period_ms");
+ periods_ms[4] = ClampTo10Ms(cfg.cpufreq_period_ms(), "cpufreq_period_ms");
tick_period_ms_ = 0;
for (uint32_t ms : periods_ms) {
@@ -168,6 +174,7 @@ SysStatsDataSource::SysStatsDataSource(base::TaskRunner* task_runner,
vmstat_ticks_ = ticks[1];
stat_ticks_ = ticks[2];
devfreq_ticks_ = ticks[3];
+ cpufreq_ticks_ = ticks[4];
}
void SysStatsDataSource::Start() {
@@ -211,6 +218,9 @@ void SysStatsDataSource::ReadSysStats() {
if (devfreq_ticks_ && tick_ % devfreq_ticks_ == 0)
ReadDevfreq(sys_stats);
+ if (cpufreq_ticks_ && tick_ % cpufreq_ticks_ == 0)
+ ReadCpufreq(sys_stats);
+
sys_stats->set_collection_end_timestamp(
static_cast<uint64_t>(base::GetBootTimeNs().count()));
@@ -234,6 +244,13 @@ void SysStatsDataSource::ReadDevfreq(protos::pbzero::SysStats* sys_stats) {
}
}
+void SysStatsDataSource::ReadCpufreq(protos::pbzero::SysStats* sys_stats) {
+ const auto& cpufreq = cpu_freq_info_->ReadCpuCurrFreq();
+
+ for (const auto& c : cpufreq)
+ sys_stats->add_cpufreq_khz(c);
+}
+
base::ScopedDir SysStatsDataSource::OpenDevfreqDir() {
const char* base_dir = "/sys/class/devfreq/";
base::ScopedDir devfreq_dir(opendir(base_dir));
@@ -248,16 +265,15 @@ const char* SysStatsDataSource::ReadDevfreqCurFreq(
const std::string& deviceName) {
const char* devfreq_base_path = "/sys/class/devfreq";
const char* freq_file_name = "cur_freq";
- char cur_freq_path[256];
- snprintf(cur_freq_path, sizeof(cur_freq_path), "%s/%s/%s", devfreq_base_path,
- deviceName.c_str(), freq_file_name);
- base::ScopedFile fd = OpenReadOnly(cur_freq_path);
+ base::StackString<256> cur_freq_path("%s/%s/%s", devfreq_base_path,
+ deviceName.c_str(), freq_file_name);
+ base::ScopedFile fd = OpenReadOnly(cur_freq_path.c_str());
if (!fd && !devfreq_error_logged_) {
devfreq_error_logged_ = true;
- PERFETTO_PLOG("Failed to open %s", cur_freq_path);
+ PERFETTO_PLOG("Failed to open %s", cur_freq_path.c_str());
return "";
}
- size_t rsize = ReadFile(&fd, cur_freq_path);
+ size_t rsize = ReadFile(&fd, cur_freq_path.c_str());
if (!rsize)
return "";
return static_cast<char*>(read_buf_.Get());
diff --git a/src/traced/probes/sys_stats/sys_stats_data_source.h b/src/traced/probes/sys_stats/sys_stats_data_source.h
index cf477709e..3140efa52 100644
--- a/src/traced/probes/sys_stats/sys_stats_data_source.h
+++ b/src/traced/probes/sys_stats/sys_stats_data_source.h
@@ -29,6 +29,7 @@
#include "perfetto/ext/tracing/core/basic_types.h"
#include "perfetto/ext/tracing/core/trace_writer.h"
#include "perfetto/tracing/core/data_source_config.h"
+#include "src/traced/probes/common/cpu_freq_info.h"
#include "src/traced/probes/probes_data_source.h"
namespace perfetto {
@@ -52,6 +53,7 @@ class SysStatsDataSource : public ProbesDataSource {
TracingSessionID,
std::unique_ptr<TraceWriter> writer,
const DataSourceConfig&,
+ std::unique_ptr<CpuFreqInfo> cpu_freq_info,
OpenFunction = nullptr);
~SysStatsDataSource() override;
@@ -84,6 +86,7 @@ class SysStatsDataSource : public ProbesDataSource {
void ReadVmstat(protos::pbzero::SysStats* sys_stats);
void ReadStat(protos::pbzero::SysStats* sys_stats);
void ReadDevfreq(protos::pbzero::SysStats* sys_stats);
+ void ReadCpufreq(protos::pbzero::SysStats* sys_stats);
size_t ReadFile(base::ScopedFile*, const char* path);
base::TaskRunner* const task_runner_;
@@ -103,8 +106,11 @@ class SysStatsDataSource : public ProbesDataSource {
uint32_t stat_ticks_ = 0;
uint32_t stat_enabled_fields_ = 0;
uint32_t devfreq_ticks_ = 0;
+ uint32_t cpufreq_ticks_ = 0;
bool devfreq_error_logged_ = false;
+ std::unique_ptr<CpuFreqInfo> cpu_freq_info_;
+
base::WeakPtrFactory<SysStatsDataSource> weak_factory_; // Keep last.
};
diff --git a/src/traced/probes/sys_stats/sys_stats_data_source_unittest.cc b/src/traced/probes/sys_stats/sys_stats_data_source_unittest.cc
index b239ffa84..a585edf3a 100644
--- a/src/traced/probes/sys_stats/sys_stats_data_source_unittest.cc
+++ b/src/traced/probes/sys_stats/sys_stats_data_source_unittest.cc
@@ -19,6 +19,7 @@
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/temp_file.h"
#include "src/base/test/test_task_runner.h"
+#include "src/traced/probes/common/cpu_freq_info_for_testing.h"
#include "src/traced/probes/sys_stats/sys_stats_data_source.h"
#include "src/tracing/core/trace_writer_for_testing.h"
#include "test/gtest_and_gmock.h"
@@ -196,11 +197,13 @@ class TestSysStatsDataSource : public SysStatsDataSource {
TracingSessionID id,
std::unique_ptr<TraceWriter> writer,
const DataSourceConfig& config,
+ std::unique_ptr<CpuFreqInfo> cpu_freq_info,
OpenFunction open_fn)
: SysStatsDataSource(task_runner,
id,
std::move(writer),
config,
+ std::move(cpu_freq_info),
open_fn) {}
MOCK_METHOD0(OpenDevfreqDir, base::ScopedDir());
@@ -230,7 +233,8 @@ class SysStatsDataSourceTest : public ::testing::Test {
writer_raw_ = writer.get();
auto instance =
std::unique_ptr<TestSysStatsDataSource>(new TestSysStatsDataSource(
- &task_runner_, 0, std::move(writer), cfg, MockOpenReadOnly));
+ &task_runner_, 0, std::move(writer), cfg,
+ cpu_freq_info_for_testing_.GetInstance(), MockOpenReadOnly));
instance->set_ns_per_user_hz_for_testing(1000000000ull / 100); // 100 Hz.
instance->Start();
return instance;
@@ -252,6 +256,7 @@ class SysStatsDataSourceTest : public ::testing::Test {
TraceWriterForTesting* writer_raw_ = nullptr;
base::TestTaskRunner task_runner_;
+ CpuFreqInfoForTesting cpu_freq_info_for_testing_;
};
TEST_F(SysStatsDataSourceTest, Meminfo) {
@@ -482,5 +487,31 @@ TEST_F(SysStatsDataSourceTest, StatForksOnly) {
ASSERT_EQ(sys_stats.num_softirq_size(), 0);
}
+TEST_F(SysStatsDataSourceTest, Cpufreq) {
+ protos::gen::SysStatsConfig cfg;
+ cfg.set_cpufreq_period_ms(10);
+ DataSourceConfig config_obj;
+ config_obj.set_sys_stats_config_raw(cfg.SerializeAsString());
+ auto data_source = GetSysStatsDataSource(config_obj);
+
+ WaitTick(data_source.get());
+
+ protos::gen::TracePacket packet = writer_raw_->GetOnlyTracePacket();
+ ASSERT_TRUE(packet.has_sys_stats());
+ const auto& sys_stats = packet.sys_stats();
+ EXPECT_GT(sys_stats.cpufreq_khz_size(), 0);
+ EXPECT_EQ(sys_stats.cpufreq_khz()[0], 2650000u);
+ if (sys_stats.cpufreq_khz_size() > 1) {
+ // We emulated 2 CPUs but it is possible the test system is single core.
+ EXPECT_EQ(sys_stats.cpufreq_khz()[1], 3698200u);
+ }
+ for (unsigned int i = 2;
+ i < static_cast<unsigned int>(sys_stats.cpufreq_khz_size()); i++) {
+ // For cpux which scaling_cur_freq was not emulated in unittest, cpufreq
+ // should be recorded as 0
+ EXPECT_EQ(sys_stats.cpufreq_khz()[i], 0u);
+ }
+}
+
} // namespace
} // namespace perfetto
diff --git a/src/traced/probes/system_info/system_info_data_source.cc b/src/traced/probes/system_info/system_info_data_source.cc
index 3e96239e6..2178556cd 100644
--- a/src/traced/probes/system_info/system_info_data_source.cc
+++ b/src/traced/probes/system_info/system_info_data_source.cc
@@ -42,6 +42,7 @@ const char kProcessor[] = "processor";
const ProbesDataSource::Descriptor SystemInfoDataSource::descriptor = {
/* name */ "linux.system_info",
/* flags */ Descriptor::kFlagsNone,
+ /* fill_descriptor_func */ nullptr,
};
SystemInfoDataSource::SystemInfoDataSource(
diff --git a/src/traced/service/builtin_producer.cc b/src/traced/service/builtin_producer.cc
index 1e10ed13c..a2007beb5 100644
--- a/src/traced/service/builtin_producer.cc
+++ b/src/traced/service/builtin_producer.cc
@@ -20,6 +20,7 @@
#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
+#include "perfetto/base/proc_utils.h"
#include "perfetto/ext/base/metatrace.h"
#include "perfetto/ext/base/utils.h"
#include "perfetto/ext/base/weak_ptr.h"
@@ -30,6 +31,11 @@
#include "perfetto/tracing/core/data_source_descriptor.h"
#include "src/tracing/core/metatrace_writer.h"
+// This translation unit is only ever used in Android in-tree builds.
+// These producers are here to dynamically start heapprofd and other services
+// via sysprops when a trace that requests them is active. That can only happen
+// in in-tree builds of Android.
+
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
#include <sys/system_properties.h>
#endif
@@ -61,8 +67,16 @@ BuiltinProducer::~BuiltinProducer() {
}
void BuiltinProducer::ConnectInProcess(TracingService* svc) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ // TODO(primiano): ConnectProducer should take a base::PlatformProcessId not
+ // pid_t, as they are different on Windows. But that is a larger refactoring
+ // and not worth given this is the only use case where it clashes.
+ const pid_t cur_proc_id = 0;
+#else
+ const pid_t cur_proc_id = base::GetProcessId();
+#endif
endpoint_ = svc->ConnectProducer(
- this, base::GetCurrentUserId(), "traced",
+ this, base::GetCurrentUserId(), cur_proc_id, "traced",
/*shared_memory_size_hint_bytes=*/16 * 1024, /*in_process=*/true,
TracingService::ProducerSMBScrapingMode::kDisabled,
/*shared_memory_page_size_hint_bytes=*/4096);
diff --git a/src/traced/service/service.cc b/src/traced/service/service.cc
index 6d9ba8b75..215392af8 100644
--- a/src/traced/service/service.cc
+++ b/src/traced/service/service.cc
@@ -17,6 +17,7 @@
#include <stdio.h>
#include <algorithm>
+#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/getopt.h"
#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/unix_task_runner.h"
@@ -38,6 +39,10 @@
#include <unistd.h>
#endif
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <sys/system_properties.h>
+#endif
+
namespace perfetto {
namespace {
#if defined(PERFETTO_SET_SOCKET_PERMISSIONS)
@@ -75,7 +80,7 @@ void SetSocketPermissions(const std::string& socket_name,
#endif // defined(PERFETTO_SET_SOCKET_PERMISSIONS)
void PrintUsage(const char* prog_name) {
- PERFETTO_ELOG(R"(
+ fprintf(stderr, R"(
Usage: %s [option] ...
Options and arguments
--background : Exits immediately and continues running in the background
@@ -87,12 +92,14 @@ Options and arguments
<prod_mode> is the mode bits (e.g. 0660) for chmod the produce socket,
<cons_group> is the group name for chgrp the consumer socket, and
<cons_mode> is the mode bits (e.g. 0660) for chmod the consumer socket.
-Example: %s --set-socket-permissions traced-producer:0660:traced-consumer:0660
+
+Example:
+ %s --set-socket-permissions traced-producer:0660:traced-consumer:0660
starts the service and sets the group ownership of the producer and consumer
sockets to "traced-producer" and "traced-consumer", respectively. Both
- producer and consumer sockets are chmod with 0660 (rw-rw----) mode bits.
+ producer and consumer sockets are chmod with 0660 (rw-rw----) mode bits.
)",
- prog_name, prog_name);
+ prog_name, prog_name);
}
} // namespace
@@ -146,7 +153,7 @@ int PERFETTO_EXPORT_ENTRYPOINT ServiceMain(int argc, char** argv) {
}
if (background) {
- base::Daemonize();
+ base::Daemonize([] { return 0; });
}
base::UnixTaskRunner task_runner;
@@ -192,8 +199,13 @@ int PERFETTO_EXPORT_ENTRYPOINT ServiceMain(int argc, char** argv) {
return 1;
}
+ // Advertise builtin producers only on in-tree builds. These producers serve
+ // only to dynamically start heapprofd and other services via sysprops, but
+ // that can only ever happen in in-tree builds.
+#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
BuiltinProducer builtin_producer(&task_runner, /*lazy_stop_delay_ms=*/30000);
builtin_producer.ConnectInProcess(svc->service());
+#endif
// Set the CPU limit and start the watchdog running. The memory limit will
// be set inside the service code as it relies on the size of buffers.
@@ -203,6 +215,24 @@ int PERFETTO_EXPORT_ENTRYPOINT ServiceMain(int argc, char** argv) {
base::kWatchdogDefaultCpuWindow);
watchdog->Start();
+ // If the TRACED_NOTIFY_FD env var is set, write 1 and close the FD. This is
+ // so tools can synchronize with the point where the IPC socket has been
+ // opened, without having to poll. This is used for //src/tracebox.
+ const char* env_notif = getenv("TRACED_NOTIFY_FD");
+ if (env_notif) {
+ int notif_fd = atoi(env_notif);
+ PERFETTO_CHECK(base::WriteAll(notif_fd, "1", 1) == 1);
+ PERFETTO_CHECK(base::CloseFile(notif_fd) == 0);
+ }
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+ // Notify init (perfetto.rc) that traced has been started. Used only by
+ // the perfetto_trace_on_boot init service.
+ if (__system_property_set("sys.trace.traced_started", "1") != 0) {
+ PERFETTO_PLOG("Failed to set property sys.trace.traced_started");
+ }
+#endif
+
PERFETTO_ILOG("Started traced, listening on %s %s", GetProducerSocket(),
GetConsumerSocket());
task_runner.Run();
diff --git a/src/tracing/BUILD.gn b/src/tracing/BUILD.gn
index 2440d39f1..ebf198ccb 100644
--- a/src/tracing/BUILD.gn
+++ b/src/tracing/BUILD.gn
@@ -50,14 +50,17 @@ if (perfetto_build_standalone) {
}
}
-# Separate target because the embedder might not want this (e.g. on Windows).
+# Separate target because the embedder might not want this.
source_set("platform_impl") {
deps = [
"../../gn:default_deps",
"../../include/perfetto/tracing",
"../base",
]
- sources = [ "platform_posix.cc" ]
+ sources = [
+ "platform_posix.cc",
+ "platform_windows.cc",
+ ]
}
# Fake platform that allows buiding the client lib on all OSes. You can only use
@@ -156,6 +159,7 @@ perfetto_unittest_source_set("unittests") {
":client_api_without_backends",
":platform_impl",
]
+
sources += [
"traced_proto_unittest.cc",
"traced_value_unittest.cc",
diff --git a/src/tracing/OWNERS b/src/tracing/OWNERS
new file mode 100644
index 000000000..d3a35f887
--- /dev/null
+++ b/src/tracing/OWNERS
@@ -0,0 +1,7 @@
+# Knowledgeable people for C++ SDK & TRACE_EVENT headers.
+skyostil@google.com
+eseckler@google.com
+nuskos@google.com
+
+# For internal/ core/ and ipc/.
+primiano@google.com
diff --git a/src/tracing/console_interceptor.cc b/src/tracing/console_interceptor.cc
index 99ce956fe..ec924c092 100644
--- a/src/tracing/console_interceptor.cc
+++ b/src/tracing/console_interceptor.cc
@@ -16,10 +16,17 @@
#include "perfetto/tracing/console_interceptor.h"
+#include <stdarg.h>
+
+#include <algorithm>
+#include <cmath>
+#include <tuple>
+
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/hash.h"
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/utils.h"
#include "perfetto/tracing/internal/track_event_internal.h"
@@ -35,10 +42,6 @@
#include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
#include "protos/perfetto/trace/track_event/track_event.pbzero.h"
-#include <algorithm>
-#include <cmath>
-#include <tuple>
-
namespace perfetto {
// sRGB color.
@@ -177,18 +180,17 @@ void ConsoleInterceptor::Delegate::OnTrackUpdated(
auto& tls = context_.GetThreadLocalState();
std::array<char, 128> message_prefix{};
- ssize_t written = 0;
+ size_t written = 0;
if (tls.use_colors) {
- written = snprintf(message_prefix.data(), message_prefix.size(),
- FMT_RGB_SET_BG " %s%s %-*.*s", track_color.r,
- track_color.g, track_color.b, kReset, kDim, title_width,
- title_width, title.data());
+ written = base::SprintfTrunc(message_prefix.data(), message_prefix.size(),
+ FMT_RGB_SET_BG " %s%s %-*.*s", track_color.r,
+ track_color.g, track_color.b, kReset, kDim,
+ title_width, title_width, title.data());
} else {
- written = snprintf(message_prefix.data(), message_prefix.size(), "%-*.*s",
- title_width + 2, title_width, title.data());
+ written = base::SprintfTrunc(message_prefix.data(), message_prefix.size(),
+ "%-*.*s", title_width + 2, title_width,
+ title.data());
}
- if (written < 0)
- written = message_prefix.size();
track.user_data.assign(message_prefix.begin(),
message_prefix.begin() + written);
}
diff --git a/src/tracing/consumer_api_deprecated/consumer_api_deprecated.cc b/src/tracing/consumer_api_deprecated/consumer_api_deprecated.cc
index 6d901d8b3..0a820428c 100644
--- a/src/tracing/consumer_api_deprecated/consumer_api_deprecated.cc
+++ b/src/tracing/consumer_api_deprecated/consumer_api_deprecated.cc
@@ -17,7 +17,6 @@
#include "perfetto/public/consumer_api.h"
#include <fcntl.h>
-#include <inttypes.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/select.h>
@@ -27,6 +26,7 @@
#include <unistd.h>
#include <atomic>
+#include <cinttypes>
#include <condition_variable>
#include <memory>
#include <mutex>
@@ -34,6 +34,7 @@
#include "perfetto/base/build_config.h"
#include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/temp_file.h"
#include "perfetto/ext/base/thread_checker.h"
#include "perfetto/ext/base/unix_task_runner.h"
@@ -149,10 +150,10 @@ bool TracingSession::Initialize() {
return false;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
- char memfd_name[64];
- snprintf(memfd_name, sizeof(memfd_name), "perfetto_trace_%" PRId64, handle_);
- buf_fd_.reset(
- static_cast<int>(syscall(__NR_memfd_create, memfd_name, MFD_CLOEXEC)));
+
+ base::StackString<64> memfd_name("perfetto_trace_%" PRId64, handle_);
+ buf_fd_.reset(static_cast<int>(
+ syscall(__NR_memfd_create, memfd_name.c_str(), MFD_CLOEXEC)));
#else
// Fallback for testing on Linux/mac.
buf_fd_ = base::TempFile::CreateUnlinked().ReleaseFD();
diff --git a/src/tracing/consumer_api_deprecated/consumer_api_deprecated_test.cc b/src/tracing/consumer_api_deprecated/consumer_api_deprecated_test.cc
index ebc885a87..c8af35cbe 100644
--- a/src/tracing/consumer_api_deprecated/consumer_api_deprecated_test.cc
+++ b/src/tracing/consumer_api_deprecated/consumer_api_deprecated_test.cc
@@ -14,11 +14,10 @@
* limitations under the License.
*/
-#include <inttypes.h>
-
#include <array>
#include <atomic>
#include <chrono>
+#include <cinttypes>
#include <thread>
#include "perfetto/base/logging.h"
diff --git a/src/tracing/core/BUILD.gn b/src/tracing/core/BUILD.gn
index c81c7163a..e082c0889 100644
--- a/src/tracing/core/BUILD.gn
+++ b/src/tracing/core/BUILD.gn
@@ -92,6 +92,7 @@ perfetto_unittest_source_set("unittests") {
"../../../protos/perfetto/trace:zero",
"../../../protos/perfetto/trace/ftrace:cpp",
"../../../protos/perfetto/trace/perfetto:cpp",
+ "../../../src/protozero/filtering:bytecode_generator",
"../../base",
"../../base:test_support",
"../test:test_support",
diff --git a/src/tracing/core/id_allocator.cc b/src/tracing/core/id_allocator.cc
index 4b32473b8..f39f735f8 100644
--- a/src/tracing/core/id_allocator.cc
+++ b/src/tracing/core/id_allocator.cc
@@ -57,7 +57,7 @@ void IdAllocatorGeneric::FreeGeneric(uint32_t id) {
}
bool IdAllocatorGeneric::IsEmpty() const {
- for (const auto id : ids_) {
+ for (auto id : ids_) {
if (id)
return false;
}
diff --git a/src/tracing/core/packet_stream_validator.cc b/src/tracing/core/packet_stream_validator.cc
index 72a20f5b4..d84eed36e 100644
--- a/src/tracing/core/packet_stream_validator.cc
+++ b/src/tracing/core/packet_stream_validator.cc
@@ -16,9 +16,10 @@
#include "src/tracing/core/packet_stream_validator.h"
-#include <inttypes.h>
#include <stddef.h>
+#include <cinttypes>
+
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/utils.h"
#include "perfetto/protozero/proto_utils.h"
@@ -38,6 +39,7 @@ const uint32_t kReservedFieldIds[] = {
protos::pbzero::TracePacket::kTraceStatsFieldNumber,
protos::pbzero::TracePacket::kCompressedPacketsFieldNumber,
protos::pbzero::TracePacket::kSynchronizationMarkerFieldNumber,
+ protos::pbzero::TracePacket::kTrustedPidFieldNumber,
};
// This translation unit is quite subtle and perf-sensitive. Remember to check
diff --git a/src/tracing/core/packet_stream_validator_unittest.cc b/src/tracing/core/packet_stream_validator_unittest.cc
index fab2a6066..74de04caa 100644
--- a/src/tracing/core/packet_stream_validator_unittest.cc
+++ b/src/tracing/core/packet_stream_validator_unittest.cc
@@ -151,6 +151,76 @@ TEST(PacketStreamValidatorTest, FragmentedPacketWithUid) {
}
}
+TEST(PacketStreamValidatorTest, SimplePacketWithPid) {
+ protos::gen::TracePacket proto;
+ proto.set_trusted_pid(123);
+ std::string ser_buf = proto.SerializeAsString();
+
+ Slices seq;
+ seq.emplace_back(&ser_buf[0], ser_buf.size());
+ EXPECT_FALSE(PacketStreamValidator::Validate(seq));
+}
+
+TEST(PacketStreamValidatorTest, SimplePacketWithZeroPid) {
+ protos::gen::TracePacket proto;
+ proto.set_trusted_pid(0);
+ std::string ser_buf = proto.SerializeAsString();
+
+ Slices seq;
+ seq.emplace_back(&ser_buf[0], ser_buf.size());
+ EXPECT_FALSE(PacketStreamValidator::Validate(seq));
+}
+
+TEST(PacketStreamValidatorTest, SimplePacketWithNegativeOnePid) {
+ protos::gen::TracePacket proto;
+ proto.set_trusted_pid(-1);
+ std::string ser_buf = proto.SerializeAsString();
+
+ Slices seq;
+ seq.emplace_back(&ser_buf[0], ser_buf.size());
+ EXPECT_FALSE(PacketStreamValidator::Validate(seq));
+}
+
+TEST(PacketStreamValidatorTest, ComplexPacketWithPid) {
+ protos::gen::TracePacket proto;
+ proto.mutable_for_testing()->set_str("string field");
+ proto.mutable_ftrace_events()->set_cpu(0);
+ auto* ft = proto.mutable_ftrace_events()->add_event();
+ ft->set_pid(42);
+ ft->mutable_sched_switch()->set_prev_comm("tom");
+ ft->mutable_sched_switch()->set_prev_pid(123);
+ ft->mutable_sched_switch()->set_next_comm("jerry");
+ ft->mutable_sched_switch()->set_next_pid(456);
+ proto.set_trusted_pid(123);
+ std::string ser_buf = proto.SerializeAsString();
+
+ Slices seq;
+ seq.emplace_back(&ser_buf[0], ser_buf.size());
+ EXPECT_FALSE(PacketStreamValidator::Validate(seq));
+}
+
+TEST(PacketStreamValidatorTest, FragmentedPacketWithPid) {
+ protos::gen::TracePacket proto;
+ proto.mutable_for_testing()->set_str("string field");
+ proto.set_trusted_pid(123);
+ proto.mutable_ftrace_events()->set_cpu(0);
+ auto* ft = proto.mutable_ftrace_events()->add_event();
+ ft->set_pid(42);
+ ft->mutable_sched_switch()->set_prev_comm("tom");
+ ft->mutable_sched_switch()->set_prev_pid(123);
+ ft->mutable_sched_switch()->set_next_comm("jerry");
+ ft->mutable_sched_switch()->set_next_pid(456);
+ proto.mutable_for_testing()->set_str("foo");
+ std::string ser_buf = proto.SerializeAsString();
+
+ for (size_t i = 0; i < ser_buf.size(); i++) {
+ Slices seq;
+ seq.emplace_back(&ser_buf[0], i);
+ seq.emplace_back(&ser_buf[i], ser_buf.size() - i);
+ EXPECT_FALSE(PacketStreamValidator::Validate(seq));
+ }
+}
+
TEST(PacketStreamValidatorTest, TruncatedPacket) {
protos::gen::TracePacket proto;
proto.mutable_for_testing()->set_str("string field");
diff --git a/src/tracing/core/shared_memory_arbiter_impl.cc b/src/tracing/core/shared_memory_arbiter_impl.cc
index 39ddd4b29..79128261d 100644
--- a/src/tracing/core/shared_memory_arbiter_impl.cc
+++ b/src/tracing/core/shared_memory_arbiter_impl.cc
@@ -107,7 +107,7 @@ Chunk SharedMemoryArbiterImpl::GetNewChunk(
static const unsigned kMaxStallIntervalUs = 100000;
static const int kLogAfterNStalls = 3;
static const int kFlushCommitsAfterEveryNStalls = 2;
- static const int kAssertAtNStalls = 100;
+ static const int kAssertAtNStalls = 200;
for (;;) {
// TODO(primiano): Probably this lock is not really required and this code
diff --git a/src/tracing/core/shared_memory_arbiter_impl_unittest.cc b/src/tracing/core/shared_memory_arbiter_impl_unittest.cc
index 2b6da0a8d..140a88184 100644
--- a/src/tracing/core/shared_memory_arbiter_impl_unittest.cc
+++ b/src/tracing/core/shared_memory_arbiter_impl_unittest.cc
@@ -42,6 +42,7 @@ using testing::Mock;
class MockProducerEndpoint : public TracingService::ProducerEndpoint {
public:
void RegisterDataSource(const DataSourceDescriptor&) override {}
+ void UpdateDataSource(const DataSourceDescriptor&) override {}
void UnregisterDataSource(const std::string&) override {}
void NotifyFlushComplete(FlushRequestID) override {}
void NotifyDataSourceStarted(DataSourceInstanceID) override {}
diff --git a/src/tracing/core/trace_buffer.cc b/src/tracing/core/trace_buffer.cc
index ce6fa3492..41633aa9e 100644
--- a/src/tracing/core/trace_buffer.cc
+++ b/src/tracing/core/trace_buffer.cc
@@ -27,25 +27,6 @@
#define TRACE_BUFFER_VERBOSE_LOGGING() 0 // Set to 1 when debugging unittests.
#if TRACE_BUFFER_VERBOSE_LOGGING()
#define TRACE_BUFFER_DLOG PERFETTO_DLOG
-namespace {
-constexpr char kHexDigits[] = "0123456789abcdef";
-std::string HexDump(const uint8_t* src, size_t size) {
- std::string buf;
- buf.reserve(4096 * 4);
- char line[64];
- char* c = line;
- for (size_t i = 0; i < size; i++) {
- *c++ = kHexDigits[(src[i] >> 4) & 0x0f];
- *c++ = kHexDigits[(src[i] >> 0) & 0x0f];
- if (i % 16 == 15) {
- buf.append("\n");
- buf.append(line);
- c = line;
- }
- }
- return buf;
-}
-} // namespace
#else
#define TRACE_BUFFER_DLOG(...) void()
#endif
@@ -107,6 +88,7 @@ bool TraceBuffer::Initialize(size_t size) {
// while we execute here. Don't do any processing on it other than memcpy().
void TraceBuffer::CopyChunkUntrusted(ProducerID producer_id_trusted,
uid_t producer_uid_trusted,
+ pid_t producer_pid_trusted,
WriterID writer_id,
ChunkID chunk_id,
uint16_t num_fragments,
@@ -224,7 +206,8 @@ void TraceBuffer::CopyChunkUntrusted(ProducerID producer_id_trusted,
TRACE_BUFFER_DLOG(" copying @ [%lu - %lu] %zu", wptr - begin(),
uintptr_t(wptr - begin()) + record_size, record_size);
WriteChunkRecord(wptr, record, src, size);
- TRACE_BUFFER_DLOG("Chunk raw: %s", HexDump(wptr, record_size).c_str());
+ TRACE_BUFFER_DLOG("Chunk raw: %s",
+ base::HexDump(wptr, record_size).c_str());
stats_.set_chunks_rewritten(stats_.chunks_rewritten() + 1);
return;
}
@@ -276,12 +259,12 @@ void TraceBuffer::CopyChunkUntrusted(ProducerID producer_id_trusted,
stats_.set_bytes_written(stats_.bytes_written() + record_size);
auto it_and_inserted = index_.emplace(
key, ChunkMeta(GetChunkRecordAt(wptr_), num_fragments, chunk_complete,
- chunk_flags, producer_uid_trusted));
+ chunk_flags, producer_uid_trusted, producer_pid_trusted));
PERFETTO_DCHECK(it_and_inserted.second);
TRACE_BUFFER_DLOG(" copying @ [%lu - %lu] %zu", wptr_ - begin(),
uintptr_t(wptr_ - begin()) + record_size, record_size);
WriteChunkRecord(wptr_, record, src, size);
- TRACE_BUFFER_DLOG("Chunk raw: %s", HexDump(wptr_, record_size).c_str());
+ TRACE_BUFFER_DLOG("Chunk raw: %s", base::HexDump(wptr_, record_size).c_str());
wptr_ += record_size;
if (wptr_ >= end()) {
PERFETTO_DCHECK(padding_size == 0);
@@ -452,17 +435,11 @@ bool TraceBuffer::TryPatchChunkContents(ProducerID producer_id,
return false;
}
- // DCHECK that we are writing into a zero-filled size field and not into
- // valid data. It relies on ScatteredStreamWriter::ReserveBytes() to
- // zero-fill reservations in debug builds.
- char zero[Patch::kSize]{};
- PERFETTO_DCHECK(memcmp(ptr, &zero, Patch::kSize) == 0);
-
memcpy(ptr, &patches[i].data[0], Patch::kSize);
}
TRACE_BUFFER_DLOG(
"Chunk raw (after patch): %s",
- HexDump(chunk_begin, chunk_meta.chunk_record->size).c_str());
+ base::HexDump(chunk_begin, chunk_meta.chunk_record->size).c_str());
stats_.set_patches_succeeded(stats_.patches_succeeded() + patches_size);
if (!other_patches_pending) {
@@ -559,7 +536,7 @@ bool TraceBuffer::ReadNextTracePacket(
TRACE_BUFFER_DLOG("ReadNextTracePacket()");
// Just in case we forget to initialize these below.
- *sequence_properties = {0, kInvalidUid, 0};
+ *sequence_properties = {0, kInvalidUid, base::kInvalidPid, 0};
*previous_packet_on_sequence_dropped = false;
// At the start of each sequence iteration, we consider the last read packet
@@ -599,6 +576,7 @@ bool TraceBuffer::ReadNextTracePacket(
const ProducerID trusted_producer_id = read_iter_.producer_id();
const WriterID writer_id = read_iter_.writer_id();
const uid_t trusted_uid = chunk_meta->trusted_uid;
+ const pid_t trusted_pid = chunk_meta->trusted_pid;
// At this point we have a chunk in |chunk_meta| that has not been fully
// read. We don't know yet whether we have enough data to read the full
@@ -672,7 +650,8 @@ bool TraceBuffer::ReadNextTracePacket(
ReadPacketResult result = ReadNextPacketInChunk(chunk_meta, packet);
if (PERFETTO_LIKELY(result == ReadPacketResult::kSucceeded)) {
- *sequence_properties = {trusted_producer_id, trusted_uid, writer_id};
+ *sequence_properties = {trusted_producer_id, trusted_uid, trusted_pid,
+ writer_id};
*previous_packet_on_sequence_dropped = previous_packet_dropped;
return true;
} else if (result == ReadPacketResult::kFailedEmptyPacket) {
@@ -697,7 +676,8 @@ bool TraceBuffer::ReadNextTracePacket(
ReadAheadResult ra_res = ReadAhead(packet);
if (ra_res == ReadAheadResult::kSucceededReturnSlices) {
stats_.set_readaheads_succeeded(stats_.readaheads_succeeded() + 1);
- *sequence_properties = {trusted_producer_id, trusted_uid, writer_id};
+ *sequence_properties = {trusted_producer_id, trusted_uid, trusted_pid,
+ writer_id};
*previous_packet_on_sequence_dropped = previous_packet_dropped;
return true;
}
diff --git a/src/tracing/core/trace_buffer.h b/src/tracing/core/trace_buffer.h
index 5196623c3..415c769d9 100644
--- a/src/tracing/core/trace_buffer.h
+++ b/src/tracing/core/trace_buffer.h
@@ -158,6 +158,7 @@ class TraceBuffer {
struct PacketSequenceProperties {
ProducerID producer_id_trusted;
uid_t producer_uid_trusted;
+ pid_t producer_pid_trusted;
WriterID writer_id;
};
@@ -190,6 +191,7 @@ class TraceBuffer {
// TODO(eseckler): Pass in a PacketStreamProperties instead of individual IDs.
void CopyChunkUntrusted(ProducerID producer_id_trusted,
uid_t producer_uid_trusted,
+ pid_t producer_pid_trusted,
WriterID writer_id,
ChunkID chunk_id,
uint16_t num_fragments,
@@ -377,8 +379,17 @@ class TraceBuffer {
kLastReadPacketSkipped = 1 << 1
};
- ChunkMeta(ChunkRecord* r, uint16_t p, bool complete, uint8_t f, uid_t u)
- : chunk_record{r}, trusted_uid{u}, flags{f}, num_fragments{p} {
+ ChunkMeta(ChunkRecord* r,
+ uint16_t p,
+ bool complete,
+ uint8_t f,
+ uid_t u,
+ pid_t pid)
+ : chunk_record{r},
+ trusted_uid{u},
+ trusted_pid(pid),
+ flags{f},
+ num_fragments{p} {
if (complete)
index_flags = kComplete;
}
@@ -407,6 +418,7 @@ class TraceBuffer {
ChunkRecord* const chunk_record; // Addr of ChunkRecord within |data_|.
const uid_t trusted_uid; // uid of the producer.
+ const pid_t trusted_pid; // pid of the producer.
// Flags set by TraceBuffer to track the state of the chunk in the index.
uint8_t index_flags = 0;
diff --git a/src/tracing/core/trace_buffer_unittest.cc b/src/tracing/core/trace_buffer_unittest.cc
index a7bf27a68..dbba1e94a 100644
--- a/src/tracing/core/trace_buffer_unittest.cc
+++ b/src/tracing/core/trace_buffer_unittest.cc
@@ -985,8 +985,9 @@ TEST_F(TraceBufferTest, Malicious_ZeroSizedChunk) {
uint8_t valid_ptr = 0;
trace_buffer()->CopyChunkUntrusted(
- ProducerID(1), uid_t(0), WriterID(1), ChunkID(1), 1 /* num packets */,
- 0 /* flags */, true /* chunk_complete */, &valid_ptr, sizeof(valid_ptr));
+ ProducerID(1), uid_t(0), pid_t(0), WriterID(1), ChunkID(1),
+ 1 /* num packets */, 0 /* flags */, true /* chunk_complete */, &valid_ptr,
+ sizeof(valid_ptr));
CreateChunk(ProducerID(1), WriterID(1), ChunkID(2))
.AddPacket(32, 'b')
@@ -1090,8 +1091,9 @@ TEST_F(TraceBufferTest, Malicious_VarintHeaderTooBig) {
chunk.insert(chunk.end(), 128 - sizeof(ChunkRecord), 0xff);
chunk.back() = 0x7f;
trace_buffer()->CopyChunkUntrusted(
- ProducerID(4), uid_t(0), WriterID(1), ChunkID(1), 1 /* num packets */,
- 0 /* flags*/, true /* chunk_complete */, chunk.data(), chunk.size());
+ ProducerID(4), uid_t(0), pid_t(0), WriterID(1), ChunkID(1),
+ 1 /* num packets */, 0 /* flags*/, true /* chunk_complete */,
+ chunk.data(), chunk.size());
// Add a valid chunk.
CreateChunk(ProducerID(1), WriterID(1), ChunkID(1))
@@ -1115,8 +1117,9 @@ TEST_F(TraceBufferTest, Malicious_JumboVarint) {
chunk.back() = 0x7f;
for (int i = 0; i < 3; i++) {
trace_buffer()->CopyChunkUntrusted(
- ProducerID(1), uid_t(0), WriterID(1), ChunkID(1), 1 /* num packets */,
- 0 /* flags */, true /* chunk_complete */, chunk.data(), chunk.size());
+ ProducerID(1), uid_t(0), pid_t(0), WriterID(1), ChunkID(1),
+ 1 /* num packets */, 0 /* flags */, true /* chunk_complete */,
+ chunk.data(), chunk.size());
}
trace_buffer()->BeginRead();
diff --git a/src/tracing/core/tracing_service_impl.cc b/src/tracing/core/tracing_service_impl.cc
index 3a4c2a97b..807b955d8 100644
--- a/src/tracing/core/tracing_service_impl.cc
+++ b/src/tracing/core/tracing_service_impl.cc
@@ -20,9 +20,10 @@
#include "perfetto/tracing/core/forward_decls.h"
#include <errno.h>
-#include <inttypes.h>
#include <limits.h>
#include <string.h>
+
+#include <cinttypes>
#include <regex>
#include <unordered_set>
@@ -33,13 +34,11 @@
#include <unistd.h>
#endif
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-#include <sys/system_properties.h>
-#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
+ PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
#include "src/android_internal/lazy_library_loader.h" // nogncheck
#include "src/android_internal/tracing_service_proxy.h" // nogncheck
-#endif // PERFETTO_ANDROID_BUILD
-#endif // PERFETTO_OS_ANDROID
+#endif
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
@@ -53,11 +52,13 @@
#include "perfetto/base/build_config.h"
#include "perfetto/base/status.h"
#include "perfetto/base/task_runner.h"
+#include "perfetto/ext/base/android_utils.h"
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/metatrace.h"
#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/temp_file.h"
#include "perfetto/ext/base/utils.h"
+#include "perfetto/ext/base/uuid.h"
#include "perfetto/ext/base/version.h"
#include "perfetto/ext/base/watchdog.h"
#include "perfetto/ext/tracing/core/basic_types.h"
@@ -286,6 +287,29 @@ bool ShouldLogEvent(const TraceConfig& cfg) {
PERFETTO_FATAL("For GCC");
}
+// Appends `data` (which has `size` bytes), to `*packet`. Splits the data in
+// slices no larger than `max_slice_size`.
+void AppendOwnedSlicesToPacket(std::unique_ptr<uint8_t[]> data,
+ size_t size,
+ size_t max_slice_size,
+ perfetto::TracePacket* packet) {
+ if (size <= max_slice_size) {
+ packet->AddSlice(Slice::TakeOwnership(std::move(data), size));
+ return;
+ }
+ uint8_t* src_ptr = data.get();
+ for (size_t size_left = size; size_left > 0;) {
+ const size_t slice_size = std::min(size_left, max_slice_size);
+
+ Slice slice = Slice::Allocate(slice_size);
+ memcpy(slice.own_data(), src_ptr, slice_size);
+ packet->AddSlice(std::move(slice));
+
+ src_ptr += slice_size;
+ size_left -= slice_size;
+ }
+}
+
} // namespace
// These constants instead are defined in the header because are used by tests.
@@ -334,6 +358,7 @@ TracingServiceImpl::~TracingServiceImpl() {
std::unique_ptr<TracingService::ProducerEndpoint>
TracingServiceImpl::ConnectProducer(Producer* producer,
uid_t uid,
+ pid_t pid,
const std::string& producer_name,
size_t shared_memory_size_hint_bytes,
bool in_process,
@@ -354,8 +379,8 @@ TracingServiceImpl::ConnectProducer(Producer* producer,
return nullptr;
}
const ProducerID id = GetNextProducerID();
- PERFETTO_DLOG("Producer %" PRIu16 " connected", id);
-
+ PERFETTO_DLOG("Producer %" PRIu16 " connected, uid=%d", id,
+ static_cast<int>(uid));
bool smb_scraping_enabled = smb_scraping_enabled_;
switch (smb_scraping_mode) {
case ProducerSMBScrapingMode::kDefault:
@@ -369,7 +394,7 @@ TracingServiceImpl::ConnectProducer(Producer* producer,
}
std::unique_ptr<ProducerEndpointImpl> endpoint(new ProducerEndpointImpl(
- id, uid, this, task_runner_, producer, producer_name, sdk_version,
+ id, uid, pid, this, task_runner_, producer, producer_name, sdk_version,
in_process, smb_scraping_enabled));
auto it_and_inserted = producers_.emplace(id, endpoint.get());
PERFETTO_DCHECK(it_and_inserted.second);
@@ -600,9 +625,10 @@ base::Status TracingServiceImpl::EnableTracing(ConsumerEndpointImpl* consumer,
cfg.write_into_file()) {
// We don't support this usecase because there are subtle assumptions which
// break around TracingServiceEvents and windowed sorting (i.e. if we don't
- // drain the events in ReadBuffers because we are waiting for STOP_TRACING,
- // we can end up queueing up a lot of TracingServiceEvents and emitting them
- // wildy out of order breaking windowed sorting in trace processor).
+ // drain the events in ReadBuffersIntoFile because we are waiting for
+ // STOP_TRACING, we can end up queueing up a lot of TracingServiceEvents and
+ // emitting them wildy out of order breaking windowed sorting in trace
+ // processor).
MaybeLogUploadEvent(
cfg, PerfettoStatsdAtom::kTracedEnableTracingStopTracingWriteIntoFile);
return PERFETTO_SVC_ERR(
@@ -653,6 +679,21 @@ base::Status TracingServiceImpl::EnableTracing(ConsumerEndpointImpl* consumer,
return PERFETTO_SVC_ERR("Too many buffers configured (%d)",
cfg.buffers_size());
}
+ // Check that the config specifies all buffers for its data sources. This
+ // is also checked in SetupDataSource, but it is simpler to return a proper
+ // error to the consumer from here (and there will be less state to undo).
+ for (const TraceConfig::DataSource& cfg_data_source : cfg.data_sources()) {
+ size_t num_buffers = static_cast<size_t>(cfg.buffers_size());
+ size_t target_buffer = cfg_data_source.config().target_buffer();
+ if (target_buffer >= num_buffers) {
+ MaybeLogUploadEvent(
+ cfg, PerfettoStatsdAtom::kTracedEnableTracingOobTargetBuffer);
+ return PERFETTO_SVC_ERR(
+ "Data source \"%s\" specified an out of bounds target_buffer (%zu >= "
+ "%zu)",
+ cfg_data_source.config().name().c_str(), target_buffer, num_buffers);
+ }
+ }
if (!cfg.unique_session_name().empty()) {
const std::string& name = cfg.unique_session_name();
@@ -1134,7 +1175,7 @@ base::Status TracingServiceImpl::StartTracing(TracingSessionID tsid) {
task_runner_->PostDelayedTask(
[weak_this, tsid] {
if (weak_this)
- weak_this->ReadBuffers(tsid, nullptr);
+ weak_this->ReadBuffersIntoFile(tsid);
},
tracing_session->delay_to_next_write_period_ms());
}
@@ -1388,12 +1429,17 @@ void TracingServiceImpl::ActivateTriggers(
trigger_name.c_str());
base::Hash hash;
hash.Update(trigger_name.c_str(), trigger_name.size());
+ std::string triggered_session_name;
+ base::Uuid triggered_session_uuid;
+ TracingSessionID triggered_session_id = 0;
+ int trigger_mode = 0;
uint64_t trigger_name_hash = hash.digest();
size_t count_in_window =
PurgeExpiredAndCountTriggerInWindow(now_ns, trigger_name_hash);
- bool trigger_applied = false;
+ bool trigger_matched = false;
+ bool trigger_activated = false;
for (auto& id_and_tracing_session : tracing_sessions_) {
auto& tracing_session = id_and_tracing_session.second;
TracingSessionID tsid = id_and_tracing_session.first;
@@ -1439,7 +1485,14 @@ void TracingServiceImpl::ActivateTriggers(
trigger_name);
continue;
}
- trigger_applied = true;
+ trigger_matched = true;
+ triggered_session_id = tracing_session.id;
+ triggered_session_name = tracing_session.config.unique_session_name();
+ triggered_session_uuid.set_lsb_msb(
+ tracing_session.config.trace_uuid_lsb(),
+ tracing_session.config.trace_uuid_msb());
+ trigger_mode = static_cast<int>(
+ tracing_session.config.trigger_config().trigger_mode());
const bool triggers_already_received =
!tracing_session.received_triggers.empty();
@@ -1456,9 +1509,7 @@ void TracingServiceImpl::ActivateTriggers(
if (tracing_session.state != TracingSession::CONFIGURED)
break;
- PERFETTO_DLOG("Triggering '%s' on tracing session %" PRIu64
- " with duration of %" PRIu32 "ms.",
- iter->name().c_str(), tsid, iter->stop_delay_ms());
+ trigger_activated = true;
MaybeLogUploadEvent(tracing_session.config,
PerfettoStatsdAtom::kTracedTriggerStartTracing,
iter->name());
@@ -1477,9 +1528,7 @@ void TracingServiceImpl::ActivateTriggers(
if (triggers_already_received)
break;
- PERFETTO_DLOG("Triggering '%s' on tracing session %" PRIu64
- " with duration of %" PRIu32 "ms.",
- iter->name().c_str(), tsid, iter->stop_delay_ms());
+ trigger_activated = true;
MaybeLogUploadEvent(tracing_session.config,
PerfettoStatsdAtom::kTracedTriggerStopTracing,
iter->name());
@@ -1504,10 +1553,21 @@ void TracingServiceImpl::ActivateTriggers(
}
} // for (.. : tracing_sessions_)
- if (trigger_applied) {
+ if (trigger_matched) {
trigger_history_.emplace_back(TriggerHistory{now_ns, trigger_name_hash});
}
- }
+
+ if (trigger_activated) {
+ // Log only the trigger that actually caused a trace stop/start, don't log
+ // the follow-up ones, even if they matched.
+ PERFETTO_LOG(
+ "Trace trigger activated: trigger_name=\"%s\" trigger_mode=%d "
+ "trace_name=\"%s\" trace_uuid=\"%s\" tsid=%" PRIu64,
+ trigger_name.c_str(), trigger_mode, triggered_session_name.c_str(),
+ triggered_session_uuid.ToPrettyString().c_str(),
+ triggered_session_id);
+ }
+ } // for (trigger_name : triggers)
}
// Always invoked kDataSourceStopTimeoutMs after DisableTracing(). In nominal
@@ -1554,7 +1614,7 @@ void TracingServiceImpl::DisableTracingNotifyConsumerAndFlushFile(
if (tracing_session->write_into_file) {
tracing_session->write_period_ms = 0;
- ReadBuffers(tracing_session->id, nullptr);
+ ReadBuffersIntoFile(tracing_session->id);
}
if (tracing_session->on_disable_callback_for_bugreport) {
@@ -1589,6 +1649,13 @@ void TracingServiceImpl::Flush(TracingSessionID tsid,
return;
}
+ if (tracing_session->state != TracingSession::STARTED) {
+ PERFETTO_ELOG("Flush() called, but tracing has not been started");
+ callback(false);
+ return;
+ }
+
+ ++tracing_session->flushes_requested;
FlushRequestID flush_request_id = ++last_flush_request_id_;
PendingFlush& pending_flush =
tracing_session->pending_flushes
@@ -1667,7 +1734,6 @@ void TracingServiceImpl::OnFlushTimeout(TracingSessionID tsid,
// If there were no producers to flush, consider it a success.
bool success = it->second.producers.empty();
-
auto callback = std::move(it->second.callback);
tracing_session->pending_flushes.erase(it);
CompleteFlush(tsid, std::move(callback), success);
@@ -1691,6 +1757,9 @@ void TracingServiceImpl::CompleteFlush(TracingSessionID tsid,
tracing_session,
protos::pbzero::TracingServiceEvent::kAllDataSourcesFlushedFieldNumber,
true /* snapshot_clocks */);
+
+ tracing_session->flushes_succeeded += success ? 1 : 0;
+ tracing_session->flushes_failed += success ? 0 : 1;
callback(success);
}
@@ -1804,9 +1873,9 @@ void TracingServiceImpl::ScrapeSharedMemoryBuffers(
chunk.header()->chunk_id.load(std::memory_order_relaxed);
CopyProducerPageIntoLogBuffer(
- producer->id_, producer->uid_, writer_id, chunk_id, *target_buffer_id,
- packet_count, flags, chunk_complete, chunk.payload_begin(),
- chunk.payload_size());
+ producer->id_, producer->uid_, producer->pid_, writer_id, chunk_id,
+ *target_buffer_id, packet_count, flags, chunk_complete,
+ chunk.payload_begin(), chunk.payload_size());
}
}
}
@@ -1822,6 +1891,8 @@ void TracingServiceImpl::FlushAndDisableTracing(TracingSessionID tsid) {
if (!weak_this)
return;
TracingSession* session = weak_this->GetTracingSession(tsid);
+ session->final_flush_outcome = success ? TraceStats::FINAL_FLUSH_SUCCEEDED
+ : TraceStats::FINAL_FLUSH_FAILED;
if (session->consumer_maybe_null) {
// If the consumer is still attached, just disable the session but give it
// a chance to read the contents.
@@ -1895,8 +1966,9 @@ void TracingServiceImpl::PeriodicClearIncrementalStateTask(
for (const auto& kv : tracing_session->data_source_instances) {
ProducerID producer_id = kv.first;
const DataSourceInstance& data_source = kv.second;
- if (data_source.handles_incremental_state_clear)
+ if (data_source.handles_incremental_state_clear) {
clear_map[producer_id].push_back(data_source.instance_id);
+ }
}
for (const auto& kv : clear_map) {
@@ -1911,42 +1983,19 @@ void TracingServiceImpl::PeriodicClearIncrementalStateTask(
}
}
-// Note: when this is called to write into a file passed when starting tracing
-// |consumer| will be == nullptr (as opposite to the case of a consumer asking
-// to send the trace data back over IPC).
-bool TracingServiceImpl::ReadBuffers(TracingSessionID tsid,
- ConsumerEndpointImpl* consumer) {
+bool TracingServiceImpl::ReadBuffersIntoConsumer(
+ TracingSessionID tsid,
+ ConsumerEndpointImpl* consumer) {
+ PERFETTO_DCHECK(consumer);
PERFETTO_DCHECK_THREAD(thread_checker_);
TracingSession* tracing_session = GetTracingSession(tsid);
if (!tracing_session) {
- // This will be hit systematically from the PostDelayedTask when directly
- // writing into the file (in which case consumer == nullptr). Suppress the
- // log in this case as it's just spam.
- if (consumer) {
- PERFETTO_DLOG("Cannot ReadBuffers(): no tracing session is active");
- }
- return false;
- }
-
- // When a tracing session is waiting for a trigger it is considered empty. If
- // a tracing session finishes and moves into DISABLED without ever receiving a
- // trigger the trace should never return any data. This includes the synthetic
- // packets like TraceConfig and Clock snapshots. So we bail out early and let
- // the consumer know there is no data.
- if (!tracing_session->config.trigger_config().triggers().empty() &&
- tracing_session->received_triggers.empty() &&
- !tracing_session->seized_for_bugreport) {
PERFETTO_DLOG(
- "ReadBuffers(): tracing session has not received a trigger yet.");
+ "Cannot ReadBuffersIntoConsumer(): no tracing session is active");
return false;
}
- // This can happen if the file is closed by a previous task because it reaches
- // |max_file_size_bytes|.
- if (!tracing_session->write_into_file && !consumer)
- return false;
-
- if (tracing_session->write_into_file && consumer) {
+ if (tracing_session->write_into_file) {
// If the consumer enabled tracing and asked to save the contents into the
// passed file makes little sense to also try to read the buffers over IPC,
// as that would just steal data from the periodic draining task.
@@ -1954,14 +2003,12 @@ bool TracingServiceImpl::ReadBuffers(TracingSessionID tsid,
return false;
}
- std::vector<TracePacket> packets;
- packets.reserve(1024); // Just an educated guess to avoid trivial expansions.
-
// If a bugreport request happened and the trace was stolen for that, give
// an empty trace with a clear signal to the consumer. This deals only with
// the case of readback-from-IPC. A similar code-path deals with the
// write_into_file case in MaybeSaveTraceForBugreport().
- if (tracing_session->seized_for_bugreport && consumer) {
+ if (tracing_session->seized_for_bugreport) {
+ std::vector<TracePacket> packets;
if (!tracing_session->config.builtin_data_sources()
.disable_service_events()) {
EmitSeizedForBugreportLifecycleEvent(&packets);
@@ -1971,6 +2018,121 @@ bool TracingServiceImpl::ReadBuffers(TracingSessionID tsid,
return true;
}
+ if (IsWaitingForTrigger(tracing_session))
+ return false;
+
+ // This is a rough threshold to determine how much to read from the buffer in
+ // each task. This is to avoid executing a single huge sending task for too
+ // long and risk to hit the watchdog. This is *not* an upper bound: we just
+ // stop accumulating new packets and PostTask *after* we cross this threshold.
+ // This constant essentially balances the PostTask and IPC overhead vs the
+ // responsiveness of the service. An extremely small value will cause one IPC
+ // and one PostTask for each slice but will keep the service extremely
+ // responsive. An extremely large value will batch the send for the full
+ // buffer in one large task, will hit the blocking send() once the socket
+ // buffers are full and hang the service for a bit (until the consumer
+ // catches up).
+ static constexpr size_t kApproxBytesPerTask = 32768;
+ bool has_more;
+ std::vector<TracePacket> packets =
+ ReadBuffers(tracing_session, kApproxBytesPerTask, &has_more);
+
+ if (has_more) {
+ auto weak_consumer = consumer->weak_ptr_factory_.GetWeakPtr();
+ auto weak_this = weak_ptr_factory_.GetWeakPtr();
+ task_runner_->PostTask([weak_this, weak_consumer, tsid] {
+ if (!weak_this || !weak_consumer)
+ return;
+ weak_this->ReadBuffersIntoConsumer(tsid, weak_consumer.get());
+ });
+ }
+
+ // Keep this as tail call, just in case the consumer re-enters.
+ consumer->consumer_->OnTraceData(std::move(packets), has_more);
+ return true;
+}
+
+bool TracingServiceImpl::ReadBuffersIntoFile(TracingSessionID tsid) {
+ PERFETTO_DCHECK_THREAD(thread_checker_);
+ TracingSession* tracing_session = GetTracingSession(tsid);
+ if (!tracing_session) {
+ // This will be hit systematically from the PostDelayedTask. Avoid logging,
+ // it would be just spam.
+ return false;
+ }
+
+ // This can happen if the file is closed by a previous task because it reaches
+ // |max_file_size_bytes|.
+ if (!tracing_session->write_into_file)
+ return false;
+
+ if (!tracing_session->seized_for_bugreport &&
+ IsWaitingForTrigger(tracing_session))
+ return false;
+
+ // ReadBuffers() can allocate memory internally, for filtering. By limiting
+ // the data that ReadBuffers() reads to kWriteIntoChunksSize per iteration,
+ // we limit the amount of memory used on each iteration.
+ //
+ // It would be tempting to split this into multiple tasks like in
+ // ReadBuffersIntoConsumer, but that's not currently possible.
+ // ReadBuffersIntoFile has to read the whole available data before returning,
+ // to support the disable_immediately=true code paths.
+ bool has_more = true;
+ bool stop_writing_into_file = false;
+ do {
+ std::vector<TracePacket> packets =
+ ReadBuffers(tracing_session, kWriteIntoFileChunkSize, &has_more);
+
+ stop_writing_into_file = WriteIntoFile(tracing_session, std::move(packets));
+ } while (has_more && !stop_writing_into_file);
+
+ if (stop_writing_into_file || tracing_session->write_period_ms == 0) {
+ // Ensure all data was written to the file before we close it.
+ base::FlushFile(tracing_session->write_into_file.get());
+ tracing_session->write_into_file.reset();
+ tracing_session->write_period_ms = 0;
+ if (tracing_session->state == TracingSession::STARTED)
+ DisableTracing(tsid);
+ return true;
+ }
+
+ auto weak_this = weak_ptr_factory_.GetWeakPtr();
+ task_runner_->PostDelayedTask(
+ [weak_this, tsid] {
+ if (weak_this)
+ weak_this->ReadBuffersIntoFile(tsid);
+ },
+ tracing_session->delay_to_next_write_period_ms());
+ return true;
+}
+
+bool TracingServiceImpl::IsWaitingForTrigger(TracingSession* tracing_session) {
+ // When a tracing session is waiting for a trigger, it is considered empty. If
+ // a tracing session finishes and moves into DISABLED without ever receiving a
+ // trigger, the trace should never return any data. This includes the
+ // synthetic packets like TraceConfig and Clock snapshots. So we bail out
+ // early and let the consumer know there is no data.
+ if (!tracing_session->config.trigger_config().triggers().empty() &&
+ tracing_session->received_triggers.empty()) {
+ PERFETTO_DLOG(
+ "ReadBuffers(): tracing session has not received a trigger yet.");
+ return true;
+ }
+ return false;
+}
+
+std::vector<TracePacket> TracingServiceImpl::ReadBuffers(
+ TracingSession* tracing_session,
+ size_t threshold,
+ bool* has_more) {
+ PERFETTO_DCHECK_THREAD(thread_checker_);
+ PERFETTO_DCHECK(tracing_session);
+ *has_more = false;
+
+ std::vector<TracePacket> packets;
+ packets.reserve(1024); // Just an educated guess to avoid trivial expansions.
+
if (!tracing_session->initial_clock_snapshot.empty()) {
EmitClockSnapshot(tracing_session,
std::move(tracing_session->initial_clock_snapshot),
@@ -2002,30 +2164,14 @@ bool TracingServiceImpl::ReadBuffers(TracingSessionID tsid,
EmitLifecycleEvents(tracing_session, &packets);
size_t packets_bytes = 0; // SUM(slice.size() for each slice in |packets|).
- size_t total_slices = 0; // SUM(#slices in |packets|).
// Add up size for packets added by the Maybe* calls above.
for (const TracePacket& packet : packets) {
packets_bytes += packet.size();
- total_slices += packet.slices().size();
}
- // This is a rough threshold to determine how much to read from the buffer in
- // each task. This is to avoid executing a single huge sending task for too
- // long and risk to hit the watchdog. This is *not* an upper bound: we just
- // stop accumulating new packets and PostTask *after* we cross this threshold.
- // This constant essentially balances the PostTask and IPC overhead vs the
- // responsiveness of the service. An extremely small value will cause one IPC
- // and one PostTask for each slice but will keep the service extremely
- // responsive. An extremely large value will batch the send for the full
- // buffer in one large task, will hit the blocking send() once the socket
- // buffers are full and hang the service for a bit (until the consumer
- // catches up).
- static constexpr size_t kApproxBytesPerTask = 32768;
bool did_hit_threshold = false;
- // TODO(primiano): Extend the ReadBuffers API to allow reading only some
- // buffers, not all of them in one go.
for (size_t buf_idx = 0;
buf_idx < tracing_session->num_buffers() && !did_hit_threshold;
buf_idx++) {
@@ -2047,6 +2193,9 @@ bool TracingServiceImpl::ReadBuffers(TracingSessionID tsid,
PERFETTO_DCHECK(sequence_properties.producer_id_trusted != 0);
PERFETTO_DCHECK(sequence_properties.writer_id != 0);
PERFETTO_DCHECK(sequence_properties.producer_uid_trusted != kInvalidUid);
+ // Not checking sequence_properties.producer_pid_trusted: it is
+ // base::kInvalidPid if the platform doesn't support it.
+
PERFETTO_DCHECK(packet.size() > 0);
if (!PacketStreamValidator::Validate(packet.slices())) {
tracing_session->invalid_packets++;
@@ -2071,6 +2220,11 @@ bool TracingServiceImpl::ReadBuffers(TracingSessionID tsid,
tracing_session->GetPacketSequenceID(
sequence_properties.producer_id_trusted,
sequence_properties.writer_id));
+ if (sequence_properties.producer_pid_trusted != base::kInvalidPid) {
+ // Not supported on all platforms.
+ trusted_packet->set_trusted_pid(
+ static_cast<int32_t>(sequence_properties.producer_pid_trusted));
+ }
if (previous_packet_dropped)
trusted_packet->set_previous_packet_dropped(previous_packet_dropped);
slice.size = trusted_packet.Finalize();
@@ -2078,18 +2232,19 @@ bool TracingServiceImpl::ReadBuffers(TracingSessionID tsid,
// Append the packet (inclusive of the trusted uid) to |packets|.
packets_bytes += packet.size();
- total_slices += packet.slices().size();
- did_hit_threshold = packets_bytes >= kApproxBytesPerTask &&
- !tracing_session->write_into_file;
+ did_hit_threshold = packets_bytes >= threshold;
packets.emplace_back(std::move(packet));
} // for(packets...)
} // for(buffers...)
- const bool has_more = did_hit_threshold;
+ *has_more = did_hit_threshold;
- size_t prev_packets_size = packets.size();
- if (!tracing_session->config.builtin_data_sources()
- .disable_service_events()) {
+ // Only emit the "read complete" lifetime event when there is no more trace
+ // data available to read. These events are used as safe points to limit
+ // sorting in trace processor: the code shouldn't emit the event unless the
+ // buffers are empty.
+ if (!*has_more && !tracing_session->config.builtin_data_sources()
+ .disable_service_events()) {
// We don't bother snapshotting clocks here because we wouldn't be able to
// emit it and we shouldn't have significant drift from the last snapshot in
// any case.
@@ -2105,156 +2260,134 @@ bool TracingServiceImpl::ReadBuffers(TracingSessionID tsid,
// reflected in the emitted stats. This is particularly important for use
// cases where ReadBuffers is only ever called after the tracing session is
// stopped.
- if (!has_more && tracing_session->should_emit_stats) {
+ if (!*has_more && tracing_session->should_emit_stats) {
EmitStats(tracing_session, &packets);
tracing_session->should_emit_stats = false;
}
- // Add sizes of packets emitted by the EmitLifecycleEvents + EmitStats.
- for (size_t i = prev_packets_size; i < packets.size(); ++i) {
- packets_bytes += packets[i].size();
- total_slices += packets[i].slices().size();
+ MaybeFilterPackets(tracing_session, &packets);
+
+ if (!*has_more) {
+ // We've observed some extremely high memory usage by scudo after
+ // MaybeFilterPackets in the past. The original bug (b/195145848) is fixed
+ // now, but this code asks scudo to release memory just in case.
+ base::MaybeReleaseAllocatorMemToOS();
}
- // +-------------------------------------------------------------------------+
- // | NO MORE CHANGES TO |packets| AFTER THIS POINT. |
- // +-------------------------------------------------------------------------+
+ return packets;
+}
+void TracingServiceImpl::MaybeFilterPackets(TracingSession* tracing_session,
+ std::vector<TracePacket>* packets) {
// If the tracing session specified a filter, run all packets through the
// filter and replace them with the filter results.
// The process below mantains the cardinality of input packets. Even if an
// entire packet is filtered out, we emit a zero-sized TracePacket proto. That
// makes debugging and reasoning about the trace stats easier.
// This place swaps the contents of each |packets| entry in place.
- if (tracing_session->trace_filter) {
- auto& trace_filter = *tracing_session->trace_filter;
- // The filter root shoud be reset from protos.Trace to protos.TracePacket
- // by the earlier call to SetFilterRoot() in EnableTracing().
- PERFETTO_DCHECK(trace_filter.root_msg_index() != 0);
- std::vector<protozero::MessageFilter::InputSlice> filter_input;
- for (auto it = packets.begin(); it != packets.end(); ++it) {
- const auto& packet_slices = it->slices();
- filter_input.clear();
- filter_input.resize(packet_slices.size());
- ++tracing_session->filter_input_packets;
- tracing_session->filter_input_bytes += it->size();
- for (size_t i = 0; i < packet_slices.size(); ++i)
- filter_input[i] = {packet_slices[i].start, packet_slices[i].size};
- auto filtered_packet = trace_filter.FilterMessageFragments(
- &filter_input[0], filter_input.size());
-
- // Replace the packet in-place with the filtered one (unless failed).
- *it = TracePacket();
- if (filtered_packet.error) {
- ++tracing_session->filter_errors;
- PERFETTO_DLOG("Trace packet filtering failed @ packet %" PRIu64,
- tracing_session->filter_input_packets);
- continue;
- }
- tracing_session->filter_output_bytes += filtered_packet.size;
- it->AddSlice(Slice::TakeOwnership(std::move(filtered_packet.data),
- filtered_packet.size));
-
- } // for (packet)
- } // if (trace_filter)
-
- // If the caller asked us to write into a file by setting
- // |write_into_file| == true in the trace config, drain the packets read
- // (if any) into the given file descriptor.
- if (tracing_session->write_into_file) {
- const uint64_t max_size = tracing_session->max_file_size_bytes
- ? tracing_session->max_file_size_bytes
- : std::numeric_limits<size_t>::max();
-
- // When writing into a file, the file should look like a root trace.proto
- // message. Each packet should be prepended with a proto preamble stating
- // its field id (within trace.proto) and size. Hence the addition below.
- const size_t max_iovecs = total_slices + packets.size();
-
- size_t num_iovecs = 0;
- bool stop_writing_into_file = tracing_session->write_period_ms == 0;
- std::unique_ptr<struct iovec[]> iovecs(new struct iovec[max_iovecs]);
- size_t num_iovecs_at_last_packet = 0;
- uint64_t bytes_about_to_be_written = 0;
- for (TracePacket& packet : packets) {
- std::tie(iovecs[num_iovecs].iov_base, iovecs[num_iovecs].iov_len) =
- packet.GetProtoPreamble();
- bytes_about_to_be_written += iovecs[num_iovecs].iov_len;
- num_iovecs++;
- for (const Slice& slice : packet.slices()) {
- // writev() doesn't change the passed pointer. However, struct iovec
- // take a non-const ptr because it's the same struct used by readv().
- // Hence the const_cast here.
- char* start = static_cast<char*>(const_cast<void*>(slice.start));
- bytes_about_to_be_written += slice.size;
- iovecs[num_iovecs++] = {start, slice.size};
- }
-
- if (tracing_session->bytes_written_into_file +
- bytes_about_to_be_written >=
- max_size) {
- stop_writing_into_file = true;
- num_iovecs = num_iovecs_at_last_packet;
- break;
- }
-
- num_iovecs_at_last_packet = num_iovecs;
+ if (!tracing_session->trace_filter) {
+ return;
+ }
+ protozero::MessageFilter& trace_filter = *tracing_session->trace_filter;
+ // The filter root shoud be reset from protos.Trace to protos.TracePacket
+ // by the earlier call to SetFilterRoot() in EnableTracing().
+ PERFETTO_DCHECK(trace_filter.root_msg_index() != 0);
+ std::vector<protozero::MessageFilter::InputSlice> filter_input;
+ for (TracePacket& packet : *packets) {
+ const auto& packet_slices = packet.slices();
+ filter_input.clear();
+ filter_input.resize(packet_slices.size());
+ ++tracing_session->filter_input_packets;
+ tracing_session->filter_input_bytes += packet.size();
+ for (size_t i = 0; i < packet_slices.size(); ++i)
+ filter_input[i] = {packet_slices[i].start, packet_slices[i].size};
+ auto filtered_packet = trace_filter.FilterMessageFragments(
+ &filter_input[0], filter_input.size());
+
+ // Replace the packet in-place with the filtered one (unless failed).
+ packet = TracePacket();
+ if (filtered_packet.error) {
+ ++tracing_session->filter_errors;
+ PERFETTO_DLOG("Trace packet filtering failed @ packet %" PRIu64,
+ tracing_session->filter_input_packets);
+ continue;
}
- PERFETTO_DCHECK(num_iovecs <= max_iovecs);
- int fd = *tracing_session->write_into_file;
+ tracing_session->filter_output_bytes += filtered_packet.size;
+ AppendOwnedSlicesToPacket(std::move(filtered_packet.data),
+ filtered_packet.size, kMaxTracePacketSliceSize,
+ &packet);
+ }
+}
- uint64_t total_wr_size = 0;
+bool TracingServiceImpl::WriteIntoFile(TracingSession* tracing_session,
+ std::vector<TracePacket> packets) {
+ if (!tracing_session->write_into_file) {
+ return false;
+ }
+ const uint64_t max_size = tracing_session->max_file_size_bytes
+ ? tracing_session->max_file_size_bytes
+ : std::numeric_limits<size_t>::max();
- // writev() can take at most IOV_MAX entries per call. Batch them.
- constexpr size_t kIOVMax = IOV_MAX;
- for (size_t i = 0; i < num_iovecs; i += kIOVMax) {
- int iov_batch_size = static_cast<int>(std::min(num_iovecs - i, kIOVMax));
- ssize_t wr_size = PERFETTO_EINTR(writev(fd, &iovecs[i], iov_batch_size));
- if (wr_size <= 0) {
- PERFETTO_PLOG("writev() failed");
- stop_writing_into_file = true;
- break;
- }
- total_wr_size += static_cast<size_t>(wr_size);
+ size_t total_slices = 0;
+ for (const TracePacket& packet : packets) {
+ total_slices += packet.slices().size();
+ }
+ // When writing into a file, the file should look like a root trace.proto
+ // message. Each packet should be prepended with a proto preamble stating
+ // its field id (within trace.proto) and size. Hence the addition below.
+ const size_t max_iovecs = total_slices + packets.size();
+
+ size_t num_iovecs = 0;
+ bool stop_writing_into_file = false;
+ std::unique_ptr<struct iovec[]> iovecs(new struct iovec[max_iovecs]);
+ size_t num_iovecs_at_last_packet = 0;
+ uint64_t bytes_about_to_be_written = 0;
+ for (TracePacket& packet : packets) {
+ std::tie(iovecs[num_iovecs].iov_base, iovecs[num_iovecs].iov_len) =
+ packet.GetProtoPreamble();
+ bytes_about_to_be_written += iovecs[num_iovecs].iov_len;
+ num_iovecs++;
+ for (const Slice& slice : packet.slices()) {
+ // writev() doesn't change the passed pointer. However, struct iovec
+ // take a non-const ptr because it's the same struct used by readv().
+ // Hence the const_cast here.
+ char* start = static_cast<char*>(const_cast<void*>(slice.start));
+ bytes_about_to_be_written += slice.size;
+ iovecs[num_iovecs++] = {start, slice.size};
}
- tracing_session->bytes_written_into_file += total_wr_size;
-
- PERFETTO_DLOG("Draining into file, written: %" PRIu64 " KB, stop: %d",
- (total_wr_size + 1023) / 1024, stop_writing_into_file);
- if (stop_writing_into_file) {
- // Ensure all data was written to the file before we close it.
- base::FlushFile(fd);
- tracing_session->write_into_file.reset();
- tracing_session->write_period_ms = 0;
- if (tracing_session->state == TracingSession::STARTED)
- DisableTracing(tsid);
- return true;
+ if (tracing_session->bytes_written_into_file + bytes_about_to_be_written >=
+ max_size) {
+ stop_writing_into_file = true;
+ num_iovecs = num_iovecs_at_last_packet;
+ break;
}
- auto weak_this = weak_ptr_factory_.GetWeakPtr();
- task_runner_->PostDelayedTask(
- [weak_this, tsid] {
- if (weak_this)
- weak_this->ReadBuffers(tsid, nullptr);
- },
- tracing_session->delay_to_next_write_period_ms());
- return true;
- } // if (tracing_session->write_into_file)
+ num_iovecs_at_last_packet = num_iovecs;
+ }
+ PERFETTO_DCHECK(num_iovecs <= max_iovecs);
+ int fd = *tracing_session->write_into_file;
- if (has_more) {
- auto weak_consumer = consumer->weak_ptr_factory_.GetWeakPtr();
- auto weak_this = weak_ptr_factory_.GetWeakPtr();
- task_runner_->PostTask([weak_this, weak_consumer, tsid] {
- if (!weak_this || !weak_consumer)
- return;
- weak_this->ReadBuffers(tsid, weak_consumer.get());
- });
+ uint64_t total_wr_size = 0;
+
+ // writev() can take at most IOV_MAX entries per call. Batch them.
+ constexpr size_t kIOVMax = IOV_MAX;
+ for (size_t i = 0; i < num_iovecs; i += kIOVMax) {
+ int iov_batch_size = static_cast<int>(std::min(num_iovecs - i, kIOVMax));
+ ssize_t wr_size = PERFETTO_EINTR(writev(fd, &iovecs[i], iov_batch_size));
+ if (wr_size <= 0) {
+ PERFETTO_PLOG("writev() failed");
+ stop_writing_into_file = true;
+ break;
+ }
+ total_wr_size += static_cast<size_t>(wr_size);
}
- // Keep this as tail call, just in case the consumer re-enters.
- consumer->consumer_->OnTraceData(std::move(packets), has_more);
- return true;
+ tracing_session->bytes_written_into_file += total_wr_size;
+
+ PERFETTO_DLOG("Draining into file, written: %" PRIu64 " KB, stop: %d",
+ (total_wr_size + 1023) / 1024, stop_writing_into_file);
+ return stop_writing_into_file;
}
void TracingServiceImpl::FreeBuffers(TracingSessionID tsid) {
@@ -2309,17 +2442,10 @@ void TracingServiceImpl::FreeBuffers(TracingSessionID tsid) {
void TracingServiceImpl::RegisterDataSource(ProducerID producer_id,
const DataSourceDescriptor& desc) {
PERFETTO_DCHECK_THREAD(thread_checker_);
- PERFETTO_DLOG("Producer %" PRIu16 " registered data source \"%s\"",
- producer_id, desc.name().c_str());
-
- PERFETTO_DCHECK(!desc.name().empty());
- auto reg_ds = data_sources_.emplace(desc.name(),
- RegisteredDataSource{producer_id, desc});
-
- // If there are existing tracing sessions, we need to check if the new
- // data source is enabled by any of them.
- if (tracing_sessions_.empty())
+ if (desc.name().empty()) {
+ PERFETTO_DLOG("Received RegisterDataSource() with empty name");
return;
+ }
ProducerEndpointImpl* producer = GetProducer(producer_id);
if (!producer) {
@@ -2327,6 +2453,29 @@ void TracingServiceImpl::RegisterDataSource(ProducerID producer_id,
return;
}
+ // Check that the producer doesn't register two data sources with the same ID.
+ // Note that we tolerate |id| == 0 because until Android T / v22 the |id|
+ // field didn't exist.
+ for (const auto& kv : data_sources_) {
+ if (desc.id() && kv.second.producer_id == producer_id &&
+ kv.second.descriptor.id() == desc.id()) {
+ PERFETTO_ELOG(
+ "Failed to register data source \"%s\". A data source with the same "
+ "id %" PRIu64 " (name=\"%s\") is already registered for producer %d",
+ desc.name().c_str(), desc.id(), kv.second.descriptor.name().c_str(),
+ producer_id);
+ return;
+ }
+ }
+
+ PERFETTO_DLOG("Producer %" PRIu16 " registered data source \"%s\"",
+ producer_id, desc.name().c_str());
+
+ auto reg_ds = data_sources_.emplace(desc.name(),
+ RegisteredDataSource{producer_id, desc});
+
+ // If there are existing tracing sessions, we need to check if the new
+ // data source is enabled by any of them.
for (auto& iter : tracing_sessions_) {
TracingSession& tracing_session = iter.second;
if (tracing_session.state != TracingSession::STARTED &&
@@ -2350,7 +2499,38 @@ void TracingServiceImpl::RegisterDataSource(ProducerID producer_id,
if (ds_inst && tracing_session.state == TracingSession::STARTED)
StartDataSourceInstance(producer, &tracing_session, ds_inst);
}
+ } // for(iter : tracing_sessions_)
+}
+
+void TracingServiceImpl::UpdateDataSource(
+ ProducerID producer_id,
+ const DataSourceDescriptor& new_desc) {
+ if (new_desc.id() == 0) {
+ PERFETTO_ELOG("UpdateDataSource() must have a non-zero id");
+ return;
+ }
+
+ // If this producer has already registered a matching descriptor name and id,
+ // just update the descriptor.
+ RegisteredDataSource* data_source = nullptr;
+ auto range = data_sources_.equal_range(new_desc.name());
+ for (auto it = range.first; it != range.second; ++it) {
+ if (it->second.producer_id == producer_id &&
+ it->second.descriptor.id() == new_desc.id()) {
+ data_source = &it->second;
+ break;
+ }
+ }
+
+ if (!data_source) {
+ PERFETTO_ELOG(
+ "UpdateDataSource() failed, could not find an existing data source "
+ "with name=\"%s\" id=%" PRIu64,
+ new_desc.name().c_str(), new_desc.id());
+ return;
}
+
+ data_source->descriptor = new_desc;
}
void TracingServiceImpl::StopDataSourceInstance(ProducerEndpointImpl* producer,
@@ -2563,6 +2743,7 @@ TracingServiceImpl::DataSourceInstance* TracingServiceImpl::SetupDataSource(
void TracingServiceImpl::CopyProducerPageIntoLogBuffer(
ProducerID producer_id_trusted,
uid_t producer_uid_trusted,
+ pid_t producer_pid_trusted,
WriterID writer_id,
ChunkID chunk_id,
BufferID buffer_id,
@@ -2617,9 +2798,10 @@ void TracingServiceImpl::CopyProducerPageIntoLogBuffer(
return;
}
- buf->CopyChunkUntrusted(producer_id_trusted, producer_uid_trusted, writer_id,
- chunk_id, num_fragments, chunk_flags, chunk_complete,
- src, size);
+ buf->CopyChunkUntrusted(producer_id_trusted, producer_uid_trusted,
+ producer_pid_trusted, writer_id, chunk_id,
+ num_fragments, chunk_flags, chunk_complete, src,
+ size);
}
void TracingServiceImpl::ApplyChunkPatches(
@@ -3008,6 +3190,10 @@ TraceStats TracingServiceImpl::GetTraceStats(TracingSession* tracing_session) {
trace_stats.set_chunks_discarded(chunks_discarded_);
trace_stats.set_patches_discarded(patches_discarded_);
trace_stats.set_invalid_packets(tracing_session->invalid_packets);
+ trace_stats.set_flushes_requested(tracing_session->flushes_requested);
+ trace_stats.set_flushes_succeeded(tracing_session->flushes_succeeded);
+ trace_stats.set_flushes_failed(tracing_session->flushes_failed);
+ trace_stats.set_final_flush_outcome(tracing_session->final_flush_outcome);
if (tracing_session->trace_filter) {
auto* filt_stats = trace_stats.mutable_filter_stats();
@@ -3062,12 +3248,20 @@ void TracingServiceImpl::MaybeEmitSystemInfo(
}
#endif // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
- char value[PROP_VALUE_MAX];
- if (__system_property_get("ro.build.fingerprint", value)) {
- info->set_android_build_fingerprint(value);
+ std::string fingerprint_value = base::GetAndroidProp("ro.build.fingerprint");
+ if (!fingerprint_value.empty()) {
+ info->set_android_build_fingerprint(fingerprint_value);
} else {
PERFETTO_ELOG("Unable to read ro.build.fingerprint");
}
+
+ std::string sdk_str_value = base::GetAndroidProp("ro.build.version.sdk");
+ base::Optional<uint64_t> sdk_value = base::StringToUInt64(sdk_str_value);
+ if (sdk_value.has_value()) {
+ info->set_android_sdk_version(*sdk_value);
+ } else {
+ PERFETTO_ELOG("Unable to read ro.build.version.sdk");
+ }
info->set_hz(sysconf(_SC_CLK_TCK));
#endif // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
packet->set_trusted_uid(static_cast<int32_t>(uid_));
@@ -3198,7 +3392,7 @@ bool TracingServiceImpl::MaybeSaveTraceForBugreport(
// If we are stealing a write_into_file session, add a marker that explains
// why the trace has been stolen rather than creating an empty file. This is
// only for write_into_file traces. A similar code path deals with the case
- // of reading-back a seized trace from IPC in ReadBuffers().
+ // of reading-back a seized trace from IPC in ReadBuffersIntoConsumer().
if (!max_session->config.builtin_data_sources().disable_service_events()) {
std::vector<TracePacket> packets;
EmitSeizedForBugreportLifecycleEvent(&packets);
@@ -3343,7 +3537,7 @@ void TracingServiceImpl::ConsumerEndpointImpl::ReadBuffers() {
consumer_->OnTraceData({}, /* has_more = */ false);
return;
}
- if (!service_->ReadBuffers(tracing_session_id_, this)) {
+ if (!service_->ReadBuffersIntoConsumer(tracing_session_id_, this)) {
consumer_->OnTraceData({}, /* has_more = */ false);
}
}
@@ -3508,7 +3702,8 @@ void TracingServiceImpl::ConsumerEndpointImpl::QueryServiceState(
producer->set_id(static_cast<int>(kv.first));
producer->set_name(kv.second->name_);
producer->set_sdk_version(kv.second->sdk_version_);
- producer->set_uid(static_cast<int32_t>(producer->uid()));
+ producer->set_uid(static_cast<int32_t>(kv.second->uid()));
+ producer->set_pid(static_cast<int32_t>(kv.second->pid()));
}
for (const auto& kv : service_->data_sources_) {
@@ -3518,6 +3713,42 @@ void TracingServiceImpl::ConsumerEndpointImpl::QueryServiceState(
data_source->set_producer_id(
static_cast<int>(registered_data_source.producer_id));
}
+
+ svc_state.set_supports_tracing_sessions(true);
+ for (const auto& kv : service_->tracing_sessions_) {
+ const TracingSession& s = kv.second;
+ // List only tracing sessions for the calling UID (or everything for root).
+ if (uid_ != 0 && uid_ != s.consumer_uid)
+ continue;
+ auto* session = svc_state.add_tracing_sessions();
+ session->set_id(s.id);
+ session->set_consumer_uid(static_cast<int>(s.consumer_uid));
+ session->set_duration_ms(s.config.duration_ms());
+ session->set_num_data_sources(
+ static_cast<uint32_t>(s.data_source_instances.size()));
+ session->set_unique_session_name(s.config.unique_session_name());
+ for (const auto& snap_kv : s.initial_clock_snapshot) {
+ if (snap_kv.first == protos::pbzero::BUILTIN_CLOCK_REALTIME)
+ session->set_start_realtime_ns(static_cast<int64_t>(snap_kv.second));
+ }
+ for (const auto& buf : s.config.buffers())
+ session->add_buffer_size_kb(buf.size_kb());
+
+ switch (s.state) {
+ case TracingSession::State::DISABLED:
+ session->set_state("DISABLED");
+ break;
+ case TracingSession::State::CONFIGURED:
+ session->set_state("CONFIGURED");
+ break;
+ case TracingSession::State::STARTED:
+ session->set_state("STARTED");
+ break;
+ case TracingSession::State::DISABLING_WAITING_STOP_ACKS:
+ session->set_state("STOP_WAIT");
+ break;
+ }
+ }
callback(/*success=*/true, svc_state);
}
@@ -3561,6 +3792,7 @@ void TracingServiceImpl::ConsumerEndpointImpl::SaveTraceForBugreport(
TracingServiceImpl::ProducerEndpointImpl::ProducerEndpointImpl(
ProducerID id,
uid_t uid,
+ pid_t pid,
TracingServiceImpl* service,
base::TaskRunner* task_runner,
Producer* producer,
@@ -3570,6 +3802,7 @@ TracingServiceImpl::ProducerEndpointImpl::ProducerEndpointImpl(
bool smb_scraping_enabled)
: id_(id),
uid_(uid),
+ pid_(pid),
service_(service),
task_runner_(task_runner),
producer_(producer),
@@ -3587,14 +3820,15 @@ TracingServiceImpl::ProducerEndpointImpl::~ProducerEndpointImpl() {
void TracingServiceImpl::ProducerEndpointImpl::RegisterDataSource(
const DataSourceDescriptor& desc) {
PERFETTO_DCHECK_THREAD(thread_checker_);
- if (desc.name().empty()) {
- PERFETTO_DLOG("Received RegisterDataSource() with empty name");
- return;
- }
-
service_->RegisterDataSource(id_, desc);
}
+void TracingServiceImpl::ProducerEndpointImpl::UpdateDataSource(
+ const DataSourceDescriptor& desc) {
+ PERFETTO_DCHECK_THREAD(thread_checker_);
+ service_->UpdateDataSource(id_, desc);
+}
+
void TracingServiceImpl::ProducerEndpointImpl::UnregisterDataSource(
const std::string& name) {
PERFETTO_DCHECK_THREAD(thread_checker_);
@@ -3658,7 +3892,8 @@ void TracingServiceImpl::ProducerEndpointImpl::CommitData(
uint8_t chunk_flags = packets.flags;
service_->CopyProducerPageIntoLogBuffer(
- id_, uid_, writer_id, chunk_id, buffer_id, num_fragments, chunk_flags,
+ id_, uid_, pid_, writer_id, chunk_id, buffer_id, num_fragments,
+ chunk_flags,
/*chunk_complete=*/true, chunk.payload_begin(), chunk.payload_size());
// This one has release-store semantics.
@@ -3836,6 +4071,7 @@ void TracingServiceImpl::ProducerEndpointImpl::ClearIncrementalState(
auto weak_this = weak_ptr_factory_.GetWeakPtr();
task_runner_->PostTask([weak_this, data_sources] {
if (weak_this) {
+ base::StringView producer_name(weak_this->name_);
weak_this->producer_->ClearIncrementalState(data_sources.data(),
data_sources.size());
}
diff --git a/src/tracing/core/tracing_service_impl.h b/src/tracing/core/tracing_service_impl.h
index 401aaa1fe..d0df0a641 100644
--- a/src/tracing/core/tracing_service_impl.h
+++ b/src/tracing/core/tracing_service_impl.h
@@ -57,6 +57,12 @@ namespace base {
class TaskRunner;
} // namespace base
+namespace protos {
+namespace gen {
+enum TraceStats_FinalFlushOutcome : int;
+}
+} // namespace protos
+
class Consumer;
class Producer;
class SharedMemory;
@@ -77,12 +83,21 @@ class TracingServiceImpl : public TracingService {
static constexpr uint8_t kSyncMarker[] = {0x82, 0x47, 0x7a, 0x76, 0xb2, 0x8d,
0x42, 0xba, 0x81, 0xdc, 0x33, 0x32,
0x6d, 0x57, 0xa0, 0x79};
+ static constexpr size_t kMaxTracePacketSliceSize =
+ 128 * 1024 - 512; // This is ipc::kIPCBufferSize - 512, see assertion in
+ // tracing_integration_test.cc and b/195065199
+
+ // This is a rough threshold to determine how many bytes to read from the
+ // buffers on each iteration when writing into a file. Since filtering
+ // allocates memory, this limits the amount of memory allocated.
+ static constexpr size_t kWriteIntoFileChunkSize = 1024 * 1024ul;
// The implementation behind the service endpoint exposed to each producer.
class ProducerEndpointImpl : public TracingService::ProducerEndpoint {
public:
ProducerEndpointImpl(ProducerID,
uid_t uid,
+ pid_t pid,
TracingServiceImpl*,
base::TaskRunner*,
Producer*,
@@ -94,6 +109,7 @@ class TracingServiceImpl : public TracingService {
// TracingService::ProducerEndpoint implementation.
void RegisterDataSource(const DataSourceDescriptor&) override;
+ void UpdateDataSource(const DataSourceDescriptor&) override;
void UnregisterDataSource(const std::string& name) override;
void RegisterTraceWriter(uint32_t writer_id,
uint32_t target_buffer) override;
@@ -135,6 +151,7 @@ class TracingServiceImpl : public TracingService {
}
uid_t uid() const { return uid_; }
+ pid_t pid() const { return pid_; }
private:
friend class TracingServiceImpl;
@@ -145,6 +162,7 @@ class TracingServiceImpl : public TracingService {
ProducerID const id_;
const uid_t uid_;
+ const pid_t pid_;
TracingServiceImpl* const service_;
base::TaskRunner* const task_runner_;
Producer* producer_;
@@ -247,9 +265,11 @@ class TracingServiceImpl : public TracingService {
// Called by ProducerEndpointImpl.
void DisconnectProducer(ProducerID);
void RegisterDataSource(ProducerID, const DataSourceDescriptor&);
+ void UpdateDataSource(ProducerID, const DataSourceDescriptor&);
void UnregisterDataSource(ProducerID, const std::string& name);
void CopyProducerPageIntoLogBuffer(ProducerID,
uid_t,
+ pid_t,
WriterID,
ChunkID,
BufferID,
@@ -280,13 +300,37 @@ class TracingServiceImpl : public TracingService {
uint32_t timeout_ms,
ConsumerEndpoint::FlushCallback);
void FlushAndDisableTracing(TracingSessionID);
- bool ReadBuffers(TracingSessionID, ConsumerEndpointImpl*);
+
+ // Starts reading the internal tracing buffers from the tracing session `tsid`
+ // and sends them to `*consumer` (which must be != nullptr).
+ //
+ // Only reads a limited amount of data in one call. If there's more data,
+ // immediately schedules itself on a PostTask.
+ //
+ // Returns false in case of error.
+ bool ReadBuffersIntoConsumer(TracingSessionID tsid,
+ ConsumerEndpointImpl* consumer);
+
+ // Reads all the tracing buffers from the tracing session `tsid` and writes
+ // them into the associated file.
+ //
+ // Reads all the data in the buffers (or until the file is full) before
+ // returning.
+ //
+ // If the tracing session write_period_ms is 0, the file is full or there has
+ // been an error, flushes the file and closes it. Otherwise, schedules itself
+ // to be executed after write_period_ms.
+ //
+ // Returns false in case of error.
+ bool ReadBuffersIntoFile(TracingSessionID);
+
void FreeBuffers(TracingSessionID);
// Service implementation.
std::unique_ptr<TracingService::ProducerEndpoint> ConnectProducer(
Producer*,
uid_t uid,
+ pid_t pid,
const std::string& producer_name,
size_t shared_memory_size_hint_bytes = 0,
bool in_process = false,
@@ -520,6 +564,14 @@ class TracingServiceImpl : public TracingService {
// Packets that failed validation of the TrustedPacket.
uint64_t invalid_packets = 0;
+ // Flush() stats. See comments in trace_stats.proto for more.
+ uint64_t flushes_requested = 0;
+ uint64_t flushes_succeeded = 0;
+ uint64_t flushes_failed = 0;
+
+ // Outcome of the final Flush() done by FlushAndDisableTracing().
+ protos::gen::TraceStats_FinalFlushOutcome final_flush_outcome{};
+
// Set to true on the first call to MaybeNotifyAllDataSourcesStarted().
bool did_notify_all_data_source_started = false;
@@ -649,6 +701,33 @@ class TracingServiceImpl : public TracingService {
void ScrapeSharedMemoryBuffers(TracingSession*, ProducerEndpointImpl*);
void PeriodicClearIncrementalStateTask(TracingSessionID, bool post_next_only);
TraceBuffer* GetBufferByID(BufferID);
+
+ // Returns true if `*tracing_session` is waiting for a trigger that hasn't
+ // happened.
+ static bool IsWaitingForTrigger(TracingSession* tracing_session);
+
+ // Reads the buffers from `*tracing_session` and returns them (along with some
+ // metadata packets).
+ //
+ // The function stops when the cumulative size of the return packets exceeds
+ // `threshold` (so it's not a strict upper bound) and sets `*has_more` to
+ // true, or when there are no more packets (and sets `*has_more` to false).
+ std::vector<TracePacket> ReadBuffers(TracingSession* tracing_session,
+ size_t threshold,
+ bool* has_more);
+
+ // If `*tracing_session` has a filter, applies it to `*packets`. Doesn't
+ // change the number of `*packets`, only their content.
+ void MaybeFilterPackets(TracingSession* tracing_session,
+ std::vector<TracePacket>* packets);
+
+ // If `*tracing_session` is configured to write into a file, writes `packets`
+ // into the file.
+ //
+ // Returns true if the file should be closed (because it's full or there has
+ // been an error), false otherwise.
+ bool WriteIntoFile(TracingSession* tracing_session,
+ std::vector<TracePacket> packets);
void OnStartTriggersTimeout(TracingSessionID tsid);
void MaybeLogUploadEvent(const TraceConfig&,
PerfettoStatsdAtom atom,
diff --git a/src/tracing/core/tracing_service_impl_unittest.cc b/src/tracing/core/tracing_service_impl_unittest.cc
index bd4062af9..00b7a3a16 100644
--- a/src/tracing/core/tracing_service_impl_unittest.cc
+++ b/src/tracing/core/tracing_service_impl_unittest.cc
@@ -30,6 +30,7 @@
#include "perfetto/tracing/core/data_source_config.h"
#include "perfetto/tracing/core/data_source_descriptor.h"
#include "src/base/test/test_task_runner.h"
+#include "src/protozero/filtering/filter_bytecode_generator.h"
#include "src/tracing/core/shared_memory_arbiter_impl.h"
#include "src/tracing/core/trace_writer_impl.h"
#include "src/tracing/test/mock_consumer.h"
@@ -37,6 +38,7 @@
#include "src/tracing/test/test_shared_memory.h"
#include "test/gtest_and_gmock.h"
+#include "protos/perfetto/common/track_event_descriptor.gen.h"
#include "protos/perfetto/trace/perfetto/tracing_service_event.gen.h"
#include "protos/perfetto/trace/test_event.gen.h"
#include "protos/perfetto/trace/test_event.pbzero.h"
@@ -1415,9 +1417,9 @@ TEST_F(TracingServiceImplTest, LockdownMode) {
producer->WaitForDataSourceStart("data_source");
std::unique_ptr<MockProducer> producer_otheruid = CreateMockProducer();
- auto x =
- svc->ConnectProducer(producer_otheruid.get(),
- base::GetCurrentUserId() + 1, "mock_producer_ouid");
+ auto x = svc->ConnectProducer(producer_otheruid.get(),
+ base::GetCurrentUserId() + 1,
+ base::GetProcessId(), "mock_producer_ouid");
EXPECT_CALL(*producer_otheruid, OnConnect()).Times(0);
task_runner.RunUntilIdle();
Mock::VerifyAndClearExpectations(producer_otheruid.get());
@@ -1730,6 +1732,73 @@ TEST_F(TracingServiceImplTest, WriteIntoFileWithPath) {
Property(&protos::gen::TestEvent::str, Eq("payload")))));
}
+TEST_F(TracingServiceImplTest, WriteIntoFileFilterMultipleChunks) {
+ static const size_t kNumTestPackets = 5;
+ static const size_t kPayloadSize = 500 * 1024UL;
+ static_assert(kNumTestPackets * kPayloadSize >
+ TracingServiceImpl::kWriteIntoFileChunkSize,
+ "This test covers filtering multiple chunks");
+
+ std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
+ consumer->Connect(svc.get());
+
+ std::unique_ptr<MockProducer> producer = CreateMockProducer();
+ producer->Connect(svc.get(), "mock_producer");
+ producer->RegisterDataSource("data_source");
+
+ TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(4096);
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("data_source");
+ ds_config->set_target_buffer(0);
+ trace_config.set_write_into_file(true);
+ trace_config.set_file_write_period_ms(100000); // 100s
+
+ protozero::FilterBytecodeGenerator filt;
+ // Message 0: root Trace proto.
+ filt.AddNestedField(1 /* root trace.packet*/, 1);
+ filt.EndMessage();
+ // Message 1: TracePacket proto. Allow all fields.
+ filt.AddSimpleFieldRange(1, 1000);
+ filt.EndMessage();
+ trace_config.mutable_trace_filter()->set_bytecode(filt.Serialize());
+
+ base::TempFile tmp_file = base::TempFile::Create();
+ consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
+
+ producer->WaitForTracingSetup();
+ producer->WaitForDataSourceSetup("data_source");
+ producer->WaitForDataSourceStart("data_source");
+
+ std::unique_ptr<TraceWriter> writer =
+ producer->CreateTraceWriter("data_source");
+ for (size_t i = 0; i < kNumTestPackets; i++) {
+ auto tp = writer->NewTracePacket();
+ std::string payload(kPayloadSize, 'c');
+ tp->set_for_testing()->set_str(payload.c_str(), payload.size());
+ }
+
+ writer->Flush();
+ writer.reset();
+
+ consumer->DisableTracing();
+ producer->WaitForDataSourceStop("data_source");
+ consumer->WaitForTracingDisabled();
+
+ consumer->GetTraceStats();
+ TraceStats stats = consumer->WaitForTraceStats(true);
+
+ std::string trace_raw;
+ ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));
+ protozero::ProtoDecoder dec(trace_raw.data(), trace_raw.size());
+ size_t total_size = 0;
+ for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+ total_size += field.size();
+ }
+ EXPECT_EQ(total_size, stats.filter_stats().output_bytes());
+ EXPECT_GT(total_size, kNumTestPackets * kPayloadSize);
+}
+
// Test the logic that allows the trace config to set the shm total size and
// page size from the trace config. Also check that, if the config doesn't
// specify a value we fall back on the hint provided by the producer.
@@ -1785,7 +1854,7 @@ TEST_F(TracingServiceImplTest, ProducerShmAndPageSizeOverriddenByTraceConfig) {
auto name = "mock_producer_" + std::to_string(i);
producer[i] = CreateMockProducer();
producer[i]->Connect(svc.get(), name, base::GetCurrentUserId(),
- kSizes[i].hint_size_kb * 1024,
+ base::GetProcessId(), kSizes[i].hint_size_kb * 1024,
kSizes[i].hint_page_size_kb * 1024);
producer[i]->RegisterDataSource("data_source");
}
@@ -2331,7 +2400,8 @@ TEST_F(TracingServiceImplTest, ResynchronizeTraceStreamUsingSyncMarker) {
const int kNumMarkers = 5;
auto writer = producer->CreateTraceWriter("data_source");
for (int i = 1; i <= 100; i++) {
- std::string payload(static_cast<size_t>(i), 'A' + (i % 25));
+ std::string payload(static_cast<size_t>(i),
+ 'A' + static_cast<char>(i % 25));
writer->NewTracePacket()->set_for_testing()->set_str(payload.c_str());
if (i % (100 / kNumMarkers) == 0) {
writer->Flush();
@@ -2425,11 +2495,13 @@ TEST_F(TracingServiceImplTest, ProducerUIDsAndPacketSequenceIDs) {
consumer->Connect(svc.get());
std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
- producer1->Connect(svc.get(), "mock_producer1", 123u /* uid */);
+ producer1->Connect(svc.get(), "mock_producer1", 123u /* uid */,
+ 1001 /* pid */);
producer1->RegisterDataSource("data_source");
std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
- producer2->Connect(svc.get(), "mock_producer2", 456u /* uid */);
+ producer2->Connect(svc.get(), "mock_producer2", 456u /* uid */,
+ 2002 /* pid */);
producer2->RegisterDataSource("data_source");
TraceConfig trace_config;
@@ -2480,6 +2552,7 @@ TEST_F(TracingServiceImplTest, ProducerUIDsAndPacketSequenceIDs) {
Property(&protos::gen::TracePacket::for_testing,
Property(&protos::gen::TestEvent::str, Eq("payload1a1"))),
Property(&protos::gen::TracePacket::trusted_uid, Eq(123)),
+ Property(&protos::gen::TracePacket::trusted_pid, Eq(1001)),
Property(&protos::gen::TracePacket::trusted_packet_sequence_id,
Eq(2u)))));
EXPECT_THAT(
@@ -2488,6 +2561,7 @@ TEST_F(TracingServiceImplTest, ProducerUIDsAndPacketSequenceIDs) {
Property(&protos::gen::TracePacket::for_testing,
Property(&protos::gen::TestEvent::str, Eq("payload1a2"))),
Property(&protos::gen::TracePacket::trusted_uid, Eq(123)),
+ Property(&protos::gen::TracePacket::trusted_pid, Eq(1001)),
Property(&protos::gen::TracePacket::trusted_packet_sequence_id,
Eq(2u)))));
EXPECT_THAT(
@@ -2496,6 +2570,7 @@ TEST_F(TracingServiceImplTest, ProducerUIDsAndPacketSequenceIDs) {
Property(&protos::gen::TracePacket::for_testing,
Property(&protos::gen::TestEvent::str, Eq("payload1b1"))),
Property(&protos::gen::TracePacket::trusted_uid, Eq(123)),
+ Property(&protos::gen::TracePacket::trusted_pid, Eq(1001)),
Property(&protos::gen::TracePacket::trusted_packet_sequence_id,
Eq(3u)))));
EXPECT_THAT(
@@ -2504,6 +2579,7 @@ TEST_F(TracingServiceImplTest, ProducerUIDsAndPacketSequenceIDs) {
Property(&protos::gen::TracePacket::for_testing,
Property(&protos::gen::TestEvent::str, Eq("payload1b2"))),
Property(&protos::gen::TracePacket::trusted_uid, Eq(123)),
+ Property(&protos::gen::TracePacket::trusted_pid, Eq(1001)),
Property(&protos::gen::TracePacket::trusted_packet_sequence_id,
Eq(3u)))));
EXPECT_THAT(
@@ -2512,6 +2588,7 @@ TEST_F(TracingServiceImplTest, ProducerUIDsAndPacketSequenceIDs) {
Property(&protos::gen::TracePacket::for_testing,
Property(&protos::gen::TestEvent::str, Eq("payload2a1"))),
Property(&protos::gen::TracePacket::trusted_uid, Eq(456)),
+ Property(&protos::gen::TracePacket::trusted_pid, Eq(2002)),
Property(&protos::gen::TracePacket::trusted_packet_sequence_id,
Eq(4u)))));
}
@@ -3534,10 +3611,10 @@ TEST_F(TracingServiceImplTest, QueryServiceState) {
consumer->Connect(svc.get());
std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
- producer1->Connect(svc.get(), "producer1");
+ producer1->Connect(svc.get(), "producer1", /*uid=*/0);
std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
- producer2->Connect(svc.get(), "producer2");
+ producer2->Connect(svc.get(), "producer2", /*uid=*/1002);
producer1->RegisterDataSource("common_ds");
producer2->RegisterDataSource("common_ds");
@@ -3545,39 +3622,137 @@ TEST_F(TracingServiceImplTest, QueryServiceState) {
producer1->RegisterDataSource("p1_ds");
producer2->RegisterDataSource("p2_ds");
+ producer2->RegisterDataSource("common_ds");
+
TracingServiceState svc_state = consumer->QueryServiceState();
EXPECT_EQ(svc_state.producers_size(), 2);
EXPECT_EQ(svc_state.producers().at(0).id(), 1);
EXPECT_EQ(svc_state.producers().at(0).name(), "producer1");
+ EXPECT_EQ(svc_state.producers().at(0).uid(), 0);
EXPECT_EQ(svc_state.producers().at(1).id(), 2);
EXPECT_EQ(svc_state.producers().at(1).name(), "producer2");
+ EXPECT_EQ(svc_state.producers().at(1).uid(), 1002);
- EXPECT_EQ(svc_state.data_sources_size(), 4);
+ EXPECT_EQ(svc_state.data_sources_size(), 5);
- EXPECT_EQ(svc_state.data_sources().at(0).producer_id(), 1);
- EXPECT_EQ(svc_state.data_sources().at(0).ds_descriptor().name(), "common_ds");
-
- EXPECT_EQ(svc_state.data_sources().at(1).producer_id(), 2);
- EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().name(), "common_ds");
-
- EXPECT_EQ(svc_state.data_sources().at(2).producer_id(), 1);
- EXPECT_EQ(svc_state.data_sources().at(2).ds_descriptor().name(), "p1_ds");
+ auto count_ds = [&](int32_t producer_id, const std::string& ds_name) {
+ int count = 0;
+ for (const auto& ds : svc_state.data_sources()) {
+ if (ds.producer_id() == producer_id &&
+ ds.ds_descriptor().name() == ds_name)
+ ++count;
+ }
+ return count;
+ };
- EXPECT_EQ(svc_state.data_sources().at(3).producer_id(), 2);
- EXPECT_EQ(svc_state.data_sources().at(3).ds_descriptor().name(), "p2_ds");
+ EXPECT_EQ(count_ds(1, "common_ds"), 1);
+ EXPECT_EQ(count_ds(1, "p1_ds"), 1);
+ EXPECT_EQ(count_ds(2, "common_ds"), 2);
+ EXPECT_EQ(count_ds(2, "p2_ds"), 1);
// Test that descriptors are cleared when a producer disconnects.
producer1.reset();
svc_state = consumer->QueryServiceState();
EXPECT_EQ(svc_state.producers_size(), 1);
- EXPECT_EQ(svc_state.data_sources_size(), 2);
+ EXPECT_EQ(svc_state.data_sources_size(), 3);
+
+ EXPECT_EQ(count_ds(1, "common_ds"), 0);
+ EXPECT_EQ(count_ds(1, "p1_ds"), 0);
+ EXPECT_EQ(count_ds(2, "common_ds"), 2);
+ EXPECT_EQ(count_ds(2, "p2_ds"), 1);
+}
+
+TEST_F(TracingServiceImplTest, UpdateDataSource) {
+ std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
+ consumer->Connect(svc.get());
+
+ std::unique_ptr<MockProducer> producer1 = CreateMockProducer();
+ producer1->Connect(svc.get(), "producer1", /*uid=*/0);
+
+ std::unique_ptr<MockProducer> producer2 = CreateMockProducer();
+ producer2->Connect(svc.get(), "producer2", /*uid=*/1002);
+
+ producer1->RegisterTrackEventDataSource({"cat1"}, 1);
+ producer2->RegisterTrackEventDataSource({}, 1);
+ producer2->RegisterTrackEventDataSource({}, 2);
+
+ // This request should fail because ID=2 is already registered.
+ producer2->RegisterTrackEventDataSource({"this_should_fail"}, 2);
+
+ TracingServiceState svc_state = consumer->QueryServiceState();
+
+ auto parse_desc = [](const perfetto::protos::gen::DataSourceDescriptor& dsd) {
+ perfetto::protos::gen::TrackEventDescriptor desc;
+ auto desc_raw = dsd.track_event_descriptor_raw();
+ EXPECT_TRUE(desc.ParseFromArray(desc_raw.data(), desc_raw.size()));
+ return desc;
+ };
+
+ EXPECT_EQ(svc_state.data_sources_size(), 3);
+
+ EXPECT_EQ(svc_state.data_sources().at(0).producer_id(), 1);
+ EXPECT_EQ(svc_state.data_sources().at(0).ds_descriptor().name(),
+ "track_event");
+ EXPECT_EQ(svc_state.data_sources().at(0).ds_descriptor().id(), 1u);
+ auto ted = parse_desc(svc_state.data_sources().at(0).ds_descriptor());
+ EXPECT_EQ(ted.available_categories_size(), 1);
+ EXPECT_EQ(ted.available_categories()[0].name(), "cat1");
- EXPECT_EQ(svc_state.data_sources().at(0).producer_id(), 2);
- EXPECT_EQ(svc_state.data_sources().at(0).ds_descriptor().name(), "common_ds");
EXPECT_EQ(svc_state.data_sources().at(1).producer_id(), 2);
- EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().name(), "p2_ds");
+ EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().name(),
+ "track_event");
+ EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().id(), 1u);
+ ted = parse_desc(svc_state.data_sources().at(1).ds_descriptor());
+ EXPECT_EQ(ted.available_categories_size(), 0);
+
+ EXPECT_EQ(svc_state.data_sources().at(2).ds_descriptor().id(), 2u);
+
+ // Test that TrackEvent DataSource is updated.
+ producer2->UpdateTrackEventDataSource({"cat1", "cat2"}, 2);
+
+ svc_state = consumer->QueryServiceState();
+
+ EXPECT_EQ(svc_state.data_sources_size(), 3);
+
+ EXPECT_EQ(svc_state.data_sources().at(0).producer_id(), 1);
+ EXPECT_EQ(svc_state.data_sources().at(0).ds_descriptor().id(), 1u);
+ ted = parse_desc(svc_state.data_sources().at(0).ds_descriptor());
+ EXPECT_EQ(ted.available_categories_size(), 1);
+
+ EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().id(), 1u);
+ ted = parse_desc(svc_state.data_sources().at(1).ds_descriptor());
+ EXPECT_EQ(ted.available_categories_size(), 0);
+
+ EXPECT_EQ(svc_state.data_sources().at(2).producer_id(), 2);
+ EXPECT_EQ(svc_state.data_sources().at(2).ds_descriptor().id(), 2u);
+ ted = parse_desc(svc_state.data_sources().at(2).ds_descriptor());
+ EXPECT_EQ(ted.available_categories_size(), 2);
+ EXPECT_EQ(ted.available_categories()[0].name(), "cat1");
+ EXPECT_EQ(ted.available_categories()[1].name(), "cat2");
+
+ // Test removal of a category.
+ producer2->UpdateTrackEventDataSource({"cat2"}, 2);
+
+ svc_state = consumer->QueryServiceState();
+
+ EXPECT_EQ(svc_state.data_sources_size(), 3);
+ EXPECT_EQ(svc_state.data_sources().at(2).ds_descriptor().id(), 2u);
+ ted = parse_desc(svc_state.data_sources().at(2).ds_descriptor());
+ EXPECT_EQ(ted.available_categories_size(), 1);
+ EXPECT_EQ(ted.available_categories()[0].name(), "cat2");
+
+ // Test adding a category to the first data source.
+ producer2->UpdateTrackEventDataSource({"cat3"}, 1);
+
+ svc_state = consumer->QueryServiceState();
+
+ EXPECT_EQ(svc_state.data_sources_size(), 3);
+ EXPECT_EQ(svc_state.data_sources().at(1).ds_descriptor().id(), 1u);
+ ted = parse_desc(svc_state.data_sources().at(1).ds_descriptor());
+ EXPECT_EQ(ted.available_categories_size(), 1);
+ EXPECT_EQ(ted.available_categories()[0].name(), "cat3");
}
TEST_F(TracingServiceImplTest, LimitSessionsPerUid) {
@@ -3628,7 +3803,7 @@ TEST_F(TracingServiceImplTest, ProducerProvidedSMB) {
SharedMemory* shm_raw = shm.get();
// Service should adopt the SMB provided by the producer.
- producer->Connect(svc.get(), "mock_producer", /*uid=*/42,
+ producer->Connect(svc.get(), "mock_producer", /*uid=*/42, /*pid=*/1025,
/*shared_memory_size_hint_bytes=*/0, kShmPageSizeBytes,
std::move(shm));
EXPECT_TRUE(producer->endpoint()->IsShmemProvidedByProducer());
@@ -3683,7 +3858,7 @@ TEST_F(TracingServiceImplTest, ProducerProvidedSMBInvalidSizes) {
// Service should not adopt the SMB provided by the producer, because the SMB
// size isn't a multiple of the page size.
- producer->Connect(svc.get(), "mock_producer", /*uid=*/42,
+ producer->Connect(svc.get(), "mock_producer", /*uid=*/42, /*pid=*/1025,
/*shared_memory_size_hint_bytes=*/0, kShmPageSizeBytes,
std::move(shm));
EXPECT_FALSE(producer->endpoint()->IsShmemProvidedByProducer());
diff --git a/src/tracing/debug_annotation.cc b/src/tracing/debug_annotation.cc
index add115a62..a72a4836e 100644
--- a/src/tracing/debug_annotation.cc
+++ b/src/tracing/debug_annotation.cc
@@ -24,7 +24,7 @@ namespace perfetto {
DebugAnnotation::~DebugAnnotation() = default;
void DebugAnnotation::WriteIntoTracedValue(TracedValue context) const {
- Add(context.context_);
+ Add(context.annotation_);
}
} // namespace perfetto
diff --git a/src/tracing/event_context.cc b/src/tracing/event_context.cc
index a4f1ade72..b73aee8f7 100644
--- a/src/tracing/event_context.cc
+++ b/src/tracing/event_context.cc
@@ -16,6 +16,7 @@
#include "perfetto/tracing/event_context.h"
+#include "perfetto/tracing/internal/track_event_interned_fields.h"
#include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
#include "protos/perfetto/trace/track_event/track_event.pbzero.h"
@@ -23,10 +24,12 @@ namespace perfetto {
EventContext::EventContext(
EventContext::TracePacketHandle trace_packet,
- internal::TrackEventIncrementalState* incremental_state)
+ internal::TrackEventIncrementalState* incremental_state,
+ const internal::TrackEventTlsState* tls_state)
: trace_packet_(std::move(trace_packet)),
event_(trace_packet_->set_track_event()),
- incremental_state_(incremental_state) {}
+ incremental_state_(incremental_state),
+ tls_state_(tls_state) {}
EventContext::~EventContext() {
if (!trace_packet_)
@@ -50,4 +53,12 @@ EventContext::~EventContext() {
serialized_interned_data.Reset();
}
+protos::pbzero::DebugAnnotation* EventContext::AddDebugAnnotation(
+ const char* name) {
+ auto annotation = event()->add_debug_annotations();
+ annotation->set_name_iid(
+ internal::InternedDebugAnnotationName::Get(this, name));
+ return annotation;
+}
+
} // namespace perfetto
diff --git a/src/tracing/internal/in_process_tracing_backend.cc b/src/tracing/internal/in_process_tracing_backend.cc
index 1df0f4bb9..ee1283d8b 100644
--- a/src/tracing/internal/in_process_tracing_backend.cc
+++ b/src/tracing/internal/in_process_tracing_backend.cc
@@ -85,13 +85,8 @@ InProcessTracingBackend::InProcessTracingBackend() {}
std::unique_ptr<ProducerEndpoint> InProcessTracingBackend::ConnectProducer(
const ConnectProducerArgs& args) {
PERFETTO_DCHECK(args.task_runner->RunsTasksOnCurrentThread());
-
- // This should never happen as we can have at most one in-process backend.
- if (service_)
- PERFETTO_FATAL("InProcessTracingBackend initialized twice");
-
return GetOrCreateService(args.task_runner)
- ->ConnectProducer(args.producer, /*uid=*/0, args.producer_name,
+ ->ConnectProducer(args.producer, /*uid=*/0, /*pid=*/0, args.producer_name,
args.shmem_size_hint_bytes,
/*in_process=*/true,
TracingService::ProducerSMBScrapingMode::kEnabled,
diff --git a/src/tracing/internal/tracing_backend_fake.cc b/src/tracing/internal/tracing_backend_fake.cc
index 3c64fed6a..c774764d2 100644
--- a/src/tracing/internal/tracing_backend_fake.cc
+++ b/src/tracing/internal/tracing_backend_fake.cc
@@ -43,6 +43,7 @@ class UnsupportedProducerEndpoint : public ProducerEndpoint {
~UnsupportedProducerEndpoint() override { producer_->OnDisconnect(); }
void RegisterDataSource(const DataSourceDescriptor&) override {}
+ void UpdateDataSource(const DataSourceDescriptor&) override {}
void UnregisterDataSource(const std::string& /*name*/) override {}
void RegisterTraceWriter(uint32_t /*writer_id*/,
diff --git a/src/tracing/internal/tracing_muxer_fake.cc b/src/tracing/internal/tracing_muxer_fake.cc
index fd4e0b591..a6700f325 100644
--- a/src/tracing/internal/tracing_muxer_fake.cc
+++ b/src/tracing/internal/tracing_muxer_fake.cc
@@ -35,6 +35,8 @@ PERFETTO_NO_DESTROY TracingMuxerFake::FakePlatform
PERFETTO_NO_DESTROY TracingMuxerFake TracingMuxerFake::instance{};
#endif // PERFETTO_HAS_NO_DESTROY()
+TracingMuxerFake::~TracingMuxerFake() = default;
+
TracingMuxerFake::FakePlatform::~FakePlatform() = default;
Platform::ThreadLocalObject*
@@ -57,6 +59,12 @@ bool TracingMuxerFake::RegisterDataSource(const DataSourceDescriptor&,
FailUninitialized();
}
+void TracingMuxerFake::UpdateDataSourceDescriptor(
+ const DataSourceDescriptor&,
+ const DataSourceStaticState*) {
+ FailUninitialized();
+}
+
std::unique_ptr<TraceWriterBase> TracingMuxerFake::CreateTraceWriter(
DataSourceStaticState*,
uint32_t,
diff --git a/src/tracing/internal/tracing_muxer_fake.h b/src/tracing/internal/tracing_muxer_fake.h
index 0c2902b55..78fc76960 100644
--- a/src/tracing/internal/tracing_muxer_fake.h
+++ b/src/tracing/internal/tracing_muxer_fake.h
@@ -41,6 +41,7 @@ class TracingMuxerFake : public TracingMuxer {
public:
TracingMuxerFake() : TracingMuxer(&FakePlatform::instance) {}
+ ~TracingMuxerFake() override;
static constexpr TracingMuxerFake* Get() {
#if PERFETTO_HAS_NO_DESTROY()
@@ -54,6 +55,8 @@ class TracingMuxerFake : public TracingMuxer {
bool RegisterDataSource(const DataSourceDescriptor&,
DataSourceFactory,
DataSourceStaticState*) override;
+ void UpdateDataSourceDescriptor(const DataSourceDescriptor&,
+ const DataSourceStaticState*) override;
std::unique_ptr<TraceWriterBase> CreateTraceWriter(
DataSourceStaticState*,
uint32_t data_source_instance_index,
diff --git a/src/tracing/internal/tracing_muxer_impl.cc b/src/tracing/internal/tracing_muxer_impl.cc
index 1fb5ae8e3..dd34ca4b3 100644
--- a/src/tracing/internal/tracing_muxer_impl.cc
+++ b/src/tracing/internal/tracing_muxer_impl.cc
@@ -24,6 +24,7 @@
#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
#include "perfetto/base/task_runner.h"
+#include "perfetto/base/time.h"
#include "perfetto/ext/base/hash.h"
#include "perfetto/ext/base/thread_checker.h"
#include "perfetto/ext/base/waitable_event.h"
@@ -128,6 +129,9 @@ uint64_t ComputeConfigHash(const DataSourceConfig& config) {
return hasher.digest();
}
+// Holds an earlier TracingMuxerImpl instance after ResetForTesting() is called.
+static TracingMuxerImpl* g_prev_instance{};
+
} // namespace
// ----- Begin of TracingMuxerImpl::ProducerImpl
@@ -139,7 +143,9 @@ TracingMuxerImpl::ProducerImpl::ProducerImpl(
backend_id_(backend_id),
shmem_batch_commits_duration_ms_(shmem_batch_commits_duration_ms) {}
-TracingMuxerImpl::ProducerImpl::~ProducerImpl() = default;
+TracingMuxerImpl::ProducerImpl::~ProducerImpl() {
+ muxer_ = nullptr;
+}
void TracingMuxerImpl::ProducerImpl::Initialize(
std::unique_ptr<ProducerEndpoint> endpoint) {
@@ -153,6 +159,10 @@ void TracingMuxerImpl::ProducerImpl::Initialize(
// that |task_runner| is assumed to outlive tracing sessions on all threads.)
auto* task_runner = muxer_->task_runner_.get();
auto deleter = [task_runner](ProducerEndpoint* e) {
+ if (task_runner->RunsTasksOnCurrentThread()) {
+ delete e;
+ return;
+ }
task_runner->PostTask([e] { delete e; });
};
std::shared_ptr<ProducerEndpoint> service(endpoint.release(), deleter);
@@ -174,23 +184,37 @@ void TracingMuxerImpl::ProducerImpl::OnConnect() {
void TracingMuxerImpl::ProducerImpl::OnDisconnect() {
PERFETTO_DCHECK_THREAD(thread_checker_);
+ // If we're being destroyed, bail out.
+ if (!muxer_)
+ return;
connected_ = false;
// Active data sources for this producer will be stopped by
// DestroyStoppedTraceWritersForCurrentThread() since the reconnected producer
// will have a different connection id (even before it has finished
// connecting).
registered_data_sources_.reset();
- // Keep the old service around as a dead connection in case it has active
- // trace writers. We can't clear |service_| here because other threads may be
- // concurrently creating new trace writers. The reconnection below will
- // atomically swap the new service in place of the old one.
- dead_services_.push_back(service_);
+ DisposeConnection();
+
// Try reconnecting the producer.
muxer_->OnProducerDisconnected(this);
}
+void TracingMuxerImpl::ProducerImpl::DisposeConnection() {
+ // Keep the old service around as a dead connection in case it has active
+ // trace writers. If any tracing sessions were created, we can't clear
+ // |service_| here because other threads may be concurrently creating new
+ // trace writers. Any reconnection attempt will atomically swap the new
+ // service in place of the old one.
+ if (did_setup_tracing_) {
+ dead_services_.push_back(service_);
+ } else {
+ service_.reset();
+ }
+}
+
void TracingMuxerImpl::ProducerImpl::OnTracingSetup() {
PERFETTO_DCHECK_THREAD(thread_checker_);
+ did_setup_tracing_ = true;
service_->MaybeSharedMemoryArbiter()->SetBatchCommitsDuration(
shmem_batch_commits_duration_ms_);
}
@@ -199,18 +223,24 @@ void TracingMuxerImpl::ProducerImpl::SetupDataSource(
DataSourceInstanceID id,
const DataSourceConfig& cfg) {
PERFETTO_DCHECK_THREAD(thread_checker_);
+ if (!muxer_)
+ return;
muxer_->SetupDataSource(backend_id_, connection_id_, id, cfg);
}
void TracingMuxerImpl::ProducerImpl::StartDataSource(DataSourceInstanceID id,
const DataSourceConfig&) {
PERFETTO_DCHECK_THREAD(thread_checker_);
+ if (!muxer_)
+ return;
muxer_->StartDataSource(backend_id_, id);
service_->NotifyDataSourceStarted(id);
}
void TracingMuxerImpl::ProducerImpl::StopDataSource(DataSourceInstanceID id) {
PERFETTO_DCHECK_THREAD(thread_checker_);
+ if (!muxer_)
+ return;
muxer_->StopDataSource_AsyncBegin(backend_id_, id);
}
@@ -226,12 +256,14 @@ void TracingMuxerImpl::ProducerImpl::ClearIncrementalState(
const DataSourceInstanceID* instances,
size_t instance_count) {
PERFETTO_DCHECK_THREAD(thread_checker_);
+ if (!muxer_)
+ return;
for (size_t inst_idx = 0; inst_idx < instance_count; inst_idx++) {
muxer_->ClearDataSourceIncrementalState(backend_id_, instances[inst_idx]);
}
}
-void TracingMuxerImpl::ProducerImpl::SweepDeadServices() {
+bool TracingMuxerImpl::ProducerImpl::SweepDeadServices() {
PERFETTO_DCHECK_THREAD(thread_checker_);
auto is_unused = [](const std::shared_ptr<ProducerEndpoint>& endpoint) {
auto* arbiter = endpoint->MaybeSharedMemoryArbiter();
@@ -245,6 +277,7 @@ void TracingMuxerImpl::ProducerImpl::SweepDeadServices() {
}
it = next_it;
}
+ return dead_services_.empty();
}
// ----- End of TracingMuxerImpl::ProducerImpl methods.
@@ -259,7 +292,9 @@ TracingMuxerImpl::ConsumerImpl::ConsumerImpl(TracingMuxerImpl* muxer,
backend_id_(backend_id),
session_id_(session_id) {}
-TracingMuxerImpl::ConsumerImpl::~ConsumerImpl() = default;
+TracingMuxerImpl::ConsumerImpl::~ConsumerImpl() {
+ muxer_ = nullptr;
+}
void TracingMuxerImpl::ConsumerImpl::Initialize(
std::unique_ptr<ConsumerEndpoint> endpoint) {
@@ -300,6 +335,9 @@ void TracingMuxerImpl::ConsumerImpl::OnConnect() {
void TracingMuxerImpl::ConsumerImpl::OnDisconnect() {
PERFETTO_DCHECK_THREAD(thread_checker_);
+ // If we're being destroyed, bail out.
+ if (!muxer_)
+ return;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
if (!connected_ && backend_type_ == kSystemBackend) {
PERFETTO_ELOG(
@@ -697,8 +735,9 @@ TracingMuxerImpl::TracingMuxerImpl(const TracingInitArgs& args)
instance_ = this;
// Create the thread where muxer, producers and service will live.
- task_runner_.reset(
- new NonReentrantTaskRunner(this, platform_->CreateTaskRunner({})));
+ Platform::CreateTaskRunnerArgs tr_args{/*name_for_debugging=*/"TracingMuxer"};
+ task_runner_.reset(new NonReentrantTaskRunner(
+ this, platform_->CreateTaskRunner(std::move(tr_args))));
// Run the initializer on that thread.
task_runner_->PostTask([this, args] { Initialize(args); });
@@ -769,8 +808,7 @@ bool TracingMuxerImpl::RegisterDataSource(
if (static_state->index != kMaxDataSources)
return true;
- static std::atomic<uint32_t> last_id{};
- uint32_t new_index = last_id++;
+ uint32_t new_index = next_data_source_index_++;
if (new_index >= kMaxDataSources) {
PERFETTO_DLOG(
"RegisterDataSource failed: too many data sources already registered");
@@ -785,18 +823,42 @@ bool TracingMuxerImpl::RegisterDataSource(
static_state->index = new_index;
+ // Generate a semi-unique id for this data source.
+ base::Hash hash;
+ hash.Update(reinterpret_cast<intptr_t>(static_state));
+ hash.Update(base::GetWallTimeNs().count());
+ static_state->id = hash.digest() ? hash.digest() : 1;
+
task_runner_->PostTask([this, descriptor, factory, static_state] {
data_sources_.emplace_back();
RegisteredDataSource& rds = data_sources_.back();
rds.descriptor = descriptor;
rds.factory = factory;
rds.static_state = static_state;
- UpdateDataSourcesOnAllBackends();
+
+ UpdateDataSourceOnAllBackends(rds, /*is_changed=*/false);
});
return true;
}
// Can be called from any thread (but not concurrently).
+void TracingMuxerImpl::UpdateDataSourceDescriptor(
+ const DataSourceDescriptor& descriptor,
+ const DataSourceStaticState* static_state) {
+ task_runner_->PostTask([this, descriptor, static_state] {
+ for (auto& rds : data_sources_) {
+ if (rds.static_state == static_state) {
+ PERFETTO_CHECK(rds.descriptor.name() == descriptor.name());
+ rds.descriptor = descriptor;
+ rds.descriptor.set_id(static_state->id);
+ UpdateDataSourceOnAllBackends(rds, /*is_changed=*/true);
+ return;
+ }
+ }
+ });
+}
+
+// Can be called from any thread (but not concurrently).
void TracingMuxerImpl::RegisterInterceptor(
const InterceptorDescriptor& descriptor,
InterceptorFactory factory,
@@ -884,6 +946,7 @@ void TracingMuxerImpl::SetupDataSource(TracingBackendId backend_id,
std::is_same<decltype(internal_state->data_source_instance_id),
DataSourceInstanceID>::value,
"data_source_instance_id type mismatch");
+ internal_state->muxer_id_for_testing = muxer_id_for_testing_;
internal_state->backend_id = backend_id;
internal_state->backend_connection_id = backend_connection_id;
internal_state->data_source_instance_id = instance_id;
@@ -1020,6 +1083,7 @@ void TracingMuxerImpl::StopDataSource_AsyncEnd(
std::lock_guard<std::recursive_mutex> guard(ds.internal_state->lock);
ds.internal_state->trace_lambda_enabled = false;
ds.internal_state->data_source.reset();
+ ds.internal_state->interceptor.reset();
}
// The other fields of internal_state are deliberately *not* cleared.
@@ -1130,7 +1194,9 @@ void TracingMuxerImpl::DestroyStoppedTraceWritersForCurrentThread() {
continue;
DataSourceState* ds_state = static_state->TryGet(inst);
- if (ds_state && ds_state->backend_id == ds_tls.backend_id &&
+ if (ds_state &&
+ ds_state->muxer_id_for_testing == ds_tls.muxer_id_for_testing &&
+ ds_state->backend_id == ds_tls.backend_id &&
ds_state->backend_connection_id == ds_tls.backend_connection_id &&
ds_state->buffer_id == ds_tls.buffer_id &&
ds_state->data_source_instance_id == ds_tls.data_source_instance_id) {
@@ -1157,22 +1223,34 @@ void TracingMuxerImpl::DestroyStoppedTraceWritersForCurrentThread() {
void TracingMuxerImpl::UpdateDataSourcesOnAllBackends() {
PERFETTO_DCHECK_THREAD(thread_checker_);
for (RegisteredDataSource& rds : data_sources_) {
- for (RegisteredBackend& backend : backends_) {
- // We cannot call RegisterDataSource on the backend before it connects.
- if (!backend.producer->connected_)
- continue;
+ UpdateDataSourceOnAllBackends(rds, /*is_changed=*/false);
+ }
+}
- PERFETTO_DCHECK(rds.static_state->index < kMaxDataSources);
- if (backend.producer->registered_data_sources_.test(
- rds.static_state->index))
- continue;
+void TracingMuxerImpl::UpdateDataSourceOnAllBackends(RegisteredDataSource& rds,
+ bool is_changed) {
+ PERFETTO_DCHECK_THREAD(thread_checker_);
+ for (RegisteredBackend& backend : backends_) {
+ // We cannot call RegisterDataSource on the backend before it connects.
+ if (!backend.producer->connected_)
+ continue;
- rds.descriptor.set_will_notify_on_start(true);
- rds.descriptor.set_will_notify_on_stop(true);
- rds.descriptor.set_handles_incremental_state_clear(true);
+ PERFETTO_DCHECK(rds.static_state->index < kMaxDataSources);
+ bool is_registered = backend.producer->registered_data_sources_.test(
+ rds.static_state->index);
+ if (is_registered && !is_changed)
+ continue;
+
+ rds.descriptor.set_will_notify_on_start(true);
+ rds.descriptor.set_will_notify_on_stop(true);
+ rds.descriptor.set_handles_incremental_state_clear(true);
+ rds.descriptor.set_id(rds.static_state->id);
+ if (is_registered) {
+ backend.producer->service_->UpdateDataSource(rds.descriptor);
+ } else {
backend.producer->service_->RegisterDataSource(rds.descriptor);
- backend.producer->registered_data_sources_.set(rds.static_state->index);
}
+ backend.producer->registered_data_sources_.set(rds.static_state->index);
}
}
@@ -1484,6 +1562,17 @@ void TracingMuxerImpl::OnProducerDisconnected(ProducerImpl* producer) {
TracingMuxer::generation_++;
}
+void TracingMuxerImpl::SweepDeadBackends() {
+ PERFETTO_DCHECK_THREAD(thread_checker_);
+ for (auto it = dead_backends_.begin(); it != dead_backends_.end();) {
+ auto next_it = it;
+ next_it++;
+ if (it->producer->SweepDeadServices())
+ dead_backends_.erase(it);
+ it = next_it;
+ }
+}
+
TracingMuxerImpl::FindDataSourceRes TracingMuxerImpl::FindDataSource(
TracingBackendId backend_id,
DataSourceInstanceID instance_id) {
@@ -1612,10 +1701,94 @@ std::unique_ptr<TracingSession> TracingMuxerImpl::CreateTracingSession(
new TracingSessionImpl(this, session_id, requested_backend_type));
}
+// static
void TracingMuxerImpl::InitializeInstance(const TracingInitArgs& args) {
if (instance_ != TracingMuxerFake::Get())
PERFETTO_FATAL("Tracing already initialized");
- new TracingMuxerImpl(args);
+ // If we previously had a TracingMuxerImpl instance which was reset,
+ // reinitialize and reuse it instead of trying to create a new one. See
+ // ResetForTesting().
+ if (g_prev_instance) {
+ auto* muxer = g_prev_instance;
+ g_prev_instance = nullptr;
+ instance_ = muxer;
+ muxer->task_runner_->PostTask([muxer, args] { muxer->Initialize(args); });
+ } else {
+ new TracingMuxerImpl(args);
+ }
+}
+
+// static
+void TracingMuxerImpl::ResetForTesting() {
+ // Ideally we'd tear down the entire TracingMuxerImpl, but the lifetimes of
+ // various objects make that a non-starter. In particular:
+ //
+ // 1) Any thread that has entered a trace event has a TraceWriter, which holds
+ // a reference back to ProducerImpl::service_.
+ //
+ // 2) ProducerImpl::service_ has a reference back to the ProducerImpl.
+ //
+ // 3) ProducerImpl holds reference to TracingMuxerImpl::task_runner_, which in
+ // turn depends on TracingMuxerImpl itself.
+ //
+ // Because of this, it's not safe to deallocate TracingMuxerImpl until all
+ // threads have dropped their TraceWriters. Since we can't really ask the
+ // caller to guarantee this, we'll instead reset enough of the muxer's state
+ // so that it can be reinitialized later and ensure all necessary objects from
+ // the old state remain alive until all references have gone away.
+ auto* muxer = reinterpret_cast<TracingMuxerImpl*>(instance_);
+
+ base::WaitableEvent reset_done;
+ auto do_reset = [muxer, &reset_done] {
+ // Unregister all data sources so they don't interfere with any future
+ // tracing sessions.
+ for (RegisteredDataSource& rds : muxer->data_sources_) {
+ for (RegisteredBackend& backend : muxer->backends_) {
+ if (!backend.producer->service_)
+ continue;
+ backend.producer->service_->UnregisterDataSource(rds.descriptor.name());
+ }
+ }
+ for (auto& backend : muxer->backends_) {
+ // Check that no consumer session is currently active on any backend.
+ for (auto& consumer : backend.consumers)
+ PERFETTO_CHECK(!consumer->service_);
+ backend.producer->muxer_ = nullptr;
+ backend.producer->DisposeConnection();
+ muxer->dead_backends_.push_back(std::move(backend));
+ }
+ muxer->backends_.clear();
+ muxer->interceptors_.clear();
+
+ for (auto& ds : muxer->data_sources_) {
+ ds.static_state->~DataSourceStaticState();
+ new (ds.static_state) DataSourceStaticState{};
+ }
+ muxer->data_sources_.clear();
+ muxer->next_data_source_index_ = 0;
+
+ // Free all backends without active trace writers or other inbound
+ // references. Note that even if all the backends get swept, the muxer still
+ // needs to stay around since |task_runner_| is assumed to be long-lived.
+ muxer->SweepDeadBackends();
+
+ // Make sure we eventually discard any per-thread trace writers from the
+ // previous instance.
+ muxer->muxer_id_for_testing_++;
+
+ g_prev_instance = muxer;
+ instance_ = TracingMuxerFake::Get();
+ reset_done.Notify();
+ };
+
+ // Some tests run the muxer and the test on the same thread. In these cases,
+ // we can reset synchronously.
+ if (muxer->task_runner_->RunsTasksOnCurrentThread()) {
+ do_reset();
+ } else {
+ muxer->task_runner_->PostTask(std::move(do_reset));
+ reset_done.Wait();
+ }
}
TracingMuxer::~TracingMuxer() = default;
diff --git a/src/tracing/internal/tracing_muxer_impl.h b/src/tracing/internal/tracing_muxer_impl.h
index d0898a744..1841cd47b 100644
--- a/src/tracing/internal/tracing_muxer_impl.h
+++ b/src/tracing/internal/tracing_muxer_impl.h
@@ -97,11 +97,14 @@ class TracingMuxerImpl : public TracingMuxer {
using TracingSessionGlobalID = uint64_t;
static void InitializeInstance(const TracingInitArgs&);
+ static void ResetForTesting();
// TracingMuxer implementation.
bool RegisterDataSource(const DataSourceDescriptor&,
DataSourceFactory,
DataSourceStaticState*) override;
+ void UpdateDataSourceDescriptor(const DataSourceDescriptor&,
+ const DataSourceStaticState*) override;
std::unique_ptr<TraceWriterBase> CreateTraceWriter(
DataSourceStaticState*,
uint32_t data_source_instance_index,
@@ -178,6 +181,7 @@ class TracingMuxerImpl : public TracingMuxer {
void RegisterDataSource(const DataSourceDescriptor&,
DataSourceFactory,
DataSourceStaticState*);
+ void DisposeConnection();
// perfetto::Producer implementation.
void OnConnect() override;
@@ -191,12 +195,13 @@ class TracingMuxerImpl : public TracingMuxer {
void Flush(FlushRequestID, const DataSourceInstanceID*, size_t) override;
void ClearIncrementalState(const DataSourceInstanceID*, size_t) override;
- void SweepDeadServices();
+ bool SweepDeadServices();
PERFETTO_THREAD_CHECKER(thread_checker_)
- TracingMuxerImpl* const muxer_;
+ TracingMuxerImpl* muxer_;
TracingBackendId const backend_id_;
bool connected_ = false;
+ bool did_setup_tracing_ = false;
uint32_t connection_id_ = 0;
const uint32_t shmem_batch_commits_duration_ms_ = 0;
@@ -258,7 +263,7 @@ class TracingMuxerImpl : public TracingMuxer {
// Will eventually inform the |muxer_| when it is safe to remove |this|.
void Disconnect();
- TracingMuxerImpl* const muxer_;
+ TracingMuxerImpl* muxer_;
BackendType const backend_type_;
TracingBackendId const backend_id_;
TracingSessionGlobalID const session_id_;
@@ -377,12 +382,15 @@ class TracingMuxerImpl : public TracingMuxer {
std::vector<std::unique_ptr<ConsumerImpl>> consumers;
};
+ void UpdateDataSourceOnAllBackends(RegisteredDataSource& rds,
+ bool is_changed);
explicit TracingMuxerImpl(const TracingInitArgs&);
void Initialize(const TracingInitArgs& args);
ConsumerImpl* FindConsumer(TracingSessionGlobalID session_id);
void InitializeConsumer(TracingSessionGlobalID session_id);
void OnConsumerDisconnected(ConsumerImpl* consumer);
void OnProducerDisconnected(ProducerImpl* producer);
+ void SweepDeadBackends();
struct FindDataSourceRes {
FindDataSourceRes() = default;
@@ -396,6 +404,7 @@ class TracingMuxerImpl : public TracingMuxer {
};
FindDataSourceRes FindDataSource(TracingBackendId, DataSourceInstanceID);
+ // WARNING: If you add new state here, be sure to update ResetForTesting.
std::unique_ptr<base::TaskRunner> task_runner_;
std::vector<RegisteredDataSource> data_sources_;
std::vector<RegisteredBackend> backends_;
@@ -403,11 +412,18 @@ class TracingMuxerImpl : public TracingMuxer {
TracingPolicy* policy_ = nullptr;
std::atomic<TracingSessionGlobalID> next_tracing_session_id_{};
+ std::atomic<uint32_t> next_data_source_index_{};
+ uint32_t muxer_id_for_testing_{};
// Maximum number of times we will try to reconnect producer backend.
// Should only be modified for testing purposes.
std::atomic<uint32_t> max_producer_reconnections_{100u};
+ // After ResetForTesting() is called, holds tracing backends which needs to be
+ // kept alive until all inbound references have gone away. See
+ // SweepDeadBackends().
+ std::list<RegisteredBackend> dead_backends_;
+
PERFETTO_THREAD_CHECKER(thread_checker_)
};
diff --git a/src/tracing/internal/track_event_internal.cc b/src/tracing/internal/track_event_internal.cc
index 736c31211..2d4d12a18 100644
--- a/src/tracing/internal/track_event_internal.cc
+++ b/src/tracing/internal/track_event_internal.cc
@@ -26,11 +26,14 @@
#include "perfetto/tracing/track_event_interned_data_index.h"
#include "protos/perfetto/common/data_source_descriptor.gen.h"
#include "protos/perfetto/common/track_event_descriptor.pbzero.h"
+#include "protos/perfetto/trace/clock_snapshot.pbzero.h"
#include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
#include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
#include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
#include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
+using perfetto::protos::pbzero::ClockSnapshot;
+
namespace perfetto {
TrackEventSessionObserver::~TrackEventSessionObserver() = default;
@@ -48,6 +51,16 @@ std::atomic<perfetto::base::PlatformThreadId> g_main_thread;
static constexpr const char kLegacySlowPrefix[] = "disabled-by-default-";
static constexpr const char kSlowTag[] = "slow";
static constexpr const char kDebugTag[] = "debug";
+// Allows to specify a custom unit different than the default (ns) for
+// the incremental clock.
+// A multiplier of 1000 means that a timestamp = 3 should be
+// interpreted as 3000 ns = 3 us.
+// TODO(mohitms): Move it to TrackEventConfig.
+constexpr uint64_t kIncrementalTimestampUnitMultiplier = 1;
+static_assert(kIncrementalTimestampUnitMultiplier >= 1, "");
+
+constexpr auto kClockIdIncremental =
+ TrackEventIncrementalState::kClockIdIncremental;
void ForEachObserver(
std::function<bool(TrackEventSessionObserver*&)> callback) {
@@ -303,48 +316,107 @@ uint64_t TrackEventInternal::GetTimeNs() {
}
// static
+TraceTimestamp TrackEventInternal::GetTraceTime() {
+ return {kClockIdIncremental, GetTimeNs()};
+}
+
+// static
int TrackEventInternal::GetSessionCount() {
return session_count_.load();
}
// static
-void TrackEventInternal::ResetIncrementalState(TraceWriterBase* trace_writer,
- uint64_t timestamp) {
+void TrackEventInternal::ResetIncrementalState(
+ TraceWriterBase* trace_writer,
+ TrackEventIncrementalState* incr_state,
+ const TrackEventTlsState& tls_state,
+ const TraceTimestamp& timestamp) {
+ auto sequence_timestamp = timestamp;
+ if (timestamp.clock_id != TrackEventInternal::GetClockId() &&
+ timestamp.clock_id != kClockIdIncremental) {
+ sequence_timestamp = TrackEventInternal::GetTraceTime();
+ }
+
+ incr_state->last_timestamp_ns = sequence_timestamp.value;
auto default_track = ThreadTrack::Current();
{
// Mark any incremental state before this point invalid. Also set up
// defaults so that we don't need to repeat constant data for each packet.
auto packet = NewTracePacket(
- trace_writer, timestamp,
+ trace_writer, incr_state, tls_state, timestamp,
protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED);
auto defaults = packet->set_trace_packet_defaults();
- defaults->set_timestamp_clock_id(GetClockId());
// Establish the default track for this event sequence.
auto track_defaults = defaults->set_track_event_defaults();
track_defaults->set_track_uuid(default_track.uuid);
+
+ if (PERFETTO_LIKELY(!tls_state.disable_incremental_timestamps)) {
+ defaults->set_timestamp_clock_id(kClockIdIncremental);
+ ClockSnapshot* clocks = packet->set_clock_snapshot();
+ // Trace clock.
+ ClockSnapshot::Clock* trace_clock = clocks->add_clocks();
+ trace_clock->set_clock_id(GetClockId());
+ trace_clock->set_timestamp(sequence_timestamp.value);
+ // Delta-encoded incremental clock in nano seconds.
+ // TODO(b/168311581): Make the unit of this clock configurable to allow
+ // trade-off between precision and encoded trace size.
+ ClockSnapshot::Clock* clock_incremental = clocks->add_clocks();
+ clock_incremental->set_clock_id(kClockIdIncremental);
+ auto ts_unit_multiplier = kIncrementalTimestampUnitMultiplier;
+ clock_incremental->set_timestamp(sequence_timestamp.value /
+ ts_unit_multiplier);
+ clock_incremental->set_is_incremental(true);
+ clock_incremental->set_unit_multiplier_ns(ts_unit_multiplier);
+ } else {
+ defaults->set_timestamp_clock_id(GetClockId());
+ }
}
// Every thread should write a descriptor for its default track, because most
- // trace points won't explicitly reference it.
- WriteTrackDescriptor(default_track, trace_writer);
-
- // Additionally the main thread should dump the process descriptor.
- if (perfetto::base::GetThreadId() == g_main_thread)
- WriteTrackDescriptor(ProcessTrack::Current(), trace_writer);
+ // trace points won't explicitly reference it. We also write the process
+ // descriptor from every thread that writes trace events to ensure it gets
+ // emitted at least once.
+ WriteTrackDescriptor(default_track, trace_writer, incr_state, tls_state,
+ sequence_timestamp);
+
+ WriteTrackDescriptor(ProcessTrack::Current(), trace_writer, incr_state,
+ tls_state, sequence_timestamp);
}
// static
protozero::MessageHandle<protos::pbzero::TracePacket>
TrackEventInternal::NewTracePacket(TraceWriterBase* trace_writer,
- uint64_t timestamp,
+ TrackEventIncrementalState* incr_state,
+ const TrackEventTlsState& tls_state,
+ TraceTimestamp timestamp,
uint32_t seq_flags) {
+ if (PERFETTO_UNLIKELY(tls_state.disable_incremental_timestamps &&
+ timestamp.clock_id == kClockIdIncremental)) {
+ timestamp.clock_id = GetClockId();
+ }
auto packet = trace_writer->NewTracePacket();
- packet->set_timestamp(timestamp);
- // TODO(skyostil): Stop emitting this for every event once the trace
- // processor understands trace packet defaults.
- if (GetClockId() != protos::pbzero::BUILTIN_CLOCK_BOOTTIME)
- packet->set_timestamp_clock_id(GetClockId());
+ // TODO(mohitms): Consider using kIncrementalTimestampUnitMultiplier.
+ if (PERFETTO_LIKELY(timestamp.clock_id == kClockIdIncremental)) {
+ if (PERFETTO_LIKELY(incr_state->last_timestamp_ns <= timestamp.value)) {
+ // No need to set the clock id here, since kClockIdIncremental is the
+ // clock id assumed by default.
+ auto ts_unit_multiplier = kIncrementalTimestampUnitMultiplier;
+ auto time_diff_ns = timestamp.value - incr_state->last_timestamp_ns;
+ packet->set_timestamp(time_diff_ns / ts_unit_multiplier);
+ incr_state->last_timestamp_ns = timestamp.value;
+ } else {
+ packet->set_timestamp(timestamp.value);
+ packet->set_timestamp_clock_id(GetClockId());
+ }
+ } else {
+ packet->set_timestamp(timestamp.value);
+ auto default_clock = tls_state.disable_incremental_timestamps
+ ? static_cast<uint32_t>(GetClockId())
+ : kClockIdIncremental;
+ if (PERFETTO_UNLIKELY(timestamp.clock_id != default_clock))
+ packet->set_timestamp_clock_id(timestamp.clock_id);
+ }
packet->set_sequence_flags(seq_flags);
return packet;
}
@@ -353,15 +425,15 @@ TrackEventInternal::NewTracePacket(TraceWriterBase* trace_writer,
EventContext TrackEventInternal::WriteEvent(
TraceWriterBase* trace_writer,
TrackEventIncrementalState* incr_state,
+ const TrackEventTlsState& tls_state,
const Category* category,
const char* name,
perfetto::protos::pbzero::TrackEvent::Type type,
- uint64_t timestamp) {
+ const TraceTimestamp& timestamp) {
PERFETTO_DCHECK(g_main_thread);
PERFETTO_DCHECK(!incr_state->was_cleared);
-
- auto packet = NewTracePacket(trace_writer, timestamp);
- EventContext ctx(std::move(packet), incr_state);
+ auto packet = NewTracePacket(trace_writer, incr_state, tls_state, timestamp);
+ EventContext ctx(std::move(packet), incr_state, &tls_state);
auto track_event = ctx.event();
if (type != protos::pbzero::TrackEvent::TYPE_UNSPECIFIED)
diff --git a/src/tracing/internal/track_event_interned_fields.cc b/src/tracing/internal/track_event_interned_fields.cc
index 804aeb439..55b8909d8 100644
--- a/src/tracing/internal/track_event_interned_fields.cc
+++ b/src/tracing/internal/track_event_interned_fields.cc
@@ -54,5 +54,18 @@ void InternedDebugAnnotationName::Add(
name->set_name(value);
}
+InternedDebugAnnotationValueTypeName::~InternedDebugAnnotationValueTypeName() =
+ default;
+
+// static
+void InternedDebugAnnotationValueTypeName::Add(
+ protos::pbzero::InternedData* interned_data,
+ size_t iid,
+ const char* value) {
+ auto name = interned_data->add_debug_annotation_value_type_names();
+ name->set_iid(iid);
+ name->set_name(value);
+}
+
} // namespace internal
} // namespace perfetto
diff --git a/src/tracing/ipc/BUILD.gn b/src/tracing/ipc/BUILD.gn
index 93c97a6c9..dfd0eda27 100644
--- a/src/tracing/ipc/BUILD.gn
+++ b/src/tracing/ipc/BUILD.gn
@@ -27,13 +27,15 @@ source_set("common") {
"../../../include/perfetto/ext/tracing/ipc",
]
sources = [
- "default_socket.cc",
"memfd.cc",
"memfd.h",
"posix_shared_memory.cc",
"posix_shared_memory.h",
+ "shared_memory_windows.cc",
+ "shared_memory_windows.h",
]
deps = [
+ ":default_socket",
"../../../gn:default_deps",
"../../../include/perfetto/ext/ipc",
"../../base",
@@ -41,6 +43,17 @@ source_set("common") {
]
}
+source_set("default_socket") {
+ sources = [ "default_socket.cc" ]
+ public_deps = [ "../../../include/perfetto/ext/tracing/ipc" ]
+ deps = [
+ "../../../gn:default_deps",
+ "../../../include/perfetto/ext/ipc",
+ "../../../include/perfetto/ext/tracing/core",
+ "../../base",
+ ]
+}
+
perfetto_unittest_source_set("unittests") {
testonly = true
deps = [
diff --git a/src/tracing/ipc/consumer/consumer_ipc_client_impl.cc b/src/tracing/ipc/consumer/consumer_ipc_client_impl.cc
index e77c03f11..e8309e9b1 100644
--- a/src/tracing/ipc/consumer/consumer_ipc_client_impl.cc
+++ b/src/tracing/ipc/consumer/consumer_ipc_client_impl.cc
@@ -16,9 +16,10 @@
#include "src/tracing/ipc/consumer/consumer_ipc_client_impl.h"
-#include <inttypes.h>
#include <string.h>
+#include <cinttypes>
+
#include "perfetto/base/task_runner.h"
#include "perfetto/ext/ipc/client.h"
#include "perfetto/ext/tracing/core/consumer.h"
@@ -277,7 +278,7 @@ void ConsumerIPCClientImpl::Attach(const std::string& key) {
}
const TraceConfig& trace_config = response->trace_config();
- // If attached succesfully, also attach to the end-of-trace
+ // If attached successfully, also attach to the end-of-trace
// notificaton callback, via EnableTracing(attach_notification_only).
protos::gen::EnableTracingRequest enable_req;
enable_req.set_attach_notification_only(true);
diff --git a/src/tracing/ipc/default_socket.cc b/src/tracing/ipc/default_socket.cc
index 3ad5cee74..b210e023c 100644
--- a/src/tracing/ipc/default_socket.cc
+++ b/src/tracing/ipc/default_socket.cc
@@ -23,19 +23,22 @@
#include "perfetto/ext/tracing/core/basic_types.h"
#include <stdlib.h>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+ PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+ PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
#include <unistd.h>
+#endif
namespace perfetto {
-#if !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-// On non-Android platforms, check /run/perfetto/ before using /tmp/ as the
-// socket base directory.
namespace {
+
const char* kRunPerfettoBaseDir = "/run/perfetto/";
+// On Linux and CrOS, check /run/perfetto/ before using /tmp/ as the socket
+// base directory.
bool UseRunPerfettoBaseDir() {
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
- PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
- PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX)
// Note that the trailing / in |kRunPerfettoBaseDir| ensures we are checking
// against a directory, not a file.
int res = PERFETTO_EINTR(access(kRunPerfettoBaseDir, X_OK));
@@ -44,18 +47,24 @@ bool UseRunPerfettoBaseDir() {
// If the path doesn't exist (ENOENT), fail silently to the caller. Otherwise,
// fail with an explicit error message.
- if (errno != ENOENT) {
+ if (errno != ENOENT
+#if PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
+ // access(2) won't return EPERM, but Chromium sandbox returns EPERM if the
+ // sandbox doesn't allow the call (e.g. in the child processes).
+ && errno != EPERM
+#endif
+ ) {
PERFETTO_PLOG("%s exists but cannot be accessed. Falling back on /tmp/ ",
kRunPerfettoBaseDir);
}
return false;
#else
+ base::ignore_result(kRunPerfettoBaseDir);
return false;
#endif
}
} // anonymous namespace
-#endif // !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
static_assert(kInvalidUid == ipc::kInvalidUid, "kInvalidUid mismatching");
@@ -74,6 +83,7 @@ const char* GetProducerSocket() {
name = producer_socket;
#endif
}
+ base::ignore_result(UseRunPerfettoBaseDir); // Silence unused func warnings.
return name;
}
diff --git a/src/tracing/ipc/producer/producer_ipc_client_impl.cc b/src/tracing/ipc/producer/producer_ipc_client_impl.cc
index 98072cdc0..abbdab3c0 100644
--- a/src/tracing/ipc/producer/producer_ipc_client_impl.cc
+++ b/src/tracing/ipc/producer/producer_ipc_client_impl.cc
@@ -16,7 +16,8 @@
#include "src/tracing/ipc/producer/producer_ipc_client_impl.h"
-#include <inttypes.h>
+#include <cinttypes>
+
#include <string.h>
#include "perfetto/base/logging.h"
@@ -30,7 +31,12 @@
#include "perfetto/tracing/core/data_source_config.h"
#include "perfetto/tracing/core/data_source_descriptor.h"
#include "perfetto/tracing/core/trace_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include "src/tracing/ipc/shared_memory_windows.h"
+#else
#include "src/tracing/ipc/posix_shared_memory.h"
+#endif
// TODO(fmayer): think to what happens when ProducerIPCClientImpl gets destroyed
// w.r.t. the Producer pointer. Also think to lifetime of the Producer* during
@@ -159,17 +165,15 @@ void ProducerIPCClientImpl::OnConnect() {
int shm_fd = -1;
if (shared_memory_) {
- shm_fd = static_cast<PosixSharedMemory*>(shared_memory_.get())->fd();
req.set_producer_provided_shmem(true);
- }
-
-#if PERFETTO_DCHECK_IS_ON()
- req.set_build_flags(
- protos::gen::InitializeConnectionRequest::BUILD_FLAGS_DCHECKS_ON);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ auto key = static_cast<SharedMemoryWindows*>(shared_memory_.get())->key();
+ req.set_shm_key_windows(key);
#else
- req.set_build_flags(
- protos::gen::InitializeConnectionRequest::BUILD_FLAGS_DCHECKS_OFF);
+ shm_fd = static_cast<PosixSharedMemory*>(shared_memory_.get())->fd();
#endif
+ }
+
req.set_sdk_version(base::GetVersionString());
producer_port_.InitializeConnection(req, std::move(on_init), shm_fd);
@@ -255,15 +259,25 @@ void ProducerIPCClientImpl::OnServiceRequest(
}
if (cmd.has_setup_tracing()) {
+ std::unique_ptr<SharedMemory> ipc_shared_memory;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ const std::string& shm_key = cmd.setup_tracing().shm_key_windows();
+ if (!shm_key.empty())
+ ipc_shared_memory = SharedMemoryWindows::Attach(shm_key);
+#else
base::ScopedFile shmem_fd = ipc_channel_->TakeReceivedFD();
if (shmem_fd) {
- // This is the nominal case used in most configurations, where the service
- // provides the SMB.
- PERFETTO_CHECK(!is_shmem_provided_by_producer_ && !shared_memory_);
// TODO(primiano): handle mmap failure in case of OOM.
- shared_memory_ =
+ ipc_shared_memory =
PosixSharedMemory::AttachToFd(std::move(shmem_fd),
/*require_seals_if_supported=*/false);
+ }
+#endif
+ if (ipc_shared_memory) {
+ // This is the nominal case used in most configurations, where the service
+ // provides the SMB.
+ PERFETTO_CHECK(!is_shmem_provided_by_producer_ && !shared_memory_);
+ shared_memory_ = std::move(ipc_shared_memory);
shared_buffer_page_size_kb_ =
cmd.setup_tracing().shared_buffer_page_size_kb();
shared_memory_arbiter_ = SharedMemoryArbiter::CreateInstance(
@@ -327,6 +341,24 @@ void ProducerIPCClientImpl::RegisterDataSource(
producer_port_.RegisterDataSource(req, std::move(async_response));
}
+void ProducerIPCClientImpl::UpdateDataSource(
+ const DataSourceDescriptor& descriptor) {
+ PERFETTO_DCHECK_THREAD(thread_checker_);
+ if (!connected_) {
+ PERFETTO_DLOG(
+ "Cannot UpdateDataSource(), not connected to tracing service");
+ }
+ protos::gen::UpdateDataSourceRequest req;
+ *req.mutable_data_source_descriptor() = descriptor;
+ ipc::Deferred<protos::gen::UpdateDataSourceResponse> async_response;
+ async_response.Bind(
+ [](ipc::AsyncResult<protos::gen::UpdateDataSourceResponse> response) {
+ if (!response)
+ PERFETTO_DLOG("UpdateDataSource() failed: connection reset");
+ });
+ producer_port_.UpdateDataSource(req, std::move(async_response));
+}
+
void ProducerIPCClientImpl::UnregisterDataSource(const std::string& name) {
PERFETTO_DCHECK_THREAD(thread_checker_);
if (!connected_) {
diff --git a/src/tracing/ipc/producer/producer_ipc_client_impl.h b/src/tracing/ipc/producer/producer_ipc_client_impl.h
index 3d66849c5..e5553632e 100644
--- a/src/tracing/ipc/producer/producer_ipc_client_impl.h
+++ b/src/tracing/ipc/producer/producer_ipc_client_impl.h
@@ -63,6 +63,7 @@ class ProducerIPCClientImpl : public TracingService::ProducerEndpoint,
// These methods are invoked by the actual Producer(s) code by clients of the
// tracing library, which know nothing about the IPC transport.
void RegisterDataSource(const DataSourceDescriptor&) override;
+ void UpdateDataSource(const DataSourceDescriptor&) override;
void UnregisterDataSource(const std::string& name) override;
void RegisterTraceWriter(uint32_t writer_id, uint32_t target_buffer) override;
void UnregisterTraceWriter(uint32_t writer_id) override;
diff --git a/src/tracing/ipc/service/consumer_ipc_service.cc b/src/tracing/ipc/service/consumer_ipc_service.cc
index daab5de0e..09b33a8fb 100644
--- a/src/tracing/ipc/service/consumer_ipc_service.cc
+++ b/src/tracing/ipc/service/consumer_ipc_service.cc
@@ -16,7 +16,7 @@
#include "src/tracing/ipc/service/consumer_ipc_service.h"
-#include <inttypes.h>
+#include <cinttypes>
#include "perfetto/base/logging.h"
#include "perfetto/base/task_runner.h"
diff --git a/src/tracing/ipc/service/producer_ipc_service.cc b/src/tracing/ipc/service/producer_ipc_service.cc
index 76ae2e848..5f9a3870e 100644
--- a/src/tracing/ipc/service/producer_ipc_service.cc
+++ b/src/tracing/ipc/service/producer_ipc_service.cc
@@ -16,7 +16,7 @@
#include "src/tracing/ipc/service/producer_ipc_service.h"
-#include <inttypes.h>
+#include <cinttypes>
#include "perfetto/base/logging.h"
#include "perfetto/base/task_runner.h"
@@ -26,7 +26,12 @@
#include "perfetto/ext/tracing/core/tracing_service.h"
#include "perfetto/tracing/core/data_source_config.h"
#include "perfetto/tracing/core/data_source_descriptor.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include "src/tracing/ipc/shared_memory_windows.h"
+#else
#include "src/tracing/ipc/posix_shared_memory.h"
+#endif
// The remote Producer(s) are not trusted. All the methods from the ProducerPort
// IPC layer (e.g. RegisterDataSource()) must assume that the remote Producer is
@@ -79,21 +84,21 @@ void ProducerIPCService::InitializeConnection(
break;
}
-#if PERFETTO_DCHECK_IS_ON()
- if (req.build_flags() ==
- protos::gen::InitializeConnectionRequest::BUILD_FLAGS_DCHECKS_OFF) {
- PERFETTO_LOG(
- "The producer is built with NDEBUG but the service binary was built "
- "with the DEBUG flag. This will likely cause crashes.");
- // The other way round (DEBUG producer with NDEBUG service) is expected to
- // work.
- }
-#endif
-
// If the producer provided an SMB, tell the service to attempt to adopt it.
std::unique_ptr<SharedMemory> shmem;
if (req.producer_provided_shmem()) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ if (!req.has_shm_key_windows() || req.shm_key_windows().empty()) {
+ PERFETTO_ELOG(
+ "shm_key_windows must be non-empty when "
+ "producer_provided_shmem = true");
+ } else {
+ shmem = SharedMemoryWindows::Attach(req.shm_key_windows());
+ // Attach() does error logging if something fails, no need to extra ELOGs.
+ }
+#else
base::ScopedFile shmem_fd = ipc::Service::TakeReceivedFD();
+
if (shmem_fd) {
shmem = PosixSharedMemory::AttachToFd(
std::move(shmem_fd), /*require_seals_if_supported=*/true);
@@ -107,11 +112,12 @@ void ProducerIPCService::InitializeConnection(
"InitializeConnectionRequest's producer_provided_shmem flag is set "
"but the producer didn't provide an FD");
}
+#endif
}
// ConnectProducer will call OnConnect() on the next task.
producer->service_endpoint = core_service_->ConnectProducer(
- producer.get(), client_info.uid(), req.producer_name(),
+ producer.get(), client_info.uid(), client_info.pid(), req.producer_name(),
req.shared_memory_size_hint_bytes(),
/*in_process=*/false, smb_scraping_mode,
req.shared_memory_page_size_hint_bytes(), std::move(shmem),
@@ -159,6 +165,29 @@ void ProducerIPCService::RegisterDataSource(
}
}
+// Called by the remote Producer through the IPC channel.
+void ProducerIPCService::UpdateDataSource(
+ const protos::gen::UpdateDataSourceRequest& req,
+ DeferredUpdateDataSourceResponse response) {
+ RemoteProducer* producer = GetProducerForCurrentRequest();
+ if (!producer) {
+ PERFETTO_DLOG(
+ "Producer invoked UpdateDataSource() before InitializeConnection()");
+ if (response.IsBound())
+ response.Reject();
+ return;
+ }
+
+ const DataSourceDescriptor& dsd = req.data_source_descriptor();
+ GetProducerForCurrentRequest()->service_endpoint->UpdateDataSource(dsd);
+
+ // UpdateDataSource doesn't expect any meaningful response.
+ if (response.IsBound()) {
+ response.Resolve(
+ ipc::AsyncResult<protos::gen::UpdateDataSourceResponse>::Create());
+ }
+}
+
// Called by the IPC layer.
void ProducerIPCService::OnClientDisconnected() {
ipc::ClientID client_id = ipc::Service::client_info().client_id();
@@ -456,10 +485,17 @@ void ProducerIPCService::RemoteProducer::SendSetupTracing() {
// Nominal case (% Chrome): service provides SMB.
setup_tracing->set_shared_buffer_page_size_kb(
static_cast<uint32_t>(service_endpoint->shared_buffer_page_size_kb()));
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ const std::string& shm_key =
+ static_cast<SharedMemoryWindows*>(service_endpoint->shared_memory())
+ ->key();
+ setup_tracing->set_shm_key_windows(shm_key);
+#else
const int shm_fd =
static_cast<PosixSharedMemory*>(service_endpoint->shared_memory())
->fd();
cmd.set_fd(shm_fd);
+#endif
}
async_producer_commands.Resolve(std::move(cmd));
}
diff --git a/src/tracing/ipc/service/producer_ipc_service.h b/src/tracing/ipc/service/producer_ipc_service.h
index f22f18617..b42ed73c0 100644
--- a/src/tracing/ipc/service/producer_ipc_service.h
+++ b/src/tracing/ipc/service/producer_ipc_service.h
@@ -48,6 +48,8 @@ class ProducerIPCService : public protos::gen::ProducerPort {
DeferredInitializeConnectionResponse) override;
void RegisterDataSource(const protos::gen::RegisterDataSourceRequest&,
DeferredRegisterDataSourceResponse) override;
+ void UpdateDataSource(const protos::gen::UpdateDataSourceRequest&,
+ DeferredUpdateDataSourceResponse) override;
void UnregisterDataSource(const protos::gen::UnregisterDataSourceRequest&,
DeferredUnregisterDataSourceResponse) override;
void RegisterTraceWriter(const protos::gen::RegisterTraceWriterRequest&,
diff --git a/src/tracing/ipc/service/service_ipc_host_impl.cc b/src/tracing/ipc/service/service_ipc_host_impl.cc
index d19fef6d6..5618b3cb3 100644
--- a/src/tracing/ipc/service/service_ipc_host_impl.cc
+++ b/src/tracing/ipc/service/service_ipc_host_impl.cc
@@ -20,10 +20,15 @@
#include "perfetto/base/task_runner.h"
#include "perfetto/ext/ipc/host.h"
#include "perfetto/ext/tracing/core/tracing_service.h"
-#include "src/tracing/ipc/posix_shared_memory.h"
#include "src/tracing/ipc/service/consumer_ipc_service.h"
#include "src/tracing/ipc/service/producer_ipc_service.h"
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include "src/tracing/ipc/shared_memory_windows.h"
+#else
+#include "src/tracing/ipc/posix_shared_memory.h"
+#endif
+
namespace perfetto {
// TODO(fmayer): implement per-uid connection limit (b/69093705).
@@ -66,8 +71,13 @@ bool ServiceIPCHostImpl::Start(base::ScopedSocketHandle producer_socket_fd,
bool ServiceIPCHostImpl::DoStart() {
// Create and initialize the platform-independent tracing business logic.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ std::unique_ptr<SharedMemory::Factory> shm_factory(
+ new SharedMemoryWindows::Factory());
+#else
std::unique_ptr<SharedMemory::Factory> shm_factory(
new PosixSharedMemory::Factory());
+#endif
svc_ = TracingService::CreateInstance(std::move(shm_factory), task_runner_);
if (!producer_ipc_port_ || !consumer_ipc_port_) {
diff --git a/src/tracing/ipc/shared_memory_windows.cc b/src/tracing/ipc/shared_memory_windows.cc
new file mode 100644
index 000000000..579d81018
--- /dev/null
+++ b/src/tracing/ipc/shared_memory_windows.cc
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/tracing/ipc/shared_memory_windows.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+#include <memory>
+#include <random>
+
+#include <Windows.h>
+
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/string_utils.h"
+
+namespace perfetto {
+
+// static
+std::unique_ptr<SharedMemoryWindows> SharedMemoryWindows::Create(size_t size) {
+ base::ScopedPlatformHandle shmem_handle;
+ std::random_device rnd_dev;
+ uint64_t rnd_key = (static_cast<uint64_t>(rnd_dev()) << 32) | rnd_dev();
+ std::string key = "perfetto_shm_" + base::Uint64ToHexStringNoPrefix(rnd_key);
+ shmem_handle.reset(CreateFileMappingA(
+ INVALID_HANDLE_VALUE, // Use paging file.
+ nullptr, // Default security.
+ PAGE_READWRITE,
+ static_cast<DWORD>(size >> 32), // maximum object size (high-order DWORD)
+ static_cast<DWORD>(size), // maximum object size (low-order DWORD)
+ key.c_str()));
+
+ if (!shmem_handle) {
+ PERFETTO_PLOG("CreateFileMapping() call failed");
+ return nullptr;
+ }
+ void* start =
+ MapViewOfFile(*shmem_handle, FILE_MAP_ALL_ACCESS, /*offsetHigh=*/0,
+ /*offsetLow=*/0, size);
+ if (!start) {
+ PERFETTO_PLOG("MapViewOfFile() failed");
+ return nullptr;
+ }
+
+ return std::unique_ptr<SharedMemoryWindows>(new SharedMemoryWindows(
+ start, size, std::move(key), std::move(shmem_handle)));
+}
+
+// static
+std::unique_ptr<SharedMemoryWindows> SharedMemoryWindows::Attach(
+ const std::string& key) {
+ base::ScopedPlatformHandle shmem_handle;
+ shmem_handle.reset(
+ OpenFileMappingA(FILE_MAP_ALL_ACCESS, /*inherit=*/false, key.c_str()));
+ if (!shmem_handle) {
+ PERFETTO_PLOG("Failed to OpenFileMapping()");
+ return nullptr;
+ }
+
+ void* start =
+ MapViewOfFile(*shmem_handle, FILE_MAP_ALL_ACCESS, /*offsetHigh=*/0,
+ /*offsetLow=*/0, /*dwNumberOfBytesToMap=*/0);
+ if (!start) {
+ PERFETTO_PLOG("MapViewOfFile() failed");
+ return nullptr;
+ }
+
+ MEMORY_BASIC_INFORMATION info{};
+ if (!VirtualQuery(start, &info, sizeof(info))) {
+ PERFETTO_PLOG("VirtualQuery() failed");
+ return nullptr;
+ }
+ size_t size = info.RegionSize;
+ return std::unique_ptr<SharedMemoryWindows>(
+ new SharedMemoryWindows(start, size, key, std::move(shmem_handle)));
+}
+
+SharedMemoryWindows::SharedMemoryWindows(void* start,
+ size_t size,
+ std::string key,
+ base::ScopedPlatformHandle handle)
+ : start_(start),
+ size_(size),
+ key_(std::move(key)),
+ handle_(std::move(handle)) {}
+
+SharedMemoryWindows::~SharedMemoryWindows() {
+ if (start_)
+ UnmapViewOfFile(start_);
+}
+
+SharedMemoryWindows::Factory::~Factory() = default;
+
+std::unique_ptr<SharedMemory> SharedMemoryWindows::Factory::CreateSharedMemory(
+ size_t size) {
+ return SharedMemoryWindows::Create(size);
+}
+
+} // namespace perfetto
+
+#endif // !OS_WIN
diff --git a/src/tracing/ipc/shared_memory_windows.h b/src/tracing/ipc/shared_memory_windows.h
new file mode 100644
index 000000000..803c8a8ed
--- /dev/null
+++ b/src/tracing/ipc/shared_memory_windows.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_IPC_SHARED_MEMORY_WINDOWS_H_
+#define SRC_TRACING_IPC_SHARED_MEMORY_WINDOWS_H_
+
+#include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+#include "perfetto/base/build_config.h"
+#include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/tracing/core/shared_memory.h"
+
+namespace perfetto {
+
+// Implements the SharedMemory and its factory for the Windows IPC transport.
+// This used only for standalone builds and NOT in chromium, which instead uses
+// a custom Mojo wrapper (MojoSharedMemory in chromium's //services/tracing/).
+class SharedMemoryWindows : public SharedMemory {
+ public:
+ class Factory : public SharedMemory::Factory {
+ public:
+ ~Factory() override;
+ std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) override;
+ };
+
+ // Create a brand new SHM region.
+ static std::unique_ptr<SharedMemoryWindows> Create(size_t size);
+ static std::unique_ptr<SharedMemoryWindows> Attach(const std::string& key);
+ ~SharedMemoryWindows() override;
+ const std::string& key() const { return key_; }
+
+ // SharedMemory implementation.
+ void* start() const override { return start_; }
+ size_t size() const override { return size_; }
+
+ private:
+ SharedMemoryWindows(void* start,
+ size_t size,
+ std::string,
+ base::ScopedPlatformHandle);
+ SharedMemoryWindows(const SharedMemoryWindows&) = delete;
+ SharedMemoryWindows& operator=(const SharedMemoryWindows&) = delete;
+
+ void* const start_;
+ const size_t size_;
+ std::string key_;
+ base::ScopedPlatformHandle handle_;
+};
+
+} // namespace perfetto
+
+#endif // OS_WIN
+
+#endif // SRC_TRACING_IPC_SHARED_MEMORY_WINDOWS_H_
diff --git a/src/tracing/platform.cc b/src/tracing/platform.cc
index e6865cd66..6b2cd2faa 100644
--- a/src/tracing/platform.cc
+++ b/src/tracing/platform.cc
@@ -29,4 +29,7 @@ PlatformThreadLocalObject::CreateInstance() {
return std::unique_ptr<PlatformThreadLocalObject>(new internal::TracingTLS());
}
+// static
+base::PlatformProcessId Platform::process_id_ = 0;
+
} // namespace perfetto
diff --git a/src/tracing/platform_posix.cc b/src/tracing/platform_posix.cc
index 6b04aafd4..cf2bcff49 100644
--- a/src/tracing/platform_posix.cc
+++ b/src/tracing/platform_posix.cc
@@ -39,6 +39,7 @@ class PlatformPosix : public Platform {
~PlatformPosix() override;
ThreadLocalObject* GetOrCreateThreadLocalObject() override;
+
std::unique_ptr<base::TaskRunner> CreateTaskRunner(
const CreateTaskRunnerArgs&) override;
std::string GetCurrentProcessName() override;
@@ -47,22 +48,39 @@ class PlatformPosix : public Platform {
pthread_key_t tls_key_{};
};
+PlatformPosix* g_instance = nullptr;
+
using ThreadLocalObject = Platform::ThreadLocalObject;
PlatformPosix::PlatformPosix() {
+ PERFETTO_CHECK(!g_instance);
+ g_instance = this;
auto tls_dtor = [](void* obj) {
+ // The Posix TLS implementation resets the key before calling this dtor.
+ // Here we re-reset it to the object we are about to delete. This is to
+ // handle re-entrant usages of tracing in the PostTask done during the dtor
+ // (see comments in TracingTLS::~TracingTLS()). Chromium's platform
+ // implementation (which does NOT use this platform impl) has a similar
+ // workaround (https://crrev.com/c/2748300).
+ pthread_setspecific(g_instance->tls_key_, obj);
delete static_cast<ThreadLocalObject*>(obj);
+ pthread_setspecific(g_instance->tls_key_, nullptr);
};
PERFETTO_CHECK(pthread_key_create(&tls_key_, tls_dtor) == 0);
}
PlatformPosix::~PlatformPosix() {
pthread_key_delete(tls_key_);
+ g_instance = nullptr;
}
ThreadLocalObject* PlatformPosix::GetOrCreateThreadLocalObject() {
// In chromium this should be implemented using base::ThreadLocalStorage.
- auto tls = static_cast<ThreadLocalObject*>(pthread_getspecific(tls_key_));
+ void* tls_ptr = pthread_getspecific(tls_key_);
+
+ // This is needed to handle re-entrant calls during TLS dtor.
+ // See comments in platform.cc and aosp/1712371 .
+ ThreadLocalObject* tls = static_cast<ThreadLocalObject*>(tls_ptr);
if (!tls) {
tls = ThreadLocalObject::CreateInstance().release();
pthread_setspecific(tls_key_, tls);
@@ -71,9 +89,9 @@ ThreadLocalObject* PlatformPosix::GetOrCreateThreadLocalObject() {
}
std::unique_ptr<base::TaskRunner> PlatformPosix::CreateTaskRunner(
- const CreateTaskRunnerArgs&) {
- return std::unique_ptr<base::TaskRunner>(
- new base::ThreadTaskRunner(base::ThreadTaskRunner::CreateAndStart()));
+ const CreateTaskRunnerArgs& args) {
+ return std::unique_ptr<base::TaskRunner>(new base::ThreadTaskRunner(
+ base::ThreadTaskRunner::CreateAndStart(args.name_for_debugging)));
}
std::string PlatformPosix::GetCurrentProcessName() {
diff --git a/src/tracing/platform_windows.cc b/src/tracing/platform_windows.cc
new file mode 100644
index 000000000..0f1664c76
--- /dev/null
+++ b/src/tracing/platform_windows.cc
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+#include <Windows.h>
+
+#include "perfetto/ext/base/thread_task_runner.h"
+#include "perfetto/tracing/internal/tracing_tls.h"
+#include "perfetto/tracing/platform.h"
+
+// Thread Termination Callbacks.
+// Windows doesn't support a per-thread destructor with its
+// TLS primitives. So, we build it manually by inserting a
+// function to be called on each thread's exit.
+// This magic is from chromium's base/threading/thread_local_storage_win.cc
+// which in turn is from http://www.codeproject.com/threads/tls.asp.
+
+#ifdef _WIN64
+#pragma comment(linker, "/INCLUDE:_tls_used")
+#pragma comment(linker, "/INCLUDE:perfetto_thread_callback_base")
+#else
+#pragma comment(linker, "/INCLUDE:__tls_used")
+#pragma comment(linker, "/INCLUDE:_perfetto_thread_callback_base")
+#endif
+
+namespace perfetto {
+
+namespace {
+
+class PlatformWindows : public Platform {
+ public:
+ static PlatformWindows* instance;
+ PlatformWindows();
+ ~PlatformWindows() override;
+
+ ThreadLocalObject* GetOrCreateThreadLocalObject() override;
+ std::unique_ptr<base::TaskRunner> CreateTaskRunner(
+ const CreateTaskRunnerArgs&) override;
+ std::string GetCurrentProcessName() override;
+ void OnThreadExit();
+
+ private:
+ DWORD tls_key_{};
+};
+
+using ThreadLocalObject = Platform::ThreadLocalObject;
+
+// static
+PlatformWindows* PlatformWindows::instance = nullptr;
+
+PlatformWindows::PlatformWindows() {
+ instance = this;
+ tls_key_ = ::TlsAlloc();
+ PERFETTO_CHECK(tls_key_ != TLS_OUT_OF_INDEXES);
+}
+
+PlatformWindows::~PlatformWindows() {
+ ::TlsFree(tls_key_);
+ instance = nullptr;
+}
+
+void PlatformWindows::OnThreadExit() {
+ auto tls = static_cast<ThreadLocalObject*>(::TlsGetValue(tls_key_));
+ if (tls) {
+ // At this point we rely on the TLS object to be still set to the TracingTLS
+ // we are deleting. See comments in TracingTLS::~TracingTLS().
+ delete tls;
+ }
+}
+
+ThreadLocalObject* PlatformWindows::GetOrCreateThreadLocalObject() {
+ void* tls_ptr = ::TlsGetValue(tls_key_);
+
+ auto* tls = static_cast<ThreadLocalObject*>(tls_ptr);
+ if (!tls) {
+ tls = ThreadLocalObject::CreateInstance().release();
+ ::TlsSetValue(tls_key_, tls);
+ }
+ return tls;
+}
+
+std::unique_ptr<base::TaskRunner> PlatformWindows::CreateTaskRunner(
+ const CreateTaskRunnerArgs& args) {
+ return std::unique_ptr<base::TaskRunner>(new base::ThreadTaskRunner(
+ base::ThreadTaskRunner::CreateAndStart(args.name_for_debugging)));
+}
+
+std::string PlatformWindows::GetCurrentProcessName() {
+ char buf[MAX_PATH];
+ auto len = ::GetModuleFileNameA(nullptr /*current*/, buf, sizeof(buf));
+ std::string name(buf, static_cast<size_t>(len));
+ size_t sep = name.find_last_of('\\');
+ if (sep != std::string::npos)
+ name = name.substr(sep + 1);
+ return name;
+}
+
+} // namespace
+
+// static
+Platform* Platform::GetDefaultPlatform() {
+ static PlatformWindows* thread_safe_init_instance = new PlatformWindows();
+ return thread_safe_init_instance;
+}
+
+} // namespace perfetto
+
+// -----------------------
+// Thread-local destructor
+// -----------------------
+
+// .CRT$XLA to .CRT$XLZ is an array of PIMAGE_TLS_CALLBACK pointers that are
+// called automatically by the OS loader code (not the CRT) when the module is
+// loaded and on thread creation. They are NOT called if the module has been
+// loaded by a LoadLibrary() call. It must have implicitly been loaded at
+// process startup.
+// See VC\crt\src\tlssup.c for reference.
+
+// extern "C" suppresses C++ name mangling so we know the symbol name for the
+// linker /INCLUDE:symbol pragma above.
+extern "C" {
+// The linker must not discard perfetto_thread_callback_base. (We force a
+// reference to this variable with a linker /INCLUDE:symbol pragma to ensure
+// that.) If this variable is discarded, the OnThreadExit function will never be
+// called.
+
+void NTAPI PerfettoOnThreadExit(PVOID, DWORD, PVOID);
+void NTAPI PerfettoOnThreadExit(PVOID module, DWORD reason, PVOID reserved) {
+ if (reason == DLL_THREAD_DETACH || reason == DLL_PROCESS_DETACH) {
+ if (perfetto::PlatformWindows::instance)
+ perfetto::PlatformWindows::instance->OnThreadExit();
+ }
+}
+
+#ifdef _WIN64
+
+// .CRT section is merged with .rdata on x64 so it must be constant data.
+#pragma const_seg(".CRT$XLP")
+
+// When defining a const variable, it must have external linkage to be sure the
+// linker doesn't discard it.
+extern const PIMAGE_TLS_CALLBACK perfetto_thread_callback_base;
+const PIMAGE_TLS_CALLBACK perfetto_thread_callback_base = PerfettoOnThreadExit;
+
+// Reset the default section.
+#pragma const_seg()
+
+#else // _WIN64
+
+#pragma data_seg(".CRT$XLP")
+PIMAGE_TLS_CALLBACK perfetto_thread_callback_base = PerfettoOnThreadExit;
+// Reset the default section.
+#pragma data_seg()
+
+#endif // _WIN64
+
+} // extern "C"
+
+#endif // OS_WIN
diff --git a/src/tracing/test/api_integrationtest.cc b/src/tracing/test/api_integrationtest.cc
index 061e2fe9e..0604d091e 100644
--- a/src/tracing/test/api_integrationtest.cc
+++ b/src/tracing/test/api_integrationtest.cc
@@ -18,11 +18,13 @@
#include <chrono>
#include <condition_variable>
+#include <fstream>
#include <functional>
#include <list>
#include <mutex>
#include <regex>
#include <thread>
+#include <unordered_set>
#include <vector>
// We also want to test legacy trace events.
@@ -43,6 +45,7 @@
#include "src/tracing/test/api_test_support.h"
#include "src/tracing/test/tracing_module.h"
+#include "perfetto/protozero/scattered_heap_buffer.h"
#include "perfetto/tracing/core/data_source_descriptor.h"
#include "perfetto/tracing/core/trace_config.h"
@@ -55,8 +58,10 @@
#include "protos/perfetto/common/trace_stats.gen.h"
#include "protos/perfetto/common/tracing_service_state.gen.h"
#include "protos/perfetto/common/track_event_descriptor.gen.h"
+#include "protos/perfetto/common/track_event_descriptor.pbzero.h"
#include "protos/perfetto/config/interceptor_config.gen.h"
#include "protos/perfetto/config/track_event/track_event_config.gen.h"
+#include "protos/perfetto/trace/clock_snapshot.gen.h"
#include "protos/perfetto/trace/clock_snapshot.pbzero.h"
#include "protos/perfetto/trace/gpu/gpu_render_stage_event.gen.h"
#include "protos/perfetto/trace/gpu/gpu_render_stage_event.pbzero.h"
@@ -70,6 +75,7 @@
#include "protos/perfetto/trace/trace.pbzero.h"
#include "protos/perfetto/trace/trace_packet.gen.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
+#include "protos/perfetto/trace/trace_packet_defaults.gen.h"
#include "protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h"
#include "protos/perfetto/trace/track_event/chrome_process_descriptor.pbzero.h"
#include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
@@ -122,6 +128,22 @@ struct std::hash<SourceLocation> {
}
};
+static void WriteFile(const std::string& file_name,
+ const char* content,
+ size_t len) {
+ std::ofstream output;
+ output.open(file_name.c_str(), std::ios::out | std::ios::binary);
+ output.write(content, static_cast<std::streamsize>(len));
+ output.close();
+}
+
+// Unused in merged code, but very handy for debugging when trace generated in
+// a test needs to be exported, to understand it further with other tools.
+__attribute__((unused)) static void WriteFile(const std::string& file_name,
+ const std::vector<char>& data) {
+ return WriteFile(file_name, data.data(), data.size());
+}
+
// Represents an opaque (from Perfetto's point of view) thread identifier (e.g.,
// base::PlatformThreadId in Chromium).
struct MyThreadId {
@@ -162,6 +184,7 @@ struct TraceTimestampTraits<MyTimestamp> {
namespace {
using perfetto::TracingInitArgs;
+using perfetto::internal::TrackEventInternal;
using ::testing::_;
using ::testing::ContainerEq;
using ::testing::ElementsAre;
@@ -247,7 +270,7 @@ class MockDataSource2 : public perfetto::DataSource<MockDataSource2> {
class MockTracingMuxer : public perfetto::internal::TracingMuxer {
public:
struct DataSource {
- const perfetto::DataSourceDescriptor dsd;
+ perfetto::DataSourceDescriptor dsd;
perfetto::internal::DataSourceStaticState* static_state;
};
@@ -264,6 +287,17 @@ class MockTracingMuxer : public perfetto::internal::TracingMuxer {
return true;
}
+ void UpdateDataSourceDescriptor(
+ const perfetto::DataSourceDescriptor& dsd,
+ const perfetto::internal::DataSourceStaticState* static_state) override {
+ for (auto& rds : data_sources) {
+ if (rds.static_state == static_state) {
+ rds.dsd = dsd;
+ return;
+ }
+ }
+ }
+
std::unique_ptr<perfetto::TraceWriterBase> CreateTraceWriter(
perfetto::internal::DataSourceStaticState*,
uint32_t,
@@ -302,6 +336,7 @@ bool TestIncrementalState::destroyed;
struct TestIncrementalDataSourceTraits
: public perfetto::DefaultDataSourceTraits {
using IncrementalStateType = TestIncrementalState;
+ using CustomTlsState = void;
};
class TestIncrementalDataSource
@@ -344,6 +379,67 @@ class TestTracingPolicy : public perfetto::TracingPolicy {
TestTracingPolicy* g_test_tracing_policy = new TestTracingPolicy(); // Leaked.
+class ParsedIncrementalState {
+ public:
+ void ClearIfNeeded(const perfetto::protos::gen::TracePacket& packet) {
+ if (packet.sequence_flags() &
+ perfetto::protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED) {
+ incremental_state_was_cleared_ = true;
+ categories_.clear();
+ event_names_.clear();
+ debug_annotation_names_.clear();
+ seen_tracks_.clear();
+ }
+ }
+
+ void Parse(const perfetto::protos::gen::TracePacket& packet) {
+ // Update incremental state.
+ if (packet.has_interned_data()) {
+ const auto& interned_data = packet.interned_data();
+ for (const auto& it : interned_data.event_categories()) {
+ EXPECT_EQ(categories_.find(it.iid()), categories_.end());
+ categories_[it.iid()] = it.name();
+ }
+ for (const auto& it : interned_data.event_names()) {
+ EXPECT_EQ(event_names_.find(it.iid()), event_names_.end());
+ event_names_[it.iid()] = it.name();
+ }
+ for (const auto& it : interned_data.debug_annotation_names()) {
+ EXPECT_EQ(debug_annotation_names_.find(it.iid()),
+ debug_annotation_names_.end());
+ debug_annotation_names_[it.iid()] = it.name();
+ }
+ }
+ }
+
+ bool HasSeenTrack(uint64_t uuid) const {
+ return seen_tracks_.count(uuid) != 0;
+ }
+
+ void InsertTrack(uint64_t uuid) { seen_tracks_.insert(uuid); }
+
+ std::string GetCategory(uint64_t iid) { return categories_[iid]; }
+
+ std::string GetEventName(const perfetto::protos::gen::TrackEvent& event) {
+ if (event.has_name_iid())
+ return event_names_[event.name_iid()];
+ return event.name();
+ }
+
+ std::string GetDebugAnnotationName(uint64_t iid) {
+ return debug_annotation_names_[iid];
+ }
+
+ bool WasCleared() const { return incremental_state_was_cleared_; }
+
+ private:
+ bool incremental_state_was_cleared_ = false;
+ std::map<uint64_t, std::string> categories_;
+ std::map<uint64_t, std::string> event_names_;
+ std::map<uint64_t, std::string> debug_annotation_names_;
+ std::set<uint64_t> seen_tracks_;
+};
+
// -------------------------
// Declaration of test class
// -------------------------
@@ -356,30 +452,16 @@ class PerfettoApiTest : public ::testing::TestWithParam<perfetto::BackendType> {
g_test_tracing_policy->should_allow_consumer_connection = true;
// Start a fresh system service for this test, tearing down any previous
- // service that was running.
- uint32_t supported_backends =
- perfetto::kInProcessBackend | perfetto::kSystemBackend;
- if (!perfetto::test::StartSystemService())
- supported_backends &= ~perfetto::kSystemBackend;
-
- // If the system backend wasn't supported, skip all system backend tests.
- auto backend = GetParam();
- if (!(supported_backends & backend))
+ // service that was running. If the system backend isn't supported, skip all
+ // system backend tests.
+ if (GetParam() == perfetto::kSystemBackend &&
+ !perfetto::test::StartSystemService()) {
GTEST_SKIP();
-
- static bool was_initialized;
- if (!was_initialized) {
- EXPECT_FALSE(perfetto::Tracing::IsInitialized());
- was_initialized = true;
- } else {
- EXPECT_TRUE(perfetto::Tracing::IsInitialized());
}
- // Since the client API can only be initialized once per process, initialize
- // both the in-process and system backends for every test here. The actual
- // service to be used is chosen by the test parameter.
+ EXPECT_FALSE(perfetto::Tracing::IsInitialized());
TracingInitArgs args;
- args.backends = supported_backends;
+ args.backends = GetParam();
args.tracing_policy = g_test_tracing_policy;
perfetto::Tracing::Initialize(args);
RegisterDataSource<MockDataSource>("my_data_source");
@@ -397,18 +479,37 @@ class PerfettoApiTest : public ::testing::TestWithParam<perfetto::BackendType> {
perfetto::test::DisableReconnectLimit();
}
- void TearDown() override { instance = nullptr; }
+ void TearDown() override {
+ instance = nullptr;
+ sessions_.clear();
+ perfetto::Tracing::ResetForTesting();
+ }
template <typename DataSourceType>
TestDataSourceHandle* RegisterDataSource(std::string name) {
- EXPECT_EQ(data_sources_.count(name), 0u);
- TestDataSourceHandle* handle = &data_sources_[name];
perfetto::DataSourceDescriptor dsd;
dsd.set_name(name);
+ return RegisterDataSource<DataSourceType>(dsd);
+ }
+
+ template <typename DataSourceType>
+ TestDataSourceHandle* RegisterDataSource(
+ const perfetto::DataSourceDescriptor& dsd) {
+ EXPECT_EQ(data_sources_.count(dsd.name()), 0u);
+ TestDataSourceHandle* handle = &data_sources_[dsd.name()];
DataSourceType::Register(dsd);
return handle;
}
+ template <typename DataSourceType>
+ TestDataSourceHandle* UpdateDataSource(
+ const perfetto::DataSourceDescriptor& dsd) {
+ EXPECT_EQ(data_sources_.count(dsd.name()), 1u);
+ TestDataSourceHandle* handle = &data_sources_[dsd.name()];
+ DataSourceType::UpdateDescriptor(dsd);
+ return handle;
+ }
+
TestTracingSessionHandle* NewTrace(const perfetto::TraceConfig& cfg,
int fd = -1) {
return NewTrace(cfg, /*backend_type=*/GetParam(), fd);
@@ -426,14 +527,13 @@ class PerfettoApiTest : public ::testing::TestWithParam<perfetto::BackendType> {
}
TestTracingSessionHandle* NewTraceWithCategories(
- std::vector<std::string> categories) {
+ std::vector<std::string> categories,
+ perfetto::protos::gen::TrackEventConfig te_cfg = {}) {
perfetto::TraceConfig cfg;
cfg.set_duration_ms(500);
cfg.add_buffers()->set_size_kb(1024);
auto* ds_cfg = cfg.add_data_sources()->mutable_config();
ds_cfg->set_name("track_event");
-
- perfetto::protos::gen::TrackEventConfig te_cfg;
te_cfg.add_disabled_categories("*");
for (const auto& category : categories)
te_cfg.add_enabled_categories(category);
@@ -498,36 +598,30 @@ class PerfettoApiTest : public ::testing::TestWithParam<perfetto::BackendType> {
std::vector<std::string> ReadSlicesFromTrace(
perfetto::TracingSession* tracing_session) {
- std::vector<char> raw_trace = tracing_session->ReadTraceBlocking();
+ return ReadSlicesFromTrace(tracing_session->ReadTraceBlocking());
+ }
+
+ std::vector<std::string> ReadSlicesFromTrace(
+ const std::vector<char>& raw_trace) {
EXPECT_GE(raw_trace.size(), 0u);
// Read back the trace, maintaining interning tables as we go.
std::vector<std::string> slices;
- std::map<uint64_t, std::string> categories;
- std::map<uint64_t, std::string> event_names;
- std::map<uint64_t, std::string> debug_annotation_names;
- std::set<uint64_t> seen_tracks;
perfetto::protos::gen::Trace parsed_trace;
EXPECT_TRUE(
parsed_trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
- bool incremental_state_was_cleared = false;
+ ParsedIncrementalState incremental_state;
+
uint32_t sequence_id = 0;
for (const auto& packet : parsed_trace.packet()) {
- if (packet.sequence_flags() & perfetto::protos::pbzero::TracePacket::
- SEQ_INCREMENTAL_STATE_CLEARED) {
- incremental_state_was_cleared = true;
- categories.clear();
- event_names.clear();
- debug_annotation_names.clear();
- seen_tracks.clear();
- }
+ incremental_state.ClearIfNeeded(packet);
if (packet.has_track_descriptor()) {
// Make sure we haven't seen any events on this track before the
// descriptor was written.
- EXPECT_EQ(seen_tracks.find(packet.track_descriptor().uuid()),
- seen_tracks.end());
+ EXPECT_FALSE(
+ incremental_state.HasSeenTrack(packet.track_descriptor().uuid()));
}
if (!packet.has_track_event())
@@ -540,28 +634,13 @@ class PerfettoApiTest : public ::testing::TestWithParam<perfetto::BackendType> {
EXPECT_EQ(sequence_id, packet.trusted_packet_sequence_id());
}
- // Update incremental state.
- if (packet.has_interned_data()) {
- const auto& interned_data = packet.interned_data();
- for (const auto& it : interned_data.event_categories()) {
- EXPECT_EQ(categories.find(it.iid()), categories.end());
- categories[it.iid()] = it.name();
- }
- for (const auto& it : interned_data.event_names()) {
- EXPECT_EQ(event_names.find(it.iid()), event_names.end());
- event_names[it.iid()] = it.name();
- }
- for (const auto& it : interned_data.debug_annotation_names()) {
- EXPECT_EQ(debug_annotation_names.find(it.iid()),
- debug_annotation_names.end());
- debug_annotation_names[it.iid()] = it.name();
- }
- }
+ incremental_state.Parse(packet);
+
const auto& track_event = packet.track_event();
std::string slice;
if (track_event.has_track_uuid()) {
- seen_tracks.insert(track_event.track_uuid());
+ incremental_state.InsertTrack(track_event.track_uuid());
std::stringstream track;
track << "[track=" << track_event.track_uuid() << "]";
slice += track.str();
@@ -619,11 +698,12 @@ class PerfettoApiTest : public ::testing::TestWithParam<perfetto::BackendType> {
}
size_t category_count = 0;
for (const auto& it : track_event.category_iids())
- slice += (category_count++ ? "," : ":") + categories[it];
+ slice +=
+ (category_count++ ? "," : ":") + incremental_state.GetCategory(it);
for (const auto& it : track_event.categories())
slice += (category_count++ ? ",$" : ":$") + it;
- if (track_event.has_name_iid())
- slice += "." + event_names[track_event.name_iid()];
+ if (track_event.has_name() || track_event.has_name_iid())
+ slice += "." + incremental_state.GetEventName(track_event);
if (track_event.debug_annotations_size()) {
slice += "(";
@@ -632,7 +712,8 @@ class PerfettoApiTest : public ::testing::TestWithParam<perfetto::BackendType> {
if (!first_annotation) {
slice += ",";
}
- slice += debug_annotation_names[it.name_iid()] + "=";
+ slice +=
+ incremental_state.GetDebugAnnotationName(it.name_iid()) + "=";
std::stringstream value;
if (it.has_bool_value()) {
value << "(bool)" << it.bool_value();
@@ -657,9 +738,37 @@ class PerfettoApiTest : public ::testing::TestWithParam<perfetto::BackendType> {
slice += ")";
}
+ if (track_event.flow_ids_size()) {
+ slice += "(flow_ids=";
+ std::stringstream value;
+ bool first_annotation = true;
+ for (uint64_t id : track_event.flow_ids()) {
+ if (!first_annotation) {
+ value << ",";
+ }
+ first_annotation = false;
+ value << id;
+ }
+ slice += value.str() + ")";
+ }
+
+ if (track_event.terminating_flow_ids_size()) {
+ slice += "(terminating_flow_ids=";
+ std::stringstream value;
+ bool first_annotation = true;
+ for (uint64_t id : track_event.terminating_flow_ids()) {
+ if (!first_annotation) {
+ value << ",";
+ }
+ value << id;
+ first_annotation = false;
+ }
+ slice += value.str() + ")";
+ }
+
slices.push_back(slice);
}
- EXPECT_TRUE(incremental_state_was_cleared);
+ EXPECT_TRUE(incremental_state.WasCleared());
return slices;
}
@@ -880,6 +989,11 @@ TEST_P(PerfettoApiTest, TrackEvent) {
bool process_descriptor_found = false;
uint32_t sequence_id = 0;
int32_t cur_pid = perfetto::test::GetCurrentProcessId();
+ uint64_t recent_absolute_time_ns = 0;
+ bool found_incremental_clock = false;
+ constexpr auto kClockIdIncremental =
+ perfetto::internal::TrackEventIncrementalState::kClockIdIncremental;
+
for (const auto& packet : trace.packet()) {
if (packet.has_track_descriptor()) {
const auto& desc = packet.track_descriptor();
@@ -896,6 +1010,17 @@ TEST_P(PerfettoApiTest, TrackEvent) {
incremental_state_was_cleared = true;
categories.clear();
event_names.clear();
+ EXPECT_EQ(kClockIdIncremental,
+ packet.trace_packet_defaults().timestamp_clock_id());
+ }
+ if (packet.has_clock_snapshot()) {
+ for (auto& clock : packet.clock_snapshot().clocks()) {
+ if (clock.is_incremental()) {
+ found_incremental_clock = true;
+ recent_absolute_time_ns = clock.timestamp();
+ EXPECT_EQ(kClockIdIncremental, clock.clock_id());
+ }
+ }
}
if (!packet.has_track_event())
@@ -925,18 +1050,13 @@ TEST_P(PerfettoApiTest, TrackEvent) {
event_names[it.iid()] = it.name();
}
}
-
- EXPECT_GT(packet.timestamp(), 0u);
- EXPECT_LE(packet.timestamp(), now);
-#if !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) && \
- !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ EXPECT_TRUE(found_incremental_clock);
+ uint64_t absolute_timestamp = packet.timestamp() + recent_absolute_time_ns;
+ recent_absolute_time_ns = absolute_timestamp;
+ EXPECT_GT(absolute_timestamp, 0u);
+ EXPECT_LE(absolute_timestamp, now);
+ // Packet uses default (incremental) clock.
EXPECT_FALSE(packet.has_timestamp_clock_id());
-#else
- constexpr auto kClockMonotonic =
- perfetto::protos::pbzero::ClockSnapshot::Clock::MONOTONIC;
- EXPECT_EQ(packet.timestamp_clock_id(),
- static_cast<uint32_t>(kClockMonotonic));
-#endif
if (track_event.type() ==
perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN) {
EXPECT_FALSE(begin_found);
@@ -963,6 +1083,109 @@ TEST_P(PerfettoApiTest, TrackEvent) {
TestCategoryAsTemplateParameter<kTestCategory>();
}
+TEST_P(PerfettoApiTest, TrackEventWithIncrementalTimestamp) {
+ for (auto disable_incremental_timestamps : {false, true}) {
+ // Create a new trace session.
+ perfetto::protos::gen::TrackEventConfig te_cfg;
+ te_cfg.set_disable_incremental_timestamps(disable_incremental_timestamps);
+ auto* tracing_session = NewTraceWithCategories({"bar"}, te_cfg);
+ constexpr auto kClockIdIncremental =
+ perfetto::internal::TrackEventIncrementalState::kClockIdIncremental;
+ tracing_session->get()->StartBlocking();
+
+ std::map<uint64_t, std::string> event_names;
+
+ auto empty_lambda = [](perfetto::EventContext) {};
+
+ constexpr uint64_t kInstantEvent1Time = 92718891479583;
+ TRACE_EVENT_INSTANT(
+ "bar", "InstantEvent1",
+ perfetto::TraceTimestamp{kClockIdIncremental, kInstantEvent1Time},
+ empty_lambda);
+
+ constexpr uint64_t kInstantEvent2Time = 92718891618959;
+ TRACE_EVENT_INSTANT(
+ "bar", "InstantEvent2",
+ perfetto::TraceTimestamp{kClockIdIncremental, kInstantEvent2Time},
+ empty_lambda);
+
+ perfetto::TrackEvent::Flush();
+ tracing_session->get()->StopBlocking();
+
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+
+ perfetto::protos::gen::Trace trace;
+ ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
+ uint64_t absolute_timestamp = 0;
+ uint64_t prv_timestamp = 0;
+ int event_count = 0;
+ // Go through the packets and add the timestamps of those packets that use
+ // the incremental clock - in order to get the absolute timestamps of the
+ // track events.
+
+ uint64_t default_clock_id = 0;
+ bool is_incremental = false;
+
+ for (const auto& packet : trace.packet()) {
+ if (!packet.has_track_event() && !packet.has_clock_snapshot())
+ continue;
+ if (packet.has_trace_packet_defaults()) {
+ auto& defaults = packet.trace_packet_defaults();
+ if (defaults.has_timestamp_clock_id()) {
+ default_clock_id = defaults.timestamp_clock_id();
+ }
+ }
+ if (packet.has_clock_snapshot()) {
+ for (auto& clock : packet.clock_snapshot().clocks()) {
+ if (clock.is_incremental()) {
+ is_incremental = true;
+ absolute_timestamp = clock.timestamp();
+ EXPECT_EQ(clock.clock_id(), kClockIdIncremental);
+ EXPECT_FALSE(disable_incremental_timestamps);
+ }
+ }
+ } else {
+ auto clock_id = packet.has_timestamp_clock_id()
+ ? packet.timestamp_clock_id()
+ : default_clock_id;
+ if (clock_id == kClockIdIncremental) {
+ absolute_timestamp = prv_timestamp + packet.timestamp();
+ EXPECT_FALSE(disable_incremental_timestamps);
+ } else {
+ absolute_timestamp = packet.timestamp();
+ EXPECT_TRUE(disable_incremental_timestamps);
+ }
+ }
+ prv_timestamp = absolute_timestamp;
+
+ if (packet.sequence_flags() & perfetto::protos::pbzero::TracePacket::
+ SEQ_INCREMENTAL_STATE_CLEARED) {
+ event_names.clear();
+ }
+
+ // Update incremental state.
+ if (packet.has_interned_data()) {
+ const auto& interned_data = packet.interned_data();
+ for (const auto& it : interned_data.event_names()) {
+ EXPECT_EQ(event_names.find(it.iid()), event_names.end());
+ event_names[it.iid()] = it.name();
+ }
+ }
+
+ if (event_names[packet.track_event().name_iid()] == "InstantEvent1") {
+ event_count++;
+ EXPECT_EQ(absolute_timestamp, kInstantEvent1Time);
+ } else if (event_names[packet.track_event().name_iid()] ==
+ "InstantEvent2") {
+ event_count++;
+ EXPECT_EQ(absolute_timestamp, kInstantEvent2Time);
+ }
+ }
+ EXPECT_NE(is_incremental, disable_incremental_timestamps);
+ EXPECT_EQ(event_count, 2);
+ }
+}
+
TEST_P(PerfettoApiTest, TrackEventCategories) {
// Create a new trace session.
auto* tracing_session = NewTraceWithCategories({"bar"});
@@ -1318,7 +1541,7 @@ TEST_P(PerfettoApiTest, TrackEventProcessAndThreadDescriptors) {
if (packet.has_track_descriptor()) {
if (packet.trusted_packet_sequence_id() == main_thread_sequence) {
descs.push_back(packet.track_descriptor());
- } else {
+ } else if (packet.track_descriptor().has_thread()) {
thread_descs.push_back(packet.track_descriptor());
}
}
@@ -1344,13 +1567,15 @@ TEST_P(PerfettoApiTest, TrackEventProcessAndThreadDescriptors) {
// The child thread records only its own thread descriptor (twice, since it
// was mutated).
- EXPECT_EQ(2u, thread_descs.size());
+ ASSERT_EQ(2u, thread_descs.size());
EXPECT_EQ("TestThread", thread_descs[0].name());
EXPECT_NE(0, thread_descs[0].thread().pid());
EXPECT_NE(0, thread_descs[0].thread().tid());
EXPECT_EQ("TestThread", thread_descs[1].name());
EXPECT_NE(0, thread_descs[1].thread().pid());
EXPECT_NE(0, thread_descs[1].thread().tid());
+ EXPECT_NE(0, descs[2].process().pid());
+ EXPECT_EQ("goodbye.exe", descs[2].name());
}
TEST_P(PerfettoApiTest, CustomTrackDescriptor) {
@@ -1387,7 +1612,8 @@ TEST_P(PerfettoApiTest, CustomTrackDescriptor) {
continue;
if (packet.has_track_descriptor()) {
auto td = packet.track_descriptor();
- EXPECT_TRUE(td.has_process());
+ if (!td.has_process())
+ continue;
EXPECT_NE(0, td.process().pid());
EXPECT_TRUE(td.has_chrome_process());
EXPECT_EQ("testing.exe", td.process().process_name());
@@ -1473,6 +1699,65 @@ TEST_P(PerfettoApiTest, TrackEventCustomTrack) {
perfetto::TrackEvent::EraseTrackDescriptor(track);
}
+TEST_P(PerfettoApiTest, TrackEventCustomTimestampClock) {
+ // Create a new trace session.
+ auto* tracing_session = NewTraceWithCategories({"foo"});
+ tracing_session->get()->StartBlocking();
+
+ const perfetto::protos::pbzero::BuiltinClock kMyClockId =
+ static_cast<perfetto::protos::pbzero::BuiltinClock>(700);
+ const uint64_t kTimestamp = 12345678;
+
+ // First emit a clock snapshot that maps our custom clock to regular trace
+ // time. Note that the clock snapshot should come before any events
+ // referencing that clock.
+ perfetto::TrackEvent::Trace([](perfetto::TrackEvent::TraceContext ctx) {
+ auto packet = ctx.NewTracePacket();
+ packet->set_timestamp_clock_id(perfetto::TrackEvent::GetTraceClockId());
+ packet->set_timestamp(perfetto::TrackEvent::GetTraceTimeNs());
+ auto* clock_snapshot = packet->set_clock_snapshot();
+ // First set the reference clock, i.e., the default trace clock in this
+ // case.
+ auto* clock = clock_snapshot->add_clocks();
+ clock->set_clock_id(perfetto::TrackEvent::GetTraceClockId());
+ clock->set_timestamp(perfetto::TrackEvent::GetTraceTimeNs());
+ // Then set the value of our reference clock at the same point in time. We
+ // pretend our clock is one second behind trace time.
+ clock = clock_snapshot->add_clocks();
+ clock->set_clock_id(kMyClockId);
+ clock->set_timestamp(kTimestamp + 1000000000ull);
+ });
+
+ // Next emit a trace event with a custom timestamp and a custom clock.
+ TRACE_EVENT_INSTANT("foo", "EventWithCustomTime",
+ perfetto::TraceTimestamp{kMyClockId, kTimestamp});
+ TRACE_EVENT_INSTANT("foo", "EventWithNormalTime");
+
+ perfetto::TrackEvent::Flush();
+ tracing_session->get()->StopBlocking();
+
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+ perfetto::protos::gen::Trace trace;
+ ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
+
+ // Check that both the clock id and the timestamp got written together with
+ // the packet. Note that we don't check the actual clock sync behavior here
+ // since that happens in the Trace Processor instead.
+ bool found_clock_snapshot = false;
+ bool found_event = false;
+ for (const auto& packet : trace.packet()) {
+ if (packet.has_clock_snapshot())
+ found_clock_snapshot = true;
+ if (!packet.has_track_event() || packet.timestamp() != kTimestamp)
+ continue;
+ found_event = true;
+ EXPECT_EQ(static_cast<uint32_t>(kMyClockId), packet.timestamp_clock_id());
+ EXPECT_EQ(kTimestamp, packet.timestamp());
+ }
+ EXPECT_TRUE(found_clock_snapshot);
+ EXPECT_TRUE(found_event);
+}
+
TEST_P(PerfettoApiTest, LegacyEventWithThreadOverride) {
// Create a new trace session.
auto* tracing_session = NewTraceWithCategories({"cat"});
@@ -1604,6 +1889,9 @@ TEST_P(PerfettoApiTest, TrackEventCustomTrackAndTimestamp) {
for (const auto& packet : trace.packet()) {
if (!packet.has_track_event())
continue;
+
+ EXPECT_EQ(packet.timestamp_clock_id(),
+ static_cast<uint32_t>(perfetto::TrackEvent::GetTraceClockId()));
event_count++;
switch (packet.track_event().type()) {
case perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN:
@@ -1778,16 +2066,71 @@ TEST_P(PerfettoApiTest, InlineTrackEventTypedArgs_SimpleRepeated) {
EXPECT_TRUE(found_args);
}
-TEST_P(PerfettoApiTest, InlineTrackEventTypedArgs_NestedSingle) {
- struct LogMessage {
- void WriteIntoTrace(
- perfetto::TracedProto<perfetto::protos::pbzero::LogMessage> context)
- const {
- context->set_source_location_iid(1);
- context->set_body_iid(2);
- }
+namespace {
+
+struct LogMessage {
+ void WriteIntoTrace(
+ perfetto::TracedProto<perfetto::protos::pbzero::LogMessage> context)
+ const {
+ context->set_source_location_iid(1);
+ context->set_body_iid(2);
+ }
+};
+
+auto GetWriteLogMessageRefLambda = []() {
+ return [](perfetto::EventContext& ctx) {
+ auto* log = ctx.event()->set_log_message();
+ log->set_source_location_iid(1);
+ log->set_body_iid(2);
};
+};
+void CheckTypedArguments(
+ const std::vector<char>& raw_trace,
+ const char* event_name,
+ perfetto::protos::gen::TrackEvent::Type type,
+ std::function<void(const perfetto::protos::gen::TrackEvent&)> checker) {
+ perfetto::protos::gen::Trace parsed_trace;
+ ASSERT_TRUE(parsed_trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
+
+ bool found_slice = false;
+ ParsedIncrementalState incremental_state;
+
+ for (const auto& packet : parsed_trace.packet()) {
+ incremental_state.ClearIfNeeded(packet);
+ incremental_state.Parse(packet);
+
+ if (!packet.has_track_event())
+ continue;
+ const auto& track_event = packet.track_event();
+ if (track_event.type() != type) {
+ continue;
+ }
+ if (event_name &&
+ incremental_state.GetEventName(track_event) != event_name) {
+ continue;
+ }
+
+ checker(track_event);
+ found_slice = true;
+ }
+ EXPECT_TRUE(found_slice);
+}
+
+void CheckLogMessagePresent(const std::vector<char>& raw_trace) {
+ CheckTypedArguments(raw_trace, nullptr,
+ perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN,
+ [](const perfetto::protos::gen::TrackEvent& track_event) {
+ EXPECT_TRUE(track_event.has_log_message());
+ const auto& log = track_event.log_message();
+ EXPECT_EQ(1u, log.source_location_iid());
+ EXPECT_EQ(2u, log.body_iid());
+ });
+}
+
+} // namespace
+
+TEST_P(PerfettoApiTest, InlineTrackEventTypedArgs_NestedSingle) {
// Create a new trace session.
auto* tracing_session = NewTraceWithCategories({"foo"});
tracing_session->get()->StartBlocking();
@@ -1799,28 +2142,305 @@ TEST_P(PerfettoApiTest, InlineTrackEventTypedArgs_NestedSingle) {
tracing_session->get()->StopBlocking();
std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+}
+
+TEST_P(PerfettoApiTest, TrackEventArgs_TypedAndUntyped) {
+ // Create a new trace session.
+ auto* tracing_session = NewTraceWithCategories({"foo"});
+ tracing_session->get()->StartBlocking();
+
+ TRACE_EVENT_BEGIN("foo", "E",
+ perfetto::protos::pbzero::TrackEvent::kLogMessage,
+ LogMessage(), "arg", "value");
+ TRACE_EVENT_END("foo");
+
+ tracing_session->get()->StopBlocking();
+
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
std::string trace(raw_trace.data(), raw_trace.size());
- perfetto::protos::gen::Trace parsed_trace;
- ASSERT_TRUE(parsed_trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
+ // Find typed argument.
+ CheckLogMessagePresent(raw_trace);
- bool found_args = false;
- for (const auto& packet : parsed_trace.packet()) {
- if (!packet.has_track_event())
- continue;
- const auto& track_event = packet.track_event();
- if (track_event.type() !=
- perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN) {
- continue;
- }
+ // Find untyped argument.
+ EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
+ ElementsAre("B:foo.E(arg=(string)value)"));
+}
- EXPECT_TRUE(track_event.has_log_message());
- const auto& log = track_event.log_message();
- EXPECT_EQ(1u, log.source_location_iid());
- EXPECT_EQ(2u, log.body_iid());
- found_args = true;
+TEST_P(PerfettoApiTest, TrackEventArgs_UntypedAndTyped) {
+ // Create a new trace session.
+ auto* tracing_session = NewTraceWithCategories({"foo"});
+ tracing_session->get()->StartBlocking();
+
+ TRACE_EVENT_BEGIN("foo", "E", "arg", "value",
+ perfetto::protos::pbzero::TrackEvent::kLogMessage,
+ LogMessage());
+ TRACE_EVENT_END("foo");
+
+ tracing_session->get()->StopBlocking();
+
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+
+ // Find typed argument.
+ CheckLogMessagePresent(raw_trace);
+
+ // Find untyped argument.
+ EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
+ ElementsAre("B:foo.E(arg=(string)value)"));
+}
+
+TEST_P(PerfettoApiTest, TrackEventArgs_UntypedAndRefLambda) {
+ // Create a new trace session.
+ auto* tracing_session = NewTraceWithCategories({"foo"});
+ tracing_session->get()->StartBlocking();
+
+ TRACE_EVENT_BEGIN("foo", "E", "arg", "value", GetWriteLogMessageRefLambda());
+ TRACE_EVENT_END("foo");
+
+ tracing_session->get()->StopBlocking();
+
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+
+ // Find typed argument.
+ CheckLogMessagePresent(raw_trace);
+
+ // Find untyped argument.
+ EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
+ ElementsAre("B:foo.E(arg=(string)value)"));
+}
+
+TEST_P(PerfettoApiTest, TrackEventArgs_RefLambdaAndUntyped) {
+ // Create a new trace session.
+ auto* tracing_session = NewTraceWithCategories({"foo"});
+ tracing_session->get()->StartBlocking();
+
+ TRACE_EVENT_BEGIN("foo", "E", GetWriteLogMessageRefLambda(), "arg", "value");
+ TRACE_EVENT_END("foo");
+
+ tracing_session->get()->StopBlocking();
+
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+
+ // Find typed argument.
+ CheckLogMessagePresent(raw_trace);
+
+ // Find untyped argument.
+ EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
+ ElementsAre("B:foo.E(arg=(string)value)"));
+}
+
+TEST_P(PerfettoApiTest, TrackEventArgs_RefLambdaAndTyped) {
+ // Create a new trace session.
+ auto* tracing_session = NewTraceWithCategories({"foo"});
+ tracing_session->get()->StartBlocking();
+
+ TRACE_EVENT_BEGIN(
+ "foo", "E",
+ [](perfetto::EventContext& ctx) {
+ ctx.AddDebugAnnotation("arg", "value");
+ },
+ perfetto::protos::pbzero::TrackEvent::kLogMessage, LogMessage());
+ TRACE_EVENT_END("foo");
+
+ tracing_session->get()->StopBlocking();
+
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+
+ // Find typed argument.
+ CheckLogMessagePresent(raw_trace);
+
+ // Find untyped argument.
+ EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
+ ElementsAre("B:foo.E(arg=(string)value)"));
+}
+
+TEST_P(PerfettoApiTest, TrackEventArgs_TypedAndRefLambda) {
+ // Create a new trace session.
+ auto* tracing_session = NewTraceWithCategories({"foo"});
+ tracing_session->get()->StartBlocking();
+
+ TRACE_EVENT_BEGIN("foo", "E",
+ perfetto::protos::pbzero::TrackEvent::kLogMessage,
+ LogMessage(), [](perfetto::EventContext& ctx) {
+ ctx.AddDebugAnnotation("arg", "value");
+ });
+ TRACE_EVENT_END("foo");
+
+ tracing_session->get()->StopBlocking();
+
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+
+ // Find typed argument.
+ CheckLogMessagePresent(raw_trace);
+
+ // Find untyped argument.
+ EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
+ ElementsAre("B:foo.E(arg=(string)value)"));
+}
+
+TEST_P(PerfettoApiTest, TrackEventArgs_RefLambdaAndRefLambda) {
+ // Create a new trace session.
+ auto* tracing_session = NewTraceWithCategories({"foo"});
+ tracing_session->get()->StartBlocking();
+
+ TRACE_EVENT_BEGIN(
+ "foo", "E",
+ [](perfetto::EventContext& ctx) {
+ ctx.AddDebugAnnotation("arg1", "value1");
+ },
+ [](perfetto::EventContext& ctx) {
+ ctx.AddDebugAnnotation("arg2", "value2");
+ });
+ TRACE_EVENT_END("foo");
+
+ tracing_session->get()->StopBlocking();
+
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+
+ // Find untyped arguments.
+ EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
+ ElementsAre("B:foo.E(arg1=(string)value1,arg2=(string)value2)"));
+}
+
+TEST_P(PerfettoApiTest, TrackEventArgs_RefLambdaAndLambda) {
+ // Create a new trace session.
+ auto* tracing_session = NewTraceWithCategories({"foo"});
+ tracing_session->get()->StartBlocking();
+
+ TRACE_EVENT_BEGIN(
+ "foo", "E",
+ [](perfetto::EventContext& ctx) {
+ ctx.AddDebugAnnotation("arg1", "value1");
+ },
+ [](perfetto::EventContext ctx) {
+ ctx.AddDebugAnnotation("arg2", "value2");
+ });
+ TRACE_EVENT_END("foo");
+
+ tracing_session->get()->StopBlocking();
+
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+
+ // Find untyped arguments.
+ EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
+ ElementsAre("B:foo.E(arg1=(string)value1,arg2=(string)value2)"));
+}
+
+TEST_P(PerfettoApiTest, TrackEventArgs_RefLambda) {
+ // Create a new trace session.
+ auto* tracing_session = NewTraceWithCategories({"foo"});
+ tracing_session->get()->StartBlocking();
+
+ TRACE_EVENT_BEGIN("foo", "E", [](perfetto::EventContext& ctx) {
+ ctx.AddDebugAnnotation("arg", "value");
+ });
+ TRACE_EVENT_END("foo");
+
+ tracing_session->get()->StopBlocking();
+
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+
+ // Find untyped argument.
+ EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
+ ElementsAre("B:foo.E(arg=(string)value)"));
+}
+
+TEST_P(PerfettoApiTest, TrackEventArgs_Flow_Global) {
+ // Create a new trace session.
+ auto* tracing_session = NewTraceWithCategories({"foo"});
+ tracing_session->get()->StartBlocking();
+
+ TRACE_EVENT_INSTANT("foo", "E1", perfetto::Flow::Global(42));
+ TRACE_EVENT_INSTANT("foo", "E2", perfetto::TerminatingFlow::Global(42));
+
+ tracing_session->get()->StopBlocking();
+
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+
+ // Find typed argument.
+ CheckTypedArguments(
+ raw_trace, "E1", perfetto::protos::gen::TrackEvent::TYPE_INSTANT,
+ [](const perfetto::protos::gen::TrackEvent& track_event) {
+ EXPECT_THAT(track_event.flow_ids(), testing::ElementsAre(42));
+ });
+}
+
+TEST_P(PerfettoApiTest, TrackEventArgs_MultipleFlows) {
+ // Create a new trace session.
+ auto* tracing_session = NewTraceWithCategories({"foo"});
+ tracing_session->get()->StartBlocking();
+
+ {
+ TRACE_EVENT("foo", "E1", perfetto::Flow::Global(1),
+ perfetto::Flow::Global(2), perfetto::Flow::Global(3));
}
- EXPECT_TRUE(found_args);
+ {
+ TRACE_EVENT("foo", "E2", perfetto::Flow::Global(1),
+ perfetto::TerminatingFlow::Global(2));
+ }
+ { TRACE_EVENT("foo", "E3", perfetto::TerminatingFlow::Global(3)); }
+
+ tracing_session->get()->StopBlocking();
+
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+ EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
+ ElementsAre("B:foo.E1(flow_ids=1,2,3)", "E",
+ "B:foo.E2(flow_ids=1)(terminating_flow_ids=2)", "E",
+ "B:foo.E3(terminating_flow_ids=3)"));
+}
+
+TEST_P(PerfettoApiTest, TrackEventArgs_Flow_ProcessScoped) {
+ // Create a new trace session.
+ auto* tracing_session = NewTraceWithCategories({"foo"});
+ tracing_session->get()->StartBlocking();
+
+ TRACE_EVENT_INSTANT("foo", "E1", perfetto::Flow::ProcessScoped(1));
+ TRACE_EVENT_INSTANT("foo", "E2", perfetto::TerminatingFlow::ProcessScoped(1));
+ TRACE_EVENT_INSTANT("foo", "Flush");
+
+ tracing_session->get()->StopBlocking();
+
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+
+ // Find typed arguments.
+ CheckTypedArguments(raw_trace, "E1",
+ perfetto::protos::gen::TrackEvent::TYPE_INSTANT,
+ [](const perfetto::protos::gen::TrackEvent& track_event) {
+ EXPECT_EQ(track_event.flow_ids_size(), 1);
+ });
+ CheckTypedArguments(raw_trace, "E2",
+ perfetto::protos::gen::TrackEvent::TYPE_INSTANT,
+ [](const perfetto::protos::gen::TrackEvent& track_event) {
+ EXPECT_EQ(track_event.terminating_flow_ids_size(), 1);
+ });
+}
+
+TEST_P(PerfettoApiTest, TrackEventArgs_Flow_FromPointer) {
+ // Create a new trace session.
+ auto* tracing_session = NewTraceWithCategories({"foo"});
+ tracing_session->get()->StartBlocking();
+
+ int a;
+ int* ptr = &a;
+ TRACE_EVENT_INSTANT("foo", "E1", perfetto::Flow::FromPointer(ptr));
+ TRACE_EVENT_INSTANT("foo", "E2", perfetto::TerminatingFlow::FromPointer(ptr));
+ TRACE_EVENT_INSTANT("foo", "Flush");
+
+ tracing_session->get()->StopBlocking();
+
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+
+ // Find typed arguments.
+ CheckTypedArguments(raw_trace, "E1",
+ perfetto::protos::gen::TrackEvent::TYPE_INSTANT,
+ [](const perfetto::protos::gen::TrackEvent& track_event) {
+ EXPECT_EQ(track_event.flow_ids_size(), 1);
+ });
+ CheckTypedArguments(raw_trace, "E2",
+ perfetto::protos::gen::TrackEvent::TYPE_INSTANT,
+ [](const perfetto::protos::gen::TrackEvent& track_event) {
+ EXPECT_EQ(track_event.terminating_flow_ids_size(), 1);
+ });
}
struct InternedLogMessageBody
@@ -2202,6 +2822,82 @@ TEST_P(PerfettoApiTest, TrackEventTrackFromPointer) {
"]I:test.Event"));
}
+TEST_P(PerfettoApiTest, TrackEventTrackFromThreadScopedPointer) {
+ // Create a new trace session.
+ auto* tracing_session = NewTraceWithCategories({"test"});
+ tracing_session->get()->StartBlocking();
+
+ int num = 2;
+ TRACE_EVENT_INSTANT("test", "Event0.1");
+ TRACE_EVENT_INSTANT("test", "Event0.2");
+ TRACE_EVENT_INSTANT("test", "Event1.1", perfetto::Track::ThreadScoped(&num));
+ TRACE_EVENT_INSTANT("test", "Event1.2", perfetto::Track::ThreadScoped(&num));
+ std::thread t1([&]() {
+ TRACE_EVENT_INSTANT("test", "Event2.1",
+ perfetto::Track::ThreadScoped(&num));
+ TRACE_EVENT_INSTANT("test", "Event2.2",
+ perfetto::Track::ThreadScoped(&num));
+ });
+ t1.join();
+ std::thread t2([&]() {
+ TRACE_EVENT_INSTANT("test", "Event3.1",
+ perfetto::Track::ThreadScoped(&num));
+ TRACE_EVENT_INSTANT("test", "Event3.2",
+ perfetto::Track::ThreadScoped(&num));
+ });
+ t2.join();
+ perfetto::TrackEvent::Flush();
+ tracing_session->get()->StopBlocking();
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+ perfetto::protos::gen::Trace parsed_trace;
+ ASSERT_TRUE(parsed_trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
+
+ std::unordered_map<std::string, uint64_t> track_uuid_map;
+ for (auto packet : parsed_trace.packet()) {
+ if (packet.has_interned_data()) {
+ for (auto& ename : packet.interned_data().event_names()) {
+ track_uuid_map.emplace(ename.name(), packet.track_event().track_uuid());
+ }
+ }
+ }
+ EXPECT_EQ(track_uuid_map.at("Event0.1"), track_uuid_map.at("Event0.2"));
+ EXPECT_EQ(track_uuid_map.at("Event1.1"), track_uuid_map.at("Event1.2"));
+ EXPECT_EQ(track_uuid_map.at("Event2.1"), track_uuid_map.at("Event2.2"));
+ EXPECT_EQ(track_uuid_map.at("Event3.1"), track_uuid_map.at("Event3.2"));
+
+ EXPECT_EQ(4u,
+ (std::unordered_set<uint64_t>{
+ track_uuid_map.at("Event0.1"), track_uuid_map.at("Event1.1"),
+ track_uuid_map.at("Event2.1"), track_uuid_map.at("Event3.1")})
+ .size());
+}
+
+TEST_P(PerfettoApiTest, FilterDebugAnnotations) {
+ for (auto flag : {false, true}) {
+ // Create a new trace session.
+ perfetto::protos::gen::TrackEventConfig te_cfg;
+ te_cfg.set_filter_debug_annotations(flag);
+ auto* tracing_session = NewTraceWithCategories({"test"}, te_cfg);
+ tracing_session->get()->StartBlocking();
+
+ TRACE_EVENT_BEGIN("test", "Event1");
+ TRACE_EVENT_BEGIN("test", "Event2", [&](perfetto::EventContext ctx) {
+ ctx.AddDebugAnnotation("debug_name", "debug_value");
+ });
+ TRACE_EVENT_BEGIN("test", "Event3");
+ perfetto::TrackEvent::Flush();
+ tracing_session->get()->StopBlocking();
+
+ auto slices = ReadSlicesFromTrace(tracing_session->get());
+ ASSERT_EQ(3u, slices.size());
+ if (flag) {
+ EXPECT_EQ("B:test.Event2", slices[1]);
+ } else {
+ EXPECT_EQ("B:test.Event2(debug_name=(string)debug_value)", slices[1]);
+ }
+ }
+}
+
TEST_P(PerfettoApiTest, TrackEventDebugAnnotations) {
// Create a new trace session.
auto* tracing_session = NewTraceWithCategories({"test"});
@@ -2229,6 +2925,9 @@ TEST_P(PerfettoApiTest, TrackEventDebugAnnotations) {
[&](perfetto::TracedValue context) {
std::move(context).WriteInt64(42);
});
+ TRACE_EVENT_BEGIN("test", "E", [&](perfetto::EventContext ctx) {
+ ctx.AddDebugAnnotation("debug_annotation", "value");
+ });
perfetto::TrackEvent::Flush();
tracing_session->get()->StopBlocking();
@@ -2243,7 +2942,8 @@ TEST_P(PerfettoApiTest, TrackEventDebugAnnotations) {
"B:test.E(ptr_arg=(pointer)baadf00d)",
"B:test.E(size_t_arg=(uint)42)", "B:test.E(ptrdiff_t_arg=(int)-7)",
"B:test.E(enum_arg=(uint)1)", "B:test.E(signed_enum_arg=(int)-1)",
- "B:test.E(class_enum_arg=(int)0)", "B:test.E(traced_value=(int)42)"));
+ "B:test.E(class_enum_arg=(int)0)", "B:test.E(traced_value=(int)42)",
+ "B:test.E(debug_annotation=(string)value)"));
}
TEST_P(PerfettoApiTest, TrackEventCustomDebugAnnotations) {
@@ -2366,6 +3066,61 @@ TEST_P(PerfettoApiTest, DebugAnnotationAndLambda) {
EXPECT_TRUE(found_args);
}
+TEST_P(PerfettoApiTest, ProtoInsideDebugAnnotation) {
+ auto* tracing_session = NewTraceWithCategories({"test"});
+ tracing_session->get()->StartBlocking();
+
+ TRACE_EVENT_INSTANT(
+ "test", "E", "key",
+ [](perfetto::TracedProto<perfetto::protos::pbzero::LogMessage> ctx) {
+ ctx->set_source_location_iid(42);
+ });
+
+ perfetto::TrackEvent::Flush();
+
+ tracing_session->get()->StopBlocking();
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+ std::string trace(raw_trace.data(), raw_trace.size());
+
+ perfetto::protos::gen::Trace parsed_trace;
+ ASSERT_TRUE(parsed_trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
+
+ std::vector<std::string> interned_debug_annotation_names;
+ std::vector<std::string> interned_debug_annotation_proto_type_names;
+
+ bool found_args = false;
+ for (const auto& packet : parsed_trace.packet()) {
+ if (packet.has_interned_data()) {
+ for (const auto& interned_name :
+ packet.interned_data().debug_annotation_names()) {
+ interned_debug_annotation_names.push_back(interned_name.name());
+ }
+ for (const auto& interned_type_name :
+ packet.interned_data().debug_annotation_value_type_names()) {
+ interned_debug_annotation_proto_type_names.push_back(
+ interned_type_name.name());
+ }
+ }
+
+ if (!packet.has_track_event())
+ continue;
+ const auto& track_event = packet.track_event();
+ if (track_event.type() != perfetto::protos::gen::TrackEvent::TYPE_INSTANT) {
+ continue;
+ }
+
+ EXPECT_EQ(track_event.debug_annotations_size(), 1);
+ found_args = true;
+ }
+ // TODO(altimin): Use DebugAnnotationParser here to parse the debug
+ // annotations.
+ EXPECT_TRUE(found_args);
+ EXPECT_THAT(interned_debug_annotation_names,
+ testing::UnorderedElementsAre("key"));
+ EXPECT_THAT(interned_debug_annotation_proto_type_names,
+ testing::UnorderedElementsAre(".perfetto.protos.LogMessage"));
+}
+
TEST_P(PerfettoApiTest, TrackEventComputedName) {
// Setup the trace config.
perfetto::TraceConfig cfg;
@@ -3258,6 +4013,51 @@ TEST_P(PerfettoApiTest, QueryServiceState) {
EXPECT_TRUE(found_ds);
}
+TEST_P(PerfettoApiTest, UpdateDataSource) {
+ class UpdateTestDataSource
+ : public perfetto::DataSource<UpdateTestDataSource> {};
+
+ perfetto::DataSourceDescriptor dsd;
+ dsd.set_name("update_test_data_source");
+
+ RegisterDataSource<UpdateTestDataSource>(dsd);
+
+ {
+ protozero::HeapBuffered<perfetto::protos::pbzero::TrackEventDescriptor> ted;
+ auto cat = ted->add_available_categories();
+ cat->set_name("new_cat");
+ dsd.set_track_event_descriptor_raw(ted.SerializeAsString());
+ }
+
+ UpdateDataSource<UpdateTestDataSource>(dsd);
+
+ perfetto::test::SyncProducers();
+
+ auto tracing_session =
+ perfetto::Tracing::NewTrace(/*BackendType=*/GetParam());
+ // Blocking read.
+ auto result = tracing_session->QueryServiceStateBlocking();
+ perfetto::protos::gen::TracingServiceState state;
+ EXPECT_TRUE(result.success);
+ EXPECT_TRUE(state.ParseFromArray(result.service_state_data.data(),
+ result.service_state_data.size()));
+ EXPECT_EQ(1, state.producers_size());
+ EXPECT_NE(std::string::npos,
+ state.producers()[0].name().find("integrationtest"));
+ bool found_ds = false;
+ for (const auto& ds : state.data_sources()) {
+ if (ds.ds_descriptor().name() == "update_test_data_source") {
+ found_ds = true;
+ perfetto::protos::gen::TrackEventDescriptor ted;
+ auto desc_raw = ds.ds_descriptor().track_event_descriptor_raw();
+ EXPECT_TRUE(ted.ParseFromArray(desc_raw.data(), desc_raw.size()));
+ EXPECT_EQ(ted.available_categories_size(), 1);
+ EXPECT_EQ(ted.available_categories()[0].name(), "new_cat");
+ }
+ }
+ EXPECT_TRUE(found_ds);
+}
+
TEST_P(PerfettoApiTest, LegacyTraceEvents) {
auto is_new_session = [] {
bool result;
@@ -3302,6 +4102,20 @@ TEST_P(PerfettoApiTest, LegacyTraceEvents) {
// Metadata event.
TRACE_EVENT_METADATA1("cat", "LegacyMetadata", "obsolete", true);
+ // Async events.
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP_AND_FLAGS0(
+ "cat", "LegacyAsync", 5678, MyTimestamp{4}, TRACE_EVENT_FLAG_NONE);
+ TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0("cat", "LegacyAsync", 5678,
+ MyTimestamp{5});
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_FLAGS0("cat", "LegacyAsync2", 9000,
+ TRACE_EVENT_FLAG_NONE);
+ TRACE_EVENT_NESTABLE_ASYNC_END_WITH_FLAGS0("cat", "LegacyAsync2", 9000,
+ TRACE_EVENT_FLAG_NONE);
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_FLAGS0("cat", "LegacyAsync3", 9001,
+ TRACE_EVENT_FLAG_NONE);
+ TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP_AND_FLAGS0(
+ "cat", "LegacyAsync3", 9001, MyTimestamp{6}, TRACE_EVENT_FLAG_NONE);
+
perfetto::TrackEvent::Flush();
tracing_session->get()->StopBlocking();
auto slices = ReadSlicesFromTrace(tracing_session->get());
@@ -3319,7 +4133,13 @@ TEST_P(PerfettoApiTest, LegacyTraceEvents) {
"]Legacy_S(unscoped_id=1):cat.LegacyWithIdTidAndTimestamp",
"Legacy_C:cat.LegacyCounter(value=(int)1234)",
"Legacy_C(unscoped_id=1234):cat.LegacyCounterWithId(value=(int)9000)",
- "Legacy_M:cat.LegacyMetadata"));
+ "Legacy_M:cat.LegacyMetadata",
+ "Legacy_b(unscoped_id=5678):cat.LegacyAsync",
+ "Legacy_e(unscoped_id=5678):cat.LegacyAsync",
+ "Legacy_b(unscoped_id=9000):cat.LegacyAsync2",
+ "Legacy_e(unscoped_id=9000):cat.LegacyAsync2",
+ "Legacy_b(unscoped_id=9001):cat.LegacyAsync3",
+ "Legacy_e(unscoped_id=9001):cat.LegacyAsync3"));
}
TEST_P(PerfettoApiTest, LegacyTraceEventsWithCustomAnnotation) {
@@ -3387,6 +4207,51 @@ TEST_P(PerfettoApiTest, LegacyTraceEventsWithId) {
"string\"):cat.WithScope"));
}
+TEST_P(PerfettoApiTest, NestableAsyncTraceEvent) {
+ auto* tracing_session = NewTraceWithCategories({"cat"});
+ tracing_session->get()->StartBlocking();
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("cat", "foo",
+ TRACE_ID_WITH_SCOPE("foo", 1));
+ // Same id, different scope.
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("cat", "bar",
+ TRACE_ID_WITH_SCOPE("bar", 1));
+ // Same scope, different id.
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("cat", "bar",
+ TRACE_ID_WITH_SCOPE("bar", 2));
+
+ TRACE_EVENT_NESTABLE_ASYNC_END0("cat", "bar", TRACE_ID_WITH_SCOPE("bar", 2));
+ TRACE_EVENT_NESTABLE_ASYNC_END0("cat", "bar", TRACE_ID_WITH_SCOPE("bar", 1));
+ TRACE_EVENT_NESTABLE_ASYNC_END0("cat", "foo", TRACE_ID_WITH_SCOPE("foo", 1));
+ perfetto::TrackEvent::Flush();
+ tracing_session->get()->StopBlocking();
+
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+ perfetto::protos::gen::Trace parsed_trace;
+ ASSERT_TRUE(parsed_trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
+ using LegacyEvent = perfetto::protos::gen::TrackEvent::LegacyEvent;
+ std::vector<const LegacyEvent*> legacy_events;
+ for (const auto& packet : parsed_trace.packet()) {
+ if (packet.has_track_event() && packet.track_event().has_legacy_event()) {
+ legacy_events.push_back(&packet.track_event().legacy_event());
+ }
+ }
+ ASSERT_EQ(6u, legacy_events.size());
+ EXPECT_EQ("foo", legacy_events[0]->id_scope());
+ EXPECT_EQ("bar", legacy_events[1]->id_scope());
+ EXPECT_EQ("bar", legacy_events[2]->id_scope());
+ EXPECT_EQ("bar", legacy_events[3]->id_scope());
+ EXPECT_EQ("bar", legacy_events[4]->id_scope());
+ EXPECT_EQ("foo", legacy_events[5]->id_scope());
+
+ EXPECT_EQ(legacy_events[0]->unscoped_id(), legacy_events[5]->unscoped_id());
+ EXPECT_EQ(legacy_events[1]->unscoped_id(), legacy_events[4]->unscoped_id());
+ EXPECT_EQ(legacy_events[2]->unscoped_id(), legacy_events[3]->unscoped_id());
+
+ EXPECT_NE(legacy_events[0]->unscoped_id(), legacy_events[1]->unscoped_id());
+ EXPECT_NE(legacy_events[1]->unscoped_id(), legacy_events[2]->unscoped_id());
+ EXPECT_NE(legacy_events[2]->unscoped_id(), legacy_events[0]->unscoped_id());
+}
+
TEST_P(PerfettoApiTest, LegacyTraceEventsWithFlow) {
auto* tracing_session = NewTraceWithCategories({"cat"});
tracing_session->get()->StartBlocking();
@@ -3914,6 +4779,70 @@ TEST_P(PerfettoApiTest, ThreadSafetyAnnotation) {
}
#endif // PERFETTO_BUILDFLAG(PERFETTO_COMPILER_CLANG)
+TEST_P(PerfettoApiTest, CountersDeltaEncoding) {
+ auto* tracing_session = NewTraceWithCategories({"cat"});
+ tracing_session->get()->StartBlocking();
+
+ // Describe a counter track.
+ perfetto::CounterTrack track1 =
+ perfetto::CounterTrack("Framerate1", "fps1").set_is_incremental(true);
+ // Global tracks can be constructed at build time.
+ constexpr perfetto::CounterTrack track2 =
+ perfetto::CounterTrack::Global("Framerate2", "fps2")
+ .set_is_incremental(true);
+ perfetto::CounterTrack track3 = perfetto::CounterTrack("Framerate3", "fps3");
+
+ TRACE_COUNTER("cat", track1, 120);
+ TRACE_COUNTER("cat", track2, 1000);
+ TRACE_COUNTER("cat", track3, 10009);
+
+ TRACE_COUNTER("cat", track1, 10);
+ TRACE_COUNTER("cat", track1, 1200);
+ TRACE_COUNTER("cat", track1, 34);
+
+ TRACE_COUNTER("cat", track3, 975);
+ TRACE_COUNTER("cat", track2, 449);
+ TRACE_COUNTER("cat", track2, 2);
+
+ TRACE_COUNTER("cat", track3, 1091);
+ TRACE_COUNTER("cat", track3, 110);
+ TRACE_COUNTER("cat", track3, 1081);
+
+ TRACE_COUNTER("cat", track1, 98);
+ TRACE_COUNTER("cat", track2, 1084);
+
+ perfetto::TrackEvent::Flush();
+
+ tracing_session->get()->StopBlocking();
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+ perfetto::protos::gen::Trace trace;
+ ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
+ std::unordered_map<uint64_t, std::string> counter_names;
+ // Map(Counter name -> counter values)
+ std::unordered_map<std::string, std::vector<int64_t>> values;
+ for (const auto& packet : trace.packet()) {
+ if (packet.has_track_descriptor()) {
+ auto& desc = packet.track_descriptor();
+ if (!desc.has_counter())
+ continue;
+ counter_names[desc.uuid()] = desc.name();
+ EXPECT_EQ((desc.name() != "Framerate3"), desc.counter().is_incremental());
+ }
+ if (packet.has_track_event()) {
+ auto event = packet.track_event();
+ EXPECT_EQ(perfetto::protos::gen::TrackEvent_Type_TYPE_COUNTER,
+ event.type());
+ auto& counter_name = counter_names.at(event.track_uuid());
+ values[counter_name].push_back(event.counter_value());
+ }
+ }
+ ASSERT_EQ(3u, values.size());
+ using IntVector = std::vector<int64_t>;
+ EXPECT_EQ((IntVector{120, -110, 1190, -1166, 64}), values.at("Framerate1"));
+ EXPECT_EQ((IntVector{1000, -551, -447, 1082}), values.at("Framerate2"));
+ EXPECT_EQ((IntVector{10009, 975, 1091, 110, 1081}), values.at("Framerate3"));
+}
+
TEST_P(PerfettoApiTest, Counters) {
auto* tracing_session = NewTraceWithCategories({"cat"});
tracing_session->get()->StartBlocking();
@@ -3994,6 +4923,35 @@ TEST_P(PerfettoApiTest, Counters) {
"Voltage = 220", "Power = 1.21"));
}
+TEST_P(PerfettoApiTest, EmptyEvent) {
+ auto* tracing_session = NewTraceWithCategories({"cat"});
+ tracing_session->get()->StartBlocking();
+
+ // Emit an empty event.
+ PERFETTO_INTERNAL_ADD_EMPTY_EVENT();
+ perfetto::TrackEvent::Flush();
+
+ tracing_session->get()->StopBlocking();
+ std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
+
+ perfetto::protos::gen::Trace trace;
+ ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
+ auto it = std::find_if(trace.packet().begin(), trace.packet().end(),
+ [](const perfetto::protos::gen::TracePacket& packet) {
+ return packet.has_trace_stats();
+ });
+ EXPECT_NE(it, trace.packet().end());
+ // The empty event required a trace chunk.
+ EXPECT_EQ(it->trace_stats().buffer_stats()[0].chunks_read(), 1u);
+ // But it isn't in the trace, because empty packets are skipped when reading
+ // from TraceBuffer.
+ it = std::find_if(trace.packet().begin(), trace.packet().end(),
+ [](const perfetto::protos::gen::TracePacket& packet) {
+ return packet.has_track_event();
+ });
+ EXPECT_EQ(it, trace.packet().end());
+}
+
struct BackendTypeAsString {
std::string operator()(
const ::testing::TestParamInfo<perfetto::BackendType>& info) const {
diff --git a/src/tracing/test/api_test_support.cc b/src/tracing/test/api_test_support.cc
index 0142d2860..a03135d5a 100644
--- a/src/tracing/test/api_test_support.cc
+++ b/src/tracing/test/api_test_support.cc
@@ -27,6 +27,10 @@
#include "test/test_helper.h"
#endif
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#endif
+
namespace perfetto {
namespace test {
diff --git a/src/tracing/test/fake_packet.cc b/src/tracing/test/fake_packet.cc
index eef70df13..d86d1b3ba 100644
--- a/src/tracing/test/fake_packet.cc
+++ b/src/tracing/test/fake_packet.cc
@@ -158,7 +158,7 @@ FakeChunk& FakeChunk::PadTo(size_t chunk_size) {
}
size_t FakeChunk::CopyIntoTraceBuffer(bool chunk_complete) {
- trace_buffer_->CopyChunkUntrusted(producer_id, uid, writer_id, chunk_id,
+ trace_buffer_->CopyChunkUntrusted(producer_id, uid, pid, writer_id, chunk_id,
num_packets, flags, chunk_complete,
data.data(), data.size());
return data.size() + TraceBuffer::InlineChunkHeaderSize;
diff --git a/src/tracing/test/fake_packet.h b/src/tracing/test/fake_packet.h
index 117df5cfb..76ad63e37 100644
--- a/src/tracing/test/fake_packet.h
+++ b/src/tracing/test/fake_packet.h
@@ -24,6 +24,7 @@
#include <string>
#include <vector>
+#include "perfetto/ext/base/utils.h"
#include "perfetto/ext/tracing/core/basic_types.h"
namespace perfetto {
@@ -85,6 +86,7 @@ class FakeChunk {
uint8_t flags = 0;
uint16_t num_packets = 0;
uid_t uid = kInvalidUid;
+ pid_t pid = base::kInvalidPid;
std::vector<uint8_t> data;
};
diff --git a/src/tracing/test/fake_producer_endpoint.h b/src/tracing/test/fake_producer_endpoint.h
index a3148d9e6..fa75e4a59 100644
--- a/src/tracing/test/fake_producer_endpoint.h
+++ b/src/tracing/test/fake_producer_endpoint.h
@@ -25,6 +25,7 @@ namespace perfetto {
class FakeProducerEndpoint : public TracingService::ProducerEndpoint {
public:
void RegisterDataSource(const DataSourceDescriptor&) override {}
+ void UpdateDataSource(const DataSourceDescriptor&) override {}
void UnregisterDataSource(const std::string&) override {}
void RegisterTraceWriter(uint32_t, uint32_t) override {}
void UnregisterTraceWriter(uint32_t) override {}
diff --git a/src/tracing/test/mock_consumer.cc b/src/tracing/test/mock_consumer.cc
index 2d7dc4c6c..cfc2458ef 100644
--- a/src/tracing/test/mock_consumer.cc
+++ b/src/tracing/test/mock_consumer.cc
@@ -125,11 +125,13 @@ void MockConsumer::GetTraceStats() {
service_endpoint_->GetTraceStats();
}
-void MockConsumer::WaitForTraceStats(bool success) {
+TraceStats MockConsumer::WaitForTraceStats(bool success) {
static int i = 0;
auto checkpoint_name = "on_trace_stats_" + std::to_string(i++);
auto on_trace_stats = task_runner_->CreateCheckpoint(checkpoint_name);
- auto result_callback = [on_trace_stats](bool, const TraceStats&) {
+ TraceStats stats;
+ auto result_callback = [on_trace_stats, &stats](bool, const TraceStats& s) {
+ stats = s;
on_trace_stats();
};
if (success) {
@@ -142,6 +144,7 @@ void MockConsumer::WaitForTraceStats(bool success) {
.WillOnce(Invoke(result_callback));
}
task_runner_->RunUntilCheckpoint(checkpoint_name);
+ return stats;
}
void MockConsumer::ObserveEvents(uint32_t enabled_event_types) {
diff --git a/src/tracing/test/mock_consumer.h b/src/tracing/test/mock_consumer.h
index 9ba12b41b..f6329bf95 100644
--- a/src/tracing/test/mock_consumer.h
+++ b/src/tracing/test/mock_consumer.h
@@ -57,7 +57,7 @@ class MockConsumer : public Consumer {
FlushRequest Flush(uint32_t timeout_ms = 10000);
std::vector<protos::gen::TracePacket> ReadBuffers();
void GetTraceStats();
- void WaitForTraceStats(bool success);
+ TraceStats WaitForTraceStats(bool success);
TracingServiceState QueryServiceState();
void ObserveEvents(uint32_t enabled_event_types);
ObservableEvents WaitForObservableEvents();
diff --git a/src/tracing/test/mock_producer.cc b/src/tracing/test/mock_producer.cc
index 067984710..ff9f9b906 100644
--- a/src/tracing/test/mock_producer.cc
+++ b/src/tracing/test/mock_producer.cc
@@ -18,8 +18,10 @@
#include "perfetto/ext/tracing/core/trace_writer.h"
#include "perfetto/ext/tracing/core/tracing_service.h"
+#include "perfetto/protozero/scattered_heap_buffer.h"
#include "perfetto/tracing/core/data_source_config.h"
#include "perfetto/tracing/core/data_source_descriptor.h"
+#include "protos/perfetto/common/track_event_descriptor.pbzero.h"
#include "src/base/test/test_task_runner.h"
using ::testing::_;
@@ -30,6 +32,26 @@ using ::testing::Property;
namespace perfetto {
+namespace {
+
+static DataSourceDescriptor CreateDataSourceDescriptor(
+ const std::initializer_list<std::string>& categories,
+ uint32_t id) {
+ DataSourceDescriptor ds_desc;
+ ds_desc.set_name("track_event");
+ ds_desc.set_id(id);
+
+ protozero::HeapBuffered<protos::pbzero::TrackEventDescriptor> ted;
+ for (auto c : categories) {
+ auto cat = ted->add_available_categories();
+ cat->set_name(c);
+ }
+ ds_desc.set_track_event_descriptor_raw(ted.SerializeAsString());
+ return ds_desc;
+}
+
+} // anonymous namespace
+
MockProducer::MockProducer(base::TestTaskRunner* task_runner)
: task_runner_(task_runner) {}
@@ -47,12 +69,13 @@ MockProducer::~MockProducer() {
void MockProducer::Connect(TracingService* svc,
const std::string& producer_name,
uid_t uid,
+ pid_t pid,
size_t shared_memory_size_hint_bytes,
size_t shared_memory_page_size_hint_bytes,
std::unique_ptr<SharedMemory> shm) {
producer_name_ = producer_name;
service_endpoint_ = svc->ConnectProducer(
- this, uid, producer_name, shared_memory_size_hint_bytes,
+ this, uid, pid, producer_name, shared_memory_size_hint_bytes,
/*in_process=*/true, TracingService::ProducerSMBScrapingMode::kDefault,
shared_memory_page_size_hint_bytes, std::move(shm));
auto checkpoint_name = "on_producer_connect_" + producer_name;
@@ -77,6 +100,20 @@ void MockProducer::UnregisterDataSource(const std::string& name) {
service_endpoint_->UnregisterDataSource(name);
}
+void MockProducer::RegisterTrackEventDataSource(
+ const std::initializer_list<std::string>& categories,
+ uint32_t id) {
+ service_endpoint_->RegisterDataSource(
+ CreateDataSourceDescriptor(categories, id));
+}
+
+void MockProducer::UpdateTrackEventDataSource(
+ const std::initializer_list<std::string>& categories,
+ uint32_t id) {
+ service_endpoint_->UpdateDataSource(
+ CreateDataSourceDescriptor(categories, id));
+}
+
void MockProducer::RegisterTraceWriter(uint32_t writer_id,
uint32_t target_buffer) {
service_endpoint_->RegisterTraceWriter(writer_id, target_buffer);
diff --git a/src/tracing/test/mock_producer.h b/src/tracing/test/mock_producer.h
index 0cbd4e298..59ff7c21e 100644
--- a/src/tracing/test/mock_producer.h
+++ b/src/tracing/test/mock_producer.h
@@ -17,6 +17,7 @@
#ifndef SRC_TRACING_TEST_MOCK_PRODUCER_H_
#define SRC_TRACING_TEST_MOCK_PRODUCER_H_
+#include <initializer_list>
#include <map>
#include <memory>
#include <string>
@@ -47,6 +48,7 @@ class MockProducer : public Producer {
void Connect(TracingService* svc,
const std::string& producer_name,
uid_t uid = 42,
+ pid_t pid = 1025,
size_t shared_memory_size_hint_bytes = 0,
size_t shared_memory_page_size_hint_bytes = 0,
std::unique_ptr<SharedMemory> shm = nullptr);
@@ -55,6 +57,12 @@ class MockProducer : public Producer {
bool ack_start = false,
bool handle_incremental_state_clear = false);
void UnregisterDataSource(const std::string& name);
+ void RegisterTrackEventDataSource(
+ const std::initializer_list<std::string>& categories,
+ uint32_t id);
+ void UpdateTrackEventDataSource(
+ const std::initializer_list<std::string>& categories,
+ uint32_t id);
void RegisterTraceWriter(uint32_t writer_id, uint32_t target_buffer);
void UnregisterTraceWriter(uint32_t writer_id);
void WaitForTracingSetup();
diff --git a/src/tracing/test/tracing_integration_test.cc b/src/tracing/test/tracing_integration_test.cc
index 3fc8d4b3e..d1ca340b6 100644
--- a/src/tracing/test/tracing_integration_test.cc
+++ b/src/tracing/test/tracing_integration_test.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include <inttypes.h>
+#include <cinttypes>
#include "perfetto/ext/base/temp_file.h"
#include "perfetto/ext/tracing/core/consumer.h"
@@ -113,6 +113,11 @@ void CheckTraceStats(const protos::gen::TracePacket& packet) {
EXPECT_EQ(0u, buf_stats.abi_violations());
}
+static_assert(TracingServiceImpl::kMaxTracePacketSliceSize <=
+ ipc::kIPCBufferSize - 512,
+ "Tracing service max packet slice should be smaller than IPC "
+ "buffer size (with some headroom)");
+
} // namespace
class TracingIntegrationTest : public ::testing::Test {
diff --git a/src/tracing/traced_proto_unittest.cc b/src/tracing/traced_proto_unittest.cc
index e5c84f10b..7ab1e3645 100644
--- a/src/tracing/traced_proto_unittest.cc
+++ b/src/tracing/traced_proto_unittest.cc
@@ -16,6 +16,7 @@
#include "perfetto/tracing/traced_proto.h"
+#include "perfetto/test/traced_value_test_support.h"
#include "perfetto/tracing/track_event.h"
#include "protos/perfetto/trace/test_event.gen.h"
#include "protos/perfetto/trace/test_event.pb.h"
@@ -40,10 +41,10 @@ class TracedProtoTest : public ::testing::Test {
using TestPayload = protos::pbzero::TestEvent::TestPayload;
-TEST_F(TracedProtoTest, SingleInt) {
+TEST_F(TracedProtoTest, SingleInt_WriteField) {
protozero::HeapBuffered<TestPayload> event;
- WriteIntoTracedProto(context().Wrap(event.get()), TestPayload::kSingleInt,
- 42);
+ perfetto::TracedProto<TestPayload> proto = context().Wrap(event.get());
+ WriteTracedProtoField(proto, TestPayload::kSingleInt, 42);
protos::TestEvent::TestPayload result;
result.ParseFromString(event.SerializeAsString());
@@ -51,20 +52,52 @@ TEST_F(TracedProtoTest, SingleInt) {
EXPECT_EQ(result.single_int(), 42);
}
-TEST_F(TracedProtoTest, RepeatedInt) {
+TEST_F(TracedProtoTest, SingleInt_Set) {
protozero::HeapBuffered<TestPayload> event;
- WriteIntoTracedProto(context().Wrap(event.get()), TestPayload::kRepeatedInts,
- std::vector<int>{1, 2, 3});
+ perfetto::TracedProto<TestPayload> proto = context().Wrap(event.get());
+ proto.Set(TestPayload::kSingleInt, 42);
+
+ protos::TestEvent::TestPayload result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_TRUE(result.has_single_int());
+ EXPECT_EQ(result.single_int(), 42);
+}
+
+TEST_F(TracedProtoTest, RepeatedInt_WriteField) {
+ protozero::HeapBuffered<TestPayload> event;
+ perfetto::TracedProto<TestPayload> proto = context().Wrap(event.get());
+ WriteTracedProtoField(proto, TestPayload::kRepeatedInts,
+ std::vector<int>{1, 2, 3});
protos::TestEvent::TestPayload result;
result.ParseFromString(event.SerializeAsString());
EXPECT_THAT(result.repeated_ints(), ::testing::ElementsAre(1, 2, 3));
}
-TEST_F(TracedProtoTest, SingleString) {
+TEST_F(TracedProtoTest, RepeatedInt_AppendValue) {
protozero::HeapBuffered<TestPayload> event;
- WriteIntoTracedProto(context().Wrap(event.get()), TestPayload::kSingleString,
- "foo");
+ perfetto::TracedProto<TestPayload> proto = context().Wrap(event.get());
+ proto.AppendValue(TestPayload::kRepeatedInts, 1);
+
+ protos::TestEvent::TestPayload result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_THAT(result.repeated_ints(), ::testing::ElementsAre(1));
+}
+
+TEST_F(TracedProtoTest, RepeatedInt_AppendFrom) {
+ protozero::HeapBuffered<TestPayload> event;
+ perfetto::TracedProto<TestPayload> proto = context().Wrap(event.get());
+ proto.AppendFrom(TestPayload::kRepeatedInts, std::vector<int>{1, 2, 3});
+
+ protos::TestEvent::TestPayload result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_THAT(result.repeated_ints(), ::testing::ElementsAre(1, 2, 3));
+}
+
+TEST_F(TracedProtoTest, SingleString_WriteField) {
+ protozero::HeapBuffered<TestPayload> event;
+ perfetto::TracedProto<TestPayload> proto = context().Wrap(event.get());
+ WriteTracedProtoField(proto, TestPayload::kSingleString, "foo");
protos::TestEvent::TestPayload result;
result.ParseFromString(event.SerializeAsString());
@@ -72,40 +105,292 @@ TEST_F(TracedProtoTest, SingleString) {
EXPECT_EQ(result.single_string(), "foo");
}
-TEST_F(TracedProtoTest, RepeatedString) {
+TEST_F(TracedProtoTest, SingleString_Set) {
protozero::HeapBuffered<TestPayload> event;
- WriteIntoTracedProto(context().Wrap(event.get()), TestPayload::kStr,
- std::vector<std::string>{"foo", "bar"});
+ perfetto::TracedProto<TestPayload> proto = context().Wrap(event.get());
+ proto.Set(TestPayload::kSingleString, "foo");
+
+ protos::TestEvent::TestPayload result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_TRUE(result.has_single_string());
+ EXPECT_EQ(result.single_string(), "foo");
+}
+
+TEST_F(TracedProtoTest, RepeatedString_WriteField) {
+ protozero::HeapBuffered<TestPayload> event;
+ perfetto::TracedProto<TestPayload> proto = context().Wrap(event.get());
+ WriteTracedProtoField(proto, TestPayload::kStr,
+ std::vector<std::string>{"foo", "bar"});
+
+ protos::TestEvent::TestPayload result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_THAT(result.str(), ::testing::ElementsAre("foo", "bar"));
+}
+
+TEST_F(TracedProtoTest, RepeatedString_AppendFrom) {
+ protozero::HeapBuffered<TestPayload> event;
+ perfetto::TracedProto<TestPayload> proto = context().Wrap(event.get());
+ proto.AppendFrom(TestPayload::kStr, std::vector<std::string>{"foo", "bar"});
protos::TestEvent::TestPayload result;
result.ParseFromString(event.SerializeAsString());
EXPECT_THAT(result.str(), ::testing::ElementsAre("foo", "bar"));
}
+TEST_F(TracedProtoTest, RepeatedString_AppendValue) {
+ protozero::HeapBuffered<TestPayload> event;
+ perfetto::TracedProto<TestPayload> proto = context().Wrap(event.get());
+ proto.AppendValue(TestPayload::kStr, "foo");
+
+ protos::TestEvent::TestPayload result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_THAT(result.str(), ::testing::ElementsAre("foo"));
+}
+
namespace {
struct Foo {
void WriteIntoTrace(TracedProto<TestPayload> message) const {
message->set_single_int(42);
+
+ auto dict = std::move(message).AddDebugAnnotations();
+ dict.Add("arg", "value");
}
};
+struct Bar {};
+
} // namespace
-TEST_F(TracedProtoTest, SingleNestedMessage) {
+template <>
+struct TraceFormatTraits<Bar> {
+ static void WriteIntoTrace(
+ TracedProto<protos::pbzero::TestEvent::TestPayload> message,
+ const Bar&) {
+ message->set_single_string("value");
+ }
+};
+
+TEST_F(TracedProtoTest, SingleNestedMessage_Method) {
protozero::HeapBuffered<protos::pbzero::TestEvent> event;
- WriteIntoTracedProto(context().Wrap(event.get()),
- protos::pbzero::TestEvent::kPayload, Foo());
+ perfetto::TracedProto<protos::pbzero::TestEvent> proto =
+ context().Wrap(event.get());
+ WriteTracedProtoField(proto, protos::pbzero::TestEvent::kPayload, Foo());
protos::TestEvent result;
result.ParseFromString(event.SerializeAsString());
EXPECT_EQ(result.payload().single_int(), 42);
}
-TEST_F(TracedProtoTest, RepeatedNestedMessage) {
+TEST_F(TracedProtoTest, SingleNestedMessage_TraceFormatTraits) {
+ protozero::HeapBuffered<protos::pbzero::TestEvent> event;
+ perfetto::TracedProto<protos::pbzero::TestEvent> proto =
+ context().Wrap(event.get());
+ WriteTracedProtoField(proto, protos::pbzero::TestEvent::kPayload, Bar());
+
+ protos::TestEvent result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_EQ(result.payload().single_string(), "value");
+}
+
+TEST_F(TracedProtoTest, SingleNestedMessage_Pointer) {
+ protozero::HeapBuffered<protos::pbzero::TestEvent> event;
+ perfetto::TracedProto<protos::pbzero::TestEvent> proto =
+ context().Wrap(event.get());
+ Bar bar;
+ WriteTracedProtoField(proto, protos::pbzero::TestEvent::kPayload, &bar);
+
+ protos::TestEvent result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_EQ(result.payload().single_string(), "value");
+}
+
+TEST_F(TracedProtoTest, SingleNestedMessage_UniquePtr) {
+ protozero::HeapBuffered<protos::pbzero::TestEvent> event;
+ perfetto::TracedProto<protos::pbzero::TestEvent> proto =
+ context().Wrap(event.get());
+ std::unique_ptr<Bar> bar(new Bar);
+ WriteTracedProtoField(proto, protos::pbzero::TestEvent::kPayload, bar);
+
+ protos::TestEvent result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_EQ(result.payload().single_string(), "value");
+}
+
+TEST_F(TracedProtoTest, SingleNestedMessage_EmptyUniquePtr) {
+ protozero::HeapBuffered<protos::pbzero::TestEvent> event;
+ perfetto::TracedProto<protos::pbzero::TestEvent> proto =
+ context().Wrap(event.get());
+ std::unique_ptr<Bar> bar;
+ WriteTracedProtoField(proto, protos::pbzero::TestEvent::kPayload, bar);
+
+ protos::TestEvent result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_FALSE(result.payload().has_single_string());
+}
+
+TEST_F(TracedProtoTest, SingleNestedMessage_Nullptr) {
+ protozero::HeapBuffered<protos::pbzero::TestEvent> event;
+ perfetto::TracedProto<protos::pbzero::TestEvent> proto =
+ context().Wrap(event.get());
+ WriteTracedProtoField(proto, protos::pbzero::TestEvent::kPayload, nullptr);
+
+ protos::TestEvent result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_FALSE(result.payload().has_single_string());
+}
+
+TEST_F(TracedProtoTest, SingleNestedMessage_Method_Set) {
+ protozero::HeapBuffered<protos::pbzero::TestEvent> event;
+ perfetto::TracedProto<protos::pbzero::TestEvent> proto =
+ context().Wrap(event.get());
+ WriteTracedProtoField(proto, protos::pbzero::TestEvent::kPayload, Foo());
+
+ protos::TestEvent result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_EQ(result.payload().single_int(), 42);
+}
+
+TEST_F(TracedProtoTest, SingleNestedMessage_TraceFormatTraits_Set) {
+ protozero::HeapBuffered<protos::pbzero::TestEvent> event;
+ perfetto::TracedProto<protos::pbzero::TestEvent> proto =
+ context().Wrap(event.get());
+ proto.Set(protos::pbzero::TestEvent::kPayload, Bar());
+
+ protos::TestEvent result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_EQ(result.payload().single_string(), "value");
+}
+
+TEST_F(TracedProtoTest, SingleNestedMessage_Pointer_Set) {
+ protozero::HeapBuffered<protos::pbzero::TestEvent> event;
+ perfetto::TracedProto<protos::pbzero::TestEvent> proto =
+ context().Wrap(event.get());
+ Bar bar;
+ proto.Set(protos::pbzero::TestEvent::kPayload, &bar);
+
+ protos::TestEvent result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_EQ(result.payload().single_string(), "value");
+}
+
+TEST_F(TracedProtoTest, SingleNestedMessage_UniquePtr_Set) {
+ protozero::HeapBuffered<protos::pbzero::TestEvent> event;
+ perfetto::TracedProto<protos::pbzero::TestEvent> proto =
+ context().Wrap(event.get());
+ std::unique_ptr<Bar> bar(new Bar);
+ proto.Set(protos::pbzero::TestEvent::kPayload, bar);
+
+ protos::TestEvent result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_EQ(result.payload().single_string(), "value");
+}
+
+TEST_F(TracedProtoTest, SingleNestedMessage_EmptyUniquePtr_Set) {
+ protozero::HeapBuffered<protos::pbzero::TestEvent> event;
+ perfetto::TracedProto<protos::pbzero::TestEvent> proto =
+ context().Wrap(event.get());
+ std::unique_ptr<Bar> bar;
+ proto.Set(protos::pbzero::TestEvent::kPayload, bar);
+
+ protos::TestEvent result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_FALSE(result.payload().has_single_string());
+}
+
+TEST_F(TracedProtoTest, SingleNestedMessage_Nullptr_Set) {
+ protozero::HeapBuffered<protos::pbzero::TestEvent> event;
+ perfetto::TracedProto<protos::pbzero::TestEvent> proto =
+ context().Wrap(event.get());
+ proto.Set(protos::pbzero::TestEvent::kPayload, nullptr);
+
+ protos::TestEvent result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_FALSE(result.payload().has_single_string());
+}
+
+TEST_F(TracedProtoTest, RepeatedNestedMessage_Method) {
+ protozero::HeapBuffered<TestPayload> event;
+ perfetto::TracedProto<TestPayload> proto = context().Wrap(event.get());
+ WriteTracedProtoField(proto, TestPayload::kNested,
+ std::vector<Foo>{Foo(), Foo()});
+
+ protos::TestEvent::TestPayload result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_EQ(result.nested_size(), 2);
+ EXPECT_EQ(result.nested(0).single_int(), 42);
+ EXPECT_EQ(result.nested(1).single_int(), 42);
+}
+
+TEST_F(TracedProtoTest, RepeatedNestedMessage_TraceFormatTraits) {
+ protozero::HeapBuffered<TestPayload> event;
+ perfetto::TracedProto<TestPayload> proto = context().Wrap(event.get());
+ WriteTracedProtoField(proto, TestPayload::kNested,
+ std::vector<Bar>{Bar(), Bar()});
+
+ protos::TestEvent::TestPayload result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_EQ(result.nested_size(), 2);
+ EXPECT_EQ(result.nested(0).single_string(), "value");
+ EXPECT_EQ(result.nested(1).single_string(), "value");
+}
+
+TEST_F(TracedProtoTest, RepeatedNestedMessage_Pointer) {
+ protozero::HeapBuffered<TestPayload> event;
+ perfetto::TracedProto<TestPayload> proto = context().Wrap(event.get());
+ Bar bar;
+ std::vector<Bar*> bars;
+ bars.push_back(&bar);
+ bars.push_back(nullptr);
+ WriteTracedProtoField(proto, TestPayload::kNested, bars);
+
+ protos::TestEvent::TestPayload result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_EQ(result.nested_size(), 2);
+ EXPECT_EQ(result.nested(0).single_string(), "value");
+ EXPECT_FALSE(result.nested(1).has_single_string());
+}
+
+TEST_F(TracedProtoTest, RepeatedNestedMessage_Method_AppendValue) {
+ protozero::HeapBuffered<TestPayload> event;
+ perfetto::TracedProto<TestPayload> proto = context().Wrap(event.get());
+ proto.AppendValue(TestPayload::kNested, Foo());
+
+ protos::TestEvent::TestPayload result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_EQ(result.nested_size(), 1);
+ EXPECT_EQ(result.nested(0).single_int(), 42);
+}
+
+TEST_F(TracedProtoTest, RepeatedNestedMessage_TraceFormatTraits_AppendValue) {
protozero::HeapBuffered<TestPayload> event;
- WriteIntoTracedProto(context().Wrap(event.get()), TestPayload::kNested,
- std::vector<Foo>{Foo(), Foo()});
+ perfetto::TracedProto<TestPayload> proto = context().Wrap(event.get());
+ proto.AppendValue(TestPayload::kNested, Bar());
+
+ protos::TestEvent::TestPayload result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_EQ(result.nested_size(), 1);
+ EXPECT_EQ(result.nested(0).single_string(), "value");
+}
+
+TEST_F(TracedProtoTest, RepeatedNestedMessage_Pointer_AppendValue) {
+ protozero::HeapBuffered<TestPayload> event;
+ perfetto::TracedProto<TestPayload> proto = context().Wrap(event.get());
+ Bar bar;
+ proto.AppendValue(TestPayload::kNested, &bar);
+ proto.AppendValue(TestPayload::kNested, nullptr);
+
+ protos::TestEvent::TestPayload result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_EQ(result.nested_size(), 2);
+ EXPECT_EQ(result.nested(0).single_string(), "value");
+ EXPECT_FALSE(result.nested(1).has_single_string());
+}
+
+TEST_F(TracedProtoTest, RepeatedNestedMessage_Method_AppendFrom) {
+ protozero::HeapBuffered<TestPayload> event;
+ perfetto::TracedProto<TestPayload> proto = context().Wrap(event.get());
+ proto.AppendFrom(TestPayload::kNested, std::vector<Foo>{Foo(), Foo()});
protos::TestEvent::TestPayload result;
result.ParseFromString(event.SerializeAsString());
@@ -114,4 +399,50 @@ TEST_F(TracedProtoTest, RepeatedNestedMessage) {
EXPECT_EQ(result.nested(1).single_int(), 42);
}
+TEST_F(TracedProtoTest, RepeatedNestedMessage_TraceFormatTraits_AppendFrom) {
+ protozero::HeapBuffered<TestPayload> event;
+ perfetto::TracedProto<TestPayload> proto = context().Wrap(event.get());
+ proto.AppendFrom(TestPayload::kNested, std::vector<Bar>{Bar(), Bar()});
+
+ protos::TestEvent::TestPayload result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_EQ(result.nested_size(), 2);
+ EXPECT_EQ(result.nested(0).single_string(), "value");
+ EXPECT_EQ(result.nested(1).single_string(), "value");
+}
+
+TEST_F(TracedProtoTest, RepeatedNestedMessage_Pointer_AppendFrom) {
+ protozero::HeapBuffered<TestPayload> event;
+ perfetto::TracedProto<TestPayload> proto = context().Wrap(event.get());
+ Bar bar;
+ std::vector<Bar*> bars;
+ bars.push_back(&bar);
+ bars.push_back(nullptr);
+ proto.AppendFrom(TestPayload::kNested, bars);
+
+ protos::TestEvent::TestPayload result;
+ result.ParseFromString(event.SerializeAsString());
+ EXPECT_EQ(result.nested_size(), 2);
+ EXPECT_EQ(result.nested(0).single_string(), "value");
+ EXPECT_FALSE(result.nested(1).has_single_string());
+}
+
+TEST_F(TracedProtoTest, WriteDebugAnnotations) {
+ protozero::HeapBuffered<protos::pbzero::TestEvent> event;
+ perfetto::TracedProto<protos::pbzero::TestEvent> proto =
+ context().Wrap(event.get());
+ WriteTracedProtoField(proto, protos::pbzero::TestEvent::kPayload, Foo());
+
+ protos::TestEvent result;
+ result.ParseFromString(event.SerializeAsString());
+
+ protos::DebugAnnotation dict;
+ for (const auto& annotation : result.payload().debug_annotations()) {
+ *dict.add_dict_entries() = annotation;
+ }
+
+ EXPECT_EQ(internal::DebugAnnotationToString(dict.SerializeAsString()),
+ "{arg:value}");
+}
+
} // namespace perfetto
diff --git a/src/tracing/traced_value.cc b/src/tracing/traced_value.cc
index 9ac3fd241..801b8b5b2 100644
--- a/src/tracing/traced_value.cc
+++ b/src/tracing/traced_value.cc
@@ -18,6 +18,7 @@
#include "perfetto/base/logging.h"
#include "perfetto/tracing/debug_annotation.h"
+#include "perfetto/tracing/internal/track_event_interned_fields.h"
#include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
namespace perfetto {
@@ -25,56 +26,61 @@ namespace perfetto {
namespace internal {
TracedValue CreateTracedValueFromProto(
- protos::pbzero::DebugAnnotation* context) {
- return TracedValue::CreateFromProto(context);
+ protos::pbzero::DebugAnnotation* annotation,
+ EventContext* event_context) {
+ return TracedValue::CreateFromProto(annotation, event_context);
}
} // namespace internal
// static
TracedValue TracedValue::CreateFromProto(
- protos::pbzero::DebugAnnotation* context) {
- return TracedValue(context, nullptr);
+ protos::pbzero::DebugAnnotation* annotation,
+ EventContext* event_context) {
+ return TracedValue(annotation, event_context, nullptr);
}
+TracedValue::TracedValue(TracedValue&&) = default;
+TracedValue::~TracedValue() = default;
+
void TracedValue::WriteInt64(int64_t value) && {
PERFETTO_DCHECK(checked_scope_.is_active());
- context_->set_int_value(value);
+ annotation_->set_int_value(value);
}
void TracedValue::WriteUInt64(uint64_t value) && {
PERFETTO_DCHECK(checked_scope_.is_active());
- context_->set_uint_value(value);
+ annotation_->set_uint_value(value);
}
void TracedValue::WriteDouble(double value) && {
PERFETTO_DCHECK(checked_scope_.is_active());
- context_->set_double_value(value);
+ annotation_->set_double_value(value);
}
void TracedValue::WriteBoolean(bool value) && {
PERFETTO_DCHECK(checked_scope_.is_active());
- context_->set_bool_value(value);
+ annotation_->set_bool_value(value);
}
void TracedValue::WriteString(const char* value) && {
PERFETTO_DCHECK(checked_scope_.is_active());
- context_->set_string_value(value);
+ annotation_->set_string_value(value);
}
void TracedValue::WriteString(const char* value, size_t len) && {
PERFETTO_DCHECK(checked_scope_.is_active());
- context_->set_string_value(value, len);
+ annotation_->set_string_value(value, len);
}
void TracedValue::WriteString(const std::string& value) && {
PERFETTO_DCHECK(checked_scope_.is_active());
- context_->set_string_value(value);
+ annotation_->set_string_value(value);
}
void TracedValue::WritePointer(const void* value) && {
PERFETTO_DCHECK(checked_scope_.is_active());
- context_->set_pointer_value(reinterpret_cast<uint64_t>(value));
+ annotation_->set_pointer_value(reinterpret_cast<uint64_t>(value));
}
TracedDictionary TracedValue::WriteDictionary() && {
@@ -83,8 +89,10 @@ TracedDictionary TracedValue::WriteDictionary() && {
PERFETTO_DCHECK(checked_scope_.is_active());
checked_scope_.Reset();
- PERFETTO_DCHECK(!context_->is_finalized());
- return TracedDictionary(context_, checked_scope_.parent_scope());
+ PERFETTO_DCHECK(!annotation_->is_finalized());
+ return TracedDictionary(annotation_,
+ protos::pbzero::DebugAnnotation::kDictEntries,
+ event_context_, checked_scope_.parent_scope());
}
TracedArray TracedValue::WriteArray() && {
@@ -93,13 +101,30 @@ TracedArray TracedValue::WriteArray() && {
PERFETTO_DCHECK(checked_scope_.is_active());
checked_scope_.Reset();
- PERFETTO_DCHECK(!context_->is_finalized());
- return TracedArray(context_, checked_scope_.parent_scope());
+ PERFETTO_DCHECK(!annotation_->is_finalized());
+ return TracedArray(annotation_, event_context_,
+ checked_scope_.parent_scope());
+}
+
+protozero::Message* TracedValue::WriteProtoInternal(const char* name) {
+ if (event_context_) {
+ annotation_->set_proto_type_name_iid(
+ internal::InternedDebugAnnotationValueTypeName::Get(event_context_,
+ name));
+ } else {
+ annotation_->set_proto_type_name(name);
+ }
+ return annotation_->template BeginNestedMessage<protozero::Message>(
+ protos::pbzero::DebugAnnotation::kProtoValueFieldNumber);
}
+TracedArray::TracedArray(TracedValue annotation)
+ : TracedArray(std::move(annotation).WriteArray()) {}
+
TracedValue TracedArray::AppendItem() {
PERFETTO_DCHECK(checked_scope_.is_active());
- return TracedValue(context_->add_array_values(), &checked_scope_);
+ return TracedValue(annotation_->add_array_values(), event_context_,
+ &checked_scope_);
}
TracedDictionary TracedArray::AppendDictionary() {
@@ -112,18 +137,23 @@ TracedArray TracedArray::AppendArray() {
return AppendItem().WriteArray();
}
+TracedDictionary::TracedDictionary(TracedValue annotation)
+ : TracedDictionary(std::move(annotation).WriteDictionary()) {}
+
TracedValue TracedDictionary::AddItem(StaticString key) {
PERFETTO_DCHECK(checked_scope_.is_active());
- protos::pbzero::DebugAnnotation* item = context_->add_dict_entries();
+ protos::pbzero::DebugAnnotation* item =
+ message_->BeginNestedMessage<protos::pbzero::DebugAnnotation>(field_id_);
item->set_name(key.value);
- return TracedValue(item, &checked_scope_);
+ return TracedValue(item, event_context_, &checked_scope_);
}
TracedValue TracedDictionary::AddItem(DynamicString key) {
PERFETTO_DCHECK(checked_scope_.is_active());
- protos::pbzero::DebugAnnotation* item = context_->add_dict_entries();
+ protos::pbzero::DebugAnnotation* item =
+ message_->BeginNestedMessage<protos::pbzero::DebugAnnotation>(field_id_);
item->set_name(key.value);
- return TracedValue(item, &checked_scope_);
+ return TracedValue(item, event_context_, &checked_scope_);
}
TracedDictionary TracedDictionary::AddDictionary(StaticString key) {
diff --git a/src/tracing/traced_value_unittest.cc b/src/tracing/traced_value_unittest.cc
index 66c86dbbb..05fa11636 100644
--- a/src/tracing/traced_value_unittest.cc
+++ b/src/tracing/traced_value_unittest.cc
@@ -32,6 +32,8 @@
#include "perfetto/test/traced_value_test_support.h"
#include "perfetto/tracing/debug_annotation.h"
#include "perfetto/tracing/track_event.h"
+#include "protos/perfetto/trace/test_event.pb.h"
+#include "protos/perfetto/trace/test_event.pbzero.h"
#include "protos/perfetto/trace/track_event/debug_annotation.gen.h"
#include "protos/perfetto/trace/track_event/debug_annotation.pb.h"
#include "test/gtest_and_gmock.h"
@@ -619,4 +621,123 @@ TEST(TracedValueTest, EmptyArray) {
}));
}
+TEST(TracedValueTest, WriteTypedProto_Explicit) {
+ protozero::HeapBuffered<protos::pbzero::DebugAnnotation> message;
+ WriteIntoTracedValue(
+ internal::CreateTracedValueFromProto(message.get()),
+ [](perfetto::TracedValue context) {
+ perfetto::TracedProto<protos::pbzero::TestEvent::TestPayload> proto =
+ std::move(context)
+ .WriteProto<protos::pbzero::TestEvent::TestPayload>();
+ proto->set_single_string("payload");
+ });
+
+ protos::DebugAnnotation annotation;
+ annotation.ParseFromString(message.SerializeAsString());
+ EXPECT_EQ(annotation.proto_type_name(),
+ ".perfetto.protos.TestEvent.TestPayload");
+
+ protos::TestEvent::TestPayload payload;
+ payload.ParseFromString(annotation.proto_value());
+ EXPECT_EQ(payload.single_string(), "payload");
+}
+
+TEST(TracedValueTest, WriteTypedProto_Implicit) {
+ protozero::HeapBuffered<protos::pbzero::DebugAnnotation> message;
+ WriteIntoTracedValue(
+ internal::CreateTracedValueFromProto(message.get()),
+ [](perfetto::TracedProto<protos::pbzero::TestEvent::TestPayload> proto) {
+ proto->set_single_string("payload");
+ });
+
+ protos::DebugAnnotation annotation;
+ annotation.ParseFromString(message.SerializeAsString());
+ EXPECT_EQ(annotation.proto_type_name(),
+ ".perfetto.protos.TestEvent.TestPayload");
+
+ protos::TestEvent::TestPayload payload;
+ payload.ParseFromString(annotation.proto_value());
+ EXPECT_EQ(payload.single_string(), "payload");
+}
+
+TEST(TracedValueTest, ImplicitTracedDictionary) {
+ EXPECT_EQ("{key:value}", TracedValueToString([&](TracedDictionary dict) {
+ dict.Add("key", "value");
+ }));
+}
+
+TEST(TracedValueTest, ImplicitTracedArray) {
+ EXPECT_EQ("[1]",
+ TracedValueToString([&](TracedArray array) { array.Append(1); }));
+}
+
+TEST(TracedValueTest, TracedProtoInDict) {
+ struct Foo {
+ void WriteIntoTrace(
+ perfetto::TracedProto<protos::pbzero::TestEvent::TestPayload> message) {
+ message->set_single_int(42);
+ }
+ };
+ Foo foo;
+ protozero::HeapBuffered<protos::pbzero::DebugAnnotation> message;
+ WriteIntoTracedValue(internal::CreateTracedValueFromProto(message.get()),
+ [&](TracedDictionary dict) { dict.Add("foo", foo); });
+ protos::DebugAnnotation annotation;
+ annotation.ParseFromString(message.SerializeAsString());
+ EXPECT_EQ(annotation.dict_entries_size(), 1);
+ EXPECT_EQ(annotation.dict_entries(0).name(), "foo");
+ EXPECT_EQ(annotation.dict_entries(0).proto_type_name(),
+ ".perfetto.protos.TestEvent.TestPayload");
+
+ protos::TestEvent::TestPayload payload;
+ payload.ParseFromString(annotation.dict_entries(0).proto_value());
+ EXPECT_EQ(payload.single_int(), 42);
+}
+
+TEST(TracedValueTest, PointerToTracedProtoInDict) {
+ struct Foo {
+ void WriteIntoTrace(
+ perfetto::TracedProto<protos::pbzero::TestEvent::TestPayload> message) {
+ message->set_single_int(42);
+ }
+ };
+ Foo foo;
+ protozero::HeapBuffered<protos::pbzero::DebugAnnotation> message;
+ WriteIntoTracedValue(internal::CreateTracedValueFromProto(message.get()),
+ [&](TracedDictionary dict) { dict.Add("foo", &foo); });
+ protos::DebugAnnotation annotation;
+ annotation.ParseFromString(message.SerializeAsString());
+ EXPECT_EQ(annotation.dict_entries_size(), 1);
+ EXPECT_EQ(annotation.dict_entries(0).name(), "foo");
+ EXPECT_EQ(annotation.dict_entries(0).proto_type_name(),
+ ".perfetto.protos.TestEvent.TestPayload");
+
+ protos::TestEvent::TestPayload payload;
+ payload.ParseFromString(annotation.dict_entries(0).proto_value());
+ EXPECT_EQ(payload.single_int(), 42);
+}
+
+TEST(TracedValueTest, UniquePointerToTracedProtoInDict) {
+ struct Foo {
+ void WriteIntoTrace(
+ perfetto::TracedProto<protos::pbzero::TestEvent::TestPayload> message) {
+ message->set_single_int(42);
+ }
+ };
+ std::unique_ptr<Foo> foo(new Foo());
+ protozero::HeapBuffered<protos::pbzero::DebugAnnotation> message;
+ WriteIntoTracedValue(internal::CreateTracedValueFromProto(message.get()),
+ [&](TracedDictionary dict) { dict.Add("foo", foo); });
+ protos::DebugAnnotation annotation;
+ annotation.ParseFromString(message.SerializeAsString());
+ EXPECT_EQ(annotation.dict_entries_size(), 1);
+ EXPECT_EQ(annotation.dict_entries(0).name(), "foo");
+ EXPECT_EQ(annotation.dict_entries(0).proto_type_name(),
+ ".perfetto.protos.TestEvent.TestPayload");
+
+ protos::TestEvent::TestPayload payload;
+ payload.ParseFromString(annotation.dict_entries(0).proto_value());
+ EXPECT_EQ(payload.single_int(), 42);
+}
+
} // namespace perfetto
diff --git a/src/tracing/tracing.cc b/src/tracing/tracing.cc
index 019341ec9..ab495cfa7 100644
--- a/src/tracing/tracing.cc
+++ b/src/tracing/tracing.cc
@@ -20,6 +20,7 @@
#include <condition_variable>
#include <mutex>
+#include "perfetto/ext/base/no_destructor.h"
#include "perfetto/ext/base/waitable_event.h"
#include "perfetto/tracing/internal/track_event_internal.h"
#include "src/tracing/internal/tracing_muxer_impl.h"
@@ -27,10 +28,17 @@
namespace perfetto {
namespace {
bool g_was_initialized = false;
+
+// Wrapped in a function to avoid global constructor
+std::mutex& InitializedMutex() {
+ static base::NoDestructor<std::mutex> initialized_mutex;
+ return initialized_mutex.ref();
+}
}
// static
void Tracing::InitializeInternal(const TracingInitArgs& args) {
+ std::unique_lock<std::mutex> lock(InitializedMutex());
static TracingInitArgs init_args;
if (g_was_initialized) {
if (!(init_args == args)) {
@@ -45,7 +53,7 @@ void Tracing::InitializeInternal(const TracingInitArgs& args) {
// Make sure the headers and implementation files agree on the build config.
PERFETTO_CHECK(args.dcheck_is_on_ == PERFETTO_DCHECK_IS_ON());
if (args.log_message_callback) {
- SetLogMessageCallback(args.log_message_callback);
+ base::SetLogMessageCallback(args.log_message_callback);
}
internal::TracingMuxerImpl::InitializeInstance(args);
internal::TrackRegistry::InitializeInstance();
@@ -55,9 +63,21 @@ void Tracing::InitializeInternal(const TracingInitArgs& args) {
// static
bool Tracing::IsInitialized() {
+ std::unique_lock<std::mutex> lock(InitializedMutex());
return g_was_initialized;
}
+// static
+void Tracing::ResetForTesting() {
+ std::unique_lock<std::mutex> lock(InitializedMutex());
+ if (!g_was_initialized)
+ return;
+ base::SetLogMessageCallback(nullptr);
+ internal::TracingMuxerImpl::ResetForTesting();
+ internal::TrackRegistry::ResetForTesting();
+ g_was_initialized = false;
+}
+
// static
std::unique_ptr<TracingSession> Tracing::NewTrace(BackendType backend) {
return static_cast<internal::TracingMuxerImpl*>(internal::TracingMuxer::Get())
diff --git a/src/tracing/track.cc b/src/tracing/track.cc
index c1e7e01da..467a56b2b 100644
--- a/src/tracing/track.cc
+++ b/src/tracing/track.cc
@@ -167,7 +167,7 @@ void TrackRegistry::InitializeInstance() {
if (uint64_t start_time = GetProcessStartTime()) {
base::Hash hash;
hash.Update(start_time);
- hash.Update(base::GetProcessId());
+ hash.Update(Platform::GetCurrentProcessId());
Track::process_uuid = hash.digest();
} else {
// Fall back to a randomly generated identifier.
@@ -175,6 +175,11 @@ void TrackRegistry::InitializeInstance() {
}
}
+void TrackRegistry::ResetForTesting() {
+ delete instance_;
+ instance_ = nullptr;
+}
+
void TrackRegistry::UpdateTrack(Track track,
const std::string& serialized_desc) {
std::lock_guard<std::mutex> lock(mutex_);
diff --git a/src/tracing/track_event_legacy.cc b/src/tracing/track_event_legacy.cc
index 744416f7f..25fd0d5fe 100644
--- a/src/tracing/track_event_legacy.cc
+++ b/src/tracing/track_event_legacy.cc
@@ -15,6 +15,7 @@
*/
#include "perfetto/tracing/track_event_legacy.h"
+#include "perfetto/ext/base/hash.h"
#include "perfetto/tracing/track.h"
@@ -51,15 +52,20 @@ void LegacyTraceId::Write(protos::pbzero::TrackEvent::LegacyEvent* event,
uint32_t scope_flags = id_flags_ & (legacy::kTraceEventFlagHasId |
legacy::kTraceEventFlagHasLocalId |
legacy::kTraceEventFlagHasGlobalId);
+ uint64_t id = raw_id_;
+ if (scope_ && scope_flags != legacy::kTraceEventFlagHasGlobalId) {
+ id = base::Hash::Combine(id, scope_);
+ }
+
switch (scope_flags) {
case legacy::kTraceEventFlagHasId:
- event->set_unscoped_id(raw_id_);
+ event->set_unscoped_id(id);
break;
case legacy::kTraceEventFlagHasLocalId:
- event->set_local_id(raw_id_);
+ event->set_local_id(id);
break;
case legacy::kTraceEventFlagHasGlobalId:
- event->set_global_id(raw_id_);
+ event->set_global_id(id);
break;
}
if (scope_)
diff --git a/src/tracing/track_event_state_tracker.cc b/src/tracing/track_event_state_tracker.cc
index 7cb1b09a6..7ff50ac00 100644
--- a/src/tracing/track_event_state_tracker.cc
+++ b/src/tracing/track_event_state_tracker.cc
@@ -17,8 +17,10 @@
#include "perfetto/tracing/track_event_state_tracker.h"
#include "perfetto/ext/base/hash.h"
+#include "perfetto/tracing/internal/track_event_internal.h"
#include "protos/perfetto/common/interceptor_descriptor.gen.h"
+#include "protos/perfetto/trace/clock_snapshot.pbzero.h"
#include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
#include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
@@ -30,6 +32,8 @@
namespace perfetto {
+using internal::TrackEventIncrementalState;
+
TrackEventStateTracker::~TrackEventStateTracker() = default;
TrackEventStateTracker::Delegate::~Delegate() = default;
@@ -45,8 +49,15 @@ void TrackEventStateTracker::ProcessTracePacket(
perfetto::protos::pbzero::TrackEvent::Decoder track_event(
packet.track_event());
- // TODO(skyostil): Support incremental timestamps.
+ auto clock_id = packet.timestamp_clock_id();
+ if (!packet.has_timestamp_clock_id())
+ clock_id = sequence_state.default_clock_id;
uint64_t timestamp = packet.timestamp();
+ // TODO(mohitms): Incorporate unit multiplier as well.
+ if (clock_id == TrackEventIncrementalState::kClockIdIncremental) {
+ timestamp += sequence_state.most_recent_absolute_time_ns;
+ sequence_state.most_recent_absolute_time_ns = timestamp;
+ }
Track* track = &sequence_state.track;
if (track_event.has_track_uuid()) {
@@ -163,6 +174,19 @@ void TrackEventStateTracker::UpdateIncrementalState(
}
#endif
+ perfetto::protos::pbzero::ClockSnapshot::Decoder snapshot(
+ packet.clock_snapshot());
+ for (auto it = snapshot.clocks(); it; ++it) {
+ perfetto::protos::pbzero::ClockSnapshot::Clock::Decoder clock(*it);
+ // TODO(mohitms) : Handle the incremental clock other than default one.
+ if (clock.is_incremental() &&
+ clock.clock_id() == TrackEventIncrementalState::kClockIdIncremental) {
+ sequence_state.most_recent_absolute_time_ns =
+ clock.timestamp() * clock.unit_multiplier_ns();
+ break;
+ }
+ }
+
if (packet.sequence_flags() &
perfetto::protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED) {
// Convert any existing event names and categories on the stack to
@@ -208,6 +232,8 @@ void TrackEventStateTracker::UpdateIncrementalState(
perfetto::protos::pbzero::TrackEventDefaults::Decoder
track_event_defaults(defaults.track_event_defaults());
sequence_state.track.uuid = track_event_defaults.track_uuid();
+ if (defaults.has_timestamp_clock_id())
+ sequence_state.default_clock_id = defaults.timestamp_clock_id();
}
}
if (packet.has_track_descriptor()) {
diff --git a/src/tracing/virtual_destructors.cc b/src/tracing/virtual_destructors.cc
index d47355171..272d013f7 100644
--- a/src/tracing/virtual_destructors.cc
+++ b/src/tracing/virtual_destructors.cc
@@ -28,6 +28,18 @@ namespace internal {
TracingTLS::~TracingTLS() {
// Avoid entering trace points while the thread is being torn down.
+ // This is the problem: when a thread exits, the at-thread-exit destroys the
+ // TracingTLS. As part of that the various TraceWriter for the active data
+ // sources are destroyd. A TraceWriter dtor will issue a PostTask on the IPC
+ // thread to issue a final flush and unregister its ID with the service.
+ // The PostTask, in chromium, might have a trace event that will try to
+ // re-enter the tracing system.
+ // We fix this by resetting the TLS key to the TracingTLS object that is
+ // being destroyed in the platform impl (platform_posix.cc,
+ // platform_windows.cc, chromium's platform.cc). We carefully rely on the fact
+ // that all the tracing path that will be invoked during thread exit will
+ // early out if |is_in_trace_point| == true and will not depend on the other
+ // TLS state that has been destroyed.
is_in_trace_point = true;
}
diff --git a/src/websocket_bridge/BUILD.gn b/src/websocket_bridge/BUILD.gn
new file mode 100644
index 000000000..38f3e66d3
--- /dev/null
+++ b/src/websocket_bridge/BUILD.gn
@@ -0,0 +1,35 @@
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source_set("lib") {
+ deps = [
+ "../../gn:default_deps",
+ "../base",
+ "../base:unix_socket",
+ "../base/http",
+ "../tracing/ipc:default_socket",
+ ]
+ sources = [
+ "websocket_bridge.cc",
+ "websocket_bridge.h",
+ ]
+}
+
+executable("websocket_bridge") {
+ deps = [
+ ":lib",
+ "../../gn:default_deps",
+ ]
+ sources = [ "websocket_bridge_main.cc" ]
+}
diff --git a/src/websocket_bridge/websocket_bridge.cc b/src/websocket_bridge/websocket_bridge.cc
new file mode 100644
index 000000000..eb265068e
--- /dev/null
+++ b/src/websocket_bridge/websocket_bridge.cc
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/websocket_bridge/websocket_bridge.h"
+
+#include <stdint.h>
+
+#include <map>
+#include <memory>
+#include <vector>
+
+#include "perfetto/ext/base/http/http_server.h"
+#include "perfetto/ext/base/unix_socket.h"
+#include "perfetto/ext/base/unix_task_runner.h"
+#include "perfetto/ext/tracing/ipc/default_socket.h"
+
+namespace perfetto {
+namespace {
+
+constexpr int kWebsocketPort = 8037;
+
+struct Endpoint {
+ const char* uri;
+ const char* endpoint;
+ base::SockFamily family;
+};
+
+class WSBridge : public base::HttpRequestHandler,
+ public base::UnixSocket::EventListener {
+ public:
+ void Main(int argc, char** argv);
+
+ // base::HttpRequestHandler implementation.
+ void OnHttpRequest(const base::HttpRequest&) override;
+ void OnWebsocketMessage(const base::WebsocketMessage&) override;
+ void OnHttpConnectionClosed(base::HttpServerConnection*) override;
+
+ // base::UnixSocket::EventListener implementation.
+ void OnNewIncomingConnection(base::UnixSocket*,
+ std::unique_ptr<base::UnixSocket>) override;
+ void OnConnect(base::UnixSocket*, bool) override;
+ void OnDisconnect(base::UnixSocket*) override;
+ void OnDataAvailable(base::UnixSocket* self) override;
+
+ private:
+ base::HttpServerConnection* GetWebsocket(base::UnixSocket*);
+
+ base::UnixTaskRunner task_runner_;
+ std::vector<Endpoint> endpoints_;
+ std::map<base::HttpServerConnection*, std::unique_ptr<base::UnixSocket>>
+ conns_;
+};
+
+void WSBridge::Main(int, char**) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ // On Windows traced used a TCP socket.
+ const auto kTracedFamily = base::SockFamily::kInet;
+#else
+ const auto kTracedFamily = base::SockFamily::kUnix;
+#endif
+ endpoints_.push_back({"/traced", GetConsumerSocket(), kTracedFamily});
+ endpoints_.push_back({"/adb", "127.0.0.1:5037", base::SockFamily::kInet});
+
+ base::HttpServer srv(&task_runner_, this);
+ srv.AddAllowedOrigin("http://localhost:10000");
+ srv.AddAllowedOrigin("http://127.0.0.1:10000");
+ srv.AddAllowedOrigin("https://ui.perfetto.dev");
+
+ srv.Start(kWebsocketPort);
+ PERFETTO_LOG("[WSBridge] Listening on 127.0.0.1:%d", kWebsocketPort);
+ task_runner_.Run();
+}
+
+void WSBridge::OnHttpRequest(const base::HttpRequest& req) {
+ for (const auto& ep : endpoints_) {
+ if (req.uri != ep.uri || !req.is_websocket_handshake)
+ continue;
+
+ // Connect to the endpoint in blocking mode.
+ auto sock_raw =
+ base::UnixSocketRaw::CreateMayFail(ep.family, base::SockType::kStream);
+ if (!sock_raw) {
+ PERFETTO_PLOG("socket() failed");
+ req.conn->SendResponseAndClose("500 Server Error");
+ return;
+ }
+ PERFETTO_LOG("[WSBridge] New connection from \"%.*s\"",
+ static_cast<int>(req.origin.size()), req.origin.data());
+ sock_raw.SetTxTimeout(3000);
+ sock_raw.SetBlocking(true);
+
+ if (!sock_raw.Connect(ep.endpoint)) {
+ PERFETTO_ELOG("[WSBridge] Connection to %s failed", ep.endpoint);
+ req.conn->SendResponseAndClose("503 Service Unavailable");
+ return;
+ }
+ sock_raw.SetBlocking(false);
+
+ PERFETTO_DLOG("[WSBridge] Connected to %s", ep.endpoint);
+ conns_[req.conn] = base::UnixSocket::AdoptConnected(
+ sock_raw.ReleaseFd(), this, &task_runner_, ep.family,
+ base::SockType::kStream);
+
+ req.conn->UpgradeToWebsocket(req);
+ return;
+ } // for (endpoint)
+ req.conn->SendResponseAndClose("404 Not Found");
+}
+
+// Called when an inbound websocket message is received from the browser.
+void WSBridge::OnWebsocketMessage(const base::WebsocketMessage& msg) {
+ auto it = conns_.find(msg.conn);
+ PERFETTO_CHECK(it != conns_.end());
+ // Pass through the websocket message onto the endpoint TCP socket.
+ base::UnixSocket& sock = *it->second;
+ sock.Send(msg.data.data(), msg.data.size());
+}
+
+// Called when a TCP message is received from the endpoint.
+void WSBridge::OnDataAvailable(base::UnixSocket* sock) {
+ base::HttpServerConnection* websocket = GetWebsocket(sock);
+ PERFETTO_CHECK(websocket);
+
+ char buf[8192];
+ auto rsize = sock->Receive(buf, sizeof(buf));
+ if (rsize > 0) {
+ websocket->SendWebsocketMessage(buf, static_cast<size_t>(rsize));
+ } else {
+ // Connection closed or errored.
+ sock->Shutdown(/*notify=*/true); // Will trigger OnDisconnect().
+ websocket->Close();
+ }
+}
+
+// Called when the browser terminates the websocket connection.
+void WSBridge::OnHttpConnectionClosed(base::HttpServerConnection* websocket) {
+ PERFETTO_DLOG("[WSBridge] Websocket connection closed");
+ auto it = conns_.find(websocket);
+ if (it == conns_.end())
+ return; // Can happen if ADB closed first.
+ base::UnixSocket& sock = *it->second;
+ sock.Shutdown(/*notify=*/true);
+ conns_.erase(websocket);
+}
+
+void WSBridge::OnDisconnect(base::UnixSocket* sock) {
+ base::HttpServerConnection* websocket = GetWebsocket(sock);
+ if (!websocket)
+ return;
+ websocket->Close();
+ sock->Shutdown(/*notify=*/false);
+ conns_.erase(websocket);
+ PERFETTO_DLOG("[WSBridge] Socket connection closed");
+}
+
+base::HttpServerConnection* WSBridge::GetWebsocket(base::UnixSocket* sock) {
+ for (const auto& it : conns_) {
+ if (it.second.get() == sock) {
+ return it.first;
+ }
+ }
+ return nullptr;
+}
+
+void WSBridge::OnConnect(base::UnixSocket*, bool) {}
+void WSBridge::OnNewIncomingConnection(base::UnixSocket*,
+ std::unique_ptr<base::UnixSocket>) {}
+
+} // namespace
+
+int PERFETTO_EXPORT_ENTRYPOINT WebsocketBridgeMain(int argc, char** argv) {
+ perfetto::WSBridge ws_bridge;
+ ws_bridge.Main(argc, argv);
+ return 0;
+}
+
+} // namespace perfetto
diff --git a/src/websocket_bridge/websocket_bridge.h b/src/websocket_bridge/websocket_bridge.h
new file mode 100644
index 000000000..d93bd6127
--- /dev/null
+++ b/src/websocket_bridge/websocket_bridge.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_WEBSOCKET_BRIDGE_WEBSOCKET_BRIDGE_H_
+#define SRC_WEBSOCKET_BRIDGE_WEBSOCKET_BRIDGE_H_
+
+#include "perfetto/base/compiler.h"
+
+namespace perfetto {
+int WebsocketBridgeMain(int argc, char** argv);
+}
+
+#endif // SRC_WEBSOCKET_BRIDGE_WEBSOCKET_BRIDGE_H_
diff --git a/src/websocket_bridge/websocket_bridge_main.cc b/src/websocket_bridge/websocket_bridge_main.cc
new file mode 100644
index 000000000..480522b58
--- /dev/null
+++ b/src/websocket_bridge/websocket_bridge_main.cc
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/websocket_bridge/websocket_bridge.h"
+
+// This is split in a dedicated translation unit so that tracebox can refer to
+// WebsocketBridgeMain() without pulling in a main() symbol.
+int main(int argc, char** argv) {
+ return perfetto::WebsocketBridgeMain(argc, argv);
+}
diff --git a/test/.gitignore b/test/.gitignore
index efce6ad5a..3cb1d2bee 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -1 +1,9 @@
+# We only keep the xxx.sha256 files in the git repo.
+# The corresponding binary files are downloaded by
+# `tools/test_data download`, ran by install-build-deps.
/data/*
+!/data/*.sha256
+
+!/data/ui-screenshots
+/data/ui-screenshots/*
+!/data/ui-screenshots/*.sha256
diff --git a/test/BUILD.gn b/test/BUILD.gn
index 64e683a3e..768b8ad2b 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -17,7 +17,7 @@ import("../gn/fuzzer.gni")
import("../gn/perfetto.gni")
if (!build_with_chromium && enable_perfetto_integration_tests) {
- source_set("end_to_end_integrationtests") {
+ source_set("integrationtests") {
testonly = true
deps = [
":test_helper",
@@ -41,6 +41,7 @@ if (!build_with_chromium && enable_perfetto_integration_tests) {
]
if (enable_perfetto_traced_probes) {
deps += [
+ "../src/protozero/filtering:bytecode_generator",
"../src/traced/probes/ftrace",
"../src/traced/probes/ftrace:ftrace_procfs",
]
@@ -53,10 +54,13 @@ if (!build_with_chromium && enable_perfetto_integration_tests) {
"../src/perfetto_cmd:trigger_perfetto",
]
- sources = [ "end_to_end_integrationtest.cc" ]
+ sources = [
+ "android_integrationtest.cc",
+ "cmdline_integrationtest.cc",
+ "ftrace_integrationtest.cc",
+ "traced_integrationtest.cc",
+ ]
if (start_daemons_for_testing) {
- cflags = [ "-DPERFETTO_START_DAEMONS_FOR_TESTING" ]
-
# In CTS mode we use /syste/bin/perfetto for the cmdline tests and the
# perfetto_cmd is not required. Outside of CTS mode, instead, we need to
# build the cmdline code as part of the test executable.
@@ -137,9 +141,6 @@ if (enable_perfetto_benchmarks || is_fuzzer ||
"android_test_utils.h",
]
}
- if (start_daemons_for_testing) {
- cflags = [ "-DPERFETTO_START_DAEMONS_FOR_TESTING" ]
- }
if (!build_with_chromium && enable_perfetto_traced_probes) {
deps += [
"../include/perfetto/ext/traced",
@@ -164,9 +165,6 @@ if (enable_perfetto_benchmarks) {
"../src/base:test_support",
]
sources = [ "end_to_end_benchmark.cc" ]
- if (start_daemons_for_testing) {
- cflags = [ "-DPERFETTO_START_DAEMONS_FOR_TESTING" ]
- }
}
source_set("benchmark_main") {
diff --git a/test/android_integrationtest.cc b/test/android_integrationtest.cc
new file mode 100644
index 000000000..19e894de2
--- /dev/null
+++ b/test/android_integrationtest.cc
@@ -0,0 +1,407 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/pipe.h"
+#include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/utils.h"
+#include "perfetto/ext/tracing/core/commit_data_request.h"
+#include "perfetto/ext/tracing/core/trace_packet.h"
+#include "perfetto/ext/tracing/core/tracing_service.h"
+#include "perfetto/protozero/scattered_heap_buffer.h"
+#include "src/base/test/test_task_runner.h"
+#include "src/base/test/utils.h"
+#include "test/gtest_and_gmock.h"
+#include "test/test_helper.h"
+
+#include "protos/perfetto/config/power/android_power_config.pbzero.h"
+#include "protos/perfetto/config/test_config.gen.h"
+#include "protos/perfetto/config/trace_config.gen.h"
+#include "protos/perfetto/trace/ftrace/ftrace.gen.h"
+#include "protos/perfetto/trace/ftrace/ftrace_event.gen.h"
+#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.gen.h"
+#include "protos/perfetto/trace/ftrace/ftrace_stats.gen.h"
+#include "protos/perfetto/trace/perfetto/tracing_service_event.gen.h"
+#include "protos/perfetto/trace/power/battery_counters.gen.h"
+#include "protos/perfetto/trace/test_event.gen.h"
+#include "protos/perfetto/trace/trace.gen.h"
+#include "protos/perfetto/trace/trace_packet.gen.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+#include "protos/perfetto/trace/trigger.gen.h"
+
+#include "protos/perfetto/common/sys_stats_counters.gen.h"
+#include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
+#include "protos/perfetto/trace/sys_stats/sys_stats.gen.h"
+
+namespace perfetto {
+
+namespace {
+
+using ::testing::ContainsRegex;
+using ::testing::Each;
+using ::testing::ElementsAreArray;
+using ::testing::HasSubstr;
+using ::testing::Property;
+using ::testing::SizeIs;
+
+// For the SaveForBugreport* tests.
+void SetTraceConfigForBugreportTest(TraceConfig* trace_config) {
+ trace_config->add_buffers()->set_size_kb(4096);
+ trace_config->set_duration_ms(60000); // Will never hit this.
+ trace_config->set_bugreport_score(10);
+ auto* ds_config = trace_config->add_data_sources()->mutable_config();
+ ds_config->set_name("android.perfetto.FakeProducer");
+ ds_config->mutable_for_testing()->set_message_count(3);
+ ds_config->mutable_for_testing()->set_message_size(10);
+ ds_config->mutable_for_testing()->set_send_batch_on_register(true);
+}
+
+// For the SaveForBugreport* tests.
+static void VerifyBugreportTraceContents() {
+ // Read the trace written in the fixed location (/data/misc/perfetto-traces/
+ // on Android, /tmp/ on Linux/Mac) and make sure it has the right contents.
+ std::string trace_str;
+ base::ReadFile(GetBugreportPath(), &trace_str);
+ ASSERT_FALSE(trace_str.empty());
+ protos::gen::Trace trace;
+ ASSERT_TRUE(trace.ParseFromString(trace_str));
+ int test_packets = 0;
+ for (const auto& p : trace.packet())
+ test_packets += p.has_for_testing() ? 1 : 0;
+ ASSERT_EQ(test_packets, 3);
+}
+
+} // namespace
+
+TEST(PerfettoAndroidIntegrationTest, TestKmemActivity) {
+ using C = protos::gen::VmstatCounters;
+
+ base::TestTaskRunner task_runner;
+
+ TestHelper helper(&task_runner);
+
+ helper.StartServiceIfRequired();
+
+#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
+ ProbesProducerThread probes(GetTestProducerSockName());
+ probes.Connect();
+#endif
+
+ auto* producer = helper.ConnectFakeProducer();
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+ helper.WaitForDataSourceConnected("linux.ftrace");
+
+ TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(1024);
+ trace_config.set_unique_session_name("kmem_activity_test");
+
+ auto* ftrace_ds_config = trace_config.add_data_sources()->mutable_config();
+ ftrace_ds_config->set_name("linux.ftrace");
+ protos::gen::FtraceConfig ftrace_config = CreateFtraceConfig({
+ "vmscan/mm_vmscan_kswapd_wake",
+ "vmscan/mm_vmscan_kswapd_sleep",
+ "vmscan/mm_vmscan_direct_reclaim_begin",
+ "vmscan/mm_vmscan_direct_reclaim_end",
+ "compaction/mm_compaction_begin",
+ "compaction/mm_compaction_end",
+ });
+ ftrace_ds_config->set_ftrace_config_raw(ftrace_config.SerializeAsString());
+
+ auto* sys_stats_ds_config = trace_config.add_data_sources()->mutable_config();
+ sys_stats_ds_config->set_name("linux.sys_stats");
+ protos::gen::SysStatsConfig sys_stats_config;
+ sys_stats_config.set_vmstat_period_ms(50);
+ std::vector<C> vmstat_counters = {
+ C::VMSTAT_NR_FREE_PAGES,
+ C::VMSTAT_NR_SLAB_RECLAIMABLE,
+ C::VMSTAT_NR_SLAB_UNRECLAIMABLE,
+ C::VMSTAT_NR_ACTIVE_FILE,
+ C::VMSTAT_NR_INACTIVE_FILE,
+ C::VMSTAT_NR_ACTIVE_ANON,
+ C::VMSTAT_NR_INACTIVE_ANON,
+ C::VMSTAT_WORKINGSET_REFAULT,
+ C::VMSTAT_WORKINGSET_ACTIVATE,
+ C::VMSTAT_NR_FILE_PAGES,
+ C::VMSTAT_PGPGIN,
+ C::VMSTAT_PGPGOUT,
+ C::VMSTAT_PSWPIN,
+ C::VMSTAT_PSWPOUT,
+ C::VMSTAT_PGSTEAL_KSWAPD_DMA,
+ C::VMSTAT_PGSTEAL_KSWAPD_NORMAL,
+ C::VMSTAT_PGSTEAL_KSWAPD_MOVABLE,
+ C::VMSTAT_PGSTEAL_DIRECT_DMA,
+ C::VMSTAT_PGSTEAL_DIRECT_NORMAL,
+ C::VMSTAT_PGSTEAL_DIRECT_MOVABLE,
+ C::VMSTAT_PGSCAN_KSWAPD_DMA,
+ C::VMSTAT_PGSCAN_KSWAPD_NORMAL,
+ C::VMSTAT_PGSCAN_KSWAPD_MOVABLE,
+ C::VMSTAT_PGSCAN_DIRECT_DMA,
+ C::VMSTAT_PGSCAN_DIRECT_NORMAL,
+ C::VMSTAT_PGSCAN_DIRECT_MOVABLE,
+ C::VMSTAT_COMPACT_MIGRATE_SCANNED,
+ C::VMSTAT_COMPACT_FREE_SCANNED,
+ };
+ for (const auto& counter : vmstat_counters) {
+ sys_stats_config.add_vmstat_counters(counter);
+ }
+ sys_stats_ds_config->set_sys_stats_config_raw(
+ sys_stats_config.SerializeAsString());
+
+ auto* trigger_cfg = trace_config.mutable_trigger_config();
+ trigger_cfg->set_trigger_mode(
+ protos::gen::TraceConfig::TriggerConfig::START_TRACING);
+ trigger_cfg->set_trigger_timeout_ms(15000);
+ auto* trigger = trigger_cfg->add_triggers();
+ trigger->set_name("kmem_activity");
+ // |stop_delay_ms| must be long enough that we can write the packets in
+ // before the trace finishes.
+ trigger->set_stop_delay_ms(1000);
+
+ helper.StartTracing(trace_config);
+
+ // Linearize with StartTracing. This ensures that the service has seen the
+ // StartTracing IPC and has armed the triggers.
+ helper.FlushAndWait(kDefaultTestTimeoutMs);
+
+ // Generating synthetic memory pressure to trigger kmem activity is
+ // inherently flaky on different devices. The same goes for writing
+ // /proc/sys/vm/compact_memory to trigger compaction, since compaction is
+ // only started if needed (even if explicitly triggered from proc).
+ // Trigger kmem activity using perfetto trigger.
+ producer->ActivateTrigger("kmem_activity");
+
+ helper.WaitForTracingDisabled();
+
+ helper.ReadData();
+ helper.WaitForReadData();
+
+ const auto& packets = helper.trace();
+ ASSERT_GT(packets.size(), 0u);
+
+ bool sys_stats_captured = false;
+ for (const auto& packet : packets) {
+ for (int ev = 0; ev < packet.ftrace_events().event_size(); ev++) {
+ auto ftrace_event =
+ packet.ftrace_events().event()[static_cast<size_t>(ev)];
+ ASSERT_TRUE(ftrace_event.has_mm_vmscan_kswapd_wake() ||
+ ftrace_event.has_mm_vmscan_kswapd_sleep() ||
+ ftrace_event.has_mm_vmscan_direct_reclaim_begin() ||
+ ftrace_event.has_mm_vmscan_direct_reclaim_end() ||
+ ftrace_event.has_mm_compaction_begin() ||
+ ftrace_event.has_mm_compaction_end());
+ }
+
+ if (packet.has_sys_stats()) {
+ sys_stats_captured = true;
+ const auto& sys_stats = packet.sys_stats();
+ const auto& vmstat = sys_stats.vmstat();
+ ASSERT_GT(vmstat.size(), 0u);
+ for (const auto& vmstat_value : vmstat) {
+ ASSERT_NE(std::find(vmstat_counters.begin(), vmstat_counters.end(),
+ vmstat_value.key()),
+ vmstat_counters.end());
+ }
+ }
+ }
+
+ // Don't explicitly check that ftrace events were captured, since this test
+ // doesn't rely on memory pressure.
+ ASSERT_TRUE(sys_stats_captured);
+}
+
+TEST(PerfettoAndroidIntegrationTest, TestBatteryTracing) {
+ base::TestTaskRunner task_runner;
+
+ TestHelper helper(&task_runner);
+ helper.StartServiceIfRequired();
+
+#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
+ ProbesProducerThread probes(GetTestProducerSockName());
+ probes.Connect();
+#endif
+
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+
+ TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(128);
+ trace_config.set_duration_ms(3000);
+
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("android.power");
+ ds_config->set_target_buffer(0);
+
+ using protos::pbzero::AndroidPowerConfig;
+ protozero::HeapBuffered<AndroidPowerConfig> power_config;
+ power_config->set_battery_poll_ms(250);
+ power_config->add_battery_counters(
+ AndroidPowerConfig::BATTERY_COUNTER_CHARGE);
+ power_config->add_battery_counters(
+ AndroidPowerConfig::BATTERY_COUNTER_CAPACITY_PERCENT);
+ ds_config->set_android_power_config_raw(power_config.SerializeAsString());
+
+ helper.StartTracing(trace_config);
+ helper.WaitForTracingDisabled();
+
+ helper.ReadData();
+ helper.WaitForReadData();
+
+ const auto& packets = helper.trace();
+ ASSERT_GT(packets.size(), 0u);
+
+ bool has_battery_packet = false;
+ for (const auto& packet : packets) {
+ if (!packet.has_battery())
+ continue;
+ has_battery_packet = true;
+ // Unfortunately we cannot make any assertions on the charge counter.
+ // On some devices it can reach negative values (b/64685329).
+ EXPECT_GE(packet.battery().capacity_percent(), 0.f);
+ EXPECT_LE(packet.battery().capacity_percent(), 100.f);
+ }
+
+ ASSERT_TRUE(has_battery_packet);
+}
+
+TEST(PerfettoAndroidIntegrationTest, SaveForBugreport) {
+ base::TestTaskRunner task_runner;
+
+ TestHelper helper(&task_runner);
+ helper.StartServiceIfRequired();
+ helper.ConnectFakeProducer();
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+
+ TraceConfig trace_config;
+ SetTraceConfigForBugreportTest(&trace_config);
+
+ helper.StartTracing(trace_config);
+ helper.WaitForProducerEnabled();
+
+ EXPECT_TRUE(helper.SaveTraceForBugreportAndWait());
+ helper.WaitForTracingDisabled();
+
+ VerifyBugreportTraceContents();
+
+ // Now read the trace returned to the consumer via ReadBuffers. This should
+ // be always empty because --save-for-bugreport takes it over and makes the
+ // buffers unreadable by the consumer (by virtue of force-setting
+ // write_into_file, which is incompatible with ReadBuffers()). The only
+ // content should be the |seized_for_bugreport| flag.
+ helper.ReadData();
+ helper.WaitForReadData();
+ const auto& packets = helper.full_trace();
+ ASSERT_EQ(packets.size(), 1u);
+ for (const auto& p : packets) {
+ ASSERT_TRUE(p.has_service_event());
+ ASSERT_TRUE(p.service_event().seized_for_bugreport());
+ }
+}
+
+// Tests that the SaveForBugreport logic works also for traces with
+// write_into_file = true (with a passed file descriptor).
+TEST(PerfettoAndroidIntegrationTest, SaveForBugreport_WriteIntoFile) {
+ base::TestTaskRunner task_runner;
+
+ TestHelper helper(&task_runner);
+ helper.StartServiceIfRequired();
+ helper.ConnectFakeProducer();
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+
+ TraceConfig trace_config;
+ SetTraceConfigForBugreportTest(&trace_config);
+ trace_config.set_file_write_period_ms(60000); // Will never hit this.
+ trace_config.set_write_into_file(true);
+
+ auto pipe_pair = base::Pipe::Create();
+ helper.StartTracing(trace_config, std::move(pipe_pair.wr));
+ helper.WaitForProducerEnabled();
+
+ EXPECT_TRUE(helper.SaveTraceForBugreportAndWait());
+ helper.WaitForTracingDisabled();
+
+ VerifyBugreportTraceContents();
+
+ // Now read the original file descriptor passed in.
+ std::string trace_bytes;
+ ASSERT_TRUE(base::ReadPlatformHandle(*pipe_pair.rd, &trace_bytes));
+ protos::gen::Trace trace;
+ ASSERT_TRUE(trace.ParseFromString(trace_bytes));
+ ASSERT_EQ(trace.packet().size(), 1u);
+ for (const auto& p : trace.packet()) {
+ ASSERT_TRUE(p.has_service_event());
+ ASSERT_TRUE(p.service_event().seized_for_bugreport());
+ }
+}
+
+// Tests that SaveTraceForBugreport() works also if the trace has triggers
+// defined and those triggers have not been hit. This is a regression test for
+// b/188008375 .
+#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+// Disabled due to b/191940560
+#define MAYBE_SaveForBugreport_Triggers DISABLED_SaveForBugreport_Triggers
+#else
+#define MAYBE_SaveForBugreport_Triggers SaveForBugreport_Triggers
+#endif
+TEST(PerfettoAndroidIntegrationTest, MAYBE_SaveForBugreport_Triggers) {
+ base::TestTaskRunner task_runner;
+
+ TestHelper helper(&task_runner);
+ helper.StartServiceIfRequired();
+ helper.ConnectFakeProducer();
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+
+ TraceConfig trace_config;
+ SetTraceConfigForBugreportTest(&trace_config);
+ trace_config.set_duration_ms(0); // set_trigger_timeout_ms is used instead.
+ auto* trigger_config = trace_config.mutable_trigger_config();
+ trigger_config->set_trigger_timeout_ms(8.64e+7);
+ trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
+ auto* trigger = trigger_config->add_triggers();
+ trigger->set_name("trigger_name");
+ trigger->set_stop_delay_ms(1);
+
+ helper.StartTracing(trace_config);
+ helper.WaitForProducerEnabled();
+
+ EXPECT_TRUE(helper.SaveTraceForBugreportAndWait());
+ helper.WaitForTracingDisabled();
+
+ VerifyBugreportTraceContents();
+
+ // Now read the original trace.
+ helper.ReadData();
+ helper.WaitForReadData();
+ const auto& packets = helper.full_trace();
+ ASSERT_EQ(packets.size(), 1u);
+ for (const auto& p : packets) {
+ ASSERT_TRUE(p.has_service_event());
+ ASSERT_TRUE(p.service_event().seized_for_bugreport());
+ }
+}
+
+} // namespace perfetto
+
+#endif // PERFETTO_OS_ANDROID
diff --git a/test/android_test_utils.cc b/test/android_test_utils.cc
index 8c6081ae2..bfb1e1c33 100644
--- a/test/android_test_utils.cc
+++ b/test/android_test_utils.cc
@@ -17,9 +17,9 @@
#include "test/android_test_utils.h"
#include <stdlib.h>
-#include <sys/system_properties.h>
#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/android_utils.h"
#include "perfetto/ext/base/file_utils.h"
namespace perfetto {
@@ -45,17 +45,13 @@ void PollRunState(bool desired_run_state,
} // namespace
bool IsDebuggableBuild() {
- char buf[PROP_VALUE_MAX + 1] = {};
- int ret = __system_property_get("ro.debuggable", buf);
- PERFETTO_CHECK(ret >= 0);
- return std::string(buf) == "1";
+ std::string debuggable = base::GetAndroidProp("ro.debuggable");
+ return debuggable == "1";
}
bool IsUserBuild() {
- char buf[PROP_VALUE_MAX + 1] = {};
- int ret = __system_property_get("ro.build.type", buf);
- PERFETTO_CHECK(ret >= 0);
- return std::string(buf) == "user";
+ std::string build_type = base::GetAndroidProp("ro.build.type");
+ return build_type == "user";
}
// note: cannot use gtest macros due to return type
diff --git a/test/ci/bazel_tests.sh b/test/ci/bazel_tests.sh
index 4af0b9549..012f0d072 100755
--- a/test/ci/bazel_tests.sh
+++ b/test/ci/bazel_tests.sh
@@ -17,6 +17,7 @@ INSTALL_BUILD_DEPS_ARGS=""
source $(dirname ${BASH_SOURCE[0]})/common.sh
bazel build //:all --verbose_failures
+bazel build //python:all --verbose_failures
# Smoke test that processes run without crashing.
./bazel-bin/traced &
diff --git a/test/ci/linux_tests.sh b/test/ci/linux_tests.sh
index fd165f2d7..1a6829187 100755
--- a/test/ci/linux_tests.sh
+++ b/test/ci/linux_tests.sh
@@ -41,7 +41,7 @@ tools/diff_test_trace_processor.py \
--perf-file=/ci/artifacts/perf/tp-perf-all.json \
${TP_SHELL}
-tools/run_python_api_tests.py ${TP_SHELL}
+python/run_tests.py ${TP_SHELL}
# Don't run benchmarks under x86 (running out of address space because of 4GB)
# limit or debug (too slow and pointless).
diff --git a/test/ci/ui_tests.sh b/test/ci/ui_tests.sh
index 9a1fa3af8..619d0f2ef 100755
--- a/test/ci/ui_tests.sh
+++ b/test/ci/ui_tests.sh
@@ -16,8 +16,18 @@
INSTALL_BUILD_DEPS_ARGS="--ui"
source $(dirname ${BASH_SOURCE[0]})/common.sh
-tools/node ui/build.js --out ${OUT_PATH}
+ui/build --out ${OUT_PATH}
cp -a ${OUT_PATH}/ui/dist/ /ci/artifacts/ui
-tools/node ui/build.js --out ${OUT_PATH} --no-build --run-tests
+ui/run-unittests --out ${OUT_PATH} --no-build
+
+set +e
+ui/run-integrationtests --out ${OUT_PATH} --no-build
+RES=$?
+
+# Copy the screenshots for diff testing when the test fails.
+if [ $RES -ne 0 -a -d ${OUT_PATH}/ui-test-artifacts ]; then
+ cp -a ${OUT_PATH}/ui-test-artifacts /ci/artifacts/ui-test-artifacts
+ exit $RES
+fi
diff --git a/test/cmdline_integrationtest.cc b/test/cmdline_integrationtest.cc
new file mode 100644
index 000000000..074778942
--- /dev/null
+++ b/test/cmdline_integrationtest.cc
@@ -0,0 +1,763 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <functional>
+#include <initializer_list>
+#include <thread>
+
+#include "perfetto/base/build_config.h"
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/pipe.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/utils.h"
+#include "perfetto/ext/traced/traced.h"
+#include "perfetto/protozero/scattered_heap_buffer.h"
+#include "src/base/test/test_task_runner.h"
+#include "src/base/test/utils.h"
+#include "test/gtest_and_gmock.h"
+#include "test/test_helper.h"
+
+#include "protos/perfetto/config/test_config.gen.h"
+#include "protos/perfetto/config/trace_config.gen.h"
+#include "protos/perfetto/trace/test_event.gen.h"
+#include "protos/perfetto/trace/trace.gen.h"
+#include "protos/perfetto/trace/trace_packet.gen.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+#include "protos/perfetto/trace/trigger.gen.h"
+
+namespace perfetto {
+
+namespace {
+
+using ::testing::ContainsRegex;
+using ::testing::Each;
+using ::testing::ElementsAreArray;
+using ::testing::HasSubstr;
+using ::testing::Property;
+using ::testing::SizeIs;
+
+std::string RandomTraceFileName() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+ constexpr char kSysTmpPath[] = "/data/misc/perfetto-traces";
+#else
+ constexpr char kSysTmpPath[] = "/tmp";
+#endif
+ static int suffix = 0;
+
+ std::string path;
+ path.assign(kSysTmpPath);
+ path.append("/trace-");
+ path.append(std::to_string(base::GetBootTimeNs().count()));
+ path.append("-");
+ path.append(std::to_string(suffix++));
+ return path;
+}
+
+class PerfettoCmdlineTest : public ::testing::Test {
+ public:
+ void SetUp() override {
+#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
+ defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER)
+ // Disable cmdline tests on sanitizets because they use fork() and that
+ // messes up leak / races detections, which has been fixed only recently
+ // (see https://github.com/google/sanitizers/issues/836 ).
+ PERFETTO_LOG("Skipping cmdline integration tests on sanitizers");
+ GTEST_SKIP();
+#endif
+ }
+
+ void TearDown() override {}
+
+ void StartServiceIfRequiredNoNewExecsAfterThis() {
+ exec_allowed_ = false;
+ test_helper_.StartServiceIfRequired();
+ }
+
+ FakeProducer* ConnectFakeProducer() {
+ return test_helper_.ConnectFakeProducer();
+ }
+
+ std::function<void()> WrapTask(const std::function<void()>& function) {
+ return test_helper_.WrapTask(function);
+ }
+
+ void WaitForProducerSetup() { test_helper_.WaitForProducerSetup(); }
+
+ void WaitForProducerEnabled() { test_helper_.WaitForProducerEnabled(); }
+
+ // Creates a process that represents the perfetto binary that will
+ // start when Run() is called. |args| will be passed as part of
+ // the command line and |std_in| will be piped into std::cin.
+ Exec ExecPerfetto(std::initializer_list<std::string> args,
+ std::string std_in = "") {
+ // You can not fork after you've started the service due to risk of
+ // deadlocks.
+ PERFETTO_CHECK(exec_allowed_);
+ return Exec("perfetto", std::move(args), std::move(std_in));
+ }
+
+ // Creates a process that represents the trigger_perfetto binary that will
+ // start when Run() is called. |args| will be passed as part of
+ // the command line and |std_in| will be piped into std::cin.
+ Exec ExecTrigger(std::initializer_list<std::string> args,
+ std::string std_in = "") {
+ // You can not fork after you've started the service due to risk of
+ // deadlocks.
+ PERFETTO_CHECK(exec_allowed_);
+ return Exec("trigger_perfetto", std::move(args), std::move(std_in));
+ }
+
+ // Tests are allowed to freely use these variables.
+ std::string stderr_;
+ base::TestTaskRunner task_runner_;
+
+ private:
+ bool exec_allowed_ = true;
+ TestHelper test_helper_{&task_runner_};
+};
+
+} // namespace
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#define AndroidOnly(x) x
+#else
+#define AndroidOnly(x) DISABLED_##x
+#endif
+
+TEST_F(PerfettoCmdlineTest, InvalidCases) {
+ std::string cfg("duration_ms: 100");
+
+ auto invalid_arg = ExecPerfetto({"--invalid-arg"});
+ auto empty_config = ExecPerfetto({"-c", "-", "-o", "-"}, "");
+
+ // Cannot make assertions on --dropbox because on standalone builds it fails
+ // prematurely due to lack of dropbox.
+ auto missing_dropbox =
+ ExecPerfetto({"-c", "-", "--txt", "-o", "-", "--dropbox=foo"}, cfg);
+ auto either_out_or_dropbox = ExecPerfetto({"-c", "-", "--txt"}, cfg);
+
+ // Disallow mixing simple and file config.
+ auto simple_and_file_1 =
+ ExecPerfetto({"-o", "-", "-c", "-", "-t", "2s"}, cfg);
+ auto simple_and_file_2 =
+ ExecPerfetto({"-o", "-", "-c", "-", "-b", "2m"}, cfg);
+ auto simple_and_file_3 =
+ ExecPerfetto({"-o", "-", "-c", "-", "-s", "2m"}, cfg);
+
+ // Invalid --attach / --detach cases.
+ auto invalid_stop =
+ ExecPerfetto({"-c", "-", "--txt", "-o", "-", "--stop"}, cfg);
+ auto attach_and_config_1 =
+ ExecPerfetto({"-c", "-", "--txt", "-o", "-", "--attach=foo"}, cfg);
+ auto attach_and_config_2 =
+ ExecPerfetto({"-t", "2s", "-o", "-", "--attach=foo"}, cfg);
+ auto attach_needs_argument = ExecPerfetto({"--attach"}, cfg);
+ auto detach_needs_argument =
+ ExecPerfetto({"-t", "2s", "-o", "-", "--detach"}, cfg);
+ auto detach_without_out_or_dropbox =
+ ExecPerfetto({"-t", "2s", "--detach=foo"}, cfg);
+
+ // Cannot trace and use --query.
+ auto trace_and_query_1 = ExecPerfetto({"-t", "2s", "--query"}, cfg);
+ auto trace_and_query_2 = ExecPerfetto({"-c", "-", "--query"}, cfg);
+
+ // Ensure all Exec:: calls have been saved to prevent deadlocks.
+ StartServiceIfRequiredNoNewExecsAfterThis();
+
+ EXPECT_EQ(1, invalid_arg.Run(&stderr_));
+
+ EXPECT_EQ(1, empty_config.Run(&stderr_));
+ EXPECT_THAT(stderr_, HasSubstr("TraceConfig is empty"));
+
+ // Cannot make assertions on --upload because on standalone builds it fails
+ // prematurely due to lack of dropbox.
+ EXPECT_EQ(1, missing_dropbox.Run(&stderr_));
+
+ EXPECT_EQ(1, either_out_or_dropbox.Run(&stderr_));
+ EXPECT_THAT(stderr_, HasSubstr("Either --out or --upload"));
+
+ // Disallow mixing simple and file config.
+ EXPECT_EQ(1, simple_and_file_1.Run(&stderr_));
+ EXPECT_THAT(stderr_, HasSubstr("Cannot specify both -c"));
+
+ EXPECT_EQ(1, simple_and_file_2.Run(&stderr_));
+ EXPECT_THAT(stderr_, HasSubstr("Cannot specify both -c"));
+
+ EXPECT_EQ(1, simple_and_file_3.Run(&stderr_));
+ EXPECT_THAT(stderr_, HasSubstr("Cannot specify both -c"));
+
+ // Invalid --attach / --detach cases.
+ EXPECT_EQ(1, invalid_stop.Run(&stderr_));
+ EXPECT_THAT(stderr_, HasSubstr("--stop is supported only in combination"));
+
+ EXPECT_EQ(1, attach_and_config_1.Run(&stderr_));
+ EXPECT_THAT(stderr_, HasSubstr("Cannot specify a trace config"));
+
+ EXPECT_EQ(1, attach_and_config_2.Run(&stderr_));
+ EXPECT_THAT(stderr_, HasSubstr("Cannot specify a trace config"));
+
+ EXPECT_EQ(1, attach_needs_argument.Run(&stderr_));
+ EXPECT_THAT(stderr_, ContainsRegex("option.*--attach.*requires an argument"));
+
+ EXPECT_EQ(1, detach_needs_argument.Run(&stderr_));
+ EXPECT_THAT(stderr_, ContainsRegex("option.*--detach.*requires an argument"));
+
+ EXPECT_EQ(1, detach_without_out_or_dropbox.Run(&stderr_));
+ EXPECT_THAT(stderr_, HasSubstr("--out or --upload is required"));
+
+ // Cannot trace and use --query.
+ EXPECT_EQ(1, trace_and_query_1.Run(&stderr_));
+ EXPECT_THAT(stderr_, HasSubstr("Cannot specify a trace config"));
+
+ EXPECT_EQ(1, trace_and_query_2.Run(&stderr_));
+ EXPECT_THAT(stderr_, HasSubstr("Cannot specify a trace config"));
+}
+
+TEST_F(PerfettoCmdlineTest, Version) {
+ auto perfetto = ExecPerfetto({"--version"});
+ EXPECT_EQ(0, perfetto.Run(&stderr_)) << stderr_;
+}
+
+TEST_F(PerfettoCmdlineTest, TxtConfig) {
+ std::string cfg("duration_ms: 100");
+ auto perfetto = ExecPerfetto({"-c", "-", "--txt", "-o", "-"}, cfg);
+ StartServiceIfRequiredNoNewExecsAfterThis();
+ EXPECT_EQ(0, perfetto.Run(&stderr_)) << stderr_;
+}
+
+TEST_F(PerfettoCmdlineTest, SimpleConfig) {
+ auto perfetto = ExecPerfetto({"-o", "-", "-c", "-", "-t", "100ms"});
+ StartServiceIfRequiredNoNewExecsAfterThis();
+ EXPECT_EQ(0, perfetto.Run(&stderr_)) << stderr_;
+}
+
+TEST_F(PerfettoCmdlineTest, DetachAndAttach) {
+ auto attach_to_not_existing = ExecPerfetto({"--attach=not_existent"});
+
+ std::string cfg("duration_ms: 10000; write_into_file: true");
+ auto detach_valid_stop =
+ ExecPerfetto({"-o", "-", "-c", "-", "--txt", "--detach=valid_stop"}, cfg);
+ auto stop_valid_stop = ExecPerfetto({"--attach=valid_stop", "--stop"});
+
+ StartServiceIfRequiredNoNewExecsAfterThis();
+
+ EXPECT_NE(0, attach_to_not_existing.Run(&stderr_));
+ EXPECT_THAT(stderr_, HasSubstr("Session re-attach failed"));
+
+ EXPECT_EQ(0, detach_valid_stop.Run(&stderr_)) << stderr_;
+ EXPECT_EQ(0, stop_valid_stop.Run(&stderr_));
+}
+
+TEST_F(PerfettoCmdlineTest, StartTracingTrigger) {
+ // See |message_count| and |message_size| in the TraceConfig above.
+ constexpr size_t kMessageCount = 11;
+ constexpr size_t kMessageSize = 32;
+ protos::gen::TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(1024);
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("android.perfetto.FakeProducer");
+ ds_config->mutable_for_testing()->set_message_count(kMessageCount);
+ ds_config->mutable_for_testing()->set_message_size(kMessageSize);
+ auto* trigger_cfg = trace_config.mutable_trigger_config();
+ trigger_cfg->set_trigger_mode(
+ protos::gen::TraceConfig::TriggerConfig::START_TRACING);
+ trigger_cfg->set_trigger_timeout_ms(15000);
+ auto* trigger = trigger_cfg->add_triggers();
+ trigger->set_name("trigger_name");
+ // |stop_delay_ms| must be long enough that we can write the packets in
+ // before the trace finishes. This has to be long enough for the slowest
+ // emulator. But as short as possible to prevent the test running a long
+ // time.
+ trigger->set_stop_delay_ms(500);
+
+ // We have to construct all the processes we want to fork before we start the
+ // service with |StartServiceIfRequired()|. this is because it is unsafe
+ // (could deadlock) to fork after we've spawned some threads which might
+ // printf (and thus hold locks).
+ const std::string path = RandomTraceFileName();
+ auto perfetto_proc = ExecPerfetto(
+ {
+ "-o",
+ path,
+ "-c",
+ "-",
+ },
+ trace_config.SerializeAsString());
+
+ auto trigger_proc = ExecTrigger({"trigger_name"});
+
+ // Start the service and connect a simple fake producer.
+ StartServiceIfRequiredNoNewExecsAfterThis();
+
+ auto* fake_producer = ConnectFakeProducer();
+ EXPECT_TRUE(fake_producer);
+
+ // Start a background thread that will deliver the config now that we've
+ // started the service. See |perfetto_proc| above for the args passed.
+ std::thread background_trace([&perfetto_proc]() {
+ std::string stderr_str;
+ EXPECT_EQ(0, perfetto_proc.Run(&stderr_str)) << stderr_str;
+ });
+
+ WaitForProducerSetup();
+ EXPECT_EQ(0, trigger_proc.Run(&stderr_));
+
+ // Wait for the producer to start, and then write out 11 packets.
+ WaitForProducerEnabled();
+ auto on_data_written = task_runner_.CreateCheckpoint("data_written");
+ fake_producer->ProduceEventBatch(WrapTask(on_data_written));
+ task_runner_.RunUntilCheckpoint("data_written");
+ background_trace.join();
+
+ std::string trace_str;
+ base::ReadFile(path, &trace_str);
+ protos::gen::Trace trace;
+ ASSERT_TRUE(trace.ParseFromString(trace_str));
+ size_t for_testing_packets = 0;
+ size_t trigger_packets = 0;
+ size_t trace_config_packets = 0;
+ for (const auto& packet : trace.packet()) {
+ if (packet.has_trace_config()) {
+ // Ensure the trace config properly includes the trigger mode we set.
+ auto kStartTrig = protos::gen::TraceConfig::TriggerConfig::START_TRACING;
+ EXPECT_EQ(kStartTrig,
+ packet.trace_config().trigger_config().trigger_mode());
+ ++trace_config_packets;
+ } else if (packet.has_trigger()) {
+ // validate that the triggers are properly added to the trace.
+ EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
+ ++trigger_packets;
+ } else if (packet.has_for_testing()) {
+ // Make sure that the data size is correctly set based on what we
+ // requested.
+ EXPECT_EQ(kMessageSize, packet.for_testing().str().size());
+ ++for_testing_packets;
+ }
+ }
+ EXPECT_EQ(trace_config_packets, 1u);
+ EXPECT_EQ(trigger_packets, 1u);
+ EXPECT_EQ(for_testing_packets, kMessageCount);
+}
+
+TEST_F(PerfettoCmdlineTest, StopTracingTrigger) {
+ // See |message_count| and |message_size| in the TraceConfig above.
+ constexpr size_t kMessageCount = 11;
+ constexpr size_t kMessageSize = 32;
+ protos::gen::TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(1024);
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("android.perfetto.FakeProducer");
+ ds_config->mutable_for_testing()->set_message_count(kMessageCount);
+ ds_config->mutable_for_testing()->set_message_size(kMessageSize);
+ auto* trigger_cfg = trace_config.mutable_trigger_config();
+ trigger_cfg->set_trigger_mode(
+ protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
+ trigger_cfg->set_trigger_timeout_ms(15000);
+ auto* trigger = trigger_cfg->add_triggers();
+ trigger->set_name("trigger_name");
+ // |stop_delay_ms| must be long enough that we can write the packets in
+ // before the trace finishes. This has to be long enough for the slowest
+ // emulator. But as short as possible to prevent the test running a long
+ // time.
+ trigger->set_stop_delay_ms(500);
+ trigger = trigger_cfg->add_triggers();
+ trigger->set_name("trigger_name_3");
+ trigger->set_stop_delay_ms(60000);
+
+ // We have to construct all the processes we want to fork before we start the
+ // service with |StartServiceIfRequired()|. this is because it is unsafe
+ // (could deadlock) to fork after we've spawned some threads which might
+ // printf (and thus hold locks).
+ const std::string path = RandomTraceFileName();
+ auto perfetto_proc = ExecPerfetto(
+ {
+ "-o",
+ path,
+ "-c",
+ "-",
+ },
+ trace_config.SerializeAsString());
+
+ auto trigger_proc =
+ ExecTrigger({"trigger_name_2", "trigger_name", "trigger_name_3"});
+
+ // Start the service and connect a simple fake producer.
+ StartServiceIfRequiredNoNewExecsAfterThis();
+ auto* fake_producer = ConnectFakeProducer();
+ EXPECT_TRUE(fake_producer);
+
+ // Start a background thread that will deliver the config now that we've
+ // started the service. See |perfetto_proc| above for the args passed.
+ std::thread background_trace([&perfetto_proc]() {
+ std::string stderr_str;
+ EXPECT_EQ(0, perfetto_proc.Run(&stderr_str)) << stderr_str;
+ });
+
+ WaitForProducerEnabled();
+ // Wait for the producer to start, and then write out 11 packets, before the
+ // trace actually starts (the trigger is seen).
+ auto on_data_written = task_runner_.CreateCheckpoint("data_written_1");
+ fake_producer->ProduceEventBatch(WrapTask(on_data_written));
+ task_runner_.RunUntilCheckpoint("data_written_1");
+
+ EXPECT_EQ(0, trigger_proc.Run(&stderr_)) << "stderr: " << stderr_;
+
+ background_trace.join();
+
+ std::string trace_str;
+ base::ReadFile(path, &trace_str);
+ protos::gen::Trace trace;
+ ASSERT_TRUE(trace.ParseFromString(trace_str));
+ bool seen_first_trigger = false;
+ size_t for_testing_packets = 0;
+ size_t trigger_packets = 0;
+ size_t trace_config_packets = 0;
+ for (const auto& packet : trace.packet()) {
+ if (packet.has_trace_config()) {
+ // Ensure the trace config properly includes the trigger mode we set.
+ auto kStopTrig = protos::gen::TraceConfig::TriggerConfig::STOP_TRACING;
+ EXPECT_EQ(kStopTrig,
+ packet.trace_config().trigger_config().trigger_mode());
+ ++trace_config_packets;
+ } else if (packet.has_trigger()) {
+ // validate that the triggers are properly added to the trace.
+ if (!seen_first_trigger) {
+ EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
+ seen_first_trigger = true;
+ } else {
+ EXPECT_EQ("trigger_name_3", packet.trigger().trigger_name());
+ }
+ ++trigger_packets;
+ } else if (packet.has_for_testing()) {
+ // Make sure that the data size is correctly set based on what we
+ // requested.
+ EXPECT_EQ(kMessageSize, packet.for_testing().str().size());
+ ++for_testing_packets;
+ }
+ }
+ EXPECT_EQ(trace_config_packets, 1u);
+ EXPECT_EQ(trigger_packets, 2u);
+ EXPECT_EQ(for_testing_packets, kMessageCount);
+}
+
+// Dropbox on the commandline client only works on android builds. So disable
+// this test on all other builds.
+TEST_F(PerfettoCmdlineTest, AndroidOnly(NoDataNoFileWithoutTrigger)) {
+ // See |message_count| and |message_size| in the TraceConfig above.
+ constexpr size_t kMessageCount = 11;
+ constexpr size_t kMessageSize = 32;
+ protos::gen::TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(1024);
+ trace_config.set_allow_user_build_tracing(true);
+ auto* incident_config = trace_config.mutable_incident_report_config();
+ incident_config->set_destination_package("foo.bar.baz");
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("android.perfetto.FakeProducer");
+ ds_config->mutable_for_testing()->set_message_count(kMessageCount);
+ ds_config->mutable_for_testing()->set_message_size(kMessageSize);
+ auto* trigger_cfg = trace_config.mutable_trigger_config();
+ trigger_cfg->set_trigger_mode(
+ protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
+ trigger_cfg->set_trigger_timeout_ms(1000);
+ auto* trigger = trigger_cfg->add_triggers();
+ trigger->set_name("trigger_name");
+ // |stop_delay_ms| must be long enough that we can write the packets in
+ // before the trace finishes. This has to be long enough for the slowest
+ // emulator. But as short as possible to prevent the test running a long
+ // time.
+ trigger->set_stop_delay_ms(500);
+ trigger = trigger_cfg->add_triggers();
+
+ // We have to construct all the processes we want to fork before we start the
+ // service with |StartServiceIfRequired()|. this is because it is unsafe
+ // (could deadlock) to fork after we've spawned some threads which might
+ // printf (and thus hold locks).
+ const std::string path = RandomTraceFileName();
+ auto perfetto_proc = ExecPerfetto(
+ {
+ "--dropbox",
+ "TAG",
+ "--no-guardrails",
+ "-c",
+ "-",
+ },
+ trace_config.SerializeAsString());
+
+ StartServiceIfRequiredNoNewExecsAfterThis();
+ auto* fake_producer = ConnectFakeProducer();
+ EXPECT_TRUE(fake_producer);
+
+ std::string stderr_str;
+ std::thread background_trace([&perfetto_proc, &stderr_str]() {
+ EXPECT_EQ(0, perfetto_proc.Run(&stderr_str));
+ });
+ background_trace.join();
+
+ EXPECT_THAT(stderr_str,
+ ::testing::HasSubstr("Skipping write to incident. Empty trace."));
+}
+
+TEST_F(PerfettoCmdlineTest, StopTracingTriggerFromConfig) {
+ // See |message_count| and |message_size| in the TraceConfig above.
+ constexpr size_t kMessageCount = 11;
+ constexpr size_t kMessageSize = 32;
+ protos::gen::TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(1024);
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("android.perfetto.FakeProducer");
+ ds_config->mutable_for_testing()->set_message_count(kMessageCount);
+ ds_config->mutable_for_testing()->set_message_size(kMessageSize);
+ auto* trigger_cfg = trace_config.mutable_trigger_config();
+ trigger_cfg->set_trigger_mode(
+ protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
+ trigger_cfg->set_trigger_timeout_ms(15000);
+ auto* trigger = trigger_cfg->add_triggers();
+ trigger->set_name("trigger_name");
+ // |stop_delay_ms| must be long enough that we can write the packets in
+ // before the trace finishes. This has to be long enough for the slowest
+ // emulator. But as short as possible to prevent the test running a long
+ // time.
+ trigger->set_stop_delay_ms(500);
+ trigger = trigger_cfg->add_triggers();
+ trigger->set_name("trigger_name_3");
+ trigger->set_stop_delay_ms(60000);
+
+ // We have to construct all the processes we want to fork before we start the
+ // service with |StartServiceIfRequired()|. this is because it is unsafe
+ // (could deadlock) to fork after we've spawned some threads which might
+ // printf (and thus hold locks).
+ const std::string path = RandomTraceFileName();
+ auto perfetto_proc = ExecPerfetto(
+ {
+ "-o",
+ path,
+ "-c",
+ "-",
+ },
+ trace_config.SerializeAsString());
+
+ std::string triggers = R"(
+ activate_triggers: "trigger_name_2"
+ activate_triggers: "trigger_name"
+ activate_triggers: "trigger_name_3"
+ )";
+ auto perfetto_proc_2 = ExecPerfetto(
+ {
+ "-o",
+ path,
+ "-c",
+ "-",
+ "--txt",
+ },
+ triggers);
+
+ // Start the service and connect a simple fake producer.
+ StartServiceIfRequiredNoNewExecsAfterThis();
+ auto* fake_producer = ConnectFakeProducer();
+ EXPECT_TRUE(fake_producer);
+
+ std::thread background_trace([&perfetto_proc]() {
+ std::string stderr_str;
+ EXPECT_EQ(0, perfetto_proc.Run(&stderr_str)) << stderr_str;
+ });
+
+ WaitForProducerEnabled();
+ // Wait for the producer to start, and then write out 11 packets, before the
+ // trace actually starts (the trigger is seen).
+ auto on_data_written = task_runner_.CreateCheckpoint("data_written_1");
+ fake_producer->ProduceEventBatch(WrapTask(on_data_written));
+ task_runner_.RunUntilCheckpoint("data_written_1");
+
+ EXPECT_EQ(0, perfetto_proc_2.Run(&stderr_)) << "stderr: " << stderr_;
+
+ background_trace.join();
+
+ std::string trace_str;
+ base::ReadFile(path, &trace_str);
+ protos::gen::Trace trace;
+ ASSERT_TRUE(trace.ParseFromString(trace_str));
+ EXPECT_LT(static_cast<int>(kMessageCount), trace.packet_size());
+ bool seen_first_trigger = false;
+ for (const auto& packet : trace.packet()) {
+ if (packet.has_trace_config()) {
+ // Ensure the trace config properly includes the trigger mode we set.
+ auto kStopTrig = protos::gen::TraceConfig::TriggerConfig::STOP_TRACING;
+ EXPECT_EQ(kStopTrig,
+ packet.trace_config().trigger_config().trigger_mode());
+ } else if (packet.has_trigger()) {
+ // validate that the triggers are properly added to the trace.
+ if (!seen_first_trigger) {
+ EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
+ seen_first_trigger = true;
+ } else {
+ EXPECT_EQ("trigger_name_3", packet.trigger().trigger_name());
+ }
+ } else if (packet.has_for_testing()) {
+ // Make sure that the data size is correctly set based on what we
+ // requested.
+ EXPECT_EQ(kMessageSize, packet.for_testing().str().size());
+ }
+ }
+}
+
+TEST_F(PerfettoCmdlineTest, TriggerFromConfigStopsFileOpening) {
+ // See |message_count| and |message_size| in the TraceConfig above.
+ constexpr size_t kMessageCount = 11;
+ constexpr size_t kMessageSize = 32;
+ protos::gen::TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(1024);
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("android.perfetto.FakeProducer");
+ ds_config->mutable_for_testing()->set_message_count(kMessageCount);
+ ds_config->mutable_for_testing()->set_message_size(kMessageSize);
+ auto* trigger_cfg = trace_config.mutable_trigger_config();
+ trigger_cfg->set_trigger_mode(
+ protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
+ trigger_cfg->set_trigger_timeout_ms(15000);
+ auto* trigger = trigger_cfg->add_triggers();
+ trigger->set_name("trigger_name");
+ // |stop_delay_ms| must be long enough that we can write the packets in
+ // before the trace finishes. This has to be long enough for the slowest
+ // emulator. But as short as possible to prevent the test running a long
+ // time.
+ trigger->set_stop_delay_ms(500);
+ trigger = trigger_cfg->add_triggers();
+ trigger->set_name("trigger_name_3");
+ trigger->set_stop_delay_ms(60000);
+
+ // We have to construct all the processes we want to fork before we start the
+ // service with |StartServiceIfRequired()|. this is because it is unsafe
+ // (could deadlock) to fork after we've spawned some threads which might
+ // printf (and thus hold locks).
+ const std::string path = RandomTraceFileName();
+ std::string triggers = R"(
+ activate_triggers: "trigger_name_2"
+ activate_triggers: "trigger_name"
+ activate_triggers: "trigger_name_3"
+ )";
+ auto perfetto_proc = ExecPerfetto(
+ {
+ "-o",
+ path,
+ "-c",
+ "-",
+ "--txt",
+ },
+ triggers);
+
+ // Start the service and connect a simple fake producer.
+ StartServiceIfRequiredNoNewExecsAfterThis();
+ auto* fake_producer = ConnectFakeProducer();
+ EXPECT_TRUE(fake_producer);
+
+ std::string trace_str;
+ EXPECT_FALSE(base::ReadFile(path, &trace_str));
+
+ EXPECT_EQ(0, perfetto_proc.Run(&stderr_)) << "stderr: " << stderr_;
+
+ EXPECT_FALSE(base::ReadFile(path, &trace_str));
+}
+
+TEST_F(PerfettoCmdlineTest, Query) {
+ auto query = ExecPerfetto({"--query"});
+ auto query_raw = ExecPerfetto({"--query-raw"});
+ StartServiceIfRequiredNoNewExecsAfterThis();
+ EXPECT_EQ(0, query.Run(&stderr_)) << stderr_;
+ EXPECT_EQ(0, query_raw.Run(&stderr_)) << stderr_;
+}
+
+TEST_F(PerfettoCmdlineTest, AndroidOnly(CmdTriggerWithUploadFlag)) {
+ // See |message_count| and |message_size| in the TraceConfig above.
+ constexpr size_t kMessageCount = 2;
+ constexpr size_t kMessageSize = 2;
+ protos::gen::TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(1024);
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("android.perfetto.FakeProducer");
+ ds_config->mutable_for_testing()->set_message_count(kMessageCount);
+ ds_config->mutable_for_testing()->set_message_size(kMessageSize);
+ auto* trigger_cfg = trace_config.mutable_trigger_config();
+ trigger_cfg->set_trigger_mode(
+ protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
+ trigger_cfg->set_trigger_timeout_ms(15000);
+ auto* trigger = trigger_cfg->add_triggers();
+ trigger->set_name("trigger_name");
+ // |stop_delay_ms| must be long enough that we can write the packets in
+ // before the trace finishes. This has to be long enough for the slowest
+ // emulator. But as short as possible to prevent the test running a long
+ // time.
+ trigger->set_stop_delay_ms(500);
+
+ // We have to construct all the processes we want to fork before we start the
+ // service with |StartServiceIfRequired()|. this is because it is unsafe
+ // (could deadlock) to fork after we've spawned some threads which might
+ // printf (and thus hold locks).
+ const std::string path = RandomTraceFileName();
+ auto perfetto_proc = ExecPerfetto(
+ {
+ "-o",
+ path,
+ "-c",
+ "-",
+ },
+ trace_config.SerializeAsString());
+
+ std::string triggers = R"(
+ activate_triggers: "trigger_name"
+ )";
+ auto perfetto_proc_2 = ExecPerfetto(
+ {
+ "--upload",
+ "-c",
+ "-",
+ "--txt",
+ },
+ triggers);
+
+ // Start the service and connect a simple fake producer.
+ StartServiceIfRequiredNoNewExecsAfterThis();
+ auto* fake_producer = ConnectFakeProducer();
+ EXPECT_TRUE(fake_producer);
+
+ std::thread background_trace([&perfetto_proc]() {
+ std::string stderr_str;
+ EXPECT_EQ(0, perfetto_proc.Run(&stderr_str)) << stderr_str;
+ });
+
+ WaitForProducerEnabled();
+ // Wait for the producer to start, and then write out 11 packets, before the
+ // trace actually starts (the trigger is seen).
+ auto on_data_written = task_runner_.CreateCheckpoint("data_written_1");
+ fake_producer->ProduceEventBatch(WrapTask(on_data_written));
+ task_runner_.RunUntilCheckpoint("data_written_1");
+
+ EXPECT_EQ(0, perfetto_proc_2.Run(&stderr_)) << "stderr: " << stderr_;
+
+ background_trace.join();
+
+ std::string trace_str;
+ base::ReadFile(path, &trace_str);
+ protos::gen::Trace trace;
+ ASSERT_TRUE(trace.ParseFromString(trace_str));
+ EXPECT_LT(static_cast<int>(kMessageCount), trace.packet_size());
+ for (const auto& packet : trace.packet()) {
+ if (packet.has_trigger()) {
+ EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
+ }
+ }
+}
+
+} // namespace perfetto
diff --git a/test/configs/BUILD.gn b/test/configs/BUILD.gn
index 4c93db1ab..230fe0147 100644
--- a/test/configs/BUILD.gn
+++ b/test/configs/BUILD.gn
@@ -21,8 +21,7 @@ action_foreach("configs") {
script = "../../tools/protoc_helper.py"
deps = [
- "../../protos/perfetto/config:merged_config",
- "../../protos/perfetto/trace:merged_trace",
+ "../../protos/perfetto/trace:non_minimal_source_set",
protoc_target,
]
diff --git a/test/configs/rss_stat.cfg b/test/configs/rss_stat.cfg
new file mode 100644
index 000000000..010aa9746
--- /dev/null
+++ b/test/configs/rss_stat.cfg
@@ -0,0 +1,17 @@
+buffers: {
+ size_kb: 512
+ fill_policy: DISCARD
+}
+
+data_sources: {
+ config {
+ name: "linux.ftrace"
+ ftrace_config {
+ ftrace_events: "sched_switch"
+ ftrace_events: "kmem/rss_stat"
+ throttle_rss_stat: true
+ }
+ }
+}
+
+duration_ms: 10000
diff --git a/test/cts/Android.bp b/test/cts/Android.bp
index 0631dbe46..856b4d24a 100644
--- a/test/cts/Android.bp
+++ b/test/cts/Android.bp
@@ -14,6 +14,7 @@ cc_test {
"end_to_end_integrationtest_cts.cc",
"heapprofd_java_test_cts.cc",
"heapprofd_test_cts.cc",
+ "reporter_test_cts.cc",
"traced_perf_test_cts.cc",
":perfetto_protos_perfetto_config_cpp_gen",
],
@@ -48,11 +49,18 @@ cc_test {
suffix: "64",
},
},
+ per_testcase_directory: true,
+ data: [
+ ":CtsPerfettoNonProfileableApp",
+ ":CtsPerfettoProfileableApp",
+ ":CtsPerfettoProducerApp",
+ ":CtsPerfettoReleaseApp",
+ ":CtsPerfettoDebuggableApp",
+ ":CtsPerfettoReporterApp",
+ "perfetto_device_preparer.sh",
+ ],
stl: "libc++_static",
defaults: [
"perfetto_defaults",
],
- data: [
- "perfetto_device_preparer.sh",
- ],
}
diff --git a/test/cts/AndroidTest.xml b/test/cts/AndroidTest.xml
index 82c2d3519..35ce3de0b 100644
--- a/test/cts/AndroidTest.xml
+++ b/test/cts/AndroidTest.xml
@@ -27,6 +27,7 @@
<option name="test-file-name" value="CtsPerfettoReleaseApp.apk" />
<option name="test-file-name" value="CtsPerfettoProfileableApp.apk" />
<option name="test-file-name" value="CtsPerfettoNonProfileableApp.apk" />
+ <option name="test-file-name" value="CtsPerfettoReporterApp.apk" />
</target_preparer>
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
@@ -50,7 +51,7 @@
<test class="com.android.tradefed.testtype.GTest" >
<option name="native-test-device-path" value="/data/local/tmp" />
<option name="module-name" value="CtsPerfettoTestCases" />
- <option name="runtime-hint" value="0m30s" />
+ <option name="runtime-hint" value="0m40s" />
<!-- test-timeout unit is ms -->
<option name="native-test-timeout" value="40000" />
</test>
diff --git a/test/cts/BUILD.gn b/test/cts/BUILD.gn
index 0404cebfd..e821de882 100644
--- a/test/cts/BUILD.gn
+++ b/test/cts/BUILD.gn
@@ -20,7 +20,7 @@ static_library("perfetto_cts_deps") {
complete_static_lib = true
testonly = true
deps = [
- "..:end_to_end_integrationtests",
+ "..:integrationtests",
"../..:libperfetto_client_experimental",
"../../gn:default_deps",
"../../gn:gtest_and_gmock",
diff --git a/test/cts/end_to_end_integrationtest_cts.cc b/test/cts/end_to_end_integrationtest_cts.cc
index 632db6d25..d87a29947 100644
--- a/test/cts/end_to_end_integrationtest_cts.cc
+++ b/test/cts/end_to_end_integrationtest_cts.cc
@@ -18,6 +18,7 @@
#include <random>
#include "test/gtest_and_gmock.h"
+#include "perfetto/ext/base/android_utils.h"
#include "perfetto/tracing/core/data_source_config.h"
#include "src/base/test/test_task_runner.h"
#include "test/android_test_utils.h"
@@ -34,10 +35,8 @@ class PerfettoCtsTest : public ::testing::Test {
void TestMockProducer(const std::string& producer_name) {
// Filter out watches; they do not have the required infrastructure to run
// these tests.
- char chars[PROP_VALUE_MAX + 1];
- int ret = __system_property_get("ro.build.characteristics", chars);
- ASSERT_GE(ret, 0);
- std::string characteristics(chars);
+ std::string characteristics =
+ base::GetAndroidProp("ro.build.characteristics");
if (characteristics.find("watch") != std::string::npos) {
return;
}
diff --git a/test/cts/heapprofd_java_test_cts.cc b/test/cts/heapprofd_java_test_cts.cc
index f7cfc1aa0..7d8112819 100644
--- a/test/cts/heapprofd_java_test_cts.cc
+++ b/test/cts/heapprofd_java_test_cts.cc
@@ -37,12 +37,12 @@ namespace {
std::string RandomSessionName() {
std::random_device rd;
std::default_random_engine generator(rd());
- std::uniform_int_distribution<char> distribution('a', 'z');
+ std::uniform_int_distribution<> distribution('a', 'z');
constexpr size_t kSessionNameLen = 20;
std::string result(kSessionNameLen, '\0');
for (size_t i = 0; i < kSessionNameLen; ++i)
- result[i] = distribution(generator);
+ result[i] = static_cast<char>(distribution(generator));
return result;
}
@@ -52,11 +52,11 @@ std::vector<protos::gen::TracePacket> ProfileRuntime(std::string app_name) {
// (re)start the target app's main activity
if (IsAppRunning(app_name)) {
StopApp(app_name, "old.app.stopped", &task_runner);
- task_runner.RunUntilCheckpoint("old.app.stopped", 1000 /*ms*/);
+ task_runner.RunUntilCheckpoint("old.app.stopped", 10000 /*ms*/);
}
StartAppActivity(app_name, "MainActivity", "target.app.running", &task_runner,
/*delay_ms=*/100);
- task_runner.RunUntilCheckpoint("target.app.running", 1000 /*ms*/);
+ task_runner.RunUntilCheckpoint("target.app.running", 10000 /*ms*/);
// If we try to dump too early in app initialization, we sometimes deadlock.
sleep(1);
@@ -85,7 +85,7 @@ std::vector<protos::gen::TracePacket> ProfileRuntime(std::string app_name) {
helper.WaitForReadData();
PERFETTO_CHECK(IsAppRunning(app_name));
StopApp(app_name, "new.app.stopped", &task_runner);
- task_runner.RunUntilCheckpoint("new.app.stopped", 1000 /*ms*/);
+ task_runner.RunUntilCheckpoint("new.app.stopped", 10000 /*ms*/);
return helper.trace();
}
@@ -134,5 +134,55 @@ TEST(HeapprofdJavaCtsTest, ReleaseAppRuntime) {
AssertNoProfileContents(packets);
}
+TEST(HeapprofdJavaCtsTest, DebuggableAppRuntimeByPid) {
+ std::string app_name = "android.perfetto.cts.app.debuggable";
+
+ base::TestTaskRunner task_runner;
+
+ // (re)start the target app's main activity
+ if (IsAppRunning(app_name)) {
+ StopApp(app_name, "old.app.stopped", &task_runner);
+ task_runner.RunUntilCheckpoint("old.app.stopped", 10000 /*ms*/);
+ }
+ StartAppActivity(app_name, "MainActivity", "target.app.running", &task_runner,
+ /*delay_ms=*/100);
+ task_runner.RunUntilCheckpoint("target.app.running", 10000 /*ms*/);
+ // If we try to dump too early in app initialization, we sometimes deadlock.
+ sleep(1);
+
+ int target_pid = PidForProcessName(app_name);
+ ASSERT_NE(target_pid, -1);
+
+ // set up tracing
+ TestHelper helper(&task_runner);
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+
+ TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(40 * 1024);
+ trace_config.set_duration_ms(6000);
+ trace_config.set_unique_session_name(RandomSessionName().c_str());
+
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("android.java_hprof");
+ ds_config->set_target_buffer(0);
+
+ protos::gen::JavaHprofConfig java_hprof_config;
+ java_hprof_config.add_pid(static_cast<uint64_t>(target_pid));
+ ds_config->set_java_hprof_config_raw(java_hprof_config.SerializeAsString());
+
+ // start tracing
+ helper.StartTracing(trace_config);
+ helper.WaitForTracingDisabled();
+ helper.ReadData();
+ helper.WaitForReadData();
+ PERFETTO_CHECK(IsAppRunning(app_name));
+ StopApp(app_name, "new.app.stopped", &task_runner);
+ task_runner.RunUntilCheckpoint("new.app.stopped", 10000 /*ms*/);
+
+ const auto& packets = helper.trace();
+ AssertGraphPresent(packets);
+}
+
} // namespace
} // namespace perfetto
diff --git a/test/cts/heapprofd_test_cts.cc b/test/cts/heapprofd_test_cts.cc
index d97e613dd..0966fe5d5 100644
--- a/test/cts/heapprofd_test_cts.cc
+++ b/test/cts/heapprofd_test_cts.cc
@@ -36,39 +36,56 @@
namespace perfetto {
namespace {
-constexpr uint64_t kTestSamplingInterval = 512;
-// Size of individual (repeated) allocations done by the test apps (must be
-// kept in sync with their sources).
-// Tests rely on the sampling behaviour where large allocations are recorded
-// at their actual size, so kExpectedIndividualAllocSz needs to be greater
-// than GetPassthroughTreshold(kExpectedIndividualAllocSz). See
-// src/profiling/memory/sampler.h.
+// Size of individual (repeated) allocations done by the test apps (must be kept
+// in sync with their sources).
+constexpr uint64_t kTestSamplingInterval = 4096;
constexpr uint64_t kExpectedIndividualAllocSz = 4153;
+// Tests rely on the sampling behaviour where allocations larger than the
+// sampling interval are recorded at their actual size.
+static_assert(kExpectedIndividualAllocSz > kTestSamplingInterval,
+ "kTestSamplingInterval invalid");
+
+// Activity that runs a JNI thread that repeatedly calls
+// malloc(kExpectedIndividualAllocSz).
+static char kMallocActivity[] = "MainActivity";
+// Activity that runs a java thread that repeatedly constructs small java
+// objects.
+static char kJavaAllocActivity[] = "JavaAllocActivity";
std::string RandomSessionName() {
std::random_device rd;
std::default_random_engine generator(rd());
- std::uniform_int_distribution<char> distribution('a', 'z');
+ std::uniform_int_distribution<> distribution('a', 'z');
constexpr size_t kSessionNameLen = 20;
std::string result(kSessionNameLen, '\0');
for (size_t i = 0; i < kSessionNameLen; ++i)
- result[i] = distribution(generator);
+ result[i] = static_cast<char>(distribution(generator));
return result;
}
+// Starts the activity `activity` of the app `app_name` and later starts
+// recording a trace with the allocations in `heap_names`.
+//
+// `heap_names` is a list of the heap names whose allocations will be recorded.
+// An empty list means that only the allocations in the default malloc heap
+// ("libc.malloc") are recorded.
+//
+// Returns the recorded trace.
std::vector<protos::gen::TracePacket> ProfileRuntime(
- const std::string& app_name) {
+ const std::string& app_name,
+ const std::string& activity,
+ const std::vector<std::string>& heap_names) {
base::TestTaskRunner task_runner;
// (re)start the target app's main activity
if (IsAppRunning(app_name)) {
StopApp(app_name, "old.app.stopped", &task_runner);
- task_runner.RunUntilCheckpoint("old.app.stopped", 1000 /*ms*/);
+ task_runner.RunUntilCheckpoint("old.app.stopped", 10000 /*ms*/);
}
- StartAppActivity(app_name, "MainActivity", "target.app.running", &task_runner,
+ StartAppActivity(app_name, activity, "target.app.running", &task_runner,
/*delay_ms=*/100);
- task_runner.RunUntilCheckpoint("target.app.running", 1000 /*ms*/);
+ task_runner.RunUntilCheckpoint("target.app.running", 10000 /*ms*/);
// set up tracing
TestHelper helper(&task_runner);
@@ -89,6 +106,9 @@ std::vector<protos::gen::TracePacket> ProfileRuntime(
heapprofd_config.add_process_cmdline(app_name.c_str());
heapprofd_config.set_block_client(true);
heapprofd_config.set_all(false);
+ for (const std::string& heap_name : heap_names) {
+ heapprofd_config.add_heaps(heap_name);
+ }
ds_config->set_heapprofd_config_raw(heapprofd_config.SerializeAsString());
// start tracing
@@ -100,14 +120,24 @@ std::vector<protos::gen::TracePacket> ProfileRuntime(
return helper.trace();
}
+// Starts recording a trace with the allocations in `heap_names` and later
+// starts the activity `activity` of the app `app_name`
+//
+// `heap_names` is a list of the heap names whose allocations will be recorded.
+// An empty list means that only the allocation in the default malloc heap
+// ("libc.malloc") are recorded.
+//
+// Returns the recorded trace.
std::vector<protos::gen::TracePacket> ProfileStartup(
const std::string& app_name,
+ const std::string& activity,
+ const std::vector<std::string>& heap_names,
const bool enable_extra_guardrails = false) {
base::TestTaskRunner task_runner;
if (IsAppRunning(app_name)) {
StopApp(app_name, "old.app.stopped", &task_runner);
- task_runner.RunUntilCheckpoint("old.app.stopped", 1000 /*ms*/);
+ task_runner.RunUntilCheckpoint("old.app.stopped", 10000 /*ms*/);
}
// set up tracing
@@ -130,15 +160,18 @@ std::vector<protos::gen::TracePacket> ProfileStartup(
heapprofd_config.add_process_cmdline(app_name.c_str());
heapprofd_config.set_block_client(true);
heapprofd_config.set_all(false);
+ for (const std::string& heap_name : heap_names) {
+ heapprofd_config.add_heaps(heap_name);
+ }
ds_config->set_heapprofd_config_raw(heapprofd_config.SerializeAsString());
// start tracing
helper.StartTracing(trace_config);
// start app
- StartAppActivity(app_name, "MainActivity", "target.app.running", &task_runner,
+ StartAppActivity(app_name, activity, "target.app.running", &task_runner,
/*delay_ms=*/100);
- task_runner.RunUntilCheckpoint("target.app.running", 2000 /*ms*/);
+ task_runner.RunUntilCheckpoint("target.app.running", 10000 /*ms*/);
helper.WaitForTracingDisabled();
helper.ReadData();
@@ -147,7 +180,8 @@ std::vector<protos::gen::TracePacket> ProfileStartup(
return helper.trace();
}
-void AssertExpectedAllocationsPresent(
+// Check that `packets` contain some allocations performed by kMallocActivity.
+void AssertExpectedMallocsPresent(
const std::vector<protos::gen::TracePacket>& packets) {
ASSERT_GT(packets.size(), 0u);
@@ -176,6 +210,28 @@ void AssertExpectedAllocationsPresent(
ASSERT_TRUE(found_alloc);
}
+// Check that `packets` contain some allocations performed by
+// kJavaAllocActivity.
+void AssertExpectedArtAllocsPresent(
+ const std::vector<protos::gen::TracePacket>& packets) {
+ ASSERT_GT(packets.size(), 0u);
+
+ bool found_alloc = false;
+ bool found_proc_dump = false;
+ for (const auto& packet : packets) {
+ for (const auto& proc_dump : packet.profile_packet().process_dumps()) {
+ found_proc_dump = true;
+ for (const auto& sample : proc_dump.samples()) {
+ if (sample.self_allocated() > 0) {
+ found_alloc = true;
+ }
+ }
+ }
+ }
+ ASSERT_TRUE(found_proc_dump);
+ ASSERT_TRUE(found_alloc);
+}
+
void AssertNoProfileContents(
const std::vector<protos::gen::TracePacket>& packets) {
// If profile packets are present, they must be empty.
@@ -186,71 +242,95 @@ void AssertNoProfileContents(
TEST(HeapprofdCtsTest, DebuggableAppRuntime) {
std::string app_name = "android.perfetto.cts.app.debuggable";
- const auto& packets = ProfileRuntime(app_name);
- AssertExpectedAllocationsPresent(packets);
+ const auto& packets =
+ ProfileRuntime(app_name, kMallocActivity, /*heap_names=*/{});
+ AssertExpectedMallocsPresent(packets);
StopApp(app_name);
}
TEST(HeapprofdCtsTest, DebuggableAppStartup) {
std::string app_name = "android.perfetto.cts.app.debuggable";
- const auto& packets = ProfileStartup(app_name);
- AssertExpectedAllocationsPresent(packets);
+ const auto& packets =
+ ProfileStartup(app_name, kMallocActivity, /*heap_names=*/{});
+ AssertExpectedMallocsPresent(packets);
StopApp(app_name);
}
TEST(HeapprofdCtsTest, ProfileableAppRuntime) {
std::string app_name = "android.perfetto.cts.app.profileable";
- const auto& packets = ProfileRuntime(app_name);
- AssertExpectedAllocationsPresent(packets);
+ const auto& packets =
+ ProfileRuntime(app_name, kMallocActivity, /*heap_names=*/{});
+ AssertExpectedMallocsPresent(packets);
StopApp(app_name);
}
TEST(HeapprofdCtsTest, ProfileableAppStartup) {
std::string app_name = "android.perfetto.cts.app.profileable";
- const auto& packets = ProfileStartup(app_name);
- AssertExpectedAllocationsPresent(packets);
+ const auto& packets =
+ ProfileStartup(app_name, kMallocActivity, /*heap_names=*/{});
+ AssertExpectedMallocsPresent(packets);
StopApp(app_name);
}
TEST(HeapprofdCtsTest, ReleaseAppRuntime) {
std::string app_name = "android.perfetto.cts.app.release";
- const auto& packets = ProfileRuntime(app_name);
+ const auto& packets =
+ ProfileRuntime(app_name, kMallocActivity, /*heap_names=*/{});
if (IsUserBuild())
AssertNoProfileContents(packets);
else
- AssertExpectedAllocationsPresent(packets);
+ AssertExpectedMallocsPresent(packets);
StopApp(app_name);
}
TEST(HeapprofdCtsTest, ReleaseAppStartup) {
std::string app_name = "android.perfetto.cts.app.release";
- const auto& packets = ProfileStartup(app_name);
+ const auto& packets =
+ ProfileStartup(app_name, kMallocActivity, /*heap_names=*/{});
if (IsUserBuild())
AssertNoProfileContents(packets);
else
- AssertExpectedAllocationsPresent(packets);
+ AssertExpectedMallocsPresent(packets);
StopApp(app_name);
}
TEST(HeapprofdCtsTest, NonProfileableAppRuntime) {
std::string app_name = "android.perfetto.cts.app.nonprofileable";
- const auto& packets = ProfileRuntime(app_name);
+ const auto& packets =
+ ProfileRuntime(app_name, kMallocActivity, /*heap_names=*/{});
if (IsUserBuild())
AssertNoProfileContents(packets);
else
- AssertExpectedAllocationsPresent(packets);
+ AssertExpectedMallocsPresent(packets);
StopApp(app_name);
}
TEST(HeapprofdCtsTest, NonProfileableAppStartup) {
std::string app_name = "android.perfetto.cts.app.nonprofileable";
- const auto& packets = ProfileStartup(app_name);
+ const auto& packets =
+ ProfileStartup(app_name, kMallocActivity, /*heap_names=*/{});
if (IsUserBuild())
AssertNoProfileContents(packets);
else
- AssertExpectedAllocationsPresent(packets);
+ AssertExpectedMallocsPresent(packets);
+ StopApp(app_name);
+}
+
+TEST(HeapprofdCtsTest, JavaHeapRuntime) {
+ std::string app_name = "android.perfetto.cts.app.debuggable";
+ const auto& packets = ProfileRuntime(app_name, kJavaAllocActivity,
+ /*heap_names=*/{"com.android.art"});
+ AssertExpectedArtAllocsPresent(packets);
+ StopApp(app_name);
+}
+
+TEST(HeapprofdCtsTest, JavaHeapStartup) {
+ std::string app_name = "android.perfetto.cts.app.debuggable";
+ const auto& packets = ProfileStartup(app_name, kJavaAllocActivity,
+ /*heap_names=*/{"com.android.art"});
+ AssertExpectedArtAllocsPresent(packets);
StopApp(app_name);
}
diff --git a/test/cts/reporter/Android.bp b/test/cts/reporter/Android.bp
new file mode 100644
index 000000000..ab2633b56
--- /dev/null
+++ b/test/cts/reporter/Android.bp
@@ -0,0 +1,30 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_perfetto_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["external_perfetto_license"],
+}
+
+android_test_helper_app {
+ name: "CtsPerfettoReporterApp",
+ manifest: "AndroidManifest.xml",
+ srcs: ["src/**/*.java"],
+ platform_apis: true,
+ privileged: true,
+}
diff --git a/test/cts/reporter/AndroidManifest.xml b/test/cts/reporter/AndroidManifest.xml
new file mode 100755
index 000000000..9a2ef404d
--- /dev/null
+++ b/test/cts/reporter/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.perfetto.cts.reporter">
+ <uses-permission android:name="android.permission.DUMP"/>
+ <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
+1
+ <application>
+ <service
+ android:name=".PerfettoReportService"
+ android:permission="android.permission.BIND_TRACE_REPORT_SERVICE"/>
+ </application>
+</manifest>
diff --git a/test/cts/reporter/src/android/perfetto/cts/reporter/PerfettoReportService.java b/test/cts/reporter/src/android/perfetto/cts/reporter/PerfettoReportService.java
new file mode 100644
index 000000000..5d0c8afc5
--- /dev/null
+++ b/test/cts/reporter/src/android/perfetto/cts/reporter/PerfettoReportService.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.perfetto.cts.reporter;
+
+import android.os.ParcelFileDescriptor.AutoCloseInputStream;
+import android.service.tracing.TraceReportService;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.UUID;
+
+public class PerfettoReportService extends TraceReportService {
+ public static final String TAG = "PerfettoReportService";
+
+ @Override
+ public void onReportTrace(TraceParams args) {
+ File f = new File(getExternalFilesDir(null), args.getUuid().toString());
+ try {
+ boolean created = f.createNewFile();
+ if (!created) {
+ throw new IllegalStateException("Failed to create file");
+ }
+ try (AutoCloseInputStream i = new AutoCloseInputStream(args.getFd())) {
+ try (FileOutputStream o = new FileOutputStream((f))) {
+ o.write(i.readAllBytes());
+ }
+ }
+ } catch (IOException ex) {
+ throw new IllegalStateException("IO Exception", ex);
+ }
+ }
+}
diff --git a/test/cts/reporter_test_cts.cc b/test/cts/reporter_test_cts.cc
new file mode 100644
index 000000000..f9294f4e5
--- /dev/null
+++ b/test/cts/reporter_test_cts.cc
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/system_properties.h>
+#include <random>
+#include "test/gtest_and_gmock.h"
+
+#include "perfetto/ext/base/android_utils.h"
+#include "perfetto/ext/base/uuid.h"
+#include "perfetto/tracing/core/data_source_config.h"
+#include "src/base/test/test_task_runner.h"
+#include "test/android_test_utils.h"
+#include "test/test_helper.h"
+
+#include "protos/perfetto/config/test_config.gen.h"
+#include "protos/perfetto/trace/test_event.gen.h"
+#include "protos/perfetto/trace/trace.gen.h"
+#include "protos/perfetto/trace/trace_packet.gen.h"
+
+namespace perfetto {
+namespace {
+
+TEST(PerfettoReporterTest, TestEndToEndReport) {
+ base::TestTaskRunner task_runner;
+ TestHelper helper(&task_runner);
+ helper.ConnectFakeProducer();
+
+ TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(1024);
+ trace_config.set_duration_ms(200);
+ trace_config.set_allow_user_build_tracing(true);
+
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("android.perfetto.FakeProducer");
+ ds_config->set_target_buffer(0);
+
+ base::Uuid uuid = base::Uuidv4();
+ trace_config.set_trace_uuid_lsb(uuid.lsb());
+ trace_config.set_trace_uuid_msb(uuid.msb());
+
+ static constexpr uint32_t kRandomSeed = 42;
+ static constexpr uint32_t kEventCount = 1;
+ static constexpr uint32_t kMessageSizeBytes = 2;
+ ds_config->mutable_for_testing()->set_seed(kRandomSeed);
+ ds_config->mutable_for_testing()->set_message_count(kEventCount);
+ ds_config->mutable_for_testing()->set_message_size(kMessageSizeBytes);
+ ds_config->mutable_for_testing()->set_send_batch_on_register(true);
+
+ auto* report_config = trace_config.mutable_android_report_config();
+ report_config->set_reporter_service_package("android.perfetto.cts.reporter");
+ report_config->set_reporter_service_class(
+ "android.perfetto.cts.reporter.PerfettoReportService");
+ report_config->set_use_pipe_in_framework_for_testing(true);
+
+ // We have to construct all the processes we want to fork before we start the
+ // service with |StartServiceIfRequired()|. this is because it is unsafe
+ // (could deadlock) to fork after we've spawned some threads which might
+ // printf (and thus hold locks).
+ auto perfetto_proc = Exec("perfetto",
+ {
+ "--upload",
+ "-c",
+ "-",
+ },
+ trace_config.SerializeAsString());
+
+ std::string stderr_str;
+ EXPECT_EQ(0, perfetto_proc.Run(&stderr_str)) << stderr_str;
+
+ static constexpr char kPath[] =
+ "/sdcard/Android/data/android.perfetto.cts.reporter/files/";
+ std::string path = kPath + uuid.ToPrettyString();
+ static constexpr uint32_t kIterationSleepMs = 500;
+ static constexpr uint32_t kIterationCount =
+ kDefaultTestTimeoutMs / kIterationSleepMs;
+ for (size_t i = 0; i < kIterationCount; ++i) {
+ if (!base::FileExists(path)) {
+ base::SleepMicroseconds(kIterationSleepMs * 1000);
+ continue;
+ }
+
+ std::string trace_str;
+ ASSERT_TRUE(base::ReadFile(path, &trace_str));
+
+ protos::gen::Trace trace;
+ ASSERT_TRUE(trace.ParseFromString(trace_str));
+ int for_testing = 0;
+ for (const auto& packet : trace.packet()) {
+ for_testing += packet.has_for_testing();
+ }
+ ASSERT_EQ(for_testing, kEventCount);
+ return;
+ }
+ FAIL() << "Timed out waiting for trace file";
+}
+
+} // namespace
+} // namespace perfetto
diff --git a/test/cts/test_apps/AndroidManifest_debuggable.xml b/test/cts/test_apps/AndroidManifest_debuggable.xml
index 871544e75..cb746c17e 100755
--- a/test/cts/test_apps/AndroidManifest_debuggable.xml
+++ b/test/cts/test_apps/AndroidManifest_debuggable.xml
@@ -45,5 +45,18 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
+ <activity
+ android:name="android.perfetto.cts.app.JavaAllocActivity"
+ android:exported="true">
+ </activity>
+ <activity-alias
+ android:name="android.perfetto.cts.app.debuggable.JavaAllocActivity"
+ android:targetActivity="android.perfetto.cts.app.JavaAllocActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity-alias>
</application>
</manifest>
diff --git a/test/cts/test_apps/AndroidManifest_nonprofileable.xml b/test/cts/test_apps/AndroidManifest_nonprofileable.xml
index c4a716d30..a332175f9 100755
--- a/test/cts/test_apps/AndroidManifest_nonprofileable.xml
+++ b/test/cts/test_apps/AndroidManifest_nonprofileable.xml
@@ -46,6 +46,19 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
+ <activity
+ android:name="android.perfetto.cts.app.JavaAllocActivity"
+ android:exported="true">
+ </activity>
+ <activity-alias
+ android:name="android.perfetto.cts.app.nonprofileable.JavaAllocActivity"
+ android:targetActivity="android.perfetto.cts.app.JavaAllocActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity-alias>
</application>
</manifest>
diff --git a/test/cts/test_apps/AndroidManifest_profileable.xml b/test/cts/test_apps/AndroidManifest_profileable.xml
index 632280612..bac8a6632 100755
--- a/test/cts/test_apps/AndroidManifest_profileable.xml
+++ b/test/cts/test_apps/AndroidManifest_profileable.xml
@@ -46,6 +46,19 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
+ <activity
+ android:name="android.perfetto.cts.app.JavaAllocActivity"
+ android:exported="true">
+ </activity>
+ <activity-alias
+ android:name="android.perfetto.cts.app.profileable.JavaAllocActivity"
+ android:targetActivity="android.perfetto.cts.app.JavaAllocActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity-alias>
</application>
</manifest>
diff --git a/test/cts/test_apps/AndroidManifest_release.xml b/test/cts/test_apps/AndroidManifest_release.xml
index 83d9c4755..5bc0f5be3 100755
--- a/test/cts/test_apps/AndroidManifest_release.xml
+++ b/test/cts/test_apps/AndroidManifest_release.xml
@@ -45,5 +45,18 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
+ <activity
+ android:name="android.perfetto.cts.app.JavaAllocActivity"
+ android:exported="true">
+ </activity>
+ <activity-alias
+ android:name="android.perfetto.cts.app.release.JavaAllocActivity"
+ android:targetActivity="android.perfetto.cts.app.JavaAllocActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity-alias>
</application>
</manifest>
diff --git a/test/cts/test_apps/src/android/perfetto/cts/app/JavaAllocActivity.java b/test/cts/test_apps/src/android/perfetto/cts/app/JavaAllocActivity.java
new file mode 100644
index 000000000..077d32f61
--- /dev/null
+++ b/test/cts/test_apps/src/android/perfetto/cts/app/JavaAllocActivity.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.perfetto.cts.app;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+import java.util.TreeMap;
+
+public class JavaAllocActivity extends Activity {
+ @Override
+ public void onCreate(Bundle state) {
+ super.onCreate(state);
+
+ new Thread(new Runnable() {
+ public void run() {
+ try {
+ runAllocationLoop();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ }).start();
+ }
+
+ private static TreeMap treeMap = new TreeMap();
+ private static long index = 0;
+
+ private static void runAllocationLoop() {
+ for (;;) {
+ for (int i = 0; i < 1000; i++) {
+ Object o = new Object();
+ treeMap.put(++index, o);
+ }
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException ignored) {
+ }
+ treeMap.clear();
+ }
+ }
+}
diff --git a/test/cts/traced_perf_test_cts.cc b/test/cts/traced_perf_test_cts.cc
index 831f8b345..d7bd60e1e 100644
--- a/test/cts/traced_perf_test_cts.cc
+++ b/test/cts/traced_perf_test_cts.cc
@@ -15,12 +15,12 @@
*/
#include <stdlib.h>
-#include <sys/system_properties.h>
#include <sys/types.h>
#include <string>
#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/android_utils.h"
#include "perfetto/tracing/core/data_source_config.h"
#include "src/base/test/test_task_runner.h"
#include "test/android_test_utils.h"
@@ -39,21 +39,18 @@ namespace {
// LSM hooks in perf_event_open. This comes up when a device with an older
// kernel upgrades to R.
bool HasPerfLsmHooks() {
- char buf[PROP_VALUE_MAX + 1] = {};
- int ret = __system_property_get("sys.init.perf_lsm_hooks", buf);
- PERFETTO_CHECK(ret >= 0);
- return std::string(buf) == "1";
+ return base::GetAndroidProp("sys.init.perf_lsm_hooks") == "1";
}
std::string RandomSessionName() {
std::random_device rd;
std::default_random_engine generator(rd());
- std::uniform_int_distribution<char> distribution('a', 'z');
+ std::uniform_int_distribution<> distribution('a', 'z');
constexpr size_t kSessionNameLen = 20;
std::string result(kSessionNameLen, '\0');
for (size_t i = 0; i < kSessionNameLen; ++i)
- result[i] = distribution(generator);
+ result[i] = static_cast<char>(distribution(generator));
return result;
}
@@ -63,12 +60,12 @@ std::vector<protos::gen::TracePacket> ProfileSystemWide(std::string app_name) {
// (re)start the target app's main activity
if (IsAppRunning(app_name)) {
StopApp(app_name, "old.app.stopped", &task_runner);
- task_runner.RunUntilCheckpoint("old.app.stopped", 1000 /*ms*/);
+ task_runner.RunUntilCheckpoint("old.app.stopped", 10000 /*ms*/);
}
StartAppActivity(app_name, "BusyWaitActivity", "target.app.running",
&task_runner,
/*delay_ms=*/100);
- task_runner.RunUntilCheckpoint("target.app.running", 1000 /*ms*/);
+ task_runner.RunUntilCheckpoint("target.app.running", 10000 /*ms*/);
// set up tracing
TestHelper helper(&task_runner);
diff --git a/test/data/README.md.sha256 b/test/data/README.md.sha256
new file mode 100644
index 000000000..c740e86dc
--- /dev/null
+++ b/test/data/README.md.sha256
@@ -0,0 +1 @@
+12f0487d0c76689562b52e25e5c879c4ff2ab2b214b45556638644dfaef1750c \ No newline at end of file
diff --git a/test/data/android_log.pb.sha256 b/test/data/android_log.pb.sha256
new file mode 100644
index 000000000..20db167ae
--- /dev/null
+++ b/test/data/android_log.pb.sha256
@@ -0,0 +1 @@
+841512535c2a95f024443455719adefdbed96073eb48a1ba950ed117d615e4d9 \ No newline at end of file
diff --git a/test/data/android_log_ring_buffer_mode.pb.sha256 b/test/data/android_log_ring_buffer_mode.pb.sha256
new file mode 100644
index 000000000..afa8fe43b
--- /dev/null
+++ b/test/data/android_log_ring_buffer_mode.pb.sha256
@@ -0,0 +1 @@
+130113fd0efb6ca6a7de1c36cb7c27a5e06f2dea5cf1183f39594b6882d0a6f9 \ No newline at end of file
diff --git a/test/data/android_sched_and_ps.pb.sha256 b/test/data/android_sched_and_ps.pb.sha256
new file mode 100644
index 000000000..aa7ac2c81
--- /dev/null
+++ b/test/data/android_sched_and_ps.pb.sha256
@@ -0,0 +1 @@
+0f0d482576280e159de5b57b2847cae2ca751ab9d523d77ef8d32fe422464714 \ No newline at end of file
diff --git a/test/data/atrace_b_193721088.atr.sha256 b/test/data/atrace_b_193721088.atr.sha256
new file mode 100644
index 000000000..9233bc471
--- /dev/null
+++ b/test/data/atrace_b_193721088.atr.sha256
@@ -0,0 +1 @@
+e875c7dc4e3923ad3752bcb97f141aa83a7e69aecc8dbcae1047853e087541b9 \ No newline at end of file
diff --git a/test/data/atrace_compressed.ctrace.sha256 b/test/data/atrace_compressed.ctrace.sha256
new file mode 100644
index 000000000..d39c5eaf2
--- /dev/null
+++ b/test/data/atrace_compressed.ctrace.sha256
@@ -0,0 +1 @@
+db92be3d78ab0619af5068240b88bad78a655f3e403c5f7c7876956eb5b260b0 \ No newline at end of file
diff --git a/test/data/atrace_uncompressed_b_208691037.sha256 b/test/data/atrace_uncompressed_b_208691037.sha256
new file mode 100644
index 000000000..7348172dd
--- /dev/null
+++ b/test/data/atrace_uncompressed_b_208691037.sha256
@@ -0,0 +1 @@
+9872b827df72895a98af2977c117ad3bc31f8c62be79d211bdf254170db4e1de \ No newline at end of file
diff --git a/test/data/callstack_sampling.pftrace.sha256 b/test/data/callstack_sampling.pftrace.sha256
new file mode 100644
index 000000000..8649b4182
--- /dev/null
+++ b/test/data/callstack_sampling.pftrace.sha256
@@ -0,0 +1 @@
+0ef35902380a75c52cd83afdb4165b545a5810bde16bad954872994ca21c5ae7 \ No newline at end of file
diff --git a/test/data/camera-ion-mem-trace.sha256 b/test/data/camera-ion-mem-trace.sha256
new file mode 100644
index 000000000..22fe93dad
--- /dev/null
+++ b/test/data/camera-ion-mem-trace.sha256
@@ -0,0 +1 @@
+49997763271536ab947ada3125b03f5d441226725789022d326b43dc24486c8b \ No newline at end of file
diff --git a/test/data/chrome_android_systrace.pftrace.sha256 b/test/data/chrome_android_systrace.pftrace.sha256
new file mode 100644
index 000000000..63f5b7d4d
--- /dev/null
+++ b/test/data/chrome_android_systrace.pftrace.sha256
@@ -0,0 +1 @@
+a96005e5ee9059b89347573f7a7ca53097244fb3532956e0a62897ad77be2ddf \ No newline at end of file
diff --git a/test/data/chrome_memory_snapshot.pftrace.sha256 b/test/data/chrome_memory_snapshot.pftrace.sha256
new file mode 100644
index 000000000..c55016ecb
--- /dev/null
+++ b/test/data/chrome_memory_snapshot.pftrace.sha256
@@ -0,0 +1 @@
+4a06b393bf14147b25296797756a4185abf31510aca2db22ddb3c5dbd21123e4 \ No newline at end of file
diff --git a/test/data/chrome_rendering_desktop.pftrace.sha256 b/test/data/chrome_rendering_desktop.pftrace.sha256
new file mode 100644
index 000000000..28c75898c
--- /dev/null
+++ b/test/data/chrome_rendering_desktop.pftrace.sha256
@@ -0,0 +1 @@
+f61971e42ea0ce0f6da71c87a0ab19da0e13deca0fa90c6bdc98782af01ae702 \ No newline at end of file
diff --git a/test/data/chrome_scroll_without_vsync.pftrace.sha256 b/test/data/chrome_scroll_without_vsync.pftrace.sha256
new file mode 100644
index 000000000..07deab4ed
--- /dev/null
+++ b/test/data/chrome_scroll_without_vsync.pftrace.sha256
@@ -0,0 +1 @@
+74890239a1042cb93a87b8b5b5d9942f821ed3cc0c1236e7734d45a550e3cde4 \ No newline at end of file
diff --git a/test/data/chrome_touch_gesture_scroll.pftrace.sha256 b/test/data/chrome_touch_gesture_scroll.pftrace.sha256
new file mode 100644
index 000000000..9d04d5d40
--- /dev/null
+++ b/test/data/chrome_touch_gesture_scroll.pftrace.sha256
@@ -0,0 +1 @@
+2fe40090c41ebeb5dc6ce0bea5bc9aef4d7f4cf7fd625209641e0c5ea2210fb7 \ No newline at end of file
diff --git a/test/data/clusterfuzz_14357.sha256 b/test/data/clusterfuzz_14357.sha256
new file mode 100644
index 000000000..c4506d082
--- /dev/null
+++ b/test/data/clusterfuzz_14357.sha256
@@ -0,0 +1 @@
+d9bbe8837573821ff3b505e68b0ed18c3193b8096f786e4b7632b160e44e91ca \ No newline at end of file
diff --git a/test/data/clusterfuzz_14730.sha256 b/test/data/clusterfuzz_14730.sha256
new file mode 100644
index 000000000..f91a3aec3
--- /dev/null
+++ b/test/data/clusterfuzz_14730.sha256
@@ -0,0 +1 @@
+bdf674c136a88137664d22bf366ea3a15ef6c7925a535b1a97b04fdd8b325517 \ No newline at end of file
diff --git a/test/data/clusterfuzz_14753.sha256 b/test/data/clusterfuzz_14753.sha256
new file mode 100644
index 000000000..eae4ae680
--- /dev/null
+++ b/test/data/clusterfuzz_14753.sha256
@@ -0,0 +1 @@
+e992a4a487aea71875a80fa0577aa2bb1324e14383a70022e81d606396a2fcee \ No newline at end of file
diff --git a/test/data/clusterfuzz_14762.sha256 b/test/data/clusterfuzz_14762.sha256
new file mode 100644
index 000000000..8af9a34bb
--- /dev/null
+++ b/test/data/clusterfuzz_14762.sha256
@@ -0,0 +1 @@
+cbeec86e06fefc086b9531a9bdb2b35533710627b9e49aeaa53651090fe11d06 \ No newline at end of file
diff --git a/test/data/clusterfuzz_14767.sha256 b/test/data/clusterfuzz_14767.sha256
new file mode 100644
index 000000000..eb98fdb83
--- /dev/null
+++ b/test/data/clusterfuzz_14767.sha256
@@ -0,0 +1 @@
+52aac563f69535cee168ae85804e2a67dc2bbcca52f5c3f8018c7f2e40f4867c \ No newline at end of file
diff --git a/test/data/clusterfuzz_14799.sha256 b/test/data/clusterfuzz_14799.sha256
new file mode 100644
index 000000000..0021481f6
--- /dev/null
+++ b/test/data/clusterfuzz_14799.sha256
@@ -0,0 +1 @@
+edec5220388bee58ce9827c16676c0285c4b4779ecc1bd9957ca0791fd98315f \ No newline at end of file
diff --git a/test/data/clusterfuzz_15252.sha256 b/test/data/clusterfuzz_15252.sha256
new file mode 100644
index 000000000..7ebfdfc06
--- /dev/null
+++ b/test/data/clusterfuzz_15252.sha256
@@ -0,0 +1 @@
+3d6047483cddadbcbedfc828d42135ca25c51ec09bf55be4f7aae7844e24ba32 \ No newline at end of file
diff --git a/test/data/clusterfuzz_17805.sha256 b/test/data/clusterfuzz_17805.sha256
new file mode 100644
index 000000000..488e5a935
--- /dev/null
+++ b/test/data/clusterfuzz_17805.sha256
@@ -0,0 +1 @@
+f9eb862fec5ef13ecaf2c90c61bb7c88bc1184682f31383a34a2edcc416e5eaa \ No newline at end of file
diff --git a/test/data/clusterfuzz_20215.sha256 b/test/data/clusterfuzz_20215.sha256
new file mode 100644
index 000000000..f9c8feb14
--- /dev/null
+++ b/test/data/clusterfuzz_20215.sha256
@@ -0,0 +1 @@
+f5478862ec1a4e006a70bc15283ba9c2d769a5dc4c513ad43aab678b61a4b43a \ No newline at end of file
diff --git a/test/data/clusterfuzz_20292.sha256 b/test/data/clusterfuzz_20292.sha256
new file mode 100644
index 000000000..ddfe70dd3
--- /dev/null
+++ b/test/data/clusterfuzz_20292.sha256
@@ -0,0 +1 @@
+cf2219b9a92fba90ba48e9ec1747e3f8b0d283afda7f56bc4a17fae002ff036c \ No newline at end of file
diff --git a/test/data/clusterfuzz_21178.sha256 b/test/data/clusterfuzz_21178.sha256
new file mode 100644
index 000000000..11032cdda
--- /dev/null
+++ b/test/data/clusterfuzz_21178.sha256
@@ -0,0 +1 @@
+c32f8fab41eeb4928091d9633f6e7b9cb42678ec1f0f1c27239f89e1ba5860ea \ No newline at end of file
diff --git a/test/data/clusterfuzz_21890.sha256 b/test/data/clusterfuzz_21890.sha256
new file mode 100644
index 000000000..a148c5deb
--- /dev/null
+++ b/test/data/clusterfuzz_21890.sha256
@@ -0,0 +1 @@
+469f2c24d560fda648d51f803eed28ef0b686fc11bd7801c808f98367dafd090 \ No newline at end of file
diff --git a/test/data/clusterfuzz_23053.sha256 b/test/data/clusterfuzz_23053.sha256
new file mode 100644
index 000000000..b896d787c
--- /dev/null
+++ b/test/data/clusterfuzz_23053.sha256
@@ -0,0 +1 @@
+e424e3b4296939ad07465f937981011927869f6d050e7d5ba2af5dd783e2b48f \ No newline at end of file
diff --git a/test/data/clusterfuzz_28338.sha256 b/test/data/clusterfuzz_28338.sha256
new file mode 100644
index 000000000..25aa86632
--- /dev/null
+++ b/test/data/clusterfuzz_28338.sha256
@@ -0,0 +1 @@
+dee9f2a655a163892299479cb2cb9327b686d8ff2f672a6b9b4f44139e901152 \ No newline at end of file
diff --git a/test/data/clusterfuzz_28766.sha256 b/test/data/clusterfuzz_28766.sha256
new file mode 100644
index 000000000..0de9c271f
--- /dev/null
+++ b/test/data/clusterfuzz_28766.sha256
@@ -0,0 +1 @@
+69f872a397a02e7f50e02b334a23e8346850db0a37c017c2076b7be7cc182c2d \ No newline at end of file
diff --git a/test/data/compact_sched.pb.sha256 b/test/data/compact_sched.pb.sha256
new file mode 100644
index 000000000..5b0e00708
--- /dev/null
+++ b/test/data/compact_sched.pb.sha256
@@ -0,0 +1 @@
+1fd2a81ae4354a38f3b433b516f083c9a8c378fe7043450ba7fee84d7fb2f5d8 \ No newline at end of file
diff --git a/test/data/compressed.pb.gz.sha256 b/test/data/compressed.pb.gz.sha256
new file mode 100644
index 000000000..99fbe2239
--- /dev/null
+++ b/test/data/compressed.pb.gz.sha256
@@ -0,0 +1 @@
+20a762af59c421dea4211e371299016b47ce7e520f69fc981bd7d43dd9b23be1 \ No newline at end of file
diff --git a/test/data/compressed.pb.sha256 b/test/data/compressed.pb.sha256
new file mode 100644
index 000000000..8e71854c6
--- /dev/null
+++ b/test/data/compressed.pb.sha256
@@ -0,0 +1 @@
+33d25b9d884f18f04b1f9ded6aadd75e630d5605e5b157e9d1da8f15bea52d96 \ No newline at end of file
diff --git a/test/data/counters.json.sha256 b/test/data/counters.json.sha256
new file mode 100644
index 000000000..dc3aff349
--- /dev/null
+++ b/test/data/counters.json.sha256
@@ -0,0 +1 @@
+5c8a3e8bd3c5e0fb2eec5acd5e11ddb0ab129727f288c35fac3f545708904c35 \ No newline at end of file
diff --git a/test/data/cpu_counters.pb.sha256 b/test/data/cpu_counters.pb.sha256
new file mode 100644
index 000000000..4c5bb68f9
--- /dev/null
+++ b/test/data/cpu_counters.pb.sha256
@@ -0,0 +1 @@
+e566d656f369d988e42b9792ac14cc6e82ce5928066bbf26210ffe5bbda3384b \ No newline at end of file
diff --git a/test/data/decimal_timestamp.json.sha256 b/test/data/decimal_timestamp.json.sha256
new file mode 100644
index 000000000..57ab15f23
--- /dev/null
+++ b/test/data/decimal_timestamp.json.sha256
@@ -0,0 +1 @@
+698d7493fe7441e491ad5037587fc38269c878b6f76203fe63dda0e7daad54a4 \ No newline at end of file
diff --git a/test/data/display_time_unit.json.sha256 b/test/data/display_time_unit.json.sha256
new file mode 100644
index 000000000..c511e18ba
--- /dev/null
+++ b/test/data/display_time_unit.json.sha256
@@ -0,0 +1 @@
+208a66ae15b873b6a04ed3e0e67aeb8827e13b8d6e175514991df5d361d11162 \ No newline at end of file
diff --git a/test/data/example_android_trace_30s.pb.gz.sha256 b/test/data/example_android_trace_30s.pb.gz.sha256
new file mode 100644
index 000000000..bb57cf121
--- /dev/null
+++ b/test/data/example_android_trace_30s.pb.gz.sha256
@@ -0,0 +1 @@
+6716542d89bb2d1d9bd7c43d696111184a274bcecf0b3a468388b0d95b3c5336 \ No newline at end of file
diff --git a/test/data/example_android_trace_30s.pb.sha256 b/test/data/example_android_trace_30s.pb.sha256
new file mode 100644
index 000000000..83f6e45d0
--- /dev/null
+++ b/test/data/example_android_trace_30s.pb.sha256
@@ -0,0 +1 @@
+62656cc8ea2a624db95087850245d16453f0723f723ed2e329080e771bc1f82c \ No newline at end of file
diff --git a/test/data/ftrace_error_stats.pftrace.sha256 b/test/data/ftrace_error_stats.pftrace.sha256
new file mode 100644
index 000000000..4a29e3ea8
--- /dev/null
+++ b/test/data/ftrace_error_stats.pftrace.sha256
@@ -0,0 +1 @@
+f2c4c42a10cb6c4bc341640f89dd714b6b63c06a93db79ea0b83cdd68ea239f0 \ No newline at end of file
diff --git a/test/data/fuchsia_trace.fxt.sha256 b/test/data/fuchsia_trace.fxt.sha256
new file mode 100644
index 000000000..0b6b942c9
--- /dev/null
+++ b/test/data/fuchsia_trace.fxt.sha256
@@ -0,0 +1 @@
+b555e6d1346c8189f0d8b1427c1f2f716b2b15dfb9b7c6a2b978e8207ceaad7f \ No newline at end of file
diff --git a/test/data/fuchsia_workstation.fxt.sha256 b/test/data/fuchsia_workstation.fxt.sha256
new file mode 100644
index 000000000..cf63c9557
--- /dev/null
+++ b/test/data/fuchsia_workstation.fxt.sha256
@@ -0,0 +1 @@
+7fb7e1568313d02f495ddc8063fa9ef209a346f0322d105fac3462ffb60fe1fb \ No newline at end of file
diff --git a/test/data/full_trace_filter.bytecode.sha256 b/test/data/full_trace_filter.bytecode.sha256
new file mode 100644
index 000000000..278daa6ab
--- /dev/null
+++ b/test/data/full_trace_filter.bytecode.sha256
@@ -0,0 +1 @@
+c394ad3e15cef817bc3f37ed02b3b3808a5bb8de5bcc8a3cfe83e455bfdad9d5 \ No newline at end of file
diff --git a/test/data/gpu_counters.pb.sha256 b/test/data/gpu_counters.pb.sha256
new file mode 100644
index 000000000..899fc60cb
--- /dev/null
+++ b/test/data/gpu_counters.pb.sha256
@@ -0,0 +1 @@
+33d59d659b9278fef11afa2ca3bd92c2cd41f46a1e8291babef9f2e256e08fee \ No newline at end of file
diff --git a/test/data/gpu_trace.pb.sha256 b/test/data/gpu_trace.pb.sha256
new file mode 100644
index 000000000..f8f9037b9
--- /dev/null
+++ b/test/data/gpu_trace.pb.sha256
@@ -0,0 +1 @@
+19596f1c578f78ef05bfc8e045eed53ce141585703ce8aee0d2fdb1127871812 \ No newline at end of file
diff --git a/test/data/heapprofd_standalone_client_example-trace.sha256 b/test/data/heapprofd_standalone_client_example-trace.sha256
new file mode 100644
index 000000000..c97735aa3
--- /dev/null
+++ b/test/data/heapprofd_standalone_client_example-trace.sha256
@@ -0,0 +1 @@
+4f10e47ae1259d1a3aac6d6225a437e313882cf9d7b267c3e7d589d57a92d497 \ No newline at end of file
diff --git a/test/data/heapprofd_standalone_client_example.sha256 b/test/data/heapprofd_standalone_client_example.sha256
new file mode 100644
index 000000000..1aea0a109
--- /dev/null
+++ b/test/data/heapprofd_standalone_client_example.sha256
@@ -0,0 +1 @@
+7b95231beb9e7087d6e51564df95a5702635a7b4b880e1c88a4488e620eb8a94 \ No newline at end of file
diff --git a/test/data/instants.json.sha256 b/test/data/instants.json.sha256
new file mode 100644
index 000000000..1d627fbf9
--- /dev/null
+++ b/test/data/instants.json.sha256
@@ -0,0 +1 @@
+fa5d3c43e9ac589d7ffa5ece7306ab630d48324494b25fd7e2c7319d6cedd3b9 \ No newline at end of file
diff --git a/test/data/kallsyms.txt.sha256 b/test/data/kallsyms.txt.sha256
new file mode 100644
index 000000000..f1855a26a
--- /dev/null
+++ b/test/data/kallsyms.txt.sha256
@@ -0,0 +1 @@
+79d35d0254881c0c18107a6985c1f1e95794287168a520dfb1934a03dfe58d3c \ No newline at end of file
diff --git a/test/data/lmk_userspace.pb.sha256 b/test/data/lmk_userspace.pb.sha256
new file mode 100644
index 000000000..f83d65213
--- /dev/null
+++ b/test/data/lmk_userspace.pb.sha256
@@ -0,0 +1 @@
+9b888ba2c4d724f9f034b7505d06e4266d1ebe8bfb4110b2b8eee44c127b24ed \ No newline at end of file
diff --git a/test/data/log.proto.sha256 b/test/data/log.proto.sha256
new file mode 100644
index 000000000..afa8fe43b
--- /dev/null
+++ b/test/data/log.proto.sha256
@@ -0,0 +1 @@
+130113fd0efb6ca6a7de1c36cb7c27a5e06f2dea5cf1183f39594b6882d0a6f9 \ No newline at end of file
diff --git a/test/data/memory_counters.pb.sha256 b/test/data/memory_counters.pb.sha256
new file mode 100644
index 000000000..52129d74b
--- /dev/null
+++ b/test/data/memory_counters.pb.sha256
@@ -0,0 +1 @@
+29fa34f6bcd6ed9663dbe9be4615cc8eafc93c1d78b1e5f7353b56da6fcf82e2 \ No newline at end of file
diff --git a/test/data/mm_event.pb.sha256 b/test/data/mm_event.pb.sha256
new file mode 100644
index 000000000..db5cc4b71
--- /dev/null
+++ b/test/data/mm_event.pb.sha256
@@ -0,0 +1 @@
+14c3405a0904552202f7325fe730fa1e99fa8b876ef08014984ad5b7ec449f1c \ No newline at end of file
diff --git a/test/data/ninja_log.sha256 b/test/data/ninja_log.sha256
new file mode 100644
index 000000000..242ae64be
--- /dev/null
+++ b/test/data/ninja_log.sha256
@@ -0,0 +1 @@
+2072bf6bad617bfaf8b453e3b9552db0e73c846122c897d3336b6ce41b4fc42b \ No newline at end of file
diff --git a/test/data/perf_sample.pb.sha256 b/test/data/perf_sample.pb.sha256
new file mode 100644
index 000000000..170e58e5b
--- /dev/null
+++ b/test/data/perf_sample.pb.sha256
@@ -0,0 +1 @@
+3e4e31dcbe5e4d924b4e391593f81d065ffac3fc9faa224154d8c9723d6b1b54 \ No newline at end of file
diff --git a/test/data/perf_sample_sc.pb.sha256 b/test/data/perf_sample_sc.pb.sha256
new file mode 100644
index 000000000..5b574ac22
--- /dev/null
+++ b/test/data/perf_sample_sc.pb.sha256
@@ -0,0 +1 @@
+aa12a4956ec01b2965209c1e4339d583e0797c8908b8fd9dacf239c027c4a769 \ No newline at end of file
diff --git a/test/data/power_rails.pb.sha256 b/test/data/power_rails.pb.sha256
new file mode 100644
index 000000000..fe4a7a02a
--- /dev/null
+++ b/test/data/power_rails.pb.sha256
@@ -0,0 +1 @@
+a2eabaafee37c407129451f0074c98ee98537b5ccdc485ebcebc98e1848c071a \ No newline at end of file
diff --git a/test/data/process_stats_poll.pb.sha256 b/test/data/process_stats_poll.pb.sha256
new file mode 100644
index 000000000..6586df9d3
--- /dev/null
+++ b/test/data/process_stats_poll.pb.sha256
@@ -0,0 +1 @@
+1e19595eb79493ff9b06ab3411adb082a507ddd55ed1e9dcee776d68b42242c5 \ No newline at end of file
diff --git a/test/data/sched_switch_compact.pb.sha256 b/test/data/sched_switch_compact.pb.sha256
new file mode 100644
index 000000000..ff665b5e4
--- /dev/null
+++ b/test/data/sched_switch_compact.pb.sha256
@@ -0,0 +1 @@
+ff9077ba16b689405b8a3678c7ce9129a91700a079a1d98f356cf0439e3b9931 \ No newline at end of file
diff --git a/test/data/sched_switch_original.pb.sha256 b/test/data/sched_switch_original.pb.sha256
new file mode 100644
index 000000000..fea71e502
--- /dev/null
+++ b/test/data/sched_switch_original.pb.sha256
@@ -0,0 +1 @@
+530a58c740e3ecd8af756c2034c81664a2022981cc944d8b0224181fad2cb19a \ No newline at end of file
diff --git a/test/data/sfgate.json.sha256 b/test/data/sfgate.json.sha256
new file mode 100644
index 000000000..cdb4c4e33
--- /dev/null
+++ b/test/data/sfgate.json.sha256
@@ -0,0 +1 @@
+56fddbeea278ce21eb314206797a81ae6758a8fe1309b5064f8c64f33873410c \ No newline at end of file
diff --git a/test/data/synth_1.pb.sha256 b/test/data/synth_1.pb.sha256
new file mode 100644
index 000000000..a722f49bc
--- /dev/null
+++ b/test/data/synth_1.pb.sha256
@@ -0,0 +1 @@
+60f6625513a9d37260b08dc655e76b88333ff36012271b2565ddc0b8ec27596b \ No newline at end of file
diff --git a/test/data/sys.pb.sha256 b/test/data/sys.pb.sha256
new file mode 100644
index 000000000..7bf8df4f0
--- /dev/null
+++ b/test/data/sys.pb.sha256
@@ -0,0 +1 @@
+fe48a7e58c3a06b21079e93da0526f02de8a63b9d08e3468249eebde6967b17f \ No newline at end of file
diff --git a/test/data/system-server-heap-graph-new.pftrace.sha256 b/test/data/system-server-heap-graph-new.pftrace.sha256
new file mode 100644
index 000000000..17717a8e6
--- /dev/null
+++ b/test/data/system-server-heap-graph-new.pftrace.sha256
@@ -0,0 +1 @@
+71dd85d790034895c429272d1dc7d429f05ee6b97ce7a02c1ed06abd3a6ff849 \ No newline at end of file
diff --git a/test/data/system-server-heap-graph.pftrace.sha256 b/test/data/system-server-heap-graph.pftrace.sha256
new file mode 100644
index 000000000..a20f454b3
--- /dev/null
+++ b/test/data/system-server-heap-graph.pftrace.sha256
@@ -0,0 +1 @@
+b887171e5c1b147c832febf7424716fb8462bfd13ff240114e425fd97eb3a6e2 \ No newline at end of file
diff --git a/test/data/system-server-native-profile.sha256 b/test/data/system-server-native-profile.sha256
new file mode 100644
index 000000000..f00c691cb
--- /dev/null
+++ b/test/data/system-server-native-profile.sha256
@@ -0,0 +1 @@
+d742984b3d3f556c3d00d82ee9c53de2cd9809a5a5ec342ff83c3b0faf053afc \ No newline at end of file
diff --git a/test/data/systrace.html.sha256 b/test/data/systrace.html.sha256
new file mode 100644
index 000000000..f478e2aee
--- /dev/null
+++ b/test/data/systrace.html.sha256
@@ -0,0 +1 @@
+a87a26703e28981ad62554005a081794cfb68cc35f14149e99b4f1c41964c9c5 \ No newline at end of file
diff --git a/test/data/trace_with_descriptor.pftrace.sha256 b/test/data/trace_with_descriptor.pftrace.sha256
new file mode 100644
index 000000000..a4753589a
--- /dev/null
+++ b/test/data/trace_with_descriptor.pftrace.sha256
@@ -0,0 +1 @@
+ce3e83427ce4c55dc348daaf6553b1750bd8f874da54337458ed4bffb6a78b46 \ No newline at end of file
diff --git a/test/data/trace_with_uuid.pftrace.sha256 b/test/data/trace_with_uuid.pftrace.sha256
new file mode 100644
index 000000000..b0bce343c
--- /dev/null
+++ b/test/data/trace_with_uuid.pftrace.sha256
@@ -0,0 +1 @@
+825f5e43c09e067e68b940094044087cd25c32db1a69d30f781f912a0bf115d2 \ No newline at end of file
diff --git a/test/data/track_event_typed_args.pb.sha256 b/test/data/track_event_typed_args.pb.sha256
new file mode 100644
index 000000000..fdc1075bf
--- /dev/null
+++ b/test/data/track_event_typed_args.pb.sha256
@@ -0,0 +1 @@
+cd5c861185ff6cb14d080f07c2d92b137c985df6aa515850e8acf761b044a84f \ No newline at end of file
diff --git a/test/data/trailing_empty.systrace.sha256 b/test/data/trailing_empty.systrace.sha256
new file mode 100644
index 000000000..0025d9c96
--- /dev/null
+++ b/test/data/trailing_empty.systrace.sha256
@@ -0,0 +1 @@
+8921b2433ecfa8c95f2e43074a5b9318b58bfd88a53fb407baa8952a60c6b0c4 \ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-android_trace_30s_expand_camera.png.sha256 b/test/data/ui-screenshots/ui-android_trace_30s_expand_camera.png.sha256
new file mode 100644
index 000000000..0d2eafa77
--- /dev/null
+++ b/test/data/ui-screenshots/ui-android_trace_30s_expand_camera.png.sha256
@@ -0,0 +1 @@
+7be9a9c82f04d1322c9e4e7b4ce75dc688152ca72af2391a0292749673ce8c1f \ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-android_trace_30s_load.png.sha256 b/test/data/ui-screenshots/ui-android_trace_30s_load.png.sha256
new file mode 100644
index 000000000..2e9be1cd9
--- /dev/null
+++ b/test/data/ui-screenshots/ui-android_trace_30s_load.png.sha256
@@ -0,0 +1 @@
+69c67284528cb436f7fc541748db2c3e3118f77bed1803447cbb8158686daed9 \ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-android_trace_30s_search.png.sha256 b/test/data/ui-screenshots/ui-android_trace_30s_search.png.sha256
new file mode 100644
index 000000000..fae0e8f2e
--- /dev/null
+++ b/test/data/ui-screenshots/ui-android_trace_30s_search.png.sha256
@@ -0,0 +1 @@
+540bf6e6be871ea65a77e6823e5a2f1c33b190fa86220749a487a3e96e08c21a \ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-chrome_rendering_desktop_expand_browser_proc.png.sha256 b/test/data/ui-screenshots/ui-chrome_rendering_desktop_expand_browser_proc.png.sha256
new file mode 100644
index 000000000..729dfb4ff
--- /dev/null
+++ b/test/data/ui-screenshots/ui-chrome_rendering_desktop_expand_browser_proc.png.sha256
@@ -0,0 +1 @@
+6699299b62ee4632f851f555703c94b541de0fb9a2792262bd428c49ec3a321c \ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-chrome_rendering_desktop_load.png.sha256 b/test/data/ui-screenshots/ui-chrome_rendering_desktop_load.png.sha256
new file mode 100644
index 000000000..ff18513e2
--- /dev/null
+++ b/test/data/ui-screenshots/ui-chrome_rendering_desktop_load.png.sha256
@@ -0,0 +1 @@
+81f1b695b54b2c732c45f86fada461e9b2875afa078e5d466467d87fc9c38eef \ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256 b/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256
new file mode 100644
index 000000000..9ed6aa2d3
--- /dev/null
+++ b/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256
@@ -0,0 +1 @@
+404f4b826297b80b5d4c67c3326bf7b044b297114247d912114efae308f99370 \ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_navigate_navigate_back_and_forward.png.sha256 b/test/data/ui-screenshots/ui-routing_navigate_navigate_back_and_forward.png.sha256
new file mode 100644
index 000000000..035f3354e
--- /dev/null
+++ b/test/data/ui-screenshots/ui-routing_navigate_navigate_back_and_forward.png.sha256
@@ -0,0 +1 @@
+e8ffe0046ea98d27b4216c8d1ff64c665392c90ab3d90e2db99069ae54d12707 \ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_navigate_open_trace_from_url.png.sha256 b/test/data/ui-screenshots/ui-routing_navigate_open_trace_from_url.png.sha256
new file mode 100644
index 000000000..fb700b470
--- /dev/null
+++ b/test/data/ui-screenshots/ui-routing_navigate_open_trace_from_url.png.sha256
@@ -0,0 +1 @@
+2eac58fab6a51f857da3515e92f6c3f521144715cc810f9e2d1a353b29290049 \ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_open_invalid_trace_from_blank_page.png.sha256 b/test/data/ui-screenshots/ui-routing_open_invalid_trace_from_blank_page.png.sha256
new file mode 100644
index 000000000..d7c7cb9dc
--- /dev/null
+++ b/test/data/ui-screenshots/ui-routing_open_invalid_trace_from_blank_page.png.sha256
@@ -0,0 +1 @@
+14e436dda252119dbe75bbe7233e8b62ade69e27bbad311181927c097adb86d0 \ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_open_trace_and_go_back_to_landing_page.png.sha256 b/test/data/ui-screenshots/ui-routing_open_trace_and_go_back_to_landing_page.png.sha256
new file mode 100644
index 000000000..59c64e132
--- /dev/null
+++ b/test/data/ui-screenshots/ui-routing_open_trace_and_go_back_to_landing_page.png.sha256
@@ -0,0 +1 @@
+f4bbc923b067b63b28b63798ed9d05894f433a8ad77bab2461c2fdc44f4495f7 \ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_access_subpage_then_go_back.png.sha256 b/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_access_subpage_then_go_back.png.sha256
new file mode 100644
index 000000000..01f95acf1
--- /dev/null
+++ b/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_access_subpage_then_go_back.png.sha256
@@ -0,0 +1 @@
+c527929e9f4f3f67383c42ebcda6ec4753e16f0fa066373b2c9a8063e6a124ee \ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_first_trace_from_url.png.sha256 b/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_first_trace_from_url.png.sha256
new file mode 100644
index 000000000..fb700b470
--- /dev/null
+++ b/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_first_trace_from_url.png.sha256
@@ -0,0 +1 @@
+2eac58fab6a51f857da3515e92f6c3f521144715cc810f9e2d1a353b29290049 \ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_second_trace_from_url.png.sha256 b/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_second_trace_from_url.png.sha256
new file mode 100644
index 000000000..93296f6f9
--- /dev/null
+++ b/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_second_trace_from_url.png.sha256
@@ -0,0 +1 @@
+368037a9a264bd2e0579398527b42783b081929628b1241c53d51160beb508d7 \ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_trace_from_url.png.sha256 b/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_trace_from_url.png.sha256
new file mode 100644
index 000000000..c2bdfba95
--- /dev/null
+++ b/test/data/ui-screenshots/ui-routing_open_two_traces_then_go_back_open_trace_from_url.png.sha256
@@ -0,0 +1 @@
+1394a4ff204fada30758050221f4c201857e201178131e0f7741a62492d48814 \ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_start_from_no_trace_go_back_to_first_trace.png.sha256 b/test/data/ui-screenshots/ui-routing_start_from_no_trace_go_back_to_first_trace.png.sha256
new file mode 100644
index 000000000..8d6577da6
--- /dev/null
+++ b/test/data/ui-screenshots/ui-routing_start_from_no_trace_go_back_to_first_trace.png.sha256
@@ -0,0 +1 @@
+c61204c99bb136619127627df5822444ebb6679aa48a20375d31e5114e4e177b \ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_start_from_no_trace_go_to_page_with_no_trace.png.sha256 b/test/data/ui-screenshots/ui-routing_start_from_no_trace_go_to_page_with_no_trace.png.sha256
new file mode 100644
index 000000000..550a84534
--- /dev/null
+++ b/test/data/ui-screenshots/ui-routing_start_from_no_trace_go_to_page_with_no_trace.png.sha256
@@ -0,0 +1 @@
+c7a964e1a72e3abdcea0a32e22701cf72043a1a1a5a2635d2de06e07137875a1 \ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_invalid_trace.png.sha256 b/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_invalid_trace.png.sha256
new file mode 100644
index 000000000..b5f3a525c
--- /dev/null
+++ b/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_invalid_trace.png.sha256
@@ -0,0 +1 @@
+77ead2d35348d988d3938b88fc66f0731f494fb77f2165d3fbddca7f37df97f6 \ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_second_trace.png.sha256 b/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_second_trace.png.sha256
new file mode 100644
index 000000000..e5cdaef66
--- /dev/null
+++ b/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_second_trace.png.sha256
@@ -0,0 +1 @@
+3182fadb2c6f0e1354064d603e268a3f63edb2a7244c78af5da0c956fc21c562 \ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_trace_.png.sha256 b/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_trace_.png.sha256
new file mode 100644
index 000000000..01f95acf1
--- /dev/null
+++ b/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_trace_.png.sha256
@@ -0,0 +1 @@
+c527929e9f4f3f67383c42ebcda6ec4753e16f0fa066373b2c9a8063e6a124ee \ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_start_from_no_trace_refresh.png.sha256 b/test/data/ui-screenshots/ui-routing_start_from_no_trace_refresh.png.sha256
new file mode 100644
index 000000000..01f95acf1
--- /dev/null
+++ b/test/data/ui-screenshots/ui-routing_start_from_no_trace_refresh.png.sha256
@@ -0,0 +1 @@
+c527929e9f4f3f67383c42ebcda6ec4753e16f0fa066373b2c9a8063e6a124ee \ No newline at end of file
diff --git a/test/data/unsorted_trace.json.sha256 b/test/data/unsorted_trace.json.sha256
new file mode 100644
index 000000000..14c96d19e
--- /dev/null
+++ b/test/data/unsorted_trace.json.sha256
@@ -0,0 +1 @@
+360b23ca6419ef1ce27de35b9e46fc4202db30f5093596e2dca841e547d13ccd \ No newline at end of file
diff --git a/test/end_to_end_integrationtest.cc b/test/end_to_end_integrationtest.cc
deleted file mode 100644
index fe4b4379f..000000000
--- a/test/end_to_end_integrationtest.cc
+++ /dev/null
@@ -1,1677 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <unistd.h>
-
-#include <chrono>
-#include <functional>
-#include <initializer_list>
-#include <random>
-#include <thread>
-
-#include "perfetto/base/build_config.h"
-#include "perfetto/base/logging.h"
-#include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/pipe.h"
-#include "perfetto/ext/base/scoped_file.h"
-#include "perfetto/ext/base/string_utils.h"
-#include "perfetto/ext/base/subprocess.h"
-#include "perfetto/ext/base/temp_file.h"
-#include "perfetto/ext/ipc/basic_types.h"
-#include "perfetto/ext/traced/traced.h"
-#include "perfetto/ext/tracing/core/commit_data_request.h"
-#include "perfetto/ext/tracing/core/trace_packet.h"
-#include "perfetto/ext/tracing/core/tracing_service.h"
-#include "perfetto/ext/tracing/ipc/default_socket.h"
-#include "perfetto/protozero/scattered_heap_buffer.h"
-#include "perfetto/tracing/core/tracing_service_state.h"
-#include "src/base/test/test_task_runner.h"
-#include "src/base/test/utils.h"
-#include "src/traced/probes/ftrace/ftrace_controller.h"
-#include "src/traced/probes/ftrace/ftrace_procfs.h"
-#include "test/gtest_and_gmock.h"
-#include "test/test_helper.h"
-
-#include "protos/perfetto/config/power/android_power_config.pbzero.h"
-#include "protos/perfetto/config/test_config.gen.h"
-#include "protos/perfetto/config/trace_config.gen.h"
-#include "protos/perfetto/trace/ftrace/ftrace.gen.h"
-#include "protos/perfetto/trace/ftrace/ftrace_event.gen.h"
-#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.gen.h"
-#include "protos/perfetto/trace/ftrace/ftrace_stats.gen.h"
-#include "protos/perfetto/trace/perfetto/tracing_service_event.gen.h"
-#include "protos/perfetto/trace/power/battery_counters.gen.h"
-#include "protos/perfetto/trace/test_event.gen.h"
-#include "protos/perfetto/trace/trace.gen.h"
-#include "protos/perfetto/trace/trace_packet.gen.h"
-#include "protos/perfetto/trace/trace_packet.pbzero.h"
-#include "protos/perfetto/trace/trigger.gen.h"
-
-#include "protos/perfetto/common/sys_stats_counters.gen.h"
-#include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
-#include "protos/perfetto/trace/sys_stats/sys_stats.gen.h"
-
-#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
-#include "test/android_test_utils.h"
-#endif
-
-namespace perfetto {
-
-namespace {
-
-using ::testing::ContainsRegex;
-using ::testing::ElementsAreArray;
-using ::testing::HasSubstr;
-
-std::string RandomTraceFileName() {
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
- constexpr char kSysTmpPath[] = "/data/misc/perfetto-traces";
-#else
- constexpr char kSysTmpPath[] = "/tmp";
-#endif
- static int suffix = 0;
-
- std::string path;
- path.assign(kSysTmpPath);
- path.append("/trace-");
- path.append(std::to_string(base::GetBootTimeNs().count()));
- path.append("-");
- path.append(std::to_string(suffix++));
- return path;
-}
-
-// This class is a reference to a child process that has in essence been execv
-// to the requested binary. The process will start and then wait for Run()
-// before proceeding. We use this to fork new processes before starting any
-// additional threads in the parent process (otherwise you would risk
-// deadlocks), but pause the forked processes until remaining setup (including
-// any necessary threads) in the parent process is complete.
-class Exec {
- public:
- // Starts the forked process that was created. If not null then |stderr_out|
- // will contain the stderr of the process.
- int Run(std::string* stderr_out = nullptr) {
- // We can't be the child process.
- PERFETTO_CHECK(getpid() != subprocess_.pid());
- // Will cause the entrypoint to continue.
- PERFETTO_CHECK(write(*sync_pipe_.wr, "1", 1) == 1);
- sync_pipe_.wr.reset();
- subprocess_.Wait();
-
- if (stderr_out) {
- *stderr_out = std::move(subprocess_.output());
- } else {
- PERFETTO_LOG("Child proc %d exited with stderr: \"%s\"",
- subprocess_.pid(), subprocess_.output().c_str());
- }
- return subprocess_.returncode();
- }
-
- Exec(const std::string& argv0,
- std::initializer_list<std::string> args,
- std::string input = "") {
- subprocess_.args.stderr_mode = base::Subprocess::kBuffer;
- subprocess_.args.stdout_mode = base::Subprocess::kDevNull;
- subprocess_.args.input = input;
-
-#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
- constexpr bool kUseSystemBinaries = false;
-#else
- constexpr bool kUseSystemBinaries = true;
-#endif
-
- std::vector<std::string>& cmd = subprocess_.args.exec_cmd;
- if (kUseSystemBinaries) {
- PERFETTO_CHECK(TestHelper::kDefaultMode ==
- TestHelper::Mode::kUseSystemService);
- cmd.push_back("/system/bin/" + argv0);
- cmd.insert(cmd.end(), args.begin(), args.end());
- } else {
- PERFETTO_CHECK(TestHelper::kDefaultMode ==
- TestHelper::Mode::kStartDaemons);
- subprocess_.args.env.push_back(
- std::string("PERFETTO_PRODUCER_SOCK_NAME=") +
- TestHelper::GetDefaultModeProducerSocketName());
- subprocess_.args.env.push_back(
- std::string("PERFETTO_CONSUMER_SOCK_NAME=") +
- TestHelper::GetDefaultModeConsumerSocketName());
- cmd.push_back(base::GetCurExecutableDir() + "/" + argv0);
- cmd.insert(cmd.end(), args.begin(), args.end());
- }
-
- if (!base::FileExists(cmd[0])) {
- PERFETTO_FATAL(
- "Cannot find %s. Make sure that the target has been built and, on "
- "Android, pushed to the device.",
- cmd[0].c_str());
- }
-
- // This pipe blocks the execution of the child process until the main test
- // process calls Run(). There are two conflicting problems here:
- // 1) We can't fork() subprocesses too late, because the test spawns threads
- // for hosting the service. fork+threads = bad (see aosp/1089744).
- // 2) We can't run the subprocess too early, because we need to wait that
- // the service threads are ready before trying to connect from the child
- // process.
- sync_pipe_ = base::Pipe::Create();
- int sync_pipe_rd = *sync_pipe_.rd;
- subprocess_.args.preserve_fds.push_back(sync_pipe_rd);
-
- // This lambda will be called on the forked child process after having
- // setup pipe redirection and closed all FDs, right before the exec().
- // The Subprocesss harness will take care of closing also |sync_pipe_.wr|.
- subprocess_.args.posix_entrypoint_for_testing = [sync_pipe_rd] {
- // Don't add any logging here, all file descriptors are closed and trying
- // to log will likely cause undefined behaviors.
- char ignored = 0;
- PERFETTO_CHECK(PERFETTO_EINTR(read(sync_pipe_rd, &ignored, 1)) > 0);
- PERFETTO_CHECK(close(sync_pipe_rd) == 0 || errno == EINTR);
- };
-
- subprocess_.Start();
- sync_pipe_.rd.reset();
- }
-
- private:
- base::Subprocess subprocess_;
- base::Pipe sync_pipe_;
-};
-
-class PerfettoTest : public ::testing::Test {
- public:
- void SetUp() override {
- ftrace_procfs_ = FtraceProcfs::CreateGuessingMountPoint();
- }
-
- std::unique_ptr<FtraceProcfs> ftrace_procfs_;
-};
-
-class PerfettoCmdlineTest : public ::testing::Test {
- public:
- void SetUp() override { exec_allowed_ = true; }
-
- void TearDown() override {}
-
- void StartServiceIfRequiredNoNewExecsAfterThis() {
- exec_allowed_ = false;
- test_helper_.StartServiceIfRequired();
- }
-
- FakeProducer* ConnectFakeProducer() {
- return test_helper_.ConnectFakeProducer();
- }
-
- std::function<void()> WrapTask(const std::function<void()>& function) {
- return test_helper_.WrapTask(function);
- }
-
- void WaitForProducerSetup() { test_helper_.WaitForProducerSetup(); }
-
- void WaitForProducerEnabled() { test_helper_.WaitForProducerEnabled(); }
-
- // Creates a process that represents the perfetto binary that will
- // start when Run() is called. |args| will be passed as part of
- // the command line and |std_in| will be piped into std::cin.
- Exec ExecPerfetto(std::initializer_list<std::string> args,
- std::string std_in = "") {
- // You can not fork after you've started the service due to risk of
- // deadlocks.
- PERFETTO_CHECK(exec_allowed_);
- return Exec("perfetto", std::move(args), std::move(std_in));
- }
-
- // Creates a process that represents the trigger_perfetto binary that will
- // start when Run() is called. |args| will be passed as part of
- // the command line and |std_in| will be piped into std::cin.
- Exec ExecTrigger(std::initializer_list<std::string> args,
- std::string std_in = "") {
- // You can not fork after you've started the service due to risk of
- // deadlocks.
- PERFETTO_CHECK(exec_allowed_);
- return Exec("trigger_perfetto", std::move(args), std::move(std_in));
- }
-
- // Tests are allowed to freely use these variables.
- std::string stderr_;
- base::TestTaskRunner task_runner_;
-
- private:
- bool exec_allowed_;
- TestHelper test_helper_{&task_runner_};
-};
-
-// For the SaveForBugreport* tests.
-void SetTraceConfigForBugreportTest(TraceConfig* trace_config) {
- trace_config->add_buffers()->set_size_kb(4096);
- trace_config->set_duration_ms(60000); // Will never hit this.
- trace_config->set_bugreport_score(10);
- auto* ds_config = trace_config->add_data_sources()->mutable_config();
- ds_config->set_name("android.perfetto.FakeProducer");
- ds_config->mutable_for_testing()->set_message_count(3);
- ds_config->mutable_for_testing()->set_message_size(10);
- ds_config->mutable_for_testing()->set_send_batch_on_register(true);
-}
-
-// For the SaveForBugreport* tests.
-static void VerifyBugreportTraceContents() {
- // Read the trace written in the fixed location (/data/misc/perfetto-traces/
- // on Android, /tmp/ on Linux/Mac) and make sure it has the right contents.
- std::string trace_str;
- base::ReadFile(GetBugreportPath(), &trace_str);
- ASSERT_FALSE(trace_str.empty());
- protos::gen::Trace trace;
- ASSERT_TRUE(trace.ParseFromString(trace_str));
- int test_packets = 0;
- for (const auto& p : trace.packet())
- test_packets += p.has_for_testing() ? 1 : 0;
- ASSERT_EQ(test_packets, 3);
-}
-
-} // namespace
-
-// If we're building on Android and starting the daemons ourselves,
-// create the sockets in a world-writable location.
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
- PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
-#define TEST_PRODUCER_SOCK_NAME "/data/local/tmp/traced_producer"
-#else
-#define TEST_PRODUCER_SOCK_NAME ::perfetto::GetProducerSocket()
-#endif
-
-#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
-#define TreeHuggerOnly(x) x
-#else
-#define TreeHuggerOnly(x) DISABLED_##x
-#endif
-
-// TODO(b/73453011): reenable on more platforms (including standalone Android).
-TEST_F(PerfettoTest, TreeHuggerOnly(TestFtraceProducer)) {
- base::TestTaskRunner task_runner;
-
- TestHelper helper(&task_runner);
- helper.StartServiceIfRequired();
-
-#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
- ProbesProducerThread probes(TEST_PRODUCER_SOCK_NAME);
- probes.Connect();
-#endif
-
- helper.ConnectConsumer();
- helper.WaitForConsumerConnect();
-
- TraceConfig trace_config;
- trace_config.add_buffers()->set_size_kb(64);
- trace_config.set_duration_ms(3000);
-
- auto* ds_config = trace_config.add_data_sources()->mutable_config();
- ds_config->set_name("linux.ftrace");
- ds_config->set_target_buffer(0);
-
- protos::gen::FtraceConfig ftrace_config;
- ftrace_config.add_ftrace_events("sched_switch");
- ftrace_config.add_ftrace_events("bar");
- ds_config->set_ftrace_config_raw(ftrace_config.SerializeAsString());
-
- helper.StartTracing(trace_config);
- helper.WaitForTracingDisabled();
-
- helper.ReadData();
- helper.WaitForReadData();
-
- const auto& packets = helper.trace();
- ASSERT_GT(packets.size(), 0u);
-
- for (const auto& packet : packets) {
- for (int ev = 0; ev < packet.ftrace_events().event_size(); ev++) {
- ASSERT_TRUE(packet.ftrace_events()
- .event()[static_cast<size_t>(ev)]
- .has_sched_switch());
- }
- }
-}
-
-// TODO(b/73453011): reenable on more platforms (including standalone Android).
-TEST_F(PerfettoTest, TreeHuggerOnly(TestFtraceFlush)) {
- base::TestTaskRunner task_runner;
-
- TestHelper helper(&task_runner);
- helper.StartServiceIfRequired();
-
-#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
- ProbesProducerThread probes(TEST_PRODUCER_SOCK_NAME);
- probes.Connect();
-#endif
-
- helper.ConnectConsumer();
- helper.WaitForConsumerConnect();
-
- const uint32_t kTestTimeoutMs = 30000;
- TraceConfig trace_config;
- trace_config.add_buffers()->set_size_kb(32);
- trace_config.set_duration_ms(kTestTimeoutMs);
-
- auto* ds_config = trace_config.add_data_sources()->mutable_config();
- ds_config->set_name("linux.ftrace");
-
- protos::gen::FtraceConfig ftrace_config;
- ftrace_config.add_ftrace_events("print");
- ds_config->set_ftrace_config_raw(ftrace_config.SerializeAsString());
-
- helper.StartTracing(trace_config);
-
- // Do a first flush just to synchronize with the producer. The problem here
- // is that, on a Linux workstation, the producer can take several seconds just
- // to get to the point where ftrace is ready. We use the flush ack as a
- // synchronization point.
- helper.FlushAndWait(kTestTimeoutMs);
-
- EXPECT_TRUE(ftrace_procfs_->IsTracingEnabled());
- const char kMarker[] = "just_one_event";
- EXPECT_TRUE(ftrace_procfs_->WriteTraceMarker(kMarker));
-
- // This is the real flush we are testing.
- helper.FlushAndWait(kTestTimeoutMs);
-
- helper.DisableTracing();
- helper.WaitForTracingDisabled(kTestTimeoutMs);
-
- helper.ReadData();
- helper.WaitForReadData();
-
- int marker_found = 0;
- for (const auto& packet : helper.trace()) {
- for (int i = 0; i < packet.ftrace_events().event_size(); i++) {
- const auto& ev = packet.ftrace_events().event()[static_cast<size_t>(i)];
- if (ev.has_print() && ev.print().buf().find(kMarker) != std::string::npos)
- marker_found++;
- }
- }
- ASSERT_EQ(marker_found, 1);
-}
-
-TEST_F(PerfettoTest, TreeHuggerOnly(TestKmemActivity)) {
- using C = protos::gen::VmstatCounters;
-
- base::TestTaskRunner task_runner;
-
- TestHelper helper(&task_runner);
-
- // Create kmem_activity trigger proc before starting service
- auto kmem_activity_trigger_proc = Exec("trigger_perfetto", {"kmem_activity"});
-
- helper.StartServiceIfRequired();
-
-#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
- ProbesProducerThread probes(TEST_PRODUCER_SOCK_NAME);
- probes.Connect();
-#endif
-
- helper.ConnectConsumer();
- helper.WaitForConsumerConnect();
-
- TraceConfig trace_config;
- trace_config.add_buffers()->set_size_kb(1024);
- trace_config.set_unique_session_name("kmem_activity_test");
-
- auto* ftrace_ds_config = trace_config.add_data_sources()->mutable_config();
- ftrace_ds_config->set_name("linux.ftrace");
- protos::gen::FtraceConfig ftrace_config = CreateFtraceConfig({
- "vmscan/mm_vmscan_kswapd_wake",
- "vmscan/mm_vmscan_kswapd_sleep",
- "vmscan/mm_vmscan_direct_reclaim_begin",
- "vmscan/mm_vmscan_direct_reclaim_end",
- "compaction/mm_compaction_begin",
- "compaction/mm_compaction_end",
- });
- ftrace_ds_config->set_ftrace_config_raw(ftrace_config.SerializeAsString());
-
- auto* sys_stats_ds_config = trace_config.add_data_sources()->mutable_config();
- sys_stats_ds_config->set_name("linux.sys_stats");
- protos::gen::SysStatsConfig sys_stats_config;
- sys_stats_config.set_vmstat_period_ms(50);
- std::vector<C> vmstat_counters = {
- C::VMSTAT_NR_FREE_PAGES,
- C::VMSTAT_NR_SLAB_RECLAIMABLE,
- C::VMSTAT_NR_SLAB_UNRECLAIMABLE,
- C::VMSTAT_NR_ACTIVE_FILE,
- C::VMSTAT_NR_INACTIVE_FILE,
- C::VMSTAT_NR_ACTIVE_ANON,
- C::VMSTAT_NR_INACTIVE_ANON,
- C::VMSTAT_WORKINGSET_REFAULT,
- C::VMSTAT_WORKINGSET_ACTIVATE,
- C::VMSTAT_NR_FILE_PAGES,
- C::VMSTAT_PGPGIN,
- C::VMSTAT_PGPGOUT,
- C::VMSTAT_PSWPIN,
- C::VMSTAT_PSWPOUT,
- C::VMSTAT_PGSTEAL_KSWAPD_DMA,
- C::VMSTAT_PGSTEAL_KSWAPD_NORMAL,
- C::VMSTAT_PGSTEAL_KSWAPD_MOVABLE,
- C::VMSTAT_PGSTEAL_DIRECT_DMA,
- C::VMSTAT_PGSTEAL_DIRECT_NORMAL,
- C::VMSTAT_PGSTEAL_DIRECT_MOVABLE,
- C::VMSTAT_PGSCAN_KSWAPD_DMA,
- C::VMSTAT_PGSCAN_KSWAPD_NORMAL,
- C::VMSTAT_PGSCAN_KSWAPD_MOVABLE,
- C::VMSTAT_PGSCAN_DIRECT_DMA,
- C::VMSTAT_PGSCAN_DIRECT_NORMAL,
- C::VMSTAT_PGSCAN_DIRECT_MOVABLE,
- C::VMSTAT_COMPACT_MIGRATE_SCANNED,
- C::VMSTAT_COMPACT_FREE_SCANNED,
- };
- for (const auto& counter : vmstat_counters) {
- sys_stats_config.add_vmstat_counters(counter);
- }
- sys_stats_ds_config->set_sys_stats_config_raw(
- sys_stats_config.SerializeAsString());
-
- auto* trigger_cfg = trace_config.mutable_trigger_config();
- trigger_cfg->set_trigger_mode(
- protos::gen::TraceConfig::TriggerConfig::START_TRACING);
- trigger_cfg->set_trigger_timeout_ms(15000);
- auto* trigger = trigger_cfg->add_triggers();
- trigger->set_name("kmem_activity");
- // |stop_delay_ms| must be long enough that we can write the packets in
- // before the trace finishes.
- trigger->set_stop_delay_ms(1000);
-
- helper.StartTracing(trace_config);
-
- // Generating synthetic memory pressure to trigger kmem activity is
- // inherently flaky on different devices. The same goes for writing
- // /proc/sys/vm/compact_memory to trigger compaction, since compaction is
- // only started if needed (even if explicitly triggered from proc).
- // Trigger kmem activity using perfetto trigger.
- std::string stderr_str;
- EXPECT_EQ(0, kmem_activity_trigger_proc.Run(&stderr_str)) << stderr_str;
-
- helper.WaitForTracingDisabled();
-
- helper.ReadData();
- helper.WaitForReadData();
-
- const auto& packets = helper.trace();
- ASSERT_GT(packets.size(), 0u);
-
- bool sys_stats_captured = false;
- for (const auto& packet : packets) {
- for (int ev = 0; ev < packet.ftrace_events().event_size(); ev++) {
- auto ftrace_event =
- packet.ftrace_events().event()[static_cast<size_t>(ev)];
- ASSERT_TRUE(ftrace_event.has_mm_vmscan_kswapd_wake() ||
- ftrace_event.has_mm_vmscan_kswapd_sleep() ||
- ftrace_event.has_mm_vmscan_direct_reclaim_begin() ||
- ftrace_event.has_mm_vmscan_direct_reclaim_end() ||
- ftrace_event.has_mm_compaction_begin() ||
- ftrace_event.has_mm_compaction_end());
- }
-
- if (packet.has_sys_stats()) {
- sys_stats_captured = true;
- const auto& sys_stats = packet.sys_stats();
- const auto& vmstat = sys_stats.vmstat();
- ASSERT_GT(vmstat.size(), 0u);
- for (const auto& vmstat_value : vmstat) {
- ASSERT_NE(std::find(vmstat_counters.begin(), vmstat_counters.end(),
- vmstat_value.key()),
- vmstat_counters.end());
- }
- }
- }
-
- // Don't explicitly check that ftrace events were captured, since this test
- // doesn't rely on memory pressure.
- ASSERT_TRUE(sys_stats_captured);
-}
-
-// Disable this test:
-// 1. On cuttlefish (x86-kvm). It's too slow when running on GCE (b/171771440).
-// We cannot change the length of the production code in
-// CanReadKernelSymbolAddresses() to deal with it.
-// 2. On user (i.e. non-userdebug) builds. As that doesn't work there by design.
-// 3. On ARM builds, because they fail on our CI.
-#if (PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD) && defined(__i386__)) || \
- defined(__arm__)
-#define MAYBE_KernelAddressSymbolization DISABLED_KernelAddressSymbolization
-#else
-#define MAYBE_KernelAddressSymbolization KernelAddressSymbolization
-#endif
-TEST_F(PerfettoTest, MAYBE_KernelAddressSymbolization) {
- // On Android in-tree builds (TreeHugger): this test must always run to
- // prevent selinux / property-related regressions. However it can run only on
- // userdebug.
- // On standalone builds and Linux, this can be optionally skipped because
- // there it requires root to lower kptr_restrict.
-#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
- if (!IsDebuggableBuild())
- GTEST_SKIP();
-#else
- if (geteuid() != 0)
- GTEST_SKIP();
-#endif
-
- base::TestTaskRunner task_runner;
-
- TestHelper helper(&task_runner);
- helper.StartServiceIfRequired();
-
-#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
- ProbesProducerThread probes(TEST_PRODUCER_SOCK_NAME);
- probes.Connect();
-#endif
-
- helper.ConnectConsumer();
- helper.WaitForConsumerConnect();
-
- TraceConfig trace_config;
- trace_config.add_buffers()->set_size_kb(1024);
-
- auto* ds_config = trace_config.add_data_sources()->mutable_config();
- ds_config->set_name("linux.ftrace");
- protos::gen::FtraceConfig ftrace_cfg;
- ftrace_cfg.set_symbolize_ksyms(true);
- ftrace_cfg.set_initialize_ksyms_synchronously_for_testing(true);
- ds_config->set_ftrace_config_raw(ftrace_cfg.SerializeAsString());
-
- helper.StartTracing(trace_config);
-
- // Synchronize with the ftrace data source. The kernel symbol map is loaded
- // at this point.
- helper.FlushAndWait(kDefaultTestTimeoutMs);
- helper.DisableTracing();
- helper.WaitForTracingDisabled();
- helper.ReadData();
- helper.WaitForReadData();
-
- const auto& packets = helper.trace();
- ASSERT_GT(packets.size(), 0u);
-
- int symbols_parsed = -1;
- for (const auto& packet : packets) {
- if (!packet.has_ftrace_stats())
- continue;
- if (packet.ftrace_stats().phase() != protos::gen::FtraceStats::END_OF_TRACE)
- continue;
- symbols_parsed =
- static_cast<int>(packet.ftrace_stats().kernel_symbols_parsed());
- }
- ASSERT_GT(symbols_parsed, 100);
-}
-
-// TODO(b/73453011): reenable on more platforms (including standalone Android).
-TEST_F(PerfettoTest, TreeHuggerOnly(TestBatteryTracing)) {
- base::TestTaskRunner task_runner;
-
- TestHelper helper(&task_runner);
- helper.StartServiceIfRequired();
-
-#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
- ProbesProducerThread probes(TEST_PRODUCER_SOCK_NAME);
- probes.Connect();
-#else
- base::ignore_result(TEST_PRODUCER_SOCK_NAME);
-#endif
-
- helper.ConnectConsumer();
- helper.WaitForConsumerConnect();
-
- TraceConfig trace_config;
- trace_config.add_buffers()->set_size_kb(128);
- trace_config.set_duration_ms(3000);
-
- auto* ds_config = trace_config.add_data_sources()->mutable_config();
- ds_config->set_name("android.power");
- ds_config->set_target_buffer(0);
-
- using protos::pbzero::AndroidPowerConfig;
- protozero::HeapBuffered<AndroidPowerConfig> power_config;
- power_config->set_battery_poll_ms(250);
- power_config->add_battery_counters(
- AndroidPowerConfig::BATTERY_COUNTER_CHARGE);
- power_config->add_battery_counters(
- AndroidPowerConfig::BATTERY_COUNTER_CAPACITY_PERCENT);
- ds_config->set_android_power_config_raw(power_config.SerializeAsString());
-
- helper.StartTracing(trace_config);
- helper.WaitForTracingDisabled();
-
- helper.ReadData();
- helper.WaitForReadData();
-
- const auto& packets = helper.trace();
- ASSERT_GT(packets.size(), 0u);
-
- bool has_battery_packet = false;
- for (const auto& packet : packets) {
- if (!packet.has_battery())
- continue;
- has_battery_packet = true;
- // Unfortunately we cannot make any assertions on the charge counter.
- // On some devices it can reach negative values (b/64685329).
- EXPECT_GE(packet.battery().capacity_percent(), 0.f);
- EXPECT_LE(packet.battery().capacity_percent(), 100.f);
- }
-
- ASSERT_TRUE(has_battery_packet);
-}
-
-TEST_F(PerfettoTest, TestFakeProducer) {
- base::TestTaskRunner task_runner;
-
- TestHelper helper(&task_runner);
- helper.StartServiceIfRequired();
- helper.ConnectFakeProducer();
- helper.ConnectConsumer();
- helper.WaitForConsumerConnect();
-
- TraceConfig trace_config;
- trace_config.add_buffers()->set_size_kb(1024);
- trace_config.set_duration_ms(200);
-
- auto* ds_config = trace_config.add_data_sources()->mutable_config();
- ds_config->set_name("android.perfetto.FakeProducer");
- ds_config->set_target_buffer(0);
-
- static constexpr size_t kNumPackets = 11;
- static constexpr uint32_t kRandomSeed = 42;
- static constexpr uint32_t kMsgSize = 1024;
- ds_config->mutable_for_testing()->set_seed(kRandomSeed);
- ds_config->mutable_for_testing()->set_message_count(kNumPackets);
- ds_config->mutable_for_testing()->set_message_size(kMsgSize);
- ds_config->mutable_for_testing()->set_send_batch_on_register(true);
-
- helper.StartTracing(trace_config);
- helper.WaitForTracingDisabled();
-
- helper.ReadData();
- helper.WaitForReadData();
-
- const auto& packets = helper.trace();
- ASSERT_EQ(packets.size(), kNumPackets);
-
- std::minstd_rand0 rnd_engine(kRandomSeed);
- for (const auto& packet : packets) {
- ASSERT_TRUE(packet.has_for_testing());
- ASSERT_EQ(packet.for_testing().seq_value(), rnd_engine());
- }
-}
-
-TEST_F(PerfettoTest, VeryLargePackets) {
- base::TestTaskRunner task_runner;
-
- TestHelper helper(&task_runner);
- helper.StartServiceIfRequired();
- helper.ConnectFakeProducer();
- helper.ConnectConsumer();
- helper.WaitForConsumerConnect();
-
- TraceConfig trace_config;
- trace_config.add_buffers()->set_size_kb(4096 * 10);
- trace_config.set_duration_ms(500);
-
- auto* ds_config = trace_config.add_data_sources()->mutable_config();
- ds_config->set_name("android.perfetto.FakeProducer");
- ds_config->set_target_buffer(0);
-
- static constexpr size_t kNumPackets = 7;
- static constexpr uint32_t kRandomSeed = 42;
- static constexpr uint32_t kMsgSize = 1024 * 1024 - 42;
- ds_config->mutable_for_testing()->set_seed(kRandomSeed);
- ds_config->mutable_for_testing()->set_message_count(kNumPackets);
- ds_config->mutable_for_testing()->set_message_size(kMsgSize);
- ds_config->mutable_for_testing()->set_send_batch_on_register(true);
-
- helper.StartTracing(trace_config);
- helper.WaitForTracingDisabled();
-
- helper.ReadData();
- helper.WaitForReadData(/* read_count */ 0, /* timeout_ms */ 10000);
-
- const auto& packets = helper.trace();
- ASSERT_EQ(packets.size(), kNumPackets);
-
- std::minstd_rand0 rnd_engine(kRandomSeed);
- for (const auto& packet : packets) {
- ASSERT_TRUE(packet.has_for_testing());
- ASSERT_EQ(packet.for_testing().seq_value(), rnd_engine());
- size_t msg_size = packet.for_testing().str().size();
- ASSERT_EQ(kMsgSize, msg_size);
- for (size_t i = 0; i < msg_size; i++)
- ASSERT_EQ(i < msg_size - 1 ? '.' : 0, packet.for_testing().str()[i]);
- }
-}
-
-// This is a regression test see b/169051440 for context.
-//
-// In this test we ensure that traced will not crash if a Producer stops
-// responding or draining the socket (i.e. after we fill up the IPC buffer
-// traced doesn't block on trying to write to the IPC buffer and watchdog
-// doesn't kill it).
-TEST_F(PerfettoTest, UnresponsiveProducer) {
- base::TestTaskRunner task_runner;
-
- TestHelper helper(&task_runner);
- helper.StartServiceIfRequired();
- auto* producer = helper.ConnectFakeProducer();
- helper.ConnectConsumer();
- helper.WaitForConsumerConnect();
-
- TraceConfig trace_config;
- trace_config.add_buffers()->set_size_kb(4096 * 10);
- trace_config.set_duration_ms(100);
- trace_config.set_flush_timeout_ms(1);
- trace_config.set_data_source_stop_timeout_ms(1);
-
- auto* ds_config = trace_config.add_data_sources()->mutable_config();
- ds_config->set_name("android.perfetto.FakeProducer");
-
- static constexpr size_t kNumPackets = 1;
- static constexpr uint32_t kRandomSeed = 42;
- static constexpr uint32_t kMsgSize = 1024 * 1024 - 42;
- ds_config->mutable_for_testing()->set_seed(kRandomSeed);
- ds_config->mutable_for_testing()->set_message_count(kNumPackets);
- ds_config->mutable_for_testing()->set_message_size(kMsgSize);
- ds_config->mutable_for_testing()->set_send_batch_on_register(true);
-
- // This string is just used to make the StartDataSource IPC larger.
- ds_config->set_legacy_config(std::string(8192, '.'));
- ds_config->set_target_buffer(0);
-
- // Run one legit trace, this ensures that the producer above is
- // valid and correct and mirrors real life producers.
- helper.StartTracing(trace_config);
- helper.WaitForProducerEnabled();
- helper.WaitForTracingDisabled();
-
- helper.ReadData();
- helper.WaitForReadData(/* read_count */ 0, /* timeout_ms */ 10000);
-
- const auto& packets = helper.trace();
- ASSERT_EQ(packets.size(), 1u);
- ASSERT_TRUE(packets[0].has_for_testing());
- ASSERT_FALSE(packets[0].for_testing().str().empty());
- helper.FreeBuffers();
-
- // Switch the producer to ignoring the IPC socket. On a pixel 4 it took 13
- // traces to fill up the IPC buffer and cause traced to block (and eventually
- // watchdog to kill it).
- helper.producer_thread()->get()->RemoveFileDescriptorWatch(
- producer->unix_socket_fd());
-
- trace_config.set_duration_ms(1);
- for (uint32_t i = 0u; i < 15u; i++) {
- helper.StartTracing(trace_config, base::ScopedFile());
- helper.WaitForTracingDisabled(/* timeout_ms = */ 20000);
- helper.FreeBuffers();
- }
- // We need to readd the FileDescriptor (otherwise when the UnixSocket attempts
- // to remove it a the FakeProducer is destroyed will hit a CHECK failure.
- helper.producer_thread()->get()->AddFileDescriptorWatch(
- producer->unix_socket_fd(), []() {});
-}
-
-TEST_F(PerfettoTest, DetachAndReattach) {
- base::TestTaskRunner task_runner;
-
- TraceConfig trace_config;
- trace_config.add_buffers()->set_size_kb(1024);
- trace_config.set_duration_ms(10000); // Max timeout, session is ended before.
- auto* ds_config = trace_config.add_data_sources()->mutable_config();
- ds_config->set_name("android.perfetto.FakeProducer");
- static constexpr size_t kNumPackets = 11;
- ds_config->mutable_for_testing()->set_message_count(kNumPackets);
- ds_config->mutable_for_testing()->set_message_size(32);
-
- // Enable tracing and detach as soon as it gets started.
- TestHelper helper(&task_runner);
- helper.StartServiceIfRequired();
- auto* fake_producer = helper.ConnectFakeProducer();
- helper.ConnectConsumer();
- helper.WaitForConsumerConnect();
- helper.StartTracing(trace_config);
-
- // Detach.
- helper.DetachConsumer("key");
-
- // Write data while detached.
- helper.WaitForProducerEnabled();
- auto on_data_written = task_runner.CreateCheckpoint("data_written");
- fake_producer->ProduceEventBatch(helper.WrapTask(on_data_written));
- task_runner.RunUntilCheckpoint("data_written");
-
- // Then reattach the consumer.
- helper.ConnectConsumer();
- helper.WaitForConsumerConnect();
- helper.AttachConsumer("key");
-
- helper.DisableTracing();
- helper.WaitForTracingDisabled();
-
- helper.ReadData();
- helper.WaitForReadData();
- const auto& packets = helper.trace();
- ASSERT_EQ(packets.size(), kNumPackets);
-}
-
-// Tests that a detached trace session is automatically cleaned up if the
-// consumer doesn't re-attach before its expiration time.
-TEST_F(PerfettoTest, ReattachFailsAfterTimeout) {
- base::TestTaskRunner task_runner;
-
- TraceConfig trace_config;
- trace_config.add_buffers()->set_size_kb(1024);
- trace_config.set_duration_ms(250);
- trace_config.set_write_into_file(true);
- trace_config.set_file_write_period_ms(100000);
- auto* ds_config = trace_config.add_data_sources()->mutable_config();
- ds_config->set_name("android.perfetto.FakeProducer");
- ds_config->mutable_for_testing()->set_message_count(1);
- ds_config->mutable_for_testing()->set_message_size(32);
- ds_config->mutable_for_testing()->set_send_batch_on_register(true);
-
- // Enable tracing and detach as soon as it gets started.
- TestHelper helper(&task_runner);
- helper.StartServiceIfRequired();
- helper.ConnectFakeProducer();
- helper.ConnectConsumer();
- helper.WaitForConsumerConnect();
-
- auto pipe_pair = base::Pipe::Create();
- helper.StartTracing(trace_config, std::move(pipe_pair.wr));
-
- // Detach.
- helper.DetachConsumer("key");
-
- // Use the file EOF (write end closed) as a way to detect when the trace
- // session is ended.
- char buf[1024];
- while (PERFETTO_EINTR(read(*pipe_pair.rd, buf, sizeof(buf))) > 0) {
- }
-
- // Give some margin for the tracing service to destroy the session.
- usleep(250000);
-
- // Reconnect and find out that it's too late and the session is gone.
- helper.ConnectConsumer();
- helper.WaitForConsumerConnect();
- EXPECT_FALSE(helper.AttachConsumer("key"));
-}
-
-TEST_F(PerfettoTest, TestProducerProvidedSMB) {
- base::TestTaskRunner task_runner;
-
- TestHelper helper(&task_runner);
- helper.CreateProducerProvidedSmb();
-
- protos::gen::TestConfig test_config;
- test_config.set_seed(42);
- test_config.set_message_count(1);
- test_config.set_message_size(1024);
- test_config.set_send_batch_on_register(true);
-
- // Write a first batch before connection.
- helper.ProduceStartupEventBatch(test_config);
-
- helper.StartServiceIfRequired();
- helper.ConnectFakeProducer();
- helper.ConnectConsumer();
- helper.WaitForConsumerConnect();
-
- TraceConfig trace_config;
- trace_config.add_buffers()->set_size_kb(1024);
- trace_config.set_duration_ms(200);
-
- auto* ds_config = trace_config.add_data_sources()->mutable_config();
- ds_config->set_name("android.perfetto.FakeProducer");
- ds_config->set_target_buffer(0);
- *ds_config->mutable_for_testing() = test_config;
-
- // The data source is configured to emit another batch when it is started via
- // send_batch_on_register in the TestConfig.
- helper.StartTracing(trace_config);
- helper.WaitForTracingDisabled();
-
- EXPECT_TRUE(helper.IsShmemProvidedByProducer());
-
- helper.ReadData();
- helper.WaitForReadData();
-
- const auto& packets = helper.trace();
- // We should have produced two batches, one before the producer connected and
- // another one when the data source was started.
- ASSERT_EQ(packets.size(), 2u);
- ASSERT_TRUE(packets[0].has_for_testing());
- ASSERT_TRUE(packets[1].has_for_testing());
-}
-
-// Regression test for b/153142114.
-TEST_F(PerfettoTest, QueryServiceStateLargeResponse) {
- base::TestTaskRunner task_runner;
-
- TestHelper helper(&task_runner);
- helper.StartServiceIfRequired();
- helper.ConnectConsumer();
- helper.WaitForConsumerConnect();
-
- FakeProducer* producer = helper.ConnectFakeProducer();
-
- // Register 5 data sources with very large descriptors. Each descriptor will
- // max out the IPC message size, so that the service has no other choice
- // than chunking them.
- std::map<std::string, std::string> ds_expected;
- for (int i = 0; i < 5; i++) {
- DataSourceDescriptor dsd;
- std::string name = "big_ds_" + std::to_string(i);
- dsd.set_name(name);
- std::string descriptor(ipc::kIPCBufferSize - 64, (' ' + i) % 64);
- dsd.set_track_event_descriptor_raw(descriptor);
- ds_expected[name] = std::move(descriptor);
- producer->RegisterDataSource(dsd);
- }
-
- // Linearize the producer with the service. We need to make sure that all the
- // RegisterDataSource() calls above have been seen by the service before
- // continuing.
- helper.SyncAndWaitProducer();
-
- // Now invoke QueryServiceState() and wait for the reply. The service will
- // send 6 (1 + 5) IPCs which will be merged together in
- // producer_ipc_client_impl.cc.
- auto svc_state = helper.QueryServiceStateAndWait();
-
- ASSERT_GE(svc_state.producers().size(), 1u);
-
- std::map<std::string, std::string> ds_found;
- for (const auto& ds : svc_state.data_sources()) {
- if (!base::StartsWith(ds.ds_descriptor().name(), "big_ds_"))
- continue;
- ds_found[ds.ds_descriptor().name()] =
- ds.ds_descriptor().track_event_descriptor_raw();
- }
- EXPECT_THAT(ds_found, ElementsAreArray(ds_expected));
-}
-
-TEST_F(PerfettoTest, SaveForBugreport) {
- base::TestTaskRunner task_runner;
-
- TestHelper helper(&task_runner);
- helper.StartServiceIfRequired();
- helper.ConnectFakeProducer();
- helper.ConnectConsumer();
- helper.WaitForConsumerConnect();
-
- TraceConfig trace_config;
- SetTraceConfigForBugreportTest(&trace_config);
-
- helper.StartTracing(trace_config);
- helper.WaitForProducerEnabled();
-
- EXPECT_TRUE(helper.SaveTraceForBugreportAndWait());
- helper.WaitForTracingDisabled();
-
- VerifyBugreportTraceContents();
-
- // Now read the trace returned to the consumer via ReadBuffers. This should
- // be always empty because --save-for-bugreport takes it over and makes the
- // buffers unreadable by the consumer (by virtue of force-setting
- // write_into_file, which is incompatible with ReadBuffers()). The only
- // content should be the |seized_for_bugreport| flag.
- helper.ReadData();
- helper.WaitForReadData();
- const auto& packets = helper.full_trace();
- ASSERT_EQ(packets.size(), 1u);
- for (const auto& p : packets) {
- ASSERT_TRUE(p.has_service_event());
- ASSERT_TRUE(p.service_event().seized_for_bugreport());
- }
-}
-
-// Tests that the SaveForBugreport logic works also for traces with
-// write_into_file = true (with a passed file descriptor).
-TEST_F(PerfettoTest, SaveForBugreport_WriteIntoFile) {
- base::TestTaskRunner task_runner;
-
- TestHelper helper(&task_runner);
- helper.StartServiceIfRequired();
- helper.ConnectFakeProducer();
- helper.ConnectConsumer();
- helper.WaitForConsumerConnect();
-
- TraceConfig trace_config;
- SetTraceConfigForBugreportTest(&trace_config);
- trace_config.set_file_write_period_ms(60000); // Will never hit this.
- trace_config.set_write_into_file(true);
-
- auto pipe_pair = base::Pipe::Create();
- helper.StartTracing(trace_config, std::move(pipe_pair.wr));
- helper.WaitForProducerEnabled();
-
- EXPECT_TRUE(helper.SaveTraceForBugreportAndWait());
- helper.WaitForTracingDisabled();
-
- VerifyBugreportTraceContents();
-
- // Now read the original file descriptor passed in.
- std::string trace_bytes;
- ASSERT_TRUE(base::ReadPlatformHandle(*pipe_pair.rd, &trace_bytes));
- protos::gen::Trace trace;
- ASSERT_TRUE(trace.ParseFromString(trace_bytes));
- ASSERT_EQ(trace.packet().size(), 1u);
- for (const auto& p : trace.packet()) {
- ASSERT_TRUE(p.has_service_event());
- ASSERT_TRUE(p.service_event().seized_for_bugreport());
- }
-}
-
-// Tests that SaveTraceForBugreport() works also if the trace has triggers
-// defined and those triggers have not been hit. This is a regression test for
-// b/188008375 .
-#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
-// Disabled due to b/191940560
-#define MAYBE_SaveForBugreport_Triggers DISABLED_SaveForBugreport_Triggers
-#else
-#define MAYBE_SaveForBugreport_Triggers SaveForBugreport_Triggers
-#endif
-TEST_F(PerfettoTest, MAYBE_SaveForBugreport_Triggers) {
- base::TestTaskRunner task_runner;
-
- TestHelper helper(&task_runner);
- helper.StartServiceIfRequired();
- helper.ConnectFakeProducer();
- helper.ConnectConsumer();
- helper.WaitForConsumerConnect();
-
- TraceConfig trace_config;
- SetTraceConfigForBugreportTest(&trace_config);
- trace_config.set_duration_ms(0); // set_trigger_timeout_ms is used instead.
- auto* trigger_config = trace_config.mutable_trigger_config();
- trigger_config->set_trigger_timeout_ms(8.64e+7);
- trigger_config->set_trigger_mode(TraceConfig::TriggerConfig::STOP_TRACING);
- auto* trigger = trigger_config->add_triggers();
- trigger->set_name("trigger_name");
- trigger->set_stop_delay_ms(1);
-
- helper.StartTracing(trace_config);
- helper.WaitForProducerEnabled();
-
- EXPECT_TRUE(helper.SaveTraceForBugreportAndWait());
- helper.WaitForTracingDisabled();
-
- VerifyBugreportTraceContents();
-
- // Now read the original trace.
- helper.ReadData();
- helper.WaitForReadData();
- const auto& packets = helper.full_trace();
- ASSERT_EQ(packets.size(), 1u);
- for (const auto& p : packets) {
- ASSERT_TRUE(p.has_service_event());
- ASSERT_TRUE(p.service_event().seized_for_bugreport());
- }
-}
-
-// Disable cmdline tests on sanitizets because they use fork() and that messes
-// up leak / races detections, which has been fixed only recently (see
-// https://github.com/google/sanitizers/issues/836 ).
-#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
- defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER)
-#define NoSanitizers(X) DISABLED_##X
-#else
-#define NoSanitizers(X) X
-#endif
-
-TEST_F(PerfettoCmdlineTest, NoSanitizers(InvalidCases)) {
- std::string cfg("duration_ms: 100");
-
- auto invalid_arg = ExecPerfetto({"--invalid-arg"});
- auto empty_config = ExecPerfetto({"-c", "-", "-o", "-"}, "");
-
- // Cannot make assertions on --dropbox because on standalone builds it fails
- // prematurely due to lack of dropbox.
- auto missing_dropbox =
- ExecPerfetto({"-c", "-", "--txt", "-o", "-", "--dropbox=foo"}, cfg);
- auto either_out_or_dropbox = ExecPerfetto({"-c", "-", "--txt"}, cfg);
-
- // Disallow mixing simple and file config.
- auto simple_and_file_1 =
- ExecPerfetto({"-o", "-", "-c", "-", "-t", "2s"}, cfg);
- auto simple_and_file_2 =
- ExecPerfetto({"-o", "-", "-c", "-", "-b", "2m"}, cfg);
- auto simple_and_file_3 =
- ExecPerfetto({"-o", "-", "-c", "-", "-s", "2m"}, cfg);
-
- // Invalid --attach / --detach cases.
- auto invalid_stop =
- ExecPerfetto({"-c", "-", "--txt", "-o", "-", "--stop"}, cfg);
- auto attach_and_config_1 =
- ExecPerfetto({"-c", "-", "--txt", "-o", "-", "--attach=foo"}, cfg);
- auto attach_and_config_2 =
- ExecPerfetto({"-t", "2s", "-o", "-", "--attach=foo"}, cfg);
- auto attach_needs_argument = ExecPerfetto({"--attach"}, cfg);
- auto detach_needs_argument =
- ExecPerfetto({"-t", "2s", "-o", "-", "--detach"}, cfg);
- auto detach_without_out_or_dropbox =
- ExecPerfetto({"-t", "2s", "--detach=foo"}, cfg);
-
- // Cannot trace and use --query.
- auto trace_and_query_1 = ExecPerfetto({"-t", "2s", "--query"}, cfg);
- auto trace_and_query_2 = ExecPerfetto({"-c", "-", "--query"}, cfg);
-
- // Ensure all Exec:: calls have been saved to prevent deadlocks.
- StartServiceIfRequiredNoNewExecsAfterThis();
-
- EXPECT_EQ(1, invalid_arg.Run(&stderr_));
-
- EXPECT_EQ(1, empty_config.Run(&stderr_));
- EXPECT_THAT(stderr_, HasSubstr("TraceConfig is empty"));
-
- // Cannot make assertions on --upload because on standalone builds it fails
- // prematurely due to lack of dropbox.
- EXPECT_EQ(1, missing_dropbox.Run(&stderr_));
-
- EXPECT_EQ(1, either_out_or_dropbox.Run(&stderr_));
- EXPECT_THAT(stderr_, HasSubstr("Either --out or --upload"));
-
- // Disallow mixing simple and file config.
- EXPECT_EQ(1, simple_and_file_1.Run(&stderr_));
- EXPECT_THAT(stderr_, HasSubstr("Cannot specify both -c"));
-
- EXPECT_EQ(1, simple_and_file_2.Run(&stderr_));
- EXPECT_THAT(stderr_, HasSubstr("Cannot specify both -c"));
-
- EXPECT_EQ(1, simple_and_file_3.Run(&stderr_));
- EXPECT_THAT(stderr_, HasSubstr("Cannot specify both -c"));
-
- // Invalid --attach / --detach cases.
- EXPECT_EQ(1, invalid_stop.Run(&stderr_));
- EXPECT_THAT(stderr_, HasSubstr("--stop is supported only in combination"));
-
- EXPECT_EQ(1, attach_and_config_1.Run(&stderr_));
- EXPECT_THAT(stderr_, HasSubstr("Cannot specify a trace config"));
-
- EXPECT_EQ(1, attach_and_config_2.Run(&stderr_));
- EXPECT_THAT(stderr_, HasSubstr("Cannot specify a trace config"));
-
- EXPECT_EQ(1, attach_needs_argument.Run(&stderr_));
- EXPECT_THAT(stderr_, ContainsRegex("option.*--attach.*requires an argument"));
-
- EXPECT_EQ(1, detach_needs_argument.Run(&stderr_));
- EXPECT_THAT(stderr_, ContainsRegex("option.*--detach.*requires an argument"));
-
- EXPECT_EQ(1, detach_without_out_or_dropbox.Run(&stderr_));
- EXPECT_THAT(stderr_, HasSubstr("--out or --upload is required"));
-
- // Cannot trace and use --query.
- EXPECT_EQ(1, trace_and_query_1.Run(&stderr_));
- EXPECT_THAT(stderr_, HasSubstr("Cannot specify a trace config"));
-
- EXPECT_EQ(1, trace_and_query_2.Run(&stderr_));
- EXPECT_THAT(stderr_, HasSubstr("Cannot specify a trace config"));
-}
-
-TEST_F(PerfettoCmdlineTest, NoSanitizers(TxtConfig)) {
- std::string cfg("duration_ms: 100");
- auto perfetto = ExecPerfetto({"-c", "-", "--txt", "-o", "-"}, cfg);
- StartServiceIfRequiredNoNewExecsAfterThis();
- EXPECT_EQ(0, perfetto.Run(&stderr_)) << stderr_;
-}
-
-TEST_F(PerfettoCmdlineTest, NoSanitizers(SimpleConfig)) {
- auto perfetto = ExecPerfetto({"-o", "-", "-c", "-", "-t", "100ms"});
- StartServiceIfRequiredNoNewExecsAfterThis();
- EXPECT_EQ(0, perfetto.Run(&stderr_)) << stderr_;
-}
-
-TEST_F(PerfettoCmdlineTest, NoSanitizers(DetachAndAttach)) {
- auto attach_to_not_existing = ExecPerfetto({"--attach=not_existent"});
-
- std::string cfg("duration_ms: 10000; write_into_file: true");
- auto detach_valid_stop =
- ExecPerfetto({"-o", "-", "-c", "-", "--txt", "--detach=valid_stop"}, cfg);
- auto stop_valid_stop = ExecPerfetto({"--attach=valid_stop", "--stop"});
-
- StartServiceIfRequiredNoNewExecsAfterThis();
-
- EXPECT_NE(0, attach_to_not_existing.Run(&stderr_));
- EXPECT_THAT(stderr_, HasSubstr("Session re-attach failed"));
-
- EXPECT_EQ(0, detach_valid_stop.Run(&stderr_)) << stderr_;
- EXPECT_EQ(0, stop_valid_stop.Run(&stderr_));
-}
-
-TEST_F(PerfettoCmdlineTest, NoSanitizers(StartTracingTrigger)) {
- // See |message_count| and |message_size| in the TraceConfig above.
- constexpr size_t kMessageCount = 11;
- constexpr size_t kMessageSize = 32;
- protos::gen::TraceConfig trace_config;
- trace_config.add_buffers()->set_size_kb(1024);
- auto* ds_config = trace_config.add_data_sources()->mutable_config();
- ds_config->set_name("android.perfetto.FakeProducer");
- ds_config->mutable_for_testing()->set_message_count(kMessageCount);
- ds_config->mutable_for_testing()->set_message_size(kMessageSize);
- auto* trigger_cfg = trace_config.mutable_trigger_config();
- trigger_cfg->set_trigger_mode(
- protos::gen::TraceConfig::TriggerConfig::START_TRACING);
- trigger_cfg->set_trigger_timeout_ms(15000);
- auto* trigger = trigger_cfg->add_triggers();
- trigger->set_name("trigger_name");
- // |stop_delay_ms| must be long enough that we can write the packets in
- // before the trace finishes. This has to be long enough for the slowest
- // emulator. But as short as possible to prevent the test running a long
- // time.
- trigger->set_stop_delay_ms(500);
-
- // We have to construct all the processes we want to fork before we start the
- // service with |StartServiceIfRequired()|. this is because it is unsafe
- // (could deadlock) to fork after we've spawned some threads which might
- // printf (and thus hold locks).
- const std::string path = RandomTraceFileName();
- auto perfetto_proc = ExecPerfetto(
- {
- "-o",
- path,
- "-c",
- "-",
- },
- trace_config.SerializeAsString());
-
- auto trigger_proc = ExecTrigger({"trigger_name"});
-
- // Start the service and connect a simple fake producer.
- StartServiceIfRequiredNoNewExecsAfterThis();
-
- auto* fake_producer = ConnectFakeProducer();
- EXPECT_TRUE(fake_producer);
-
- // Start a background thread that will deliver the config now that we've
- // started the service. See |perfetto_proc| above for the args passed.
- std::thread background_trace([&perfetto_proc]() {
- std::string stderr_str;
- EXPECT_EQ(0, perfetto_proc.Run(&stderr_str)) << stderr_str;
- });
-
- WaitForProducerSetup();
- EXPECT_EQ(0, trigger_proc.Run(&stderr_));
-
- // Wait for the producer to start, and then write out 11 packets.
- WaitForProducerEnabled();
- auto on_data_written = task_runner_.CreateCheckpoint("data_written");
- fake_producer->ProduceEventBatch(WrapTask(on_data_written));
- task_runner_.RunUntilCheckpoint("data_written");
- background_trace.join();
-
- std::string trace_str;
- base::ReadFile(path, &trace_str);
- protos::gen::Trace trace;
- ASSERT_TRUE(trace.ParseFromString(trace_str));
- size_t for_testing_packets = 0;
- size_t trigger_packets = 0;
- size_t trace_config_packets = 0;
- for (const auto& packet : trace.packet()) {
- if (packet.has_trace_config()) {
- // Ensure the trace config properly includes the trigger mode we set.
- auto kStartTrig = protos::gen::TraceConfig::TriggerConfig::START_TRACING;
- EXPECT_EQ(kStartTrig,
- packet.trace_config().trigger_config().trigger_mode());
- ++trace_config_packets;
- } else if (packet.has_trigger()) {
- // validate that the triggers are properly added to the trace.
- EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
- ++trigger_packets;
- } else if (packet.has_for_testing()) {
- // Make sure that the data size is correctly set based on what we
- // requested.
- EXPECT_EQ(kMessageSize, packet.for_testing().str().size());
- ++for_testing_packets;
- }
- }
- EXPECT_EQ(trace_config_packets, 1u);
- EXPECT_EQ(trigger_packets, 1u);
- EXPECT_EQ(for_testing_packets, kMessageCount);
-}
-
-TEST_F(PerfettoCmdlineTest, NoSanitizers(StopTracingTrigger)) {
- // See |message_count| and |message_size| in the TraceConfig above.
- constexpr size_t kMessageCount = 11;
- constexpr size_t kMessageSize = 32;
- protos::gen::TraceConfig trace_config;
- trace_config.add_buffers()->set_size_kb(1024);
- auto* ds_config = trace_config.add_data_sources()->mutable_config();
- ds_config->set_name("android.perfetto.FakeProducer");
- ds_config->mutable_for_testing()->set_message_count(kMessageCount);
- ds_config->mutable_for_testing()->set_message_size(kMessageSize);
- auto* trigger_cfg = trace_config.mutable_trigger_config();
- trigger_cfg->set_trigger_mode(
- protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
- trigger_cfg->set_trigger_timeout_ms(15000);
- auto* trigger = trigger_cfg->add_triggers();
- trigger->set_name("trigger_name");
- // |stop_delay_ms| must be long enough that we can write the packets in
- // before the trace finishes. This has to be long enough for the slowest
- // emulator. But as short as possible to prevent the test running a long
- // time.
- trigger->set_stop_delay_ms(500);
- trigger = trigger_cfg->add_triggers();
- trigger->set_name("trigger_name_3");
- trigger->set_stop_delay_ms(60000);
-
- // We have to construct all the processes we want to fork before we start the
- // service with |StartServiceIfRequired()|. this is because it is unsafe
- // (could deadlock) to fork after we've spawned some threads which might
- // printf (and thus hold locks).
- const std::string path = RandomTraceFileName();
- auto perfetto_proc = ExecPerfetto(
- {
- "-o",
- path,
- "-c",
- "-",
- },
- trace_config.SerializeAsString());
-
- auto trigger_proc =
- ExecTrigger({"trigger_name_2", "trigger_name", "trigger_name_3"});
-
- // Start the service and connect a simple fake producer.
- StartServiceIfRequiredNoNewExecsAfterThis();
- auto* fake_producer = ConnectFakeProducer();
- EXPECT_TRUE(fake_producer);
-
- // Start a background thread that will deliver the config now that we've
- // started the service. See |perfetto_proc| above for the args passed.
- std::thread background_trace([&perfetto_proc]() {
- std::string stderr_str;
- EXPECT_EQ(0, perfetto_proc.Run(&stderr_str)) << stderr_str;
- });
-
- WaitForProducerEnabled();
- // Wait for the producer to start, and then write out 11 packets, before the
- // trace actually starts (the trigger is seen).
- auto on_data_written = task_runner_.CreateCheckpoint("data_written_1");
- fake_producer->ProduceEventBatch(WrapTask(on_data_written));
- task_runner_.RunUntilCheckpoint("data_written_1");
-
- EXPECT_EQ(0, trigger_proc.Run(&stderr_)) << "stderr: " << stderr_;
-
- background_trace.join();
-
- std::string trace_str;
- base::ReadFile(path, &trace_str);
- protos::gen::Trace trace;
- ASSERT_TRUE(trace.ParseFromString(trace_str));
- bool seen_first_trigger = false;
- size_t for_testing_packets = 0;
- size_t trigger_packets = 0;
- size_t trace_config_packets = 0;
- for (const auto& packet : trace.packet()) {
- if (packet.has_trace_config()) {
- // Ensure the trace config properly includes the trigger mode we set.
- auto kStopTrig = protos::gen::TraceConfig::TriggerConfig::STOP_TRACING;
- EXPECT_EQ(kStopTrig,
- packet.trace_config().trigger_config().trigger_mode());
- ++trace_config_packets;
- } else if (packet.has_trigger()) {
- // validate that the triggers are properly added to the trace.
- if (!seen_first_trigger) {
- EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
- seen_first_trigger = true;
- } else {
- EXPECT_EQ("trigger_name_3", packet.trigger().trigger_name());
- }
- ++trigger_packets;
- } else if (packet.has_for_testing()) {
- // Make sure that the data size is correctly set based on what we
- // requested.
- EXPECT_EQ(kMessageSize, packet.for_testing().str().size());
- ++for_testing_packets;
- }
- }
- EXPECT_EQ(trace_config_packets, 1u);
- EXPECT_EQ(trigger_packets, 2u);
- EXPECT_EQ(for_testing_packets, kMessageCount);
-}
-
-// Dropbox on the commandline client only works on android builds. So disable
-// this test on all other builds.
-#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
-TEST_F(PerfettoCmdlineTest, NoSanitizers(NoDataNoFileWithoutTrigger)) {
-#else
-TEST_F(PerfettoCmdlineTest, DISABLED_NoDataNoFileWithoutTrigger) {
-#endif
- // See |message_count| and |message_size| in the TraceConfig above.
- constexpr size_t kMessageCount = 11;
- constexpr size_t kMessageSize = 32;
- protos::gen::TraceConfig trace_config;
- trace_config.add_buffers()->set_size_kb(1024);
- trace_config.set_allow_user_build_tracing(true);
- auto* incident_config = trace_config.mutable_incident_report_config();
- incident_config->set_destination_package("foo.bar.baz");
- auto* ds_config = trace_config.add_data_sources()->mutable_config();
- ds_config->set_name("android.perfetto.FakeProducer");
- ds_config->mutable_for_testing()->set_message_count(kMessageCount);
- ds_config->mutable_for_testing()->set_message_size(kMessageSize);
- auto* trigger_cfg = trace_config.mutable_trigger_config();
- trigger_cfg->set_trigger_mode(
- protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
- trigger_cfg->set_trigger_timeout_ms(1000);
- auto* trigger = trigger_cfg->add_triggers();
- trigger->set_name("trigger_name");
- // |stop_delay_ms| must be long enough that we can write the packets in
- // before the trace finishes. This has to be long enough for the slowest
- // emulator. But as short as possible to prevent the test running a long
- // time.
- trigger->set_stop_delay_ms(500);
- trigger = trigger_cfg->add_triggers();
-
- // We have to construct all the processes we want to fork before we start the
- // service with |StartServiceIfRequired()|. this is because it is unsafe
- // (could deadlock) to fork after we've spawned some threads which might
- // printf (and thus hold locks).
- const std::string path = RandomTraceFileName();
- auto perfetto_proc = ExecPerfetto(
- {
- "--dropbox",
- "TAG",
- "--no-guardrails",
- "-c",
- "-",
- },
- trace_config.SerializeAsString());
-
- StartServiceIfRequiredNoNewExecsAfterThis();
- auto* fake_producer = ConnectFakeProducer();
- EXPECT_TRUE(fake_producer);
-
- std::string stderr_str;
- std::thread background_trace([&perfetto_proc, &stderr_str]() {
- EXPECT_EQ(0, perfetto_proc.Run(&stderr_str));
- });
- background_trace.join();
-
- EXPECT_THAT(stderr_str,
- ::testing::HasSubstr("Skipping write to incident. Empty trace."));
-}
-
-TEST_F(PerfettoCmdlineTest, NoSanitizers(StopTracingTriggerFromConfig)) {
- // See |message_count| and |message_size| in the TraceConfig above.
- constexpr size_t kMessageCount = 11;
- constexpr size_t kMessageSize = 32;
- protos::gen::TraceConfig trace_config;
- trace_config.add_buffers()->set_size_kb(1024);
- auto* ds_config = trace_config.add_data_sources()->mutable_config();
- ds_config->set_name("android.perfetto.FakeProducer");
- ds_config->mutable_for_testing()->set_message_count(kMessageCount);
- ds_config->mutable_for_testing()->set_message_size(kMessageSize);
- auto* trigger_cfg = trace_config.mutable_trigger_config();
- trigger_cfg->set_trigger_mode(
- protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
- trigger_cfg->set_trigger_timeout_ms(15000);
- auto* trigger = trigger_cfg->add_triggers();
- trigger->set_name("trigger_name");
- // |stop_delay_ms| must be long enough that we can write the packets in
- // before the trace finishes. This has to be long enough for the slowest
- // emulator. But as short as possible to prevent the test running a long
- // time.
- trigger->set_stop_delay_ms(500);
- trigger = trigger_cfg->add_triggers();
- trigger->set_name("trigger_name_3");
- trigger->set_stop_delay_ms(60000);
-
- // We have to construct all the processes we want to fork before we start the
- // service with |StartServiceIfRequired()|. this is because it is unsafe
- // (could deadlock) to fork after we've spawned some threads which might
- // printf (and thus hold locks).
- const std::string path = RandomTraceFileName();
- auto perfetto_proc = ExecPerfetto(
- {
- "-o",
- path,
- "-c",
- "-",
- },
- trace_config.SerializeAsString());
-
- std::string triggers = R"(
- activate_triggers: "trigger_name_2"
- activate_triggers: "trigger_name"
- activate_triggers: "trigger_name_3"
- )";
- auto perfetto_proc_2 = ExecPerfetto(
- {
- "-o",
- path,
- "-c",
- "-",
- "--txt",
- },
- triggers);
-
- // Start the service and connect a simple fake producer.
- StartServiceIfRequiredNoNewExecsAfterThis();
- auto* fake_producer = ConnectFakeProducer();
- EXPECT_TRUE(fake_producer);
-
- std::thread background_trace([&perfetto_proc]() {
- std::string stderr_str;
- EXPECT_EQ(0, perfetto_proc.Run(&stderr_str)) << stderr_str;
- });
-
- WaitForProducerEnabled();
- // Wait for the producer to start, and then write out 11 packets, before the
- // trace actually starts (the trigger is seen).
- auto on_data_written = task_runner_.CreateCheckpoint("data_written_1");
- fake_producer->ProduceEventBatch(WrapTask(on_data_written));
- task_runner_.RunUntilCheckpoint("data_written_1");
-
- EXPECT_EQ(0, perfetto_proc_2.Run(&stderr_)) << "stderr: " << stderr_;
-
- background_trace.join();
-
- std::string trace_str;
- base::ReadFile(path, &trace_str);
- protos::gen::Trace trace;
- ASSERT_TRUE(trace.ParseFromString(trace_str));
- EXPECT_LT(static_cast<int>(kMessageCount), trace.packet_size());
- bool seen_first_trigger = false;
- for (const auto& packet : trace.packet()) {
- if (packet.has_trace_config()) {
- // Ensure the trace config properly includes the trigger mode we set.
- auto kStopTrig = protos::gen::TraceConfig::TriggerConfig::STOP_TRACING;
- EXPECT_EQ(kStopTrig,
- packet.trace_config().trigger_config().trigger_mode());
- } else if (packet.has_trigger()) {
- // validate that the triggers are properly added to the trace.
- if (!seen_first_trigger) {
- EXPECT_EQ("trigger_name", packet.trigger().trigger_name());
- seen_first_trigger = true;
- } else {
- EXPECT_EQ("trigger_name_3", packet.trigger().trigger_name());
- }
- } else if (packet.has_for_testing()) {
- // Make sure that the data size is correctly set based on what we
- // requested.
- EXPECT_EQ(kMessageSize, packet.for_testing().str().size());
- }
- }
-}
-
-TEST_F(PerfettoCmdlineTest, NoSanitizers(TriggerFromConfigStopsFileOpening)) {
- // See |message_count| and |message_size| in the TraceConfig above.
- constexpr size_t kMessageCount = 11;
- constexpr size_t kMessageSize = 32;
- protos::gen::TraceConfig trace_config;
- trace_config.add_buffers()->set_size_kb(1024);
- auto* ds_config = trace_config.add_data_sources()->mutable_config();
- ds_config->set_name("android.perfetto.FakeProducer");
- ds_config->mutable_for_testing()->set_message_count(kMessageCount);
- ds_config->mutable_for_testing()->set_message_size(kMessageSize);
- auto* trigger_cfg = trace_config.mutable_trigger_config();
- trigger_cfg->set_trigger_mode(
- protos::gen::TraceConfig::TriggerConfig::STOP_TRACING);
- trigger_cfg->set_trigger_timeout_ms(15000);
- auto* trigger = trigger_cfg->add_triggers();
- trigger->set_name("trigger_name");
- // |stop_delay_ms| must be long enough that we can write the packets in
- // before the trace finishes. This has to be long enough for the slowest
- // emulator. But as short as possible to prevent the test running a long
- // time.
- trigger->set_stop_delay_ms(500);
- trigger = trigger_cfg->add_triggers();
- trigger->set_name("trigger_name_3");
- trigger->set_stop_delay_ms(60000);
-
- // We have to construct all the processes we want to fork before we start the
- // service with |StartServiceIfRequired()|. this is because it is unsafe
- // (could deadlock) to fork after we've spawned some threads which might
- // printf (and thus hold locks).
- const std::string path = RandomTraceFileName();
- std::string triggers = R"(
- activate_triggers: "trigger_name_2"
- activate_triggers: "trigger_name"
- activate_triggers: "trigger_name_3"
- )";
- auto perfetto_proc = ExecPerfetto(
- {
- "-o",
- path,
- "-c",
- "-",
- "--txt",
- },
- triggers);
-
- // Start the service and connect a simple fake producer.
- StartServiceIfRequiredNoNewExecsAfterThis();
- auto* fake_producer = ConnectFakeProducer();
- EXPECT_TRUE(fake_producer);
-
- std::string trace_str;
- EXPECT_FALSE(base::ReadFile(path, &trace_str));
-
- EXPECT_EQ(0, perfetto_proc.Run(&stderr_)) << "stderr: " << stderr_;
-
- EXPECT_FALSE(base::ReadFile(path, &trace_str));
-}
-
-TEST_F(PerfettoCmdlineTest, NoSanitizers(Query)) {
- auto query = ExecPerfetto({"--query"});
- auto query_raw = ExecPerfetto({"--query-raw"});
- StartServiceIfRequiredNoNewExecsAfterThis();
- EXPECT_EQ(0, query.Run(&stderr_)) << stderr_;
- EXPECT_EQ(0, query_raw.Run(&stderr_)) << stderr_;
-}
-
-} // namespace perfetto
diff --git a/test/fake_producer.cc b/test/fake_producer.cc
index f716c906e..90c393225 100644
--- a/test/fake_producer.cc
+++ b/test/fake_producer.cc
@@ -151,6 +151,11 @@ void FakeProducer::Sync(std::function<void()> callback) {
task_runner_->PostTask([this, callback] { endpoint_->Sync(callback); });
}
+void FakeProducer::ActivateTrigger(const std::string& trigger_name) {
+ task_runner_->PostTask(
+ [this, trigger_name] { endpoint_->ActivateTriggers({trigger_name}); });
+}
+
void FakeProducer::OnTracingSetup() {}
void FakeProducer::Flush(FlushRequestID flush_request_id,
diff --git a/test/fake_producer.h b/test/fake_producer.h
index 27cd5d3e8..59221657e 100644
--- a/test/fake_producer.h
+++ b/test/fake_producer.h
@@ -64,6 +64,7 @@ class FakeProducer : public Producer {
void RegisterDataSource(const DataSourceDescriptor&);
void CommitData(const CommitDataRequest&, std::function<void()> callback);
void Sync(std::function<void()> callback);
+ void ActivateTrigger(const std::string& trigger_name);
bool IsShmemProvidedByProducer() const {
return endpoint_->IsShmemProvidedByProducer();
diff --git a/test/ftrace_integrationtest.cc b/test/ftrace_integrationtest.cc
new file mode 100644
index 000000000..42d251fa0
--- /dev/null
+++ b/test/ftrace_integrationtest.cc
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+ PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX)
+
+#include "perfetto/base/build_config.h"
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/temp_file.h"
+#include "perfetto/ext/base/utils.h"
+#include "perfetto/ext/traced/traced.h"
+#include "perfetto/ext/tracing/core/commit_data_request.h"
+#include "perfetto/ext/tracing/core/trace_packet.h"
+#include "perfetto/ext/tracing/core/tracing_service.h"
+#include "perfetto/protozero/scattered_heap_buffer.h"
+#include "perfetto/tracing/core/tracing_service_state.h"
+#include "src/base/test/test_task_runner.h"
+#include "src/base/test/utils.h"
+#include "src/traced/probes/ftrace/ftrace_controller.h"
+#include "src/traced/probes/ftrace/ftrace_procfs.h"
+#include "test/gtest_and_gmock.h"
+#include "test/test_helper.h"
+
+#include "protos/perfetto/config/test_config.gen.h"
+#include "protos/perfetto/config/trace_config.gen.h"
+#include "protos/perfetto/trace/ftrace/ftrace.gen.h"
+#include "protos/perfetto/trace/ftrace/ftrace_event.gen.h"
+#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.gen.h"
+#include "protos/perfetto/trace/ftrace/ftrace_stats.gen.h"
+#include "protos/perfetto/trace/perfetto/tracing_service_event.gen.h"
+#include "protos/perfetto/trace/test_event.gen.h"
+#include "protos/perfetto/trace/trace.gen.h"
+#include "protos/perfetto/trace/trace_packet.gen.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+#include "test/android_test_utils.h"
+#endif
+
+namespace perfetto {
+
+namespace {
+
+using ::testing::ContainsRegex;
+using ::testing::Each;
+using ::testing::ElementsAreArray;
+using ::testing::HasSubstr;
+using ::testing::Property;
+using ::testing::SizeIs;
+using ::testing::UnorderedElementsAreArray;
+
+class PerfettoFtraceIntegrationTest : public ::testing::Test {
+ public:
+ void SetUp() override {
+ ftrace_procfs_ = FtraceProcfs::CreateGuessingMountPoint();
+
+// On android we do expect that tracefs is accessible, both in the case of
+// running as part of traced/probes system daemons and shell. On Linux this is
+// up to the system admin, don't hard fail.
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+ if (!ftrace_procfs_) {
+ PERFETTO_ELOG(
+ "Cannot acces tracefs. On Linux you need to manually run `sudo chown "
+ "-R $USER /sys/kernel/tracing` to enable these tests. Skipping");
+ GTEST_SKIP();
+ } else {
+ // Recent kernels set tracing_on=1 by default. On Android this is
+ // disabled by initrc scripts. Be tolerant on Linux where we don't have
+ // that and force disable ftrace.
+ ftrace_procfs_->SetTracingOn(false);
+ }
+#endif
+ }
+
+ std::unique_ptr<FtraceProcfs> ftrace_procfs_;
+};
+
+} // namespace
+
+TEST_F(PerfettoFtraceIntegrationTest, TestFtraceProducer) {
+ base::TestTaskRunner task_runner;
+
+ TestHelper helper(&task_runner);
+ helper.StartServiceIfRequired();
+
+#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
+ ProbesProducerThread probes(GetTestProducerSockName());
+ probes.Connect();
+#endif
+
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+
+ TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(1024);
+ trace_config.set_duration_ms(3000);
+
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("linux.ftrace");
+ ds_config->set_target_buffer(0);
+
+ protos::gen::FtraceConfig ftrace_config;
+ ftrace_config.add_ftrace_events("sched_switch");
+ ftrace_config.add_ftrace_events("bar");
+ ds_config->set_ftrace_config_raw(ftrace_config.SerializeAsString());
+
+ helper.StartTracing(trace_config);
+ helper.WaitForTracingDisabled();
+
+ helper.ReadData();
+ helper.WaitForReadData();
+
+ const auto& packets = helper.trace();
+ ASSERT_GT(packets.size(), 0u);
+
+ for (const auto& packet : packets) {
+ for (int ev = 0; ev < packet.ftrace_events().event_size(); ev++) {
+ ASSERT_TRUE(packet.ftrace_events()
+ .event()[static_cast<size_t>(ev)]
+ .has_sched_switch());
+ }
+ }
+}
+
+TEST_F(PerfettoFtraceIntegrationTest, TestFtraceFlush) {
+ base::TestTaskRunner task_runner;
+
+ TestHelper helper(&task_runner);
+ helper.StartServiceIfRequired();
+
+#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
+ ProbesProducerThread probes(GetTestProducerSockName());
+ probes.Connect();
+#endif
+
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+
+ // Wait for the traced_probes service to connect. We want to start tracing
+ // only after it connects, otherwise we'll start a tracing session with 0
+ // producers connected (which is valid but not what we want here).
+ helper.WaitForDataSourceConnected("linux.ftrace");
+
+ TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(32);
+ trace_config.set_duration_ms(kDefaultTestTimeoutMs);
+
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("linux.ftrace");
+
+ protos::gen::FtraceConfig ftrace_config;
+ ftrace_config.add_ftrace_events("print");
+ ds_config->set_ftrace_config_raw(ftrace_config.SerializeAsString());
+
+ helper.StartTracing(trace_config);
+
+ // Wait for traced_probes to start.
+ helper.WaitFor([&] { return ftrace_procfs_->IsTracingEnabled(); }, "ftrace");
+
+ // Do a first flush just to synchronize with the producer. The problem here
+ // is that, on a Linux workstation, the producer can take several seconds just
+ // to get to the point where it is fully ready. We use the flush ack as a
+ // synchronization point.
+ helper.FlushAndWait(kDefaultTestTimeoutMs);
+
+ const char kMarker[] = "just_one_event";
+ EXPECT_TRUE(ftrace_procfs_->WriteTraceMarker(kMarker));
+
+ // This is the real flush we are testing.
+ helper.FlushAndWait(kDefaultTestTimeoutMs);
+
+ helper.DisableTracing();
+ helper.WaitForTracingDisabled(kDefaultTestTimeoutMs);
+
+ helper.ReadData();
+ helper.WaitForReadData();
+
+ int marker_found = 0;
+ for (const auto& packet : helper.trace()) {
+ for (int i = 0; i < packet.ftrace_events().event_size(); i++) {
+ const auto& ev = packet.ftrace_events().event()[static_cast<size_t>(i)];
+ if (ev.has_print() && ev.print().buf().find(kMarker) != std::string::npos)
+ marker_found++;
+ }
+ }
+ ASSERT_EQ(marker_found, 1);
+}
+
+// Disable this test:
+// 1. On cuttlefish (x86-kvm). It's too slow when running on GCE (b/171771440).
+// We cannot change the length of the production code in
+// CanReadKernelSymbolAddresses() to deal with it.
+// 2. On user (i.e. non-userdebug) builds. As that doesn't work there by design.
+// 3. On ARM builds, because they fail on our CI.
+#if (PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD) && defined(__i386__)) || \
+ defined(__arm__)
+#define MAYBE_KernelAddressSymbolization DISABLED_KernelAddressSymbolization
+#else
+#define MAYBE_KernelAddressSymbolization KernelAddressSymbolization
+#endif
+TEST_F(PerfettoFtraceIntegrationTest, MAYBE_KernelAddressSymbolization) {
+ // On Android in-tree builds (TreeHugger): this test must always run to
+ // prevent selinux / property-related regressions. However it can run only on
+ // userdebug.
+ // On standalone builds and Linux, this can be optionally skipped because
+ // there it requires root to lower kptr_restrict.
+#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+ if (!IsDebuggableBuild())
+ GTEST_SKIP();
+#else
+ if (geteuid() != 0)
+ GTEST_SKIP();
+#endif
+
+ base::TestTaskRunner task_runner;
+
+ TestHelper helper(&task_runner);
+ helper.StartServiceIfRequired();
+
+#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
+ ProbesProducerThread probes(GetTestProducerSockName());
+ probes.Connect();
+#endif
+
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+
+ TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(1024);
+
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("linux.ftrace");
+ protos::gen::FtraceConfig ftrace_cfg;
+ ftrace_cfg.set_symbolize_ksyms(true);
+ ftrace_cfg.set_initialize_ksyms_synchronously_for_testing(true);
+ ds_config->set_ftrace_config_raw(ftrace_cfg.SerializeAsString());
+
+ helper.StartTracing(trace_config);
+
+ // Synchronize with the ftrace data source. The kernel symbol map is loaded
+ // at this point.
+ helper.FlushAndWait(kDefaultTestTimeoutMs);
+ helper.DisableTracing();
+ helper.WaitForTracingDisabled();
+ helper.ReadData();
+ helper.WaitForReadData();
+
+ const auto& packets = helper.trace();
+ ASSERT_GT(packets.size(), 0u);
+
+ int symbols_parsed = -1;
+ for (const auto& packet : packets) {
+ if (!packet.has_ftrace_stats())
+ continue;
+ if (packet.ftrace_stats().phase() != protos::gen::FtraceStats::END_OF_TRACE)
+ continue;
+ symbols_parsed =
+ static_cast<int>(packet.ftrace_stats().kernel_symbols_parsed());
+ }
+ ASSERT_GT(symbols_parsed, 100);
+}
+
+TEST_F(PerfettoFtraceIntegrationTest, ReportFtraceFailuresInStats) {
+ base::TestTaskRunner task_runner;
+
+ TestHelper helper(&task_runner);
+ helper.StartServiceIfRequired();
+
+#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
+ ProbesProducerThread probes(GetTestProducerSockName());
+ probes.Connect();
+#endif
+
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+
+ // Wait for the traced_probes service to connect. We want to start tracing
+ // only after it connects, otherwise we'll start a tracing session with 0
+ // producers connected (which is valid but not what we want here).
+ helper.WaitForDataSourceConnected("linux.ftrace");
+
+ TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(32);
+ trace_config.set_duration_ms(1);
+
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("linux.ftrace");
+
+ protos::gen::FtraceConfig ftrace_config;
+ ftrace_config.add_ftrace_events("sched/sched_process_fork"); // Good.
+ ftrace_config.add_ftrace_events("sched/does_not_exist"); // Bad.
+ ftrace_config.add_ftrace_events("foobar/i_just_made_this_up"); // Bad.
+ ftrace_config.add_atrace_categories("madeup_atrace_cat"); // Bad.
+ ds_config->set_ftrace_config_raw(ftrace_config.SerializeAsString());
+
+ helper.StartTracing(trace_config);
+ helper.WaitForTracingDisabled(kDefaultTestTimeoutMs);
+
+ helper.ReadData();
+ helper.WaitForReadData();
+ const auto& packets = helper.trace();
+ ASSERT_GT(packets.size(), 0u);
+
+ base::Optional<protos::gen::FtraceStats> stats;
+ for (const auto& packet : packets) {
+ if (!packet.has_ftrace_stats() ||
+ packet.ftrace_stats().phase() !=
+ protos::gen::FtraceStats::START_OF_TRACE) {
+ continue;
+ }
+ stats = packet.ftrace_stats();
+ }
+ ASSERT_TRUE(stats.has_value());
+ EXPECT_THAT(stats->unknown_ftrace_events(),
+ UnorderedElementsAreArray(
+ {"sched/does_not_exist", "foobar/i_just_made_this_up"}));
+
+ // Atrace is not available on Linux and on the O-based emulator on the CI.
+ if (base::FileExists("/system/bin/atrace")) {
+ EXPECT_THAT(stats->atrace_errors(), HasSubstr("madeup_atrace_cat"));
+ }
+}
+
+} // namespace perfetto
+#endif // OS_ANDROID || OS_LINUX
diff --git a/test/stress_test/stress_test.cc b/test/stress_test/stress_test.cc
index c8e9503bc..75de80a50 100644
--- a/test/stress_test/stress_test.cc
+++ b/test/stress_test/stress_test.cc
@@ -178,7 +178,8 @@ void TestHarness::RunConfig(const char* cfg_name,
traced.args.env = env_;
if (!verbose) {
traced.args.out_fd = OpenLogFile(result_dir + "/traced.log");
- traced.args.stderr_mode = traced.args.stdout_mode = base::Subprocess::kFd;
+ traced.args.stderr_mode = traced.args.stdout_mode =
+ base::Subprocess::OutputMode::kFd;
}
traced.Start();
g_sig->pids_to_kill.emplace_back(traced.pid());
@@ -195,7 +196,7 @@ void TestHarness::RunConfig(const char* cfg_name,
producer.args.out_fd =
OpenLogFile(result_dir + "/producer." + std::to_string(i) + ".log");
producer.args.stderr_mode = producer.args.stdout_mode =
- base::Subprocess::kFd;
+ base::Subprocess::OutputMode::kFd;
}
producer.args.env = env_;
producer.Start();
@@ -213,7 +214,7 @@ void TestHarness::RunConfig(const char* cfg_name,
if (!verbose) {
consumer.args.out_fd = OpenLogFile(result_dir + "/perfetto.log");
consumer.args.stderr_mode = consumer.args.stdout_mode =
- base::Subprocess::kFd;
+ base::Subprocess::OutputMode::kFd;
}
remove(trace_file_path.c_str());
consumer.Start();
diff --git a/test/synth_common.py b/test/synth_common.py
index 0cf5fdd28..be52735dc 100644
--- a/test/synth_common.py
+++ b/test/synth_common.py
@@ -16,7 +16,7 @@
import argparse
from collections import namedtuple
-from google.protobuf import descriptor, descriptor_pb2, message_factory, descriptor_pool
+from google.protobuf import descriptor_pb2, message_factory, descriptor_pool
CLONE_THREAD = 0x00010000
CLONE_VFORK = 0x00004000
@@ -187,6 +187,9 @@ class Trace(object):
def add_atrace_async_end(self, ts, tid, pid, buf):
self.add_print(ts, tid, 'F|{}|{}|0'.format(pid, buf))
+ def add_atrace_instant(self, ts, tid, pid, buf):
+ self.add_print(ts, tid, 'I|{}|{}'.format(pid, buf))
+
def add_process(self, pid, ppid, cmdline, uid=None):
process = self.packet.process_tree.processes.add()
process.pid = pid
@@ -214,6 +217,35 @@ class Trace(object):
battery_count.current_ua = curr_ua
battery_count.current_avg_ua = curr_avg_ua
+ def add_binder_transaction(self, transaction_id, ts_start, ts_end, tid, pid,
+ reply_id, reply_ts_start, reply_ts_end, reply_tid,
+ reply_pid):
+ # Binder transaction start.
+ ftrace = self.__add_ftrace_event(ts_start, tid)
+ binder_transaction = ftrace.binder_transaction
+ binder_transaction.debug_id = transaction_id
+ binder_transaction.to_proc = reply_pid
+ binder_transaction.to_thread = reply_tid
+ binder_transaction.reply = False
+
+ # Binder reply start
+ ftrace = self.__add_ftrace_event(reply_ts_start, reply_tid)
+ binder_transaction_received = ftrace.binder_transaction_received
+ binder_transaction_received.debug_id = transaction_id
+
+ # Binder reply finish
+ ftrace = self.__add_ftrace_event(reply_ts_end, reply_tid)
+ reply_binder_transaction = ftrace.binder_transaction
+ reply_binder_transaction.debug_id = reply_id
+ reply_binder_transaction.to_proc = pid
+ reply_binder_transaction.to_thread = tid
+ reply_binder_transaction.reply = True
+
+ # Binder transaction finish
+ ftrace = self.__add_ftrace_event(ts_end, tid)
+ reply_binder_transaction_received = ftrace.binder_transaction_received
+ reply_binder_transaction_received.debug_id = reply_id
+
def add_battery_counters_no_curr_ua(self, ts, charge_uah, cap_prct,
curr_avg_ua):
self.packet = self.trace.packet.add()
@@ -404,8 +436,8 @@ class Trace(object):
thread.cpu_freq_indices.append(index)
thread.cpu_freq_ticks.append(freqs[index])
- def add_gpu_mem_total_ftrace_event(self, pid, ts, size):
- ftrace = self.__add_ftrace_event(ts, pid)
+ def add_gpu_mem_total_ftrace_event(self, ftrace_pid, pid, ts, size):
+ ftrace = self.__add_ftrace_event(ts, ftrace_pid)
gpu_mem_total_ftrace_event = ftrace.gpu_mem_total
gpu_mem_total_ftrace_event.pid = pid
gpu_mem_total_ftrace_event.size = size
@@ -616,6 +648,7 @@ class Trace(object):
track=None,
trusted_sequence_id=None,
trace_id=None,
+ step=None,
flow_ids=[],
terminating_flow_ids=[]):
packet = self.add_track_event_slice(
@@ -626,6 +659,8 @@ class Trace(object):
trusted_sequence_id=trusted_sequence_id)
if trace_id is not None:
packet.track_event.chrome_latency_info.trace_id = trace_id
+ if step is not None:
+ packet.track_event.chrome_latency_info.step = step
for flow_id in flow_ids:
packet.track_event.flow_ids.append(flow_id)
for flow_id in terminating_flow_ids:
@@ -639,13 +674,24 @@ class Trace(object):
track=None,
trace_id=None,
gesture_scroll_id=None,
- is_coalesced=None):
+ touch_id=None,
+ is_coalesced=None,
+ gets_to_gpu=True):
packet = self.add_track_event_slice(
"InputLatency::" + name, ts=ts, dur=dur, track=track)
- packet.track_event.chrome_latency_info.trace_id = trace_id
- packet.track_event.chrome_latency_info.gesture_scroll_id = gesture_scroll_id
+ latency_info = packet.track_event.chrome_latency_info
+ latency_info.trace_id = trace_id
+ if gesture_scroll_id is not None:
+ latency_info.gesture_scroll_id = gesture_scroll_id
+ if touch_id is not None:
+ latency_info.touch_id = touch_id
+ if gets_to_gpu:
+ component = latency_info.component_info.add()
+ component.component_type = self.prototypes \
+ .ChromeLatencyInfo.ComponentType \
+ .COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER
if is_coalesced is not None:
- packet.track_event.chrome_latency_info.is_coalesced = is_coalesced
+ latency_info.is_coalesced = is_coalesced
return packet
def add_chrome_metadata(self, os_name=None):
@@ -667,7 +713,8 @@ class Trace(object):
def add_actual_display_frame_start_event(self, ts, cookie, token, pid,
present_type, on_time_finish,
- gpu_composition, jank_type, prediction_type):
+ gpu_composition, jank_type,
+ prediction_type):
packet = self.add_packet()
packet.timestamp = ts
event = packet.frame_timeline_event.actual_display_frame_start
@@ -697,7 +744,8 @@ class Trace(object):
def add_actual_surface_frame_start_event(self, ts, cookie, token,
display_frame_token, pid, layer_name,
present_type, on_time_finish,
- gpu_composition, jank_type, prediction_type):
+ gpu_composition, jank_type,
+ prediction_type):
packet = self.add_packet()
packet.timestamp = ts
event = packet.frame_timeline_event.actual_surface_frame_start
@@ -759,24 +807,40 @@ def create_trace():
setattr(res, desc.name, desc.number)
return res
+ ChromeLatencyInfo = namedtuple('ChromeLatencyInfo', [
+ 'ComponentType',
+ 'Step',
+ ])
+
Prototypes = namedtuple('Prototypes', [
'TrackEvent',
'ChromeRAILMode',
- 'ThreadDescriptor',
+ 'ChromeLatencyInfo',
'ChromeProcessDescriptor',
'CounterDescriptor',
+ 'ThreadDescriptor',
])
+
+ chrome_latency_info_prototypes = ChromeLatencyInfo(
+ ComponentType=EnumPrototype.from_descriptor(
+ pool.FindEnumTypeByName(
+ 'perfetto.protos.ChromeLatencyInfo.LatencyComponentType')),
+ Step=EnumPrototype.from_descriptor(
+ pool.FindEnumTypeByName('perfetto.protos.ChromeLatencyInfo.Step')),
+ )
+
prototypes = Prototypes(
TrackEvent=factory.GetPrototype(
pool.FindMessageTypeByName('perfetto.protos.TrackEvent')),
ChromeRAILMode=EnumPrototype.from_descriptor(
pool.FindEnumTypeByName('perfetto.protos.ChromeRAILMode')),
- ThreadDescriptor=factory.GetPrototype(
- pool.FindMessageTypeByName('perfetto.protos.ThreadDescriptor')),
+ ChromeLatencyInfo=chrome_latency_info_prototypes,
ChromeProcessDescriptor=factory.GetPrototype(
pool.FindMessageTypeByName(
'perfetto.protos.ChromeProcessDescriptor')),
CounterDescriptor=factory.GetPrototype(
pool.FindMessageTypeByName('perfetto.protos.CounterDescriptor')),
+ ThreadDescriptor=factory.GetPrototype(
+ pool.FindMessageTypeByName('perfetto.protos.ThreadDescriptor')),
)
return Trace(ProtoTrace(), prototypes)
diff --git a/test/test_helper.cc b/test/test_helper.cc
index ce0392888..79c054a04 100644
--- a/test/test_helper.cc
+++ b/test/test_helper.cc
@@ -230,6 +230,29 @@ void TestHelper::WaitForReadData(uint32_t read_count, uint32_t timeout_ms) {
timeout_ms);
}
+void TestHelper::WaitFor(std::function<bool()> predicate,
+ const std::string& error_msg,
+ uint32_t timeout_ms) {
+ int64_t deadline_ms = base::GetWallTimeMs().count() + timeout_ms;
+ while (base::GetWallTimeMs().count() < deadline_ms) {
+ if (predicate())
+ return;
+ base::SleepMicroseconds(500 * 1000); // 0.5 s.
+ }
+ PERFETTO_FATAL("Test timed out waiting for: %s", error_msg.c_str());
+}
+
+void TestHelper::WaitForDataSourceConnected(const std::string& ds_name) {
+ auto predicate = [&] {
+ auto dss = QueryServiceStateAndWait().data_sources();
+ return std::any_of(dss.begin(), dss.end(),
+ [&](const TracingServiceState::DataSource& ds) {
+ return ds.ds_descriptor().name() == ds_name;
+ });
+ };
+ WaitFor(predicate, "connection of data source " + ds_name);
+}
+
void TestHelper::SyncAndWaitProducer() {
static int sync_id = 0;
std::string checkpoint_name = "producer_sync_" + std::to_string(++sync_id);
@@ -241,13 +264,15 @@ void TestHelper::SyncAndWaitProducer() {
TracingServiceState TestHelper::QueryServiceStateAndWait() {
TracingServiceState res;
- auto checkpoint = CreateCheckpoint("query_svc_state");
+ static int n = 0;
+ std::string checkpoint_name = "query_svc_state_" + std::to_string(n++);
+ auto checkpoint = CreateCheckpoint(checkpoint_name);
auto callback = [&checkpoint, &res](bool, const TracingServiceState& tss) {
res = tss;
checkpoint();
};
endpoint_->QueryServiceState(callback);
- RunUntilCheckpoint("query_svc_state");
+ RunUntilCheckpoint(checkpoint_name);
return res;
}
diff --git a/test/test_helper.h b/test/test_helper.h
index 4ac4c46b1..7331c6441 100644
--- a/test/test_helper.h
+++ b/test/test_helper.h
@@ -20,22 +20,25 @@
#include <stdio.h>
#include <stdlib.h>
+#include "perfetto/base/build_config.h"
+#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/subprocess.h"
#include "perfetto/ext/base/thread_task_runner.h"
#include "perfetto/ext/base/utils.h"
#include "perfetto/ext/tracing/core/consumer.h"
#include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
#include "perfetto/ext/tracing/core/trace_packet.h"
#include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
+#include "perfetto/ext/tracing/ipc/default_socket.h"
#include "perfetto/ext/tracing/ipc/service_ipc_host.h"
#include "perfetto/tracing/core/trace_config.h"
#include "src/base/test/test_task_runner.h"
#include "test/fake_producer.h"
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
-// TODO(primiano): uncomment in next CL.
-// #include "src/tracing/ipc/shared_memory_windows.h"
+#include "src/tracing/ipc/shared_memory_windows.h"
#else
#include "src/traced/probes/probes_producer.h"
#include "src/tracing/ipc/posix_shared_memory.h"
@@ -45,10 +48,21 @@
namespace perfetto {
-// This value has been bumped to 10s in Oct 2020 because the x86 cuttlefish
-// emulator is sensibly slower (up to 10x) than real hw and caused flakes.
+// This value has been bumped to 10s in Oct 2020 because the GCE-based emulator
+// can be sensibly slower than real hw (more than 10x) and caused flakes.
// See bugs duped against b/171771440.
-constexpr uint32_t kDefaultTestTimeoutMs = 10000;
+constexpr uint32_t kDefaultTestTimeoutMs = 30000;
+
+inline const char* GetTestProducerSockName() {
+// If we're building on Android and starting the daemons ourselves,
+// create the sockets in a world-writable location.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
+ PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
+ return "/data/local/tmp/traced_producer";
+#else
+ return ::perfetto::GetProducerSocket();
+#endif
+}
// This is used only in daemon starting integrations tests.
class ServiceThread {
@@ -168,12 +182,12 @@ class FakeProducerThread {
void CreateProducerProvidedSmb() {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
- // TODO(primiano): in next CLs introduce SharedMemoryWindows.
+ SharedMemoryWindows::Factory factory;
#else
PosixSharedMemory::Factory factory;
+#endif
shm_ = factory.CreateSharedMemory(1024 * 1024);
shm_arbiter_ = SharedMemoryArbiter::CreateUnboundInstance(shm_.get(), 4096);
-#endif
}
void ProduceStartupEventBatch(const protos::gen::TestConfig& config,
@@ -242,9 +256,13 @@ class TestHelper : public Consumer {
bool IsShmemProvidedByProducer();
void ProduceStartupEventBatch(const protos::gen::TestConfig& config);
+ void WaitFor(std::function<bool()> predicate,
+ const std::string& error_msg,
+ uint32_t timeout_ms = kDefaultTestTimeoutMs);
void WaitForConsumerConnect();
void WaitForProducerSetup();
void WaitForProducerEnabled();
+ void WaitForDataSourceConnected(const std::string& ds_name);
void WaitForTracingDisabled(uint32_t timeout_ms = kDefaultTestTimeoutMs);
void WaitForReadData(uint32_t read_count = 0,
uint32_t timeout_ms = kDefaultTestTimeoutMs);
@@ -300,6 +318,107 @@ class TestHelper : public Consumer {
std::unique_ptr<TracingService::ConsumerEndpoint> endpoint_; // Keep last.
};
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+// This class is a reference to a child process that has in essence been execv
+// to the requested binary. The process will start and then wait for Run()
+// before proceeding. We use this to fork new processes before starting any
+// additional threads in the parent process (otherwise you would risk
+// deadlocks), but pause the forked processes until remaining setup (including
+// any necessary threads) in the parent process is complete.
+class Exec {
+ public:
+ // Starts the forked process that was created. If not null then |stderr_out|
+ // will contain the stderr of the process.
+ int Run(std::string* stderr_out = nullptr) {
+ // We can't be the child process.
+ PERFETTO_CHECK(getpid() != subprocess_.pid());
+ // Will cause the entrypoint to continue.
+ PERFETTO_CHECK(write(*sync_pipe_.wr, "1", 1) == 1);
+ sync_pipe_.wr.reset();
+ subprocess_.Wait();
+
+ if (stderr_out) {
+ *stderr_out = std::move(subprocess_.output());
+ } else {
+ PERFETTO_LOG("Child proc %d exited with stderr: \"%s\"",
+ subprocess_.pid(), subprocess_.output().c_str());
+ }
+ return subprocess_.returncode();
+ }
+
+ Exec(const std::string& argv0,
+ std::initializer_list<std::string> args,
+ std::string input = "") {
+ subprocess_.args.stderr_mode = base::Subprocess::OutputMode::kBuffer;
+ subprocess_.args.stdout_mode = base::Subprocess::OutputMode::kDevNull;
+ subprocess_.args.input = input;
+
+#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
+ constexpr bool kUseSystemBinaries = false;
+#else
+ constexpr bool kUseSystemBinaries = true;
+#endif
+
+ std::vector<std::string>& cmd = subprocess_.args.exec_cmd;
+ if (kUseSystemBinaries) {
+ PERFETTO_CHECK(TestHelper::kDefaultMode ==
+ TestHelper::Mode::kUseSystemService);
+ cmd.push_back("/system/bin/" + argv0);
+ cmd.insert(cmd.end(), args.begin(), args.end());
+ } else {
+ PERFETTO_CHECK(TestHelper::kDefaultMode ==
+ TestHelper::Mode::kStartDaemons);
+ subprocess_.args.env.push_back(
+ std::string("PERFETTO_PRODUCER_SOCK_NAME=") +
+ TestHelper::GetDefaultModeProducerSocketName());
+ subprocess_.args.env.push_back(
+ std::string("PERFETTO_CONSUMER_SOCK_NAME=") +
+ TestHelper::GetDefaultModeConsumerSocketName());
+ cmd.push_back(base::GetCurExecutableDir() + "/" + argv0);
+ cmd.insert(cmd.end(), args.begin(), args.end());
+ }
+
+ if (!base::FileExists(cmd[0])) {
+ PERFETTO_FATAL(
+ "Cannot find %s. Make sure that the target has been built and, on "
+ "Android, pushed to the device.",
+ cmd[0].c_str());
+ }
+
+ // This pipe blocks the execution of the child process until the main test
+ // process calls Run(). There are two conflicting problems here:
+ // 1) We can't fork() subprocesses too late, because the test spawns threads
+ // for hosting the service. fork+threads = bad (see aosp/1089744).
+ // 2) We can't run the subprocess too early, because we need to wait that
+ // the service threads are ready before trying to connect from the child
+ // process.
+ sync_pipe_ = base::Pipe::Create();
+ int sync_pipe_rd = *sync_pipe_.rd;
+ subprocess_.args.preserve_fds.push_back(sync_pipe_rd);
+
+ // This lambda will be called on the forked child process after having
+ // setup pipe redirection and closed all FDs, right before the exec().
+ // The Subprocesss harness will take care of closing also |sync_pipe_.wr|.
+ subprocess_.args.posix_entrypoint_for_testing = [sync_pipe_rd] {
+ // Don't add any logging here, all file descriptors are closed and trying
+ // to log will likely cause undefined behaviors.
+ char ignored = 0;
+ PERFETTO_CHECK(PERFETTO_EINTR(read(sync_pipe_rd, &ignored, 1)) > 0);
+ PERFETTO_CHECK(close(sync_pipe_rd) == 0 || errno == EINTR);
+ };
+
+ subprocess_.Start();
+ sync_pipe_.rd.reset();
+ }
+
+ private:
+ base::Subprocess subprocess_;
+ base::Pipe sync_pipe_;
+};
+
+#endif // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
} // namespace perfetto
#endif // TEST_TEST_HELPER_H_
diff --git a/test/trace_processor/parsing/android_async_slice.textproto b/test/trace_processor/atrace/android_async_slice.textproto
index 787d929f6..787d929f6 100644
--- a/test/trace_processor/parsing/android_async_slice.textproto
+++ b/test/trace_processor/atrace/android_async_slice.textproto
diff --git a/test/trace_processor/parsing/android_b2b_async_begin.textproto b/test/trace_processor/atrace/android_b2b_async_begin.textproto
index 121dfe193..121dfe193 100644
--- a/test/trace_processor/parsing/android_b2b_async_begin.textproto
+++ b/test/trace_processor/atrace/android_b2b_async_begin.textproto
diff --git a/test/trace_processor/parsing/android_b2b_async_begin_list_slices.out b/test/trace_processor/atrace/android_b2b_async_begin_list_slices.out
index a11b96c55..a11b96c55 100644
--- a/test/trace_processor/parsing/android_b2b_async_begin_list_slices.out
+++ b/test/trace_processor/atrace/android_b2b_async_begin_list_slices.out
diff --git a/test/trace_processor/atrace/async_track_atrace.py b/test/trace_processor/atrace/async_track_atrace.py
new file mode 100644
index 000000000..121f6d31f
--- /dev/null
+++ b/test/trace_processor/atrace/async_track_atrace.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python3
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from os import sys, path
+
+import synth_common
+
+trace = synth_common.create_trace()
+
+trace.add_packet()
+trace.add_process(pid=1, ppid=0, cmdline="p1")
+trace.add_process(pid=2, ppid=1, cmdline="p2")
+
+trace.add_thread(tid=1, tgid=1, cmdline='p1', name='p1')
+trace.add_thread(tid=2, tgid=2, cmdline='p2', name='p2')
+
+trace.add_ftrace_packet(cpu=0)
+trace.add_print(ts=50, tid=1, buf='T|1|track|ev|1024\n')
+trace.add_print(ts=55, tid=1, buf='T|1|track|ev|2048\n')
+trace.add_print(ts=60, tid=2, buf='T|2|track|ev|1024\n')
+trace.add_print(ts=65, tid=2, buf='U|2|track|ev|1024\n')
+trace.add_print(ts=70, tid=1, buf='U|1|track|ev|2048\n')
+trace.add_print(ts=75, tid=1, buf='U|1|track|ev|1024\n')
+
+sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/atrace/async_track_atrace_process_track_slices.out b/test/trace_processor/atrace/async_track_atrace_process_track_slices.out
new file mode 100644
index 000000000..3023fcf15
--- /dev/null
+++ b/test/trace_processor/atrace/async_track_atrace_process_track_slices.out
@@ -0,0 +1,4 @@
+"ts","dur","pid","slice_name","track_name"
+50,25,1,"ev","track"
+55,15,1,"ev","track"
+60,5,2,"ev","track"
diff --git a/test/trace_processor/parsing/bad_print.systrace b/test/trace_processor/atrace/bad_print.systrace
index cb1278024..cb1278024 100644
--- a/test/trace_processor/parsing/bad_print.systrace
+++ b/test/trace_processor/atrace/bad_print.systrace
diff --git a/test/trace_processor/parsing/bad_print.textproto b/test/trace_processor/atrace/bad_print.textproto
index 388946dec..388946dec 100644
--- a/test/trace_processor/parsing/bad_print.textproto
+++ b/test/trace_processor/atrace/bad_print.textproto
diff --git a/test/trace_processor/parsing/bad_print_systrace_list_slices.out b/test/trace_processor/atrace/bad_print_systrace_list_slices.out
index 6b081c875..6b081c875 100644
--- a/test/trace_processor/parsing/bad_print_systrace_list_slices.out
+++ b/test/trace_processor/atrace/bad_print_systrace_list_slices.out
diff --git a/test/trace_processor/parsing/bad_print_textproto_list_slices.out b/test/trace_processor/atrace/bad_print_textproto_list_slices.out
index 1f44a902a..1f44a902a 100644
--- a/test/trace_processor/parsing/bad_print_textproto_list_slices.out
+++ b/test/trace_processor/atrace/bad_print_textproto_list_slices.out
diff --git a/test/trace_processor/atrace/index b/test/trace_processor/atrace/index
new file mode 100644
index 000000000..32a8119dd
--- /dev/null
+++ b/test/trace_processor/atrace/index
@@ -0,0 +1,13 @@
+# Check error handling when parsing print events.
+bad_print.textproto ../common/list_slices.sql bad_print_textproto_list_slices.out
+bad_print.systrace ../common/list_slices.sql bad_print_systrace_list_slices.out
+instant_atrace.py instant_with_thread.sql instant_atrace_instant_with_thread.out
+instant_async_atrace.py instant_async.sql instant_async_atrace_instant_async.out
+
+# Match legacy Catapult behaviour when we see multiple S events b2b with the same cookie
+# name and upid.
+android_b2b_async_begin.textproto ../common/list_slices.sql android_b2b_async_begin_list_slices.out
+
+# Android userspace async slices
+android_async_slice.textproto ../common/process_track_slices.sql process_track_slices_android_async_slice.out
+async_track_atrace.py ../common/process_track_slices.sql async_track_atrace_process_track_slices.out
diff --git a/test/trace_processor/atrace/instant_async.sql b/test/trace_processor/atrace/instant_async.sql
new file mode 100644
index 000000000..a02b2ba94
--- /dev/null
+++ b/test/trace_processor/atrace/instant_async.sql
@@ -0,0 +1,9 @@
+SELECT
+ process.name AS process_name,
+ process_track.name as track_name,
+ instant.name as instant_name,
+ ts
+FROM slice instant
+JOIN process_track ON instant.track_id = process_track.id
+JOIN process USING (upid)
+WHERE dur = 0;
diff --git a/test/trace_processor/atrace/instant_async_atrace.py b/test/trace_processor/atrace/instant_async_atrace.py
new file mode 100644
index 000000000..effdf8bf3
--- /dev/null
+++ b/test/trace_processor/atrace/instant_async_atrace.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from os import sys, path
+
+import synth_common
+
+trace = synth_common.create_trace()
+
+trace.add_packet()
+trace.add_process(pid=1, ppid=0, cmdline="p1")
+trace.add_process(pid=2, ppid=1, cmdline="p2")
+
+trace.add_ftrace_packet(cpu=0)
+trace.add_sched(ts=50, prev_pid=1, next_pid=2, prev_comm='t1', next_comm='t2')
+trace.add_print(ts=51, tid=2, buf='N|2|track_p2|ev1\n')
+trace.add_sched(ts=52, prev_pid=2, next_pid=1, prev_comm='t2', next_comm='t1')
+trace.add_print(ts=53, tid=1, buf='N|1|track_p1|ev2\n')
+
+sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/atrace/instant_async_atrace_instant_async.out b/test/trace_processor/atrace/instant_async_atrace_instant_async.out
new file mode 100644
index 000000000..d95fe518b
--- /dev/null
+++ b/test/trace_processor/atrace/instant_async_atrace_instant_async.out
@@ -0,0 +1,3 @@
+"process_name","track_name","instant_name","ts"
+"p2","track_p2","ev1",51
+"p1","track_p1","ev2",53
diff --git a/test/trace_processor/atrace/instant_atrace.py b/test/trace_processor/atrace/instant_atrace.py
new file mode 100644
index 000000000..c7d6b628c
--- /dev/null
+++ b/test/trace_processor/atrace/instant_atrace.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from os import sys, path
+
+import synth_common
+
+trace = synth_common.create_trace()
+
+trace.add_ftrace_packet(cpu=0)
+trace.add_sched(ts=50, prev_pid=1, next_pid=2, prev_comm='t1', next_comm='t2')
+trace.add_print(ts=51, tid=2, buf='I|2|t2_event\n')
+trace.add_sched(ts=52, prev_pid=2, next_pid=1, prev_comm='t2', next_comm='t1')
+trace.add_print(ts=53, tid=1, buf='I|1|t1_event\n')
+
+sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/atrace/instant_atrace_instant_with_thread.out b/test/trace_processor/atrace/instant_atrace_instant_with_thread.out
new file mode 100644
index 000000000..c1b730562
--- /dev/null
+++ b/test/trace_processor/atrace/instant_atrace_instant_with_thread.out
@@ -0,0 +1,3 @@
+"thread_name","track_name","ts"
+"t2","t2_event",51
+"t1","t1_event",53
diff --git a/test/trace_processor/atrace/instant_with_thread.sql b/test/trace_processor/atrace/instant_with_thread.sql
new file mode 100644
index 000000000..2e39608cb
--- /dev/null
+++ b/test/trace_processor/atrace/instant_with_thread.sql
@@ -0,0 +1,5 @@
+SELECT thread.name as thread_name, instant.name as track_name, instant.ts
+FROM slice instant
+JOIN thread_track ON instant.track_id = thread_track.id
+JOIN thread USING (utid)
+WHERE dur = 0;
diff --git a/test/trace_processor/parsing/process_track_slices_android_async_slice.out b/test/trace_processor/atrace/process_track_slices_android_async_slice.out
index a30a8f038..a30a8f038 100644
--- a/test/trace_processor/parsing/process_track_slices_android_async_slice.out
+++ b/test/trace_processor/atrace/process_track_slices_android_async_slice.out
diff --git a/test/trace_processor/camera/camera-ion-mem-trace_android_camera.out b/test/trace_processor/camera/camera-ion-mem-trace_android_camera.out
new file mode 100644
index 000000000..39281130c
--- /dev/null
+++ b/test/trace_processor/camera/camera-ion-mem-trace_android_camera.out
@@ -0,0 +1,7 @@
+android_camera {
+ gc_rss_and_dma {
+ min: 47779840.0
+ max: 2529583104.0
+ avg: 1459479416.3297353
+ }
+}
diff --git a/test/trace_processor/camera/camera-ion-mem-trace_android_camera_unagg.out b/test/trace_processor/camera/camera-ion-mem-trace_android_camera_unagg.out
new file mode 100644
index 000000000..c6b2069e0
--- /dev/null
+++ b/test/trace_processor/camera/camera-ion-mem-trace_android_camera_unagg.out
@@ -0,0 +1,35834 @@
+android_camera_unagg: {
+ gc_rss_and_dma: {
+ ts: 686109156135
+ value: 47779840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 686161655118
+ value: 117669888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 686167624031
+ value: 118198272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698897318454
+ value: 118763520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698898242852
+ value: 119816192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698898244399
+ value: 120328192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698899686130
+ value: 436695040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698899712213
+ value: 437399552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698899943210
+ value: 437403648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698900190403
+ value: 438886400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698900281793
+ value: 439111680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698901481947
+ value: 439754752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698901982395
+ value: 440279040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698902063124
+ value: 440807424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698902071588
+ value: 459063296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698902711073
+ value: 460181504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698902817681
+ value: 460722176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698903110080
+ value: 461127680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698903355482
+ value: 461733888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698904614231
+ value: 462524416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698904754815
+ value: 462897152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698904755629
+ value: 463364096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698904908461
+ value: 463843328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698907350437
+ value: 463847424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698908181207
+ value: 464437248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698908362115
+ value: 482693120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698908420017
+ value: 483254272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698908621636
+ value: 483258368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698909570611
+ value: 501514240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698909821791
+ value: 501518336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698911886773
+ value: 502689792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698912174534
+ value: 502898688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698912175469
+ value: 503365632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698916808974
+ value: 504328192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698916935927
+ value: 504459264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698917850803
+ value: 505716736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698917851576
+ value: 506216448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698919297580
+ value: 506617856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698919454604
+ value: 507068416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698919454848
+ value: 507588608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698919544895
+ value: 508243968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698919555149
+ value: 508567552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698919727227
+ value: 509222912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698919806370
+ value: 509751296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698919887872
+ value: 510177280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698920118747
+ value: 510910464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698920398940
+ value: 512614400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698920501560
+ value: 514744320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698920615614
+ value: 516841472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698920615777
+ value: 517308416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698920771010
+ value: 519143424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698920896051
+ value: 521109504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698921038629
+ value: 523337728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698921168064
+ value: 525369344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698921288385
+ value: 527400960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698921419285
+ value: 528252928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698921558485
+ value: 528490496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698921558648
+ value: 529096704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698921726291
+ value: 529887232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698921907566
+ value: 530739200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698924669936
+ value: 531230720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698928467218
+ value: 531726336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698931362888
+ value: 532365312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698931487807
+ value: 532836352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698932794122
+ value: 533245952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698936086114
+ value: 533770240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698936087416
+ value: 534355968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698936598280
+ value: 535187456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698937599582
+ value: 535527424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698938414931
+ value: 535965696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698938899062
+ value: 536526848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698941986912
+ value: 830709760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698943755303
+ value: 831246336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698947065850
+ value: 831705088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698947067803
+ value: 832262144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698950813002
+ value: 832716800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698952370579
+ value: 833228800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698954385675
+ value: 833748992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698954388441
+ value: 834281472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698960691542
+ value: 834961408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698962184706
+ value: 835538944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698962271702
+ value: 835956736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698962354180
+ value: 836349952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698962701064
+ value: 837578752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698962825535
+ value: 838823936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698962926405
+ value: 839704576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698963023980
+ value: 840916992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698963120172
+ value: 842182656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698963655653
+ value: 842944512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698963656549
+ value: 843382784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698963656833
+ value: 843378688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698963763319
+ value: 843382784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698963763767
+ value: 843378688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698963852309
+ value: 843382784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698963852716
+ value: 843378688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698964526584
+ value: 843640832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698964628879
+ value: 843911168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698965582167
+ value: 843776000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698965595758
+ value: 844398592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698965770684
+ value: 843878400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698966068902
+ value: 842788864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698966154962
+ value: 843390976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698966355849
+ value: 843845632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698967201959
+ value: 844468224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698967320489
+ value: 845000704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698967585544
+ value: 845537280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698967708266
+ value: 847855616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698967829970
+ value: 848232448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698968425022
+ value: 848809984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698968768446
+ value: 849432576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698968924981
+ value: 849801216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698969383640
+ value: 850481152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698969552911
+ value: 850882560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698969874485
+ value: 851521536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698970044407
+ value: 851824640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698970362522
+ value: 852426752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698970519382
+ value: 852934656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698970778578
+ value: 853405696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698971035292
+ value: 854151168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698971210341
+ value: 854446080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698971553765
+ value: 855044096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698971718764
+ value: 855547904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698971921116
+ value: 856141824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698972125136
+ value: 857866240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698974581516
+ value: 858148864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698974925510
+ value: 857882624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698974980849
+ value: 856645632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698975016290
+ value: 855871488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698975042576
+ value: 855281664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698975101536
+ value: 853962752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698975111383
+ value: 853749760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698983360732
+ value: 854159360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698983361789
+ value: 854355968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698988707777
+ value: 855076864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698988709080
+ value: 855613440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698991351414
+ value: 856006656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698993098728
+ value: 856584192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698993952081
+ value: 857833472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698993952528
+ value: 858361856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 698998661757
+ value: 858546176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699000071181
+ value: 859172864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699000681817
+ value: 859557888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699001185113
+ value: 859947008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699006457981
+ value: 860622848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699007445530
+ value: 861052928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699007741672
+ value: 860880896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699007835585
+ value: 860356608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699012239679
+ value: 860626944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699016924371
+ value: 861020160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699019815850
+ value: 860803072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699019882541
+ value: 860459008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699021294040
+ value: 860942336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699023187799
+ value: 861093888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699023403253
+ value: 861634560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699024326511
+ value: 862175232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699025298313
+ value: 862605312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699026997572
+ value: 863145984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699027479465
+ value: 863686656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699028562066
+ value: 864301056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699028769057
+ value: 864940032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699029102594
+ value: 866848768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699029220351
+ value: 866979840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699029340549
+ value: 867504128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699029478082
+ value: 868093952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699029809584
+ value: 868601856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030133437
+ value: 868798464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030165338
+ value: 868995072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030190728
+ value: 869044224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030214166
+ value: 869093376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030231581
+ value: 869117952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030255222
+ value: 870690816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030293349
+ value: 872263680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030325453
+ value: 872656896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030347792
+ value: 873050112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030375217
+ value: 873148416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030395318
+ value: 873246720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030468804
+ value: 874819584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030502008
+ value: 877965312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030540297
+ value: 878161920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030556736
+ value: 878358528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030577651
+ value: 878751744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030600315
+ value: 879538176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030623997
+ value: 879587328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030664402
+ value: 879636480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030681817
+ value: 879734784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030697320
+ value: 879931392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030715915
+ value: 879955968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030731459
+ value: 879980544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030759006
+ value: 880029696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030776178
+ value: 880128000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030795221
+ value: 880140288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030812799
+ value: 880152576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030829075
+ value: 880177152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699030848972
+ value: 880226304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699031548883
+ value: 880750592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699032682834
+ value: 881209344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699032731093
+ value: 881283072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699032828383
+ value: 881291264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699042436212
+ value: 881971200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699042968276
+ value: 882462720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699051078708
+ value: 883118080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699051176039
+ value: 883499008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699051844781
+ value: 883867648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699053406956
+ value: 884412416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699054561944
+ value: 884817920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699055037774
+ value: 885338112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699056342340
+ value: 885862400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699057732802
+ value: 886497280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699060176487
+ value: 887033856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699064427911
+ value: 887623680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699069611464
+ value: 888487936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699072439752
+ value: 889278464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699072465631
+ value: 889675776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699072475234
+ value: 889679872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699073011122
+ value: 905351168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699073026218
+ value: 905355264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699073582004
+ value: 906539008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699073589817
+ value: 906543104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699076604587
+ value: 931909632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699076618707
+ value: 931913728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699076675103
+ value: 931917824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699076689630
+ value: 931921920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699077701633
+ value: 932184064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699077717014
+ value: 932188160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699078234511
+ value: 932290560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699078252130
+ value: 932294656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699078399753
+ value: 932397056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699078409885
+ value: 932401152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699078500095
+ value: 932413440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699078509413
+ value: 932417536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699078590468
+ value: 932429824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699078601373
+ value: 932433920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699078658217
+ value: 932839424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699078677016
+ value: 932851712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699078684421
+ value: 932855808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699078760064
+ value: 932876288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699078767226
+ value: 932880384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699078840997
+ value: 933081088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699078848850
+ value: 933085184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699078941786
+ value: 933400576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699078948419
+ value: 933404672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699079036920
+ value: 933421056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699079044895
+ value: 933425152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699079122939
+ value: 933527552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699079130263
+ value: 933531648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699079226169
+ value: 933826560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699079274631
+ value: 934289408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699079396213
+ value: 934887424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699080620782
+ value: 935022592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699081849908
+ value: 938926080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699081859430
+ value: 938930176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699082006646
+ value: 954601472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699082021498
+ value: 954605568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699083581069
+ value: 954609664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699083586155
+ value: 979976192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699083595554
+ value: 979980288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699083608534
+ value: 979984384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699083774306
+ value: 980246528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699083787611
+ value: 980250624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699085366876
+ value: 980353024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699085381850
+ value: 980357120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699085482843
+ value: 996028416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699085495701
+ value: 996032512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699085625706
+ value: 999936000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699085638848
+ value: 999940096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699085799737
+ value: 1000042496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699085818902
+ value: 1000046592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699085993341
+ value: 1000058880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699086001926
+ value: 1000062976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699086087823
+ value: 1000075264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699086094822
+ value: 1000079360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699086169488
+ value: 1000091648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699086177423
+ value: 1000095744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699086256768
+ value: 1000116224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699086264377
+ value: 1000120320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699087036106
+ value: 1000321024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699087050144
+ value: 1000325120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699087348931
+ value: 1000640512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699087368707
+ value: 1000644608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699087700697
+ value: 1000660992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699087710178
+ value: 1000665088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699087815606
+ value: 1000767488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699087827854
+ value: 1000771584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699087993381
+ value: 1001066496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699088100803
+ value: 1001529344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699088196384
+ value: 1001906176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699089298761
+ value: 1027272704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699089314630
+ value: 1027276800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699089355076
+ value: 1027280896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699089364516
+ value: 1027284992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699089646335
+ value: 1027547136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699089654555
+ value: 1027551232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699089892673
+ value: 1027653632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699089899428
+ value: 1027657728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090027276
+ value: 1027760128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090036350
+ value: 1027764224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090122206
+ value: 1027776512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090127903
+ value: 1027780608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090214369
+ value: 1027792896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090223199
+ value: 1027796992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090296604
+ value: 1027809280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090303928
+ value: 1027813376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090378391
+ value: 1027833856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090385797
+ value: 1027837952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090462335
+ value: 1028038656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090471490
+ value: 1028042752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090556980
+ value: 1028358144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090563612
+ value: 1028362240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090655125
+ value: 1028378624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090664402
+ value: 1028382720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090739597
+ value: 1028485120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090745863
+ value: 1028489216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090827895
+ value: 1044160512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090841038
+ value: 1044455424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090841567
+ value: 1044459520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090891086
+ value: 1044922368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090913547
+ value: 1045508096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090914849
+ value: 1049411584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699090933608
+ value: 1049415680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699091079807
+ value: 1049837568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699099723525
+ value: 1050406912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699114900445
+ value: 1050910720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699114968357
+ value: 1051500544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699115816461
+ value: 1051918336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699116709690
+ value: 1052516352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699117742852
+ value: 1052237824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699124032281
+ value: 1052811264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699125878961
+ value: 1053327360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699127047011
+ value: 1078693888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699127078831
+ value: 1078697984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699127370172
+ value: 1078943744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699131058933
+ value: 1078947840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699131070611
+ value: 1078951936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699131551121
+ value: 1078956032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699131617161
+ value: 1094627328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699131636082
+ value: 1094631424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699131663059
+ value: 1098534912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699131686415
+ value: 1098539008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699135659438
+ value: 1099304960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699138200860
+ value: 1100005376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699138678765
+ value: 1099743232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699141699599
+ value: 1104490496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699141699924
+ value: 1104494592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699141709934
+ value: 1104498688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699141710422
+ value: 1104502784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699141849542
+ value: 1106878464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699141860284
+ value: 1106882560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699141861016
+ value: 1107144704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699141869521
+ value: 1107148800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699142088393
+ value: 1107152896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699142110528
+ value: 1107156992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699142285740
+ value: 1107185664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699142299493
+ value: 1107189760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699142328342
+ value: 1107484672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699142397841
+ value: 1107947520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699143211277
+ value: 1114374144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699143225803
+ value: 1117589504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699143239353
+ value: 1117593600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699146087213
+ value: 1117859840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699146416355
+ value: 1118400512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699146774998
+ value: 1118670848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699146968154
+ value: 1119191040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699148249078
+ value: 1119129600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699148314141
+ value: 1118605312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699148367812
+ value: 1118081024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699151479628
+ value: 1118154752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699151741347
+ value: 1118105600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699152098565
+ value: 1118400512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699152243788
+ value: 1118670848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699152876153
+ value: 1119211520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699153298883
+ value: 1119752192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699154594374
+ value: 1121361920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699154638442
+ value: 1121226752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699154676975
+ value: 1120702464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699154727065
+ value: 1120178176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699154775445
+ value: 1119653888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699154994928
+ value: 1119764480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699155394179
+ value: 1120305152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699156176731
+ value: 1120182272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699156197076
+ value: 1119657984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699157170750
+ value: 1119768576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699158251560
+ value: 1120317440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699158583754
+ value: 1120874496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699158790704
+ value: 1121402880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699159201633
+ value: 1121665024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699160359714
+ value: 1122254848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699161004408
+ value: 1130278912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699161140395
+ value: 1130901504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699161483901
+ value: 1131208704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699161776503
+ value: 1133436928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699162050022
+ value: 1135075328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699162088962
+ value: 1135267840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699162158787
+ value: 1135841280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699162572931
+ value: 1137086464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699162702976
+ value: 1136992256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699162737156
+ value: 1136467968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699162783909
+ value: 1138237440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699162965997
+ value: 1139740672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699163220636
+ value: 1141239808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699163561252
+ value: 1143005184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699163925754
+ value: 1144381440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699163926243
+ value: 1144406016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699164271661
+ value: 1144799232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699165309421
+ value: 1176887296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699167884657
+ value: 1195143168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699168206313
+ value: 1195147264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699169003066
+ value: 1195405312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699170980727
+ value: 1208115200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699171500787
+ value: 1208631296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699171501397
+ value: 1208623104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699172069146
+ value: 1208848384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699174129775
+ value: 1209274368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699176505344
+ value: 1209765888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699177553766
+ value: 1213702144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699177567804
+ value: 1213706240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699177712660
+ value: 1215676416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699177721978
+ value: 1215680512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699178155572
+ value: 1216864256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699178166314
+ value: 1216868352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699178549696
+ value: 1217658880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699178574599
+ value: 1218056192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699178581882
+ value: 1218060288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699183524713
+ value: 1218670592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699183809259
+ value: 1219145728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699185824965
+ value: 1219727360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699188857639
+ value: 1220108288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699193946954
+ value: 1220657152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699197747613
+ value: 1236328448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699197766168
+ value: 1236332544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699200915704
+ value: 1236901888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699203399753
+ value: 1218646016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699203429986
+ value: 1218641920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699203605645
+ value: 1200386048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699203618626
+ value: 1200381952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699203968113
+ value: 1201008640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699203994683
+ value: 1201012736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699207472263
+ value: 1205174272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699207473403
+ value: 1205698560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699210996148
+ value: 1187442688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699211023655
+ value: 1187438592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699211211196
+ value: 1188065280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699211404677
+ value: 1188605952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699211507460
+ value: 1188876288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699212362237
+ value: 1189138432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699212378635
+ value: 1189142528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699212599745
+ value: 1193889792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699212665419
+ value: 1193893888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699212849461
+ value: 1196269568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699212858331
+ value: 1196273664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699213022800
+ value: 1196277760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699213042047
+ value: 1196793856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699213887465
+ value: 1215049728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699214063084
+ value: 1215053824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699216421360
+ value: 1215639552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699218079156
+ value: 1216151552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699219557753
+ value: 1220898816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699219584039
+ value: 1220902912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699219868219
+ value: 1223278592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699219890720
+ value: 1223282688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699220843479
+ value: 1228001280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699220872979
+ value: 1229180928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699220902805
+ value: 1229475840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699220926080
+ value: 1229549568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699220950860
+ value: 1229570048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699221111342
+ value: 1230053376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699221234836
+ value: 1232019456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699224888238
+ value: 1232785408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699226439589
+ value: 1233326080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699227278334
+ value: 1233661952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699228382460
+ value: 1251917824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699228790378
+ value: 1251921920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699229147353
+ value: 1251926016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699229155369
+ value: 1251930112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699230134128
+ value: 1253113856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699230145929
+ value: 1253117952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699230718357
+ value: 1253908480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699230745904
+ value: 1254305792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699230759047
+ value: 1254309888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699233084812
+ value: 1269981184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699233095717
+ value: 1269985280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699234480523
+ value: 1270435840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699235250339
+ value: 1270439936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699235259373
+ value: 1270444032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699235314101
+ value: 1275191296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699235320611
+ value: 1275195392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699235462294
+ value: 1275224064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699235480320
+ value: 1275228160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699235482232
+ value: 1277603840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699235492608
+ value: 1277607936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699235643365
+ value: 1277710336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699235667006
+ value: 1277714432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699235868829
+ value: 1277816832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699235888482
+ value: 1277820928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699236096409
+ value: 1277833216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699236111139
+ value: 1277837312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699236259047
+ value: 1277849600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699236271702
+ value: 1277853696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699236413059
+ value: 1277865984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699236427382
+ value: 1277870080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699236565728
+ value: 1277890560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699236577854
+ value: 1277894656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699236720147
+ value: 1278095360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699236734511
+ value: 1278099456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699236896010
+ value: 1278414848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699236907769
+ value: 1278418944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699237328627
+ value: 1278435328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699237337416
+ value: 1278439424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699237349623
+ value: 1283186688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699237377618
+ value: 1283190784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699237489150
+ value: 1283293184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699237503269
+ value: 1283297280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699237831109
+ value: 1283932160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699238393894
+ value: 1286307840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699238408827
+ value: 1286311936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699239075087
+ value: 1286983680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699239748346
+ value: 1285541888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699239845351
+ value: 1284198400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699239970025
+ value: 1282301952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699240085545
+ value: 1281261568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699241792983
+ value: 1299517440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699242014622
+ value: 1299521536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699242689223
+ value: 1306755072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699243316664
+ value: 1306492928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699244181777
+ value: 1305812992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699244893772
+ value: 1304948736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699244964410
+ value: 1304424448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699245309096
+ value: 1307041792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699245310276
+ value: 1307078656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699245966607
+ value: 1307070464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699246046319
+ value: 1306136576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699246442031
+ value: 1304027136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699247450331
+ value: 1304154112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699247582615
+ value: 1304596480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699247668878
+ value: 1305128960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699247972304
+ value: 1305767936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699248421441
+ value: 1306353664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699248613458
+ value: 1306816512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699248757908
+ value: 1307312128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699248940606
+ value: 1308495872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699248958469
+ value: 1308499968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699249299859
+ value: 1309052928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699249375217
+ value: 1309503488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699249522271
+ value: 1309958144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699249778049
+ value: 1310547968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699249797825
+ value: 1310392320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699250091323
+ value: 1309868032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699250138971
+ value: 1310019584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699250144586
+ value: 1309888512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699250304091
+ value: 1310035968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699250335545
+ value: 1309904896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699250786838
+ value: 1310695424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699250813124
+ value: 1311092736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699250824762
+ value: 1311096832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699251138279
+ value: 1311293440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699251409682
+ value: 1311064064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699251844985
+ value: 1344675840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699251898289
+ value: 1344974848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699252098321
+ value: 1345286144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699252358494
+ value: 1345933312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699252540378
+ value: 1346535424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699252637791
+ value: 1346871296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699254724216
+ value: 1348640768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699256320489
+ value: 1349066752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699256427708
+ value: 1349644288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699256428033
+ value: 1349308416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699257144464
+ value: 1349636096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699257255833
+ value: 1350098944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699257791681
+ value: 1350430720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699259768650
+ value: 1351114752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699262146824
+ value: 1351606272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699263581720
+ value: 1352237056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699263762180
+ value: 1352663040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699265270033
+ value: 1353199616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699265570733
+ value: 1353568256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699265722629
+ value: 1353469952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699266366998
+ value: 1359515648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699266367975
+ value: 1359630336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699266899672
+ value: 1375301632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699266912164
+ value: 1375305728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699267834853
+ value: 1376079872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699267963922
+ value: 1376350208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699268163629
+ value: 1376870400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699268462091
+ value: 1377636352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699268639500
+ value: 1377996800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699268931532
+ value: 1378537472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699269239394
+ value: 1379078144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699269421401
+ value: 1379594240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699269573989
+ value: 1380233216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699269891127
+ value: 1380773888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699270088800
+ value: 1381289984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699270224827
+ value: 1381703680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699270390354
+ value: 1382215680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699270499851
+ value: 1382543360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699270721246
+ value: 1383133184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699270959609
+ value: 1383641088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699271233168
+ value: 1384181760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699271367120
+ value: 1384185856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699271555841
+ value: 1384189952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699271563002
+ value: 1384673280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699271719130
+ value: 1385213952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699272090224
+ value: 1385754624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699272295058
+ value: 1386303488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699272486464
+ value: 1386881024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699272665663
+ value: 1387450368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699272840427
+ value: 1388023808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699272997369
+ value: 1388294144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699273386611
+ value: 1388834816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699273569513
+ value: 1389404160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699273786147
+ value: 1389965312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699273914809
+ value: 1390530560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699274071344
+ value: 1391108096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699274222060
+ value: 1391685632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699274406020
+ value: 1391976448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699274487197
+ value: 1394327552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699274610162
+ value: 1394913280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699275024306
+ value: 1395630080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699275232273
+ value: 1396060160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699275506240
+ value: 1396649984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699276107029
+ value: 1396948992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699276439019
+ value: 1397551104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699277377415
+ value: 1398165504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699277559503
+ value: 1398697984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699277829807
+ value: 1399066624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699278360772
+ value: 1399697408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699278651788
+ value: 1400184832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699278910984
+ value: 1400692736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699279741225
+ value: 1401290752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699279886244
+ value: 1401847808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699280083673
+ value: 1402376192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699280263116
+ value: 1402949632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699280463922
+ value: 1403346944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699280864882
+ value: 1403949056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699281101251
+ value: 1404514304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699281411025
+ value: 1404862464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699281714858
+ value: 1405460480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699282158298
+ value: 1406038016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699282390558
+ value: 1406410752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699282610488
+ value: 1406926848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699283498549
+ value: 1407520768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699283898411
+ value: 1408061440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699284288629
+ value: 1409245184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699284303725
+ value: 1409249280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699284316868
+ value: 1409818624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699284872491
+ value: 1410609152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699284903945
+ value: 1411006464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699284914117
+ value: 1411010560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699285230930
+ value: 1411555328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699285461725
+ value: 1411944448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699285747532
+ value: 1412530176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699285810927
+ value: 1429438464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699285978814
+ value: 1430032384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699286102146
+ value: 1430568960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699286435927
+ value: 1430908928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699286964654
+ value: 1431638016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699287332615
+ value: 1432178688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699287655735
+ value: 1432477696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699287898207
+ value: 1433030656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699288384820
+ value: 1433755648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699288584690
+ value: 1434071040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699288929295
+ value: 1434718208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699289261407
+ value: 1435312128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699289456272
+ value: 1435656192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699290156386
+ value: 1436188672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699291863702
+ value: 1436688384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699292391087
+ value: 1437368320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699292641412
+ value: 1437863936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699293550714
+ value: 1438253056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699294648980
+ value: 1453924352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699294660292
+ value: 1453928448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699295666518
+ value: 1454501888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699295907118
+ value: 1455104000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699295907566
+ value: 1456648192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699296058689
+ value: 1457184768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699296239597
+ value: 1457569792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699296240167
+ value: 1457311744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699296279189
+ value: 1457225728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699297479425
+ value: 1457881088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699297480320
+ value: 1458089984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699298070937
+ value: 1458593792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699298150974
+ value: 1458372608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699298204075
+ value: 1457831936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699298301121
+ value: 1457430528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699298634169
+ value: 1457512448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699299765232
+ value: 1458122752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699299969171
+ value: 1458511872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699300300429
+ value: 1459073024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699300480768
+ value: 1459597312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699300725234
+ value: 1460305920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699300822524
+ value: 1460613120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699300837742
+ value: 1460580352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699300898492
+ value: 1460707328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699302465671
+ value: 1461325824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699303606622
+ value: 1464127488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699303608005
+ value: 1464561664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699305148167
+ value: 1465962496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699305362400
+ value: 1466540032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699307924127
+ value: 1467092992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699307924778
+ value: 1467666432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699308449721
+ value: 1468207104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699308518040
+ value: 1468596224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699308546808
+ value: 1468506112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699308561578
+ value: 1468768256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699308822727
+ value: 1469149184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699309083510
+ value: 1469665280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699309481459
+ value: 1470320640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699310184950
+ value: 1470771200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699310669366
+ value: 1471262720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699310868463
+ value: 1471750144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699312230401
+ value: 1472266240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699313048394
+ value: 1472917504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699313556858
+ value: 1473437696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699313808730
+ value: 1473888256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699314853936
+ value: 1475493888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699315203993
+ value: 1476218880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699315421930
+ value: 1476538368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699315579563
+ value: 1477980160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699315633884
+ value: 1479794688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699315833307
+ value: 1480396800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699315872491
+ value: 1482305536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699315980930
+ value: 1482711040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699316050632
+ value: 1483366400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699316985203
+ value: 1483964416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699317619561
+ value: 1484496896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699317748020
+ value: 1484988416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699317749159
+ value: 1485467648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699317749444
+ value: 1485398016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699317951918
+ value: 1486581760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699317962905
+ value: 1486585856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699318155328
+ value: 1486618624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699318288059
+ value: 1487192064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699318536147
+ value: 1487679488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699318572646
+ value: 1487474688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699318667616
+ value: 1488228352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699319500868
+ value: 1489420288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699319501601
+ value: 1489911808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699320795139
+ value: 1490333696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699325086196
+ value: 1490186240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699326198378
+ value: 1490038784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699326439264
+ value: 1490538496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699327961847
+ value: 1506209792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699327974786
+ value: 1506213888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699331599461
+ value: 1506783232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699331661147
+ value: 1507299328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699334508274
+ value: 1507991552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699334881769
+ value: 1508704256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699335933689
+ value: 1509142528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699338360772
+ value: 1509675008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699338600641
+ value: 1510207488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699339321751
+ value: 1510633472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699339640029
+ value: 1511178240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699339781956
+ value: 1511718912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699339801243
+ value: 1511772160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699340465102
+ value: 1512357888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699340560805
+ value: 1512910848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699341426487
+ value: 1513558016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699341573663
+ value: 1513332736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699341590753
+ value: 1513349120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699341599216
+ value: 1513205760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699341627577
+ value: 1512800256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699341661147
+ value: 1511858176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699341713515
+ value: 1511723008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699341762709
+ value: 1510846464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699341858494
+ value: 1510580224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699342284316
+ value: 1510871040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699342295302
+ value: 1510682624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699343119155
+ value: 1510838272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699343383477
+ value: 1510608896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699344467665
+ value: 1510776832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699346410292
+ value: 1511256064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699346537530
+ value: 1511784448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699347004286
+ value: 1512411136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699349325372
+ value: 1512976384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699350691257
+ value: 1513340928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699350932672
+ value: 1514110976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699351105320
+ value: 1514647552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699351444838
+ value: 1515048960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699351912449
+ value: 1515663360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699352043105
+ value: 1515991040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699352234063
+ value: 1516552192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699352438124
+ value: 1517154304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699352739557
+ value: 1517735936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699352864475
+ value: 1518071808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699353915297
+ value: 1518731264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699354099542
+ value: 1519271936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699355081801
+ value: 1519865856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699355382135
+ value: 1520267264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699355613051
+ value: 1520758784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699357387669
+ value: 1521291264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699357737888
+ value: 1521885184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699358048720
+ value: 1522479104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699358197931
+ value: 1547845632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699358210707
+ value: 1547849728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699358358209
+ value: 1548378112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699359192722
+ value: 1548931072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699359356988
+ value: 1549201408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699359724827
+ value: 1549811712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699359962783
+ value: 1569550336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699360174330
+ value: 1570226176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699360463474
+ value: 1574129664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699360471490
+ value: 1574133760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699360743666
+ value: 1589805056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699360754002
+ value: 1589809152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699360884495
+ value: 1590161408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699361375991
+ value: 1590734848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699363572605
+ value: 1591255040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699363904474
+ value: 1591799808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699363997166
+ value: 1592983552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699364036879
+ value: 1592987648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699364805515
+ value: 1593704448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699366018080
+ value: 1594433536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699366018813
+ value: 1594925056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699366042535
+ value: 1595011072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699366123631
+ value: 1594982400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699366582737
+ value: 1595244544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699366625258
+ value: 1595281408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699366660943
+ value: 1595318272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699366681329
+ value: 1595355136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699366698215
+ value: 1595392000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699366937026
+ value: 1595428864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699368161594
+ value: 1595822080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699368181655
+ value: 1595801600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699368285170
+ value: 1595215872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699370679457
+ value: 1595678720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699373307387
+ value: 1596030976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699373309828
+ value: 1596137472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699373743870
+ value: 1596596224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699374043837
+ value: 1597317120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699376384780
+ value: 1597796352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699376841526
+ value: 1598525440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699377363255
+ value: 1599037440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699378000462
+ value: 1601585152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699378118544
+ value: 1602072576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699378237766
+ value: 1602105344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699378504612
+ value: 1602564096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699378938124
+ value: 1603104768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699379125543
+ value: 1603674112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699379302301
+ value: 1602035712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699379304376
+ value: 1602547712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699379443943
+ value: 1603121152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699379598403
+ value: 1603637248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699379709202
+ value: 1604169728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699379858331
+ value: 1604694016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699379862726
+ value: 1605181440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699380134902
+ value: 1605545984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699380215631
+ value: 1606057984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699380431736
+ value: 1606598656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699380521783
+ value: 1607319552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699380530247
+ value: 1607827456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699380734063
+ value: 1608368128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699380824762
+ value: 1608884224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699380977024
+ value: 1608949760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699381033502
+ value: 1609494528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699381090794
+ value: 1609953280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699381107029
+ value: 1610461184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699381427097
+ value: 1610981376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699381460097
+ value: 1611550720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699381644789
+ value: 1612091392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699381680027
+ value: 1612550144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699382304824
+ value: 1613074432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699382306817
+ value: 1613795328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699382775405
+ value: 1614254080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699382776544
+ value: 1614737408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699383224379
+ value: 1615216640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699383450982
+ value: 1615937536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699383674127
+ value: 1616412672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699383732883
+ value: 1616482304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699383799859
+ value: 1616551936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699383908136
+ value: 1617010688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699384182835
+ value: 1617494016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699384397678
+ value: 1617424384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699384414239
+ value: 1617948672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699384445408
+ value: 1617879040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699384456028
+ value: 1617813504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699384512831
+ value: 1617780736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699384643569
+ value: 1617801216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699384659682
+ value: 1618284544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699384913344
+ value: 1618743296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699385402765
+ value: 1618776064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699385405491
+ value: 1619234816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699385406305
+ value: 1619951616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699386149265
+ value: 1619517440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699386180393
+ value: 1618874368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699386236261
+ value: 1618939904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699386265639
+ value: 1619464192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699386267226
+ value: 1619939328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699386687229
+ value: 1621233664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699386745131
+ value: 1621745664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699386839247
+ value: 1622286336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699386983168
+ value: 1620635648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699387045058
+ value: 1618538496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699387108412
+ value: 1616441344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699387174168
+ value: 1614344192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699387196018
+ value: 1613590528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699388097060
+ value: 1614147584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699388212783
+ value: 1614688256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699388826593
+ value: 1614757888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699388903375
+ value: 1614827520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699389106703
+ value: 1614831616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699389126601
+ value: 1614835712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699389139500
+ value: 1614856192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699390789361
+ value: 1615339520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699390791396
+ value: 1615749120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699390937311
+ value: 1616932864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699390947076
+ value: 1616936960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699391941339
+ value: 1616957440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699392832574
+ value: 1617567744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699392882298
+ value: 1616441344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699392963352
+ value: 1616257024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699393056085
+ value: 1615482880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699393120782
+ value: 1614942208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699393209690
+ value: 1614061568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699393332411
+ value: 1613000704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699393350925
+ value: 1613246464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699393465346
+ value: 1612890112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699393514133
+ value: 1612431360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699393677464
+ value: 1612701696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699393910211
+ value: 1613242368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699394140639
+ value: 1613778944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699394376235
+ value: 1614319616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699394604343
+ value: 1614860288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699394828098
+ value: 1615400960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699395057143
+ value: 1615937536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699395289036
+ value: 1616478208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699395519220
+ value: 1617018880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699395728937
+ value: 1617559552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699395942478
+ value: 1618096128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699396915663
+ value: 1618640896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699397224623
+ value: 1619935232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699397369277
+ value: 1635606528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699397384169
+ value: 1635610624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699397575291
+ value: 1635926016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699398348769
+ value: 1636573184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699398570326
+ value: 1637113856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699398718723
+ value: 1637654528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699398860569
+ value: 1638195200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699399002944
+ value: 1638735872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699399163100
+ value: 1639272448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699399334771
+ value: 1639825408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699399485528
+ value: 1640366080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699399641127
+ value: 1640906752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699399717584
+ value: 1641172992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699399869521
+ value: 1641713664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699400104750
+ value: 1642254336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699400246433
+ value: 1642795008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699401230971
+ value: 1643331584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699401385268
+ value: 1643872256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699401550714
+ value: 1644412928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699401703342
+ value: 1644953600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699401857192
+ value: 1645490176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699405989109
+ value: 1646006272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699406001275
+ value: 1645879296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699406374485
+ value: 1645998080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699406383315
+ value: 1645883392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699407060642
+ value: 1646022656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699410420628
+ value: 1646514176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699410561497
+ value: 1647046656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699412222589
+ value: 1647460352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699412587823
+ value: 1648201728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699412873997
+ value: 1648529408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699413001438
+ value: 1649049600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699413494114
+ value: 1649582080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699413668593
+ value: 1650147328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699413857883
+ value: 1650728960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699414054498
+ value: 1651343360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699414161839
+ value: 1651683328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699414334202
+ value: 1652244480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699414523167
+ value: 1652838400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699414707574
+ value: 1653436416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699414813165
+ value: 1653772288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699415141982
+ value: 1654329344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699415507460
+ value: 1655578624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699416037123
+ value: 1656102912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699416037612
+ value: 1656762368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699416194431
+ value: 1657221120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699416194675
+ value: 1657704448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699416352797
+ value: 1658187776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699416529433
+ value: 1658843136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699416610691
+ value: 1659293696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699417236912
+ value: 1659789312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699417469863
+ value: 1660555264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699417653863
+ value: 1661095936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699417755466
+ value: 1661370368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699418880304
+ value: 1662033920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699418993259
+ value: 1662566400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699419233128
+ value: 1663107072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699420452651
+ value: 1664290816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699420464125
+ value: 1664294912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699422302667
+ value: 1663787008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699422486464
+ value: 1663406080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699426434422
+ value: 1663934464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699428347507
+ value: 1664835584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699429284845
+ value: 1665429504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699430697320
+ value: 1681100800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699430708225
+ value: 1681104896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699431885919
+ value: 1681514496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699432058323
+ value: 1682055168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699432228448
+ value: 1682595840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699432435479
+ value: 1682993152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699432588474
+ value: 1683529728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699432724745
+ value: 1684070400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699432867649
+ value: 1684611072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699433141290
+ value: 1685016576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699433262343
+ value: 1684291584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699433309422
+ value: 1684557824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699433351983
+ value: 1684406272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699433626886
+ value: 1684471808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699433877537
+ value: 1685012480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699434123020
+ value: 1685553152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699435262384
+ value: 1686102016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699435363173
+ value: 1686028288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699435415175
+ value: 1686536192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699435560357
+ value: 1687076864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699435714329
+ value: 1687617536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699435812473
+ value: 1688100864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699435844781
+ value: 1688735744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699436108372
+ value: 1689432064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699436752944
+ value: 1689948160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699437356948
+ value: 1690267648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699437655816
+ value: 1690808320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699437911188
+ value: 1691348992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699438181085
+ value: 1692053504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699438437636
+ value: 1692598272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699438565891
+ value: 1693011968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699438857232
+ value: 1693581312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699439134169
+ value: 1694126080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699439394667
+ value: 1694666752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699439660211
+ value: 1695207424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699439795058
+ value: 1695547392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699440093113
+ value: 1696092160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699440756687
+ value: 1696628736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699440935479
+ value: 1697169408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699441103692
+ value: 1697710080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699441191868
+ value: 1698127872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699441374119
+ value: 1698668544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699441555922
+ value: 1699282944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699442960178
+ value: 1699782656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699443631443
+ value: 1700241408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699444093398
+ value: 1700769792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699445813572
+ value: 1701048320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699446410130
+ value: 1702232064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699446423761
+ value: 1702236160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699446654026
+ value: 1702793216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699448854343
+ value: 1703284736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699450525201
+ value: 1703030784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699451177179
+ value: 1703534592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699451253798
+ value: 1703911424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699451374973
+ value: 1704415232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699451602105
+ value: 1704955904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699453762628
+ value: 1705615360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699455517674
+ value: 1705979904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699458127252
+ value: 1706655744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699460962213
+ value: 1707274240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699463163995
+ value: 1707634688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699463988173
+ value: 1707495424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699463988417
+ value: 1707708416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699465727553
+ value: 1708109824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699469368382
+ value: 1708666880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699472482070
+ value: 1710764032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699472484226
+ value: 1711370240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699472493788
+ value: 1727041536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699472506280
+ value: 1727045632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699474464247
+ value: 1727594496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699477711765
+ value: 1727574016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699477712050
+ value: 1727537152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699477734633
+ value: 1727516672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699477739190
+ value: 1727479808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699477749729
+ value: 1727442944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699477758722
+ value: 1727406080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699477766738
+ value: 1727369216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699478956923
+ value: 1725952000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699479017877
+ value: 1723854848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699479088963
+ value: 1722015744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699479130060
+ value: 1721757696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699479183160
+ value: 1720770560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699479215997
+ value: 1719660544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699479247410
+ value: 1718345728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699480178969
+ value: 1717563392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699480226536
+ value: 1715466240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699480280369
+ value: 1713369088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699480327244
+ value: 1711271936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699480359186
+ value: 1709355008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699481362359
+ value: 1708630016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699481430556
+ value: 1708240896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699481523045
+ value: 1707761664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699482614638
+ value: 1707208704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699482703058
+ value: 1706528768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699482733128
+ value: 1705984000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699482870742
+ value: 1705676800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699492033990
+ value: 1706860544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699492046848
+ value: 1706864640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699492047418
+ value: 1706954752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699492934869
+ value: 1722626048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699492951918
+ value: 1722630144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699493346328
+ value: 1704374272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699493374078
+ value: 1704370176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699493619195
+ value: 1705005056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699494299575
+ value: 1705529344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699495018731
+ value: 1706061824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699495615493
+ value: 1706532864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699496169122
+ value: 1707073536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699496714614
+ value: 1707552768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699497152602
+ value: 1708089344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699497711603
+ value: 1708642304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699497843967
+ value: 1708679168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699497890110
+ value: 1708716032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699497920750
+ value: 1708752896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699497953098
+ value: 1708789760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699498112563
+ value: 1708826624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699498198093
+ value: 1709465600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699498397800
+ value: 1709735936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699498799005
+ value: 1710276608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699499399387
+ value: 1710817280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699499843276
+ value: 1711357952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699500938897
+ value: 1711890432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699501619724
+ value: 1711894528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699501645359
+ value: 1711898624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699501659397
+ value: 1711919104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699502085911
+ value: 1712455680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699502508762
+ value: 1712996352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699502790419
+ value: 1713537024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699503351861
+ value: 1714077696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699503604425
+ value: 1714098176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699504806573
+ value: 1714532352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699505375787
+ value: 1715073024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699505873793
+ value: 1715613696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699506348240
+ value: 1716146176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699506503635
+ value: 1716056064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699507282200
+ value: 1716293632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699508314915
+ value: 1716314112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699508698582
+ value: 1716842496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699508799941
+ value: 1716862976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699509085952
+ value: 1717403648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699509241510
+ value: 1717686272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699509592991
+ value: 1718231040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699509959283
+ value: 1718775808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699510175104
+ value: 1719959552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699510190566
+ value: 1719963648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699511530165
+ value: 1720500224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699512588881
+ value: 1721040896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699512891534
+ value: 1721581568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699513213312
+ value: 1722122240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699513512587
+ value: 1722662912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699513764825
+ value: 1723203584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699514028253
+ value: 1723744256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699514390761
+ value: 1724280832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699514597955
+ value: 1724821504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699515004164
+ value: 1725362176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699515264378
+ value: 1725902848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699515509780
+ value: 1726443520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699515865086
+ value: 1726889984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699516116835
+ value: 1727430656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699516733087
+ value: 1727971328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699517088393
+ value: 1728372736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699518152724
+ value: 1728913408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699518830458
+ value: 1729449984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699519812392
+ value: 1729990656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699523247532
+ value: 1730502656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699523645522
+ value: 1730482176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699523680108
+ value: 1730461696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699523703505
+ value: 1730424832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699524311375
+ value: 1730465792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699524360528
+ value: 1730506752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699524392999
+ value: 1730547712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699524433486
+ value: 1730588672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699524584120
+ value: 1730629632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699525364231
+ value: 1746300928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699525393243
+ value: 1746305024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699525975926
+ value: 1746948096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699526599339
+ value: 1747488768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699526984633
+ value: 1747836928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699527583347
+ value: 1748377600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699527903823
+ value: 1748873216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699528517714
+ value: 1749413888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699529125421
+ value: 1749954560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699529312311
+ value: 1750667264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699529341974
+ value: 1750937600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699529701918
+ value: 1751650304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699529945001
+ value: 1752190976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699530167820
+ value: 1752588288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699530182875
+ value: 1752551424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699530214329
+ value: 1752514560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699530232273
+ value: 1752477696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699530244317
+ value: 1752440832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699530296279
+ value: 1752326144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699530332859
+ value: 1751801856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699530375299
+ value: 1751277568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699530430149
+ value: 1750753280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699530482639
+ value: 1750228992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699530553847
+ value: 1750208512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699530564182
+ value: 1749696512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699530691176
+ value: 1749159936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699530745416
+ value: 1748635648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699530816583
+ value: 1748119552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699530857721
+ value: 1747591168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699531282241
+ value: 1747709952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699531721409
+ value: 1748267008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699532183852
+ value: 1748807680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699532627700
+ value: 1749340160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699533035414
+ value: 1749876736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699533488865
+ value: 1750417408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699533914890
+ value: 1750958080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699534321181
+ value: 1751498752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699534711521
+ value: 1752035328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699535098443
+ value: 1752576000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699535485813
+ value: 1753116672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699535678115
+ value: 1753387008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699536158705
+ value: 1753923584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699536551243
+ value: 1754464256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699536956760
+ value: 1755004928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699537357232
+ value: 1755545600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699537793593
+ value: 1756082176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699538184015
+ value: 1756622848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699538690688
+ value: 1757163520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699538995782
+ value: 1757704192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699539136082
+ value: 1758109696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699539270237
+ value: 1758650368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699539409031
+ value: 1759191040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699539553562
+ value: 1759731712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699539690647
+ value: 1760268288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699539822931
+ value: 1760808960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699539972548
+ value: 1761349632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699540176284
+ value: 1761890304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699540325087
+ value: 1762426880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699540470188
+ value: 1762967552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699540623590
+ value: 1763508224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699540788466
+ value: 1764048896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699540964532
+ value: 1764585472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699541118951
+ value: 1765126144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699541287978
+ value: 1765666816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699541456964
+ value: 1766207488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699541501072
+ value: 1767391232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699541520929
+ value: 1767395328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699541629246
+ value: 1767936000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699541772149
+ value: 1768280064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699541963352
+ value: 1768816640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699542136733
+ value: 1769357312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699542333469
+ value: 1769897984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699542517714
+ value: 1770438656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699542687799
+ value: 1770975232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699542859104
+ value: 1771515904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699543036391
+ value: 1772056576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699543232884
+ value: 1772597248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699543412408
+ value: 1773133824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699543594212
+ value: 1773674496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699543757420
+ value: 1774215168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699543907729
+ value: 1774755840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699543988417
+ value: 1775026176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699544168919
+ value: 1775566848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699544319147
+ value: 1776107520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699544481093
+ value: 1776648192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699544909560
+ value: 1777025024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699545107721
+ value: 1777565696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699545297784
+ value: 1778106368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699545504083
+ value: 1778647040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699545701756
+ value: 1779187712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699545863987
+ value: 1779638272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699546041803
+ value: 1780178944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699546225356
+ value: 1780719616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699546408868
+ value: 1781260288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699546596531
+ value: 1781800960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699546787408
+ value: 1782341632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699546933486
+ value: 1782792192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699547115493
+ value: 1783332864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699547284601
+ value: 1783873536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699547459283
+ value: 1784414208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699547636285
+ value: 1784954880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699547777602
+ value: 1785405440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699555901463
+ value: 1784537088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699556079319
+ value: 1782439936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699556219293
+ value: 1780342784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699556345758
+ value: 1778245632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699556435927
+ value: 1776779264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699557911472
+ value: 1777438720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699559675714
+ value: 1777913856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699560644993
+ value: 1782050816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699561257949
+ value: 1782591488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699561985244
+ value: 1783402496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699562197605
+ value: 1783930880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699562355849
+ value: 1784471552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699562379897
+ value: 1800142848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699562399225
+ value: 1800146944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699563358209
+ value: 1800503296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699563760309
+ value: 1801031680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699563856866
+ value: 1801572352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699564322931
+ value: 1801453568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699564369277
+ value: 1800929280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699568997329
+ value: 1801437184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699568998549
+ value: 1801547776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699570622857
+ value: 1802096640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699570991957
+ value: 1802629120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699572877822
+ value: 1803276288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699573627903
+ value: 1803587584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699575015354
+ value: 1804771328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699575035699
+ value: 1804775424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699575602106
+ value: 1805381632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699577894952
+ value: 1805836288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699578736586
+ value: 1805869056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699578737726
+ value: 1805836288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699578794448
+ value: 1805869056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699578795302
+ value: 1805836288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699579008681
+ value: 1806471168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699579190566
+ value: 1807028224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699579376398
+ value: 1807634432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699579460260
+ value: 1807933440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699580165297
+ value: 1808535552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699580466160
+ value: 1809117184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699580656264
+ value: 1809715200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699580738580
+ value: 1810132992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699580986342
+ value: 1810685952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699581419122
+ value: 1811283968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699582414728
+ value: 1811304448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699582447158
+ value: 1811009536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699584763930
+ value: 1811173376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699584970961
+ value: 1811685376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699585314142
+ value: 1812324352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699585318862
+ value: 1813946368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699586784885
+ value: 1814474752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699590375624
+ value: 1814962176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699590379409
+ value: 1815502848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699591518691
+ value: 1815953408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699592184869
+ value: 1816477696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699592309747
+ value: 1817014272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699592514500
+ value: 1816580096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699592598240
+ value: 1817096192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699593004938
+ value: 1817706496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699593174859
+ value: 1818218496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699593274876
+ value: 1818750976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699593750095
+ value: 1834422272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699593760594
+ value: 1834426368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699593972182
+ value: 1834840064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699594151015
+ value: 1835380736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699594317397
+ value: 1835929600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699594485244
+ value: 1836470272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699594593845
+ value: 1836830720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699594737156
+ value: 1837346816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699594962416
+ value: 1837940736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699595106826
+ value: 1838493696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699595310113
+ value: 1839083520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699595580052
+ value: 1839644672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699595987766
+ value: 1840103424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699596470799
+ value: 1840504832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699596811049
+ value: 1841029120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699597465956
+ value: 1841713152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699599010268
+ value: 1842212864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699600898533
+ value: 1842790400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699606555027
+ value: 1843212288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699609331069
+ value: 1844396032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699609344252
+ value: 1844400128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699615888157
+ value: 1844994048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699616858046
+ value: 1845518336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699644654596
+ value: 1846702080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699644666355
+ value: 1846706176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699652306777
+ value: 1847263232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699674904352
+ value: 1848446976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699674920506
+ value: 1848451072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699676255670
+ value: 1848786944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699704570489
+ value: 1849970688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699704596368
+ value: 1849974784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699713337294
+ value: 1850699776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699720778741
+ value: 1850695680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699720889378
+ value: 1850691584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699720941909
+ value: 1850687488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699724099217
+ value: 1850683392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699724245050
+ value: 1832427520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699724764785
+ value: 1814171648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699724937840
+ value: 1795915776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699741289768
+ value: 1797099520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699741303318
+ value: 1797103616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699744184178
+ value: 1778847744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699744801772
+ value: 1779204096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699745555597
+ value: 1779773440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699746442194
+ value: 1780248576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699746443007
+ value: 1780191232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699746466282
+ value: 1779666944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699749218805
+ value: 1779773440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699749219863
+ value: 1779666944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699772903334
+ value: 1780850688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699772912734
+ value: 1780854784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699776833063
+ value: 1780924416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699776838841
+ value: 1780850688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699776926772
+ value: 1780879360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699806480686
+ value: 1782063104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699806492242
+ value: 1782067200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699811570856
+ value: 1782657024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699812392592
+ value: 1783160832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699815566868
+ value: 1783033856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699815774143
+ value: 1782509568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699816640110
+ value: 1782603776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699827547215
+ value: 1783095296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699839543308
+ value: 1784279040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699839558567
+ value: 1784283136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699873305149
+ value: 1785466880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699873322280
+ value: 1785470976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699881475763
+ value: 1786093568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699906209487
+ value: 1787277312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699906223159
+ value: 1787281408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699911142552
+ value: 1787723776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699911143569
+ value: 1787650048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699916406549
+ value: 1787801600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699916415664
+ value: 1787596800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699939526585
+ value: 1788780544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699939543553
+ value: 1788784640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699949965428
+ value: 1789075456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699975913141
+ value: 1790259200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699975930068
+ value: 1790263296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 699982261814
+ value: 1790574592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700030983006
+ value: 1806245888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700031005589
+ value: 1806249984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700036207737
+ value: 1807433728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700036234552
+ value: 1807437824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700038042454
+ value: 1813864448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700038073826
+ value: 1817079808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700038093642
+ value: 1817083904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700066947972
+ value: 1818267648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700066973240
+ value: 1818271744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700078732029
+ value: 1818894336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700080671604
+ value: 1819435008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700082990574
+ value: 1819205632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700083034926
+ value: 1818681344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700088226170
+ value: 1818877952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700102880752
+ value: 1820061696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700102903172
+ value: 1820065792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700135188938
+ value: 1821249536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700135214736
+ value: 1821253632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700167146987
+ value: 1822437376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700167171930
+ value: 1822441472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700177586155
+ value: 1822900224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700200888686
+ value: 1824083968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700200915379
+ value: 1824088064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700236903091
+ value: 1825271808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700236923680
+ value: 1825275904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700280277602
+ value: 1826459648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700280377090
+ value: 1826463744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700290035822
+ value: 1827098624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700317996515
+ value: 1828282368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700318047012
+ value: 1828286464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700332916396
+ value: 1828847616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700333997614
+ value: 1829388288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700336338597
+ value: 1829093376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700336374119
+ value: 1828601856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700360861058
+ value: 1829785600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700360894017
+ value: 1829789696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700378496515
+ value: 1830100992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700379323704
+ value: 1829847040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700379852309
+ value: 1830084608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700397902399
+ value: 1830608896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700397935236
+ value: 1830281216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700400417291
+ value: 1831464960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700400444269
+ value: 1831469056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700419454604
+ value: 1831636992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700420928929
+ value: 1832177664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700422208144
+ value: 1832718336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700423458511
+ value: 1832603648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700423507420
+ value: 1832079360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700423546361
+ value: 1831555072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700425223688
+ value: 1831653376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700447580011
+ value: 1832837120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700447604263
+ value: 1832841216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700461592747
+ value: 1833361408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700461595189
+ value: 1833259008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700464556940
+ value: 1833324544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700464560277
+ value: 1833246720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700486673395
+ value: 1834430464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700486701512
+ value: 1834434560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700512966282
+ value: 1834647552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700531761082
+ value: 1835831296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700531785740
+ value: 1835835392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700574500259
+ value: 1837019136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700574524876
+ value: 1837023232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700588912531
+ value: 1837592576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700595907729
+ value: 1847418880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700597058323
+ value: 1847947264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700598817479
+ value: 1847611392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700601380548
+ value: 1847955456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700601838312
+ value: 1847689216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700616755019
+ value: 1848872960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700616787612
+ value: 1848877056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700626369318
+ value: 1848942592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700665017837
+ value: 1850126336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700665046849
+ value: 1850130432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700702305190
+ value: 1851314176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700702332412
+ value: 1851318272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700726442113
+ value: 1851854848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700726457046
+ value: 1851797504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700727061213
+ value: 1852043264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700742487767
+ value: 1853227008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700742514256
+ value: 1853231104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700759868545
+ value: 1853575168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700760605239
+ value: 1854095360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700761637384
+ value: 1853960192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700771771051
+ value: 1854124032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700774481826
+ value: 1854664704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700775010594
+ value: 1853714432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700775092178
+ value: 1851617280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700775112767
+ value: 1851072512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700775623021
+ value: 1850560512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700775681940
+ value: 1848463360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700775748143
+ value: 1846366208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700775774795
+ value: 1845391360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700776574559
+ value: 1844211712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700776758682
+ value: 1842085888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700776792821
+ value: 1839988736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700776826309
+ value: 1837891584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700776858739
+ value: 1835794432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700776867853
+ value: 1835233280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700777824355
+ value: 1834614784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700777923192
+ value: 1833574400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700777947687
+ value: 1832996864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700778235814
+ value: 1830834176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700778587620
+ value: 1830375424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700778660659
+ value: 1829867520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700778716567
+ value: 1829408768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700778798883
+ value: 1828667392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700778905898
+ value: 1828118528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700778981908
+ value: 1827553280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700779183690
+ value: 1827233792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700779300511
+ value: 1825415168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700779347386
+ value: 1823318016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700779379368
+ value: 1821220864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700779410374
+ value: 1819123712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700779417414
+ value: 1818742784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700780398981
+ value: 1817587712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700780455581
+ value: 1815490560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700780487645
+ value: 1813393408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700780520238
+ value: 1811296256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700780543594
+ value: 1809760256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700781401138
+ value: 1809133568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700781432957
+ value: 1807036416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700781466160
+ value: 1804939264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700781498184
+ value: 1802842112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700781529434
+ value: 1800781824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700782489354
+ value: 1800503296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700784713597
+ value: 1799958528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700784795384
+ value: 1799434240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700785993952
+ value: 1800617984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700786021133
+ value: 1800622080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700804689061
+ value: 1800765440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700804704198
+ value: 1800622080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700829115290
+ value: 1801805824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700829156712
+ value: 1801809920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700853283177
+ value: 1801912320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700853288101
+ value: 1801891840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700879906183
+ value: 1801940992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700923672622
+ value: 1802510336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 700982881200
+ value: 1803108352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701022799006
+ value: 1803730944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701065248428
+ value: 1804095488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701067338556
+ value: 1804619776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701069166478
+ value: 1805205504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701075830825
+ value: 1805709312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701076295425
+ value: 1806249984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701078812393
+ value: 1806790656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701081393936
+ value: 1806532608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701081497777
+ value: 1806008320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701081584162
+ value: 1805484032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701110999201
+ value: 1805733888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701112766616
+ value: 1806274560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701117685847
+ value: 1806782464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701117713516
+ value: 1806589952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701117822484
+ value: 1806065664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701117899958
+ value: 1805541376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701119315851
+ value: 1805639680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701119317560
+ value: 1805524992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701141893407
+ value: 1805832192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701180204523
+ value: 1806139392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701204486424
+ value: 1806077952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701233961481
+ value: 1806307328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701273032689
+ value: 1806684160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701287335912
+ value: 1806823424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701311318212
+ value: 1807417344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701313178563
+ value: 1807958016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701314174901
+ value: 1808498688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701315942723
+ value: 1808277504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701316207412
+ value: 1807757312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701316306167
+ value: 1807253504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701316689265
+ value: 1807306752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701316690241
+ value: 1807278080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701317116226
+ value: 1807360000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701317125259
+ value: 1807253504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701320964859
+ value: 1807302656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701320967626
+ value: 1807273984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701322938532
+ value: 1807503360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701354066218
+ value: 1807880192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701356263158
+ value: 1807728640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701362785049
+ value: 1807818752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701362790298
+ value: 1807691776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701403898086
+ value: 1807986688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701407443781
+ value: 1807720448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701411852676
+ value: 1807974400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701490771133
+ value: 1808420864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701532972020
+ value: 1809022976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701533224624
+ value: 1808760832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701538551203
+ value: 1808912384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701607878555
+ value: 1809489920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701618474380
+ value: 1809920000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701618479589
+ value: 1809825792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701699493993
+ value: 1809940480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701749857763
+ value: 1810489344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701752898371
+ value: 1810325504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701781680110
+ value: 1810440192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701871989273
+ value: 1811189760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701875691950
+ value: 1811599360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701877809138
+ value: 1812140032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701885514338
+ value: 1812680704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701886072850
+ value: 1812430848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701886246150
+ value: 1811906560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701886398168
+ value: 1811382272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701918165909
+ value: 1811709952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701920160131
+ value: 1812250624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701923081151
+ value: 1811984384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701923185074
+ value: 1811460096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 701949085261
+ value: 1811542016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702037419205
+ value: 1812262912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702043311620
+ value: 1812660224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702045342748
+ value: 1812475904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702125382869
+ value: 1812668416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702125413956
+ value: 1812492288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702125991877
+ value: 1812553728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702125994563
+ value: 1812516864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702130385229
+ value: 1812553728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702130390600
+ value: 1812520960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702132683772
+ value: 1812742144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702138343155
+ value: 1813274624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702141068293
+ value: 1813696512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702141085587
+ value: 1813544960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702141159358
+ value: 1813020672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702141224543
+ value: 1813278720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702143928197
+ value: 1813856256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702145126439
+ value: 1814396928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702152152522
+ value: 1814142976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702152276545
+ value: 1813618688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702159110855
+ value: 1813692416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702214448705
+ value: 1814179840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702214454971
+ value: 1814089728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702230103246
+ value: 1814003712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702239288712
+ value: 1814052864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702257873754
+ value: 1814319104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702289218806
+ value: 1814650880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702321948217
+ value: 1815281664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702323664444
+ value: 1815142400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702336791519
+ value: 1815281664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702336818944
+ value: 1815113728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702343374568
+ value: 1815379968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702345048721
+ value: 1815117824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702372726578
+ value: 1815183360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702381785294
+ value: 1815756800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702384180883
+ value: 1815568384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702387411596
+ value: 1815736320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702388708064
+ value: 1815601152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702430157852
+ value: 1815842816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702430902563
+ value: 1815691264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702467291764
+ value: 1815924736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702472669734
+ value: 1816436736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702514189835
+ value: 1816801280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702544192887
+ value: 1817296896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702595431941
+ value: 1817796608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702678916275
+ value: 1818333184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702678921931
+ value: 1818275840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702685629776
+ value: 1818505216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702689488256
+ value: 1819041792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702691517797
+ value: 1818722304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702724324967
+ value: 1818857472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702802305395
+ value: 1819377664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702802308609
+ value: 1819344896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702802508764
+ value: 1819377664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702802510351
+ value: 1819344896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702814438533
+ value: 1819856896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702842481339
+ value: 1819889664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702842485123
+ value: 1819856896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702842689021
+ value: 1819889664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702842690771
+ value: 1819856896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702889041398
+ value: 1819889664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702889044246
+ value: 1819856896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702889208675
+ value: 1819889664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702889209977
+ value: 1819856896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702925255753
+ value: 1820577792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702927101456
+ value: 1820610560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702927104752
+ value: 1820577792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702927327978
+ value: 1820610560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702927329687
+ value: 1820577792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702968116959
+ value: 1820610560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702968121761
+ value: 1820577792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702968345190
+ value: 1820610560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702968346858
+ value: 1820577792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702987183243
+ value: 1820946432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702987186824
+ value: 1820856320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 702987515275
+ value: 1821036544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703014967626
+ value: 1821077504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703014971044
+ value: 1821044736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703015197037
+ value: 1821077504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703015199153
+ value: 1821044736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703056000830
+ value: 1821077504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703056046362
+ value: 1821044736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703056287573
+ value: 1821077504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703056289729
+ value: 1821044736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703060541927
+ value: 1821487104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703099307267
+ value: 1821519872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703099310034
+ value: 1821487104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703099451228
+ value: 1821519872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703099452408
+ value: 1821487104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703137023087
+ value: 1821519872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703137026790
+ value: 1821487104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703137174251
+ value: 1821519872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703137175309
+ value: 1821487104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703139800512
+ value: 1822220288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703141580908
+ value: 1822232576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703141642390
+ value: 1821839360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703146167781
+ value: 1821974528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703232287939
+ value: 1822519296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703232291967
+ value: 1822486528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703233491878
+ value: 1822711808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703272421158
+ value: 1823047680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703368347062
+ value: 1823780864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703370606502
+ value: 1824133120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703370609106
+ value: 1824063488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703370673030
+ value: 1823539200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703381065364
+ value: 1823551488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703381069637
+ value: 1823531008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703406888077
+ value: 1823580160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703447542659
+ value: 1824182272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703447546159
+ value: 1824055296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703458759822
+ value: 1824227328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703465550675
+ value: 1824768000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703468642838
+ value: 1825124352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703468644995
+ value: 1825054720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703468709122
+ value: 1824489472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703468825659
+ value: 1823940608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703472274145
+ value: 1823481856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703472435563
+ value: 1822957568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703524813086
+ value: 1823047680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703613315649
+ value: 1823711232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703668602189
+ value: 1824186368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703696449194
+ value: 1824604160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703696452083
+ value: 1824571392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703699177018
+ value: 1824808960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703756861833
+ value: 1825161216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703798816341
+ value: 1825800192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703800147436
+ value: 1825533952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703801463721
+ value: 1825660928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703823249853
+ value: 1826213888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703823253719
+ value: 1826152448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703857990128
+ value: 1826160640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703869241634
+ value: 1826881536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 703909267025
+ value: 1827246080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704005050675
+ value: 1827790848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704088355037
+ value: 1828257792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704161944881
+ value: 1828818944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704171659237
+ value: 1828790272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704208359473
+ value: 1829285888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704208363664
+ value: 1829228544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704214148210
+ value: 1829257216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704227383927
+ value: 1829453824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704254375627
+ value: 1829445632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704258300716
+ value: 1829814272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704341212175
+ value: 1830526976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704367806291
+ value: 1830535168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704368874732
+ value: 1830526976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704387245988
+ value: 1830887424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704451145890
+ value: 1830899712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704471861141
+ value: 1831505920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704504973487
+ value: 1832099840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704505489234
+ value: 1831837696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704551547258
+ value: 1831936000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704582488338
+ value: 1832562688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704632823950
+ value: 1832964096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704632827409
+ value: 1832927232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704637224829
+ value: 1833115648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704637248308
+ value: 1832931328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704676371314
+ value: 1832996864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704686586239
+ value: 1833545728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704724282935
+ value: 1834184704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704725831356
+ value: 1834725376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704727714494
+ value: 1835225088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704729040869
+ value: 1835765760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704730233090
+ value: 1836306432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704731406307
+ value: 1836847104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704733396338
+ value: 1837387776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704742473365
+ value: 1837928448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704748623226
+ value: 1838260224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704749110734
+ value: 1838792704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704749613990
+ value: 1839448064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704749856706
+ value: 1839988736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704750129370
+ value: 1840435200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704759527645
+ value: 1840857088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704785164405
+ value: 1841451008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704791063656
+ value: 1841987584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704795011898
+ value: 1841750016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704795112118
+ value: 1841225728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704839255510
+ value: 1841364992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704899367855
+ value: 1841917952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704934766862
+ value: 1842315264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704949005144
+ value: 1842806784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704949009416
+ value: 1842704384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 704988642391
+ value: 1842929664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705028383318
+ value: 1843408896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705028389055
+ value: 1843281920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705058056739
+ value: 1843412992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705121780697
+ value: 1843855360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705121786353
+ value: 1843826688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705150583106
+ value: 1843875840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705181778459
+ value: 1844445184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705181781836
+ value: 1844342784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705187477474
+ value: 1844420608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705187482927
+ value: 1844350976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705191101417
+ value: 1844572160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705193927344
+ value: 1845096448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705202504818
+ value: 1845637120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705207162045
+ value: 1845313536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705207328508
+ value: 1844789248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705229882341
+ value: 1844940800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705275365902
+ value: 1845559296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705367449765
+ value: 1846005760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705454442359
+ value: 1846476800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705454449968
+ value: 1846358016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705462525001
+ value: 1846513664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705576656186
+ value: 1847164928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705608465268
+ value: 1847681024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705617937965
+ value: 1848074240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705620549578
+ value: 1848614912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705622999488
+ value: 1848455168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705623078223
+ value: 1847930880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705657551409
+ value: 1848049664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705661828997
+ value: 1848582144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705754203346
+ value: 1849102336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705754207333
+ value: 1849044992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705774983049
+ value: 1849212928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705824076555
+ value: 1849630720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705836421851
+ value: 1850195968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705839486834
+ value: 1850109952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705866974382
+ value: 1850626048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705866978858
+ value: 1850564608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705921965593
+ value: 1850826752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 705952636004
+ value: 1851166720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706038460507
+ value: 1851637760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706072660865
+ value: 1851699200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706126758684
+ value: 1852416000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706178482968
+ value: 1852854272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706181131813
+ value: 1853394944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706183839983
+ value: 1853935616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706187394630
+ value: 1853919232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706187745745
+ value: 1853763584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706187826596
+ value: 1853239296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706187902442
+ value: 1852715008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706214914690
+ value: 1852964864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706251251889
+ value: 1853276160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706265588681
+ value: 1853779968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706282925758
+ value: 1853796352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706307455502
+ value: 1854337024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706347048846
+ value: 1854971904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706350918393
+ value: 1855512576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706351454404
+ value: 1855291392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706351526995
+ value: 1853865984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706351549171
+ value: 1852928000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706351858294
+ value: 1851863040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706351970965
+ value: 1851600896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706351985125
+ value: 1850937344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706352327369
+ value: 1850011648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706354886207
+ value: 1849524224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706354986508
+ value: 1848999936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706387580665
+ value: 1849126912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706387583310
+ value: 1849049088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706388928321
+ value: 1849204736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706388947120
+ value: 1848971264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706414025734
+ value: 1849077760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706487769264
+ value: 1849675776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706564130877
+ value: 1850204160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706564153704
+ value: 1850118144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706587408831
+ value: 1850191872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706634661435
+ value: 1850675200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706634664568
+ value: 1850630144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706637145769
+ value: 1850863616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706643275856
+ value: 1851367424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706643321754
+ value: 1851064320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706671606341
+ value: 1851191296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706758970599
+ value: 1851756544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706769404355
+ value: 1852329984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706856233823
+ value: 1852776448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706937210670
+ value: 1853378560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 706970161069
+ value: 1853812736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707068959165
+ value: 1854369792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707203842099
+ value: 1855037440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707235486142
+ value: 1855578112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707247156512
+ value: 1855946752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707271491514
+ value: 1856471040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707275602435
+ value: 1856450560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707281363991
+ value: 1856991232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707281367002
+ value: 1856921600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707282121885
+ value: 1857114112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707286859678
+ value: 1857519616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707286863869
+ value: 1857437696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707289370420
+ value: 1857462272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707306751727
+ value: 1857466368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707365472796
+ value: 1858166784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707408927712
+ value: 1858580480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707408949847
+ value: 1858502656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707436852394
+ value: 1858527232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707436861224
+ value: 1858506752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707437083880
+ value: 1858576384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707528380877
+ value: 1859063808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707620878395
+ value: 1859620864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707620900938
+ value: 1859526656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707633882179
+ value: 1859776512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707652326841
+ value: 1860112384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707747366026
+ value: 1860775936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707755741595
+ value: 1861316608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707757906390
+ value: 1861050368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707830149391
+ value: 1861263360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707870941262
+ value: 1861709824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707870961525
+ value: 1861627904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707872966612
+ value: 1861894144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707874491717
+ value: 1861636096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707876471291
+ value: 1861902336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707882356423
+ value: 1862438912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707883032204
+ value: 1862074368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707887284239
+ value: 1862197248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707887287697
+ value: 1862176768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707887490253
+ value: 1862434816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707890527525
+ value: 1862791168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707900645933
+ value: 1862651904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707900743467
+ value: 1862127616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707909136696
+ value: 1862209536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707909140196
+ value: 1862144000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707925887022
+ value: 1862258688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707993177508
+ value: 1862729728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 707999485207
+ value: 1863266304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708001115253
+ value: 1863806976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708010107969
+ value: 1864335360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708011056171
+ value: 1864880128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708014879453
+ value: 1865420800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708017729958
+ value: 1865953280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708019454364
+ value: 1865740288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708019520445
+ value: 1865216000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708075454160
+ value: 1865342976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708124317320
+ value: 1865965568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708206152484
+ value: 1866379264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708295119688
+ value: 1867087872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708337136778
+ value: 1867436032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708459599913
+ value: 1867952128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708469194843
+ value: 1868505088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708591571267
+ value: 1869045760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708651104226
+ value: 1869680640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708691632383
+ value: 1870049280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708691639464
+ value: 1870045184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708693861876
+ value: 1870221312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708806896544
+ value: 1870598144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708863321877
+ value: 1871241216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708875760435
+ value: 1870995456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708891026549
+ value: 1871261696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708893525409
+ value: 1871642624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708894889464
+ value: 1872171008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708899206399
+ value: 1872711680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708906840717
+ value: 1873272832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708906866799
+ value: 1873068032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708906970966
+ value: 1872543744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708907119241
+ value: 1872023552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708909289366
+ value: 1872318464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708914313455
+ value: 1872850944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708918942930
+ value: 1873383424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708925418923
+ value: 1873924096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708927333718
+ value: 1874317312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708927349221
+ value: 1874128896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708927401264
+ value: 1873604608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708927445006
+ value: 1873080320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708927510028
+ value: 1872556032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708927563210
+ value: 1872035840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708931852883
+ value: 1872154624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708936776671
+ value: 1872691200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708943898456
+ value: 1873412096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708948061379
+ value: 1873948672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708948901589
+ value: 1873690624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708949801654
+ value: 1873797120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708949803933
+ value: 1873694720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708949872618
+ value: 1873170432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708949963438
+ value: 1872646144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708957595762
+ value: 1872912384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708963139464
+ value: 1873551360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708967080829
+ value: 1874018304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708967691954
+ value: 1873752064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708969051044
+ value: 1874018304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708976629779
+ value: 1873825792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708976847960
+ value: 1874071552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708978031228
+ value: 1874608128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708980510598
+ value: 1875144704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708981017841
+ value: 1875415040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708985293313
+ value: 1875955712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708991306903
+ value: 1876717568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708992221007
+ value: 1876987904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708993355528
+ value: 1877516288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708998965188
+ value: 1877401600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708999010354
+ value: 1876877312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708999071470
+ value: 1876353024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708999135679
+ value: 1875828736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708999192808
+ value: 1875304448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 708999245014
+ value: 1874825216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709000492410
+ value: 1875091456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709000924132
+ value: 1874825216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709001424579
+ value: 1874923520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709001425841
+ value: 1874870272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709001699848
+ value: 1874886656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709001700743
+ value: 1874849792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709002545551
+ value: 1875091456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709003651427
+ value: 1875632128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709005451353
+ value: 1876058112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709006651142
+ value: 1876598784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709011970844
+ value: 1876361216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709012050027
+ value: 1875836928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709012523782
+ value: 1875312640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709013101866
+ value: 1875456000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709013284036
+ value: 1878605824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709013302428
+ value: 1878609920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709014782367
+ value: 1879171072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709016529641
+ value: 1879805952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709017448505
+ value: 1882955776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709017473733
+ value: 1882959872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709017511168
+ value: 1883013120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709017681619
+ value: 1883017216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709017737771
+ value: 1883021312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709017776915
+ value: 1883025408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709017868223
+ value: 1883029504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709017916726
+ value: 1883033600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709017956480
+ value: 1883037696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709017996316
+ value: 1883041792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709018035216
+ value: 1883045888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709018079080
+ value: 1883049984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709018111347
+ value: 1883602944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709018121763
+ value: 1883607040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709019108702
+ value: 1884790784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709019645526
+ value: 1885974528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709019977110
+ value: 1887158272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709020420022
+ value: 1889722368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709020631855
+ value: 1890906112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709024808775
+ value: 1892089856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709025272602
+ value: 1893273600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709027460793
+ value: 1893830656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709029362771
+ value: 1894100992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709029545103
+ value: 1897250816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709029568582
+ value: 1897254912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709030308531
+ value: 1898242048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709042034931
+ value: 1898983424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709043301370
+ value: 1899466752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709057064879
+ value: 1915138048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709057088764
+ value: 1915142144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709059206480
+ value: 1915650048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709060034524
+ value: 1916055552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709068575580
+ value: 1916637184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709076143980
+ value: 1916436480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709076254657
+ value: 1915981824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709076449970
+ value: 1915457536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709076636982
+ value: 1914933248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709076805317
+ value: 1914408960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709080578876
+ value: 1914593280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709083055927
+ value: 1915195392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709085240050
+ value: 1915551744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709086885557
+ value: 1916096512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709088830911
+ value: 1931767808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709088859719
+ value: 1931771904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709089332091
+ value: 1932296192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709092589252
+ value: 1932820480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709093052712
+ value: 1933361152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709093835509
+ value: 1933901824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709094223285
+ value: 1934319616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709095599709
+ value: 1934860288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709096700214
+ value: 1935400960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709097517719
+ value: 1936052224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709097746438
+ value: 1936580608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709097851988
+ value: 1936986112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709098061339
+ value: 1937526784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709098273822
+ value: 1938067456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709098485492
+ value: 1938608128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709098696837
+ value: 1939148800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709103565245
+ value: 1939742720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709104810199
+ value: 1940197376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709106965636
+ value: 1940738048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709109063414
+ value: 1941229568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709113601012
+ value: 1941905408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709114193744
+ value: 1942429696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709114706847
+ value: 1942151168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709114852476
+ value: 1941630976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709114995339
+ value: 1941106688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709115157774
+ value: 1940582400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709116744281
+ value: 1940619264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709116750019
+ value: 1940570112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709117095640
+ value: 1940643840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709120101174
+ value: 1941348352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709120827004
+ value: 1941712896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709121700173
+ value: 1942224896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709122638365
+ value: 1942114304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709123209980
+ value: 1942224896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709124733254
+ value: 1942851584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709124769184
+ value: 1942573056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709125509540
+ value: 1942724608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709125511575
+ value: 1942675456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709125901264
+ value: 1942740992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709125902891
+ value: 1942679552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709126205382
+ value: 1942712320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709126206602
+ value: 1942671360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709126536965
+ value: 1942740992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709126538186
+ value: 1942671360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709126942971
+ value: 1942900736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709127372659
+ value: 1943437312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709128710020
+ value: 1943977984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709128782327
+ value: 1944330240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709130282083
+ value: 1944195072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709130332253
+ value: 1943670784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709130808206
+ value: 1959342080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709130868264
+ value: 1959346176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709131347838
+ value: 1959591936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709131997089
+ value: 1959993344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709132253844
+ value: 1959878656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709132690693
+ value: 1959993344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709132997618
+ value: 1960534016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709133634906
+ value: 1961209856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709134034972
+ value: 1961611264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709135867817
+ value: 1962283008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709137171690
+ value: 1962823680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709139518329
+ value: 1963249664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709141859638
+ value: 1963048960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709141914732
+ value: 1962524672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709141990904
+ value: 1962000384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709142050352
+ value: 1961476096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709143785378
+ value: 1961725952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709144115619
+ value: 1962774528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709144484272
+ value: 1963102208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709146783751
+ value: 1963855872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709147970030
+ value: 1964396544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709150143044
+ value: 1964789760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709150634988
+ value: 1965350912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709151803648
+ value: 1965166592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709151855365
+ value: 1964642304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709151914936
+ value: 1964118016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709153355528
+ value: 1964232704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709153366189
+ value: 1964064768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709156100238
+ value: 1964314624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709156717629
+ value: 1964097536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709156994078
+ value: 1964167168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709156999164
+ value: 1964122112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709157128722
+ value: 1964154880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709157129698
+ value: 1964134400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709157199075
+ value: 1964154880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709163351012
+ value: 1967304704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709163372048
+ value: 1967308800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709163821593
+ value: 1967886336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709165744404
+ value: 1968451584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709165745990
+ value: 1968357376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709169286396
+ value: 1968517120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709175891498
+ value: 1969012736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709177522642
+ value: 1969541120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709179359272
+ value: 1969426432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709179453062
+ value: 1968906240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709179521869
+ value: 1968381952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709179701516
+ value: 1967853568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709179799254
+ value: 1967329280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709179821267
+ value: 1967431680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709179837380
+ value: 1967333376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709179936583
+ value: 1966809088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709180056008
+ value: 1966284800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709180138040
+ value: 1965760512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709180198871
+ value: 1964675072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709180287820
+ value: 1964195840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709180388813
+ value: 1963663360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709180462584
+ value: 1963139072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709180532164
+ value: 1962614784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709180610533
+ value: 1962090496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709180669086
+ value: 1961218048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709180686868
+ value: 1959120896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709180691222
+ value: 1958617088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709180851134
+ value: 1956474880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709180888446
+ value: 1954377728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709180924132
+ value: 1952280576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709180961160
+ value: 1950183424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709180969135
+ value: 1949761536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709181457945
+ value: 1948221440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709181484028
+ value: 1946124288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709181527851
+ value: 1944027136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709181554340
+ value: 1941929984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709181567564
+ value: 1940905984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709182016905
+ value: 1941286912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709182067157
+ value: 1940291584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709182100849
+ value: 1939070976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709182124042
+ value: 1938128896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709182389586
+ value: 1936953344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709182422708
+ value: 1935560704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709182434630
+ value: 1935065088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709182685403
+ value: 1934741504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709182738178
+ value: 1933955072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709182795429
+ value: 1932906496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709182800963
+ value: 1932644352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709182920063
+ value: 1931071488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709182939635
+ value: 1930285056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709183101093
+ value: 1929760768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709183114602
+ value: 1929236480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709183228738
+ value: 1927925760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709183364439
+ value: 1927389184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709183458596
+ value: 1925029888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709183506163
+ value: 1922932736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709183540465
+ value: 1921089536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709183579283
+ value: 1919045632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709183615172
+ value: 1916948480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709183647439
+ value: 1914851328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709183683653
+ value: 1912754176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709183712706
+ value: 1910870016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709183739480
+ value: 1908953088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709183754739
+ value: 1908064256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709183763650
+ value: 1907544064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709185295429
+ value: 1907720192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709189248920
+ value: 1908260864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709192608499
+ value: 1908748288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709195632628
+ value: 1908375552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709196440489
+ value: 1908637696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709198173033
+ value: 1909178368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709200586363
+ value: 1909719040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709200905943
+ value: 1910255616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709201466856
+ value: 1910755328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709201668272
+ value: 1911275520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709202073993
+ value: 1911975936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709202319111
+ value: 1911644160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709202336038
+ value: 1911906304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709202362446
+ value: 1911681024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709203194070
+ value: 1911881728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709204604796
+ value: 1912557568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709205350320
+ value: 1912999936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709205653949
+ value: 1913405440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709208368630
+ value: 1913937920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709208777932
+ value: 1914593280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709209257506
+ value: 1915097088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709209660338
+ value: 1915637760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709210107156
+ value: 1916149760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709210507099
+ value: 1916682240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709211268655
+ value: 1917222912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709212148416
+ value: 1917739008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709212367491
+ value: 1918173184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709212544290
+ value: 1918746624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709212745136
+ value: 1919225856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709213184548
+ value: 1919889408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709213275043
+ value: 1920208896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709213601378
+ value: 1920765952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709213991881
+ value: 1921363968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709214040872
+ value: 1921896448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709214575540
+ value: 1922490368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709214800434
+ value: 1922789376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709216289488
+ value: 1923465216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709217303241
+ value: 1923960832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709217920714
+ value: 1924558848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709221731708
+ value: 1925115904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709222093687
+ value: 1925644288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709222738829
+ value: 1926115328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709223446837
+ value: 1926582272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709223851174
+ value: 1927118848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709224702940
+ value: 1927569408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709227876850
+ value: 1928105984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709243187315
+ value: 1928667136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709244634581
+ value: 1929166848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709244864928
+ value: 1929682944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709245278136
+ value: 1930190848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709245460631
+ value: 1930686464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709245737039
+ value: 1931202560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709246183450
+ value: 1931718656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709246412169
+ value: 1932238848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709246857237
+ value: 1932771328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709247080422
+ value: 1933295616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709247494607
+ value: 1933824000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709247757750
+ value: 1934352384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709247940082
+ value: 1934864384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709248226744
+ value: 1935372288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709248413552
+ value: 1935900672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709248688251
+ value: 1936416768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709248919330
+ value: 1936936960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709249636168
+ value: 1937473536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709249937641
+ value: 1937985536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709250512389
+ value: 1938767872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709250734353
+ value: 1939034112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709250936095
+ value: 1939562496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709251433043
+ value: 1940094976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709251856383
+ value: 1940631552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709252203632
+ value: 1941155840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709254661396
+ value: 1941757952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709254909727
+ value: 1942269952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709255387633
+ value: 1942798336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709255849384
+ value: 1943322624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709256123025
+ value: 1943826432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709256469013
+ value: 1944358912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709259870380
+ value: 1944801280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709260379088
+ value: 1945333760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709260658995
+ value: 1961005056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709260712340
+ value: 1961009152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709261582579
+ value: 1961615360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709263068785
+ value: 1962180608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709263460387
+ value: 1962573824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709263566303
+ value: 1963098112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709263972553
+ value: 1963622400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709264401549
+ value: 1964150784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709264787820
+ value: 1964916736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709265183002
+ value: 1965436928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709265472472
+ value: 1965973504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709265726215
+ value: 1966501888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709266472716
+ value: 1966768128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709271164651
+ value: 1967321088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709275033914
+ value: 1968033792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709293355528
+ value: 1968402432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709293382953
+ value: 1968300032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709301418191
+ value: 1968566272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709302070046
+ value: 1969106944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709303155984
+ value: 1969647616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709303764057
+ value: 1969917952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709312138976
+ value: 1970442240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709313584695
+ value: 1970323456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709313620746
+ value: 1969799168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709313654519
+ value: 1969274880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709313698342
+ value: 1968832512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709313939228
+ value: 1968889856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709313939920
+ value: 1968857088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709317395445
+ value: 1969094656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709326736225
+ value: 1969618944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709326738788
+ value: 1969586176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709326816588
+ value: 1969618944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709326817158
+ value: 1969586176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709329817361
+ value: 1969905664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709330213072
+ value: 1970642944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709332177184
+ value: 1971171328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709332593687
+ value: 1971691520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709333314513
+ value: 1972219904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709334073912
+ value: 1972731904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709334863178
+ value: 1973268480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709336339415
+ value: 1973796864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709337041726
+ value: 1974333440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709337785216
+ value: 1974603776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709337933084
+ value: 1975140352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709338293883
+ value: 1975664640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709339199075
+ value: 1976193024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709340903217
+ value: 1976713216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709350135191
+ value: 1977446400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709357320453
+ value: 1977970688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709365846170
+ value: 1978548224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709372654885
+ value: 1978593280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709372656391
+ value: 1978560512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709372710753
+ value: 1978593280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709372711323
+ value: 1978560512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709375648741
+ value: 1978892288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709378815855
+ value: 1979420672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709398881529
+ value: 1980153856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709399855121
+ value: 1980481536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709399874775
+ value: 1980416000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709410926817
+ value: 1980452864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709410935362
+ value: 1980416000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709411115375
+ value: 1980653568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709411282937
+ value: 1980690432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709411283670
+ value: 1980657664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709411352680
+ value: 1980690432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709411353453
+ value: 1980657664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709416365131
+ value: 1980968960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709428636819
+ value: 1981505536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709431819924
+ value: 1982042112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709435564309
+ value: 1981931520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709435613707
+ value: 1981407232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709435660623
+ value: 1980882944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709447359313
+ value: 1981071360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709474890603
+ value: 1981648896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709475039488
+ value: 1982156800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709476067239
+ value: 1982201856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709476069151
+ value: 1982169088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709476127867
+ value: 1982201856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709476128355
+ value: 1982169088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709479538878
+ value: 1982177280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709482502175
+ value: 1982697472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709486704039
+ value: 1983205376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709508984394
+ value: 1983209472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709509002175
+ value: 1983213568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709512103616
+ value: 1983782912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709512528299
+ value: 1984307200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709513536070
+ value: 1984806912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709513722146
+ value: 1985314816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709514494363
+ value: 1985830912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709515508523
+ value: 1986326528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709518516539
+ value: 1987006464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709519847187
+ value: 1987010560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709519870421
+ value: 1987014656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709523178933
+ value: 1987551232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709523333556
+ value: 1987821568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709525219339
+ value: 1988362240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709526303689
+ value: 1988902912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709533444965
+ value: 1989443584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709535384296
+ value: 1989984256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709535724140
+ value: 1990524928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709537986428
+ value: 1991065600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709539187967
+ value: 1991712768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709539321227
+ value: 1992179712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709539388772
+ value: 1992622080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709539631773
+ value: 1993195520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709539855325
+ value: 1993601024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709540982075
+ value: 1994227712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709543860208
+ value: 1994752000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709547374490
+ value: 1995288576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709552517312
+ value: 1995821056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709557484190
+ value: 1996353536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709561961323
+ value: 1996890112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709563897968
+ value: 1997430784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709565729999
+ value: 1997971456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709571833800
+ value: 1998512128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709575892556
+ value: 1999052800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709577994322
+ value: 1999593472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709580047545
+ value: 2000130048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709582671284
+ value: 2000400384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709585004210
+ value: 2000941056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709590006326
+ value: 2001481728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709591883849
+ value: 2002022400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709596865253
+ value: 2002563072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709599966775
+ value: 2003103744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709603571471
+ value: 2003644416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709607465880
+ value: 2004185088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709608862690
+ value: 2004721664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709612396992
+ value: 2005241856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709616512755
+ value: 2005778432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709618037779
+ value: 2006319104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709622193663
+ value: 2006859776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709624439513
+ value: 2007375872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709629325784
+ value: 2007920640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709630471536
+ value: 2008461312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709639191547
+ value: 2008993792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709639704161
+ value: 2009329664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709639705301
+ value: 2009288704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709641797748
+ value: 2009534464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709642640766
+ value: 2010075136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709646759418
+ value: 2010615808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709647335672
+ value: 2010886144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709652936298
+ value: 2011426816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709656881163
+ value: 2011967488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709656976948
+ value: 2012508160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709664789610
+ value: 2013040640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709664982075
+ value: 2013577216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709669806863
+ value: 2014097408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709673327249
+ value: 2014638080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709677388732
+ value: 2015178752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709681596088
+ value: 2030850048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709681618061
+ value: 2030854144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709686700825
+ value: 2031394816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709690465595
+ value: 2031935488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709691058165
+ value: 2032476160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709692551085
+ value: 2033012736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709698425597
+ value: 2033455104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709698448465
+ value: 2033336320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709698538268
+ value: 2030772224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709698587543
+ value: 2028675072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709698612690
+ value: 2027524096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709699032490
+ value: 2026852352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709699104999
+ value: 2025914368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709703115701
+ value: 2026094592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709707077330
+ value: 2026635264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709708699563
+ value: 2027147264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709708853209
+ value: 2027012096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709708925963
+ value: 2025017344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709708927916
+ value: 2024964096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709709118264
+ value: 2024456192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709709238951
+ value: 2023927808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709711090310
+ value: 2024140800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709721041279
+ value: 2024660992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709727344746
+ value: 2025181184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709729284850
+ value: 2025725952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709729483377
+ value: 2026176512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709729597960
+ value: 2026672128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709729743671
+ value: 2027188224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709729995462
+ value: 2027716608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709730113138
+ value: 2028236800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709730212828
+ value: 2028736512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709730421446
+ value: 2029260800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709730598937
+ value: 2029731840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709730789244
+ value: 2030235648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709731024840
+ value: 2030772224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709731194599
+ value: 2031276032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709731374816
+ value: 2031800320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709731607482
+ value: 2032332800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709731873758
+ value: 2032865280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709732358051
+ value: 2033385472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709732651630
+ value: 2033917952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709732964863
+ value: 2034446336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709733023334
+ value: 2034946048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709733229877
+ value: 2035486720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709733503559
+ value: 2036027392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709733917174
+ value: 2036568064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709734183409
+ value: 2037108736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709734449930
+ value: 2037645312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709734528055
+ value: 2038177792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709734865660
+ value: 2038706176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709734944314
+ value: 2039193600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709735303933
+ value: 2039730176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709735391946
+ value: 2040258560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709735673806
+ value: 2040795136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709735802998
+ value: 2041315328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709735988260
+ value: 2041794560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709736244729
+ value: 2042327040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709736468484
+ value: 2042863616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709736606098
+ value: 2043371520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709736686380
+ value: 2043899904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709736914082
+ value: 2044628992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709737158873
+ value: 2045100032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709737283344
+ value: 2045628416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709737592263
+ value: 2046144512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709737707498
+ value: 2046681088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709737935729
+ value: 2047217664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709738256652
+ value: 2047746048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709738407124
+ value: 2048282624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709738626525
+ value: 2048811008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709738795063
+ value: 2049331200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709739005919
+ value: 2049871872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709739369485
+ value: 2050400256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709739548766
+ value: 2050908160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709739643655
+ value: 2051432448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709739881733
+ value: 2051940352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709740233255
+ value: 2052444160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709740599588
+ value: 2052960256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709740665668
+ value: 2053496832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709740910664
+ value: 2054004736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709741281839
+ value: 2054533120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709741422586
+ value: 2055057408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709741647602
+ value: 2055585792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709741755919
+ value: 2056114176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709742083759
+ value: 2056654848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709742295226
+ value: 2057191424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709742555520
+ value: 2057728000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709742573709
+ value: 2058264576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709742801573
+ value: 2058797056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709742956725
+ value: 2059329536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709743038634
+ value: 2059587584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709743188374
+ value: 2060124160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709743292784
+ value: 2060660736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709743426166
+ value: 2061189120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709743654641
+ value: 2061705216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709743748473
+ value: 2062217216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709743880797
+ value: 2062749696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709761550922
+ value: 2063335424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709762126362
+ value: 2063855616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709763045348
+ value: 2064392192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709763879210
+ value: 2064924672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709764374002
+ value: 2065465344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709764573139
+ value: 2065993728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709765330708
+ value: 2066534400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709765444477
+ value: 2067054592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709765890807
+ value: 2067591168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709766544656
+ value: 2068131840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709767105895
+ value: 2068672512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709767745747
+ value: 2069213184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709767796324
+ value: 2069753856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709768442402
+ value: 2070286336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709769092833
+ value: 2070827008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709769126647
+ value: 2071367680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709769654072
+ value: 2071908352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709770210834
+ value: 2072178688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709770495177
+ value: 2072719360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709771410053
+ value: 2073260032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709771820413
+ value: 2073800704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709772492654
+ value: 2074329088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709772683125
+ value: 2074869760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709773787983
+ value: 2075410432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709773870340
+ value: 2075951104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709774443867
+ value: 2076487680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709774953632
+ value: 2077020160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709775286762
+ value: 2077556736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709775835143
+ value: 2078097408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709776249612
+ value: 2078638080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709777061298
+ value: 2079174656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709777477884
+ value: 2079715328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709777705138
+ value: 2080256000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709777807473
+ value: 2080792576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709778508238
+ value: 2081329152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709778562275
+ value: 2081845248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709779155862
+ value: 2082381824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709779804503
+ value: 2082918400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709779811258
+ value: 2083188736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709780131570
+ value: 2083729408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709780777281
+ value: 2084253696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709780964578
+ value: 2084794368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709781256936
+ value: 2085330944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709781606871
+ value: 2085867520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709781989073
+ value: 2086404096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709782264708
+ value: 2086944768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709782808653
+ value: 2087481344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709783274311
+ value: 2088022016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709783497456
+ value: 2088550400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709784174580
+ value: 2089078784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709784465514
+ value: 2089615360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709785052631
+ value: 2090156032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709785185607
+ value: 2090696704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709785890603
+ value: 2091237376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709786727192
+ value: 2091773952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709787960794
+ value: 2092314624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709788353901
+ value: 2092855296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709789195169
+ value: 2093395968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709789552509
+ value: 2093928448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709789924132
+ value: 2094198784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709790623351
+ value: 2094735360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709790811014
+ value: 2095276032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709791357156
+ value: 2095812608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709791688780
+ value: 2096349184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709791916320
+ value: 2096865280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709792812885
+ value: 2097405952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709793099059
+ value: 2097942528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709793789204
+ value: 2098483200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709794106139
+ value: 2099023872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709794447692
+ value: 2099564544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709795139016
+ value: 2100101120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709795399881
+ value: 2100637696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709795580830
+ value: 2101178368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709796176370
+ value: 2101719040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709796560403
+ value: 2102259712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709796849669
+ value: 2102800384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709797116962
+ value: 2103336960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709797493020
+ value: 2103877632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709797959370
+ value: 2104418304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709798127908
+ value: 2104688640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709798715921
+ value: 2105225216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709798909036
+ value: 2105753600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709799312600
+ value: 2106277888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709799901630
+ value: 2106818560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709801195901
+ value: 2107359232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709802033466
+ value: 2107899904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709802863463
+ value: 2108440576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709803714130
+ value: 2108981248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709804223448
+ value: 2109517824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709804507018
+ value: 2110058496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709805141132
+ value: 2110590976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709805526223
+ value: 2111131648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709806083597
+ value: 2111655936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709806569640
+ value: 2112196608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709807202778
+ value: 2112741376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709807672667
+ value: 2113282048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709808246113
+ value: 2113822720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709808887389
+ value: 2114363392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709808998066
+ value: 2114904064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709809443989
+ value: 2115174400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709810293557
+ value: 2115715072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709810767394
+ value: 2116255744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709811046162
+ value: 2116796416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709811690245
+ value: 2117337088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709812266743
+ value: 2117877760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709812640115
+ value: 2118418432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709813158873
+ value: 2118959104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709813548969
+ value: 2119499776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709814220559
+ value: 2120028160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709814772643
+ value: 2120568832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709815240986
+ value: 2121109504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709815486144
+ value: 2121650176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709816372334
+ value: 2122190848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709816640115
+ value: 2122731520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709817442931
+ value: 2123259904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709818731220
+ value: 2123800576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709819115620
+ value: 2124341248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709819208963
+ value: 2124611584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709820313251
+ value: 2125144064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709820946593
+ value: 2125684736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709821513813
+ value: 2126225408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709822148253
+ value: 2126757888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709822529967
+ value: 2127294464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709822810240
+ value: 2127826944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709823365823
+ value: 2128359424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709823905862
+ value: 2128891904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709824084248
+ value: 2129432576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709825150857
+ value: 2129973248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709825972797
+ value: 2130509824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709826273619
+ value: 2131050496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709826919493
+ value: 2131587072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709827508849
+ value: 2132127744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709828649718
+ value: 2132668416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709829388365
+ value: 2133209088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709829859353
+ value: 2133749760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709830559996
+ value: 2134290432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709830982197
+ value: 2134560768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709831761575
+ value: 2135101440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709832667093
+ value: 2135642112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709834315978
+ value: 2136174592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709836150166
+ value: 2136657920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709837343037
+ value: 2137436160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709838548766
+ value: 2137706496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709841822325
+ value: 2138247168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709843821186
+ value: 2138787840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709845074279
+ value: 2139328512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709846157083
+ value: 2140033024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709846219135
+ value: 2140487680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709846620991
+ value: 2140975104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709848946023
+ value: 2141474816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709849751443
+ value: 2141974528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709852159199
+ value: 2142511104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709855490457
+ value: 2143051776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709869170266
+ value: 2142797824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709894178567
+ value: 2143981568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709894205830
+ value: 2143985664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709898941588
+ value: 2144329728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709903533588
+ value: 2213990400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709903535379
+ value: 2214539264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709904332986
+ value: 2215051264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709905023782
+ value: 2215591936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709905556741
+ value: 2216120320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709905807189
+ value: 2216652800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709906529194
+ value: 2217185280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709906996479
+ value: 2217721856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709907398375
+ value: 2218008576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709907801492
+ value: 2218541056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709908727680
+ value: 2219081728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709909533711
+ value: 2219622400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709910224954
+ value: 2220158976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709910935729
+ value: 2220699648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709912344339
+ value: 2221240320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709913030293
+ value: 2221772800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709914545999
+ value: 2222313472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709915973815
+ value: 2222858240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709924239765
+ value: 2223386624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709941286844
+ value: 2223906816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709943066100
+ value: 2224447488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709945866759
+ value: 2225037312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709947172098
+ value: 2225442816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709947187763
+ value: 2225303552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709947261738
+ value: 2225565696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709947943541
+ value: 2226085888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709949469217
+ value: 2226614272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709950159524
+ value: 2227154944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709951546569
+ value: 2227691520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709952255146
+ value: 2228232192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709958360859
+ value: 2228760576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709960270039
+ value: 2229030912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709963776671
+ value: 2229571584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709966211323
+ value: 2230112256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709983972350
+ value: 2230652928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709984952859
+ value: 2231193600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709985808532
+ value: 2231730176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709986320454
+ value: 2232254464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709986717467
+ value: 2232786944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709987193867
+ value: 2233294848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709987896870
+ value: 2233835520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709988413553
+ value: 2234376192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709989183613
+ value: 2234912768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709990586038
+ value: 2235453440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709991968444
+ value: 2235994112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709993440205
+ value: 2236534784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 709997736347
+ value: 2237075456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710018048807
+ value: 2237423616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710022974791
+ value: 2237964288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710027222024
+ value: 2237812736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710037818989
+ value: 2237964288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710038614603
+ value: 2238504960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710039522033
+ value: 2239041536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710040364806
+ value: 2239582208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710040802835
+ value: 2240114688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710041384012
+ value: 2240634880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710042087910
+ value: 2241167360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710042749490
+ value: 2241687552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710043255146
+ value: 2242228224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710043654153
+ value: 2242768896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710044273497
+ value: 2243309568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710045661966
+ value: 2243850240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710111908385
+ value: 2218692608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710111910135
+ value: 2219159552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710111938903
+ value: 2217877504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710111971048
+ value: 2215780352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710112029682
+ value: 2213683200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710112053283
+ value: 2211586048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710112079202
+ value: 2209488896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710112104552
+ value: 2207391744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710112128885
+ value: 2205294592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710112152485
+ value: 2203197440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710112178120
+ value: 2201100288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710112203632
+ value: 2199003136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710112227558
+ value: 2196905984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710112247659
+ value: 2194808832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710112270527
+ value: 2192711680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710112296691
+ value: 2190614528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710112320250
+ value: 2188517376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710112342671
+ value: 2186420224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710112366067
+ value: 2184323072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710112390156
+ value: 2182225920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710112413268
+ value: 2180128768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710112420470
+ value: 2179436544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710113895079
+ value: 2178031616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710113914448
+ value: 2175934464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710113932148
+ value: 2173837312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710113950174
+ value: 2171740160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710113967304
+ value: 2169643008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710113984150
+ value: 2167545856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710114001321
+ value: 2165448704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710114017638
+ value: 2163351552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710114033711
+ value: 2161254400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710114050190
+ value: 2159157248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710114066100
+ value: 2157060096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710114082376
+ value: 2154962944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710114099873
+ value: 2152865792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710114118305
+ value: 2150768640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710114136982
+ value: 2148671488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710114154438
+ value: 2146574336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710114171772
+ value: 2144477184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710114179178
+ value: 2143657984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710116414489
+ value: 2144194560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710116626565
+ value: 2144735232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710116905008
+ value: 2145234944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710117061339
+ value: 2145738752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710117173929
+ value: 2146193408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710117424498
+ value: 2146934784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710117447692
+ value: 2147356672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710117600605
+ value: 2147811328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710117694274
+ value: 2148286464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710119021707
+ value: 2148958208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710119823994
+ value: 2149384192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710120261168
+ value: 2149916672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710120893696
+ value: 2150592512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710121854633
+ value: 2151129088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710122032775
+ value: 2151669760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710123350361
+ value: 2152124416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710123599629
+ value: 2152525824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710125216165
+ value: 2153103360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710126278136
+ value: 2153541632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710126744689
+ value: 2154233856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710126956318
+ value: 2154774528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710131615538
+ value: 2155302912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710131802387
+ value: 2155843584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710133581033
+ value: 2156150784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710133583963
+ value: 2156130304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710135391784
+ value: 2156376064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710148133483
+ value: 2156892160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710158756245
+ value: 2156670976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710161186990
+ value: 2156732416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710161823831
+ value: 2156736512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710161824238
+ value: 2156724224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710164156595
+ value: 2156990464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710164233296
+ value: 2157260800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710164580789
+ value: 2157850624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710164829935
+ value: 2158374912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710165077330
+ value: 2158936064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710165382425
+ value: 2159431680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710166274515
+ value: 2159984640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710166768167
+ value: 2160529408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710167250467
+ value: 2160992256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710167822326
+ value: 2160742400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710167880024
+ value: 2159431680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710167899840
+ value: 2158661632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710168096902
+ value: 2157551616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710168238423
+ value: 2155376640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710168246276
+ value: 2154934272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710168439269
+ value: 2154086400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710168499205
+ value: 2153418752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710168511697
+ value: 2152648704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710168610167
+ value: 2151788544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710168621845
+ value: 2151084032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710168713561
+ value: 2150895616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710169140807
+ value: 2151157760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710170717996
+ value: 2151555072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710171893248
+ value: 2152157184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710173498351
+ value: 2152755200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710173891784
+ value: 2152488960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710175302103
+ value: 2152673280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710190755065
+ value: 2153279488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710199438740
+ value: 2153660416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710200660542
+ value: 2154221568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710201135843
+ value: 2154704896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710201881733
+ value: 2155393024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710202371967
+ value: 2155761664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710202919087
+ value: 2156314624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710203326557
+ value: 2156748800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710203708027
+ value: 2157305856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710203966572
+ value: 2157805568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710204804015
+ value: 2158370816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710206271626
+ value: 2158911488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710207350117
+ value: 2159505408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710207718566
+ value: 2160062464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710208119038
+ value: 2160435200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710208582295
+ value: 2161057792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710208782734
+ value: 2161590272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710209117858
+ value: 2162237440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710209315937
+ value: 2162753536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710209721821
+ value: 2163294208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710210026264
+ value: 2163560448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710210102762
+ value: 2164076544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710210263121
+ value: 2164617216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710210494201
+ value: 2165145600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710210811868
+ value: 2165686272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710211341938
+ value: 2166218752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710211784891
+ value: 2166759424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710212597228
+ value: 2167300096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710212806904
+ value: 2167840768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710213317809
+ value: 2168270848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710213612853
+ value: 2168799232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710213937723
+ value: 2169331712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710214514261
+ value: 2169864192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710215059630
+ value: 2170404864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710215549051
+ value: 2170945536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710215981871
+ value: 2171486208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710217131530
+ value: 2172030976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710217733947
+ value: 2172579840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710218160420
+ value: 2173108224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710220358133
+ value: 2173648896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710220640482
+ value: 2174189568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710220888325
+ value: 2174722048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710221502054
+ value: 2175258624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710221895079
+ value: 2175787008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710222140034
+ value: 2176315392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710222362324
+ value: 2176856064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710222577127
+ value: 2177384448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710222858703
+ value: 2177904640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710223377542
+ value: 2178285568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710223402037
+ value: 2178224128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710223420307
+ value: 2178494464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710225159199
+ value: 2178764800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710226283507
+ value: 2179305472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710226887918
+ value: 2179846144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710229929829
+ value: 2180382720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710231944152
+ value: 2180067328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710232828633
+ value: 2180337664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710237510151
+ value: 2180878336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710237914814
+ value: 2181414912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710238301858
+ value: 2181955584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710238608092
+ value: 2182492160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710238929178
+ value: 2183032832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710239156147
+ value: 2183573504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710239680846
+ value: 2184110080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710242060607
+ value: 2184650752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710242686828
+ value: 2185187328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710243402363
+ value: 2185728000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710246059956
+ value: 2186268672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710246476297
+ value: 2186805248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710246890400
+ value: 2187345920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710247298196
+ value: 2187882496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710247678242
+ value: 2188423168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710248740010
+ value: 2188947456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710249695861
+ value: 2189484032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710250679056
+ value: 2190024704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710251716206
+ value: 2190295040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710252268167
+ value: 2190835712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710254563496
+ value: 2191376384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710255318460
+ value: 2191917056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710255932840
+ value: 2192457728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710262007140
+ value: 2193059840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710262397399
+ value: 2193600512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710262774149
+ value: 2194137088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710263164407
+ value: 2194677760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710263548603
+ value: 2195214336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710263958637
+ value: 2195750912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710265679137
+ value: 2196291584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710266636494
+ value: 2196824064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710267190652
+ value: 2197364736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710267732970
+ value: 2197635072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710270789936
+ value: 2198175744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710271065652
+ value: 2198716416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710271553690
+ value: 2199252992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710271940042
+ value: 2199793664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710278145812
+ value: 2200338432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710278539082
+ value: 2200875008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710278937153
+ value: 2201415680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710279341613
+ value: 2201952256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710279746276
+ value: 2202492928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710282429137
+ value: 2203033600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710282883361
+ value: 2203574272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710283173318
+ value: 2204098560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710283560973
+ value: 2204639232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710284048481
+ value: 2205179904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710286938943
+ value: 2205720576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710287790831
+ value: 2206261248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710295012226
+ value: 2206633984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710295014668
+ value: 2206433280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710295650003
+ value: 2205859840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710295670877
+ value: 2206117888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710299456522
+ value: 2206003200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710306240010
+ value: 2205827072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710306690449
+ value: 2205949952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710306693338
+ value: 2205884416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710320331400
+ value: 2206470144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710320448058
+ value: 2206715904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710326842630
+ value: 2256855040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710326861225
+ value: 2256859136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710339436258
+ value: 2257371136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710339438374
+ value: 2257784832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710342478047
+ value: 2258399232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710343103332
+ value: 2259046400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710346977965
+ value: 2259587072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710347624246
+ value: 2259898368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710348140359
+ value: 2260414464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710348573302
+ value: 2260959232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710349134826
+ value: 2261721088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710349600361
+ value: 2261987328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710350149108
+ value: 2262515712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710350593769
+ value: 2263265280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710351042947
+ value: 2263756800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710351638366
+ value: 2264207360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710352207702
+ value: 2264686592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710352693338
+ value: 2265198592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710352854756
+ value: 2265686016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710353705504
+ value: 2266378240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710354171772
+ value: 2266853376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710354662169
+ value: 2267353088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710355537251
+ value: 2267865088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710356291442
+ value: 2268405760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710356979959
+ value: 2268946432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710357737039
+ value: 2269478912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710358233011
+ value: 2270007296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710358845112
+ value: 2270535680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710359388773
+ value: 2271064064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710360127501
+ value: 2271604736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710360729552
+ value: 2272145408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710361396260
+ value: 2275295232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710361493712
+ value: 2276872192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710361513691
+ value: 2276876288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710364747822
+ value: 2276925440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710365519551
+ value: 2277343232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710368807352
+ value: 2277326848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710373393086
+ value: 2277957632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710374453063
+ value: 2278420480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710381039326
+ value: 2278887424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710386286071
+ value: 2279559168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710398822977
+ value: 2280742912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710398851785
+ value: 2280747008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710400898416
+ value: 2281259008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710401749938
+ value: 2281287680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710402193175
+ value: 2281615360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710402333312
+ value: 2284765184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710402430399
+ value: 2286342144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710402446186
+ value: 2286346240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710409774596
+ value: 2283196416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710409801126
+ value: 2281619456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710409809712
+ value: 2281615360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710415439432
+ value: 2282209280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710415469258
+ value: 2282094592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710425528706
+ value: 2282160128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710425535745
+ value: 2282110976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710435043192
+ value: 2282147840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710435308857
+ value: 2282119168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710437158426
+ value: 2281250816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710437211323
+ value: 2279153664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710437225117
+ value: 2278498304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710437466735
+ value: 2277437440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710438839090
+ value: 2277945344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710439431823
+ value: 2278678528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710439556701
+ value: 2279010304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710441997985
+ value: 2279632896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710442161152
+ value: 2280108032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710442278502
+ value: 2280554496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710442552957
+ value: 2281086976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710442815124
+ value: 2281811968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710442950215
+ value: 2282168320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710443351582
+ value: 2282651648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710443492085
+ value: 2283298816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710443602477
+ value: 2283753472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710443794087
+ value: 2284257280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710443966369
+ value: 2284748800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710444483540
+ value: 2285367296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710444587625
+ value: 2285928448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710444720356
+ value: 2286350336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710445012064
+ value: 2286948352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710445166523
+ value: 2287489024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710445456278
+ value: 2287902720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710445991271
+ value: 2288558080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710446089334
+ value: 2288984064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710446273253
+ value: 2289569792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710446568948
+ value: 2290216960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710446838358
+ value: 2290720768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710447079243
+ value: 2291224576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710447469746
+ value: 2291712000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710447577412
+ value: 2292174848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710447670755
+ value: 2292674560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710447871846
+ value: 2293235712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710448181294
+ value: 2293743616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710448291035
+ value: 2294333440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710448753275
+ value: 2294751232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710448921365
+ value: 2295410688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710449050556
+ value: 2295840768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710449255513
+ value: 2296446976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710449433817
+ value: 2297032704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710449538797
+ value: 2297389056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710449713724
+ value: 2297913344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710450117370
+ value: 2298548224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710450207010
+ value: 2298925056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710450492166
+ value: 2299600896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710450607441
+ value: 2299953152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710450902282
+ value: 2300596224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710451319722
+ value: 2301124608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710451400898
+ value: 2301546496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710451522969
+ value: 2302164992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710451632547
+ value: 2302603264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710451974303
+ value: 2303221760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710452077900
+ value: 2303684608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710452560119
+ value: 2304319488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710452664855
+ value: 2304872448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710452740661
+ value: 2305200128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710452877827
+ value: 2305769472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710453161640
+ value: 2306420736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710453361917
+ value: 2307014656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710453822082
+ value: 2307444736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710453890685
+ value: 2307846144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710454038512
+ value: 2308423680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710454279642
+ value: 2308931584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710454372985
+ value: 2309414912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710454603332
+ value: 2309947392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710455079121
+ value: 2310615040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710455159443
+ value: 2311000064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710455326680
+ value: 2311643136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710455412251
+ value: 2312097792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710455787739
+ value: 2312667136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710455903584
+ value: 2313138176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710456484598
+ value: 2313687040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710456573180
+ value: 2314129408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710456706074
+ value: 2314633216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710456848774
+ value: 2315190272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710457214578
+ value: 2315796480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710457499368
+ value: 2316324864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710458204650
+ value: 2266185728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710458228576
+ value: 2266181632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710459641499
+ value: 2266714112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710461034525
+ value: 2267250688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710461699645
+ value: 2267791360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710462358540
+ value: 2268332032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710463015848
+ value: 2268872704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710463677550
+ value: 2269413376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710465883808
+ value: 2269949952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710466559752
+ value: 2270490624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710467216735
+ value: 2271031296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710467547627
+ value: 2271301632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710468266092
+ value: 2271842304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710468927388
+ value: 2272382976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710469585184
+ value: 2272919552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710470423237
+ value: 2273456128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710471093607
+ value: 2273996800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710471748880
+ value: 2274537472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710472423400
+ value: 2275078144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710473081237
+ value: 2275618816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710473740823
+ value: 2276155392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710474401265
+ value: 2276696064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710477000060
+ value: 2277236736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710477731505
+ value: 2277777408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710478708800
+ value: 2278318080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710479375426
+ value: 2278858752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710480161478
+ value: 2279395328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710480843607
+ value: 2279936000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710481503926
+ value: 2280476672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710481844298
+ value: 2280747008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710482508035
+ value: 2281287680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710483171284
+ value: 2281828352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710483833475
+ value: 2282369024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710484571308
+ value: 2282909696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710485354715
+ value: 2283450368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710486017760
+ value: 2283991040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710486680032
+ value: 2284531712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710488480285
+ value: 2284998656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710488527526
+ value: 2282942464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710488562235
+ value: 2280845312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710488581522
+ value: 2278748160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710488601012
+ value: 2276651008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710488618224
+ value: 2274553856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710488635517
+ value: 2272456704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710488653299
+ value: 2270359552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710488671487
+ value: 2268262400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710488689635
+ value: 2266165248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710488706969
+ value: 2264068096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710488725524
+ value: 2261970944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710488741800
+ value: 2259873792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710488759175
+ value: 2257776640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710488776793
+ value: 2255679488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710488794168
+ value: 2253582336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710488811909
+ value: 2251485184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710488829609
+ value: 2249388032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710488845723
+ value: 2247393280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710492646504
+ value: 2247921664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710493004658
+ value: 2248462336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710493244648
+ value: 2248794112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710493595560
+ value: 2249363456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710493979552
+ value: 2249900032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710494308166
+ value: 2250338304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710494309712
+ value: 2250240000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710494347432
+ value: 2250440704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710494714578
+ value: 2250981376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710495216369
+ value: 2251522048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710495573180
+ value: 2252058624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710495927754
+ value: 2252599296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710496298278
+ value: 2253139968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710496649108
+ value: 2253680640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710496997619
+ value: 2254217216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710497362080
+ value: 2254757888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710497723123
+ value: 2255298560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710498078266
+ value: 2255839232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710498225361
+ value: 2254086144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710498263406
+ value: 2252255232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710498298807
+ value: 2250158080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710498658223
+ value: 2248339456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710498685200
+ value: 2246512640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710498711486
+ value: 2244415488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710499027038
+ value: 2243928064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710499161478
+ value: 2242236416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710499217305
+ value: 2240139264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710499260111
+ value: 2238042112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710499272440
+ value: 2237480960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710499297505
+ value: 2237751296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710499739359
+ value: 2238291968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710500338154
+ value: 2238828544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710500749816
+ value: 2239369216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710501134053
+ value: 2239909888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710501508849
+ value: 2240450560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710501875508
+ value: 2240987136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710502242166
+ value: 2241527808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710502611022
+ value: 2242068480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710503013284
+ value: 2242605056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710503454121
+ value: 2243145728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710503822163
+ value: 2243686400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710504212462
+ value: 2244227072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710504570535
+ value: 2244763648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710504985290
+ value: 2245304320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710505407327
+ value: 2245844992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710505768655
+ value: 2246385664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710506130024
+ value: 2246922240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710506311868
+ value: 2247192576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710506673603
+ value: 2247733248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710507040018
+ value: 2248273920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710507405008
+ value: 2248814592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710507767353
+ value: 2249351168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710508143086
+ value: 2249891840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710508500101
+ value: 2250432512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710508856017
+ value: 2250969088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710509212747
+ value: 2251509760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710509566548
+ value: 2252050432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710509767150
+ value: 2252566528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710510203958
+ value: 2253107200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710510590636
+ value: 2253643776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710510949930
+ value: 2254184448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710511310119
+ value: 2254725120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710511665750
+ value: 2255265792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710512043232
+ value: 2255802368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710512394469
+ value: 2256343040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710512745910
+ value: 2256883712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710512922545
+ value: 2257154048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710513269225
+ value: 2257690624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710513622171
+ value: 2258231296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710514001077
+ value: 2258771968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710514407856
+ value: 2259312640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710514772521
+ value: 2259849216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710515256204
+ value: 2260389888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710515619892
+ value: 2260930560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710516040832
+ value: 2261471232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710516400044
+ value: 2262007808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710516760111
+ value: 2262548480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710517116719
+ value: 2263089152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710517474792
+ value: 2263629824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710517835469
+ value: 2264166400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710518197407
+ value: 2264707072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710518545999
+ value: 2265247744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710519499531
+ value: 2265722880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710520104349
+ value: 2322796544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710520357726
+ value: 2325200896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710520534891
+ value: 2325057536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710520664977
+ value: 2326757376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710520865254
+ value: 2328461312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710521075133
+ value: 2328911872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710521461038
+ value: 2329632768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710521972432
+ value: 2331631616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710522107197
+ value: 2333794304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710522138162
+ value: 2334302208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710522503153
+ value: 2332729344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710522822692
+ value: 2333302784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710523094298
+ value: 2333761536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710523215718
+ value: 2334150656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710523373351
+ value: 2334072832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710523446227
+ value: 2333548544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710523573669
+ value: 2334466048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710523638284
+ value: 2334691328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710523810607
+ value: 2335346688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710523994323
+ value: 2335674368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710523994648
+ value: 2336165888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710524195454
+ value: 2336563200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710524387796
+ value: 2337218560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710524453633
+ value: 2337906688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710524638000
+ value: 2338430976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710524703226
+ value: 2339024896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710524837666
+ value: 2339565568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710525138854
+ value: 2340352000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710525240783
+ value: 2340700160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710525369567
+ value: 2341240832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710525558817
+ value: 2342092800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710525697570
+ value: 2342711296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710525958800
+ value: 2343497728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710525959207
+ value: 2343895040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710526092020
+ value: 2344427520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710526364643
+ value: 2345279488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710526581115
+ value: 2345607168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710526581603
+ value: 2346266624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710526899881
+ value: 2346831872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710527078877
+ value: 2347618304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710527145812
+ value: 2347954176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710527264912
+ value: 2348216320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710527471170
+ value: 2348675072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710527626566
+ value: 2349297664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710527987080
+ value: 2349711360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710528180724
+ value: 2350301184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710528297016
+ value: 2350886912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710530771667
+ value: 2351329280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710531540140
+ value: 2353963008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710533698587
+ value: 2337005568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710534098327
+ value: 2337693696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710535086852
+ value: 2338033664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710537422749
+ value: 2338770944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710537622863
+ value: 2339168256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710541055683
+ value: 2339737600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710541895080
+ value: 2340184064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710542747171
+ value: 2340843520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710543499084
+ value: 2341269504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710544719136
+ value: 2341830656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710544984028
+ value: 2342363136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710545249572
+ value: 2342899712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710545997049
+ value: 2343280640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710546255309
+ value: 2343821312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710546570169
+ value: 2344439808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710552918029
+ value: 2344931328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710553135640
+ value: 2345463808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710553729390
+ value: 2346004480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710553947000
+ value: 2346622976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710554681619
+ value: 2347028480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710554814839
+ value: 2347560960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710555422505
+ value: 2348077056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710555936624
+ value: 2348535808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710556675679
+ value: 2349170688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710557015441
+ value: 2349613056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710557614766
+ value: 2350313472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710557734679
+ value: 2350649344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710558392638
+ value: 2351181824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710558927591
+ value: 2351796224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710559846048
+ value: 2352300032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710560408304
+ value: 2352779264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710561090311
+ value: 2353278976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710582006937
+ value: 2353811456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710590227314
+ value: 2350661632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710590257059
+ value: 2349084672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710590263122
+ value: 2349080576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710595930968
+ value: 2516209664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710595932718
+ value: 2516746240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710596493021
+ value: 2518474752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710597189269
+ value: 2520150016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710598158304
+ value: 2520731648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710598954731
+ value: 2521202688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710599504821
+ value: 2522120192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710599505594
+ value: 2522607616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710602315653
+ value: 2523914240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710611993265
+ value: 2524418048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710627992899
+ value: 2525085696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710643782653
+ value: 2526019584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710643784728
+ value: 2526576640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710666349710
+ value: 2526994432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710689994160
+ value: 2526961664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710697361348
+ value: 2527490048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710703489847
+ value: 2527936512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710713626037
+ value: 2528534528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710727784687
+ value: 2529005568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710759976623
+ value: 2529583104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710765233133
+ value: 2527981568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710765272155
+ value: 2526326784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710765510884
+ value: 2524921856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710765561746
+ value: 2522824704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710765608581
+ value: 2520727552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710765657612
+ value: 2518630400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710765686828
+ value: 2516922368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710766390319
+ value: 2514395136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710766410013
+ value: 2512297984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710766428853
+ value: 2510200832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710766445454
+ value: 2508103680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710766450418
+ value: 2507517952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710766946268
+ value: 2506063872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710766964009
+ value: 2503966720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710766980854
+ value: 2501869568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710766999246
+ value: 2499772416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710767012430
+ value: 2498113536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710767468241
+ value: 2497732608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710767485371
+ value: 2495635456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710767502502
+ value: 2493538304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710767519063
+ value: 2491441152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710767535257
+ value: 2489344000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710767540588
+ value: 2488709120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710768083638
+ value: 2486530048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710768102599
+ value: 2485182464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710792074930
+ value: 2485547008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710825170389
+ value: 2486030336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710841458638
+ value: 2486616064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710841463887
+ value: 2486472704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710841950866
+ value: 2486550528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710841953185
+ value: 2486505472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710853459289
+ value: 2486669312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710871274718
+ value: 2487222272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710880148701
+ value: 2487586816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710890783426
+ value: 2488098816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710890857848
+ value: 2487566336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710890890685
+ value: 2487037952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710890909769
+ value: 2486509568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710890950296
+ value: 2485981184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710896339456
+ value: 2486038528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710896351867
+ value: 2485981184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710898295430
+ value: 2486054912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710898297790
+ value: 2485919744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710898357604
+ value: 2484998144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710906284118
+ value: 2484920320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710910700622
+ value: 2485096448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710922962463
+ value: 2485669888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710923813740
+ value: 2485997568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710926077941
+ value: 2486538240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710929444681
+ value: 2487054336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710931512634
+ value: 2486947840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710931614684
+ value: 2486423552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710931708109
+ value: 2485899264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710931814269
+ value: 2485436416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710938473612
+ value: 2485702656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710941794453
+ value: 2486231040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710943675719
+ value: 2486726656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710947418395
+ value: 2487119872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710947420755
+ value: 2487013376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710947487528
+ value: 2486489088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710947639627
+ value: 2485964800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710950474588
+ value: 2486005760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710950477599
+ value: 2485981184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710951012918
+ value: 2486026240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710951014953
+ value: 2485985280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710952666198
+ value: 2486087680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710952667948
+ value: 2485960704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710952952819
+ value: 2486202368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710953008402
+ value: 2485960704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710954829976
+ value: 2486255616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710976944518
+ value: 2498801664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710991572570
+ value: 2499289088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 710992866231
+ value: 2499330048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711004912210
+ value: 2499633152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711013677184
+ value: 2500329472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711027822204
+ value: 2500804608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711070455261
+ value: 2500521984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711070494120
+ value: 2500145152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711076179504
+ value: 2500259840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711083821634
+ value: 2500042752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711083858255
+ value: 2499616768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711084867818
+ value: 2498863104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711084923766
+ value: 2498310144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711085531026
+ value: 2497884160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711088164530
+ value: 2498129920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711094501891
+ value: 2497798144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711103585632
+ value: 2498142208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711114274637
+ value: 2498691072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711126338073
+ value: 2498256896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711146372700
+ value: 2498596864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711146374694
+ value: 2497921024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711146429138
+ value: 2497466368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711146502990
+ value: 2496790528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711146551655
+ value: 2496335872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711146590637
+ value: 2495660032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711146635558
+ value: 2494984192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711146670145
+ value: 2494308352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711146712341
+ value: 2493853696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711146745422
+ value: 2493227008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711146797180
+ value: 2492575744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711146833882
+ value: 2492182528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711147296773
+ value: 2491604992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711176749328
+ value: 2491867136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711176751647
+ value: 2491080704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711179801615
+ value: 2491273216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711197792785
+ value: 2491240448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711201800394
+ value: 2491940864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711201802347
+ value: 2490363904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711201808085
+ value: 2489978880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711201957377
+ value: 2489487360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711202036600
+ value: 2487918592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711211455098
+ value: 2488029184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711213910013
+ value: 2488217600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711213911966
+ value: 2488012800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711213953348
+ value: 2485915648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711213983052
+ value: 2483818496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711214281026
+ value: 2483138560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711225521952
+ value: 2482667520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711249565612
+ value: 2483052544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711257096944
+ value: 2483523584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711295299092
+ value: 2484035584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711295301249
+ value: 2483466240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711295368998
+ value: 2483408896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711295379536
+ value: 2482896896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711295460550
+ value: 2482331648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711295500345
+ value: 2481778688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711295557718
+ value: 2481201152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711295639058
+ value: 2480640000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711295667053
+ value: 2480193536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711295728129
+ value: 2479243264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711296353129
+ value: 2478665728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711308467386
+ value: 2477989888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711308559387
+ value: 2477531136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711308563130
+ value: 2477121536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711308663472
+ value: 2476261376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711308749654
+ value: 2475728896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711309428080
+ value: 2475511808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711309481058
+ value: 2474852352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711312304707
+ value: 2475200512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711319621846
+ value: 2474901504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711319653015
+ value: 2472804352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711319680440
+ value: 2470707200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711319715474
+ value: 2468610048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711319734924
+ value: 2466512896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711319756693
+ value: 2464415744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711319789774
+ value: 2462318592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711319810526
+ value: 2460221440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711319832255
+ value: 2458124288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711319861958
+ value: 2456027136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711319882100
+ value: 2453929984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711319902119
+ value: 2451832832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711319924336
+ value: 2450341888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711321114400
+ value: 2447810560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711321133809
+ value: 2447200256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711321390604
+ value: 2445414400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711321460795
+ value: 2443317248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711321491027
+ value: 2442498048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711321929585
+ value: 2441900032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711321948059
+ value: 2439802880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711321965230
+ value: 2437795840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711322202209
+ value: 2436952064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711322219421
+ value: 2434854912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711322236144
+ value: 2432757760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711322254781
+ value: 2430660608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711322274678
+ value: 2428563456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711322292338
+ value: 2426466304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711322309631
+ value: 2424369152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711322327128
+ value: 2422272000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711322343688
+ value: 2420174848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711322360656
+ value: 2418077696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711322377583
+ value: 2415980544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711322394673
+ value: 2413883392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711322405253
+ value: 2412625920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711323363667
+ value: 2411048960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711323540262
+ value: 2409472000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711324627054
+ value: 2409578496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711327543924
+ value: 2410209280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711328970235
+ value: 2410733568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711330222310
+ value: 2411261952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711330601379
+ value: 2411782144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711337754943
+ value: 2412154880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711337756327
+ value: 2412134400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711339634053
+ value: 2412388352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711344756001
+ value: 2412924928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711347880716
+ value: 2413334528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711347882303
+ value: 2412744704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711347932149
+ value: 2412507136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711366892842
+ value: 2415153152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711366895690
+ value: 2414055424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711366912984
+ value: 2411958272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711366931091
+ value: 2409861120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711366948221
+ value: 2407763968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711366966044
+ value: 2405666816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711366983622
+ value: 2403569664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711366991719
+ value: 2402586624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711367865376
+ value: 2402095104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711376426615
+ value: 2402230272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711376428487
+ value: 2402209792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711381303690
+ value: 2402377728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711388082336
+ value: 2402828288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711388379252
+ value: 2403360768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711388715677
+ value: 2403901440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711389233988
+ value: 2404438016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711389508646
+ value: 2404974592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711389794169
+ value: 2405515264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711390280985
+ value: 2406055936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711390777567
+ value: 2406596608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711391045511
+ value: 2407137280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711391326761
+ value: 2407677952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711391803446
+ value: 2408218624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711392256245
+ value: 2408759296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711392453959
+ value: 2409029632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711392735778
+ value: 2409570304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711393018086
+ value: 2410098688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711393307393
+ value: 2410635264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711393591695
+ value: 2411175936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711393862894
+ value: 2411716608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711394136983
+ value: 2412257280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711394414367
+ value: 2412797952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711394688456
+ value: 2413338624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711395013854
+ value: 2413875200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711395287333
+ value: 2414415872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711395555806
+ value: 2414952448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711395832824
+ value: 2415493120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711396277608
+ value: 2416033792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711396551534
+ value: 2416574464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711396826395
+ value: 2417111040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711397116597
+ value: 2417651712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711397411966
+ value: 2418192384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711397713195
+ value: 2418733056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711397735493
+ value: 2419003392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711398022237
+ value: 2419544064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711398307556
+ value: 2420080640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711398579284
+ value: 2420621312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711398853413
+ value: 2421157888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711399143819
+ value: 2421682176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711399412617
+ value: 2422210560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711399681579
+ value: 2422751232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711400070861
+ value: 2423287808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711400382914
+ value: 2423828480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711400653422
+ value: 2424365056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711400935607
+ value: 2424905728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711401224019
+ value: 2425446400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711401495056
+ value: 2425987072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711401771870
+ value: 2426527744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711402047058
+ value: 2427068416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711402329406
+ value: 2427609088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711402604715
+ value: 2428145664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711402879211
+ value: 2428686336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711403009460
+ value: 2428956672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711403279561
+ value: 2429493248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711403550923
+ value: 2430033920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711403827738
+ value: 2430574592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711404133768
+ value: 2431115264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711404410217
+ value: 2431655936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711404683776
+ value: 2432192512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711405003885
+ value: 2432733184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711405492207
+ value: 2433273856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711406004414
+ value: 2433814528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711406456807
+ value: 2434351104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711406737854
+ value: 2434887680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711407077006
+ value: 2435428352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711407593200
+ value: 2435969024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711408135843
+ value: 2436509696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711408640848
+ value: 2437046272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711409201314
+ value: 2437586944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711410819274
+ value: 2438127616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711411072326
+ value: 2438397952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711411578104
+ value: 2438938624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711412226745
+ value: 2439479296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711414107198
+ value: 2440065024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711414523173
+ value: 2440605696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711414936136
+ value: 2441146368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711415344868
+ value: 2441687040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711415778747
+ value: 2442227712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711416258768
+ value: 2442768384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711417544738
+ value: 2443300864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711417939554
+ value: 2443841536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711418343485
+ value: 2444382208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711418766621
+ value: 2444922880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711419179178
+ value: 2445463552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711419387430
+ value: 2445733888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711419797871
+ value: 2446278656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711420246846
+ value: 2446819328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711420646057
+ value: 2447360000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711421042948
+ value: 2447900672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711421618591
+ value: 2448441344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711422411804
+ value: 2448982016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711422805969
+ value: 2449514496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711423201436
+ value: 2450055168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711423594787
+ value: 2450595840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711423990254
+ value: 2451136512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711424424255
+ value: 2451677184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711424816426
+ value: 2452217856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711425207499
+ value: 2452758528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711425666483
+ value: 2453299200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711426071472
+ value: 2453839872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711426463114
+ value: 2454380544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711426660013
+ value: 2454650880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711427056823
+ value: 2455191552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711427454406
+ value: 2455724032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711427840271
+ value: 2456264704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711428259175
+ value: 2456805376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711428657653
+ value: 2457346048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711429102233
+ value: 2457886720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711429522847
+ value: 2458427392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711429935770
+ value: 2458968064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711430347188
+ value: 2459508736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711430765808
+ value: 2460049408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711431186462
+ value: 2460590080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711431598775
+ value: 2461130752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711432158752
+ value: 2461671424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711432577290
+ value: 2462203904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711432984191
+ value: 2462744576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711433404805
+ value: 2463285248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711433618143
+ value: 2463555584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711434043070
+ value: 2464096256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711434447489
+ value: 2464636928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711434844055
+ value: 2465177600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711435240295
+ value: 2465718272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711435660257
+ value: 2466258944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711436120829
+ value: 2466799616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711436521748
+ value: 2467340288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711436891947
+ value: 2467880960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711437290995
+ value: 2468413440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711437900492
+ value: 2468823040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711438277526
+ value: 2469363712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711438663757
+ value: 2469904384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711439058003
+ value: 2470445056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711439445210
+ value: 2470985728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711439837585
+ value: 2471526400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711440286031
+ value: 2472067072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711440650126
+ value: 2472607744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711441018534
+ value: 2473148416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711441379943
+ value: 2473689088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711441742167
+ value: 2474225664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711442102559
+ value: 2474766336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711442452819
+ value: 2475307008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711442803039
+ value: 2475847680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711443164815
+ value: 2476388352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711443538675
+ value: 2476929024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711445397521
+ value: 2477277184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711448798767
+ value: 2477817856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711452118225
+ value: 2478358528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711455105407
+ value: 2478899200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711458028299
+ value: 2479439872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711461433532
+ value: 2479980544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711464614074
+ value: 2480517120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711467488098
+ value: 2481057792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711469680318
+ value: 2481385472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711472423116
+ value: 2481922048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711473803975
+ value: 2482434048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711477298197
+ value: 2483122176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711480135030
+ value: 2483662848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711482854024
+ value: 2484195328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711485537292
+ value: 2484736000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711488227966
+ value: 2485276672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711493645650
+ value: 2485817344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711496474548
+ value: 2486353920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711496535095
+ value: 2486624256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711499199727
+ value: 2487164928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711502103780
+ value: 2487705600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711505204895
+ value: 2488246272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711507878438
+ value: 2488786944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711510628723
+ value: 2489327616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711516485616
+ value: 2489872384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711517469543
+ value: 2489544704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711517572001
+ value: 2488963072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711517623759
+ value: 2488631296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711517801452
+ value: 2488090624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711518767598
+ value: 2486964224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711518922342
+ value: 2484867072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711519051330
+ value: 2482769920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711519427022
+ value: 2480672768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711519502380
+ value: 2478575616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711519606262
+ value: 2476478464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711519695577
+ value: 2474381312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711519786071
+ value: 2472284160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711519876607
+ value: 2470187008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711519947245
+ value: 2468089856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711520042134
+ value: 2465992704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711520081237
+ value: 2464751616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711520147969
+ value: 2463895552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711520258850
+ value: 2461798400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711520320129
+ value: 2459701248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711520375264
+ value: 2457604096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711520420511
+ value: 2455506944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711520463806
+ value: 2453409792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711520508931
+ value: 2451312640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711520526306
+ value: 2450489344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711528992736
+ value: 2451017728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711533639668
+ value: 2451542016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711533870870
+ value: 2452078592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711534082499
+ value: 2452619264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711534324930
+ value: 2453155840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711534568705
+ value: 2453692416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711534823710
+ value: 2454233088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711535071146
+ value: 2454769664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711535272562
+ value: 2455310336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711535497131
+ value: 2455846912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711535699523
+ value: 2456387584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711535927592
+ value: 2456924160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711536232198
+ value: 2457460736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711536455953
+ value: 2458001408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711536667948
+ value: 2458537984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711536870625
+ value: 2459078656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711537079203
+ value: 2459615232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711537178243
+ value: 2459885568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711537369730
+ value: 2460422144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711537552225
+ value: 2460962816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711537744567
+ value: 2461499392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711537933939
+ value: 2462035968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711538128316
+ value: 2462576640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711538370422
+ value: 2463113216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711538619893
+ value: 2463653888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711538810852
+ value: 2464190464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711539029642
+ value: 2464731136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711539250386
+ value: 2465267712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711539477681
+ value: 2465804288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711539692077
+ value: 2466344960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711539895162
+ value: 2466881536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711540306661
+ value: 2467422208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711540516906
+ value: 2467962880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711544242858
+ value: 2468503552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711544476013
+ value: 2469044224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711544696634
+ value: 2469584896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711544808939
+ value: 2469855232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711545037740
+ value: 2470395904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711545278829
+ value: 2470936576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711545505757
+ value: 2471477248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711545730082
+ value: 2472017920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711549507832
+ value: 2472587264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711549740498
+ value: 2473127936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711549990051
+ value: 2473668608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711550222025
+ value: 2474209280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711550454203
+ value: 2474749952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711550599914
+ value: 2475286528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711550805074
+ value: 2475827200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711551055521
+ value: 2476367872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711551322774
+ value: 2476908544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711555154927
+ value: 2477449216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711555270894
+ value: 2477719552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711555491963
+ value: 2478260224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711555716329
+ value: 2478800896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711555965718
+ value: 2479341568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711556517517
+ value: 2479882240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711556749125
+ value: 2480422912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711556966532
+ value: 2480963584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711560568583
+ value: 2481504256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711560774271
+ value: 2482044928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711560975280
+ value: 2482585600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711561176778
+ value: 2483126272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711561382548
+ value: 2483666944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711561590149
+ value: 2484207616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711561793355
+ value: 2484748288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711565002258
+ value: 2485288960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711565212178
+ value: 2485829632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711565316467
+ value: 2486099968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711565520609
+ value: 2486640640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711565731262
+ value: 2487181312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711565933085
+ value: 2487721984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711566142801
+ value: 2488262656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711566350606
+ value: 2488803328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711566564595
+ value: 2489344000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711585067850
+ value: 2489053184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711585092305
+ value: 2488717312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711585110616
+ value: 2487828480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711591758931
+ value: 2488201216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711591760721
+ value: 2488160256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711593837056
+ value: 2488397824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711594193420
+ value: 2488922112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711600351664
+ value: 2489438208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711606451273
+ value: 2489942016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711606641377
+ value: 2490474496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711607219706
+ value: 2491015168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711617795878
+ value: 2491555840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711627197896
+ value: 2492043264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711627408060
+ value: 2492575744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711627590108
+ value: 2493112320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711627776672
+ value: 2493652992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711628946594
+ value: 2494193664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711634788391
+ value: 2494504960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711649300394
+ value: 2495045632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711661328186
+ value: 2495586304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711661514221
+ value: 2496126976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711661697977
+ value: 2496667648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711661897277
+ value: 2497208320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711662086690
+ value: 2497748992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711662282857
+ value: 2498289664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711662464416
+ value: 2498830336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711662577413
+ value: 2497822720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711662627583
+ value: 2495725568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711662675720
+ value: 2493628416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711662734598
+ value: 2491531264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711662781636
+ value: 2489434112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711662819600
+ value: 2487336960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711662869486
+ value: 2485239808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711662905700
+ value: 2483142656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711662942077
+ value: 2481045504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711662972676
+ value: 2478948352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711663004862
+ value: 2476851200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711663035339
+ value: 2474754048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711663074808
+ value: 2472656896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711663112528
+ value: 2470559744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711663144226
+ value: 2468462592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711663179667
+ value: 2466365440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711663213765
+ value: 2464268288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711663250834
+ value: 2462171136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711663264302
+ value: 2461347840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711665733052
+ value: 2459160576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711665782857
+ value: 2457063424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711665811910
+ value: 2454966272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711665830179
+ value: 2452869120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711665874694
+ value: 2450771968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711665935526
+ value: 2448674816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711665984476
+ value: 2446577664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711666027771
+ value: 2444480512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711666070129
+ value: 2442383360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711666111307
+ value: 2440286208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711666147603
+ value: 2438189056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711666180033
+ value: 2436091904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711666210754
+ value: 2433994752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711666228698
+ value: 2431897600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711666245544
+ value: 2429800448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711666262512
+ value: 2427703296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711666282002
+ value: 2425606144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711666299174
+ value: 2423742464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711671697408
+ value: 2422554624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711671730245
+ value: 2420457472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711671758117
+ value: 2418360320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711671785217
+ value: 2416263168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711671802714
+ value: 2414166016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711671820577
+ value: 2412068864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711671845601
+ value: 2409971712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711671872334
+ value: 2407874560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711671889994
+ value: 2405777408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711671908345
+ value: 2403680256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711671925598
+ value: 2401845248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711671926208
+ value: 2403942400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711671943746
+ value: 2399748096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711671961690
+ value: 2397650944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711671978414
+ value: 2395553792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711671995219
+ value: 2393456640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711672042338
+ value: 2391359488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711672059590
+ value: 2389262336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711672076355
+ value: 2387165184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711672082377
+ value: 2386751488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711672271911
+ value: 2387021824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711672641581
+ value: 2387562496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711673027038
+ value: 2388103168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711673464172
+ value: 2388643840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711673898905
+ value: 2389184512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711674140645
+ value: 2389725184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711674401224
+ value: 2390265856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711674621968
+ value: 2390806528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711674846211
+ value: 2391347200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711675190328
+ value: 2391887872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711675444071
+ value: 2392428544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711675667500
+ value: 2392969216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711683354675
+ value: 2393473024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711694661845
+ value: 2393964544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711694679016
+ value: 2393792512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711694915222
+ value: 2394042368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711696995056
+ value: 2394578944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711697326517
+ value: 2395062272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711697745870
+ value: 2395602944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711698138448
+ value: 2396143616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711698532857
+ value: 2396684288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711698915995
+ value: 2397224960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711699233052
+ value: 2397495296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711699594665
+ value: 2398035968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711700055969
+ value: 2398576640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711700450134
+ value: 2399117312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711700807841
+ value: 2399657984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711701173604
+ value: 2400198656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711701574442
+ value: 2400739328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711701993794
+ value: 2401280000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711702428324
+ value: 2401820672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711702839823
+ value: 2402361344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711703254781
+ value: 2402902016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711703645935
+ value: 2403442688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711704050720
+ value: 2403983360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711704512471
+ value: 2404524032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711704742574
+ value: 2405064704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711720802999
+ value: 2405371904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711732683329
+ value: 2405330944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711776709900
+ value: 2405810176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711776711975
+ value: 2406039552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711792077006
+ value: 2405822464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711792201355
+ value: 2405265408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711792387268
+ value: 2403926016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711792426330
+ value: 2402471936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711792783345
+ value: 2402152448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711792893249
+ value: 2401632256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711792958964
+ value: 2400956416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711793055399
+ value: 2399379456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711793249695
+ value: 2398973952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711793350525
+ value: 2397208576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711793430643
+ value: 2395111424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711793498677
+ value: 2393014272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711793588521
+ value: 2390917120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711793661885
+ value: 2388819968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711793727071
+ value: 2386722816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711793747986
+ value: 2386149376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711794612732
+ value: 2385334272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711794707011
+ value: 2384265216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711794747904
+ value: 2382168064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711794779439
+ value: 2380070912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711794806945
+ value: 2377973760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711794831644
+ value: 2375876608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711794852722
+ value: 2373779456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711794861918
+ value: 2372796416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711795610534
+ value: 2372202496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711795666320
+ value: 2371506176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711795689351
+ value: 2370977792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711795730814
+ value: 2370674688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711795799174
+ value: 2370117632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711795864481
+ value: 2369507328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711795883321
+ value: 2369110016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711795946675
+ value: 2368315392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711795987894
+ value: 2367967232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796073791
+ value: 2367442944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796132426
+ value: 2366156800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796184997
+ value: 2365562880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796220235
+ value: 2365165568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796225321
+ value: 2364674048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796270284
+ value: 2363785216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796319315
+ value: 2362896384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796359924
+ value: 2362744832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796543314
+ value: 2362253312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796613667
+ value: 2361761792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796627339
+ value: 2361167872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796686137
+ value: 2360602624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796717834
+ value: 2360037376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796747619
+ value: 2359652352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796782369
+ value: 2359087104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796824971
+ value: 2358632448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796903096
+ value: 2357358592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796924662
+ value: 2355261440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796943705
+ value: 2353164288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796961975
+ value: 2351067136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796980082
+ value: 2348969984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711796998148
+ value: 2346872832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711797006775
+ value: 2345824256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711797515238
+ value: 2344783872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711797552795
+ value: 2342686720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711797582173
+ value: 2340589568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711797607890
+ value: 2338492416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711797631978
+ value: 2336395264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711797651916
+ value: 2334298112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711797661600
+ value: 2333286400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711799046814
+ value: 2332209152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711799082743
+ value: 2330112000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711799108703
+ value: 2328014848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711799132181
+ value: 2325917696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711799152364
+ value: 2323820544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711799172180
+ value: 2321723392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711799180155
+ value: 2320748544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711799963195
+ value: 2319724544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711800216369
+ value: 2318708736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711800231181
+ value: 2317623296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711800369568
+ value: 2316627968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711800402893
+ value: 2314530816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711800548279
+ value: 2313883648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711800613301
+ value: 2313474048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711805475362
+ value: 2313728000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711828957946
+ value: 2314223616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711835992004
+ value: 2314747904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711836445333
+ value: 2315280384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711837231669
+ value: 2315669504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711837948466
+ value: 2316206080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711838249613
+ value: 2316746752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711839028137
+ value: 2317287424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711839585429
+ value: 2317963264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711840100077
+ value: 2318544896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711840333231
+ value: 2318852096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711840738627
+ value: 2319392768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711841150411
+ value: 2319962112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711841544616
+ value: 2320609280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711841793233
+ value: 2320928768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711842154968
+ value: 2321498112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711843226460
+ value: 2322190336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711843552225
+ value: 2322731008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711843712056
+ value: 2323001344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711844060119
+ value: 2323542016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711844364441
+ value: 2324082688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711844664530
+ value: 2324623360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711862513773
+ value: 2325180416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711881575378
+ value: 2325819392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711886007588
+ value: 2326196224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711886009338
+ value: 2326138880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711893434306
+ value: 2326343680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711928289286
+ value: 2326683648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711932350687
+ value: 2327216128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711937335307
+ value: 2327752704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711938207540
+ value: 2328289280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711940906351
+ value: 2328829952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711993208313
+ value: 2329387008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 711993221944
+ value: 2329247744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712011663065
+ value: 2329292800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712074977722
+ value: 2329931776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712123249003
+ value: 2330578944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712128499898
+ value: 2331115520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712134341207
+ value: 2330816512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712134457621
+ value: 2330292224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712144833191
+ value: 2330345472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712144836812
+ value: 2330304512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712146953796
+ value: 2330447872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712146981832
+ value: 2330271744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712150881734
+ value: 2330341376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712150884582
+ value: 2330300416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712151998230
+ value: 2330525696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712226808126
+ value: 2330992640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712297707296
+ value: 2331574272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712316395447
+ value: 2331987968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712404356506
+ value: 2332446720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712404361918
+ value: 2332397568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712439352763
+ value: 2332471296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712439373027
+ value: 2332409856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712442001282
+ value: 2332659712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712531165751
+ value: 2333204480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712619262431
+ value: 2333515776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712705719828
+ value: 2334052352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712822869080
+ value: 2333913088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712823002014
+ value: 2332475392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712823137390
+ value: 2330648576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712857344462
+ value: 2330955776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712905244772
+ value: 2331516928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712961938823
+ value: 2331344896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 712962195984
+ value: 2330640384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713027599467
+ value: 2330882048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713115969137
+ value: 2331488256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713158317973
+ value: 2331918336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713158321025
+ value: 2331836416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713195266093
+ value: 2332024832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713241856873
+ value: 2332479488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713241861186
+ value: 2332389376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713246064230
+ value: 2332471296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713246067851
+ value: 2332393472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713248504090
+ value: 2332483584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713248508199
+ value: 2332401664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713253954895
+ value: 2332585984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713363761536
+ value: 2332971008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713422580180
+ value: 2333515776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713452094381
+ value: 2334097408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713508836365
+ value: 2334658560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713544829977
+ value: 2335240192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713546620301
+ value: 2335780864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713548420390
+ value: 2336321536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713563796408
+ value: 2336862208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713565638123
+ value: 2337402880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713568482443
+ value: 2337943552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713569411072
+ value: 2338213888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713576140605
+ value: 2338754560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713582636740
+ value: 2338607104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713582730246
+ value: 2338082816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713582856955
+ value: 2337607680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713583009542
+ value: 2337087488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713583155661
+ value: 2336563200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713583288392
+ value: 2336038912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713583407288
+ value: 2335514624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713583527487
+ value: 2334994432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713592978537
+ value: 2335260672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713670600770
+ value: 2335608832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713791726828
+ value: 2336354304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713843574891
+ value: 2336649216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713883717306
+ value: 2337267712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713885238872
+ value: 2337120256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713914736756
+ value: 2337640448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713914741313
+ value: 2337607680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713914953797
+ value: 2337640448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713914955750
+ value: 2337607680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713954603171
+ value: 2337640448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713954606344
+ value: 2337607680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713954846579
+ value: 2337640448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713954850444
+ value: 2337607680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713957549500
+ value: 2337812480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713993958517
+ value: 2337853440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713993961162
+ value: 2337820672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713994118226
+ value: 2337853440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 713994119528
+ value: 2337820672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714025169943
+ value: 2338390016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714035181418
+ value: 2338930688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714037264425
+ value: 2339274752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714037266623
+ value: 2338791424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714037371115
+ value: 2338676736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714037460959
+ value: 2337988608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714037515524
+ value: 2337349632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714039737570
+ value: 2337124352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714040127300
+ value: 2337157120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714040130067
+ value: 2337124352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714040175273
+ value: 2336489472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714040447897
+ value: 2336522240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714040452332
+ value: 2336489472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714077941143
+ value: 2336522240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714077944561
+ value: 2336489472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714078085552
+ value: 2336522240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714078086569
+ value: 2336489472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714087567892
+ value: 2336706560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714087607769
+ value: 2336555008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714125162619
+ value: 2336595968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714125165345
+ value: 2336563200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714125306947
+ value: 2336616448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714125307883
+ value: 2336649216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714125308534
+ value: 2336616448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714171960755
+ value: 2336649216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714171963726
+ value: 2336616448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714172250469
+ value: 2336649216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714172252422
+ value: 2336616448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714178780091
+ value: 2337185792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714210765117
+ value: 2337218560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714210768128
+ value: 2337185792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714210897767
+ value: 2337218560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714210898906
+ value: 2337185792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714243624289
+ value: 2337652736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714243636659
+ value: 2337591296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714245264873
+ value: 2337624064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714245267030
+ value: 2337591296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714245398540
+ value: 2337624064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714245399476
+ value: 2337591296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714248468812
+ value: 2338078720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714248472271
+ value: 2338107392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714359366314
+ value: 2338131968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714359399354
+ value: 2338119680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714382926494
+ value: 2338652160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714382929872
+ value: 2338578432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714396257468
+ value: 2338779136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714409267762
+ value: 2338783232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714458403626
+ value: 2339164160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714503063376
+ value: 2339688448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714591718202
+ value: 2339680256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714638373597
+ value: 2340421632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714645144715
+ value: 2340737024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714659866029
+ value: 2341318656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714663732158
+ value: 2341851136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714667809958
+ value: 2342383616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714673183981
+ value: 2342895616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714682192893
+ value: 2343440384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714685140565
+ value: 2343202816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714685249574
+ value: 2342735872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714685327740
+ value: 2342281216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714685459413
+ value: 2341724160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714685553488
+ value: 2341216256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714685647279
+ value: 2340696064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714685742331
+ value: 2340167680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714685831809
+ value: 2339655680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714685925396
+ value: 2339041280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714686038352
+ value: 2338615296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714686179058
+ value: 2338091008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714686317689
+ value: 2337566720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714686480856
+ value: 2337042432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714686551250
+ value: 2337062912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714686569724
+ value: 2337050624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714686738506
+ value: 2336321536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714686799989
+ value: 2335793152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714686903952
+ value: 2334973952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714686927756
+ value: 2334474240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714687142844
+ value: 2333110272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714687415305
+ value: 2332848128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714687542868
+ value: 2332069888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714687609966
+ value: 2331000832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714687647279
+ value: 2328903680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714687652772
+ value: 2328604672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714687739401
+ value: 2328870912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714687980409
+ value: 2328571904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714688086081
+ value: 2328125440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714688239849
+ value: 2326401024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714688333111
+ value: 2324303872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714688887839
+ value: 2322206720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714688954489
+ value: 2320625664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714689433330
+ value: 2319843328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714689514589
+ value: 2317746176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714689530498
+ value: 2316828672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714690016257
+ value: 2316603392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714690284201
+ value: 2316079104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714690552390
+ value: 2315542528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714690638286
+ value: 2313605120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714690687766
+ value: 2312286208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714691146913
+ value: 2310627328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714691227967
+ value: 2308599808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714691274761
+ value: 2307559424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714691898378
+ value: 2306830336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714692073101
+ value: 2306134016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714692075949
+ value: 2306101248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714692237692
+ value: 2304741376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714692269349
+ value: 2303959040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714692597637
+ value: 2303434752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714692621522
+ value: 2302910464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714692836040
+ value: 2301603840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714692855694
+ value: 2301079552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714693138937
+ value: 2300817408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714693242128
+ value: 2299150336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714693522930
+ value: 2298245120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714693560894
+ value: 2297278464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714693596538
+ value: 2296377344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714694007102
+ value: 2295398400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714694226909
+ value: 2294874112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714694291322
+ value: 2294419456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714698084331
+ value: 2293846016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714699124126
+ value: 2293522432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714699472963
+ value: 2292264960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714700253561
+ value: 2291597312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714700693055
+ value: 2290806784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714701814353
+ value: 2290995200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714805068422
+ value: 2291572736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714881916363
+ value: 2292109312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714927676901
+ value: 2292535296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714927680848
+ value: 2292436992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 714970525209
+ value: 2292617216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 715137463360
+ value: 2293141504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 715187451560
+ value: 2293551104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 715187457785
+ value: 2293452800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 715269924542
+ value: 2293620736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 715435559877
+ value: 2294128640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 715440227846
+ value: 2294636544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 715615181947
+ value: 2295169024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 715737857200
+ value: 2295689216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 715737899843
+ value: 2295590912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 715738076560
+ value: 2294988800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 715738314760
+ value: 2293559296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 715738392152
+ value: 2292654080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 715739106711
+ value: 2292371456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 715739568300
+ value: 2291957760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 715765701316
+ value: 2291986432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 715765801129
+ value: 2291957760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 715807082094
+ value: 2292228096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 715858461773
+ value: 2292535296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 715951393211
+ value: 2293125120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716066262107
+ value: 2293551104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716066265484
+ value: 2293518336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716069317730
+ value: 2293731328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716144900372
+ value: 2294071296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716151410952
+ value: 2294587392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716229021262
+ value: 2295156736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716232979230
+ value: 2295730176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716233781354
+ value: 2293551104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716233816998
+ value: 2291453952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716233851951
+ value: 2289356800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716233887066
+ value: 2287259648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716233921857
+ value: 2285162496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716233956769
+ value: 2283065344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716233990826
+ value: 2280968192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716234024925
+ value: 2278871040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716234054303
+ value: 2277068800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716237909975
+ value: 2276712448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716238066306
+ value: 2276188160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716241146181
+ value: 2275143680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716311276796
+ value: 2275213312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716401743471
+ value: 2275778560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716477843447
+ value: 2276356096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716489562604
+ value: 2276831232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716489567527
+ value: 2276732928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716525903017
+ value: 2276970496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716572777854
+ value: 2277289984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716572784528
+ value: 2277265408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716573869163
+ value: 2277351424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716573889630
+ value: 2277244928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716574289451
+ value: 2277306368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716574291567
+ value: 2277269504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716618638206
+ value: 2277302272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716618657127
+ value: 2277281792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716621440289
+ value: 2277531648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716711434959
+ value: 2277842944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716775990582
+ value: 2278334464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 716922398297
+ value: 2278912000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717038895083
+ value: 2279538688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717132114647
+ value: 2280112128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717166952212
+ value: 2280513536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717166970075
+ value: 2280415232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717201923118
+ value: 2280452096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717205272891
+ value: 2280984576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717290925478
+ value: 2281549824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717404672590
+ value: 2281562112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717425459170
+ value: 2282135552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717433105288
+ value: 2282127360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717456373192
+ value: 2282659840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717521027041
+ value: 2283126784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717521031720
+ value: 2283012096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717529506940
+ value: 2283200512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717543045718
+ value: 2283741184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717669917544
+ value: 2284163072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717669936668
+ value: 2284097536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717708625186
+ value: 2284142592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717708657005
+ value: 2284097536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717708661603
+ value: 2284130304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717754511823
+ value: 2284679168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717758454206
+ value: 2284589056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717759373599
+ value: 2284638208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717759376406
+ value: 2284584960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717787687686
+ value: 2284867584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717843624006
+ value: 2285170688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717843650983
+ value: 2285142016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717859923973
+ value: 2285170688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717859930280
+ value: 2285150208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717874246402
+ value: 2285174784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717874354881
+ value: 2285142016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 717874480573
+ value: 2285170688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718020592064
+ value: 2285780992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718039461083
+ value: 2286317568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718043044172
+ value: 2286891008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718046496035
+ value: 2286608384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718046621849
+ value: 2286084096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718100310651
+ value: 2286370816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718186614769
+ value: 2286751744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718186627668
+ value: 2286714880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718188195336
+ value: 2286968832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718263919986
+ value: 2287267840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718435241316
+ value: 2287853568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718435266340
+ value: 2287738880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718437563703
+ value: 2287992832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718466265526
+ value: 2288324608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718542944807
+ value: 2288390144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718547085839
+ value: 2289152000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718548375552
+ value: 2289418240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718578449893
+ value: 2289344512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718599295881
+ value: 2289950720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718601272403
+ value: 2289737728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718639023135
+ value: 2290040832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718670094099
+ value: 2290053120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718675983625
+ value: 2290417664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718751398583
+ value: 2290991104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718774411278
+ value: 2291568640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718845598494
+ value: 2291974144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718921782738
+ value: 2310230016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718922053287
+ value: 2310234112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718922923689
+ value: 2328489984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718923182722
+ value: 2328494080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718924023298
+ value: 2346749952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718924254377
+ value: 2346754048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718925063907
+ value: 2365009920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718925309268
+ value: 2365014016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718932729434
+ value: 2376699904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718932935163
+ value: 2376704000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718945523746
+ value: 2377424896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 718976965030
+ value: 2377764864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719039378848
+ value: 2377760768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719078436303
+ value: 2377764864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719078438866
+ value: 2377748480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719098991723
+ value: 2378276864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719106788598
+ value: 2378833920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719180462263
+ value: 2379501568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719239192000
+ value: 2379857920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719357202905
+ value: 2361602048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719357270532
+ value: 2361597952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719357526025
+ value: 2343342080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719357553165
+ value: 2343337984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719387650943
+ value: 2343923712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719387654076
+ value: 2343796736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719395224186
+ value: 2343837696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719395244815
+ value: 2343833600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719427435367
+ value: 2344083456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719428286157
+ value: 2344624128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719428686181
+ value: 2344894464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719429773827
+ value: 2345562112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719430322900
+ value: 2345934848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719431318546
+ value: 2346606592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719434836897
+ value: 2328350720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719434876000
+ value: 2328346624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719459134871
+ value: 2328793088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719480843123
+ value: 2299138048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719497542179
+ value: 2299539456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719497590234
+ value: 2299543552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719513735742
+ value: 2299523072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719513799259
+ value: 2299449344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719513863549
+ value: 2299154432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719513888085
+ value: 2298572800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719513937036
+ value: 2297393152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719514068627
+ value: 2292674560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719514166243
+ value: 2290708480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719514238590
+ value: 2290225152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719514240706
+ value: 2290221056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719515141585
+ value: 2289725440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719515559024
+ value: 2289057792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719515649275
+ value: 2288611328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719515985009
+ value: 2288136192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719516213688
+ value: 2287595520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719516348941
+ value: 2287091712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719516475162
+ value: 2286501888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719516601383
+ value: 2285789184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719516888533
+ value: 2285715456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517403019
+ value: 2285518848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517443627
+ value: 2285322240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517462385
+ value: 2285273088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517486555
+ value: 2285223936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517504662
+ value: 2285199360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517520654
+ value: 2285174784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517537174
+ value: 2285162496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517553084
+ value: 2285150208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517580916
+ value: 2282004480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517610497
+ value: 2280431616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517629785
+ value: 2279645184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517648176
+ value: 2279251968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517662581
+ value: 2279055360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517676171
+ value: 2278957056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517687809
+ value: 2278858752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517699975
+ value: 2278809600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517713240
+ value: 2278760448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517728906
+ value: 2278735872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517754947
+ value: 2278539264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517773950
+ value: 2278342656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517789168
+ value: 2278293504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517804711
+ value: 2278244352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517822208
+ value: 2278219776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517849674
+ value: 2276646912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517884220
+ value: 2275074048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517903507
+ value: 2274680832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517923364
+ value: 2274287616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517938663
+ value: 2274189312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517953352
+ value: 2274091008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719517974308
+ value: 2274082816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719519795190
+ value: 2274078720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719519848087
+ value: 2274074624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719520112003
+ value: 2274054144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719535660139
+ value: 2255798272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719535688378
+ value: 2255794176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719543147932
+ value: 2255638528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719548694319
+ value: 2255761408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719553726749
+ value: 2251825152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719553745751
+ value: 2251821056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719553892358
+ value: 2251358208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719553924706
+ value: 2250895360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719553954980
+ value: 2250432512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719553987369
+ value: 2249969664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554016910
+ value: 2249506816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554085554
+ value: 2249244672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554094628
+ value: 2249240576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554142358
+ value: 2248978432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554153385
+ value: 2248974336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554195621
+ value: 2248712192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554204207
+ value: 2248708096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554251041
+ value: 2248445952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554260766
+ value: 2248441856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554302636
+ value: 2248179712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554311629
+ value: 2248175616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554346297
+ value: 2248155136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554355533
+ value: 2248151040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554385888
+ value: 2248130560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554392805
+ value: 2248126464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554421736
+ value: 2248105984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554430607
+ value: 2248101888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554466739
+ value: 2248081408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554476383
+ value: 2248077312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554506412
+ value: 2248065024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554515038
+ value: 2248060928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554540104
+ value: 2248048640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554547468
+ value: 2248044544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554570987
+ value: 2248032256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554578067
+ value: 2248028160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554603987
+ value: 2248015872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554613427
+ value: 2248011776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554638818
+ value: 2247999488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554646264
+ value: 2247995392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554669457
+ value: 2247983104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554676049
+ value: 2247979008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554702091
+ value: 2247966720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554713362
+ value: 2247962624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554738956
+ value: 2247950336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554748600
+ value: 2247946240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554769474
+ value: 2247933952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554776350
+ value: 2247929856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554801009
+ value: 2247917568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554809594
+ value: 2247913472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554832055
+ value: 2247901184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554838810
+ value: 2247897088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554861108
+ value: 2247884800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554868229
+ value: 2247880704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554892480
+ value: 2247585792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554915999
+ value: 2247290880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554938216
+ value: 2246995968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719554964705
+ value: 2246701056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555001448
+ value: 2246500352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555011132
+ value: 2246496256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555043196
+ value: 2246295552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555052026
+ value: 2246291456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555085148
+ value: 2246090752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555093977
+ value: 2246086656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555127302
+ value: 2245885952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555135847
+ value: 2245881856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555165348
+ value: 2245877760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555173242
+ value: 2245873664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555200992
+ value: 2245869568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555208805
+ value: 2245865472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555238102
+ value: 2245861376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555246321
+ value: 2245857280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555276961
+ value: 2245853184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555284488
+ value: 2245849088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555321842
+ value: 2245533696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555327945
+ value: 2245529600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555365787
+ value: 2245214208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555372786
+ value: 2245210112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555411238
+ value: 2244894720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555419173
+ value: 2244890624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555460758
+ value: 2244575232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555467675
+ value: 2244571136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555492455
+ value: 2244554752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555499210
+ value: 2244550656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555524153
+ value: 2244534272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555530989
+ value: 2244530176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555554386
+ value: 2244513792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555563541
+ value: 2244509696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555590112
+ value: 2244493312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555596704
+ value: 2244489216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555629337
+ value: 2244386816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555635969
+ value: 2244382720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555664005
+ value: 2244280320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555669702
+ value: 2244276224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555694807
+ value: 2244173824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555701236
+ value: 2244169728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555748111
+ value: 2244067328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555756982
+ value: 2244063232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555781396
+ value: 2243960832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555789290
+ value: 2243956736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555818098
+ value: 2243854336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555825504
+ value: 2243850240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555852075
+ value: 2243747840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555858382
+ value: 2243743744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555887068
+ value: 2243641344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555894881
+ value: 2243637248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555921940
+ value: 2243534848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555930891
+ value: 2243530752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555959781
+ value: 2243428352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555969913
+ value: 2243424256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719555999536
+ value: 2243321856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719556073022
+ value: 2243317760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719556280216
+ value: 2239414272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719556290877
+ value: 2239410176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719556619164
+ value: 2235506688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719556631168
+ value: 2235502592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719556994612
+ value: 2231599104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719557005680
+ value: 2231595008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719557331730
+ value: 2226847744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719557343896
+ value: 2226843648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719557693790
+ value: 2222096384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719557706892
+ value: 2222092288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719557783105
+ value: 2222088192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719557794905
+ value: 2222084096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719557838565
+ value: 2222080000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719557852359
+ value: 2222075904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719557945174
+ value: 2222047232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719557957136
+ value: 2222043136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719557996158
+ value: 2222039040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719558253238
+ value: 2215612416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719558267073
+ value: 2212397056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719558274397
+ value: 2212392960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719559427677
+ value: 2187026432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719559438134
+ value: 2187022336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719560634830
+ value: 2161655808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719560646223
+ value: 2161651712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719561602685
+ value: 2136285184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719561618066
+ value: 2136281088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719563925561
+ value: 2131533824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719563938907
+ value: 2131529728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719564357934
+ value: 2126782464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719564372704
+ value: 2126778368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719564550846
+ value: 2124402688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719564565006
+ value: 2124398592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719564764835
+ value: 2119651328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719564773299
+ value: 2119647232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719564834903
+ value: 2119643136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719564848779
+ value: 2119639040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719564884342
+ value: 2119634944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719564896752
+ value: 2119630848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719564931787
+ value: 2119626752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719564943709
+ value: 2119622656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719568975121
+ value: 2119933952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719574009627
+ value: 2119884800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719585964623
+ value: 2119819264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719588378971
+ value: 2119233536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719588597558
+ value: 2118668288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719588744978
+ value: 2118066176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719588812117
+ value: 2117730304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719589061181
+ value: 2116644864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719589467106
+ value: 2116038656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719591064640
+ value: 2114068480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719591069645
+ value: 2110164992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719591073103
+ value: 2084798464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719591108137
+ value: 2084794368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719591115746
+ value: 2084790272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719591117537
+ value: 2084786176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719591343001
+ value: 2084683776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719591354313
+ value: 2084679680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719591732934
+ value: 2082304000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719591747094
+ value: 2078400512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719591757552
+ value: 2078396416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719591767643
+ value: 2078392320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719591861881
+ value: 2053025792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719591887963
+ value: 2053021696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719591985782
+ value: 2050646016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719592001245
+ value: 2050641920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719592102644
+ value: 2048266240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719592124454
+ value: 2048237568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719592126774
+ value: 2048233472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719592150130
+ value: 2048229376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719592174706
+ value: 2041802752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719592202498
+ value: 2038587392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719592214135
+ value: 2038583296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719592397607
+ value: 2038128640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719592428409
+ value: 2038124544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719592452457
+ value: 2038120448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719592460799
+ value: 2038284288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719592499373
+ value: 2035908608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719592517358
+ value: 2035904512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719592563094
+ value: 2034864128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719592663028
+ value: 2034696192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719592766707
+ value: 2033807360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719592905908
+ value: 2033283072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719593094303
+ value: 2032394240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719593286482
+ value: 2032099328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719593307153
+ value: 2031505408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719593534244
+ value: 2030911488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719593720646
+ value: 2030514176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719593921004
+ value: 2029719552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719594036726
+ value: 2029445120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719594132552
+ value: 2028924928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719594334537
+ value: 2028130304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719596272241
+ value: 2027929600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719596611759
+ value: 2027339776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719596803531
+ value: 2026872832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719597005436
+ value: 2026319872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719597293481
+ value: 2025791488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719597307356
+ value: 2026311680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719597499861
+ value: 2025799680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719597604150
+ value: 2025201664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719597706160
+ value: 2024706048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719597819482
+ value: 2024218624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719597870670
+ value: 2023632896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719598152774
+ value: 2023170048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719598303206
+ value: 2022653952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719598416487
+ value: 2022117376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719598543806
+ value: 2021552128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719598632429
+ value: 2021056512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719598755151
+ value: 2020556800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719598851790
+ value: 2020028416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719599010563
+ value: 2019377152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719599142805
+ value: 2018971648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719599241235
+ value: 2018430976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719599297591
+ value: 2017734656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719599354028
+ value: 2016997376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719599429264
+ value: 2016768000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719599505029
+ value: 2016301056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719599606510
+ value: 2015797248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719599679955
+ value: 2015264768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719599741560
+ value: 2014789632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719599832788
+ value: 2014261248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719600050968
+ value: 2013728768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719600271508
+ value: 2012852224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719603917260
+ value: 1997180928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719603976708
+ value: 1997176832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719604550846
+ value: 1981505536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719604585921
+ value: 1981501440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719604956811
+ value: 1965830144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719604989241
+ value: 1965826048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719605353173
+ value: 1950154752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719605385563
+ value: 1950150656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719605750309
+ value: 1934479360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719605781070
+ value: 1934475264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719606612491
+ value: 1918803968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719606664819
+ value: 1918799872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719607162784
+ value: 1918009344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719607220727
+ value: 1917612032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719607237329
+ value: 1917607936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719607365421
+ value: 1901936640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719607400537
+ value: 1901932544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719607756738
+ value: 1886261248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719607792057
+ value: 1886257152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719608630802
+ value: 1870585856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719608672753
+ value: 1870581760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719609125390
+ value: 1854910464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719609158634
+ value: 1854906368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719610145816
+ value: 1854115840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719610184350
+ value: 1853718528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719610196557
+ value: 1853714432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719612485782
+ value: 1852530688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719612549706
+ value: 1852526592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719613013899
+ value: 1851342848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719613065657
+ value: 1851338752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719613216821
+ value: 1850155008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719613247094
+ value: 1850150912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719621770410
+ value: 1850327040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719623455875
+ value: 1849536512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719623495222
+ value: 1849139200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719623504703
+ value: 1849135104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719632118758
+ value: 1848344576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719632167789
+ value: 1847947264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719632176904
+ value: 1847943168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719634892032
+ value: 1847152640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719634936262
+ value: 1846755328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719634946883
+ value: 1846751232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719636475610
+ value: 1831079936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719636590112
+ value: 1831075840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719637285953
+ value: 1815404544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719637320499
+ value: 1815400448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719638637272
+ value: 1799729152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719638679833
+ value: 1799725056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719639780704
+ value: 1784053760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719639830183
+ value: 1784049664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719640840234
+ value: 1768378368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719640893009
+ value: 1768374272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719641599348
+ value: 1752702976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719641640323
+ value: 1752698880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719642938907
+ value: 1737027584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719642990787
+ value: 1737023488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719644181664
+ value: 1721352192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719644225040
+ value: 1721348096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719644911279
+ value: 1705676800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719644944848
+ value: 1705672704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719645536157
+ value: 1690001408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719645570540
+ value: 1689997312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719646202254
+ value: 1674326016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719646235009
+ value: 1674321920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719650111108
+ value: 1658650624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719650158715
+ value: 1658646528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719653944075
+ value: 1657462784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719654004174
+ value: 1657458688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719654295760
+ value: 1656274944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719654335921
+ value: 1656270848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719654656803
+ value: 1655087104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719654732812
+ value: 1655083008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719657960961
+ value: 1653899264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719658014265
+ value: 1653895168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719658257307
+ value: 1652711424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719658337019
+ value: 1652707328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719664327254
+ value: 1651523584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719664369165
+ value: 1651519488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719664754296
+ value: 1650335744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719664792057
+ value: 1650331648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719666483341
+ value: 1649147904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719666535546
+ value: 1649143808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719666825504
+ value: 1647960064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719666864078
+ value: 1647955968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719667434106
+ value: 1646772224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719667470076
+ value: 1646768128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719667800846
+ value: 1645584384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719667838850
+ value: 1645580288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719668211083
+ value: 1644396544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719668247623
+ value: 1644392448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719668470361
+ value: 1643208704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719668505192
+ value: 1643204608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719668724999
+ value: 1642020864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719668757755
+ value: 1642016768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719668995222
+ value: 1640833024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719669035099
+ value: 1640828928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719669267114
+ value: 1639645184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719669301212
+ value: 1639641088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719669524845
+ value: 1638457344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719669558699
+ value: 1638453248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719669736800
+ value: 1638850560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719669792382
+ value: 1637666816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719669829858
+ value: 1637662720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719670044824
+ value: 1636478976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719670082869
+ value: 1636474880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719670310042
+ value: 1635291136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719670344669
+ value: 1635287040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719670568383
+ value: 1634103296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719670602604
+ value: 1634099200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719670836165
+ value: 1632915456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719670870914
+ value: 1632911360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719671117862
+ value: 1631727616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719671156355
+ value: 1631723520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719671377831
+ value: 1630539776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719671413191
+ value: 1630535680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719671644962
+ value: 1629351936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719671676944
+ value: 1629347840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719671903263
+ value: 1628164096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719671939355
+ value: 1628160000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719672227807
+ value: 1626976256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719672270613
+ value: 1626972160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719680340315
+ value: 1625788416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719680386783
+ value: 1625784320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719680612369
+ value: 1624600576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719680653873
+ value: 1624596480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719680875024
+ value: 1623412736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719680907495
+ value: 1623408640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719681368351
+ value: 1622224896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719681404117
+ value: 1622220800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719681614282
+ value: 1621037056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719681655175
+ value: 1621032960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719681882836
+ value: 1619849216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719681917016
+ value: 1619845120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719682125878
+ value: 1618661376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719682161686
+ value: 1618657280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719682367252
+ value: 1617473536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719682402571
+ value: 1617469440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719682632023
+ value: 1616285696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719682670841
+ value: 1616281600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719682871199
+ value: 1615097856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719682905786
+ value: 1615093760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719683358056
+ value: 1613910016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719683395939
+ value: 1613905920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719683667748
+ value: 1612722176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719683809147
+ value: 1612718080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719684550154
+ value: 1611534336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719684587426
+ value: 1611530240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719685444197
+ value: 1610346496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719685485620
+ value: 1610342400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719685694929
+ value: 1609158656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719685729109
+ value: 1609154560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719687680688
+ value: 1593483264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719687723453
+ value: 1593479168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719688357568
+ value: 1592295424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719688382511
+ value: 1592291328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719693389021
+ value: 1591107584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719693441715
+ value: 1591103488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719695643660
+ value: 1589919744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719695698103
+ value: 1589915648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719708970320
+ value: 1586765824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719709370711
+ value: 1586761728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719709518741
+ value: 1586757632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719709674462
+ value: 1586753536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719709790714
+ value: 1586749440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719711076888
+ value: 1586708480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719711251041
+ value: 1586667520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719711287988
+ value: 1586626560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719711331730
+ value: 1586585600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719711376896
+ value: 1586544640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719711474023
+ value: 1589694464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719711508040
+ value: 1589698560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719712830346
+ value: 1586548736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719718637190
+ value: 1587732480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719722021834
+ value: 1587728384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719726683292
+ value: 1588277248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719726686385
+ value: 1588224000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719728621158
+ value: 1588219904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719728687809
+ value: 1588215808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719729983382
+ value: 1588195328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719730041324
+ value: 1588191232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719730084497
+ value: 1588187136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719730124820
+ value: 1588183040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719730164453
+ value: 1588178944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719730202945
+ value: 1588174848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719730241153
+ value: 1588170752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719730283227
+ value: 1588166656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719730322737
+ value: 1588162560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719730361678
+ value: 1588158464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719730405786
+ value: 1588154368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719730449039
+ value: 1588101120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719730525821
+ value: 1585537024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719730580305
+ value: 1585467392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719730627913
+ value: 1585397760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719730642521
+ value: 1585332224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719730712955
+ value: 1585299456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719730763574
+ value: 1582149632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719730816512
+ value: 1578999808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719730868839
+ value: 1575849984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719732620548
+ value: 1574666240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719732806746
+ value: 1573482496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719732866805
+ value: 1572298752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719732897444
+ value: 1571115008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719732924991
+ value: 1569931264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719732954248
+ value: 1568747520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719732982731
+ value: 1567563776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719740932845
+ value: 1567637504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719740936385
+ value: 1567555584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719746757836
+ value: 1567739904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719756206445
+ value: 1567604736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719760192081
+ value: 1566310400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719763796004
+ value: 1565929472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719769898299
+ value: 1565302784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719846737898
+ value: 1565704192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719846742211
+ value: 1565671424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719872301782
+ value: 1565667328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719954856795
+ value: 1565143040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719955370182
+ value: 1564176384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719956369856
+ value: 1564094464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719956889103
+ value: 1563488256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719957292545
+ value: 1562849280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719957590437
+ value: 1560752128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719959511743
+ value: 1560182784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719960064396
+ value: 1558908928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719961204370
+ value: 1558757376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719961631534
+ value: 1556873216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719961978499
+ value: 1556668416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719964428247
+ value: 1556226048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719964766137
+ value: 1555648512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719965281111
+ value: 1555177472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719965713281
+ value: 1554657280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719966287052
+ value: 1553702912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719966404931
+ value: 1552834560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719967514754
+ value: 1551974400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719969245345
+ value: 1551499264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 719971707666
+ value: 1551572992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720615530745
+ value: 1551486976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720616136784
+ value: 1550925824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720616800521
+ value: 1550405632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720617496077
+ value: 1549926400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720617939925
+ value: 1549344768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720619932723
+ value: 1548800000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720620438542
+ value: 1547894784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720620972477
+ value: 1547759616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720621121891
+ value: 1546944512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720621713403
+ value: 1546592256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720622076074
+ value: 1545977856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720622641219
+ value: 1545736192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720622758284
+ value: 1544761344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720623217554
+ value: 1544646656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720623330916
+ value: 1543856128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720624044010
+ value: 1543622656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720624305729
+ value: 1542807552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720624710921
+ value: 1542578176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720809235050
+ value: 1542070272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720809841943
+ value: 1541435392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720952995508
+ value: 1541017600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720953595036
+ value: 1540456448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720954070134
+ value: 1539903488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720954535750
+ value: 1539350528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720958165959
+ value: 1538908160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720958805444
+ value: 1538355200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720959622420
+ value: 1537802240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720960104517
+ value: 1537359872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720960640202
+ value: 1536786432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720961141138
+ value: 1536208896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720961616195
+ value: 1535320064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720962082422
+ value: 1535049728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720962510563
+ value: 1534599168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720962805404
+ value: 1533960192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720963655176
+ value: 1533476864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720964449854
+ value: 1533050880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720964846135
+ value: 1532461056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720965245589
+ value: 1531961344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720966026839
+ value: 1531576320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720966528019
+ value: 1531011072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720966753158
+ value: 1530388480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720966807438
+ value: 1529958400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720968443791
+ value: 1529237504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720968548446
+ value: 1528598528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720969326156
+ value: 1528442880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720969748153
+ value: 1527296000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720970912459
+ value: 1526697984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720971455184
+ value: 1525833728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720972692529
+ value: 1525350400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720973030786
+ value: 1525100544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720973379582
+ value: 1524649984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720973602767
+ value: 1524011008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720974256657
+ value: 1523527680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720979505029
+ value: 1521647616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720979563216
+ value: 1521418240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720979620264
+ value: 1520865280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720981482039
+ value: 1520140288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720981998112
+ value: 1519337472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720983303410
+ value: 1518567424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720983631535
+ value: 1518346240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720984424789
+ value: 1517895680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720985029525
+ value: 1517432832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720985527328
+ value: 1516728320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720985886540
+ value: 1516326912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720986444930
+ value: 1514819584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720987125106
+ value: 1514811392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720987971297
+ value: 1513848832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720990881820
+ value: 1513447424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720995485417
+ value: 1513168896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720995848250
+ value: 1512718336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720996231226
+ value: 1512079360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720996987289
+ value: 1511596032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 720997514632
+ value: 1511116800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 721155417505
+ value: 1510170624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 721155875676
+ value: 1509859328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 721364646346
+ value: 1509568512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 721446685083
+ value: 1509593088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 721732490381
+ value: 1509224448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 721733467269
+ value: 1508990976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 721734114405
+ value: 1508503552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 721735015162
+ value: 1507999744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 721735768417
+ value: 1506344960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 721743440048
+ value: 1505902592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 721744926050
+ value: 1505366016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 721749300318
+ value: 1504845824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 721749435653
+ value: 1504059392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 721750166732
+ value: 1503215616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 721750960271
+ value: 1502097408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 721752062769
+ value: 1501659136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722036639633
+ value: 1499983872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722036999008
+ value: 1497886720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722037073267
+ value: 1497432064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722040611964
+ value: 1496969216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722049678126
+ value: 1496068096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722049840316
+ value: 1494667264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722050283513
+ value: 1493970944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722050325668
+ value: 1493630976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722052967717
+ value: 1492467712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722053540268
+ value: 1491922944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722053613062
+ value: 1491161088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722056047185
+ value: 1490149376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722056224797
+ value: 1489190912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722057006739
+ value: 1488015360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722057709009
+ value: 1487552512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722057892685
+ value: 1486630912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722058164372
+ value: 1486323712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722058596583
+ value: 1485774848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722338191147
+ value: 1485307904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722338406804
+ value: 1484898304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722338708765
+ value: 1483960320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722338987533
+ value: 1483702272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722339168604
+ value: 1483251712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722339346542
+ value: 1482612736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722339842921
+ value: 1482129408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722608571599
+ value: 1481629696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722608802393
+ value: 1480765440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722609183660
+ value: 1480282112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 722749995468
+ value: 1480130560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723161694280
+ value: 1479618560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723165598007
+ value: 1478094848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723165923406
+ value: 1477361664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723168265447
+ value: 1476681728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723909874945
+ value: 1477128192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723910093817
+ value: 1477668864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723910574977
+ value: 1478197248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723910684311
+ value: 1478737920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723910906520
+ value: 1479278592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723911604071
+ value: 1479819264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723911950872
+ value: 1480359936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723912193304
+ value: 1480900608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723912419053
+ value: 1481441280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723912539007
+ value: 1481572352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723912754420
+ value: 1482113024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723913135361
+ value: 1482653696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723913688625
+ value: 1483194368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723914070216
+ value: 1483735040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723915224798
+ value: 1484275712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723915447210
+ value: 1484546048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723915690293
+ value: 1485086720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723915873114
+ value: 1485627392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723916085394
+ value: 1486168064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723916273382
+ value: 1486708736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723916455226
+ value: 1487249408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723916659531
+ value: 1487790080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723916833156
+ value: 1488330752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723917009100
+ value: 1488871424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723917593573
+ value: 1489276928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723917594997
+ value: 1489244160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723917672145
+ value: 1488728064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723917682480
+ value: 1488781312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723917692490
+ value: 1488556032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723917733343
+ value: 1487917056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723917939072
+ value: 1487667200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723918506781
+ value: 1487155200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723918621323
+ value: 1486626816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723918719753
+ value: 1486090240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723918775254
+ value: 1485004800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723918905544
+ value: 1483218944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723923780177
+ value: 1483501568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723929314601
+ value: 1483354112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723929378566
+ value: 1482833920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723929463446
+ value: 1481744384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723930379705
+ value: 1482022912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723936225490
+ value: 1482571776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723937178371
+ value: 1482457088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723937509954
+ value: 1482567680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723937672959
+ value: 1482522624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723945090399
+ value: 1482649600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723945322007
+ value: 1483190272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723949940781
+ value: 1501446144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723950129380
+ value: 1501450240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723958307114
+ value: 1501847552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723959336492
+ value: 1501814784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723960088812
+ value: 1501859840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723963221339
+ value: 1502404608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723964580714
+ value: 1503051776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723964897283
+ value: 1503592448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723965272650
+ value: 1504133120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723966056829
+ value: 1504673792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723966451890
+ value: 1505214464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723966750229
+ value: 1505755136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723968629868
+ value: 1506295808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723968900742
+ value: 1505996800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723968943914
+ value: 1505472512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723969013413
+ value: 1504952320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723969123968
+ value: 1504428032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723969222194
+ value: 1503903744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723969289455
+ value: 1503379456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723969359157
+ value: 1502855168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723971546535
+ value: 1503170560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723973635850
+ value: 1503383552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723973851182
+ value: 1503924224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723978634385
+ value: 1522180096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723978902451
+ value: 1522184192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723986498073
+ value: 1522593792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723986511094
+ value: 1522515968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723988939357
+ value: 1540771840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723989140570
+ value: 1540775936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723989780544
+ value: 1540648960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723989848984
+ value: 1540243456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723992167181
+ value: 1540382720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723992369167
+ value: 1540923392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723992657822
+ value: 1541464064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723994131455
+ value: 1559719936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723994316473
+ value: 1559724032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723995160874
+ value: 1559961600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723996335475
+ value: 1560502272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723997870143
+ value: 1561042944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 723998179591
+ value: 1561583616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724000108262
+ value: 1561903104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724002146999
+ value: 1562099712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724002174302
+ value: 1562296320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724002212510
+ value: 1562345472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724002224757
+ value: 1562394624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724002257554
+ value: 1562419200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724002272650
+ value: 1563992064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724002311834
+ value: 1565564928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724002331528
+ value: 1565958144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724002363796
+ value: 1566351360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724002377101
+ value: 1566449664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724002388413
+ value: 1566547968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724002493109
+ value: 1568120832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724002534409
+ value: 1571266560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724002740098
+ value: 1571463168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724002820135
+ value: 1571659776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724003659328
+ value: 1572052992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724003758286
+ value: 1572839424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724003806748
+ value: 1572888576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724003821763
+ value: 1572937728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724003853908
+ value: 1573036032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724003867132
+ value: 1573232640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724003878159
+ value: 1573257216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724003909409
+ value: 1573281792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724003921250
+ value: 1573330944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724003933254
+ value: 1573429248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724003960679
+ value: 1573441536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724003971014
+ value: 1573453824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724003981227
+ value: 1573478400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724004028957
+ value: 1573527552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724005992580
+ value: 1574252544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724007571559
+ value: 1574719488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724007662257
+ value: 1574793216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724007790472
+ value: 1574801408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724020522975
+ value: 1575297024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724021011745
+ value: 1575821312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724022390041
+ value: 1576423424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724023200303
+ value: 1576865792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724026576686
+ value: 1577512960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724029508693
+ value: 1577955328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724030869492
+ value: 1578455040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724032856309
+ value: 1578946560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724039564642
+ value: 1594617856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724039582301
+ value: 1594621952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724040973008
+ value: 1595805696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724040986151
+ value: 1595809792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724041579209
+ value: 1596600320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724041603704
+ value: 1596997632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724041613104
+ value: 1597001728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724047018703
+ value: 1597358080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724047711370
+ value: 1597890560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724049291571
+ value: 1598406656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724052892401
+ value: 1598947328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724071905096
+ value: 1598951424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724071917140
+ value: 1598955520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724071924180
+ value: 1624322048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724071947332
+ value: 1624326144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724072070501
+ value: 1624588288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724072080104
+ value: 1624592384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724072678208
+ value: 1624694784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724072687078
+ value: 1624698880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724072795314
+ value: 1624801280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724072806463
+ value: 1624805376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724072891709
+ value: 1624817664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724072900946
+ value: 1624821760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724072977565
+ value: 1624834048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724072987005
+ value: 1624838144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724073066025
+ value: 1624850432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724073073268
+ value: 1624854528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724073152736
+ value: 1624875008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724073160101
+ value: 1624879104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724073238999
+ value: 1625079808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724073247707
+ value: 1625083904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724073342067
+ value: 1625399296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724073350815
+ value: 1625403392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724073446885
+ value: 1625419776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724073454494
+ value: 1625423872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724073535955
+ value: 1625526272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724073544663
+ value: 1625530368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724073645046
+ value: 1625825280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724073694647
+ value: 1626288128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724073839137
+ value: 1626968064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724073863755
+ value: 1642639360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724073877427
+ value: 1642643456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724073919744
+ value: 1646546944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724073941147
+ value: 1646551040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724075907375
+ value: 1671917568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724075918646
+ value: 1671921664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724075977362
+ value: 1671925760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724075990423
+ value: 1671929856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724076247544
+ value: 1672192000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724076261867
+ value: 1672196096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724076653224
+ value: 1672298496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724076668564
+ value: 1672302592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724077502712
+ value: 1672404992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724077517157
+ value: 1672409088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724077796413
+ value: 1672421376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724077811712
+ value: 1672425472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724077855698
+ value: 1676328960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724077864976
+ value: 1676333056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724077988673
+ value: 1676345344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724078000636
+ value: 1676349440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724078135768
+ value: 1676361728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724078143906
+ value: 1676365824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724078267482
+ value: 1676386304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724078277085
+ value: 1676390400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724078364406
+ value: 1676591104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724078372381
+ value: 1676595200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724078464666
+ value: 1676910592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724078473211
+ value: 1676914688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724078569159
+ value: 1692585984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724078570461
+ value: 1692602368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724078578517
+ value: 1692606464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724078579657
+ value: 1692610560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724078654852
+ value: 1717977088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724078665228
+ value: 1718079488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724078665960
+ value: 1718083584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724078674871
+ value: 1718087680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724078775457
+ value: 1718382592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724078830755
+ value: 1718845440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724078856756
+ value: 1719136256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724079030625
+ value: 1719640064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724080023870
+ value: 1719644160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724080042588
+ value: 1719648256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724080155828
+ value: 1719910400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724080168605
+ value: 1719914496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724080447739
+ value: 1720016896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724080459051
+ value: 1720020992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724080558457
+ value: 1720123392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724080569810
+ value: 1720127488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724080649318
+ value: 1720139776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724080659572
+ value: 1720143872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724080774644
+ value: 1720156160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724080782171
+ value: 1720160256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724080859401
+ value: 1720172544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724080868312
+ value: 1720176640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724080967840
+ value: 1720197120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724080976263
+ value: 1720201216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724081015244
+ value: 1724104704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724081036403
+ value: 1724108800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724081057969
+ value: 1724309504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724081065903
+ value: 1724313600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724081154038
+ value: 1724628992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724081164862
+ value: 1724633088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724081263779
+ value: 1724649472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724081271917
+ value: 1724653568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724081352362
+ value: 1724755968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724081359889
+ value: 1724760064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724081468328
+ value: 1725054976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724081516912
+ value: 1725517824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724081695339
+ value: 1726042112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724081726873
+ value: 1741713408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724081747340
+ value: 1741717504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724114167344
+ value: 1742450688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724114315252
+ value: 1742954496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724115190537
+ value: 1743540224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724116766221
+ value: 1768906752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724116777329
+ value: 1768910848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724118026922
+ value: 1784582144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724118035630
+ value: 1784586240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724118087510
+ value: 1788489728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724118095119
+ value: 1788493824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724122001776
+ value: 1788497920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724122013332
+ value: 1788502016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724122445827
+ value: 1788506112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724127853460
+ value: 1793253376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724127868516
+ value: 1793257472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724127994736
+ value: 1793261568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724127995387
+ value: 1793265664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724128032131
+ value: 1795641344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724128039862
+ value: 1795645440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724128047878
+ value: 1795649536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724128050929
+ value: 1795653632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724128266912
+ value: 1795915776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724128275050
+ value: 1795919872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724128289007
+ value: 1795948544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724128298000
+ value: 1795952640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724128596340
+ value: 1802379264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724128604559
+ value: 1805594624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724128612778
+ value: 1805598720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724129601995
+ value: 1805701120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724129608750
+ value: 1805705216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724129722967
+ value: 1805807616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724129730495
+ value: 1805811712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724129811590
+ value: 1805824000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724129822699
+ value: 1805828096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724129901556
+ value: 1805840384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724129910060
+ value: 1805844480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724129987127
+ value: 1805856768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724129997015
+ value: 1805860864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724130076971
+ value: 1805881344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724130083929
+ value: 1805885440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724130162583
+ value: 1806086144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724130169948
+ value: 1806090240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724130263494
+ value: 1806405632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724130270290
+ value: 1806409728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724130363429
+ value: 1806426112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724130372341
+ value: 1806430208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724130448228
+ value: 1806532608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724130455674
+ value: 1806536704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724130563584
+ value: 1806831616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724130612738
+ value: 1807294464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724130666571
+ value: 1807568896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724168906357
+ value: 1811505152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724168918402
+ value: 1811509248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724169079779
+ value: 1813479424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724169089992
+ value: 1813483520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724169564967
+ value: 1814274048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724169604803
+ value: 1814671360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724169622951
+ value: 1814675456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724170342393
+ value: 1815859200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724170358180
+ value: 1815863296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724176045029
+ value: 1816489984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724176062730
+ value: 1816494080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724176683783
+ value: 1817063424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724177314316
+ value: 1817595904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724177623358
+ value: 1818136576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724178641139
+ value: 1818677248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724179235622
+ value: 1819217920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724179483425
+ value: 1819758592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724179971543
+ value: 1820299264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724180344915
+ value: 1820839936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724180675604
+ value: 1821380608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724181001735
+ value: 1821921280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724181168442
+ value: 1822191616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724181511786
+ value: 1822732288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724181847723
+ value: 1823272960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724182183254
+ value: 1823813632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724182538356
+ value: 1824354304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724183615708
+ value: 1824894976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724184034165
+ value: 1825431552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724184175604
+ value: 1825972224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724184457668
+ value: 1826512896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724185116522
+ value: 1842184192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724185148423
+ value: 1842188288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724185888576
+ value: 1842728960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724186161240
+ value: 1843269632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724186626369
+ value: 1843810304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724187009710
+ value: 1844350976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724187366807
+ value: 1844891648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724187687119
+ value: 1845432320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724188000677
+ value: 1845972992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724188189845
+ value: 1846243328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724188565537
+ value: 1846784000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724188897039
+ value: 1847324672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724189210068
+ value: 1847865344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724189522446
+ value: 1848406016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724191519720
+ value: 1848913920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724194373561
+ value: 1849528320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724197800563
+ value: 1850109952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724200836208
+ value: 1850372096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724200847357
+ value: 1850376192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724201065456
+ value: 1855123456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724201079616
+ value: 1855127552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724201238267
+ value: 1857503232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724201253200
+ value: 1857507328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724201273301
+ value: 1858260992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724202690130
+ value: 1858265088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724203343695
+ value: 1858789376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724204056341
+ value: 1840533504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724204113836
+ value: 1840529408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724205643662
+ value: 1845276672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724205656846
+ value: 1845280768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724205820379
+ value: 1847656448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724205829819
+ value: 1847660544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724206474432
+ value: 1852379136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724206488226
+ value: 1853558784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724206502020
+ value: 1853853696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724206511908
+ value: 1853927424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724206522813
+ value: 1853947904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724206683254
+ value: 1855913984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724212852199
+ value: 1856454656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724214884141
+ value: 1857245184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724214945786
+ value: 1857642496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724214988023
+ value: 1857646592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724215658148
+ value: 1858830336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724215690212
+ value: 1858834432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724216513047
+ value: 1859133440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724218583400
+ value: 1859137536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724218614284
+ value: 1859141632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724218684108
+ value: 1874812928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724218694565
+ value: 1874817024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724218720566
+ value: 1875152896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724218722886
+ value: 1875116032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724222398342
+ value: 1875300352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724222447577
+ value: 1857044480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724222470770
+ value: 1857040384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724223619167
+ value: 1838784512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724223653306
+ value: 1838780416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724225514430
+ value: 1839316992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724226041082
+ value: 1839845376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724226134181
+ value: 1840386048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724226338934
+ value: 1840926720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724226622381
+ value: 1841463296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724226907497
+ value: 1842003968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724227330511
+ value: 1842544640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724227448350
+ value: 1842814976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724227770859
+ value: 1843355648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724227971299
+ value: 1843261440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724227989609
+ value: 1843400704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724227996974
+ value: 1843269632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724228206081
+ value: 1843417088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724228364284
+ value: 1843957760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724228489121
+ value: 1844436992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724228787705
+ value: 1844977664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724229052883
+ value: 1845469184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724229179836
+ value: 1846009856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724230006781
+ value: 1846550528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724230609116
+ value: 1847091200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724230749741
+ value: 1851838464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724230760199
+ value: 1851842560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724230969305
+ value: 1854218240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724230978949
+ value: 1854222336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724230985093
+ value: 1854226432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724231006984
+ value: 1854230528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724231333115
+ value: 1854771200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724231394517
+ value: 1854799872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724231419053
+ value: 1854803968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724231775091
+ value: 1855344640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724231968654
+ value: 1856053248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724233765651
+ value: 1860800512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724233779160
+ value: 1860804608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724233854681
+ value: 1861332992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724233936509
+ value: 1861873664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724234014390
+ value: 1862414336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724234121974
+ value: 1862955008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724234181748
+ value: 1865330688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724234204697
+ value: 1865334784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724234252061
+ value: 1865875456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724236088690
+ value: 1866416128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724236470485
+ value: 1866956800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724236909084
+ value: 1867497472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724237360459
+ value: 1868038144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724237499375
+ value: 1868308480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724237911159
+ value: 1868849152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724238302557
+ value: 1869389824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724238714341
+ value: 1869930496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724239180243
+ value: 1870471168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724239549098
+ value: 1870950400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724240076157
+ value: 1871482880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724240296372
+ value: 1872023552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724240943345
+ value: 1872564224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724241271104
+ value: 1873104896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724241597927
+ value: 1873645568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724241990383
+ value: 1874186240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724242179469
+ value: 1874726912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724242361354
+ value: 1875267584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724242653224
+ value: 1875808256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724242859157
+ value: 1876598784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724242894150
+ value: 1876996096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724242911729
+ value: 1877000192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724242964178
+ value: 1877540864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724243244981
+ value: 1878061056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724243532538
+ value: 1878601728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724243702622
+ value: 1879785472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724243721136
+ value: 1879789568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724244838283
+ value: 1880326144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724246064032
+ value: 1880662016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724247003973
+ value: 1881026560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724247481919
+ value: 1881354240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724248870916
+ value: 1882132480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724248968654
+ value: 1882402816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724250059108
+ value: 1882943488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724251262884
+ value: 1886846976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724251279526
+ value: 1886851072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724252133164
+ value: 1902522368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724252144028
+ value: 1902526464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724252465887
+ value: 1903112192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724252898504
+ value: 1903652864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724253049546
+ value: 1904193536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724253659084
+ value: 1904693248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724253941880
+ value: 1905233920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724254207383
+ value: 1905717248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724254562730
+ value: 1906257920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724254877752
+ value: 1906798592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724255121527
+ value: 1907339264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724255430772
+ value: 1907879936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724255697495
+ value: 1908420608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724255975693
+ value: 1908961280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724256191473
+ value: 1909420032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724256391058
+ value: 1909424128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724256447251
+ value: 1909428224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724256635239
+ value: 1910026240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724257008368
+ value: 1910542336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724257105942
+ value: 1910816768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724258616644
+ value: 1911336960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724259456040
+ value: 1911865344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724260330918
+ value: 1912369152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724260355332
+ value: 1912184832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724260515407
+ value: 1912725504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724260934474
+ value: 1913102336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724261122829
+ value: 1913634816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724261232692
+ value: 1914175488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724261670314
+ value: 1914716160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724261813991
+ value: 1915256832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724262227931
+ value: 1915797504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724262622341
+ value: 1916338176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724262762274
+ value: 1916608512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724262964015
+ value: 1917149184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724263252468
+ value: 1898893312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724263279974
+ value: 1898889216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724263315578
+ value: 1899438080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724263560695
+ value: 1899978752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724263752223
+ value: 1900519424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724264036973
+ value: 1901060096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724264968206
+ value: 1901600768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724267314723
+ value: 1902030848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724267674505
+ value: 1902821376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724267703924
+ value: 1903218688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724267715846
+ value: 1903222784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724268772446
+ value: 1904406528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724268785060
+ value: 1904410624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724272037380
+ value: 1904934912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724275130194
+ value: 1905315840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724275252752
+ value: 1905881088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724275856512
+ value: 1906421760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724276801174
+ value: 1906454528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724277515936
+ value: 1906520064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724277696763
+ value: 1907134464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724277831732
+ value: 1907675136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724277942083
+ value: 1908076544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724278087469
+ value: 1908617216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724278252142
+ value: 1909227520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724278379909
+ value: 1909768192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724278521348
+ value: 1910312960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724278642523
+ value: 1910853632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724278770778
+ value: 1911398400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724278896226
+ value: 1911939072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724279190374
+ value: 1912385536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724279346380
+ value: 1912926208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724280533799
+ value: 1912995840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724280583359
+ value: 1913065472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724284001735
+ value: 1912995840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724284059393
+ value: 1912926208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724284067938
+ value: 1912860672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724284112697
+ value: 1912827904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724285394232
+ value: 1928499200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724285426418
+ value: 1928503296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724285505234
+ value: 1928536064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724286121201
+ value: 1928601600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724287335353
+ value: 1928142848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724287355332
+ value: 1927614464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724287840317
+ value: 1928908800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724287887884
+ value: 1929187328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724287975856
+ value: 1929728000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724289127061
+ value: 1929797632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724289198390
+ value: 1929867264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724289346380
+ value: 1929871360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724289367173
+ value: 1929875456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724289377834
+ value: 1929895936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724290577826
+ value: 1930608640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724299267442
+ value: 1931792384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724299280829
+ value: 1931796480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724305383205
+ value: 1932546048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724309508164
+ value: 1933078528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724312322617
+ value: 1933082624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724312361883
+ value: 1933086720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724312390285
+ value: 1933107200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724318222316
+ value: 1948778496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724318241522
+ value: 1948782592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724326845811
+ value: 1948823552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724326892726
+ value: 1948864512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724326923529
+ value: 1948905472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724326952215
+ value: 1948946432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724326984076
+ value: 1949270016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724327105454
+ value: 1949310976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724340398301
+ value: 1950494720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724340415309
+ value: 1950498816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724348451239
+ value: 1950765056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724351683864
+ value: 1966436352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724351702826
+ value: 1966440448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724353850287
+ value: 1967079424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724362235988
+ value: 1967493120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724364977321
+ value: 1968676864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724364991807
+ value: 1968680960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724367641546
+ value: 1770385408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724367646917
+ value: 1771057152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724370023423
+ value: 1771474944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724370027370
+ value: 1771028480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724374547878
+ value: 1771548672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724377337998
+ value: 1772052480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724382179836
+ value: 1772560384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724383902044
+ value: 1788231680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724383913519
+ value: 1788235776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724385775783
+ value: 1788854272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724388741725
+ value: 1789313024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724390794053
+ value: 1789902848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724392497015
+ value: 1790382080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724395646836
+ value: 1790914560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724398046047
+ value: 1791447040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724400289170
+ value: 1792630784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724400299627
+ value: 1792634880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724401390082
+ value: 1793167360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724403009100
+ value: 1793708032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724403399929
+ value: 1794220032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724404115627
+ value: 1794744320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724405037787
+ value: 1795293184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724409292181
+ value: 1795854336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724411760606
+ value: 1795325952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724411798122
+ value: 1795194880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724411881659
+ value: 1794670592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724411968532
+ value: 1794138112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724412110825
+ value: 1793613824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724412222276
+ value: 1793089536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724412310288
+ value: 1792503808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724412371283
+ value: 1792045056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724412440130
+ value: 1791520768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724412514675
+ value: 1790996480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724412598985
+ value: 1790472192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724412760402
+ value: 1788649472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724412814927
+ value: 1786552320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724412864650
+ value: 1784455168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724412916978
+ value: 1782366208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724412962795
+ value: 1780666368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724412996974
+ value: 1779355648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724413851019
+ value: 1778307072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724413933945
+ value: 1777823744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724413967881
+ value: 1777233920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724414027166
+ value: 1776558080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724414168849
+ value: 1776279552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724414520046
+ value: 1775652864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724414621730
+ value: 1775079424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724414634955
+ value: 1774510080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724414713812
+ value: 1773920256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724414754095
+ value: 1772277760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724414784491
+ value: 1770491904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724414814113
+ value: 1769340928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724414856390
+ value: 1767632896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724414879909
+ value: 1766727680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724414898220
+ value: 1766084608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724415487494
+ value: 1765629952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724415532334
+ value: 1765105664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724415548569
+ value: 1764581376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724415551743
+ value: 1764057088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724415597642
+ value: 1763532800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724415628119
+ value: 1763008512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724415658148
+ value: 1762222080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724415677150
+ value: 1762160640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724415724473
+ value: 1761611776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724417496242
+ value: 1761107968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724418693304
+ value: 1776779264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724418704697
+ value: 1776783360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724418878037
+ value: 1775693824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724419042303
+ value: 1775034368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724419127671
+ value: 1773846528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724419254461
+ value: 1773445120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724419359605
+ value: 1773105152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724419378159
+ value: 1772486656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724419462306
+ value: 1772056576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724419570501
+ value: 1770766336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724419671209
+ value: 1769680896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724419776922
+ value: 1769209856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724419787014
+ value: 1768595456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724419912380
+ value: 1767809024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724420335557
+ value: 1765851136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724420355780
+ value: 1764655104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724420619777
+ value: 1762381824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724420627630
+ value: 1761505280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724431396673
+ value: 1760321536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724431427313
+ value: 1760317440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724431745672
+ value: 1744646144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724431767319
+ value: 1744642048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724434375474
+ value: 1745825792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724434396958
+ value: 1745829888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724439950750
+ value: 1745928192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724451539496
+ value: 1761599488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724451559271
+ value: 1761603584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724452746771
+ value: 1762189312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724466257554
+ value: 1763373056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724466268988
+ value: 1763377152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724485174058
+ value: 1779048448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724485191473
+ value: 1779052544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724498414170
+ value: 1780236288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724498425482
+ value: 1780240384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724501065252
+ value: 1780101120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724507667303
+ value: 1780707328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724508267889
+ value: 1781248000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724510087225
+ value: 1781800960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724518148545
+ value: 1797472256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724518164780
+ value: 1797476352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724524779567
+ value: 1797537792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724532197292
+ value: 1798721536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724532210760
+ value: 1798725632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724539231187
+ value: 1799299072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724552296006
+ value: 1814970368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724552310614
+ value: 1814974464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724564877834
+ value: 1816158208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724564890489
+ value: 1816162304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724569795355
+ value: 1816543232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724584300685
+ value: 1832214528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724584321885
+ value: 1832218624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724600254543
+ value: 1833402368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724600264471
+ value: 1833406464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724631854600
+ value: 1834590208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724631866644
+ value: 1834594304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724665063015
+ value: 1835778048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724665078355
+ value: 1835782144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724670662705
+ value: 1836294144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724699606756
+ value: 1837477888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724699624986
+ value: 1837481984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724719570624
+ value: 1838026752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724731871446
+ value: 1839210496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724731882554
+ value: 1839214592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724737353990
+ value: 1839763456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724765756130
+ value: 1840947200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724765767523
+ value: 1840951296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724771068793
+ value: 1841426432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724771069769
+ value: 1841405952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724772348537
+ value: 1841639424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724797277980
+ value: 1842823168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724797290716
+ value: 1842827264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724831216864
+ value: 1844011008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724831229193
+ value: 1844015104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724866141058
+ value: 1845198848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724866153672
+ value: 1845202944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724899644558
+ value: 1846386688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724899655341
+ value: 1846390784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724935316758
+ value: 1847574528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724935338731
+ value: 1847578624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724942320868
+ value: 1847934976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724942329860
+ value: 1847873536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724993096503
+ value: 1863544832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724993122341
+ value: 1863548928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724994448635
+ value: 1864732672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724994472561
+ value: 1864736768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 724999721421
+ value: 1865199616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725018770941
+ value: 1865428992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725033965603
+ value: 1866612736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725034003241
+ value: 1866616832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725038363023
+ value: 1873043456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725038404486
+ value: 1876258816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725038440985
+ value: 1876262912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725063256944
+ value: 1901629440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725063296250
+ value: 1901633536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725069370876
+ value: 1902817280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725069409735
+ value: 1902821376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725100821519
+ value: 1904005120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725100850612
+ value: 1904009216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725143968451
+ value: 1905192960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725144052232
+ value: 1905197056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725158327378
+ value: 1905594368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725158351752
+ value: 1905467392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725164460639
+ value: 1905713152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725187610663
+ value: 1906896896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725187640977
+ value: 1906900992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725207382514
+ value: 1907380224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725211636379
+ value: 1907871744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725213837307
+ value: 1907724288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725214102077
+ value: 1907163136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725214352728
+ value: 1906593792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725214499945
+ value: 1906139136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725214840521
+ value: 1905295360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725215145127
+ value: 1905106944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725215455308
+ value: 1903874048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725215876573
+ value: 1902747648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725215928615
+ value: 1902305280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725216549587
+ value: 1901457408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725216876695
+ value: 1900789760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725216938829
+ value: 1900142592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725217551296
+ value: 1899159552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725217594021
+ value: 1898713088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725218495998
+ value: 1896693760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725230488349
+ value: 1897877504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725230522365
+ value: 1897881600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725273125149
+ value: 1899065344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725273148383
+ value: 1899069440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725314150539
+ value: 1900253184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725314171413
+ value: 1900257280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725351245998
+ value: 1900814336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725351248887
+ value: 1900724224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725358513658
+ value: 1901907968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725358553941
+ value: 1901912064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725360771023
+ value: 1902084096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725379701972
+ value: 1902673920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725391703233
+ value: 1902825472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725402710435
+ value: 1904009216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725402738796
+ value: 1904013312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725418349717
+ value: 1903865856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725435758083
+ value: 1905049600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725435784084
+ value: 1905053696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725454475328
+ value: 1905491968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725454508327
+ value: 1905356800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725456275865
+ value: 1905414144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725456297960
+ value: 1905356800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725456448757
+ value: 1904799744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725456576524
+ value: 1904259072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725456671942
+ value: 1903083520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725456693467
+ value: 1902694400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725483489162
+ value: 1903878144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725483546902
+ value: 1903882240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725529819892
+ value: 1905065984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725529853746
+ value: 1905070080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725547674791
+ value: 1904140288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725547865709
+ value: 1904017408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725564091742
+ value: 1905201152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725564119940
+ value: 1905205248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725569513170
+ value: 1905254400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725601855740
+ value: 1905229824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725610249498
+ value: 1906413568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725610276557
+ value: 1906417664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725612538682
+ value: 1906442240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725620619167
+ value: 1906589696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725648836168
+ value: 1907773440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725648865058
+ value: 1907777536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725686388007
+ value: 1907699712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725691917467
+ value: 1908883456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725691946438
+ value: 1908887552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725704002102
+ value: 1909592064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725732582384
+ value: 1910775808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725732609117
+ value: 1910779904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725752576646
+ value: 1911046144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725776543280
+ value: 1912229888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725776580553
+ value: 1912233984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725821259508
+ value: 1913417728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725821295925
+ value: 1913421824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725838346096
+ value: 1914023936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725859473456
+ value: 1915207680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725859513292
+ value: 1915211776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 725956527696
+ value: 1915654144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726044426866
+ value: 1916305408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726088826118
+ value: 1916878848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726173485257
+ value: 1917485056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726173796943
+ value: 1917218816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726178123725
+ value: 1917272064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726211992459
+ value: 1917456384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726211998074
+ value: 1917423616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726212288723
+ value: 1917456384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726212291612
+ value: 1917423616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726259205268
+ value: 1917456384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726259208279
+ value: 1917423616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726259367744
+ value: 1917456384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726259369453
+ value: 1917423616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726297162177
+ value: 1917456384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726297165961
+ value: 1917423616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726297371853
+ value: 1917456384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726297374213
+ value: 1917423616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726343883084
+ value: 1917456384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726343885973
+ value: 1917423616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726344214138
+ value: 1917456384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726344215970
+ value: 1917423616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726348258857
+ value: 1917915136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726348264920
+ value: 1917894656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726348704536
+ value: 1918132224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726353456651
+ value: 1918550016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726353491604
+ value: 1918390272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726360649523
+ value: 1918656512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726367021756
+ value: 1919197184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726369195909
+ value: 1919565824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726369196804
+ value: 1919414272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726369334907
+ value: 1918861312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726369407986
+ value: 1918341120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726369472399
+ value: 1917284352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726369484443
+ value: 1916772352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726372421495
+ value: 1916248064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726372561917
+ value: 1915723776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726372679877
+ value: 1915199488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726379547390
+ value: 1915277312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726382138699
+ value: 1915547648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726382853868
+ value: 1915580416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726382856635
+ value: 1915547648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726383090481
+ value: 1915580416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726383092272
+ value: 1915547648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726402398058
+ value: 1915912192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726418300076
+ value: 1915944960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726418303372
+ value: 1915912192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726418897569
+ value: 1915944960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726418901232
+ value: 1915912192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726461871080
+ value: 1915944960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726461874376
+ value: 1915912192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726462039415
+ value: 1915944960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726462041409
+ value: 1915912192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726463494046
+ value: 1916522496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726505106676
+ value: 1916555264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726505109158
+ value: 1916522496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726505217719
+ value: 1916555264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726505218818
+ value: 1916522496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726508204210
+ value: 1916997632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726510062568
+ value: 1916829696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726551345730
+ value: 1916870656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726551349433
+ value: 1916837888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726551519518
+ value: 1916870656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726551521512
+ value: 1916837888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726556814969
+ value: 1917075456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726563615017
+ value: 1917530112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726563639391
+ value: 1917390848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726563769477
+ value: 1916866560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726588158719
+ value: 1916907520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726588162584
+ value: 1916874752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726588310208
+ value: 1916907520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726588311591
+ value: 1916874752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726593794054
+ value: 1916993536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726593800646
+ value: 1916936192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726594757718
+ value: 1917124608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726635369005
+ value: 1917157376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726635372545
+ value: 1917124608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726635549629
+ value: 1917157376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726635551460
+ value: 1917124608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726672706652
+ value: 1917513728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726672710517
+ value: 1917546496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726672711331
+ value: 1917513728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726672880846
+ value: 1917546496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726672883247
+ value: 1917513728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726719309353
+ value: 1917546496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726719313382
+ value: 1917513728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726719518826
+ value: 1917546496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726719520942
+ value: 1917513728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726762362332
+ value: 1917550592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726762366076
+ value: 1917517824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726762527168
+ value: 1917550592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726762529080
+ value: 1917517824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726766055488
+ value: 1918164992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726768806424
+ value: 1918529536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726768810737
+ value: 1918476288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726798695055
+ value: 1918513152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726798699694
+ value: 1918480384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726798909044
+ value: 1918513152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726798910916
+ value: 1918480384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726800797065
+ value: 1918570496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726800814358
+ value: 1918513152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726802674222
+ value: 1918726144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726802709948
+ value: 1918513152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726846695543
+ value: 1918582784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726846699205
+ value: 1918615552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726846700182
+ value: 1918582784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726846896634
+ value: 1918615552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726846898831
+ value: 1918582784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726886453966
+ value: 1918615552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726886457832
+ value: 1918582784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726886631334
+ value: 1918615552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726886633043
+ value: 1918582784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726927449816
+ value: 1918615552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726927451972
+ value: 1918582784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726927553087
+ value: 1918615552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726927553942
+ value: 1918582784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726940764513
+ value: 1919225856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726970255765
+ value: 1919258624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726970259508
+ value: 1919225856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726970438301
+ value: 1919258624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 726970440172
+ value: 1919225856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727011882067
+ value: 1919258624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727011885485
+ value: 1919225856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727012121406
+ value: 1919258624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727012123400
+ value: 1919225856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727015716621
+ value: 1919807488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727016565539
+ value: 1919815680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727055071846
+ value: 1920155648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727190498807
+ value: 1920647168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727190502591
+ value: 1920622592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727194613472
+ value: 1920860160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727252990506
+ value: 1921179648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727396684923
+ value: 1921691648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727446782051
+ value: 1922285568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727489843208
+ value: 1922854912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727577540555
+ value: 1923256320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727577544583
+ value: 1923231744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727603078031
+ value: 1923284992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727607962186
+ value: 1923788800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727691535835
+ value: 1924444160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727727012520
+ value: 1925046272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727740913277
+ value: 1925636096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727859522814
+ value: 1926082560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 727981946968
+ value: 1926541312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728065123075
+ value: 1927172096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728137940539
+ value: 1927577600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728142885241
+ value: 1928187904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728143945137
+ value: 1928040448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728144569201
+ value: 1928273920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728145974271
+ value: 1928597504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728145988269
+ value: 1928572928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728146923083
+ value: 1928810496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728147755684
+ value: 1929367552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728158248726
+ value: 1929248768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728158738553
+ value: 1929551872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728208808296
+ value: 1930252288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728237377185
+ value: 1930604544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728274352120
+ value: 1930674176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728322787951
+ value: 1931309056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728335176867
+ value: 1931845632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728338544177
+ value: 1932386304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728342497994
+ value: 1932070912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728342614937
+ value: 1931546624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728407400622
+ value: 1931767808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728447427193
+ value: 1932238848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728545649686
+ value: 1932976128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728621208972
+ value: 1933352960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728746040149
+ value: 1933807616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728786799019
+ value: 1934409728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728830196521
+ value: 1934995456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 728909757353
+ value: 1935376384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729036668119
+ value: 1936097280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729037923979
+ value: 1935835136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729069557239
+ value: 1935896576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729113486112
+ value: 1936482304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729174457874
+ value: 1936936960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729174463611
+ value: 1936896000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729209986967
+ value: 1936936960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729343651436
+ value: 1937645568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729344764758
+ value: 1938161664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729345687081
+ value: 1938702336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729346536446
+ value: 1939238912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729347194731
+ value: 1939779584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729347861642
+ value: 1940320256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729348268136
+ value: 1940590592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729348936145
+ value: 1941127168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729353194731
+ value: 1941667840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729358264636
+ value: 1942171648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729358724435
+ value: 1942704128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729359228259
+ value: 1943359488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729359519072
+ value: 1943900160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729359808867
+ value: 1944346624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729361670764
+ value: 1943683072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729361773954
+ value: 1943060480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729361852608
+ value: 1942495232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729361977364
+ value: 1942052864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729369248889
+ value: 1942355968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729380661080
+ value: 1942683648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729460461414
+ value: 1943281664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729460903837
+ value: 1943199744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729498499744
+ value: 1943707648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729504253121
+ value: 1943728128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729655150012
+ value: 1944322048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729724658842
+ value: 1944932352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729794917509
+ value: 1945464832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729838004708
+ value: 1945849856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 729893690133
+ value: 1946443776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 730009108956
+ value: 1946890240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 730136622710
+ value: 1947611136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 730147860991
+ value: 1948106752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 730182240589
+ value: 1948442624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 730264110991
+ value: 1949093888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 730306638050
+ value: 1949708288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 730306691069
+ value: 1949466624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 730340278024
+ value: 1949532160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 730472610177
+ value: 1950015488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 730512850452
+ value: 1950797824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 730565644967
+ value: 1951084544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 730696696278
+ value: 1951752192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 730778234648
+ value: 1952137216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 730850064971
+ value: 1952817152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 730894079823
+ value: 1953173504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 730894086618
+ value: 1953144832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 730933609852
+ value: 1953189888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 730963162383
+ value: 1953685504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731037474802
+ value: 1954324480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731076524240
+ value: 1954918400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731102818267
+ value: 1955233792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731184579172
+ value: 1955897344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731200655466
+ value: 1956282368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731200659616
+ value: 1956257792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731237384103
+ value: 1956302848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731313054961
+ value: 1957056512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731313351429
+ value: 1957498880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731313398345
+ value: 1957306368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731313734282
+ value: 1957347328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731313746612
+ value: 1957306368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731335262074
+ value: 1957392384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731335290028
+ value: 1957306368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731356399973
+ value: 1957371904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731372097808
+ value: 1957851136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731497277577
+ value: 1958432768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731539307321
+ value: 1959047168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731608563262
+ value: 1959493632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731649995188
+ value: 1960120320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731697145456
+ value: 1960534016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731697172190
+ value: 1960460288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731697454213
+ value: 1960497152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731697464222
+ value: 1960460288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731707965036
+ value: 1960722432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731816834665
+ value: 1961271296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731823475819
+ value: 1961545728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731861318430
+ value: 1962209280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731904954172
+ value: 1962586112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731904960845
+ value: 1962565632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731945736521
+ value: 1962602496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731950168568
+ value: 1960837120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731950205678
+ value: 1960280064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731950682159
+ value: 1959890944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731950811350
+ value: 1958825984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731951021596
+ value: 1958182912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731951237253
+ value: 1957822464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731951283314
+ value: 1956974592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731963515980
+ value: 1957490688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731968906483
+ value: 1958031360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731975138987
+ value: 1958502400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731975172190
+ value: 1958260736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 731975276885
+ value: 1957736448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 732112341420
+ value: 1957924864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 732194567901
+ value: 1958412288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 732197796457
+ value: 1958948864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 732325324412
+ value: 1959456768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 732405610829
+ value: 1960087552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 732455965728
+ value: 1960513536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 732541045684
+ value: 1961160704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 732578886668
+ value: 1961656320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 732660423411
+ value: 1962086400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 732711374176
+ value: 1962713088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 732792369212
+ value: 1963167744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 732872064890
+ value: 1963782144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 732912852773
+ value: 1964163072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 732999694366
+ value: 1964908544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733044506866
+ value: 1965273088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733127261871
+ value: 1965752320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733127276601
+ value: 1965719552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733127431956
+ value: 1965936640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733164944814
+ value: 1966276608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733250710683
+ value: 1966882816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733291472809
+ value: 1967316992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733377777089
+ value: 1967968256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733426648102
+ value: 1968381952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733504138865
+ value: 1968902144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733504166209
+ value: 1968873472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733544536041
+ value: 1968947200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733589957428
+ value: 1969565696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733689861033
+ value: 1970049024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733758503164
+ value: 1970470912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733850073476
+ value: 1971220480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733890693024
+ value: 1971568640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733890716217
+ value: 1971429376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733937392894
+ value: 1971695616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733958035431
+ value: 1972207616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733966687368
+ value: 1972559872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733988555654
+ value: 1973071872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733988557852
+ value: 1972998144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733990948354
+ value: 1973141504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 733997636221
+ value: 1973665792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734007721955
+ value: 1974140928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734010403962
+ value: 1977290752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734010427236
+ value: 1977294848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734010981842
+ value: 1977851904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734021159577
+ value: 1977905152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734021308055
+ value: 1977909248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734021369538
+ value: 1977913344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734021423900
+ value: 1977917440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734021474193
+ value: 1977921536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734021537669
+ value: 1977925632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734021600454
+ value: 1977929728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734021646312
+ value: 1977933824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734021661489
+ value: 1978507264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734021698599
+ value: 1978511360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734021745555
+ value: 1978515456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734021795767
+ value: 1978519552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734023082225
+ value: 1979703296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734023958079
+ value: 1980887040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734024283682
+ value: 1982070784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734024639964
+ value: 1984634880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734024701894
+ value: 1985818624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734026095449
+ value: 1988968448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734026119660
+ value: 1988972544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734028226146
+ value: 1990156288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734028694977
+ value: 1991340032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734036154328
+ value: 1994489856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734036222443
+ value: 1994493952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734038389517
+ value: 1995001856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734039406606
+ value: 2010673152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734039612539
+ value: 2010677248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734039719066
+ value: 2011201536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734041602000
+ value: 2011709440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734043317129
+ value: 2012274688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734044237539
+ value: 2012815360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734044773468
+ value: 2013237248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734045417430
+ value: 2013777920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734046067983
+ value: 2014281728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734046316925
+ value: 2014838784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734046544831
+ value: 2015510528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734046773306
+ value: 2016051200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734046999217
+ value: 2016591872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734047220286
+ value: 2017132544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734047445588
+ value: 2017673216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734048337148
+ value: 2018009088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734051425771
+ value: 2018549760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734055182811
+ value: 2019045376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734058277253
+ value: 2019594240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734058877065
+ value: 2022744064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734058920807
+ value: 2022748160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734061203766
+ value: 2023194624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734063176138
+ value: 2023735296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734066817129
+ value: 2024296448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734068901968
+ value: 2024755200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734069979808
+ value: 2025299968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734072233022
+ value: 2025857024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734079142609
+ value: 2026438656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734081199779
+ value: 2026852352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734081201488
+ value: 2026827776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734081270661
+ value: 2027073536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734083298574
+ value: 2027384832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734083306224
+ value: 2027372544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734085081167
+ value: 2027642880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734086024282
+ value: 2028105728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734086897126
+ value: 2028662784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734088129059
+ value: 2029187072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734089832713
+ value: 2029473792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734090754873
+ value: 2030014464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734092129710
+ value: 2030559232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734093586619
+ value: 2031284224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734094707428
+ value: 2031775744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734096039460
+ value: 2032193536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734096448151
+ value: 2032869376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734096628856
+ value: 2033254400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734099007843
+ value: 2033786880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734102149282
+ value: 2034327552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734104695303
+ value: 2034880512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734106096344
+ value: 2035294208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734107356924
+ value: 2035818496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734107813996
+ value: 2036371456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734109050527
+ value: 2036973568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734111049347
+ value: 2037411840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734112634878
+ value: 2037948416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734114686066
+ value: 2038480896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734118411571
+ value: 2039017472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734121282339
+ value: 2039549952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734122467153
+ value: 2039398400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734123353791
+ value: 2039554048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734123565908
+ value: 2055225344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734123586864
+ value: 2055229440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734126150422
+ value: 2055888896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734128744823
+ value: 2056167424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734130573517
+ value: 2056683520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734130576610
+ value: 2056597504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734131697459
+ value: 2056908800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734133601593
+ value: 2057207808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734133605825
+ value: 2057203712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734137419261
+ value: 2057420800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734145019359
+ value: 2057760768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734152107900
+ value: 2058280960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734153068553
+ value: 2058817536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734154683828
+ value: 2059358208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734157374950
+ value: 2059231232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734157418569
+ value: 2058706944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734161732209
+ value: 2058858496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734170569326
+ value: 2062008320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734170600088
+ value: 2062012416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734171334626
+ value: 2062614528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734171361237
+ value: 2063798272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734173136750
+ value: 2064982016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734178043285
+ value: 2065539072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734178931183
+ value: 2065985536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734180807526
+ value: 2067169280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734187132030
+ value: 2068353024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734188963247
+ value: 2069536768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734190632843
+ value: 2070085632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734191498403
+ value: 2070622208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734192353587
+ value: 2071805952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734192418407
+ value: 2072379392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734193212271
+ value: 2072920064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734194001984
+ value: 2073460736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734195091828
+ value: 2073997312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734195855907
+ value: 2074537984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734196275625
+ value: 2074808320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734197088735
+ value: 2075348992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734197905223
+ value: 2075889664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734198244416
+ value: 2076426240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734198649364
+ value: 2076966912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734199472240
+ value: 2077507584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734205211701
+ value: 2077409280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734205305166
+ value: 2076884992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734205412018
+ value: 2076364800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734205519603
+ value: 2075840512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734205633454
+ value: 2075316224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734205743358
+ value: 2074791936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734205848216
+ value: 2073673728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734205980581
+ value: 2073227264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734206116527
+ value: 2072690688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734206225007
+ value: 2072166400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734206326650
+ value: 2071642112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734206427358
+ value: 2071117824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734206778636
+ value: 2070593536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734206902741
+ value: 2070069248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734207075796
+ value: 2068033536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734207138215
+ value: 2066173952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734207593903
+ value: 2065715200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734207750438
+ value: 2063716352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734207815827
+ value: 2061619200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734207832022
+ value: 2061033472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734207900259
+ value: 2059522048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734207917064
+ value: 2059001856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734208062165
+ value: 2057424896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734208103262
+ value: 2056114176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734209355134
+ value: 2055852032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734210386546
+ value: 2056105984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734210749299
+ value: 2055319552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734211123607
+ value: 2054533120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734211416372
+ value: 2053484544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734211448395
+ value: 2053222400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734212545156
+ value: 2051903488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734212605662
+ value: 2051375104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734213211742
+ value: 2051768320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734213259837
+ value: 2051395584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734213302481
+ value: 2050879488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734213788117
+ value: 2049568768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734213815461
+ value: 2048782336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734214188304
+ value: 2047995904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734215386221
+ value: 2045906944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734215458608
+ value: 2044067840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734215523957
+ value: 2042290176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734215584341
+ value: 2040233984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734215610464
+ value: 2039382016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734215621613
+ value: 2039033856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734218140778
+ value: 2039578624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734218167064
+ value: 2039521280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734218746776
+ value: 2037686272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734218758210
+ value: 2037161984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734219911123
+ value: 2036408320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734221023387
+ value: 2036678656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734221676911
+ value: 2037022720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734223258535
+ value: 2037563392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734224075918
+ value: 2037301248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734224674307
+ value: 2036195328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734224819001
+ value: 2034495488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734224920604
+ value: 2033258496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734226223135
+ value: 2033520640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734228334666
+ value: 2034044928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734232891470
+ value: 2033266688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734233268748
+ value: 2033520640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734234661286
+ value: 2033250304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734234929271
+ value: 2032689152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734236926056
+ value: 2032107520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734237688996
+ value: 2031759360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734238030060
+ value: 2031804416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734238037547
+ value: 2031759360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734238284984
+ value: 2031923200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734240578685
+ value: 2032435200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734245560049
+ value: 2032185344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734245647777
+ value: 2031661056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734264333161
+ value: 2031857664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734271965078
+ value: 2031906816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734273776398
+ value: 2032513024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734274366038
+ value: 2033041408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734274672598
+ value: 2033532928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734274925812
+ value: 2034057216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734275503286
+ value: 2034581504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734275734772
+ value: 2035118080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734277382640
+ value: 2035654656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734277592642
+ value: 2036174848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734278131135
+ value: 2036703232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734278422964
+ value: 2037219328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734278748607
+ value: 2037755904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734278921458
+ value: 2038288384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734278994701
+ value: 2038804480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734279229401
+ value: 2039328768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734279447541
+ value: 2039857152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734279674836
+ value: 2040373248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734279994497
+ value: 2040893440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734280231883
+ value: 2041397248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734280501252
+ value: 2041925632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734280727489
+ value: 2042445824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734280811677
+ value: 2042953728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734281045156
+ value: 2043465728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734281276724
+ value: 2043998208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734281583690
+ value: 2044530688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734282729645
+ value: 2045054976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734285031403
+ value: 2045472768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734285268830
+ value: 2045997056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734285764069
+ value: 2046537728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734286193879
+ value: 2047070208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734286693350
+ value: 2047610880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734287174958
+ value: 2048151552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734287615632
+ value: 2048692224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734288526113
+ value: 2049261568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734289154531
+ value: 2049781760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734289876740
+ value: 2065453056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734289912791
+ value: 2065457152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734289936392
+ value: 2065997824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734290845612
+ value: 2066538496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734291634430
+ value: 2067075072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734292825918
+ value: 2067615744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734293610789
+ value: 2068140032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734293992544
+ value: 2068676608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734294387686
+ value: 2069217280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734294752310
+ value: 2069729280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734294994660
+ value: 2070081536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734295723053
+ value: 2070614016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734296373119
+ value: 2071150592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734310028718
+ value: 2071719936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734330293447
+ value: 2072215552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734331869782
+ value: 2072735744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734334547354
+ value: 2073243648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734335570750
+ value: 2088914944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734335592886
+ value: 2088919040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734340388499
+ value: 2089558016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734341089834
+ value: 2090082304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734341444896
+ value: 2090590208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734341579295
+ value: 2091081728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734342096141
+ value: 2091589632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734342684398
+ value: 2092118016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734343229442
+ value: 2092646400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734343770702
+ value: 2093162496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734344504019
+ value: 2093846528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734344683218
+ value: 2094116864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734345494050
+ value: 2094895104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734345895702
+ value: 2095165440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734346782176
+ value: 2095706112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734350937653
+ value: 2096287744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734376517121
+ value: 2111959040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734376535147
+ value: 2111963136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734379256541
+ value: 2112425984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734401267487
+ value: 2112950272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734401480500
+ value: 2113462272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734417974234
+ value: 2114244608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734419379507
+ value: 2114736128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734422317048
+ value: 2115145728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734422338532
+ value: 2114998272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734422774445
+ value: 2115244032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734455375926
+ value: 2115788800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734467360586
+ value: 2116308992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734467440949
+ value: 2116804608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734468712759
+ value: 2117304320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734469056834
+ value: 2117795840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734469826610
+ value: 2118303744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734485356965
+ value: 2118823936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734485799510
+ value: 2119348224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734485823924
+ value: 2119831552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734487274893
+ value: 2120347648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734487925161
+ value: 2120851456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734489122142
+ value: 2121359360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734489812287
+ value: 2121867264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734490377920
+ value: 2122416128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734495338247
+ value: 2122956800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734496261424
+ value: 2123493376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734500863597
+ value: 2124034048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734503104605
+ value: 2124587008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734503298656
+ value: 2125127680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734504244335
+ value: 2125668352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734505595165
+ value: 2126209024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734505785920
+ value: 2126749696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734506485098
+ value: 2127179776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734506526642
+ value: 2127675392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734506799510
+ value: 2128252928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734508289582
+ value: 2128695296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734511125479
+ value: 2129399808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734515364574
+ value: 2129940480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734519364533
+ value: 2130472960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734522659129
+ value: 2131005440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734523081127
+ value: 2131542016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734525833853
+ value: 2131808256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734530647533
+ value: 2132594688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734530677603
+ value: 2132865024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734536484488
+ value: 2133397504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734540135000
+ value: 2133934080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734544427196
+ value: 2134474752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734548393871
+ value: 2135015424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734549481151
+ value: 2135552000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734551831737
+ value: 2136092672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734556741568
+ value: 2136633344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734559778433
+ value: 2137174016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734564183218
+ value: 2137710592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734568514069
+ value: 2138312704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734572923615
+ value: 2138746880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734572986034
+ value: 2138517504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734573073314
+ value: 2137915392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734573162222
+ value: 2137505792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734573289663
+ value: 2136977408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734573467357
+ value: 2135658496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734573485871
+ value: 2135269376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734573782827
+ value: 2134933504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734573942984
+ value: 2133782528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734573962962
+ value: 2133237760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734574159089
+ value: 2132680704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734574245474
+ value: 2132008960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734574332754
+ value: 2131767296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734574448843
+ value: 2131263488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734577301504
+ value: 2131369984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734578575796
+ value: 2131910656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734583606558
+ value: 2132447232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734584859040
+ value: 2132983808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734590918651
+ value: 2133524480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734592487783
+ value: 2134052864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734596441519
+ value: 2134597632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734600987417
+ value: 2135126016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734602892609
+ value: 2135666688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734603852652
+ value: 2136199168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734608726594
+ value: 2136727552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734610930126
+ value: 2137260032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734613628775
+ value: 2137800704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734618662466
+ value: 2138341376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734622281729
+ value: 2138882048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734626440054
+ value: 2139152384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734629608267
+ value: 2139701248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734634884024
+ value: 2140241920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734635966503
+ value: 2140741632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734636717967
+ value: 2141282304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734642066234
+ value: 2141822976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734644770051
+ value: 2142363648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734648408072
+ value: 2142900224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734651943187
+ value: 2143440896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734658903392
+ value: 2144043008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734659649160
+ value: 2144583680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734663953156
+ value: 2145116160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734667314932
+ value: 2145656832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734670596752
+ value: 2146197504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734674318716
+ value: 2146738176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734688640819
+ value: 2147246080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734690144847
+ value: 2147753984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734692033845
+ value: 2148085760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734692529043
+ value: 2148814848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734692667145
+ value: 2149335040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734692971833
+ value: 2149801984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734693155101
+ value: 2150273024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734693254833
+ value: 2150764544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734693318187
+ value: 2151280640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734693607372
+ value: 2151989248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734693852530
+ value: 2152493056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734694097728
+ value: 2152992768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734694246613
+ value: 2153492480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734694397370
+ value: 2154029056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734694567658
+ value: 2154557440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734694797720
+ value: 2155085824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734695139029
+ value: 2155618304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734695298981
+ value: 2156154880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734695569286
+ value: 2156670976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734695608145
+ value: 2157195264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734695896271
+ value: 2157699072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734696096385
+ value: 2158227456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734696317089
+ value: 2158735360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734696433381
+ value: 2159276032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734696631989
+ value: 2159808512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734696897004
+ value: 2160336896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734697107046
+ value: 2160873472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734697299592
+ value: 2161311744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734697368155
+ value: 2161831936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734697629751
+ value: 2162368512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734697790355
+ value: 2162905088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734697952342
+ value: 2163400704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734698038931
+ value: 2163937280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734698356314
+ value: 2164477952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734698542145
+ value: 2165014528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734698635122
+ value: 2165555200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734698875113
+ value: 2166091776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734698919994
+ value: 2166607872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734699232494
+ value: 2167111680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734699431794
+ value: 2167648256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734699642894
+ value: 2168176640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734700061229
+ value: 2168672256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734700273103
+ value: 2169159680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734700482331
+ value: 2169700352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734700638174
+ value: 2170232832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734700839590
+ value: 2170773504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734700893301
+ value: 2171281408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734701187816
+ value: 2171813888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734701391633
+ value: 2172350464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734701589794
+ value: 2172891136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734701661815
+ value: 2173427712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734701862214
+ value: 2173964288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734702043570
+ value: 2174435328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734702188345
+ value: 2174922752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734702367463
+ value: 2175463424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734702445140
+ value: 2175991808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734702711498
+ value: 2176528384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734702987214
+ value: 2177069056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734703186026
+ value: 2177597440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734703484447
+ value: 2178138112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734703574738
+ value: 2178674688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734703749706
+ value: 2179207168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734704067129
+ value: 2179706880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734704331208
+ value: 2180243456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734704533926
+ value: 2180780032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734704861359
+ value: 2181312512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734705162873
+ value: 2181844992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734705531892
+ value: 2182385664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734705816397
+ value: 2182926336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734706009512
+ value: 2183196672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734706223094
+ value: 2183733248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734706435131
+ value: 2184470528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734706785879
+ value: 2184974336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734710361034
+ value: 2184978432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734710384797
+ value: 2184982528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734719182119
+ value: 2185433088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734719727774
+ value: 2185961472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734719995474
+ value: 2186399744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734720578767
+ value: 2186924032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734721208609
+ value: 2187464704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734721723745
+ value: 2187997184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734722211335
+ value: 2188537856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734722345653
+ value: 2188541952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734722375560
+ value: 2188546048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734722961660
+ value: 2189086720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734723592194
+ value: 2189627392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734724287466
+ value: 2190168064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734724844025
+ value: 2190675968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734725402294
+ value: 2191216640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734725493317
+ value: 2191757312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734726778311
+ value: 2192297984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734727407176
+ value: 2192838656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734727973786
+ value: 2193379328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734728066112
+ value: 2193920000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734728640900
+ value: 2194456576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734729266511
+ value: 2194997248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734729269440
+ value: 2195267584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734729896068
+ value: 2195808256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734730463980
+ value: 2196348928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734731676016
+ value: 2196889600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734732932567
+ value: 2197430272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734733760570
+ value: 2197958656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734734712678
+ value: 2198499328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734735144685
+ value: 2199040000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734735721426
+ value: 2199580672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734736382315
+ value: 2200121344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734736938020
+ value: 2200662016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734737562531
+ value: 2201202688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734737585643
+ value: 2201743360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734738190502
+ value: 2202284032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734738761791
+ value: 2202824704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734739389151
+ value: 2203357184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734740105866
+ value: 2203897856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734740590363
+ value: 2204438528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734740651927
+ value: 2204708864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734740950715
+ value: 2205249536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734741773916
+ value: 2205777920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734741912507
+ value: 2206318592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734742585277
+ value: 2206859264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734743148672
+ value: 2207399936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734743791291
+ value: 2207940608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734743970165
+ value: 2208481280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734744457347
+ value: 2209021952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734745109650
+ value: 2209562624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734745632762
+ value: 2210103296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734745723054
+ value: 2210639872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734746320059
+ value: 2211176448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734746695873
+ value: 2211717120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734747118765
+ value: 2212257792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734747951813
+ value: 2212798464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734748559479
+ value: 2213339136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734749066275
+ value: 2213867520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734749070262
+ value: 2214137856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734750848461
+ value: 2214678528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734751593741
+ value: 2215219200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734752074576
+ value: 2215755776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734752596752
+ value: 2216296448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734752891877
+ value: 2216837120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734753264965
+ value: 2217377792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734753871491
+ value: 2217918464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734754453604
+ value: 2218459136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734755179312
+ value: 2218999808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734755578726
+ value: 2219540480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734755958283
+ value: 2220077056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734756465119
+ value: 2220617728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734757112865
+ value: 2221158400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734757677766
+ value: 2221694976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734758310863
+ value: 2222231552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734758626903
+ value: 2222759936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734759385000
+ value: 2223300608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734759736197
+ value: 2223841280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734759963817
+ value: 2224111616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734760612499
+ value: 2224640000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734761190827
+ value: 2225180672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734761785106
+ value: 2225717248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734762323965
+ value: 2226257920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734762954296
+ value: 2226794496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734763042552
+ value: 2227310592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734763518545
+ value: 2227843072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734764183910
+ value: 2228383744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734765628856
+ value: 2228924416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734766297842
+ value: 2229465088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734766721955
+ value: 2230005760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734767165884
+ value: 2230546432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734767933299
+ value: 2231087104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734768532176
+ value: 2231627776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734769095653
+ value: 2232168448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734769562938
+ value: 2232705024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734769886018
+ value: 2233245696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734770342927
+ value: 2233786368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734770730744
+ value: 2234314752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734770785432
+ value: 2234585088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734771407217
+ value: 2235121664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734771753693
+ value: 2235662336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734772288565
+ value: 2236203008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734772682038
+ value: 2236743680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734773087678
+ value: 2237284352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734773729035
+ value: 2237825024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734773924185
+ value: 2238365696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734774283316
+ value: 2238902272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734774909577
+ value: 2239430656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734775140168
+ value: 2239967232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734775661490
+ value: 2240507904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734776285391
+ value: 2241048576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734776760489
+ value: 2241589248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734777549673
+ value: 2242129920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734777685700
+ value: 2242666496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734777895824
+ value: 2243207168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734778442536
+ value: 2243747840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734778881338
+ value: 2244284416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734779106355
+ value: 2244554752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734779695547
+ value: 2245079040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734780174470
+ value: 2245603328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734780527782
+ value: 2246135808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734781153352
+ value: 2246676480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734781477896
+ value: 2247217152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734781723583
+ value: 2247761920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734782104198
+ value: 2248302592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734782625275
+ value: 2248843264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734783247020
+ value: 2249383936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734783494823
+ value: 2249920512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734783869986
+ value: 2250461184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734784521149
+ value: 2251001856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734784578726
+ value: 2251542528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734785258495
+ value: 2252083200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734785840485
+ value: 2252623872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734786001740
+ value: 2253164544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734786568513
+ value: 2253705216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734787012849
+ value: 2254245888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734787070140
+ value: 2254516224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734787650544
+ value: 2255056896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734788266674
+ value: 2255597568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734788900788
+ value: 2256138240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734789524934
+ value: 2256662528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734790636058
+ value: 2257207296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734791755077
+ value: 2257747968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734793090607
+ value: 2258288640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734795801382
+ value: 2258829312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734796981477
+ value: 2259369984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734799964265
+ value: 2259910656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734801167064
+ value: 2260451328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734802409659
+ value: 2260992000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734804768586
+ value: 2261532672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734807096467
+ value: 2261979136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734807234488
+ value: 2262392832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734807425487
+ value: 2263117824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734807677074
+ value: 2263617536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734808203685
+ value: 2264088576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734809142691
+ value: 2264612864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734813763174
+ value: 2265128960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734830716950
+ value: 2265645056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734862112621
+ value: 2266263552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734865851797
+ value: 2266664960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734866320140
+ value: 2267197440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734866549714
+ value: 2267717632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734866783397
+ value: 2268250112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734867237621
+ value: 2268786688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734867353262
+ value: 2269290496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734867670441
+ value: 2269822976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734868097362
+ value: 2270355456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734868843537
+ value: 2270892032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734869192333
+ value: 2271432704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734869566967
+ value: 2271911936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734870056916
+ value: 2272448512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734870489696
+ value: 2272968704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734870892162
+ value: 2273492992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734871293204
+ value: 2274025472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734871703156
+ value: 2274545664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734884043651
+ value: 2275065856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734885970368
+ value: 2275659776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734894249421
+ value: 2276843520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734894269400
+ value: 2276847616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734903711457
+ value: 2277367808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734904330679
+ value: 2277900288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734905033763
+ value: 2278440960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734905758739
+ value: 2278969344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734906405793
+ value: 2279501824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734907053335
+ value: 2280034304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734907547964
+ value: 2280574976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734907945466
+ value: 2281115648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734908522492
+ value: 2281644032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734908758169
+ value: 2281914368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734909955679
+ value: 2282455040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734911344554
+ value: 2282995712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734941794465
+ value: 2283540480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734943288850
+ value: 2284081152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734944150341
+ value: 2284617728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734944956696
+ value: 2285158400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734945795075
+ value: 2285699072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734946661612
+ value: 2286239744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734947482738
+ value: 2286776320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734948382966
+ value: 2287316992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734949524161
+ value: 2287857664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734950217113
+ value: 2288381952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734950747915
+ value: 2288906240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734951745515
+ value: 2289442816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734952925853
+ value: 2289983488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734986811026
+ value: 2290491392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734987595206
+ value: 2291027968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734987991283
+ value: 2291560448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734988420116
+ value: 2292101120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734988800975
+ value: 2292613120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734989217683
+ value: 2293149696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734989629629
+ value: 2293690368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734990111034
+ value: 2294231040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734990421215
+ value: 2294493184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734990830150
+ value: 2295029760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734991231314
+ value: 2295570432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734991628368
+ value: 2296111104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 734992440705
+ value: 2296651776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735035658886
+ value: 2297184256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735061539338
+ value: 2296496128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735061586620
+ value: 2294398976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735061627229
+ value: 2292301824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735061665152
+ value: 2290204672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735061701976
+ value: 2288107520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735061739330
+ value: 2286010368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735061778677
+ value: 2283913216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735061816275
+ value: 2281816064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735061854117
+ value: 2279718912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735061892081
+ value: 2277621760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735061929109
+ value: 2275524608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735061968252
+ value: 2273427456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735062007030
+ value: 2271330304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735062044343
+ value: 2269233152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735062079784
+ value: 2267136000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735062115673
+ value: 2265038848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735062153230
+ value: 2262941696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735062189932
+ value: 2260844544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735062225251
+ value: 2258747392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735062243643
+ value: 2257678336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735065155142
+ value: 2256650240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735065181265
+ value: 2254553088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735065204052
+ value: 2252455936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735065226513
+ value: 2250358784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735065248567
+ value: 2248261632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735065270743
+ value: 2246164480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735065292837
+ value: 2244067328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735065315298
+ value: 2241970176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735065337190
+ value: 2239873024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735065359122
+ value: 2237775872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735065380769
+ value: 2235678720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735065402253
+ value: 2233581568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735065424063
+ value: 2231484416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735065446972
+ value: 2229387264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735065470531
+ value: 2227290112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735065493236
+ value: 2225192960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735065515941
+ value: 2223095808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735065529328
+ value: 2221899776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735069085603
+ value: 2222166016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735069385611
+ value: 2222702592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735069701163
+ value: 2223243264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735070285106
+ value: 2223759360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735070534415
+ value: 2224480256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735070716910
+ value: 2224906240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735070852082
+ value: 2225405952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735071019034
+ value: 2225934336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735071061840
+ value: 2226384896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735071129914
+ value: 2226896896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735071285961
+ value: 2227396608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735071768220
+ value: 2228023296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735073015819
+ value: 2228543488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735074270905
+ value: 2229071872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735074452505
+ value: 2229624832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735075659821
+ value: 2230054912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735075861319
+ value: 2230583296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735075969839
+ value: 2231103488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735076308666
+ value: 2231627776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735080234081
+ value: 2232160256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735080484813
+ value: 2232676352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735086172802
+ value: 2233208832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735086357006
+ value: 2233749504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735086690461
+ value: 2233561088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735096099275
+ value: 2233081856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735096167064
+ value: 2232291328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735096373851
+ value: 2231918592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735096447460
+ value: 2231468032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735096521190
+ value: 2230902784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735096651439
+ value: 2230521856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735105970816
+ value: 2230632448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735120447948
+ value: 2231173120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735120821117
+ value: 2231705600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735121111889
+ value: 2232168448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735121182160
+ value: 2232791040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735121400015
+ value: 2233233408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735121714468
+ value: 2233700352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735122193106
+ value: 2234224640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735122950634
+ value: 2234732544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735123489940
+ value: 2235305984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735124069652
+ value: 2235854848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735131798331
+ value: 2236387328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735133961457
+ value: 2236248064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735138279166
+ value: 2236395520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735157378653
+ value: 2236829696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735158458568
+ value: 2237468672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735158988109
+ value: 2238017536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735159147859
+ value: 2238418944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735159517610
+ value: 2238963712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735159885774
+ value: 2239500288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735160322501
+ value: 2240053248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735160669628
+ value: 2240540672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735160875764
+ value: 2241052672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735161325105
+ value: 2241560576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735161616080
+ value: 2241404928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735162079011
+ value: 2241679360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735162271434
+ value: 2242289664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735162469107
+ value: 2242834432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735162631379
+ value: 2243112960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735162839306
+ value: 2243637248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735163102530
+ value: 2244194304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735163541210
+ value: 2244718592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735163824576
+ value: 2245259264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735164322134
+ value: 2245885952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735164396109
+ value: 2246410240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735164663199
+ value: 2246930432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735164724966
+ value: 2247467008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735165186351
+ value: 2248003584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735165482738
+ value: 2248523776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735165552278
+ value: 2249052160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735165673249
+ value: 2249580544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735165897818
+ value: 2250063872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735166143586
+ value: 2250559488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735166247224
+ value: 2251100160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735166416657
+ value: 2251608064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735166656688
+ value: 2252087296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735166885245
+ value: 2252558336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735167149527
+ value: 2253180928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735167985953
+ value: 2253713408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735168744986
+ value: 2254254080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735169366853
+ value: 2254794752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735170462556
+ value: 2255335424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735171031241
+ value: 2255876096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735172325756
+ value: 2256420864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735174131623
+ value: 2256961536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735174842154
+ value: 2257498112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735175257274
+ value: 2258038784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735175584952
+ value: 2258575360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735175670442
+ value: 2258845696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735176390616
+ value: 2259378176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735176716218
+ value: 2259914752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735176968049
+ value: 2260430848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735177461254
+ value: 2261192704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735177667064
+ value: 2261618688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735180868562
+ value: 2262151168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735182245596
+ value: 2262544384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735183590892
+ value: 2263089152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735187279491
+ value: 2263691264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735187670035
+ value: 2264227840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735188093904
+ value: 2264768512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735188402741
+ value: 2265305088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735188700878
+ value: 2265845760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735188966706
+ value: 2266382336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735189177359
+ value: 2266832896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735189558300
+ value: 2267303936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735190450064
+ value: 2267836416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735191425243
+ value: 2268372992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735192124665
+ value: 2268913664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735192963980
+ value: 2269454336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735195718212
+ value: 2269995008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735195974926
+ value: 2270527488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735196398428
+ value: 2271068160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735196634105
+ value: 2271588352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735196811555
+ value: 2272129024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735196996939
+ value: 2272657408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735197392650
+ value: 2273193984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735197621003
+ value: 2273734656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735198296255
+ value: 2274246656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735200376130
+ value: 2274775040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735201444164
+ value: 2275315712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735203750967
+ value: 2275713024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735204858308
+ value: 2276147200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735205773266
+ value: 2276745216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735207063060
+ value: 2277285888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735210077424
+ value: 2277871616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735210503246
+ value: 2278350848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735211281648
+ value: 2278834176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735211725414
+ value: 2279518208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735212326488
+ value: 2279948288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735212708283
+ value: 2280353792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735213526561
+ value: 2280882176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735214497305
+ value: 2281422848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735215686148
+ value: 2281963520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735218812613
+ value: 2282459136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735219531851
+ value: 2282999808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735222167024
+ value: 2283540480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735222401358
+ value: 2284081152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735222813020
+ value: 2284617728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735223235627
+ value: 2285158400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735223649934
+ value: 2285694976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735223868073
+ value: 2286235648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735224418936
+ value: 2286772224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735226187613
+ value: 2287312896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735227111278
+ value: 2287853568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735227800121
+ value: 2288394240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735228538280
+ value: 2288934912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735230094677
+ value: 2289475584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735231440868
+ value: 2290003968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735245544791
+ value: 2290466816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735246052807
+ value: 2291060736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735249487011
+ value: 2290782208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735249554393
+ value: 2290286592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735249640412
+ value: 2289655808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735249711946
+ value: 2289209344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735249791576
+ value: 2288439296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735249870881
+ value: 2288189440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735249950349
+ value: 2287669248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735249997142
+ value: 2286731264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735250142569
+ value: 2286342144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735250211376
+ value: 2285940736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735250242992
+ value: 2284974080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735250443350
+ value: 2284195840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735250493480
+ value: 2283696128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735250570751
+ value: 2283253760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735250630809
+ value: 2282938368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735250647452
+ value: 2282352640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735250756867
+ value: 2280456192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735250942129
+ value: 2280136704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735251118440
+ value: 2279763968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735252394888
+ value: 2329903104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735252416128
+ value: 2329907200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735262982942
+ value: 2330107904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735264859203
+ value: 2330673152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735267280671
+ value: 2331176960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735267627961
+ value: 2331729920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735267782502
+ value: 2332164096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735268309561
+ value: 2332672000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735268752676
+ value: 2333171712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735269223746
+ value: 2333671424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735269649242
+ value: 2334220288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735270222891
+ value: 2334777344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735270686840
+ value: 2335256576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735271100780
+ value: 2335727616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735271597484
+ value: 2336321536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735272044099
+ value: 2336911360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735272572256
+ value: 2337353728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735273035473
+ value: 2337882112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735273433788
+ value: 2338410496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735273699372
+ value: 2338213888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735273841096
+ value: 2338398208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735274310334
+ value: 2338906112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735274312491
+ value: 2338709504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735274377514
+ value: 2338881536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735274872712
+ value: 2339393536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735274890453
+ value: 2339196928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735275312735
+ value: 2339438592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735275830842
+ value: 2339971072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735276581534
+ value: 2340503552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735277193432
+ value: 2341056512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735277766226
+ value: 2341502976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735278229117
+ value: 2342117376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735278639436
+ value: 2342617088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735283032950
+ value: 2343145472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735293763744
+ value: 2346295296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735295947256
+ value: 2346754048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735296695547
+ value: 2348331008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735296730134
+ value: 2348335104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735303876822
+ value: 2348937216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735307270539
+ value: 2349551616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735308837475
+ value: 2350047232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735312338899
+ value: 2350505984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735337425121
+ value: 2353655808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735337594270
+ value: 2355232768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735337609854
+ value: 2355236864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735343690054
+ value: 2352087040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735343726594
+ value: 2350510080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735343738191
+ value: 2350505984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735345500072
+ value: 2351157248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735363175569
+ value: 2351525888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735363561392
+ value: 2351423488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735364878450
+ value: 2351689728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735365128368
+ value: 2352099328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735365544669
+ value: 2352693248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735366033845
+ value: 2353102848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735366375032
+ value: 2353635328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735366547517
+ value: 2354192384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735366625357
+ value: 2354614272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735366934154
+ value: 2355191808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735367097444
+ value: 2355675136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735367464509
+ value: 2356248576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735367614696
+ value: 2356801536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735367712108
+ value: 2357329920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735367949128
+ value: 2357841920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735368268627
+ value: 2358452224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735368343782
+ value: 2358841344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735368764802
+ value: 2359455744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735368881990
+ value: 2359869440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735368977164
+ value: 2360414208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735369100414
+ value: 2360909824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735369376863
+ value: 2361536512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735369452790
+ value: 2362036224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735369839794
+ value: 2362613760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735369956330
+ value: 2363015168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735370099885
+ value: 2363539456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735370230460
+ value: 2364116992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735370467561
+ value: 2364690432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735370638622
+ value: 2365345792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735371010285
+ value: 2365849600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735371103506
+ value: 2366287872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735371201692
+ value: 2366828544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735371311067
+ value: 2367250432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735371505769
+ value: 2367729664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735371687328
+ value: 2368417792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735372184765
+ value: 2368819200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735372335074
+ value: 2369462272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735372415355
+ value: 2369863680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735372671215
+ value: 2370416640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735372850862
+ value: 2371092480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735373374747
+ value: 2371584000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735373437735
+ value: 2371981312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735373529695
+ value: 2372452352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735373606192
+ value: 2373025792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735373752147
+ value: 2373513216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735374059317
+ value: 2374139904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735374257193
+ value: 2374660096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735374553214
+ value: 2375184384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735374688915
+ value: 2375667712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735374771150
+ value: 2376110080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735374876171
+ value: 2376691712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735375145377
+ value: 2377314304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735375608796
+ value: 2377838592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735375694815
+ value: 2378256384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735375777579
+ value: 2378858496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735375915518
+ value: 2379268096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735376241894
+ value: 2379993088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735376267610
+ value: 2380320768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735376501171
+ value: 2380967936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735376881013
+ value: 2381389824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735376992789
+ value: 2381918208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735377114411
+ value: 2382536704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735377335481
+ value: 2382950400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735377624869
+ value: 2383704064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735378007600
+ value: 2383970304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735378123078
+ value: 2384601088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735378203279
+ value: 2385047552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735378318310
+ value: 2385645568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735378426138
+ value: 2386141184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735378748811
+ value: 2386604032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735379202628
+ value: 2387357696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735379644481
+ value: 2387681280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735379784984
+ value: 2388275200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735379888093
+ value: 2388754432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735380230744
+ value: 2389327872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735380473176
+ value: 2389901312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735380677074
+ value: 2390380544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735383911531
+ value: 2340241408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735383943269
+ value: 2340237312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735384862784
+ value: 2340868096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735385562898
+ value: 2341408768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735386251415
+ value: 2341945344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735386582714
+ value: 2342215680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735387250601
+ value: 2342756352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735387906526
+ value: 2343292928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735388674348
+ value: 2343833600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735389406363
+ value: 2344374272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735390068676
+ value: 2344910848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735390726879
+ value: 2345451520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735391381420
+ value: 2345992192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735392056754
+ value: 2346532864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735392715526
+ value: 2347073536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735393372143
+ value: 2347614208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735394027050
+ value: 2348150784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735394770621
+ value: 2348691456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735395437003
+ value: 2349232128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735396101960
+ value: 2349768704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735396762361
+ value: 2350309376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735397420116
+ value: 2350850048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735398066560
+ value: 2351386624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735398394644
+ value: 2351656960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735399118196
+ value: 2352197632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735399805980
+ value: 2352738304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735400493847
+ value: 2353278976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735401150748
+ value: 2353819648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735401805370
+ value: 2354356224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735402458609
+ value: 2354896896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735403112418
+ value: 2355437568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735403768505
+ value: 2355978240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735404538687
+ value: 2356518912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735405192170
+ value: 2357059584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735405843293
+ value: 2357600256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735406497265
+ value: 2358140928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735407161246
+ value: 2358681600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735407861116
+ value: 2359144448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735407876618
+ value: 2358362112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735407897452
+ value: 2356264960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735407915884
+ value: 2354167808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735407933422
+ value: 2352070656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735407950552
+ value: 2349973504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735407969351
+ value: 2347876352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735407986889
+ value: 2345779200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735408025219
+ value: 2343682048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735408043651
+ value: 2341584896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735408061107
+ value: 2339487744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735408077790
+ value: 2337390592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735408095735
+ value: 2335293440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735408112906
+ value: 2333196288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735408129467
+ value: 2331099136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735408147208
+ value: 2329001984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735408164704
+ value: 2326904832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735408181509
+ value: 2324807680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735408200878
+ value: 2322710528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735408210277
+ value: 2321539072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735410376008
+ value: 2321805312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735410720328
+ value: 2322341888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735411067740
+ value: 2322882560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735411422680
+ value: 2323423232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735411766959
+ value: 2323963904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735412139273
+ value: 2324500480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735412482942
+ value: 2325041152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735412848949
+ value: 2325581824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735413196931
+ value: 2326122496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735413543570
+ value: 2326659072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735413891633
+ value: 2327199744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735414324861
+ value: 2327740416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735414672191
+ value: 2328281088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735415019481
+ value: 2328817664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735415367138
+ value: 2329358336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735415715689
+ value: 2329899008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735415889517
+ value: 2330169344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735416255932
+ value: 2330705920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735416605582
+ value: 2331246592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735416950471
+ value: 2331787264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735417294099
+ value: 2332327936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735417644400
+ value: 2332864512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735417987621
+ value: 2333405184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735418332266
+ value: 2333945856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735418678743
+ value: 2334486528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735419023713
+ value: 2335023104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735419446199
+ value: 2335563776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735419797354
+ value: 2336104448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735420191153
+ value: 2336645120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735420547110
+ value: 2337181696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735420899975
+ value: 2337722368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735421248607
+ value: 2338263040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735421601431
+ value: 2338803712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735421773550
+ value: 2339069952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735422119009
+ value: 2339610624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735422463614
+ value: 2340151296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735422809154
+ value: 2340691968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735423153189
+ value: 2341228544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735423501130
+ value: 2341769216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735423847322
+ value: 2342309888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735424293936
+ value: 2342850560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735424647859
+ value: 2343387136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735424999014
+ value: 2343927808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735425349437
+ value: 2344468480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735425698152
+ value: 2345009152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735426047395
+ value: 2345545728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735426403474
+ value: 2346086400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735426753205
+ value: 2346627072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735427107047
+ value: 2347167744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735427460440
+ value: 2347704320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735427810009
+ value: 2348244992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735427985546
+ value: 2348515328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735428354158
+ value: 2349056000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735428705679
+ value: 2349592576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735429067007
+ value: 2350133248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735429494498
+ value: 2350673920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735429844433
+ value: 2351214592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735430192862
+ value: 2351751168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735430539338
+ value: 2352291840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735430883902
+ value: 2352832512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735431228181
+ value: 2353373184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735431573274
+ value: 2353909760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735431919669
+ value: 2354450432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735432301871
+ value: 2354991104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735432649934
+ value: 2355531776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735432997549
+ value: 2356068352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735433346223
+ value: 2356609024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735433690868
+ value: 2357149696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735433864696
+ value: 2357420032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735434293082
+ value: 2357960704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735434644319
+ value: 2358501376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735434993887
+ value: 2359042048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735436626212
+ value: 2359652352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735437073721
+ value: 2360164352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735437300691
+ value: 2360823808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735437441519
+ value: 2361221120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735437602774
+ value: 2361618432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735437806387
+ value: 2362212352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735437935782
+ value: 2362753024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735438228466
+ value: 2363412480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735438408926
+ value: 2363768832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735438545238
+ value: 2364301312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735438817333
+ value: 2364964864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735438943513
+ value: 2365505536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735439590771
+ value: 2365931520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735439725536
+ value: 2366464000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735439989778
+ value: 2366861312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735440563752
+ value: 2367479808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735440909374
+ value: 2367967232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735441203930
+ value: 2368499712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735445564770
+ value: 2368970752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735446220043
+ value: 2369568768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735446710155
+ value: 2370191360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735446857209
+ value: 2370592768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735447276236
+ value: 2371080192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735447976146
+ value: 2371653632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735448413402
+ value: 2372313088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735448850780
+ value: 2372743168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735449091788
+ value: 2372521984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735449184073
+ value: 2371338240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735449201977
+ value: 2371039232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735449264314
+ value: 2368942080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735449320588
+ value: 2366844928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735450320954
+ value: 2367000576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735450491975
+ value: 2367533056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735450693879
+ value: 2368131072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735451072501
+ value: 2368454656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735451263785
+ value: 2368995328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735451495963
+ value: 2369617920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735452288240
+ value: 2370117632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735452452912
+ value: 2370650112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735453138378
+ value: 2371272704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735453291698
+ value: 2371813376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735454014110
+ value: 2372210688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735454248038
+ value: 2372751360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735455006257
+ value: 2373160960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735455712963
+ value: 2373799936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735456384187
+ value: 2374324224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735456511059
+ value: 2374856704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735457100373
+ value: 2375262208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735457616161
+ value: 2375774208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735458017488
+ value: 2376347648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735458708406
+ value: 2376982528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735459793244
+ value: 2377379840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735460647493
+ value: 2378080256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735470404451
+ value: 2378584064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735471117585
+ value: 2378055680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735471172029
+ value: 2375958528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735471227611
+ value: 2373861376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735471267813
+ value: 2372313088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735471712678
+ value: 2371907584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735471747712
+ value: 2371366912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735471779125
+ value: 2369269760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735471802115
+ value: 2367172608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735471817740
+ value: 2365636608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735488402742
+ value: 2365882368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735505955639
+ value: 2366394368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735519927318
+ value: 2366898176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735528832795
+ value: 2367483904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735540174226
+ value: 2368024576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735558401846
+ value: 2367762432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735558427440
+ value: 2367365120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735558516999
+ value: 2366373888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735558565583
+ value: 2364784640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735558758780
+ value: 2364313600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735558796296
+ value: 2363457536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735558924836
+ value: 2362970112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735558954377
+ value: 2361348096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735559164989
+ value: 2360987648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735559236441
+ value: 2359767040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735579228547
+ value: 2360098816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735588752432
+ value: 2360606720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735595730663
+ value: 2361790464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735595754426
+ value: 2361794560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735642737011
+ value: 2362355712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735684153311
+ value: 2362888192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735712712393
+ value: 2363351040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735712715811
+ value: 2361434112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735712823884
+ value: 2359336960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735712935701
+ value: 2357239808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735713044058
+ value: 2355142656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735713112581
+ value: 2353946624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735714464753
+ value: 2352214016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735714515453
+ value: 2350538752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735714774568
+ value: 2350030848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735714804556
+ value: 2347933696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735714841015
+ value: 2345836544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735714869335
+ value: 2343739392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735714896923
+ value: 2341642240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735714929882
+ value: 2341134336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735717122631
+ value: 2339500032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735717261791
+ value: 2337402880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735717310579
+ value: 2335305728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735717358715
+ value: 2333208576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735717385530
+ value: 2331729920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735718199413
+ value: 2330054656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735718228588
+ value: 2327957504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735718255688
+ value: 2325860352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735718283764
+ value: 2323763200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735718302644
+ value: 2322325504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735720251822
+ value: 2321661952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735720311474
+ value: 2319564800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735720328564
+ value: 2318798848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735731922151
+ value: 2319327232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735760167024
+ value: 2319843328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735783322094
+ value: 2320396288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735848849356
+ value: 2320912384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735861281363
+ value: 2321465344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735864532055
+ value: 2320936960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735864607210
+ value: 2320408576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735864685986
+ value: 2320121856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735864748079
+ value: 2319351808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735864781933
+ value: 2318823424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735864811637
+ value: 2318295040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735891155671
+ value: 2318917632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735922677074
+ value: 2319347712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735939880525
+ value: 2319261696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735943275097
+ value: 2319319040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735943287141
+ value: 2319261696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735944854727
+ value: 2319294464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735949489697
+ value: 2319814656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 735975822664
+ value: 2320494592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736006478629
+ value: 2320961536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736014733268
+ value: 2320658432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736014772493
+ value: 2320232448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736022747631
+ value: 2319523840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736030405183
+ value: 2319085568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736037932283
+ value: 2319331328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736043850618
+ value: 2319192064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736043913362
+ value: 2318639104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736043967602
+ value: 2318213120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736051499137
+ value: 2318241792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736051502229
+ value: 2317815808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736063732088
+ value: 2318352384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736085573233
+ value: 2318848000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736085576407
+ value: 2318172160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736085632722
+ value: 2317496320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736103848054
+ value: 2317824000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736103851025
+ value: 2317148160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736104031811
+ value: 2316521472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736104045035
+ value: 2316017664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736104189973
+ value: 2315341824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736104265657
+ value: 2315034624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736104295198
+ value: 2314432512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736104329052
+ value: 2313977856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736104363761
+ value: 2313302016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736104419181
+ value: 2312675328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736104460278
+ value: 2312097792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736104489737
+ value: 2311925760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736123785270
+ value: 2311270400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736135299470
+ value: 2311483392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736135301952
+ value: 2310696960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736135420157
+ value: 2309111808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736135426261
+ value: 2308734976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736135557364
+ value: 2308243456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736142833447
+ value: 2308427776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736157017814
+ value: 2308988928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736162350740
+ value: 2308792320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736162387971
+ value: 2306695168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736162417390
+ value: 2304598016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736162663281
+ value: 2303393792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736162675162
+ value: 2302881792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736162792919
+ value: 2302504960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736192973421
+ value: 2302644224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736199785717
+ value: 2303033344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736209412019
+ value: 2302869504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736233337394
+ value: 2302386176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736233404817
+ value: 2301833216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736233486157
+ value: 2301255680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736233525178
+ value: 2300694528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736233561515
+ value: 2300116992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736233597892
+ value: 2299826176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736233621655
+ value: 2299248640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736233678092
+ value: 2298580992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736233716666
+ value: 2297810944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736233747631
+ value: 2297569280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736233750968
+ value: 2297241600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736233781404
+ value: 2296672256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736233820141
+ value: 2296094720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736241668692
+ value: 2296320000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736260508373
+ value: 2295709696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736260556510
+ value: 2293612544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736260617301
+ value: 2291515392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736260651114
+ value: 2289418240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736260691764
+ value: 2287321088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736260750724
+ value: 2285223936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736260784659
+ value: 2283126784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736260822460
+ value: 2281029632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736260882763
+ value: 2278932480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736260914176
+ value: 2276835328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736260954500
+ value: 2274738176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736261012565
+ value: 2272641024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736261027254
+ value: 2271666176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736262480745
+ value: 2271100928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736262543367
+ value: 2270810112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736262572786
+ value: 2270257152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736262613842
+ value: 2269687808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736262649161
+ value: 2269429760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736262696484
+ value: 2268704768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736262780834
+ value: 2266607616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736262800122
+ value: 2265976832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736263084057
+ value: 2265387008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736263145092
+ value: 2263289856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736263203605
+ value: 2261274624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736263496614
+ value: 2260332544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736263548453
+ value: 2258235392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736263569856
+ value: 2256572416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736263820182
+ value: 2255654912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736263837353
+ value: 2253557760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736263855216
+ value: 2251460608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736263878613
+ value: 2249363456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736263903312
+ value: 2247266304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736263921256
+ value: 2245169152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736263939444
+ value: 2243072000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736263956738
+ value: 2240974848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736263975130
+ value: 2238877696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736263994295
+ value: 2236780544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736264048779
+ value: 2234683392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736264069409
+ value: 2232586240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736264145703
+ value: 2231971840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736264168082
+ value: 2231402496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736265193391
+ value: 2230112256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736265343579
+ value: 2228248576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736265458121
+ value: 2227658752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736290289542
+ value: 2228211712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736290292268
+ value: 2227220480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736290379304
+ value: 2225123328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736290454703
+ value: 2223026176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736290521028
+ value: 2220929024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736290573925
+ value: 2218831872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736290611116
+ value: 2216734720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736290621004
+ value: 2215673856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736291601798
+ value: 2215378944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736295188956
+ value: 2215645184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736295376904
+ value: 2216185856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736296781811
+ value: 2216726528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736298114127
+ value: 2217267200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736298587394
+ value: 2217807872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736314146394
+ value: 2218172416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736317236116
+ value: 2218094592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736344528068
+ value: 2217009152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736344570873
+ value: 2215534592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736352557568
+ value: 2216075264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736353607210
+ value: 2216611840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736354739860
+ value: 2217152512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736355797517
+ value: 2217689088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736356611116
+ value: 2218229760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736357086010
+ value: 2218770432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736358040275
+ value: 2219307008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736358532014
+ value: 2219847680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736359322176
+ value: 2220388352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736359974235
+ value: 2220929024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736360539827
+ value: 2221469696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736361459749
+ value: 2222010368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736361602205
+ value: 2222297088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736362415844
+ value: 2222837760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736362908601
+ value: 2223378432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736363876660
+ value: 2223919104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736364419506
+ value: 2224459776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736365046175
+ value: 2225000448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736365874829
+ value: 2225537024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736366376212
+ value: 2226077696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736367154329
+ value: 2226618368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736367802726
+ value: 2227159040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736368481640
+ value: 2227699712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736369303743
+ value: 2228240384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736369798819
+ value: 2228776960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736370645458
+ value: 2229317632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736371261588
+ value: 2229858304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736371817252
+ value: 2230394880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736372328401
+ value: 2230935552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736372605908
+ value: 2231205888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736372862499
+ value: 2231742464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736373224845
+ value: 2232279040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736373634879
+ value: 2232819712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736373908683
+ value: 2233360384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736374278474
+ value: 2233901056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736374688264
+ value: 2234441728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736375090364
+ value: 2234978304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736375361889
+ value: 2235518976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736375671175
+ value: 2236059648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736376206778
+ value: 2236600320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736376512849
+ value: 2237140992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736376805086
+ value: 2237681664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736377244824
+ value: 2238222336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736377635856
+ value: 2238758912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736377910310
+ value: 2239299584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736378254752
+ value: 2239840256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736378735791
+ value: 2240380928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736378755240
+ value: 2240651264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736379250927
+ value: 2241191936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736379654288
+ value: 2241728512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736379927563
+ value: 2242265088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736380338289
+ value: 2242805760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736380783927
+ value: 2243346432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736381051790
+ value: 2243887104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736381340201
+ value: 2244427776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736381830232
+ value: 2244960256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736382179516
+ value: 2245480448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736382454256
+ value: 2246021120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736382843660
+ value: 2246561792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736383283805
+ value: 2247098368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736383577058
+ value: 2247634944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736383845084
+ value: 2248175616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736384359570
+ value: 2248716288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736384806876
+ value: 2249256960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736385082267
+ value: 2249797632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736385353466
+ value: 2250338304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736385633251
+ value: 2250608640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736385911409
+ value: 2251149312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736386353059
+ value: 2251689984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736386815950
+ value: 2252230656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736387342073
+ value: 2252771328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736387913525
+ value: 2253316096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736388199454
+ value: 2253856768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736388427726
+ value: 2254397440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736388657869
+ value: 2254938112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736388879630
+ value: 2255470592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736389109041
+ value: 2256011264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736389326977
+ value: 2256551936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736389541088
+ value: 2257092608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736389888907
+ value: 2257633280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736390793774
+ value: 2258173952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736391029939
+ value: 2258714624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736391279695
+ value: 2259255296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736391415152
+ value: 2259525632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736391684236
+ value: 2260066304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736392143831
+ value: 2260606976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736392374544
+ value: 2261147648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736392614046
+ value: 2261680128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736392867789
+ value: 2262220800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736393090079
+ value: 2262761472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736393350740
+ value: 2263302144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736393580110
+ value: 2263842816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736394337231
+ value: 2264383488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736394632397
+ value: 2264924160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736394884676
+ value: 2265464832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736395277091
+ value: 2266005504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736395488598
+ value: 2266546176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736395734285
+ value: 2267086848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736395984407
+ value: 2267623424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736396264640
+ value: 2268160000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736396393912
+ value: 2268430336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736396647574
+ value: 2268971008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736396901277
+ value: 2269511680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736397153352
+ value: 2270052352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736397408642
+ value: 2270593024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736397667513
+ value: 2271133696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736397889518
+ value: 2271674368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736398105908
+ value: 2272215040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736398323885
+ value: 2272755712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736398671175
+ value: 2273296384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736398916984
+ value: 2273837056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736399170971
+ value: 2274369536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736399381502
+ value: 2274910208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736399615958
+ value: 2275450880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736400064526
+ value: 2275991552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736400334545
+ value: 2276532224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736400552115
+ value: 2277072896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736400652661
+ value: 2277343232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736400869986
+ value: 2277883904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736401105216
+ value: 2278424576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736401350944
+ value: 2278965248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736401596183
+ value: 2279505920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736401949820
+ value: 2280046592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736402193107
+ value: 2280579072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736402418937
+ value: 2281119744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736402669384
+ value: 2281660416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736402926627
+ value: 2282201088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736403141959
+ value: 2282741760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736403351676
+ value: 2283282432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736403582023
+ value: 2283823104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736403831982
+ value: 2284363776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736404238313
+ value: 2284904448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736404552197
+ value: 2285445120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736404782584
+ value: 2285985792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736404880118
+ value: 2286256128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736405218416
+ value: 2286854144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736405449373
+ value: 2287394816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736405635815
+ value: 2287935488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736405822338
+ value: 2288476160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736406027823
+ value: 2289016832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736406216463
+ value: 2289557504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736406434114
+ value: 2290098176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736406733553
+ value: 2290638848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736408724031
+ value: 2290987008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736417540153
+ value: 2291523584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736424552970
+ value: 2292064256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736431266552
+ value: 2292604928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736435972078
+ value: 2293137408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736438920402
+ value: 2293669888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736443979931
+ value: 2294210560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736447051871
+ value: 2294751232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736449810172
+ value: 2295328768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736452497672
+ value: 2295832576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736455560823
+ value: 2296369152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736456861075
+ value: 2296119296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736456920931
+ value: 2295525376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736457000358
+ value: 2295128064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736457099723
+ value: 2294439936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736457307283
+ value: 2293907456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736457427563
+ value: 2293510144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736457548413
+ value: 2292977664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736457667797
+ value: 2292375552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736457792350
+ value: 2291834880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736458089388
+ value: 2292105216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736460795564
+ value: 2292637696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736463452221
+ value: 2293178368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736466833081
+ value: 2293719040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736469551424
+ value: 2294259712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736472349519
+ value: 2294796288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736475077750
+ value: 2295336960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736477753450
+ value: 2295877632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736480526074
+ value: 2296418304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736483190706
+ value: 2296958976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736485948722
+ value: 2297483264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736491487174
+ value: 2298019840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736497381176
+ value: 2298322944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736500324292
+ value: 2298892288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736502761100
+ value: 2298560512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736502795931
+ value: 2298294272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736503197542
+ value: 2297511936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736503270336
+ value: 2295414784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736503341056
+ value: 2293317632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736503411531
+ value: 2291220480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736503482535
+ value: 2289123328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736503553946
+ value: 2287026176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736503627229
+ value: 2284929024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736503697379
+ value: 2282831872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736503754996
+ value: 2280734720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736503809196
+ value: 2278637568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736503856762
+ value: 2276540416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736503917594
+ value: 2274443264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736503977124
+ value: 2272346112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736504052604
+ value: 2270248960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736504124178
+ value: 2268151808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736504187125
+ value: 2266054656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736504249951
+ value: 2263957504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736504310660
+ value: 2261860352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736504344759
+ value: 2260688896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736508358634
+ value: 2261217280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736511465405
+ value: 2261729280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736511693595
+ value: 2262265856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736511898266
+ value: 2262802432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736512138745
+ value: 2263343104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736512382519
+ value: 2263879680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736512612255
+ value: 2264420352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736512829500
+ value: 2264956928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736513046297
+ value: 2265497600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736513265942
+ value: 2266034176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736513481396
+ value: 2266570752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736513700227
+ value: 2267111424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736513806184
+ value: 2267381760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736514037019
+ value: 2267918336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736514301220
+ value: 2268454912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736514525463
+ value: 2268995584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736514743115
+ value: 2269532160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736515083772
+ value: 2270072832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736515356884
+ value: 2270609408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736515575838
+ value: 2271145984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736515811067
+ value: 2271686656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736516247224
+ value: 2272223232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736516502799
+ value: 2272763904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736516737581
+ value: 2273300480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736516994580
+ value: 2273841152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736517204988
+ value: 2274377728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736517444002
+ value: 2274914304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736517673535
+ value: 2275454976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736517863069
+ value: 2275991552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736518048291
+ value: 2276532224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736518243155
+ value: 2277068800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736518426139
+ value: 2277609472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736518514925
+ value: 2277879808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736522531689
+ value: 2278420480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736522923087
+ value: 2278961152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736523175488
+ value: 2279501824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736523427685
+ value: 2280042496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736523716829
+ value: 2280583168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736524049593
+ value: 2281123840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736524299471
+ value: 2281664512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736524551586
+ value: 2282205184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736528317334
+ value: 2282745856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736528558178
+ value: 2283286528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736528823559
+ value: 2283827200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736529057446
+ value: 2284367872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736529292553
+ value: 2284908544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736529524853
+ value: 2285449216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736529770092
+ value: 2285989888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736529996899
+ value: 2286260224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736533937858
+ value: 2286882816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736534156811
+ value: 2287407104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736534392407
+ value: 2287947776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736534612825
+ value: 2288488448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736534833935
+ value: 2289029120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736535035555
+ value: 2289569792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736535314729
+ value: 2290110464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736535533398
+ value: 2290651136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736538962923
+ value: 2291191808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736539202832
+ value: 2291732480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736539473014
+ value: 2292273152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736539726269
+ value: 2292813824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736539863313
+ value: 2293084160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736540159334
+ value: 2293624832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736540501985
+ value: 2294165504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736540751416
+ value: 2294706176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736541752067
+ value: 2295246848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736543865673
+ value: 2295787520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736544106152
+ value: 2296328192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736544317781
+ value: 2296868864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736544537874
+ value: 2297409536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736544762524
+ value: 2297950208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736545125805
+ value: 2298490880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736545369376
+ value: 2299031552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736545584952
+ value: 2299572224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736567001945
+ value: 2300084224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736572744783
+ value: 2300452864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736573055004
+ value: 2300985344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736581737378
+ value: 2301558784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736585631339
+ value: 2301997056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736585826489
+ value: 2302529536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736586394482
+ value: 2303070208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736597218497
+ value: 2303610880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736606807324
+ value: 2304098304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736606998771
+ value: 2304630784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736607197298
+ value: 2305167360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736607378206
+ value: 2305708032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736608530997
+ value: 2306248704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736619858227
+ value: 2306150400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736621680371
+ value: 2306387968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736635855623
+ value: 2306928640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736642375887
+ value: 2307469312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736642592195
+ value: 2308009984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736642691438
+ value: 2308280320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736642909293
+ value: 2308820992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736643115389
+ value: 2309361664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736643325146
+ value: 2309902336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736643531364
+ value: 2310443008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736643668733
+ value: 2309873664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736643718416
+ value: 2307776512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736643767488
+ value: 2305679360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736643815462
+ value: 2303582208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736643858105
+ value: 2301485056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736643905631
+ value: 2299387904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736643953605
+ value: 2297290752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736644041007
+ value: 2295361536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736644119946
+ value: 2293096448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736644159578
+ value: 2290999296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736644205721
+ value: 2288902144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736644248282
+ value: 2286804992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736644288281
+ value: 2284707840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736644341381
+ value: 2282610688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736644386100
+ value: 2280513536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736644428824
+ value: 2278416384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736644467602
+ value: 2276319232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736644501985
+ value: 2274222080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736644520418
+ value: 2273050624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736647610506
+ value: 2272354304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736647640088
+ value: 2270257152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736647658724
+ value: 2268160000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736647675488
+ value: 2266062848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736647692089
+ value: 2263965696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736647708528
+ value: 2261868544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736647725089
+ value: 2259771392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736647741487
+ value: 2257674240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736647757804
+ value: 2255577088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736647774446
+ value: 2253479936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736647790844
+ value: 2251382784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736647807405
+ value: 2249285632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736647824047
+ value: 2247188480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736647840527
+ value: 2245091328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736647857129
+ value: 2242994176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736647873649
+ value: 2240897024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736647890169
+ value: 2238799872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736647906526
+ value: 2236702720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736647916495
+ value: 2235445248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736650925284
+ value: 2234593280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736650945019
+ value: 2232496128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736650963492
+ value: 2230398976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736650983146
+ value: 2228301824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736651001212
+ value: 2226204672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736651019401
+ value: 2224107520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736651037142
+ value: 2222010368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736651055696
+ value: 2219913216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736651073763
+ value: 2217816064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736651091788
+ value: 2215718912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736651109611
+ value: 2213621760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736651127311
+ value: 2211524608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736651148348
+ value: 2209427456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736651165397
+ value: 2207330304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736651182975
+ value: 2205233152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736651201123
+ value: 2203136000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736651218416
+ value: 2201038848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736651235669
+ value: 2198941696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736651243969
+ value: 2197880832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736652728182
+ value: 2198401024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736653774812
+ value: 2198827008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736654626823
+ value: 2199367680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736655200879
+ value: 2199908352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736655793082
+ value: 2200449024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736656430656
+ value: 2200989696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736657077465
+ value: 2201530368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736657652010
+ value: 2202071040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736661627840
+ value: 2202370048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736662021232
+ value: 2202943488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736662649243
+ value: 2203484160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736663846875
+ value: 2204024832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736664596346
+ value: 2204565504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736676841015
+ value: 2205065216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736681111401
+ value: 2205581312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736683901969
+ value: 2206117888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736684467317
+ value: 2206605312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736684995231
+ value: 2207145984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736685523551
+ value: 2207686656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736686013134
+ value: 2208227328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736686513582
+ value: 2208768000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736687012687
+ value: 2209308672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736687552970
+ value: 2209849344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736688358471
+ value: 2210390016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736688834708
+ value: 2210930688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736689316561
+ value: 2211471360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736689794181
+ value: 2212012032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736690289502
+ value: 2212552704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736690810457
+ value: 2213093376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736691317415
+ value: 2213634048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736691526847
+ value: 2213904384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736691943758
+ value: 2214445056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736692397086
+ value: 2214985728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736692813387
+ value: 2215526400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736693239249
+ value: 2216067072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736693664257
+ value: 2216607744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736706767936
+ value: 2217148416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736791430249
+ value: 2217578496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736791432161
+ value: 2217558016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736794124666
+ value: 2217578496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736794126782
+ value: 2217558016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736830921622
+ value: 2217578496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736848340853
+ value: 2218328064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736872804272
+ value: 2218647552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736881999585
+ value: 2219167744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736910834586
+ value: 2219122688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736914666048
+ value: 2219200512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736973596142
+ value: 2219745280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736976572664
+ value: 2220285952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736982306429
+ value: 2220142592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736982388786
+ value: 2219618304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736982461336
+ value: 2219139072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 736994944531
+ value: 2219163648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737169698030
+ value: 2219835392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737221113721
+ value: 2220347392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737256606844
+ value: 2220838912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737256609489
+ value: 2220773376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737265625602
+ value: 2220572672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737303303377
+ value: 2220638208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737319207064
+ value: 2221191168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737445972811
+ value: 2221105152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737446171053
+ value: 2220281856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737446276969
+ value: 2219884544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737446539461
+ value: 2219487232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737446833040
+ value: 2219012096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737447049593
+ value: 2218217472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737447192904
+ value: 2217328640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737447500765
+ value: 2216439808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737447730664
+ value: 2216112128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737447758822
+ value: 2215550976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737448114168
+ value: 2214662144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737448517163
+ value: 2214203392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737448761914
+ value: 2213724160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737448907992
+ value: 2213195776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737449164705
+ value: 2212552704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737450001986
+ value: 2212065280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737450196688
+ value: 2211672064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737450408805
+ value: 2211094528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737450727002
+ value: 2210631680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737482867464
+ value: 2210709504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737550555371
+ value: 2211426304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737634902295
+ value: 2211733504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737658565503
+ value: 2212286464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737660634595
+ value: 2212790272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737660645866
+ value: 2210865152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737660896354
+ value: 2208768000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737661143954
+ value: 2206670848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737661392489
+ value: 2204573696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737661639722
+ value: 2202476544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737661884066
+ value: 2200379392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737668968864
+ value: 2198929408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737669786735
+ value: 2197970944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737669846875
+ value: 2195873792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737669889559
+ value: 2193776640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737669972811
+ value: 2191679488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737670035230
+ value: 2189582336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737670077100
+ value: 2187485184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737670104443
+ value: 2186141696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737671852694
+ value: 2185396224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737671955151
+ value: 2183299072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737672089998
+ value: 2181201920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737672182691
+ value: 2179104768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737672256991
+ value: 2177007616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737672332512
+ value: 2174910464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737672371045
+ value: 2173603840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737674030021
+ value: 2172944384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737674095451
+ value: 2171539456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737674192578
+ value: 2170847232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737674215324
+ value: 2170380288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737674287671
+ value: 2168750080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737674336703
+ value: 2166652928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737674381258
+ value: 2164555776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737674425936
+ value: 2162458624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737674453768
+ value: 2161065984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737675912386
+ value: 2160533504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737676053662
+ value: 2159796224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737676169100
+ value: 2157445120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737676253776
+ value: 2155347968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737676327547
+ value: 2153250816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737676395052
+ value: 2151153664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737676468539
+ value: 2149056512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737676512402
+ value: 2147995648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737678115877
+ value: 2147467264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737678199007
+ value: 2146414592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737678365959
+ value: 2144518144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737678562533
+ value: 2143354880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737678617424
+ value: 2141257728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737678625806
+ value: 2140864512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737679005363
+ value: 2140119040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737680201042
+ value: 2140655616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737682028719
+ value: 2141028352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737683620109
+ value: 2141569024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737688704582
+ value: 2142105600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737702579134
+ value: 2142629888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737702797518
+ value: 2142445568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737760056633
+ value: 2142564352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737809451937
+ value: 2143219712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737844517448
+ value: 2143571968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737892529492
+ value: 2144182272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 737984766390
+ value: 2144620544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 738099619418
+ value: 2145140736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 738187481804
+ value: 2145796096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 738227475090
+ value: 2146222080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 738313127108
+ value: 2146701312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 738321893913
+ value: 2147221504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 738444588453
+ value: 2147745792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 738487923698
+ value: 2148376576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 738524951449
+ value: 2148999168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 738572254346
+ value: 2149351424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 738647672234
+ value: 2149896192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 738773324049
+ value: 2150424576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 738822739494
+ value: 2151084032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 738857368482
+ value: 2151452672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 738982352857
+ value: 2151944192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739038994052
+ value: 2152603648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739114229729
+ value: 2153021440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739191564446
+ value: 2153742336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739238061313
+ value: 2154156032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739320650180
+ value: 2154594304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739407611891
+ value: 2155106304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739407614820
+ value: 2155073536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739442732252
+ value: 2155106304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739490246941
+ value: 2155749376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739542921787
+ value: 2156142592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739542925611
+ value: 2156126208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739543795118
+ value: 2156384256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739546231886
+ value: 2156675072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739546234205
+ value: 2156654592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739546574619
+ value: 2156670976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739546576816
+ value: 2156650496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739569889763
+ value: 2156687360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739633524936
+ value: 2157203456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739751108636
+ value: 2157735936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739831590529
+ value: 2158243840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739831694207
+ value: 2158215168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739844440708
+ value: 2158456832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739865045444
+ value: 2158792704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 739956085686
+ value: 2159292416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740001098870
+ value: 2159906816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740085117750
+ value: 2160357376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740162180861
+ value: 2161057792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740204955844
+ value: 2161401856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740334472487
+ value: 2161938432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740345886915
+ value: 2162475008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740421170485
+ value: 2163195904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740457561639
+ value: 2163511296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740549019972
+ value: 2164170752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740601850132
+ value: 2164617216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740669856520
+ value: 2165100544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740793848219
+ value: 2165579776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740844686680
+ value: 2166218752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740850513991
+ value: 2166738944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740923747389
+ value: 2167173120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740975282383
+ value: 2167812096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740983909092
+ value: 2168352768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740989768467
+ value: 2168864768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740989806105
+ value: 2168594432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740989877435
+ value: 2168094720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740989916823
+ value: 2167549952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740990066888
+ value: 2166824960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740990170973
+ value: 2166272000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740990261550
+ value: 2166001664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740990371209
+ value: 2165170176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740990488071
+ value: 2164572160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740990573846
+ value: 2164416512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740992506341
+ value: 2163965952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 740992657749
+ value: 2163441664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 741005921543
+ value: 2163638272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 741093073032
+ value: 2164019200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 741097807529
+ value: 2164576256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 741219454868
+ value: 2165108736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 741257219476
+ value: 2165661696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 741304504510
+ value: 2166095872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 741343010004
+ value: 2166747136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 741428831252
+ value: 2167160832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 741552539219
+ value: 2167697408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 741595831578
+ value: 2168360960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 741652068150
+ value: 2168823808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 741723612543
+ value: 2169274368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 741776195673
+ value: 2169819136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 741823434971
+ value: 2170433536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 741891820673
+ value: 2170904576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 741931880691
+ value: 2171392000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 742027417393
+ value: 2171887616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 742107635370
+ value: 2172391424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 742107653396
+ value: 2172383232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 742145499628
+ value: 2172407808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 742227313349
+ value: 2173050880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 742232968093
+ value: 2173673472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 742318843012
+ value: 2173980672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 742319208775
+ value: 2173915136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 742323916498
+ value: 2174119936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 742408887568
+ value: 2174578688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 742482924514
+ value: 2175008768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 742572356277
+ value: 2175660032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 742604903559
+ value: 2176081920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 742695700800
+ value: 2176614400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 742787119501
+ value: 2177105920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 742826611607
+ value: 2177732608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 742903170608
+ value: 2178179072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 742995083247
+ value: 2178924544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743033222244
+ value: 2179268608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743110945348
+ value: 2179743744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743168739659
+ value: 2180341760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743210402989
+ value: 2180784128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743285433792
+ value: 2181509120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743331966954
+ value: 2181849088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743453334467
+ value: 2182381568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743505248327
+ value: 2183008256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743541712397
+ value: 2183434240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743541733515
+ value: 2183380992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743575131668
+ value: 2183643136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743578606806
+ value: 2183995392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743618224441
+ value: 2184630272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743675698766
+ value: 2184982528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743751970535
+ value: 2185539584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743751991491
+ value: 2185396224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743761411616
+ value: 2185539584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743872503820
+ value: 2186063872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743919630732
+ value: 2186743808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743950889155
+ value: 2204999680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743951156937
+ value: 2205003776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743952062698
+ value: 2223259648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743952310257
+ value: 2223263744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743953393224
+ value: 2241519616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743953662471
+ value: 2241523712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743954853633
+ value: 2259779584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743955126379
+ value: 2259783680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743957711990
+ value: 2260131840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743960783686
+ value: 2271817728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 743961039098
+ value: 2271821824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744019762975
+ value: 2272419840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744078864660
+ value: 2272878592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744169977453
+ value: 2273419264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744204082677
+ value: 2273939456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744293010453
+ value: 2274451456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744357013748
+ value: 2256195584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744357079544
+ value: 2256191488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744364547725
+ value: 2237935616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744364591751
+ value: 2237931520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744368613032
+ value: 2234781696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744368692785
+ value: 2233204736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744368718664
+ value: 2233200640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744376949255
+ value: 2233921536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744377791418
+ value: 2234462208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744378662308
+ value: 2234822656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744382189367
+ value: 2235363328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744383118078
+ value: 2236030976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744391357499
+ value: 2236436480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744391711950
+ value: 2236432384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744391777339
+ value: 2236428288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744392086787
+ value: 2236407808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744458380733
+ value: 2218151936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744458422969
+ value: 2218147840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744491685908
+ value: 2218008576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744508598791
+ value: 2218164224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744510466711
+ value: 2217910272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744510598954
+ value: 2217455616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744510845047
+ value: 2216894464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744511100988
+ value: 2216181760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744511223058
+ value: 2215768064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744511437048
+ value: 2215096320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744511645422
+ value: 2214793216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744511793168
+ value: 2214338560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744512852290
+ value: 2213695488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744512909785
+ value: 2212995072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744515690384
+ value: 2212159488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744520702795
+ value: 2211692544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744520747147
+ value: 2211188736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744521593298
+ value: 2211590144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744521620560
+ value: 2211594240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744525193884
+ value: 2210705408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744529669754
+ value: 2210111488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744529939489
+ value: 2209714176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744530051183
+ value: 2209501184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744530196122
+ value: 2208919552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744530433793
+ value: 2208124928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744530530879
+ value: 2207727616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744530659663
+ value: 2207330304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744531007930
+ value: 2206822400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744536420324
+ value: 2206326784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744536830155
+ value: 2205741056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744537035274
+ value: 2205298688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744537308019
+ value: 2204741632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744537682043
+ value: 2204188672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744538023392
+ value: 2203746304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744551483882
+ value: 2185490432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744551513138
+ value: 2185486336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744551977453
+ value: 2185465856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744552057979
+ value: 2185392128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744552132116
+ value: 2185097216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744552215002
+ value: 2183917568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744552384110
+ value: 2179198976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744552496048
+ value: 2177232896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744553261999
+ value: 2176487424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744553678666
+ value: 2176483328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744554607092
+ value: 2176196608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744554856603
+ value: 2175483904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744554931433
+ value: 2175090688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744555074092
+ value: 2174570496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744555141638
+ value: 2173964288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744555225663
+ value: 2173349888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744555272090
+ value: 2173054976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744555343827
+ value: 2172342272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744555386185
+ value: 2171940864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744555573522
+ value: 2171867136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556216263
+ value: 2171670528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556236161
+ value: 2171473920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556250850
+ value: 2171424768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556262650
+ value: 2171375616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556276078
+ value: 2171351040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556287145
+ value: 2171326464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556298010
+ value: 2171314176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556309077
+ value: 2171301888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556328893
+ value: 2168156160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556348628
+ value: 2166583296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556365759
+ value: 2165796864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556382767
+ value: 2165403648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556392818
+ value: 2165207040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556401159
+ value: 2165108736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556409338
+ value: 2165010432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556418941
+ value: 2164961280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556427852
+ value: 2164912128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556439448
+ value: 2164887552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556460851
+ value: 2164690944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556474686
+ value: 2164494336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556485794
+ value: 2164445184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556495357
+ value: 2164396032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556505977
+ value: 2164371456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556525793
+ value: 2162798592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556555700
+ value: 2161225728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556571732
+ value: 2160832512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556584265
+ value: 2160439296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556594681
+ value: 2160340992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556604894
+ value: 2160242688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556619136
+ value: 2160234496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744556701818
+ value: 2159808512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744557546952
+ value: 2160066560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744603619746
+ value: 2159865856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744603637365
+ value: 2159861760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744603679073
+ value: 2159661056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744603688268
+ value: 2159656960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744603731034
+ value: 2159456256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744603741206
+ value: 2159452160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744603776810
+ value: 2159251456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744603787674
+ value: 2159247360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744603822464
+ value: 2159243264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744603832311
+ value: 2159239168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744603867183
+ value: 2159235072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744603875931
+ value: 2159230976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744603906978
+ value: 2159226880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744603916703
+ value: 2159222784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744603944698
+ value: 2159218688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744603953771
+ value: 2159214592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744603981685
+ value: 2159198208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744603990555
+ value: 2159194112.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604078893
+ value: 2159177728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604090083
+ value: 2159173632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604142573
+ value: 2159157248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604150264
+ value: 2159153152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604181148
+ value: 2159136768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604188024
+ value: 2159132672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604212805
+ value: 2159120384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604221309
+ value: 2159116288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604247473
+ value: 2159104000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604254390
+ value: 2159099904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604274735
+ value: 2159087616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604280676
+ value: 2159083520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604308630
+ value: 2159071232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604319209
+ value: 2159067136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604341548
+ value: 2159054848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604346634
+ value: 2159050752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604366166
+ value: 2159038464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604375280
+ value: 2159034368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604398718
+ value: 2159022080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604407141
+ value: 2159017984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604434891
+ value: 2159005696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604442582
+ value: 2159001600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604468664
+ value: 2158989312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604475134
+ value: 2158985216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604497635
+ value: 2158972928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604505000
+ value: 2158968832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604525183
+ value: 2158956544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604532059
+ value: 2158952448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604552364
+ value: 2158940160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604560298
+ value: 2158936064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604591670
+ value: 2158641152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604620316
+ value: 2158346240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604641393
+ value: 2158051328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604661861
+ value: 2157756416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604701004
+ value: 2157494272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604710323
+ value: 2157490176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604749059
+ value: 2157228032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604753617
+ value: 2157223936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604785192
+ value: 2156961792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604790034
+ value: 2156957696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604829382
+ value: 2156695552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604834509
+ value: 2156691456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604874344
+ value: 2156429312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604881262
+ value: 2156425216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604903804
+ value: 2156404736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604909175
+ value: 2156400640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604930904
+ value: 2156380160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604935583
+ value: 2156376064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604959305
+ value: 2156355584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604963496
+ value: 2156351488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604988114
+ value: 2156331008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744604993648
+ value: 2156326912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605015295
+ value: 2155864064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605032710
+ value: 2155401216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605051835
+ value: 2154938368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605073115
+ value: 2154475520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605091223
+ value: 2154012672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605121089
+ value: 2153910272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605126216
+ value: 2153906176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605156490
+ value: 2153803776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605162796
+ value: 2153799680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605190262
+ value: 2153697280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605195104
+ value: 2153693184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605260819
+ value: 2153590784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605266312
+ value: 2153586688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605295324
+ value: 2153484288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605301428
+ value: 2153480192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605328324
+ value: 2153377792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605335974
+ value: 2153373696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605362666
+ value: 2153271296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605367630
+ value: 2153267200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605397497
+ value: 2153164800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605402502
+ value: 2153160704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605430659
+ value: 2153058304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605437007
+ value: 2153054208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605465572
+ value: 2152951808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605472123
+ value: 2152947712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605498856
+ value: 2152845312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605505041
+ value: 2152841216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605543859
+ value: 2152525824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605549556
+ value: 2152521728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605590327
+ value: 2152206336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605597367
+ value: 2152202240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605640661
+ value: 2151886848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605647009
+ value: 2151882752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605691931
+ value: 2151567360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605697668
+ value: 2151563264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605869909
+ value: 2147659776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744605878902
+ value: 2147655680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744606050044
+ value: 2143752192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744606058833
+ value: 2143748096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744606200598
+ value: 2139844608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744606208736
+ value: 2139840512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744606365393
+ value: 2135937024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744606374955
+ value: 2135932928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744607043859
+ value: 2110566400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744607050166
+ value: 2110562304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744607806351
+ value: 2085195776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744607813716
+ value: 2085191680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744609142533
+ value: 2059825152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744609153194
+ value: 2059821056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744609806066
+ value: 2034454528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744609816524
+ value: 2034450432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744610118363
+ value: 2029703168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744610129024
+ value: 2029699072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744610395178
+ value: 2024951808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744610403926
+ value: 2024947712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744610516393
+ value: 2022572032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744610527909
+ value: 2022567936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744610680619
+ value: 2017820672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744610687902
+ value: 2017816576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744610778519
+ value: 2017787904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744610785965
+ value: 2017783808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744610893184
+ value: 2015408128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744610901688
+ value: 2015404032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744611063268
+ value: 2010656768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744611071366
+ value: 2010652672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744611171504
+ value: 2008276992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744611180415
+ value: 2008272896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744611323075
+ value: 2003525632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744611332230
+ value: 2003521536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744611914261
+ value: 2003517440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744611961055
+ value: 2003513344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744611968542
+ value: 2003509248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744611994584
+ value: 2003505152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744612022009
+ value: 2003501056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744612059566
+ value: 2003496960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744612068436
+ value: 2003492864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744612105749
+ value: 2003488768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744612113887
+ value: 2003484672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744612409989
+ value: 1999548416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744612420853
+ value: 1999544320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744626139318
+ value: 1999622144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744639986730
+ value: 1999355904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744640486568
+ value: 1999314944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744640662959
+ value: 1999273984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744640687211
+ value: 1999233024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744640707678
+ value: 1999192064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744640727941
+ value: 1999151104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744642038041
+ value: 1999147008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744642046545
+ value: 1999118336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744642050777
+ value: 1996742656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744642072424
+ value: 1996738560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744642080318
+ value: 1996734464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744642087479
+ value: 1996730368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744642190710
+ value: 1996726272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744642212642
+ value: 1996722176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744642323848
+ value: 1990295552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744642355668
+ value: 1987080192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744642371577
+ value: 1987076096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744642409175
+ value: 1961709568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744642423091
+ value: 1961705472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744642753454
+ value: 1959735296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744642777298
+ value: 1959731200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744642930130
+ value: 1959628800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744642947383
+ value: 1959624704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744642953202
+ value: 1953198080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744642974890
+ value: 1949982720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744642988195
+ value: 1949978624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744643327998
+ value: 1947602944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744643344925
+ value: 1943695360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744643345658
+ value: 1943699456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744643370275
+ value: 1943691264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744643651525
+ value: 1943429120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744643870642
+ value: 1942908928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744644443884
+ value: 1927237632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744644461665
+ value: 1927233536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744644563309
+ value: 1911562240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744644575801
+ value: 1911558144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744644673335
+ value: 1895886848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744644685624
+ value: 1895882752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744645103145
+ value: 1880211456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744645113846
+ value: 1880207360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744645215734
+ value: 1864536064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744645227005
+ value: 1864531968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744645343867
+ value: 1848860672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744645356319
+ value: 1848856576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744645451981
+ value: 1833185280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744645462398
+ value: 1833181184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744645585445
+ value: 1817509888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744645595943
+ value: 1817505792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744645716874
+ value: 1801834496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744645726192
+ value: 1801830400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744645887243
+ value: 1786159104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744645899409
+ value: 1786155008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744645960648
+ value: 1785384960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744646075150
+ value: 1769713664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744646086462
+ value: 1769709568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744646245682
+ value: 1754038272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744646259639
+ value: 1754034176.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744646460892
+ value: 1738362880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744646478104
+ value: 1738358784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744646613643
+ value: 1722687488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744646626053
+ value: 1722683392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744646744502
+ value: 1707012096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744646757157
+ value: 1707008000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744646880163
+ value: 1691336704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744646890865
+ value: 1691332608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744646980627
+ value: 1675661312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744646991410
+ value: 1675657216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744647141516
+ value: 1659985920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744647152543
+ value: 1659981824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744647384273
+ value: 1644310528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744647396398
+ value: 1644306432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744647725785
+ value: 1628635136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744647744217
+ value: 1628631040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744647927486
+ value: 1612959744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744647938675
+ value: 1612955648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744648176875
+ value: 1597284352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744648189204
+ value: 1597280256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744649735713
+ value: 1596723200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744649887487
+ value: 1596198912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744650084916
+ value: 1595654144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744650224401
+ value: 1595129856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744650340572
+ value: 1594540032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744650574702
+ value: 1595019264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744650609899
+ value: 1594462208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744650661413
+ value: 1594040320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744651034623
+ value: 1593532416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744651189367
+ value: 1592991744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744651315669
+ value: 1592475648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744651469966
+ value: 1591955456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744651617712
+ value: 1591431168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744651735754
+ value: 1590865920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744651864416
+ value: 1590386688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744652059973
+ value: 1589862400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744652265946
+ value: 1589313536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744652362015
+ value: 1588805632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744652441483
+ value: 1588256768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744652462154
+ value: 1587564544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744652689286
+ value: 1586941952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744652764562
+ value: 1586671616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744652887935
+ value: 1586184192.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744652959102
+ value: 1585655808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744653069820
+ value: 1585094656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744653223913
+ value: 1584545792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744653358150
+ value: 1583988736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744653523148
+ value: 1583108096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744655203080
+ value: 1582317568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744655238887
+ value: 1581920256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744655250769
+ value: 1581916160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744655411739
+ value: 1581125632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744655442541
+ value: 1580728320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744655454951
+ value: 1580724224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744655594315
+ value: 1579933696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744655619339
+ value: 1579536384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744655628291
+ value: 1579532288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744655753006
+ value: 1578741760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744655783931
+ value: 1578344448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744655795568
+ value: 1578340352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744659277502
+ value: 1577549824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744659323767
+ value: 1577152512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744659335892
+ value: 1577148416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744659539587
+ value: 1561477120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744659569616
+ value: 1561473024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744669272538
+ value: 1560289280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744669320837
+ value: 1560285184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744669476110
+ value: 1559101440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744669501379
+ value: 1559097344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744669611771
+ value: 1557913600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744669637284
+ value: 1557909504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744669741328
+ value: 1556725760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744669764685
+ value: 1556721664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744669867142
+ value: 1555537920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744669894445
+ value: 1555533824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744669998327
+ value: 1554350080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744670021358
+ value: 1554345984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744670112463
+ value: 1553162240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744670142167
+ value: 1553158144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744670247676
+ value: 1551974400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744670269160
+ value: 1551970304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744670372228
+ value: 1550786560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744670395544
+ value: 1550782464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744670483923
+ value: 1549598720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744670510941
+ value: 1549594624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744670613765
+ value: 1548410880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744670638342
+ value: 1548406784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744670734777
+ value: 1547223040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744670757320
+ value: 1547218944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744671142411
+ value: 1546035200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744671173986
+ value: 1546031104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744671285721
+ value: 1544847360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744671314082
+ value: 1544843264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744671416133
+ value: 1543659520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744671444128
+ value: 1543655424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744671537023
+ value: 1542471680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744671561193
+ value: 1542467584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744671659704
+ value: 1541283840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744671685298
+ value: 1541279744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744671775223
+ value: 1540096000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744671798010
+ value: 1540091904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744671895015
+ value: 1538908160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744671919470
+ value: 1538904064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744672059322
+ value: 1537720320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744672088374
+ value: 1537716224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744672193355
+ value: 1536532480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744672217606
+ value: 1536528384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744672322017
+ value: 1535344640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744672344193
+ value: 1535340544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744672441524
+ value: 1534156800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744672463496
+ value: 1534152704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744672555293
+ value: 1532968960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744672577022
+ value: 1532964864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744672665645
+ value: 1531781120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744672689937
+ value: 1531777024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744672780716
+ value: 1530593280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744672803544
+ value: 1530589184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744672899328
+ value: 1529405440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744676218827
+ value: 1529401344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744676428706
+ value: 1528217600.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744676454341
+ value: 1528213504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744676555049
+ value: 1527029760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744676579016
+ value: 1527025664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744676666011
+ value: 1525841920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744676691849
+ value: 1525837824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744676783687
+ value: 1524654080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744676807979
+ value: 1524649984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744676886226
+ value: 1523466240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744676906612
+ value: 1523462144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744677001053
+ value: 1522278400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744677024409
+ value: 1522274304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744677111730
+ value: 1521090560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744677132604
+ value: 1521086464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744677214473
+ value: 1519902720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744677234737
+ value: 1519898624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744677339188
+ value: 1518714880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744677359899
+ value: 1518710784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744677437943
+ value: 1517527040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744677459305
+ value: 1517522944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744677544999
+ value: 1516339200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744677565466
+ value: 1516335104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744677649816
+ value: 1515151360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744677670406
+ value: 1515147264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744677750809
+ value: 1513963520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744677772375
+ value: 1513959424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744677850337
+ value: 1512775680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744677871455
+ value: 1512771584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744677969681
+ value: 1511587840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744677989823
+ value: 1511583744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744678072342
+ value: 1510400000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744678095210
+ value: 1510395904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744678170812
+ value: 1509212160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744678190669
+ value: 1509208064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744678263749
+ value: 1508024320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744678285233
+ value: 1508020224.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744678367224
+ value: 1506836480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744678386958
+ value: 1506832384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744678477087
+ value: 1505648640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744678500484
+ value: 1505644544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744678580318
+ value: 1504460800.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744678603999
+ value: 1504456704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744696036779
+ value: 1501306880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744696089066
+ value: 1501302784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744696221594
+ value: 1501298688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744696367142
+ value: 1498148864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744696388667
+ value: 1498144768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744696498775
+ value: 1498140672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744696633744
+ value: 1498136576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744699665360
+ value: 1501286400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744699703609
+ value: 1501290496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744709783483
+ value: 1501286400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744713223303
+ value: 1501282304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744713279292
+ value: 1501278208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744714332474
+ value: 1501257728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744714377193
+ value: 1501253632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744714406856
+ value: 1501249536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744714435135
+ value: 1501245440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744714462601
+ value: 1501241344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744714512853
+ value: 1501237248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744714542395
+ value: 1501233152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744714585323
+ value: 1501229056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744714612992
+ value: 1501224960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744714639685
+ value: 1501220864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744714666337
+ value: 1501216768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744714699173
+ value: 1501163520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744714761592
+ value: 1498599424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744714819372
+ value: 1498529792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744714863073
+ value: 1498460160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744714873327
+ value: 1498394624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744714931555
+ value: 1498361856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744714990515
+ value: 1495212032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744715050533
+ value: 1492062208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744715107173
+ value: 1488912384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744715163814
+ value: 1485762560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744716994950
+ value: 1484578816.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744717063024
+ value: 1483395072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744717096675
+ value: 1482211328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744717123571
+ value: 1481027584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744717148677
+ value: 1479843840.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744717179642
+ value: 1478660096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744717607132
+ value: 1477476352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744717668046
+ value: 1476292608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744717695145
+ value: 1475108864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744717720292
+ value: 1473925120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744717747635
+ value: 1472741376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744717774409
+ value: 1471557632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744743593013
+ value: 1470930944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 744743931555
+ value: 1470926848.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745471096187
+ value: 1470894080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745471769242
+ value: 1470369792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745472833085
+ value: 1469837312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745473590165
+ value: 1469308928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745474293575
+ value: 1468207104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745476621415
+ value: 1467731968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745478108760
+ value: 1467211776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745478518510
+ value: 1466216448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745478990515
+ value: 1466155008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745479561072
+ value: 1465630720.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745480130611
+ value: 1465102336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745480674394
+ value: 1464586240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745498298173
+ value: 1464078336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745498443599
+ value: 1463496704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745499136389
+ value: 1462984704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745500385657
+ value: 1462267904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745500473466
+ value: 1461714944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745501265661
+ value: 1461006336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745501708939
+ value: 1460621312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745502079382
+ value: 1460236288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745502802038
+ value: 1459884032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745507047237
+ value: 1459093504.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745507533524
+ value: 1458479104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745508208736
+ value: 1456947200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745509742956
+ value: 1456705536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745510183793
+ value: 1455833088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745510955196
+ value: 1455382528.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745511354407
+ value: 1455144960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745515010901
+ value: 1454579712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745516227982
+ value: 1454092288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745516923336
+ value: 1453584384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745517395422
+ value: 1452474368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745518495601
+ value: 1452011520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745519138098
+ value: 1451446272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745519690954
+ value: 1450938368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745520766150
+ value: 1450352640.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745530493404
+ value: 1449811968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745530775142
+ value: 1449361408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745530997514
+ value: 1448722432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745531436234
+ value: 1448316928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745532951046
+ value: 1447817216.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745544157182
+ value: 1447268352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745680804643
+ value: 1446764544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745681393754
+ value: 1446113280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745684371212
+ value: 1445699584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745684606726
+ value: 1445146624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745685147335
+ value: 1444593664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745685346391
+ value: 1444151296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745685641028
+ value: 1443598336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745686049679
+ value: 1443045376.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745689332068
+ value: 1442025472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745690130774
+ value: 1441234944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745690291703
+ value: 1440792576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745691320593
+ value: 1440481280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745691747229
+ value: 1439801344.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745691831864
+ value: 1439277056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745692766435
+ value: 1438826496.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745693279130
+ value: 1437962240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745693849402
+ value: 1437478912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745694241410
+ value: 1437323264.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745694600745
+ value: 1436643328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745694816077
+ value: 1436229632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745701264929
+ value: 1435676672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745701750077
+ value: 1435176960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745835990963
+ value: 1434705920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 745840112382
+ value: 1434132480.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746342202796
+ value: 1433645056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746428773841
+ value: 1433001984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746568696204
+ value: 1432612864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746572930986
+ value: 1431949312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746574426429
+ value: 1431121920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746574691484
+ value: 1430736896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746575569414
+ value: 1430466560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746575908932
+ value: 1429729280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746576884192
+ value: 1429409792.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746577229122
+ value: 1428733952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746577423499
+ value: 1428418560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746578990393
+ value: 1427759104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746579081092
+ value: 1427218432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746580432329
+ value: 1426497536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746580483842
+ value: 1426202624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746586221147
+ value: 1425788928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746586367306
+ value: 1425268736.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746586714921
+ value: 1423171584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746586862708
+ value: 1422254080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746591451331
+ value: 1422135296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746592236731
+ value: 1421504512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746592465776
+ value: 1420140544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746593961300
+ value: 1419886592.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746594254432
+ value: 1419415552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746595296505
+ value: 1417912320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746596518958
+ value: 1417404416.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746596644975
+ value: 1416642560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746597422319
+ value: 1416351744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746597666460
+ value: 1415315456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746597766761
+ value: 1414672384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746599919633
+ value: 1413496832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746601308102
+ value: 1412272128.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746602605424
+ value: 1412083712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746603205237
+ value: 1411633152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746603633216
+ value: 1410793472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746603763953
+ value: 1409978368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746605488603
+ value: 1408712704.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746605609046
+ value: 1407979520.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746608287065
+ value: 1407295488.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746609305498
+ value: 1406787584.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746609640133
+ value: 1406394368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746609896928
+ value: 1405861888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746610042151
+ value: 1405308928.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746610121171
+ value: 1404440576.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746611101193
+ value: 1403564032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746611729407
+ value: 1403162624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746612694251
+ value: 1402699776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746613466183
+ value: 1402212352.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746614341101
+ value: 1401610240.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746614756710
+ value: 1401147392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746615037838
+ value: 1400569856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746615531531
+ value: 1400078336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746616159339
+ value: 1399566336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746616516069
+ value: 1399029760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746616727942
+ value: 1398390784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 746617183020
+ value: 1397907456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747172327959
+ value: 1397362688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747173559079
+ value: 1396498432.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747174036292
+ value: 1396015104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747174446896
+ value: 1395765248.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747174924842
+ value: 1395314688.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747175230750
+ value: 1394675712.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747175728105
+ value: 1394192384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747179998817
+ value: 1393713152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747180693519
+ value: 1393082368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747181472856
+ value: 1392365568.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747182500363
+ value: 1392111616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747182871131
+ value: 1391661056.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747183126828
+ value: 1391022080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747183537228
+ value: 1390538752.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747457092730
+ value: 1390039040.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747457651160
+ value: 1389174784.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747458308916
+ value: 1388691456.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747737318519
+ value: 1388576768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747738757402
+ value: 1387679744.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747740424680
+ value: 1387524096.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747740966468
+ value: 1386885120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747741635943
+ value: 1386319872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747742096799
+ value: 1385545728.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747743033078
+ value: 1385414656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747743384315
+ value: 1384706048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747743915077
+ value: 1384378368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 747749193234
+ value: 1383854080.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749335742185
+ value: 1383227392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749348729612
+ value: 1383526400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749353209186
+ value: 1384067072.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749362019895
+ value: 1384599552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749366336708
+ value: 1385132032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749374740354
+ value: 1385664512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749382716673
+ value: 1386139648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749388098305
+ value: 1386668032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749395473346
+ value: 1387200512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749402511269
+ value: 1387732992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749407430214
+ value: 1388265472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749413006996
+ value: 1388797952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749422656533
+ value: 1389318144.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749435528440
+ value: 1389850624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749447597003
+ value: 1390383104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749451348793
+ value: 1390919680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749463899086
+ value: 1391448064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749472697182
+ value: 1391976448.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749478419187
+ value: 1392254976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749478422117
+ value: 1392205824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749485102903
+ value: 1392480256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749497093585
+ value: 1393016832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749507104286
+ value: 1393324032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749507107867
+ value: 1393221632.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749517788694
+ value: 1392762880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749518072833
+ value: 1392160768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749518252154
+ value: 1391714304.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749518563881
+ value: 1391181824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749518982379
+ value: 1390387200.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749519059894
+ value: 1390055424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749519355304
+ value: 1389531136.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749519804319
+ value: 1389096960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749520075478
+ value: 1388572672.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749520234007
+ value: 1388044288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749520346026
+ value: 1387515904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749520686114
+ value: 1386950656.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749520933632
+ value: 1386471424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749521140826
+ value: 1385705472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749521419716
+ value: 1385402368.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749521662880
+ value: 1384898560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749521934161
+ value: 1384374272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749522232013
+ value: 1383849984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749522416461
+ value: 1382776832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749522545937
+ value: 1380679680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749523376137
+ value: 1380151296.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749523600462
+ value: 1379659776.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749523762693
+ value: 1378586624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749523861855
+ value: 1376489472.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749524081500
+ value: 1375805440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749524827553
+ value: 1374752768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749525270546
+ value: 1374392320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749525363889
+ value: 1373339648.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749525984088
+ value: 1372401664.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749526172076
+ value: 1370304512.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749526251218
+ value: 1369387008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749527716876
+ value: 1368698880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749527976967
+ value: 1368207360.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749528031004
+ value: 1367949312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749528309487
+ value: 1366110208.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749528338336
+ value: 1365807104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749529540810
+ value: 1365499904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749529818479
+ value: 1364975616.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749529886839
+ value: 1364414464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749530035642
+ value: 1362317312.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749530109902
+ value: 1361260544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749531223305
+ value: 1360785408.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749531484617
+ value: 1360261120.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749531746580
+ value: 1359736832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749532034340
+ value: 1359212544.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749532483030
+ value: 1358688256.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749532728432
+ value: 1358163968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749532983274
+ value: 1357639680.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749533357704
+ value: 1357115392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749533593544
+ value: 1356591104.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749534126544
+ value: 1354240000.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749534217649
+ value: 1352536064.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749534304197
+ value: 1351094272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749534412636
+ value: 1349419008.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749534530556
+ value: 1347579904.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749534613523
+ value: 1346330624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749534714760
+ value: 1344999424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749534839353
+ value: 1343148032.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749535015419
+ value: 1341054976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749535072345
+ value: 1340698624.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749535152911
+ value: 1340125184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749535356850
+ value: 1338961920.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749535478147
+ value: 1337126912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749535613116
+ value: 1335054336.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749535743894
+ value: 1332989952.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749535878375
+ value: 1330900992.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749535956093
+ value: 1330278400.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749536256590
+ value: 1328807936.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749536374550
+ value: 1327071232.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749536511106
+ value: 1325031424.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749536652830
+ value: 1322934272.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749536736122
+ value: 1321787392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749536814044
+ value: 1320570880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749536902504
+ value: 1319170048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749536972166
+ value: 1318137856.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749537010821
+ value: 1317601280.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749537072792
+ value: 1316798464.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749547734820
+ value: 1316536320.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749547906492
+ value: 1315975168.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749547933022
+ value: 1315450880.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749548285642
+ value: 1314652160.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749548353920
+ value: 1313271808.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749548445229
+ value: 1311264768.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749548520709
+ value: 1309401088.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749548595375
+ value: 1307561984.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749548633299
+ value: 1306939392.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749551556354
+ value: 1306640384.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749551757078
+ value: 1306148864.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749551893186
+ value: 1305509888.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749552403318
+ value: 1305026560.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749553147133
+ value: 1304588288.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749559387693
+ value: 1304150016.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749559820188
+ value: 1303629824.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749560135374
+ value: 1302822912.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749560488116
+ value: 1302568960.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749560883299
+ value: 1300946944.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749561512815
+ value: 1300451328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749561615598
+ value: 1299664896.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749562018959
+ value: 1299070976.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749562496621
+ value: 1297117184.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749562596555
+ value: 1295921152.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749563559975
+ value: 1295745024.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749563709999
+ value: 1293647872.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749563771848
+ value: 1292771328.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749569344846
+ value: 1291972608.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749571534829
+ value: 1291509760.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749573572060
+ value: 1290579968.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749575812294
+ value: 1290141696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749575825478
+ value: 1289986048.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749576072345
+ value: 1289367552.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749578991860
+ value: 1288568832.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749588083819
+ value: 1272897536.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749588152464
+ value: 1272893440.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749588637001
+ value: 1271709696.000000
+ }
+ gc_rss_and_dma: {
+ ts: 749588670571
+ value: 1271705600.000000
+ }
+}
diff --git a/test/trace_processor/camera/index b/test/trace_processor/camera/index
new file mode 100644
index 000000000..5927fa4b7
--- /dev/null
+++ b/test/trace_processor/camera/index
@@ -0,0 +1,2 @@
+../../data/camera-ion-mem-trace android_camera camera-ion-mem-trace_android_camera.out
+../../data/camera-ion-mem-trace android_camera_unagg camera-ion-mem-trace_android_camera_unagg.out
diff --git a/test/trace_processor/chrome/chrome_dropped_frames_metric.out b/test/trace_processor/chrome/chrome_dropped_frames_metric.out
new file mode 100644
index 000000000..f1fbf5a33
--- /dev/null
+++ b/test/trace_processor/chrome/chrome_dropped_frames_metric.out
@@ -0,0 +1,12 @@
+[perfetto.protos.chrome_dropped_frames]: {
+ dropped_frame: {
+ ts: 166479338462000
+ process_name: "Renderer"
+ pid: 12743
+ }
+ dropped_frame: {
+ ts: 166479355302000
+ process_name: "Renderer"
+ pid: 12743
+ }
+} \ No newline at end of file
diff --git a/test/trace_processor/chrome/chrome_dropped_frames_metric.sql b/test/trace_processor/chrome/chrome_dropped_frames_metric.sql
new file mode 100644
index 000000000..372d8df0c
--- /dev/null
+++ b/test/trace_processor/chrome/chrome_dropped_frames_metric.sql
@@ -0,0 +1,18 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+SELECT RUN_METRIC('experimental/chrome_dropped_frames.sql') AS suppress_query_output;
+
+SELECT * FROM dropped_frames_with_process_info; \ No newline at end of file
diff --git a/test/trace_processor/chrome/chrome_histogram_hashes.out b/test/trace_processor/chrome/chrome_histogram_hashes.out
new file mode 100644
index 000000000..4cd61a5ae
--- /dev/null
+++ b/test/trace_processor/chrome/chrome_histogram_hashes.out
@@ -0,0 +1,4 @@
+[perfetto.protos.chrome_histogram_hashes]: {
+ hash: 10
+ hash: 20
+}
diff --git a/test/trace_processor/chrome/chrome_histogram_hashes.textproto b/test/trace_processor/chrome/chrome_histogram_hashes.textproto
new file mode 100644
index 000000000..dfc12601c
--- /dev/null
+++ b/test/trace_processor/chrome/chrome_histogram_hashes.textproto
@@ -0,0 +1,27 @@
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat1"
+ type: 3
+ name_iid: 1
+ chrome_histogram_sample {
+ name_hash: 10
+ sample: 100
+ }
+ }
+}
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat2"
+ type: 3
+ name_iid: 2
+ chrome_histogram_sample {
+ name_hash: 20
+ }
+ }
+}
diff --git a/test/trace_processor/chrome/chrome_long_latency_metric.out b/test/trace_processor/chrome/chrome_long_latency_metric.out
new file mode 100644
index 000000000..8c47494ac
--- /dev/null
+++ b/test/trace_processor/chrome/chrome_long_latency_metric.out
@@ -0,0 +1,5 @@
+
+"ts","event_type","process_name","process_id"
+200111000,"FirstGestureScrollUpdate,GestureScrollUpdate","Renderer",1001
+200111000,"GestureScrollUpdate","Renderer",1002
+280111001,"GestureScrollUpdate","Renderer",1001
diff --git a/test/trace_processor/chrome/chrome_long_latency_metric.sql b/test/trace_processor/chrome/chrome_long_latency_metric.sql
new file mode 100644
index 000000000..13db1ffc2
--- /dev/null
+++ b/test/trace_processor/chrome/chrome_long_latency_metric.sql
@@ -0,0 +1,18 @@
+--
+-- Copyright 2022 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+SELECT RUN_METRIC('experimental/chrome_long_latency.sql') AS suppress_query_output;
+
+SELECT * FROM long_latency_with_process_info; \ No newline at end of file
diff --git a/test/trace_processor/chrome/chrome_performance_mark_hashes.out b/test/trace_processor/chrome/chrome_performance_mark_hashes.out
new file mode 100644
index 000000000..9c581ba54
--- /dev/null
+++ b/test/trace_processor/chrome/chrome_performance_mark_hashes.out
@@ -0,0 +1,6 @@
+[perfetto.protos.chrome_performance_mark_hashes]: {
+ site_hash: 10
+ site_hash: 20
+ mark_hash: 100
+ mark_hash: 200
+}
diff --git a/test/trace_processor/chrome/chrome_performance_mark_hashes.textproto b/test/trace_processor/chrome/chrome_performance_mark_hashes.textproto
new file mode 100644
index 000000000..fb5364215
--- /dev/null
+++ b/test/trace_processor/chrome/chrome_performance_mark_hashes.textproto
@@ -0,0 +1,28 @@
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat1"
+ type: 3
+ name: "name1"
+ [perfetto.protos.ChromeTrackEvent.chrome_hashed_performance_mark] {
+ site_hash: 10
+ mark_hash: 100
+ }
+ }
+}
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat2"
+ type: 3
+ name: "name2"
+ [perfetto.protos.ChromeTrackEvent.chrome_hashed_performance_mark] {
+ site_hash: 20
+ mark_hash: 200
+ }
+ }
+}
diff --git a/test/trace_processor/chrome/chrome_slice_names.out b/test/trace_processor/chrome/chrome_slice_names.out
new file mode 100644
index 000000000..b6890d24f
--- /dev/null
+++ b/test/trace_processor/chrome/chrome_slice_names.out
@@ -0,0 +1,5 @@
+[perfetto.protos.chrome_slice_names]: {
+ chrome_version_code: 123
+ slice_name: "Looper.Dispatch: class1"
+ slice_name: "name2"
+}
diff --git a/test/trace_processor/chrome/chrome_slice_names.textproto b/test/trace_processor/chrome/chrome_slice_names.textproto
new file mode 100644
index 000000000..f864416ec
--- /dev/null
+++ b/test/trace_processor/chrome/chrome_slice_names.textproto
@@ -0,0 +1,23 @@
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 1000
+ track_event {
+ categories: "cat"
+ name: "Looper.Dispatch: class1"
+ type: 3
+ }
+}
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 2000
+ track_event {
+ categories: "cat"
+ name: "name2"
+ type: 3
+ }
+}
+packet {
+ chrome_metadata {
+ chrome_version_code: 123
+ }
+}
diff --git a/test/trace_processor/chrome/chrome_thread_slice.out b/test/trace_processor/chrome/chrome_thread_slice.out
new file mode 100644
index 000000000..e3ed29024
--- /dev/null
+++ b/test/trace_processor/chrome/chrome_thread_slice.out
@@ -0,0 +1,7 @@
+
+"trace_id","dur","thread_dur"
+2734,25000,25000
+2734,1000,2000
+2734,2000,2000
+2734,258000,171000
+2734,1000,1000
diff --git a/test/trace_processor/chrome/chrome_thread_slice.sql b/test/trace_processor/chrome/chrome_thread_slice.sql
new file mode 100644
index 000000000..654f42491
--- /dev/null
+++ b/test/trace_processor/chrome/chrome_thread_slice.sql
@@ -0,0 +1,27 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+SELECT RUN_METRIC('chrome/chrome_thread_slice.sql')
+ AS suppress_query_output;
+
+SELECT
+ EXTRACT_ARG(arg_set_id, 'chrome_latency_info.trace_id') AS trace_id,
+ dur,
+ thread_dur
+FROM chrome_thread_slice
+WHERE
+ name = 'LatencyInfo.Flow' AND
+ EXTRACT_ARG(arg_set_id, 'chrome_latency_info.trace_id') = 2734;
diff --git a/test/trace_processor/chrome/chrome_thread_slice_repeated.out b/test/trace_processor/chrome/chrome_thread_slice_repeated.out
new file mode 100644
index 000000000..1efb2b14e
--- /dev/null
+++ b/test/trace_processor/chrome/chrome_thread_slice_repeated.out
@@ -0,0 +1,9 @@
+
+"name","ts","dur","thread_dur"
+"event1_on_t1",1000,100,10000
+"event2_on_t1",2000,200,30000
+"event3_on_t1",2000,200,10000
+"event4_on_t1",4000,0,0
+"float_counter_on_t1",4300,0,"[NULL]"
+"float_counter_on_t1",4500,0,"[NULL]"
+"event1_on_t3",4000,100,5000
diff --git a/test/trace_processor/chrome/chrome_thread_slice_repeated.sql b/test/trace_processor/chrome/chrome_thread_slice_repeated.sql
new file mode 100644
index 000000000..124d30668
--- /dev/null
+++ b/test/trace_processor/chrome/chrome_thread_slice_repeated.sql
@@ -0,0 +1,25 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+SELECT RUN_METRIC('chrome/chrome_thread_slice.sql')
+ AS suppress_query_output;
+
+SELECT
+ name,
+ ts,
+ dur,
+ thread_dur
+FROM chrome_thread_slice
diff --git a/test/trace_processor/chrome/chrome_thread_slice_with_cpu_time.out b/test/trace_processor/chrome/chrome_thread_slice_with_cpu_time.out
deleted file mode 100644
index 92b2a6d6d..000000000
--- a/test/trace_processor/chrome/chrome_thread_slice_with_cpu_time.out
+++ /dev/null
@@ -1,7 +0,0 @@
-
-"trace_id","dur","start_cpu_time","end_cpu_time","slice_cpu_time"
-2734,2000,3192921000.000000,3192923000.000000,2000.000000
-2734,258000,3192951000.000000,3193122000.000000,171000.000000
-2734,1000,3193009000.000000,3193010000.000000,1000.000000
-2734,25000,1579266000.000000,1579291000.000000,25000.000000
-2734,1000,1579284000.000000,1579286000.000000,2000.000000
diff --git a/test/trace_processor/chrome/chrome_thread_slice_with_cpu_time.sql b/test/trace_processor/chrome/chrome_thread_slice_with_cpu_time.sql
deleted file mode 100644
index 10857defd..000000000
--- a/test/trace_processor/chrome/chrome_thread_slice_with_cpu_time.sql
+++ /dev/null
@@ -1,29 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
-SELECT RUN_METRIC('chrome/chrome_thread_slice_with_cpu_time.sql')
- AS suppress_query_output;
-
-SELECT
- EXTRACT_ARG(arg_set_id, 'chrome_latency_info.trace_id') AS trace_id,
- dur,
- start_cpu_time,
- end_cpu_time,
- slice_cpu_time
-FROM chrome_thread_slice_with_cpu_time
-WHERE
- name = 'LatencyInfo.Flow' AND
- EXTRACT_ARG(arg_set_id, 'chrome_latency_info.trace_id') = 2734;
diff --git a/test/trace_processor/chrome/chrome_thread_slice_with_cpu_time_repeated.out b/test/trace_processor/chrome/chrome_thread_slice_with_cpu_time_repeated.out
deleted file mode 100644
index 0794b25f2..000000000
--- a/test/trace_processor/chrome/chrome_thread_slice_with_cpu_time_repeated.out
+++ /dev/null
@@ -1,9 +0,0 @@
-
-"name","ts","dur","start_cpu_time","end_cpu_time","slice_cpu_time"
-"event1_on_t1",1000,100,1000000.000000,1010000.000000,10000.000000
-"event2_on_t1",2000,200,2000000.000000,2030000.000000,30000.000000
-"event3_on_t1",2000,200,2000000.000000,2030000.000000,30000.000000
-"event4_on_t1",4000,0,2040000.000000,2040000.000000,0.000000
-"float_counter_on_t1",4300,0,"[NULL]","[NULL]","[NULL]"
-"float_counter_on_t1",4500,0,"[NULL]","[NULL]","[NULL]"
-"event1_on_t3",4000,100,10000.000000,15000.000000,5000.000000
diff --git a/test/trace_processor/chrome/chrome_thread_slice_with_cpu_time_repeated.sql b/test/trace_processor/chrome/chrome_thread_slice_with_cpu_time_repeated.sql
deleted file mode 100644
index 4702b5553..000000000
--- a/test/trace_processor/chrome/chrome_thread_slice_with_cpu_time_repeated.sql
+++ /dev/null
@@ -1,27 +0,0 @@
---
--- Copyright 2020 The Android Open Source Project
---
--- Licensed under the Apache License, Version 2.0 (the "License");
--- you may not use this file except in compliance with the License.
--- You may obtain a copy of the License at
---
--- https://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
-SELECT RUN_METRIC('chrome/chrome_thread_slice_with_cpu_time.sql')
- AS suppress_query_output;
-
-SELECT
- name,
- ts,
- dur,
- start_cpu_time,
- end_cpu_time,
- slice_cpu_time
-FROM chrome_thread_slice_with_cpu_time
diff --git a/test/trace_processor/chrome/chrome_user_event_hashes.out b/test/trace_processor/chrome/chrome_user_event_hashes.out
new file mode 100644
index 000000000..69ca70fa9
--- /dev/null
+++ b/test/trace_processor/chrome/chrome_user_event_hashes.out
@@ -0,0 +1,5 @@
+[perfetto.protos.chrome_user_event_hashes]: {
+ action_hash: 10
+ action_hash: 20
+}
+
diff --git a/test/trace_processor/chrome/chrome_user_event_hashes.textproto b/test/trace_processor/chrome/chrome_user_event_hashes.textproto
new file mode 100644
index 000000000..41b21b916
--- /dev/null
+++ b/test/trace_processor/chrome/chrome_user_event_hashes.textproto
@@ -0,0 +1,27 @@
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat1"
+ type: 3
+ name_iid: 1
+ chrome_user_event {
+ action_hash: 10
+ }
+ }
+}
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat2"
+ type: 3
+ name_iid: 2
+ chrome_user_event {
+ action_hash: 20
+ }
+ }
+}
+
diff --git a/test/trace_processor/chrome/index b/test/trace_processor/chrome/index
index 546634631..800f1690c 100644
--- a/test/trace_processor/chrome/index
+++ b/test/trace_processor/chrome/index
@@ -1,6 +1,8 @@
# Tests related to Chrome's use of Perfetto.
# Chrome metrics (found in the trace_processor/chrome directory).
+
+# Scroll jank metrics
../../data/chrome_scroll_without_vsync.pftrace scroll_jank_general_validation.sql scroll_jank_general_validation.out
../../data/chrome_scroll_without_vsync.pftrace scroll_jank.sql scroll_jank.out
../../data/chrome_scroll_without_vsync.pftrace scroll_flow_event.sql scroll_flow_event.out
@@ -9,11 +11,23 @@
../../data/chrome_scroll_without_vsync.pftrace scroll_flow_event_queuing_delay.sql scroll_flow_event_queuing_delay.out
../../data/chrome_scroll_without_vsync.pftrace scroll_flow_event_queuing_delay_general_validation.sql scroll_flow_event_general_validation.out
../../data/chrome_scroll_without_vsync.pftrace scroll_jank_cause_queuing_delay.sql scroll_jank_cause_queuing_delay.out
+../../data/chrome_scroll_without_vsync.pftrace scroll_jank_cause_queuing_delay_restricted.sql scroll_jank_cause_queuing_delay_restricted.out
../../data/chrome_scroll_without_vsync.pftrace scroll_jank_cause_queuing_delay_general_validation.sql scroll_jank_cause_queuing_delay_general_validation.out
-../../data/chrome_scroll_without_vsync.pftrace chrome_thread_slice_with_cpu_time.sql chrome_thread_slice_with_cpu_time.out
-../track_event/track_event_counters.textproto chrome_thread_slice_with_cpu_time_repeated.sql chrome_thread_slice_with_cpu_time_repeated.out
+../../data/chrome_scroll_without_vsync.pftrace chrome_thread_slice.sql chrome_thread_slice.out
+../track_event/track_event_counters.textproto chrome_thread_slice_repeated.sql chrome_thread_slice_repeated.out
../../data/chrome_rendering_desktop.pftrace frame_times frame_times_metric.out
+../../data/chrome_rendering_desktop.pftrace chrome_dropped_frames chrome_dropped_frames_metric.out
+../chrome/long_event_latency.textproto chrome_long_latency_metric.sql chrome_long_latency_metric.out
scroll_jank_mojo_simple_watcher.py scroll_jank_mojo_simple_watcher.sql scroll_jank_mojo_simple_watcher.out
+scroll_jank_gpu_check.py scroll_jank_gpu_check.sql scroll_jank_gpu_check.out
+
+# Touch gesture metrics
+../../data/chrome_touch_gesture_scroll.pftrace touch_jank.sql touch_jank.out
+../../data/chrome_touch_gesture_scroll.pftrace touch_flow_event.sql touch_flow_event.out
+../../data/chrome_touch_gesture_scroll.pftrace touch_flow_event_queuing_delay.sql touch_flow_event_queuing_delay.out
+touch_jank.py touch_jank.sql touch_jank_synth.out
+touch_jank.py touch_flow_event.sql touch_flow_event_synth.out
+touch_jank.py touch_flow_event_queuing_delay_full.sql touch_flow_event_queuing_delay_synth.out
# Chrome memory snapshots.
../../data/chrome_memory_snapshot.pftrace memory_snapshot_general_validation.sql memory_snapshot_general_validation.out
@@ -40,3 +54,15 @@ modified_rail_modes_extra_long.py modified_rail_modes.sql modified_rail_modes_ex
../../data/chrome_android_systrace.pftrace chrome_processes.sql chrome_processes_android_systrace.out
../../data/chrome_scroll_without_vsync.pftrace chrome_threads.sql chrome_threads.out
../../data/chrome_android_systrace.pftrace chrome_threads.sql chrome_threads_android_systrace.out
+
+# Chrome histogram hashes
+chrome_histogram_hashes.textproto chrome_histogram_hashes chrome_histogram_hashes.out
+
+# Chrome user events
+chrome_user_event_hashes.textproto chrome_user_event_hashes chrome_user_event_hashes.out
+
+# Chrome performance mark
+chrome_performance_mark_hashes.textproto chrome_performance_mark_hashes chrome_performance_mark_hashes.out
+
+# Chrome slices
+chrome_slice_names.textproto chrome_slice_names chrome_slice_names.out
diff --git a/test/trace_processor/chrome/long_event_latency.textproto b/test/trace_processor/chrome/long_event_latency.textproto
new file mode 100644
index 000000000..10635a986
--- /dev/null
+++ b/test/trace_processor/chrome/long_event_latency.textproto
@@ -0,0 +1,212 @@
+# Long latency events from two renderer processes
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ track_descriptor {
+ uuid: 10
+ process {
+ pid: 1001
+ process_name: "Renderer"
+ }
+ }
+}
+
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ track_descriptor {
+ uuid: 20
+ process {
+ pid: 1002
+ process_name: "Renderer"
+ }
+ }
+}
+
+# EventLatency 1: 200ms duration
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ track_descriptor {
+ uuid: 101
+ parent_uuid: 10
+ name: "EventLatency"
+ }
+}
+
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 111000
+ track_event {
+ track_uuid: 101
+ categories: "cat"
+ debug_annotations: {
+ name: "event"
+ string_value: "FirstGestureScrollUpdate"
+ }
+ name: "EventLatency"
+ type: 1
+ }
+}
+
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 200111000
+ track_event {
+ track_uuid: 101
+ categories: "cat"
+ name: "EventLatency"
+ type: 2
+ }
+}
+
+# EventLatency 2: 110ms ending at the same timestamp as EventLatency 1.
+# EventLatency 1 and 2 are reported as one occurrence of long latency.
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ track_descriptor {
+ uuid: 102
+ parent_uuid: 10
+ name: "EventLatency"
+ }
+}
+
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 90111000
+ track_event {
+ track_uuid: 102
+ categories: "cat"
+ debug_annotations: {
+ name: "event"
+ string_value: "GestureScrollUpdate"
+ }
+ name: "EventLatency"
+ type: 1
+ }
+}
+
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 200111000
+ track_event {
+ track_uuid: 102
+ categories: "cat"
+ name: "EventLatency"
+ type: 2
+ }
+}
+
+# EventLatency 3: a long latency slightly above the 100ms threshold
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ track_descriptor {
+ uuid: 103
+ parent_uuid: 10
+ name: "EventLatency"
+ }
+}
+
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 180111000
+ track_event {
+ track_uuid: 103
+ categories: "cat"
+ debug_annotations: {
+ name: "event"
+ string_value: "GestureScrollUpdate"
+ }
+ name: "EventLatency"
+ type: 1
+ }
+}
+
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 280111001
+ track_event {
+ track_uuid: 103
+ categories: "cat"
+ name: "EventLatency"
+ type: 2
+ }
+}
+
+# EventLatency 4: below the 100ms threshold; not a long latency
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ track_descriptor {
+ uuid: 104
+ parent_uuid: 10
+ name: "EventLatency"
+ }
+}
+
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 250111001
+ track_event {
+ track_uuid: 104
+ categories: "cat"
+ debug_annotations: {
+ name: "event"
+ string_value: "GestureScrollUpdate"
+ }
+ name: "EventLatency"
+ type: 1
+ }
+}
+
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 350111000
+ track_event {
+ track_uuid: 104
+ categories: "cat"
+ name: "EventLatency"
+ type: 2
+ }
+}
+
+# EventLatency 5: long latency from the second renderer process;
+# should be reported as a standalone long latency occurrence despite having
+# the same end time as EventLatency 1.
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ track_descriptor {
+ uuid: 201
+ parent_uuid: 20
+ name: "EventLatency"
+ }
+}
+
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 111000
+ track_event {
+ track_uuid: 201
+ categories: "cat"
+ debug_annotations: {
+ name: "event"
+ string_value: "GestureScrollUpdate"
+ }
+ name: "EventLatency"
+ type: 1
+ }
+}
+
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 200111000
+ track_event {
+ track_uuid: 201
+ categories: "cat"
+ name: "EventLatency"
+ type: 2
+ }
+} \ No newline at end of file
diff --git a/test/trace_processor/chrome/scroll_flow_event.out b/test/trace_processor/chrome/scroll_flow_event.out
index 569ae8677..148f46b29 100644
--- a/test/trace_processor/chrome/scroll_flow_event.out
+++ b/test/trace_processor/chrome/scroll_flow_event.out
@@ -48,14 +48,14 @@
2721,545022454611,5000,0,"STEP_SWAP_BUFFERS",545022459611,545034641829,545034641829,2721,"STEP_DRAW_AND_SWAP"
2721,545034641829,5000,0,"STEP_DRAW_AND_SWAP",545034646829,545044471829,545044471829,2721,"End"
2721,545044471829,3000,0,"End",545044474829,"[NULL]",545024000403,2725,"AsyncBegin"
-2725,545024000403,31889426,1,"AsyncBegin",545024000403,545025279403,545025586403,2725,"Begin"
-2725,545025586403,2000,1,"Begin",545025746403,545025279403,545025615403,2725,"STEP_SEND_INPUT_EVENT_UI"
-2725,545025615403,117000,1,"STEP_SEND_INPUT_EVENT_UI",545025746403,545025698611,545025703611,2725,"STEP_HANDLE_INPUT_EVENT_IMPL"
-2725,545025703611,9000,1,"STEP_HANDLE_INPUT_EVENT_IMPL",545025713611,545033251611,545033256611,2725,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL"
-2725,545033256611,3000,1,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",545033344611,545034007611,545034007611,2725,"STEP_SWAP_BUFFERS"
-2725,545034007611,5000,1,"STEP_SWAP_BUFFERS",545034012611,545047703829,545047703829,2725,"STEP_DRAW_AND_SWAP"
-2725,545047703829,1000,1,"STEP_DRAW_AND_SWAP",545047704829,545055892829,545055892829,2725,"End"
-2725,545055892829,1000,1,"End",545055893829,"[NULL]",545032000403,2727,"AsyncBegin"
+2725,545024000403,31889426,0,"AsyncBegin",545024000403,545025279403,545025586403,2725,"Begin"
+2725,545025586403,2000,0,"Begin",545025746403,545025279403,545025615403,2725,"STEP_SEND_INPUT_EVENT_UI"
+2725,545025615403,117000,0,"STEP_SEND_INPUT_EVENT_UI",545025746403,545025698611,545025703611,2725,"STEP_HANDLE_INPUT_EVENT_IMPL"
+2725,545025703611,9000,0,"STEP_HANDLE_INPUT_EVENT_IMPL",545025713611,545033251611,545033256611,2725,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL"
+2725,545033256611,3000,0,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",545033344611,545034007611,545034007611,2725,"STEP_SWAP_BUFFERS"
+2725,545034007611,5000,0,"STEP_SWAP_BUFFERS",545034012611,545047703829,545047703829,2725,"STEP_DRAW_AND_SWAP"
+2725,545047703829,1000,0,"STEP_DRAW_AND_SWAP",545047704829,545055892829,545055892829,2725,"End"
+2725,545055892829,1000,0,"End",545055893829,"[NULL]",545032000403,2727,"AsyncBegin"
2727,545032000403,23876426,0,"AsyncBegin",545032000403,545033878403,545034017403,2727,"Begin"
2727,545034017403,1000,0,"Begin",545034128403,545033878403,545034048403,2727,"STEP_SEND_INPUT_EVENT_UI"
2727,545034048403,36000,0,"STEP_SEND_INPUT_EVENT_UI",545034128403,545034224611,545034228611,2727,"STEP_HANDLE_INPUT_EVENT_IMPL"
@@ -752,14 +752,14 @@
2956,546195772611,6000,1,"STEP_SWAP_BUFFERS",546195778611,546207402829,546207402829,2956,"STEP_DRAW_AND_SWAP"
2956,546207402829,7000,1,"STEP_DRAW_AND_SWAP",546207409829,546228297829,546228297829,2956,"End"
2956,546228297829,7000,1,"End",546228304829,"[NULL]",546200000403,2960,"AsyncBegin"
-2960,546200000403,40097426,1,"AsyncBegin",546200000403,546201377403,546201519403,2960,"Begin"
-2960,546201519403,1000,1,"Begin",546201586403,546201377403,546201544403,2960,"STEP_SEND_INPUT_EVENT_UI"
-2960,546201544403,31000,1,"STEP_SEND_INPUT_EVENT_UI",546201586403,546201665611,546201667611,2960,"STEP_HANDLE_INPUT_EVENT_IMPL"
-2960,546201667611,9000,1,"STEP_HANDLE_INPUT_EVENT_IMPL",546201677611,546205643611,546205647611,2960,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL"
-2960,546205647611,3000,1,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",546205696611,546206945611,546206945611,2960,"STEP_SWAP_BUFFERS"
-2960,546206945611,8000,1,"STEP_SWAP_BUFFERS",546206953611,546220078829,546220078829,2960,"STEP_DRAW_AND_SWAP"
-2960,546220078829,1000,1,"STEP_DRAW_AND_SWAP",546220079829,546240099829,546240099829,2960,"End"
-2960,546240099829,1000,1,"End",546240100829,"[NULL]",546208000403,2962,"AsyncBegin"
+2960,546200000403,40097426,0,"AsyncBegin",546200000403,546201377403,546201519403,2960,"Begin"
+2960,546201519403,1000,0,"Begin",546201586403,546201377403,546201544403,2960,"STEP_SEND_INPUT_EVENT_UI"
+2960,546201544403,31000,0,"STEP_SEND_INPUT_EVENT_UI",546201586403,546201665611,546201667611,2960,"STEP_HANDLE_INPUT_EVENT_IMPL"
+2960,546201667611,9000,0,"STEP_HANDLE_INPUT_EVENT_IMPL",546201677611,546205643611,546205647611,2960,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL"
+2960,546205647611,3000,0,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",546205696611,546206945611,546206945611,2960,"STEP_SWAP_BUFFERS"
+2960,546206945611,8000,0,"STEP_SWAP_BUFFERS",546206953611,546220078829,546220078829,2960,"STEP_DRAW_AND_SWAP"
+2960,546220078829,1000,0,"STEP_DRAW_AND_SWAP",546220079829,546240099829,546240099829,2960,"End"
+2960,546240099829,1000,0,"End",546240100829,"[NULL]",546208000403,2962,"AsyncBegin"
2962,546208000403,32086426,0,"AsyncBegin",546208000403,546209350403,546209483403,2962,"Begin"
2962,546209483403,1000,0,"Begin",546209547403,546209350403,546209508403,2962,"STEP_SEND_INPUT_EVENT_UI"
2962,546209508403,29000,0,"STEP_SEND_INPUT_EVENT_UI",546209547403,546209595611,546209597611,2962,"STEP_HANDLE_INPUT_EVENT_IMPL"
diff --git a/test/trace_processor/chrome/scroll_flow_event_general_validation.out b/test/trace_processor/chrome/scroll_flow_event_general_validation.out
index 295637e00..5a223bf5a 100644
--- a/test/trace_processor/chrome/scroll_flow_event_general_validation.out
+++ b/test/trace_processor/chrome/scroll_flow_event_general_validation.out
@@ -1,3 +1,3 @@
"total_scroll_updates","total_flow_event_steps","total_janky_flow_event_steps","number_of_unique_steps"
-139,1112,72,8
+139,1112,56,8
diff --git a/test/trace_processor/chrome/scroll_flow_event_queuing_delay.out b/test/trace_processor/chrome/scroll_flow_event_queuing_delay.out
index 610f04b72..519e25c4e 100644
--- a/test/trace_processor/chrome/scroll_flow_event_queuing_delay.out
+++ b/test/trace_processor/chrome/scroll_flow_event_queuing_delay.out
@@ -1,26 +1,26 @@
-"trace_id","step","next_step","ancestor_end","maybe_next_ancestor_ts","queuing_time_ns"
-2721,"AsyncBegin","Begin",545007000403,545010006403,3006000
-2721,"Begin","STEP_SEND_INPUT_EVENT_UI",545010323403,545010006403,0
-2721,"STEP_SEND_INPUT_EVENT_UI","STEP_HANDLE_INPUT_EVENT_IMPL",545010323403,545010685611,362208
-2721,"STEP_HANDLE_INPUT_EVENT_IMPL","STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",545010695611,545021699611,11004000
-2721,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL","STEP_SWAP_BUFFERS",545021748611,545022454611,706000
-2721,"STEP_SWAP_BUFFERS","STEP_DRAW_AND_SWAP",545022459611,545034641829,12182218
-2721,"STEP_DRAW_AND_SWAP","End",545034646829,545044471829,9825000
-2721,"End","AsyncBegin",545044474829,"[NULL]","[NULL]"
-2725,"AsyncBegin","Begin",545024000403,545025279403,1279000
-2725,"Begin","STEP_SEND_INPUT_EVENT_UI",545025746403,545025279403,0
-2725,"STEP_SEND_INPUT_EVENT_UI","STEP_HANDLE_INPUT_EVENT_IMPL",545025746403,545025698611,0
-2725,"STEP_HANDLE_INPUT_EVENT_IMPL","STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",545025713611,545033251611,7538000
-2725,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL","STEP_SWAP_BUFFERS",545033344611,545034007611,663000
-2725,"STEP_SWAP_BUFFERS","STEP_DRAW_AND_SWAP",545034012611,545047703829,13691218
-2725,"STEP_DRAW_AND_SWAP","End",545047704829,545055892829,8188000
-2725,"End","AsyncBegin",545055893829,"[NULL]","[NULL]"
-2727,"AsyncBegin","Begin",545032000403,545033878403,1878000
-2727,"Begin","STEP_SEND_INPUT_EVENT_UI",545034128403,545033878403,0
-2727,"STEP_SEND_INPUT_EVENT_UI","STEP_HANDLE_INPUT_EVENT_IMPL",545034128403,545034224611,96208
-2727,"STEP_HANDLE_INPUT_EVENT_IMPL","STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",545034237611,545044106611,9869000
-2727,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL","STEP_SWAP_BUFFERS",545044160611,545046053611,1893000
-2727,"STEP_SWAP_BUFFERS","STEP_DRAW_AND_SWAP",545046061611,545047694829,1633218
-2727,"STEP_DRAW_AND_SWAP","End",545047701829,545055884829,8183000
-2727,"End","AsyncBegin",545055886829,"[NULL]","[NULL]"
+"trace_id","jank","step","next_step","ancestor_end","maybe_next_ancestor_ts","queuing_time_ns"
+2954,0,"AsyncBegin","Begin",546175000403,546176663403,1663000
+2954,0,"Begin","STEP_SEND_INPUT_EVENT_UI",546176884403,546176663403,0
+2954,0,"STEP_SEND_INPUT_EVENT_UI","STEP_HANDLE_INPUT_EVENT_IMPL",546176884403,546176948611,64208
+2954,0,"STEP_HANDLE_INPUT_EVENT_IMPL","STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",546176961611,546183503611,6542000
+2954,0,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL","STEP_SWAP_BUFFERS",546183547611,546184802611,1255000
+2954,0,"STEP_SWAP_BUFFERS","STEP_DRAW_AND_SWAP",546184809611,546186327829,1518218
+2954,0,"STEP_DRAW_AND_SWAP","End",546186335829,546205976829,19641000
+2954,0,"End","AsyncBegin",546205978829,"[NULL]","[NULL]"
+2956,1,"AsyncBegin","Begin",546183000403,546186878403,3878000
+2956,1,"Begin","STEP_SEND_INPUT_EVENT_UI",546187103403,546186878403,0
+2956,1,"STEP_SEND_INPUT_EVENT_UI","STEP_HANDLE_INPUT_EVENT_IMPL",546187103403,546187138611,35208
+2956,1,"STEP_HANDLE_INPUT_EVENT_IMPL","STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",546187149611,546194427611,7278000
+2956,1,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL","STEP_SWAP_BUFFERS",546194464611,546195772611,1308000
+2956,1,"STEP_SWAP_BUFFERS","STEP_DRAW_AND_SWAP",546195778611,546207402829,11624218
+2956,1,"STEP_DRAW_AND_SWAP","End",546207409829,546228297829,20888000
+2956,1,"End","AsyncBegin",546228304829,"[NULL]","[NULL]"
+2960,0,"AsyncBegin","Begin",546200000403,546201377403,1377000
+2960,0,"Begin","STEP_SEND_INPUT_EVENT_UI",546201586403,546201377403,0
+2960,0,"STEP_SEND_INPUT_EVENT_UI","STEP_HANDLE_INPUT_EVENT_IMPL",546201586403,546201665611,79208
+2960,0,"STEP_HANDLE_INPUT_EVENT_IMPL","STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",546201677611,546205643611,3966000
+2960,0,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL","STEP_SWAP_BUFFERS",546205696611,546206945611,1249000
+2960,0,"STEP_SWAP_BUFFERS","STEP_DRAW_AND_SWAP",546206953611,546220078829,13125218
+2960,0,"STEP_DRAW_AND_SWAP","End",546220079829,546240099829,20020000
+2960,0,"End","AsyncBegin",546240100829,"[NULL]","[NULL]"
diff --git a/test/trace_processor/chrome/scroll_flow_event_queuing_delay.sql b/test/trace_processor/chrome/scroll_flow_event_queuing_delay.sql
index fdbb40cef..50e79b855 100644
--- a/test/trace_processor/chrome/scroll_flow_event_queuing_delay.sql
+++ b/test/trace_processor/chrome/scroll_flow_event_queuing_delay.sql
@@ -16,15 +16,16 @@
SELECT RUN_METRIC('chrome/scroll_flow_event_queuing_delay.sql')
AS suppress_query_output;
--- trace 2725 is janky and 2721 and 2727 surround it (both are not janky). We
+-- trace 2956 is janky and 2954 and 2960 surround it (both are not janky). We
-- just manually computed these values to ensure the queuing time is correct.
SELECT
trace_id,
+ jank,
step,
next_step,
ancestor_end,
maybe_next_ancestor_ts,
queuing_time_ns
FROM scroll_flow_event_queuing_delay
-WHERE trace_id = 2721 OR trace_id = 2725 OR trace_id = 2727
+WHERE trace_id = 2954 OR trace_id = 2956 OR trace_id = 2960
ORDER BY trace_id, ts;
diff --git a/test/trace_processor/chrome/scroll_jank.out b/test/trace_processor/chrome/scroll_jank.out
index fb1120f77..163727e48 100644
--- a/test/trace_processor/chrome/scroll_jank.out
+++ b/test/trace_processor/chrome/scroll_jank.out
@@ -1,141 +1,141 @@
-"gesture_scroll_id","trace_id","jank","ts","dur"
-2708,2709,0,544958000403,19009426
-2708,2711,0,544966000403,22609426
-2708,2715,0,544983000403,28089426
-2708,2717,0,544991000403,30714426
-2708,2719,0,544999000403,34740426
-2708,2721,0,545007000403,37462426
-2708,2725,1,545024000403,31889426
-2708,2727,0,545032000403,23876426
-2708,2729,0,545040000403,28316426
-2708,2733,0,545056000403,22620426
-2708,2735,0,545065000403,23642426
-2708,2739,0,545081000403,19016426
-2708,2741,0,545089000403,22491426
-2708,2743,0,545098000403,24940426
-2708,2747,0,545114000403,19365426
-2708,2749,0,545122000403,22629426
-2708,2753,0,545139000403,17669426
-2708,2755,0,545147000403,20941426
-2708,2757,0,545155000403,23321426
-2708,2761,0,545172000403,18585426
-2708,2763,0,545180000403,22430426
-2708,2765,0,545188000403,23545426
-2708,2769,0,545204000403,19115426
-2708,2771,0,545213000403,21107426
-2708,2773,0,545221000403,25065426
-2708,2777,0,545237000403,20064426
-2708,2779,0,545246000403,22190426
-2708,2783,0,545262000403,16635426
-2708,2785,0,545270000403,19926426
-2708,2787,0,545278000403,23003426
-2708,2791,0,545295000403,17169426
-2708,2793,0,545303000403,20626426
-2708,2795,0,545311000403,23560426
-2708,2799,0,545328000403,18191426
-2708,2801,0,545336000403,20911426
-2708,2803,0,545344000403,24228426
-2708,2807,0,545361000403,18189426
-2708,2809,0,545369000403,21379426
-2708,2811,0,545377000403,24913426
-2708,2815,0,545394000403,18671426
-2708,2817,0,545402000403,21928426
-2708,2821,0,545418000403,17254426
-2708,2823,0,545426000403,20407426
-2708,2825,0,545435000403,22633426
-2708,2827,0,545443000403,27179426
-2708,2831,0,545459000403,20575426
-2708,2833,0,545468000403,23489426
-2708,2837,0,545484000403,18277426
-2708,2839,0,545492000403,21649426
-2708,2841,0,545500000403,24734426
-2708,2845,0,545517000403,18824426
-2708,2847,0,545525000403,22343426
-2708,2849,0,545533000403,25222426
-2708,2853,0,545550000403,19151426
-2708,2855,0,545558000403,22660426
-2708,2859,0,545574000403,17603426
-2708,2861,0,545583000403,19608426
-2708,2863,0,545591000403,22822426
-2708,2867,0,545607000403,18005426
-2708,2869,0,545615000403,21063426
-2708,2871,0,545624000403,23894426
-2708,2875,0,545640000403,18611426
-2708,2877,0,545648000403,21759426
-2708,2879,0,545656000403,25004426
-2708,2881,0,545671000403,32742426
-2708,2884,0,545681794403,32652426
-2708,2885,0,545691182403,34488426
-2708,2886,0,545702355403,34887426
-2708,2887,0,545713526403,34615426
-2708,2888,0,545724697403,36799426
-2708,2889,0,545735867403,35326426
-2708,2890,0,545747040403,35047426
-2708,2891,0,545758211403,34990426
-2708,2892,0,545769381403,39529426
-2708,2893,0,545780550403,35967426
-2708,2894,1,545791721403,45468426
-2708,2895,1,545802892403,45651426
-2708,2897,0,545825234403,34662426
-2917,2918,0,546027000403,24672426
-2917,2920,0,546035000403,27274426
-2917,2922,0,546044000403,28587426
-2917,2924,1,546052000403,41821426
-2917,2926,1,546060000403,44914426
-2917,2930,0,546076000403,28902426
-2917,2932,0,546085000403,31881426
-2917,2934,0,546093000403,34989426
-2917,2938,1,546109000403,41953426
-2917,2940,0,546118000403,32872426
-2917,2942,0,546126000403,35348426
-2917,2946,0,546142000403,42106426
-2917,2948,1,546150000403,45005426
-2917,2950,0,546159000403,35994426
-2917,2954,0,546175000403,30970426
-2917,2956,1,546183000403,45256426
-2917,2960,1,546200000403,40097426
-2917,2962,0,546208000403,32086426
-2917,2964,0,546216000403,34686426
-2917,2968,0,546233000403,28852426
-2917,2970,0,546241000403,32494426
-2917,2972,0,546249000403,37304426
-2917,2976,0,546265000403,32101426
-2917,2978,0,546273000403,34156426
-2917,2982,0,546290000403,27915426
-2917,2984,0,546298000403,30723426
-2917,2986,0,546307000403,32918426
-2917,2990,0,546323000403,29800426
-2917,2992,0,546331000403,31314426
-2917,2994,0,546339000403,35092426
-2917,2998,0,546356000403,28702426
-2917,3000,0,546364000403,32457426
-2917,3002,0,546372000403,35043426
-2917,3006,0,546389000403,29285426
-2917,3008,0,546397000403,32831426
-2917,3010,0,546405000403,35630426
-2917,3014,0,546422000403,30119426
-2917,3016,0,546430000403,33185426
-2917,3020,0,546446000403,28386426
-2917,3022,0,546455000403,30102426
-2917,3024,0,546463000403,33512426
-2917,3028,0,546479000403,28455426
-2917,3030,0,546488000403,30791426
-2917,3032,0,546496000403,34105426
-2917,3036,0,546512000403,29329426
-2917,3038,0,546520000403,32321426
-2917,3040,0,546529000403,34457426
-2917,3044,0,546545000403,29668426
-2917,3046,0,546553000403,32830426
-2917,3048,0,546561000403,35849426
-2917,3052,0,546578000403,30365426
-2917,3054,0,546586000403,33666426
-2917,3056,0,546594000403,36913426
-2917,3060,0,546611000403,30855426
-2917,3062,0,546619000403,33897426
-2917,3064,0,546627000403,36941426
-2917,3068,0,546644000403,31194426
-2917,3070,0,546652000403,34276426
-2917,3074,0,546676000403,32746426
-2917,3077,0,546701627403,29680426
-2917,3079,0,546718977403,34597426
+"gesture_scroll_id","trace_id","jank","ts","dur","jank_budget"
+2708,2709,0,544958000403,19009426,-11933333.350000
+2708,2711,0,544966000403,22609426,-4733333.350000
+2708,2715,0,544983000403,28089426,-2853333.350000
+2708,2717,0,544991000403,30714426,-5708333.350000
+2708,2719,0,544999000403,34740426,-4307333.350000
+2708,2721,0,545007000403,37462426,-2760333.350000
+2708,2725,0,545024000403,31889426,-320333.350000
+2708,2727,0,545032000403,23876426,-12773333.350000
+2708,2729,0,545040000403,28316426,-2637333.350000
+2708,2733,0,545056000403,22620426,-9355333.350000
+2708,2735,0,545065000403,23642426,-3707333.350000
+2708,2739,0,545081000403,19016426,-11808333.350000
+2708,2741,0,545089000403,22491426,-4858333.350000
+2708,2743,0,545098000403,24940426,-2758333.350000
+2708,2747,0,545114000403,19365426,-11597333.350000
+2708,2749,0,545122000403,22629426,-3373333.350000
+2708,2753,0,545139000403,17669426,-11605333.350000
+2708,2755,0,545147000403,20941426,-5061333.350000
+2708,2757,0,545155000403,23321426,-3597333.350000
+2708,2761,0,545172000403,18585426,-12178333.350000
+2708,2763,0,545180000403,22430426,-4488333.350000
+2708,2765,0,545188000403,23545426,-3903333.350000
+2708,2769,0,545204000403,19115426,-10325333.350000
+2708,2771,0,545213000403,21107426,-6341333.350000
+2708,2773,0,545221000403,25065426,-3332333.350000
+2708,2777,0,545237000403,20064426,-10459333.350000
+2708,2779,0,545246000403,22190426,-2778333.350000
+2708,2783,0,545262000403,16635426,-11624333.350000
+2708,2785,0,545270000403,19926426,-5042333.350000
+2708,2787,0,545278000403,23003426,-2499333.350000
+2708,2791,0,545295000403,17169426,-11790333.350000
+2708,2793,0,545303000403,20626426,-4876333.350000
+2708,2795,0,545311000403,23560426,-2964333.350000
+2708,2799,0,545328000403,18191426,-11053333.350000
+2708,2801,0,545336000403,20911426,-5613333.350000
+2708,2803,0,545344000403,24228426,-2294333.350000
+2708,2807,0,545361000403,18189426,-11523333.350000
+2708,2809,0,545369000403,21379426,-5143333.350000
+2708,2811,0,545377000403,24913426,-2091333.350000
+2708,2815,0,545394000403,18671426,-11590333.350000
+2708,2817,0,545402000403,21928426,-3659333.350000
+2708,2821,0,545418000403,17254426,-11486333.350000
+2708,2823,0,545426000403,20407426,-5180333.350000
+2708,2825,0,545435000403,22633426,-6107333.350000
+2708,2827,0,545443000403,27179426,-1729333.350000
+2708,2831,0,545459000403,20575426,-11247333.350000
+2708,2833,0,545468000403,23489426,-3121333.350000
+2708,2837,0,545484000403,18277426,-11705333.350000
+2708,2839,0,545492000403,21649426,-4961333.350000
+2708,2841,0,545500000403,24734426,-2423333.350000
+2708,2845,0,545517000403,18824426,-11852333.350000
+2708,2847,0,545525000403,22343426,-4814333.350000
+2708,2849,0,545533000403,25222426,-2262333.350000
+2708,2853,0,545550000403,19151426,-11842333.350000
+2708,2855,0,545558000403,22660426,-3276333.350000
+2708,2859,0,545574000403,17603426,-10338333.350000
+2708,2861,0,545583000403,19608426,-6328333.350000
+2708,2863,0,545591000403,22822426,-3516333.350000
+2708,2867,0,545607000403,18005426,-11391333.350000
+2708,2869,0,545615000403,21063426,-5275333.350000
+2708,2871,0,545624000403,23894426,-3050333.350000
+2708,2875,0,545640000403,18611426,-11481333.350000
+2708,2877,0,545648000403,21759426,-5185333.350000
+2708,2879,0,545656000403,25004426,-5088333.350000
+2708,2881,0,545671000403,32742426,-595333.350000
+2708,2884,0,545681794403,32652426,-8423333.350000
+2708,2885,0,545691182403,34488426,-6497333.350000
+2708,2886,0,545702355403,34887426,-7934333.350000
+2708,2887,0,545713526403,34615426,-8605333.350000
+2708,2888,0,545724697403,36799426,-6149333.350000
+2708,2889,0,545735867403,35326426,-8054333.350000
+2708,2890,0,545747040403,35047426,-8276333.350000
+2708,2891,0,545758211403,34990426,-8390333.350000
+2708,2892,0,545769381403,39529426,-3794333.350000
+2708,2893,0,545780550403,35967426,-11895333.350000
+2708,2894,1,545791721403,45468426,1167666.650000
+2708,2895,1,545802892403,45651426,2655666.650000
+2708,2897,0,545825234403,34662426,1656666.650000
+2917,2918,0,546027000403,24672426,-10935333.350000
+2917,2920,0,546035000403,27274426,-5731333.350000
+2917,2922,0,546044000403,28587426,-7020333.350000
+2917,2924,1,546052000403,41821426,4900666.650000
+2917,2926,1,546060000403,44914426,7678666.650000
+2917,2930,0,546076000403,28902426,-11312333.350000
+2917,2932,0,546085000403,31881426,-5354333.350000
+2917,2934,0,546093000403,34989426,-5225333.350000
+2917,2938,1,546109000403,41953426,747666.650000
+2917,2940,0,546118000403,32872426,-10809333.350000
+2917,2942,0,546126000403,35348426,-5857333.350000
+2917,2946,0,546142000403,42106426,-1575333.350000
+2917,2948,1,546150000403,45005426,677666.650000
+2917,2950,0,546159000403,35994426,-3309333.350000
+2917,2954,0,546175000403,30970426,-13357333.350000
+2917,2956,1,546183000403,45256426,5952666.650000
+2917,2960,0,546200000403,40097426,-322333.350000
+2917,2962,0,546208000403,32086426,-10933333.350000
+2917,2964,0,546216000403,34686426,-2499333.350000
+2917,2968,0,546233000403,28852426,-11975333.350000
+2917,2970,0,546241000403,32494426,-4691333.350000
+2917,2972,0,546249000403,37304426,-3130333.350000
+2917,2976,0,546265000403,32101426,-10388333.350000
+2917,2978,0,546273000403,34156426,-2092333.350000
+2917,2982,0,546290000403,27915426,-11141333.350000
+2917,2984,0,546298000403,30723426,-5525333.350000
+2917,2986,0,546307000403,32918426,-5215333.350000
+2917,2990,0,546323000403,29800426,-9847333.350000
+2917,2992,0,546331000403,31314426,-6819333.350000
+2917,2994,0,546339000403,35092426,-1943333.350000
+2917,2998,0,546356000403,28702426,-12088333.350000
+2917,3000,0,546364000403,32457426,-4578333.350000
+2917,3002,0,546372000403,35043426,-2575333.350000
+2917,3006,0,546389000403,29285426,-11879333.350000
+2917,3008,0,546397000403,32831426,-4787333.350000
+2917,3010,0,546405000403,35630426,-2822333.350000
+2917,3014,0,546422000403,30119426,-11399333.350000
+2917,3016,0,546430000403,33185426,-3534333.350000
+2917,3020,0,546446000403,28386426,-10049333.350000
+2917,3022,0,546455000403,30102426,-6617333.350000
+2917,3024,0,546463000403,33512426,-3276333.350000
+2917,3028,0,546479000403,28455426,-10669333.350000
+2917,3030,0,546488000403,30791426,-5997333.350000
+2917,3032,0,546496000403,34105426,-3557333.350000
+2917,3036,0,546512000403,29329426,-11325333.350000
+2917,3038,0,546520000403,32321426,-5341333.350000
+2917,3040,0,546529000403,34457426,-3544333.350000
+2917,3044,0,546545000403,29668426,-11495333.350000
+2917,3046,0,546553000403,32830426,-5171333.350000
+2917,3048,0,546561000403,35849426,-2849333.350000
+2917,3052,0,546578000403,30365426,-11634333.350000
+2917,3054,0,546586000403,33666426,-5032333.350000
+2917,3056,0,546594000403,36913426,-2275333.350000
+2917,3060,0,546611000403,30855426,-11375333.350000
+2917,3062,0,546619000403,33897426,-5291333.350000
+2917,3064,0,546627000403,36941426,-2586333.350000
+2917,3068,0,546644000403,31194426,-11415333.350000
+2917,3070,0,546652000403,34276426,-5251333.350000
+2917,3074,0,546676000403,32746426,-5267333.350000
+2917,3077,0,546701627403,29680426,-11399333.350000
+2917,3079,0,546718977403,34597426,-3416333.350000
diff --git a/test/trace_processor/chrome/scroll_jank.sql b/test/trace_processor/chrome/scroll_jank.sql
index 2a502c169..9aaa99b08 100644
--- a/test/trace_processor/chrome/scroll_jank.sql
+++ b/test/trace_processor/chrome/scroll_jank.sql
@@ -20,5 +20,6 @@ SELECT
trace_id,
jank,
ts,
- dur
+ dur,
+ jank_budget
FROM scroll_jank;
diff --git a/test/trace_processor/chrome/scroll_jank_cause.out b/test/trace_processor/chrome/scroll_jank_cause.out
index 06ced33de..c8d577e86 100644
--- a/test/trace_processor/chrome/scroll_jank_cause.out
+++ b/test/trace_processor/chrome/scroll_jank_cause.out
@@ -1,3 +1,3 @@
"total","total_jank","sum_explained_and_unexplained","error_rows"
-139,9,9,0
+139,7,7,0
diff --git a/test/trace_processor/chrome/scroll_jank_cause_queuing_delay.out b/test/trace_processor/chrome/scroll_jank_cause_queuing_delay.out
index eedf5a225..a54d9b95c 100644
--- a/test/trace_processor/chrome/scroll_jank_cause_queuing_delay.out
+++ b/test/trace_processor/chrome/scroll_jank_cause_queuing_delay.out
@@ -8,6 +8,7 @@
"Renderer","Compositor",2918,0,7000,"InputLatency.LatencyInfo.Flow.QueuingDelay.NoJank.BlockingTasksUs.ScrollPredictor::ResampleScrollEvents"
"Renderer","Compositor",2918,0,25000,"InputLatency.LatencyInfo.Flow.QueuingDelay.NoJank.BlockingTasksUs.InputHandlerProxy::HandleGestureScrollUpdate-DeltaUnits"
"Renderer","Compositor",2918,0,6000,"InputLatency.LatencyInfo.Flow.QueuingDelay.NoJank.BlockingTasksUs.LatencyInfo.Flow"
+"Gpu","VizCompositorThread",2918,0,10000,"InputLatency.LatencyInfo.Flow.QueuingDelay.NoJank.BlockingTasksUs.LatencyInfo.Flow"
"Browser","CrProcessMain",2926,1,52000,"InputLatency.LatencyInfo.Flow.QueuingDelay.Jank.BlockingTasksUs.InputRouterImpl::GestureEventHandled-GestureEventQueue::ProcessGestureAck"
"Browser","CrProcessMain",2926,1,17000,"InputLatency.LatencyInfo.Flow.QueuingDelay.Jank.BlockingTasksUs.GestureProvider::OnTouchEvent"
"Renderer","Compositor",2926,1,1208,"InputLatency.LatencyInfo.Flow.QueuingDelay.Jank.BlockingTasksUs.WidgetInputHandlerImpl::DispatchNonBlockingEvent-LatencyInfo.Flow"
@@ -19,3 +20,6 @@
"Gpu","VizCompositorThread",2926,1,2000,"InputLatency.LatencyInfo.Flow.QueuingDelay.Jank.BlockingTasksUs.LatencyInfo.Flow"
"Gpu","VizCompositorThread",2926,1,5000,"InputLatency.LatencyInfo.Flow.QueuingDelay.Jank.BlockingTasksUs.LatencyInfo.Flow"
"Gpu","VizCompositorThread",2926,1,8000,"InputLatency.LatencyInfo.Flow.QueuingDelay.Jank.BlockingTasksUs.LatencyInfo.Flow"
+"Gpu","VizCompositorThread",2926,1,2000,"InputLatency.LatencyInfo.Flow.QueuingDelay.Jank.BlockingTasksUs.LatencyInfo.Flow"
+"Gpu","VizCompositorThread",2926,1,8000,"InputLatency.LatencyInfo.Flow.QueuingDelay.Jank.BlockingTasksUs.LatencyInfo.Flow"
+"Gpu","VizCompositorThread",2926,1,2000,"InputLatency.LatencyInfo.Flow.QueuingDelay.Jank.BlockingTasksUs.LatencyInfo.Flow"
diff --git a/test/trace_processor/chrome/scroll_jank_cause_queuing_delay_general_validation.out b/test/trace_processor/chrome/scroll_jank_cause_queuing_delay_general_validation.out
index 48fe6de44..daf9c401d 100644
--- a/test/trace_processor/chrome/scroll_jank_cause_queuing_delay_general_validation.out
+++ b/test/trace_processor/chrome/scroll_jank_cause_queuing_delay_general_validation.out
@@ -1,3 +1,3 @@
"total","janky_latency_info_non_jank_avg_dur","non_janky_latency_info_non_jank_avg_dur"
-139,6387.096774,6387.096774
+139,6185.000000,6185.000000
diff --git a/test/trace_processor/chrome/scroll_jank_cause_queuing_delay_restricted.out b/test/trace_processor/chrome/scroll_jank_cause_queuing_delay_restricted.out
new file mode 100644
index 000000000..4049795c7
--- /dev/null
+++ b/test/trace_processor/chrome/scroll_jank_cause_queuing_delay_restricted.out
@@ -0,0 +1,25 @@
+
+"process_name","thread_name","trace_id","jank","dur_overlapping_ns","restricted_metric_name"
+"Browser","CrProcessMain",2918,0,55000,"QueuingDelay.NoJank.BlockingTasksUs.GestureProvider::OnTouchEvent"
+"Browser","CrProcessMain",2918,0,433000,"QueuingDelay.NoJank.BlockingTasksUs.RenderWidgetHostImpl::ForwardTouchEvent-UnknownEvent"
+"Renderer","Compositor",2918,0,66000,"QueuingDelay.NoJank.BlockingTasksUs.WidgetInputHandlerImpl::DispatchNonBlockingEvent-UnknownEvent"
+"Renderer","Compositor",2918,0,116000,"QueuingDelay.NoJank.BlockingTasksUs.WidgetInputHandlerImpl::DispatchEvent-UnknownEvent"
+"Renderer","Compositor",2918,0,29000,"QueuingDelay.NoJank.BlockingTasksUs.WidgetInputHandlerImpl::DispatchNonBlockingEvent-UnknownEvent"
+"Renderer","Compositor",2918,0,7000,"QueuingDelay.NoJank.BlockingTasksUs.ScrollPredictor::ResampleScrollEvents"
+"Renderer","Compositor",2918,0,25000,"QueuingDelay.NoJank.BlockingTasksUs.InputHandlerProxy::HandleGestureScrollUpdate-UnknownEvent"
+"Renderer","Compositor",2918,0,6000,"QueuingDelay.NoJank.BlockingTasksUs.LatencyInfo.Flow"
+"Gpu","VizCompositorThread",2918,0,10000,"QueuingDelay.NoJank.BlockingTasksUs.LatencyInfo.Flow"
+"Browser","CrProcessMain",2926,1,52000,"QueuingDelay.Jank.BlockingTasksUs.InputRouterImpl::GestureEventHandled-UnknownEvent"
+"Browser","CrProcessMain",2926,1,17000,"QueuingDelay.Jank.BlockingTasksUs.GestureProvider::OnTouchEvent"
+"Renderer","Compositor",2926,1,1208,"QueuingDelay.Jank.BlockingTasksUs.WidgetInputHandlerImpl::DispatchNonBlockingEvent-UnknownEvent"
+"Renderer","Compositor",2926,1,38000,"QueuingDelay.Jank.BlockingTasksUs.WidgetInputHandlerImpl::DispatchNonBlockingEvent-UnknownEvent"
+"Renderer","Compositor",2926,1,21000,"QueuingDelay.Jank.BlockingTasksUs.WidgetInputHandlerImpl::DispatchEvent-UnknownEvent"
+"Renderer","Compositor",2926,1,6000,"QueuingDelay.Jank.BlockingTasksUs.ScrollPredictor::ResampleScrollEvents"
+"Renderer","Compositor",2926,1,30000,"QueuingDelay.Jank.BlockingTasksUs.InputHandlerProxy::HandleGestureScrollUpdate-UnknownEvent"
+"Renderer","Compositor",2926,1,14000,"QueuingDelay.Jank.BlockingTasksUs.WidgetInputHandlerManager::DidHandleInputEventSentToCompositor-UnknownEvent"
+"Gpu","VizCompositorThread",2926,1,2000,"QueuingDelay.Jank.BlockingTasksUs.LatencyInfo.Flow"
+"Gpu","VizCompositorThread",2926,1,5000,"QueuingDelay.Jank.BlockingTasksUs.LatencyInfo.Flow"
+"Gpu","VizCompositorThread",2926,1,8000,"QueuingDelay.Jank.BlockingTasksUs.LatencyInfo.Flow"
+"Gpu","VizCompositorThread",2926,1,2000,"QueuingDelay.Jank.BlockingTasksUs.LatencyInfo.Flow"
+"Gpu","VizCompositorThread",2926,1,8000,"QueuingDelay.Jank.BlockingTasksUs.LatencyInfo.Flow"
+"Gpu","VizCompositorThread",2926,1,2000,"QueuingDelay.Jank.BlockingTasksUs.LatencyInfo.Flow"
diff --git a/test/trace_processor/chrome/scroll_jank_cause_queuing_delay_restricted.sql b/test/trace_processor/chrome/scroll_jank_cause_queuing_delay_restricted.sql
new file mode 100644
index 000000000..7c8b59a17
--- /dev/null
+++ b/test/trace_processor/chrome/scroll_jank_cause_queuing_delay_restricted.sql
@@ -0,0 +1,27 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the 'License');
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an 'AS IS' BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+SELECT RUN_METRIC('chrome/scroll_jank_cause_queuing_delay.sql')
+ AS suppress_query_output;
+
+SELECT
+ process_name,
+ thread_name,
+ trace_id,
+ jank,
+ dur_overlapping_ns,
+ restricted_metric_name
+FROM scroll_jank_cause_queuing_delay
+WHERE trace_id = 2918 OR trace_id = 2926
+ORDER BY trace_id ASC, ts ASC
diff --git a/test/trace_processor/chrome/scroll_jank_general_validation.out b/test/trace_processor/chrome/scroll_jank_general_validation.out
index d4323b2b0..d76d3bc52 100644
--- a/test/trace_processor/chrome/scroll_jank_general_validation.out
+++ b/test/trace_processor/chrome/scroll_jank_general_validation.out
@@ -1,3 +1,3 @@
"total","scroll_dur","non_coalesced_updates","non_coalesced_dur","non_coalesced_janky_updates","non_coalesced_janky_dur","janky_percentage","avg_vsync_interval"
-2,1628470852,139,3974685214,9,382057834,9,16000000.000000
+2,1628470852,139,3974685214,7,310070982,7,16666666.666667
diff --git a/test/trace_processor/chrome/scroll_jank_general_validation.sql b/test/trace_processor/chrome/scroll_jank_general_validation.sql
index 41438758a..1aa3059b1 100644
--- a/test/trace_processor/chrome/scroll_jank_general_validation.sql
+++ b/test/trace_processor/chrome/scroll_jank_general_validation.sql
@@ -34,7 +34,7 @@ SELECT (
-- This means we should have scroll_dur == 1628470852
SELECT SUM(scroll_dur) FROM (
SELECT
- gesture_scroll_id, max(maybe_scroll_end) - begin_ts AS scroll_dur
+ gesture_scroll_id, max(maybe_gesture_end) - begin_ts AS scroll_dur
FROM scroll_jank
GROUP BY gesture_scroll_id
)
diff --git a/test/trace_processor/chrome/scroll_jank_gpu_check.out b/test/trace_processor/chrome/scroll_jank_gpu_check.out
new file mode 100644
index 000000000..f5dad3d52
--- /dev/null
+++ b/test/trace_processor/chrome/scroll_jank_gpu_check.out
@@ -0,0 +1,5 @@
+
+"ts","jank"
+15000000,0
+30000000,1
+115000000,0
diff --git a/test/trace_processor/chrome/scroll_jank_gpu_check.py b/test/trace_processor/chrome/scroll_jank_gpu_check.py
new file mode 100644
index 000000000..7e33ac21e
--- /dev/null
+++ b/test/trace_processor/chrome/scroll_jank_gpu_check.py
@@ -0,0 +1,86 @@
+#!/usr/bin/env python3
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Discarded events that do not get to GPU are invisible for UMA metric and
+# therefore should be excluded in trace-based metric. This tests ensures that's
+# the case.
+
+from os import sys
+
+import synth_common
+
+from synth_common import ms_to_ns
+trace = synth_common.create_trace()
+
+
+class Helper:
+
+ def __init__(self, trace, start_id, start_gesture_id):
+ self.trace = trace
+ self.id = start_id
+ self.gesture_id = start_gesture_id
+
+ def begin(self, from_ms, dur_ms):
+ self.trace.add_input_latency_event_slice(
+ "GestureScrollBegin",
+ ts=ms_to_ns(from_ms),
+ dur=ms_to_ns(dur_ms),
+ track=self.id,
+ trace_id=self.id,
+ gesture_scroll_id=self.gesture_id,
+ )
+ self.id += 1
+
+ def update(self, from_ms, dur_ms, gets_to_gpu=True):
+ self.trace.add_input_latency_event_slice(
+ "GestureScrollUpdate",
+ ts=ms_to_ns(from_ms),
+ dur=ms_to_ns(dur_ms),
+ track=self.id,
+ trace_id=self.id,
+ gesture_scroll_id=self.gesture_id,
+ gets_to_gpu=gets_to_gpu,
+ is_coalesced=False,
+ )
+ self.id += 1
+
+ def end(self, from_ms, dur_ms):
+ self.trace.add_input_latency_event_slice(
+ "GestureScrollEnd",
+ ts=ms_to_ns(from_ms),
+ dur=ms_to_ns(dur_ms),
+ track=self.id,
+ trace_id=self.id,
+ gesture_scroll_id=self.gesture_id)
+ self.id += 1
+ self.gesture_id += 1
+
+
+helper = Helper(trace, start_id=1234, start_gesture_id=5678)
+
+helper.begin(from_ms=0, dur_ms=10)
+helper.update(from_ms=15, dur_ms=10)
+# The next update should be recognized as janky
+helper.update(from_ms=30, dur_ms=30)
+helper.end(from_ms=70, dur_ms=10)
+
+helper.begin(from_ms=100, dur_ms=10)
+helper.update(from_ms=115, dur_ms=10)
+# The next update doesn't get to GPU, therefore would not be a part of jank
+# calculation
+helper.update(from_ms=130, dur_ms=30, gets_to_gpu=False)
+helper.end(from_ms=170, dur_ms=10)
+
+sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/chrome/scroll_jank_gpu_check.sql b/test/trace_processor/chrome/scroll_jank_gpu_check.sql
new file mode 100644
index 000000000..d3740b542
--- /dev/null
+++ b/test/trace_processor/chrome/scroll_jank_gpu_check.sql
@@ -0,0 +1,20 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+SELECT RUN_METRIC('chrome/scroll_jank.sql') AS suppress_query_output;
+
+SELECT ts, jank
+FROM scroll_jank
+ORDER BY ts ASC;
diff --git a/test/trace_processor/chrome/scroll_jank_mojo_simple_watcher.out b/test/trace_processor/chrome/scroll_jank_mojo_simple_watcher.out
index 13709b329..207e7d25e 100644
--- a/test/trace_processor/chrome/scroll_jank_mojo_simple_watcher.out
+++ b/test/trace_processor/chrome/scroll_jank_mojo_simple_watcher.out
@@ -2,4 +2,4 @@
"trace_id","jank","dur_overlapping_ns","metric_name"
34577,0,6000000,"InputLatency.LatencyInfo.Flow.QueuingDelay.NoJank.BlockingTasksUs.task-subtask"
34578,1,29000000,"InputLatency.LatencyInfo.Flow.QueuingDelay.Jank.BlockingTasksUs.task-subtask"
-34579,0,29000000,"InputLatency.LatencyInfo.Flow.QueuingDelay.NoJank.BlockingTasksUs.task-subtask(foo)"
+34579,0,29000000,"InputLatency.LatencyInfo.Flow.QueuingDelay.NoJank.BlockingTasksUs.task-foo"
diff --git a/test/trace_processor/chrome/touch_flow_event.out b/test/trace_processor/chrome/touch_flow_event.out
new file mode 100644
index 000000000..ae13efdc0
--- /dev/null
+++ b/test/trace_processor/chrome/touch_flow_event.out
@@ -0,0 +1,170 @@
+
+"trace_id","ts","dur","jank","step","ancestor_end","maybe_next_ancestor_ts","next_ts","next_trace_id","next_step"
+6288,1383122421558418,226350000,1,"AsyncBegin",1383122421558418,1383122426402418,1383122426484418,6288,"Begin"
+6288,1383122426484418,11000,1,"Begin",1383122426884418,1383122426402418,1383122426625418,6288,"STEP_SEND_INPUT_EVENT_UI"
+6288,1383122426625418,237000,1,"STEP_SEND_INPUT_EVENT_UI",1383122426884418,1383122427140418,1383122427169418,6288,"STEP_HANDLE_INPUT_EVENT_IMPL"
+6288,1383122427169418,163000,1,"STEP_HANDLE_INPUT_EVENT_IMPL",1383122427336418,1383122427140418,1383122427275418,6288,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL"
+6288,1383122427275418,5000,1,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",1383122427336418,1383122456261418,1383122456261418,6288,"STEP_HANDLE_INPUT_EVENT_MAIN"
+6288,1383122456261418,37514000,1,"STEP_HANDLE_INPUT_EVENT_MAIN",1383122493775418,1383122456261418,1383122493472418,6288,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL"
+6288,1383122493472418,10000,1,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL",1383122493775418,1383122496371418,1383122496371418,6288,"STEP_HANDLED_INPUT_EVENT_IMPL"
+6288,1383122496371418,7000,1,"STEP_HANDLED_INPUT_EVENT_IMPL",1383122496378418,1383122589999418,1383122589999418,6288,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT"
+6288,1383122589999418,24000,1,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT",1383122590023418,1383122601085418,1383122601085418,6288,"STEP_SWAP_BUFFERS"
+6288,1383122601085418,19000,1,"STEP_SWAP_BUFFERS",1383122601104418,1383122611053418,1383122611053418,6288,"STEP_DRAW_AND_SWAP"
+6288,1383122611053418,88000,1,"STEP_DRAW_AND_SWAP",1383122611141418,1383122647945418,1383122647945418,6288,"STEP_FINISHED_SWAP_BUFFERS"
+6288,1383122647945418,100000,1,"STEP_FINISHED_SWAP_BUFFERS",1383122648045418,"[NULL]",1383122543558418,6312,"AsyncBegin"
+6312,1383122543558418,185244000,0,"AsyncBegin",1383122543558418,1383122548583418,1383122548633418,6312,"Begin"
+6312,1383122548633418,6000,0,"Begin",1383122548862418,1383122548583418,1383122548703418,6312,"STEP_SEND_INPUT_EVENT_UI"
+6312,1383122548703418,148000,0,"STEP_SEND_INPUT_EVENT_UI",1383122548862418,1383122550407418,1383122550456418,6312,"STEP_HANDLE_INPUT_EVENT_IMPL"
+6312,1383122550456418,364000,0,"STEP_HANDLE_INPUT_EVENT_IMPL",1383122550827418,1383122550407418,1383122550719418,6312,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL"
+6312,1383122550719418,10000,0,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",1383122550827418,1383122591844418,1383122591844418,6312,"STEP_HANDLE_INPUT_EVENT_MAIN"
+6312,1383122591844418,9681000,0,"STEP_HANDLE_INPUT_EVENT_MAIN",1383122601525418,1383122591844418,1383122601331418,6312,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL"
+6312,1383122601331418,9000,0,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL",1383122601525418,1383122603068418,1383122603068418,6312,"STEP_HANDLED_INPUT_EVENT_IMPL"
+6312,1383122603068418,16000,0,"STEP_HANDLED_INPUT_EVENT_IMPL",1383122603084418,1383122667027418,1383122667027418,6312,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT"
+6312,1383122667027418,18000,0,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT",1383122667045418,1383122676422418,1383122676422418,6312,"STEP_SWAP_BUFFERS"
+6312,1383122676422418,18000,0,"STEP_SWAP_BUFFERS",1383122676440418,1383122688317418,1383122688317418,6312,"STEP_DRAW_AND_SWAP"
+6312,1383122688317418,30000,0,"STEP_DRAW_AND_SWAP",1383122688347418,1383122728832418,1383122728832418,6312,"STEP_FINISHED_SWAP_BUFFERS"
+6312,1383122728832418,24000,0,"STEP_FINISHED_SWAP_BUFFERS",1383122728856418,"[NULL]",1383123604558418,6328,"AsyncBegin"
+6328,1383123604558418,207945000,1,"AsyncBegin",1383123604558418,1383123610384418,1383123610436418,6328,"Begin"
+6328,1383123610436418,7000,1,"Begin",1383123610707418,1383123610384418,1383123610515418,6328,"STEP_SEND_INPUT_EVENT_UI"
+6328,1383123610515418,181000,1,"STEP_SEND_INPUT_EVENT_UI",1383123610707418,1383123611090418,1383123611121418,6328,"STEP_HANDLE_INPUT_EVENT_IMPL"
+6328,1383123611121418,262000,1,"STEP_HANDLE_INPUT_EVENT_IMPL",1383123611387418,1383123611090418,1383123611283418,6328,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL"
+6328,1383123611283418,11000,1,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",1383123611387418,1383123645509418,1383123645509418,6328,"STEP_HANDLE_INPUT_EVENT_MAIN"
+6328,1383123645509418,9318000,1,"STEP_HANDLE_INPUT_EVENT_MAIN",1383123654827418,1383123645509418,1383123654631418,6328,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL"
+6328,1383123654631418,8000,1,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL",1383123654827418,1383123656978418,1383123656978418,6328,"STEP_HANDLED_INPUT_EVENT_IMPL"
+6328,1383123656978418,30000,1,"STEP_HANDLED_INPUT_EVENT_IMPL",1383123657008418,1383123762642418,1383123762642418,6328,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT"
+6328,1383123762642418,13000,1,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT",1383123762655418,1383123768318418,1383123768318418,6328,"STEP_SWAP_BUFFERS"
+6328,1383123768318418,14000,1,"STEP_SWAP_BUFFERS",1383123768332418,1383123774132418,1383123774132418,6328,"STEP_DRAW_AND_SWAP"
+6328,1383123774132418,28000,1,"STEP_DRAW_AND_SWAP",1383123774160418,1383123812534418,1383123812534418,6328,"STEP_FINISHED_SWAP_BUFFERS"
+6328,1383123812534418,19000,1,"STEP_FINISHED_SWAP_BUFFERS",1383123812553418,"[NULL]",1383124088558418,6414,"AsyncBegin"
+6414,1383124088558418,173233000,0,"AsyncBegin",1383124088558418,1383124093797418,1383124093844418,6414,"Begin"
+6414,1383124093844418,6000,0,"Begin",1383124094081418,1383124093797418,1383124093918418,6414,"STEP_SEND_INPUT_EVENT_UI"
+6414,1383124093918418,153000,0,"STEP_SEND_INPUT_EVENT_UI",1383124094081418,1383124094617418,1383124094661418,6414,"STEP_HANDLE_INPUT_EVENT_IMPL"
+6414,1383124094661418,320000,0,"STEP_HANDLE_INPUT_EVENT_IMPL",1383124094988418,1383124094617418,1383124094887418,6414,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL"
+6414,1383124094887418,10000,0,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",1383124094988418,1383124119033418,1383124119033418,6414,"STEP_HANDLE_INPUT_EVENT_MAIN"
+6414,1383124119033418,8738000,0,"STEP_HANDLE_INPUT_EVENT_MAIN",1383124127771418,1383124119033418,1383124127596418,6414,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL"
+6414,1383124127596418,7000,0,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL",1383124127771418,1383124127712418,1383124127712418,6414,"STEP_HANDLED_INPUT_EVENT_IMPL"
+6414,1383124127712418,19000,0,"STEP_HANDLED_INPUT_EVENT_IMPL",1383124127731418,1383124207955418,1383124207955418,6414,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT"
+6414,1383124207955418,19000,0,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT",1383124207974418,1383124213046418,1383124213046418,6414,"STEP_SWAP_BUFFERS"
+6414,1383124213046418,22000,0,"STEP_SWAP_BUFFERS",1383124213068418,1383124221194418,1383124221194418,6414,"STEP_DRAW_AND_SWAP"
+6414,1383124221194418,20000,0,"STEP_DRAW_AND_SWAP",1383124221214418,1383124261843418,1383124261843418,6414,"STEP_FINISHED_SWAP_BUFFERS"
+6414,1383124261843418,37000,0,"STEP_FINISHED_SWAP_BUFFERS",1383124261880418,"[NULL]",1383125521558418,6552,"AsyncBegin"
+6552,1383125521558418,161901000,0,"AsyncBegin",1383125521558418,1383125525770418,1383125525814418,6552,"Begin"
+6552,1383125525814418,6000,0,"Begin",1383125526039418,1383125525770418,1383125525888418,6552,"STEP_SEND_INPUT_EVENT_UI"
+6552,1383125525888418,141000,0,"STEP_SEND_INPUT_EVENT_UI",1383125526039418,1383125529143418,1383125529178418,6552,"STEP_HANDLE_INPUT_EVENT_IMPL"
+6552,1383125529178418,162000,0,"STEP_HANDLE_INPUT_EVENT_IMPL",1383125529344418,1383125529143418,1383125529282418,6552,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL"
+6552,1383125529282418,5000,0,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",1383125529344418,1383125581612418,1383125581612418,6552,"STEP_HANDLE_INPUT_EVENT_MAIN"
+6552,1383125581612418,12061000,0,"STEP_HANDLE_INPUT_EVENT_MAIN",1383125593673418,1383125581612418,1383125593621418,6552,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL"
+6552,1383125593621418,7000,0,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL",1383125593673418,1383125593686418,1383125593686418,6552,"STEP_HANDLED_INPUT_EVENT_IMPL"
+6552,1383125593686418,11000,0,"STEP_HANDLED_INPUT_EVENT_IMPL",1383125593697418,1383125647723418,1383125647723418,6552,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT"
+6552,1383125647723418,23000,0,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT",1383125647746418,1383125654069418,1383125654069418,6552,"STEP_SWAP_BUFFERS"
+6552,1383125654069418,19000,0,"STEP_SWAP_BUFFERS",1383125654088418,1383125663282418,1383125663282418,6552,"STEP_DRAW_AND_SWAP"
+6552,1383125663282418,20000,0,"STEP_DRAW_AND_SWAP",1383125663302418,1383125683484418,1383125683484418,6552,"STEP_FINISHED_SWAP_BUFFERS"
+6552,1383125683484418,19000,0,"STEP_FINISHED_SWAP_BUFFERS",1383125683503418,"[NULL]",1383126581558418,6602,"AsyncBegin"
+6602,1383126581558418,87964000,0,"AsyncBegin",1383126581558418,1383126586079418,1383126586122418,6602,"Begin"
+6602,1383126586122418,6000,0,"Begin",1383126586328418,1383126586079418,1383126586193418,6602,"STEP_SEND_INPUT_EVENT_UI"
+6602,1383126586193418,126000,0,"STEP_SEND_INPUT_EVENT_UI",1383126586328418,1383126588328418,1383126588364418,6602,"STEP_HANDLE_INPUT_EVENT_IMPL"
+6602,1383126588364418,821000,0,"STEP_HANDLE_INPUT_EVENT_IMPL",1383126589192418,1383126588328418,1383126589084418,6602,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL"
+6602,1383126589084418,11000,0,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",1383126589192418,1383126595233418,1383126595233418,6602,"STEP_HANDLE_INPUT_EVENT_MAIN"
+6602,1383126595233418,8145000,0,"STEP_HANDLE_INPUT_EVENT_MAIN",1383126603378418,1383126595233418,1383126603302418,6602,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL"
+6602,1383126603302418,7000,0,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL",1383126603378418,1383126603940418,1383126603940418,6602,"STEP_HANDLED_INPUT_EVENT_IMPL"
+6602,1383126603940418,5000,0,"STEP_HANDLED_INPUT_EVENT_IMPL",1383126603945418,1383126630232418,1383126630232418,6602,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT"
+6602,1383126630232418,17000,0,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT",1383126630249418,1383126634508418,1383126634508418,6602,"STEP_SWAP_BUFFERS"
+6602,1383126634508418,9000,0,"STEP_SWAP_BUFFERS",1383126634517418,1383126642230418,1383126642230418,6602,"STEP_DRAW_AND_SWAP"
+6602,1383126642230418,20000,0,"STEP_DRAW_AND_SWAP",1383126642250418,1383126669549418,1383126669549418,6602,"STEP_FINISHED_SWAP_BUFFERS"
+6602,1383126669549418,14000,0,"STEP_FINISHED_SWAP_BUFFERS",1383126669563418,"[NULL]",1383127076558418,6693,"AsyncBegin"
+6693,1383127076558418,140115000,1,"AsyncBegin",1383127076558418,1383127082044418,1383127082090418,6693,"Begin"
+6693,1383127082090418,7000,1,"Begin",1383127082341418,1383127082044418,1383127082166418,6693,"STEP_SEND_INPUT_EVENT_UI"
+6693,1383127082166418,164000,1,"STEP_SEND_INPUT_EVENT_UI",1383127082341418,1383127082917418,1383127082960418,6693,"STEP_HANDLE_INPUT_EVENT_IMPL"
+6693,1383127082960418,348000,1,"STEP_HANDLE_INPUT_EVENT_IMPL",1383127083315418,1383127082917418,1383127083114418,6693,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL"
+6693,1383127083114418,9000,1,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",1383127083315418,1383127096393418,1383127096393418,6693,"STEP_HANDLE_INPUT_EVENT_MAIN"
+6693,1383127096393418,7736000,1,"STEP_HANDLE_INPUT_EVENT_MAIN",1383127104129418,1383127096393418,1383127104038418,6693,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL"
+6693,1383127104038418,7000,1,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL",1383127104129418,1383127104330418,1383127104330418,6693,"STEP_HANDLED_INPUT_EVENT_IMPL"
+6693,1383127104330418,12000,1,"STEP_HANDLED_INPUT_EVENT_IMPL",1383127104342418,1383127168839418,1383127168839418,6693,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT"
+6693,1383127168839418,36000,1,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT",1383127168875418,1383127175184418,1383127175184418,6693,"STEP_SWAP_BUFFERS"
+6693,1383127175184418,22000,1,"STEP_SWAP_BUFFERS",1383127175206418,1383127201828418,1383127201828418,6693,"STEP_DRAW_AND_SWAP"
+6693,1383127201828418,31000,1,"STEP_DRAW_AND_SWAP",1383127201859418,1383127216685418,1383127216685418,6693,"STEP_FINISHED_SWAP_BUFFERS"
+6693,1383127216685418,18000,1,"STEP_FINISHED_SWAP_BUFFERS",1383127216703418,"[NULL]",1383127670558418,6698,"AsyncBegin"
+6698,1383127670558418,301236000,1,"AsyncBegin",1383127670558418,1383127698512418,1383127698547418,6698,"Begin"
+6698,1383127698547418,6000,1,"Begin",1383127698732418,1383127698512418,1383127698610418,6698,"STEP_SEND_INPUT_EVENT_UI"
+6698,1383127698610418,113000,1,"STEP_SEND_INPUT_EVENT_UI",1383127698732418,1383127699155418,1383127699173418,6698,"STEP_HANDLE_INPUT_EVENT_IMPL"
+6698,1383127699173418,196000,1,"STEP_HANDLE_INPUT_EVENT_IMPL",1383127699373418,1383127699155418,1383127699323418,6698,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL"
+6698,1383127699323418,4000,1,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",1383127699373418,1383127844723418,1383127844723418,6698,"STEP_HANDLE_INPUT_EVENT_MAIN"
+6698,1383127844723418,14082000,1,"STEP_HANDLE_INPUT_EVENT_MAIN",1383127858805418,1383127844723418,1383127858076418,6698,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL"
+6698,1383127858076418,7000,1,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL",1383127858805418,1383127861637418,1383127861637418,6698,"STEP_HANDLED_INPUT_EVENT_IMPL"
+6698,1383127861637418,13000,1,"STEP_HANDLED_INPUT_EVENT_IMPL",1383127861650418,1383127928519418,1383127928519418,6698,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT"
+6698,1383127928519418,3000,1,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT",1383127928522418,1383127936811418,1383127936811418,6698,"STEP_SWAP_BUFFERS"
+6698,1383127936811418,8000,1,"STEP_SWAP_BUFFERS",1383127936819418,1383127949728418,1383127949728418,6698,"STEP_DRAW_AND_SWAP"
+6698,1383127949728418,7000,1,"STEP_DRAW_AND_SWAP",1383127949735418,1383127971881418,1383127971881418,6698,"STEP_FINISHED_SWAP_BUFFERS"
+6698,1383127971881418,7000,1,"STEP_FINISHED_SWAP_BUFFERS",1383127971888418,"[NULL]",1383127837558418,6723,"AsyncBegin"
+6723,1383127837558418,134236000,0,"AsyncBegin",1383127837558418,1383127846715418,1383127846793418,6723,"Begin"
+6723,1383127846793418,11000,0,"Begin",1383127847217418,1383127846715418,1383127846940418,6723,"STEP_SEND_INPUT_EVENT_UI"
+6723,1383127846940418,255000,0,"STEP_SEND_INPUT_EVENT_UI",1383127847217418,1383127848602418,1383127848665418,6723,"STEP_HANDLE_INPUT_EVENT_IMPL"
+6723,1383127848665418,1045000,0,"STEP_HANDLE_INPUT_EVENT_IMPL",1383127849717418,1383127848602418,1383127849609418,6723,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL"
+6723,1383127849609418,12000,0,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",1383127849717418,1383127874642418,1383127874642418,6723,"STEP_HANDLE_INPUT_EVENT_MAIN"
+6723,1383127874642418,8527000,0,"STEP_HANDLE_INPUT_EVENT_MAIN",1383127883169418,1383127874642418,1383127883061418,6723,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL"
+6723,1383127883061418,8000,0,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL",1383127883169418,1383127885270418,1383127885270418,6723,"STEP_HANDLED_INPUT_EVENT_IMPL"
+6723,1383127885270418,14000,0,"STEP_HANDLED_INPUT_EVENT_IMPL",1383127885284418,1383127928530418,1383127928530418,6723,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT"
+6723,1383127928530418,3000,0,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT",1383127928533418,1383127936838418,1383127936838418,6723,"STEP_SWAP_BUFFERS"
+6723,1383127936838418,8000,0,"STEP_SWAP_BUFFERS",1383127936846418,1383127949753418,1383127949753418,6723,"STEP_DRAW_AND_SWAP"
+6723,1383127949753418,7000,0,"STEP_DRAW_AND_SWAP",1383127949760418,1383127971906418,1383127971906418,6723,"STEP_FINISHED_SWAP_BUFFERS"
+6723,1383127971906418,7000,0,"STEP_FINISHED_SWAP_BUFFERS",1383127971913418,"[NULL]",1383129053558418,6802,"AsyncBegin"
+6802,1383129053558418,163272000,0,"AsyncBegin",1383129053558418,1383129081907418,1383129081950418,6802,"Begin"
+6802,1383129081950418,46000,0,"Begin",1383129082214418,1383129081907418,1383129082066418,6802,"STEP_SEND_INPUT_EVENT_UI"
+6802,1383129082066418,138000,0,"STEP_SEND_INPUT_EVENT_UI",1383129082214418,1383129082616418,1383129082657418,6802,"STEP_HANDLE_INPUT_EVENT_IMPL"
+6802,1383129082657418,782000,0,"STEP_HANDLE_INPUT_EVENT_IMPL",1383129083446418,1383129082616418,1383129083335418,6802,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL"
+6802,1383129083335418,10000,0,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",1383129083446418,1383129105125418,1383129105125418,6802,"STEP_HANDLE_INPUT_EVENT_MAIN"
+6802,1383129105125418,6978000,0,"STEP_HANDLE_INPUT_EVENT_MAIN",1383129112103418,1383129105125418,1383129111999418,6802,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL"
+6802,1383129111999418,8000,0,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL",1383129112103418,1383129113877418,1383129113877418,6802,"STEP_HANDLED_INPUT_EVENT_IMPL"
+6802,1383129113877418,12000,0,"STEP_HANDLED_INPUT_EVENT_IMPL",1383129113889418,1383129155519418,1383129155519418,6802,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT"
+6802,1383129155519418,18000,0,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT",1383129155537418,1383129177753418,1383129177753418,6802,"STEP_SWAP_BUFFERS"
+6802,1383129177753418,30000,0,"STEP_SWAP_BUFFERS",1383129177783418,1383129181587418,1383129181587418,6802,"STEP_DRAW_AND_SWAP"
+6802,1383129181587418,21000,0,"STEP_DRAW_AND_SWAP",1383129181608418,1383129216866418,1383129216866418,6802,"STEP_FINISHED_SWAP_BUFFERS"
+6802,1383129216866418,29000,0,"STEP_FINISHED_SWAP_BUFFERS",1383129216895418,"[NULL]",1383129492558418,6877,"AsyncBegin"
+6877,1383129492558418,370407000,1,"AsyncBegin",1383129492558418,1383129497787418,1383129497859418,6877,"Begin"
+6877,1383129497859418,11000,1,"Begin",1383129498184418,1383129497787418,1383129497995418,6877,"STEP_SEND_INPUT_EVENT_UI"
+6877,1383129497995418,168000,1,"STEP_SEND_INPUT_EVENT_UI",1383129498184418,1383129498483418,1383129498503418,6877,"STEP_HANDLE_INPUT_EVENT_IMPL"
+6877,1383129498503418,329000,1,"STEP_HANDLE_INPUT_EVENT_IMPL",1383129498836418,1383129498483418,1383129498775418,6877,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL"
+6877,1383129498775418,5000,1,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",1383129498836418,1383129719266418,1383129719266418,6877,"STEP_HANDLE_INPUT_EVENT_MAIN"
+6877,1383129719266418,24639000,1,"STEP_HANDLE_INPUT_EVENT_MAIN",1383129743905418,1383129719266418,1383129742223418,6877,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL"
+6877,1383129742223418,13000,1,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL",1383129743905418,1383129743178418,1383129743178418,6877,"STEP_HANDLED_INPUT_EVENT_IMPL"
+6877,1383129743178418,12000,1,"STEP_HANDLED_INPUT_EVENT_IMPL",1383129743190418,1383129816012418,1383129816012418,6877,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT"
+6877,1383129816012418,18000,1,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT",1383129816030418,1383129823726418,1383129823726418,6877,"STEP_SWAP_BUFFERS"
+6877,1383129823726418,46000,1,"STEP_SWAP_BUFFERS",1383129823772418,1383129835535418,1383129835535418,6877,"STEP_DRAW_AND_SWAP"
+6877,1383129835535418,18000,1,"STEP_DRAW_AND_SWAP",1383129835553418,1383129863003418,1383129863003418,6877,"STEP_FINISHED_SWAP_BUFFERS"
+6877,1383129863003418,30000,1,"STEP_FINISHED_SWAP_BUFFERS",1383129863033418,"[NULL]",1383130519558418,6911,"AsyncBegin"
+6911,1383130519558418,198057000,1,"AsyncBegin",1383130519558418,1383130544003418,1383130544042418,6911,"Begin"
+6911,1383130544042418,7000,1,"Begin",1383130544237418,1383130544003418,1383130544113418,6911,"STEP_SEND_INPUT_EVENT_UI"
+6911,1383130544113418,115000,1,"STEP_SEND_INPUT_EVENT_UI",1383130544237418,1383130546898418,1383130546932418,6911,"STEP_HANDLE_INPUT_EVENT_IMPL"
+6911,1383130546932418,833000,1,"STEP_HANDLE_INPUT_EVENT_IMPL",1383130547772418,1383130546898418,1383130547581418,6911,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL"
+6911,1383130547581418,10000,1,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",1383130547772418,1383130555182418,1383130555182418,6911,"STEP_HANDLE_INPUT_EVENT_MAIN"
+6911,1383130555182418,18263000,1,"STEP_HANDLE_INPUT_EVENT_MAIN",1383130573445418,1383130555182418,1383130573221418,6911,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL"
+6911,1383130573221418,12000,1,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL",1383130573445418,1383130573311418,1383130573311418,6911,"STEP_HANDLED_INPUT_EVENT_IMPL"
+6911,1383130573311418,10000,1,"STEP_HANDLED_INPUT_EVENT_IMPL",1383130573321418,1383130656314418,1383130656314418,6911,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT"
+6911,1383130656314418,11000,1,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT",1383130656325418,1383130667367418,1383130667367418,6911,"STEP_SWAP_BUFFERS"
+6911,1383130667367418,17000,1,"STEP_SWAP_BUFFERS",1383130667384418,1383130681350418,1383130681350418,6911,"STEP_DRAW_AND_SWAP"
+6911,1383130681350418,25000,1,"STEP_DRAW_AND_SWAP",1383130681375418,1383130717639418,1383130717639418,6911,"STEP_FINISHED_SWAP_BUFFERS"
+6911,1383130717639418,18000,1,"STEP_FINISHED_SWAP_BUFFERS",1383130717657418,"[NULL]",1383130553558418,6915,"AsyncBegin"
+6915,1383130553558418,164057000,0,"AsyncBegin",1383130553558418,1383130558151418,1383130558197418,6915,"Begin"
+6915,1383130558197418,6000,0,"Begin",1383130558425418,1383130558151418,1383130558273418,6915,"STEP_SEND_INPUT_EVENT_UI"
+6915,1383130558273418,141000,0,"STEP_SEND_INPUT_EVENT_UI",1383130558425418,1383130558645418,1383130558675418,6915,"STEP_HANDLE_INPUT_EVENT_IMPL"
+6915,1383130558675418,155000,0,"STEP_HANDLE_INPUT_EVENT_IMPL",1383130558834418,1383130558645418,1383130558779418,6915,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL"
+6915,1383130558779418,4000,0,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",1383130558834418,1383130587655418,1383130587655418,6915,"STEP_HANDLE_INPUT_EVENT_MAIN"
+6915,1383130587655418,7138000,0,"STEP_HANDLE_INPUT_EVENT_MAIN",1383130594793418,1383130587655418,1383130594603418,6915,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL"
+6915,1383130594603418,6000,0,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL",1383130594793418,1383130594791418,1383130594791418,6915,"STEP_HANDLED_INPUT_EVENT_IMPL"
+6915,1383130594791418,20000,0,"STEP_HANDLED_INPUT_EVENT_IMPL",1383130594811418,1383130656335418,1383130656335418,6915,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT"
+6915,1383130656335418,4000,0,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT",1383130656339418,1383130667392418,1383130667392418,6915,"STEP_SWAP_BUFFERS"
+6915,1383130667392418,3000,0,"STEP_SWAP_BUFFERS",1383130667395418,1383130681397418,1383130681397418,6915,"STEP_DRAW_AND_SWAP"
+6915,1383130681397418,7000,0,"STEP_DRAW_AND_SWAP",1383130681404418,1383130717665418,1383130717665418,6915,"STEP_FINISHED_SWAP_BUFFERS"
+6915,1383130717665418,3000,0,"STEP_FINISHED_SWAP_BUFFERS",1383130717668418,"[NULL]",1383130681558418,6940,"AsyncBegin"
+6940,1383130681558418,167758000,0,"AsyncBegin",1383130681558418,1383130686495418,1383130686567418,6940,"Begin"
+6940,1383130686567418,13000,0,"Begin",1383130686909418,1383130686495418,1383130686705418,6940,"STEP_SEND_INPUT_EVENT_UI"
+6940,1383130686705418,184000,0,"STEP_SEND_INPUT_EVENT_UI",1383130686909418,1383130687055418,1383130687081418,6940,"STEP_HANDLE_INPUT_EVENT_IMPL"
+6940,1383130687081418,334000,0,"STEP_HANDLE_INPUT_EVENT_IMPL",1383130687419418,1383130687055418,1383130687360418,6940,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL"
+6940,1383130687360418,5000,0,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",1383130687419418,1383130719656418,1383130719656418,6940,"STEP_HANDLE_INPUT_EVENT_MAIN"
+6940,1383130719656418,8298000,0,"STEP_HANDLE_INPUT_EVENT_MAIN",1383130727954418,1383130719656418,1383130727856418,6940,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL"
+6940,1383130727856418,7000,0,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL",1383130727954418,1383130728343418,1383130728343418,6940,"STEP_HANDLED_INPUT_EVENT_IMPL"
+6940,1383130728343418,13000,0,"STEP_HANDLED_INPUT_EVENT_IMPL",1383130728356418,1383130815135418,1383130815135418,6940,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT"
+6940,1383130815135418,19000,0,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT",1383130815154418,1383130825051418,1383130825051418,6940,"STEP_SWAP_BUFFERS"
+6940,1383130825051418,35000,0,"STEP_SWAP_BUFFERS",1383130825086418,1383130834387418,1383130834387418,6940,"STEP_DRAW_AND_SWAP"
+6940,1383130834387418,18000,0,"STEP_DRAW_AND_SWAP",1383130834405418,1383130849338418,1383130849338418,6940,"STEP_FINISHED_SWAP_BUFFERS"
+6940,1383130849338418,17000,0,"STEP_FINISHED_SWAP_BUFFERS",1383130849355418,"[NULL]","[NULL]","[NULL]","[NULL]"
diff --git a/test/trace_processor/chrome/touch_flow_event.sql b/test/trace_processor/chrome/touch_flow_event.sql
new file mode 100644
index 000000000..dbb5c8958
--- /dev/null
+++ b/test/trace_processor/chrome/touch_flow_event.sql
@@ -0,0 +1,29 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+SELECT RUN_METRIC('chrome/touch_flow_event.sql') AS suppress_query_output;
+
+SELECT
+ trace_id,
+ ts,
+ dur,
+ jank,
+ step,
+ ancestor_end,
+ maybe_next_ancestor_ts,
+ next_ts,
+ next_trace_id,
+ next_step
+FROM touch_flow_event
+ORDER BY touch_id, trace_id, ts;
diff --git a/test/trace_processor/chrome/touch_flow_event_queuing_delay.out b/test/trace_processor/chrome/touch_flow_event_queuing_delay.out
new file mode 100644
index 000000000..aa26ef677
--- /dev/null
+++ b/test/trace_processor/chrome/touch_flow_event_queuing_delay.out
@@ -0,0 +1,38 @@
+
+"trace_id","jank","step","next_step","ancestor_end","maybe_next_ancestor_ts","queuing_time_ns"
+6911,1,"AsyncBegin","Begin",1383130519558418,1383130544003418,24445000
+6911,1,"Begin","STEP_SEND_INPUT_EVENT_UI",1383130544237418,1383130544003418,0
+6911,1,"STEP_SEND_INPUT_EVENT_UI","STEP_HANDLE_INPUT_EVENT_IMPL",1383130544237418,1383130546898418,2661000
+6911,1,"STEP_HANDLE_INPUT_EVENT_IMPL","STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",1383130547772418,1383130546898418,0
+6911,1,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL","STEP_HANDLE_INPUT_EVENT_MAIN",1383130547772418,1383130555182418,7410000
+6911,1,"STEP_HANDLE_INPUT_EVENT_MAIN","STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL",1383130573445418,1383130555182418,0
+6911,1,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL","STEP_HANDLED_INPUT_EVENT_IMPL",1383130573445418,1383130573311418,0
+6911,1,"STEP_HANDLED_INPUT_EVENT_IMPL","STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT",1383130573321418,1383130656314418,82993000
+6911,1,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT","STEP_SWAP_BUFFERS",1383130656325418,1383130667367418,11042000
+6911,1,"STEP_SWAP_BUFFERS","STEP_DRAW_AND_SWAP",1383130667384418,1383130681350418,13966000
+6911,1,"STEP_DRAW_AND_SWAP","STEP_FINISHED_SWAP_BUFFERS",1383130681375418,1383130717639418,36264000
+6911,1,"STEP_FINISHED_SWAP_BUFFERS","AsyncBegin",1383130717657418,"[NULL]","[NULL]"
+6915,0,"AsyncBegin","Begin",1383130553558418,1383130558151418,4593000
+6915,0,"Begin","STEP_SEND_INPUT_EVENT_UI",1383130558425418,1383130558151418,0
+6915,0,"STEP_SEND_INPUT_EVENT_UI","STEP_HANDLE_INPUT_EVENT_IMPL",1383130558425418,1383130558645418,220000
+6915,0,"STEP_HANDLE_INPUT_EVENT_IMPL","STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",1383130558834418,1383130558645418,0
+6915,0,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL","STEP_HANDLE_INPUT_EVENT_MAIN",1383130558834418,1383130587655418,28821000
+6915,0,"STEP_HANDLE_INPUT_EVENT_MAIN","STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL",1383130594793418,1383130587655418,0
+6915,0,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL","STEP_HANDLED_INPUT_EVENT_IMPL",1383130594793418,1383130594791418,0
+6915,0,"STEP_HANDLED_INPUT_EVENT_IMPL","STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT",1383130594811418,1383130656335418,61524000
+6915,0,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT","STEP_SWAP_BUFFERS",1383130656339418,1383130667392418,11053000
+6915,0,"STEP_SWAP_BUFFERS","STEP_DRAW_AND_SWAP",1383130667395418,1383130681397418,14002000
+6915,0,"STEP_DRAW_AND_SWAP","STEP_FINISHED_SWAP_BUFFERS",1383130681404418,1383130717665418,36261000
+6915,0,"STEP_FINISHED_SWAP_BUFFERS","AsyncBegin",1383130717668418,"[NULL]","[NULL]"
+6940,0,"AsyncBegin","Begin",1383130681558418,1383130686495418,4937000
+6940,0,"Begin","STEP_SEND_INPUT_EVENT_UI",1383130686909418,1383130686495418,0
+6940,0,"STEP_SEND_INPUT_EVENT_UI","STEP_HANDLE_INPUT_EVENT_IMPL",1383130686909418,1383130687055418,146000
+6940,0,"STEP_HANDLE_INPUT_EVENT_IMPL","STEP_DID_HANDLE_INPUT_AND_OVERSCROLL",1383130687419418,1383130687055418,0
+6940,0,"STEP_DID_HANDLE_INPUT_AND_OVERSCROLL","STEP_HANDLE_INPUT_EVENT_MAIN",1383130687419418,1383130719656418,32237000
+6940,0,"STEP_HANDLE_INPUT_EVENT_MAIN","STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL",1383130727954418,1383130719656418,0
+6940,0,"STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL","STEP_HANDLED_INPUT_EVENT_IMPL",1383130727954418,1383130728343418,389000
+6940,0,"STEP_HANDLED_INPUT_EVENT_IMPL","STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT",1383130728356418,1383130815135418,86779000
+6940,0,"STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT","STEP_SWAP_BUFFERS",1383130815154418,1383130825051418,9897000
+6940,0,"STEP_SWAP_BUFFERS","STEP_DRAW_AND_SWAP",1383130825086418,1383130834387418,9301000
+6940,0,"STEP_DRAW_AND_SWAP","STEP_FINISHED_SWAP_BUFFERS",1383130834405418,1383130849338418,14933000
+6940,0,"STEP_FINISHED_SWAP_BUFFERS","[NULL]",1383130849355418,"[NULL]","[NULL]"
diff --git a/test/trace_processor/chrome/touch_flow_event_queuing_delay.sql b/test/trace_processor/chrome/touch_flow_event_queuing_delay.sql
new file mode 100644
index 000000000..023090826
--- /dev/null
+++ b/test/trace_processor/chrome/touch_flow_event_queuing_delay.sql
@@ -0,0 +1,30 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the 'License');
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an 'AS IS' BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+SELECT RUN_METRIC('chrome/touch_flow_event_queuing_delay.sql')
+ AS suppress_query_output;
+
+-- trace 6911 is janky and 6915 and 6940 succeed it (both are not janky).
+SELECT
+ trace_id,
+ jank,
+ step,
+ next_step,
+ ancestor_end,
+ maybe_next_ancestor_ts,
+ queuing_time_ns
+FROM touch_flow_event_queuing_delay
+WHERE trace_id = 6915 OR trace_id = 6911 OR trace_id = 6940
+ORDER BY trace_id, ts;
diff --git a/test/trace_processor/chrome/touch_flow_event_queuing_delay_full.sql b/test/trace_processor/chrome/touch_flow_event_queuing_delay_full.sql
new file mode 100644
index 000000000..f1e9c33fc
--- /dev/null
+++ b/test/trace_processor/chrome/touch_flow_event_queuing_delay_full.sql
@@ -0,0 +1,29 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the 'License');
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an 'AS IS' BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+SELECT RUN_METRIC('chrome/touch_flow_event_queuing_delay.sql')
+ AS suppress_query_output;
+
+-- trace 6911 is janky and 6915 and 6940 succeed it (both are not janky).
+SELECT
+ trace_id,
+ jank,
+ step,
+ next_step,
+ ancestor_end,
+ maybe_next_ancestor_ts,
+ queuing_time_ns
+FROM touch_flow_event_queuing_delay
+ORDER BY trace_id, ts;
diff --git a/test/trace_processor/chrome/touch_flow_event_queuing_delay_synth.out b/test/trace_processor/chrome/touch_flow_event_queuing_delay_synth.out
new file mode 100644
index 000000000..7c5c8b01c
--- /dev/null
+++ b/test/trace_processor/chrome/touch_flow_event_queuing_delay_synth.out
@@ -0,0 +1,12 @@
+
+"trace_id","jank","step","next_step","ancestor_end","maybe_next_ancestor_ts","queuing_time_ns"
+34577,0,"AsyncBegin","Begin",0,0,0
+34577,0,"Begin","End",1000000,11000000,10000000
+34577,0,"End","AsyncBegin",12000000,"[NULL]","[NULL]"
+34578,1,"AsyncBegin","Begin",16000000,16000000,0
+34578,1,"Begin","End",17000000,50000000,33000000
+34578,1,"End","AsyncBegin",51000000,"[NULL]","[NULL]"
+34579,0,"AsyncBegin","Begin",55000000,55000000,0
+34579,0,"Begin","STEP_SEND_INPUT_EVENT_UI",56000000,87000000,31000000
+34579,0,"STEP_SEND_INPUT_EVENT_UI","End",88000000,89000000,1000000
+34579,0,"End","[NULL]",90000000,"[NULL]","[NULL]"
diff --git a/test/trace_processor/chrome/touch_flow_event_synth.out b/test/trace_processor/chrome/touch_flow_event_synth.out
new file mode 100644
index 000000000..570f3c0a5
--- /dev/null
+++ b/test/trace_processor/chrome/touch_flow_event_synth.out
@@ -0,0 +1,12 @@
+
+"trace_id","ts","dur","jank","step","ancestor_end","maybe_next_ancestor_ts","next_ts","next_trace_id","next_step"
+34577,0,10000000,0,"AsyncBegin",0,0,0,34577,"Begin"
+34577,0,1000000,0,"Begin",1000000,11000000,11000000,34577,"End"
+34577,11000000,1000000,0,"End",12000000,"[NULL]",16000000,34578,"AsyncBegin"
+34578,16000000,33000000,1,"AsyncBegin",16000000,16000000,16000000,34578,"Begin"
+34578,16000000,1000000,1,"Begin",17000000,50000000,50000000,34578,"End"
+34578,50000000,1000000,1,"End",51000000,"[NULL]",55000000,34579,"AsyncBegin"
+34579,55000000,33000000,0,"AsyncBegin",55000000,55000000,55000000,34579,"Begin"
+34579,55000000,1000000,0,"Begin",56000000,87000000,87000000,34579,"STEP_SEND_INPUT_EVENT_UI"
+34579,87000000,1000000,0,"STEP_SEND_INPUT_EVENT_UI",88000000,89000000,89000000,34579,"End"
+34579,89000000,1000000,0,"End",90000000,"[NULL]","[NULL]","[NULL]","[NULL]"
diff --git a/test/trace_processor/chrome/touch_jank.out b/test/trace_processor/chrome/touch_jank.out
new file mode 100644
index 000000000..18edb3f45
--- /dev/null
+++ b/test/trace_processor/chrome/touch_jank.out
@@ -0,0 +1,16 @@
+
+"touch_id","trace_id","jank","ts","dur","jank_budget"
+6280,6288,1,1383122421558418,226350000,32772666.650000
+6280,6312,0,1383122543558418,185244000,-31034333.350000
+6318,6328,1,1383123604558418,207945000,26378666.650000
+6318,6414,0,1383124088558418,173233000,2998666.650000
+6420,6552,0,1383125521558418,161901000,65603666.650000
+6586,6602,0,1383126581558418,87964000,-60484333.350000
+6586,6693,1,1383127076558418,140115000,43817666.650000
+6697,6698,1,1383127670558418,301236000,158666666.650000
+6697,6723,0,1383127837558418,134236000,-37369333.350000
+6788,6802,0,1383129053558418,163272000,20702666.650000
+6788,6877,1,1383129492558418,370407000,198801666.650000
+6906,6911,1,1383130519558418,198057000,25666666.650000
+6906,6915,0,1383130553558418,164057000,-12034333.350000
+6906,6940,0,1383130681558418,167758000,-4632333.350000
diff --git a/test/trace_processor/chrome/touch_jank.py b/test/trace_processor/chrome/touch_jank.py
new file mode 100644
index 000000000..0dd0e8dd5
--- /dev/null
+++ b/test/trace_processor/chrome/touch_jank.py
@@ -0,0 +1,186 @@
+#!/usr/bin/env python3
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is intended to test the handling of simple_watcher style mojo events,
+# which are often missing trace events below them and so are all aggregated
+# together despite them coming into different mojo interfaces.
+
+from os import sys
+
+import synth_common
+
+from synth_common import ms_to_ns
+trace = synth_common.create_trace()
+
+process_track1 = 1234
+
+trace.add_process_track_descriptor(process_track1, pid=0)
+
+process_pid1 = 2345
+
+thread_track1 = 1235
+
+# Main threads have the same ID as the process
+thread_tid1 = process_pid1
+
+seq1 = 9876
+
+thread1_counter = 60
+
+touch_move_trace_id = 34576
+trace_id1 = touch_move_trace_id + 1
+trace_id2 = trace_id1 + 1
+trace_id3 = trace_id2 + 1
+touch_end_trace_id = trace_id3 + 1
+
+touch_gesture_id = 87654
+
+flow_id1 = 45678
+flow_id2 = 45679
+flow_id3 = 45680
+
+trace.add_input_latency_event_slice(
+ "TouchStart",
+ ts=ms_to_ns(0),
+ dur=ms_to_ns(1),
+ track=touch_move_trace_id,
+ trace_id=touch_move_trace_id,
+ touch_id=touch_gesture_id)
+
+trace.add_chrome_process_track_descriptor(process_track1, process_pid1)
+
+trace.add_chrome_thread_with_cpu_counter(
+ process_track1,
+ thread_track1,
+ trusted_packet_sequence_id=seq1,
+ counter_track=thread1_counter,
+ pid=process_pid1,
+ tid=thread_tid1,
+ thread_type=trace.prototypes.ThreadDescriptor.ChromeThreadType
+ .CHROME_THREAD_MAIN)
+
+# Touch move 1 - not janky
+trace.add_input_latency_event_slice(
+ "TouchMove",
+ ts=ms_to_ns(0),
+ dur=ms_to_ns(10),
+ track=trace_id1,
+ trace_id=trace_id1,
+ touch_id=touch_gesture_id,
+ is_coalesced=0)
+
+trace.add_latency_info_flow(
+ ts=ms_to_ns(0),
+ dur=ms_to_ns(1),
+ trusted_sequence_id=seq1,
+ trace_id=trace_id1,
+ flow_ids=[flow_id1])
+
+# The slices below will block this "not janky" touch move 1.
+trace.add_track_event_slice(
+ "task", ts=ms_to_ns(2), dur=ms_to_ns(6), trusted_sequence_id=seq1)
+
+trace.add_track_event_slice(
+ "subtask", ts=ms_to_ns(3), dur=ms_to_ns(4), trusted_sequence_id=seq1)
+# This ends the blocking slices of "not janky" touch move 1.
+
+trace.add_latency_info_flow(
+ ts=ms_to_ns(11),
+ dur=ms_to_ns(1),
+ trusted_sequence_id=seq1,
+ trace_id=trace_id1,
+ terminating_flow_ids=[flow_id1])
+
+# Touch move 2 - janky
+trace.add_input_latency_event_slice(
+ "TouchMove",
+ ts=ms_to_ns(16),
+ dur=ms_to_ns(33),
+ track=trace_id2,
+ trace_id=trace_id2,
+ touch_id=touch_gesture_id,
+ is_coalesced=0)
+
+trace.add_latency_info_flow(
+ ts=ms_to_ns(16),
+ dur=ms_to_ns(1),
+ trusted_sequence_id=seq1,
+ trace_id=trace_id2,
+ flow_ids=[flow_id2])
+
+# The slices below will block this "janky" touch move 2.
+trace.add_track_event_slice(
+ "task", ts=ms_to_ns(18), dur=ms_to_ns(29), trusted_sequence_id=seq1)
+
+trace.add_track_event_slice(
+ "subtask", ts=ms_to_ns(19), dur=ms_to_ns(27), trusted_sequence_id=seq1)
+# This ends the blocking slices of "janky" touch move 2.
+
+trace.add_latency_info_flow(
+ ts=ms_to_ns(50),
+ dur=ms_to_ns(1),
+ trusted_sequence_id=seq1,
+ trace_id=trace_id2,
+ terminating_flow_ids=[flow_id2])
+
+# Touch move 3 - janky
+trace.add_input_latency_event_slice(
+ "TouchMove",
+ ts=ms_to_ns(55),
+ dur=ms_to_ns(33),
+ track=trace_id3,
+ trace_id=trace_id3,
+ touch_id=touch_gesture_id,
+ is_coalesced=0)
+
+trace.add_latency_info_flow(
+ ts=ms_to_ns(55),
+ dur=ms_to_ns(1),
+ trusted_sequence_id=seq1,
+ trace_id=trace_id3,
+ flow_ids=[flow_id3])
+
+# The slices below will block this "janky" touch move 3.
+trace.add_track_event_slice(
+ "task", ts=ms_to_ns(57), dur=ms_to_ns(29), trusted_sequence_id=seq1)
+
+packet = trace.add_track_event_slice(
+ "subtask", ts=ms_to_ns(58), dur=ms_to_ns(27), trusted_sequence_id=seq1)
+# This ends the blocking slices of "janky" touch move 3.
+
+trace.add_latency_info_flow(
+ ts=ms_to_ns(87),
+ dur=ms_to_ns(1),
+ trusted_sequence_id=seq1,
+ trace_id=trace_id3,
+ step=trace.prototypes.ChromeLatencyInfo.Step.STEP_SEND_INPUT_EVENT_UI,
+ terminating_flow_ids=[flow_id3])
+
+trace.add_latency_info_flow(
+ ts=ms_to_ns(89),
+ dur=ms_to_ns(1),
+ trusted_sequence_id=seq1,
+ trace_id=trace_id3,
+ terminating_flow_ids=[flow_id3])
+
+trace.add_input_latency_event_slice(
+ "TouchEnd",
+ ts=ms_to_ns(90),
+ dur=ms_to_ns(2),
+ track=touch_end_trace_id,
+ trace_id=touch_end_trace_id,
+ touch_id=touch_gesture_id)
+
+sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/chrome/touch_jank.sql b/test/trace_processor/chrome/touch_jank.sql
new file mode 100644
index 000000000..d601148a9
--- /dev/null
+++ b/test/trace_processor/chrome/touch_jank.sql
@@ -0,0 +1,25 @@
+--
+-- Copyright 2020 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+SELECT RUN_METRIC('chrome/touch_jank.sql') AS suppress_query_output;
+
+SELECT
+ touch_id,
+ trace_id,
+ jank,
+ ts,
+ dur,
+ jank_budget
+FROM touch_jank;
diff --git a/test/trace_processor/chrome/touch_jank_synth.out b/test/trace_processor/chrome/touch_jank_synth.out
new file mode 100644
index 000000000..44758af38
--- /dev/null
+++ b/test/trace_processor/chrome/touch_jank_synth.out
@@ -0,0 +1,5 @@
+
+"touch_id","trace_id","jank","ts","dur","jank_budget"
+87654,34577,0,0,10000000,-31333333.350000
+87654,34578,1,16000000,33000000,14666666.650000
+87654,34579,0,55000000,33000000,-8333333.350000
diff --git a/test/trace_processor/common/list_slices.sql b/test/trace_processor/common/list_slices.sql
new file mode 100644
index 000000000..55b0d7256
--- /dev/null
+++ b/test/trace_processor/common/list_slices.sql
@@ -0,0 +1,2 @@
+SELECT ts, dur, name
+FROM slice
diff --git a/test/trace_processor/parsing/process_track_slices.sql b/test/trace_processor/common/process_track_slices.sql
index 1b9151dca..1b9151dca 100644
--- a/test/trace_processor/parsing/process_track_slices.sql
+++ b/test/trace_processor/common/process_track_slices.sql
diff --git a/test/trace_processor/cros/cros_ec_sensorhub_data.out b/test/trace_processor/cros/cros_ec_sensorhub_data.out
new file mode 100644
index 000000000..708ce4b25
--- /dev/null
+++ b/test/trace_processor/cros/cros_ec_sensorhub_data.out
@@ -0,0 +1,2 @@
+"name","ts","value","ec_num","ec_delta","sample_ts"
+"cros_ec.cros_ec_sensorhub_data.0",223951135789653,83399770.000000,0,80599926,223951052378946
diff --git a/test/trace_processor/cros/cros_ec_sensorhub_data.sql b/test/trace_processor/cros/cros_ec_sensorhub_data.sql
new file mode 100644
index 000000000..805f19474
--- /dev/null
+++ b/test/trace_processor/cros/cros_ec_sensorhub_data.sql
@@ -0,0 +1,11 @@
+SELECT
+ t.name,
+ c.ts,
+ c.value,
+ EXTRACT_ARG(c.arg_set_id, 'ec_num') AS ec_num,
+ EXTRACT_ARG(c.arg_set_id, 'ec_delta') AS ec_delta,
+ EXTRACT_ARG(c.arg_set_id, 'sample_ts') AS sample_ts
+FROM counter c
+JOIN track t
+ ON c.track_id = t.id
+WHERE t.name == 'cros_ec.cros_ec_sensorhub_data.0';
diff --git a/test/trace_processor/cros/cros_ec_sensorhub_data.textproto b/test/trace_processor/cros/cros_ec_sensorhub_data.textproto
new file mode 100644
index 000000000..dedcdc503
--- /dev/null
+++ b/test/trace_processor/cros/cros_ec_sensorhub_data.textproto
@@ -0,0 +1,18 @@
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 223951135789653
+ pid: 181
+ cros_ec_sensorhub_data {
+ current_time: 223951135778716
+ current_timestamp: 223951052378946
+ delta: -83399770
+ ec_fifo_timestamp: 2128620968
+ ec_sensor_num: 0
+ fifo_timestamp: 223951132978872
+ }
+ }
+ }
+}
+
diff --git a/test/trace_processor/cros/index b/test/trace_processor/cros/index
new file mode 100644
index 000000000..058e2e618
--- /dev/null
+++ b/test/trace_processor/cros/index
@@ -0,0 +1,5 @@
+# Tests related to cros's use of Perfetto.
+
+# cros_ec_sensorhub_data
+cros_ec_sensorhub_data.textproto cros_ec_sensorhub_data.sql cros_ec_sensorhub_data.out
+
diff --git a/test/trace_processor/dynamic/ancestor_slice_by_stack.out b/test/trace_processor/dynamic/ancestor_slice_by_stack.out
new file mode 100644
index 000000000..13881bc82
--- /dev/null
+++ b/test/trace_processor/dynamic/ancestor_slice_by_stack.out
@@ -0,0 +1,5 @@
+"ts","name"
+1000,"event_depth_0"
+2000,"event_depth_1"
+8000,"event_depth_0"
+9000,"event_depth_1"
diff --git a/test/trace_processor/dynamic/ancestor_slice_by_stack.sql b/test/trace_processor/dynamic/ancestor_slice_by_stack.sql
new file mode 100644
index 000000000..3b5089e9d
--- /dev/null
+++ b/test/trace_processor/dynamic/ancestor_slice_by_stack.sql
@@ -0,0 +1,5 @@
+SELECT ts, name FROM ancestor_slice_by_stack((
+ SELECT stack_id FROM slice
+ WHERE name = 'event_depth_2'
+ LIMIT 1
+));
diff --git a/test/trace_processor/dynamic/descendant_slice_by_stack.out b/test/trace_processor/dynamic/descendant_slice_by_stack.out
new file mode 100644
index 000000000..c32f639fc
--- /dev/null
+++ b/test/trace_processor/dynamic/descendant_slice_by_stack.out
@@ -0,0 +1,5 @@
+"ts","name"
+2000,"event_depth_1"
+3000,"event_depth_2"
+9000,"event_depth_1"
+10000,"event_depth_2"
diff --git a/test/trace_processor/dynamic/descendant_slice_by_stack.sql b/test/trace_processor/dynamic/descendant_slice_by_stack.sql
new file mode 100644
index 000000000..ac42bda20
--- /dev/null
+++ b/test/trace_processor/dynamic/descendant_slice_by_stack.sql
@@ -0,0 +1,6 @@
+SELECT ts, name FROM descendant_slice_by_stack((
+ SELECT stack_id FROM slice
+ WHERE name = 'event_depth_0'
+ LIMIT 1
+));
+
diff --git a/test/trace_processor/dynamic/index b/test/trace_processor/dynamic/index
index 3c5953b88..6fe5cf139 100644
--- a/test/trace_processor/dynamic/index
+++ b/test/trace_processor/dynamic/index
@@ -6,6 +6,12 @@ relationship_tables.textproto ancestor_slice.sql ancestor_slice.out
# Descendant slice table.
relationship_tables.textproto descendant_slice.sql descendant_slice.out
+# Ancestor slice by stack table.
+slice_stacks.textproto ancestor_slice_by_stack.sql ancestor_slice_by_stack.out
+
+# Descendant slice by stack table.
+slice_stacks.textproto descendant_slice_by_stack.sql descendant_slice_by_stack.out
+
# Connected/Following/Perceeding flow table.
connected_flow_data.json connected_flow.sql connected_flow.out
diff --git a/test/trace_processor/dynamic/slice_stacks.textproto b/test/trace_processor/dynamic/slice_stacks.textproto
new file mode 100644
index 000000000..8361afc07
--- /dev/null
+++ b/test/trace_processor/dynamic/slice_stacks.textproto
@@ -0,0 +1,154 @@
+# Sequence 1 defaults to track for "t1".
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_descriptor {
+ uuid: 1
+ parent_uuid: 10
+ thread {
+ pid: 5
+ tid: 1
+ thread_name: "t1"
+ }
+ }
+ trace_packet_defaults {
+ track_event_defaults {
+ track_uuid: 1
+ }
+ }
+}
+
+# Thread track is nested underneath this process track.
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ track_descriptor {
+ uuid: 10
+ process {
+ pid: 5
+ process_name: "p1"
+ }
+ }
+}
+
+# ----------------------
+# Slices
+# ----------------------
+
+# We create stacks of various depths on track "t1".
+# t1 |-------------| |-------------|
+# |-------| |-------|
+# |-| |-|
+
+# Should appear on default track "t1", range from 1000 to 6000.
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 1000
+ track_event {
+ categories: "cat"
+ name: "event_depth_0"
+ type: 1
+ }
+}
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 2000
+ track_event {
+ categories: "cat"
+ name: "event_depth_1"
+ type: 1
+ }
+}
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 3000
+ track_event {
+ categories: "cat"
+ name: "event_depth_2"
+ type: 1
+ }
+}
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 4000
+ track_event {
+ categories: "cat"
+ name: "event_depth_2"
+ type: 2
+ }
+}
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 5000
+ track_event {
+ categories: "cat"
+ name: "event_depth_1"
+ type: 2
+ }
+}
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 6000
+ track_event {
+ categories: "cat"
+ name: "event_depth_0"
+ type: 2
+ }
+}
+
+# Should appear on default track "t1", range from 8000 to 13000.
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 8000
+ track_event {
+ categories: "cat"
+ name: "event_depth_0"
+ type: 1
+ }
+}
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 9000
+ track_event {
+ categories: "cat"
+ name: "event_depth_1"
+ type: 1
+ }
+}
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 10000
+ track_event {
+ categories: "cat"
+ name: "event_depth_2"
+ type: 1
+ }
+}
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 11000
+ track_event {
+ categories: "cat"
+ name: "event_depth_2"
+ type: 2
+ }
+}
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 12000
+ track_event {
+ categories: "cat"
+ name: "event_depth_1"
+ type: 2
+ }
+}
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 13000
+ track_event {
+ categories: "cat"
+ name: "event_depth_0"
+ type: 2
+ }
+}
diff --git a/test/trace_processor/fuchsia/fuchsia_smoke_instants.out b/test/trace_processor/fuchsia/fuchsia_smoke_instants.out
index 6e2dd9d54..87964abb1 100644
--- a/test/trace_processor/fuchsia/fuchsia_smoke_instants.out
+++ b/test/trace_processor/fuchsia/fuchsia_smoke_instants.out
@@ -1,11 +1,11 @@
-"ts","name","value"
-21442756010,"task_start",0.000000
-21446583438,"task_end",0.000000
-21448366538,"task_start",0.000000
-21450363277,"task_end",0.000000
-21454255741,"task_start",0.000000
-21457834528,"task_end",0.000000
-21459006408,"task_start",0.000000
-21460601866,"task_end",0.000000
-21461282720,"task_start",0.000000
-21462998487,"task_end",0.000000
+"ts","name"
+21442756010,"task_start"
+21446583438,"task_end"
+21448366538,"task_start"
+21450363277,"task_end"
+21454255741,"task_start"
+21457834528,"task_end"
+21459006408,"task_start"
+21460601866,"task_end"
+21461282720,"task_start"
+21462998487,"task_end"
diff --git a/test/trace_processor/fuchsia/fuchsia_smoke_slices.out b/test/trace_processor/fuchsia/fuchsia_smoke_slices.out
index e437aa41c..39c37a035 100644
--- a/test/trace_processor/fuchsia/fuchsia_smoke_slices.out
+++ b/test/trace_processor/fuchsia/fuchsia_smoke_slices.out
@@ -1,3 +1,3 @@
"type","depth","count"
-"thread_track",0,1153
-"thread_track",1,5
+"thread_track",0,2153
+"thread_track",1,1004
diff --git a/test/trace_processor/fuchsia/fuchsia_smoke_type.out b/test/trace_processor/fuchsia/fuchsia_smoke_type.out
new file mode 100644
index 000000000..ba17fcfd3
--- /dev/null
+++ b/test/trace_processor/fuchsia/fuchsia_smoke_type.out
@@ -0,0 +1,11 @@
+"id","name","type"
+0,"[NULL]","thread_track"
+1,"[NULL]","thread_track"
+2,"[NULL]","thread_track"
+3,"[NULL]","thread_track"
+4,"[NULL]","thread_track"
+5,"cpu_usage:average_cpu_percentage","process_counter_track"
+6,"[NULL]","thread_track"
+7,"[NULL]","thread_track"
+8,"[NULL]","thread_track"
+9,"[NULL]","thread_track"
diff --git a/test/trace_processor/fuchsia/fuchsia_workstation_smoke_slices.out b/test/trace_processor/fuchsia/fuchsia_workstation_smoke_slices.out
index daab85f89..68945e2f0 100644
--- a/test/trace_processor/fuchsia/fuchsia_workstation_smoke_slices.out
+++ b/test/trace_processor/fuchsia/fuchsia_workstation_smoke_slices.out
@@ -2,8 +2,8 @@
"process_track",0,85
"process_track",1,14
"process_track",2,1
-"thread_track",0,13379
-"thread_track",1,11548
+"thread_track",0,15198
+"thread_track",1,11607
"thread_track",2,10181
"thread_track",3,1927
"thread_track",4,4001
diff --git a/test/trace_processor/fuchsia/index b/test/trace_processor/fuchsia/index
index bb89b3020..05e4051bf 100644
--- a/test/trace_processor/fuchsia/index
+++ b/test/trace_processor/fuchsia/index
@@ -6,6 +6,7 @@
../../data/fuchsia_trace.fxt smoke_instants.sql fuchsia_smoke_instants.out
../../data/fuchsia_trace.fxt smoke_counters.sql fuchsia_smoke_counters.out
../../data/fuchsia_trace.fxt smoke_flow.sql fuchsia_smoke_flow.out
+../../data/fuchsia_trace.fxt smoke_type.sql fuchsia_smoke_type.out
# Smoke test a high-CPU trace.
../../data/fuchsia_workstation.fxt ../common/smoke_slices.sql fuchsia_workstation_smoke_slices.out
diff --git a/test/trace_processor/fuchsia/smoke_instants.sql b/test/trace_processor/fuchsia/smoke_instants.sql
index b57a5310a..cc5c40eb7 100644
--- a/test/trace_processor/fuchsia/smoke_instants.sql
+++ b/test/trace_processor/fuchsia/smoke_instants.sql
@@ -15,7 +15,8 @@
--
select
ts,
- name,
- value
-from instants
+ name
+from slice
+where
+ dur = 0
limit 10;
diff --git a/test/trace_processor/fuchsia/smoke_type.sql b/test/trace_processor/fuchsia/smoke_type.sql
new file mode 100644
index 000000000..4a29c1220
--- /dev/null
+++ b/test/trace_processor/fuchsia/smoke_type.sql
@@ -0,0 +1,21 @@
+--
+-- Copyright 2022 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+select
+ id,
+ name,
+ type
+from track
+limit 10;
diff --git a/test/trace_processor/graphics/android_sysui_cuj.out b/test/trace_processor/graphics/android_sysui_cuj.out
index 1cdea9065..974113a62 100644
--- a/test/trace_processor/graphics/android_sysui_cuj.out
+++ b/test/trace_processor/graphics/android_sysui_cuj.out
@@ -1,7 +1,7 @@
android_sysui_cuj {
cuj_name: "SHADE_ROW_EXPAND"
- cuj_start: 0
- cuj_dur: 1000000000
+ cuj_start: 10
+ cuj_dur: 901000000
process {
name: "com.android.systemui"
uid: 10001
@@ -61,8 +61,28 @@ android_sysui_cuj {
}
frames {
number: 8
+ ts: 300000000
+ dur: 4000000
+ vsync: 110
+ }
+ frames {
+ number: 9
ts: 400000000
dur: 10000000
vsync: 120
}
+ frames {
+ number: 10
+ ts: 500000000
+ dur: 56000000
+ vsync: 130
+ jank_cause: "MainThread - binder transaction time"
+ }
+ frames {
+ number: 11
+ ts: 600000000
+ dur: 26000000
+ vsync: 140
+ jank_cause: "MainThread - binder transaction time"
+ }
}
diff --git a/test/trace_processor/graphics/android_sysui_cuj.py b/test/trace_processor/graphics/android_sysui_cuj.py
index dcbbf9b10..1845aa783 100644
--- a/test/trace_processor/graphics/android_sysui_cuj.py
+++ b/test/trace_processor/graphics/android_sysui_cuj.py
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from lib2to3.pgen2 import token
from os import sys, path
import synth_common
@@ -28,11 +29,19 @@ def add_main_thread_atrace(trace, ts, ts_end, buf):
trace.add_atrace_end(ts=ts_end, tid=PID, pid=PID)
-def add_render_thread_atrace(trace, ts, ts_end, buf):
+def add_render_thread_atrace_begin(trace, ts, buf):
trace.add_atrace_begin(ts=ts, tid=RTID, pid=PID, buf=buf)
+
+
+def add_render_thread_atrace_end(trace, ts_end):
trace.add_atrace_end(ts=ts_end, tid=RTID, pid=PID)
+def add_render_thread_atrace(trace, ts, ts_end, buf):
+ add_render_thread_atrace_begin(trace, ts, buf)
+ add_render_thread_atrace_end(trace, ts_end)
+
+
def add_gpu_thread_atrace(trace, ts, ts_end, buf):
trace.add_atrace_begin(ts=ts, tid=1666, pid=PID, buf=buf)
trace.add_atrace_end(ts=ts_end, tid=1666, pid=PID)
@@ -43,62 +52,63 @@ def add_jit_thread_atrace(trace, ts, ts_end, buf):
trace.add_atrace_end(ts=ts_end, tid=JITID, pid=PID)
-def add_frame(trace, vsync, ts_do_frame, ts_end_do_frame, ts_draw_frame,
- ts_end_draw_frame, ts_gpu, ts_end_gpu):
+def add_frame(trace,
+ vsync,
+ ts_do_frame,
+ ts_end_do_frame,
+ ts_draw_frame,
+ ts_end_draw_frame,
+ ts_gpu=None,
+ ts_end_gpu=None):
add_main_thread_atrace(trace, ts_do_frame, ts_end_do_frame,
"Choreographer#doFrame %d" % vsync)
- add_render_thread_atrace(trace, ts_draw_frame, ts_end_draw_frame,
- "DrawFrames %d" % vsync)
- add_gpu_thread_atrace(trace, ts_gpu, ts_end_gpu,
- "waiting for GPU completion 123")
+
+ gpu_idx = 1000 + vsync * 10 + 1
+ if ts_gpu is None:
+ gpu_fence_message = "GPU completion fence %d has signaled"
+ else:
+ gpu_fence_message = "Trace GPU completion fence %d"
+ add_render_thread_atrace_begin(trace, ts_draw_frame, "DrawFrames %d" % vsync)
+ add_render_thread_atrace(trace, ts_end_draw_frame - 100,
+ ts_end_draw_frame - 1, gpu_fence_message % gpu_idx)
+ add_render_thread_atrace_end(trace, ts_end_draw_frame)
+
+ if ts_gpu is not None:
+ add_gpu_thread_atrace(trace, ts_gpu, ts_end_gpu,
+ "waiting for GPU completion %d" % gpu_idx)
+
+
+def add_expected_frame_events(ts, dur, token_start):
+ trace.add_expected_display_frame_start_event(
+ ts=ts, cookie=token_start, token=token_start, pid=PID)
+ trace.add_frame_end_event(ts=ts + dur, cookie=token_start)
-def add_display_frame_events(ts,
- dur,
- token_start,
- jank=None,
- on_time_finish_override=None):
+def add_actual_frame_events(ts,
+ dur,
+ token_start,
+ cookie=None,
+ jank=None,
+ on_time_finish_override=None):
+ if cookie is None:
+ cookie = token_start + 1
jank_type = jank if jank is not None else 1
present_type = 2 if jank is not None else 1
if on_time_finish_override is None:
on_time_finish = 1 if jank is None else 0
else:
on_time_finish = on_time_finish_override
- trace.add_expected_display_frame_start_event(
- ts=ts, cookie=token_start, token=token_start, pid=PID)
- trace.add_frame_end_event(ts=ts + 20_500_000, cookie=token_start)
trace.add_actual_display_frame_start_event(
ts=ts,
- cookie=token_start + 1,
- token=token_start,
- pid=PID,
- present_type=present_type,
- on_time_finish=on_time_finish,
- gpu_composition=0,
- jank_type=jank_type,
- prediction_type=3)
- trace.add_frame_end_event(ts=ts + dur, cookie=token_start + 1)
- trace.add_expected_surface_frame_start_event(
- ts=ts,
- cookie=token_start + 2,
- token=token_start,
- display_frame_token=token_start,
- pid=PID,
- layer_name=LAYER)
- trace.add_frame_end_event(ts=ts + 20_500_000, cookie=token_start + 2)
- trace.add_actual_surface_frame_start_event(
- ts=ts,
- cookie=token_start + 3,
+ cookie=cookie,
token=token_start,
- display_frame_token=token_start,
pid=PID,
- layer_name=LAYER,
present_type=present_type,
on_time_finish=on_time_finish,
gpu_composition=0,
jank_type=jank_type,
prediction_type=3)
- trace.add_frame_end_event(ts=ts + dur, cookie=token_start + 3)
+ trace.add_frame_end_event(ts=ts + dur, cookie=cookie)
trace = synth_common.create_trace()
@@ -115,9 +125,9 @@ trace.add_thread(
trace.add_thread(
tid=JITID, tgid=PID, cmdline="Jit thread pool", name="Jit thread pool")
trace.add_ftrace_packet(cpu=0)
-trace.add_atrace_async_begin(ts=0, tid=PID, pid=PID, buf="J<SHADE_ROW_EXPAND>")
+trace.add_atrace_async_begin(ts=10, tid=PID, pid=PID, buf="J<SHADE_ROW_EXPAND>")
trace.add_atrace_async_end(
- ts=1_000_000_000, tid=PID, pid=PID, buf="J<SHADE_ROW_EXPAND>")
+ ts=901_000_010, tid=PID, pid=PID, buf="J<SHADE_ROW_EXPAND>")
add_frame(
trace,
@@ -137,14 +147,14 @@ add_render_thread_atrace(
add_frame(
trace,
vsync=20,
- ts_do_frame=8_000_000,
+ ts_do_frame=20_000_000,
ts_end_do_frame=23_000_000,
ts_draw_frame=22_000_000,
ts_end_draw_frame=26_000_000,
ts_gpu=27_500_000,
ts_end_gpu=35_000_000)
add_main_thread_atrace(
- trace, ts=9_000_000, ts_end=20_000_000, buf="binder transaction")
+ trace, ts=9_000_000, ts_end=19_000_000, buf="binder transaction")
add_render_thread_atrace(
trace, ts=24_000_000, ts_end=25_000_000, buf="flush layers")
@@ -248,13 +258,19 @@ add_frame(
ts_gpu=108_000_000,
ts_end_gpu=115_600_000)
+add_render_thread_atrace_begin(trace, ts=108_000_000, buf="DrawFrames 90")
add_render_thread_atrace(
- trace, ts=108_000_000, ts_end=114_000_000, buf="DrawFrames 90")
+ trace,
+ ts=113_000_000,
+ ts_end=113_500_000,
+ buf="Trace GPU completion fence 1902")
+add_render_thread_atrace_end(trace, ts_end=114_000_000)
+
add_gpu_thread_atrace(
trace,
ts=121_500_000,
ts_end=122_000_000,
- buf="waiting for GPU completion 123")
+ buf="waiting for GPU completion 1902")
add_frame(
trace,
@@ -276,8 +292,8 @@ add_frame(
ts_end_do_frame=315_000_000,
ts_draw_frame=302_000_000,
ts_end_draw_frame=304_000_000,
- ts_gpu=308_000_000,
- ts_end_gpu=310_000_000)
+ ts_gpu=None,
+ ts_end_gpu=None)
add_render_thread_atrace(
trace, ts=305_000_000, ts_end=308_000_000, buf="dispatchFrameCallbacks")
@@ -295,10 +311,38 @@ add_frame(
add_render_thread_atrace(
trace, ts=415_000_000, ts_end=418_000_000, buf="dispatchFrameCallbacks")
-# One more frame after the CUJ is finished
+# Frame start delayed by 50ms by a long binder transaction
+add_main_thread_atrace(
+ trace, ts=500_000_000, ts_end=549_500_000, buf="binder transaction")
+
add_frame(
trace,
vsync=130,
+ ts_do_frame=550_000_000,
+ ts_end_do_frame=555_000_000,
+ ts_draw_frame=552_000_000,
+ ts_end_draw_frame=556_000_000,
+ ts_gpu=None,
+ ts_end_gpu=None)
+
+# Frame start delayed by 8ms by a long binder transaction
+add_main_thread_atrace(
+ trace, ts=600_000_000, ts_end=608_049_000, buf="binder transaction")
+
+add_frame(
+ trace,
+ vsync=140,
+ ts_do_frame=608_500_000,
+ ts_end_do_frame=610_000_000,
+ ts_draw_frame=609_000_000,
+ ts_end_draw_frame=626_000_000,
+ ts_gpu=None,
+ ts_end_gpu=None)
+
+# One more frame after the CUJ is finished
+add_frame(
+ trace,
+ vsync=140,
ts_do_frame=1_100_000_000,
ts_end_do_frame=1_200_000_000,
ts_draw_frame=1_150_000_000,
@@ -306,23 +350,54 @@ add_frame(
ts_gpu=1_400_000_000,
ts_end_gpu=1_500_000_000)
-add_display_frame_events(ts=1, dur=16_000_000, token_start=10)
-add_display_frame_events(ts=8_000_000, dur=28_000_000, token_start=20, jank=66)
-add_display_frame_events(ts=30_000_000, dur=25_000_000, token_start=30, jank=64)
-add_display_frame_events(ts=40_000_000, dur=40_000_000, token_start=40, jank=64)
-add_display_frame_events(ts=70_000_000, dur=20_000_000, token_start=60, jank=64)
-add_display_frame_events(
- ts=100_000_000, dur=23_000_000, token_start=90, jank=64)
-add_display_frame_events(
+add_expected_frame_events(ts=0, dur=16_000_000, token_start=10)
+add_actual_frame_events(ts=0, dur=16_000_000, token_start=10)
+
+add_expected_frame_events(ts=8_000_000, dur=20_000_000, token_start=20)
+add_actual_frame_events(ts=8_000_000, dur=28_000_000, token_start=20, jank=66)
+
+add_expected_frame_events(ts=30_000_000, dur=20_000_000, token_start=30)
+add_actual_frame_events(ts=30_000_000, dur=25_000_000, token_start=30, jank=64)
+
+add_expected_frame_events(ts=40_000_000, dur=20_000_000, token_start=40)
+add_actual_frame_events(ts=40_000_000, dur=40_000_000, token_start=40, jank=64)
+
+add_expected_frame_events(ts=70_000_000, dur=20_000_000, token_start=60)
+add_actual_frame_events(ts=70_000_000, dur=10_000_000, token_start=60, jank=64)
+add_actual_frame_events(
+ ts=70_000_000, dur=20_000_000, token_start=60, cookie=62, jank=64)
+
+add_expected_frame_events(ts=100_000_000, dur=20_000_000, token_start=90)
+add_actual_frame_events(ts=100_000_000, dur=23_000_000, token_start=90, jank=64)
+
+add_expected_frame_events(ts=200_000_000, dur=20_000_000, token_start=100)
+add_actual_frame_events(
ts=200_000_000, dur=22_000_000, token_start=100, jank=34)
-add_display_frame_events(ts=300_000_000, dur=61_000_000, token_start=110)
-add_display_frame_events(
+
+add_expected_frame_events(ts=300_000_000, dur=20_000_000, token_start=110)
+add_actual_frame_events(ts=300_000_000, dur=61_000_000, token_start=110)
+
+add_expected_frame_events(ts=400_000_000, dur=20_000_000, token_start=120)
+add_actual_frame_events(
ts=400_000_000,
dur=61_000_000,
token_start=120,
jank=128,
on_time_finish_override=1)
-add_display_frame_events(
- ts=1_100_000_000, dur=500_000_000, token_start=130, jank=64)
+
+# Multiple layers but only one of them janked (the one we care about)
+add_expected_frame_events(ts=500_000_000, dur=20_000_000, token_start=130)
+add_actual_frame_events(ts=500_000_000, dur=2_000_000, token_start=130)
+add_actual_frame_events(
+ ts=550_000_000, dur=6_000_000, token_start=130, cookie=132, jank=64)
+
+# Single layer but actual frame event is slighly after doFrame start
+add_expected_frame_events(ts=600_000_000, dur=20_000_000, token_start=140)
+add_actual_frame_events(
+ ts=608_600_000, dur=17_000_000, token_start=140, jank=64)
+
+add_expected_frame_events(ts=1_100_000_000, dur=20_000_000, token_start=1000)
+add_actual_frame_events(
+ ts=1_100_000_000, dur=500_000_000, token_start=1000, jank=64)
sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/graphics/android_sysui_cuj_event.out b/test/trace_processor/graphics/android_sysui_cuj_event.out
index 4519815cb..e5104e8b5 100644
--- a/test/trace_processor/graphics/android_sysui_cuj_event.out
+++ b/test/trace_processor/graphics/android_sysui_cuj_event.out
@@ -6,3 +6,5 @@
"slice","SHADE_ROW_EXPAND - jank cause",70000000,10000000,"RenderThread - scheduler"
"slice","SHADE_ROW_EXPAND - jank cause",100000000,15000000,"GPU completion - long completion time"
"slice","SHADE_ROW_EXPAND - jank cause",200000000,15000000,"SurfaceFlinger GPU Deadline Missed,SurfaceFlinger Scheduling"
+"slice","SHADE_ROW_EXPAND - jank cause",500000000,55000000,"MainThread - binder transaction time"
+"slice","SHADE_ROW_EXPAND - jank cause",600000000,10000000,"MainThread - binder transaction time"
diff --git a/test/trace_processor/graphics/clock_sync.sql b/test/trace_processor/graphics/clock_sync.sql
index 227767b0f..ac9e48ab0 100644
--- a/test/trace_processor/graphics/clock_sync.sql
+++ b/test/trace_processor/graphics/clock_sync.sql
@@ -15,4 +15,4 @@
--
select ts, cast(value as integer) as int_value
from counters
-where name like 'gpu_counter%' \ No newline at end of file
+where name GLOB 'gpu_counter*' \ No newline at end of file
diff --git a/test/trace_processor/graphics/dpu_vote_clock_bw.out b/test/trace_processor/graphics/dpu_vote_clock_bw.out
new file mode 100644
index 000000000..78ad37bb8
--- /dev/null
+++ b/test/trace_processor/graphics/dpu_vote_clock_bw.out
@@ -0,0 +1,17 @@
+android_hwcomposer {
+ skipped_validation_count: 0
+ unskipped_validation_count: 0
+ separated_validation_count: 0
+ unknown_validation_count: 0
+ dpu_vote_metrics {
+ tid: 237
+ avg_dpu_vote_clock: 206250
+ avg_dpu_vote_avg_bw: 210000
+ avg_dpu_vote_peak_bw: 205000
+ avg_dpu_vote_rt_bw: 271000
+ }
+ dpu_vote_metrics {
+ tid: 299
+ avg_dpu_vote_clock: 250000
+ }
+}
diff --git a/test/trace_processor/graphics/dpu_vote_clock_bw.textproto b/test/trace_processor/graphics/dpu_vote_clock_bw.textproto
new file mode 100644
index 000000000..7da1d073b
--- /dev/null
+++ b/test/trace_processor/graphics/dpu_vote_clock_bw.textproto
@@ -0,0 +1,127 @@
+packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 1000000
+ pid: 237
+ dpu_tracing_mark_write {
+ pid: 237
+ name: "dpu_vote_clock"
+ type: 67
+ value: 200000
+ }
+ }
+ event {
+ timestamp: 2000000
+ pid: 237
+ dpu_tracing_mark_write {
+ pid: 237
+ name: "dpu_vote_avg_bw"
+ type: 67
+ value: 210000
+ }
+ }
+ event {
+ timestamp: 3000000
+ pid: 237
+ dpu_tracing_mark_write {
+ pid: 237
+ name: "dpu_vote_peak_bw"
+ type: 67
+ value: 210000
+ }
+ }
+ event {
+ timestamp: 4000000
+ pid: 237
+ dpu_tracing_mark_write {
+ pid: 237
+ name: "dpu_vote_clock"
+ type: 67
+ value: 210000
+ }
+ }
+ event {
+ timestamp: 5000000
+ pid: 237
+ dpu_tracing_mark_write {
+ pid: 237
+ name: "dpu_vote_avg_bw"
+ type: 67
+ value: 210000
+ }
+ }
+ event {
+ timestamp: 6000000
+ pid: 237
+ dpu_tracing_mark_write {
+ pid: 237
+ name: "dpu_vote_peak_bw"
+ type: 67
+ value: 200000
+ }
+ }
+ event {
+ timestamp: 7000000
+ pid: 237
+ dpu_tracing_mark_write {
+ pid: 237
+ name: "dpu_vote_clock"
+ type: 67
+ value: 210000
+ }
+ }
+ event {
+ timestamp: 7000000
+ pid: 299
+ dpu_tracing_mark_write {
+ pid: 299
+ name: "dpu_vote_clock"
+ type: 67
+ value: 200000
+ }
+ }
+ event {
+ timestamp: 8000000
+ pid: 237
+ dpu_tracing_mark_write {
+ pid: 237
+ name: "dpu_vote_avg_bw"
+ type: 67
+ value: 210000
+ }
+ }
+ event {
+ timestamp: 8000000
+ pid: 299
+ dpu_tracing_mark_write {
+ pid: 299
+ name: "dpu_vote_clock"
+ type: 67
+ value: 300000
+ }
+ }
+ event {
+ timestamp: 8000000
+ pid: 237
+ dpu_tracing_mark_write {
+ pid: 237
+ name: "dpu_vote_rt_bw"
+ type: 67
+ value: 271000
+ }
+ }
+ event {
+ timestamp: 8999999
+ pid: 237
+ dpu_tracing_mark_write {
+ pid: 237
+ name: "dpu_vote_peak_bw"
+ type: 67
+ value: 200000
+ }
+ }
+ }
+ trusted_uid: 9999
+ trusted_packet_sequence_id: 3
+} \ No newline at end of file
diff --git a/test/trace_processor/graphics/frame_missed_metrics.out b/test/trace_processor/graphics/frame_missed_metrics.out
index ec59e69bb..aad41d28e 100644
--- a/test/trace_processor/graphics/frame_missed_metrics.out
+++ b/test/trace_processor/graphics/frame_missed_metrics.out
@@ -3,4 +3,5 @@ android_surfaceflinger {
missed_hwc_frames: 0
missed_gpu_frames: 0
missed_frame_rate: 0.42857142857142855 # = 3/7
+ gpu_invocations: 0
}
diff --git a/test/trace_processor/graphics/g2d_metrics.out b/test/trace_processor/graphics/g2d_metrics.out
index a28e4fdfb..86bd88992 100644
--- a/test/trace_processor/graphics/g2d_metrics.out
+++ b/test/trace_processor/graphics/g2d_metrics.out
@@ -2,39 +2,39 @@ g2d {
g2d_hw {
instances {
name: "g2d_frame_hw#10"
- max_dur_ns: 20
- min_dur_ns: 20
- avg_dur_ns: 20
frame_count: 1
error_count: 0
+ max_dur_ms: 20
+ min_dur_ms: 20
+ avg_dur_ms: 20
}
- max_dur_ns: 20
- min_dur_ns: 20
- avg_dur_ns: 20
frame_count: 1
error_count: 0
+ max_dur_ms: 20
+ min_dur_ms: 20
+ avg_dur_ms: 20
}
g2d_sw {
instances {
name: "g2d_frame_sw#10"
- max_dur_ns: 40
- min_dur_ns: 20
- avg_dur_ns: 30
frame_count: 2
error_count: 0
+ max_dur_ms: 40
+ min_dur_ms: 20
+ avg_dur_ms: 30
}
instances {
name: "g2d_frame_sw#11"
- max_dur_ns: 40
- min_dur_ns: 40
- avg_dur_ns: 40
frame_count: 1
error_count: 2
+ max_dur_ms: 40
+ min_dur_ms: 40
+ avg_dur_ms: 40
}
- max_dur_ns: 40
- min_dur_ns: 20
- avg_dur_ns: 33
frame_count: 3
error_count: 2
+ max_dur_ms: 40
+ min_dur_ms: 20
+ avg_dur_ms: 33.33333333333333
}
}
diff --git a/test/trace_processor/graphics/g2d_metrics.textproto b/test/trace_processor/graphics/g2d_metrics.textproto
index 9ed87bfe1..6a0eae99d 100644
--- a/test/trace_processor/graphics/g2d_metrics.textproto
+++ b/test/trace_processor/graphics/g2d_metrics.textproto
@@ -2,7 +2,7 @@ packet {
ftrace_events {
cpu: 2
event {
- timestamp: 1000
+ timestamp: 1000000000
pid: 237
g2d_tracing_mark_write {
pid: 237
@@ -12,7 +12,7 @@ packet {
}
}
event {
- timestamp: 1003
+ timestamp: 1003000000
pid: 237
g2d_tracing_mark_write {
pid: 237
@@ -22,7 +22,7 @@ packet {
}
}
event {
- timestamp: 1005
+ timestamp: 1005000000
pid: 237
g2d_tracing_mark_write {
pid: 237
@@ -32,7 +32,7 @@ packet {
}
}
event {
- timestamp: 1010
+ timestamp: 1010000000
pid: 237
g2d_tracing_mark_write {
pid: 237
@@ -42,7 +42,7 @@ packet {
}
}
event {
- timestamp: 1020
+ timestamp: 1020000000
pid: 237
g2d_tracing_mark_write {
pid: 237
@@ -52,7 +52,7 @@ packet {
}
}
event {
- timestamp: 1030
+ timestamp: 1030000000
pid: 237
g2d_tracing_mark_write {
pid: 237
@@ -62,7 +62,7 @@ packet {
}
}
event {
- timestamp: 1040
+ timestamp: 1040000000
pid: 237
g2d_tracing_mark_write {
pid: 237
@@ -72,7 +72,7 @@ packet {
}
}
event {
- timestamp: 1050
+ timestamp: 1050000000
pid: 237
g2d_tracing_mark_write {
pid: 237
@@ -82,7 +82,7 @@ packet {
}
}
event {
- timestamp: 1060
+ timestamp: 1060000000
pid: 237
g2d_tracing_mark_write {
pid: 237
@@ -92,7 +92,7 @@ packet {
}
}
event {
- timestamp: 1070
+ timestamp: 1070000000
pid: 237
g2d_tracing_mark_write {
pid: 237
@@ -102,7 +102,7 @@ packet {
}
}
event {
- timestamp: 1080
+ timestamp: 1080000000
pid: 237
g2d_tracing_mark_write {
pid: 237
@@ -112,7 +112,7 @@ packet {
}
}
event {
- timestamp: 1085
+ timestamp: 1085000000
pid: 237
g2d_tracing_mark_write {
pid: 237
diff --git a/test/trace_processor/graphics/gpu_frequency_metric.out b/test/trace_processor/graphics/gpu_frequency_metric.out
new file mode 100644
index 000000000..dd9b0ab2c
--- /dev/null
+++ b/test/trace_processor/graphics/gpu_frequency_metric.out
@@ -0,0 +1,39 @@
+android_gpu {
+ freq_metrics {
+ gpu_id: 0
+ freq_max: 603000
+ freq_min: 0
+ freq_avg: 475200.0 # = (585000 * 2 + 0 * 1 + 603000 * 2) / 5
+ used_freqs {
+ freq: 0
+ dur_ms: 1.0
+ percentage: 20.0
+ }
+ used_freqs {
+ freq: 585000
+ dur_ms: 2.0
+ percentage: 40.0
+ }
+ used_freqs {
+ freq: 603000
+ dur_ms: 2.0
+ percentage: 40.0
+ }
+ }
+ freq_metrics {
+ gpu_id: 1
+ freq_max: 758000
+ freq_min: 400000
+ freq_avg: 489500.0 # = (400000 * 3 + 758000 * 1) / 4
+ used_freqs {
+ freq: 400000
+ dur_ms: 3.0
+ percentage: 75.0
+ }
+ used_freqs {
+ freq: 758000
+ dur_ms: 1.0
+ percentage: 25.0
+ }
+ }
+} \ No newline at end of file
diff --git a/test/trace_processor/graphics/gpu_frequency_metric.textproto b/test/trace_processor/graphics/gpu_frequency_metric.textproto
new file mode 100644
index 000000000..8f0710f4f
--- /dev/null
+++ b/test/trace_processor/graphics/gpu_frequency_metric.textproto
@@ -0,0 +1,55 @@
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 200001000000
+ pid: 527
+ gpu_frequency {
+ gpu_id: 0
+ state: 585000
+ }
+ }
+ event {
+ timestamp: 200002000000
+ pid: 527
+ gpu_frequency {
+ gpu_id: 1
+ state: 400000
+ }
+ }
+ event {
+ timestamp: 200003000000
+ pid: 527
+ gpu_frequency {
+ gpu_id: 0
+ state: 0
+ }
+ }
+ event {
+ timestamp: 200004000000
+ pid: 527
+ gpu_frequency {
+ gpu_id: 0
+ state: 603000
+ }
+ }
+ event {
+ timestamp: 200005000000
+ pid: 527
+ gpu_frequency {
+ gpu_id: 1
+ state: 758000
+ }
+ }
+ event {
+ timestamp: 200005999999
+ pid: 527
+ gpu_frequency {
+ gpu_id: 0
+ state: 603000
+ }
+ }
+ }
+ trusted_uid: 9999
+ trusted_packet_sequence_id: 2
+} \ No newline at end of file
diff --git a/test/trace_processor/graphics/gpu_mem_total.py b/test/trace_processor/graphics/gpu_mem_total.py
index e21d8a8b5..5157bc8ec 100755
--- a/test/trace_processor/graphics/gpu_mem_total.py
+++ b/test/trace_processor/graphics/gpu_mem_total.py
@@ -25,15 +25,15 @@ trace.add_gpu_mem_total_event(pid=0, ts=0, size=123)
# Global gpu_mem_total ftrace event
trace.add_ftrace_packet(cpu=0)
-trace.add_gpu_mem_total_ftrace_event(pid=0, ts=5, size=256)
-trace.add_gpu_mem_total_ftrace_event(pid=0, ts=10, size=123)
+trace.add_gpu_mem_total_ftrace_event(ftrace_pid=0, pid=0, ts=5, size=256)
+trace.add_gpu_mem_total_ftrace_event(ftrace_pid=0, pid=0, ts=10, size=123)
# gpu_mem_total initial counter event for pid = 1
trace.add_gpu_mem_total_event(pid=1, ts=0, size=100)
# gpu_mem_total ftrace event for pid = 1
trace.add_ftrace_packet(cpu=1)
-trace.add_gpu_mem_total_ftrace_event(pid=1, ts=5, size=233)
-trace.add_gpu_mem_total_ftrace_event(pid=1, ts=10, size=0)
+trace.add_gpu_mem_total_ftrace_event(ftrace_pid=1, pid=1, ts=5, size=233)
+trace.add_gpu_mem_total_ftrace_event(ftrace_pid=1, pid=1, ts=10, size=0)
sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/graphics/gpu_mem_total_after_free.py b/test/trace_processor/graphics/gpu_mem_total_after_free.py
new file mode 100644
index 000000000..2b68d4c06
--- /dev/null
+++ b/test/trace_processor/graphics/gpu_mem_total_after_free.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python3
+# Copyright (C) 2020 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from os import sys, path
+
+import synth_common
+
+trace = synth_common.create_trace()
+trace.add_packet()
+
+# gpu_mem_total initial counter event for pid = 1
+trace.add_gpu_mem_total_event(pid=1, ts=0, size=100)
+
+# gpu_mem_total ftrace event for pid = 1
+trace.add_ftrace_packet(cpu=1)
+trace.add_gpu_mem_total_ftrace_event(ftrace_pid=1, pid=1, ts=5, size=233)
+trace.add_gpu_mem_total_ftrace_event(ftrace_pid=1, pid=1, ts=10, size=50)
+
+# Finish the process at ts = 12
+trace.add_process_free(ts=12, tid=1, comm="app", prio=10)
+
+# Emit another event now at ts = 15 - this should be ignored
+# (see b/192274404 for more info).
+trace.add_gpu_mem_total_ftrace_event(ftrace_pid=0, pid=1, ts=15, size=0)
+
+sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/graphics/gpu_mem_total_after_free_gpu_mem_total.out b/test/trace_processor/graphics/gpu_mem_total_after_free_gpu_mem_total.out
new file mode 100644
index 000000000..b88ad313e
--- /dev/null
+++ b/test/trace_processor/graphics/gpu_mem_total_after_free_gpu_mem_total.out
@@ -0,0 +1,4 @@
+"name","unit","description","ts","pid","value"
+"GPU Memory","7","Total GPU memory used by this process",0,1,100
+"GPU Memory","7","Total GPU memory used by this process",5,1,233
+"GPU Memory","7","Total GPU memory used by this process",10,1,50
diff --git a/test/trace_processor/graphics/gpu_metric.py b/test/trace_processor/graphics/gpu_metric.py
index 8179d08d6..e7dfb3b4d 100644
--- a/test/trace_processor/graphics/gpu_metric.py
+++ b/test/trace_processor/graphics/gpu_metric.py
@@ -26,21 +26,21 @@ trace.add_process(3, 0, "app_2")
trace.add_ftrace_packet(cpu=0)
# max=4, min=1, avg=(2*1+5*2+(10-9)*4)/(10-2)=2
-trace.add_gpu_mem_total_ftrace_event(pid=0, ts=2, size=1)
-trace.add_gpu_mem_total_ftrace_event(pid=0, ts=4, size=2)
-trace.add_gpu_mem_total_ftrace_event(pid=0, ts=9, size=4)
+trace.add_gpu_mem_total_ftrace_event(ftrace_pid=0, pid=0, ts=2, size=1)
+trace.add_gpu_mem_total_ftrace_event(ftrace_pid=0, pid=0, ts=4, size=2)
+trace.add_gpu_mem_total_ftrace_event(ftrace_pid=0, pid=0, ts=9, size=4)
# max=8, min=2, avg=(5*2+(10-9)*8)/(10-4)=3
-trace.add_gpu_mem_total_ftrace_event(pid=1, ts=4, size=2)
-trace.add_gpu_mem_total_ftrace_event(pid=1, ts=9, size=8)
+trace.add_gpu_mem_total_ftrace_event(ftrace_pid=1, pid=1, ts=4, size=2)
+trace.add_gpu_mem_total_ftrace_event(ftrace_pid=1, pid=1, ts=9, size=8)
# max=8, min=6, avgxdur=2*6+(10-4)*8=60, dur=2+(10-4)=8
-trace.add_gpu_mem_total_ftrace_event(pid=2, ts=2, size=6)
-trace.add_gpu_mem_total_ftrace_event(pid=2, ts=4, size=8)
+trace.add_gpu_mem_total_ftrace_event(ftrace_pid=2, pid=2, ts=2, size=6)
+trace.add_gpu_mem_total_ftrace_event(ftrace_pid=2, pid=2, ts=4, size=8)
# max=10, min=7, avgxdur=1*7+(10-7)*10=37, dur=1+(10-7)=4
-trace.add_gpu_mem_total_ftrace_event(pid=3, ts=6, size=7)
-trace.add_gpu_mem_total_ftrace_event(pid=3, ts=7, size=10)
+trace.add_gpu_mem_total_ftrace_event(ftrace_pid=3, pid=3, ts=6, size=7)
+trace.add_gpu_mem_total_ftrace_event(ftrace_pid=3, pid=3, ts=7, size=10)
# app_2 will be aggregated
# max=10, min=6, avg=(60+37)/(8+4)=8
diff --git a/test/trace_processor/graphics/index b/test/trace_processor/graphics/index
index c479deaa8..34cc13694 100644
--- a/test/trace_processor/graphics/index
+++ b/test/trace_processor/graphics/index
@@ -13,16 +13,19 @@ graphics_frame_events.py graphics_frame_events.sql graphics_frame_events.out
# GPU Memory ftrace packets
gpu_mem_total.py gpu_mem_total.sql gpu_mem_total.out
+gpu_mem_total_after_free.py gpu_mem_total.sql gpu_mem_total_after_free_gpu_mem_total.out
# Clock sync
clock_sync.py clock_sync.sql clock_sync.out
-# Missed frames
+# Android SurfaceFlinger metrics
frame_missed.py frame_missed_event.sql frame_missed_event_frame_missed.out
frame_missed.py android_surfaceflinger frame_missed_metrics.out
+surfaceflinger_gpu_invocation.py android_surfaceflinger surfaceflinger_gpu_invocation.out
# GPU metrics
gpu_metric.py android_gpu gpu_metric.out
+gpu_frequency_metric.textproto android_gpu gpu_frequency_metric.out
# Android SysUI CUJs metrics
android_sysui_cuj.py android_sysui_cuj android_sysui_cuj.out
@@ -46,3 +49,6 @@ composer_execution.py composer_execution.sql composer_execution.out
# Display metrics
panel_fps.py display_metrics panel_fps.out
+
+# DPU vote clock and bandwidth
+dpu_vote_clock_bw.textproto android_hwcomposer dpu_vote_clock_bw.out
diff --git a/test/trace_processor/graphics/surfaceflinger_gpu_invocation.out b/test/trace_processor/graphics/surfaceflinger_gpu_invocation.out
new file mode 100644
index 000000000..9495fed5d
--- /dev/null
+++ b/test/trace_processor/graphics/surfaceflinger_gpu_invocation.out
@@ -0,0 +1,8 @@
+android_surfaceflinger {
+ missed_frames: 0
+ missed_hwc_frames: 0
+ missed_gpu_frames: 0
+ gpu_invocations: 4
+ avg_gpu_waiting_dur_ms: 4
+ total_non_empty_gpu_waiting_dur_ms: 11
+}
diff --git a/test/trace_processor/graphics/surfaceflinger_gpu_invocation.py b/test/trace_processor/graphics/surfaceflinger_gpu_invocation.py
new file mode 100644
index 000000000..53c6326f0
--- /dev/null
+++ b/test/trace_processor/graphics/surfaceflinger_gpu_invocation.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This synthetic trace tests handling of the mm_id field in the rss_stat
+# event when mm_structs are reused on process death.
+
+from os import sys, path
+
+import synth_common
+
+trace = synth_common.create_trace()
+
+trace.add_packet(ts=1)
+trace.add_process(pid=10, ppid=1, cmdline='/system/bin/surfaceflinger', uid=None)
+trace.add_thread(tid=10, tgid=10, cmdline='', name='Main thread')
+trace.add_thread(tid=33, tgid=10, cmdline='', name='GPU completion')
+trace.add_ftrace_packet(1)
+
+trace.add_atrace_begin(ts=1_000_000, tid=33, pid=10, buf='waiting for GPU completion 4')
+trace.add_atrace_end(ts=2_000_000, tid=33, pid=10)
+
+trace.add_atrace_begin(ts=3_000_000, tid=10, pid=10, buf='Trace GPU completion fence 5')
+trace.add_atrace_begin(ts=3_000_000, tid=33, pid=10, buf='waiting for GPU completion 5')
+trace.add_atrace_end(ts=3_000_500, tid=10, pid=10)
+trace.add_atrace_end(ts=6_000_000, tid=33, pid=10)
+
+trace.add_atrace_begin(ts=7_000_000, tid=10, pid=10, buf='Trace GPU completion fence 6')
+trace.add_atrace_begin(ts=7_000_000, tid=33, pid=10, buf='waiting for GPU completion 6')
+trace.add_atrace_end(ts=7_000_500, tid=10, pid=10)
+trace.add_atrace_begin(ts=10_000_000, tid=10, pid=10, buf='Trace GPU completion fence 7')
+trace.add_atrace_end(ts=10_000_500, tid=10, pid=10)
+trace.add_atrace_end(ts=12_000_000, tid=33, pid=10)
+trace.add_atrace_begin(ts=12_000_000, tid=33, pid=10, buf='waiting for GPU completion 7')
+trace.add_atrace_end(ts=14_000_000, tid=33, pid=10)
+
+trace.add_atrace_begin(ts=15_000_000, tid=10, pid=10, buf='Trace GPU completion fence 8')
+trace.add_atrace_end(ts=15_000_500, tid=10, pid=10)
+
+sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/include_index b/test/trace_processor/include_index
index b07a07fce..29a7b414e 100644
--- a/test/trace_processor/include_index
+++ b/test/trace_processor/include_index
@@ -1,9 +1,15 @@
+atrace/index
+camera/index
chrome/index
+cros/index
dynamic/index
fuchsia/index
graphics/index
+io/index
memory/index
+network/index
parsing/index
+performance/index
power/index
process_tracking/index
profiling/index
@@ -12,3 +18,4 @@ span_join/index
startup/index
tables/index
track_event/index
+translation/index
diff --git a/test/trace_processor/io/index b/test/trace_processor/io/index
new file mode 100644
index 000000000..1200ca953
--- /dev/null
+++ b/test/trace_processor/io/index
@@ -0,0 +1,2 @@
+# UFS command
+ufshcd_command.textproto ufshcd_command.sql ufshcd_command.out
diff --git a/test/trace_processor/io/ufshcd_command.out b/test/trace_processor/io/ufshcd_command.out
new file mode 100644
index 000000000..6be82e699
--- /dev/null
+++ b/test/trace_processor/io/ufshcd_command.out
@@ -0,0 +1,5 @@
+"ts","value"
+10000,1.000000
+10008,2.000000
+10010,3.000000
+10011,1.000000
diff --git a/test/trace_processor/io/ufshcd_command.sql b/test/trace_processor/io/ufshcd_command.sql
new file mode 100644
index 000000000..b1408a2a9
--- /dev/null
+++ b/test/trace_processor/io/ufshcd_command.sql
@@ -0,0 +1,11 @@
+SELECT
+ ts,
+ value
+FROM
+ counter AS c
+ JOIN
+ counter_track AS ct
+ ON c.track_id = ct.id
+WHERE
+ ct.name = "UFS Command Count"
+ORDER BY ts
diff --git a/test/trace_processor/io/ufshcd_command.textproto b/test/trace_processor/io/ufshcd_command.textproto
new file mode 100644
index 000000000..35a0fea98
--- /dev/null
+++ b/test/trace_processor/io/ufshcd_command.textproto
@@ -0,0 +1,52 @@
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 10000
+ pid: 200
+ ufshcd_command {
+ dev_name: "cat"
+ doorbell: 0x200
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 10008
+ pid: 300
+ ufshcd_command {
+ dev_name: "cat"
+ doorbell: 0x240
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 10010
+ pid: 400
+ ufshcd_command {
+ dev_name: "dd"
+ doorbell: 0x111
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 10011
+ pid: 500
+ ufshcd_command {
+ dev_name: "dd"
+ doorbell: 0x400
+ }
+ }
+ }
+}
diff --git a/test/trace_processor/memory/android_mem_by_priority.out b/test/trace_processor/memory/android_mem_by_priority.out
index 4189eaccc..dbd595419 100644
--- a/test/trace_processor/memory/android_mem_by_priority.out
+++ b/test/trace_processor/memory/android_mem_by_priority.out
@@ -6,21 +6,25 @@ android_mem {
min: 2000.0
max: 4000.0
avg: 3000.0
+ delta: 2000.0
}
file_rss {
min: 10000.0
max: 10000.0
avg: 10000.0
+ delta: 0.0
}
swap {
min: 0.0
max: 0.0
avg: 0.0
+ delta: 0.0
}
anon_and_swap {
min: 2000.0
max: 4000.0
avg: 3000.0
+ delta: 2000.0
}
}
priority_breakdown {
@@ -81,21 +85,25 @@ android_mem {
min: 4000.0
max: 8000.0
avg: 6000.0
+ delta: 4000.0
}
file_rss {
min: 10000.0
max: 10000.0
avg: 10000.0
+ delta: 0.0
}
swap {
min: 0.0
max: 0.0
avg: 0.0
+ delta: 0.0
}
anon_and_swap {
min: 4000.0
max: 8000.0
avg: 6000.0
+ delta: 4000.0
}
}
priority_breakdown {
diff --git a/test/trace_processor/memory/android_mem_counters.out b/test/trace_processor/memory/android_mem_counters.out
index c72912080..224bd80e2 100644
--- a/test/trace_processor/memory/android_mem_counters.out
+++ b/test/trace_processor/memory/android_mem_counters.out
@@ -3,24 +3,28 @@ android_mem {
process_name: "/system/bin/adbd"
total_counters {
anon_rss {
- min: 2523136
- max: 2523136
- avg: 2523136
+ min: 2523136.0
+ max: 2523136.0
+ avg: 2523136.0
+ delta: 0.0
}
file_rss {
- min: 2392064
- max: 2392064
- avg: 2392064
+ min: 2392064.0
+ max: 2392064.0
+ avg: 2392064.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 2523136
- max: 2523136
- avg: 2523136
+ min: 2523136.0
+ max: 2523136.0
+ avg: 2523136.0
+ delta: 0.0
}
}
}
@@ -28,24 +32,28 @@ android_mem {
process_name: "/system/bin/apexd"
total_counters {
anon_rss {
- min: 884736
- max: 884736
- avg: 884736
+ min: 884736.0
+ max: 884736.0
+ avg: 884736.0
+ delta: 0.0
}
file_rss {
- min: 2101248
- max: 2101248
- avg: 2101248
+ min: 2101248.0
+ max: 2101248.0
+ avg: 2101248.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 884736
- max: 884736
- avg: 884736
+ min: 884736.0
+ max: 884736.0
+ avg: 884736.0
+ delta: 0.0
}
}
}
@@ -53,24 +61,28 @@ android_mem {
process_name: "/system/bin/audioserver"
total_counters {
anon_rss {
- min: 3989504
- max: 3989504
- avg: 3989504
+ min: 3989504.0
+ max: 3989504.0
+ avg: 3989504.0
+ delta: 0.0
}
file_rss {
- min: 9334784
- max: 9334784
- avg: 9334784
+ min: 9334784.0
+ max: 9334784.0
+ avg: 9334784.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 3989504
- max: 3989504
- avg: 3989504
+ min: 3989504.0
+ max: 3989504.0
+ avg: 3989504.0
+ delta: 0.0
}
}
}
@@ -78,24 +90,28 @@ android_mem {
process_name: "/system/bin/cameraserver"
total_counters {
anon_rss {
- min: 2052096
- max: 2191360
+ min: 2052096.0
+ max: 2191360.0
avg: 2075342.7950470024
+ delta: 139264.0
}
file_rss {
- min: 6197248
- max: 6594560
- avg: 6277623.7430821592
+ min: 6197248.0
+ max: 6594560.0
+ avg: 6277623.743082159
+ delta: 397312.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 2052096
- max: 2191360
+ min: 2052096.0
+ max: 2191360.0
avg: 2075342.7950470024
+ delta: 139264.0
}
}
}
@@ -103,24 +119,28 @@ android_mem {
process_name: "/system/bin/drmserver"
total_counters {
anon_rss {
- min: 1552384
- max: 1552384
- avg: 1552384
+ min: 1552384.0
+ max: 1552384.0
+ avg: 1552384.0
+ delta: 0.0
}
file_rss {
- min: 4943872
- max: 4943872
- avg: 4943872
+ min: 4943872.0
+ max: 4943872.0
+ avg: 4943872.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1552384
- max: 1552384
- avg: 1552384
+ min: 1552384.0
+ max: 1552384.0
+ avg: 1552384.0
+ delta: 0.0
}
}
}
@@ -128,24 +148,28 @@ android_mem {
process_name: "/system/bin/folio_daemon"
total_counters {
anon_rss {
- min: 3444736
- max: 3444736
- avg: 3444736
+ min: 3444736.0
+ max: 3444736.0
+ avg: 3444736.0
+ delta: 0.0
}
file_rss {
- min: 8974336
- max: 8974336
- avg: 8974336
+ min: 8974336.0
+ max: 8974336.0
+ avg: 8974336.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 3444736
- max: 3444736
- avg: 3444736
+ min: 3444736.0
+ max: 3444736.0
+ avg: 3444736.0
+ delta: 0.0
}
}
}
@@ -153,24 +177,28 @@ android_mem {
process_name: "/system/bin/gatekeeperd"
total_counters {
anon_rss {
- min: 1134592
- max: 1134592
- avg: 1134592
+ min: 1134592.0
+ max: 1134592.0
+ avg: 1134592.0
+ delta: 0.0
}
file_rss {
- min: 2863104
- max: 2863104
- avg: 2863104
+ min: 2863104.0
+ max: 2863104.0
+ avg: 2863104.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1134592
- max: 1134592
- avg: 1134592
+ min: 1134592.0
+ max: 1134592.0
+ avg: 1134592.0
+ delta: 0.0
}
}
}
@@ -178,24 +206,28 @@ android_mem {
process_name: "/system/bin/gpuservice"
total_counters {
anon_rss {
- min: 1146880
- max: 1146880
- avg: 1146880
+ min: 1146880.0
+ max: 1146880.0
+ avg: 1146880.0
+ delta: 0.0
}
file_rss {
- min: 2678784
- max: 2678784
- avg: 2678784
+ min: 2678784.0
+ max: 2678784.0
+ avg: 2678784.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1146880
- max: 1146880
- avg: 1146880
+ min: 1146880.0
+ max: 1146880.0
+ avg: 1146880.0
+ delta: 0.0
}
}
}
@@ -203,24 +235,28 @@ android_mem {
process_name: "/system/bin/healthd"
total_counters {
anon_rss {
- min: 794624
- max: 794624
- avg: 794624
+ min: 794624.0
+ max: 794624.0
+ avg: 794624.0
+ delta: 0.0
}
file_rss {
- min: 2117632
- max: 2117632
- avg: 2117632
+ min: 2117632.0
+ max: 2117632.0
+ avg: 2117632.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 794624
- max: 794624
- avg: 794624
+ min: 794624.0
+ max: 794624.0
+ avg: 794624.0
+ delta: 0.0
}
}
}
@@ -228,24 +264,28 @@ android_mem {
process_name: "/system/bin/hw/android.hidl.allocator@1.0-service"
total_counters {
anon_rss {
- min: 770048
- max: 770048
- avg: 770048
+ min: 770048.0
+ max: 770048.0
+ avg: 770048.0
+ delta: 0.0
}
file_rss {
- min: 1875968
- max: 1875968
- avg: 1875968
+ min: 1875968.0
+ max: 1875968.0
+ avg: 1875968.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 770048
- max: 770048
- avg: 770048
+ min: 770048.0
+ max: 770048.0
+ avg: 770048.0
+ delta: 0.0
}
}
}
@@ -253,24 +293,28 @@ android_mem {
process_name: "/system/bin/hw/android.system.suspend@1.0-service"
total_counters {
anon_rss {
- min: 868352
- max: 868352
- avg: 868352
+ min: 868352.0
+ max: 868352.0
+ avg: 868352.0
+ delta: 0.0
}
file_rss {
- min: 2994176
- max: 2994176
- avg: 2994176
+ min: 2994176.0
+ max: 2994176.0
+ avg: 2994176.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 868352
- max: 868352
- avg: 868352
+ min: 868352.0
+ max: 868352.0
+ avg: 868352.0
+ delta: 0.0
}
}
}
@@ -278,24 +322,28 @@ android_mem {
process_name: "/system/bin/hwservicemanager"
total_counters {
anon_rss {
- min: 1314816
- max: 1417216
- avg: 1334151.2064734141
+ min: 1314816.0
+ max: 1417216.0
+ avg: 1334151.206473414
+ delta: 102400.0
}
file_rss {
- min: 2895872
- max: 2940928
+ min: 2895872.0
+ max: 2940928.0
avg: 2905098.926868665
+ delta: 45056.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1314816
- max: 1417216
- avg: 1334151.2064734141
+ min: 1314816.0
+ max: 1417216.0
+ avg: 1334151.206473414
+ delta: 102400.0
}
}
}
@@ -303,24 +351,28 @@ android_mem {
process_name: "/system/bin/incidentd"
total_counters {
anon_rss {
- min: 974848
- max: 974848
- avg: 974848
+ min: 974848.0
+ max: 974848.0
+ avg: 974848.0
+ delta: 0.0
}
file_rss {
- min: 2359296
- max: 2359296
- avg: 2359296
+ min: 2359296.0
+ max: 2359296.0
+ avg: 2359296.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 974848
- max: 974848
- avg: 974848
+ min: 974848.0
+ max: 974848.0
+ avg: 974848.0
+ delta: 0.0
}
}
}
@@ -328,24 +380,28 @@ android_mem {
process_name: "/system/bin/init"
total_counters {
anon_rss {
- min: 1355776
- max: 2281472
+ min: 1355776.0
+ max: 2281472.0
avg: 1686186.6666666667
+ delta: 0.0
}
file_rss {
- min: 2297856
- max: 3047424
+ min: 2297856.0
+ max: 3047424.0
avg: 2681514.6666666665
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1355776
- max: 2281472
+ min: 1355776.0
+ max: 2281472.0
avg: 1686186.6666666667
+ delta: 0.0
}
}
}
@@ -353,24 +409,28 @@ android_mem {
process_name: "/system/bin/installd"
total_counters {
anon_rss {
- min: 1699840
- max: 1699840
- avg: 1699840
+ min: 1699840.0
+ max: 1699840.0
+ avg: 1699840.0
+ delta: 0.0
}
file_rss {
- min: 2519040
- max: 2519040
- avg: 2519040
+ min: 2519040.0
+ max: 2519040.0
+ avg: 2519040.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1699840
- max: 1699840
- avg: 1699840
+ min: 1699840.0
+ max: 1699840.0
+ avg: 1699840.0
+ delta: 0.0
}
}
}
@@ -378,24 +438,28 @@ android_mem {
process_name: "/system/bin/iorapd"
total_counters {
anon_rss {
- min: 749568
- max: 749568
- avg: 749568
+ min: 749568.0
+ max: 749568.0
+ avg: 749568.0
+ delta: 0.0
}
file_rss {
- min: 1724416
- max: 1724416
- avg: 1724416
+ min: 1724416.0
+ max: 1724416.0
+ avg: 1724416.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 749568
- max: 749568
- avg: 749568
+ min: 749568.0
+ max: 749568.0
+ avg: 749568.0
+ delta: 0.0
}
}
}
@@ -403,24 +467,28 @@ android_mem {
process_name: "/system/bin/ip6tables-restore"
total_counters {
anon_rss {
- min: 897024
- max: 897024
- avg: 897024
+ min: 897024.0
+ max: 897024.0
+ avg: 897024.0
+ delta: 0.0
}
file_rss {
- min: 1445888
- max: 1445888
- avg: 1445888
+ min: 1445888.0
+ max: 1445888.0
+ avg: 1445888.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 897024
- max: 897024
- avg: 897024
+ min: 897024.0
+ max: 897024.0
+ avg: 897024.0
+ delta: 0.0
}
}
}
@@ -428,24 +496,28 @@ android_mem {
process_name: "/system/bin/iptables-restore"
total_counters {
anon_rss {
- min: 901120
- max: 901120
- avg: 901120
+ min: 901120.0
+ max: 901120.0
+ avg: 901120.0
+ delta: 0.0
}
file_rss {
- min: 1429504
- max: 1429504
- avg: 1429504
+ min: 1429504.0
+ max: 1429504.0
+ avg: 1429504.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 901120
- max: 901120
- avg: 901120
+ min: 901120.0
+ max: 901120.0
+ avg: 901120.0
+ delta: 0.0
}
}
}
@@ -453,24 +525,28 @@ android_mem {
process_name: "/system/bin/keystore"
total_counters {
anon_rss {
- min: 1302528
- max: 1302528
- avg: 1302528
+ min: 1302528.0
+ max: 1302528.0
+ avg: 1302528.0
+ delta: 0.0
}
file_rss {
- min: 3624960
- max: 3624960
- avg: 3624960
+ min: 3624960.0
+ max: 3624960.0
+ avg: 3624960.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1302528
- max: 1302528
- avg: 1302528
+ min: 1302528.0
+ max: 1302528.0
+ avg: 1302528.0
+ delta: 0.0
}
}
}
@@ -478,24 +554,28 @@ android_mem {
process_name: "/system/bin/lmkd"
total_counters {
anon_rss {
- min: 569344
- max: 569344
- avg: 569344
+ min: 569344.0
+ max: 569344.0
+ avg: 569344.0
+ delta: 0.0
}
file_rss {
- min: 1130496
- max: 1130496
- avg: 1130496
+ min: 1130496.0
+ max: 1130496.0
+ avg: 1130496.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 569344
- max: 569344
- avg: 569344
+ min: 569344.0
+ max: 569344.0
+ avg: 569344.0
+ delta: 0.0
}
}
}
@@ -503,24 +583,28 @@ android_mem {
process_name: "/system/bin/logd"
total_counters {
anon_rss {
- min: 7372800
- max: 7553024
+ min: 7372800.0
+ max: 7553024.0
avg: 7448831.74711258
+ delta: 180224.0
}
file_rss {
- min: 1527808
- max: 1527808
- avg: 1527808
+ min: 1527808.0
+ max: 1527808.0
+ avg: 1527808.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 7372800
- max: 7553024
+ min: 7372800.0
+ max: 7553024.0
avg: 7448831.74711258
+ delta: 180224.0
}
}
}
@@ -528,24 +612,28 @@ android_mem {
process_name: "/system/bin/mediadrmserver"
total_counters {
anon_rss {
- min: 823296
- max: 823296
- avg: 823296
+ min: 823296.0
+ max: 823296.0
+ avg: 823296.0
+ delta: 0.0
}
file_rss {
- min: 2424832
- max: 2424832
- avg: 2424832
+ min: 2424832.0
+ max: 2424832.0
+ avg: 2424832.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 823296
- max: 823296
- avg: 823296
+ min: 823296.0
+ max: 823296.0
+ avg: 823296.0
+ delta: 0.0
}
}
}
@@ -553,24 +641,28 @@ android_mem {
process_name: "/system/bin/mediaserver"
total_counters {
anon_rss {
- min: 3031040
- max: 3248128
+ min: 3031040.0
+ max: 3248128.0
avg: 3093219.997135757
+ delta: 217088.0
}
file_rss {
- min: 9068544
- max: 9179136
+ min: 9068544.0
+ max: 9179136.0
avg: 9086542.591674462
+ delta: 110592.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 3031040
- max: 3248128
+ min: 3031040.0
+ max: 3248128.0
avg: 3093219.997135757
+ delta: 217088.0
}
}
}
@@ -578,24 +670,28 @@ android_mem {
process_name: "/system/bin/netd"
total_counters {
anon_rss {
- min: 1515520
- max: 1515520
- avg: 1515520
+ min: 1515520.0
+ max: 1515520.0
+ avg: 1515520.0
+ delta: 0.0
}
file_rss {
- min: 3424256
- max: 3424256
- avg: 3424256
+ min: 3424256.0
+ max: 3424256.0
+ avg: 3424256.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1515520
- max: 1515520
- avg: 1515520
+ min: 1515520.0
+ max: 1515520.0
+ avg: 1515520.0
+ delta: 0.0
}
}
}
@@ -603,24 +699,28 @@ android_mem {
process_name: "/system/bin/perfprofd"
total_counters {
anon_rss {
- min: 1691648
- max: 1691648
- avg: 1691648
+ min: 1691648.0
+ max: 1691648.0
+ avg: 1691648.0
+ delta: 0.0
}
file_rss {
- min: 3538944
- max: 3538944
- avg: 3538944
+ min: 3538944.0
+ max: 3538944.0
+ avg: 3538944.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1691648
- max: 1691648
- avg: 1691648
+ min: 1691648.0
+ max: 1691648.0
+ avg: 1691648.0
+ delta: 0.0
}
}
}
@@ -628,24 +728,28 @@ android_mem {
process_name: "/system/bin/servicemanager"
total_counters {
anon_rss {
- min: 888832
- max: 888832
- avg: 888832
+ min: 888832.0
+ max: 888832.0
+ avg: 888832.0
+ delta: 0.0
}
file_rss {
- min: 1548288
- max: 1548288
- avg: 1548288
+ min: 1548288.0
+ max: 1548288.0
+ avg: 1548288.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 888832
- max: 888832
- avg: 888832
+ min: 888832.0
+ max: 888832.0
+ avg: 888832.0
+ delta: 0.0
}
}
}
@@ -653,24 +757,28 @@ android_mem {
process_name: "/system/bin/statsd"
total_counters {
anon_rss {
- min: 1196032
- max: 1196032
- avg: 1196032
+ min: 1196032.0
+ max: 1196032.0
+ avg: 1196032.0
+ delta: 0.0
}
file_rss {
- min: 3047424
- max: 3047424
- avg: 3047424
+ min: 3047424.0
+ max: 3047424.0
+ avg: 3047424.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1196032
- max: 1196032
- avg: 1196032
+ min: 1196032.0
+ max: 1196032.0
+ avg: 1196032.0
+ delta: 0.0
}
}
}
@@ -678,24 +786,28 @@ android_mem {
process_name: "/system/bin/storaged"
total_counters {
anon_rss {
- min: 1069056
- max: 1069056
- avg: 1069056
+ min: 1069056.0
+ max: 1069056.0
+ avg: 1069056.0
+ delta: 0.0
}
file_rss {
- min: 2637824
- max: 2637824
- avg: 2637824
+ min: 2637824.0
+ max: 2637824.0
+ avg: 2637824.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1069056
- max: 1069056
- avg: 1069056
+ min: 1069056.0
+ max: 1069056.0
+ avg: 1069056.0
+ delta: 0.0
}
}
}
@@ -703,24 +815,28 @@ android_mem {
process_name: "/system/bin/surfaceflinger"
total_counters {
anon_rss {
- min: 8888320
- max: 9207808
- avg: 9034572.8459068146
+ min: 8888320.0
+ max: 9207808.0
+ avg: 9034572.845906815
+ delta: 319488.0
}
file_rss {
- min: 16490496
- max: 16498688
+ min: 16490496.0
+ max: 16498688.0
avg: 16492131.200899113
+ delta: 8192.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 8888320
- max: 9207808
- avg: 9034572.8459068146
+ min: 8888320.0
+ max: 9207808.0
+ avg: 9034572.845906815
+ delta: 319488.0
}
}
}
@@ -728,24 +844,28 @@ android_mem {
process_name: "/system/bin/thermalserviced"
total_counters {
anon_rss {
- min: 901120
- max: 901120
- avg: 901120
+ min: 901120.0
+ max: 901120.0
+ avg: 901120.0
+ delta: 0.0
}
file_rss {
- min: 2269184
- max: 2269184
- avg: 2269184
+ min: 2269184.0
+ max: 2269184.0
+ avg: 2269184.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 901120
- max: 901120
- avg: 901120
+ min: 901120.0
+ max: 901120.0
+ avg: 901120.0
+ delta: 0.0
}
}
}
@@ -753,24 +873,28 @@ android_mem {
process_name: "/system/bin/tombstoned"
total_counters {
anon_rss {
- min: 552960
- max: 552960
- avg: 552960
+ min: 552960.0
+ max: 552960.0
+ avg: 552960.0
+ delta: 0.0
}
file_rss {
- min: 1138688
- max: 1138688
- avg: 1138688
+ min: 1138688.0
+ max: 1138688.0
+ avg: 1138688.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 552960
- max: 552960
- avg: 552960
+ min: 552960.0
+ max: 552960.0
+ avg: 552960.0
+ delta: 0.0
}
}
}
@@ -778,24 +902,28 @@ android_mem {
process_name: "/system/bin/traced"
total_counters {
anon_rss {
- min: 937984
- max: 7172096
- avg: 2960290.8411428952
+ min: 937984.0
+ max: 7172096.0
+ avg: 2960290.841142895
+ delta: 6234112.0
}
file_rss {
- min: 1740800
- max: 1744896
+ min: 1740800.0
+ max: 1744896.0
avg: 1743446.0249764551
+ delta: 4096.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 937984
- max: 7172096
- avg: 2960290.8411428952
+ min: 937984.0
+ max: 7172096.0
+ avg: 2960290.841142895
+ delta: 6234112.0
}
}
}
@@ -803,24 +931,28 @@ android_mem {
process_name: "/system/bin/traced_probes"
total_counters {
anon_rss {
- min: 929792
- max: 1056768
- avg: 992675.73074393929
+ min: 929792.0
+ max: 1056768.0
+ avg: 992675.7307439393
+ delta: 126976.0
}
file_rss {
- min: 1863680
- max: 1863680
- avg: 1863680
+ min: 1863680.0
+ max: 1863680.0
+ avg: 1863680.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 929792
- max: 1056768
- avg: 992675.73074393929
+ min: 929792.0
+ max: 1056768.0
+ avg: 992675.7307439393
+ delta: 126976.0
}
}
}
@@ -828,24 +960,28 @@ android_mem {
process_name: "/system/bin/ueventd"
total_counters {
anon_rss {
- min: 1437696
- max: 1437696
- avg: 1437696
+ min: 1437696.0
+ max: 1437696.0
+ avg: 1437696.0
+ delta: 0.0
}
file_rss {
- min: 2740224
- max: 2740224
- avg: 2740224
+ min: 2740224.0
+ max: 2740224.0
+ avg: 2740224.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1437696
- max: 1437696
- avg: 1437696
+ min: 1437696.0
+ max: 1437696.0
+ avg: 1437696.0
+ delta: 0.0
}
}
}
@@ -853,24 +989,28 @@ android_mem {
process_name: "/system/bin/update_engine"
total_counters {
anon_rss {
- min: 1421312
- max: 1421312
- avg: 1421312
+ min: 1421312.0
+ max: 1421312.0
+ avg: 1421312.0
+ delta: 0.0
}
file_rss {
- min: 4141056
- max: 4141056
- avg: 4141056
+ min: 4141056.0
+ max: 4141056.0
+ avg: 4141056.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1421312
- max: 1421312
- avg: 1421312
+ min: 1421312.0
+ max: 1421312.0
+ avg: 1421312.0
+ delta: 0.0
}
}
}
@@ -878,24 +1018,28 @@ android_mem {
process_name: "/system/bin/vold"
total_counters {
anon_rss {
- min: 1830912
- max: 1830912
- avg: 1830912
+ min: 1830912.0
+ max: 1830912.0
+ avg: 1830912.0
+ delta: 0.0
}
file_rss {
- min: 3612672
- max: 3612672
- avg: 3612672
+ min: 3612672.0
+ max: 3612672.0
+ avg: 3612672.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1830912
- max: 1830912
- avg: 1830912
+ min: 1830912.0
+ max: 1830912.0
+ avg: 1830912.0
+ delta: 0.0
}
}
}
@@ -903,24 +1047,28 @@ android_mem {
process_name: "/system/bin/wificond"
total_counters {
anon_rss {
- min: 1167360
- max: 1224704
+ min: 1167360.0
+ max: 1224704.0
avg: 1201049.4439232084
+ delta: 57344.0
}
file_rss {
- min: 2777088
- max: 2777088
- avg: 2777088
+ min: 2777088.0
+ max: 2777088.0
+ avg: 2777088.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1167360
- max: 1224704
+ min: 1167360.0
+ max: 1224704.0
avg: 1201049.4439232084
+ delta: 57344.0
}
}
}
@@ -928,24 +1076,28 @@ android_mem {
process_name: "/vendor/bin/adsprpcd"
total_counters {
anon_rss {
- min: 745472
- max: 745472
- avg: 745472
+ min: 745472.0
+ max: 745472.0
+ avg: 745472.0
+ delta: 0.0
}
file_rss {
- min: 1507328
- max: 1507328
- avg: 1507328
+ min: 1507328.0
+ max: 1507328.0
+ avg: 1507328.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 745472
- max: 745472
- avg: 745472
+ min: 745472.0
+ max: 745472.0
+ avg: 745472.0
+ delta: 0.0
}
}
}
@@ -953,24 +1105,28 @@ android_mem {
process_name: "/vendor/bin/chre"
total_counters {
anon_rss {
- min: 1929216
- max: 1929216
- avg: 1929216
+ min: 1929216.0
+ max: 1929216.0
+ avg: 1929216.0
+ delta: 0.0
}
file_rss {
- min: 1703936
- max: 1703936
- avg: 1703936
+ min: 1703936.0
+ max: 1703936.0
+ avg: 1703936.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1929216
- max: 1929216
- avg: 1929216
+ min: 1929216.0
+ max: 1929216.0
+ avg: 1929216.0
+ delta: 0.0
}
}
}
@@ -978,24 +1134,28 @@ android_mem {
process_name: "/vendor/bin/cnd"
total_counters {
anon_rss {
- min: 1552384
- max: 1552384
- avg: 1552384
+ min: 1552384.0
+ max: 1552384.0
+ avg: 1552384.0
+ delta: 0.0
}
file_rss {
- min: 3313664
- max: 3313664
- avg: 3313664
+ min: 3313664.0
+ max: 3313664.0
+ avg: 3313664.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1552384
- max: 1552384
- avg: 1552384
+ min: 1552384.0
+ max: 1552384.0
+ avg: 1552384.0
+ delta: 0.0
}
}
}
@@ -1003,24 +1163,28 @@ android_mem {
process_name: "/vendor/bin/cnss-daemon"
total_counters {
anon_rss {
- min: 1363968
- max: 1363968
- avg: 1363968
+ min: 1363968.0
+ max: 1363968.0
+ avg: 1363968.0
+ delta: 0.0
}
file_rss {
- min: 2265088
- max: 2265088
- avg: 2265088
+ min: 2265088.0
+ max: 2265088.0
+ avg: 2265088.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1363968
- max: 1363968
- avg: 1363968
+ min: 1363968.0
+ max: 1363968.0
+ avg: 1363968.0
+ delta: 0.0
}
}
}
@@ -1028,24 +1192,28 @@ android_mem {
process_name: "/vendor/bin/esed"
total_counters {
anon_rss {
- min: 921600
- max: 921600
- avg: 921600
+ min: 921600.0
+ max: 921600.0
+ avg: 921600.0
+ delta: 0.0
}
file_rss {
- min: 2301952
- max: 2301952
- avg: 2301952
+ min: 2301952.0
+ max: 2301952.0
+ avg: 2301952.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 921600
- max: 921600
- avg: 921600
+ min: 921600.0
+ max: 921600.0
+ avg: 921600.0
+ delta: 0.0
}
}
}
@@ -1053,24 +1221,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.audio@2.0-service"
total_counters {
anon_rss {
- min: 7827456
- max: 7835648
- avg: 7828961.4625952831
+ min: 7827456.0
+ max: 7835648.0
+ avg: 7828961.462595283
+ delta: 8192.0
}
file_rss {
- min: 5828608
- max: 5853184
+ min: 5828608.0
+ max: 5853184.0
avg: 5833124.38778585
+ delta: 24576.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 7827456
- max: 7835648
- avg: 7828961.4625952831
+ min: 7827456.0
+ max: 7835648.0
+ avg: 7828961.462595283
+ delta: 8192.0
}
}
}
@@ -1078,24 +1250,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.biometrics.fingerprint@2.1-service.fpc"
total_counters {
anon_rss {
- min: 987136
- max: 987136
- avg: 987136
+ min: 987136.0
+ max: 987136.0
+ avg: 987136.0
+ delta: 0.0
}
file_rss {
- min: 2682880
- max: 2682880
- avg: 2682880
+ min: 2682880.0
+ max: 2682880.0
+ avg: 2682880.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 987136
- max: 987136
- avg: 987136
+ min: 987136.0
+ max: 987136.0
+ avg: 987136.0
+ delta: 0.0
}
}
}
@@ -1103,24 +1279,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.bluetooth@1.0-service-qti"
total_counters {
anon_rss {
- min: 1134592
- max: 1134592
- avg: 1134592
+ min: 1134592.0
+ max: 1134592.0
+ avg: 1134592.0
+ delta: 0.0
}
file_rss {
- min: 2670592
- max: 2670592
- avg: 2670592
+ min: 2670592.0
+ max: 2670592.0
+ avg: 2670592.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1134592
- max: 1134592
- avg: 1134592
+ min: 1134592.0
+ max: 1134592.0
+ avg: 1134592.0
+ delta: 0.0
}
}
}
@@ -1128,24 +1308,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.boot@1.0-service"
total_counters {
anon_rss {
- min: 933888
- max: 933888
- avg: 933888
+ min: 933888.0
+ max: 933888.0
+ avg: 933888.0
+ delta: 0.0
}
file_rss {
- min: 2416640
- max: 2416640
- avg: 2416640
+ min: 2416640.0
+ max: 2416640.0
+ avg: 2416640.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 933888
- max: 933888
- avg: 933888
+ min: 933888.0
+ max: 933888.0
+ avg: 933888.0
+ delta: 0.0
}
}
}
@@ -1153,24 +1337,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.camera.provider@2.4-service"
total_counters {
anon_rss {
- min: 19959808
- max: 30146560
+ min: 19959808.0
+ max: 30146560.0
avg: 20339380.697334375
+ delta: 10186752.0
}
file_rss {
- min: 19906560
- max: 20475904
- avg: 19984240.090238161
+ min: 19906560.0
+ max: 20475904.0
+ avg: 19984240.09023816
+ delta: 569344.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 19959808
- max: 30146560
+ min: 19959808.0
+ max: 30146560.0
avg: 20339380.697334375
+ delta: 10186752.0
}
}
}
@@ -1178,24 +1366,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.cas@1.0-service"
total_counters {
anon_rss {
- min: 753664
- max: 753664
- avg: 753664
+ min: 753664.0
+ max: 753664.0
+ avg: 753664.0
+ delta: 0.0
}
file_rss {
- min: 2359296
- max: 2359296
- avg: 2359296
+ min: 2359296.0
+ max: 2359296.0
+ avg: 2359296.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 753664
- max: 753664
- avg: 753664
+ min: 753664.0
+ max: 753664.0
+ avg: 753664.0
+ delta: 0.0
}
}
}
@@ -1203,24 +1395,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.configstore@1.1-service"
total_counters {
anon_rss {
- min: 954368
- max: 954368
- avg: 954368
+ min: 954368.0
+ max: 954368.0
+ avg: 954368.0
+ delta: 0.0
}
file_rss {
- min: 2400256
- max: 2400256
- avg: 2400256
+ min: 2400256.0
+ max: 2400256.0
+ avg: 2400256.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 954368
- max: 954368
- avg: 954368
+ min: 954368.0
+ max: 954368.0
+ avg: 954368.0
+ delta: 0.0
}
}
}
@@ -1228,24 +1424,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.contexthub@1.0-service"
total_counters {
anon_rss {
- min: 925696
- max: 925696
- avg: 925696
+ min: 925696.0
+ max: 925696.0
+ avg: 925696.0
+ delta: 0.0
}
file_rss {
- min: 2424832
- max: 2424832
- avg: 2424832
+ min: 2424832.0
+ max: 2424832.0
+ avg: 2424832.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 925696
- max: 925696
- avg: 925696
+ min: 925696.0
+ max: 925696.0
+ avg: 925696.0
+ delta: 0.0
}
}
}
@@ -1253,24 +1453,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.drm@1.0-service"
total_counters {
anon_rss {
- min: 884736
- max: 884736
- avg: 884736
+ min: 884736.0
+ max: 884736.0
+ avg: 884736.0
+ delta: 0.0
}
file_rss {
- min: 2772992
- max: 2772992
- avg: 2772992
+ min: 2772992.0
+ max: 2772992.0
+ avg: 2772992.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 884736
- max: 884736
- avg: 884736
+ min: 884736.0
+ max: 884736.0
+ avg: 884736.0
+ delta: 0.0
}
}
}
@@ -1278,24 +1482,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.drm@1.1-service.clearkey"
total_counters {
anon_rss {
- min: 1056768
- max: 1056768
- avg: 1056768
+ min: 1056768.0
+ max: 1056768.0
+ avg: 1056768.0
+ delta: 0.0
}
file_rss {
- min: 2912256
- max: 2912256
- avg: 2912256
+ min: 2912256.0
+ max: 2912256.0
+ avg: 2912256.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1056768
- max: 1056768
- avg: 1056768
+ min: 1056768.0
+ max: 1056768.0
+ avg: 1056768.0
+ delta: 0.0
}
}
}
@@ -1303,24 +1511,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.drm@1.1-service.widevine"
total_counters {
anon_rss {
- min: 901120
- max: 901120
- avg: 901120
+ min: 901120.0
+ max: 901120.0
+ avg: 901120.0
+ delta: 0.0
}
file_rss {
- min: 3371008
- max: 3371008
- avg: 3371008
+ min: 3371008.0
+ max: 3371008.0
+ avg: 3371008.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 901120
- max: 901120
- avg: 901120
+ min: 901120.0
+ max: 901120.0
+ avg: 901120.0
+ delta: 0.0
}
}
}
@@ -1328,24 +1540,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.dumpstate@1.0-service.wahoo"
total_counters {
anon_rss {
- min: 856064
- max: 856064
- avg: 856064
+ min: 856064.0
+ max: 856064.0
+ avg: 856064.0
+ delta: 0.0
}
file_rss {
- min: 2285568
- max: 2285568
- avg: 2285568
+ min: 2285568.0
+ max: 2285568.0
+ avg: 2285568.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 856064
- max: 856064
- avg: 856064
+ min: 856064.0
+ max: 856064.0
+ avg: 856064.0
+ delta: 0.0
}
}
}
@@ -1353,24 +1569,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.gatekeeper@1.0-service-qti"
total_counters {
anon_rss {
- min: 978944
- max: 978944
- avg: 978944
+ min: 978944.0
+ max: 978944.0
+ avg: 978944.0
+ delta: 0.0
}
file_rss {
- min: 2523136
- max: 2523136
- avg: 2523136
+ min: 2523136.0
+ max: 2523136.0
+ avg: 2523136.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 978944
- max: 978944
- avg: 978944
+ min: 978944.0
+ max: 978944.0
+ avg: 978944.0
+ delta: 0.0
}
}
}
@@ -1378,24 +1598,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.gnss@1.0-service-qti"
total_counters {
anon_rss {
- min: 2297856
- max: 2297856
- avg: 2297856
+ min: 2297856.0
+ max: 2297856.0
+ avg: 2297856.0
+ delta: 0.0
}
file_rss {
- min: 4608000
- max: 4608000
- avg: 4608000
+ min: 4608000.0
+ max: 4608000.0
+ avg: 4608000.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 2297856
- max: 2297856
- avg: 2297856
+ min: 2297856.0
+ max: 2297856.0
+ avg: 2297856.0
+ delta: 0.0
}
}
}
@@ -1403,24 +1627,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.graphics.allocator@2.0-service"
total_counters {
anon_rss {
- min: 1036288
- max: 1036288
- avg: 1036288
+ min: 1036288.0
+ max: 1036288.0
+ avg: 1036288.0
+ delta: 0.0
}
file_rss {
- min: 2646016
- max: 2646016
- avg: 2646016
+ min: 2646016.0
+ max: 2646016.0
+ avg: 2646016.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1036288
- max: 1036288
- avg: 1036288
+ min: 1036288.0
+ max: 1036288.0
+ avg: 1036288.0
+ delta: 0.0
}
}
}
@@ -1428,24 +1656,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.graphics.composer@2.1-service"
total_counters {
anon_rss {
- min: 7061504
- max: 7127040
+ min: 7061504.0
+ max: 7127040.0
avg: 7093193.651419105
+ delta: 65536.0
}
file_rss {
- min: 6201344
- max: 6209536
- avg: 6206722.4514569445
+ min: 6201344.0
+ max: 6209536.0
+ avg: 6206722.451456944
+ delta: 8192.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 7061504
- max: 7127040
+ min: 7061504.0
+ max: 7127040.0
avg: 7093193.651419105
+ delta: 65536.0
}
}
}
@@ -1453,24 +1685,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.health@2.0-service.wahoo"
total_counters {
anon_rss {
- min: 884736
- max: 884736
- avg: 884736
+ min: 884736.0
+ max: 884736.0
+ avg: 884736.0
+ delta: 0.0
}
file_rss {
- min: 2453504
- max: 2453504
- avg: 2453504
+ min: 2453504.0
+ max: 2453504.0
+ avg: 2453504.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 884736
- max: 884736
- avg: 884736
+ min: 884736.0
+ max: 884736.0
+ avg: 884736.0
+ delta: 0.0
}
}
}
@@ -1478,24 +1714,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.keymaster@3.0-service-qti"
total_counters {
anon_rss {
- min: 1024000
- max: 1024000
- avg: 1024000
+ min: 1024000.0
+ max: 1024000.0
+ avg: 1024000.0
+ delta: 0.0
}
file_rss {
- min: 2637824
- max: 2637824
- avg: 2637824
+ min: 2637824.0
+ max: 2637824.0
+ avg: 2637824.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1024000
- max: 1024000
- avg: 1024000
+ min: 1024000.0
+ max: 1024000.0
+ avg: 1024000.0
+ delta: 0.0
}
}
}
@@ -1503,24 +1743,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.light@2.0-service"
total_counters {
anon_rss {
- min: 880640
- max: 880640
- avg: 880640
+ min: 880640.0
+ max: 880640.0
+ avg: 880640.0
+ delta: 0.0
}
file_rss {
- min: 2248704
- max: 2248704
- avg: 2248704
+ min: 2248704.0
+ max: 2248704.0
+ avg: 2248704.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 880640
- max: 880640
- avg: 880640
+ min: 880640.0
+ max: 880640.0
+ avg: 880640.0
+ delta: 0.0
}
}
}
@@ -1528,24 +1772,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.memtrack@1.0-service"
total_counters {
anon_rss {
- min: 868352
- max: 868352
- avg: 868352
+ min: 868352.0
+ max: 868352.0
+ avg: 868352.0
+ delta: 0.0
}
file_rss {
- min: 2347008
- max: 2347008
- avg: 2347008
+ min: 2347008.0
+ max: 2347008.0
+ avg: 2347008.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 868352
- max: 868352
- avg: 868352
+ min: 868352.0
+ max: 868352.0
+ avg: 868352.0
+ delta: 0.0
}
}
}
@@ -1553,24 +1801,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.nfc@1.1-service"
total_counters {
anon_rss {
- min: 1064960
- max: 1064960
- avg: 1064960
+ min: 1064960.0
+ max: 1064960.0
+ avg: 1064960.0
+ delta: 0.0
}
file_rss {
- min: 2842624
- max: 2842624
- avg: 2842624
+ min: 2842624.0
+ max: 2842624.0
+ avg: 2842624.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1064960
- max: 1064960
- avg: 1064960
+ min: 1064960.0
+ max: 1064960.0
+ avg: 1064960.0
+ delta: 0.0
}
}
}
@@ -1578,24 +1830,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.oemlock@1.0-service"
total_counters {
anon_rss {
- min: 868352
- max: 868352
- avg: 868352
+ min: 868352.0
+ max: 868352.0
+ avg: 868352.0
+ delta: 0.0
}
file_rss {
- min: 2273280
- max: 2273280
- avg: 2273280
+ min: 2273280.0
+ max: 2273280.0
+ avg: 2273280.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 868352
- max: 868352
- avg: 868352
+ min: 868352.0
+ max: 868352.0
+ avg: 868352.0
+ delta: 0.0
}
}
}
@@ -1603,24 +1859,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.power@1.2-service.wahoo-libperfmgr"
total_counters {
anon_rss {
- min: 1007616
- max: 1007616
- avg: 1007616
+ min: 1007616.0
+ max: 1007616.0
+ avg: 1007616.0
+ delta: 0.0
}
file_rss {
- min: 2568192
- max: 2568192
- avg: 2568192
+ min: 2568192.0
+ max: 2568192.0
+ avg: 2568192.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1007616
- max: 1007616
- avg: 1007616
+ min: 1007616.0
+ max: 1007616.0
+ avg: 1007616.0
+ delta: 0.0
}
}
}
@@ -1628,24 +1888,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.sensors@1.0-service"
total_counters {
anon_rss {
- min: 1605632
- max: 1605632
- avg: 1605632
+ min: 1605632.0
+ max: 1605632.0
+ avg: 1605632.0
+ delta: 0.0
}
file_rss {
- min: 4190208
- max: 4190208
- avg: 4190208
+ min: 4190208.0
+ max: 4190208.0
+ avg: 4190208.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1605632
- max: 1605632
- avg: 1605632
+ min: 1605632.0
+ max: 1605632.0
+ avg: 1605632.0
+ delta: 0.0
}
}
}
@@ -1653,24 +1917,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.usb@1.1-service.wahoo"
total_counters {
anon_rss {
- min: 1064960
- max: 1064960
- avg: 1064960
+ min: 1064960.0
+ max: 1064960.0
+ avg: 1064960.0
+ delta: 0.0
}
file_rss {
- min: 2486272
- max: 2486272
- avg: 2486272
+ min: 2486272.0
+ max: 2486272.0
+ avg: 2486272.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1064960
- max: 1064960
- avg: 1064960
+ min: 1064960.0
+ max: 1064960.0
+ avg: 1064960.0
+ delta: 0.0
}
}
}
@@ -1678,24 +1946,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.vibrator@1.2-service.wahoo"
total_counters {
anon_rss {
- min: 925696
- max: 925696
- avg: 925696
+ min: 925696.0
+ max: 925696.0
+ avg: 925696.0
+ delta: 0.0
}
file_rss {
- min: 2416640
- max: 2416640
- avg: 2416640
+ min: 2416640.0
+ max: 2416640.0
+ avg: 2416640.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 925696
- max: 925696
- avg: 925696
+ min: 925696.0
+ max: 925696.0
+ avg: 925696.0
+ delta: 0.0
}
}
}
@@ -1703,24 +1975,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.vr@1.0-service.wahoo"
total_counters {
anon_rss {
- min: 856064
- max: 856064
- avg: 856064
+ min: 856064.0
+ max: 856064.0
+ avg: 856064.0
+ delta: 0.0
}
file_rss {
- min: 2265088
- max: 2265088
- avg: 2265088
+ min: 2265088.0
+ max: 2265088.0
+ avg: 2265088.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 856064
- max: 856064
- avg: 856064
+ min: 856064.0
+ max: 856064.0
+ avg: 856064.0
+ delta: 0.0
}
}
}
@@ -1728,24 +2004,28 @@ android_mem {
process_name: "/vendor/bin/hw/android.hardware.wifi@1.0-service"
total_counters {
anon_rss {
- min: 4300800
- max: 4362240
+ min: 4300800.0
+ max: 4362240.0
avg: 4333974.416470373
+ delta: 61440.0
}
file_rss {
- min: 3801088
- max: 3801088
- avg: 3801088
+ min: 3801088.0
+ max: 3801088.0
+ avg: 3801088.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 4300800
- max: 4362240
+ min: 4300800.0
+ max: 4362240.0
avg: 4333974.416470373
+ delta: 61440.0
}
}
}
@@ -1753,24 +2033,28 @@ android_mem {
process_name: "/vendor/bin/hw/rild"
total_counters {
anon_rss {
- min: 4169728
- max: 4169728
- avg: 4169728
+ min: 4169728.0
+ max: 4169728.0
+ avg: 4169728.0
+ delta: 0.0
}
file_rss {
- min: 14327808
- max: 14327808
- avg: 14327808
+ min: 14327808.0
+ max: 14327808.0
+ avg: 14327808.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 4169728
- max: 4169728
- avg: 4169728
+ min: 4169728.0
+ max: 4169728.0
+ avg: 4169728.0
+ delta: 0.0
}
}
}
@@ -1778,24 +2062,28 @@ android_mem {
process_name: "/vendor/bin/hw/wpa_supplicant"
total_counters {
anon_rss {
- min: 1421312
- max: 1425408
+ min: 1421312.0
+ max: 1425408.0
avg: 1422839.3064999864
+ delta: 4096.0
}
file_rss {
- min: 4632576
- max: 4632576
- avg: 4632576
+ min: 4632576.0
+ max: 4632576.0
+ avg: 4632576.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1421312
- max: 1425408
+ min: 1421312.0
+ max: 1425408.0
avg: 1422839.3064999864
+ delta: 4096.0
}
}
}
@@ -1803,24 +2091,28 @@ android_mem {
process_name: "/vendor/bin/imsdatadaemon"
total_counters {
anon_rss {
- min: 1683456
- max: 1683456
- avg: 1683456
+ min: 1683456.0
+ max: 1683456.0
+ avg: 1683456.0
+ delta: 0.0
}
file_rss {
- min: 2973696
- max: 2973696
- avg: 2973696
+ min: 2973696.0
+ max: 2973696.0
+ avg: 2973696.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1683456
- max: 1683456
- avg: 1683456
+ min: 1683456.0
+ max: 1683456.0
+ avg: 1683456.0
+ delta: 0.0
}
}
}
@@ -1828,24 +2120,28 @@ android_mem {
process_name: "/vendor/bin/imsqmidaemon"
total_counters {
anon_rss {
- min: 901120
- max: 901120
- avg: 901120
+ min: 901120.0
+ max: 901120.0
+ avg: 901120.0
+ delta: 0.0
}
file_rss {
- min: 1757184
- max: 1757184
- avg: 1757184
+ min: 1757184.0
+ max: 1757184.0
+ avg: 1757184.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 901120
- max: 901120
- avg: 901120
+ min: 901120.0
+ max: 901120.0
+ avg: 901120.0
+ delta: 0.0
}
}
}
@@ -1853,24 +2149,28 @@ android_mem {
process_name: "/vendor/bin/ipacm"
total_counters {
anon_rss {
- min: 1089536
- max: 1089536
- avg: 1089536
+ min: 1089536.0
+ max: 1089536.0
+ avg: 1089536.0
+ delta: 0.0
}
file_rss {
- min: 3125248
- max: 3125248
- avg: 3125248
+ min: 3125248.0
+ max: 3125248.0
+ avg: 3125248.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1089536
- max: 1089536
- avg: 1089536
+ min: 1089536.0
+ max: 1089536.0
+ avg: 1089536.0
+ delta: 0.0
}
}
}
@@ -1878,24 +2178,28 @@ android_mem {
process_name: "/vendor/bin/loc_launcher"
total_counters {
anon_rss {
- min: 741376
- max: 741376
- avg: 741376
+ min: 741376.0
+ max: 741376.0
+ avg: 741376.0
+ delta: 0.0
}
file_rss {
- min: 1617920
- max: 1617920
- avg: 1617920
+ min: 1617920.0
+ max: 1617920.0
+ avg: 1617920.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 741376
- max: 741376
- avg: 741376
+ min: 741376.0
+ max: 741376.0
+ avg: 741376.0
+ delta: 0.0
}
}
}
@@ -1903,24 +2207,28 @@ android_mem {
process_name: "/vendor/bin/msm_irqbalance"
total_counters {
anon_rss {
- min: 761856
- max: 761856
- avg: 761856
+ min: 761856.0
+ max: 761856.0
+ avg: 761856.0
+ delta: 0.0
}
file_rss {
- min: 1630208
- max: 1630208
- avg: 1630208
+ min: 1630208.0
+ max: 1630208.0
+ avg: 1630208.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 761856
- max: 761856
- avg: 761856
+ min: 761856.0
+ max: 761856.0
+ avg: 761856.0
+ delta: 0.0
}
}
}
@@ -1928,24 +2236,28 @@ android_mem {
process_name: "/vendor/bin/netmgrd"
total_counters {
anon_rss {
- min: 3330048
- max: 3330048
- avg: 3330048
+ min: 3330048.0
+ max: 3330048.0
+ avg: 3330048.0
+ delta: 0.0
}
file_rss {
- min: 4530176
- max: 4530176
- avg: 4530176
+ min: 4530176.0
+ max: 4530176.0
+ avg: 4530176.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 3330048
- max: 3330048
- avg: 3330048
+ min: 3330048.0
+ max: 3330048.0
+ avg: 3330048.0
+ delta: 0.0
}
}
}
@@ -1953,24 +2265,28 @@ android_mem {
process_name: "/vendor/bin/oemlock-bridge"
total_counters {
anon_rss {
- min: 659456
- max: 659456
- avg: 659456
+ min: 659456.0
+ max: 659456.0
+ avg: 659456.0
+ delta: 0.0
}
file_rss {
- min: 1441792
- max: 1441792
- avg: 1441792
+ min: 1441792.0
+ max: 1441792.0
+ avg: 1441792.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 659456
- max: 659456
- avg: 659456
+ min: 659456.0
+ max: 659456.0
+ avg: 659456.0
+ delta: 0.0
}
}
}
@@ -1978,24 +2294,28 @@ android_mem {
process_name: "/vendor/bin/pd-mapper"
total_counters {
anon_rss {
- min: 884736
- max: 884736
- avg: 884736
+ min: 884736.0
+ max: 884736.0
+ avg: 884736.0
+ delta: 0.0
}
file_rss {
- min: 1736704
- max: 1736704
- avg: 1736704
+ min: 1736704.0
+ max: 1736704.0
+ avg: 1736704.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 884736
- max: 884736
- avg: 884736
+ min: 884736.0
+ max: 884736.0
+ avg: 884736.0
+ delta: 0.0
}
}
}
@@ -2003,24 +2323,28 @@ android_mem {
process_name: "/vendor/bin/pm-proxy"
total_counters {
anon_rss {
- min: 778240
- max: 778240
- avg: 778240
+ min: 778240.0
+ max: 778240.0
+ avg: 778240.0
+ delta: 0.0
}
file_rss {
- min: 1798144
- max: 1798144
- avg: 1798144
+ min: 1798144.0
+ max: 1798144.0
+ avg: 1798144.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 778240
- max: 778240
- avg: 778240
+ min: 778240.0
+ max: 778240.0
+ avg: 778240.0
+ delta: 0.0
}
}
}
@@ -2028,24 +2352,28 @@ android_mem {
process_name: "/vendor/bin/pm-service"
total_counters {
anon_rss {
- min: 966656
- max: 966656
- avg: 966656
+ min: 966656.0
+ max: 966656.0
+ avg: 966656.0
+ delta: 0.0
}
file_rss {
- min: 2080768
- max: 2080768
- avg: 2080768
+ min: 2080768.0
+ max: 2080768.0
+ avg: 2080768.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 966656
- max: 966656
- avg: 966656
+ min: 966656.0
+ max: 966656.0
+ avg: 966656.0
+ delta: 0.0
}
}
}
@@ -2053,24 +2381,28 @@ android_mem {
process_name: "/vendor/bin/port-bridge"
total_counters {
anon_rss {
- min: 696320
- max: 696320
- avg: 696320
+ min: 696320.0
+ max: 696320.0
+ avg: 696320.0
+ delta: 0.0
}
file_rss {
- min: 1470464
- max: 1470464
- avg: 1470464
+ min: 1470464.0
+ max: 1470464.0
+ avg: 1470464.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 696320
- max: 696320
- avg: 696320
+ min: 696320.0
+ max: 696320.0
+ avg: 696320.0
+ delta: 0.0
}
}
}
@@ -2078,24 +2410,28 @@ android_mem {
process_name: "/vendor/bin/qseecomd"
total_counters {
anon_rss {
- min: 729088
- max: 815104
- avg: 772096
+ min: 729088.0
+ max: 815104.0
+ avg: 772096.0
+ delta: 0.0
}
file_rss {
- min: 749568
- max: 1642496
- avg: 1196032
+ min: 749568.0
+ max: 1642496.0
+ avg: 1196032.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 729088
- max: 815104
- avg: 772096
+ min: 729088.0
+ max: 815104.0
+ avg: 772096.0
+ delta: 0.0
}
}
}
@@ -2103,24 +2439,28 @@ android_mem {
process_name: "/vendor/bin/qti"
total_counters {
anon_rss {
- min: 1069056
- max: 1069056
- avg: 1069056
+ min: 1069056.0
+ max: 1069056.0
+ avg: 1069056.0
+ delta: 0.0
}
file_rss {
- min: 1925120
- max: 1925120
- avg: 1925120
+ min: 1925120.0
+ max: 1925120.0
+ avg: 1925120.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1069056
- max: 1069056
- avg: 1069056
+ min: 1069056.0
+ max: 1069056.0
+ avg: 1069056.0
+ delta: 0.0
}
}
}
@@ -2128,24 +2468,28 @@ android_mem {
process_name: "/vendor/bin/rmt_storage"
total_counters {
anon_rss {
- min: 794624
- max: 794624
- avg: 794624
+ min: 794624.0
+ max: 794624.0
+ avg: 794624.0
+ delta: 0.0
}
file_rss {
- min: 1634304
- max: 1634304
- avg: 1634304
+ min: 1634304.0
+ max: 1634304.0
+ avg: 1634304.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 794624
- max: 794624
- avg: 794624
+ min: 794624.0
+ max: 794624.0
+ avg: 794624.0
+ delta: 0.0
}
}
}
@@ -2153,24 +2497,28 @@ android_mem {
process_name: "/vendor/bin/sensors.qcom"
total_counters {
anon_rss {
- min: 868352
- max: 872448
+ min: 868352.0
+ max: 872448.0
avg: 871437.0053584798
+ delta: 0.0
}
file_rss {
- min: 1986560
- max: 1986560
- avg: 1986560
+ min: 1986560.0
+ max: 1986560.0
+ avg: 1986560.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 868352
- max: 872448
+ min: 868352.0
+ max: 872448.0
avg: 871437.0053584798
+ delta: 0.0
}
}
}
@@ -2178,24 +2526,28 @@ android_mem {
process_name: "/vendor/bin/subsystem_ramdump"
total_counters {
anon_rss {
- min: 663552
- max: 663552
- avg: 663552
+ min: 663552.0
+ max: 663552.0
+ avg: 663552.0
+ delta: 0.0
}
file_rss {
- min: 1441792
- max: 1441792
- avg: 1441792
+ min: 1441792.0
+ max: 1441792.0
+ avg: 1441792.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 663552
- max: 663552
- avg: 663552
+ min: 663552.0
+ max: 663552.0
+ avg: 663552.0
+ delta: 0.0
}
}
}
@@ -2203,24 +2555,28 @@ android_mem {
process_name: "/vendor/bin/tftp_server"
total_counters {
anon_rss {
- min: 565248
- max: 565248
- avg: 565248
+ min: 565248.0
+ max: 565248.0
+ avg: 565248.0
+ delta: 0.0
}
file_rss {
- min: 1703936
- max: 1703936
- avg: 1703936
+ min: 1703936.0
+ max: 1703936.0
+ avg: 1703936.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 565248
- max: 565248
- avg: 565248
+ min: 565248.0
+ max: 565248.0
+ avg: 565248.0
+ delta: 0.0
}
}
}
@@ -2228,24 +2584,28 @@ android_mem {
process_name: "/vendor/bin/thermal-engine"
total_counters {
anon_rss {
- min: 1912832
- max: 1912832
- avg: 1912832
+ min: 1912832.0
+ max: 1912832.0
+ avg: 1912832.0
+ delta: 0.0
}
file_rss {
- min: 2813952
- max: 2813952
- avg: 2813952
+ min: 2813952.0
+ max: 2813952.0
+ avg: 2813952.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1912832
- max: 1912832
- avg: 1912832
+ min: 1912832.0
+ max: 1912832.0
+ avg: 1912832.0
+ delta: 0.0
}
}
}
@@ -2253,24 +2613,28 @@ android_mem {
process_name: "/vendor/bin/time_daemon"
total_counters {
anon_rss {
- min: 1130496
- max: 1130496
- avg: 1130496
+ min: 1130496.0
+ max: 1130496.0
+ avg: 1130496.0
+ delta: 0.0
}
file_rss {
- min: 1802240
- max: 1802240
- avg: 1802240
+ min: 1802240.0
+ max: 1802240.0
+ avg: 1802240.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1130496
- max: 1130496
- avg: 1130496
+ min: 1130496.0
+ max: 1130496.0
+ avg: 1130496.0
+ delta: 0.0
}
}
}
@@ -2278,24 +2642,28 @@ android_mem {
process_name: "/vendor/bin/vndservicemanager"
total_counters {
anon_rss {
- min: 749568
- max: 749568
- avg: 749568
+ min: 749568.0
+ max: 749568.0
+ avg: 749568.0
+ delta: 0.0
}
file_rss {
- min: 1716224
- max: 1716224
- avg: 1716224
+ min: 1716224.0
+ max: 1716224.0
+ avg: 1716224.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 749568
- max: 749568
- avg: 749568
+ min: 749568.0
+ max: 749568.0
+ avg: 749568.0
+ delta: 0.0
}
}
}
@@ -2303,24 +2671,28 @@ android_mem {
process_name: "android.ext.services"
total_counters {
anon_rss {
- min: 30580736
- max: 30580736
- avg: 30580736
+ min: 30580736.0
+ max: 30580736.0
+ avg: 30580736.0
+ delta: 0.0
}
file_rss {
- min: 24633344
- max: 24633344
- avg: 24633344
+ min: 24633344.0
+ max: 24633344.0
+ avg: 24633344.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 30580736
- max: 30580736
- avg: 30580736
+ min: 30580736.0
+ max: 30580736.0
+ avg: 30580736.0
+ delta: 0.0
}
}
}
@@ -2328,29 +2700,34 @@ android_mem {
process_name: "android.process.acore"
total_counters {
anon_rss {
- min: 32718848
- max: 32796672
+ min: 32718848.0
+ max: 32796672.0
avg: 32765771.09452733
+ delta: 77824.0
}
file_rss {
- min: 31182848
- max: 31232000
+ min: 31182848.0
+ max: 31232000.0
avg: 31213957.855388246
+ delta: 49152.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 32718848
- max: 32796672
+ min: 32718848.0
+ max: 32796672.0
avg: 32765771.09452733
+ delta: 77824.0
}
java_heap {
- min: 1374208
- max: 1427456
+ min: 1374208.0
+ max: 1427456.0
avg: 1419596.8920014114
+ delta: 16384.0
}
}
}
@@ -2358,29 +2735,34 @@ android_mem {
process_name: "android.process.media"
total_counters {
anon_rss {
- min: 30797824
- max: 31100928
+ min: 30797824.0
+ max: 31100928.0
avg: 30828073.014492534
+ delta: 303104.0
}
file_rss {
- min: 27017216
- max: 27131904
- avg: 27028661.573051229
+ min: 27017216.0
+ max: 27131904.0
+ avg: 27028661.57305123
+ delta: 114688.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 30797824
- max: 31100928
+ min: 30797824.0
+ max: 31100928.0
avg: 30828073.014492534
+ delta: 303104.0
}
java_heap {
- min: 1193984
- max: 1193984
- avg: 1193984
+ min: 1193984.0
+ max: 1193984.0
+ avg: 1193984.0
+ delta: 0.0
}
}
}
@@ -2388,29 +2770,34 @@ android_mem {
process_name: "com.android.calculator2"
total_counters {
anon_rss {
- min: 30457856
- max: 38170624
+ min: 30457856.0
+ max: 38170624.0
avg: 37379428.70679906
+ delta: 7712768.0
}
file_rss {
- min: 15327232
- max: 46215168
- avg: 44927669.371485837
+ min: 15327232.0
+ max: 46215168.0
+ avg: 44927669.37148584
+ delta: 30887936.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 30457856
- max: 38170624
+ min: 30457856.0
+ max: 38170624.0
avg: 37379428.70679906
+ delta: 7712768.0
}
java_heap {
- min: 1499136
- max: 4316160
+ min: 1499136.0
+ max: 4316160.0
avg: 2972808.7655181894
+ delta: 1228800.0
}
}
}
@@ -2418,24 +2805,28 @@ android_mem {
process_name: "com.android.calendar"
total_counters {
anon_rss {
- min: 30556160
- max: 30556160
- avg: 30556160
+ min: 30556160.0
+ max: 30556160.0
+ avg: 30556160.0
+ delta: 0.0
}
file_rss {
- min: 25948160
- max: 25948160
- avg: 25948160
+ min: 25948160.0
+ max: 25948160.0
+ avg: 25948160.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 30556160
- max: 30556160
- avg: 30556160
+ min: 30556160.0
+ max: 30556160.0
+ avg: 30556160.0
+ delta: 0.0
}
}
}
@@ -2443,29 +2834,34 @@ android_mem {
process_name: "com.android.camera2"
total_counters {
anon_rss {
- min: 32026624
- max: 43556864
+ min: 32026624.0
+ max: 43556864.0
avg: 37778954.5579197
+ delta: 11530240.0
}
file_rss {
- min: 27398144
- max: 42573824
+ min: 27398144.0
+ max: 42573824.0
avg: 35737674.626115516
+ delta: 15175680.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 32026624
- max: 43556864
+ min: 32026624.0
+ max: 43556864.0
avg: 37778954.5579197
+ delta: 11530240.0
}
java_heap {
- min: 3152896
- max: 7367680
- avg: 5624331.5376309063
+ min: 3152896.0
+ max: 7367680.0
+ avg: 5624331.537630906
+ delta: 4214784.0
}
}
}
@@ -2473,24 +2869,28 @@ android_mem {
process_name: "com.android.deskclock"
total_counters {
anon_rss {
- min: 30760960
- max: 30760960
- avg: 30760960
+ min: 30760960.0
+ max: 30760960.0
+ avg: 30760960.0
+ delta: 0.0
}
file_rss {
- min: 26918912
- max: 26918912
- avg: 26918912
+ min: 26918912.0
+ max: 26918912.0
+ avg: 26918912.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 30760960
- max: 30760960
- avg: 30760960
+ min: 30760960.0
+ max: 30760960.0
+ avg: 30760960.0
+ delta: 0.0
}
}
}
@@ -2498,24 +2898,28 @@ android_mem {
process_name: "com.android.dialer"
total_counters {
anon_rss {
- min: 30515200
- max: 30515200
- avg: 30515200
+ min: 30515200.0
+ max: 30515200.0
+ avg: 30515200.0
+ delta: 0.0
}
file_rss {
- min: 26562560
- max: 26562560
- avg: 26562560
+ min: 26562560.0
+ max: 26562560.0
+ avg: 26562560.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 30515200
- max: 30515200
- avg: 30515200
+ min: 30515200.0
+ max: 30515200.0
+ avg: 30515200.0
+ delta: 0.0
}
}
}
@@ -2523,29 +2927,34 @@ android_mem {
process_name: "com.android.inputmethod.latin"
total_counters {
anon_rss {
- min: 32301056
- max: 32333824
+ min: 32301056.0
+ max: 32333824.0
avg: 32312115.023602
+ delta: 32768.0
}
file_rss {
- min: 32784384
- max: 32784384
- avg: 32784384
+ min: 32784384.0
+ max: 32784384.0
+ avg: 32784384.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 32301056
- max: 32333824
+ min: 32301056.0
+ max: 32333824.0
avg: 32312115.023602
+ delta: 32768.0
}
java_heap {
- min: 1345536
- max: 1395712
+ min: 1345536.0
+ max: 1395712.0
avg: 1378703.0378377116
+ delta: 50176.0
}
}
}
@@ -2553,24 +2962,28 @@ android_mem {
process_name: "com.android.keychain"
total_counters {
anon_rss {
- min: 29995008
- max: 29995008
- avg: 29995008
+ min: 29995008.0
+ max: 29995008.0
+ avg: 29995008.0
+ delta: 0.0
}
file_rss {
- min: 20553728
- max: 20553728
- avg: 20553728
+ min: 20553728.0
+ max: 20553728.0
+ avg: 20553728.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 29995008
- max: 29995008
- avg: 29995008
+ min: 29995008.0
+ max: 29995008.0
+ avg: 29995008.0
+ delta: 0.0
}
}
}
@@ -2578,29 +2991,34 @@ android_mem {
process_name: "com.android.launcher3"
total_counters {
anon_rss {
- min: 50225152
- max: 51023872
+ min: 50225152.0
+ max: 51023872.0
avg: 50602448.04672049
+ delta: 798720.0
}
file_rss {
- min: 61640704
- max: 65015808
+ min: 61640704.0
+ max: 65015808.0
avg: 63338514.4484315
+ delta: 2129920.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 50225152
- max: 51023872
+ min: 50225152.0
+ max: 51023872.0
avg: 50602448.04672049
+ delta: 798720.0
}
java_heap {
- min: 2658304
- max: 3159040
+ min: 2658304.0
+ max: 3159040.0
avg: 2933014.4999347096
+ delta: 452608.0
}
}
}
@@ -2608,29 +3026,34 @@ android_mem {
process_name: "com.android.messaging"
total_counters {
anon_rss {
- min: 33431552
- max: 39768064
- avg: 38817213.791344121
+ min: 33431552.0
+ max: 39768064.0
+ avg: 38817213.79134412
+ delta: 6336512.0
}
file_rss {
- min: 31301632
- max: 50712576
- avg: 50276775.478137366
+ min: 31301632.0
+ max: 50712576.0
+ avg: 50276775.47813737
+ delta: 19410944.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 33431552
- max: 39768064
- avg: 38817213.791344121
+ min: 33431552.0
+ max: 39768064.0
+ avg: 38817213.79134412
+ delta: 6336512.0
}
java_heap {
- min: 1519616
- max: 4826112
- avg: 2558538.0852529262
+ min: 1519616.0
+ max: 4826112.0
+ avg: 2558538.085252926
+ delta: 1787904.0
}
}
}
@@ -2638,24 +3061,28 @@ android_mem {
process_name: "com.android.nfc"
total_counters {
anon_rss {
- min: 33431552
- max: 33431552
- avg: 33431552
+ min: 33431552.0
+ max: 33431552.0
+ avg: 33431552.0
+ delta: 0.0
}
file_rss {
- min: 32583680
- max: 32583680
- avg: 32583680
+ min: 32583680.0
+ max: 32583680.0
+ avg: 32583680.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 33431552
- max: 33431552
- avg: 33431552
+ min: 33431552.0
+ max: 33431552.0
+ avg: 33431552.0
+ delta: 0.0
}
}
}
@@ -2663,29 +3090,34 @@ android_mem {
process_name: "com.android.packageinstaller"
total_counters {
anon_rss {
- min: 34000896
- max: 36679680
+ min: 34000896.0
+ max: 36679680.0
avg: 36364002.255620666
+ delta: 2678784.0
}
file_rss {
- min: 47640576
- max: 56872960
- avg: 55784981.963561147
+ min: 47640576.0
+ max: 56872960.0
+ avg: 55784981.96356115
+ delta: 9232384.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 34000896
- max: 36679680
+ min: 34000896.0
+ max: 36679680.0
avg: 36364002.255620666
+ delta: 2678784.0
}
java_heap {
- min: 3202048
- max: 4088832
- avg: 4043650.9270121339
+ min: 3202048.0
+ max: 4088832.0
+ avg: 4043650.927012134
+ delta: 886784.0
}
}
}
@@ -2693,29 +3125,34 @@ android_mem {
process_name: "com.android.phone"
total_counters {
anon_rss {
- min: 34975744
- max: 35635200
- avg: 35418527.859008193
+ min: 34975744.0
+ max: 35635200.0
+ avg: 35418527.85900819
+ delta: 659456.0
}
file_rss {
- min: 41607168
- max: 41644032
- avg: 41631930.862992339
+ min: 41607168.0
+ max: 41644032.0
+ avg: 41631930.86299234
+ delta: 36864.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 34975744
- max: 35635200
- avg: 35418527.859008193
+ min: 34975744.0
+ max: 35635200.0
+ avg: 35418527.85900819
+ delta: 659456.0
}
java_heap {
- min: 3026944
- max: 3207168
+ min: 3026944.0
+ max: 3207168.0
avg: 3204534.0849129637
+ delta: 180224.0
}
}
}
@@ -2723,24 +3160,28 @@ android_mem {
process_name: "com.android.printspooler"
total_counters {
anon_rss {
- min: 30093312
- max: 30093312
- avg: 30093312
+ min: 30093312.0
+ max: 30093312.0
+ avg: 30093312.0
+ delta: 0.0
}
file_rss {
- min: 22540288
- max: 22540288
- avg: 22540288
+ min: 22540288.0
+ max: 22540288.0
+ avg: 22540288.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 30093312
- max: 30093312
- avg: 30093312
+ min: 30093312.0
+ max: 30093312.0
+ avg: 30093312.0
+ delta: 0.0
}
}
}
@@ -2748,24 +3189,28 @@ android_mem {
process_name: "com.android.providers.calendar"
total_counters {
anon_rss {
- min: 30814208
- max: 30814208
- avg: 30814208
+ min: 30814208.0
+ max: 30814208.0
+ avg: 30814208.0
+ delta: 0.0
}
file_rss {
- min: 27041792
- max: 27041792
- avg: 27041792
+ min: 27041792.0
+ max: 27041792.0
+ avg: 27041792.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 30814208
- max: 30814208
- avg: 30814208
+ min: 30814208.0
+ max: 30814208.0
+ avg: 30814208.0
+ delta: 0.0
}
}
}
@@ -2773,24 +3218,28 @@ android_mem {
process_name: "com.android.se"
total_counters {
anon_rss {
- min: 30208000
- max: 30208000
- avg: 30208000
+ min: 30208000.0
+ max: 30208000.0
+ avg: 30208000.0
+ delta: 0.0
}
file_rss {
- min: 20955136
- max: 20955136
- avg: 20955136
+ min: 20955136.0
+ max: 20955136.0
+ avg: 20955136.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 30208000
- max: 30208000
- avg: 30208000
+ min: 30208000.0
+ max: 30208000.0
+ avg: 30208000.0
+ delta: 0.0
}
}
}
@@ -2798,24 +3247,28 @@ android_mem {
process_name: "com.android.settings"
total_counters {
anon_rss {
- min: 34762752
- max: 34762752
- avg: 34762752
+ min: 34762752.0
+ max: 34762752.0
+ avg: 34762752.0
+ delta: 0.0
}
file_rss {
- min: 43851776
- max: 43851776
- avg: 43851776
+ min: 43851776.0
+ max: 43851776.0
+ avg: 43851776.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 34762752
- max: 34762752
- avg: 34762752
+ min: 34762752.0
+ max: 34762752.0
+ avg: 34762752.0
+ delta: 0.0
}
}
}
@@ -2823,24 +3276,28 @@ android_mem {
process_name: "com.android.smspush"
total_counters {
anon_rss {
- min: 30130176
- max: 30130176
- avg: 30130176
+ min: 30130176.0
+ max: 30130176.0
+ avg: 30130176.0
+ delta: 0.0
}
file_rss {
- min: 20025344
- max: 20025344
- avg: 20025344
+ min: 20025344.0
+ max: 20025344.0
+ avg: 20025344.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 30130176
- max: 30130176
- avg: 30130176
+ min: 30130176.0
+ max: 30130176.0
+ avg: 30130176.0
+ delta: 0.0
}
}
}
@@ -2848,29 +3305,34 @@ android_mem {
process_name: "com.android.systemui"
total_counters {
anon_rss {
- min: 66408448
- max: 71012352
- avg: 68351542.715876162
+ min: 66408448.0
+ max: 71012352.0
+ avg: 68351542.71587616
+ delta: 229376.0
}
file_rss {
- min: 84123648
- max: 84856832
- avg: 84582561.858931765
+ min: 84123648.0
+ max: 84856832.0
+ avg: 84582561.85893176
+ delta: 667648.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 66408448
- max: 71012352
- avg: 68351542.715876162
+ min: 66408448.0
+ max: 71012352.0
+ avg: 68351542.71587616
+ delta: 229376.0
}
java_heap {
- min: 6224896
- max: 10747904
+ min: 6224896.0
+ max: 10747904.0
avg: 6949136.10971856
+ delta: 163840.0
}
}
}
@@ -2878,24 +3340,28 @@ android_mem {
process_name: "com.qualcomm.qti.telephonyservice"
total_counters {
anon_rss {
- min: 30720000
- max: 30720000
- avg: 30720000
+ min: 30720000.0
+ max: 30720000.0
+ avg: 30720000.0
+ delta: 0.0
}
file_rss {
- min: 23228416
- max: 23228416
- avg: 23228416
+ min: 23228416.0
+ max: 23228416.0
+ avg: 23228416.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 30720000
- max: 30720000
- avg: 30720000
+ min: 30720000.0
+ max: 30720000.0
+ avg: 30720000.0
+ delta: 0.0
}
}
}
@@ -2903,24 +3369,28 @@ android_mem {
process_name: "lowi-server"
total_counters {
anon_rss {
- min: 1445888
- max: 1449984
+ min: 1445888.0
+ max: 1449984.0
avg: 1447415.3064999864
+ delta: 4096.0
}
file_rss {
- min: 2252800
- max: 2252800
- avg: 2252800
+ min: 2252800.0
+ max: 2252800.0
+ avg: 2252800.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1445888
- max: 1449984
+ min: 1445888.0
+ max: 1449984.0
avg: 1447415.3064999864
+ delta: 4096.0
}
}
}
@@ -2928,24 +3398,28 @@ android_mem {
process_name: "media.codec"
total_counters {
anon_rss {
- min: 5189632
- max: 5210112
- avg: 5206347.9833998242
+ min: 5189632.0
+ max: 5210112.0
+ avg: 5206347.983399824
+ delta: 0.0
}
file_rss {
- min: 15314944
- max: 15314944
- avg: 15314944
+ min: 15314944.0
+ max: 15314944.0
+ avg: 15314944.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 5189632
- max: 5210112
- avg: 5206347.9833998242
+ min: 5189632.0
+ max: 5210112.0
+ avg: 5206347.983399824
+ delta: 0.0
}
}
}
@@ -2953,24 +3427,28 @@ android_mem {
process_name: "media.extractor"
total_counters {
anon_rss {
- min: 4214784
- max: 4296704
+ min: 4214784.0
+ max: 4296704.0
avg: 4225535.91987478
+ delta: 81920.0
}
file_rss {
- min: 7778304
- max: 7778304
- avg: 7778304
+ min: 7778304.0
+ max: 7778304.0
+ avg: 7778304.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 4214784
- max: 4296704
+ min: 4214784.0
+ max: 4296704.0
avg: 4225535.91987478
+ delta: 81920.0
}
}
}
@@ -2978,24 +3456,28 @@ android_mem {
process_name: "media.metrics"
total_counters {
anon_rss {
- min: 2465792
- max: 2465792
- avg: 2465792
+ min: 2465792.0
+ max: 2465792.0
+ avg: 2465792.0
+ delta: 0.0
}
file_rss {
- min: 5373952
- max: 5373952
- avg: 5373952
+ min: 5373952.0
+ max: 5373952.0
+ avg: 5373952.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 2465792
- max: 2465792
- avg: 2465792
+ min: 2465792.0
+ max: 2465792.0
+ avg: 2465792.0
+ delta: 0.0
}
}
}
@@ -3003,24 +3485,28 @@ android_mem {
process_name: "perfetto"
total_counters {
anon_rss {
- min: 3489792
- max: 3489792
- avg: 3489792
+ min: 3489792.0
+ max: 3489792.0
+ avg: 3489792.0
+ delta: 0.0
}
file_rss {
- min: 9125888
- max: 9125888
- avg: 9125888
+ min: 9125888.0
+ max: 9125888.0
+ avg: 9125888.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 3489792
- max: 3489792
- avg: 3489792
+ min: 3489792.0
+ max: 3489792.0
+ avg: 3489792.0
+ delta: 0.0
}
}
}
@@ -3028,29 +3514,34 @@ android_mem {
process_name: "system_server"
total_counters {
anon_rss {
- min: 57307136
- max: 82853888
- avg: 68519057.186817423
+ min: 57307136.0
+ max: 82853888.0
+ avg: 68519057.18681742
+ delta: 25546752.0
}
file_rss {
- min: 215744512
- max: 225366016
- avg: 221489764.25049949
+ min: 215744512.0
+ max: 225366016.0
+ avg: 221489764.2504995
+ delta: 8851456.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 57307136
- max: 82853888
- avg: 68519057.186817423
+ min: 57307136.0
+ max: 82853888.0
+ avg: 68519057.18681742
+ delta: 25546752.0
}
java_heap {
- min: 8163328
- max: 14021632
+ min: 8163328.0
+ max: 14021632.0
avg: 11450919.918936323
+ delta: 2381824.0
}
}
}
@@ -3058,24 +3549,28 @@ android_mem {
process_name: "webview_zygote"
total_counters {
anon_rss {
- min: 23068672
- max: 23068672
- avg: 23068672
+ min: 23068672.0
+ max: 23068672.0
+ avg: 23068672.0
+ delta: 0.0
}
file_rss {
- min: 10244096
- max: 10244096
- avg: 10244096
+ min: 10244096.0
+ max: 10244096.0
+ avg: 10244096.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 23068672
- max: 23068672
- avg: 23068672
+ min: 23068672.0
+ max: 23068672.0
+ avg: 23068672.0
+ delta: 0.0
}
}
}
@@ -3083,24 +3578,28 @@ android_mem {
process_name: "xtra-daemon"
total_counters {
anon_rss {
- min: 1748992
- max: 1748992
- avg: 1748992
+ min: 1748992.0
+ max: 1748992.0
+ avg: 1748992.0
+ delta: 0.0
}
file_rss {
- min: 3473408
- max: 3473408
- avg: 3473408
+ min: 3473408.0
+ max: 3473408.0
+ avg: 3473408.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 1748992
- max: 1748992
- avg: 1748992
+ min: 1748992.0
+ max: 1748992.0
+ avg: 1748992.0
+ delta: 0.0
}
}
}
@@ -3108,24 +3607,28 @@ android_mem {
process_name: "zygote"
total_counters {
anon_rss {
- min: 22667264
- max: 22667264
- avg: 22667264
+ min: 22667264.0
+ max: 22667264.0
+ avg: 22667264.0
+ delta: 0.0
}
file_rss {
- min: 53350400
- max: 53350400
- avg: 53350400
+ min: 53350400.0
+ max: 53350400.0
+ avg: 53350400.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 22667264
- max: 22667264
- avg: 22667264
+ min: 22667264.0
+ max: 22667264.0
+ avg: 22667264.0
+ delta: 0.0
}
}
}
@@ -3133,24 +3636,28 @@ android_mem {
process_name: "zygote64"
total_counters {
anon_rss {
- min: 30040064
- max: 30109696
+ min: 30040064.0
+ max: 30109696.0
avg: 30068614.768896315
+ delta: 69632.0
}
file_rss {
- min: 56365056
- max: 56365056
- avg: 56365056
+ min: 56365056.0
+ max: 56365056.0
+ avg: 56365056.0
+ delta: 0.0
}
swap {
- min: 0
- max: 0
- avg: 0
+ min: 0.0
+ max: 0.0
+ avg: 0.0
+ delta: 0.0
}
anon_and_swap {
- min: 30040064
- max: 30109696
+ min: 30040064.0
+ max: 30109696.0
avg: 30068614.768896315
+ delta: 69632.0
}
}
}
diff --git a/test/trace_processor/memory/android_mem_delta.out b/test/trace_processor/memory/android_mem_delta.out
new file mode 100644
index 000000000..7a43ef8bc
--- /dev/null
+++ b/test/trace_processor/memory/android_mem_delta.out
@@ -0,0 +1,13 @@
+android_mem {
+ process_metrics {
+ process_name: "com.my.pkg"
+ total_counters {
+ file_rss {
+ min: 2000.0
+ max: 10000.0
+ avg: 6666.666666666667
+ delta: 7000.0
+ }
+ }
+ }
+}
diff --git a/test/trace_processor/memory/android_mem_delta.py b/test/trace_processor/memory/android_mem_delta.py
new file mode 100644
index 000000000..f78597b86
--- /dev/null
+++ b/test/trace_processor/memory/android_mem_delta.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python3
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from os import sys, path
+
+import synth_common
+
+file_member = 0
+anon_member = 1
+swap_member = 2
+
+trace = synth_common.create_trace()
+trace.add_packet()
+trace.add_process(1, 0, 'com.my.pkg')
+
+trace.add_ftrace_packet(cpu=0)
+trace.add_rss_stat(100, 1, file_member, 10000)
+trace.add_rss_stat(101, 1, file_member, 2000)
+trace.add_rss_stat(102, 1, file_member, 5000)
+trace.add_rss_stat(103, 1, file_member, 8000)
+trace.add_rss_stat(104, 1, file_member, 9000)
+trace.add_rss_stat(105, 1, file_member, 6000)
+
+sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/memory/android_systrace_lmk.py b/test/trace_processor/memory/android_systrace_lmk.py
new file mode 100644
index 000000000..472a0cca7
--- /dev/null
+++ b/test/trace_processor/memory/android_systrace_lmk.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from os import sys, path
+
+import synth_common
+
+trace = synth_common.create_trace()
+trace.add_packet()
+trace.add_process(1, 0, 'init')
+trace.add_process(2, 1, 'lmkd')
+trace.add_process(3, 1, 'com.google.android.calendar')
+
+trace.add_ftrace_packet(cpu=0)
+trace.add_oom_score_update(ts=100, oom_score_adj=0, pid=3)
+trace.add_atrace_begin(ts=100000, pid=1, tid=1, buf='lmk,3,1,900')
+trace.add_atrace_end(ts=100001, pid=1, tid=1)
+
+sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/memory/index b/test/trace_processor/memory/index
index 683d4f133..091fe8d22 100644
--- a/test/trace_processor/memory/index
+++ b/test/trace_processor/memory/index
@@ -5,8 +5,10 @@
../../data/memory_counters.pb trace_metadata trace_metadata.out
android_mem_by_priority.py android_mem android_mem_by_priority.out
android_lmk.py android_lmk android_mem_lmk.out
+android_systrace_lmk.py android_lmk android_mem_lmk.out
android_lmk_reason.py android_lmk_reason android_lmk_reason.out
../common/oom_kill.textproto android_lmk android_lmk_oom.out
+android_mem_delta.py android_mem android_mem_delta.out
# ION metric
android_ion.py android_ion android_ion.out
diff --git a/test/trace_processor/memory/trace_metadata.out b/test/trace_processor/memory/trace_metadata.out
index b66bf1ae8..e26a7649b 100644
--- a/test/trace_processor/memory/trace_metadata.out
+++ b/test/trace_processor/memory/trace_metadata.out
@@ -1,6 +1,7 @@
trace_metadata {
trace_duration_ns: 9519159074,
+ trace_uuid: "00000000-0000-0000-e77f-20a2204c2a49",
trace_size_bytes: 6365447
- trace_config_pbtxt: "buffers: {\n size_kb: 32768\n fill_policy: UNSPECIFIED\n}\ndata_sources: {\n config: {\n name: \"linux.ftrace\"\n target_buffer: 0\n trace_duration_ms: 0\n tracing_session_id: 0\n ftrace_config: {\n ftrace_events: \"print\"\n ftrace_events: \"sched_switch\"\n ftrace_events: \"rss_stat\"\n ftrace_events: \"ion_heap_shrink\"\n ftrace_events: \"ion_heap_grow\"\n atrace_categories: \"am\"\n atrace_categories: \"dalvik\"\n buffer_size_kb: 0\n drain_period_ms: 0\n }\n chrome_config: {\n trace_config: \"\"\n }\n inode_file_config: {\n scan_interval_ms: 0\n scan_delay_ms: 0\n scan_batch_size: 0\n do_not_scan: false\n }\n process_stats_config: {\n scan_all_processes_on_start: false\n record_thread_names: false\n proc_stats_poll_ms: 0\n }\n sys_stats_config: {\n meminfo_period_ms: 0\n vmstat_period_ms: 0\n stat_period_ms: 0\n }\n heapprofd_config: {\n sampling_interval_bytes: 0\n all: false\n continuous_dump_config: {\n dump_phase_ms: 0\n dump_interval_ms: 0\n }\n }\n legacy_config: \"\"\n }\n}\ndata_sources: {\n config: {\n name: \"linux.process_stats\"\n target_buffer: 0\n trace_duration_ms: 0\n tracing_session_id: 0\n ftrace_config: {\n buffer_size_kb: 0\n drain_period_ms: 0\n }\n chrome_config: {\n trace_config: \"\"\n }\n inode_file_config: {\n scan_interval_ms: 0\n scan_delay_ms: 0\n scan_batch_size: 0\n do_not_scan: false\n }\n process_stats_config: {\n scan_all_processes_on_start: false\n record_thread_names: false\n proc_stats_poll_ms: 100\n }\n sys_stats_config: {\n meminfo_period_ms: 0\n vmstat_period_ms: 0\n stat_period_ms: 0\n }\n heapprofd_config: {\n sampling_interval_bytes: 0\n all: false\n continuous_dump_config: {\n dump_phase_ms: 0\n dump_interval_ms: 0\n }\n }\n legacy_config: \"\"\n }\n}\ndata_sources: {\n config: {\n name: \"linux.sys_stats\"\n target_buffer: 0\n trace_duration_ms: 0\n tracing_session_id: 0\n ftrace_config: {\n buffer_size_kb: 0\n drain_period_ms: 0\n }\n chrome_config: {\n trace_config: \"\"\n }\n inode_file_config: {\n scan_interval_ms: 0\n scan_delay_ms: 0\n scan_batch_size: 0\n do_not_scan: false\n }\n process_stats_config: {\n scan_all_processes_on_start: false\n record_thread_names: false\n proc_stats_poll_ms: 0\n }\n sys_stats_config: {\n meminfo_period_ms: 50\n meminfo_counters: MEMINFO_MEM_AVAILABLE\n meminfo_counters: MEMINFO_SWAP_CACHED\n meminfo_counters: MEMINFO_ACTIVE\n meminfo_counters: MEMINFO_INACTIVE\n vmstat_period_ms: 0\n stat_period_ms: 0\n }\n heapprofd_config: {\n sampling_interval_bytes: 0\n all: false\n continuous_dump_config: {\n dump_phase_ms: 0\n dump_interval_ms: 0\n }\n }\n legacy_config: \"\"\n }\n}\nduration_ms: 10000\nenable_extra_guardrails: false\nlockdown_mode: LOCKDOWN_UNCHANGED\nstatsd_metadata: {\n triggering_alert_id: 0\n triggering_config_uid: 0\n triggering_config_id: 0\n}\nwrite_into_file: false\nfile_write_period_ms: 0\nmax_file_size_bytes: 0\nguardrail_overrides: {\n max_upload_per_day_bytes: 0\n}\ndeferred_start: false",
+ trace_config_pbtxt: "buffers {\n size_kb: 32768\n fill_policy: UNSPECIFIED\n}\ndata_sources {\n config {\n name: \"linux.ftrace\"\n target_buffer: 0\n trace_duration_ms: 0\n tracing_session_id: 0\n ftrace_config {\n ftrace_events: \"print\"\n ftrace_events: \"sched_switch\"\n ftrace_events: \"rss_stat\"\n ftrace_events: \"ion_heap_shrink\"\n ftrace_events: \"ion_heap_grow\"\n atrace_categories: \"am\"\n atrace_categories: \"dalvik\"\n buffer_size_kb: 0\n drain_period_ms: 0\n }\n chrome_config {\n trace_config: \"\"\n }\n inode_file_config {\n scan_interval_ms: 0\n scan_delay_ms: 0\n scan_batch_size: 0\n do_not_scan: false\n }\n process_stats_config {\n scan_all_processes_on_start: false\n record_thread_names: false\n proc_stats_poll_ms: 0\n }\n sys_stats_config {\n meminfo_period_ms: 0\n vmstat_period_ms: 0\n stat_period_ms: 0\n }\n heapprofd_config {\n sampling_interval_bytes: 0\n all: false\n continuous_dump_config {\n dump_phase_ms: 0\n dump_interval_ms: 0\n }\n }\n legacy_config: \"\"\n }\n}\ndata_sources {\n config {\n name: \"linux.process_stats\"\n target_buffer: 0\n trace_duration_ms: 0\n tracing_session_id: 0\n ftrace_config {\n buffer_size_kb: 0\n drain_period_ms: 0\n }\n chrome_config {\n trace_config: \"\"\n }\n inode_file_config {\n scan_interval_ms: 0\n scan_delay_ms: 0\n scan_batch_size: 0\n do_not_scan: false\n }\n process_stats_config {\n scan_all_processes_on_start: false\n record_thread_names: false\n proc_stats_poll_ms: 100\n }\n sys_stats_config {\n meminfo_period_ms: 0\n vmstat_period_ms: 0\n stat_period_ms: 0\n }\n heapprofd_config {\n sampling_interval_bytes: 0\n all: false\n continuous_dump_config {\n dump_phase_ms: 0\n dump_interval_ms: 0\n }\n }\n legacy_config: \"\"\n }\n}\ndata_sources {\n config {\n name: \"linux.sys_stats\"\n target_buffer: 0\n trace_duration_ms: 0\n tracing_session_id: 0\n ftrace_config {\n buffer_size_kb: 0\n drain_period_ms: 0\n }\n chrome_config {\n trace_config: \"\"\n }\n inode_file_config {\n scan_interval_ms: 0\n scan_delay_ms: 0\n scan_batch_size: 0\n do_not_scan: false\n }\n process_stats_config {\n scan_all_processes_on_start: false\n record_thread_names: false\n proc_stats_poll_ms: 0\n }\n sys_stats_config {\n meminfo_period_ms: 50\n meminfo_counters: MEMINFO_MEM_AVAILABLE\n meminfo_counters: MEMINFO_SWAP_CACHED\n meminfo_counters: MEMINFO_ACTIVE\n meminfo_counters: MEMINFO_INACTIVE\n vmstat_period_ms: 0\n stat_period_ms: 0\n }\n heapprofd_config {\n sampling_interval_bytes: 0\n all: false\n continuous_dump_config {\n dump_phase_ms: 0\n dump_interval_ms: 0\n }\n }\n legacy_config: \"\"\n }\n}\nduration_ms: 10000\nenable_extra_guardrails: false\nlockdown_mode: LOCKDOWN_UNCHANGED\nstatsd_metadata {\n triggering_alert_id: 0\n triggering_config_uid: 0\n triggering_config_id: 0\n}\nwrite_into_file: false\nfile_write_period_ms: 0\nmax_file_size_bytes: 0\nguardrail_overrides {\n max_upload_per_day_bytes: 0\n}\ndeferred_start: false",
sched_duration_ns: 9452761359
}
diff --git a/test/trace_processor/network/index b/test/trace_processor/network/index
new file mode 100644
index 000000000..01ad31b61
--- /dev/null
+++ b/test/trace_processor/network/index
@@ -0,0 +1,8 @@
+# Network performance
+netif_receive_skb.textproto netif_receive_skb.sql netif_receive_skb.out
+net_dev_xmit.textproto net_dev_xmit.sql net_dev_xmit.out
+netperf_metric.textproto android_netperf netperf_metric.out
+inet_sock_set_state.textproto inet_sock_set_state.sql inet_sock_set_state.out
+tcp_retransmit_skb.textproto tcp_retransmit_skb.sql tcp_retransmit_skb.out
+napi_gro_receive.textproto napi_gro_receive.sql napi_gro_receive.out
+kfree_skb.textproto kfree_skb.sql kfree_skb.out \ No newline at end of file
diff --git a/test/trace_processor/network/inet_sock_set_state.out b/test/trace_processor/network/inet_sock_set_state.out
new file mode 100644
index 000000000..fd67a199e
--- /dev/null
+++ b/test/trace_processor/network/inet_sock_set_state.out
@@ -0,0 +1,7 @@
+"ts","name","dur","name"
+10000000,"TCP_SYN_SENT(pid=123)",100000000,"TCP stream#1"
+110000000,"TCP_ESTABLISHED(sport=56789,dport=5001)",500000000,"TCP stream#1"
+610000000,"TCP_CLOSE_WAIT",-1,"TCP stream#1"
+710000000,"TCP_SYN_SENT(pid=567)",10000000,"TCP stream#2"
+720000000,"TCP_ESTABLISHED(sport=56790,dport=5002)",300000000,"TCP stream#2"
+1020000000,"TCP_CLOSE_WAIT",-1,"TCP stream#2"
diff --git a/test/trace_processor/network/inet_sock_set_state.sql b/test/trace_processor/network/inet_sock_set_state.sql
new file mode 100644
index 000000000..badba1e3f
--- /dev/null
+++ b/test/trace_processor/network/inet_sock_set_state.sql
@@ -0,0 +1,12 @@
+SELECT
+ ts,
+ s.name,
+ dur,
+ t.name
+FROM
+ slice AS s
+ LEFT JOIN track AS t
+ ON s.track_id = t.id
+WHERE
+ t.name GLOB "TCP stream#*"
+ORDER BY ts;
diff --git a/test/trace_processor/network/inet_sock_set_state.textproto b/test/trace_processor/network/inet_sock_set_state.textproto
new file mode 100644
index 000000000..00362f953
--- /dev/null
+++ b/test/trace_processor/network/inet_sock_set_state.textproto
@@ -0,0 +1,121 @@
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 10000000
+ pid: 123
+ inet_sock_set_state {
+ family: 2
+ protocol: 6
+ daddr: 19216801
+ saddr: 127001
+ dport: 5001
+ sport: 0
+ newstate: 2
+ oldstate: 7
+ skaddr: 77889900
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 110000000
+ pid: 234
+ inet_sock_set_state {
+ family: 2
+ protocol: 6
+ daddr: 19216801
+ saddr: 127001
+ dport: 5001
+ sport: 56789
+ newstate: 1
+ oldstate: 2
+ skaddr: 77889900
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 610000000
+ pid: 456
+ inet_sock_set_state {
+ family: 2
+ protocol: 6
+ daddr: 19216801
+ saddr: 127001
+ dport: 5001
+ sport: 56789
+ newstate: 8
+ oldstate: 1
+ skaddr: 77889900
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 710000000
+ pid:567
+ inet_sock_set_state {
+ family: 10
+ protocol: 6
+ daddr: 0
+ saddr: 0
+ dport: 5002
+ sport: 0
+ newstate: 2
+ oldstate: 7
+ skaddr: 33445566
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 720000000
+ pid: 234
+ inet_sock_set_state {
+ family: 10
+ protocol: 6
+ daddr: 0
+ saddr: 0
+ dport: 5002
+ sport: 56790
+ newstate: 1
+ oldstate: 2
+ skaddr: 33445566
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 1020000000
+ pid: 456
+ inet_sock_set_state {
+ family: 10
+ protocol: 6
+ daddr: 0
+ saddr: 0
+ dport: 5002
+ sport: 567090
+ newstate: 8
+ oldstate: 1
+ skaddr: 33445566
+ }
+ }
+ }
+}
+
diff --git a/test/trace_processor/network/kfree_skb.out b/test/trace_processor/network/kfree_skb.out
new file mode 100644
index 000000000..6db1bd9cf
--- /dev/null
+++ b/test/trace_processor/network/kfree_skb.out
@@ -0,0 +1,4 @@
+"ts","value","prot"
+10000,1.000000,"IP"
+10020,2.000000,"IPV6"
+20020,3.000000,"IP"
diff --git a/test/trace_processor/network/kfree_skb.sql b/test/trace_processor/network/kfree_skb.sql
new file mode 100644
index 000000000..6ec20565f
--- /dev/null
+++ b/test/trace_processor/network/kfree_skb.sql
@@ -0,0 +1,12 @@
+SELECT
+ ts,
+ value,
+ EXTRACT_ARG(arg_set_id, 'protocol') AS prot
+FROM
+ counter AS c
+ LEFT JOIN
+ counter_track AS t
+ ON c.track_id = t.id
+WHERE
+ name GLOB "Kfree Skb IP Prot"
+ORDER BY ts;
diff --git a/test/trace_processor/network/kfree_skb.textproto b/test/trace_processor/network/kfree_skb.textproto
new file mode 100644
index 000000000..695683114
--- /dev/null
+++ b/test/trace_processor/network/kfree_skb.textproto
@@ -0,0 +1,48 @@
+packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 10000
+ pid: 200
+ kfree_skb {
+ protocol: 2048
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 10020
+ pid: 300
+ kfree_skb {
+ protocol: 34525
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 20000
+ pid: 200
+ kfree_skb {
+ protocol: 1536
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 20020
+ pid: 300
+ kfree_skb {
+ protocol: 2048
+ }
+ }
+ }
+}
diff --git a/test/trace_processor/network/napi_gro_receive.out b/test/trace_processor/network/napi_gro_receive.out
new file mode 100644
index 000000000..0648e41ae
--- /dev/null
+++ b/test/trace_processor/network/napi_gro_receive.out
@@ -0,0 +1,4 @@
+"ts","name","dur","cat","name","ret","len"
+10000,"rmnet0",20,"napi_gro","Napi Gro Cpu 2",2,1000
+20000,"rmnet0",20,"napi_gro","Napi Gro Cpu 2",1,1000
+30000,"wlan",20,"napi_gro","Napi Gro Cpu 4",3,500
diff --git a/test/trace_processor/network/napi_gro_receive.sql b/test/trace_processor/network/napi_gro_receive.sql
new file mode 100644
index 000000000..48ee38f16
--- /dev/null
+++ b/test/trace_processor/network/napi_gro_receive.sql
@@ -0,0 +1,16 @@
+SELECT
+ ts,
+ s.name,
+ dur,
+ cat,
+ t.name,
+ EXTRACT_ARG(arg_set_id, 'ret') AS ret,
+ EXTRACT_ARG(arg_set_id, 'len') AS len
+FROM
+ slice AS s
+LEFT JOIN
+ track AS t
+ ON s.track_id = t.id
+WHERE
+ t.name GLOB "Napi Gro Cpu *"
+ORDER BY ts;
diff --git a/test/trace_processor/network/napi_gro_receive.textproto b/test/trace_processor/network/napi_gro_receive.textproto
new file mode 100644
index 000000000..ee202f8a1
--- /dev/null
+++ b/test/trace_processor/network/napi_gro_receive.textproto
@@ -0,0 +1,75 @@
+packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 10000
+ pid: 200
+ napi_gro_receive_entry {
+ name: "rmnet0"
+ len: 1000
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 10020
+ pid: 300
+ napi_gro_receive_exit {
+ ret: 2
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 20000
+ pid: 200
+ napi_gro_receive_entry {
+ name: "rmnet0"
+ len: 1000
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 20020
+ pid: 300
+ napi_gro_receive_exit {
+ ret: 1
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 4
+ event {
+ timestamp: 30000
+ pid: 200
+ napi_gro_receive_entry {
+ name: "wlan"
+ len: 500
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 4
+ event {
+ timestamp: 30020
+ pid: 300
+ napi_gro_receive_exit {
+ ret: 3
+ }
+ }
+ }
+}
diff --git a/test/trace_processor/network/net_dev_xmit.out b/test/trace_processor/network/net_dev_xmit.out
new file mode 100644
index 000000000..020428b3c
--- /dev/null
+++ b/test/trace_processor/network/net_dev_xmit.out
@@ -0,0 +1,5 @@
+"ts","dev","cpu","len"
+10000,"rmnet0",0,1000
+10000,"rmnet0",1,1000
+10010,"rmnet0",0,1000
+12000,"wlan0",4,1300
diff --git a/test/trace_processor/network/net_dev_xmit.sql b/test/trace_processor/network/net_dev_xmit.sql
new file mode 100644
index 000000000..8c4fcd4a6
--- /dev/null
+++ b/test/trace_processor/network/net_dev_xmit.sql
@@ -0,0 +1,13 @@
+SELECT
+ ts,
+ REPLACE(name, " Transmitted KB", "") AS dev,
+ EXTRACT_ARG(arg_set_id, 'cpu') AS cpu,
+ EXTRACT_ARG(arg_set_id, 'len') AS len
+FROM
+ counter AS c
+ LEFT JOIN
+ counter_track AS t
+ ON c.track_id = t.id
+WHERE
+ name GLOB "* Transmitted KB"
+ORDER BY ts;
diff --git a/test/trace_processor/network/net_dev_xmit.textproto b/test/trace_processor/network/net_dev_xmit.textproto
new file mode 100644
index 000000000..693380b30
--- /dev/null
+++ b/test/trace_processor/network/net_dev_xmit.textproto
@@ -0,0 +1,70 @@
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 10000
+ pid: 200
+ net_dev_xmit {
+ name: "rmnet0"
+ len: 1000
+ rc: 0
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 10000
+ pid: 300
+ net_dev_xmit {
+ name: "rmnet0"
+ len: 1000
+ rc: 0
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 10010
+ pid: 400
+ net_dev_xmit {
+ name: "rmnet0"
+ len: 1000
+ rc: 0
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 10011
+ pid: 500
+ net_dev_xmit {
+ name: "rmnet0"
+ len: 1000
+ rc: 16
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 4
+ event {
+ timestamp: 12000
+ pid: 600
+ net_dev_xmit {
+ name: "wlan0"
+ len: 1300
+ rc: 0
+ }
+ }
+ }
+}
diff --git a/test/trace_processor/network/netif_receive_skb.out b/test/trace_processor/network/netif_receive_skb.out
new file mode 100644
index 000000000..468292b63
--- /dev/null
+++ b/test/trace_processor/network/netif_receive_skb.out
@@ -0,0 +1,6 @@
+"ts","dev","cpu","len"
+10000,"rmnet0",0,1000
+10000,"rmnet0",1,1000
+10010,"rmnet0",0,1000
+10011,"rmnet0",1,1000
+12000,"wlan",4,1300
diff --git a/test/trace_processor/network/netif_receive_skb.sql b/test/trace_processor/network/netif_receive_skb.sql
new file mode 100644
index 000000000..20dc4688e
--- /dev/null
+++ b/test/trace_processor/network/netif_receive_skb.sql
@@ -0,0 +1,13 @@
+SELECT
+ ts,
+ REPLACE(name, " Received KB", "") AS dev,
+ EXTRACT_ARG(arg_set_id, 'cpu') AS cpu,
+ EXTRACT_ARG(arg_set_id, 'len') AS len
+FROM
+ counter AS c
+ LEFT JOIN
+ counter_track AS t
+ ON c.track_id = t.id
+WHERE
+ name GLOB "* Received KB"
+ORDER BY ts;
diff --git a/test/trace_processor/network/netif_receive_skb.textproto b/test/trace_processor/network/netif_receive_skb.textproto
new file mode 100644
index 000000000..8f30c55d8
--- /dev/null
+++ b/test/trace_processor/network/netif_receive_skb.textproto
@@ -0,0 +1,65 @@
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 10000
+ pid: 200
+ netif_receive_skb {
+ name: "rmnet0"
+ len: 1000
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 10000
+ pid: 300
+ netif_receive_skb {
+ name: "rmnet0"
+ len: 1000
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 10010
+ pid: 400
+ netif_receive_skb {
+ name: "rmnet0"
+ len: 1000
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 10011
+ pid: 500
+ netif_receive_skb {
+ name: "rmnet0"
+ len: 1000
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 4
+ event {
+ timestamp: 12000
+ pid: 600
+ netif_receive_skb {
+ name: "wlan"
+ len: 1300
+ }
+ }
+ }
+}
diff --git a/test/trace_processor/network/netperf_metric.out b/test/trace_processor/network/netperf_metric.out
new file mode 100644
index 000000000..cbb642e22
--- /dev/null
+++ b/test/trace_processor/network/netperf_metric.out
@@ -0,0 +1,147 @@
+android_netperf{
+ net_devices {
+ name: "rmnet0"
+ rx {
+ total {
+ packets: 4
+ bytes: 4096
+ first_packet_timestamp_ns: 100000000
+ last_packet_timestamp_ns: 140000000
+ interval_ns: 40000000
+ data_rate_kbps: 800.0
+ }
+ core {
+ id: 0
+ packet_statistic {
+ packets: 2
+ bytes: 2048
+ first_packet_timestamp_ns: 100000000
+ last_packet_timestamp_ns: 140000000
+ interval_ns: 40000000
+ data_rate_kbps: 400.0
+ }
+ }
+ core {
+ id: 1
+ packet_statistic {
+ packets: 2
+ bytes: 2048
+ first_packet_timestamp_ns: 120000000
+ last_packet_timestamp_ns: 140000000
+ interval_ns: 20000000
+ data_rate_kbps: 800.0
+ }
+ }
+ gro_aggregation_ratio: '1:1.75'
+ }
+ tx {
+ total {
+ packets: 4
+ bytes: 4096
+ first_packet_timestamp_ns: 100100000
+ last_packet_timestamp_ns: 140100000
+ interval_ns: 40000000
+ data_rate_kbps: 800.0
+ }
+ core {
+ id: 0
+ packet_statistic {
+ packets: 2
+ bytes: 2048
+ first_packet_timestamp_ns: 100100000
+ last_packet_timestamp_ns: 140100000
+ interval_ns: 40000000
+ data_rate_kbps: 400.0
+ }
+ }
+ core {
+ id: 1
+ packet_statistic {
+ packets: 2
+ bytes: 2048
+ first_packet_timestamp_ns: 120100000
+ last_packet_timestamp_ns: 140100000
+ interval_ns: 20000000
+ data_rate_kbps: 800.0
+ }
+ }
+ }
+ }
+ net_devices {
+ name: "wlan0"
+ rx {
+ total {
+ packets: 1
+ bytes: 512
+ first_packet_timestamp_ns: 100000000
+ last_packet_timestamp_ns: 100000000
+ interval_ns: 10000000
+ data_rate_kbps: 400.0
+ }
+ core {
+ id: 4
+ packet_statistic {
+ packets: 1
+ bytes: 512
+ first_packet_timestamp_ns: 100000000
+ last_packet_timestamp_ns: 100000000
+ interval_ns: 10000000
+ data_rate_kbps: 400.0
+ }
+ }
+ }
+ tx {
+ total {
+ packets: 1
+ bytes: 512
+ first_packet_timestamp_ns: 101000000
+ last_packet_timestamp_ns: 101000000
+ interval_ns: 10000000
+ data_rate_kbps: 400.0
+ }
+ core {
+ id: 4
+ packet_statistic {
+ packets: 1
+ bytes: 512
+ first_packet_timestamp_ns: 101000000
+ last_packet_timestamp_ns: 101000000
+ interval_ns: 10000000
+ data_rate_kbps: 400.0
+ }
+ }
+ }
+ }
+ net_rx_action {
+ total {
+ count: 4
+ runtime_ms: 2.0
+ avg_runtime_ms: 0.5
+ avg_freq_khz: 1500000
+ mcycles: 3
+ }
+ core {
+ id: 0
+ net_rx_action_statistic {
+ count: 2
+ runtime_ms: 1.0
+ avg_runtime_ms: 0.5
+ avg_freq_khz: 1500000
+ mcycles: 1
+ }
+ }
+ core {
+ id: 1
+ net_rx_action_statistic {
+ count: 2
+ runtime_ms: 1.0
+ avg_runtime_ms: 0.5
+ avg_freq_khz: 1500000
+ mcycles: 1
+ }
+ }
+ avg_interstack_latency_ms: 0.4
+ }
+ retransmission_rate: 20.0
+ kfree_skb_rate: 10.0
+}
diff --git a/test/trace_processor/network/netperf_metric.textproto b/test/trace_processor/network/netperf_metric.textproto
new file mode 100644
index 000000000..60d196ea5
--- /dev/null
+++ b/test/trace_processor/network/netperf_metric.textproto
@@ -0,0 +1,336 @@
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 99999900
+ pid: 200
+ napi_gro_receive_entry {
+ name: "rmnet0"
+ len: 512
+ }
+ }
+ event {
+ timestamp: 99999920
+ pid: 300
+ napi_gro_receive_exit {
+ ret: 1
+ }
+ }
+ event {
+ timestamp: 99999930
+ pid: 200
+ napi_gro_receive_entry {
+ name: "rmnet0"
+ len: 512
+ }
+ }
+ event {
+ timestamp: 99999940
+ pid: 300
+ napi_gro_receive_exit {
+ ret: 2
+ }
+ }
+ event {
+ timestamp: 99999945
+ pid: 200
+ kfree_skb {
+ protocol: 2048
+ }
+ }
+ event {
+ timestamp: 100000000
+ pid: 200
+ cpu_frequency {
+ cpu_id: 0
+ state: 2000000
+ }
+ }
+ event {
+ timestamp: 100000000
+ pid: 200
+ softirq_entry {
+ vec: 3
+ }
+ }
+ event {
+ timestamp: 100000000
+ pid: 200
+ netif_receive_skb {
+ name: "rmnet0"
+ len: 1024
+ }
+ }
+ event {
+ timestamp: 100090000
+ pid: 234
+ tcp_retransmit_skb {
+ daddr: 19216801
+ saddr: 127001
+ dport: 5001
+ sport: 56789
+ state: 1
+ skaddr: 77889900
+ }
+ }
+ event {
+ timestamp: 100100000
+ pid: 200
+ net_dev_xmit {
+ name: "rmnet0"
+ len: 1024
+ }
+ }
+ event {
+ timestamp: 100500000
+ pid: 200
+ softirq_exit {
+ vec: 3
+ }
+ }
+ }
+}
+
+packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 1119999800
+ pid: 200
+ kfree_skb {
+ protocol: 600
+ }
+ }
+ event {
+ timestamp: 119999900
+ pid: 200
+ napi_gro_receive_entry {
+ name: "rmnet0"
+ len: 512
+ }
+ }
+ event {
+ timestamp: 119999920
+ pid: 300
+ napi_gro_receive_exit {
+ ret: 1
+ }
+ }
+ event {
+ timestamp: 119999930
+ pid: 200
+ napi_gro_receive_entry {
+ name: "rmnet0"
+ len: 512
+ }
+ }
+ event {
+ timestamp: 119999940
+ pid: 300
+ napi_gro_receive_exit {
+ ret: 2
+ }
+ }
+ event {
+ timestamp: 120000000
+ pid: 200
+ cpu_frequency {
+ cpu_id: 1
+ state: 2000000
+ }
+ }
+ event {
+ timestamp: 120000000
+ pid: 300
+ softirq_entry {
+ vec: 3
+ }
+ }
+ event {
+ timestamp: 120000000
+ pid: 300
+ netif_receive_skb {
+ name: "rmnet0"
+ len: 1024
+ }
+ }
+ event {
+ timestamp: 120100000
+ pid: 300
+ net_dev_xmit {
+ name: "rmnet0"
+ len: 1024
+ }
+ }
+ event {
+ timestamp: 120500000
+ pid: 300
+ softirq_exit {
+ vec: 3
+ }
+ }
+ }
+}
+
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 139999900
+ pid: 200
+ napi_gro_receive_entry {
+ name: "rmnet0"
+ len: 512
+ }
+ }
+ event {
+ timestamp: 139999920
+ pid: 300
+ napi_gro_receive_exit {
+ ret: 1
+ }
+ }
+ event {
+ timestamp: 139999930
+ pid: 200
+ napi_gro_receive_entry {
+ name: "rmnet0"
+ len: 512
+ }
+ }
+ event {
+ timestamp: 139999940
+ pid: 300
+ napi_gro_receive_exit {
+ ret: 2
+ }
+ }
+ event {
+ timestamp: 140000000
+ pid: 200
+ cpu_frequency {
+ cpu_id: 0
+ state: 1000000
+ }
+ }
+ event {
+ timestamp: 140000000
+ pid: 400
+ softirq_entry {
+ vec: 3
+ }
+ }
+ event {
+ timestamp: 140000000
+ pid: 400
+ netif_receive_skb {
+ name: "rmnet0"
+ len: 1024
+ }
+ }
+ event {
+ timestamp: 140100000
+ pid: 400
+ net_dev_xmit {
+ name: "rmnet0"
+ len: 1024
+ }
+ }
+ event {
+ timestamp: 140500000
+ pid: 400
+ softirq_exit {
+ vec: 3
+ }
+ }
+ }
+}
+
+packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 139999900
+ pid: 200
+ napi_gro_receive_entry {
+ name: "rmnet0"
+ len: 1024
+ }
+ }
+ event {
+ timestamp: 139999920
+ pid: 300
+ napi_gro_receive_exit {
+ ret: 3
+ }
+ }
+ event {
+ timestamp: 140000000
+ pid: 200
+ cpu_frequency {
+ cpu_id: 1
+ state: 1000000
+ }
+ }
+ event {
+ timestamp: 140000000
+ pid: 500
+ softirq_entry {
+ vec: 3
+ }
+ }
+ event {
+ timestamp: 140000000
+ pid: 500
+ netif_receive_skb {
+ name: "rmnet0"
+ len: 1024
+ }
+ }
+ event {
+ timestamp: 140100000
+ pid: 500
+ net_dev_xmit {
+ name: "rmnet0"
+ len: 1024
+ }
+ }
+ event {
+ timestamp: 140500000
+ pid: 500
+ softirq_exit {
+ vec: 3
+ }
+ }
+ }
+}
+
+packet {
+ ftrace_events {
+ cpu: 4
+ event {
+ timestamp: 100000000
+ pid: 200
+ cpu_frequency {
+ cpu_id: 4
+ state: 2000000
+ }
+ }
+ event {
+ timestamp: 100000000
+ pid: 600
+ netif_receive_skb {
+ name: "wlan0"
+ len: 512
+ }
+ }
+ event {
+ timestamp: 101000000
+ pid: 600
+ net_dev_xmit {
+ name: "wlan0"
+ len: 512
+ }
+ }
+ }
+}
diff --git a/test/trace_processor/network/tcp_retransmit_skb.out b/test/trace_processor/network/tcp_retransmit_skb.out
new file mode 100644
index 000000000..9a3629fae
--- /dev/null
+++ b/test/trace_processor/network/tcp_retransmit_skb.out
@@ -0,0 +1,3 @@
+"ts","name","dur"
+110000000,"sport=56789,dport=5001",0
+720000000,"sport=56790,dport=5002",0
diff --git a/test/trace_processor/network/tcp_retransmit_skb.sql b/test/trace_processor/network/tcp_retransmit_skb.sql
new file mode 100644
index 000000000..44dacb3aa
--- /dev/null
+++ b/test/trace_processor/network/tcp_retransmit_skb.sql
@@ -0,0 +1,11 @@
+SELECT
+ ts,
+ s.name,
+ dur
+FROM
+ slice AS s
+ LEFT JOIN track AS t
+ ON s.track_id = t.id
+WHERE
+ t.name = "TCP Retransmit Skb"
+ORDER BY ts;
diff --git a/test/trace_processor/network/tcp_retransmit_skb.textproto b/test/trace_processor/network/tcp_retransmit_skb.textproto
new file mode 100644
index 000000000..3e96e757d
--- /dev/null
+++ b/test/trace_processor/network/tcp_retransmit_skb.textproto
@@ -0,0 +1,34 @@
+packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 110000000
+ pid: 234
+ tcp_retransmit_skb {
+ daddr: 19216801
+ saddr: 127001
+ dport: 5001
+ sport: 56789
+ state: 1
+ skaddr: 77889900
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 720000000
+ pid: 234
+ tcp_retransmit_skb {
+ daddr: 0
+ saddr: 0
+ dport: 5002
+ sport: 56790
+ state: 2
+ skaddr: 33445566
+ }
+ }
+ }
+}
diff --git a/test/trace_processor/parsing/android_log_counts.sql b/test/trace_processor/parsing/android_log_counts.sql
index f22fea139..35a2a4735 100644
--- a/test/trace_processor/parsing/android_log_counts.sql
+++ b/test/trace_processor/parsing/android_log_counts.sql
@@ -17,6 +17,6 @@ select count(*) as cnt from android_logs union all
select count(*) as cnt from android_logs where prio = 3 union all
select count(*) as cnt from android_logs where prio > 4 union all
select count(*) as cnt from android_logs where tag = 'screen_toggled' union all
-select count(*) as cnt from android_logs where tag like '%_pss' union all
-select count(*) as cnt from android_logs where msg like '%i2c_write%' union all
-select count(*) as cnt from android_logs where ts >= 1510113924391 and ts < 1512610021879; \ No newline at end of file
+select count(*) as cnt from android_logs where tag GLOB '*_pss' union all
+select count(*) as cnt from android_logs where msg GLOB '*i2c?write*' or msg GLOB '*I2C?Write*' union all
+select count(*) as cnt from android_logs where ts >= 1510113924391 and ts < 1512610021879;
diff --git a/test/trace_processor/parsing/android_log_msgs.sql b/test/trace_processor/parsing/android_log_msgs.sql
index dfbd6a3d4..16660956f 100644
--- a/test/trace_processor/parsing/android_log_msgs.sql
+++ b/test/trace_processor/parsing/android_log_msgs.sql
@@ -13,11 +13,15 @@
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-create view v1 as select tag, count(*) from android_logs group by tag order by 2 desc limit 5
+create view v1 as select tag, count(*) from android_logs group by tag order by 2 desc limit 5;
create view v2 as select tag, count(*) from android_logs group by tag order by 2 asc limit 5;
-create view v3 as select tag, count(*) from android_logs where msg like '%wakelock%' group by tag;
+create view v3 as
+select tag, count(*)
+from android_logs
+where msg GLOB '*wakelock*' or msg GLOB '*Wakelock*' or msg GLOB '*WakeLock*' or msg GLOB '*wakeLock*'
+group by tag;
create view v4 as select msg, 1 from android_logs limit 10;
@@ -27,4 +31,4 @@ select * from v2 union all
select '-----', 0 union all
select * from v3 union all
select '-----', 0 union all
-select * from v4; \ No newline at end of file
+select * from v4;
diff --git a/test/trace_processor/parsing/android_multiuser_switch.out b/test/trace_processor/parsing/android_multiuser_switch.out
new file mode 100644
index 000000000..a49f9e323
--- /dev/null
+++ b/test/trace_processor/parsing/android_multiuser_switch.out
@@ -0,0 +1,5 @@
+android_multiuser: {
+ user_switch: {
+ duration_ms: 4900
+ }
+} \ No newline at end of file
diff --git a/test/trace_processor/parsing/android_multiuser_switch.textproto b/test/trace_processor/parsing/android_multiuser_switch.textproto
new file mode 100644
index 000000000..d2a836cf0
--- /dev/null
+++ b/test/trace_processor/parsing/android_multiuser_switch.textproto
@@ -0,0 +1,114 @@
+packet {
+ process_tree {
+ processes {
+ pid: 2609
+ ppid: 129
+ cmdline: "system_server"
+ uid: 1000
+ }
+ }
+ process_tree {
+ processes {
+ pid: 5993
+ ppid: 129
+ cmdline: "com.android.systemui"
+ uid: 10216
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 3
+ event {
+ timestamp: 3000000000 # 3e9
+ pid: 4064
+ print {
+ buf: "S|5993|UserDetailView.Adapter#onClick|0\n"
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 3
+ event {
+ timestamp: 3100000000
+ pid: 4064
+ print {
+ buf: "F|5993|UserDetailView.Adapter#onClick|0\n"
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 5186970000
+ pid: 4032
+ print {
+ buf: "S|2609|MetricsLogger:launchObserverNotifyIntentStarted|0\n"
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 5187000000
+ pid: 4032
+ print {
+ buf: "F|2609|MetricsLogger:launchObserverNotifyIntentStarted|0\n"
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 5200000000
+ pid: 4065
+ print {
+ buf: "S|2609|launching: com.google.android.apps.nexuslauncher|0\n"
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 7900000000 # 7.9e9
+ pid: 4065
+ print {
+ buf: "F|2609|launching: com.google.android.apps.nexuslauncher|0\n"
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 7900016000
+ pid: 4075
+ print {
+ buf: "S|2609|MetricsLogger:launchObserverNotifyActivityLaunchFinished|0\n"
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 7900516000
+ pid: 4075
+ print {
+ buf: "F|2609|MetricsLogger:launchObserverNotifyActivityLaunchFinished|0\n"
+ }
+ }
+ }
+}
diff --git a/test/trace_processor/parsing/android_sched_and_ps_stats.out b/test/trace_processor/parsing/android_sched_and_ps_stats.out
index 4ff60f730..a3db195ee 100644
--- a/test/trace_processor/parsing/android_sched_and_ps_stats.out
+++ b/test/trace_processor/parsing/android_sched_and_ps_stats.out
@@ -15,38 +15,62 @@
"ftrace_cpu_bytes_read_end",5,"info","trace",1188
"ftrace_cpu_bytes_read_end",6,"info","trace",1576
"ftrace_cpu_bytes_read_end",7,"info","trace",3264
-"ftrace_cpu_commit_overrun_begin",0,"error","trace",0
-"ftrace_cpu_commit_overrun_begin",1,"error","trace",0
-"ftrace_cpu_commit_overrun_begin",2,"error","trace",0
-"ftrace_cpu_commit_overrun_begin",3,"error","trace",0
-"ftrace_cpu_commit_overrun_begin",4,"error","trace",0
-"ftrace_cpu_commit_overrun_begin",5,"error","trace",0
-"ftrace_cpu_commit_overrun_begin",6,"error","trace",0
-"ftrace_cpu_commit_overrun_begin",7,"error","trace",0
-"ftrace_cpu_commit_overrun_end",0,"error","trace",0
-"ftrace_cpu_commit_overrun_end",1,"error","trace",0
-"ftrace_cpu_commit_overrun_end",2,"error","trace",0
-"ftrace_cpu_commit_overrun_end",3,"error","trace",0
-"ftrace_cpu_commit_overrun_end",4,"error","trace",0
-"ftrace_cpu_commit_overrun_end",5,"error","trace",0
-"ftrace_cpu_commit_overrun_end",6,"error","trace",0
-"ftrace_cpu_commit_overrun_end",7,"error","trace",0
-"ftrace_cpu_dropped_events_begin",0,"error","trace",0
-"ftrace_cpu_dropped_events_begin",1,"error","trace",0
-"ftrace_cpu_dropped_events_begin",2,"error","trace",0
-"ftrace_cpu_dropped_events_begin",3,"error","trace",0
-"ftrace_cpu_dropped_events_begin",4,"error","trace",0
-"ftrace_cpu_dropped_events_begin",5,"error","trace",0
-"ftrace_cpu_dropped_events_begin",6,"error","trace",0
-"ftrace_cpu_dropped_events_begin",7,"error","trace",0
-"ftrace_cpu_dropped_events_end",0,"error","trace",0
-"ftrace_cpu_dropped_events_end",1,"error","trace",0
-"ftrace_cpu_dropped_events_end",2,"error","trace",0
-"ftrace_cpu_dropped_events_end",3,"error","trace",0
-"ftrace_cpu_dropped_events_end",4,"error","trace",0
-"ftrace_cpu_dropped_events_end",5,"error","trace",0
-"ftrace_cpu_dropped_events_end",6,"error","trace",0
-"ftrace_cpu_dropped_events_end",7,"error","trace",0
+"ftrace_cpu_bytes_read_delta",0,"info","trace",20236
+"ftrace_cpu_bytes_read_delta",1,"info","trace",11380
+"ftrace_cpu_bytes_read_delta",2,"info","trace",12336
+"ftrace_cpu_bytes_read_delta",3,"info","trace",6236
+"ftrace_cpu_bytes_read_delta",4,"info","trace",2676
+"ftrace_cpu_bytes_read_delta",5,"info","trace",1188
+"ftrace_cpu_bytes_read_delta",6,"info","trace",1576
+"ftrace_cpu_bytes_read_delta",7,"info","trace",3264
+"ftrace_cpu_commit_overrun_begin",0,"info","trace",0
+"ftrace_cpu_commit_overrun_begin",1,"info","trace",0
+"ftrace_cpu_commit_overrun_begin",2,"info","trace",0
+"ftrace_cpu_commit_overrun_begin",3,"info","trace",0
+"ftrace_cpu_commit_overrun_begin",4,"info","trace",0
+"ftrace_cpu_commit_overrun_begin",5,"info","trace",0
+"ftrace_cpu_commit_overrun_begin",6,"info","trace",0
+"ftrace_cpu_commit_overrun_begin",7,"info","trace",0
+"ftrace_cpu_commit_overrun_end",0,"info","trace",0
+"ftrace_cpu_commit_overrun_end",1,"info","trace",0
+"ftrace_cpu_commit_overrun_end",2,"info","trace",0
+"ftrace_cpu_commit_overrun_end",3,"info","trace",0
+"ftrace_cpu_commit_overrun_end",4,"info","trace",0
+"ftrace_cpu_commit_overrun_end",5,"info","trace",0
+"ftrace_cpu_commit_overrun_end",6,"info","trace",0
+"ftrace_cpu_commit_overrun_end",7,"info","trace",0
+"ftrace_cpu_commit_overrun_delta",0,"error","trace",0
+"ftrace_cpu_commit_overrun_delta",1,"error","trace",0
+"ftrace_cpu_commit_overrun_delta",2,"error","trace",0
+"ftrace_cpu_commit_overrun_delta",3,"error","trace",0
+"ftrace_cpu_commit_overrun_delta",4,"error","trace",0
+"ftrace_cpu_commit_overrun_delta",5,"error","trace",0
+"ftrace_cpu_commit_overrun_delta",6,"error","trace",0
+"ftrace_cpu_commit_overrun_delta",7,"error","trace",0
+"ftrace_cpu_dropped_events_begin",0,"info","trace",0
+"ftrace_cpu_dropped_events_begin",1,"info","trace",0
+"ftrace_cpu_dropped_events_begin",2,"info","trace",0
+"ftrace_cpu_dropped_events_begin",3,"info","trace",0
+"ftrace_cpu_dropped_events_begin",4,"info","trace",0
+"ftrace_cpu_dropped_events_begin",5,"info","trace",0
+"ftrace_cpu_dropped_events_begin",6,"info","trace",0
+"ftrace_cpu_dropped_events_begin",7,"info","trace",0
+"ftrace_cpu_dropped_events_end",0,"info","trace",0
+"ftrace_cpu_dropped_events_end",1,"info","trace",0
+"ftrace_cpu_dropped_events_end",2,"info","trace",0
+"ftrace_cpu_dropped_events_end",3,"info","trace",0
+"ftrace_cpu_dropped_events_end",4,"info","trace",0
+"ftrace_cpu_dropped_events_end",5,"info","trace",0
+"ftrace_cpu_dropped_events_end",6,"info","trace",0
+"ftrace_cpu_dropped_events_end",7,"info","trace",0
+"ftrace_cpu_dropped_events_delta",0,"error","trace",0
+"ftrace_cpu_dropped_events_delta",1,"error","trace",0
+"ftrace_cpu_dropped_events_delta",2,"error","trace",0
+"ftrace_cpu_dropped_events_delta",3,"error","trace",0
+"ftrace_cpu_dropped_events_delta",4,"error","trace",0
+"ftrace_cpu_dropped_events_delta",5,"error","trace",0
+"ftrace_cpu_dropped_events_delta",6,"error","trace",0
+"ftrace_cpu_dropped_events_delta",7,"error","trace",0
"ftrace_cpu_entries_begin",0,"info","trace",4
"ftrace_cpu_entries_begin",1,"info","trace",4
"ftrace_cpu_entries_begin",2,"info","trace",23
@@ -63,6 +87,14 @@
"ftrace_cpu_entries_end",5,"info","trace",21
"ftrace_cpu_entries_end",6,"info","trace",26
"ftrace_cpu_entries_end",7,"info","trace",54
+"ftrace_cpu_entries_delta",0,"info","trace",337
+"ftrace_cpu_entries_delta",1,"info","trace",191
+"ftrace_cpu_entries_delta",2,"info","trace",202
+"ftrace_cpu_entries_delta",3,"info","trace",107
+"ftrace_cpu_entries_delta",4,"info","trace",45
+"ftrace_cpu_entries_delta",5,"info","trace",21
+"ftrace_cpu_entries_delta",6,"info","trace",26
+"ftrace_cpu_entries_delta",7,"info","trace",54
"ftrace_cpu_now_ts_begin",0,"info","trace",81473010735000
"ftrace_cpu_now_ts_begin",1,"info","trace",81473010800000
"ftrace_cpu_now_ts_begin",2,"info","trace",81473010839000
@@ -103,14 +135,22 @@
"ftrace_cpu_overrun_begin",5,"info","trace",0
"ftrace_cpu_overrun_begin",6,"info","trace",0
"ftrace_cpu_overrun_begin",7,"info","trace",0
-"ftrace_cpu_overrun_end",0,"data_loss","trace",0
-"ftrace_cpu_overrun_end",1,"data_loss","trace",0
-"ftrace_cpu_overrun_end",2,"data_loss","trace",0
-"ftrace_cpu_overrun_end",3,"data_loss","trace",0
-"ftrace_cpu_overrun_end",4,"data_loss","trace",0
-"ftrace_cpu_overrun_end",5,"data_loss","trace",0
-"ftrace_cpu_overrun_end",6,"data_loss","trace",0
-"ftrace_cpu_overrun_end",7,"data_loss","trace",0
+"ftrace_cpu_overrun_end",0,"info","trace",0
+"ftrace_cpu_overrun_end",1,"info","trace",0
+"ftrace_cpu_overrun_end",2,"info","trace",0
+"ftrace_cpu_overrun_end",3,"info","trace",0
+"ftrace_cpu_overrun_end",4,"info","trace",0
+"ftrace_cpu_overrun_end",5,"info","trace",0
+"ftrace_cpu_overrun_end",6,"info","trace",0
+"ftrace_cpu_overrun_end",7,"info","trace",0
+"ftrace_cpu_overrun_delta",0,"data_loss","trace",0
+"ftrace_cpu_overrun_delta",1,"data_loss","trace",0
+"ftrace_cpu_overrun_delta",2,"data_loss","trace",0
+"ftrace_cpu_overrun_delta",3,"data_loss","trace",0
+"ftrace_cpu_overrun_delta",4,"data_loss","trace",0
+"ftrace_cpu_overrun_delta",5,"data_loss","trace",0
+"ftrace_cpu_overrun_delta",6,"data_loss","trace",0
+"ftrace_cpu_overrun_delta",7,"data_loss","trace",0
"ftrace_cpu_read_events_begin",0,"info","trace",0
"ftrace_cpu_read_events_begin",1,"info","trace",0
"ftrace_cpu_read_events_begin",2,"info","trace",0
@@ -127,6 +167,15 @@
"ftrace_cpu_read_events_end",5,"info","trace",23232
"ftrace_cpu_read_events_end",6,"info","trace",36733
"ftrace_cpu_read_events_end",7,"info","trace",39240
+"ftrace_cpu_read_events_delta",0,"info","trace",62303
+"ftrace_cpu_read_events_delta",1,"info","trace",54916
+"ftrace_cpu_read_events_delta",2,"info","trace",55882
+"ftrace_cpu_read_events_delta",3,"info","trace",47953
+"ftrace_cpu_read_events_delta",4,"info","trace",31345
+"ftrace_cpu_read_events_delta",5,"info","trace",23232
+"ftrace_cpu_read_events_delta",6,"info","trace",36733
+"ftrace_cpu_read_events_delta",7,"info","trace",39240
+"traced_buf_abi_violations",0,"data_loss","trace",0
"traced_buf_buffer_size",0,"info","trace",0
"traced_buf_bytes_overwritten",0,"info","trace",0
"traced_buf_bytes_read",0,"info","trace",0
diff --git a/test/trace_processor/parsing/args_string_filter_null.sql b/test/trace_processor/parsing/args_string_filter_null.sql
index 50f90e196..c42e2f3ad 100644
--- a/test/trace_processor/parsing/args_string_filter_null.sql
+++ b/test/trace_processor/parsing/args_string_filter_null.sql
@@ -39,7 +39,7 @@ where string_value >= NULL
UNION
select string_value
from args
-where string_value LIKE NULL
+where string_value GLOB NULL
UNION
select string_value
from args
diff --git a/test/trace_processor/parsing/atrace_compressed_sched_count.out b/test/trace_processor/parsing/atrace_compressed_sched_count.out
new file mode 100644
index 000000000..c03bd1147
--- /dev/null
+++ b/test/trace_processor/parsing/atrace_compressed_sched_count.out
@@ -0,0 +1,2 @@
+"COUNT(1)"
+1120
diff --git a/test/trace_processor/parsing/atrace_uncompressed_sched_count.out b/test/trace_processor/parsing/atrace_uncompressed_sched_count.out
new file mode 100644
index 000000000..41c340bb2
--- /dev/null
+++ b/test/trace_processor/parsing/atrace_uncompressed_sched_count.out
@@ -0,0 +1,2 @@
+"COUNT(1)"
+9
diff --git a/test/trace_processor/parsing/b120487929.sql b/test/trace_processor/parsing/b120487929.sql
index 179d3242a..a266d7a19 100644
--- a/test/trace_processor/parsing/b120487929.sql
+++ b/test/trace_processor/parsing/b120487929.sql
@@ -38,19 +38,19 @@ create view idle_view
where name = 'cpuidle';
create virtual table freq_idle
- using span_join(freq_view PARTITIONED cpu, idle_view PARTITIONED cpu)
+ using span_join(freq_view PARTITIONED cpu, idle_view PARTITIONED cpu);
create virtual table window_freq_idle using window;
create virtual table span_freq_idle
- using span_join(freq_idle PARTITIONED cpu, window_freq_idle)
+ using span_join(freq_idle PARTITIONED cpu, window_freq_idle);
update window_freq_idle
set
window_start=(select min(ts) from sched),
window_dur=(select max(ts) - min(ts) from sched),
quantum=1000000
- where rowid = 0
+ where rowid = 0;
create view counter_view
as select
@@ -66,6 +66,6 @@ create view counter_view
when 4294967295 then freq_value
else idle_value
end as value
- from span_freq_idle
+ from span_freq_idle;
-select cpu, name, value, sum(dur) from counter_view group by cpu, name, value
+select cpu, name, value, sum(dur) from counter_view group by cpu, name, value;
diff --git a/test/trace_processor/parsing/cgroup_attach_task_post_s.textproto b/test/trace_processor/parsing/cgroup_attach_task_post_s.textproto
new file mode 100644
index 000000000..6950e5a77
--- /dev/null
+++ b/test/trace_processor/parsing/cgroup_attach_task_post_s.textproto
@@ -0,0 +1,17 @@
+packet {
+ ftrace_events {
+ cpu: 3
+ event {
+ timestamp: 74289018336
+ pid: 1
+ cgroup_attach_task {
+ dst_root: 1
+ dst_id: 2
+ pid: 3
+ comm: "foo"
+ dst_level: 4
+ dst_path: "bar"
+ }
+ }
+ }
+ } \ No newline at end of file
diff --git a/test/trace_processor/parsing/cgroup_attach_task_post_s_print_systrace.out b/test/trace_processor/parsing/cgroup_attach_task_post_s_print_systrace.out
new file mode 100644
index 000000000..5d47364b8
--- /dev/null
+++ b/test/trace_processor/parsing/cgroup_attach_task_post_s_print_systrace.out
@@ -0,0 +1,2 @@
+"to_ftrace(id)"
+" <unknown>-1 (-----) [003] .... 74.289018: cgroup_attach_task: dst_root=1 dst_id=2 dst_level=4 dst_path=bar pid=3 comm=foo"
diff --git a/test/trace_processor/parsing/cgroup_attach_task_pre_s.textproto b/test/trace_processor/parsing/cgroup_attach_task_pre_s.textproto
new file mode 100644
index 000000000..679b211c1
--- /dev/null
+++ b/test/trace_processor/parsing/cgroup_attach_task_pre_s.textproto
@@ -0,0 +1,16 @@
+packet {
+ ftrace_events {
+ cpu: 3
+ event {
+ timestamp: 74289018336
+ pid: 1
+ cgroup_attach_task {
+ dst_root: 1
+ dst_id: 2
+ pid: 3
+ comm: "foo"
+ cname: "bar"
+ }
+ }
+ }
+ } \ No newline at end of file
diff --git a/test/trace_processor/parsing/cgroup_attach_task_pre_s_print_systrace.out b/test/trace_processor/parsing/cgroup_attach_task_pre_s_print_systrace.out
new file mode 100644
index 000000000..e7d5df70b
--- /dev/null
+++ b/test/trace_processor/parsing/cgroup_attach_task_pre_s_print_systrace.out
@@ -0,0 +1,2 @@
+"to_ftrace(id)"
+" <unknown>-1 (-----) [003] .... 74.289018: cgroup_attach_task: dst_root=1 dst_id=2 cgroup=bar pid=3 comm=foo"
diff --git a/test/trace_processor/parsing/chrome_metadata.out b/test/trace_processor/parsing/chrome_metadata.out
index 71e8908de..ffdc3733e 100644
--- a/test/trace_processor/parsing/chrome_metadata.out
+++ b/test/trace_processor/parsing/chrome_metadata.out
@@ -1,4 +1,5 @@
"id","type","name","key_type","int_value","str_value"
-0,"metadata","cr-playstore_version_code","single",101,"[NULL]"
-1,"metadata","cr-enabled_categories","single","[NULL]","cat1,cat2,cat3"
-2,"metadata","trace_size_bytes","single",50,"[NULL]"
+0,"metadata","trace_uuid","single","[NULL]","00000000-0000-0000-23b6-9c184f48509d"
+1,"metadata","cr-playstore_version_code","single",101,"[NULL]"
+2,"metadata","cr-enabled_categories","single","[NULL]","cat1,cat2,cat3"
+3,"metadata","trace_size_bytes","single",50,"[NULL]"
diff --git a/test/trace_processor/parsing/counters_json_counters.out b/test/trace_processor/parsing/counters_json_counters.out
new file mode 100644
index 000000000..dfe4747d8
--- /dev/null
+++ b/test/trace_processor/parsing/counters_json_counters.out
@@ -0,0 +1,4 @@
+"name","ts","value"
+"ctr cats",0,0.000000
+"ctr cats",10000,10.000000
+"ctr cats",20000,0.000000
diff --git a/test/trace_processor/parsing/display_time_unit_slices.out b/test/trace_processor/parsing/display_time_unit_slices.out
index 4343a9e91..cee485bc8 100644
--- a/test/trace_processor/parsing/display_time_unit_slices.out
+++ b/test/trace_processor/parsing/display_time_unit_slices.out
@@ -1,2 +1,2 @@
"ts","dur","name"
-1597071955492308000,211463000,"add_graph"
+-7794778920422990592,211463000000,"add_graph"
diff --git a/test/trace_processor/parsing/flow_events_json_v2.json b/test/trace_processor/parsing/flow_events_json_v2.json
index f62e86d78..7b53b6789 100644
--- a/test/trace_processor/parsing/flow_events_json_v2.json
+++ b/test/trace_processor/parsing/flow_events_json_v2.json
@@ -10,7 +10,9 @@
"args":{},
"dur": 10,
"bind_id": "0x402",
- "flow_out": true
+ "flow_out": true,
+ "tts":3005,
+ "tdur":7
},
{
"cat": "ipc",
@@ -23,7 +25,9 @@
"dur": 10,
"bind_id": "0x403",
"flow_out": true,
- "flow_in": false
+ "flow_in": false,
+ "tts":1,
+ "tdur":5
},
{
"cat": "ipc",
@@ -48,7 +52,9 @@
"dur": 500,
"bind_id": "0x402",
"flow_in": true,
- "flow_out": true
+ "flow_out": true,
+ "tts":3204,
+ "tdur":100
},
{
"cat": "ipc",
@@ -60,7 +66,9 @@
"args": {},
"dur": 400,
"bind_id": "0x402",
- "flow_in": true
+ "flow_in": true,
+ "tts":3335,
+ "tdur":340
},
{
"cat": "ipc",
@@ -71,7 +79,18 @@
"name": "SomeOtherSlice",
"args": {},
"bind_id": "0x402",
- "flow_in": true
+ "flow_in": true,
+ "tts":3335
+ },
+ {
+ "cat": "ipc",
+ "pid": 15875,
+ "tid": 15895,
+ "ts": 3366,
+ "dur": 0,
+ "ph": "i",
+ "name": "SomeOtherSliceInstant",
+ "args": {}
},
{
"cat": "ipc",
@@ -80,7 +99,8 @@
"ts": 4330,
"ph": "E",
"name": "SomeOtherSlice",
+ "tts":4331,
"args": {}
}
]
- } \ No newline at end of file
+ }
diff --git a/test/trace_processor/parsing/index b/test/trace_processor/parsing/index
index 4b2ca9a7a..9952dea32 100644
--- a/test/trace_processor/parsing/index
+++ b/test/trace_processor/parsing/index
@@ -56,28 +56,22 @@ ion_stat.textproto ion_stat.sql ion_stat.out
# Mm Event
../../data/mm_event.pb mm_event.sql mm_event.out
-# Android userspace async slices
-android_async_slice.textproto process_track_slices.sql process_track_slices_android_async_slice.out
-
# Check the systrace conversion code in the raw table.
# Print events
../../data/lmk_userspace.pb print_systrace.sql print_systrace_lmk_userspace.out
kernel_tmw_counter.textproto thread_counter_and_track.sql kernel_tmw_counter_thread_counter_and_track.out
+kernel_dpu_tmw_counter.textproto thread_counter_and_track.sql kernel_dpu_tmw_counter_thread_counter_and_track.out
# Unsigned integers
print_systrace_unsigned.py print_systrace.sql print_systrace_unsigned.out
+# cgroup_attach_task systrace conversion.
+cgroup_attach_task_pre_s.textproto print_systrace.sql cgroup_attach_task_pre_s_print_systrace.out
+cgroup_attach_task_post_s.textproto print_systrace.sql cgroup_attach_task_post_s_print_systrace.out
+
# Parsing systrace files
../../data/systrace.html systrace_html.sql systrace_html.out
../../data/trailing_empty.systrace sched_smoke.sql sched_smoke_trailing_empty.out
-# Check error handling when parsing print events.
-bad_print.textproto list_slices.sql bad_print_textproto_list_slices.out
-bad_print.systrace list_slices.sql bad_print_systrace_list_slices.out
-
-# Match legacy Catapult behaviour when we see multiple S events b2b with the same cookie
-# name and upid.
-android_b2b_async_begin.textproto list_slices.sql android_b2b_async_begin_list_slices.out
-
# LMK handling
kernel_lmk.py lmk.sql lmk_kernel_lmk.out
../../data/lmk_userspace.pb lmk.sql lmk_userspace_lmk.out
@@ -104,6 +98,9 @@ thread_time_in_state_event.py thread_time_in_state_event.sql thread_time_in_stat
thread_time_in_state.textproto android_thread_time_in_state android_thread_time_in_state.out
thread_time_in_state_unknown.textproto android_thread_time_in_state android_thread_time_in_state_unknown.out
+# thread_slice tables.
+flow_events_json_v2.json thread_time_in_thread_slice.sql thread_time_in_thread_slice.out
+
# Initial display state
initial_display_state.textproto initial_display_state.sql initial_display_state.out
@@ -142,3 +139,24 @@ sched_blocked_reason_symbolized.textproto ../common/to_systrace.sql sched_blocke
# Floating point numbers
../../data/decimal_timestamp.json slices.sql decimal_timestamp_slices.out
+
+# JSON instants and counters
+../../data/counters.json json_counters.sql counters_json_counters.out
+../../data/instants.json json_instants.sql instants_json_instants.out
+
+# Trace quality metric
+very_long_sched.py android_trace_quality very_long_sched_android_trace_quality.out
+
+# Regression test for b/193721088 (infra prepending " done\n" to atrace)
+../../data/atrace_b_193721088.atr sched_smoke.sql sched_smoke_trailing_empty.out
+
+# Multiuser
+android_multiuser_switch.textproto android_multiuser android_multiuser_switch.out
+
+# Output of atrace -z.
+../../data/atrace_compressed.ctrace sched_smoke.sql atrace_compressed_sched_count.out
+
+# Output of adb shell "atrace -t 1 sched" > out.txt". It has extra garbage
+# coming from stderr before the TRACE: marker. See b/208691037.
+../../data/atrace_uncompressed_b_208691037 sched_smoke.sql atrace_uncompressed_sched_count.out
+otheruuids.textproto android_other_traces otheruuids_android_other_traces.out
diff --git a/test/trace_processor/parsing/instants_json_instants.out b/test/trace_processor/parsing/instants_json_instants.out
new file mode 100644
index 000000000..2fb9fb402
--- /dev/null
+++ b/test/trace_processor/parsing/instants_json_instants.out
@@ -0,0 +1,5 @@
+"ts","slice_name","tid","pid"
+1234523300,"Thread",2347,"[NULL]"
+1235523300,"Global","[NULL]","[NULL]"
+1236523300,"Process","[NULL]",2320
+1237523300,"None",6790,"[NULL]"
diff --git a/test/trace_processor/parsing/ion_stat.sql b/test/trace_processor/parsing/ion_stat.sql
index 1032ac639..5cdc8d084 100644
--- a/test/trace_processor/parsing/ion_stat.sql
+++ b/test/trace_processor/parsing/ion_stat.sql
@@ -1,4 +1,4 @@
SELECT t.name, c.ts, c.value
FROM counter c
JOIN track t ON c.track_id = t.id
-WHERE t.name LIKE 'mem.ion%';
+WHERE t.name GLOB 'mem.ion*';
diff --git a/test/trace_processor/parsing/json_counters.sql b/test/trace_processor/parsing/json_counters.sql
new file mode 100644
index 000000000..604c2c1ae
--- /dev/null
+++ b/test/trace_processor/parsing/json_counters.sql
@@ -0,0 +1,6 @@
+select
+ process_counter_track.name,
+ counter.ts,
+ counter.value
+from counter
+join process_counter_track on (counter.track_id = process_counter_track.id); \ No newline at end of file
diff --git a/test/trace_processor/parsing/json_instants.sql b/test/trace_processor/parsing/json_instants.sql
new file mode 100644
index 000000000..d76ef8905
--- /dev/null
+++ b/test/trace_processor/parsing/json_instants.sql
@@ -0,0 +1,12 @@
+select
+ slice.ts,
+ slice.name as slice_name,
+ thread.tid,
+ process.pid
+from slice
+join track on (slice.track_id = track.id)
+left join thread_track on (slice.track_id = thread_track.id)
+left join thread on (thread_track.utid = thread.utid)
+left join process_track on (slice.track_id = process_track.id)
+left join process on (process_track.upid = process.upid)
+where dur = 0; \ No newline at end of file
diff --git a/test/trace_processor/parsing/kernel_dpu_tmw_counter.textproto b/test/trace_processor/parsing/kernel_dpu_tmw_counter.textproto
new file mode 100644
index 000000000..32bd0cf83
--- /dev/null
+++ b/test/trace_processor/parsing/kernel_dpu_tmw_counter.textproto
@@ -0,0 +1,47 @@
+packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 795572805481
+ pid: 237
+ dpu_tracing_mark_write {
+ pid: 237
+ name: "dpu_vote_clock"
+ type: 67
+ value: 123
+ }
+ }
+ event {
+ timestamp: 795572870504
+ pid: 515
+ dpu_tracing_mark_write {
+ pid: 237
+ name: "dpu_vote_clock"
+ type: 67
+ value: 100
+ }
+ }
+ event {
+ timestamp: 795620516581
+ pid: 237
+ dpu_tracing_mark_write {
+ pid: 237
+ name: "dpu_vote_clock"
+ type: 67
+ value: 125
+ }
+ }
+ event {
+ timestamp: 795620943421
+ pid: 515
+ dpu_tracing_mark_write {
+ pid: 237
+ name: "dpu_vote_clock"
+ type: 67
+ value: 100
+ }
+ }
+ }
+ trusted_uid: 9999
+ trusted_packet_sequence_id: 3
+} \ No newline at end of file
diff --git a/test/trace_processor/parsing/kernel_dpu_tmw_counter_thread_counter_and_track.out b/test/trace_processor/parsing/kernel_dpu_tmw_counter_thread_counter_and_track.out
new file mode 100644
index 000000000..683b8daa0
--- /dev/null
+++ b/test/trace_processor/parsing/kernel_dpu_tmw_counter_thread_counter_and_track.out
@@ -0,0 +1,5 @@
+"ts","name","value","tid"
+795572805481,"dpu_vote_clock",123.000000,237
+795572870504,"dpu_vote_clock",100.000000,237
+795620516581,"dpu_vote_clock",125.000000,237
+795620943421,"dpu_vote_clock",100.000000,237
diff --git a/test/trace_processor/parsing/list_slices.sql b/test/trace_processor/parsing/list_slices.sql
deleted file mode 100644
index 211ae893a..000000000
--- a/test/trace_processor/parsing/list_slices.sql
+++ /dev/null
@@ -1,2 +0,0 @@
-SELECT ts, dur, name
-FROM slice \ No newline at end of file
diff --git a/test/trace_processor/parsing/mm_event.sql b/test/trace_processor/parsing/mm_event.sql
index 5130db6b0..56d4eabef 100644
--- a/test/trace_processor/parsing/mm_event.sql
+++ b/test/trace_processor/parsing/mm_event.sql
@@ -17,6 +17,6 @@ select ts, name, value, upid
from counter
inner join process_counter_track
on counter.track_id = process_counter_track.id
-where name like 'mem.mm.%'
+where name GLOB 'mem.mm.*'
order by ts
limit 40
diff --git a/test/trace_processor/parsing/otheruuids.textproto b/test/trace_processor/parsing/otheruuids.textproto
new file mode 100644
index 000000000..e5281e8e0
--- /dev/null
+++ b/test/trace_processor/parsing/otheruuids.textproto
@@ -0,0 +1,46 @@
+packet {
+ ftrace_events {
+ cpu: 4
+ event {
+ timestamp: 171311335293
+ pid: 7663
+ print {
+ buf: "N|7663|OtherTraces|finalize-uuid-75e4c6d0-d8f6-4f82-fa4b-9e09c5512288\n"
+ }
+ }
+ }
+ trusted_uid: 9999
+ trusted_packet_sequence_id: 2
+ trusted_pid: 1277
+ previous_packet_dropped: true
+}
+packet {
+ ftrace_events {
+ cpu: 4
+ event {
+ timestamp: 187198579688
+ pid: 7752
+ print {
+ buf: "N|7752|OtherTraces|finalize-uuid-ad836701-3113-3fb1-be4f-f7731e23fbbf\n"
+ }
+ }
+ }
+ trusted_uid: 9999
+ trusted_packet_sequence_id: 2
+ trusted_pid: 1277
+}
+packet {
+ ftrace_events {
+ cpu: 6
+ event {
+ timestamp: 200857707872
+ pid: 7824
+ print {
+ buf: "N|7824|OtherTraces|finalize-uuid-0de1a010-efa1-a081-2345-969b1186a6ab\n"
+ }
+ }
+ }
+ trusted_uid: 9999
+ trusted_packet_sequence_id: 2
+ trusted_pid: 1277
+}
diff --git a/test/trace_processor/parsing/otheruuids_android_other_traces.out b/test/trace_processor/parsing/otheruuids_android_other_traces.out
new file mode 100644
index 000000000..61df98266
--- /dev/null
+++ b/test/trace_processor/parsing/otheruuids_android_other_traces.out
@@ -0,0 +1,5 @@
+android_other_traces {
+ finalized_traces_uuid: "75e4c6d0-d8f6-4f82-fa4b-9e09c5512288"
+ finalized_traces_uuid: "ad836701-3113-3fb1-be4f-f7731e23fbbf"
+ finalized_traces_uuid: "0de1a010-efa1-a081-2345-969b1186a6ab"
+}
diff --git a/test/trace_processor/parsing/rss_stat_mm_id_clone.py b/test/trace_processor/parsing/rss_stat_mm_id_clone.py
index 3b36d887f..a12f5164a 100644
--- a/test/trace_processor/parsing/rss_stat_mm_id_clone.py
+++ b/test/trace_processor/parsing/rss_stat_mm_id_clone.py
@@ -81,7 +81,7 @@ trace.add_rss_stat(108, tid=10, member=0, size=110, mm_id=0x1234, curr=1)
# In this packet, we check what happens to kernel threads in RSS stat.
trace.add_ftrace_packet(1)
-# Emit an rss stat event for the the existing kernel thread.
+# Emit an rss stat event for the existing kernel thread.
trace.add_rss_stat(100, tid=3, member=0, size=10, mm_id=0x2345, curr=1)
# Start a new kernel thread.
diff --git a/test/trace_processor/parsing/stats.sql b/test/trace_processor/parsing/stats.sql
index d68b28fe2..02316b24f 100644
--- a/test/trace_processor/parsing/stats.sql
+++ b/test/trace_processor/parsing/stats.sql
@@ -14,4 +14,4 @@
-- limitations under the License.
--
select name, idx, severity, source, value
-from stats where name like 'ftrace_cpu_%' or name like 'traced_buf_%'; \ No newline at end of file
+from stats where name GLOB 'ftrace_cpu_*' or name GLOB 'traced_buf_*'; \ No newline at end of file
diff --git a/test/trace_processor/parsing/systrace_html.out b/test/trace_processor/parsing/systrace_html.out
index fccba890d..7bc920339 100644
--- a/test/trace_processor/parsing/systrace_html.out
+++ b/test/trace_processor/parsing/systrace_html.out
@@ -3022,8 +3022,8 @@
6824713437995000,7,43000,6824713438038000,0,"R",120,"[NULL]","swapper",0
6824713438009000,6,19000,6824713438028000,630,"S",100,630,"kworker/u17:1",1134
6824713438028000,6,10000,6824713438038000,669,"S",120,669,"kworker/6:1",14833
-6824713438038000,7,7000,6824713438045000,2487,"S",120,739,"UsbFfs-worker",20308
6824713438038000,6,283000,6824713438321000,0,"R",120,"[NULL]","swapper",0
+6824713438038000,7,7000,6824713438045000,2487,"S",120,739,"UsbFfs-worker",20308
6824713438045000,7,470000,6824713438515000,0,"R",120,"[NULL]","swapper",0
6824713438321000,6,20000,6824713438341000,630,"S",100,630,"kworker/u17:1",1134
6824713438341000,6,34000,6824713438375000,0,"R",120,"[NULL]","swapper",0
@@ -3194,8 +3194,8 @@
6824713461977000,0,38000,6824713462015000,0,"R",120,"[NULL]","swapper",0
6824713462015000,0,162000,6824713462177000,771,"S",97,493,"DispSync",676
6824713462129000,1,262000,6824713462391000,0,"R",120,"[NULL]","swapper",0
-6824713462177000,2,255000,6824713462432000,773,"S",97,493,"app",678
6824713462177000,0,142000,6824713462319000,0,"R",120,"[NULL]","swapper",0
+6824713462177000,2,255000,6824713462432000,773,"S",97,493,"app",678
6824713462319000,0,1790000,6824713464109000,644,"S",120,644,"ndroid.systemui",1664
6824713462391000,1,75000,6824713462466000,771,"S",97,493,"DispSync",676
6824713462432000,2,1186000,6824713463618000,0,"R",120,"[NULL]","swapper",0
diff --git a/test/trace_processor/parsing/systrace_html.sql b/test/trace_processor/parsing/systrace_html.sql
index 55236aaa6..e94b82aa6 100644
--- a/test/trace_processor/parsing/systrace_html.sql
+++ b/test/trace_processor/parsing/systrace_html.sql
@@ -13,4 +13,7 @@
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-select ts, cpu, dur, ts_end, utid, end_state, priority, upid, name, tid from sched join thread using(utid) order by ts \ No newline at end of file
+select ts, cpu, dur, ts_end, utid, end_state, priority, upid, name, tid
+from sched
+join thread using(utid)
+order by ts;
diff --git a/test/trace_processor/parsing/thread_time_in_state_event.out b/test/trace_processor/parsing/thread_time_in_state_event.out
index af8192ca3..f71fd2984 100644
--- a/test/trace_processor/parsing/thread_time_in_state_event.out
+++ b/test/trace_processor/parsing/thread_time_in_state_event.out
@@ -1,13 +1,13 @@
-"track_type","track_name","ts","dur","upid","value"
-"counter","Total big core cycles / sec",2000000000,1000000000,0,1000
-"counter","Total little core cycles / sec",2000000000,1000000000,0,100
-"counter","Thread 10 (1) (big core)",2000000000,1000000000,1,1000
-"counter","Thread 10 (1) (little core)",2000000000,1000000000,1,100
-"counter","Total big core cycles / sec",3000000000,1000000000,0,30000
-"counter","Total little core cycles / sec",3000000000,1000000000,0,3100
-"counter","Thread 10 (1) (big core)",3000000000,1000000000,1,20000
-"counter","Thread 10 (1) (little core)",3000000000,1000000000,1,2000
-"counter","Thread 20 (3) (big core)",3000000000,1000000000,2,10000
-"counter","Thread 20 (3) (little core)",3000000000,1000000000,2,1000
-"counter","Thread 40 (7) (little core)",3000000000,1000000000,4,100
+"track_type","track_name","upid","ts","value"
+"counter","Total big core mcycles",0,2000000000,1.100000
+"counter","Total little core mcycles",0,2000000000,1.100000
+"counter","Thread 10 (1) (big core) mcycles",1,2000000000,1.100000
+"counter","Thread 10 (1) (little core) mcycles",1,2000000000,1.100000
+"counter","Total big core mcycles",0,3000000000,23.100000
+"counter","Total little core mcycles",0,3000000000,23.100000
+"counter","Thread 10 (1) (big core) mcycles",1,3000000000,23.100000
+"counter","Thread 10 (1) (little core) mcycles",1,3000000000,23.100000
+"counter","Thread 20 (3) (big core) mcycles",2,3000000000,11.000000
+"counter","Thread 20 (3) (little core) mcycles",2,3000000000,11.000000
+"counter","Thread 40 (7) (little core) mcycles",4,3000000000,0.100000
diff --git a/test/trace_processor/parsing/thread_time_in_thread_slice.out b/test/trace_processor/parsing/thread_time_in_thread_slice.out
new file mode 100644
index 000000000..1be63042c
--- /dev/null
+++ b/test/trace_processor/parsing/thread_time_in_thread_slice.out
@@ -0,0 +1,8 @@
+"name","thread_ts","thread_dur"
+"SenderB",1000,5000
+"Blergh","[NULL]","[NULL]"
+"SenderA",3005000,7000
+"OtherSlice",3204000,100000
+"SomeSlice",3335000,340000
+"SomeOtherSlice",3335000,996000
+"SomeOtherSliceInstant","[NULL]","[NULL]"
diff --git a/test/trace_processor/parsing/thread_time_in_thread_slice.sql b/test/trace_processor/parsing/thread_time_in_thread_slice.sql
new file mode 100644
index 000000000..207376b53
--- /dev/null
+++ b/test/trace_processor/parsing/thread_time_in_thread_slice.sql
@@ -0,0 +1,3 @@
+SELECT
+ name, thread_ts, thread_dur
+FROM thread_slice;
diff --git a/test/trace_processor/parsing/very_long_sched.py b/test/trace_processor/parsing/very_long_sched.py
new file mode 100644
index 000000000..878fcd250
--- /dev/null
+++ b/test/trace_processor/parsing/very_long_sched.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python3
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from os import sys, path
+
+import synth_common
+
+trace = synth_common.create_trace()
+
+trace.add_packet(ts=1)
+trace.add_process(10, 0, "processa")
+trace.add_process(20, 0, "processb")
+
+trace.add_ftrace_packet(0)
+
+# Add a very long (~1 month long) sched slice.
+trace.add_sched(ts=50, prev_pid=10, next_pid=20)
+
+end_ts = 1 * 30 * 24 * 60 * 60 * 60 * 1000 * 1000 * 1000
+trace.add_sched(ts=end_ts, prev_pid=20, next_pid=10)
+
+sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/parsing/very_long_sched_android_trace_quality.out b/test/trace_processor/parsing/very_long_sched_android_trace_quality.out
new file mode 100644
index 000000000..3c0537cf0
--- /dev/null
+++ b/test/trace_processor/parsing/very_long_sched_android_trace_quality.out
@@ -0,0 +1,5 @@
+android_trace_quality {
+ failures {
+ name: "sched_slice_too_long"
+ }
+} \ No newline at end of file
diff --git a/test/trace_processor/performance/cpu_frequency_limits.out b/test/trace_processor/performance/cpu_frequency_limits.out
new file mode 100644
index 000000000..1c4348f0c
--- /dev/null
+++ b/test/trace_processor/performance/cpu_frequency_limits.out
@@ -0,0 +1,13 @@
+"ts","value","cpu"
+90000000,2800000.000000,"Cpu 6 Max"
+90000000,500000.000000,"Cpu 6 Min"
+100000000,1700000.000000,"Cpu 6 Max"
+100000000,500000.000000,"Cpu 6 Min"
+110000000,2800000.000000,"Cpu 6 Max"
+110000000,1400000.000000,"Cpu 6 Min"
+120000000,1500000.000000,"Cpu 6 Max"
+120000000,500000.000000,"Cpu 6 Min"
+120000000,1400000.000000,"Cpu 4 Max"
+120000000,600000.000000,"Cpu 4 Min"
+130000000,2200000.000000,"Cpu 4 Max"
+130000000,800000.000000,"Cpu 4 Min"
diff --git a/test/trace_processor/performance/cpu_frequency_limits.sql b/test/trace_processor/performance/cpu_frequency_limits.sql
new file mode 100644
index 000000000..06e18523b
--- /dev/null
+++ b/test/trace_processor/performance/cpu_frequency_limits.sql
@@ -0,0 +1,12 @@
+SELECT
+ ts,
+ value,
+ REPLACE(name, " Freq Limit", "") AS cpu
+FROM
+ counter AS c
+ LEFT JOIN
+ counter_track AS t
+ ON c.track_id = t.id
+WHERE
+ name GLOB "* Freq Limit"
+ORDER BY ts;
diff --git a/test/trace_processor/performance/cpu_frequency_limits.textproto b/test/trace_processor/performance/cpu_frequency_limits.textproto
new file mode 100644
index 000000000..2ad9ac020
--- /dev/null
+++ b/test/trace_processor/performance/cpu_frequency_limits.textproto
@@ -0,0 +1,84 @@
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 90000000
+ pid: 200
+ cpu_frequency_limits {
+ max_freq: 2800000
+ min_freq: 500000
+ cpu_id: 6
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 100000000
+ pid: 500
+ cpu_frequency_limits {
+ max_freq: 1700000
+ min_freq: 500000
+ cpu_id: 6
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 110000000
+ pid: 80
+ cpu_frequency_limits {
+ max_freq: 2800000
+ min_freq: 1400000
+ cpu_id: 6
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 120000000
+ pid: 300
+ cpu_frequency_limits {
+ max_freq: 1500000
+ min_freq: 500000
+ cpu_id: 6
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 4
+ event {
+ timestamp: 120000000
+ pid: 300
+ cpu_frequency_limits {
+ max_freq: 1400000
+ min_freq: 600000
+ cpu_id: 4
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 4
+ event {
+ timestamp: 130000000
+ pid: 600
+ cpu_frequency_limits {
+ max_freq: 2200000
+ min_freq: 800000
+ cpu_id: 4
+ }
+ }
+ }
+}
diff --git a/test/trace_processor/performance/index b/test/trace_processor/performance/index
new file mode 100644
index 000000000..484f71799
--- /dev/null
+++ b/test/trace_processor/performance/index
@@ -0,0 +1,4 @@
+# IRQ max runtime and count over 1ms
+irq_runtime_metric.textproto android_irq_runtime irq_runtime_metric.out
+# CPU frequency maximum & minimum limits change
+cpu_frequency_limits.textproto cpu_frequency_limits.sql cpu_frequency_limits.out
diff --git a/test/trace_processor/performance/irq_runtime_metric.out b/test/trace_processor/performance/irq_runtime_metric.out
new file mode 100644
index 000000000..8bfe55735
--- /dev/null
+++ b/test/trace_processor/performance/irq_runtime_metric.out
@@ -0,0 +1,50 @@
+android_irq_runtime: {
+ hw_irq: {
+ max_runtime: 4000000
+ total_count: 4
+ threshold_metric: {
+ threshold: "1ms"
+ over_threshold_count: 3
+ anomaly_ratio: 0.75
+ }
+ longest_irq_slices: {
+ irq_name: "IRQ (resource3)"
+ ts: 300005000000
+ dur: 4000000
+ }
+ longest_irq_slices: {
+ irq_name: "IRQ (resource3)"
+ ts: 300001000000
+ dur: 3000000
+ }
+ longest_irq_slices: {
+ irq_name: "IRQ (resource2)"
+ ts: 200001000000
+ dur: 2000000
+ }
+ longest_irq_slices: {
+ irq_name: "IRQ (resource1)"
+ ts: 100001000000
+ dur: 1000000
+ }
+ }
+ sw_irq: {
+ max_runtime: 6000000
+ total_count: 2
+ threshold_metric: {
+ threshold: "5ms"
+ over_threshold_count: 1
+ anomaly_ratio: 0.5
+ }
+ longest_irq_slices: {
+ irq_name: "TIMER"
+ ts: 500001000000
+ dur: 6000000
+ }
+ longest_irq_slices: {
+ irq_name: "BLOCK"
+ ts: 400001000000
+ dur: 800000
+ }
+ }
+}
diff --git a/test/trace_processor/performance/irq_runtime_metric.textproto b/test/trace_processor/performance/irq_runtime_metric.textproto
new file mode 100644
index 000000000..9da0b1155
--- /dev/null
+++ b/test/trace_processor/performance/irq_runtime_metric.textproto
@@ -0,0 +1,97 @@
+packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 100001000000
+ pid: 10
+ irq_handler_entry {
+ irq: 100
+ name : "resource1"
+ }
+ }
+ event {
+ timestamp: 100002000000
+ pid: 10
+ irq_handler_exit {
+ irq: 100
+ ret: 1
+ }
+ }
+ event {
+ timestamp: 200001000000
+ pid: 20
+ irq_handler_entry {
+ irq: 200
+ name : "resource2"
+ }
+ }
+ event {
+ timestamp: 200003000000
+ pid: 20
+ irq_handler_exit {
+ irq: 200
+ ret: 1
+ }
+ }
+ event {
+ timestamp: 300001000000
+ pid: 30
+ irq_handler_entry {
+ irq: 300
+ name : "resource3"
+ }
+ }
+ event {
+ timestamp: 300004000000
+ pid: 30
+ irq_handler_exit {
+ irq: 300
+ ret: 1
+ }
+ }
+ event {
+ timestamp: 300005000000
+ pid: 30
+ irq_handler_entry {
+ irq: 300
+ name : "resource3"
+ }
+ }
+ event {
+ timestamp: 300009000000
+ pid: 30
+ irq_handler_exit {
+ irq: 300
+ ret: 1
+ }
+ }
+ event {
+ timestamp: 400001000000
+ pid: 40
+ softirq_entry {
+ vec: 4
+ }
+ }
+ event {
+ timestamp: 400001800000
+ pid: 40
+ softirq_exit {
+ vec: 4
+ }
+ }
+ event {
+ timestamp: 500001000000
+ pid: 50
+ softirq_entry {
+ vec: 1
+ }
+ }
+ event {
+ timestamp: 500007000000
+ pid: 50
+ softirq_exit {
+ vec: 1
+ }
+ }
+ }
+}
diff --git a/test/trace_processor/power/dvfs_metric.out b/test/trace_processor/power/dvfs_metric.out
new file mode 100644
index 000000000..4b38bd288
--- /dev/null
+++ b/test/trace_processor/power/dvfs_metric.out
@@ -0,0 +1,33 @@
+android_dvfs {
+ freq_residencies {
+ freq_name: "bus_throughput Frequency"
+ band_stat: {
+ freq_value: 1014000
+ percentage: 75.0
+ duration_ns: 3000000
+ }
+ band_stat: {
+ freq_value: 2028000
+ percentage: 25.0
+ duration_ns: 1000000
+ }
+ }
+ freq_residencies {
+ freq_name: "domain@1 Frequency"
+ band_stat: {
+ freq_value: 400000
+ percentage: 40.0
+ duration_ns: 2000000
+ }
+ band_stat: {
+ freq_value: 553000
+ percentage: 40.0
+ duration_ns: 2000000
+ }
+ band_stat: {
+ freq_value: 1024000
+ percentage: 20.0
+ duration_ns: 1000000
+ }
+ }
+}
diff --git a/test/trace_processor/power/dvfs_metric.textproto b/test/trace_processor/power/dvfs_metric.textproto
new file mode 100644
index 000000000..830151961
--- /dev/null
+++ b/test/trace_processor/power/dvfs_metric.textproto
@@ -0,0 +1,55 @@
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 200001000000
+ pid: 2
+ clock_set_rate {
+ name : "domain@1"
+ state: 400000
+ }
+ }
+ event {
+ timestamp: 200002000000
+ pid: 2
+ clock_set_rate {
+ name : "bus_throughput"
+ state: 1014000
+ }
+ }
+ event {
+ timestamp: 200003000000
+ pid: 2
+ clock_set_rate {
+ name: "domain@1"
+ state: 1024000
+ }
+ }
+ event {
+ timestamp: 200004000000
+ pid: 2
+ clock_set_rate {
+ name: "domain@1"
+ state: 553000
+ }
+ }
+ event {
+ timestamp: 200005000000
+ pid: 2
+ clock_set_rate {
+ name: "bus_throughput"
+ state: 2028000
+ }
+ }
+ event {
+ timestamp: 200005999999
+ pid: 527
+ clock_set_rate {
+ name: "domain@1"
+ state: 553000
+ }
+ }
+ }
+ trusted_uid: 9999
+ trusted_packet_sequence_id: 2
+}
diff --git a/test/trace_processor/power/index b/test/trace_processor/power/index
index 004f7a3f3..4f03585d9 100644
--- a/test/trace_processor/power/index
+++ b/test/trace_processor/power/index
@@ -3,3 +3,9 @@
power_rails_custom_clock.textproto power_rails_event.sql power_rails_event_power_rails_custom_clock.out
power_rails.textproto power_rails_timestamp_sort.sql power_rails_timestamp_sort.out
power_rails_well_known.textproto power_rails.sql power_rails_well_known_power_rails.out
+
+# Dynamic Voltage and Frequency Scaling
+
+dvfs_metric.textproto android_dvfs dvfs_metric.out
+wakesource.textproto wakesource.sql wakesource_wakesource.out
+suspend_resume.textproto suspend_resume.sql suspend_resume.out
diff --git a/test/trace_processor/power/power_rails.sql b/test/trace_processor/power/power_rails.sql
index c095608d8..31af22779 100644
--- a/test/trace_processor/power/power_rails.sql
+++ b/test/trace_processor/power/power_rails.sql
@@ -15,6 +15,6 @@
--
select name, AVG(value), COUNT(*)
from counters
-where name like "power.%"
+where name GLOB "power.*"
group by name
limit 20 \ No newline at end of file
diff --git a/test/trace_processor/power/power_rails_event.sql b/test/trace_processor/power/power_rails_event.sql
index 9a1a25486..ca04ce273 100644
--- a/test/trace_processor/power/power_rails_event.sql
+++ b/test/trace_processor/power/power_rails_event.sql
@@ -15,5 +15,5 @@
--
select ts, value
from counters
-where name like "power.%"
+where name GLOB "power.*"
limit 20
diff --git a/test/trace_processor/power/suspend_resume.out b/test/trace_processor/power/suspend_resume.out
new file mode 100644
index 000000000..ca21b0642
--- /dev/null
+++ b/test/trace_processor/power/suspend_resume.out
@@ -0,0 +1,3 @@
+"ts","dur","action"
+10000,10000,"suspend_enter(3)"
+30000,10000,"CPU(0)"
diff --git a/test/trace_processor/power/suspend_resume.sql b/test/trace_processor/power/suspend_resume.sql
new file mode 100644
index 000000000..30f454280
--- /dev/null
+++ b/test/trace_processor/power/suspend_resume.sql
@@ -0,0 +1,12 @@
+SELECT
+ s.ts,
+ s.dur,
+ s.name AS action
+FROM
+ slice AS s
+ JOIN
+ track AS t
+ ON s.track_id = t.id
+WHERE
+ t.name = 'Suspend/Resume Latency'
+ORDER BY s.ts;
diff --git a/test/trace_processor/power/suspend_resume.textproto b/test/trace_processor/power/suspend_resume.textproto
new file mode 100644
index 000000000..ad40430a5
--- /dev/null
+++ b/test/trace_processor/power/suspend_resume.textproto
@@ -0,0 +1,56 @@
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 10000
+ pid: 0
+ suspend_resume {
+ action: "suspend_enter"
+ val: 3
+ start: 1
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 20000
+ pid: 0
+ suspend_resume {
+ action: "suspend_enter"
+ val: 3
+ start: 0
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 30000
+ pid: 0
+ suspend_resume {
+ action: "CPU"
+ val: 0
+ start: 1
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 0
+ event {
+ timestamp: 40000
+ pid: 0
+ suspend_resume {
+ action: "CPU"
+ val: 0
+ start: 0
+ }
+ }
+ }
+}
diff --git a/test/trace_processor/power/wakesource.sql b/test/trace_processor/power/wakesource.sql
new file mode 100644
index 000000000..8497e876b
--- /dev/null
+++ b/test/trace_processor/power/wakesource.sql
@@ -0,0 +1,5 @@
+SELECT ts, dur, slice.name
+FROM slice
+JOIN track on slice.track_id = track.id
+WHERE track.name GLOB 'Wakelock*'
+ORDER BY ts
diff --git a/test/trace_processor/power/wakesource.textproto b/test/trace_processor/power/wakesource.textproto
new file mode 100644
index 000000000..e5ffb8d60
--- /dev/null
+++ b/test/trace_processor/power/wakesource.textproto
@@ -0,0 +1,88 @@
+packet {
+ ftrace_events: {
+ cpu: 0
+ event: {
+ timestamp: 34298714043271
+ pid: 38
+ wakeup_source_activate: {
+ name: "s2mpw02-power-keys"
+ state: 3376218114
+ }
+ }
+ event: {
+ timestamp: 34298714043273
+ pid: 38
+ wakeup_source_activate: {
+ name: "s2mpw02-power-keys"
+ state: 3376218114
+ }
+ }
+ event: {
+ timestamp: 34298721846504
+ pid: 11174
+ wakeup_source_activate: {
+ name: "event0"
+ state: 3376218115
+ }
+ }
+ event: {
+ timestamp: 34298721915735
+ pid: 11174
+ wakeup_source_deactivate: {
+ name: "s2mpw02-power-keys"
+ state: 3376283650
+ }
+ }
+ event: {
+ timestamp: 34298721915738
+ pid: 11174
+ wakeup_source_deactivate: {
+ name: "s2mpw02-power-keys"
+ state: 3376283651
+ }
+ }
+ event: {
+ timestamp: 34298721915739
+ pid: 38
+ wakeup_source_activate: {
+ name: "s2mpw02-power-keys"
+ state: 3376218114
+ }
+ }
+ event: {
+ timestamp: 34298721915755
+ pid: 11174
+ wakeup_source_deactivate: {
+ name: "s2mpw02-power-keys"
+ state: 3376283651
+ }
+ }
+ event: {
+ timestamp: 34298764569658
+ pid: 743
+ wakeup_source_activate: {
+ name: "eventpoll"
+ state: 3376414723
+ }
+ }
+ event: {
+ timestamp: 34298764579158
+ pid: 743
+ wakeup_source_deactivate: {
+ name: "event0"
+ state: 3376480258
+ }
+ }
+ event: {
+ timestamp: 34298764584196
+ pid: 743
+ wakeup_source_deactivate: {
+ name: "eventpoll"
+ state: 3376545793
+ }
+ }
+ }
+ trusted_uid: 0
+ trusted_packet_sequence_id: 2
+ trusted_pid: 11246
+}
diff --git a/test/trace_processor/power/wakesource_wakesource.out b/test/trace_processor/power/wakesource_wakesource.out
new file mode 100644
index 000000000..179e4f51b
--- /dev/null
+++ b/test/trace_processor/power/wakesource_wakesource.out
@@ -0,0 +1,5 @@
+"ts","dur","name"
+34298714043271,7872467,"Wakelock(s2mpw02-power-keys)"
+34298721846504,42732654,"Wakelock(event0)"
+34298721915739,16,"Wakelock(s2mpw02-power-keys)"
+34298764569658,14538,"Wakelock(eventpoll)"
diff --git a/test/trace_processor/profiling/callstack_sampling_flamegraph.out b/test/trace_processor/profiling/callstack_sampling_flamegraph.out
new file mode 100644
index 000000000..d16a96e57
--- /dev/null
+++ b/test/trace_processor/profiling/callstack_sampling_flamegraph.out
@@ -0,0 +1,11 @@
+"id","type","depth","name","map_name","count","cumulative_count","size","cumulative_size","alloc_count","cumulative_alloc_count","alloc_size","cumulative_alloc_size","parent_id","source_file","line_number","upid_group"
+0,"experimental_flamegraph_nodes",0,"__start_thread","/apex/com.android.runtime/lib64/bionic/libc.so",0,560,0,560,0,0,0,0,"[NULL]","[NULL]","[NULL]","[NULL]"
+1,"experimental_flamegraph_nodes",1,"_ZL15__pthread_startPv","/apex/com.android.runtime/lib64/bionic/libc.so",0,560,0,560,0,0,0,0,0,"[NULL]","[NULL]","[NULL]"
+2,"experimental_flamegraph_nodes",2,"_ZN3art6Thread14CreateCallbackEPv","/apex/com.android.art/lib64/libart.so",0,301,0,301,0,0,0,0,1,"[NULL]","[NULL]","[NULL]"
+3,"experimental_flamegraph_nodes",3,"_ZN3art35InvokeVirtualOrInterfaceWithJValuesIPNS_9ArtMethodEEENS_6JValueERKNS_33ScopedObjectAccessAlreadyRunnableEP8_jobjectT_PK6jvalue","/apex/com.android.art/lib64/libart.so",0,301,0,301,0,0,0,0,2,"[NULL]","[NULL]","[NULL]"
+4,"experimental_flamegraph_nodes",4,"_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc","/apex/com.android.art/lib64/libart.so",0,301,0,301,0,0,0,0,3,"[NULL]","[NULL]","[NULL]"
+5,"experimental_flamegraph_nodes",5,"art_quick_invoke_stub","/apex/com.android.art/lib64/libart.so",0,301,0,301,0,0,0,0,4,"[NULL]","[NULL]","[NULL]"
+6,"experimental_flamegraph_nodes",6,"android.os.HandlerThread.run","/system/framework/arm64/boot-framework.oat",0,43,0,43,0,0,0,0,5,"[NULL]","[NULL]","[NULL]"
+7,"experimental_flamegraph_nodes",7,"android.os.Looper.loop","/system/framework/arm64/boot-framework.oat",0,43,0,43,0,0,0,0,6,"[NULL]","[NULL]","[NULL]"
+8,"experimental_flamegraph_nodes",8,"android.os.Looper.loopOnce","/system/framework/arm64/boot-framework.oat",1,43,1,43,0,0,0,0,7,"[NULL]","[NULL]","[NULL]"
+9,"experimental_flamegraph_nodes",9,"android.os.Handler.dispatchMessage","/system/framework/arm64/boot-framework.oat",0,35,0,35,0,0,0,0,8,"[NULL]","[NULL]","[NULL]"
diff --git a/test/trace_processor/profiling/callstack_sampling_flamegraph.sql b/test/trace_processor/profiling/callstack_sampling_flamegraph.sql
new file mode 100644
index 000000000..f9da1da8e
--- /dev/null
+++ b/test/trace_processor/profiling/callstack_sampling_flamegraph.sql
@@ -0,0 +1,5 @@
+select * from experimental_flamegraph
+where upid = 30
+ and profile_type = 'perf'
+ and ts <= 7689491063351
+limit 10;
diff --git a/test/trace_processor/profiling/callstack_sampling_flamegraph_multi_process.out b/test/trace_processor/profiling/callstack_sampling_flamegraph_multi_process.out
new file mode 100644
index 000000000..a0b68b39e
--- /dev/null
+++ b/test/trace_processor/profiling/callstack_sampling_flamegraph_multi_process.out
@@ -0,0 +1,4 @@
+"count","description"
+658,"BothProcesses"
+483,"FirstProcess"
+175,"SecondProcess"
diff --git a/test/trace_processor/profiling/callstack_sampling_flamegraph_multi_process.sql b/test/trace_processor/profiling/callstack_sampling_flamegraph_multi_process.sql
new file mode 100644
index 000000000..510b9d328
--- /dev/null
+++ b/test/trace_processor/profiling/callstack_sampling_flamegraph_multi_process.sql
@@ -0,0 +1,17 @@
+select count(*) as count, 'BothProcesses' as description from experimental_flamegraph
+where upid_group = "30,41"
+ and profile_type = 'perf'
+ and ts <= 7689491063351
+ and size > 0
+union all
+select count(*) as count, 'FirstProcess' as description from experimental_flamegraph
+where upid = 30
+ and profile_type = 'perf'
+ and ts <= 7689491063351
+ and size > 0
+union all
+select count(*) as count, 'SecondProcess' as description from experimental_flamegraph
+where upid = 41
+ and profile_type = 'perf'
+ and ts <= 7689491063351
+ and size > 0;
diff --git a/test/trace_processor/profiling/heap_graph.textproto b/test/trace_processor/profiling/heap_graph.textproto
index b4c2037b7..b3decefb9 100644
--- a/test/trace_processor/profiling/heap_graph.textproto
+++ b/test/trace_processor/profiling/heap_graph.textproto
@@ -124,7 +124,7 @@ packet {
id: 3
class_name: "a"
location_id: 1
- object_size: 256
+ object_size: 1024
}
types {
id: 4
diff --git a/test/trace_processor/profiling/heap_graph_baseapk.textproto b/test/trace_processor/profiling/heap_graph_baseapk.textproto
index 18cae91a0..86d2d9081 100644
--- a/test/trace_processor/profiling/heap_graph_baseapk.textproto
+++ b/test/trace_processor/profiling/heap_graph_baseapk.textproto
@@ -70,7 +70,7 @@ packet {
objects {
id: 0x04
type_id: 3
- self_size: 256
+ self_size: 1024
reference_field_id: 2
reference_object_id: 0x01
}
diff --git a/test/trace_processor/profiling/heap_graph_deobfuscate_pkg.textproto b/test/trace_processor/profiling/heap_graph_deobfuscate_pkg.textproto
new file mode 100644
index 000000000..469754836
--- /dev/null
+++ b/test/trace_processor/profiling/heap_graph_deobfuscate_pkg.textproto
@@ -0,0 +1,141 @@
+packet {
+ process_tree {
+ processes {
+ pid: 2
+ ppid: 1
+ cmdline: "<ignored>"
+ uid: 10001
+ }
+ }
+}
+packet {
+ packages_list {
+ packages {
+ name: "com.google.android.gm"
+ uid: 10001
+ }
+ }
+}
+packet {
+ trusted_packet_sequence_id: 999
+ timestamp: 10
+ heap_graph {
+ pid: 2
+ roots {
+ root_type: ROOT_JAVA_FRAME
+ object_ids: 0x01
+ object_ids: 0x05
+ }
+ objects {
+ id: 0x01
+ type_id: 1
+ self_size: 64
+ reference_field_id: 1
+ reference_object_id: 0x02
+ reference_field_id: 4
+ reference_object_id: 0x00
+ reference_field_id: 3
+ reference_object_id: 0x02
+ }
+ objects {
+ id: 0x02
+ type_id: 2
+ self_size: 32
+ }
+ objects {
+ id: 0x03
+ type_id: 2
+ self_size: 128
+ }
+ objects {
+ id: 0x04
+ type_id: 3
+ self_size: 1024
+ reference_field_id: 2
+ reference_object_id: 0x01
+ }
+ objects {
+ id: 0x05
+ type_id: 4
+ self_size: 256
+ }
+ objects {
+ id: 0x06
+ type_id: 5
+ self_size: 256
+ }
+ continued: true
+ index: 0
+ }
+}
+packet {
+ trusted_packet_sequence_id: 999
+ timestamp: 10
+ heap_graph {
+ pid: 2
+ location_names {
+ iid: 1
+ str: "base.apk!classes.dex"
+ }
+ types {
+ id: 1
+ class_name: "FactoryProducerDelegateImplActor"
+ location_id: 1
+ }
+ types {
+ id: 2
+ class_name: "Foo"
+ location_id: 1
+ }
+ types {
+ id: 3
+ class_name: "a"
+ location_id: 1
+ }
+ types {
+ id: 4
+ class_name: "a[]"
+ location_id: 1
+ }
+ types {
+ id: 5
+ class_name: "java.lang.Class<a[]>"
+ location_id: 1
+ }
+ field_names {
+ iid: 1
+ str: "FactoryProducerDelegateImplActor.foo"
+ }
+ field_names {
+ iid: 2
+ str: "int a.a"
+ }
+ field_names {
+ iid: 3
+ str: "a.b"
+ }
+ field_names {
+ iid: 4
+ str: "FactoryProducerDelegateImplActor.setToNULL"
+ }
+ continued: true
+ index: 1
+ }
+}
+packet {
+ deobfuscation_mapping {
+ package_name: "com.google.android.gm"
+ obfuscated_classes {
+ obfuscated_name: "a"
+ deobfuscated_name: "DeobfuscatedA"
+ obfuscated_members {
+ obfuscated_name: "a"
+ deobfuscated_name: "deobfuscatedA"
+ }
+ obfuscated_members {
+ obfuscated_name: "b"
+ deobfuscated_name: "Other.deobfuscatedA"
+ }
+ }
+ }
+}
diff --git a/test/trace_processor/profiling/heap_graph_flamegraph.sql b/test/trace_processor/profiling/heap_graph_flamegraph.sql
index 92367f91b..34692efd2 100644
--- a/test/trace_processor/profiling/heap_graph_flamegraph.sql
+++ b/test/trace_processor/profiling/heap_graph_flamegraph.sql
@@ -8,8 +8,8 @@ SELECT
size,
cumulative_size,
parent_id
-FROM experimental_flamegraph(
- (select max(graph_sample_ts) from heap_graph_object),
- (select max(upid) from heap_graph_object),
- 'graph')
+FROM experimental_flamegraph
+where upid = (select max(upid) from heap_graph_object)
+ and profile_type = 'graph'
+ and ts = (select max(graph_sample_ts) from heap_graph_object)
LIMIT 10
diff --git a/test/trace_processor/profiling/heap_graph_flamegraph_focused.sql b/test/trace_processor/profiling/heap_graph_flamegraph_focused.sql
index 95d498a5f..e6b514c46 100644
--- a/test/trace_processor/profiling/heap_graph_flamegraph_focused.sql
+++ b/test/trace_processor/profiling/heap_graph_flamegraph_focused.sql
@@ -7,9 +7,9 @@ SELECT
size,
cumulative_size,
parent_id
-FROM experimental_flamegraph(
- (select max(graph_sample_ts) from heap_graph_object),
- (select max(upid) from heap_graph_object),
- 'graph')
-WHERE focus_str = 'left'
+FROM experimental_flamegraph
+where upid = (select max(upid) from heap_graph_object)
+ and profile_type = 'graph'
+ and ts = (select max(graph_sample_ts) from heap_graph_object)
+ and focus_str = 'left'
LIMIT 10
diff --git a/test/trace_processor/profiling/heap_graph_flamegraph_matches_objects.out b/test/trace_processor/profiling/heap_graph_flamegraph_matches_objects.out
new file mode 100644
index 000000000..031cd760f
--- /dev/null
+++ b/test/trace_processor/profiling/heap_graph_flamegraph_matches_objects.out
@@ -0,0 +1,2 @@
+"upid","ts","total_objects_size","total_flamegraph_size"
+1,10,3000000036,3000000036
diff --git a/test/trace_processor/profiling/heap_graph_flamegraph_matches_objects.sql b/test/trace_processor/profiling/heap_graph_flamegraph_matches_objects.sql
new file mode 100644
index 000000000..59674afb1
--- /dev/null
+++ b/test/trace_processor/profiling/heap_graph_flamegraph_matches_objects.sql
@@ -0,0 +1,23 @@
+-- For each heap graph dump (upid, ts), builds a flamegraph and outputs:
+-- * total_objects_size: the sum of the size (native + java) of all the
+-- reachable objects
+-- * total_flamegraph_size: the sum of the cumulative size of the roots in the
+-- flamegraph
+-- If the flamegraph has been built correctly, the numbers should match.
+SELECT
+ obj.upid AS upid,
+ obj.graph_sample_ts AS ts,
+ SUM(obj.self_size + obj.native_size) AS total_objects_size,
+ (
+ SELECT SUM(cumulative_size)
+ FROM experimental_flamegraph
+ WHERE experimental_flamegraph.upid = obj.upid
+ AND experimental_flamegraph.ts = obj.graph_sample_ts
+ AND profile_type = 'graph'
+ AND depth = 0 -- only the roots
+ ) AS total_flamegraph_size
+FROM
+ heap_graph_object AS obj
+WHERE
+ obj.reachable != 0
+GROUP BY obj.upid, obj.graph_sample_ts
diff --git a/test/trace_processor/profiling/heap_graph_huge_size.textproto b/test/trace_processor/profiling/heap_graph_huge_size.textproto
new file mode 100644
index 000000000..7b6b0b031
--- /dev/null
+++ b/test/trace_processor/profiling/heap_graph_huge_size.textproto
@@ -0,0 +1,76 @@
+packet {
+ trusted_packet_sequence_id: 999
+ timestamp: 10
+ heap_graph {
+ pid: 2
+ types {
+ id: 54
+ location_id: 5
+ class_name: "java.lang.Object"
+ object_size: 8
+ kind: KIND_NOREFERENCES
+ classloader_id: 0
+ }
+ types {
+ id: 55
+ location_id: 5
+ class_name: "dev.perfetto.BigStuff"
+ object_size: 1000000000 # Three of these overflow signed 32-bit
+ superclass_id: 54
+ kind: KIND_NORMAL
+ classloader_id: 0
+ }
+ types {
+ id: 56
+ location_id: 5
+ class_name: "dev.perfetto.Container"
+ object_size: 36
+ superclass_id: 54
+ reference_field_id: 601 # obj1
+ reference_field_id: 602 # obj2
+ reference_field_id: 603 # obj3
+ kind: KIND_NORMAL
+ classloader_id: 0
+ }
+ objects {
+ id: 0x1
+ type_id: 55 # dev.perfetto.BigStuff
+ }
+ objects {
+ id: 0x2
+ type_id: 55 # dev.perfetto.BigStuff
+ }
+ objects {
+ id: 0x3
+ type_id: 55 # dev.perfetto.BigStuff
+ }
+ objects {
+ id: 0x4
+ type_id: 56 # dev.perfetto.Container
+ reference_object_id: 0x1 # obj1
+ reference_object_id: 0x2 # obj2
+ reference_object_id: 0x3 # obj3
+ }
+ roots {
+ object_ids: 0x4
+ root_type: ROOT_JAVA_FRAME
+ }
+ field_names {
+ iid: 601
+ str: "dev.perfetto.BigStuff dev.perfetto.Container.obj1"
+ }
+ field_names {
+ iid: 602
+ str: "dev.perfetto.BigStuff dev.perfetto.Container.obj2"
+ }
+ field_names {
+ iid: 603
+ str: "dev.perfetto.BigStuff dev.perfetto.Container.obj3"
+ }
+ location_names {
+ iid: 5
+ str: "/apex/com.android.art/javalib/core-oj.jar"
+ }
+ index: 0
+ }
+}
diff --git a/test/trace_processor/profiling/heap_graph_legacy.textproto b/test/trace_processor/profiling/heap_graph_legacy.textproto
index 54d19cd79..d0bc1c85c 100644
--- a/test/trace_processor/profiling/heap_graph_legacy.textproto
+++ b/test/trace_processor/profiling/heap_graph_legacy.textproto
@@ -70,7 +70,7 @@ packet {
objects {
id: 0x04
type_id: 3
- self_size: 256
+ self_size: 1024
reference_field_id: 2
reference_object_id: 0x01
}
diff --git a/test/trace_processor/profiling/heap_graph_native_size.out b/test/trace_processor/profiling/heap_graph_native_size.out
new file mode 100644
index 000000000..c0d6b61cd
--- /dev/null
+++ b/test/trace_processor/profiling/heap_graph_native_size.out
@@ -0,0 +1,3 @@
+"type_name","native_size"
+"android.graphics.Bitmap",123456
+"android.os.BinderProxy",0
diff --git a/test/trace_processor/profiling/heap_graph_native_size.sql b/test/trace_processor/profiling/heap_graph_native_size.sql
new file mode 100644
index 000000000..fcef1f6c7
--- /dev/null
+++ b/test/trace_processor/profiling/heap_graph_native_size.sql
@@ -0,0 +1,19 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+select c.name as type_name,
+ o.native_size
+from heap_graph_object o join heap_graph_class c on o.type_id = c.id
+where o.root_type = "ROOT_JAVA_FRAME"
diff --git a/test/trace_processor/profiling/heap_graph_native_size.textproto b/test/trace_processor/profiling/heap_graph_native_size.textproto
new file mode 100644
index 000000000..00a2bc640
--- /dev/null
+++ b/test/trace_processor/profiling/heap_graph_native_size.textproto
@@ -0,0 +1,217 @@
+packet {
+ trusted_packet_sequence_id: 999
+ timestamp: 10
+ heap_graph {
+ pid: 2
+ types {
+ id: 54
+ location_id: 5
+ class_name: "java.lang.Object"
+ object_size: 8
+ kind: KIND_NOREFERENCES
+ classloader_id: 0
+ }
+ types {
+ id: 12171
+ location_id: 5
+ class_name: "java.lang.ref.Reference"
+ object_size: 24
+ superclass_id: 54
+ reference_field_id: 1 # pendingNext
+ reference_field_id: 2 # queue
+ reference_field_id: 3 # queueNext
+ reference_field_id: 15420 # referent
+ kind: KIND_NORMAL
+ classloader_id: 0
+ }
+ types {
+ id: 11645
+ location_id: 5
+ class_name: "java.lang.ref.PhantomReference"
+ object_size: 24
+ superclass_id: 12171
+ kind: KIND_PHANTOM_REFERENCE
+ classloader_id: 0
+ }
+ types {
+ id: 17
+ location_id: 5
+ class_name: "sun.misc.Cleaner"
+ object_size: 36
+ superclass_id: 11645
+ reference_field_id: 14946 # next
+ reference_field_id: 14947 # prev
+ reference_field_id: 14948 # thunk
+ kind: KIND_PHANTOM_REFERENCE
+ classloader_id: 0
+ }
+ types {
+ id: 11646
+ location_id: 5
+ class_name: "java.lang.Class<sun.misc.Cleaner>"
+ }
+ types {
+ id: 16
+ location_id: 10
+ class_name: "libcore.util.NativeAllocationRegistry$CleanerThunk"
+ object_size: 24
+ superclass_id: 54
+ reference_field_id: 19501 # this$0
+ kind: KIND_NORMAL
+ classloader_id: 0
+ }
+ types {
+ id: 778
+ location_id: 10
+ class_name: "libcore.util.NativeAllocationRegistry"
+ object_size: 32
+ superclass_id: 54
+ reference_field_id: 19502
+ kind: KIND_NORMAL
+ classloader_id: 0
+ }
+ types {
+ id: 777
+ location_id: 6
+ class_name: "android.graphics.Bitmap"
+ object_size: 46
+ superclass_id: 54
+ # References omitted
+ kind: KIND_NORMAL
+ classloader_id: 0
+ }
+ types {
+ id: 15
+ location_id: 8
+ class_name: "android.os.BinderProxy"
+ object_size: 17
+ superclass_id: 54
+ kind: KIND_NOREFERENCES
+ classloader_id: 0
+ }
+ objects {
+ id: 0x1
+ type_id: 777 # android.graphics.Bitmap
+ }
+ objects {
+ id: 0x2
+ type_id: 15 # android.os.BinderProxy
+ }
+ objects {
+ id: 0x3
+ type_id: 778 # libcore.util.NativeAllocationRegistry
+ reference_object_id: 0x0 # classLoader omitted
+ native_allocation_registry_size_field: 123456
+ }
+ objects {
+ id: 0x4
+ type_id: 16 # libcore.util.NativeAllocationRegistry$CleanerThunk
+ reference_object_id: 0x3 # this$0
+ }
+ objects {
+ id: 0x5
+ type_id: 16 # libcore.util.NativeAllocationRegistry$CleanerThunk
+ reference_object_id: 0x3 # this$0
+ }
+ # This Cleaner has not been deleted: it's reachable from a root (through the
+ # sun.misc.Cleaner.first static field).
+ objects {
+ id: 0x6
+ type_id: 17 # sun.misc.Cleaner
+ reference_object_id: 0x0 # next
+ reference_object_id: 0x0 # prev
+ reference_object_id: 0x4 # thunk
+ reference_object_id: 0x0 # pendingNext
+ reference_object_id: 0x0 # queue
+ reference_object_id: 0x0 # queueNext
+ reference_object_id: 0x1 # referent
+ }
+ # This Cleaner has been deleted: it's not reachable from a root and its .prev
+ # and .next point to this.
+ objects {
+ id: 0x7
+ type_id: 17 # sun.misc.Cleaner
+ reference_object_id: 0x7 # next
+ reference_object_id: 0x7 # prev
+ reference_object_id: 0x5 # thunk
+ reference_object_id: 0x0 # pendingNext
+ reference_object_id: 0x0 # queue
+ reference_object_id: 0x0 # queueNext
+ reference_object_id: 0x2 # referent
+ }
+ objects {
+ id: 0x8
+ type_id: 11646 # java.lang.Class<sun.misc.Cleaner>
+ self_size: 288
+ # omitted fields
+ reference_field_id: 14950 # first
+ reference_object_id: 0x6
+ }
+ roots {
+ object_ids: 0x8
+ root_type: ROOT_STICKY_CLASS
+ }
+ roots {
+ object_ids: 0x1
+ object_ids: 0x2
+ root_type: ROOT_JAVA_FRAME
+ }
+ field_names {
+ iid: 1
+ str: "java.lang.ref.Reference java.lang.ref.Reference.pendingNext"
+ }
+ field_names {
+ iid: 2
+ str: "java.lang.ref.ReferenceQueue java.lang.ref.Reference.queue"
+ }
+ field_names {
+ iid: 3
+ str: "java.lang.ref.Reference java.lang.ref.Reference.queueNext"
+ }
+ field_names {
+ iid: 14950
+ str: "sun.misc.Cleaner sun.misc.Cleaner.first"
+ }
+ field_names {
+ iid: 15420
+ str: "java.lang.Object java.lang.ref.Reference.referent"
+ }
+ field_names {
+ iid: 14946
+ str: "sun.misc.Cleaner sun.misc.Cleaner.next"
+ }
+ field_names {
+ iid: 14947
+ str: "sun.misc.Cleaner sun.misc.Cleaner.prev"
+ }
+ field_names {
+ iid: 14948
+ str: "java.lang.Runnable sun.misc.Cleaner.thunk"
+ }
+ field_names {
+ iid: 19501
+ str: "libcore.util.NativeAllocationRegistry libcore.util.NativeAllocationRegistry$CleanerThunk.this$0"
+ }
+ field_names {
+ iid: 19502
+ str: "java.lang.ClassLoader libcore.util.NativeAllocationRegistry.classLoader"
+ }
+ location_names {
+ iid: 5
+ str: "/apex/com.android.art/javalib/core-oj.jar"
+ }
+ location_names {
+ iid: 10
+ str: "/apex/com.android.art/javalib/core-libart.jar"
+ }
+ location_names {
+ iid: 6
+ str: "/system/framework/framework.jar"
+ }
+ location_names {
+ iid: 8
+ str: "/system/framework/framework.jar!classes2.dex"
+ }
+ index: 0
+ }
+}
diff --git a/test/trace_processor/profiling/heap_graph_object.out b/test/trace_processor/profiling/heap_graph_object.out
index e4aa0b17b..ac4a6a3a6 100644
--- a/test/trace_processor/profiling/heap_graph_object.out
+++ b/test/trace_processor/profiling/heap_graph_object.out
@@ -2,6 +2,6 @@
0,"heap_graph_object",2,10,64,0,1,"FactoryProducerDelegateImplActor","[NULL]","ROOT_JAVA_FRAME"
1,"heap_graph_object",2,10,32,"[NULL]",1,"Foo","[NULL]","[NULL]"
2,"heap_graph_object",2,10,128,"[NULL]",0,"Foo","[NULL]","[NULL]"
-3,"heap_graph_object",2,10,256,3,0,"a","DeobfuscatedA","[NULL]"
+3,"heap_graph_object",2,10,1024,3,0,"a","DeobfuscatedA","[NULL]"
4,"heap_graph_object",2,10,256,"[NULL]",1,"a[]","DeobfuscatedA[]","ROOT_JAVA_FRAME"
5,"heap_graph_object",2,10,256,"[NULL]",0,"java.lang.Class<a[]>","java.lang.Class<DeobfuscatedA[]>","[NULL]"
diff --git a/test/trace_processor/profiling/heap_profile_flamegraph.sql b/test/trace_processor/profiling/heap_profile_flamegraph.sql
index fa90b151f..e1feb37a3 100644
--- a/test/trace_processor/profiling/heap_profile_flamegraph.sql
+++ b/test/trace_processor/profiling/heap_profile_flamegraph.sql
@@ -1 +1,5 @@
-select * from experimental_flamegraph(605908369259172, 1, 'native') limit 10;
+select * from experimental_flamegraph
+where ts = 605908369259172
+ and upid = 1
+ and profile_type = 'native'
+limit 10;
diff --git a/test/trace_processor/profiling/heap_profile_flamegraph_system-server-native-profile.out b/test/trace_processor/profiling/heap_profile_flamegraph_system-server-native-profile.out
index 42ab65d72..511538acf 100644
--- a/test/trace_processor/profiling/heap_profile_flamegraph_system-server-native-profile.out
+++ b/test/trace_processor/profiling/heap_profile_flamegraph_system-server-native-profile.out
@@ -1,11 +1,11 @@
-"id","type","depth","name","map_name","count","cumulative_count","size","cumulative_size","alloc_count","cumulative_alloc_count","alloc_size","cumulative_alloc_size","parent_id"
-0,"experimental_flamegraph_nodes",0,"__start_thread","/apex/com.android.runtime/lib64/bionic/libc.so",0,8,0,84848,0,210,0,1084996,"[NULL]"
-1,"experimental_flamegraph_nodes",1,"_ZL15__pthread_startPv","/apex/com.android.runtime/lib64/bionic/libc.so",0,8,0,84848,0,210,0,1084996,0
-2,"experimental_flamegraph_nodes",2,"_ZN7android14AndroidRuntime15javaThreadShellEPv","/system/lib64/libandroid_runtime.so",0,5,0,27704,0,77,0,348050,1
-3,"experimental_flamegraph_nodes",3,"_ZN7android6Thread11_threadLoopEPv","/system/lib64/libutils.so",0,5,0,27704,0,77,0,348050,2
-4,"experimental_flamegraph_nodes",4,"_ZN7android10PoolThread10threadLoopEv","/system/lib64/libbinder.so",0,1,0,4096,0,64,0,279182,3
-5,"experimental_flamegraph_nodes",5,"_ZN7android14IPCThreadState14joinThreadPoolEb","/system/lib64/libbinder.so",0,1,0,4096,0,64,0,279182,4
-6,"experimental_flamegraph_nodes",6,"_ZN7android14IPCThreadState20getAndExecuteCommandEv","/system/lib64/libbinder.so",0,1,0,4096,0,64,0,279182,5
-7,"experimental_flamegraph_nodes",7,"_ZN7android14IPCThreadState14executeCommandEi","/system/lib64/libbinder.so",0,1,0,4096,0,64,0,279182,6
-8,"experimental_flamegraph_nodes",8,"_ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j","/system/lib64/libbinder.so",0,1,0,4096,0,64,0,279182,7
-9,"experimental_flamegraph_nodes",9,"_ZN11JavaBBinder10onTransactEjRKN7android6ParcelEPS1_j","/system/lib64/libandroid_runtime.so",0,0,0,0,0,60,0,262730,8
+"id","type","depth","name","map_name","count","cumulative_count","size","cumulative_size","alloc_count","cumulative_alloc_count","alloc_size","cumulative_alloc_size","parent_id","source_file","line_number","upid_group"
+0,"experimental_flamegraph_nodes",0,"__start_thread","/apex/com.android.runtime/lib64/bionic/libc.so",0,8,0,84848,0,210,0,1084996,"[NULL]","[NULL]","[NULL]","[NULL]"
+1,"experimental_flamegraph_nodes",1,"_ZL15__pthread_startPv","/apex/com.android.runtime/lib64/bionic/libc.so",0,8,0,84848,0,210,0,1084996,0,"[NULL]","[NULL]","[NULL]"
+2,"experimental_flamegraph_nodes",2,"_ZN7android14AndroidRuntime15javaThreadShellEPv","/system/lib64/libandroid_runtime.so",0,5,0,27704,0,77,0,348050,1,"[NULL]","[NULL]","[NULL]"
+3,"experimental_flamegraph_nodes",3,"_ZN7android6Thread11_threadLoopEPv","/system/lib64/libutils.so",0,5,0,27704,0,77,0,348050,2,"[NULL]","[NULL]","[NULL]"
+4,"experimental_flamegraph_nodes",4,"_ZN7android10PoolThread10threadLoopEv","/system/lib64/libbinder.so",0,1,0,4096,0,64,0,279182,3,"[NULL]","[NULL]","[NULL]"
+5,"experimental_flamegraph_nodes",5,"_ZN7android14IPCThreadState14joinThreadPoolEb","/system/lib64/libbinder.so",0,1,0,4096,0,64,0,279182,4,"[NULL]","[NULL]","[NULL]"
+6,"experimental_flamegraph_nodes",6,"_ZN7android14IPCThreadState20getAndExecuteCommandEv","/system/lib64/libbinder.so",0,1,0,4096,0,64,0,279182,5,"[NULL]","[NULL]","[NULL]"
+7,"experimental_flamegraph_nodes",7,"_ZN7android14IPCThreadState14executeCommandEi","/system/lib64/libbinder.so",0,1,0,4096,0,64,0,279182,6,"[NULL]","[NULL]","[NULL]"
+8,"experimental_flamegraph_nodes",8,"_ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j","/system/lib64/libbinder.so",0,1,0,4096,0,64,0,279182,7,"[NULL]","[NULL]","[NULL]"
+9,"experimental_flamegraph_nodes",9,"_ZN11JavaBBinder10onTransactEjRKN7android6ParcelEPS1_j","/system/lib64/libandroid_runtime.so",0,0,0,0,0,60,0,262730,8,"[NULL]","[NULL]","[NULL]"
diff --git a/test/trace_processor/profiling/heap_profile_no_symbols.textproto b/test/trace_processor/profiling/heap_profile_no_symbols.textproto
index d18c8c989..efc18a05c 100644
--- a/test/trace_processor/profiling/heap_profile_no_symbols.textproto
+++ b/test/trace_processor/profiling/heap_profile_no_symbols.textproto
@@ -52,3 +52,58 @@ packet {
}
}
}
+packet {
+ trusted_packet_sequence_id: 999
+ timestamp: 11
+ profile_packet {
+ strings {
+ iid: 1
+ str: "f1"
+ }
+ strings {
+ iid: 2
+ str: "f2"
+ }
+ strings {
+ iid: 4
+ str: "libmonochrome_64.so"
+ }
+ strings {
+ iid: 5
+ str: "\x7f\x07\x15\xc2\x86\xf8\xb1\x6c\x10\xe4\xad\x34\x9c\xda\x3b\x9b\x56\xc7\xa7\x73"
+ }
+ frames {
+ iid: 1
+ function_name_id: 1
+ mapping_id: 1
+ rel_pc: 0x1000
+ }
+ frames {
+ iid: 2
+ function_name_id: 2
+ mapping_id: 1
+ rel_pc: 0x2000
+ }
+ callstacks {
+ iid: 1
+ frame_ids: 1
+ frame_ids: 2
+ }
+ mappings {
+ iid: 1
+ path_string_ids: 4
+ build_id: 5
+ }
+ process_dumps {
+ pid: 2
+ samples {
+ callstack_id: 1
+ self_allocated: 2000
+ self_freed: 1000
+ alloc_count: 2
+ free_count: 1
+ }
+ }
+ }
+}
+
diff --git a/test/trace_processor/profiling/heap_stats_closest_proc.out b/test/trace_processor/profiling/heap_stats_closest_proc.out
index ddcdc9512..1ee09bf04 100644
--- a/test/trace_processor/profiling/heap_stats_closest_proc.out
+++ b/test/trace_processor/profiling/heap_stats_closest_proc.out
@@ -8,7 +8,9 @@ java_heap_stats {
samples {
ts: 200000000
heap_size: 64
+ heap_native_size: 0
reachable_heap_size: 64
+ reachable_heap_native_size: 0
obj_count: 1
reachable_obj_count: 1
anon_rss_and_swap_size: 2048
@@ -30,7 +32,9 @@ java_heap_stats {
samples {
ts: 1500000000
heap_size: 64
+ heap_native_size: 0
reachable_heap_size: 64
+ reachable_heap_native_size: 0
obj_count: 1
reachable_obj_count: 1
anon_rss_and_swap_size: 3072
@@ -41,4 +45,4 @@ java_heap_stats {
}
}
}
-} \ No newline at end of file
+}
diff --git a/test/trace_processor/profiling/index b/test/trace_processor/profiling/index
index 66ae8e43f..5c88ba11a 100644
--- a/test/trace_processor/profiling/index
+++ b/test/trace_processor/profiling/index
@@ -8,10 +8,12 @@ heap_profile_dump_max.textproto heap_profile_tracker_new_stack.sql heap_profile_
profiler_smaps.textproto profiler_smaps.sql profiler_smaps.out
+profiler_smaps.textproto profiler_smaps profiler_smaps_metric.out
heap_graph_baseapk.textproto heap_graph_flamegraph.sql heap_graph_flamegraph.out
heap_graph_baseapk.textproto heap_graph_object.sql heap_graph_object.out
heap_graph_baseapk.textproto heap_graph_reference.sql heap_graph_reference.out
+heap_graph_deobfuscate_pkg.textproto heap_graph_object.sql heap_graph_object.out
heap_graph_duplicate.textproto heap_graph_flamegraph.sql heap_graph_duplicate_flamegraph.out
@@ -29,6 +31,10 @@ heap_profile_tracker_new_stack.textproto heap_profile_tracker_new_stack.sql heap
heap_profile_tracker_twoheaps.textproto heap_profile_tracker_twoheaps.sql heap_profile_tracker_twoheaps.out
heap_graph_branching.textproto heap_graph_flamegraph_focused.sql heap_graph_flamegraph_focused.out
heap_graph_superclass.textproto heap_graph_superclass.sql heap_graph_superclass.out
+heap_graph_native_size.textproto heap_graph_native_size.sql heap_graph_native_size.out
+# Regression test for b/222297079: when cumulative size in a flamegraph
+# overflows a signed 32-bit integer.
+heap_graph_huge_size.textproto heap_graph_flamegraph_matches_objects.sql heap_graph_flamegraph_matches_objects.out
# TODO(b/153552977): Stop supporting legacy heap graphs. These never made
# it into a public release, so we should eventually stop
@@ -51,3 +57,5 @@ heap_graph.textproto java_heap_histogram java_heap_histogram.out
# this uses llvm-symbolizer to test the offline symbolization built into
# trace_processor_shell.
../../data/heapprofd_standalone_client_example-trace stack_profile_symbols.sql stack_profile_symbols.out
+../../data/callstack_sampling.pftrace callstack_sampling_flamegraph.sql callstack_sampling_flamegraph.out
+../../data/callstack_sampling.pftrace callstack_sampling_flamegraph_multi_process.sql callstack_sampling_flamegraph_multi_process.out
diff --git a/test/trace_processor/profiling/java_heap_histogram.out b/test/trace_processor/profiling/java_heap_histogram.out
index 824b68c8b..206dc7ccb 100644
--- a/test/trace_processor/profiling/java_heap_histogram.out
+++ b/test/trace_processor/profiling/java_heap_histogram.out
@@ -8,30 +8,50 @@ java_heap_histogram {
samples {
ts: 10
type_count {
- type_name: "DeobfuscatedA[]"
- obj_count: 1
- reachable_obj_count: 1
- }
- type_count {
type_name: "FactoryProducerDelegateImplActor"
obj_count: 1
reachable_obj_count: 1
+ size_kb: 0
+ reachable_size_kb: 0
+ native_size_kb: 0
+ reachable_native_size_kb: 0
}
type_count {
type_name: "Foo"
obj_count: 2
reachable_obj_count: 1
+ size_kb: 0
+ reachable_size_kb: 0
+ native_size_kb: 0
+ reachable_native_size_kb: 0
}
type_count {
type_name: "DeobfuscatedA"
obj_count: 1
reachable_obj_count: 0
+ size_kb: 1
+ reachable_size_kb: 0
+ native_size_kb: 0
+ reachable_native_size_kb: 0
+ }
+ type_count {
+ type_name: "DeobfuscatedA[]"
+ obj_count: 1
+ reachable_obj_count: 1
+ size_kb: 0
+ reachable_size_kb: 0
+ native_size_kb: 0
+ reachable_native_size_kb: 0
}
type_count {
type_name: "java.lang.Class<DeobfuscatedA[]>"
obj_count: 1
reachable_obj_count: 0
- }
- }
+ size_kb: 0
+ reachable_size_kb: 0
+ native_size_kb: 0
+ reachable_native_size_kb: 0
+ }
+ }
}
}
diff --git a/test/trace_processor/profiling/java_heap_stats.out b/test/trace_processor/profiling/java_heap_stats.out
index a4ff25c56..6a1237fff 100644
--- a/test/trace_processor/profiling/java_heap_stats.out
+++ b/test/trace_processor/profiling/java_heap_stats.out
@@ -7,8 +7,10 @@ java_heap_stats {
}
samples {
ts: 10
- heap_size: 992
+ heap_size: 1760
+ heap_native_size: 0
reachable_heap_size: 352
+ reachable_heap_native_size: 0
obj_count: 6
reachable_obj_count: 3
anon_rss_and_swap_size: 4096000
diff --git a/test/trace_processor/profiling/profiler_smaps_metric.out b/test/trace_processor/profiling/profiler_smaps_metric.out
new file mode 100644
index 000000000..1c83553b4
--- /dev/null
+++ b/test/trace_processor/profiling/profiler_smaps_metric.out
@@ -0,0 +1,20 @@
+profiler_smaps {
+ instance {
+ process {
+ name: "system_server"
+ uid: 1000
+ }
+ mappings {
+ path: "[anon: libc_malloc]"
+ size_kb: 30
+ private_dirty_kb: 10
+ swap_kb: 10
+ }
+ mappings {
+ path: "/system/lib64/libc.so"
+ size_kb: 20
+ private_dirty_kb: 4
+ swap_kb: 4
+ }
+ }
+}
diff --git a/test/trace_processor/profiling/unsymbolized_frames.out b/test/trace_processor/profiling/unsymbolized_frames.out
index a587f461b..e4474ac5a 100644
--- a/test/trace_processor/profiling/unsymbolized_frames.out
+++ b/test/trace_processor/profiling/unsymbolized_frames.out
@@ -3,10 +3,24 @@ unsymbolized_frames {
module: "/liblib.so"
build_id: "6275696c642d6964"
address: 4096
+ google_lookup_id: "6275696c642d6964"
}
frames {
module: "/liblib.so"
build_id: "6275696c642d6964"
address: 8192
+ google_lookup_id: "6275696c642d6964"
+ }
+ frames {
+ module: "/libmonochrome_64.so"
+ build_id: "7f0715c286f8b16c10e4ad349cda3b9b56c7a773"
+ address: 4096
+ google_lookup_id: "c215077ff8866cb110e4ad349cda3b9b0"
+ }
+ frames {
+ module: "/libmonochrome_64.so"
+ build_id: "7f0715c286f8b16c10e4ad349cda3b9b56c7a773"
+ address: 8192
+ google_lookup_id: "c215077ff8866cb110e4ad349cda3b9b0"
}
}
diff --git a/test/trace_processor/python/api_integrationtest.py b/test/trace_processor/python/api_integrationtest.py
deleted file mode 100644
index 392e28e1d..000000000
--- a/test/trace_processor/python/api_integrationtest.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (C) 2020 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-import unittest
-
-from trace_processor.api import TraceProcessor
-
-
-class TestApi(unittest.TestCase):
-
- def test_trace_file(self):
- # Get path to trace_processor_shell and construct TraceProcessor
- tp = TraceProcessor(
- file_path=os.path.join(os.environ["ROOT_DIR"], 'test', 'data',
- 'example_android_trace_30s.pb'),
- bin_path=os.environ["SHELL_PATH"])
- qr_iterator = tp.query('select * from slice limit 10')
- dur_result = [
- 178646, 119740, 58073, 155000, 173177, 20209377, 3589167, 90104, 275312,
- 65313
- ]
-
- for num, row in enumerate(qr_iterator):
- self.assertEqual(row.type, 'internal_slice')
- self.assertEqual(row.dur, dur_result[num])
-
- # Test the batching logic by issuing a large query and ensuring we receive
- # all rows, not just a truncated subset.
- qr_iterator = tp.query('select count(*) as cnt from slice')
- expected_count = next(qr_iterator).cnt
- self.assertGreater(expected_count, 0)
-
- qr_iterator = tp.query('select * from slice')
- count = sum(1 for _ in qr_iterator)
- self.assertEqual(count, expected_count)
-
- tp.close()
diff --git a/test/trace_processor/python/api_unittest.py b/test/trace_processor/python/api_unittest.py
deleted file mode 100755
index 52e2c4154..000000000
--- a/test/trace_processor/python/api_unittest.py
+++ /dev/null
@@ -1,292 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (C) 2020 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import unittest
-
-from trace_processor.api import TraceProcessor, TraceProcessorException
-from trace_processor.protos import ProtoFactory
-
-
-class TestQueryResultIterator(unittest.TestCase):
- # The numbers input into cells correspond the the CellType enum values
- # defined under trace_processor.proto
- CELL_VARINT = ProtoFactory().CellsBatch().CELL_VARINT
- CELL_STRING = ProtoFactory().CellsBatch().CELL_STRING
- CELL_INVALID = ProtoFactory().CellsBatch().CELL_INVALID
-
- def test_one_batch(self):
- int_values = [100, 200]
- str_values = ['bar1', 'bar2']
-
- batch = ProtoFactory().CellsBatch()
- batch.cells.extend([
- TestQueryResultIterator.CELL_STRING,
- TestQueryResultIterator.CELL_VARINT,
- TestQueryResultIterator.CELL_STRING, TestQueryResultIterator.CELL_VARINT
- ])
- batch.varint_cells.extend(int_values)
- batch.string_cells = "\0".join(str_values) + "\0"
- batch.is_last_batch = True
-
- qr_iterator = TraceProcessor.QueryResultIterator(['foo_id', 'foo_num'],
- [batch])
-
- for num, row in enumerate(qr_iterator):
- self.assertEqual(row.foo_id, str_values[num])
- self.assertEqual(row.foo_num, int_values[num])
-
- def test_many_batches(self):
- int_values = [100, 200, 300, 400]
- str_values = ['bar1', 'bar2', 'bar3', 'bar4']
-
- batch_1 = ProtoFactory().CellsBatch()
- batch_1.cells.extend([
- TestQueryResultIterator.CELL_STRING,
- TestQueryResultIterator.CELL_VARINT,
- TestQueryResultIterator.CELL_STRING, TestQueryResultIterator.CELL_VARINT
- ])
- batch_1.varint_cells.extend(int_values[:2])
- batch_1.string_cells = "\0".join(str_values[:2]) + "\0"
- batch_1.is_last_batch = False
-
- batch_2 = ProtoFactory().CellsBatch()
- batch_2.cells.extend([
- TestQueryResultIterator.CELL_STRING,
- TestQueryResultIterator.CELL_VARINT,
- TestQueryResultIterator.CELL_STRING, TestQueryResultIterator.CELL_VARINT
- ])
- batch_2.varint_cells.extend(int_values[2:])
- batch_2.string_cells = "\0".join(str_values[2:]) + "\0"
- batch_2.is_last_batch = True
-
- qr_iterator = TraceProcessor.QueryResultIterator(['foo_id', 'foo_num'],
- [batch_1, batch_2])
-
- for num, row in enumerate(qr_iterator):
- self.assertEqual(row.foo_id, str_values[num])
- self.assertEqual(row.foo_num, int_values[num])
-
- def test_empty_batch(self):
- batch = ProtoFactory().CellsBatch()
- batch.is_last_batch = True
-
- qr_iterator = TraceProcessor.QueryResultIterator([], [batch])
-
- for num, row in enumerate(qr_iterator):
- self.assertIsNone(row.foo_id)
- self.assertIsNone(row.foo_num)
-
- def test_invalid_batch(self):
- batch = ProtoFactory().CellsBatch()
-
- qr_iterator = TraceProcessor.QueryResultIterator([], [batch])
-
- # Since the batch isn't defined as the last batch, the QueryResultsIterator
- # expects another batch and thus raises IndexError as no next batch exists.
- with self.assertRaises(IndexError):
- for row in qr_iterator:
- pass
-
- def test_incorrect_cells_batch(self):
- str_values = ['bar1', 'bar2']
-
- batch = ProtoFactory().CellsBatch()
- batch.cells.extend([
- TestQueryResultIterator.CELL_STRING,
- TestQueryResultIterator.CELL_VARINT,
- TestQueryResultIterator.CELL_STRING, TestQueryResultIterator.CELL_VARINT
- ])
- batch.string_cells = "\0".join(str_values) + "\0"
- batch.is_last_batch = True
-
- qr_iterator = TraceProcessor.QueryResultIterator(['foo_id', 'foo_num'],
- [batch])
-
- # The batch specifies there ought to be 2 cells of type VARINT and 2 cells
- # of type STRING, but there are no string cells defined in the batch. Thus
- # an IndexError occurs as it tries to access the empty string cells list.
- with self.assertRaises(IndexError):
- for row in qr_iterator:
- pass
-
- def test_incorrect_columns_batch(self):
- batch = ProtoFactory().CellsBatch()
- batch.cells.extend([
- TestQueryResultIterator.CELL_VARINT, TestQueryResultIterator.CELL_VARINT
- ])
- batch.varint_cells.extend([100, 200])
- batch.is_last_batch = True
-
- qr_iterator = TraceProcessor.QueryResultIterator(
- ['foo_id', 'foo_num', 'foo_dur', 'foo_ms'], [batch])
-
- # It's always the case that the number of cells is a multiple of the number
- # of columns. However, here this is clearly not the case, so when the
- # iterator tries to access the cell for the third column, it raises an
- # IndexError due to having exhausted the cells list.
- with self.assertRaises(IndexError):
- for row in qr_iterator:
- pass
-
- def test_invalid_cell_type(self):
- batch = ProtoFactory().CellsBatch()
- batch.cells.extend([
- TestQueryResultIterator.CELL_INVALID,
- TestQueryResultIterator.CELL_VARINT
- ])
- batch.varint_cells.extend([100, 200])
- batch.is_last_batch = True
-
- qr_iterator = TraceProcessor.QueryResultIterator(['foo_id', 'foo_num'],
- [batch])
-
- # In this batch we declare the columns types to be CELL_INVALID,
- # CELL_VARINT but that doesn't match the data which are both ints*
- # so we should raise a TraceProcessorException.
- with self.assertRaises(TraceProcessorException):
- for row in qr_iterator:
- pass
-
- def test_one_batch_as_pandas(self):
- int_values = [100, 200]
- str_values = ['bar1', 'bar2']
-
- batch = ProtoFactory().CellsBatch()
- batch.cells.extend([
- TestQueryResultIterator.CELL_STRING,
- TestQueryResultIterator.CELL_VARINT,
- TestQueryResultIterator.CELL_STRING, TestQueryResultIterator.CELL_VARINT
- ])
- batch.varint_cells.extend(int_values)
- batch.string_cells = "\0".join(str_values) + "\0"
- batch.is_last_batch = True
-
- qr_iterator = TraceProcessor.QueryResultIterator(['foo_id', 'foo_num'],
- [batch])
-
- qr_df = qr_iterator.as_pandas_dataframe()
- for num, row in qr_df.iterrows():
- self.assertEqual(row['foo_id'], str_values[num])
- self.assertEqual(row['foo_num'], int_values[num])
-
- def test_many_batches_as_pandas(self):
- int_values = [100, 200, 300, 400]
- str_values = ['bar1', 'bar2', 'bar3', 'bar4']
-
- batch_1 = ProtoFactory().CellsBatch()
- batch_1.cells.extend([
- TestQueryResultIterator.CELL_STRING,
- TestQueryResultIterator.CELL_VARINT,
- TestQueryResultIterator.CELL_STRING, TestQueryResultIterator.CELL_VARINT
- ])
- batch_1.varint_cells.extend(int_values[:2])
- batch_1.string_cells = "\0".join(str_values[:2]) + "\0"
- batch_1.is_last_batch = False
-
- batch_2 = ProtoFactory().CellsBatch()
- batch_2.cells.extend([
- TestQueryResultIterator.CELL_STRING,
- TestQueryResultIterator.CELL_VARINT,
- TestQueryResultIterator.CELL_STRING, TestQueryResultIterator.CELL_VARINT
- ])
- batch_2.varint_cells.extend(int_values[2:])
- batch_2.string_cells = "\0".join(str_values[2:]) + "\0"
- batch_2.is_last_batch = True
-
- qr_iterator = TraceProcessor.QueryResultIterator(['foo_id', 'foo_num'],
- [batch_1, batch_2])
-
- qr_df = qr_iterator.as_pandas_dataframe()
- for num, row in qr_df.iterrows():
- self.assertEqual(row['foo_id'], str_values[num])
- self.assertEqual(row['foo_num'], int_values[num])
-
- def test_empty_batch_as_pandas(self):
- batch = ProtoFactory().CellsBatch()
- batch.is_last_batch = True
-
- qr_iterator = TraceProcessor.QueryResultIterator([], [batch])
-
- qr_df = qr_iterator.as_pandas_dataframe()
- for num, row in qr_df.iterrows():
- self.assertEqual(row['foo_id'], str_values[num])
- self.assertEqual(row['foo_num'], int_values[num])
-
- def test_invalid_batch_as_pandas(self):
- batch = ProtoFactory().CellsBatch()
-
- qr_iterator = TraceProcessor.QueryResultIterator([], [batch])
-
- # Since the batch isn't defined as the last batch, the QueryResultsIterator
- # expects another batch and thus raises IndexError as no next batch exists.
- with self.assertRaises(IndexError):
- qr_df = qr_iterator.as_pandas_dataframe()
-
- def test_incorrect_cells_batch_as_pandas(self):
- str_values = ['bar1', 'bar2']
-
- batch = ProtoFactory().CellsBatch()
- batch.cells.extend([
- TestQueryResultIterator.CELL_STRING,
- TestQueryResultIterator.CELL_VARINT,
- TestQueryResultIterator.CELL_STRING, TestQueryResultIterator.CELL_VARINT
- ])
- batch.string_cells = "\0".join(str_values) + "\0"
- batch.is_last_batch = True
-
- qr_iterator = TraceProcessor.QueryResultIterator(['foo_id', 'foo_num'],
- [batch])
-
- # The batch specifies there ought to be 2 cells of type VARINT and 2 cells
- # of type STRING, but there are no string cells defined in the batch. Thus
- # an IndexError occurs as it tries to access the empty string cells list.
- with self.assertRaises(IndexError):
- qr_df = qr_iterator.as_pandas_dataframe()
-
- def test_incorrect_columns_batch_as_pandas(self):
- batch = ProtoFactory().CellsBatch()
- batch.cells.extend([
- TestQueryResultIterator.CELL_VARINT, TestQueryResultIterator.CELL_VARINT
- ])
- batch.varint_cells.extend([100, 200])
- batch.is_last_batch = True
-
- qr_iterator = TraceProcessor.QueryResultIterator(
- ['foo_id', 'foo_num', 'foo_dur', 'foo_ms'], [batch])
-
- # It's always the case that the number of cells is a multiple of the number
- # of columns. However, here this is clearly not the case, so when the
- # iterator tries to access the cell for the third column, it raises an
- # IndexError due to having exhausted the cells list.
- with self.assertRaises(IndexError):
- qr_df = qr_iterator.as_pandas_dataframe()
-
- def test_invalid_cell_type_as_pandas(self):
- batch = ProtoFactory().CellsBatch()
- batch.cells.extend([
- TestQueryResultIterator.CELL_INVALID,
- TestQueryResultIterator.CELL_VARINT
- ])
- batch.varint_cells.extend([100, 200])
- batch.is_last_batch = True
-
- qr_iterator = TraceProcessor.QueryResultIterator(['foo_id', 'foo_num'],
- [batch])
-
- # In this batch we declare the columns types to be CELL_INVALID,
- # CELL_VARINT but that doesn't match the data which are both ints*
- # so we should raise a TraceProcessorException.
- with self.assertRaises(TraceProcessorException):
- qr_df = qr_iterator.as_pandas_dataframe()
diff --git a/test/trace_processor/span_join/index b/test/trace_processor/span_join/index
index b0635e218..774b414d0 100644
--- a/test/trace_processor/span_join/index
+++ b/test/trace_processor/span_join/index
@@ -10,14 +10,25 @@
../../data/android_sched_and_ps.pb span_join_unpartitioned_empty.sql span_join_unpartitioned_empty.out
# Outer join
-../../data/android_sched_and_ps.pb span_outer_join.sql span_outer_join.out
-../../data/android_sched_and_ps.pb span_outer_join_empty.sql span_outer_join_empty_android_sched_and_ps.out
+../common/synth_1.py span_outer_join.sql span_outer_join.out
-# Left join
-../../data/android_sched_and_ps.pb span_left_join.sql span_left_join.out
-../../data/android_sched_and_ps.pb span_left_join_unpartitioned.sql span_left_join_unpartitioned.out
-../../data/android_sched_and_ps.pb span_left_join_left_unpartitioned.sql span_left_join_left_unpartitioned.out
-../../data/android_sched_and_ps.pb span_left_join_left_partitioned.sql span_left_join_left_partitioned.out
-../../data/android_sched_and_ps.pb span_left_join_empty_right.sql span_left_join_empty_right.out
-../../data/android_sched_and_ps.pb span_left_join_unordered.sql span_left_join_unordered_android_sched_and_ps.out
+../common/synth_1.py span_outer_join_empty.sql span_outer_join_empty.out
+../common/synth_1.py span_outer_join_unpartitioned_empty.sql span_outer_join_unpartitioned_empty.out
+../common/synth_1.py span_outer_join_unpartitioned_left_empty.sql span_outer_join_unpartitioned_left_empty.out
+../common/synth_1.py span_outer_join_unpartitioned_right_empty.sql span_outer_join_unpartitioned_right_empty.out
+
+../common/synth_1.py span_outer_join_mixed.sql span_outer_join_mixed.out
+../common/synth_1.py span_outer_join_mixed_empty.sql span_outer_join_mixed_empty.out
+../common/synth_1.py span_outer_join_mixed_left_empty.sql span_outer_join_mixed_left_empty.out
+../common/synth_1.py span_outer_join_mixed_left_empty_rev.sql span_outer_join_mixed_left_empty_rev.out
+../common/synth_1.py span_outer_join_mixed_right_empty.sql span_outer_join_mixed_right_empty.out
+../common/synth_1.py span_outer_join_mixed_right_empty_rev.sql span_outer_join_mixed_right_empty_rev.out
+../common/synth_1.py span_outer_join_mixed.sql span_outer_join_mixed.out
+# Left join
+../common/synth_1.py span_left_join.sql span_left_join.out
+../common/synth_1.py span_left_join_unpartitioned.sql span_left_join_unpartitioned.out
+../common/synth_1.py span_left_join_left_unpartitioned.sql span_left_join_left_unpartitioned.out
+../common/synth_1.py span_left_join_left_partitioned.sql span_left_join_left_partitioned.out
+../common/synth_1.py span_left_join_empty_right.sql span_left_join_empty_right.out
+../common/synth_1.py span_left_join_unordered.sql span_left_join_unordered_android_sched_and_ps.out
diff --git a/test/trace_processor/span_join/span_outer_join_empty_android_sched_and_ps.out b/test/trace_processor/span_join/span_outer_join_empty.out
index a64e00bf0..a64e00bf0 100644
--- a/test/trace_processor/span_join/span_outer_join_empty_android_sched_and_ps.out
+++ b/test/trace_processor/span_join/span_outer_join_empty.out
diff --git a/test/trace_processor/span_join/span_outer_join_mixed.out b/test/trace_processor/span_join/span_outer_join_mixed.out
new file mode 100644
index 000000000..f2e5496b0
--- /dev/null
+++ b/test/trace_processor/span_join/span_outer_join_mixed.out
@@ -0,0 +1,23 @@
+
+
+
+
+
+"ts","dur","part","a","b"
+50,50,1,"[NULL]",14
+100,50,1,10,14
+150,350,1,10,"[NULL]"
+500,50,1,11,"[NULL]"
+550,50,1,11,15
+600,50,1,"[NULL]",16
+900,500,1,"[NULL]",17
+50,100,2,"[NULL]",14
+500,50,2,12,"[NULL]"
+550,50,2,"[NULL]",15
+600,50,2,"[NULL]",16
+900,500,2,"[NULL]",17
+50,100,3,"[NULL]",14
+550,50,3,"[NULL]",15
+600,50,3,13,16
+650,50,3,13,"[NULL]"
+900,500,3,"[NULL]",17
diff --git a/test/trace_processor/span_join/span_outer_join_mixed.sql b/test/trace_processor/span_join/span_outer_join_mixed.sql
new file mode 100644
index 000000000..b05b18e7a
--- /dev/null
+++ b/test/trace_processor/span_join/span_outer_join_mixed.sql
@@ -0,0 +1,49 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+create table t1(
+ ts BIG INT,
+ dur BIG INT,
+ part BIG INT,
+ a BIG INT,
+ PRIMARY KEY (part, ts)
+) without rowid;
+
+create table t2(
+ ts BIG INT,
+ dur BIG INT,
+ b BIG INT,
+ PRIMARY KEY (ts)
+) without rowid;
+
+-- Add some rows to t1.
+INSERT INTO t1(ts, dur, part, a)
+VALUES
+(100, 400, 1, 10),
+(500, 100, 1, 11),
+(500, 50, 2, 12),
+(600, 100, 3, 13);
+
+-- Add some rows to t2.
+INSERT INTO t2(ts, dur, b)
+VALUES
+(50, 100, 14),
+(550, 50, 15),
+(600, 50, 16),
+(900, 500, 17);
+
+create virtual table sp using span_outer_join(t1 PARTITIONED part, t2);
+
+select * from sp;
diff --git a/test/trace_processor/span_join/span_outer_join_mixed_empty.out b/test/trace_processor/span_join/span_outer_join_mixed_empty.out
new file mode 100644
index 000000000..29a8f1bd8
--- /dev/null
+++ b/test/trace_processor/span_join/span_outer_join_mixed_empty.out
@@ -0,0 +1,4 @@
+
+
+
+"ts","dur","part"
diff --git a/test/trace_processor/span_join/span_outer_join_mixed_empty.sql b/test/trace_processor/span_join/span_outer_join_mixed_empty.sql
new file mode 100644
index 000000000..f5dc5babb
--- /dev/null
+++ b/test/trace_processor/span_join/span_outer_join_mixed_empty.sql
@@ -0,0 +1,33 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+create table t1(
+ ts BIG INT,
+ dur BIG INT,
+ part BIG INT,
+ PRIMARY KEY (part, ts)
+) without rowid;
+
+create table t2(
+ ts BIG INT,
+ dur BIG INT,
+ PRIMARY KEY (ts)
+) without rowid;
+
+-- t1 and t2 are empty.
+
+create virtual table sp using span_outer_join(t1 PARTITIONED part, t2);
+
+select * from sp;
diff --git a/test/trace_processor/span_join/span_outer_join_mixed_left_empty.out b/test/trace_processor/span_join/span_outer_join_mixed_left_empty.out
new file mode 100644
index 000000000..75e52f055
--- /dev/null
+++ b/test/trace_processor/span_join/span_outer_join_mixed_left_empty.out
@@ -0,0 +1,5 @@
+
+
+
+
+"ts","dur","part"
diff --git a/test/trace_processor/span_join/span_outer_join_mixed_left_empty.sql b/test/trace_processor/span_join/span_outer_join_mixed_left_empty.sql
new file mode 100644
index 000000000..2eeae2727
--- /dev/null
+++ b/test/trace_processor/span_join/span_outer_join_mixed_left_empty.sql
@@ -0,0 +1,37 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+create table t1(
+ ts BIG INT,
+ dur BIG INT,
+ part BIG INT,
+ PRIMARY KEY (part, ts)
+) without rowid;
+
+create table t2(
+ ts BIG INT,
+ dur BIG INT,
+ PRIMARY KEY (ts)
+) without rowid;
+
+INSERT INTO t2(ts, dur)
+VALUES
+(100, 400),
+(500, 50),
+(600, 100);
+
+create virtual table sp using span_outer_join(t1 PARTITIONED part, t2);
+
+select * from sp;
diff --git a/test/trace_processor/span_join/span_outer_join_mixed_left_empty_rev.out b/test/trace_processor/span_join/span_outer_join_mixed_left_empty_rev.out
new file mode 100644
index 000000000..f43c5e2de
--- /dev/null
+++ b/test/trace_processor/span_join/span_outer_join_mixed_left_empty_rev.out
@@ -0,0 +1,8 @@
+
+
+
+
+"ts","dur","part"
+100,400,0
+100,50,1
+600,100,1
diff --git a/test/trace_processor/span_join/span_outer_join_mixed_left_empty_rev.sql b/test/trace_processor/span_join/span_outer_join_mixed_left_empty_rev.sql
new file mode 100644
index 000000000..5926fb39f
--- /dev/null
+++ b/test/trace_processor/span_join/span_outer_join_mixed_left_empty_rev.sql
@@ -0,0 +1,37 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+create table t1(
+ ts BIG INT,
+ dur BIG INT,
+ part BIG INT,
+ PRIMARY KEY (part, ts)
+) without rowid;
+
+create table t2(
+ ts BIG INT,
+ dur BIG INT,
+ PRIMARY KEY (ts)
+) without rowid;
+
+INSERT INTO t1(ts, dur, part)
+VALUES
+(100, 400, 0),
+(100, 50, 1),
+(600, 100, 1);
+
+create virtual table sp using span_outer_join(t2, t1 PARTITIONED part);
+
+select * from sp;
diff --git a/test/trace_processor/span_join/span_outer_join_mixed_right_empty.out b/test/trace_processor/span_join/span_outer_join_mixed_right_empty.out
new file mode 100644
index 000000000..31a5fbb87
--- /dev/null
+++ b/test/trace_processor/span_join/span_outer_join_mixed_right_empty.out
@@ -0,0 +1,8 @@
+
+
+
+
+"ts","dur","part","b"
+100,400,0,"[NULL]"
+100,50,1,"[NULL]"
+600,100,1,"[NULL]"
diff --git a/test/trace_processor/span_join/span_outer_join_mixed_right_empty.sql b/test/trace_processor/span_join/span_outer_join_mixed_right_empty.sql
new file mode 100644
index 000000000..3001d28e2
--- /dev/null
+++ b/test/trace_processor/span_join/span_outer_join_mixed_right_empty.sql
@@ -0,0 +1,38 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+create table t1(
+ ts BIG INT,
+ dur BIG INT,
+ part BIG INT,
+ PRIMARY KEY (part, ts)
+) without rowid;
+
+create table t2(
+ ts BIG INT,
+ dur BIG INT,
+ b BIG INT,
+ PRIMARY KEY (ts)
+) without rowid;
+
+INSERT INTO t1(ts, dur, part)
+VALUES
+(100, 400, 0),
+(100, 50, 1),
+(600, 100, 1);
+
+create virtual table sp using span_outer_join(t1 PARTITIONED part, t2);
+
+select * from sp;
diff --git a/test/trace_processor/span_join/span_outer_join_mixed_right_empty_rev.out b/test/trace_processor/span_join/span_outer_join_mixed_right_empty_rev.out
new file mode 100644
index 000000000..724e3b426
--- /dev/null
+++ b/test/trace_processor/span_join/span_outer_join_mixed_right_empty_rev.out
@@ -0,0 +1,5 @@
+
+
+
+
+"ts","dur","part","b"
diff --git a/test/trace_processor/span_join/span_outer_join_mixed_right_empty_rev.sql b/test/trace_processor/span_join/span_outer_join_mixed_right_empty_rev.sql
new file mode 100644
index 000000000..f325cc4de
--- /dev/null
+++ b/test/trace_processor/span_join/span_outer_join_mixed_right_empty_rev.sql
@@ -0,0 +1,38 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+create table t1(
+ ts BIG INT,
+ dur BIG INT,
+ part BIG INT,
+ PRIMARY KEY (part, ts)
+) without rowid;
+
+create table t2(
+ ts BIG INT,
+ dur BIG INT,
+ b BIG INT,
+ PRIMARY KEY (ts)
+) without rowid;
+
+INSERT INTO t2(ts, dur)
+VALUES
+(100, 400),
+(500, 50),
+(600, 100);
+
+create virtual table sp using span_outer_join(t2, t1 PARTITIONED part);
+
+select * from sp;
diff --git a/test/trace_processor/span_join/span_outer_join_unpartitioned.out b/test/trace_processor/span_join/span_outer_join_unpartitioned.out
new file mode 100644
index 000000000..d668103c6
--- /dev/null
+++ b/test/trace_processor/span_join/span_outer_join_unpartitioned.out
@@ -0,0 +1,14 @@
+
+
+
+
+
+"ts","dur","a","b"
+50,50,"[NULL]",4
+100,50,1,4
+150,350,1,"[NULL]"
+500,50,2,"[NULL]"
+550,50,"[NULL]",5
+600,50,3,6
+650,50,3,"[NULL]"
+900,500,"[NULL]",7
diff --git a/test/trace_processor/span_join/span_outer_join_unpartitioned.sql b/test/trace_processor/span_join/span_outer_join_unpartitioned.sql
new file mode 100644
index 000000000..ce4fa79fa
--- /dev/null
+++ b/test/trace_processor/span_join/span_outer_join_unpartitioned.sql
@@ -0,0 +1,47 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+create table t1(
+ ts BIG INT,
+ dur BIG INT,
+ a BIG INT,
+ PRIMARY KEY (ts)
+) without rowid;
+
+create table t2(
+ ts BIG INT,
+ dur BIG INT,
+ b BIG INT,
+ PRIMARY KEY (ts)
+) without rowid;
+
+-- Add some rows to t1.
+INSERT INTO t1(ts, dur, a)
+VALUES
+(100, 400, 1),
+(500, 50, 2),
+(600, 100, 3);
+
+-- Add some rows to t2.
+INSERT INTO t2(ts, dur, b)
+VALUES
+(50, 100, 4),
+(550, 50, 5),
+(600, 50, 6),
+(900, 500, 7);
+
+create virtual table sp using span_outer_join(t1, t2);
+
+select * from sp;
diff --git a/test/trace_processor/span_join/span_outer_join_unpartitioned_empty.out b/test/trace_processor/span_join/span_outer_join_unpartitioned_empty.out
new file mode 100644
index 000000000..d02fdd715
--- /dev/null
+++ b/test/trace_processor/span_join/span_outer_join_unpartitioned_empty.out
@@ -0,0 +1,4 @@
+
+
+
+"ts","dur"
diff --git a/test/trace_processor/span_join/span_outer_join_unpartitioned_empty.sql b/test/trace_processor/span_join/span_outer_join_unpartitioned_empty.sql
new file mode 100644
index 000000000..8155974b7
--- /dev/null
+++ b/test/trace_processor/span_join/span_outer_join_unpartitioned_empty.sql
@@ -0,0 +1,32 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+create table t1(
+ ts BIG INT,
+ dur BIG INT,
+ PRIMARY KEY (ts)
+) without rowid;
+
+create table t2(
+ ts BIG INT,
+ dur BIG INT,
+ PRIMARY KEY (ts)
+) without rowid;
+
+-- t1 and t2 are empty.
+
+create virtual table sp using span_outer_join(t1, t2);
+
+select * from sp;
diff --git a/test/trace_processor/span_join/span_outer_join_unpartitioned_left_empty.out b/test/trace_processor/span_join/span_outer_join_unpartitioned_left_empty.out
new file mode 100644
index 000000000..4ea997f21
--- /dev/null
+++ b/test/trace_processor/span_join/span_outer_join_unpartitioned_left_empty.out
@@ -0,0 +1,8 @@
+
+
+
+
+"ts","dur"
+100,400
+500,50
+600,100
diff --git a/test/trace_processor/span_join/span_outer_join_unpartitioned_left_empty.sql b/test/trace_processor/span_join/span_outer_join_unpartitioned_left_empty.sql
new file mode 100644
index 000000000..ab41a286a
--- /dev/null
+++ b/test/trace_processor/span_join/span_outer_join_unpartitioned_left_empty.sql
@@ -0,0 +1,37 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+create table t1(
+ ts BIG INT,
+ dur BIG INT,
+ PRIMARY KEY (ts)
+) without rowid;
+
+create table t2(
+ ts BIG INT,
+ dur BIG INT,
+ PRIMARY KEY (ts)
+) without rowid;
+
+-- Add some rows to t2.
+INSERT INTO t2(ts, dur)
+VALUES
+(100, 400),
+(500, 50),
+(600, 100);
+
+create virtual table sp using span_outer_join(t1, t2);
+
+select * from sp;
diff --git a/test/trace_processor/span_join/span_outer_join_unpartitioned_right_empty.out b/test/trace_processor/span_join/span_outer_join_unpartitioned_right_empty.out
new file mode 100644
index 000000000..4ea997f21
--- /dev/null
+++ b/test/trace_processor/span_join/span_outer_join_unpartitioned_right_empty.out
@@ -0,0 +1,8 @@
+
+
+
+
+"ts","dur"
+100,400
+500,50
+600,100
diff --git a/test/trace_processor/span_join/span_outer_join_unpartitioned_right_empty.sql b/test/trace_processor/span_join/span_outer_join_unpartitioned_right_empty.sql
new file mode 100644
index 000000000..1e3d959da
--- /dev/null
+++ b/test/trace_processor/span_join/span_outer_join_unpartitioned_right_empty.sql
@@ -0,0 +1,37 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+create table t1(
+ ts BIG INT,
+ dur BIG INT,
+ PRIMARY KEY (ts)
+) without rowid;
+
+create table t2(
+ ts BIG INT,
+ dur BIG INT,
+ PRIMARY KEY (ts)
+) without rowid;
+
+-- Add some rows to t1.
+INSERT INTO t1(ts, dur)
+VALUES
+(100, 400),
+(500, 50),
+(600, 100);
+
+create virtual table sp using span_outer_join(t1, t2);
+
+select * from sp;
diff --git a/test/trace_processor/startup/android_startup.out b/test/trace_processor/startup/android_startup.out
index a7dd38334..5d323e495 100644
--- a/test/trace_processor/startup/android_startup.out
+++ b/test/trace_processor/startup/android_startup.out
@@ -18,12 +18,12 @@ android_startup {
}
}
zygote_new_process: false
- activity_hosting_process_count: 2
+ activity_hosting_process_count: 1
to_first_frame {
dur_ns: 108
main_thread_by_task_state {
- running_dur_ns: 41
- runnable_dur_ns: 129
+ running_dur_ns: 10
+ runnable_dur_ns: 80
uninterruptible_sleep_dur_ns: 0
interruptible_sleep_dur_ns: 10
}
@@ -34,6 +34,10 @@ android_startup {
}
mcycles_by_core_type {
}
+ time_activity_start {
+ dur_ns: 2
+ dur_ms: 2e-06
+ }
dur_ms: 0.000108
}
report_fully_drawn {
diff --git a/test/trace_processor/startup/android_startup.py b/test/trace_processor/startup/android_startup.py
index 494849cb6..c5f0e37a9 100644
--- a/test/trace_processor/startup/android_startup.py
+++ b/test/trace_processor/startup/android_startup.py
@@ -22,7 +22,7 @@ trace.add_packet()
trace.add_process(1, 0, 'init')
trace.add_process(2, 1, 'system_server')
trace.add_process(3, 1, 'com.google.android.calendar', 10001)
-trace.add_process(4, 1, 'com.google.android.calendar')
+trace.add_process(4, 3, 'com.google.android.calendar', 10001)
trace.add_package_list(
ts=1, name='com.google.android.calendar', uid=10001, version_code=123)
@@ -42,6 +42,13 @@ trace.add_atrace_async_begin(
ts=110, tid=2, pid=2, buf='launching: com.google.android.calendar')
trace.add_sched(ts=110, prev_pid=0, next_pid=3)
+
+# As the process already existed before intent started, this is a
+# warm/hot start (we choose warm). Therefore, emit an activityStart
+# slice.
+trace.add_atrace_begin(ts=115, tid=3, pid=3, buf='activityStart')
+trace.add_atrace_end(ts=117, tid=3, pid=3)
+
# P1: 10ns running
trace.add_sched(ts=120, prev_pid=3, next_pid=0, prev_state='S')
# P1: 10ns sleep
diff --git a/test/trace_processor/startup/android_startup_attribution.out b/test/trace_processor/startup/android_startup_attribution.out
index 5046ed44b..3c741456c 100644
--- a/test/trace_processor/startup/android_startup_attribution.out
+++ b/test/trace_processor/startup/android_startup_attribution.out
@@ -17,6 +17,10 @@ android_startup {
dur_ns: 2
dur_ms: 2e-06
}
+ time_activity_resume {
+ dur_ns: 5
+ dur_ms: 5e-06
+ }
dur_ms: 999.9999
time_dex_open {
dur_ns: 20
@@ -56,6 +60,9 @@ android_startup {
dur_ms: 100
}
thread: "Binder"
+ destination_process: "system_server"
+ flags: "0x00 No Flags Set"
+ code: "0x00 Java Layer Dependent"
}
long_binder_transactions {
duration {
@@ -63,6 +70,10 @@ android_startup {
dur_ms: 200
}
thread: "fonts"
+ destination_thread: "Binder"
+ destination_process: "com.some.app"
+ flags: "0x00 No Flags Set"
+ code: "0x00 Java Layer Dependent"
}
}
}
diff --git a/test/trace_processor/startup/android_startup_attribution.py b/test/trace_processor/startup/android_startup_attribution.py
index 61d9ebc5f..2f8a4bebf 100644
--- a/test/trace_processor/startup/android_startup_attribution.py
+++ b/test/trace_processor/startup/android_startup_attribution.py
@@ -18,7 +18,7 @@ from os import sys, path
import synth_common
APP_PID = 3
-APP_TID = 1
+APP_TID = APP_PID
SECOND_APP_TID = 3
JIT_TID = 4
GC_TID = 5
@@ -65,6 +65,10 @@ trace.add_atrace_async_begin(
tid=SYSTEM_SERVER_TID,
buf='launching: com.some.app')
+# Emulate a hot start (and therefore that we only see activityResume).
+trace.add_atrace_begin(ts=125, tid=APP_TID, pid=APP_PID, buf='activityResume')
+trace.add_atrace_end(ts=130, tid=APP_TID, pid=APP_PID)
+
# OpenDex slices within the startup.
trace.add_atrace_begin(
ts=150, pid=APP_PID, tid=APP_TID, buf='OpenDexFilesFromOat(something)')
@@ -150,18 +154,18 @@ trace.add_sched(ts=350, prev_pid=GC2_TID, next_pid=GC_TID)
trace.add_sched(ts=360, prev_pid=GC_TID, next_pid=0)
# Long binder transactions.
-trace.add_atrace_begin(
- ts=10**8, pid=APP_PID, tid=BINDER_TID, buf='binder transaction')
-trace.add_atrace_end(ts=2 * (10**8), pid=APP_PID, tid=BINDER_TID)
+trace.add_binder_transaction(1, 10**8, 2 * (10**8), BINDER_TID, APP_PID, 2,
+ 10**8 + 1, 2 * (10**8) - 1, SYSTEM_SERVER_TID,
+ SYSTEM_SERVER_PID)
-trace.add_atrace_begin(
- ts=3 * (10**8), pid=APP_PID, tid=FONTS_TID, buf='binder transaction')
-trace.add_atrace_end(ts=5 * (10**8), pid=APP_PID, tid=FONTS_TID)
+trace.add_binder_transaction(3, 3 * (10**8), 5 * (10**8), FONTS_TID, APP_PID, 4,
+ 3 * (10**8) + 1, 5 * (10**8) - 1, BINDER_TID,
+ APP_PID)
# A short binder transaction.
-trace.add_atrace_begin(
- ts=10**7, pid=APP_PID, tid=BINDER_TID, buf='binder transaction')
-trace.add_atrace_end(ts=6 * (10**7), pid=APP_PID, tid=BINDER_TID)
+trace.add_binder_transaction(5, 10**7, 5 * (10**7), BINDER_TID, APP_TID, 6,
+ 10**7 + 1, 5 * (10**7) - 1, SYSTEM_SERVER_TID,
+ SYSTEM_SERVER_PID)
# Intent successful.
trace.add_atrace_begin(
diff --git a/test/trace_processor/startup/android_startup_minsdk33.out b/test/trace_processor/startup/android_startup_minsdk33.out
new file mode 100644
index 000000000..e7022b5bf
--- /dev/null
+++ b/test/trace_processor/startup/android_startup_minsdk33.out
@@ -0,0 +1,25 @@
+android_startup {
+ startup {
+ startup_id: 1
+ package_name: "com.google.android.calendar"
+ zygote_new_process: false
+ to_first_frame {
+ dur_ns: 100
+ main_thread_by_task_state {
+ running_dur_ns: 0
+ runnable_dur_ns: 0
+ uninterruptible_sleep_dur_ns: 0
+ interruptible_sleep_dur_ns: 0
+ }
+ other_processes_spawned_count: 0
+ dur_ms: 0.0001
+ mcycles_by_core_type {
+ }
+ }
+ activity_hosting_process_count: 0
+ event_timestamps {
+ intent_received: 110
+ first_frame: 210
+ }
+ }
+}
diff --git a/test/trace_processor/startup/android_startup_minsdk33.py b/test/trace_processor/startup/android_startup_minsdk33.py
new file mode 100644
index 000000000..dddc503a9
--- /dev/null
+++ b/test/trace_processor/startup/android_startup_minsdk33.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python3
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from os import sys, path
+
+import synth_common
+
+trace = synth_common.create_trace()
+trace.add_packet()
+trace.add_process(1, 0, 'init')
+trace.add_process(2, 1, 'system_server')
+trace.add_process(3, 1, 'com.google.android.calendar', 10001)
+
+trace.add_package_list(
+ ts=1, name='com.google.android.calendar', uid=10001, version_code=123)
+
+trace.add_ftrace_packet(cpu=0)
+trace.add_atrace_async_begin(ts=110, tid=2, pid=2, buf='launchingActivity#1')
+trace.add_atrace_async_end(ts=210, tid=2, pid=2, buf='launchingActivity#1')
+trace.add_atrace_instant(
+ ts=211,
+ tid=2,
+ pid=2,
+ buf='launchingActivity#1:completed:com.google.android.calendar')
+
+sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/startup/android_startup_powrails.out b/test/trace_processor/startup/android_startup_powrails.out
index 67d567721..3c263813f 100644
--- a/test/trace_processor/startup/android_startup_powrails.out
+++ b/test/trace_processor/startup/android_startup_powrails.out
@@ -9,6 +9,7 @@ android_powrails{
timestamp_ms: 6
energy_uws: 50
}
+ avg_used_power_mw: 38
}
power_rails{
name: "power.PR_2_uws"
@@ -20,6 +21,7 @@ android_powrails{
timestamp_ms: 6
energy_uws: 70
}
+ avg_used_power_mw: 60
}
power_rails{
name: "power.PR_3_uws"
@@ -31,5 +33,6 @@ android_powrails{
timestamp_ms: 6
energy_uws: 15
}
+ avg_used_power_mw: 7
}
} \ No newline at end of file
diff --git a/test/trace_processor/startup/android_startup_process_track.out b/test/trace_processor/startup/android_startup_process_track.out
index 357603db0..7a8ae0f86 100644
--- a/test/trace_processor/startup/android_startup_process_track.out
+++ b/test/trace_processor/startup/android_startup_process_track.out
@@ -8,7 +8,7 @@ android_startup {
}
zygote_new_process: false
to_first_frame {
- dur_ns: 4
+ dur_ns: 5
main_thread_by_task_state {
running_dur_ns: 0
runnable_dur_ns: 0
@@ -22,11 +22,19 @@ android_startup {
}
mcycles_by_core_type {
}
- dur_ms: 4e-06
+ time_bind_application {
+ dur_ns: 1
+ dur_ms: 1e-06
+ }
+ dur_ms: 5e-06
+ to_bind_application {
+ dur_ns: 3
+ dur_ms: 3e-06
+ }
}
event_timestamps {
intent_received: 100
- first_frame: 104
+ first_frame: 105
}
activity_hosting_process_count: 1
}
@@ -39,7 +47,7 @@ android_startup {
}
zygote_new_process: false
to_first_frame {
- dur_ns: 4
+ dur_ns: 5
main_thread_by_task_state {
running_dur_ns: 0
runnable_dur_ns: 0
@@ -53,11 +61,19 @@ android_startup {
}
mcycles_by_core_type {
}
- dur_ms: 4e-06
+ time_bind_application {
+ dur_ns: 1
+ dur_ms: 1e-06
+ }
+ dur_ms: 5e-06
+ to_bind_application {
+ dur_ns: 3
+ dur_ms: 3e-06
+ }
}
event_timestamps {
intent_received: 200
- first_frame: 204
+ first_frame: 205
}
activity_hosting_process_count: 1
}
diff --git a/test/trace_processor/startup/android_startup_process_track.py b/test/trace_processor/startup/android_startup_process_track.py
index a9696ad06..07fcf92cd 100644
--- a/test/trace_processor/startup/android_startup_process_track.py
+++ b/test/trace_processor/startup/android_startup_process_track.py
@@ -34,10 +34,12 @@ def add_startup(trace, ts, pid):
new_tid=pid,
new_comm='com.google.android.calendar',
flags=0)
+ trace.add_atrace_begin(ts=ts + 3, tid=pid, pid=pid, buf='bindApplication')
+ trace.add_atrace_end(ts=ts + 4, tid=pid, pid=pid)
trace.add_atrace_async_end(
- ts=ts + 4, tid=2, pid=2, buf='launching: com.google.android.calendar')
+ ts=ts + 5, tid=2, pid=2, buf='launching: com.google.android.calendar')
trace.add_atrace_begin(
- ts=ts + 5,
+ ts=ts + 6,
tid=2,
pid=2,
buf='MetricsLogger:launchObserverNotifyActivityLaunchFinished')
diff --git a/test/trace_processor/startup/index b/test/trace_processor/startup/index
index 1780fa81f..ee6003ed2 100644
--- a/test/trace_processor/startup/index
+++ b/test/trace_processor/startup/index
@@ -2,6 +2,7 @@
# Startup metric tests.
android_startup.py android_startup android_startup.out
+android_startup_minsdk33.py android_startup android_startup_minsdk33.out
android_startup_breakdown.py android_startup android_startup_breakdown.out
android_startup_process_track.py android_startup android_startup_process_track.out
android_startup_attribution.py android_startup android_startup_attribution.out
diff --git a/test/trace_processor/tables/ftrace_setup_errors.out b/test/trace_processor/tables/ftrace_setup_errors.out
new file mode 100644
index 000000000..5309e5413
--- /dev/null
+++ b/test/trace_processor/tables/ftrace_setup_errors.out
@@ -0,0 +1,7 @@
+"value"
+3
+"Ftrace event unknown: foo/bar
+Ftrace event unknown: sched/foobar
+Atrace failures: error: unknown tracing category "bar"
+error enabling tracing category "bar"
+"
diff --git a/test/trace_processor/tables/ftrace_setup_errors.sql b/test/trace_processor/tables/ftrace_setup_errors.sql
new file mode 100644
index 000000000..cc1b3c023
--- /dev/null
+++ b/test/trace_processor/tables/ftrace_setup_errors.sql
@@ -0,0 +1,3 @@
+SELECT value FROM stats WHERE name = 'ftrace_setup_errors'
+UNION ALL
+SELECT str_value FROM metadata WHERE name = 'ftrace_setup_errors'
diff --git a/test/trace_processor/tables/index b/test/trace_processor/tables/index
index 811c198de..10b6d9418 100644
--- a/test/trace_processor/tables/index
+++ b/test/trace_processor/tables/index
@@ -33,3 +33,6 @@ thread_main_thread.textproto thread_main_thread.sql thread_main_thread.out
# Processes as a metric
process_uids.textproto android_task_names android_task_names.out
+
+# Ftrace stats imports in metadata and stats tables
+../../data/ftrace_error_stats.pftrace ftrace_setup_errors.sql ftrace_setup_errors.out
diff --git a/test/trace_processor/tables/nulls.sql b/test/trace_processor/tables/nulls.sql
index 44e513247..cccbc47b1 100644
--- a/test/trace_processor/tables/nulls.sql
+++ b/test/trace_processor/tables/nulls.sql
@@ -37,6 +37,6 @@ VALUES
(2, NULL, NULL, NULL, "test", NULL),
(1, "other", NULL, NULL, NULL, NULL),
(4, NULL, NULL, NULL, NULL, 1.0),
-(NULL, "test", 1.0, 1, NULL, NULL)
+(NULL, "test", 1.0, 1, NULL, NULL);
SELECT * from null_test;
diff --git a/test/trace_processor/tables/trace_metadata.json.out b/test/trace_processor/tables/trace_metadata.json.out
index 0d3f5d079..26214e6e2 100644
--- a/test/trace_processor/tables/trace_metadata.json.out
+++ b/test/trace_processor/tables/trace_metadata.json.out
@@ -1,8 +1,9 @@
{
"trace_metadata": {
"trace_duration_ns": 9519159074,
+ "trace_uuid": "00000000-0000-0000-e77f-20a2204c2a49",
"trace_size_bytes": 6365447,
- "trace_config_pbtxt": "buffers: {\n size_kb: 32768\n fill_policy: UNSPECIFIED\n}\ndata_sources: {\n config: {\n name: \"linux.ftrace\"\n target_buffer: 0\n trace_duration_ms: 0\n tracing_session_id: 0\n ftrace_config: {\n ftrace_events: \"print\"\n ftrace_events: \"sched_switch\"\n ftrace_events: \"rss_stat\"\n ftrace_events: \"ion_heap_shrink\"\n ftrace_events: \"ion_heap_grow\"\n atrace_categories: \"am\"\n atrace_categories: \"dalvik\"\n buffer_size_kb: 0\n drain_period_ms: 0\n }\n chrome_config: {\n trace_config: \"\"\n }\n inode_file_config: {\n scan_interval_ms: 0\n scan_delay_ms: 0\n scan_batch_size: 0\n do_not_scan: false\n }\n process_stats_config: {\n scan_all_processes_on_start: false\n record_thread_names: false\n proc_stats_poll_ms: 0\n }\n sys_stats_config: {\n meminfo_period_ms: 0\n vmstat_period_ms: 0\n stat_period_ms: 0\n }\n heapprofd_config: {\n sampling_interval_bytes: 0\n all: false\n continuous_dump_config: {\n dump_phase_ms: 0\n dump_interval_ms: 0\n }\n }\n legacy_config: \"\"\n }\n}\ndata_sources: {\n config: {\n name: \"linux.process_stats\"\n target_buffer: 0\n trace_duration_ms: 0\n tracing_session_id: 0\n ftrace_config: {\n buffer_size_kb: 0\n drain_period_ms: 0\n }\n chrome_config: {\n trace_config: \"\"\n }\n inode_file_config: {\n scan_interval_ms: 0\n scan_delay_ms: 0\n scan_batch_size: 0\n do_not_scan: false\n }\n process_stats_config: {\n scan_all_processes_on_start: false\n record_thread_names: false\n proc_stats_poll_ms: 100\n }\n sys_stats_config: {\n meminfo_period_ms: 0\n vmstat_period_ms: 0\n stat_period_ms: 0\n }\n heapprofd_config: {\n sampling_interval_bytes: 0\n all: false\n continuous_dump_config: {\n dump_phase_ms: 0\n dump_interval_ms: 0\n }\n }\n legacy_config: \"\"\n }\n}\ndata_sources: {\n config: {\n name: \"linux.sys_stats\"\n target_buffer: 0\n trace_duration_ms: 0\n tracing_session_id: 0\n ftrace_config: {\n buffer_size_kb: 0\n drain_period_ms: 0\n }\n chrome_config: {\n trace_config: \"\"\n }\n inode_file_config: {\n scan_interval_ms: 0\n scan_delay_ms: 0\n scan_batch_size: 0\n do_not_scan: false\n }\n process_stats_config: {\n scan_all_processes_on_start: false\n record_thread_names: false\n proc_stats_poll_ms: 0\n }\n sys_stats_config: {\n meminfo_period_ms: 50\n meminfo_counters: MEMINFO_MEM_AVAILABLE\n meminfo_counters: MEMINFO_SWAP_CACHED\n meminfo_counters: MEMINFO_ACTIVE\n meminfo_counters: MEMINFO_INACTIVE\n vmstat_period_ms: 0\n stat_period_ms: 0\n }\n heapprofd_config: {\n sampling_interval_bytes: 0\n all: false\n continuous_dump_config: {\n dump_phase_ms: 0\n dump_interval_ms: 0\n }\n }\n legacy_config: \"\"\n }\n}\nduration_ms: 10000\nenable_extra_guardrails: false\nlockdown_mode: LOCKDOWN_UNCHANGED\nstatsd_metadata: {\n triggering_alert_id: 0\n triggering_config_uid: 0\n triggering_config_id: 0\n}\nwrite_into_file: false\nfile_write_period_ms: 0\nmax_file_size_bytes: 0\nguardrail_overrides: {\n max_upload_per_day_bytes: 0\n}\ndeferred_start: false",
+ "trace_config_pbtxt": "buffers {\n size_kb: 32768\n fill_policy: UNSPECIFIED\n}\ndata_sources {\n config {\n name: \"linux.ftrace\"\n target_buffer: 0\n trace_duration_ms: 0\n tracing_session_id: 0\n ftrace_config {\n ftrace_events: \"print\"\n ftrace_events: \"sched_switch\"\n ftrace_events: \"rss_stat\"\n ftrace_events: \"ion_heap_shrink\"\n ftrace_events: \"ion_heap_grow\"\n atrace_categories: \"am\"\n atrace_categories: \"dalvik\"\n buffer_size_kb: 0\n drain_period_ms: 0\n }\n chrome_config {\n trace_config: \"\"\n }\n inode_file_config {\n scan_interval_ms: 0\n scan_delay_ms: 0\n scan_batch_size: 0\n do_not_scan: false\n }\n process_stats_config {\n scan_all_processes_on_start: false\n record_thread_names: false\n proc_stats_poll_ms: 0\n }\n sys_stats_config {\n meminfo_period_ms: 0\n vmstat_period_ms: 0\n stat_period_ms: 0\n }\n heapprofd_config {\n sampling_interval_bytes: 0\n all: false\n continuous_dump_config {\n dump_phase_ms: 0\n dump_interval_ms: 0\n }\n }\n legacy_config: \"\"\n }\n}\ndata_sources {\n config {\n name: \"linux.process_stats\"\n target_buffer: 0\n trace_duration_ms: 0\n tracing_session_id: 0\n ftrace_config {\n buffer_size_kb: 0\n drain_period_ms: 0\n }\n chrome_config {\n trace_config: \"\"\n }\n inode_file_config {\n scan_interval_ms: 0\n scan_delay_ms: 0\n scan_batch_size: 0\n do_not_scan: false\n }\n process_stats_config {\n scan_all_processes_on_start: false\n record_thread_names: false\n proc_stats_poll_ms: 100\n }\n sys_stats_config {\n meminfo_period_ms: 0\n vmstat_period_ms: 0\n stat_period_ms: 0\n }\n heapprofd_config {\n sampling_interval_bytes: 0\n all: false\n continuous_dump_config {\n dump_phase_ms: 0\n dump_interval_ms: 0\n }\n }\n legacy_config: \"\"\n }\n}\ndata_sources {\n config {\n name: \"linux.sys_stats\"\n target_buffer: 0\n trace_duration_ms: 0\n tracing_session_id: 0\n ftrace_config {\n buffer_size_kb: 0\n drain_period_ms: 0\n }\n chrome_config {\n trace_config: \"\"\n }\n inode_file_config {\n scan_interval_ms: 0\n scan_delay_ms: 0\n scan_batch_size: 0\n do_not_scan: false\n }\n process_stats_config {\n scan_all_processes_on_start: false\n record_thread_names: false\n proc_stats_poll_ms: 0\n }\n sys_stats_config {\n meminfo_period_ms: 50\n meminfo_counters: MEMINFO_MEM_AVAILABLE\n meminfo_counters: MEMINFO_SWAP_CACHED\n meminfo_counters: MEMINFO_ACTIVE\n meminfo_counters: MEMINFO_INACTIVE\n vmstat_period_ms: 0\n stat_period_ms: 0\n }\n heapprofd_config {\n sampling_interval_bytes: 0\n all: false\n continuous_dump_config {\n dump_phase_ms: 0\n dump_interval_ms: 0\n }\n }\n legacy_config: \"\"\n }\n}\nduration_ms: 10000\nenable_extra_guardrails: false\nlockdown_mode: LOCKDOWN_UNCHANGED\nstatsd_metadata {\n triggering_alert_id: 0\n triggering_config_uid: 0\n triggering_config_id: 0\n}\nwrite_into_file: false\nfile_write_period_ms: 0\nmax_file_size_bytes: 0\nguardrail_overrides {\n max_upload_per_day_bytes: 0\n}\ndeferred_start: false",
"sched_duration_ns": 9452761359
}
}
diff --git a/test/trace_processor/track_event/experimental_slice_layout_depth.out b/test/trace_processor/track_event/experimental_slice_layout_depth.out
new file mode 100644
index 000000000..00f83ee87
--- /dev/null
+++ b/test/trace_processor/track_event/experimental_slice_layout_depth.out
@@ -0,0 +1,4 @@
+"layout_depth"
+0
+0
+0
diff --git a/test/trace_processor/track_event/experimental_slice_layout_depth.py b/test/trace_processor/track_event/experimental_slice_layout_depth.py
new file mode 100644
index 000000000..3baf368a4
--- /dev/null
+++ b/test/trace_processor/track_event/experimental_slice_layout_depth.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python3
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is intended to test the layout depth of async slices starting and
+# ending at the same time (see b/189222451).
+
+from os import sys
+
+import synth_common
+
+from synth_common import ms_to_ns
+trace = synth_common.create_trace()
+
+track1 = 1234
+track2 = 1235
+track3 = 1236
+
+trace.add_track_descriptor(track1)
+trace.add_track_descriptor(track2)
+trace.add_track_descriptor(track3)
+
+trace.add_track_event_slice(
+ "AsyncSlice", ts=ms_to_ns(0), dur=ms_to_ns(10), track=track1)
+
+trace.add_track_event_slice(
+ "AsyncSlice", ts=ms_to_ns(10), dur=ms_to_ns(10), track=track2)
+
+trace.add_track_event_slice(
+ "AsyncSlice", ts=ms_to_ns(20), dur=ms_to_ns(10), track=track3)
+
+sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/track_event/experimental_slice_layout_depth.sql b/test/trace_processor/track_event/experimental_slice_layout_depth.sql
new file mode 100644
index 000000000..b13dbe628
--- /dev/null
+++ b/test/trace_processor/track_event/experimental_slice_layout_depth.sql
@@ -0,0 +1,14 @@
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+select layout_depth from experimental_slice_layout
+where filter_track_ids = (select group_concat(track_id, ',') from slice); \ No newline at end of file
diff --git a/test/trace_processor/track_event/flow_events_proto_v1.textproto b/test/trace_processor/track_event/flow_events_proto_v1.textproto
index 19c12656a..1ed6906db 100644
--- a/test/trace_processor/track_event/flow_events_proto_v1.textproto
+++ b/test/trace_processor/track_event/flow_events_proto_v1.textproto
@@ -139,4 +139,4 @@ packet {
unscoped_id: 331
}
}
-} \ No newline at end of file
+}
diff --git a/test/trace_processor/track_event/flow_events_track_event.out b/test/trace_processor/track_event/flow_events_track_event.out
index 895f2a1c1..d44237e38 100644
--- a/test/trace_processor/track_event/flow_events_track_event.out
+++ b/test/trace_processor/track_event/flow_events_track_event.out
@@ -4,4 +4,5 @@
"FlowSlice1Start2Start","FlowSlice2End"
"FlowSlice3Begin","FlowSlice3End4Begin"
"FlowSlice3End4Begin","FlowSlice4Step"
-"FlowSlice4Step","FlowSlice4End"
+"FlowSlice4Step","FlowSlice4Step2_FlowIdOnAsyncEndEvent"
+"FlowSlice4Step2_FlowIdOnAsyncEndEvent","FlowSlice4End"
diff --git a/test/trace_processor/track_event/flow_events_track_event.textproto b/test/trace_processor/track_event/flow_events_track_event.textproto
index af20150fb..60d93360a 100644
--- a/test/trace_processor/track_event/flow_events_track_event.textproto
+++ b/test/trace_processor/track_event/flow_events_track_event.textproto
@@ -28,8 +28,8 @@ packet {
track_event {
name: "FlowSlice1Start"
categories: "test"
- track_uuid: 1,
- flow_ids: 1,
+ track_uuid: 1
+ flow_ids: 1
legacy_event {
duration_us: 10
phase: 88 # 'X'
@@ -42,8 +42,8 @@ packet {
track_event {
name: "FlowSlice1End"
categories: "test"
- track_uuid: 2,
- terminating_flow_ids: 1,
+ track_uuid: 2
+ terminating_flow_ids: 1
legacy_event {
duration_us: 10
phase: 88 # 'X'
@@ -56,9 +56,9 @@ packet {
track_event {
name: "FlowSlice1Start2Start"
categories: "test"
- track_uuid: 1,
- flow_ids: 1,
- flow_ids: 2,
+ track_uuid: 1
+ flow_ids: 1
+ flow_ids: 2
legacy_event {
duration_us: 10
phase: 88 # 'X'
@@ -71,8 +71,8 @@ packet {
track_event {
name: "FlowSlice1End"
categories: "test"
- track_uuid: 2,
- flow_ids: 1,
+ track_uuid: 2
+ flow_ids: 1
legacy_event {
duration_us: 10
phase: 88 # 'X'
@@ -86,8 +86,8 @@ packet {
track_event {
name: "FlowSlice3Begin"
categories: "test"
- track_uuid: 2,
- flow_ids: 3,
+ track_uuid: 2
+ flow_ids: 3
legacy_event {
phase: 73 # 'I'
}
@@ -99,8 +99,8 @@ packet {
track_event {
name: "FlowSlice2End"
categories: "test"
- track_uuid: 2,
- flow_ids: 2,
+ track_uuid: 2
+ flow_ids: 2
legacy_event {
duration_us: 10
phase: 88 # 'X'
@@ -121,9 +121,9 @@ packet {
track_event {
name: "FlowSlice3End4Begin"
categories: "test"
- track_uuid: 11,
- terminating_flow_ids: 3,
- flow_ids: 4,
+ track_uuid: 11
+ terminating_flow_ids: 3
+ flow_ids: 4
type: 1, # 'TYPE_SLICE_BEGIN'
}
}
@@ -133,8 +133,8 @@ packet {
track_event {
name: "FlowSlice4Step"
categories: "test"
- track_uuid: 11,
- flow_ids: 4,
+ track_uuid: 11
+ flow_ids: 4
type: 3, # 'TYPE_SLICE_INSTANT'
}
}
@@ -144,8 +144,50 @@ packet {
track_event {
name: "FlowSlice3End4Begin"
categories: "test"
- track_uuid: 11,
- type: 2, # 'TYPE_SLICE_END'
+ track_uuid: 11
+ type: 2 # 'TYPE_SLICE_END'
+ }
+}
+packet {
+ timestamp: 63000
+ trusted_packet_sequence_id: 1
+ track_event {
+ name: "FlowSlice4Step2_FlowIdOnAsyncEndEvent"
+ categories: "test"
+ track_uuid: 11
+ type: 1 # 'TYPE_SLICE_BEGIN'
+ }
+}
+packet {
+ timestamp: 64000
+ trusted_packet_sequence_id: 1
+ track_event {
+ name: "FlowSlice4Step2_FlowIdOnAsyncEndEvent"
+ categories: "test"
+ track_uuid: 11
+ flow_ids: 4
+ type: 2 # 'TYPE_SLICE_END'
+ }
+}
+packet {
+ timestamp: 65000
+ trusted_packet_sequence_id: 1
+ track_event {
+ name: "FlowSlice4Step2_FlowIdOnEndEvent"
+ categories: "test"
+ track_uuid: 2
+ type: 1 # 'TYPE_SLICE_BEGIN'
+ }
+}
+packet {
+ timestamp: 66000
+ trusted_packet_sequence_id: 1
+ track_event {
+ name: "FlowSlice4Step2_FlowIdOnEndEvent"
+ categories: "test"
+ track_uuid: 2
+ flow_ids: 4
+ type: 2 # 'TYPE_SLICE_END'
}
}
packet {
@@ -161,13 +203,13 @@ packet {
}
}
packet {
- timestamp: 65000
+ timestamp: 67000
trusted_packet_sequence_id: 1
track_event {
name: "FlowSlice4End"
categories: "test"
- track_uuid: 13,
- terminating_flow_ids: 4,
+ track_uuid: 13
+ terminating_flow_ids: 4
legacy_event {
phase: 105 # 'i'
instant_event_scope: 2 # SCOPE_PROCESS
diff --git a/test/trace_processor/track_event/index b/test/trace_processor/track_event/index
index d0881e0cf..d45510c8e 100644
--- a/test/trace_processor/track_event/index
+++ b/test/trace_processor/track_event/index
@@ -38,3 +38,9 @@ track_event_chrome_histogram_sample.textproto track_event_args.sql track_event_c
flow_events_track_event.textproto flow_events.sql flow_events_track_event.out
flow_events_proto_v2.textproto flow_events.sql flow_events_proto_v2.out
flow_events_proto_v1.textproto flow_events.sql flow_events_proto_v1.out
+
+# Async slices starting and ending at the same time
+experimental_slice_layout_depth.py experimental_slice_layout_depth.sql experimental_slice_layout_depth.out
+
+# Descriptor merging regression test (bug: b/197203390)
+../../data/trace_with_descriptor.pftrace merging_regression.sql merging_regression.out
diff --git a/test/trace_processor/track_event/merging_regression.out b/test/trace_processor/track_event/merging_regression.out
new file mode 100644
index 000000000..5158c9da4
--- /dev/null
+++ b/test/trace_processor/track_event/merging_regression.out
@@ -0,0 +1,11 @@
+"ts"
+605361018360000
+605361018360000
+605361028265000
+605361028265000
+605361028361000
+605361028878000
+605361033445000
+605361033445000
+605361034257000
+605361035040000
diff --git a/test/trace_processor/track_event/merging_regression.sql b/test/trace_processor/track_event/merging_regression.sql
new file mode 100644
index 000000000..270e2697a
--- /dev/null
+++ b/test/trace_processor/track_event/merging_regression.sql
@@ -0,0 +1,19 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+-- Actual query in this file does not matter: we only want to ensure that
+-- parsing of the trace succeeds.
+select ts from slice order by ts limit 10;
diff --git a/test/trace_processor/track_event/track_event_merged_debug_annotations_args.out b/test/trace_processor/track_event/track_event_merged_debug_annotations_args.out
index b0c0529df..8cecb1d91 100644
--- a/test/trace_processor/track_event/track_event_merged_debug_annotations_args.out
+++ b/test/trace_processor/track_event/track_event_merged_debug_annotations_args.out
@@ -22,6 +22,6 @@
"debug.debug2.key4","debug.debug2.key4",40,"[NULL]"
"debug.debug3","debug.debug3",32,"[NULL]"
"debug.debug4.key1","debug.debug4.key1",10,"[NULL]"
-"debug.debug4.key2[0]","debug.debug4.key2[0]",20,"[NULL]"
-"debug.debug4.key2[1]","debug.debug4.key2[1]",21,"[NULL]"
+"debug.debug4.key2","debug.debug4.key2[0]",20,"[NULL]"
+"debug.debug4.key2","debug.debug4.key2[1]",21,"[NULL]"
"legacy_event.passthrough_utid","legacy_event.passthrough_utid",1,"[NULL]"
diff --git a/test/trace_processor/track_event/track_event_typed_args.textproto b/test/trace_processor/track_event/track_event_typed_args.textproto
index 6ff29b14b..b2d9208bb 100644
--- a/test/trace_processor/track_event/track_event_typed_args.textproto
+++ b/test/trace_processor/track_event/track_event_typed_args.textproto
@@ -78,6 +78,17 @@ packet {
"should be absent from result"
[perfetto.protos.TestExtension.nested_message_extension_for_testing] {
child_field_for_testing: "nesting test"
+ debug_annotations {
+ name: "arg1"
+ string_value: "value"
+ }
+ debug_annotations {
+ name: "arg2"
+ dict_entries {
+ name: "key"
+ string_value: "value"
+ }
+ }
}
}
}
@@ -120,6 +131,13 @@ packet {
type: TYPE_STRING
label: LABEL_OPTIONAL
}
+ field {
+ name: "debug_annotations"
+ number: 99
+ type: TYPE_MESSAGE
+ label: LABEL_REPEATED
+ type_name: ".perfetto.protos.DebugAnnotation"
+ }
}
}
}
diff --git a/test/trace_processor/track_event/track_event_typed_args_args.out b/test/trace_processor/track_event/track_event_typed_args_args.out
index ac7d60868..fae18d723 100644
--- a/test/trace_processor/track_event/track_event_typed_args_args.out
+++ b/test/trace_processor/track_event/track_event_typed_args_args.out
@@ -13,6 +13,8 @@
"chrome_latency_info.trace_id","chrome_latency_info.trace_id",7,"[NULL]"
"int_extension_for_testing","int_extension_for_testing[0]",42,"[NULL]"
"int_extension_for_testing","int_extension_for_testing[1]",1337,"[NULL]"
+"nested_message_extension_for_testing.arg1","nested_message_extension_for_testing.arg1","[NULL]","value"
+"nested_message_extension_for_testing.arg2.key","nested_message_extension_for_testing.arg2.key","[NULL]","value"
"nested_message_extension_for_testing.child_field_for_testing","nested_message_extension_for_testing.child_field_for_testing","[NULL]","nesting test"
"string_extension_for_testing","string_extension_for_testing","[NULL]","an extension string!"
"chrome_app_state","chrome_app_state","[NULL]","APP_STATE_FOREGROUND"
diff --git a/test/trace_processor/translation/chrome_args.sql b/test/trace_processor/translation/chrome_args.sql
new file mode 100644
index 000000000..63c2492d0
--- /dev/null
+++ b/test/trace_processor/translation/chrome_args.sql
@@ -0,0 +1,16 @@
+--
+-- Copyright 2022 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+select flat_key, key, int_value, string_value from args order by arg_set_id, key asc;
diff --git a/test/trace_processor/translation/chrome_histogram.out b/test/trace_processor/translation/chrome_histogram.out
new file mode 100644
index 000000000..e0c4decb7
--- /dev/null
+++ b/test/trace_processor/translation/chrome_histogram.out
@@ -0,0 +1,10 @@
+"flat_key","key","int_value","string_value"
+"is_root_in_scope","is_root_in_scope",1,"[NULL]"
+"source","source","[NULL]","descriptor"
+"source_id","source_id",0,"[NULL]"
+"chrome_histogram_sample.name","chrome_histogram_sample.name","[NULL]","histogram_name1"
+"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",10,"[NULL]"
+"chrome_histogram_sample.sample","chrome_histogram_sample.sample",100,"[NULL]"
+"chrome_histogram_sample.name","chrome_histogram_sample.name","[NULL]","histogram_name2"
+"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",20,"[NULL]"
+"chrome_histogram_sample.name_hash","chrome_histogram_sample.name_hash",30,"[NULL]"
diff --git a/test/trace_processor/translation/chrome_histogram.textproto b/test/trace_processor/translation/chrome_histogram.textproto
new file mode 100644
index 000000000..fb6a04e01
--- /dev/null
+++ b/test/trace_processor/translation/chrome_histogram.textproto
@@ -0,0 +1,53 @@
+# Chrome histogram hashes translation rules
+packet {
+ translation_table {
+ chrome_histogram {
+ hash_to_name { key: 10 value: "histogram_name1" }
+ hash_to_name { key: 20 value: "histogram_name2" }
+ }
+ }
+}
+# Known histogram hash, should be translated to a name
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat1"
+ type: 3
+ name_iid: 1
+ chrome_histogram_sample {
+ name_hash: 10
+ sample: 100
+ }
+ }
+}
+# Another known hash, should be translated to a name
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat2"
+ type: 3
+ name_iid: 2
+ chrome_histogram_sample {
+ name_hash: 20
+ }
+ }
+}
+# Unknown hash, should not be translated to any name
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat3"
+ type: 3
+ name_iid: 3
+ chrome_histogram_sample {
+ name_hash: 30
+ }
+ }
+}
+
diff --git a/test/trace_processor/translation/chrome_performance_mark.out b/test/trace_processor/translation/chrome_performance_mark.out
new file mode 100644
index 000000000..0231cb71b
--- /dev/null
+++ b/test/trace_processor/translation/chrome_performance_mark.out
@@ -0,0 +1,8 @@
+"flat_key","key","int_value","string_value"
+"is_root_in_scope","is_root_in_scope",1,"[NULL]"
+"source","source","[NULL]","descriptor"
+"source_id","source_id",0,"[NULL]"
+"chrome_hashed_performance_mark.mark","chrome_hashed_performance_mark.mark","[NULL]","mark2"
+"chrome_hashed_performance_mark.mark_hash","chrome_hashed_performance_mark.mark_hash",20,"[NULL]"
+"chrome_hashed_performance_mark.site","chrome_hashed_performance_mark.site","[NULL]","site1"
+"chrome_hashed_performance_mark.site_hash","chrome_hashed_performance_mark.site_hash",10,"[NULL]"
diff --git a/test/trace_processor/translation/chrome_performance_mark.textproto b/test/trace_processor/translation/chrome_performance_mark.textproto
new file mode 100644
index 000000000..6e5234b8c
--- /dev/null
+++ b/test/trace_processor/translation/chrome_performance_mark.textproto
@@ -0,0 +1,23 @@
+# Chrome performance mark hashes translation rules
+packet {
+ translation_table {
+ chrome_performance_mark {
+ site_hash_to_name { key: 10 value: "site1" }
+ mark_hash_to_name { key: 20 value: "mark2" }
+ }
+ }
+}
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat1"
+ type: 3
+ name_iid: 1
+ [perfetto.protos.ChromeTrackEvent.chrome_hashed_performance_mark] {
+ site_hash: 10
+ mark_hash: 20
+ }
+ }
+}
diff --git a/test/trace_processor/translation/chrome_user_event.out b/test/trace_processor/translation/chrome_user_event.out
new file mode 100644
index 000000000..b092f7a28
--- /dev/null
+++ b/test/trace_processor/translation/chrome_user_event.out
@@ -0,0 +1,9 @@
+"flat_key","key","int_value","string_value"
+"is_root_in_scope","is_root_in_scope",1,"[NULL]"
+"source","source","[NULL]","descriptor"
+"source_id","source_id",0,"[NULL]"
+"chrome_user_event.action","chrome_user_event.action","[NULL]","action1"
+"chrome_user_event.action_hash","chrome_user_event.action_hash",10,"[NULL]"
+"chrome_user_event.action","chrome_user_event.action","[NULL]","action2"
+"chrome_user_event.action_hash","chrome_user_event.action_hash",20,"[NULL]"
+"chrome_user_event.action_hash","chrome_user_event.action_hash",30,"[NULL]"
diff --git a/test/trace_processor/translation/chrome_user_event.textproto b/test/trace_processor/translation/chrome_user_event.textproto
new file mode 100644
index 000000000..9dd30c149
--- /dev/null
+++ b/test/trace_processor/translation/chrome_user_event.textproto
@@ -0,0 +1,52 @@
+# Chrome histogram hashes translation rules
+packet {
+ translation_table {
+ chrome_user_event {
+ action_hash_to_name { key: 10 value: "action1" }
+ action_hash_to_name { key: 20 value: "action2" }
+ }
+ }
+}
+# Known action hash, should be translated to a name
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat1"
+ type: 3
+ name_iid: 1
+ chrome_user_event {
+ action_hash: 10
+ }
+ }
+}
+# Another known hash, should be translated to a name
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat2"
+ type: 3
+ name_iid: 2
+ chrome_user_event {
+ action_hash: 20
+ }
+ }
+}
+# Unknown hash, should not be translated to any name
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_event {
+ categories: "cat3"
+ type: 3
+ name_iid: 3
+ chrome_user_event {
+ action_hash: 30
+ }
+ }
+}
+
diff --git a/test/trace_processor/translation/index b/test/trace_processor/translation/index
new file mode 100644
index 000000000..2e4696c7e
--- /dev/null
+++ b/test/trace_processor/translation/index
@@ -0,0 +1,4 @@
+chrome_histogram.textproto chrome_args.sql chrome_histogram.out
+chrome_user_event.textproto chrome_args.sql chrome_user_event.out
+chrome_performance_mark.textproto chrome_args.sql chrome_performance_mark.out
+slice_name.textproto slice_name.sql slice_name.out
diff --git a/test/trace_processor/translation/slice_name.out b/test/trace_processor/translation/slice_name.out
new file mode 100644
index 000000000..32dedecce
--- /dev/null
+++ b/test/trace_processor/translation/slice_name.out
@@ -0,0 +1,5 @@
+"name"
+"mapped_name1"
+"mapped_name2"
+"raw_name3"
+"slice_begin"
diff --git a/test/trace_processor/translation/slice_name.sql b/test/trace_processor/translation/slice_name.sql
new file mode 100644
index 000000000..a3011a825
--- /dev/null
+++ b/test/trace_processor/translation/slice_name.sql
@@ -0,0 +1 @@
+SELECT name FROM slice ORDER BY name;
diff --git a/test/trace_processor/translation/slice_name.textproto b/test/trace_processor/translation/slice_name.textproto
new file mode 100644
index 000000000..f9927b0ec
--- /dev/null
+++ b/test/trace_processor/translation/slice_name.textproto
@@ -0,0 +1,72 @@
+packet {
+ translation_table {
+ slice_name {
+ raw_to_deobfuscated_name { key: "raw_name1" value: "mapped_name1" }
+ raw_to_deobfuscated_name { key: "raw_name2" value: "mapped_name2" }
+ raw_to_deobfuscated_name { key: "raw_slice_begin" value: "slice_begin" }
+ }
+ }
+}
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 1000
+ track_event {
+ categories: "cat"
+ name: "raw_name1"
+ type: 3
+ }
+}
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 2000
+ track_event {
+ categories: "cat"
+ name: "raw_name2"
+ type: 3
+ }
+}
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 3000
+ track_event {
+ categories: "cat"
+ name: "raw_name3"
+ type: 3
+ }
+}
+# Track for slice begin/end events.
+packet {
+ timestamp: 4000
+ trusted_packet_sequence_id: 2
+ track_descriptor {
+ uuid: 12345
+ thread {
+ pid: 123
+ tid: 345
+ }
+ parent_uuid: 0
+ chrome_thread {
+ thread_type: THREAD_POOL_FG_WORKER
+ }
+ }
+}
+# Slice begin/end events
+packet {
+ trusted_packet_sequence_id: 2
+ timestamp: 5000
+ track_event {
+ track_uuid: 12345
+ categories: "cat"
+ name: "raw_slice_begin"
+ type: 1
+ }
+}
+packet {
+ trusted_packet_sequence_id: 2
+ timestamp: 6000
+ track_event {
+ track_uuid: 12345
+ categories: "cat"
+ type: 2
+ }
+}
diff --git a/test/traced_integrationtest.cc b/test/traced_integrationtest.cc
new file mode 100644
index 000000000..de71c270f
--- /dev/null
+++ b/test/traced_integrationtest.cc
@@ -0,0 +1,455 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "perfetto/base/build_config.h"
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/pipe.h"
+#include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/temp_file.h"
+#include "perfetto/ext/base/utils.h"
+#include "perfetto/ext/tracing/core/commit_data_request.h"
+#include "perfetto/ext/tracing/core/trace_packet.h"
+#include "perfetto/ext/tracing/core/tracing_service.h"
+#include "perfetto/protozero/scattered_heap_buffer.h"
+#include "perfetto/tracing/core/tracing_service_state.h"
+#include "src/base/test/test_task_runner.h"
+#include "src/base/test/utils.h"
+#include "src/protozero/filtering/filter_bytecode_generator.h"
+#include "test/gtest_and_gmock.h"
+#include "test/test_helper.h"
+
+#include "protos/perfetto/config/test_config.gen.h"
+#include "protos/perfetto/config/trace_config.gen.h"
+#include "protos/perfetto/trace/perfetto/tracing_service_event.gen.h"
+#include "protos/perfetto/trace/test_event.gen.h"
+#include "protos/perfetto/trace/trace.gen.h"
+#include "protos/perfetto/trace/trace_packet.gen.h"
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+
+namespace {
+
+using ::testing::ContainsRegex;
+using ::testing::Each;
+using ::testing::ElementsAreArray;
+using ::testing::HasSubstr;
+using ::testing::Property;
+using ::testing::SizeIs;
+
+} // namespace
+
+TEST(PerfettoTracedIntegrationTest, TestFakeProducer) {
+ base::TestTaskRunner task_runner;
+
+ TestHelper helper(&task_runner);
+ helper.StartServiceIfRequired();
+ helper.ConnectFakeProducer();
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+
+ TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(1024);
+ trace_config.set_duration_ms(200);
+
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("android.perfetto.FakeProducer");
+ ds_config->set_target_buffer(0);
+
+ static constexpr size_t kNumPackets = 11;
+ static constexpr uint32_t kRandomSeed = 42;
+ static constexpr uint32_t kMsgSize = 1024;
+ ds_config->mutable_for_testing()->set_seed(kRandomSeed);
+ ds_config->mutable_for_testing()->set_message_count(kNumPackets);
+ ds_config->mutable_for_testing()->set_message_size(kMsgSize);
+ ds_config->mutable_for_testing()->set_send_batch_on_register(true);
+
+ helper.StartTracing(trace_config);
+ helper.WaitForTracingDisabled();
+
+ helper.ReadData();
+ helper.WaitForReadData();
+
+ const auto& packets = helper.trace();
+ ASSERT_EQ(packets.size(), kNumPackets);
+
+ std::minstd_rand0 rnd_engine(kRandomSeed);
+ for (const auto& packet : packets) {
+ ASSERT_TRUE(packet.has_for_testing());
+ ASSERT_EQ(packet.for_testing().seq_value(), rnd_engine());
+ }
+}
+
+TEST(PerfettoTracedIntegrationTest, VeryLargePackets) {
+ base::TestTaskRunner task_runner;
+
+ TestHelper helper(&task_runner);
+ helper.StartServiceIfRequired();
+ helper.ConnectFakeProducer();
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+
+ TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(4096 * 10);
+ trace_config.set_duration_ms(500);
+
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("android.perfetto.FakeProducer");
+ ds_config->set_target_buffer(0);
+
+ static constexpr size_t kNumPackets = 7;
+ static constexpr uint32_t kRandomSeed = 42;
+ static constexpr uint32_t kMsgSize = 1024 * 1024 - 42;
+ ds_config->mutable_for_testing()->set_seed(kRandomSeed);
+ ds_config->mutable_for_testing()->set_message_count(kNumPackets);
+ ds_config->mutable_for_testing()->set_message_size(kMsgSize);
+ ds_config->mutable_for_testing()->set_send_batch_on_register(true);
+
+ helper.StartTracing(trace_config);
+ helper.WaitForTracingDisabled();
+
+ helper.ReadData();
+ helper.WaitForReadData(/* read_count */ 0, /* timeout_ms */ 10000);
+
+ const auto& packets = helper.trace();
+ ASSERT_EQ(packets.size(), kNumPackets);
+
+ std::minstd_rand0 rnd_engine(kRandomSeed);
+ for (const auto& packet : packets) {
+ ASSERT_TRUE(packet.has_for_testing());
+ ASSERT_EQ(packet.for_testing().seq_value(), rnd_engine());
+ size_t msg_size = packet.for_testing().str().size();
+ ASSERT_EQ(kMsgSize, msg_size);
+ for (size_t i = 0; i < msg_size; i++)
+ ASSERT_EQ(i < msg_size - 1 ? '.' : 0, packet.for_testing().str()[i]);
+ }
+}
+
+// This is a regression test see b/169051440 for context.
+//
+// In this test we ensure that traced will not crash if a Producer stops
+// responding or draining the socket (i.e. after we fill up the IPC buffer
+// traced doesn't block on trying to write to the IPC buffer and watchdog
+// doesn't kill it).
+TEST(PerfettoTracedIntegrationTest, UnresponsiveProducer) {
+ base::TestTaskRunner task_runner;
+
+ TestHelper helper(&task_runner);
+ helper.StartServiceIfRequired();
+ auto* producer = helper.ConnectFakeProducer();
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+
+ TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(4096 * 10);
+ trace_config.set_duration_ms(100);
+ trace_config.set_flush_timeout_ms(1);
+ trace_config.set_data_source_stop_timeout_ms(1);
+
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("android.perfetto.FakeProducer");
+
+ static constexpr size_t kNumPackets = 1;
+ static constexpr uint32_t kRandomSeed = 42;
+ static constexpr uint32_t kMsgSize = 1024 * 1024 - 42;
+ ds_config->mutable_for_testing()->set_seed(kRandomSeed);
+ ds_config->mutable_for_testing()->set_message_count(kNumPackets);
+ ds_config->mutable_for_testing()->set_message_size(kMsgSize);
+ ds_config->mutable_for_testing()->set_send_batch_on_register(true);
+
+ // This string is just used to make the StartDataSource IPC larger.
+ ds_config->set_legacy_config(std::string(8192, '.'));
+ ds_config->set_target_buffer(0);
+
+ // Run one legit trace, this ensures that the producer above is
+ // valid and correct and mirrors real life producers.
+ helper.StartTracing(trace_config);
+ helper.WaitForProducerEnabled();
+ helper.WaitForTracingDisabled();
+
+ helper.ReadData();
+ helper.WaitForReadData(/* read_count */ 0, /* timeout_ms */ 10000);
+
+ const auto& packets = helper.trace();
+ ASSERT_EQ(packets.size(), 1u);
+ ASSERT_TRUE(packets[0].has_for_testing());
+ ASSERT_FALSE(packets[0].for_testing().str().empty());
+ helper.FreeBuffers();
+
+ // Switch the producer to ignoring the IPC socket. On a pixel 4 it took 13
+ // traces to fill up the IPC buffer and cause traced to block (and eventually
+ // watchdog to kill it).
+ helper.producer_thread()->get()->RemoveFileDescriptorWatch(
+ producer->unix_socket_fd());
+
+ trace_config.set_duration_ms(1);
+ for (uint32_t i = 0u; i < 15u; i++) {
+ helper.StartTracing(trace_config, base::ScopedFile());
+ helper.WaitForTracingDisabled(/* timeout_ms = */ 20000);
+ helper.FreeBuffers();
+ }
+ // We need to readd the FileDescriptor (otherwise when the UnixSocket attempts
+ // to remove it a the FakeProducer is destroyed will hit a CHECK failure.
+ helper.producer_thread()->get()->AddFileDescriptorWatch(
+ producer->unix_socket_fd(), []() {});
+}
+
+TEST(PerfettoTracedIntegrationTest, DetachAndReattach) {
+ base::TestTaskRunner task_runner;
+
+ TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(1024);
+ trace_config.set_duration_ms(10000); // Max timeout, session is ended before.
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("android.perfetto.FakeProducer");
+ static constexpr size_t kNumPackets = 11;
+ ds_config->mutable_for_testing()->set_message_count(kNumPackets);
+ ds_config->mutable_for_testing()->set_message_size(32);
+
+ // Enable tracing and detach as soon as it gets started.
+ TestHelper helper(&task_runner);
+ helper.StartServiceIfRequired();
+ auto* fake_producer = helper.ConnectFakeProducer();
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+ helper.StartTracing(trace_config);
+
+ // Detach.
+ helper.DetachConsumer("key");
+
+ // Write data while detached.
+ helper.WaitForProducerEnabled();
+ auto on_data_written = task_runner.CreateCheckpoint("data_written");
+ fake_producer->ProduceEventBatch(helper.WrapTask(on_data_written));
+ task_runner.RunUntilCheckpoint("data_written");
+
+ // Then reattach the consumer.
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+ helper.AttachConsumer("key");
+
+ helper.DisableTracing();
+ helper.WaitForTracingDisabled();
+
+ helper.ReadData();
+ helper.WaitForReadData();
+ const auto& packets = helper.trace();
+ ASSERT_EQ(packets.size(), kNumPackets);
+}
+
+// Tests that a detached trace session is automatically cleaned up if the
+// consumer doesn't re-attach before its expiration time.
+TEST(PerfettoTracedIntegrationTest, ReattachFailsAfterTimeout) {
+ base::TestTaskRunner task_runner;
+
+ TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(1024);
+ trace_config.set_duration_ms(250);
+ trace_config.set_write_into_file(true);
+ trace_config.set_file_write_period_ms(100000);
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("android.perfetto.FakeProducer");
+ ds_config->mutable_for_testing()->set_message_count(1);
+ ds_config->mutable_for_testing()->set_message_size(32);
+ ds_config->mutable_for_testing()->set_send_batch_on_register(true);
+
+ // Enable tracing and detach as soon as it gets started.
+ TestHelper helper(&task_runner);
+ helper.StartServiceIfRequired();
+ helper.ConnectFakeProducer();
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+
+ auto pipe_pair = base::Pipe::Create();
+ helper.StartTracing(trace_config, std::move(pipe_pair.wr));
+
+ // Detach.
+ helper.DetachConsumer("key");
+
+ // Use the file EOF (write end closed) as a way to detect when the trace
+ // session is ended.
+ char buf[1024];
+ while (PERFETTO_EINTR(read(*pipe_pair.rd, buf, sizeof(buf))) > 0) {
+ }
+
+ // Give some margin for the tracing service to destroy the session.
+ usleep(250000);
+
+ // Reconnect and find out that it's too late and the session is gone.
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+ EXPECT_FALSE(helper.AttachConsumer("key"));
+}
+
+TEST(PerfettoTracedIntegrationTest, TestProducerProvidedSMB) {
+ base::TestTaskRunner task_runner;
+
+ TestHelper helper(&task_runner);
+ helper.CreateProducerProvidedSmb();
+
+ protos::gen::TestConfig test_config;
+ test_config.set_seed(42);
+ test_config.set_message_count(1);
+ test_config.set_message_size(1024);
+ test_config.set_send_batch_on_register(true);
+
+ // Write a first batch before connection.
+ helper.ProduceStartupEventBatch(test_config);
+
+ helper.StartServiceIfRequired();
+ helper.ConnectFakeProducer();
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+
+ TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(1024);
+ trace_config.set_duration_ms(200);
+
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("android.perfetto.FakeProducer");
+ ds_config->set_target_buffer(0);
+ *ds_config->mutable_for_testing() = test_config;
+
+ // The data source is configured to emit another batch when it is started via
+ // send_batch_on_register in the TestConfig.
+ helper.StartTracing(trace_config);
+ helper.WaitForTracingDisabled();
+
+ EXPECT_TRUE(helper.IsShmemProvidedByProducer());
+
+ helper.ReadData();
+ helper.WaitForReadData();
+
+ const auto& packets = helper.trace();
+ // We should have produced two batches, one before the producer connected and
+ // another one when the data source was started.
+ ASSERT_EQ(packets.size(), 2u);
+ ASSERT_TRUE(packets[0].has_for_testing());
+ ASSERT_TRUE(packets[1].has_for_testing());
+}
+
+// Regression test for b/153142114.
+TEST(PerfettoTracedIntegrationTest, QueryServiceStateLargeResponse) {
+ base::TestTaskRunner task_runner;
+
+ TestHelper helper(&task_runner);
+ helper.StartServiceIfRequired();
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+
+ FakeProducer* producer = helper.ConnectFakeProducer();
+
+ // Register 5 data sources with very large descriptors. Each descriptor will
+ // max out the IPC message size, so that the service has no other choice
+ // than chunking them.
+ std::map<std::string, std::string> ds_expected;
+ for (int i = 0; i < 5; i++) {
+ DataSourceDescriptor dsd;
+ std::string name = "big_ds_" + std::to_string(i);
+ dsd.set_name(name);
+ std::string descriptor(ipc::kIPCBufferSize - 64,
+ static_cast<char>((' ' + i) % 64));
+ dsd.set_track_event_descriptor_raw(descriptor);
+ ds_expected[name] = std::move(descriptor);
+ producer->RegisterDataSource(dsd);
+ }
+
+ // Linearize the producer with the service. We need to make sure that all the
+ // RegisterDataSource() calls above have been seen by the service before
+ // continuing.
+ helper.SyncAndWaitProducer();
+
+ // Now invoke QueryServiceState() and wait for the reply. The service will
+ // send 6 (1 + 5) IPCs which will be merged together in
+ // producer_ipc_client_impl.cc.
+ auto svc_state = helper.QueryServiceStateAndWait();
+
+ ASSERT_GE(svc_state.producers().size(), 1u);
+
+ std::map<std::string, std::string> ds_found;
+ for (const auto& ds : svc_state.data_sources()) {
+ if (!base::StartsWith(ds.ds_descriptor().name(), "big_ds_"))
+ continue;
+ ds_found[ds.ds_descriptor().name()] =
+ ds.ds_descriptor().track_event_descriptor_raw();
+ }
+ EXPECT_THAT(ds_found, ElementsAreArray(ds_expected));
+}
+
+// Regression test for b/195065199. Check that trace filtering works when a
+// packet size exceeds the IPC limit. This tests that the tracing service, when
+// reassembling packets after filtering, doesn't "overglue" them. They still
+// need to be slice-able to fit into the ReadBuffers ipc.
+TEST(PerfettoTracedIntegrationTest, TraceFilterLargePackets) {
+ base::TestTaskRunner task_runner;
+ TestHelper helper(&task_runner);
+
+ helper.StartServiceIfRequired();
+ helper.ConnectFakeProducer();
+ helper.ConnectConsumer();
+ helper.WaitForConsumerConnect();
+
+ TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(1024 * 16);
+ trace_config.set_duration_ms(500);
+ auto* prod_config = trace_config.add_producers();
+ prod_config->set_producer_name("android.perfetto.FakeProducer");
+ prod_config->set_shm_size_kb(1024 * 16);
+ prod_config->set_page_size_kb(32);
+
+ static constexpr size_t kNumPackets = 3;
+ static constexpr uint32_t kRandomSeed = 42;
+ static constexpr uint32_t kMsgSize = 8 * ipc::kIPCBufferSize;
+ auto* ds_config = trace_config.add_data_sources()->mutable_config();
+ ds_config->set_name("android.perfetto.FakeProducer");
+ auto* test_config = ds_config->mutable_for_testing();
+ test_config->set_seed(kRandomSeed);
+ test_config->set_message_count(kNumPackets);
+ test_config->set_message_size(kMsgSize);
+ test_config->set_send_batch_on_register(true);
+
+ protozero::FilterBytecodeGenerator filt;
+ // Message 0: root Trace proto.
+ filt.AddNestedField(1 /* root trace.packet*/, 1);
+ filt.EndMessage();
+
+ // Message 1: TracePacket proto. Allow all fields.
+ filt.AddSimpleFieldRange(1, 1000);
+ filt.EndMessage();
+
+ trace_config.mutable_trace_filter()->set_bytecode(filt.Serialize());
+
+ // The data source is configured to emit another batch when it is started via
+ // send_batch_on_register in the TestConfig.
+ helper.StartTracing(trace_config);
+ helper.WaitForTracingDisabled();
+
+ helper.ReadData();
+ helper.WaitForReadData(/* read_count */ 0, /* timeout_ms */ 10000);
+
+ const std::vector<protos::gen::TracePacket>& packets = helper.trace();
+ EXPECT_EQ(packets.size(), kNumPackets);
+ EXPECT_THAT(packets,
+ Each(Property(&protos::gen::TracePacket::has_for_testing, true)));
+ EXPECT_THAT(
+ packets,
+ Each(Property(&protos::gen::TracePacket::for_testing,
+ Property(&protos::gen::TestEvent::str, SizeIs(kMsgSize)))));
+}
+
+} // namespace perfetto
diff --git a/tools/BUILD.gn b/tools/BUILD.gn
index 772f6a239..2328a1618 100644
--- a/tools/BUILD.gn
+++ b/tools/BUILD.gn
@@ -25,6 +25,7 @@ group("tools") {
"compact_reencode",
"ftrace_proto_gen",
"proto_filter",
+ "proto_merger",
"protoprofile",
]
if (is_linux || is_android) {
@@ -36,12 +37,6 @@ group("tools") {
"skippy",
]
}
- if (enable_perfetto_tools_trace_to_text) {
- deps += [
- "trace_to_text",
- "trace_to_text:trace_to_text_lite",
- ]
- }
}
if (is_linux && enable_perfetto_heapprofd) {
diff --git a/tools/add_test_trace.sh b/tools/add_test_trace.sh
deleted file mode 100755
index 1eea75973..000000000
--- a/tools/add_test_trace.sh
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/bin/bash
-# Copyright (C) 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -e
-
-echo ""
-echo "Downloading latest copy of test data"
-echo ""
-LATEST_ZIP="$(cat tools/install-build-deps | grep -o 'https://.*/perfetto/test-data-.*.zip')"
-curl -o /tmp/latest-test-data.zip $LATEST_ZIP
-
-echo ""
-echo "Extracting test data to temp folder"
-echo ""
-rm -rf /tmp/latest-test-data 2>/dev/null
-unzip /tmp/latest-test-data.zip -d /tmp/latest-test-data
-
-echo ""
-echo "Copying trace to temp folder"
-echo ""
-cp $1 /tmp/latest-test-data
-
-echo ""
-echo "Zipping file back up"
-echo ""
-NEW_TEST_DATA="test-data-$(date +%Y%m%d-%H%M%S).zip"
-CWD="$(pwd)"
-cd /tmp/latest-test-data
-zip -r /tmp/$NEW_TEST_DATA *
-cd $CWD
-
-echo ""
-echo "Uploading file to Google Cloud"
-echo ""
-gsutil cp /tmp/$NEW_TEST_DATA gs://perfetto/$NEW_TEST_DATA
-
-echo ""
-echo "Setting file to world readable"
-echo ""
-gsutil acl ch -u AllUsers:R gs://perfetto/$NEW_TEST_DATA
-
-echo ""
-echo "SHA-256 of file $NEW_TEST_DATA is"
-NEW_SHA=$(shasum -a 256 /tmp/$NEW_TEST_DATA | cut -c1-64)
-echo $NEW_SHA
-
-echo ""
-echo "Cleaning up leftover files"
-echo ""
-rm -r /tmp/latest-test-data
-rm /tmp/latest-test-data.zip
-rm /tmp/$NEW_TEST_DATA
-
-echo ""
-echo "Updating tools/install-build-deps"
-echo ""
-
-OLD_SHA=$(cat tools/install-build-deps | grep '/test-data-.*.zip' -A1 | tail -n1 | egrep -o '[a-f0-9]+')
-
-# Cannot easily use sed -i, it has different syntax on Linux vs Mac.
-cat tools/install-build-deps \
- | sed -e "s|/test-data-.*.zip|/$NEW_TEST_DATA|g" \
- | sed -e "s|$OLD_SHA|$NEW_SHA|g" \
- > tools/install-build-deps.tmp
-
-mv -f tools/install-build-deps.tmp tools/install-build-deps
-chmod 755 tools/install-build-deps
-
-echo "All done!"
diff --git a/tools/add_tp_diff_test.py b/tools/add_tp_diff_test.py
index 83ce9d082..026598825 100755
--- a/tools/add_tp_diff_test.py
+++ b/tools/add_tp_diff_test.py
@@ -13,7 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import argparse
import os
import pathlib
import sys
@@ -83,8 +82,8 @@ def main():
print()
trace_file = ''
if trace_type == 'proto':
- print('Proto traces should be added to the test-data zip '
- 'using the tools/add_test_trace.sh')
+ print('Proto traces should be added to the test_data GCS bucket '
+ 'using tools/test_data upload')
stdout_write('Provide the name of the trace (including any '
'extension) relative to test/data: ')
@@ -127,18 +126,22 @@ def main():
return 1
print()
- print('Provide the path to the SQL file relative to the chosen folder {}'
- .format(chosen_folder_path_rel_root))
+ print(
+ 'Provide either the name of a built-in metric OR path to the file (with '
+ 'extension .sql) relative to the chosen folder {}'.format(
+ chosen_folder_path_rel_root))
stdout_write(
'If the file does not already exist, an empty file will be created: ')
- sql_file = sys.stdin.readline().rstrip()
- sql_path = os.path.abspath(os.path.join(chosen_folder_path, sql_file))
- create_if_not_exists(sql_path)
+ sql_file_or_metric = sys.stdin.readline().rstrip()
+ if sql_file_or_metric.endswith('.sql'):
+ sql_path = os.path.abspath(
+ os.path.join(chosen_folder_path, sql_file_or_metric))
+ create_if_not_exists(sql_path)
default_out_file = '{}_{}.out'.format(
pathlib.Path(trace_file).stem,
- pathlib.Path(sql_file).stem)
+ pathlib.Path(sql_file_or_metric).stem)
print()
print('Provide the name of the output file (or leave empty '
@@ -155,7 +158,8 @@ def main():
print()
print('Appending test to index file')
with open(os.path.join(chosen_folder_path, 'index'), 'a') as index_file:
- index_file.write('{} {} {}\n'.format(trace_file, sql_file, out_file))
+ index_file.write('{} {} {}\n'.format(trace_file, sql_file_or_metric,
+ out_file))
return 0
diff --git a/tools/busy_threads/busy_threads.cc b/tools/busy_threads/busy_threads.cc
index 56a80e242..7d745ac55 100644
--- a/tools/busy_threads/busy_threads.cc
+++ b/tools/busy_threads/busy_threads.cc
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-#include <inttypes.h>
#include <stdint.h>
#include <unistd.h>
+#include <cinttypes>
#include <thread>
#include "perfetto/base/logging.h"
@@ -25,6 +25,7 @@
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/getopt.h"
#include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/string_utils.h"
#define PERFETTO_HAVE_PTHREADS \
(PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
@@ -43,10 +44,9 @@ namespace {
void SetRandomThreadName(uint32_t thread_name_count) {
#if PERFETTO_HAVE_PTHREADS
- char name[16] = {};
- snprintf(name, sizeof(name), "busy-%" PRIu32,
- static_cast<uint32_t>(rand()) % thread_name_count);
- pthread_setname_np(pthread_self(), name);
+ base::StackString<16> name("busy-%" PRIu32,
+ static_cast<uint32_t>(rand()) % thread_name_count);
+ pthread_setname_np(pthread_self(), name.c_str());
#endif
}
diff --git a/tools/check_include_violations b/tools/check_include_violations
index d86931b71..7402a4d69 100755
--- a/tools/check_include_violations
+++ b/tools/check_include_violations
@@ -36,8 +36,8 @@ def main():
include_root = os.path.join(ROOT_DIR, 'include')
for root, _, files in os.walk(include_root):
for fname in files:
- fpath = os.path.join(root, fname)
- rel_path = os.path.relpath(fpath, ROOT_DIR)
+ fpath = os.path.join(root, fname).replace('\\', '/') # For Windows.
+ rel_path = os.path.relpath(fpath, ROOT_DIR).replace('\\', '/')
if not os.path.isfile(fpath):
continue
if fpath.endswith('.cc'):
diff --git a/tools/check_proto_comments b/tools/check_proto_comments
index 6e7392f78..74b584b8e 100755
--- a/tools/check_proto_comments
+++ b/tools/check_proto_comments
@@ -35,7 +35,7 @@ def main():
continue
if not fpath.endswith('.proto'):
continue
- with open(fpath) as f:
+ with open(fpath, encoding='UTF-8') as f:
lines = f.readlines()
for line in lines:
comm = line.find('//')
diff --git a/tools/check_sql_metrics.py b/tools/check_sql_metrics.py
index 2fe57df11..b45edf8a1 100755
--- a/tools/check_sql_metrics.py
+++ b/tools/check_sql_metrics.py
@@ -31,6 +31,7 @@ def check(path):
with open(path) as f:
lines = [l.strip() for l in f.readlines()]
+ # Check that CREATE VIEW/TABLE has a matching DROP VIEW/TABLE before it.
errors = 0
d_type, d_name = None, None
for line in lines:
@@ -43,15 +44,30 @@ def check(path):
continue
type, name = m.group(1), m.group(2)
if type != d_type or name != d_name:
- sys.stderr.write(('%s:\n "%s" vs %s %s\n') % (path, line, d_type, d_name))
+ sys.stderr.write(
+ ('Missing DROP %s before CREATE %s\n') % (d_type, d_type))
+ sys.stderr.write(('%s:\n"%s" vs %s %s\n') % (path, line, d_type, d_name))
errors += 1
d_type, d_name = None, None
+
+ # Ban the use of LIKE in non-comment lines.
+ for line in lines:
+ if line.startswith('--'):
+ continue
+
+ if 'like' in line.casefold():
+ sys.stderr.write(
+ 'LIKE is banned in trace processor metrics. Prefer GLOB instead.\n')
+ sys.stderr.write('Offending file: %s\n' % path)
+ errors += 1
+
return errors
def main():
errors = 0
- metrics_sources = os.path.join(ROOT_DIR, 'src', 'trace_processor', 'metrics')
+ metrics_sources = os.path.join(ROOT_DIR, 'src', 'trace_processor', 'metrics',
+ 'sql')
for root, _, files in os.walk(metrics_sources, topdown=True):
for f in files:
path = os.path.join(root, f)
diff --git a/tools/compact_reencode/main.cc b/tools/compact_reencode/main.cc
index 19d4c2201..df662acdf 100644
--- a/tools/compact_reencode/main.cc
+++ b/tools/compact_reencode/main.cc
@@ -79,11 +79,12 @@ void ReEncodeBundle(protos::pbzero::TracePacket* packet_out,
if (bundle.has_cpu())
bundle_out->set_cpu(bundle.cpu());
- protozero::PackedVarInt switch_timestamp;
- protozero::PackedVarInt switch_prev_state;
- protozero::PackedVarInt switch_next_pid;
- protozero::PackedVarInt switch_next_prio;
- protozero::PackedVarInt switch_next_comm_index;
+ using protozero::PackedVarInt;
+ std::unique_ptr<PackedVarInt> switch_timestamp(new PackedVarInt());
+ std::unique_ptr<PackedVarInt> switch_prev_state(new PackedVarInt());
+ std::unique_ptr<PackedVarInt> switch_next_pid(new PackedVarInt());
+ std::unique_ptr<PackedVarInt> switch_next_prio(new PackedVarInt());
+ std::unique_ptr<PackedVarInt> switch_next_comm_index(new PackedVarInt());
uint64_t last_switch_timestamp = 0;
@@ -99,11 +100,11 @@ void ReEncodeBundle(protos::pbzero::TracePacket* packet_out,
};
// sched_waking pieces
- protozero::PackedVarInt waking_timestamp;
- protozero::PackedVarInt waking_pid;
- protozero::PackedVarInt waking_target_cpu;
- protozero::PackedVarInt waking_prio;
- protozero::PackedVarInt waking_comm_index;
+ std::unique_ptr<PackedVarInt> waking_timestamp(new PackedVarInt());
+ std::unique_ptr<PackedVarInt> waking_pid(new PackedVarInt());
+ std::unique_ptr<PackedVarInt> waking_target_cpu(new PackedVarInt());
+ std::unique_ptr<PackedVarInt> waking_prio(new PackedVarInt());
+ std::unique_ptr<PackedVarInt> waking_comm_index(new PackedVarInt());
uint64_t last_waking_timestamp = 0;
@@ -112,31 +113,31 @@ void ReEncodeBundle(protos::pbzero::TracePacket* packet_out,
if (!event.has_sched_switch() && !event.has_sched_waking()) {
CopyField(bundle_out, event_it.field());
} else if (event.has_sched_switch()) {
- switch_timestamp.Append(event.timestamp() - last_switch_timestamp);
+ switch_timestamp->Append(event.timestamp() - last_switch_timestamp);
last_switch_timestamp = event.timestamp();
protos::pbzero::SchedSwitchFtraceEvent::Decoder sswitch(
event.sched_switch());
auto iid = intern(sswitch.next_comm().ToStdString());
- switch_next_comm_index.Append(iid);
+ switch_next_comm_index->Append(iid);
- switch_next_pid.Append(sswitch.next_pid());
- switch_next_prio.Append(sswitch.next_prio());
- switch_prev_state.Append(sswitch.prev_state());
+ switch_next_pid->Append(sswitch.next_pid());
+ switch_next_prio->Append(sswitch.next_prio());
+ switch_prev_state->Append(sswitch.prev_state());
} else {
- waking_timestamp.Append(event.timestamp() - last_waking_timestamp);
+ waking_timestamp->Append(event.timestamp() - last_waking_timestamp);
last_waking_timestamp = event.timestamp();
protos::pbzero::SchedWakingFtraceEvent::Decoder swaking(
event.sched_waking());
auto iid = intern(swaking.comm().ToStdString());
- waking_comm_index.Append(iid);
+ waking_comm_index->Append(iid);
- waking_pid.Append(swaking.pid());
- waking_target_cpu.Append(swaking.target_cpu());
- waking_prio.Append(swaking.prio());
+ waking_pid->Append(swaking.pid());
+ waking_target_cpu->Append(swaking.target_cpu());
+ waking_prio->Append(swaking.prio());
}
}
@@ -145,17 +146,17 @@ void ReEncodeBundle(protos::pbzero::TracePacket* packet_out,
for (const auto& s : string_table)
compact_sched->add_intern_table(s.data(), s.size());
- compact_sched->set_switch_timestamp(switch_timestamp);
- compact_sched->set_switch_next_comm_index(switch_next_comm_index);
- compact_sched->set_switch_next_pid(switch_next_pid);
- compact_sched->set_switch_next_prio(switch_next_prio);
- compact_sched->set_switch_prev_state(switch_prev_state);
-
- compact_sched->set_waking_timestamp(waking_timestamp);
- compact_sched->set_waking_pid(waking_pid);
- compact_sched->set_waking_target_cpu(waking_target_cpu);
- compact_sched->set_waking_prio(waking_prio);
- compact_sched->set_waking_comm_index(waking_comm_index);
+ compact_sched->set_switch_timestamp(*switch_timestamp);
+ compact_sched->set_switch_next_comm_index(*switch_next_comm_index);
+ compact_sched->set_switch_next_pid(*switch_next_pid);
+ compact_sched->set_switch_next_prio(*switch_next_prio);
+ compact_sched->set_switch_prev_state(*switch_prev_state);
+
+ compact_sched->set_waking_timestamp(*waking_timestamp);
+ compact_sched->set_waking_pid(*waking_pid);
+ compact_sched->set_waking_target_cpu(*waking_target_cpu);
+ compact_sched->set_waking_prio(*waking_prio);
+ compact_sched->set_waking_comm_index(*waking_comm_index);
}
std::string ReEncode(const std::string& raw) {
diff --git a/tools/cpu_profile b/tools/cpu_profile
new file mode 100755
index 000000000..9dbeb445f
--- /dev/null
+++ b/tools/cpu_profile
@@ -0,0 +1,568 @@
+#!/usr/bin/env python3
+
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Runs tracing with CPU profiling enabled, and symbolizes traces if requested.
+
+For usage instructions, please see:
+https://perfetto.dev/docs/quickstart/callstack-sampling
+
+Adapted in large part from `heap_profile`.
+"""
+
+import argparse
+import os
+import shutil
+import signal
+import subprocess
+import sys
+import tempfile
+import time
+import uuid
+
+# Used for creating directories, etc.
+UUID = str(uuid.uuid4())[-6:]
+
+# See `sigint_handler` below.
+IS_INTERRUPTED = False
+
+
+def sigint_handler(signal, frame):
+ """Useful for cleanly interrupting tracing."""
+ global IS_INTERRUPTED
+ IS_INTERRUPTED = True
+
+
+def exit_with_no_profile():
+ sys.exit("No profiles generated.")
+
+
+def exit_with_bug_report(error):
+ sys.exit(
+ "{}\n\n If this is unexpected, please consider filing a bug at: \n"
+ "https://perfetto.dev/docs/contributing/getting-started#bugs.".format(
+ error))
+
+
+def adb_check_output(command):
+ """Runs an `adb` command and returns its output."""
+ try:
+ return subprocess.check_output(command).decode('utf-8')
+ except FileNotFoundError:
+ sys.exit("`adb` not found: Is it installed or on PATH?")
+ except subprocess.CalledProcessError as error:
+ sys.exit("`adb` error: Are any (or multiple) devices connected?\n"
+ "If multiple devices are connected, please select one by "
+ "setting `ANDROID_SERIAL=device_id`.\n"
+ "{}".format(error))
+ except Exception as error:
+ exit_with_bug_report(error)
+
+
+def parse_and_validate_args():
+ """Parses, validates, and returns command-line arguments for this script."""
+ DESCRIPTION = """Runs tracing with CPU profiling enabled, and symbolizes
+ traces if requested.
+
+ For usage instructions, please see:
+ https://perfetto.dev/docs/quickstart/cpu-profiling
+ """
+ parser = argparse.ArgumentParser(description=DESCRIPTION)
+ parser.add_argument(
+ "-f",
+ "--frequency",
+ help="Sampling frequency (Hz). "
+ "Default: 100 Hz.",
+ metavar="FREQUENCY",
+ type=int,
+ default=100)
+ parser.add_argument(
+ "-d",
+ "--duration",
+ help="Duration of profile (ms). 0 to run until interrupted. "
+ "Default: until interrupted by user.",
+ metavar="DURATION",
+ type=int,
+ default=0)
+ parser.add_argument(
+ "-n",
+ "--name",
+ help="Comma-separated list of names of processes to be profiled.",
+ metavar="NAMES",
+ default=None)
+ parser.add_argument(
+ "-p",
+ "--partial-matching",
+ help="If set, enables \"partial matching\" on the strings in --names/-n."
+ "Processes that are already running when profiling is started, and whose "
+ "names include any of the values in --names/-n as substrings will be profiled.",
+ action="store_true")
+ parser.add_argument(
+ "-c",
+ "--config",
+ help="A custom configuration file, if any, to be used for profiling. "
+ "If provided, --frequency/-f, --duration/-d, and --name/-n are not used.",
+ metavar="CONFIG",
+ default=None)
+ parser.add_argument(
+ "-o",
+ "--output",
+ help="Output directory for recorded trace.",
+ metavar="DIRECTORY",
+ default=None)
+
+ args = parser.parse_args()
+ if args.config is not None and args.name is not None:
+ sys.exit("--name/-n should not be provided when --config/-c is provided.")
+ elif args.config is None and args.name is None:
+ sys.exit("One of --names/-n or --config/-c is required.")
+
+ return args
+
+
+def get_matching_processes(args, names_to_match):
+ """Returns a list of currently-running processes whose names match `names_to_match`.
+
+ Args:
+ args: The command-line arguments provided to this script.
+ names_to_match: The list of process names provided by the user.
+ """
+ # Returns names as they are.
+ if not args.partial_matching:
+ return names_to_match
+
+ # Attempt to match names to names of currently running processes.
+ PS_PROCESS_OFFSET = 8
+ matching_processes = []
+ for line in adb_check_output(['adb', 'shell', 'ps', '-A']).splitlines():
+ line_split = line.split()
+ if len(line_split) <= PS_PROCESS_OFFSET:
+ continue
+ process = line_split[PS_PROCESS_OFFSET]
+ for name in names_to_match:
+ if name in process:
+ matching_processes.append(process)
+ break
+
+ return matching_processes
+
+
+def get_perfetto_config(args):
+ """Returns a Perfetto config with CPU profiling enabled for the selected processes.
+
+ Args:
+ args: The command-line arguments provided to this script.
+ """
+ if args.config is not None:
+ try:
+ with open(args.config, 'r') as config_file:
+ return config_file.read()
+ except IOError as error:
+ sys.exit("Unable to read config file: {}".format(error))
+
+ CONFIG_INDENT = ' '
+ CONFIG = '''buffers {{
+ size_kb: 2048
+ }}
+
+ buffers {{
+ size_kb: 63488
+ }}
+
+ data_sources {{
+ config {{
+ name: "linux.process_stats"
+ target_buffer: 0
+ process_stats_config {{
+ proc_stats_poll_ms: 100
+ }}
+ }}
+ }}
+
+ data_sources {{
+ config {{
+ name: "linux.perf"
+ target_buffer: 1
+ perf_event_config {{
+ all_cpus: true
+ sampling_frequency: {frequency}
+{target_config}
+ }}
+ }}
+ }}
+
+ duration_ms: {duration}
+ write_into_file: true
+ flush_timeout_ms: 30000
+ flush_period_ms: 604800000
+ '''
+
+ target_config = ""
+ matching_processes = []
+ if args.name is not None:
+ names_to_match = [name.strip() for name in args.name.split(',')]
+ matching_processes = get_matching_processes(args, names_to_match)
+
+ if not matching_processes:
+ sys.exit("No running processes matched for profiling.")
+
+ for process in matching_processes:
+ target_config += CONFIG_INDENT + 'target_cmdline: "{}"\n'.format(process)
+
+ print("Configured profiling for these processes:\n")
+ for matching_process in matching_processes:
+ print(matching_process)
+ print()
+
+ config = CONFIG.format(
+ frequency=args.frequency,
+ duration=args.duration,
+ target_config=target_config)
+
+ return config
+
+
+def release_or_newer(release):
+ """Returns whether a new enough Android release is being used."""
+ SDK = {'R': 30}
+ sdk = int(
+ adb_check_output(
+ ['adb', 'shell', 'getprop', 'ro.system.build.version.sdk']).strip())
+ if sdk >= SDK[release]:
+ return True
+
+ codename = adb_check_output(
+ ['adb', 'shell', 'getprop', 'ro.build.version.codename']).strip()
+ return codename == release
+
+
+def get_and_prepare_profile_target(args):
+ """Returns the target where the trace/profile will be output. Creates a new directory if necessary.
+
+ Args:
+ args: The command-line arguments provided to this script.
+ """
+ profile_target = os.path.join(tempfile.gettempdir(), UUID)
+ if args.output is not None:
+ profile_target = args.output
+ else:
+ os.makedirs(profile_target, exist_ok=True)
+ if not os.path.isdir(profile_target):
+ sys.exit("Output directory {} not found.".format(profile_target))
+ if os.listdir(profile_target):
+ sys.exit("Output directory {} not empty.".format(profile_target))
+
+ return profile_target
+
+
+def record_trace(config, profile_target):
+ """Runs Perfetto with the provided configuration to record a trace.
+
+ Args:
+ config: The Perfetto config to be used for tracing/profiling.
+ profile_target: The directory where the recorded trace is output.
+ """
+ NULL = open(os.devnull)
+ NO_OUT = {
+ 'stdout': NULL,
+ 'stderr': NULL,
+ }
+ if not release_or_newer('R'):
+ sys.exit("This tool requires Android R+ to run.")
+ profile_device_path = '/data/misc/perfetto-traces/profile-' + UUID
+ perfetto_command = ('CONFIG=\'{}\'; echo ${{CONFIG}} | '
+ 'perfetto --txt -c - -o {} -d')
+ try:
+ perfetto_pid = int(
+ adb_check_output([
+ 'adb', 'exec-out',
+ perfetto_command.format(config, profile_device_path)
+ ]).strip())
+ except ValueError as error:
+ sys.exit("Unable to start profiling: {}".format(error))
+
+ print("Profiling active. Press Ctrl+C to terminate.")
+
+ old_handler = signal.signal(signal.SIGINT, sigint_handler)
+
+ perfetto_alive = True
+ while perfetto_alive and not IS_INTERRUPTED:
+ perfetto_alive = subprocess.call(
+ ['adb', 'shell', '[ -d /proc/{} ]'.format(perfetto_pid)], **NO_OUT) == 0
+ time.sleep(0.25)
+
+ print("Finishing profiling and symbolization...")
+
+ if IS_INTERRUPTED:
+ adb_check_output(['adb', 'shell', 'kill', '-INT', str(perfetto_pid)])
+
+ # Restore old handler.
+ signal.signal(signal.SIGINT, old_handler)
+
+ while perfetto_alive:
+ perfetto_alive = subprocess.call(
+ ['adb', 'shell', '[ -d /proc/{} ]'.format(perfetto_pid)]) == 0
+ time.sleep(0.25)
+
+ profile_host_path = os.path.join(profile_target, 'raw-trace')
+ adb_check_output(['adb', 'pull', profile_device_path, profile_host_path])
+ adb_check_output(['adb', 'shell', 'rm', profile_device_path])
+
+
+def get_trace_to_text():
+ """Sets up and returns the path to `trace_to_text`."""
+ try:
+ trace_to_text = get_perfetto_prebuilt('trace_to_text', soft_fail=True)
+ except Exception as error:
+ exit_with_bug_report(error)
+ if trace_to_text is None:
+ exit_with_bug_report(
+ "Unable to download `trace_to_text` for symbolizing profiles.")
+
+ return trace_to_text
+
+
+def concatenate_files(files_to_concatenate, output_file):
+ """Concatenates files.
+
+ Args:
+ files_to_concatenate: Paths for input files to concatenate.
+ output_file: Path to the resultant output file.
+ """
+ with open(output_file, 'wb') as output:
+ for file in files_to_concatenate:
+ with open(file, 'rb') as input:
+ shutil.copyfileobj(input, output)
+
+
+def symbolize_trace(trace_to_text, profile_target):
+ """Attempts symbolization of the recorded trace/profile, if symbols are available.
+
+ Args:
+ trace_to_text: The path to the `trace_to_text` binary used for symbolization.
+ profile_target: The directory where the recorded trace was output.
+
+ Returns:
+ The path to the symbolized trace file if symbolization was completed,
+ and the original trace file, if it was not.
+ """
+ binary_path = os.getenv('PERFETTO_BINARY_PATH')
+ trace_file = os.path.join(profile_target, 'raw-trace')
+ files_to_concatenate = [trace_file]
+
+ if binary_path is not None:
+ try:
+ with open(os.path.join(profile_target, 'symbols'), 'w') as symbols_file:
+ return_code = subprocess.call([trace_to_text, 'symbolize', trace_file],
+ env=dict(
+ os.environ,
+ PERFETTO_BINARY_PATH=binary_path),
+ stdout=symbols_file)
+ except IOError as error:
+ sys.exit("Unable to write symbols to disk: {}".format(error))
+ if return_code == 0:
+ files_to_concatenate.append(os.path.join(profile_target, 'symbols'))
+ else:
+ print("Failed to symbolize. Continuing without symbols.", file=sys.stderr)
+
+ if len(files_to_concatenate) > 1:
+ trace_file = os.path.join(profile_target, 'symbolized-trace')
+ try:
+ concatenate_files(files_to_concatenate, trace_file)
+ except Exception as error:
+ sys.exit("Unable to write symbolized profile to disk: {}".format(error))
+
+ return trace_file
+
+
+def generate_pprof_profiles(trace_to_text, trace_file):
+ """Generates pprof profiles from the recorded trace.
+
+ Args:
+ trace_to_text: The path to the `trace_to_text` binary used for generating profiles.
+ trace_file: The oath to the recorded and potentially symbolized trace file.
+
+ Returns:
+ The directory where pprof profiles are output.
+ """
+ try:
+ trace_to_text_output = subprocess.check_output(
+ [trace_to_text, 'profile', '--perf', trace_file])
+ except Exception as error:
+ exit_with_bug_report(
+ "Unable to extract profiles from trace: {}".format(error))
+
+ profiles_output_directory = None
+ for word in trace_to_text_output.decode('utf-8').split():
+ if 'perf_profile-' in word:
+ profiles_output_directory = word
+ if profiles_output_directory is None:
+ exit_with_no_profile()
+ return profiles_output_directory
+
+
+def copy_profiles_to_destination(profile_target, profile_path):
+ """Copies recorded profiles to `profile_target` from `profile_path`."""
+ profile_files = os.listdir(profile_path)
+ if not profile_files:
+ exit_with_no_profile()
+
+ try:
+ for profile_file in profile_files:
+ shutil.copy(os.path.join(profile_path, profile_file), profile_target)
+ except Exception as error:
+ sys.exit("Unable to copy profiles to {}: {}".format(profile_target, error))
+
+ print("Wrote profiles to {}".format(profile_target))
+
+
+def main(argv):
+ args = parse_and_validate_args()
+ profile_target = get_and_prepare_profile_target(args)
+ record_trace(get_perfetto_config(args), profile_target)
+ trace_to_text = get_trace_to_text()
+ trace_file = symbolize_trace(trace_to_text, profile_target)
+ copy_profiles_to_destination(
+ profile_target, generate_pprof_profiles(trace_to_text, trace_file))
+ return 0
+
+
+# BEGIN_SECTION_GENERATED_BY(roll-prebuilts)
+# Revision: v25.0
+PERFETTO_PREBUILT_MANIFEST = [{
+ 'tool':
+ 'trace_to_text',
+ 'arch':
+ 'mac-amd64',
+ 'file_name':
+ 'trace_to_text',
+ 'file_size':
+ 6525752,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/mac-amd64/trace_to_text',
+ 'sha256':
+ '64ccf6bac87825145691c6533412e514891f82300d68ff7ce69e8d2ca69aaf62',
+ 'platform':
+ 'darwin',
+ 'machine': ['x86_64']
+}, {
+ 'tool':
+ 'trace_to_text',
+ 'arch':
+ 'windows-amd64',
+ 'file_name':
+ 'trace_to_text.exe',
+ 'file_size':
+ 5925888,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/windows-amd64/trace_to_text.exe',
+ 'sha256':
+ '29e50ec4d8e28c7c322ba13273afcce80c63fe7d9f182b83af0e2077b4d2b952',
+ 'platform':
+ 'win32',
+ 'machine': ['amd64']
+}, {
+ 'tool':
+ 'trace_to_text',
+ 'arch':
+ 'linux-amd64',
+ 'file_name':
+ 'trace_to_text',
+ 'file_size':
+ 6939560,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-amd64/trace_to_text',
+ 'sha256':
+ '109f4ff3bbd47633b0c08a338f1230e69d529ddf1584656ed45d8a59acaaabeb',
+ 'platform':
+ 'linux',
+ 'machine': ['x86_64']
+}]
+
+
+# DO NOT EDIT. If you wish to make edits to this code, you need to change only
+# //tools/get_perfetto_prebuilt.py and run /tools/roll-prebuilts to regenerate
+# all the others scripts this is embedded into.
+def get_perfetto_prebuilt(tool_name, soft_fail=False, arch=None):
+ """ Downloads the prebuilt, if necessary, and returns its path on disk. """
+
+ # The first time this is invoked, it downloads the |url| and caches it into
+ # ~/.perfetto/prebuilts/$tool_name. On subsequent invocations it just runs the
+ # cached version.
+ def download_or_get_cached(file_name, url, sha256):
+ import os, hashlib, subprocess
+ dir = os.path.join(
+ os.path.expanduser('~'), '.local', 'share', 'perfetto', 'prebuilts')
+ os.makedirs(dir, exist_ok=True)
+ bin_path = os.path.join(dir, file_name)
+ sha256_path = os.path.join(dir, file_name + '.sha256')
+ needs_download = True
+
+ # Avoid recomputing the SHA-256 on each invocation. The SHA-256 of the last
+ # download is cached into file_name.sha256, just check if that matches.
+ if os.path.exists(bin_path) and os.path.exists(sha256_path):
+ with open(sha256_path, 'rb') as f:
+ digest = f.read().decode()
+ if digest == sha256:
+ needs_download = False
+
+ if needs_download:
+ # Either the filed doesn't exist or the SHA256 doesn't match.
+ tmp_path = bin_path + '.tmp'
+ print('Downloading ' + url)
+ subprocess.check_call(['curl', '-f', '-L', '-#', '-o', tmp_path, url])
+ with open(tmp_path, 'rb') as fd:
+ actual_sha256 = hashlib.sha256(fd.read()).hexdigest()
+ if actual_sha256 != sha256:
+ raise Exception('Checksum mismatch for %s (actual: %s, expected: %s)' %
+ (url, actual_sha256, sha256))
+ os.chmod(tmp_path, 0o755)
+ os.rename(tmp_path, bin_path)
+ with open(sha256_path, 'w') as f:
+ f.write(sha256)
+ return bin_path
+ # --- end of download_or_get_cached() ---
+
+ # --- get_perfetto_prebuilt() function starts here. ---
+ import os, platform, sys
+ plat = sys.platform.lower()
+ machine = platform.machine().lower()
+ manifest_entry = None
+ for entry in PERFETTO_PREBUILT_MANIFEST:
+ # If the caller overrides the arch, just match that (for Android prebuilts).
+ if arch and entry.get('arch') == arch:
+ manifest_entry = entry
+ break
+ # Otherwise guess the local machine arch.
+ if entry.get('tool') == tool_name and entry.get(
+ 'platform') == plat and machine in entry.get('machine', []):
+ manifest_entry = entry
+ break
+ if manifest_entry is None:
+ if soft_fail:
+ return None
+ raise Exception(
+ ('No prebuilts available for %s-%s\n' % (plat, machine)) +
+ 'See https://perfetto.dev/docs/contributing/build-instructions')
+
+ return download_or_get_cached(
+ file_name=manifest_entry['file_name'],
+ url=manifest_entry['url'],
+ sha256=manifest_entry['sha256'])
+
+
+# END_SECTION_GENERATED_BY(roll-prebuilts)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
diff --git a/tools/cpu_utilization/cpu_utilization.cc b/tools/cpu_utilization/cpu_utilization.cc
index 2aea7bae2..63d261891 100644
--- a/tools/cpu_utilization/cpu_utilization.cc
+++ b/tools/cpu_utilization/cpu_utilization.cc
@@ -15,13 +15,13 @@
*/
#include <fcntl.h>
-#include <inttypes.h>
#include <stdint.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
+#include <cinttypes>
#include <string>
#include "perfetto/base/logging.h"
diff --git a/tools/export_power_profiles.py b/tools/export_power_profiles.py
index db6e7ce9b..cea30f815 100755
--- a/tools/export_power_profiles.py
+++ b/tools/export_power_profiles.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env vpython
+#!/usr/bin/env python3
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
diff --git a/tools/ftrace_proto_gen/event_list b/tools/ftrace_proto_gen/event_list
index a4193d486..60a4a5748 100644
--- a/tools/ftrace_proto_gen/event_list
+++ b/tools/ftrace_proto_gen/event_list
@@ -353,3 +353,63 @@ sde/sde_perf_calc_crtc
sde/sde_perf_crtc_update
sde/sde_perf_set_qos_luts
sde/sde_perf_update_bus
+synthetic/rss_stat_throttled
+net/netif_receive_skb
+net/net_dev_xmit
+sock/inet_sock_set_state
+tcp/tcp_retransmit_skb
+cros_ec/cros_ec_sensorhub_data
+net/napi_gro_receive_entry
+net/napi_gro_receive_exit
+skb/kfree_skb
+kvm/kvm_access_fault
+kvm/kvm_ack_irq
+kvm/kvm_age_hva
+kvm/kvm_age_page
+kvm/kvm_arm_clear_debug
+kvm/kvm_arm_set_dreg32
+kvm/kvm_arm_set_regset
+kvm/kvm_arm_setup_debug
+kvm/kvm_entry
+kvm/kvm_exit
+kvm/kvm_fpu
+kvm/kvm_get_timer_map
+kvm/kvm_guest_fault
+kvm/kvm_handle_sys_reg
+kvm/kvm_hvc_arm64
+kvm/kvm_irq_line
+kvm/kvm_mmio
+kvm/kvm_mmio_emulate
+kvm/kvm_set_guest_debug
+kvm/kvm_set_irq
+kvm/kvm_set_spte_hva
+kvm/kvm_set_way_flush
+kvm/kvm_sys_access
+kvm/kvm_test_age_hva
+kvm/kvm_timer_emulate
+kvm/kvm_timer_hrtimer_expire
+kvm/kvm_timer_restore_state
+kvm/kvm_timer_save_state
+kvm/kvm_timer_update_irq
+kvm/kvm_toggle_cache
+kvm/kvm_unmap_hva_range
+kvm/kvm_userspace_exit
+kvm/kvm_vcpu_wakeup
+kvm/kvm_wfx_arm64
+kvm/trap_reg
+kvm/vgic_update_irq_pending
+power/wakeup_source_activate
+power/wakeup_source_deactivate
+ufs/ufshcd_command
+ufs/ufshcd_clk_gating
+printk/console
+drm/drm_vblank_event
+drm/drm_vblank_event_delivered
+gpu_scheduler/drm_sched_job
+gpu_scheduler/drm_run_job
+gpu_scheduler/drm_sched_process_job
+dma_fence/dma_fence_init
+dma_fence/dma_fence_emit
+dma_fence/dma_fence_signaled
+dma_fence/dma_fence_wait_start
+dma_fence/dma_fence_wait_end
diff --git a/tools/ftrace_proto_gen/proto_gen_utils.cc b/tools/ftrace_proto_gen/proto_gen_utils.cc
index 189c8f1a9..95a6531ba 100644
--- a/tools/ftrace_proto_gen/proto_gen_utils.cc
+++ b/tools/ftrace_proto_gen/proto_gen_utils.cc
@@ -38,8 +38,8 @@ std::string RunClangFmt(const std::string& input) {
const std::string platform = "linux64";
#endif
base::Subprocess clang_fmt({"buildtools/" + platform + "/clang-format"});
- clang_fmt.args.stdout_mode = base::Subprocess::kBuffer;
- clang_fmt.args.stderr_mode = base::Subprocess::kInherit;
+ clang_fmt.args.stdout_mode = base::Subprocess::OutputMode::kBuffer;
+ clang_fmt.args.stderr_mode = base::Subprocess::OutputMode::kInherit;
clang_fmt.args.input = input;
PERFETTO_CHECK(clang_fmt.Call());
return std::move(clang_fmt.output());
diff --git a/tools/gen_all b/tools/gen_all
index b065236ae..bcf6bd39a 100755
--- a/tools/gen_all
+++ b/tools/gen_all
@@ -14,22 +14,25 @@
# limitations under the License.
from __future__ import print_function
+
import os
import argparse
import subprocess
+import sys
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
+IS_WIN = sys.platform.startswith('win')
def protoc_path(out_directory):
- path = os.path.join(out_directory, 'protoc')
+ path = os.path.join(out_directory, 'protoc') + ('.exe' if IS_WIN else '')
assert os.path.isfile(path)
return path
def call(cmd, *args):
path = os.path.join('tools', cmd)
- command = [path] + list(args)
+ command = ['python3', path] + list(args)
print('Running', ' '.join(command))
try:
subprocess.check_call(command, cwd=ROOT_DIR)
@@ -51,12 +54,18 @@ def main():
call('check_include_violations')
call('check_proto_comments')
call('fix_include_guards', *check_only)
- call('gen_bazel', *check_only)
- call('gen_android_bp', *check_only)
+ if not IS_WIN:
+ call('gen_bazel', *check_only)
+ call('gen_android_bp', *check_only)
call('gen_merged_protos', *check_only)
call('ninja', '-C', out, 'protoc')
call('gen_binary_descriptors', '--protoc', protoc_path(out), *check_only)
+ if IS_WIN:
+ print('WARNING: Cannot generate BUILD / Android.bp from Windows. ' +
+ 'They might be left stale and fail in the CI if you edited any ' +
+ 'BUILD.gn file')
+
except AssertionError as e:
if not str(e):
raise
diff --git a/tools/gen_amalgamated b/tools/gen_amalgamated
index bff4641aa..c1cb2bc4d 100755
--- a/tools/gen_amalgamated
+++ b/tools/gen_amalgamated
@@ -43,11 +43,12 @@ default_targets = [
# Arguments for the GN output directory (unless overridden from the command
# line).
gn_args = ' '.join([
+ 'enable_perfetto_ipc=true',
'is_debug=false',
'is_perfetto_build_generator=true',
'is_perfetto_embedder=true',
+ 'perfetto_enable_git_rev_version_header=true',
'use_custom_libcxx=false',
- 'enable_perfetto_ipc=true',
])
# By default, the amalgamated .h only recurses in #includes but not in the
@@ -580,7 +581,7 @@ def main():
args = parser.parse_args()
targets = args.targets or default_targets
- # The CHANGELOG mtime triggers the the perfetto_version.gen.h genrule. This is
+ # The CHANGELOG mtime triggers the perfetto_version.gen.h genrule. This is
# to avoid emitting a stale version information in the remote case of somebody
# running gen_amalgamated incrementally after having moved to another commit.
changelog_path = os.path.join(project_root, 'CHANGELOG')
diff --git a/tools/gen_amalgamated_sql_metrics.py b/tools/gen_amalgamated_sql_metrics.py
new file mode 100755
index 000000000..16f6aac35
--- /dev/null
+++ b/tools/gen_amalgamated_sql_metrics.py
@@ -0,0 +1,131 @@
+#!/usr/bin/env python3
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import argparse
+import os
+import sys
+
+# Converts the SQL metrics for trace processor into a C++ header with the SQL
+# as a string constant to allow trace processor to exectue the metrics.
+
+REPLACEMENT_HEADER = '''/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ *******************************************************************************
+ * AUTOGENERATED BY tools/gen_merged_sql_metrics - DO NOT EDIT
+ *******************************************************************************
+ */
+
+ #include <string.h>
+'''
+
+NAMESPACE_BEGIN = '''
+namespace perfetto {
+namespace trace_processor {
+namespace metrics {
+namespace sql_metrics {
+'''
+
+FILE_TO_SQL_STRUCT = '''
+struct FileToSql {
+ const char* path;
+ const char* sql;
+};
+'''
+
+NAMESPACE_END = '''
+} // namespace sql_metrics
+} // namespace metrics
+} // namespace trace_processor
+} // namsepace perfetto
+'''
+
+
+def filename_to_variable(filename):
+ return "k" + "".join([x.capitalize() for x in filename.split("_")])
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--cpp_out', required=True)
+ parser.add_argument('sql_files', nargs='*')
+ args = parser.parse_args()
+
+ root_path = os.path.commonprefix([os.path.abspath(x) for x in args.sql_files])
+
+ # Extract the SQL output from each file.
+ sql_outputs = {}
+ for file_name in args.sql_files:
+ with open(file_name, 'r') as f:
+ relpath = os.path.relpath(file_name, root_path)
+ sql_outputs[relpath] = "".join(
+ x.lstrip() for x in f.readlines() if not x.lstrip().startswith('--'))
+
+ with open(args.cpp_out, 'w+') as output:
+ output.write(REPLACEMENT_HEADER)
+ output.write(NAMESPACE_BEGIN)
+
+ # Create the C++ variable for each SQL file.
+ for path, sql in sql_outputs.items():
+ name = os.path.basename(path)
+ variable = filename_to_variable(os.path.splitext(name)[0])
+ output.write('\nconst char {}[] = '.format(variable))
+ # MSVC doesn't like string literals that are individually longer than 16k.
+ # However it's still fine "if" "we" "concatenate" "many" "of" "them".
+ # This code splits the sql in string literals of ~1000 chars each.
+ line_groups = ['']
+ for line in sql.split('\n'):
+ line_groups[-1] += line + '\n'
+ if len(line_groups[-1]) > 1000:
+ line_groups.append('')
+
+ for line in line_groups:
+ output.write('R"_d3l1m1t3r_({})_d3l1m1t3r_"\n'.format(line))
+ output.write(';\n')
+
+ output.write(FILE_TO_SQL_STRUCT)
+
+ # Create mapping of filename to variable name for each variable.
+ output.write("\nconst FileToSql kFileToSql[] = {")
+ for path in sql_outputs.keys():
+ name = os.path.basename(path)
+ variable = filename_to_variable(os.path.splitext(name)[0])
+
+ # This is for Windows which has \ as a path separator.
+ path = path.replace("\\", "/")
+ output.write('\n {{"{}", {}}},\n'.format(path, variable))
+ output.write("};\n")
+
+ output.write(NAMESPACE_END)
+
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/tools/gen_android_bp b/tools/gen_android_bp
index 9c4f408bf..11e5bea91 100755
--- a/tools/gen_android_bp
+++ b/tools/gen_android_bp
@@ -94,10 +94,24 @@ target_initrc = {
target_host_supported = [
'//:libperfetto',
+ '//:libperfetto_client_experimental',
'//protos/perfetto/trace:perfetto_trace_protos',
+ '//src/trace_processor:demangle',
'//src/trace_processor:trace_processor_shell',
]
+target_vendor_available = [
+ '//:libperfetto_client_experimental',
+]
+
+# Proto target groups which will be made public.
+proto_groups = {
+ 'trace': [
+ '//protos/perfetto/trace:non_minimal_source_set',
+ '//protos/perfetto/trace:minimal_source_set'
+ ],
+}
+
# All module names are prefixed with this string to avoid collisions.
module_prefix = 'perfetto_'
@@ -106,6 +120,7 @@ shared_library_allowlist = [
'android',
'android.hardware.atrace@1.0',
'android.hardware.health@2.0',
+ 'android.hardware.health-V1-ndk',
'android.hardware.power.stats@1.0',
"android.hardware.power.stats-V1-cpp",
'base',
@@ -147,12 +162,6 @@ cflag_allowlist = r'^-DPERFETTO.*$'
# Compiler defines which are passed through to the blueprint.
define_allowlist = r'^(GOOGLE_PROTO.*)|(ZLIB_.*)|(USE_MMAP)|(HAVE_HIDDEN)$'
-# Shared libraries which are not in PDK.
-library_not_in_pdk = {
- 'libandroid',
- 'libservices',
-}
-
# The directory where the generated perfetto_build_flags.h will be copied into.
buildflags_dir = 'include/perfetto/base/build_configs/android_tree'
@@ -163,11 +172,11 @@ def enumerate_data_deps():
for line in (line.strip() for line in lines if not line.startswith('#')):
assert os.path.exists(line), 'file %s should exist' % line
if line.startswith('test/data/'):
- # Skip test data files that require GCS. They are only for benchmarks.
- # We don't run benchmarks in the android tree.
- continue
- if line.endswith('/'):
- yield line + '**/*'
+ # Skip test data files that require GCS. They are only for benchmarks.
+ # We don't run benchmarks in the android tree.
+ continue
+ if line.endswith('/.'):
+ yield line[:-1] + '**/*'
else:
yield line
@@ -182,16 +191,16 @@ additional_args = {
('cflags', {'-Wglobal-constructors', '-Werror=global-constructors'}),
('version_script', 'src/profiling/memory/heapprofd_client_api.map.txt'),
('stubs', {
- 'versions': ['S'],
- 'symbol_file': 'src/profiling/memory/heapprofd_client_api.map.txt',
+ 'versions': ['S'],
+ 'symbol_file': 'src/profiling/memory/heapprofd_client_api.map.txt',
}),
('export_include_dirs', {'src/profiling/memory/include'}),
],
'heapprofd_api_noop': [
('version_script', 'src/profiling/memory/heapprofd_client_api.map.txt'),
('stubs', {
- 'versions': ['S'],
- 'symbol_file': 'src/profiling/memory/heapprofd_client_api.map.txt',
+ 'versions': ['S'],
+ 'symbol_file': 'src/profiling/memory/heapprofd_client_api.map.txt',
}),
('export_include_dirs', {'src/profiling/memory/include'}),
],
@@ -210,42 +219,42 @@ additional_args = {
('include_dirs', {'bionic/libc/kernel'}),
],
'perfetto_integrationtests': [
- ('test_suites', {'general-tests'}),
- ('test_config', 'PerfettoIntegrationTests.xml'),
- ],
- 'traced_probes': [
- ('required', {'libperfetto_android_internal',
- 'trigger_perfetto',
- 'traced_perf',
- 'mm_events'}),
+ ('test_suites', {'general-tests'}),
+ ('test_config', 'PerfettoIntegrationTests.xml'),
],
+ 'traced_probes': [('required', {
+ 'libperfetto_android_internal', 'trigger_perfetto', 'traced_perf',
+ 'mm_events'
+ }),],
'libperfetto_android_internal': [('static_libs', {'libhealthhalutils'}),],
'trace_processor_shell': [
- ('strip', {'all': True}),
- ('host', {
- 'stl': 'libc++_static',
- 'dist': {'targets': ['sdk_repo']},
- }),
+ ('strip', {
+ 'all': True
+ }),
+ ('host', {
+ 'stl': 'libc++_static',
+ 'dist': {
+ 'targets': ['sdk_repo']
+ },
+ }),
],
'libperfetto_client_experimental': [
- ('apex_available', {
- '//apex_available:platform',
- 'com.android.art',
- 'com.android.art.debug'}),
- ('min_sdk_version', 'S'),
- ('shared_libs', {'liblog'}),
- ('export_include_dirs', {'include', buildflags_dir}),
+ ('apex_available', {
+ '//apex_available:platform', 'com.android.art',
+ 'com.android.art.debug'
+ }),
+ ('min_sdk_version', 'S'),
+ ('shared_libs', {'liblog'}),
+ ('export_include_dirs', {'include', buildflags_dir}),
],
'perfetto_trace_protos': [
- ('apex_available', {
- '//apex_available:platform',
- 'com.android.art',
- 'com.android.art.debug'}),
- ('min_sdk_version', 'S'),
- ],
- 'libperfetto': [
- ('export_include_dirs', {'include', buildflags_dir}),
+ ('apex_available', {
+ '//apex_available:platform', 'com.android.art',
+ 'com.android.art.debug'
+ }),
+ ('min_sdk_version', 'S'),
],
+ 'libperfetto': [('export_include_dirs', {'include', buildflags_dir}),],
}
@@ -288,6 +297,7 @@ def enable_libunwindstack(module):
module.static_libs.add('libbase')
module.static_libs.add('liblzma')
module.static_libs.add('libdexfile_support')
+ module.runtime_libs.add('libdexfile') # libdexfile_support dependency
def enable_libunwind(module):
@@ -301,13 +311,13 @@ def enable_sqlite(module):
elif module.host_supported:
# Copy what the sqlite3 command line tool does.
module.android.shared_libs.add('libsqlite')
- module.android.shared_libs.add('libandroidicu')
+ module.android.shared_libs.add('libicu')
module.android.shared_libs.add('liblog')
module.android.shared_libs.add('libutils')
module.host.static_libs.add('libsqlite')
else:
module.shared_libs.add('libsqlite')
- module.shared_libs.add('libandroidicu')
+ module.shared_libs.add('libicu')
module.shared_libs.add('liblog')
module.shared_libs.add('libutils')
@@ -325,6 +335,7 @@ def enable_zlib(module):
def enable_uapi_headers(module):
module.include_dirs.add('bionic/libc/kernel')
+
def enable_bionic_libc_platform_headers_on_android(module):
module.header_libs.add('bionic_libc_platform_headers')
@@ -332,20 +343,32 @@ def enable_bionic_libc_platform_headers_on_android(module):
# Android equivalents for third-party libraries that the upstream project
# depends on.
builtin_deps = {
- '//gn:default_deps': lambda x: None,
- '//gn:gtest_main': lambda x: None,
- '//gn:protoc': lambda x: None,
- '//gn:gtest_and_gmock': enable_gtest_and_gmock,
- '//gn:libunwind': enable_libunwind,
- '//gn:protobuf_full': enable_protobuf_full,
- '//gn:protobuf_lite': enable_protobuf_lite,
- '//gn:protoc_lib': enable_protoc_lib,
- '//gn:libunwindstack': enable_libunwindstack,
- '//gn:sqlite': enable_sqlite,
- '//gn:zlib': enable_zlib,
- '//gn:bionic_kernel_uapi_headers' : enable_uapi_headers,
+ '//gn:default_deps':
+ lambda x: None,
+ '//gn:gtest_main':
+ lambda x: None,
+ '//gn:protoc':
+ lambda x: None,
+ '//gn:gtest_and_gmock':
+ enable_gtest_and_gmock,
+ '//gn:libunwind':
+ enable_libunwind,
+ '//gn:protobuf_full':
+ enable_protobuf_full,
+ '//gn:protobuf_lite':
+ enable_protobuf_lite,
+ '//gn:protoc_lib':
+ enable_protoc_lib,
+ '//gn:libunwindstack':
+ enable_libunwindstack,
+ '//gn:sqlite':
+ enable_sqlite,
+ '//gn:zlib':
+ enable_zlib,
+ '//gn:bionic_kernel_uapi_headers':
+ enable_uapi_headers,
'//src/profiling/memory:bionic_libc_platform_headers_on_android':
- enable_bionic_libc_platform_headers_on_android,
+ enable_bionic_libc_platform_headers_on_android,
}
# ----------------------------------------------------------------------------
@@ -370,18 +393,21 @@ class ThrowingArgumentParser(argparse.ArgumentParser):
def write_blueprint_key_value(output, name, value, sort=True):
"""Writes a Blueprint key-value pair to the output"""
+ if isinstance(value, bool):
+ if value:
+ output.append(' %s: true,' % name)
+ else:
+ output.append(' %s: false,' % name)
+ return
if not value:
return
if isinstance(value, set):
value = sorted(value)
if isinstance(value, list):
- output.append(' %s: [' % name)
+ output.append(' %s: [' % name)
for item in sorted(value) if sort else value:
- output.append(' "%s",' % item)
- output.append(' ],')
- return
- if isinstance(value, bool):
- output.append(' %s: true,' % name)
+ output.append(' "%s",' % item)
+ output.append(' ],')
return
if isinstance(value, Target):
value.to_string(output)
@@ -391,12 +417,12 @@ def write_blueprint_key_value(output, name, value, sort=True):
for k, v in value.items():
write_blueprint_key_value(kv_output, k, v)
- output.append(' %s: {' % name)
+ output.append(' %s: {' % name)
for line in kv_output:
- output.append(' %s' % line)
- output.append(' },')
+ output.append(' %s' % line)
+ output.append(' },')
return
- output.append(' %s: "%s",' % (name, value))
+ output.append(' %s: "%s",' % (name, value))
class Target(object):
@@ -423,10 +449,10 @@ class Target(object):
self._output_field(nested_out, 'strip')
if nested_out:
- output.append(' %s: {' % self.name)
+ output.append(' %s: {' % self.name)
for line in nested_out:
- output.append(' %s' % line)
- output.append(' },')
+ output.append(' %s' % line)
+ output.append(' },')
def _output_field(self, output, name, sort=True):
value = getattr(self, name)
@@ -445,9 +471,11 @@ class Module(object):
self.shared_libs = set()
self.static_libs = set()
self.whole_static_libs = set()
+ self.runtime_libs = set()
self.tools = set()
self.cmd = None
self.host_supported = False
+ self.vendor_available = False
self.init_rc = set()
self.out = set()
self.export_include_dirs = set()
@@ -469,6 +497,7 @@ class Module(object):
self.data = set()
self.apex_available = set()
self.min_sdk_version = None
+ self.proto = dict()
# The genrule_XXX below are properties that must to be propagated back
# on the module(s) that depend on the genrule.
self.genrule_headers = set()
@@ -488,9 +517,13 @@ class Module(object):
self._output_field(output, 'shared_libs')
self._output_field(output, 'static_libs')
self._output_field(output, 'whole_static_libs')
+ self._output_field(output, 'runtime_libs')
self._output_field(output, 'tools')
self._output_field(output, 'cmd', sort=False)
- self._output_field(output, 'host_supported')
+ if self.host_supported:
+ self._output_field(output, 'host_supported')
+ if self.vendor_available:
+ self._output_field(output, 'vendor_available')
self._output_field(output, 'init_rc')
self._output_field(output, 'out')
self._output_field(output, 'export_include_dirs')
@@ -512,41 +545,36 @@ class Module(object):
self._output_field(output, 'test_suites')
self._output_field(output, 'test_config')
self._output_field(output, 'stubs')
+ self._output_field(output, 'proto')
target_out = []
self._output_field(target_out, 'android')
self._output_field(target_out, 'host')
if target_out:
- output.append(' target: {')
+ output.append(' target: {')
for line in target_out:
- output.append(' %s' % line)
- output.append(' },')
-
- disable_pdk = any(name in library_not_in_pdk for name in self.shared_libs)
- if self.user_debug_flag or disable_pdk:
- output.append(' product_variables: {')
- if disable_pdk:
- output.append(' pdk: {')
- output.append(' enabled: false,')
- output.append(' },')
- if self.user_debug_flag:
- output.append(' debuggable: {')
- output.append(
- ' cflags: ["-DPERFETTO_BUILD_WITH_ANDROID_USERDEBUG"],')
- output.append(' },')
- output.append(' },')
+ output.append(' %s' % line)
+ output.append(' },')
+
+ if self.user_debug_flag:
+ output.append(' product_variables: {')
+ output.append(' debuggable: {')
+ output.append(
+ ' cflags: ["-DPERFETTO_BUILD_WITH_ANDROID_USERDEBUG"],')
+ output.append(' },')
+ output.append(' },')
if self.lto is not None:
- output.append(' target: {')
- output.append(' android: {')
- output.append(' lto: {')
- output.append(' thin: %s,' % 'true' if self.lto else 'false')
- output.append(' },')
+ output.append(' target: {')
+ output.append(' android: {')
+ output.append(' lto: {')
+ output.append(' thin: %s,' %
+ 'true' if self.lto else 'false')
+ output.append(' },')
+ output.append(' },')
output.append(' },')
- output.append(' },')
output.append('}')
output.append('')
-
def add_android_static_lib(self, lib):
if self.type == 'cc_binary_host':
raise Exception('Adding Android static lib for host tool is unsupported')
@@ -555,7 +583,6 @@ class Module(object):
else:
self.static_libs.add(lib)
-
def add_android_shared_lib(self, lib):
if self.type == 'cc_binary_host':
raise Exception('Adding Android shared lib for host tool is unsupported')
@@ -564,7 +591,6 @@ class Module(object):
else:
self.shared_libs.add(lib)
-
def _output_field(self, output, name, sort=True):
value = getattr(self, name)
return write_blueprint_key_value(output, name, value, sort)
@@ -660,18 +686,12 @@ def create_proto_modules(blueprint, gn, target):
# Recursively extract the .proto files of all the dependencies and
# add them to srcs.
- target_queue = collections.deque([target.name])
- seen_targets = set()
- while target_queue:
- dep = target_queue.popleft()
- if dep in seen_targets:
- continue
- seen_targets.add(dep)
-
+ descriptor_module.srcs.update(
+ gn_utils.label_to_path(src) for src in target.sources)
+ for dep in target.transitive_proto_deps:
current_target = gn.get_target(dep)
descriptor_module.srcs.update(
gn_utils.label_to_path(src) for src in current_target.sources)
- target_queue.extend(current_target.proto_deps)
return descriptor_module
@@ -742,14 +762,14 @@ def create_proto_modules(blueprint, gn, target):
return source_module
-def create_merged_sql_metrics_module(blueprint, target):
+def create_amalgamated_sql_metrics_module(blueprint, target):
bp_module_name = label_to_module_name(target.name)
module = Module('genrule', bp_module_name, target.name)
module.tool_files = [
- 'tools/gen_merged_sql_metrics.py',
+ 'tools/gen_amalgamated_sql_metrics.py',
]
module.cmd = ' '.join([
- '$(location tools/gen_merged_sql_metrics.py)',
+ '$(location tools/gen_amalgamated_sql_metrics.py)',
'--cpp_out=$(out)',
'$(in)',
])
@@ -767,10 +787,8 @@ def create_cc_proto_descriptor_module(blueprint, target):
'tools/gen_cc_proto_descriptor.py',
]
module.cmd = ' '.join([
- '$(location tools/gen_cc_proto_descriptor.py)',
- '--gen_dir=$(genDir)',
- '--cpp_out=$(out)',
- '$(in)'
+ '$(location tools/gen_cc_proto_descriptor.py)', '--gen_dir=$(genDir)',
+ '--cpp_out=$(out)', '$(in)'
])
module.genrule_headers.add(module.name)
module.srcs.update(
@@ -784,19 +802,36 @@ def create_gen_version_module(blueprint, target, bp_module_name):
module = Module('genrule', bp_module_name, gn_utils.GEN_VERSION_TARGET)
script_path = gn_utils.label_to_path(target.script)
module.genrule_headers.add(bp_module_name)
- module.tool_files = [ script_path ]
+ module.tool_files = [script_path]
module.out.update(target.outputs)
module.srcs.update(gn_utils.label_to_path(src) for src in target.inputs)
module.cmd = ' '.join([
- 'python3 $(location %s)' % script_path,
- '--no_git',
- '--changelog=$(location CHANGELOG)',
- '--cpp_out=$(out)'
+ 'python3 $(location %s)' % script_path, '--no_git',
+ '--changelog=$(location CHANGELOG)', '--cpp_out=$(out)'
])
blueprint.add_module(module)
return module
+def create_proto_group_modules(blueprint, gn, module_name, target_names):
+ # TODO(lalitm): today, we're only adding a Java lite module because that's
+ # the only one used in practice. In the future, if we need other target types
+ # (e.g. C++, Java full etc.) add them here.
+ bp_module_name = label_to_module_name(module_name) + '_java_protos'
+ module = Module('java_library', bp_module_name, bp_module_name)
+ module.comment = f'''GN: [{', '.join(target_names)}]'''
+ module.proto = {'type': 'lite', 'canonical_path_from_root': False}
+
+ for name in target_names:
+ target = gn.get_target(name)
+ module.srcs.update(gn_utils.label_to_path(src) for src in target.sources)
+ for dep_label in target.transitive_proto_deps:
+ dep = gn.get_target(dep_label)
+ module.srcs.update(gn_utils.label_to_path(src) for src in dep.sources)
+
+ blueprint.add_module(module)
+
+
def _get_cflags(target):
cflags = {flag for flag in target.cflags if re.match(cflag_allowlist, flag)}
cflags |= set("-D%s" % define
@@ -821,6 +856,7 @@ def create_modules_from_target(blueprint, gn, gn_target_name):
return blueprint.modules[bp_module_name]
target = gn.get_target(gn_target_name)
+ name_without_toolchain = gn_utils.label_without_toolchain(target.name)
if target.type == 'executable':
if target.toolchain == gn_utils.HOST_TOOLCHAIN:
module_type = 'cc_binary_host'
@@ -844,12 +880,12 @@ def create_modules_from_target(blueprint, gn, gn_target_name):
if module is None:
return None
elif target.type == 'action':
- if 'gen_merged_sql_metrics' in target.name:
- module = create_merged_sql_metrics_module(blueprint, target)
- elif re.match('.*gen_cc_.*_descriptor$', target.name):
+ if 'gen_amalgamated_sql_metrics' in target.name:
+ module = create_amalgamated_sql_metrics_module(blueprint, target)
+ elif re.match('.*gen_cc_.*_descriptor$', name_without_toolchain):
module = create_cc_proto_descriptor_module(blueprint, target)
- elif target.type == 'action' and gn_utils.label_without_toolchain(
- target.name) == gn_utils.GEN_VERSION_TARGET:
+ elif target.type == 'action' and \
+ name_without_toolchain == gn_utils.GEN_VERSION_TARGET:
module = create_gen_version_module(blueprint, target, bp_module_name)
else:
raise Error('Unhandled action: {}'.format(target.name))
@@ -857,8 +893,8 @@ def create_modules_from_target(blueprint, gn, gn_target_name):
raise Error('Unknown target %s (%s)' % (target.name, target.type))
blueprint.add_module(module)
- module.host_supported = (gn_utils.label_without_toolchain(target.name) in
- target_host_supported)
+ module.host_supported = (name_without_toolchain in target_host_supported)
+ module.vendor_available = (name_without_toolchain in target_vendor_available)
module.init_rc = target_initrc.get(target.name, [])
module.srcs.update(
gn_utils.label_to_path(src)
@@ -875,9 +911,10 @@ def create_modules_from_target(blueprint, gn, gn_target_name):
module.defaults = [defaults_module]
for lib in target.libs:
# Generally library names should be mangled as 'libXXX', unless they
- # are HAL libraries (e.g., android.hardware.health@2.0) or AIDL c++
+ # are HAL libraries (e.g., android.hardware.health@2.0) or AIDL c++ / NDK
# libraries (e.g. "android.hardware.power.stats-V1-cpp")
- android_lib = lib if '@' in lib or "-cpp" in lib else 'lib' + lib
+ android_lib = lib if '@' in lib or "-cpp" in lib or "-ndk" in lib \
+ else 'lib' + lib
if lib in shared_library_allowlist:
module.add_android_shared_lib(android_lib)
if lib in static_library_allowlist:
@@ -905,7 +942,8 @@ def create_modules_from_target(blueprint, gn, gn_target_name):
(type(add_val), key))
# dep_name is an unmangled GN target name (e.g. //foo:bar(toolchain)).
- for dep_name in target.deps | target.source_set_deps | target.proto_deps:
+ all_deps = target.deps | target.source_set_deps | target.transitive_proto_deps
+ for dep_name in all_deps:
# If the dependency refers to a library which we can replace with an
# Android equivalent, stop recursing and patch the dependency in.
# Don't recurse into //buildtools, builtin_deps are intercepted at
@@ -984,7 +1022,6 @@ def create_blueprint_for_targets(gn, desc, targets):
defaults.lto = True
blueprint.add_module(defaults)
- gn = gn_utils.GnParser(desc)
for target in targets:
create_modules_from_target(blueprint, gn, target)
return blueprint
@@ -1033,7 +1070,11 @@ def main():
# perfetto_component.gni is fixed.
# Check for ODR violations
# for target_name in default_targets:
- # checker = gn_utils.ODRChecker(gn, target_name)
+ # checker = gn_utils.ODRChecker(gn, target_name)
+
+ # Add any proto groups to the blueprint.
+ for l_name, t_names in proto_groups.items():
+ create_proto_group_modules(blueprint, gn, l_name, t_names)
output = [
"""// Copyright (C) 2017 The Android Open Source Project
diff --git a/tools/gen_bazel b/tools/gen_bazel
index f4e365040..1f4fbfd3e 100755
--- a/tools/gen_bazel
+++ b/tools/gen_bazel
@@ -25,6 +25,7 @@
from __future__ import print_function
import argparse
+import itertools
import json
import os
import re
@@ -40,9 +41,12 @@ gn_args = ' '.join([
'host_os="linux"',
'is_debug=false',
'is_perfetto_build_generator=true',
- 'enable_perfetto_watchdog=true',
'monolithic_binaries=true',
'target_os="linux"',
+ 'enable_perfetto_heapprofd=false',
+ 'enable_perfetto_traced_perf=false',
+ 'perfetto_force_dcheck="off"',
+ 'enable_perfetto_llvm_demangle=true',
])
# Default targets to translate to the blueprint file.
@@ -62,25 +66,27 @@ public_targets = [
# These targets are required by internal build rules but don't need to be
# exported publicly.
default_targets = [
- '//test:client_api_example',
'//src/ipc:perfetto_ipc',
'//src/ipc/protoc_plugin:ipc_plugin',
'//src/protozero:protozero',
'//src/protozero/protoc_plugin:protozero_plugin',
'//src/protozero/protoc_plugin:cppgen_plugin',
+ '//test:client_api_example',
+ '//tools/proto_filter:proto_filter',
+ '//tools/proto_merger:proto_merger',
] + public_targets
-# Root proto targets (to force discovery of intermediate proto targets).
-# These targets are marked public.
-proto_targets = [
- '//protos/perfetto/trace:merged_trace',
- '//protos/perfetto/trace:non_minimal_lite',
- '//protos/perfetto/config:merged_config',
- '//protos/perfetto/metrics:lite',
- '//protos/perfetto/metrics/android:lite',
- '//protos/perfetto/trace:lite',
- '//protos/perfetto/config:lite',
-]
+# Proto target groups which will be made public.
+proto_groups = {
+ 'config': ['//protos/perfetto/config:source_set'],
+ 'trace': [
+ '//protos/perfetto/trace:non_minimal_source_set',
+ '//protos/perfetto/trace:minimal_source_set'
+ ],
+ 'metrics': ['//protos/perfetto/metrics:source_set',],
+ 'chromium': ['//protos/third_party/chromium:source_set',],
+ 'chrome_metrics': ['//protos/perfetto/metrics/chrome:source_set',],
+}
# Path for the protobuf sources in the standalone build.
buildtools_protobuf_src = '//buildtools/protobuf/src'
@@ -103,24 +109,26 @@ external_deps = {
'PERFETTO_CONFIG.deps.sqlite_ext_percentile'
],
'//gn:zlib': ['PERFETTO_CONFIG.deps.zlib'],
- '//src/trace_processor/metrics:gen_merged_sql_metrics': [[
- ':cc_merged_sql_metrics'
+ '//gn:llvm_demangle': ['PERFETTO_CONFIG.deps.llvm_demangle'],
+ '//src/trace_processor:demangle': ['PERFETTO_CONFIG.deps.demangle_wrapper'],
+ '//src/trace_processor/metrics/sql:gen_amalgamated_sql_metrics': [[
+ ':cc_amalgamated_sql_metrics'
]],
gn_utils.GEN_VERSION_TARGET: ['PERFETTO_CONFIG.deps.version_header'],
}
-def gen_sql_metrics(target):
- label = BazelLabel(get_bazel_label_name(target.name), 'genrule')
+def gen_amalgamated_sql_metrics(target):
+ label = BazelLabel(get_bazel_label_name(target.name), 'perfetto_genrule')
label.srcs += [re.sub('^//', '', x) for x in sorted(target.inputs)]
label.outs += target.outputs
- label.cmd = r'$(location gen_merged_sql_metrics_py) --cpp_out=$@ $(SRCS)'
- label.exec_tools += [':gen_merged_sql_metrics_py']
+ label.cmd = r'$(location gen_amalgamated_sql_metrics_py) --cpp_out=$@ $(SRCS)'
+ label.exec_tools += [':gen_amalgamated_sql_metrics_py']
return [label]
def gen_version_header(target):
- label = BazelLabel(get_bazel_label_name(target.name), 'genrule')
+ label = BazelLabel(get_bazel_label_name(target.name), 'perfetto_genrule')
label.srcs += [re.sub('^//', '', x) for x in sorted(target.inputs)]
label.outs += target.outputs
label.cmd = r'$(location gen_version_header_py)'
@@ -138,8 +146,10 @@ def gen_cc_metrics_descriptor(target):
custom_actions = {
- gn_utils.GEN_VERSION_TARGET: gen_version_header,
- '//src/trace_processor/metrics:gen_merged_sql_metrics': gen_sql_metrics,
+ gn_utils.GEN_VERSION_TARGET:
+ gen_version_header,
+ '//src/trace_processor/metrics/sql:gen_amalgamated_sql_metrics':
+ gen_amalgamated_sql_metrics,
}
# ------------------------------------------------------------------------------
@@ -165,12 +175,14 @@ class BazelLabel(object):
self.tools = []
self.exec_tools = []
self.outs = []
+ self.exports = []
def __lt__(self, other):
if isinstance(other, self.__class__):
return self.name < other.name
- raise TypeError('\'<\' not supported between instances of \'%s\' and \'%s\''
- % (type(self).__name__, type(other).__name__))
+ raise TypeError(
+ '\'<\' not supported between instances of \'%s\' and \'%s\'' %
+ (type(self).__name__, type(other).__name__))
def __str__(self):
"""Converts the object into a Bazel Starlark label."""
@@ -179,8 +191,8 @@ class BazelLabel(object):
res += '%s(\n' % self.type
any_deps = len(self.deps) + len(self.external_deps) > 0
ORD = [
- 'name','srcs', 'hdrs', 'visibility', 'deps', 'outs', 'cmd', 'tools',
- 'exec_tools'
+ 'name', 'srcs', 'hdrs', 'visibility', 'deps', 'outs', 'cmd', 'tools',
+ 'exec_tools', 'exports'
]
hasher = lambda x: sum((99,) + tuple(ord(c) for c in x))
key_sorter = lambda kv: ORD.index(kv[0]) if kv[0] in ORD else hasher(kv[0])
@@ -244,63 +256,49 @@ def get_bazel_label_name(gn_name):
return gn_utils.label_to_target_name_with_path(gn_name)
-def gen_proto_labels(target):
- """ Generates the xx_proto_library label for proto targets.
-
- Bazel requires that each protobuf-related target is modeled with two labels:
- 1. A plugin-agnostic target that defines only the .proto sources and their
- dependencies.
- 2. A plugin-dependent target (e.g. cc_library, cc_protozero_library) that has
- only a dependency on 1 and does NOT refer to any .proto sources.
- """
- assert (target.type == 'proto_library')
-
- def get_sources_label(target_name):
- return re.sub('_(lite|zero|cpp|ipc|source_set|descriptor)$', '',
- get_bazel_label_name(target_name)) + '_protos'
-
- sources_label_name = get_sources_label(target.name)
+def get_bazel_proto_sources_label(target_name):
+ """Converts a GN target name into a Bazel proto label name."""
+ return re.sub('_(lite|zero|cpp|ipc|source_set|descriptor)$', '',
+ get_bazel_label_name(target_name)) + '_protos'
- # Generates 1.
- sources_label = BazelLabel(sources_label_name, 'perfetto_proto_library')
- sources_label.comment = target.name
- assert (all(x.startswith('//') for x in target.sources))
- assert (all(x.endswith('.proto') for x in target.sources))
- sources_label.srcs = sorted([x[2:] for x in target.sources]) # Strip //.
- deps = [
- ':' + get_sources_label(x)
- for x in target.proto_deps
-
- # This is to avoid a dependency-on-self in the case where
- # protos/perfetto/ipc:ipc depends on protos/perfetto/ipc:cpp and both
- # targets resolve to "protos_perfetto_ipc_protos".
- if get_sources_label(x) != sources_label_name
- ]
- sources_label.deps = sorted(deps)
-
- # In Bazel, proto_paths are not a supported concept becauase strong dependency
- # checking is enabled. Instead, we need to depend on the target which includes
- # the proto we want to depend on.
- # For example, we include the proto_path |buildtools_protobuf_src| because we
- # want to depend on the "google/protobuf/descriptor.proto" proto file. This
- # will be exposed by the |protobuf_descriptor_proto| dep.
- if buildtools_protobuf_src in target.proto_paths:
- sources_label.external_deps = [
- 'PERFETTO_CONFIG.deps.protobuf_descriptor_proto'
- ]
+def gen_proto_label(target):
+ """ Generates the xx_proto_library label for proto targets."""
+ assert (target.type == 'proto_library')
- if target.name in proto_targets:
- sources_label.visibility = PUBLIC_VISIBILITY
- else:
- sources_label.visibility = ['PERFETTO_CONFIG.proto_library_visibility']
+ sources_label_name = get_bazel_proto_sources_label(target.name)
# For 'source_set' plugins, we don't want to generate any plugin-dependent
# targets so just return the label of the proto sources only.
if target.proto_plugin == 'source_set':
- return [sources_label]
+ sources_label = BazelLabel(sources_label_name, 'perfetto_proto_library')
+ sources_label.comment = target.name
+ assert (all(x.startswith('//') for x in target.sources))
+ assert (all(x.endswith('.proto') for x in target.sources))
+ sources_label.srcs = sorted([x[2:] for x in target.sources]) # Strip //.
+ sources_label.deps = sorted([
+ ':' + get_bazel_proto_sources_label(x)
+ for x in target.transitive_proto_deps
+ ])
+
+ # In Bazel, proto_paths are not a supported concept becauase strong
+ # dependency checking is enabled. Instead, we need to depend on the target
+ # which includes the proto we want to depend on.
+ # For example, we include the proto_path |buildtools_protobuf_src| because
+ # we want to depend on the "google/protobuf/descriptor.proto" proto file.
+ # This will be exposed by the |protobuf_descriptor_proto| dep.
+ if buildtools_protobuf_src in target.proto_paths:
+ sources_label.external_deps = [
+ 'PERFETTO_CONFIG.deps.protobuf_descriptor_proto'
+ ]
+
+ sources_label.visibility = ['PERFETTO_CONFIG.proto_library_visibility']
- # Generates 2.
+ sources_label.exports = sorted(
+ [':' + get_bazel_proto_sources_label(d) for d in target.proto_exports])
+ return sources_label
+
+ # For all other types of plugins, we need to generate
if target.proto_plugin == 'proto':
plugin_label_type = 'perfetto_cc_proto_library'
elif target.proto_plugin == 'protozero':
@@ -316,28 +314,82 @@ def gen_proto_labels(target):
plugin_label_name = get_bazel_label_name(target.name)
plugin_label = BazelLabel(plugin_label_name, plugin_label_type)
plugin_label.comment = target.name
- plugin_label.deps += [':' + sources_label_name]
# When using the plugins we need to pass down also the transitive deps.
# For instance consider foo.proto including common.proto. The generated
# foo.cc will #include "common.gen.h". Hence the generated cc_protocpp_library
# rule need to pass down the dependency on the target that generates
# common.gen.{cc,h}.
- if target.proto_deps and target.proto_plugin in (
- 'cppgen', 'ipc', 'protozero'):
+ if target.proto_plugin in ('cppgen', 'ipc', 'protozero'):
plugin_label.deps += [
- ':' + get_bazel_label_name(x) for x in target.proto_deps
+ ':' + get_bazel_label_name(x) for x in target.transitive_proto_deps
]
+ # Add any dependencies on source_set targets (i.e. targets containing proto
+ # files). For descriptors, we will have an explicit edge between the
+ # descriptor and source set wheras for other plugin types, this edge is
+ # implicit.
+ if target.proto_plugin == 'descriptor':
+ plugin_label.deps += [
+ ':' + get_bazel_proto_sources_label(x) for x in target.proto_deps
+ ]
+ else:
+ plugin_label.deps += [':' + sources_label_name]
+
+ # Since the descriptor generates an explicit output file which can be
+ # referenced by other targets, we specify a name for it.
if target.proto_plugin == 'descriptor':
plugin_label.outs = [plugin_label_name + '.bin']
- return [sources_label, plugin_label]
+ return plugin_label
+
+
+def gen_proto_group_target(gn, name, target_names):
+ # Get a recursive list of the proto_library targets rooted here which
+ # have src.
+ deps_set = set(target_names)
+ for target_name in target_names:
+ target = gn.get_target(target_name)
+ deps_set.update(target.transitive_proto_deps)
+
+ # First, create a root source set target which references all the child
+ # source set targets. We publish this as well as depending on this in all
+ # subsequent targets.
+ sources_label = BazelLabel(name + '_proto', 'perfetto_proto_library')
+ sources_label.deps = [
+ ':' + get_bazel_proto_sources_label(name)
+ for name in sorted(list(deps_set))
+ ]
+ sources_label.visibility = PUBLIC_VISIBILITY
+ sources_label.comment = f'''[{', '.join(target_names)}]'''
+
+ cc_label = BazelLabel(name + '_cc_proto', 'perfetto_cc_proto_library')
+ cc_label.deps = [':' + sources_label.name]
+ cc_label.visibility = PUBLIC_VISIBILITY
+ cc_label.comment = sources_label.comment
+
+ java_label = BazelLabel(name + '_java_proto', 'perfetto_java_proto_library')
+ java_label.deps = [':' + sources_label.name]
+ java_label.visibility = PUBLIC_VISIBILITY
+ java_label.comment = sources_label.comment
+
+ lite_name = name + '_java_proto_lite'
+ java_lite_label = BazelLabel(lite_name, 'perfetto_java_lite_proto_library')
+ java_lite_label.deps = [':' + sources_label.name]
+ java_lite_label.visibility = PUBLIC_VISIBILITY
+ java_lite_label.comment = sources_label.comment
+
+ py_label = BazelLabel(name + '_py_pb2', 'perfetto_py_proto_library')
+ py_label.deps = [':' + sources_label.name]
+ py_label.visibility = PUBLIC_VISIBILITY
+ py_label.comment = sources_label.comment
+
+ return [sources_label, cc_label, java_label, java_lite_label, py_label]
def gen_target(gn_target):
if gn_target.type == 'proto_library':
- return gen_proto_labels(gn_target)
+ return [gen_proto_label(gn_target)]
elif gn_target.type == 'action':
if gn_target.name in custom_actions:
return custom_actions[gn_target.name](gn_target)
@@ -354,7 +406,7 @@ def gen_target(gn_target):
elif gn_target.type == 'static_library':
bazel_type = 'perfetto_cc_library'
elif gn_target.type == 'source_set':
- bazel_type = 'filegroup'
+ bazel_type = 'perfetto_filegroup'
else:
raise Error('target type not supported: %s' % gn_target.type)
@@ -368,7 +420,7 @@ def gen_target(gn_target):
label.hdrs += [x[2:] for x in gn_target.public_headers]
else:
raise Error('%s: \'public\' currently supported only for cc_library' %
- gn_target.name)
+ gn_target.name)
raw_srcs = [x[2:] for x in gn_target.sources]
if bazel_type == 'perfetto_cc_library':
@@ -401,7 +453,9 @@ def gen_target(gn_target):
label.external_deps += external_deps[dep]
else:
label.deps += [':' + get_bazel_label_name(dep)]
- label.deps += [':' + get_bazel_label_name(x) for x in gn_target.proto_deps]
+ label.deps += [
+ ':' + get_bazel_label_name(x) for x in gn_target.transitive_proto_deps
+ ]
# All items starting with : need to be sorted to the end of the list.
# However, Python makes specifying a comparator function hard so cheat
@@ -443,7 +497,10 @@ def generate_build(gn_desc, targets, extras):
load("@perfetto_cfg//:perfetto_cfg.bzl", "PERFETTO_CONFIG")
load(
"@perfetto//bazel:rules.bzl",
+ "perfetto_build_config_cc_library",
"perfetto_cc_binary",
+ "perfetto_filegroup",
+ "perfetto_genrule",
"perfetto_cc_ipc_library",
"perfetto_cc_library",
"perfetto_cc_proto_descriptor",
@@ -456,6 +513,7 @@ load(
"perfetto_proto_descriptor",
"perfetto_py_binary",
"perfetto_py_library",
+ "perfetto_py_proto_library",
"perfetto_gensignature_internal_only",
)
@@ -498,24 +556,24 @@ exports_files(["NOTICE"])
# ##############################################################################
'''.lstrip()
- # Force discovery of explicilty listed root proto targets.
- for target_name in sorted(proto_targets):
- gn.get_target(target_name)
+ # Generate targets for proto groups.
+ for l_name, t_names in proto_groups.items():
+ res += ''.join(str(x) for x in gen_proto_group_target(gn, l_name, t_names))
+
+ # For any non-source set and non-descriptor targets, ensure the source set
+ # associated to that target is discovered.
+ for target in sorted(itervalues(gn.all_targets)):
+ plugin = target.proto_plugin
+ if plugin is None or plugin == 'source_set' or plugin == 'descriptor':
+ continue
+ gn.get_target(re.sub('(lite|zero|cpp|ipc)$', 'source_set', target.name))
# Generate targets for the transitive set of proto targets.
- # TODO explain deduping here.
- labels = {}
- for target in sorted(itervalues(gn.proto_libs)):
- for label in gen_target(target):
- # Ensure that if the existing target has public visibility, we preserve
- # that in the new label; this ensures that we don't accidentaly reduce
- # the visibility of targets which are meant to be public.
- existing_label = labels.get(label.name)
- if existing_label and existing_label.visibility == PUBLIC_VISIBILITY:
- label.visibility = PUBLIC_VISIBILITY
- labels[label.name] = label
-
- res += ''.join(str(x) for x in sorted(itervalues(labels)))
+ labels = [
+ l for target in sorted(itervalues(gn.proto_libs))
+ for l in gen_target(target)
+ ]
+ res += ''.join(str(x) for x in sorted(labels))
res += '''
# ##############################################################################
@@ -528,11 +586,12 @@ exports_files(["NOTICE"])
res += extras
# Check for ODR violations
- for target_name in default_targets + proto_targets:
+ for target_name in default_targets:
checker = gn_utils.ODRChecker(gn, target_name)
return res
+
def main():
parser = argparse.ArgumentParser(
description='Generate BUILD from a GN description.')
diff --git a/tools/gen_binary_descriptors b/tools/gen_binary_descriptors
index d25d9bd60..dbbf8c732 100755
--- a/tools/gen_binary_descriptors
+++ b/tools/gen_binary_descriptors
@@ -25,14 +25,11 @@ import hashlib
from compat import iteritems
SOURCE_TARGET = [
- (
- 'protos/perfetto/trace_processor/trace_processor.proto',
- 'src/trace_processor/python/perfetto/trace_processor/trace_processor.descriptor'
- ),
- (
- 'protos/perfetto/metrics/metrics.proto',
- 'src/trace_processor/python/perfetto/trace_processor/metrics.descriptor'
+ ('protos/perfetto/trace_processor/trace_processor.proto',
+ 'python/perfetto/trace_processor/trace_processor.descriptor'
),
+ ('protos/perfetto/metrics/metrics.proto',
+ 'python/perfetto/trace_processor/metrics.descriptor'),
]
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
@@ -54,7 +51,6 @@ def find_protoc():
return None
-
def check(source, target):
assert os.path.exists(os.path.join(ROOT_DIR, target)), \
'Output file {} does not exist and so cannot be checked'.format(target)
@@ -75,7 +71,9 @@ def check(source, target):
def generate(source, target, protoc_path):
- with tempfile.NamedTemporaryFile() as fdescriptor:
+ # delete=False + manual unlink is required for Windows. Otherwise the temp
+ # file is kept locked exclusively and unaccassible until it's destroyed.
+ with tempfile.NamedTemporaryFile(delete=False) as fdescriptor:
subprocess.check_call([
protoc_path,
'--include_imports',
@@ -84,10 +82,11 @@ def generate(source, target, protoc_path):
os.path.join(ROOT_DIR, "buildtools", "protobuf", "src"),
'--descriptor_set_out={}'.format(fdescriptor.name),
source,
- ],
- cwd=ROOT_DIR)
+ ], cwd=ROOT_DIR)
s = fdescriptor.read()
+ fdescriptor.close()
+ os.remove(fdescriptor.name)
with open(target, 'wb') as out:
out.write(s)
@@ -105,6 +104,7 @@ def generate(source, target, protoc_path):
source_hash=hash_path(os.path.join(source)),
).encode())
+
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--check-only', action='store_true')
diff --git a/tools/gen_merged_protos b/tools/gen_merged_protos
index 67adf4cc5..a7fc12d69 100755
--- a/tools/gen_merged_protos
+++ b/tools/gen_merged_protos
@@ -22,7 +22,7 @@ import sys
from codecs import open
PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
-SELF_PATH = os.path.relpath(__file__, PROJECT_ROOT)
+SELF_PATH = os.path.relpath(__file__, PROJECT_ROOT).replace('\\', '/')
CONFIG_PROTO_ROOTS = [
'protos/perfetto/common/data_source_descriptor.proto',
@@ -32,7 +32,7 @@ CONFIG_PROTO_ROOTS = [
MERGED_CONFIG_PROTO = 'protos/perfetto/config/perfetto_config.proto'
TRACE_PROTO_ROOTS = CONFIG_PROTO_ROOTS + [
- 'protos/perfetto/trace/trace.proto',
+ 'protos/perfetto/trace/trace.proto',
]
MERGED_TRACE_PROTO = 'protos/perfetto/trace/perfetto_trace.proto'
@@ -52,6 +52,8 @@ REPLACEMENT_HEADER = '''
syntax = "proto2";
package perfetto.protos;
+
+option go_package = "github.com/google/perfetto/perfetto_proto";
'''
diff --git a/tools/gen_merged_sql_metrics.py b/tools/gen_merged_sql_metrics.py
deleted file mode 100755
index eed5d8e2a..000000000
--- a/tools/gen_merged_sql_metrics.py
+++ /dev/null
@@ -1,131 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (C) 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import argparse
-import os
-import sys
-
-# Converts the SQL metrics for trace processor into a C++ header with the SQL
-# as a string constant to allow trace processor to exectue the metrics.
-
-REPLACEMENT_HEADER = '''/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- *******************************************************************************
- * AUTOGENERATED BY tools/gen_merged_sql_metrics - DO NOT EDIT
- *******************************************************************************
- */
-
- #include <string.h>
-'''
-
-NAMESPACE_BEGIN = '''
-namespace perfetto {
-namespace trace_processor {
-namespace metrics {
-namespace sql_metrics {
-'''
-
-FILE_TO_SQL_STRUCT = '''
-struct FileToSql {
- const char* path;
- const char* sql;
-};
-'''
-
-NAMESPACE_END = '''
-} // namespace sql_metrics
-} // namespace metrics
-} // namespace trace_processor
-} // namsepace perfetto
-'''
-
-
-def filename_to_variable(filename):
- return "k" + "".join([x.capitalize() for x in filename.split("_")])
-
-
-def main():
- parser = argparse.ArgumentParser()
- parser.add_argument('--cpp_out', required=True)
- parser.add_argument('sql_files', nargs='*')
- args = parser.parse_args()
-
- root_path = os.path.commonprefix([os.path.abspath(x) for x in args.sql_files])
-
- # Extract the SQL output from each file.
- sql_outputs = {}
- for file_name in args.sql_files:
- with open(file_name, 'r') as f:
- relpath = os.path.relpath(file_name, root_path)
- sql_outputs[relpath] = "".join(
- x for x in f.readlines() if not x.startswith('--'))
-
- with open(args.cpp_out, 'w+') as output:
- output.write(REPLACEMENT_HEADER)
- output.write(NAMESPACE_BEGIN)
-
- # Create the C++ variable for each SQL file.
- for path, sql in sql_outputs.items():
- name = os.path.basename(path)
- variable = filename_to_variable(os.path.splitext(name)[0])
- output.write('\nconst char {}[] = '.format(variable))
- # MSVC doesn't like string literals that are individually longer than 16k.
- # However it's still fine "if" "we" "concatenate" "many" "of" "them".
- # This code splits the sql in string literals of ~1000 chars each.
- line_groups = ['']
- for line in sql.split('\n'):
- line_groups[-1] += line + '\n'
- if len(line_groups[-1]) > 1000:
- line_groups.append('')
-
- for line in line_groups:
- output.write('R"_d3l1m1t3r_({})_d3l1m1t3r_"\n'.format(line))
- output.write(';\n')
-
- output.write(FILE_TO_SQL_STRUCT)
-
- # Create mapping of filename to variable name for each variable.
- output.write("\nconst FileToSql kFileToSql[] = {")
- for path in sql_outputs.keys():
- name = os.path.basename(path)
- variable = filename_to_variable(os.path.splitext(name)[0])
-
- # This is for Windows which has \ as a path separator.
- path = path.replace("\\", "/")
- output.write('\n {{"{}", {}}},\n'.format(path, variable))
- output.write("};\n")
-
- output.write(NAMESPACE_END)
-
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/tools/gen_ui_imports b/tools/gen_ui_imports
new file mode 100755
index 000000000..1f10a38ff
--- /dev/null
+++ b/tools/gen_ui_imports
@@ -0,0 +1,77 @@
+#!/usr/bin/env python3
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Generates TypeScript files that import all subdirectories.
+This is useful for plugins/extensions. If you have two modules:
+- core/
+- plugins/myplugin/
+In general you would like the dependency to only go one way:
+- plugins/myplugin/ -> core/
+But you still need some index file to import all plugins for the sake of
+bundling. This avoids having to manually edit core/ for every
+plugin you add.
+"""
+
+from __future__ import print_function
+
+import os
+import argparse
+import subprocess
+import sys
+
+ROOT_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
+UI_SRC_DIR = os.path.join(ROOT_DIR, 'ui', 'src')
+
+def gen_imports(input_dir, output_path):
+ paths = [os.path.join(input_dir, p) for p in os.listdir(input_dir)]
+ paths = [p for p in paths if os.path.isdir(p)]
+ paths.sort()
+
+ lines = []
+ for path in paths:
+ rel_path = os.path.relpath(path, os.path.dirname(output_path))
+ lines.append(f"import '{rel_path}';")
+ expected = '\n'.join(lines)
+
+ with open(output_path, 'w') as f:
+ f.write(expected)
+ return True
+
+def main():
+ parser = argparse.ArgumentParser(description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter)
+ parser.add_argument('INPUT')
+ parser.add_argument('--out', required=True)
+ args = parser.parse_args()
+ input_dir = args.INPUT
+ output_path = args.out
+
+ if not os.path.isdir(input_dir):
+ print(f'INPUT argument {input_dir} must be a directory')
+ exit(1)
+
+ output_dir = os.path.dirname(output_path)
+ if output_dir and not os.path.isdir(output_dir):
+ print(f'--out ({output_path}) parent directory ({output_dir}) must exist')
+ exit(1)
+ if os.path.isdir(output_path):
+ print(f'--out ({output_path}) should not be a directory')
+ exit(1)
+
+ success = gen_imports(input_dir, output_path)
+ return 0 if success else 1
+
+if __name__ == '__main__':
+ exit(main())
diff --git a/tools/get_perfetto_prebuilt.py b/tools/get_perfetto_prebuilt.py
new file mode 100644
index 000000000..99f3459d8
--- /dev/null
+++ b/tools/get_perfetto_prebuilt.py
@@ -0,0 +1,122 @@
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""
+This source defines a self-contained function to fetch a perfetto prebuilt.
+
+This function is copy/pasted by //tools/roll-prebuilts in different places:
+- Into the //tools/{trace_processor, traceconv} scripts, which are just plain
+ wrappers around executables.
+- Into the //tools/{heap_profiler, record_android_trace} scripts, which contain
+ some other hand-written python code.
+In both cases toll-prebuilts copies this source (together with a manifest) into
+a section annotated with "BEGIN_SECTION_GENERATED_BY(roll-prebuilts)" / END... .
+The automated-copy-paste is to keep those script hermetic, so people can just
+download and run them without checking out the repo.
+
+The manifest argument looks as follows in the generated files:
+PERFETTO_PREBUILT_MANIFEST = [{
+ 'tool': 'trace_to_text',
+ 'arch': 'mac-amd64',
+ 'file_name': 'trace_to_text',
+ 'file_size': 7087080,
+ 'url': https://commondatastorage.googleapis.com/.../trace_to_text',
+ 'sha256': 7d957c005b0dc130f5bd855d6cec27e060d38841b320d04840afc569f9087490',
+ 'platform': 'darwin',
+ 'machine': 'x86_64'
+ },
+ ...
+]
+
+The intended usage is:
+
+bin_path = get_perfetto_prebuilt('trace_processor_shell')
+subprocess.call(bin_path, ...)
+"""
+
+from logging import exception
+
+PERFETTO_PREBUILT_MANIFEST = []
+
+# COPIED_SECTION_START_MARKER
+
+
+# DO NOT EDIT. If you wish to make edits to this code, you need to change only
+# //tools/get_perfetto_prebuilt.py and run /tools/roll-prebuilts to regenerate
+# all the others scripts this is embedded into.
+def get_perfetto_prebuilt(tool_name, soft_fail=False, arch=None):
+ """ Downloads the prebuilt, if necessary, and returns its path on disk. """
+
+ # The first time this is invoked, it downloads the |url| and caches it into
+ # ~/.perfetto/prebuilts/$tool_name. On subsequent invocations it just runs the
+ # cached version.
+ def download_or_get_cached(file_name, url, sha256):
+ import os, hashlib, subprocess
+ dir = os.path.join(
+ os.path.expanduser('~'), '.local', 'share', 'perfetto', 'prebuilts')
+ os.makedirs(dir, exist_ok=True)
+ bin_path = os.path.join(dir, file_name)
+ sha256_path = os.path.join(dir, file_name + '.sha256')
+ needs_download = True
+
+ # Avoid recomputing the SHA-256 on each invocation. The SHA-256 of the last
+ # download is cached into file_name.sha256, just check if that matches.
+ if os.path.exists(bin_path) and os.path.exists(sha256_path):
+ with open(sha256_path, 'rb') as f:
+ digest = f.read().decode()
+ if digest == sha256:
+ needs_download = False
+
+ if needs_download:
+ # Either the filed doesn't exist or the SHA256 doesn't match.
+ tmp_path = bin_path + '.tmp'
+ print('Downloading ' + url)
+ subprocess.check_call(['curl', '-f', '-L', '-#', '-o', tmp_path, url])
+ with open(tmp_path, 'rb') as fd:
+ actual_sha256 = hashlib.sha256(fd.read()).hexdigest()
+ if actual_sha256 != sha256:
+ raise Exception('Checksum mismatch for %s (actual: %s, expected: %s)' %
+ (url, actual_sha256, sha256))
+ os.chmod(tmp_path, 0o755)
+ os.rename(tmp_path, bin_path)
+ with open(sha256_path, 'w') as f:
+ f.write(sha256)
+ return bin_path
+ # --- end of download_or_get_cached() ---
+
+ # --- get_perfetto_prebuilt() function starts here. ---
+ import os, platform, sys
+ plat = sys.platform.lower()
+ machine = platform.machine().lower()
+ manifest_entry = None
+ for entry in PERFETTO_PREBUILT_MANIFEST:
+ # If the caller overrides the arch, just match that (for Android prebuilts).
+ if arch and entry.get('arch') == arch:
+ manifest_entry = entry
+ break
+ # Otherwise guess the local machine arch.
+ if entry.get('tool') == tool_name and entry.get(
+ 'platform') == plat and machine in entry.get('machine', []):
+ manifest_entry = entry
+ break
+ if manifest_entry is None:
+ if soft_fail:
+ return None
+ raise Exception(
+ ('No prebuilts available for %s-%s\n' % (plat, machine)) +
+ 'See https://perfetto.dev/docs/contributing/build-instructions')
+
+ return download_or_get_cached(
+ file_name=manifest_entry['file_name'],
+ url=manifest_entry['url'],
+ sha256=manifest_entry['sha256'])
diff --git a/tools/gn b/tools/gn
index fc0f3542e..51141bf22 100755
--- a/tools/gn
+++ b/tools/gn
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env python3
# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,5 +13,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-CMD="gn"
-source "$(dirname "${BASH_SOURCE[0]}")/run-buildtools-binary.sh"
+import os
+import sys
+
+ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+sys.path.append(ROOT_DIR)
+__package__ = 'tools'
+from .run_buildtools_binary import run_buildtools_binary
+run_buildtools_binary(['gn'] + sys.argv[1:])
diff --git a/tools/gn_utils.py b/tools/gn_utils.py
index 85f0ee5d8..0b9a9d38d 100644
--- a/tools/gn_utils.py
+++ b/tools/gn_utils.py
@@ -60,7 +60,9 @@ def repo_root():
def _tool_path(name):
- return os.path.join(repo_root(), 'tools', name)
+ wrapper = os.path.abspath(
+ os.path.join(repo_root(), 'tools', 'run_buildtools_binary.py'))
+ return ['python3', wrapper, name]
def prepare_out_directory(gn_args, name, root=repo_root()):
@@ -75,18 +77,17 @@ def prepare_out_directory(gn_args, name, root=repo_root()):
except OSError as e:
if e.errno != errno.EEXIST:
raise
- _check_command_output([_tool_path('gn'), 'gen', out,
- '--args=%s' % gn_args],
- cwd=repo_root())
+ _check_command_output(
+ _tool_path('gn') + ['gen', out, '--args=%s' % gn_args], cwd=repo_root())
return out
def load_build_description(out):
"""Creates the JSON build description by running GN."""
- desc = _check_command_output([
- _tool_path('gn'), 'desc', out, '--format=json', '--all-toolchains', '//*'
- ],
- cwd=repo_root())
+ desc = _check_command_output(
+ _tool_path('gn') +
+ ['desc', out, '--format=json', '--all-toolchains', '//*'],
+ cwd=repo_root())
return json.loads(desc)
@@ -111,14 +112,14 @@ def build_targets(out, targets, quiet=False):
targets = [t.replace('//', '') for t in targets]
with open(os.devnull, 'w') as devnull:
stdout = devnull if quiet else None
- subprocess.check_call(
- [_tool_path('ninja')] + targets, cwd=out, stdout=stdout)
+ cmd = _tool_path('ninja') + targets
+ subprocess.check_call(cmd, cwd=os.path.abspath(out), stdout=stdout)
def compute_source_dependencies(out):
"""For each source file, computes a set of headers it depends on."""
- ninja_deps = _check_command_output([_tool_path('ninja'), '-t', 'deps'],
- cwd=out)
+ ninja_deps = _check_command_output(
+ _tool_path('ninja') + ['-t', 'deps'], cwd=out)
deps = {}
current_source = None
for line in ninja_deps.split('\n'):
@@ -244,7 +245,8 @@ class ODRChecker(object):
for ssdep in target.source_set_deps:
name_and_path = '%s (via %s)' % (target_name, path)
self.source_sets[ssdep].add(name_and_path)
- deps = set(target.deps).union(target.proto_deps) - self.deps_visited
+ deps = set(target.deps).union(
+ target.transitive_proto_deps) - self.deps_visited
for dep_name in deps:
dep = self.gn.get_target(dep_name)
if dep.type == 'executable':
@@ -309,6 +311,7 @@ class GnParser(object):
# This is typically: 'proto', 'protozero', 'ipc'.
self.proto_plugin = None
self.proto_paths = set()
+ self.proto_exports = set()
self.sources = set()
# TODO(primiano): consider whether the public section should be part of
@@ -330,7 +333,8 @@ class GnParser(object):
self.include_dirs = set()
self.ldflags = set()
self.source_set_deps = set() # Transitive set of source_set deps.
- self.proto_deps = set() # Transitive set of protobuf deps.
+ self.proto_deps = set()
+ self.transitive_proto_deps = set()
# Deps on //gn:xxx have this flag set to True. These dependencies
# are special because they pull third_party code from buildtools/.
@@ -356,7 +360,8 @@ class GnParser(object):
def update(self, other):
for key in ('cflags', 'defines', 'deps', 'include_dirs', 'ldflags',
- 'source_set_deps', 'proto_deps', 'libs', 'proto_paths'):
+ 'source_set_deps', 'proto_deps', 'transitive_proto_deps',
+ 'libs', 'proto_paths'):
self.__dict__[key].update(other.__dict__.get(key, []))
def __init__(self, gn_desc):
@@ -394,12 +399,13 @@ class GnParser(object):
target.is_third_party_dep_ = True
return target
- proto_target_type, proto_desc = self.get_proto_target_type_(target)
+ proto_target_type, proto_desc = self.get_proto_target_type(target)
if proto_target_type is not None:
self.proto_libs[target.name] = target
target.type = 'proto_library'
target.proto_plugin = proto_target_type
target.proto_paths.update(self.get_proto_paths(proto_desc))
+ target.proto_exports.update(self.get_proto_exports(proto_desc))
target.sources.update(proto_desc.get('sources', []))
assert (all(x.endswith('.proto') for x in target.sources))
elif target.type == 'source_set':
@@ -440,11 +446,9 @@ class GnParser(object):
target.deps.add(dep_name)
elif dep.type == 'proto_library':
target.proto_deps.add(dep_name)
+ target.transitive_proto_deps.add(dep_name)
target.proto_paths.update(dep.proto_paths)
-
- # Don't bubble deps for action targets
- if target.type != 'action':
- target.proto_deps.update(dep.proto_deps) # Bubble up deps.
+ target.transitive_proto_deps.update(dep.transitive_proto_deps)
elif dep.type == 'source_set':
target.source_set_deps.add(dep_name)
target.update(dep) # Bubble up source set's cflags/ldflags etc.
@@ -458,24 +462,17 @@ class GnParser(object):
return target
+ def get_proto_exports(self, proto_desc):
+ # exports in metadata will be available for source_set targets.
+ metadata = proto_desc.get('metadata', {})
+ return metadata.get('exports', [])
+
def get_proto_paths(self, proto_desc):
# import_dirs in metadata will be available for source_set targets.
metadata = proto_desc.get('metadata', {})
- import_dirs = metadata.get('import_dirs', [])
- if import_dirs:
- return import_dirs
-
- # For all non-source-set targets, we need to parse the command line
- # of the protoc invocation.
- proto_paths = []
- args = proto_desc.get('args', [])
- for i, arg in enumerate(args):
- if arg != '--proto_path':
- continue
- proto_paths.append(re.sub('^../../', '//', args[i + 1]))
- return proto_paths
+ return metadata.get('import_dirs', [])
- def get_proto_target_type_(self, target):
+ def get_proto_target_type(self, target):
""" Checks if the target is a proto library and return the plugin.
Returns:
@@ -496,7 +493,7 @@ class GnParser(object):
return 'descriptor', desc
# Source set proto targets have a non-empty proto_library_sources in the
- # metadata of the descirption.
+ # metadata of the description.
metadata = desc.get('metadata', {})
if 'proto_library_sources' in metadata:
return 'source_set', desc
diff --git a/tools/heap_profile b/tools/heap_profile
index b635a1208..65a3213f7 100755
--- a/tools/heap_profile
+++ b/tools/heap_profile
@@ -29,15 +29,6 @@ import sys
import tempfile
import time
import uuid
-import platform
-
-
-TRACE_TO_TEXT_SHAS = {
- 'linux': '7e3e10dfb324e31723efd63ac25037856e06eba0',
- 'mac': '21f0f42dd019b4f09addd404a114fbf2322ca8a4',
-}
-TRACE_TO_TEXT_PATH = tempfile.gettempdir()
-TRACE_TO_TEXT_BASE_URL = ('https://storage.googleapis.com/perfetto/')
NULL = open(os.devnull)
NOOUT = {
@@ -47,37 +38,6 @@ NOOUT = {
UUID = str(uuid.uuid4())[-6:]
-def check_hash(file_name, sha_value):
- file_hash = hashlib.sha1()
- with open(file_name, 'rb') as fd:
- while True:
- chunk = fd.read(4096)
- if not chunk:
- break
- file_hash.update(chunk)
- return file_hash.hexdigest() == sha_value
-
-
-def load_trace_to_text(os_name):
- sha_value = TRACE_TO_TEXT_SHAS[os_name]
- file_name = 'trace_to_text-' + os_name + '-' + sha_value
- local_file = os.path.join(TRACE_TO_TEXT_PATH, file_name)
-
- if os.path.exists(local_file):
- if not check_hash(local_file, sha_value):
- os.remove(local_file)
- else:
- return local_file
-
- url = TRACE_TO_TEXT_BASE_URL + file_name
- subprocess.check_call(['curl', '-L', '-#', '-o', local_file, url])
- if not check_hash(local_file, sha_value):
- os.remove(local_file)
- raise ValueError("Invalid signature.")
- os.chmod(local_file, 0o755)
- return local_file
-
-
PACKAGES_LIST_CFG = '''data_sources {
config {
name: "android.packages_list"
@@ -120,6 +80,7 @@ PROFILE_LOCAL_PATH = os.path.join(tempfile.gettempdir(), UUID)
IS_INTERRUPTED = False
+
def sigint_handler(sig, frame):
global IS_INTERRUPTED
IS_INTERRUPTED = True
@@ -128,42 +89,71 @@ def sigint_handler(sig, frame):
def print_no_profile_error():
print("No profiles generated", file=sys.stderr)
print(
- "If this is unexpected, check "
- "https://perfetto.dev/docs/data-sources/native-heap-profiler#troubleshooting.",
- file=sys.stderr)
+ "If this is unexpected, check "
+ "https://perfetto.dev/docs/data-sources/native-heap-profiler#troubleshooting.",
+ file=sys.stderr)
+
def known_issues_url(number):
return ('https://perfetto.dev/docs/data-sources/native-heap-profiler'
'#known-issues-android{}'.format(number))
+
KNOWN_ISSUES = {
- '10': known_issues_url(10),
- 'Q': known_issues_url(10),
- '11': known_issues_url(11),
- 'R': known_issues_url(11),
+ '10': known_issues_url(10),
+ 'Q': known_issues_url(10),
+ '11': known_issues_url(11),
+ 'R': known_issues_url(11),
}
+
def maybe_known_issues():
release_or_codename = subprocess.check_output(
- ['adb', 'shell', 'getprop', 'ro.build.version.release_or_codename']
- ).decode('utf-8').strip()
+ ['adb', 'shell', 'getprop',
+ 'ro.build.version.release_or_codename']).decode('utf-8').strip()
return KNOWN_ISSUES.get(release_or_codename, None)
+
SDK = {
'R': 30,
}
+
def release_or_newer(release):
- sdk = int(subprocess.check_output(
- ['adb', 'shell', 'getprop', 'ro.system.build.version.sdk']
- ).decode('utf-8').strip())
+ sdk = int(
+ subprocess.check_output(
+ ['adb', 'shell', 'getprop',
+ 'ro.system.build.version.sdk']).decode('utf-8').strip())
if sdk >= SDK[release]:
return True
codename = subprocess.check_output(
- ['adb', 'shell', 'getprop', 'ro.build.version.codename']
- ).decode('utf-8').strip()
+ ['adb', 'shell', 'getprop',
+ 'ro.build.version.codename']).decode('utf-8').strip()
return codename == release
+
+ORDER = ['-n', '-p', '-i', '-o']
+
+
+def arg_order(action):
+ result = len(ORDER)
+ for opt in action.option_strings:
+ if opt in ORDER:
+ result = min(ORDER.index(opt), result)
+ return result, action.option_strings[0].strip('-')
+
+
+def print_options(parser):
+ for action in sorted(parser._actions, key=arg_order):
+ if action.help is argparse.SUPPRESS:
+ continue
+ opts = ', '.join('`' + x + '`' for x in action.option_strings)
+ metavar = '' if action.metavar is None else ' _' + action.metavar + '_'
+ print('{}{}'.format(opts, metavar))
+ print(': {}'.format(action.help))
+ print()
+
+
def main(argv):
parser = argparse.ArgumentParser()
parser.add_argument(
@@ -210,14 +200,12 @@ def main(argv):
parser.add_argument(
"--all-heaps",
action="store_true",
- help="Collect allocations from all heaps registered by target."
- )
+ help="Collect allocations from all heaps registered by target.")
parser.add_argument(
"--no-android-tree-symbolization",
action="store_true",
help="Do not symbolize using currently lunched target in the "
- "Android tree."
- )
+ "Android tree.")
parser.add_argument(
"--disable-selinux",
action="store_true",
@@ -294,8 +282,13 @@ def main(argv):
help="Output directory.",
metavar="DIRECTORY",
default=None)
+ parser.add_argument(
+ "--print-options", action="store_true", help=argparse.SUPPRESS)
args = parser.parse_args()
+ if args.print_options:
+ print_options(parser)
+ return 0
fail = False
if args.block_client and args.no_block_client:
print(
@@ -325,8 +318,8 @@ def main(argv):
target_cfg += CFG_INDENT + "block_client: true\n"
if args.block_client_timeout:
target_cfg += (
- CFG_INDENT + "block_client_timeout_us: %s\n" % args.block_client_timeout
- )
+ CFG_INDENT +
+ "block_client_timeout_us: %s\n" % args.block_client_timeout)
if args.no_startup:
target_cfg += CFG_INDENT + "no_startup: true\n"
if args.no_running:
@@ -374,25 +367,9 @@ def main(argv):
# Do this AFTER print_config so we do not download trace_to_text only to
# print out the config.
- has_trace_to_text = True
if trace_to_text_binary is None:
- os_name = None
- if sys.platform.startswith('linux'):
- os_name = 'linux'
- elif sys.platform.startswith('darwin'):
- os_name = 'mac'
- elif sys.platform.startswith('win32'):
- has_trace_to_text = False
- else:
- print("Invalid platform: {}".format(sys.platform), file=sys.stderr)
- return 1
-
- arch = platform.machine()
- if arch not in ['x86_64', 'amd64']:
- has_trace_to_text = False
-
- if has_trace_to_text:
- trace_to_text_binary = load_trace_to_text(os_name)
+ trace_to_text_binary = get_perfetto_prebuilt(
+ 'trace_to_text', soft_fail=True)
known_issues = maybe_known_issues()
if known_issues:
@@ -405,8 +382,8 @@ def main(argv):
if uuid_trace:
profile_device_path = '/data/misc/perfetto-traces/profile-' + UUID
else:
- user = subprocess.check_output(
- ['adb', 'shell', 'whoami']).decode('utf-8').strip()
+ user = subprocess.check_output(['adb', 'shell',
+ 'whoami']).decode('utf-8').strip()
profile_device_path = '/data/misc/perfetto-traces/profile-' + user
perfetto_cmd = ('CFG=\'{cfg}\'; echo ${{CFG}} | '
@@ -434,18 +411,17 @@ def main(argv):
os.mkdir(profile_target)
if not os.path.isdir(profile_target):
- print("Output directory {} not found".format(profile_target),
- file=sys.stderr)
+ print(
+ "Output directory {} not found".format(profile_target), file=sys.stderr)
return 1
if os.listdir(profile_target):
- print("Output directory {} not empty".format(profile_target),
- file=sys.stderr)
+ print(
+ "Output directory {} not empty".format(profile_target), file=sys.stderr)
return 1
perfetto_pid = subprocess.check_output(
- ['adb', 'exec-out',
- perfetto_cmd.format(cfg=cfg)]).strip()
+ ['adb', 'exec-out', perfetto_cmd.format(cfg=cfg)]).strip()
try:
perfetto_pid = int(perfetto_pid.strip())
except ValueError:
@@ -476,8 +452,8 @@ def main(argv):
time.sleep(1)
subprocess.check_call(
['adb', 'pull', '/data/local/tmp/heapprofd_profile', profile_target])
- print(
- "Pulled simpleperf profile to " + profile_target + "/heapprofd_profile")
+ print("Pulled simpleperf profile to " + profile_target +
+ "/heapprofd_profile")
# Wait for perfetto cmd to return.
while exists:
@@ -486,15 +462,17 @@ def main(argv):
time.sleep(1)
profile_host_path = os.path.join(profile_target, 'raw-trace')
- subprocess.check_call(
- ['adb', 'pull', profile_device_path, profile_host_path], stdout=NULL)
+ subprocess.check_call(['adb', 'pull', profile_device_path, profile_host_path],
+ stdout=NULL)
if uuid_trace:
- subprocess.check_call(
- ['adb', 'shell', 'rm', profile_device_path], stdout=NULL)
+ subprocess.check_call(['adb', 'shell', 'rm', profile_device_path],
+ stdout=NULL)
- if not has_trace_to_text:
+ if trace_to_text_binary is None:
print('Wrote profile to {}'.format(profile_host_path))
- print('This file can be opened using the Perfetto UI, https://ui.perfetto.dev')
+ print(
+ 'This file can be opened using the Perfetto UI, https://ui.perfetto.dev'
+ )
return 0
binary_path = os.getenv('PERFETTO_BINARY_PATH')
@@ -517,29 +495,32 @@ def main(argv):
with open(os.path.join(profile_target, 'symbols'), 'w') as fd:
ret = subprocess.call([
trace_to_text_binary, 'symbolize',
- os.path.join(profile_target, 'raw-trace')],
- env=dict(os.environ, PERFETTO_BINARY_PATH=binary_path),
- stdout=fd)
+ os.path.join(profile_target, 'raw-trace')
+ ],
+ env=dict(
+ os.environ, PERFETTO_BINARY_PATH=binary_path),
+ stdout=fd)
if ret == 0:
concat_files.append(os.path.join(profile_target, 'symbols'))
else:
- print("Failed to symbolize. Continuing without symbols.",
- file=sys.stderr)
+ print("Failed to symbolize. Continuing without symbols.", file=sys.stderr)
proguard_map = os.getenv('PERFETTO_PROGUARD_MAP')
if proguard_map is not None:
with open(os.path.join(profile_target, 'deobfuscation-packets'), 'w') as fd:
ret = subprocess.call([
trace_to_text_binary, 'deobfuscate',
- os.path.join(profile_target, 'raw-trace')],
- env=dict(os.environ, PERFETTO_PROGUARD_MAP=proguard_map),
- stdout=fd)
+ os.path.join(profile_target, 'raw-trace')
+ ],
+ env=dict(
+ os.environ, PERFETTO_PROGUARD_MAP=proguard_map),
+ stdout=fd)
if ret == 0:
- concat_files.append(
- os.path.join(profile_target, 'deobfuscation-packets'))
+ concat_files.append(os.path.join(profile_target, 'deobfuscation-packets'))
else:
- print("Failed to deobfuscate. Continuing without deobfuscated.",
- file=sys.stderr)
+ print(
+ "Failed to deobfuscate. Continuing without deobfuscated.",
+ file=sys.stderr)
if len(concat_files) > 1:
with open(os.path.join(profile_target, 'symbolized-trace'), 'wb') as out:
@@ -570,27 +551,171 @@ def main(argv):
for profile_file in profile_files:
shutil.copy(os.path.join(profile_path, profile_file), profile_target)
- subprocess.check_call(
- ['gzip'] +
- [os.path.join(profile_target, x) for x in profile_files])
-
symlink_path = None
- if args.output is None:
- symlink_path = os.path.join(
- os.path.dirname(profile_target), "heap_profile-latest")
- if os.path.lexists(symlink_path):
- os.unlink(symlink_path)
- os.symlink(profile_target, symlink_path)
+ if not sys.platform.startswith('win'):
+ subprocess.check_call(
+ ['gzip'] + [os.path.join(profile_target, x) for x in profile_files])
+ if args.output is None:
+ symlink_path = os.path.join(
+ os.path.dirname(profile_target), "heap_profile-latest")
+ if os.path.lexists(symlink_path):
+ os.unlink(symlink_path)
+ os.symlink(profile_target, symlink_path)
if symlink_path is not None:
- print("Wrote profiles to {} (symlink {})".format(
- profile_target, symlink_path))
+ print("Wrote profiles to {} (symlink {})".format(profile_target,
+ symlink_path))
else:
print("Wrote profiles to {}".format(profile_target))
- print("These can be viewed using pprof. Googlers: head to pprof/ and "
- "upload them.")
-
+ print("The raw-trace file can be viewed using https://ui.perfetto.dev.")
+ print("The heap_dump.* files can be viewed using pprof/ (Googlers only) " +
+ "or https://www.speedscope.app/.")
+ print("The two above are equivalent. The raw-trace contains the union of " +
+ "all the heap dumps.")
+
+
+# BEGIN_SECTION_GENERATED_BY(roll-prebuilts)
+# Revision: v25.0
+PERFETTO_PREBUILT_MANIFEST = [{
+ 'tool':
+ 'trace_to_text',
+ 'arch':
+ 'mac-amd64',
+ 'file_name':
+ 'trace_to_text',
+ 'file_size':
+ 6525752,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/mac-amd64/trace_to_text',
+ 'sha256':
+ '64ccf6bac87825145691c6533412e514891f82300d68ff7ce69e8d2ca69aaf62',
+ 'platform':
+ 'darwin',
+ 'machine': ['x86_64']
+}, {
+ 'tool':
+ 'trace_to_text',
+ 'arch':
+ 'mac-arm64',
+ 'file_name':
+ 'trace_to_text',
+ 'file_size':
+ 5661424,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/mac-arm64/trace_to_text',
+ 'sha256':
+ 'fbb6d256c96cdc296f2faec2965d16a1527c4900e66a33aca979ff1c336a9f2f',
+ 'platform':
+ 'darwin',
+ 'machine': ['arm64']
+}, {
+ 'tool':
+ 'trace_to_text',
+ 'arch':
+ 'windows-amd64',
+ 'file_name':
+ 'trace_to_text.exe',
+ 'file_size':
+ 5925888,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/windows-amd64/trace_to_text.exe',
+ 'sha256':
+ '29e50ec4d8e28c7c322ba13273afcce80c63fe7d9f182b83af0e2077b4d2b952',
+ 'platform':
+ 'win32',
+ 'machine': ['amd64']
+}, {
+ 'tool':
+ 'trace_to_text',
+ 'arch':
+ 'linux-amd64',
+ 'file_name':
+ 'trace_to_text',
+ 'file_size':
+ 6939560,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-amd64/trace_to_text',
+ 'sha256':
+ '109f4ff3bbd47633b0c08a338f1230e69d529ddf1584656ed45d8a59acaaabeb',
+ 'platform':
+ 'linux',
+ 'machine': ['x86_64']
+}]
+
+
+# DO NOT EDIT. If you wish to make edits to this code, you need to change only
+# //tools/get_perfetto_prebuilt.py and run /tools/roll-prebuilts to regenerate
+# all the others scripts this is embedded into.
+def get_perfetto_prebuilt(tool_name, soft_fail=False, arch=None):
+ """ Downloads the prebuilt, if necessary, and returns its path on disk. """
+
+ # The first time this is invoked, it downloads the |url| and caches it into
+ # ~/.perfetto/prebuilts/$tool_name. On subsequent invocations it just runs the
+ # cached version.
+ def download_or_get_cached(file_name, url, sha256):
+ import os, hashlib, subprocess
+ dir = os.path.join(
+ os.path.expanduser('~'), '.local', 'share', 'perfetto', 'prebuilts')
+ os.makedirs(dir, exist_ok=True)
+ bin_path = os.path.join(dir, file_name)
+ sha256_path = os.path.join(dir, file_name + '.sha256')
+ needs_download = True
+
+ # Avoid recomputing the SHA-256 on each invocation. The SHA-256 of the last
+ # download is cached into file_name.sha256, just check if that matches.
+ if os.path.exists(bin_path) and os.path.exists(sha256_path):
+ with open(sha256_path, 'rb') as f:
+ digest = f.read().decode()
+ if digest == sha256:
+ needs_download = False
+
+ if needs_download:
+ # Either the filed doesn't exist or the SHA256 doesn't match.
+ tmp_path = bin_path + '.tmp'
+ print('Downloading ' + url)
+ subprocess.check_call(['curl', '-f', '-L', '-#', '-o', tmp_path, url])
+ with open(tmp_path, 'rb') as fd:
+ actual_sha256 = hashlib.sha256(fd.read()).hexdigest()
+ if actual_sha256 != sha256:
+ raise Exception('Checksum mismatch for %s (actual: %s, expected: %s)' %
+ (url, actual_sha256, sha256))
+ os.chmod(tmp_path, 0o755)
+ os.rename(tmp_path, bin_path)
+ with open(sha256_path, 'w') as f:
+ f.write(sha256)
+ return bin_path
+ # --- end of download_or_get_cached() ---
+
+ # --- get_perfetto_prebuilt() function starts here. ---
+ import os, platform, sys
+ plat = sys.platform.lower()
+ machine = platform.machine().lower()
+ manifest_entry = None
+ for entry in PERFETTO_PREBUILT_MANIFEST:
+ # If the caller overrides the arch, just match that (for Android prebuilts).
+ if arch and entry.get('arch') == arch:
+ manifest_entry = entry
+ break
+ # Otherwise guess the local machine arch.
+ if entry.get('tool') == tool_name and entry.get(
+ 'platform') == plat and machine in entry.get('machine', []):
+ manifest_entry = entry
+ break
+ if manifest_entry is None:
+ if soft_fail:
+ return None
+ raise Exception(
+ ('No prebuilts available for %s-%s\n' % (plat, machine)) +
+ 'See https://perfetto.dev/docs/contributing/build-instructions')
+
+ return download_or_get_cached(
+ file_name=manifest_entry['file_name'],
+ url=manifest_entry['url'],
+ sha256=manifest_entry['sha256'])
+
+
+# END_SECTION_GENERATED_BY(roll-prebuilts)
if __name__ == '__main__':
sys.exit(main(sys.argv))
diff --git a/tools/idle_alloc.cc b/tools/idle_alloc.cc
index 1a1dd5ac4..5224884f3 100644
--- a/tools/idle_alloc.cc
+++ b/tools/idle_alloc.cc
@@ -14,11 +14,8 @@
* limitations under the License.
*/
-#include <memory>
-
#include <errno.h>
#include <fcntl.h>
-#include <inttypes.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@@ -27,6 +24,9 @@
#include <sys/types.h>
#include <unistd.h>
+#include <cinttypes>
+#include <memory>
+
namespace {
constexpr auto kIdleSize = 10000 * 4096;
diff --git a/tools/install-build-deps b/tools/install-build-deps
index 878f1f683..de21e945b 100755
--- a/tools/install-build-deps
+++ b/tools/install-build-deps
@@ -28,7 +28,7 @@ from collections import namedtuple
from platform import system, machine
# The format for the deps below is the following:
-# (target_folder, source_url, sha1, target_platform)
+# (target_folder, source_url, sha1, target_os, target_arch)
# |source_url| can be either a git repo or a http url.
# If a git repo, |checksum| is the SHA1 committish that will be checked out.
# If a http url, |checksum| is the SHA256 of the downloaded file.
@@ -37,7 +37,7 @@ from platform import system, machine
# root (to avoid ending up with buildtools/protobuf/protobuf-1.2.3/... and have
# instead just buildtools/protobuf).
# |target_os| is either 'darwin', 'linux', 'windows' or 'all'
-# |target_arch| is either 'x64', 'aarch64' or 'all'
+# |target_arch| is either 'x64', 'arm64' or 'all'
# in both cases the dep only applies on matching platforms
# |target_arch| can be 'all' when 'target_os' is not 'all' for example in the
# case of MacOS universal binaries.
@@ -57,21 +57,26 @@ CLEANUP_OLD_DIRS = [
# Dependencies required to build code on the host or when targeting desktop OS.
BUILD_DEPS_TOOLCHAIN_HOST = [
# GN. From https://chrome-infra-packages.appspot.com/dl/gn/gn/.
- # git_revision:83dad00afb232d7235dd70dff1ee90292d72a01e .
+ # git_revision:0725d7827575b239594fbc8fd5192873a1d62f44 .
Dependency(
'buildtools/mac/gn',
- 'https://storage.googleapis.com/perfetto/gn-mac-1695-83dad00a',
- '513d3adeb56b745e62af4e3ccb76b76f023c6aaa25d6a2be9a89e44cd10a4c1a',
+ 'https://storage.googleapis.com/perfetto/gn-mac-1968-0725d782',
+ '9ced623a664560bba38bbadb9b91158ca4186358c847e17ab7d982b351373c2e',
'darwin', 'x64'),
Dependency(
+ 'buildtools/mac/gn',
+ 'https://storage.googleapis.com/perfetto/gn-mac-arm64-1968-0725d782',
+ 'd22336b5210b4dad5e36e8c28ce81187f491822cf4d8fd0a257b30d6bee3fd3f',
+ 'darwin', 'arm64'),
+ Dependency(
'buildtools/linux64/gn',
- 'https://storage.googleapis.com/perfetto/gn-linux64-1695-83dad00a',
- '4f589364153f182b05cd845e93407489d6ce8acc03290c897928a7bd22b20cce',
+ 'https://storage.googleapis.com/perfetto/gn-linux64-1968-0725d782',
+ 'f706aaa0676e3e22f5fc9ca482295d7caee8535d1869f99efa2358177b64f5cd',
'linux', 'x64'),
Dependency(
'buildtools/win/gn.exe',
- 'https://storage.googleapis.com/perfetto/gn-win-1695-83dad00a',
- '908c29556539292203d2952ebf55df03697cbc7cf526a3e295f31ba2576e4cac',
+ 'https://storage.googleapis.com/perfetto/gn-win-1968-0725d782',
+ '001f777f023c7a6959c778fb3a6b6cfc63f6baef953410ecdeaec350fb12285b',
'windows', 'x64'),
# clang-format
@@ -80,7 +85,7 @@ BUILD_DEPS_TOOLCHAIN_HOST = [
'buildtools/mac/clang-format',
'https://storage.googleapis.com/chromium-clang-format/62bde1baa7196ad9df969fc1f06b66360b1a927b',
'6df686a937443cbe6efc013467a7ba5f98d3f187eb7765bb7abc6ce47626cf66',
- 'darwin', 'x64'),
+ 'darwin', 'all'),
# From https://chromium.googlesource.com/chromium/src/buildtools/+/refs/heads/master/linux64/clang-format.sha1
Dependency(
'buildtools/linux64/clang-format',
@@ -103,31 +108,31 @@ BUILD_DEPS_TOOLCHAIN_HOST = [
# Ninja
Dependency(
'buildtools/mac/ninja',
- 'https://storage.googleapis.com/perfetto/ninja-mac-c15b0698da038b2bd2e8970c14c75fadc06b1add',
- '4224b90734590b0148ad8ee63ee7b295e88e0652e4d1f4271ef2b91d880b0e19',
- 'darwin', 'x64'),
+ 'https://storage.googleapis.com/perfetto/ninja-mac-x64_and_arm64-182',
+ '36e8b7aaa06911e1334feb664dd731a1cd69a15eb916a231a3d10ff65fca2c73',
+ 'darwin', 'all'),
Dependency(
'buildtools/linux64/ninja',
- 'https://storage.googleapis.com/perfetto/ninja-linux64-c866952bda50c29a669222477309287119bbb7e8',
+ 'https://storage.googleapis.com/perfetto/ninja-linux64-182',
'54ac6a01362190aaabf4cf276f9c8982cdf11b225438940fdde3339be0f2ecdc',
'linux', 'x64'),
Dependency(
'buildtools/win/ninja.exe',
- 'https://storage.googleapis.com/perfetto/ninja-win-4a5f05c24afef05ef03329a1bbfedee0678b524a',
- '6f8af488be74ed8787d04e107080d05330587a4198ba047bd5b7f5b0c3150d61',
+ 'https://storage.googleapis.com/perfetto/ninja-win-182',
+ '09ced0fcd1a4dec7d1b798a2cf9ce5d20e5d2fbc2337343827f192ce47d0f491',
'windows', 'x64'),
# Keep the revision in sync with Chrome's PACKAGE_VERSION in
# tools/clang/scripts/update.py.
Dependency(
'buildtools/linux64/clang.tgz',
- 'https://commondatastorage.googleapis.com/chromium-browser-clang/Linux_x64/clang-llvmorg-12-init-5035-gd0abc757-3.tgz',
- 'b0c3015209b6d624844ad230064eb5c9b4429a2eafd4854981e73217c563d93d',
+ 'https://commondatastorage.googleapis.com/chromium-browser-clang/Linux_x64/clang-llvmorg-14-init-3191-g0e03450a-1.tgz',
+ 'dd7479d43ce61401e057a5dee8b7e32bc2bd0d0e15d4f46c6858daf9170c9978',
'linux', 'x64'),
Dependency(
'buildtools/win/clang.tgz',
- 'https://commondatastorage.googleapis.com/chromium-browser-clang/Win/clang-llvmorg-12-init-5035-gd0abc757-3.tgz',
- 'b2854d871a466e3a060469b5edb24ca355ef64576d38778f64acbd3c6d7cf530',
+ 'https://commondatastorage.googleapis.com/chromium-browser-clang/Win/clang-llvmorg-14-init-3191-g0e03450a-1.tgz',
+ '4292d191742e7120200c63224f02e1f2f2a7be8b57c0f18edf6ca0955bdd43df',
'windows', 'x64'),
]
@@ -143,7 +148,8 @@ BUILD_DEPS_HOST = [
'buildtools/protobuf',
'https://chromium.googlesource.com/external/github.com/google/protobuf.git',
'6a59a2ad1f61d9696092f79b6d74368b4d7970a3', # refs/tags/v3.9.0
- 'all', 'all'),
+ 'all',
+ 'all'),
# libc++, libc++abi and libunwind for Linux where we need to rebuild the C++
# lib from sources. Keep the SHA1s in sync with Chrome's src/buildtools/DEPS.
@@ -184,6 +190,7 @@ BUILD_DEPS_HOST = [
# This is the amalgamated source whose compiled output is meant to be faster.
# We still pull the full source for the extensions (which are not available
# in the amalgamation).
+ # If updating the version, also update bazel/deps.bzl.
Dependency(
'buildtools/sqlite.zip',
'https://storage.googleapis.com/perfetto/sqlite-amalgamation-3350400.zip',
@@ -193,14 +200,28 @@ BUILD_DEPS_HOST = [
'buildtools/sqlite_src',
'https://chromium.googlesource.com/external/github.com/sqlite/sqlite.git',
'ee3686eb50c0e3dbb087c9a0976f7e37e1b014ae', # refs/tags/version-3.32.3.
- 'all', 'all'),
+ 'all',
+ 'all'),
# JsonCpp for legacy json import. Used only by the trace processor in
# standalone builds.
+ # If updating the version, also update bazel/deps.bzl.
Dependency(
'buildtools/jsoncpp',
'https://chromium.googlesource.com/external/github.com/open-source-parsers/jsoncpp.git',
'6aba23f4a8628d599a9ef7fa4811c4ff6e4070e2', # refs/tags/1.9.3.
+ 'all',
+ 'all'),
+
+ # Archive with only the demangling sources from llvm-project.
+ # See tools/repackage_llvm_demangler.sh on how to update this.
+ # File suffix is the git reference to the commit at which we rearchived the
+ # sources, as hosted on https://llvm.googlesource.com/llvm-project.
+ # If updating the version, also update bazel/deps.bzl.
+ Dependency(
+ 'buildtools/llvm-project.tgz',
+ 'https://storage.googleapis.com/perfetto/llvm-project-3b4c59c156919902c785ce3cbae0eee2ee53064d.tgz',
+ 'f4a52e7f36edd7cacc844d5ae0e5f60b6f57c5afc40683e99f295886c9ce8ff4',
'all', 'all'),
# These dependencies are for libunwindstack, which is used by src/profiling.
@@ -210,7 +231,7 @@ BUILD_DEPS_HOST = [
Dependency(
'buildtools/android-unwinding',
'https://android.googlesource.com/platform/system/unwinding.git',
- '5150e1292ec6b16e4717e86b9e3cfb855eec18a3', 'all', 'all'),
+ '215644709bd7bbda4c05a9db4d55e96be61bcf64', 'all', 'all'),
Dependency('buildtools/android-logging',
'https://android.googlesource.com/platform/system/logging.git',
'7b36b566c9113fc703d68f76e8f40c0c2432481c', 'all', 'all'),
@@ -224,25 +245,29 @@ BUILD_DEPS_HOST = [
Dependency('buildtools/lzma',
'https://android.googlesource.com/platform/external/lzma.git',
'7851dce6f4ca17f5caa1c93a4e0a45686b1d56c3', 'all', 'all'),
- Dependency('buildtools/zlib',
- 'https://android.googlesource.com/platform/external/zlib.git',
- '5c85a2da4c13eda07f69d81a1579a5afddd35f59', 'all', 'all'),
Dependency('buildtools/bionic',
'https://android.googlesource.com/platform/bionic.git',
'332065d57e734b65f56474d136d22d767e36cbcd', 'all', 'all'),
- # Example traces for regression tests.
- Dependency(
- 'test/data.zip',
- 'https://storage.googleapis.com/perfetto/test-data-20210513-224349.zip',
- '3dcc146f4ce38d17fd1f8c4c65af07e7cf7c5c4cb8aa4c7bf73ec3a095d997d1',
- 'all', 'all',
- ),
+ # Zlib used both in the tracing binaries, as well as the trace processor and
+ # assorted tools.
+ # If updating the version, also update bazel/deps.bzl.
+ Dependency('buildtools/zlib',
+ 'https://android.googlesource.com/platform/external/zlib.git',
+ '5c85a2da4c13eda07f69d81a1579a5afddd35f59', 'all', 'all'),
# Linenoise, used only by trace_processor in standalone builds.
+ # If updating the version, also update bazel/deps.bzl.
Dependency('buildtools/linenoise',
'https://fuchsia.googlesource.com/third_party/linenoise.git',
'c894b9e59f02203dbe4e2be657572cf88c4230c3', 'all', 'all'),
+
+ # Bloaty, used to investigate binary size
+ Dependency(
+ 'buildtools/bloaty.zip',
+ 'https://storage.googleapis.com/perfetto/bloaty-1.1-b3b829de35babc2fe831b9488ad2e50bca939412-mac.zip',
+ '2d301bd72a20e3f42888c9274ceb4dca76c103608053572322412c2c65ab8cb8',
+ 'darwin', 'all'),
]
# Dependencies required to build Android code.
@@ -255,7 +280,7 @@ BUILD_DEPS_ANDROID = [
'buildtools/ndk.zip',
'https://dl.google.com/android/repository/android-ndk-r21e-darwin-x86_64.zip',
'437278103a3db12632c05b1be5c41bbb8522791a67e415cc54411a65366f499d',
- 'darwin', 'x64'),
+ 'darwin', 'all'),
Dependency(
'buildtools/ndk.zip',
'https://dl.google.com/android/repository/android-ndk-r21e-linux-x86_64.zip',
@@ -277,7 +302,7 @@ TEST_DEPS_ANDROID = [
'buildtools/android_sdk/platform-tools.zip',
'https://dl.google.com/android/repository/platform-tools_r26.0.0-darwin.zip',
'98d392cbd21ca20d643c7e1605760cc49075611e317c534096b5564053f4ac8e',
- 'darwin', 'x64'),
+ 'darwin', 'all'),
Dependency(
'buildtools/android_sdk/platform-tools.zip',
'https://dl.google.com/android/repository/platform-tools_r26.0.0-linux.zip',
@@ -294,14 +319,14 @@ TEST_DEPS_ANDROID = [
# This variable is updated by tools/roll-catapult-trace-viewer.
CATAPULT_SHA256 = 'b30108e05268ce6c65bb4126b65f6bfac165d17f5c1fd285046e7e6fd76c209f'
-TYPEFACES_SHA256 = 'b3f0f14eeecd4555ae94f897ec246b2c6e046ce0ea417407553f5767e7812575'
+TYPEFACES_SHA256 = 'f5f78f8f4395db65cdf5fdc1bf51da65f2161e6d61a305091d6ea54d3094a1f0'
UI_DEPS = [
Dependency(
'buildtools/mac/nodejs.tgz',
'https://storage.googleapis.com/chromium-nodejs/14.15.4/17ba7216e09de1bffb9dc80b7ec617a1cee40330',
'b81a466347d2ae34b1370b6681ba173e9fb082338170a41624b37be7a2052b7e',
- 'darwin', 'x64'),
+ 'darwin', 'all'),
Dependency(
'buildtools/linux64/nodejs.tgz',
'https://storage.googleapis.com/chromium-nodejs/14.15.4/b2e40ddbac04d05baafbb007f203c6663c9d4ca9',
@@ -311,7 +336,7 @@ UI_DEPS = [
'buildtools/mac/emsdk.tgz',
'https://storage.googleapis.com/perfetto/emscripten-2.0.12-mac.tgz',
'aa125f8c8ff8a386d43e18c8ea0c98c875cc19160a899403e8967a5478f96f31',
- 'darwin', 'x64'),
+ 'darwin', 'all'),
Dependency(
'buildtools/linux64/emsdk.tgz',
'https://storage.googleapis.com/perfetto/emscripten-2.0.12-linux.tgz',
@@ -327,10 +352,30 @@ UI_DEPS = [
TYPEFACES_SHA256, TYPEFACES_SHA256, 'all', 'all')
]
+# Sysroots required to cross-compile Linux targets (linux-arm{,64}).
+# These are taken from Chromium's build/linux/sysroot_scripts/sysroots.json.
+BUILD_DEPS_LINUX_CROSS_SYSROOTS = [
+ Dependency(
+ 'buildtools/debian_sid_arm-sysroot.tgz',
+ 'https://commondatastorage.googleapis.com/chrome-linux-sysroot/toolchain/11d6f690ca49e8ba01a1d8c5346cedad2cf308fd/debian_sid_arm_sysroot.tar.xz',
+ 'ff192fe073d140d836c9ca1e68f7200d558bb9aa6c5c8f4f76f794f82890f99a',
+ 'linux', 'all'),
+ Dependency(
+ 'buildtools/debian_sid_arm64-sysroot.tgz',
+ 'https://commondatastorage.googleapis.com/chrome-linux-sysroot/toolchain/2befe8ce3e88be6080e4fb7e6d412278ea6a7625/debian_sid_arm64_sysroot.tar.xz',
+ 'e4389eab2fe363f3fbdfa4d3ce9d94457d78fd2c0e62171a7534867623eadc90',
+ 'linux', 'all'),
+]
+
+ALL_DEPS = (
+ BUILD_DEPS_HOST + BUILD_DEPS_ANDROID + BUILD_DEPS_LINUX_CROSS_SYSROOTS +
+ TEST_DEPS_ANDROID + UI_DEPS)
+
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
UI_DIR = os.path.join(ROOT_DIR, 'ui')
TOOLS_DIR = os.path.join(ROOT_DIR, 'tools')
NODE_MODULES_STATUS_FILE = os.path.join(UI_DIR, 'node_modules', '.last_install')
+TEST_DATA_SCRIPT = os.path.join(TOOLS_DIR, 'test_data')
def DownloadURL(url, out_file):
@@ -339,8 +384,8 @@ def DownloadURL(url, out_file):
def GetArch():
arch = machine()
- if arch == 'aarch64':
- return 'aarch64'
+ if arch == 'arm64':
+ return 'arm64'
else:
# Assume everything else is x64 matching previous behaviour.
return 'x64'
@@ -398,8 +443,7 @@ def RmtreeIfExists(path):
not os.path.abspath(path).startswith(test_path)):
# Safety check to prevent that some merge confilct ends up doing some
# rm -rf / or similar.
- logging.fatal(
- 'Cannot remove %s: outside of buildtools and test/data', path)
+ logging.fatal('Cannot remove %s: outside of buildtools and test/data', path)
sys.exit(1)
logging.info('Removing %s' % path)
shutil.rmtree(path, onerror=del_read_only_for_windows)
@@ -428,9 +472,9 @@ def InstallNodeModules(force_clean=False):
logging.info('Clearing %s', node_modules)
subprocess.check_call(['git', 'clean', '-qxffd', node_modules],
cwd=ROOT_DIR)
- logging.info("Running npm install in {0}".format(UI_DIR))
- subprocess.check_call(
- [os.path.join(TOOLS_DIR, 'npm'), 'install', '--no-save'], cwd=UI_DIR)
+ logging.info("Running `npm ci` in {0}".format(UI_DIR))
+ # `npm ci` is like `npm install` but respects package-lock.json.
+ subprocess.check_call([os.path.join(TOOLS_DIR, 'npm'), 'ci'], cwd=UI_DIR)
# pbjs has the bad habit of installing extra packages on its first run. Run
# it here, so we avoid fetches while building.
node_bin = os.path.join(TOOLS_DIR, 'node')
@@ -455,40 +499,57 @@ def CheckNodeModules():
def CheckHashes():
- for deps in [BUILD_DEPS_HOST, BUILD_DEPS_ANDROID, TEST_DEPS_ANDROID, UI_DEPS]:
- for dep in deps:
- if dep.source_url.endswith('.git'):
- continue
- logging.info('Downloading %s from %s', dep.target_platform,
- dep.source_url)
- with tempfile.NamedTemporaryFile(delete=False) as f:
- f.close()
- DownloadURL(dep.source_url, f.name)
- actual_checksum = HashLocalFile(f.name)
- os.unlink(f.name)
- if (actual_checksum != dep.checksum):
- logging.fatal('SHA-256 mismatch for {} expected {} was {}'.format(
- dep.source_url, dep.checksum, actual_checksum))
+ for dep in ALL_DEPS:
+ if dep.source_url.endswith('.git'):
+ continue
+ logging.info('Downloading %s for %s-%s', dep.source_url, dep.target_os,
+ dep.target_arch)
+ with tempfile.NamedTemporaryFile(delete=False) as f:
+ f.close()
+ DownloadURL(dep.source_url, f.name)
+ actual_checksum = HashLocalFile(f.name)
+ os.unlink(f.name)
+ if (actual_checksum != dep.checksum):
+ logging.fatal('SHA-256 mismatch for {} expected {} was {}'.format(
+ dep.source_url, dep.checksum, actual_checksum))
def Main():
parser = argparse.ArgumentParser()
- parser.add_argument('--android', action='store_true')
- parser.add_argument('--ui', action='store_true')
+ parser.add_argument(
+ '--android',
+ action='store_true',
+ help='NDK and emulator images target_os="android"')
+ parser.add_argument(
+ '--linux-arm',
+ action='store_true',
+ help='Debian sysroots for target_os="linux" target_cpu="arm|arm64"')
+ parser.add_argument(
+ '--ui',
+ action='store_true',
+ help='Node and NPM packages to Build the Web-based UI via ./ui/build')
parser.add_argument('--check-only')
parser.add_argument('--filter', default='')
parser.add_argument('--verify', help='Check all URLs', action='store_true')
- parser.add_argument('--no-toolchain', help='Do not download toolchain',
- action='store_true')
+ parser.add_argument(
+ '--no-toolchain', help='Do not download toolchain', action='store_true')
args = parser.parse_args()
if args.verify:
CheckHashes()
return 0
+
+ target_os = system().lower()
+ if args.ui and target_os == 'windows':
+ print('Building the UI on Windows is unsupported')
+ return 1
+
deps = BUILD_DEPS_HOST
if not args.no_toolchain:
deps += BUILD_DEPS_TOOLCHAIN_HOST
if args.android:
deps += BUILD_DEPS_ANDROID + TEST_DEPS_ANDROID
+ if args.linux_arm:
+ deps += BUILD_DEPS_LINUX_CROSS_SYSROOTS
if args.ui:
deps += UI_DEPS
deps_updated = False
@@ -498,7 +559,6 @@ def Main():
RmtreeIfExists(os.path.join(ROOT_DIR, old_dir))
for dep in deps:
- target_os = system().lower()
target_arch = GetArch()
matches_os = dep.target_os == 'all' or target_os == dep.target_os
matches_arch = dep.target_arch == 'all' or target_arch == dep.target_arch
@@ -575,16 +635,30 @@ def Main():
else:
InstallNodeModules(force_clean=nodejs_updated)
+ cur_python_interpreter = sys.executable
+ test_data_synced = 0 == subprocess.call([
+ cur_python_interpreter, TEST_DATA_SCRIPT, 'status', '--quiet',
+ '--ignore-new'
+ ])
if args.check_only:
- if not deps_updated:
+ if not deps_updated and test_data_synced:
with open(args.check_only, 'w') as f:
f.write('OK') # The content is irrelevant, just keep GN happy.
return 0
- argz = ' '.join([x for x in sys.argv[1:] if not x.startswith('--check-only')])
+ argz = ' '.join(
+ [x for x in sys.argv[1:] if not x.startswith('--check-only')])
print('\033[91mBuild deps are stale. ' +
'Please run tools/install-build-deps %s\033[0m' % argz)
+ if not test_data_synced:
+ print('//test/data/ is out of sync. `tools/test_data status` for details')
return 1
+ if not test_data_synced:
+ cmd = [cur_python_interpreter, TEST_DATA_SCRIPT, 'download', '--overwrite']
+ if not sys.stdout.isatty():
+ cmd += ['--verbose'] # For CI bots
+ subprocess.check_call(cmd)
+
if deps_updated:
# Stale binary files may be compiled against old sysroot headers that aren't
# tracked by gn.
diff --git a/tools/java_heap_dump b/tools/java_heap_dump
index 03abb0162..a0e69220e 100755
--- a/tools/java_heap_dump
+++ b/tools/java_heap_dump
@@ -24,6 +24,7 @@ import subprocess
import sys
import tempfile
import time
+import uuid
NULL = open(os.devnull)
@@ -61,10 +62,26 @@ CONTINUOUS_DUMP = """
}}
"""
+UUID = str(uuid.uuid4())[-6:]
+PROFILE_PATH = '/data/misc/perfetto-traces/java-profile-' + UUID
+
PERFETTO_CMD = ('CFG=\'{cfg}\'; echo ${{CFG}} | '
- 'perfetto --txt -c - -o '
- '/data/misc/perfetto-traces/java-profile-{user} -d')
+ 'perfetto --txt -c - -o ' + PROFILE_PATH + ' -d')
+
+SDK = {
+ 'S': 31,
+}
+def release_or_newer(release):
+ sdk = int(subprocess.check_output(
+ ['adb', 'shell', 'getprop', 'ro.system.build.version.sdk']
+ ).decode('utf-8').strip())
+ if sdk >= SDK[release]:
+ return True
+ codename = subprocess.check_output(
+ ['adb', 'shell', 'getprop', 'ro.build.version.codename']
+ ).decode('utf-8').strip()
+ return codename == release
def main(argv):
parser = argparse.ArgumentParser()
@@ -107,11 +124,20 @@ def main(argv):
parser.add_argument(
"--stop-when-done",
action="store_true",
- help="On recent builds of S, use a new method to stop the profile when "
- "the dump is done. Previously, we would hardcode a duration.")
+ default=None,
+ help="Use a new method to stop the profile when the dump is done. "
+ "Previously, we would hardcode a duration. Available and default on S.")
+ parser.add_argument(
+ "--no-stop-when-done",
+ action="store_false",
+ dest='stop_when_done',
+ help="Do not use a new method to stop the profile when the dump is done.")
args = parser.parse_args()
+ if args.stop_when_done is None:
+ args.stop_when_done = release_or_newer('S')
+
fail = False
if args.pid is None and args.name is None:
print("FATAL: Neither PID nor NAME given.", file=sys.stderr)
@@ -147,8 +173,6 @@ def main(argv):
continuous_dump_cfg = CONTINUOUS_DUMP.format(
dump_interval=args.continuous_dump)
- # TODO(fmayer): Once the changes have been in S for long enough, make this
- # the default for S+.
if args.stop_when_done:
duration_ms = 1000
data_source_stop_timeout_ms = 100000
@@ -189,8 +213,10 @@ def main(argv):
time.sleep(1)
subprocess.check_call(
- ['adb', 'pull', '/data/misc/perfetto-traces/java-profile-{}'.format(user),
- output_file], stdout=NULL)
+ ['adb', 'pull', PROFILE_PATH, output_file], stdout=NULL)
+
+ subprocess.check_call(
+ ['adb', 'shell', 'rm', PROFILE_PATH], stdout=NULL)
print("Wrote profile to {}".format(output_file))
print("This can be viewed using https://ui.perfetto.dev.")
diff --git a/tools/measure_tp_performance.py b/tools/measure_tp_performance.py
new file mode 100755
index 000000000..e5e09cedf
--- /dev/null
+++ b/tools/measure_tp_performance.py
@@ -0,0 +1,169 @@
+#!/usr/bin/env python3
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import argparse
+import os
+import re
+import signal
+import sys
+import subprocess
+
+import psutil
+
+ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+REGEX = re.compile(
+ '.*Trace loaded: ([0-9.]+) MB in ([0-9.]+)s \(([0-9.]+) MB/s\)')
+
+
+def run_tp_until_ingestion(args, env):
+ tp_args = [os.path.join(args.out, 'trace_processor_shell'), args.trace_file]
+ if not args.ftrace_raw:
+ tp_args.append('--no-ftrace-raw')
+ tp = subprocess.Popen(
+ tp_args,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.PIPE,
+ universal_newlines=True,
+ env=env)
+
+ lines = []
+ while True:
+ line = tp.stderr.readline()
+ lines.append(line)
+
+ match = REGEX.match(line)
+ if match:
+ break
+
+ if tp.poll():
+ break
+
+ ret = tp.poll()
+ fail = ret is not None and ret > 0
+ if fail:
+ print("Failed")
+ for line in lines:
+ sys.stderr.write(line)
+ return tp, fail, match[2]
+
+
+def heap_profile_run(args, dump_at_max: bool):
+ profile_args = [
+ os.path.join(ROOT_DIR, 'tools', 'heap_profile'), '-i', '1', '-n',
+ 'trace_processor_shell', '--print-config'
+ ]
+ if dump_at_max:
+ profile_args.append('--dump-at-max')
+ config = subprocess.check_output(
+ profile_args,
+ stderr=subprocess.DEVNULL,
+ )
+
+ out_file = os.path.join(
+ args.result, args.result_prefix + ('max' if dump_at_max else 'rest'))
+ perfetto_args = [
+ os.path.join(args.out, 'perfetto'), '-c', '-', '--txt', '-o', out_file
+ ]
+ profile = subprocess.Popen(
+ perfetto_args,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL)
+ profile.stdin.write(config)
+ profile.stdin.close()
+
+ env = {
+ 'LD_PRELOAD': os.path.join(args.out, 'libheapprofd_glibc_preload.so'),
+ 'TRACE_PROCESSOR_NO_MMAP': '1',
+ 'PERFETTO_HEAPPROFD_BLOCKING_INIT': '1'
+ }
+ (tp, fail, _) = run_tp_until_ingestion(args, env)
+
+ profile.send_signal(signal.SIGINT)
+ profile.wait()
+
+ tp.stdin.close()
+ tp.wait()
+
+ if fail:
+ os.remove(out_file)
+
+
+def regular_run(args):
+ env = {'TRACE_PROCESSOR_NO_MMAP': '1'}
+ (tp, fail, time) = run_tp_until_ingestion(args, env)
+
+ p = psutil.Process(tp.pid)
+ mem = 0
+ for m in p.memory_maps():
+ mem += m.anonymous
+
+ tp.stdin.close()
+ tp.wait()
+
+ print(f'Time taken: {time}s, Memory: {mem / 1024.0 / 1024.0}MB')
+
+
+def only_sort_run(args):
+ env = {
+ 'TRACE_PROCESSOR_NO_MMAP': '1',
+ 'TRACE_PROCESSOR_SORT_ONLY': '1',
+ }
+ (tp, fail, time) = run_tp_until_ingestion(args, env)
+
+ tp.stdin.close()
+ tp.wait()
+
+ print(f'Time taken: {time}s')
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description="This script measures the running time of "
+ "ingesting a trace with trace processor as well as profiling "
+ "trace processor's memory usage with heapprofd")
+ parser.add_argument('--out', type=str, help='Out directory', required=True)
+ parser.add_argument(
+ '--result', type=str, help='Result directory', required=True)
+ parser.add_argument(
+ '--result-prefix', type=str, help='Result file prefix', required=True)
+ parser.add_argument(
+ '--ftrace-raw',
+ action='store_true',
+ help='Whether to ingest ftrace into raw table',
+ default=False)
+ parser.add_argument('trace_file', type=str, help='Path to trace')
+ args = parser.parse_args()
+
+ traced = subprocess.Popen([os.path.join(args.out, 'traced')],
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL)
+ print('Heap profile dump at max')
+ heap_profile_run(args, dump_at_max=True)
+ print('Heap profile dump at resting')
+ heap_profile_run(args, dump_at_max=False)
+ print('Regular run')
+ regular_run(args)
+ print('Only sort run')
+ only_sort_run(args)
+
+ traced.send_signal(signal.SIGINT)
+ traced.wait()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tools/multithreaded_alloc.cc b/tools/multithreaded_alloc.cc
index 61257770e..4c5e603b5 100644
--- a/tools/multithreaded_alloc.cc
+++ b/tools/multithreaded_alloc.cc
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <atomic>
+#include <cinttypes>
#include <condition_variable>
#include <iterator>
#include <mutex>
diff --git a/tools/ninja b/tools/ninja
index 724ccb0bd..67b8ed910 100755
--- a/tools/ninja
+++ b/tools/ninja
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env python3
# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,5 +13,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-CMD="ninja"
-source "$(dirname "${BASH_SOURCE[0]}")/run-buildtools-binary.sh"
+import os
+import sys
+
+ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+sys.path.append(ROOT_DIR)
+__package__ = 'tools'
+from .run_buildtools_binary import run_buildtools_binary
+run_buildtools_binary(['ninja'] + sys.argv[1:])
diff --git a/tools/open_trace_in_ui b/tools/open_trace_in_ui
new file mode 100755
index 000000000..25995b836
--- /dev/null
+++ b/tools/open_trace_in_ui
@@ -0,0 +1,102 @@
+#!/usr/bin/env python3
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import argparse
+import http.server
+import os
+import socketserver
+import sys
+import webbrowser
+
+
+class ANSI:
+ END = '\033[0m'
+ BOLD = '\033[1m'
+ RED = '\033[91m'
+ BLACK = '\033[30m'
+ BLUE = '\033[94m'
+ BG_YELLOW = '\033[43m'
+ BG_BLUE = '\033[44m'
+
+
+# HTTP Server used to open the trace in the browser.
+class HttpHandler(http.server.SimpleHTTPRequestHandler):
+
+ def end_headers(self):
+ self.send_header('Access-Control-Allow-Origin', '*')
+ return super().end_headers()
+
+ def do_GET(self):
+ self.server.last_request = self.path
+ return super().do_GET()
+
+ def do_POST(self):
+ self.send_error(404, "File not found")
+
+
+def prt(msg, colors=ANSI.END):
+ print(colors + msg + ANSI.END)
+
+
+def open_trace(path, open_browser):
+ # We reuse the HTTP+RPC port because it's the only one allowed by the CSP.
+ PORT = 9001
+ path = os.path.abspath(path)
+ os.chdir(os.path.dirname(path))
+ fname = os.path.basename(path)
+ socketserver.TCPServer.allow_reuse_address = True
+ with socketserver.TCPServer(('127.0.0.1', PORT), HttpHandler) as httpd:
+ if open_browser:
+ webbrowser.open_new_tab(
+ 'https://ui.perfetto.dev/#!/?url=http://127.0.0.1:%d/%s' %
+ (PORT, fname))
+ else:
+ print('Open URL in browser: '
+ 'https://ui.perfetto.dev/#!/?url=http://127.0.0.1:%d/%s' %
+ (PORT, fname))
+
+ while httpd.__dict__.get('last_request') != '/' + fname:
+ httpd.handle_request()
+
+
+def main():
+ examples = '\n'.join([
+ ANSI.BOLD + 'Usage:' + ANSI.END, ' -i path/trace_file_name [-n]'
+ ])
+ parser = argparse.ArgumentParser(
+ epilog=examples, formatter_class=argparse.RawTextHelpFormatter)
+
+ help = 'Input trace filename'
+ parser.add_argument('-i', '--trace', help=help)
+ parser.add_argument('-n', '--no-open-browser', action='store_true',
+ default=False)
+
+ args = parser.parse_args()
+ trace_file = args.trace
+ open_browser = not args.no_open_browser
+
+ if trace_file is None:
+ prt('Please specify trace file name with -i/--trace argument', ANSI.RED)
+ sys.exit(1)
+ elif not os.path.exists(trace_file):
+ prt('%s not found ' % trace_file, ANSI.RED)
+ sys.exit(1)
+
+ prt('Opening the trace (%s) in the browser' % trace_file)
+ open_trace(trace_file, open_browser)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/tools/package-prebuilts-for-github-release b/tools/package-prebuilts-for-github-release
new file mode 100755
index 000000000..d7a9414d2
--- /dev/null
+++ b/tools/package-prebuilts-for-github-release
@@ -0,0 +1,55 @@
+#!/usr/bin/env python3
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Pulls LUCI-generated binaries and generates .zip files for GitHub releases.
+
+Usage: ./tools/package_prebuilts_for_github_release v20.0
+
+This will generate one .zip file for every os-arch combo (e.g. android-arm.zip)
+into /tmp/perfetto-prebuilts-v20.0/ .
+"""
+
+import argparse
+import subprocess
+import os
+import sys
+
+
+def exec(*args):
+ print(' '.join(args))
+ subprocess.check_call(args)
+
+
+def main():
+ parser = argparse.ArgumentParser(epilog='Example %s v19.0' % __file__)
+ parser.add_argument('version')
+
+ args = parser.parse_args()
+ tmpdir = '/tmp/perfetto-prebuilts-' + args.version
+ src = 'gs://perfetto-luci-artifacts/%s/' % args.version
+ os.makedirs(tmpdir, exist_ok=True)
+ os.chdir(tmpdir)
+ exec('gsutil', '-m', 'rsync', '-rc', src, tmpdir + '/')
+ zips = []
+ for arch in os.listdir(tmpdir):
+ if not os.path.isdir(arch):
+ continue
+ exec('zip', '-9r', '%s.zip' % arch, arch)
+ zips.append(arch + '.zip')
+ print('')
+ print('%d zip files saved in %s (%s)' % (len(zips), tmpdir, ','.join(zips)))
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/tools/proto_filter/proto_filter.cc b/tools/proto_filter/proto_filter.cc
index e7443cb99..f3727e7a4 100644
--- a/tools/proto_filter/proto_filter.cc
+++ b/tools/proto_filter/proto_filter.cc
@@ -226,7 +226,7 @@ int Main(int argc, char** argv) {
}
std::string oct_str;
oct_str.reserve(filter_data.size() * 4 + 64);
- oct_str.append("trace_filter{\n bytecode: \"");
+ oct_str.append("trace_filter {\n bytecode: \"");
for (char c : filter_data) {
uint8_t octect = static_cast<uint8_t>(c);
char buf[5]{'\\', '0', '0', '0', 0};
diff --git a/tools/proto_merger/BUILD.gn b/tools/proto_merger/BUILD.gn
new file mode 100644
index 000000000..533d8aaf4
--- /dev/null
+++ b/tools/proto_merger/BUILD.gn
@@ -0,0 +1,35 @@
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("../../gn/perfetto_host_executable.gni")
+
+perfetto_host_executable("proto_merger") {
+ testonly = true
+ deps = [
+ "../../gn:default_deps",
+ "../../gn:protobuf_full",
+ "../../src/base",
+ ]
+ sources = [
+ "allowlist.cc",
+ "allowlist.h",
+ "main.cc",
+ "proto_file.cc",
+ "proto_file.h",
+ "proto_file_serializer.cc",
+ "proto_file_serializer.h",
+ "proto_merger.cc",
+ "proto_merger.h",
+ ]
+}
diff --git a/tools/proto_merger/allowlist.cc b/tools/proto_merger/allowlist.cc
new file mode 100644
index 000000000..2a1c8599c
--- /dev/null
+++ b/tools/proto_merger/allowlist.cc
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by appicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tools/proto_merger/allowlist.h"
+
+#include <google/protobuf/descriptor.pb.h>
+
+#include "perfetto/ext/base/string_utils.h"
+
+namespace perfetto {
+namespace proto_merger {
+namespace {
+
+std::vector<std::string> SplitFieldPath(const std::string& name) {
+ if (name.empty())
+ return {};
+
+ if (name[0] == '.')
+ return base::SplitString(name.substr(1), ".");
+
+ return base::SplitString(name, ".");
+}
+
+Allowlist::Message& ResolveMessageForDescriptor(
+ const google::protobuf::Descriptor& desc,
+ Allowlist& allowlist) {
+ if (!desc.containing_type())
+ return allowlist.messages[desc.name()];
+
+ Allowlist::Message& parent =
+ ResolveMessageForDescriptor(*desc.containing_type(), allowlist);
+ return parent.nested_messages[desc.name()];
+}
+
+void AllowlistEnum(const google::protobuf::EnumDescriptor& desc,
+ Allowlist& allowlist) {
+ if (!desc.containing_type()) {
+ allowlist.enums.emplace(desc.name());
+ return;
+ }
+
+ auto& containing =
+ ResolveMessageForDescriptor(*desc.containing_type(), allowlist);
+ containing.enums.emplace(desc.name());
+}
+
+void AllowlistField(const google::protobuf::FieldDescriptor& desc,
+ Allowlist& allowlist) {
+ auto& containing =
+ ResolveMessageForDescriptor(*desc.containing_type(), allowlist);
+
+ // Check if this field is already allowed and return if so; otherwise add it.
+ // We need to do slightly different things based on whether or not this field
+ // is in a oneof.
+ if (desc.containing_oneof()) {
+ auto& oneof = containing.oneofs[desc.containing_oneof()->name()];
+ if (!oneof.emplace(desc.number()).second) {
+ return;
+ }
+ } else {
+ if (!containing.fields.emplace(desc.number()).second)
+ return;
+ }
+
+ switch (desc.type()) {
+ case google::protobuf::FieldDescriptor::TYPE_MESSAGE:
+ // For message types, we recursively allow all fields under it including
+ // any types those fields may depend on.
+ for (int i = 0; i < desc.message_type()->field_count(); ++i) {
+ AllowlistField(*desc.message_type()->field(i), allowlist);
+ }
+ break;
+ case google::protobuf::FieldDescriptor::TYPE_ENUM:
+ // For enums, we allow the enum type.
+ AllowlistEnum(*desc.enum_type(), allowlist);
+ break;
+ default:
+ // We don't need to do anything for primitive types.
+ break;
+ }
+}
+
+} // namespace
+
+base::Status AllowlistFromFieldList(
+ const google::protobuf::Descriptor& desc,
+ const std::vector<std::string>& allowed_fields,
+ Allowlist& allowlist) {
+ for (const auto& field_path : allowed_fields) {
+ std::vector<std::string> pieces = SplitFieldPath(field_path);
+ const auto* current = &desc;
+ for (size_t i = 0; i < pieces.size(); ++i) {
+ const auto* field = current->FindFieldByName(pieces[i]);
+ if (!field) {
+ return base::ErrStatus("Field %s in message %s not found.",
+ pieces[i].c_str(), current->name().c_str());
+ }
+ if (i == pieces.size() - 1) {
+ // For the last field, allow the field and any messages it depends on
+ // recursively.
+ AllowlistField(*field, allowlist);
+ break;
+ }
+
+ // All fields before the last should lead to a message type.
+ if (field->type() != google::protobuf::FieldDescriptor::TYPE_MESSAGE) {
+ return base::ErrStatus("Field %s in message %s has a non-message type",
+ field->name().c_str(), desc.name().c_str());
+ }
+ current = field->message_type();
+ }
+ }
+ return base::OkStatus();
+}
+
+} // namespace proto_merger
+} // namespace perfetto
diff --git a/tools/proto_merger/allowlist.h b/tools/proto_merger/allowlist.h
new file mode 100644
index 000000000..64d70a536
--- /dev/null
+++ b/tools/proto_merger/allowlist.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TOOLS_PROTO_MERGER_ALLOWLIST_H_
+#define TOOLS_PROTO_MERGER_ALLOWLIST_H_
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "perfetto/base/status.h"
+
+// We include this intentionally instead of forward declaring to allow
+// for an easy find/replace transformation when moving to Google3.
+#include <google/protobuf/descriptor.h>
+
+namespace perfetto {
+namespace proto_merger {
+
+// Represents an allow-list for proto messages, fields and enums.
+struct Allowlist {
+ using Oneof = std::set<int>;
+ struct Message {
+ std::set<std::string> enums;
+ std::map<std::string, Oneof> oneofs;
+ std::set<int> fields;
+
+ // Needs to be a std::map as std::unordered_map causes complaints about
+ // self-referentiality from GCC.
+ std::map<std::string, Message> nested_messages;
+ };
+ std::map<std::string, Message> messages;
+ std::set<std::string> enums;
+};
+
+// Creates a Allowlist struct from a list of allowed fields rooted at the given
+// descriptor.
+base::Status AllowlistFromFieldList(
+ const google::protobuf::Descriptor&,
+ const std::vector<std::string>& allowed_fields,
+ Allowlist& allowlist);
+
+} // namespace proto_merger
+} // namespace perfetto
+
+#endif // TOOLS_PROTO_MERGER_ALLOWLIST_H_
diff --git a/tools/proto_merger/main.cc b/tools/proto_merger/main.cc
new file mode 100644
index 000000000..3e4376c32
--- /dev/null
+++ b/tools/proto_merger/main.cc
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <string>
+
+#include <google/protobuf/compiler/importer.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/file_utils.h"
+#include "perfetto/ext/base/getopt.h"
+#include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/version.h"
+#include "tools/proto_merger/allowlist.h"
+#include "tools/proto_merger/proto_file.h"
+#include "tools/proto_merger/proto_file_serializer.h"
+#include "tools/proto_merger/proto_merger.h"
+
+namespace perfetto {
+namespace proto_merger {
+namespace {
+
+class MultiFileErrorCollectorImpl
+ : public google::protobuf::compiler::MultiFileErrorCollector {
+ public:
+ ~MultiFileErrorCollectorImpl() override;
+ void AddError(const std::string&, int, int, const std::string&) override;
+ void AddWarning(const std::string&, int, int, const std::string&) override;
+};
+
+MultiFileErrorCollectorImpl::~MultiFileErrorCollectorImpl() = default;
+
+void MultiFileErrorCollectorImpl::AddError(const std::string& filename,
+ int line,
+ int column,
+ const std::string& message) {
+ PERFETTO_ELOG("Error %s %d:%d: %s", filename.c_str(), line, column,
+ message.c_str());
+}
+
+void MultiFileErrorCollectorImpl::AddWarning(const std::string& filename,
+ int line,
+ int column,
+ const std::string& message) {
+ PERFETTO_ELOG("Warning %s %d:%d: %s", filename.c_str(), line, column,
+ message.c_str());
+}
+
+struct ImportResult {
+ std::unique_ptr<google::protobuf::compiler::Importer> importer;
+ const google::protobuf::FileDescriptor* file_descriptor;
+};
+
+ImportResult ImportProto(const std::string& proto_file,
+ const std::string& proto_dir_path) {
+ MultiFileErrorCollectorImpl mfe;
+
+ google::protobuf::compiler::DiskSourceTree dst;
+ dst.MapPath("", proto_dir_path);
+
+ ImportResult result;
+ result.importer.reset(new google::protobuf::compiler::Importer(&dst, &mfe));
+ result.file_descriptor = result.importer->Import(proto_file);
+ return result;
+}
+
+const char kUsage[] =
+ R"(Usage: proto_merger [-i input proto] [-I import dir]
+
+-i, --input: Path to the input .proto file (relative to
+ --input-include directory). The contents of this
+ file will be updated using the upstream proto.
+-I, --input-include: Root directory from which includes for --input
+ proto should be searched.
+-u, --upstream: Path to the upstream .proto file; the contents of
+ this file will be used to update
+ the input proto.
+-U, --upstream-include: Root directory from which includes for --upstream
+ proto should be searched.
+-a, --allowlist: Allowlist file which is used to add new fields in
+ the upstream proto to the input proto.
+-r, --upstream-root-message: Root message in the upstream proto for which new
+ fields from the allowlist will be allowed.
+-o, --output: Output path for writing the merged proto file.
+
+Example usage:
+
+# Updating logs proto from Perfetto repo (must be run in G3):
+ proto_merger \
+ -u third_party/perfetto/protos/perfetto/trace/perfetto_trace.proto \
+ -U . \
+ -i <path to logs proto>/perfetto_log.proto \
+ -I . \
+ --allowlist /tmp/allowlist.txt \
+ -r perfetto.protos.Trace \
+ --output /tmp/output.proto
+)";
+
+int Main(int argc, char** argv) {
+ static const option long_options[] = {
+ {"help", no_argument, nullptr, 'h'},
+ {"version", no_argument, nullptr, 'v'},
+ {"input", required_argument, nullptr, 'i'},
+ {"input-include", required_argument, nullptr, 'I'},
+ {"upstream", required_argument, nullptr, 'u'},
+ {"upstream-include", required_argument, nullptr, 'U'},
+ {"allowlist", required_argument, nullptr, 'a'},
+ {"upstream-root-message", required_argument, nullptr, 'r'},
+ {"output", required_argument, nullptr, 'o'},
+ {nullptr, 0, nullptr, 0}};
+
+ std::string input;
+ std::string input_include;
+ std::string upstream;
+ std::string upstream_include;
+ std::string allowlist;
+ std::string upstream_root_message;
+ std::string output;
+
+ for (;;) {
+ int option =
+ getopt_long(argc, argv, "hvi:I:u:U:a:r:o:", long_options, nullptr);
+
+ if (option == -1)
+ break; // EOF.
+
+ if (option == 'v') {
+ printf("%s\n", base::GetVersionString());
+ return 0;
+ }
+
+ if (option == 'i') {
+ input = optarg;
+ continue;
+ }
+
+ if (option == 'I') {
+ input_include = optarg;
+ continue;
+ }
+
+ if (option == 'u') {
+ upstream = optarg;
+ continue;
+ }
+
+ if (option == 'U') {
+ upstream_include = optarg;
+ continue;
+ }
+
+ if (option == 'a') {
+ allowlist = optarg;
+ continue;
+ }
+
+ if (option == 'r') {
+ upstream_root_message = optarg;
+ continue;
+ }
+
+ if (option == 'o') {
+ output = optarg;
+ continue;
+ }
+
+ if (option == 'h') {
+ fprintf(stdout, kUsage);
+ return 0;
+ }
+
+ fprintf(stderr, kUsage);
+ return 1;
+ }
+
+ if (input.empty()) {
+ PERFETTO_ELOG("Input proto (--input) should be specified");
+ return 1;
+ }
+
+ if (input_include.empty()) {
+ PERFETTO_ELOG(
+ "Input include directory (--input-include) should be specified");
+ return 1;
+ }
+
+ if (upstream.empty()) {
+ PERFETTO_ELOG("Upstream proto (--upstream) should be specified");
+ return 1;
+ }
+
+ if (upstream_include.empty()) {
+ PERFETTO_ELOG(
+ "Upstream include directory (--upstream-include) should be specified");
+ return 1;
+ }
+
+ if (output.empty()) {
+ PERFETTO_ELOG("Output file (--output) should be specified");
+ return 1;
+ }
+
+ if (!allowlist.empty() && upstream_root_message.empty()) {
+ PERFETTO_ELOG(
+ "Need to specifiy upstream root message (--upstream-root-message) when "
+ "specifying allowlist");
+ return 1;
+ }
+
+ ImportResult input_proto = ImportProto(input, input_include);
+ ProtoFile input_file = ProtoFileFromDescriptor(*input_proto.file_descriptor);
+
+ ImportResult upstream_proto = ImportProto(upstream, upstream_include);
+ ProtoFile upstream_file =
+ ProtoFileFromDescriptor(*upstream_proto.file_descriptor);
+
+ Allowlist allowed;
+ if (!allowlist.empty()) {
+ std::string allowlist_contents;
+ if (!base::ReadFile(allowlist, &allowlist_contents)) {
+ PERFETTO_ELOG("Failed to read allowlist");
+ return 1;
+ }
+
+ auto* desc = upstream_proto.importer->pool()->FindMessageTypeByName(
+ upstream_root_message);
+ if (!desc) {
+ PERFETTO_ELOG(
+ "Failed to find root message descriptor in upstream proto file");
+ return 1;
+ }
+
+ auto field_list = base::SplitString(allowlist_contents, "\n");
+ base::Status status = AllowlistFromFieldList(*desc, field_list, allowed);
+ if (!status.ok()) {
+ PERFETTO_ELOG("Failed creating allowlist: %s", status.c_message());
+ return 1;
+ }
+ }
+
+ ProtoFile merged;
+ base::Status status =
+ MergeProtoFiles(input_file, upstream_file, allowed, merged);
+ if (!status.ok()) {
+ PERFETTO_ELOG("Failed merging protos: %s", status.c_message());
+ return 1;
+ }
+
+ base::ScopedFile output_file(
+ base::OpenFile(output, O_CREAT | O_WRONLY | O_TRUNC, 0664));
+ if (!output_file) {
+ PERFETTO_ELOG("Failed opening output file: %s", output.c_str());
+ return 1;
+ }
+ std::string out = ProtoFileToDotProto(merged);
+ base::WriteAll(*output_file, out.c_str(), out.size());
+
+ return 0;
+}
+
+} // namespace
+} // namespace proto_merger
+} // namespace perfetto
+
+int main(int argc, char** argv) {
+ return perfetto::proto_merger::Main(argc, argv);
+}
diff --git a/tools/proto_merger/proto_file.cc b/tools/proto_merger/proto_file.cc
new file mode 100644
index 000000000..e51018c29
--- /dev/null
+++ b/tools/proto_merger/proto_file.cc
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tools/proto_merger/proto_file.h"
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/text_format.h>
+
+#include "perfetto/ext/base/string_utils.h"
+
+namespace perfetto {
+namespace proto_merger {
+namespace {
+
+const char* const
+ kTypeToName[google::protobuf::FieldDescriptor::Type::MAX_TYPE + 1] = {
+ "ERROR", // 0 is reserved for errors
+
+ "double", // TYPE_DOUBLE
+ "float", // TYPE_FLOAT
+ "int64", // TYPE_INT64
+ "uint64", // TYPE_UINT64
+ "int32", // TYPE_INT32
+ "fixed64", // TYPE_FIXED64
+ "fixed32", // TYPE_FIXED32
+ "bool", // TYPE_BOOL
+ "string", // TYPE_STRING
+ "group", // TYPE_GROUP
+ "message", // TYPE_MESSAGE
+ "bytes", // TYPE_BYTES
+ "uint32", // TYPE_UINT32
+ "enum", // TYPE_ENUM
+ "sfixed32", // TYPE_SFIXED32
+ "sfixed64", // TYPE_SFIXED64
+ "sint32", // TYPE_SINT32
+ "sint64", // TYPE_SINT64
+};
+
+const char* const
+ kLabelToName[google::protobuf::FieldDescriptor::MAX_LABEL + 1] = {
+ "ERROR", // 0 is reserved for errors
+
+ "optional", // LABEL_OPTIONAL
+ "required", // LABEL_REQUIRED
+ "repeated", // LABEL_REPEATED
+};
+
+base::Optional<std::string> MinimizeType(const std::string& a,
+ const std::string& b) {
+ auto a_pieces = base::SplitString(a, ".");
+ auto b_pieces = base::SplitString(b, ".");
+
+ size_t skip = 0;
+ for (size_t i = 0; i < std::min(a_pieces.size(), b_pieces.size()); ++i) {
+ if (a_pieces[i] != b_pieces[i])
+ return a.substr(skip);
+ skip += a_pieces[i].size() + 1;
+ }
+ return base::nullopt;
+}
+
+std::string SimpleFieldTypeFromDescriptor(
+ const google::protobuf::Descriptor& parent,
+ const google::protobuf::FieldDescriptor& desc,
+ bool packageless_type) {
+ switch (desc.type()) {
+ case google::protobuf::FieldDescriptor::TYPE_MESSAGE:
+ if (packageless_type) {
+ return base::StripPrefix(desc.message_type()->full_name(),
+ desc.message_type()->file()->package() + ".");
+ } else {
+ return MinimizeType(desc.message_type()->full_name(),
+ parent.full_name())
+ .value_or(desc.message_type()->name());
+ }
+ case google::protobuf::FieldDescriptor::TYPE_ENUM:
+ if (packageless_type) {
+ return base::StripPrefix(desc.enum_type()->full_name(),
+ desc.enum_type()->file()->package() + ".");
+ } else {
+ return MinimizeType(desc.enum_type()->full_name(), parent.full_name())
+ .value_or(desc.enum_type()->name());
+ }
+ default:
+ return kTypeToName[desc.type()];
+ }
+}
+
+std::string FieldTypeFromDescriptor(
+ const google::protobuf::Descriptor& parent,
+ const google::protobuf::FieldDescriptor& desc,
+ bool packageless_type) {
+ if (!desc.is_map())
+ return SimpleFieldTypeFromDescriptor(parent, desc, packageless_type);
+
+ std::string field_type;
+ field_type += "map<";
+ field_type += FieldTypeFromDescriptor(parent, *desc.message_type()->field(0),
+ packageless_type);
+ field_type += ",";
+ field_type += FieldTypeFromDescriptor(parent, *desc.message_type()->field(1),
+ packageless_type);
+ field_type += ">";
+ return field_type;
+}
+
+std::unique_ptr<google::protobuf::Message> NormalizeOptionsMessage(
+ const google::protobuf::DescriptorPool& pool,
+ google::protobuf::DynamicMessageFactory* factory,
+ const google::protobuf::Message& message) {
+ const auto* option_descriptor =
+ pool.FindMessageTypeByName(message.GetDescriptor()->full_name());
+ if (!option_descriptor)
+ return nullptr;
+
+ std::unique_ptr<google::protobuf::Message> dynamic_options(
+ factory->GetPrototype(option_descriptor)->New());
+ PERFETTO_CHECK(dynamic_options->ParseFromString(message.SerializeAsString()));
+ return dynamic_options;
+}
+
+std::vector<ProtoFile::Option> OptionsFromMessage(
+ const google::protobuf::DescriptorPool& pool,
+ const google::protobuf::Message& raw_message) {
+ google::protobuf::DynamicMessageFactory factory;
+
+ auto normalized = NormalizeOptionsMessage(pool, &factory, raw_message);
+ const auto* message = normalized ? normalized.get() : &raw_message;
+ const auto* reflection = message->GetReflection();
+
+ std::vector<const google::protobuf::FieldDescriptor*> fields;
+ reflection->ListFields(*message, &fields);
+
+ std::vector<ProtoFile::Option> options;
+ for (size_t i = 0; i < fields.size(); i++) {
+ int count = 1;
+ bool repeated = false;
+ if (fields[i]->is_repeated()) {
+ count = reflection->FieldSize(*message, fields[i]);
+ repeated = true;
+ }
+ for (int j = 0; j < count; j++) {
+ std::string name;
+ if (fields[i]->is_extension()) {
+ name = "(" + fields[i]->full_name() + ")";
+ } else {
+ name = fields[i]->name();
+ }
+
+ std::string fieldval;
+ if (fields[i]->cpp_type() ==
+ google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+ std::string tmp;
+ google::protobuf::TextFormat::Printer printer;
+ printer.PrintFieldValueToString(*message, fields[i], repeated ? j : -1,
+ &tmp);
+ fieldval.append("{\n");
+ fieldval.append(tmp);
+ fieldval.append("}");
+ } else {
+ google::protobuf::TextFormat::PrintFieldValueToString(
+ *message, fields[i], repeated ? j : -1, &fieldval);
+ }
+ options.push_back(ProtoFile::Option{name, fieldval});
+ }
+ }
+ return options;
+}
+
+template <typename Output, typename Descriptor>
+Output InitFromDescriptor(const Descriptor& desc) {
+ google::protobuf::SourceLocation source_loc;
+ if (!desc.GetSourceLocation(&source_loc))
+ return {};
+
+ Output out;
+ out.leading_comments = base::SplitString(source_loc.leading_comments, "\n");
+ out.trailing_comments = base::SplitString(source_loc.trailing_comments, "\n");
+ return out;
+}
+
+ProtoFile::Field FieldFromDescriptor(
+ const google::protobuf::Descriptor& parent,
+ const google::protobuf::FieldDescriptor& desc) {
+ auto field = InitFromDescriptor<ProtoFile::Field>(desc);
+ field.label = kLabelToName[desc.label()];
+ field.packageless_type = FieldTypeFromDescriptor(parent, desc, true);
+ field.type = FieldTypeFromDescriptor(parent, desc, false);
+ field.name = desc.name();
+ field.number = desc.number();
+ field.options = OptionsFromMessage(*desc.file()->pool(), desc.options());
+ return field;
+}
+
+ProtoFile::Enum::Value EnumValueFromDescriptor(
+ const google::protobuf::EnumValueDescriptor& desc) {
+ auto value = InitFromDescriptor<ProtoFile::Enum::Value>(desc);
+ value.name = desc.name();
+ value.number = desc.number();
+ value.options = OptionsFromMessage(*desc.file()->pool(), desc.options());
+ return value;
+}
+
+ProtoFile::Enum EnumFromDescriptor(
+ const google::protobuf::EnumDescriptor& desc) {
+ auto en = InitFromDescriptor<ProtoFile::Enum>(desc);
+ en.name = desc.name();
+ for (int i = 0; i < desc.value_count(); ++i) {
+ en.values.emplace_back(EnumValueFromDescriptor(*desc.value(i)));
+ }
+ return en;
+}
+
+ProtoFile::Oneof OneOfFromDescriptor(
+ const google::protobuf::Descriptor& parent,
+ const google::protobuf::OneofDescriptor& desc) {
+ auto oneof = InitFromDescriptor<ProtoFile::Oneof>(desc);
+ oneof.name = desc.name();
+ for (int i = 0; i < desc.field_count(); ++i) {
+ oneof.fields.emplace_back(FieldFromDescriptor(parent, *desc.field(i)));
+ }
+ return oneof;
+}
+
+ProtoFile::Message MessageFromDescriptor(
+ const google::protobuf::Descriptor& desc) {
+ auto message = InitFromDescriptor<ProtoFile::Message>(desc);
+ message.name = desc.name();
+ for (int i = 0; i < desc.enum_type_count(); ++i) {
+ message.enums.emplace_back(EnumFromDescriptor(*desc.enum_type(i)));
+ }
+ for (int i = 0; i < desc.nested_type_count(); ++i) {
+ message.nested_messages.emplace_back(
+ MessageFromDescriptor(*desc.nested_type(i)));
+ }
+ for (int i = 0; i < desc.oneof_decl_count(); ++i) {
+ message.oneofs.emplace_back(OneOfFromDescriptor(desc, *desc.oneof_decl(i)));
+ }
+ for (int i = 0; i < desc.field_count(); ++i) {
+ auto* field = desc.field(i);
+ if (field->containing_oneof())
+ continue;
+ message.fields.emplace_back(FieldFromDescriptor(desc, *field));
+ }
+ return message;
+}
+
+} // namespace
+
+ProtoFile ProtoFileFromDescriptor(
+ const google::protobuf::FileDescriptor& desc) {
+ ProtoFile file;
+ for (int i = 0; i < desc.enum_type_count(); ++i) {
+ file.enums.push_back(EnumFromDescriptor(*desc.enum_type(i)));
+ }
+ for (int i = 0; i < desc.message_type_count(); ++i) {
+ file.messages.push_back(MessageFromDescriptor(*desc.message_type(i)));
+ }
+ return file;
+}
+
+} // namespace proto_merger
+} // namespace perfetto
diff --git a/tools/proto_merger/proto_file.h b/tools/proto_merger/proto_file.h
new file mode 100644
index 000000000..3e48bd902
--- /dev/null
+++ b/tools/proto_merger/proto_file.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TOOLS_PROTO_MERGER_PROTO_FILE_H_
+#define TOOLS_PROTO_MERGER_PROTO_FILE_H_
+
+#include <string>
+#include <vector>
+
+// We include this intentionally instead of forward declaring to allow
+// for an easy find/replace transformation when moving to Google3.
+#include <google/protobuf/descriptor.h>
+
+namespace perfetto {
+namespace proto_merger {
+
+/// Simplified representation of the coomponents of a .proto file.
+struct ProtoFile {
+ struct Option {
+ std::string key;
+ std::string value;
+ };
+ struct Member {
+ std::vector<std::string> leading_comments;
+ std::vector<std::string> trailing_comments;
+ };
+ struct Enum : Member {
+ struct Value : Member {
+ std::string name;
+ int number;
+ std::vector<Option> options;
+ };
+ std::string name;
+ std::vector<Value> values;
+
+ std::vector<Value> deleted_values;
+ };
+ struct Field : Member {
+ std::string label;
+ std::string packageless_type;
+ std::string type;
+ std::string name;
+ int number;
+ std::vector<Option> options;
+ };
+ struct Oneof : Member {
+ std::string name;
+ std::vector<Field> fields;
+
+ std::vector<Field> deleted_fields;
+ };
+ struct Message : Member {
+ std::string name;
+ std::vector<Enum> enums;
+ std::vector<Message> nested_messages;
+ std::vector<Oneof> oneofs;
+ std::vector<Field> fields;
+
+ std::vector<Enum> deleted_enums;
+ std::vector<Message> deleted_nested_messages;
+ std::vector<Oneof> deleted_oneofs;
+ std::vector<Field> deleted_fields;
+ };
+
+ std::vector<Message> messages;
+ std::vector<Enum> enums;
+
+ std::vector<Message> deleted_messages;
+ std::vector<Enum> deleted_enums;
+};
+
+// Creates a ProtoFile struct from a libprotobuf-full descriptor clas.
+ProtoFile ProtoFileFromDescriptor(const google::protobuf::FileDescriptor&);
+
+} // namespace proto_merger
+} // namespace perfetto
+
+#endif // TOOLS_PROTO_MERGER_PROTO_FILE_H_
diff --git a/tools/proto_merger/proto_file_serializer.cc b/tools/proto_merger/proto_file_serializer.cc
new file mode 100644
index 000000000..82232b2ed
--- /dev/null
+++ b/tools/proto_merger/proto_file_serializer.cc
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tools/proto_merger/proto_file_serializer.h"
+
+#include "perfetto/ext/base/string_utils.h"
+
+namespace perfetto {
+namespace proto_merger {
+namespace {
+
+std::string DeletedComment(const std::string& prefix) {
+ std::string output;
+ output += "\n";
+ output += prefix + " //\n";
+ output += prefix;
+ output +=
+ " // The following enums/messages/fields are not present upstream\n";
+ output += prefix + " //\n";
+ return output;
+}
+
+std::string SerializeComments(const std::string& prefix,
+ const std::vector<std::string>& lines) {
+ std::string output;
+ for (const auto& line : lines) {
+ output.append(prefix);
+ output.append("//");
+ output.append(line);
+ output.append("\n");
+ }
+ return output;
+}
+
+std::string SerializeLeadingComments(const std::string& prefix,
+ const ProtoFile::Member& member,
+ bool prefix_newline_if_comment = true) {
+ if (member.leading_comments.empty())
+ return "";
+
+ std::string output;
+ if (prefix_newline_if_comment) {
+ output += "\n";
+ }
+ output += SerializeComments(prefix, member.leading_comments);
+ return output;
+}
+
+std::string SerializeTrailingComments(const std::string& prefix,
+ const ProtoFile::Member& member) {
+ return SerializeComments(prefix, member.trailing_comments);
+}
+
+std::string SerializeOptions(const std::vector<ProtoFile::Option>& options) {
+ if (options.empty())
+ return "";
+
+ std::string output;
+ output += " [";
+ for (const auto& option : options) {
+ output += option.key + " = " + option.value;
+ }
+ output += "]";
+ return output;
+}
+
+std::string SerializeEnumValue(size_t indent,
+ const ProtoFile::Enum::Value& value) {
+ std::string prefix(indent * 2, ' ');
+
+ std::string output;
+ output += SerializeLeadingComments(prefix, value, false);
+
+ output += prefix + value.name + " = " + std::to_string(value.number);
+ output += SerializeOptions(value.options);
+ output += ";\n";
+
+ output += SerializeTrailingComments(prefix, value);
+ return output;
+}
+
+std::string SerializeEnum(size_t indent, const ProtoFile::Enum& en) {
+ std::string prefix(indent * 2, ' ');
+ ++indent;
+
+ std::string output;
+ output += SerializeLeadingComments(prefix, en);
+
+ output += prefix + "enum " + en.name + " {\n";
+ for (const auto& value : en.values) {
+ output += SerializeEnumValue(indent, value);
+ }
+ output += prefix + "}\n";
+
+ output += SerializeTrailingComments(prefix, en);
+ return output;
+}
+
+std::string SerializeField(size_t indent,
+ const ProtoFile::Field& field,
+ bool write_label) {
+ std::string prefix(indent * 2, ' ');
+
+ std::string output;
+ output += SerializeLeadingComments(prefix, field);
+
+ std::string label;
+ if (write_label) {
+ label = field.label + " ";
+ }
+ output += prefix + label + field.type + " " + field.name + " = " +
+ std::to_string(field.number);
+
+ output += SerializeOptions(field.options);
+ output += ";\n";
+
+ output += SerializeTrailingComments(prefix, field);
+ return output;
+}
+
+std::string SerializeOneof(size_t indent, const ProtoFile::Oneof& oneof) {
+ std::string prefix(indent * 2, ' ');
+ ++indent;
+
+ std::string output;
+ output += SerializeLeadingComments(prefix, oneof);
+
+ output += prefix + "oneof " + oneof.name + " {\n";
+ for (const auto& field : oneof.fields) {
+ output += SerializeField(indent, field, false);
+ }
+ output += prefix + "}\n";
+
+ output += SerializeTrailingComments(prefix, oneof);
+ return output;
+}
+
+std::string SerializeMessage(size_t indent, const ProtoFile::Message& message) {
+ std::string prefix(indent * 2, ' ');
+ ++indent;
+
+ std::string output;
+ output += SerializeLeadingComments(prefix, message);
+
+ output += prefix + "message " + message.name + " {\n";
+ for (const auto& en : message.enums) {
+ output += SerializeEnum(indent, en);
+ }
+ for (const auto& nested : message.nested_messages) {
+ output += SerializeMessage(indent, nested);
+ }
+ for (const auto& oneof : message.oneofs) {
+ output += SerializeOneof(indent, oneof);
+ }
+ for (const auto& field : message.fields) {
+ output += SerializeField(indent, field, true);
+ }
+
+ if (!message.deleted_enums.empty() || !message.deleted_fields.empty() ||
+ !message.deleted_nested_messages.empty() ||
+ !message.deleted_oneofs.empty()) {
+ output += DeletedComment(prefix);
+ for (const auto& en : message.deleted_enums) {
+ output += SerializeEnum(indent, en);
+ }
+ for (const auto& nested : message.deleted_nested_messages) {
+ output += SerializeMessage(indent, nested);
+ }
+ for (const auto& oneof : message.deleted_oneofs) {
+ output += SerializeOneof(indent, oneof);
+ }
+ for (const auto& field : message.deleted_fields) {
+ output += SerializeField(indent, field, true);
+ }
+ }
+
+ output += prefix + "}\n";
+
+ output += SerializeTrailingComments(prefix, message);
+ return output;
+}
+
+} // namespace
+
+std::string ProtoFileToDotProto(const ProtoFile& proto_file) {
+ std::string output;
+ for (const auto& en : proto_file.enums) {
+ output += SerializeEnum(0, en);
+ }
+ for (const auto& message : proto_file.messages) {
+ output += SerializeMessage(0, message);
+ }
+
+ if (!proto_file.deleted_enums.empty() ||
+ !proto_file.deleted_messages.empty()) {
+ output += DeletedComment("");
+
+ for (const auto& en : proto_file.deleted_enums) {
+ output += SerializeEnum(0, en);
+ }
+ for (const auto& nested : proto_file.deleted_messages) {
+ output += SerializeMessage(0, nested);
+ }
+ }
+ return output;
+}
+
+} // namespace proto_merger
+} // namespace perfetto
diff --git a/tools/proto_merger/proto_file_serializer.h b/tools/proto_merger/proto_file_serializer.h
new file mode 100644
index 000000000..23addadf0
--- /dev/null
+++ b/tools/proto_merger/proto_file_serializer.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TOOLS_PROTO_MERGER_PROTO_FILE_SERIALIZER_H_
+#define TOOLS_PROTO_MERGER_PROTO_FILE_SERIALIZER_H_
+
+#include "tools/proto_merger/proto_file.h"
+
+namespace perfetto {
+namespace proto_merger {
+
+// Serializes a ProtoFile struct into a .proto file which is
+// capable of being parsed by protoc.
+// For example:
+// ProtoFile {
+// messages: [
+// Message {
+// name: Baz
+// fields: [
+// Field {
+// label: optional
+// type: Foo
+// name: foo
+// number: 1
+// }
+// Field {
+// label: optional
+// type: Bar
+// name: bar
+// number: 2
+// }
+// ]
+// }
+// ]
+// }
+//
+// will convert to:
+//
+// message Baz {
+// optional Foo foo = 1;
+// optonal Bar bar = 2;
+// }
+std::string ProtoFileToDotProto(const ProtoFile&);
+
+} // namespace proto_merger
+} // namespace perfetto
+
+#endif // TOOLS_PROTO_MERGER_PROTO_FILE_SERIALIZER_H_
diff --git a/tools/proto_merger/proto_merger.cc b/tools/proto_merger/proto_merger.cc
new file mode 100644
index 000000000..c362d59f1
--- /dev/null
+++ b/tools/proto_merger/proto_merger.cc
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tools/proto_merger/proto_merger.h"
+
+#include "perfetto/base/logging.h"
+#include "perfetto/base/status.h"
+#include "perfetto/ext/base/optional.h"
+
+namespace perfetto {
+namespace proto_merger {
+namespace {
+
+template <typename Key, typename Value>
+base::Optional<Value> FindInMap(const std::map<Key, Value>& map,
+ const Key& key) {
+ auto it = map.find(key);
+ return it == map.end() ? base::nullopt : base::make_optional(it->second);
+}
+
+// Finds the given 'name' in the vector by comparing against
+// the field named 'name' for each item in the vector.
+// T is ProtoFile::Enum, ProtoFile::Oneof or ProtoFile::Message.
+template <typename T>
+const T* FindByName(const std::vector<T>& items, const std::string& name) {
+ for (const auto& item : items) {
+ if (item.name == name)
+ return &item;
+ }
+ return nullptr;
+}
+
+// Compute the items present in the |input| vector but deleted in
+// the |upstream| vector by looking at the field |name|.
+// T is ProtoFile::Enum, ProtoFile::Oneof or ProtoFile::Message.
+template <typename T>
+std::vector<T> ComputeDeletedByName(const std::vector<T>& input,
+ const std::vector<T>& upstream) {
+ std::vector<T> deleted;
+ std::set<std::string> seen;
+ for (const auto& upstream_item : upstream) {
+ auto* input_item = FindByName(input, upstream_item.name);
+ if (!input_item)
+ continue;
+ seen.insert(input_item->name);
+ }
+
+ for (const auto& input_item : input) {
+ if (seen.count(input_item.name))
+ continue;
+ deleted.emplace_back(input_item);
+ }
+ return deleted;
+}
+
+// Finds the given 'number' in the vector by comparing against
+// the field named 'number for each item in the vector.
+// T is ProtoFile::EnumValue or ProtoFile::Field.
+template <typename T>
+const T* FindByNumber(const std::vector<T>& items, int number) {
+ for (const auto& item : items) {
+ if (item.number == number)
+ return &item;
+ }
+ return nullptr;
+}
+
+// Compute the items present in the |input| vector but deleted in
+// the |upstream| vector by looking at the field |number|.
+// T is ProtoFile::EnumValue or ProtoFile::Field.
+template <typename T>
+std::vector<T> ComputeDeletedByNumber(const std::vector<T>& input,
+ const std::vector<T>& upstream) {
+ std::vector<T> deleted;
+ std::set<int> seen;
+ for (const auto& upstream_item : upstream) {
+ auto* input_item = FindByNumber(input, upstream_item.number);
+ if (!input_item)
+ continue;
+ seen.insert(input_item->number);
+ }
+
+ for (const auto& input_item : input) {
+ if (seen.count(input_item.number))
+ continue;
+ deleted.emplace_back(input_item);
+ }
+ return deleted;
+}
+
+ProtoFile::Enum::Value MergeEnumValue(const ProtoFile::Enum::Value& input,
+ const ProtoFile::Enum::Value& upstream) {
+ PERFETTO_CHECK(input.number == upstream.number);
+
+ ProtoFile::Enum::Value out;
+ out.name = upstream.name;
+
+ // Get the comments from the source of truth.
+ out.leading_comments = upstream.leading_comments;
+ out.trailing_comments = upstream.trailing_comments;
+
+ // Get everything else from the input.
+ out.number = input.number;
+ out.options = input.options;
+ return out;
+}
+
+ProtoFile::Enum MergeEnum(const ProtoFile::Enum& input,
+ const ProtoFile::Enum& upstream) {
+ PERFETTO_CHECK(input.name == upstream.name);
+
+ ProtoFile::Enum out;
+ out.name = upstream.name;
+
+ // Get the comments from the source of truth.
+ out.leading_comments = upstream.leading_comments;
+ out.trailing_comments = upstream.trailing_comments;
+
+ for (const auto& upstream_value : upstream.values) {
+ // If an enum is allowlisted, we implicitly assume that all its
+ // values are also allowed. Therefore, if the value doesn't exist
+ // in the input, just take it from the source of truth.
+ auto* input_value = FindByNumber(input.values, upstream_value.number);
+ auto out_value = input_value ? MergeEnumValue(*input_value, upstream_value)
+ : upstream_value;
+ out.values.emplace_back(std::move(out_value));
+ }
+
+ // Compute all the values present in the input but deleted in the
+ // source of truth.
+ out.deleted_values = ComputeDeletedByNumber(input.values, upstream.values);
+ return out;
+}
+
+std::vector<ProtoFile::Enum> MergeEnums(
+ const std::vector<ProtoFile::Enum>& input,
+ const std::vector<ProtoFile::Enum>& upstream,
+ const std::set<std::string>& allowlist) {
+ std::vector<ProtoFile::Enum> out;
+ for (const auto& upstream_enum : upstream) {
+ auto* input_enum = FindByName(input, upstream_enum.name);
+ if (!input_enum) {
+ // If the enum is missing from the input but is present
+ // in the allowlist, take the whole enum from the
+ // source of truth.
+ if (allowlist.count(upstream_enum.name))
+ out.emplace_back(upstream_enum);
+ continue;
+ }
+
+ // Otherwise, merge the enums from the input and source of truth.
+ out.emplace_back(MergeEnum(*input_enum, upstream_enum));
+ }
+ return out;
+}
+
+base::Status MergeField(const ProtoFile::Field& input,
+ const ProtoFile::Field& upstream,
+ ProtoFile::Field& out) {
+ PERFETTO_CHECK(input.number == upstream.number);
+
+ if (input.packageless_type != upstream.packageless_type) {
+ return base::ErrStatus(
+ "The type of field with id %d and name %s (source of truth name: %s) "
+ "changed from %s to %s. Please resolve conflict manually before "
+ "rerunning.",
+ input.number, input.name.c_str(), upstream.name.c_str(),
+ input.packageless_type.c_str(), upstream.packageless_type.c_str());
+ }
+
+ // If the packageless type mathces, the type should also match.
+ PERFETTO_CHECK(input.type == upstream.type);
+
+ // Get the comments, label and the name from the source of truth.
+ out.leading_comments = upstream.leading_comments;
+ out.trailing_comments = upstream.trailing_comments;
+ out.label = upstream.label;
+ out.name = upstream.name;
+
+ // Get everything else from the input.
+ out.number = input.number;
+ out.options = input.options;
+ out.packageless_type = input.packageless_type;
+ out.type = input.type;
+
+ return base::OkStatus();
+}
+
+base::Status MergeFields(const std::vector<ProtoFile::Field>& input,
+ const std::vector<ProtoFile::Field>& upstream,
+ const std::set<int>& allowlist,
+ std::vector<ProtoFile::Field>& out) {
+ for (const auto& upstream_field : upstream) {
+ auto* input_field = FindByNumber(input, upstream_field.number);
+ if (!input_field) {
+ // If the field is missing from the input but is present
+ // in the allowlist, take the whole field from the
+ // source of truth.
+ if (allowlist.count(upstream_field.number))
+ out.emplace_back(upstream_field);
+ continue;
+ }
+
+ // Otherwise, merge the fields from the input and source of truth.
+ ProtoFile::Field out_field;
+ base::Status status = MergeField(*input_field, upstream_field, out_field);
+ if (!status.ok())
+ return status;
+ out.emplace_back(std::move(out_field));
+ }
+ return base::OkStatus();
+}
+
+// We call both of these just "Merge" so that |MergeRecursive| below can
+// reference them with the same name.
+base::Status Merge(const ProtoFile::Oneof& input,
+ const ProtoFile::Oneof& upstream,
+ const Allowlist::Oneof& allowlist,
+ ProtoFile::Oneof& out);
+
+base::Status Merge(const ProtoFile::Message& input,
+ const ProtoFile::Message& upstream,
+ const Allowlist::Message& allowlist,
+ ProtoFile::Message& out);
+
+template <typename T, typename AllowlistType>
+base::Status MergeRecursive(
+ const std::vector<T>& input,
+ const std::vector<T>& upstream,
+ const std::map<std::string, AllowlistType>& allowlist_map,
+ std::vector<T>& out) {
+ for (const auto& upstream_item : upstream) {
+ auto opt_allowlist = FindInMap(allowlist_map, upstream_item.name);
+ auto* input_item = FindByName(input, upstream_item.name);
+
+ // If the value is not present in the input and the allowlist doesn't
+ // exist either, this field is not approved so should not be included
+ // in the output.
+ if (!input_item && !opt_allowlist)
+ continue;
+
+ // If the input value doesn't exist, create a fake "input" that we can pass
+ // to the merge functon. This basically has the effect that the upstream
+ // item is taken but *not* recrusively; i.e. any fields which are inside the
+ // message/oneof are checked against the allowlist individually. If we just
+ // took the whole upstream here, we could add fields which were not
+ // allowlisted.
+ T input_or_fake;
+ if (input_item) {
+ input_or_fake = *input_item;
+ } else {
+ input_or_fake.name = upstream_item.name;
+ }
+
+ auto allowlist = opt_allowlist.value_or(AllowlistType{});
+ T out_item;
+ auto status = Merge(input_or_fake, upstream_item, allowlist, out_item);
+ if (!status.ok())
+ return status;
+ out.emplace_back(std::move(out_item));
+ }
+ return base::OkStatus();
+}
+
+base::Status Merge(const ProtoFile::Oneof& input,
+ const ProtoFile::Oneof& upstream,
+ const Allowlist::Oneof& allowlist,
+ ProtoFile::Oneof& out) {
+ PERFETTO_CHECK(input.name == upstream.name);
+ out.name = input.name;
+
+ // Get the comments from the source of truth.
+ out.leading_comments = upstream.leading_comments;
+ out.trailing_comments = upstream.trailing_comments;
+
+ // Compute all the fields present in the input but deleted in the
+ // source of truth.
+ out.deleted_fields = ComputeDeletedByNumber(input.fields, upstream.fields);
+
+ // Finish by merging the list of fields.
+ return MergeFields(input.fields, upstream.fields, allowlist, out.fields);
+}
+
+base::Status Merge(const ProtoFile::Message& input,
+ const ProtoFile::Message& upstream,
+ const Allowlist::Message& allowlist,
+ ProtoFile::Message& out) {
+ PERFETTO_CHECK(input.name == upstream.name);
+ out.name = input.name;
+
+ // Get the comments from the source of truth.
+ out.leading_comments = upstream.leading_comments;
+ out.trailing_comments = upstream.trailing_comments;
+
+ // Compute all the values present in the input but deleted in the
+ // source of truth.
+ out.deleted_enums = ComputeDeletedByName(input.enums, upstream.enums);
+ out.deleted_nested_messages =
+ ComputeDeletedByName(input.nested_messages, upstream.nested_messages);
+ out.deleted_oneofs = ComputeDeletedByName(input.oneofs, upstream.oneofs);
+ out.deleted_fields = ComputeDeletedByNumber(input.fields, upstream.fields);
+
+ // Merge any nested enum types.
+ out.enums = MergeEnums(input.enums, upstream.enums, allowlist.enums);
+
+ // Merge any nested message types.
+ auto status = MergeRecursive(input.nested_messages, upstream.nested_messages,
+ allowlist.nested_messages, out.nested_messages);
+ if (!status.ok())
+ return status;
+
+ // Merge any oneofs.
+ status = MergeRecursive(input.oneofs, upstream.oneofs, allowlist.oneofs,
+ out.oneofs);
+ if (!status.ok())
+ return status;
+
+ // Finish by merging the list of fields.
+ return MergeFields(input.fields, upstream.fields, allowlist.fields,
+ out.fields);
+}
+
+} // namespace
+
+base::Status MergeProtoFiles(const ProtoFile& input,
+ const ProtoFile& upstream,
+ const Allowlist& allowlist,
+ ProtoFile& out) {
+ // Compute all the enums and messages present in the input but deleted in the
+ // source of truth.
+ out.deleted_enums = ComputeDeletedByName(input.enums, upstream.enums);
+ out.deleted_messages =
+ ComputeDeletedByName(input.messages, upstream.messages);
+
+ // Merge the top-level enums.
+ out.enums = MergeEnums(input.enums, upstream.enums, allowlist.enums);
+
+ // Finish by merging the top-level messages.
+ return MergeRecursive(input.messages, upstream.messages, allowlist.messages,
+ out.messages);
+}
+
+} // namespace proto_merger
+} // namespace perfetto
diff --git a/tools/proto_merger/proto_merger.h b/tools/proto_merger/proto_merger.h
new file mode 100644
index 000000000..159aa3544
--- /dev/null
+++ b/tools/proto_merger/proto_merger.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TOOLS_PROTO_MERGER_PROTO_MERGER_H_
+#define TOOLS_PROTO_MERGER_PROTO_MERGER_H_
+
+#include "perfetto/base/status.h"
+#include "tools/proto_merger/allowlist.h"
+#include "tools/proto_merger/proto_file.h"
+
+namespace perfetto {
+namespace proto_merger {
+
+// Merges any updates in the proto |upstream| into the proto |input|
+// optionally adding any messages/fields/enums/values specified in the
+// the |allowlist|.
+//
+// Some notes about the merging algorithm:
+// * Comments for all values are always taken from |upstream|.
+// * If an enum is allowed, then so are all it's values.
+// * Options for fields are always taken from |input|; any new options in
+// |upstream| are ignored.
+// * Changing the type of an existing field is not supported (even if its
+// just a move); this needs to be handled manually.
+base::Status MergeProtoFiles(const ProtoFile& input,
+ const ProtoFile& upstream,
+ const Allowlist& allowlist,
+ ProtoFile& out);
+
+} // namespace proto_merger
+} // namespace perfetto
+
+#endif // TOOLS_PROTO_MERGER_PROTO_MERGER_H_
diff --git a/tools/pull_ftrace_format_files.py b/tools/pull_ftrace_format_files.py
index 9f33df9e4..6926c0150 100755
--- a/tools/pull_ftrace_format_files.py
+++ b/tools/pull_ftrace_format_files.py
@@ -34,7 +34,7 @@ def adb(*cmd, **kwargs):
if serial:
prefix += ['-s', serial]
cmd = prefix + list(cmd)
- output = subprocess.check_output(cmd).replace('\r', '')
+ output = subprocess.check_output(cmd, encoding='utf-8').replace('\r', '')
return output
@@ -88,7 +88,7 @@ def ensure_single_device(serial):
def pull_format_files(serial, output_directory):
# Pulling each file individually is 100x slower so we pipe all together then
# split them on the host.
- cmd = "find /sys/kernel/debug/tracing/ " \
+ cmd = "find /sys/kernel/tracing/ " \
"-name available_events -o " \
"-name format -o " \
"-name header_event -o " \
@@ -97,14 +97,14 @@ def pull_format_files(serial, output_directory):
"while read f; do echo 'path:' $f; cat $f; done"
output = adb('shell', cmd, serial=serial)
- sections = output.split('path: /sys/kernel/debug/tracing/')
+ sections = output.split('path: /sys/kernel/tracing/')
for section in sections:
if not section:
continue
path, rest = section.split('\n', 1)
path = os.path.join(output_directory, path)
ensure_dir(os.path.dirname(path))
- with open(path, 'wb') as f:
+ with open(path, 'w') as f:
f.write(rest)
@@ -116,7 +116,8 @@ def get_output_directory(prefix=None, serial=None):
parts = ['android', product, build_id, kernel]
if prefix:
parts = [prefix] + parts
- return '_'.join(parts)
+ dir_name = '_'.join(parts)
+ return os.path.join(ROOT_DIR, 'src/traced/probes/ftrace/test/data', dir_name)
def main():
diff --git a/tools/record_android_trace b/tools/record_android_trace
index 787463846..f2931ed86 100755
--- a/tools/record_android_trace
+++ b/tools/record_android_trace
@@ -1,14 +1,30 @@
#!/usr/bin/env python3
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
import atexit
import argparse
import datetime
+import hashlib
import http.server
import os
+import re
import shutil
import socketserver
import subprocess
import sys
+import tempfile
import time
import webbrowser
@@ -18,6 +34,16 @@ ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# PATH. It's fine if it doesn't exist so this script can be copied elsewhere.
HERMETIC_ADB_PATH = ROOT_DIR + '/buildtools/android_sdk/platform-tools/adb'
+# Translates the Android ro.product.cpu.abi into the GN's target_cpu.
+ABI_TO_ARCH = {
+ 'armeabi-v7a': 'arm',
+ 'arm64-v8a': 'arm64',
+ 'x86': 'x86',
+ 'x86_64': 'x64',
+}
+
+MAX_ADB_FAILURES = 15 # 2 seconds between retries, 30 seconds total.
+
devnull = open(os.devnull, 'rb')
adb_path = None
procs = []
@@ -54,7 +80,7 @@ def main():
default_out_dir = os.path.expanduser(default_out_dir_str)
examples = '\n'.join([
- ANSI.BOLD + 'Examples' + ANSI.END, ' -t 10s -b 32mb sched gfx wm',
+ ANSI.BOLD + 'Examples' + ANSI.END, ' -t 10s -b 32mb sched gfx wm -a*',
' -t 5s sched/sched_switch raw_syscalls/sys_enter raw_syscalls/sys_exit',
' -c /path/to/full-textual-trace.config', '',
ANSI.BOLD + 'Long traces' + ANSI.END,
@@ -71,6 +97,16 @@ def main():
help = 'Don\'t open in the browser'
parser.add_argument('-n', '--no-open', action='store_true', help=help)
+ help = 'Force the use of the sideloaded binaries rather than system daemons'
+ parser.add_argument('--sideload', action='store_true', help=help)
+
+ help = ('Sideload the given binary rather than downloading it. ' +
+ 'Implies --sideload')
+ parser.add_argument('--sideload-path', default=None, help=help)
+
+ help = 'Don\'t run `adb root` run as user (only when sideloading)'
+ parser.add_argument('-u', '--user', action='store_true', help=help)
+
grp = parser.add_argument_group(
'Short options: (only when not using -c/--config)')
@@ -80,11 +116,12 @@ def main():
help = 'Ring buffer size N[mb,gb] (default: 32mb)'
grp.add_argument('-b', '--buffer', default='32mb', help=help)
- help = 'Android (atrace) app names (can be specified multiple times)'
+ help = ('Android (atrace) app names. Can be specified multiple times.\n-a*' +
+ 'for all apps (without space between a and * or bash will expand it)')
grp.add_argument(
'-a',
'--app',
- metavar='Atrace apps',
+ metavar='com.myapp',
action='append',
default=[],
help=help)
@@ -106,11 +143,15 @@ def main():
help = 'Can be generated with https://ui.perfetto.dev/#!/record'
grp.add_argument('-c', '--config', default=None, help=help)
+
+ help = 'Specify the ADB device serial'
+ grp.add_argument('--serial', '-s', default=None, help=help)
+
args = parser.parse_args()
+ args.sideload = args.sideload or args.sideload_path is not None
- tstamp = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M')
- fname = '%s.pftrace' % tstamp
- device_file = '/data/misc/perfetto-traces/' + fname
+ if args.serial:
+ os.environ["ANDROID_SERIAL"] = args.serial
find_adb()
@@ -137,13 +178,75 @@ def main():
'Did you mean to pass -c / --config ?'), ANSI.RED)
sys.exit(1)
- cmd = ['perfetto', '--background', '--txt', '-o', device_file]
+ perfetto_cmd = 'perfetto'
+ device_dir = '/data/misc/perfetto-traces/'
+
+ # Check the version of android. If too old (< Q) sideload tracebox. Also use
+ # use /data/local/tmp as /data/misc/perfetto-traces was introduced only later.
+ probe_cmd = 'getprop ro.build.version.sdk; getprop ro.product.cpu.abi; whoami'
+ probe = adb('shell', probe_cmd, stdout=subprocess.PIPE)
+ lines = probe.communicate()[0].decode().strip().split('\n')
+ lines = [x.strip() for x in lines] # To strip \r(s) on Windows.
+ if probe.returncode != 0:
+ prt('ADB connection failed', ANSI.RED)
+ sys.exit(1)
+ api_level = int(lines[0])
+ abi = lines[1]
+ arch = ABI_TO_ARCH.get(abi)
+ if arch is None:
+ prt('Unsupported ABI: ' + abi)
+ sys.exit(1)
+ shell_user = lines[2]
+ if api_level < 29 or args.sideload: # 29: Android Q.
+ tracebox_bin = args.sideload_path
+ if tracebox_bin is None:
+ tracebox_bin = get_perfetto_prebuilt('tracebox', arch='android-' + arch)
+ perfetto_cmd = '/data/local/tmp/tracebox'
+ exit_code = adb('push', '--sync', tracebox_bin, perfetto_cmd).wait()
+ exit_code |= adb('shell', 'chmod 755 ' + perfetto_cmd).wait()
+ if exit_code != 0:
+ prt('ADB push failed', ANSI.RED)
+ sys.exit(1)
+ device_dir = '/data/local/tmp/'
+ if shell_user != 'root' and not args.user:
+ # Run as root if possible as that will give access to more tracing
+ # capabilities. Non-root still works, but some ftrace events might not be
+ # available.
+ adb('root').wait()
+
+ tstamp = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M')
+ fname = '%s-%s.pftrace' % (tstamp, os.urandom(3).hex())
+ device_file = device_dir + fname
+
+ cmd = [perfetto_cmd, '--background', '--txt', '-o', device_file]
+ on_device_config = None
+ on_host_config = None
if args.config is not None:
cmd += ['-c', '-']
+ if api_level < 24:
+ # adb shell does not redirect stdin. Push the config on a temporary file
+ # on the device.
+ mktmp = adb(
+ 'shell',
+ 'mktemp',
+ '--tmpdir',
+ '/data/local/tmp',
+ stdout=subprocess.PIPE)
+ on_device_config = mktmp.communicate()[0].decode().strip().strip()
+ if mktmp.returncode != 0:
+ prt('Failed to create config on device', ANSI.RED)
+ sys.exit(1)
+ exit_code = adb('push', '--sync', args.config, on_device_config).wait()
+ if exit_code != 0:
+ prt('Failed to push config on device', ANSI.RED)
+ sys.exit(1)
+ cmd = ['cat', on_device_config, '|'] + cmd
+ else:
+ on_host_config = args.config
else:
cmd += ['-t', args.time, '-b', args.buffer]
for app in args.app:
- cmd += ['--app', app]
+ cmd += ['--app', '\'' + app + '\'']
cmd += args.events
# Perfetto will error out with a proper message if both a config file and
@@ -162,10 +265,23 @@ def main():
if not os.path.exists(host_dir):
shutil.os.makedirs(host_dir)
- with open(args.config or os.devnull, 'rb') as f:
+ with open(on_host_config or os.devnull, 'rb') as f:
print('Running ' + ' '.join(cmd))
proc = adb('shell', *cmd, stdin=f, stdout=subprocess.PIPE)
- bg_pid = proc.communicate()[0].decode().strip()
+ proc_out = proc.communicate()[0].decode().strip()
+ if on_device_config is not None:
+ adb('shell', 'rm', on_device_config).wait()
+ # On older versions of Android (x86_64 emulator running API 22) the output
+ # looks like:
+ # WARNING: linker: /data/local/tmp/tracebox: unused DT entry: ...
+ # WARNING: ... (other 2 WARNING: linker: lines)
+ # 1234 <-- The actual pid we want.
+ match = re.search(r'^(\d+)$', proc_out, re.M)
+ if match is None:
+ prt('Failed to read the pid from perfetto --background', ANSI.RED)
+ prt(proc_out)
+ sys.exit(1)
+ bg_pid = match.group(1)
exit_code = proc.wait()
if exit_code != 0:
@@ -177,17 +293,39 @@ def main():
'1')
ctrl_c_count = 0
+ adb_failure_count = 0
while ctrl_c_count < 2:
try:
- poll = adb('shell', 'test -d /proc/' + bg_pid)
- if poll.wait() != 0:
- break
- time.sleep(0.5)
+ # On older Android devices adbd doesn't propagate the exit code. Hence
+ # the RUN/TERM parts.
+ poll = adb(
+ 'shell',
+ 'test -d /proc/%s && echo RUN || echo TERM' % bg_pid,
+ stdout=subprocess.PIPE)
+ poll_res = poll.communicate()[0].decode().strip()
+ if poll_res == 'TERM':
+ break # Process terminated
+ if poll_res == 'RUN':
+ # The 'perfetto' cmdline client is still running. If previously we had
+ # an ADB error, tell the user now it's all right again.
+ if adb_failure_count > 0:
+ adb_failure_count = 0
+ prt('ADB connection re-established, the trace is still ongoing',
+ ANSI.BLUE)
+ time.sleep(0.5)
+ continue
+ # Some ADB error happened. This can happen when tracing soon after boot,
+ # before logging in, when adb gets restarted.
+ adb_failure_count += 1
+ if adb_failure_count >= MAX_ADB_FAILURES:
+ prt('Too many unrecoverable ADB failures, bailing out', ANSI.RED)
+ sys.exit(1)
+ time.sleep(2)
except KeyboardInterrupt:
sig = 'TERM' if ctrl_c_count == 0 else 'KILL'
ctrl_c_count += 1
prt('Stopping the trace (SIG%s)' % sig, ANSI.BLACK + ANSI.BG_YELLOW)
- res = adb('shell', 'kill -%s %s' % (sig, bg_pid)).wait()
+ adb('shell', 'kill -%s %s' % (sig, bg_pid)).wait()
logcat.kill()
logcat.wait()
@@ -195,6 +333,7 @@ def main():
prt('\n')
prt('Pulling into %s' % host_file, ANSI.BOLD)
adb('pull', device_file, host_file).wait()
+ adb('shell', 'rm -f ' + device_file).wait()
if not args.no_open:
prt('\n')
@@ -235,7 +374,7 @@ def open_trace_in_browser(path):
socketserver.TCPServer.allow_reuse_address = True
with socketserver.TCPServer(('127.0.0.1', PORT), HttpHandler) as httpd:
webbrowser.open_new_tab(
- 'https://ui.perfetto.dev/#!/?url=http://127.0.0.1:%d/%s' %
+ 'https://ui.perfetto.dev/#!/?url=http://127.0.0.1:%d/%s' %
(PORT, fname))
while httpd.__dict__.get('last_request') != '/' + fname:
httpd.handle_request()
@@ -258,5 +397,141 @@ def kill_all_subprocs_on_exit():
p.kill()
+def check_hash(file_name, sha_value):
+ with open(file_name, 'rb') as fd:
+ file_hash = hashlib.sha1(fd.read()).hexdigest()
+ return file_hash == sha_value
+
+
+# BEGIN_SECTION_GENERATED_BY(roll-prebuilts)
+# Revision: v25.0
+PERFETTO_PREBUILT_MANIFEST = [{
+ 'tool':
+ 'tracebox',
+ 'arch':
+ 'android-arm',
+ 'file_name':
+ 'tracebox',
+ 'file_size':
+ 1067004,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/android-arm/tracebox',
+ 'sha256':
+ '6fff40fc02d154b187187fe70069cc93bde00d3be5b3582ba6120b0cfa83d379'
+}, {
+ 'tool':
+ 'tracebox',
+ 'arch':
+ 'android-arm64',
+ 'file_name':
+ 'tracebox',
+ 'file_size':
+ 1620704,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/android-arm64/tracebox',
+ 'sha256':
+ 'd482c86eccd7dc0ff4f57bd5d841d90e97ca5e31b881fcea442d4ad03ecfd4f4'
+}, {
+ 'tool':
+ 'tracebox',
+ 'arch':
+ 'android-x86',
+ 'file_name':
+ 'tracebox',
+ 'file_size':
+ 1644500,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/android-x86/tracebox',
+ 'sha256':
+ '48de1d10959b6130d2d6d68ae3ba0d8bb3f3aa6fe526d77ea9abad058a631d8f'
+}, {
+ 'tool':
+ 'tracebox',
+ 'arch':
+ 'android-x64',
+ 'file_name':
+ 'tracebox',
+ 'file_size':
+ 1870560,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/android-x64/tracebox',
+ 'sha256':
+ '333c17912a143300ca6afa3b27d93497821615028e612e5d6132889427c10599'
+}]
+
+
+# DO NOT EDIT. If you wish to make edits to this code, you need to change only
+# //tools/get_perfetto_prebuilt.py and run /tools/roll-prebuilts to regenerate
+# all the others scripts this is embedded into.
+def get_perfetto_prebuilt(tool_name, soft_fail=False, arch=None):
+ """ Downloads the prebuilt, if necessary, and returns its path on disk. """
+
+ # The first time this is invoked, it downloads the |url| and caches it into
+ # ~/.perfetto/prebuilts/$tool_name. On subsequent invocations it just runs the
+ # cached version.
+ def download_or_get_cached(file_name, url, sha256):
+ import os, hashlib, subprocess
+ dir = os.path.join(
+ os.path.expanduser('~'), '.local', 'share', 'perfetto', 'prebuilts')
+ os.makedirs(dir, exist_ok=True)
+ bin_path = os.path.join(dir, file_name)
+ sha256_path = os.path.join(dir, file_name + '.sha256')
+ needs_download = True
+
+ # Avoid recomputing the SHA-256 on each invocation. The SHA-256 of the last
+ # download is cached into file_name.sha256, just check if that matches.
+ if os.path.exists(bin_path) and os.path.exists(sha256_path):
+ with open(sha256_path, 'rb') as f:
+ digest = f.read().decode()
+ if digest == sha256:
+ needs_download = False
+
+ if needs_download:
+ # Either the filed doesn't exist or the SHA256 doesn't match.
+ tmp_path = bin_path + '.tmp'
+ print('Downloading ' + url)
+ subprocess.check_call(['curl', '-f', '-L', '-#', '-o', tmp_path, url])
+ with open(tmp_path, 'rb') as fd:
+ actual_sha256 = hashlib.sha256(fd.read()).hexdigest()
+ if actual_sha256 != sha256:
+ raise Exception('Checksum mismatch for %s (actual: %s, expected: %s)' %
+ (url, actual_sha256, sha256))
+ os.chmod(tmp_path, 0o755)
+ os.rename(tmp_path, bin_path)
+ with open(sha256_path, 'w') as f:
+ f.write(sha256)
+ return bin_path
+ # --- end of download_or_get_cached() ---
+
+ # --- get_perfetto_prebuilt() function starts here. ---
+ import os, platform, sys
+ plat = sys.platform.lower()
+ machine = platform.machine().lower()
+ manifest_entry = None
+ for entry in PERFETTO_PREBUILT_MANIFEST:
+ # If the caller overrides the arch, just match that (for Android prebuilts).
+ if arch and entry.get('arch') == arch:
+ manifest_entry = entry
+ break
+ # Otherwise guess the local machine arch.
+ if entry.get('tool') == tool_name and entry.get(
+ 'platform') == plat and machine in entry.get('machine', []):
+ manifest_entry = entry
+ break
+ if manifest_entry is None:
+ if soft_fail:
+ return None
+ raise Exception(
+ ('No prebuilts available for %s-%s\n' % (plat, machine)) +
+ 'See https://perfetto.dev/docs/contributing/build-instructions')
+
+ return download_or_get_cached(
+ file_name=manifest_entry['file_name'],
+ url=manifest_entry['url'],
+ sha256=manifest_entry['sha256'])
+
+
+# END_SECTION_GENERATED_BY(roll-prebuilts)
+
if __name__ == '__main__':
sys.exit(main())
diff --git a/tools/repackage_llvm_demangler.sh b/tools/repackage_llvm_demangler.sh
new file mode 100644
index 000000000..54081d5bb
--- /dev/null
+++ b/tools/repackage_llvm_demangler.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -eu
+
+# For perfetto maintainers. Pulls out demangling-related sources out of
+# llvm-project and repackages them as a single tar archive. This works around
+# the fact that gitiles, when generating an on-demand archive, uses a current
+# timestamp, so the hash of the archive is different every time you fetch.
+
+# Usage example:
+# sh tools/repackage_llvm_demangler.sh 3b4c59c156919902c785ce3cbae0eee2ee53064d
+#
+# Then upload the tar with "gsutil cp -n -a public-read ... gs://perfetto/...",
+# and update install-build-deps.
+
+GIT_REF=$1
+
+WORK_DIR=$(mktemp -d)
+pushd . && cd "${WORK_DIR}"
+
+CC_DIR="llvm-project/llvm/lib/Demangle"
+H_DIR="llvm-project/llvm/include/llvm/Demangle"
+
+CC_TGZ="Demangle_lib.tgz"
+H_TGZ="Demangle_include.tgz"
+
+curl -f -L -# "https://llvm.googlesource.com/llvm-project/+archive/${GIT_REF}/llvm/lib/Demangle.tar.gz" -o "${CC_TGZ}"
+curl -f -L -# "https://llvm.googlesource.com/llvm-project/+archive/${GIT_REF}/llvm/include/llvm/Demangle.tar.gz" -o "${H_TGZ}"
+
+mkdir -p "${CC_DIR}"
+mkdir -p "${H_DIR}"
+
+tar xf "${CC_TGZ}" -C "${CC_DIR}"
+tar xf "${H_TGZ}" -C "${H_DIR}"
+
+TAR_NAME="llvm-project-${GIT_REF}.tgz"
+tar czf "${TAR_NAME}" --sort=name --owner=root:0 --group=root:0 --mtime='UTC 2019-01-01' llvm-project
+
+TAR_SHA=$(sha256sum "${TAR_NAME}")
+
+echo "output file: ${WORK_DIR}/${TAR_NAME}"
+echo "contents sha256: ${TAR_SHA}"
+
+popd
diff --git a/tools/roll-prebuilts b/tools/roll-prebuilts
new file mode 100755
index 000000000..9ef513c0d
--- /dev/null
+++ b/tools/roll-prebuilts
@@ -0,0 +1,190 @@
+#!/usr/bin/env python3
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Updates the python scripts in tools/{trace_processor, traceconv, tracebox}
+
+This script does the following, for each entry in SCRIPTS_TO_UPDATE:
+ - Downloads the artifact by the LUCI infrastructure, one for each arch.
+ - Computes the SHA-256 of each artifact.
+ - Generates a manifest with URL, SHA-256 and other details.
+ - Merges get_perfetto_prebuilt.py with the manifest and writes tools/xxx.
+
+This script is supposed to be run by Perfetto OWNERS after every monthly release
+after the LUCI jobs have completed.
+"""
+
+import argparse
+import hashlib
+import logging
+import os
+import subprocess
+import sys
+
+from concurrent.futures import ThreadPoolExecutor
+
+GCS_URL = 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts'
+
+ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+TOOLS_DIR = os.path.join(ROOT_DIR, 'tools')
+
+SCRIPTS_TO_UPDATE = [
+ {
+ 'script':
+ 'trace_processor',
+ 'tool':
+ 'trace_processor_shell',
+ 'archs': [
+ 'mac-amd64', 'mac-arm64', 'windows-amd64', 'linux-amd64',
+ 'linux-arm', 'linux-arm64'
+ ]
+ },
+ {
+ 'script': 'traceconv',
+ 'tool': 'trace_to_text',
+ 'archs': ['mac-amd64', 'mac-arm64', 'linux-amd64', 'windows-amd64']
+ },
+ {
+ 'script':
+ 'tracebox',
+ 'tool':
+ 'tracebox',
+ 'archs': [
+ 'mac-amd64', 'mac-arm64', 'linux-amd64', 'linux-amd64', 'linux-arm',
+ 'linux-arm64'
+ ]
+ },
+ {
+ 'script': 'heap_profile',
+ 'tool': 'trace_to_text',
+ 'archs': ['mac-amd64', 'mac-arm64', 'windows-amd64', 'linux-amd64']
+ },
+ {
+ 'script': 'cpu_profile',
+ 'tool': 'trace_to_text',
+ 'archs': ['mac-amd64', 'windows-amd64', 'linux-amd64']
+ },
+ {
+ 'script': 'record_android_trace',
+ 'tool': 'tracebox',
+ 'archs': ['android-arm', 'android-arm64', 'android-x86', 'android-x64']
+ },
+]
+
+# Maps a 'os-arch' string (were arch follows LUCI conventions) into
+# corresponding tuples that match against python's platform / machine API
+# (see get_perfetto_prebuilt.py for usage).
+ARCH_TO_PYTHON = {
+ 'mac-amd64': {
+ 'platform': 'darwin',
+ 'machine': ['x86_64'],
+ },
+ 'mac-arm64': {
+ 'platform': 'darwin',
+ 'machine': ['arm64'],
+ },
+ 'windows-amd64': {
+ 'platform': 'win32',
+ 'machine': ['amd64'],
+ },
+ 'linux-amd64': {
+ 'platform': 'linux',
+ 'machine': ['x86_64'],
+ },
+ 'linux-arm': {
+ 'platform': 'linux',
+ 'machine': ['armv6l', 'armv7l', 'armv8l'],
+ },
+ 'linux-arm64': {
+ 'platform': 'linux',
+ 'machine': ['aarch64'],
+ },
+}
+
+
+def make_manifest(git_revision, tool, arch):
+ ext = '.exe' if arch.startswith('windows') else ''
+ file_name = tool + ext
+ url = '%s/%s/%s/%s' % (GCS_URL, git_revision, arch, file_name)
+ logging.info('Downloading %s', url)
+ data = subprocess.check_output(['curl', '-fsL', '-o', '-', url])
+ manifest = {
+ 'tool': tool,
+ 'arch': arch,
+ 'file_name': file_name,
+ 'file_size': len(data),
+ 'url': url,
+ 'sha256': hashlib.sha256(data).hexdigest()
+ }
+ manifest.update(ARCH_TO_PYTHON.get(arch, {}))
+ return manifest
+
+
+# Returns the section of get_perfetto_prebuilt.py which should be copy/pasted
+# in the various scripts.
+def read_get_perfetto_prebuilt_script():
+ in_file = os.path.join(TOOLS_DIR, 'get_perfetto_prebuilt.py')
+ with open(in_file, 'r') as f:
+ contents = f.read()
+ return contents.split('COPIED_SECTION_START_MARKER')[1]
+
+
+def update_script(git_revision, tool_name, script_name, archs):
+ with ThreadPoolExecutor(max_workers=8) as executor:
+ manifests = list(
+ executor.map(lambda arch: make_manifest(git_revision, tool_name, arch),
+ archs))
+ out_file = os.path.join(TOOLS_DIR, script_name)
+ with open(out_file) as f:
+ script = f.read()
+
+ begin_marker = '\n# BEGIN_SECTION_GENERATED_BY(roll-prebuilts)\n'
+ end_marker = '\n# END_SECTION_GENERATED_BY(roll-prebuilts)\n'
+ before = script.partition(begin_marker)[0]
+ after = script.partition(end_marker)[2]
+
+ content = '# Revision: {git_revision}\n'
+ content += 'PERFETTO_PREBUILT_MANIFEST = {manifests}\n'
+ content += '{fn_body}\n'
+ content = content.format(
+ git_revision=git_revision,
+ manifests=str(manifests),
+ fn_body=read_get_perfetto_prebuilt_script())
+
+ script = before + begin_marker + content + end_marker + after
+
+ with open(out_file + '.tmp', 'w') as f:
+ f.write(script)
+ subprocess.check_call(['yapf', '-i', out_file + '.tmp'])
+ os.rename(out_file + '.tmp', out_file)
+ os.chmod(out_file, 0o755)
+
+
+def main():
+ usage = '%s v20.0 | 0a1b2c3d\n\n' % __file__
+ usage += 'To list available revisions run\n'
+ usage += 'gsutil ls gs://perfetto-luci-artifacts/\n'
+ usage += 'or visit https://chrome-infra-packages.appspot.com/p/perfetto\n'
+ parser = argparse.ArgumentParser(usage=usage)
+ parser.add_argument('version')
+ args = parser.parse_args()
+
+ git_revision = args.version
+ for spec in SCRIPTS_TO_UPDATE:
+ logging.info('Updating %s', spec['script'])
+ update_script(git_revision, spec['tool'], spec['script'], spec['archs'])
+
+
+if __name__ == '__main__':
+ logging.basicConfig(level=logging.INFO)
+ sys.exit(main())
diff --git a/tools/run_buildtools_binary.py b/tools/run_buildtools_binary.py
new file mode 100644
index 000000000..6fcfe1a30
--- /dev/null
+++ b/tools/run_buildtools_binary.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python3
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+""" A wrapper to run gn, ninja and other buildtools/ for all platforms. """
+
+from __future__ import print_function
+
+import os
+import subprocess
+import sys
+
+from platform import system, machine
+
+ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+
+def run_buildtools_binary(args):
+ if len(args) < 1:
+ print('Usage %s command [args]\n' % sys.argv[0])
+ return 1
+
+ sys_name = system().lower()
+ os_dir = None
+ ext = ''
+ if sys_name == 'windows':
+ os_dir = 'win'
+ ext = '.exe'
+ elif sys_name == 'darwin':
+ os_dir = 'mac'
+ elif sys_name == 'linux':
+ os_dir = 'linux64'
+ else:
+ print('OS not supported: %s\n' % sys_name)
+ return 1
+
+ cmd = args[0]
+ args = args[1:]
+ exe_path = os.path.join(ROOT_DIR, 'buildtools', os_dir, cmd) + ext
+ if sys_name == 'windows':
+ # execl() behaves oddly on Windows: the spawned process doesn't seem to
+ # receive CTRL+C. Use subprocess instead.
+ return subprocess.call([exe_path] + args)
+ else:
+ os.execl(exe_path, os.path.basename(exe_path), *args)
+
+
+if __name__ == '__main__':
+ sys.exit(run_buildtools_binary(sys.argv[1:]))
diff --git a/tools/run_python_api_tests.py b/tools/run_python_api_tests.py
deleted file mode 100755
index 789a1f004..000000000
--- a/tools/run_python_api_tests.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (C) 2020 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import argparse
-import os
-import sys
-import unittest
-
-ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-
-
-def main():
- # Append test and src paths so that all imports are loaded in correctly
- sys.path.append(os.path.join(ROOT_DIR, 'test', 'trace_processor', 'python'))
- sys.path.append(
- os.path.join(ROOT_DIR, 'src', 'trace_processor', 'python', 'perfetto'))
- import api_unittest
- import api_integrationtest
-
- # Set paths to trace_processor_shell and root directory as environment
- # variables
- parser = argparse.ArgumentParser()
- parser.add_argument("shell", type=str)
- os.environ["SHELL_PATH"] = parser.parse_args().shell
- os.environ["ROOT_DIR"] = ROOT_DIR
-
- # Initialise test suite
- loader = unittest.TestLoader()
- suite = unittest.TestSuite()
-
- # Add all relevant tests to test suite
- suite.addTests(loader.loadTestsFromModule(api_unittest))
- suite.addTests(loader.loadTestsFromModule(api_integrationtest))
-
- # Initialise runner to run all tests in suite
- runner = unittest.TextTestRunner(verbosity=3)
- result = runner.run(suite)
-
- return 0 if result.wasSuccessful() else 1
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/tools/size-report b/tools/size-report
new file mode 100755
index 000000000..ef0a4a33a
--- /dev/null
+++ b/tools/size-report
@@ -0,0 +1,106 @@
+#!/usr/bin/env python3
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""
+Generate a size report for target binaries.
+
+For example:
+$ tools/ninja -C out/r traced_probes traced
+$ tools/size-report.py -C out/r traced_probes traced
+"""
+
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+
+import argparse
+import os
+import subprocess
+import sys
+import json
+
+ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+BLOATY_PATH = os.path.join(ROOT_DIR, 'buildtools', 'bloaty', 'bloaty')
+GN_PATH = os.path.join(ROOT_DIR, 'tools', 'gn')
+
+def GetGnArgValueOrNone(arg):
+ if 'current' in arg:
+ return eval(arg['current']['value'])
+ if 'default' in arg:
+ return eval(arg['default']['value'])
+ return None
+
+
+def GetTargetOsForBuildDir(build_dir):
+ cmd = [GN_PATH, 'args', '--list', '--json', build_dir]
+ args = json.loads(subprocess.check_output(cmd))
+ target_os = None
+ host_os = None
+ for arg in args:
+ if arg['name'] == 'target_os':
+ print(arg)
+ target_os = GetGnArgValueOrNone(arg)
+ if arg['name'] == 'host_os':
+ print(arg)
+ host_os = GetGnArgValueOrNone(arg)
+ return target_os or host_os or None
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ formatter_class=argparse.RawDescriptionHelpFormatter, description=__doc__)
+ parser.add_argument(
+ '-C', '--build-dir', metavar='DIR', help='build directory', required=True)
+ parser.add_argument('-o', '--output', help='output path', default=None)
+ parser.add_argument(
+ 'binaries', metavar='BINARY', nargs='+', help='subjects of size report')
+ args = parser.parse_args()
+
+ if not os.path.exists(BLOATY_PATH):
+ print(
+ 'Could not find bloaty at expected path "{}". Try re-running ./tools/install-build-deps'
+ .format(BLOATY_PATH))
+ return 1
+
+ results = []
+
+ out_directory = args.build_dir
+ target_os = GetTargetOsForBuildDir(out_directory)
+ print('target_os', target_os)
+ for binary in args.binaries:
+ binary_path = os.path.join(out_directory, binary)
+ output = '{} - {}\n'.format(binary, binary_path)
+ if target_os == 'mac':
+ subprocess.check_output(['dsymutil', binary_path])
+ symbols = '--debug-file={}.dSYM/Contents/Resources/DWARF/{}'.format(
+ binary_path, binary)
+ cmd = [symbols, '-d', 'compileunits', '-n', '100', binary_path]
+ else:
+ cmd = ['-d', 'compileunits', '-n', '100', binary_path]
+ output += subprocess.check_output([BLOATY_PATH] + cmd).decode('utf-8')
+ results.append(output)
+
+ if args.output is None or args.output == '-':
+ out = sys.stdout
+ else:
+ out = open(args.output, 'w')
+
+ for result in results:
+ out.write(result)
+ out.write('\n')
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/tools/symbolize-ui-crash b/tools/symbolize-ui-crash
index 3792ad01d..77ea74c34 100755
--- a/tools/symbolize-ui-crash
+++ b/tools/symbolize-ui-crash
@@ -23,8 +23,8 @@ copied from a bug reports, of the form:
it fetches the corresponding source maps and emits in output a translated
crash report, of the form:
-(https://github.com/google/perfetto/blob/de4db33f/ui/src/foo.ts#L61) at foo()
-(https://github.com/google/perfetto/blob/de4db33f/ui/src/baz.ts#L300) at bar()
+https://android.googlesource.com/platform/external/perfetto/+/de4db33f/ui/src/foo.ts#61 at foo()
+https://android.googlesource.com/platform/external/perfetto/+/de4db33f/ui/src/baz.ts#300 at bar()
"""
import logging
@@ -42,6 +42,8 @@ except:
sys.exit(1)
+GERRIT_BASE_URL = 'https://android.googlesource.com/platform/external/perfetto/'
+
def fetch_url_cached(url):
normalized = re.sub('[^a-zA-Z0-9-._]', '_', url)
local_file = os.path.join(tempfile.gettempdir(), normalized)
@@ -89,8 +91,7 @@ def Main():
sym_url = '%s#%s' % (src, sym.src_line)
if src.startswith('../out/ui/'):
src = src.replace('../out/ui/', 'ui/')
- sym_url = 'https://github.com/google/perfetto/blob/%s/%s#L%d' % (
- git_rev, src, sym.src_line)
+ sym_url = GERRIT_BASE_URL + '/+/%s/%s#%d' % (git_rev, src, sym.src_line)
sym_lines += sym_url + '\n'
txt = txt.replace(whole_token, sym_url)
diff --git a/tools/test_data b/tools/test_data
new file mode 100755
index 000000000..5d16b9940
--- /dev/null
+++ b/tools/test_data
@@ -0,0 +1,255 @@
+#!/usr/bin/env python3
+"""
+Script to synchronize (local>remote and viceversa) test data files from/to GCS.
+
+//test/data files are not checked in the codebase because they are large binary
+file and change frequently. Instead we check-in only xxx.sha256 files, which
+contain the SHA-256 of the actual binary file, and sync them from a GCS bucket.
+
+File in the GCS bucket are content-indexed as gs://bucket/file_name-a1b2c3f4 .
+
+Usage:
+./test_data status # Prints the status of new & modified files.
+./test_data download # To sync remote>local (used by install-build-deps).
+./test_data upload # To upload newly created and modified files.
+"""
+
+import argparse
+import logging
+import os
+import sys
+import hashlib
+import subprocess
+
+from multiprocessing.pool import ThreadPool
+from collections import namedtuple, defaultdict
+
+ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+BUCKET = 'gs://perfetto/test_data'
+SUFFIX = '.sha256'
+
+FS_MATCH = 'matches'
+FS_NEW_FILE = 'needs upload'
+FS_MODIFIED = 'modified'
+FS_MISSING = 'needs download'
+
+FileStat = namedtuple('FileStat',
+ ['path', 'status', 'actual_digest', 'expected_digest'])
+args = None
+
+
+def relpath(path):
+ return os.path.relpath(path, ROOT_DIR)
+
+
+def download(url, out_file):
+ subprocess.check_call(['curl', '-L', '-s', '-o', out_file, url])
+
+
+def list_files(path, scan_new_files=False):
+ """ List files recursively in path.
+
+ If scan_new_files=False, returns only files with a maching xxx.sha256 tracker.
+ If scan_new_files=True returns all files including untracked ones.
+ """
+ seen = set()
+ for root, _, files in os.walk(path):
+ for fname in files:
+ if fname.endswith('.swp'):
+ continue # Temporary files left around if CTRL-C-ing while downloading.
+ fpath = os.path.join(root, fname)
+ if not os.path.isfile(fpath) or fname.startswith('.'):
+ continue
+ if fpath.endswith(SUFFIX):
+ fpath = fpath[:-len(SUFFIX)]
+ elif not scan_new_files:
+ continue
+ if fpath not in seen:
+ seen.add(fpath)
+ yield fpath
+
+
+def hash_file(fpath):
+ hasher = hashlib.sha256()
+ with open(fpath, 'rb') as f:
+ for chunk in iter(lambda: f.read(32768), b''):
+ hasher.update(chunk)
+ return hasher.hexdigest()
+
+
+def map_concurrently(fn, files):
+ done = 0
+ for fs in ThreadPool(args.jobs).imap_unordered(fn, files):
+ assert (isinstance(fs, FileStat))
+ done += 1
+ if not args.quiet:
+ print(
+ '[%d/%d] %-60s' % (done, len(files), relpath(fs.path)[-60:]),
+ end='\r')
+ if not args.quiet:
+ print('')
+
+
+def get_file_status(fpath):
+ sha_file = fpath + SUFFIX
+ sha_exists = os.path.exists(sha_file)
+ file_exists = os.path.exists(fpath)
+ actual_digest = None
+ expected_digest = None
+ if sha_exists:
+ with open(sha_file, 'r') as f:
+ expected_digest = f.readline().strip()
+ if file_exists:
+ actual_digest = hash_file(fpath)
+ if sha_exists and not file_exists:
+ status = FS_MISSING
+ elif not sha_exists and file_exists:
+ status = FS_NEW_FILE
+ elif not sha_exists and not file_exists:
+ raise Exception(fpath)
+ elif expected_digest == actual_digest:
+ status = FS_MATCH
+ else:
+ status = FS_MODIFIED
+ return FileStat(fpath, status, actual_digest, expected_digest)
+
+
+def cmd_upload(dir):
+ all_files = list_files(dir, scan_new_files=True)
+ files_to_upload = []
+ for fs in ThreadPool(args.jobs).imap_unordered(get_file_status, all_files):
+ if fs.status in (FS_NEW_FILE, FS_MODIFIED):
+ files_to_upload.append(fs)
+ if len(files_to_upload) == 0:
+ if not args.quiet:
+ print('No modified or new files require uploading')
+ return 0
+ if args.dry_run:
+ return 0
+ if not args.quiet:
+ print('About to upload %d files:' % len(files_to_upload))
+ print('\n'.join(relpath(f.path) for f in files_to_upload))
+ print('')
+ input('Press a key to continue or CTRL-C to abort')
+
+ def upload_one_file(fs):
+ assert (fs.actual_digest is not None)
+ dst_name = '%s/%s-%s' % (args.bucket, os.path.basename(
+ fs.path), fs.actual_digest)
+ cmd = ['gsutil', '-q', 'cp', '-n', '-a', 'public-read', fs.path, dst_name]
+ logging.debug(' '.join(cmd))
+ subprocess.check_call(cmd)
+ with open(fs.path + SUFFIX + '.swp', 'w') as f:
+ f.write(fs.actual_digest)
+ os.replace(fs.path + SUFFIX + '.swp', fs.path + SUFFIX)
+ return fs
+
+ map_concurrently(upload_one_file, files_to_upload)
+ return 0
+
+
+def cmd_download(dir, overwrite_locally_modified=False):
+ files_to_download = []
+ modified = []
+ all_files = list_files(dir, scan_new_files=False)
+ for fs in ThreadPool(args.jobs).imap_unordered(get_file_status, all_files):
+ if fs.status == FS_MISSING:
+ files_to_download.append(fs)
+ elif fs.status == FS_MODIFIED:
+ modified.append(fs)
+
+ if len(modified) > 0 and not overwrite_locally_modified:
+ print('WARNING: The following files diverged locally and will NOT be ' +
+ 'overwritten if you continue')
+ print('\n'.join(relpath(f.path) for f in modified))
+ print('')
+ print('Re run `download --overwrite` to overwrite locally modified files')
+ print('or `upload` to sync them on the GCS bucket')
+ print('')
+ input('Press a key to continue or CTRL-C to abort')
+ elif overwrite_locally_modified:
+ files_to_download += modified
+
+ if len(files_to_download) == 0:
+ if not args.quiet:
+ print('Nothing to do, all files are synced')
+ return 0
+
+ if not args.quiet:
+ print('Downloading %d files in //%s' %
+ (len(files_to_download), relpath(args.dir)))
+ if args.dry_run:
+ print('\n'.join(files_to_download))
+ return
+
+ def download_one_file(fs):
+ assert (fs.expected_digest is not None)
+ uri = '%s/%s-%s' % (args.bucket, os.path.basename(
+ fs.path), fs.expected_digest)
+ uri = uri.replace('gs://', 'https://storage.googleapis.com/')
+ logging.debug(uri)
+ tmp_path = fs.path + '.swp'
+ download(uri, tmp_path)
+ digest = hash_file(tmp_path)
+ if digest != fs.expected_digest:
+ raise Exception('Mismatching digest for %s. expected=%s, actual=%s' %
+ (uri, fs.expected_digest, digest))
+ os.replace(tmp_path, fs.path)
+ return fs
+
+ map_concurrently(download_one_file, files_to_download)
+ return 0
+
+
+def cmd_status(dir):
+ files = list_files(dir, scan_new_files=True)
+ file_by_status = defaultdict(list)
+ num_files = 0
+ num_out_of_sync = 0
+ for fs in ThreadPool(args.jobs).imap_unordered(get_file_status, files):
+ file_by_status[fs.status].append(relpath(fs.path))
+ num_files += 1
+ for status, rpaths in sorted(file_by_status.items()):
+ if status == FS_NEW_FILE and args.ignore_new:
+ continue
+ if status != FS_MATCH:
+ for rpath in rpaths:
+ num_out_of_sync += 1
+ if not args.quiet:
+ print('%-15s: %s' % (status, rpath))
+ if num_out_of_sync == 0:
+ if not args.quiet:
+ print('Scanned %d files in //%s, everything in sync.' %
+ (num_files, relpath(dir)))
+ return 0
+ return 1
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--dir', default=os.path.join(ROOT_DIR, 'test/data'))
+ parser.add_argument('--overwrite', action='store_true')
+ parser.add_argument('--bucket', default=BUCKET)
+ parser.add_argument('--jobs', '-j', default=10, type=int)
+ parser.add_argument('--dry-run', '-n', action='store_true')
+ parser.add_argument('--quiet', '-q', action='store_true')
+ parser.add_argument('--verbose', '-v', action='store_true')
+ parser.add_argument('--ignore-new', action='store_true')
+ parser.add_argument('cmd', choices=['status', 'download', 'upload'])
+ global args
+ args = parser.parse_args()
+ logging.basicConfig(
+ format='%(asctime)s %(levelname).1s %(message)s',
+ level=logging.DEBUG if args.verbose else logging.INFO,
+ datefmt=r'%H:%M:%S')
+ if args.cmd == 'status':
+ return cmd_status(args.dir)
+ if args.cmd == 'download':
+ return cmd_download(args.dir, overwrite_locally_modified=args.overwrite)
+ if args.cmd == 'upload':
+ return cmd_upload(args.dir)
+ print('Unknown command: %s' % args.cmd)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/tools/test_data.txt b/tools/test_data.txt
index 55ee848de..036f9a7bd 100644
--- a/tools/test_data.txt
+++ b/tools/test_data.txt
@@ -1,8 +1,13 @@
# List of test deps that should be pushed on the device. Paths are relative
# to the root.
-src/traced/probes/filesystem/testdata/
-src/traced/probes/ftrace/test/data/
+# The trailing /. at the end of a directory is to avoid creating a nesting
+# directory when pushing a 2nd-time. adb push has a slightly different behavior
+# than `cp` on directoriesm, trailing slash is not enough.
+src/profiling/memory/test/data/.
+src/traced/probes/filesystem/testdata/.
+src/traced/probes/ftrace/test/data/.
test/data/android_log_ring_buffer_mode.pb
test/data/example_android_trace_30s.pb
test/data/full_trace_filter.bytecode
test/data/kallsyms.txt
+test/data/trace_with_uuid.pftrace
diff --git a/tools/tmux b/tools/tmux
index 51d140070..6843ecd57 100755
--- a/tools/tmux
+++ b/tools/tmux
@@ -56,7 +56,9 @@ function tmux_ensure_bash() {
function reset_tracing() {
if is_android "$OUT"; then
- adb shell 'echo 0 > /d/tracing/tracing_on'
+ # Newer versions of Android don't have debugfs mounted at all
+ # anymore so use /sys/kernel/tracing if /d/tracing doesn't exist
+ adb shell 'test -d /sys/kernel/tracing && echo 0 > /sys/kernel/tracing/tracing_on || echo 0 > /sys/kernel/debug/tracing/tracing_on'
elif ! is_mac; then
# shellcheck disable=SC2016
local script='
@@ -193,10 +195,17 @@ else
DIR=$(mktemp -p $TMPDIR -d perfetto.XXXXXX)
fi
+if is_android "$OUT"; then
+ TRACE_TO_TEXT="gcc_like_host/trace_to_text"
+else
+ TRACE_TO_TEXT="trace_to_text"
+fi
+
+
# (re)build the binaries
BUILD_TARGETS=(traced traced_probes perfetto test/configs)
if [[ SKIP_CONVERTERS -eq 0 ]]; then
- BUILD_TARGETS+=(trace_to_text)
+ BUILD_TARGETS+=($TRACE_TO_TEXT)
fi
"$SCRIPT_DIR/ninja" -C "$OUT" ${BUILD_TARGETS[*]}
@@ -370,13 +379,10 @@ fi
reset_tracing
TRACE=$TMPDIR/trace
-echo -e "\n\x1b[32mPulling trace into $TRACE.protobuf\x1b[0m"
-pull trace "$TRACE.protobuf"
+echo -e "\n\x1b[32mPulling trace into $TRACE.perfetto-trace\x1b[0m"
+pull trace "$TRACE.perfetto-trace"
if [[ SKIP_CONVERTERS -eq 0 ]]; then
echo -e "\n\x1b[32mPulling trace into $TRACE.pbtext\x1b[0m"
- "$OUT/trace_to_text" text <"$TRACE.protobuf" >"$TRACE.pbtext"
- echo -e "\n\x1b[32mPulling trace into $TRACE.json\x1b[0m"
- "$OUT/trace_to_text" systrace <"$TRACE.protobuf" >"$TRACE.json"
- # Keep this last so it can fail.
+ "$OUT/$TRACE_TO_TEXT" text <"$TRACE.perfetto-trace" >"$TRACE.pbtext"
fi
diff --git a/tools/trace_processor b/tools/trace_processor
index 22aaab63b..10c783679 100755
--- a/tools/trace_processor
+++ b/tools/trace_processor
@@ -24,73 +24,185 @@ BASH_FALLBACK = """ "
exec python3 - "$@" <<'#'EOF
#"""
-import hashlib
-import os
-import sys
-import tempfile
-import subprocess
-import platform
-
-TRACE_PROCESSOR_SHELL_SHAS = {
- 'linux': 'a3ce2cbf4cbe4f86cc10b02957db727cecfafae8',
- 'mac': 'c39a5be9a3831911ef2e50d66d11c12d877688f3',
-}
-TRACE_PROCESSOR_SHELL_PATH = tempfile.gettempdir()
-TRACE_PROCESSOR_SHELL_BASE_URL = ('https://storage.googleapis.com/perfetto/')
-
-
-def DownloadURL(url, out_file):
- subprocess.check_call(['curl', '-L', '-#', '-o', out_file, url])
-
-
-def check_hash(file_name, sha_value):
- with open(file_name, 'rb') as fd:
- file_hash = hashlib.sha1(fd.read()).hexdigest()
- return file_hash == sha_value
-
-
-def load_trace_processor_shell(platform):
- sha_value = TRACE_PROCESSOR_SHELL_SHAS[platform]
- file_name = 'trace_processor_shell-' + platform + '-' + sha_value
- local_file = os.path.join(TRACE_PROCESSOR_SHELL_PATH, file_name)
-
- if os.path.exists(local_file):
- if not check_hash(local_file, sha_value):
- os.remove(local_file)
- else:
- return local_file
-
- url = TRACE_PROCESSOR_SHELL_BASE_URL + file_name
- DownloadURL(url, local_file)
- if not check_hash(local_file, sha_value):
- os.remove(local_file)
- raise ValueError("Invalid signature.")
- os.chmod(local_file, 0o755)
- return local_file
-
-
-def main(argv):
- os_name = None
- if sys.platform.startswith('linux'):
- os_name = 'linux'
- elif sys.platform.startswith('darwin'):
- os_name = 'mac'
- else:
- print("Invalid platform: {}".format(sys.platform))
- return 1
-
- arch = platform.machine()
- if arch not in ['x86_64', 'amd64']:
- print("Prebuilts are only available for x86_64 (found '{}' instead).".format(arch))
- print("Follow https://perfetto.dev/docs/contributing/build-instructions to build locally.")
- return 1
-
- trace_processor_shell_binary = load_trace_processor_shell(os_name)
- os.execv(trace_processor_shell_binary,
- [trace_processor_shell_binary] + argv[1:])
-
+TOOL_NAME = 'trace_processor_shell'
+
+# BEGIN_SECTION_GENERATED_BY(roll-prebuilts)
+# Revision: v25.0
+PERFETTO_PREBUILT_MANIFEST = [{
+ 'tool':
+ 'trace_processor_shell',
+ 'arch':
+ 'mac-amd64',
+ 'file_name':
+ 'trace_processor_shell',
+ 'file_size':
+ 7302832,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/mac-amd64/trace_processor_shell',
+ 'sha256':
+ 'edc841a7f6769959f3b03f1e93dcd263d30864dc3e1fc4e3fcdbe4e44e19b02a',
+ 'platform':
+ 'darwin',
+ 'machine': ['x86_64']
+}, {
+ 'tool':
+ 'trace_processor_shell',
+ 'arch':
+ 'mac-arm64',
+ 'file_name':
+ 'trace_processor_shell',
+ 'file_size':
+ 6393768,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/mac-arm64/trace_processor_shell',
+ 'sha256':
+ '9f768e35d85501d18f09b0313c037a34f3306663d504f31e4874b1b3b20a00d6',
+ 'platform':
+ 'darwin',
+ 'machine': ['arm64']
+}, {
+ 'tool':
+ 'trace_processor_shell',
+ 'arch':
+ 'windows-amd64',
+ 'file_name':
+ 'trace_processor_shell.exe',
+ 'file_size':
+ 6942720,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/windows-amd64/trace_processor_shell.exe',
+ 'sha256':
+ 'c7118d820f720ca99acc9ef736f553cb0ba01d034e8f61b83f44d857f76058ce',
+ 'platform':
+ 'win32',
+ 'machine': ['amd64']
+}, {
+ 'tool':
+ 'trace_processor_shell',
+ 'arch':
+ 'linux-amd64',
+ 'file_name':
+ 'trace_processor_shell',
+ 'file_size':
+ 7824920,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-amd64/trace_processor_shell',
+ 'sha256':
+ '77ec0f9dbec36079d83f2843372446c354d04e7971c1f159c465d4e8e78a3d4d',
+ 'platform':
+ 'linux',
+ 'machine': ['x86_64']
+}, {
+ 'tool':
+ 'trace_processor_shell',
+ 'arch':
+ 'linux-arm',
+ 'file_name':
+ 'trace_processor_shell',
+ 'file_size':
+ 5076040,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-arm/trace_processor_shell',
+ 'sha256':
+ '7290ef3bda83736d0076e49bab5524294906bc8d1785ccef876ba8bd490e62b9',
+ 'platform':
+ 'linux',
+ 'machine': ['armv6l', 'armv7l', 'armv8l']
+}, {
+ 'tool':
+ 'trace_processor_shell',
+ 'arch':
+ 'linux-arm64',
+ 'file_name':
+ 'trace_processor_shell',
+ 'file_size':
+ 7055416,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-arm64/trace_processor_shell',
+ 'sha256':
+ 'b3d91b69a4152419bc3de2df3aeaef400d829e4a87e5c5cb985af0b56f319279',
+ 'platform':
+ 'linux',
+ 'machine': ['aarch64']
+}]
+
+
+# DO NOT EDIT. If you wish to make edits to this code, you need to change only
+# //tools/get_perfetto_prebuilt.py and run /tools/roll-prebuilts to regenerate
+# all the others scripts this is embedded into.
+def get_perfetto_prebuilt(tool_name, soft_fail=False, arch=None):
+ """ Downloads the prebuilt, if necessary, and returns its path on disk. """
+
+ # The first time this is invoked, it downloads the |url| and caches it into
+ # ~/.perfetto/prebuilts/$tool_name. On subsequent invocations it just runs the
+ # cached version.
+ def download_or_get_cached(file_name, url, sha256):
+ import os, hashlib, subprocess
+ dir = os.path.join(
+ os.path.expanduser('~'), '.local', 'share', 'perfetto', 'prebuilts')
+ os.makedirs(dir, exist_ok=True)
+ bin_path = os.path.join(dir, file_name)
+ sha256_path = os.path.join(dir, file_name + '.sha256')
+ needs_download = True
+
+ # Avoid recomputing the SHA-256 on each invocation. The SHA-256 of the last
+ # download is cached into file_name.sha256, just check if that matches.
+ if os.path.exists(bin_path) and os.path.exists(sha256_path):
+ with open(sha256_path, 'rb') as f:
+ digest = f.read().decode()
+ if digest == sha256:
+ needs_download = False
+
+ if needs_download:
+ # Either the filed doesn't exist or the SHA256 doesn't match.
+ tmp_path = bin_path + '.tmp'
+ print('Downloading ' + url)
+ subprocess.check_call(['curl', '-f', '-L', '-#', '-o', tmp_path, url])
+ with open(tmp_path, 'rb') as fd:
+ actual_sha256 = hashlib.sha256(fd.read()).hexdigest()
+ if actual_sha256 != sha256:
+ raise Exception('Checksum mismatch for %s (actual: %s, expected: %s)' %
+ (url, actual_sha256, sha256))
+ os.chmod(tmp_path, 0o755)
+ os.rename(tmp_path, bin_path)
+ with open(sha256_path, 'w') as f:
+ f.write(sha256)
+ return bin_path
+ # --- end of download_or_get_cached() ---
+
+ # --- get_perfetto_prebuilt() function starts here. ---
+ import os, platform, sys
+ plat = sys.platform.lower()
+ machine = platform.machine().lower()
+ manifest_entry = None
+ for entry in PERFETTO_PREBUILT_MANIFEST:
+ # If the caller overrides the arch, just match that (for Android prebuilts).
+ if arch and entry.get('arch') == arch:
+ manifest_entry = entry
+ break
+ # Otherwise guess the local machine arch.
+ if entry.get('tool') == tool_name and entry.get(
+ 'platform') == plat and machine in entry.get('machine', []):
+ manifest_entry = entry
+ break
+ if manifest_entry is None:
+ if soft_fail:
+ return None
+ raise Exception(
+ ('No prebuilts available for %s-%s\n' % (plat, machine)) +
+ 'See https://perfetto.dev/docs/contributing/build-instructions')
+
+ return download_or_get_cached(
+ file_name=manifest_entry['file_name'],
+ url=manifest_entry['url'],
+ sha256=manifest_entry['sha256'])
+
+
+# END_SECTION_GENERATED_BY(roll-prebuilts)
if __name__ == '__main__':
- sys.exit(main(sys.argv))
+ import sys, os
+ bin_path = get_perfetto_prebuilt(TOOL_NAME)
+ os.execv(bin_path, [bin_path] + sys.argv[1:])
#EOF
diff --git a/tools/trace_to_text/BUILD.gn b/tools/trace_to_text/BUILD.gn
index 7c409a36a..aae3b3bc9 100644
--- a/tools/trace_to_text/BUILD.gn
+++ b/tools/trace_to_text/BUILD.gn
@@ -13,25 +13,15 @@
# limitations under the License.
import("../../gn/perfetto.gni")
+import("../../gn/perfetto_cc_proto_descriptor.gni")
import("../../gn/perfetto_host_executable.gni")
+import("../../gn/test.gni")
import("../../gn/wasm.gni")
-perfetto_host_executable("trace_to_text") {
+executable("trace_to_text") {
testonly = true
deps = [
- ":full",
- "../../gn:default_deps",
- ]
-}
-
-# This is just to check that we can build a version of trace_to_text against
-# libprotobuf-lite. This configuration is only used by WASM. Unfortunately,
-# however, the WASM linker is very permissive and failures show up only when
-# loading the executable in the browser.
-perfetto_host_executable("trace_to_text_lite") {
- testonly = true
- deps = [
- ":lite",
+ ":main",
"../../gn:default_deps",
]
}
@@ -82,10 +72,9 @@ static_library("libpprofbuilder") {
public_deps = [ ":pprofbuilder" ]
}
-# The core source files that are used both by the "full" version (the host
-# executable) and by the "lite" version (the WASM module for the UI).
-source_set("common") {
+source_set("lib") {
deps = [
+ ":gen_cc_trace_descriptor",
":pprofbuilder",
":utils",
"../../gn:default_deps",
@@ -96,12 +85,16 @@ source_set("common") {
"../../src/profiling:deobfuscator",
"../../src/profiling/symbolizer",
"../../src/profiling/symbolizer:symbolize_database",
+ "../../src/protozero:proto_ring_buffer",
"../../src/trace_processor:lib",
+ "../../src/trace_processor:storage_minimal",
+ "../../src/trace_processor/util:descriptors",
+ "../../src/trace_processor/util:gzip",
+ "../../src/trace_processor/util:protozero_to_text",
]
sources = [
"deobfuscate_profile.cc",
"deobfuscate_profile.h",
- "main.cc",
"symbolize_profile.cc",
"symbolize_profile.h",
"trace_to_hprof.cc",
@@ -112,46 +105,44 @@ source_set("common") {
"trace_to_profile.h",
"trace_to_systrace.cc",
"trace_to_systrace.h",
+ "trace_to_text.cc",
+ "trace_to_text.h",
"trace_to_text.h",
]
}
-# Lite target for the WASM UI. Doesn't have any dependency on libprotobuf-full.
-source_set("lite") {
+source_set("main") {
deps = [
- ":common",
+ ":lib",
"../../gn:default_deps",
- "../../include/perfetto/base",
- ]
- sources = [ "lite_fallbacks.cc" ]
-}
-
-# Full target for the host. Depends on libprotobuf-full.
-source_set("full") {
- testonly = true
- deps = [
- ":common",
- ":utils",
- "../../gn:default_deps",
- "../../gn:protobuf_full",
- "../../protos/perfetto/trace:zero",
- ]
- if (enable_perfetto_zlib) {
- deps += [ "../../gn:zlib" ]
- }
- sources = [
- "proto_full_utils.cc",
- "proto_full_utils.h",
- "trace_to_text.cc",
+ "../../include/perfetto/ext/base:base",
]
+ sources = [ "main.cc" ]
}
if (enable_perfetto_ui) {
wasm_lib("trace_to_text_wasm") {
name = "trace_to_text"
deps = [
- ":lite",
+ ":main",
"../../gn:default_deps",
]
}
}
+
+perfetto_cc_proto_descriptor("gen_cc_trace_descriptor") {
+ descriptor_name = "trace.descriptor"
+ descriptor_target = "../../protos/perfetto/trace:descriptor"
+}
+
+perfetto_unittest_source_set("unittests") {
+ testonly = true
+ deps = [
+ ":lib",
+ "../../gn:default_deps",
+ "../../gn:gtest_and_gmock",
+ "../../include/perfetto/base",
+ "../../include/perfetto/ext/base:base",
+ ]
+ sources = [ "trace_to_text_unittest.cc" ]
+}
diff --git a/tools/trace_to_text/lite_fallbacks.cc b/tools/trace_to_text/lite_fallbacks.cc
index 82e09ff10..e208a1265 100644
--- a/tools/trace_to_text/lite_fallbacks.cc
+++ b/tools/trace_to_text/lite_fallbacks.cc
@@ -24,7 +24,7 @@
namespace perfetto {
namespace trace_to_text {
-int TraceToText(std::istream*, std::ostream*) {
+bool TraceToText(std::istream*, std::ostream*) {
PERFETTO_FATAL(
"The 'text' command is not available in lite builds of trace_to_text");
}
diff --git a/tools/trace_to_text/main.cc b/tools/trace_to_text/main.cc
index e4a9f1ddd..dfd75b6da 100644
--- a/tools/trace_to_text/main.cc
+++ b/tools/trace_to_text/main.cc
@@ -187,8 +187,9 @@ int Main(int argc, char** argv) {
return 1;
}
- if (format == "text")
- return TraceToText(input_stream, output_stream);
+ if (format == "text") {
+ return TraceToText(input_stream, output_stream) ? 0 : 1;
+ }
if (format == "profile") {
return perf_profile
diff --git a/tools/trace_to_text/pprof_builder.cc b/tools/trace_to_text/pprof_builder.cc
index 588c43817..3f6f556ee 100644
--- a/tools/trace_to_text/pprof_builder.cc
+++ b/tools/trace_to_text/pprof_builder.cc
@@ -14,25 +14,22 @@
* limitations under the License.
*/
-#include "perfetto/base/build_config.h"
-
#include "perfetto/profiling/pprof_builder.h"
+#include "perfetto/base/build_config.h"
+
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <cxxabi.h>
#endif
-#include <inttypes.h>
-
#include <algorithm>
+#include <cinttypes>
#include <map>
#include <set>
#include <unordered_map>
#include <utility>
#include <vector>
-#include "tools/trace_to_text/utils.h"
-
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/hash.h"
#include "perfetto/ext/base/string_utils.h"
@@ -43,6 +40,7 @@
#include "src/profiling/symbolizer/symbolize_database.h"
#include "src/profiling/symbolizer/symbolizer.h"
#include "src/trace_processor/containers/string_pool.h"
+#include "tools/trace_to_text/utils.h"
#include "protos/perfetto/trace/trace.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
@@ -145,19 +143,6 @@ namespace {
using ::perfetto::trace_processor::Iterator;
-void MaybeDemangle(std::string* name) {
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
- char* data = nullptr;
-#else
- int ignored;
- char* data = abi::__cxa_demangle(name->c_str(), nullptr, nullptr, &ignored);
-#endif
- if (data) {
- *name = data;
- free(data);
- }
-}
-
uint64_t ToPprofId(int64_t id) {
PERFETTO_DCHECK(id >= 0);
return static_cast<uint64_t>(id) + 1;
@@ -261,12 +246,13 @@ class LocationTracker {
};
struct PreprocessedInline {
- StringId system_name_id = StringId::Null();
+ // |name_id| is already demangled
+ StringId name_id = StringId::Null();
StringId filename_id = StringId::Null();
int64_t line_no = 0;
PreprocessedInline(StringId s, StringId f, int64_t line)
- : system_name_id(s), filename_id(f), line_no(line) {}
+ : name_id(s), filename_id(f), line_no(line) {}
};
std::unordered_map<int64_t, std::vector<PreprocessedInline>>
@@ -338,8 +324,9 @@ LocationTracker PreprocessLocations(trace_processor::TraceProcessor* tp,
continue;
std::string annotated_query =
- "select sp.id, sp.annotation, spf.mapping, "
- "ifnull(spf.deobfuscated_name, spf.name), spf.symbol_set_id from "
+ "select sp.id, sp.annotation, spf.mapping, spf.name, "
+ "coalesce(spf.deobfuscated_name, demangle(spf.name), spf.name), "
+ "spf.symbol_set_id from "
"experimental_annotated_callstack(" +
std::to_string(query_cid) +
") sp join stack_profile_frame spf on (sp.frame_id == spf.id) "
@@ -349,24 +336,25 @@ LocationTracker PreprocessLocations(trace_processor::TraceProcessor* tp,
std::vector<int64_t> callstack_loc_ids;
while (c_it.Next()) {
int64_t cid = c_it.Get(0).AsLong();
- int64_t mapping_id = c_it.Get(2).AsLong();
auto annotation = c_it.Get(1).is_null() ? "" : c_it.Get(1).AsString();
+ int64_t mapping_id = c_it.Get(2).AsLong();
auto func_sysname = c_it.Get(3).is_null() ? "" : c_it.Get(3).AsString();
+ auto func_name = c_it.Get(4).is_null() ? "" : c_it.Get(4).AsString();
base::Optional<int64_t> symbol_set_id =
- c_it.Get(4).is_null() ? base::nullopt
- : base::make_optional(c_it.Get(4).AsLong());
+ c_it.Get(5).is_null() ? base::nullopt
+ : base::make_optional(c_it.Get(5).AsLong());
Location loc(mapping_id, /*single_function_id=*/-1, {});
auto intern_function = [interner, &tracker, annotate_frames](
- StringId func_sysname_id, StringId filename_id,
+ StringId func_sysname_id,
+ StringId original_func_name_id,
+ StringId filename_id,
const std::string& anno) {
- std::string func_name = interner->Get(func_sysname_id).ToStdString();
- MaybeDemangle(&func_name);
- if (annotate_frames && !anno.empty() && !func_name.empty())
- func_name = func_name + " [" + anno + "]";
- StringId func_name_id =
- interner->InternString(base::StringView(func_name));
+ std::string fname = interner->Get(original_func_name_id).ToStdString();
+ if (annotate_frames && !anno.empty() && !fname.empty())
+ fname = fname + " [" + anno + "]";
+ StringId func_name_id = interner->InternString(base::StringView(fname));
Function func(func_name_id, func_sysname_id, filename_id);
return tracker.InternFunction(func);
};
@@ -383,8 +371,13 @@ LocationTracker PreprocessLocations(trace_processor::TraceProcessor* tp,
}
// N inlined functions
+ // The symbolised packets currently assume pre-demangled data (as that's
+ // the default of llvm-symbolizer), so we don't have a system name for
+ // each deinlined frame. Set the human-readable name for both fields. We
+ // can change this, but there's no demand for accurate system names in
+ // pprofs.
for (const auto& line : it->second) {
- int64_t func_id = intern_function(line.system_name_id,
+ int64_t func_id = intern_function(line.name_id, line.name_id,
line.filename_id, annotation);
loc.inlined_functions.emplace_back(func_id, line.line_no);
@@ -393,6 +386,7 @@ LocationTracker PreprocessLocations(trace_processor::TraceProcessor* tp,
// Otherwise - single function
int64_t func_id =
intern_function(interner->InternString(func_sysname),
+ interner->InternString(func_name),
/*filename_id=*/StringId::Null(), annotation);
loc.single_function_id = func_id;
}
diff --git a/tools/trace_to_text/symbolize_profile.cc b/tools/trace_to_text/symbolize_profile.cc
index 4f97f5807..229ce2402 100644
--- a/tools/trace_to_text/symbolize_profile.cc
+++ b/tools/trace_to_text/symbolize_profile.cc
@@ -21,9 +21,10 @@
#include "perfetto/base/logging.h"
#include "perfetto/trace_processor/trace_processor.h"
+#include "src/profiling/symbolizer/breakpad_symbolizer.h"
+#include "src/profiling/symbolizer/local_symbolizer.h"
#include "src/profiling/symbolizer/symbolize_database.h"
#include "src/profiling/symbolizer/symbolizer.h"
-#include "src/profiling/symbolizer/local_symbolizer.h"
#include "protos/perfetto/trace/trace.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
@@ -35,9 +36,14 @@ namespace trace_to_text {
// Ingest profile, and emit a symbolization table for each sequence. This can
// be prepended to the profile to attach the symbol information.
int SymbolizeProfile(std::istream* input, std::ostream* output) {
- std::unique_ptr<profiling::Symbolizer> symbolizer =
- profiling::LocalSymbolizerOrDie(profiling::GetPerfettoBinaryPath(),
- getenv("PERFETTO_SYMBOLIZER_MODE"));
+ std::unique_ptr<profiling::Symbolizer> symbolizer;
+ const char* breakpad_dir = getenv("BREAKPAD_SYMBOL_DIR");
+ if (breakpad_dir == nullptr) {
+ symbolizer = profiling::LocalSymbolizerOrDie(
+ profiling::GetPerfettoBinaryPath(), getenv("PERFETTO_SYMBOLIZER_MODE"));
+ } else {
+ symbolizer.reset(new profiling::BreakpadSymbolizer(breakpad_dir));
+ }
if (!symbolizer)
PERFETTO_FATAL("No symbolizer selected");
diff --git a/tools/trace_to_text/trace_to_profile.cc b/tools/trace_to_text/trace_to_profile.cc
index c71a827af..5b3fc4fdd 100644
--- a/tools/trace_to_text/trace_to_profile.cc
+++ b/tools/trace_to_text/trace_to_profile.cc
@@ -59,10 +59,9 @@ uint64_t ToConversionFlags(bool annotate_frames) {
std::string GetRandomString(size_t n) {
std::random_device r;
auto rng = std::default_random_engine(r());
- std::uniform_int_distribution<char> dist('a', 'z');
std::string result(n, ' ');
for (size_t i = 0; i < n; ++i) {
- result[i] = dist(rng);
+ result[i] = 'a' + (rng() % ('z' - 'a'));
}
return result;
}
diff --git a/tools/trace_to_text/trace_to_systrace.cc b/tools/trace_to_text/trace_to_systrace.cc
index 498b6c9d5..3ed00f326 100644
--- a/tools/trace_to_text/trace_to_systrace.cc
+++ b/tools/trace_to_text/trace_to_systrace.cc
@@ -16,10 +16,10 @@
#include "tools/trace_to_text/trace_to_systrace.h"
-#include <inttypes.h>
#include <stdio.h>
#include <algorithm>
+#include <cinttypes>
#include <functional>
#include <map>
#include <memory>
@@ -47,8 +47,9 @@ const char kProcessDumpHeader[] =
const char kThreadHeader[] = "USER PID TID CMD \\n";
-const char kSystemTraceEvents[] =
- " \"systemTraceEvents\": \"";
+const char kProcessDumpFooter[] = "\"";
+
+const char kSystemTraceEvents[] = " \"systemTraceEvents\": \"";
const char kFtraceHeader[] =
"# tracer: nop\n"
@@ -160,97 +161,33 @@ class QueryWriter {
TraceWriter* trace_writer_;
};
-} // namespace
-
-int TraceToSystrace(std::istream* input,
- std::ostream* output,
- bool ctrace,
- Keep truncate_keep,
- bool full_sort) {
- std::unique_ptr<TraceWriter> trace_writer(
- ctrace ? new DeflateTraceWriter(output) : new TraceWriter(output));
-
- trace_processor::Config config;
- config.sorting_mode = full_sort
- ? trace_processor::SortingMode::kForceFullSort
- : trace_processor::SortingMode::kDefaultHeuristics;
- std::unique_ptr<trace_processor::TraceProcessor> tp =
- trace_processor::TraceProcessor::CreateInstance(config);
-
- if (!ReadTrace(tp.get(), input))
- return 1;
- tp->NotifyEndOfFile();
-
- if (ctrace)
- *output << "TRACE:\n";
-
- return ExtractSystrace(tp.get(), trace_writer.get(),
- /*wrapped_in_json=*/false, truncate_keep);
-}
-
-int ExtractSystrace(trace_processor::TraceProcessor* tp,
- TraceWriter* trace_writer,
- bool wrapped_in_json,
- Keep truncate_keep) {
+int ExtractRawEvents(TraceWriter* trace_writer,
+ QueryWriter& q_writer,
+ bool wrapped_in_json,
+ Keep truncate_keep) {
using trace_processor::Iterator;
- QueryWriter q_writer(tp, trace_writer);
- if (wrapped_in_json) {
- trace_writer->Write(kProcessDumpHeader);
-
- // Write out all the processes in the trace.
- // TODO(lalitm): change this query to actually use ppid when it is exposed
- // by the process table.
- static const char kPSql[] = "select pid, 0 as ppid, name from process";
- auto p_callback = [](Iterator* it, base::StringWriter* writer) {
- uint32_t pid = static_cast<uint32_t>(it->Get(0 /* col */).long_value);
- uint32_t ppid = static_cast<uint32_t>(it->Get(1 /* col */).long_value);
- const auto& name_col = it->Get(2 /* col */);
- auto name_view = name_col.type == trace_processor::SqlValue::kString
- ? base::StringView(name_col.string_value)
- : base::StringView();
- FormatProcess(pid, ppid, name_view, writer);
- };
- if (!q_writer.RunQuery(kPSql, p_callback))
- return 1;
-
- trace_writer->Write(kThreadHeader);
-
- // Write out all the threads in the trace.
- static const char kTSql[] =
- "select tid, COALESCE(upid, 0), thread.name "
- "from thread left join process using (upid)";
- auto t_callback = [](Iterator* it, base::StringWriter* writer) {
- uint32_t tid = static_cast<uint32_t>(it->Get(0 /* col */).long_value);
- uint32_t tgid = static_cast<uint32_t>(it->Get(1 /* col */).long_value);
- const auto& name_col = it->Get(2 /* col */);
- auto name_view = name_col.type == trace_processor::SqlValue::kString
- ? base::StringView(name_col.string_value)
- : base::StringView();
- FormatThread(tid, tgid, name_view, writer);
- };
- if (!q_writer.RunQuery(kTSql, t_callback))
- return 1;
-
- trace_writer->Write("\",\n");
- trace_writer->Write(kSystemTraceEvents);
- trace_writer->Write(kFtraceJsonHeader);
- } else {
- trace_writer->Write(kFtraceHeader);
- }
-
- fprintf(stderr, "Converting ftrace events%c", kProgressChar);
- fflush(stderr);
-
- static const char kEstimateSql[] =
+ static const char kRawEventsCountSql[] =
"select count(1) from raw" FILTER_RAW_EVENTS;
uint32_t raw_events = 0;
auto e_callback = [&raw_events](Iterator* it, base::StringWriter*) {
raw_events = static_cast<uint32_t>(it->Get(0).long_value);
};
- if (!q_writer.RunQuery(kEstimateSql, e_callback))
+ if (!q_writer.RunQuery(kRawEventsCountSql, e_callback))
return 1;
+ if (raw_events == 0) {
+ if (!wrapped_in_json) {
+ // Write out the normal header even if we won't actually have
+ // any events under it.
+ trace_writer->Write(kFtraceHeader);
+ }
+ return 0;
+ }
+
+ fprintf(stderr, "Converting ftrace events%c", kProgressChar);
+ fflush(stderr);
+
auto raw_callback = [wrapped_in_json](Iterator* it,
base::StringWriter* writer) {
const char* line = it->Get(0 /* col */).string_value;
@@ -299,6 +236,16 @@ int ExtractSystrace(trace_processor::TraceProcessor* tp,
static const char kRawEventsQuery[] =
"select to_ftrace(id) from raw" FILTER_RAW_EVENTS;
+ // 1. Write the appropriate header for the file type.
+ if (wrapped_in_json) {
+ trace_writer->Write(",\n");
+ trace_writer->Write(kSystemTraceEvents);
+ trace_writer->Write(kFtraceJsonHeader);
+ } else {
+ trace_writer->Write(kFtraceHeader);
+ }
+
+ // 2. Write the actual events.
if (truncate_keep == Keep::kEnd && raw_events > max_ftrace_events) {
char end_truncate[150];
sprintf(end_truncate, "%s limit %d offset %d", kRawEventsQuery,
@@ -315,11 +262,90 @@ int ExtractSystrace(trace_processor::TraceProcessor* tp,
return 1;
}
+ // 3. Write the footer for JSON.
if (wrapped_in_json)
trace_writer->Write(kSystemTraceEventsFooter);
return 0;
}
+} // namespace
+
+int TraceToSystrace(std::istream* input,
+ std::ostream* output,
+ bool ctrace,
+ Keep truncate_keep,
+ bool full_sort) {
+ std::unique_ptr<TraceWriter> trace_writer(
+ ctrace ? new DeflateTraceWriter(output) : new TraceWriter(output));
+
+ trace_processor::Config config;
+ config.sorting_mode = full_sort
+ ? trace_processor::SortingMode::kForceFullSort
+ : trace_processor::SortingMode::kDefaultHeuristics;
+ std::unique_ptr<trace_processor::TraceProcessor> tp =
+ trace_processor::TraceProcessor::CreateInstance(config);
+
+ if (!ReadTrace(tp.get(), input))
+ return 1;
+ tp->NotifyEndOfFile();
+
+ if (ctrace)
+ *output << "TRACE:\n";
+
+ return ExtractSystrace(tp.get(), trace_writer.get(),
+ /*wrapped_in_json=*/false, truncate_keep);
+}
+
+int ExtractSystrace(trace_processor::TraceProcessor* tp,
+ TraceWriter* trace_writer,
+ bool wrapped_in_json,
+ Keep truncate_keep) {
+ using trace_processor::Iterator;
+
+ QueryWriter q_writer(tp, trace_writer);
+ if (wrapped_in_json) {
+ trace_writer->Write(kProcessDumpHeader);
+
+ // Write out all the processes in the trace.
+ // TODO(lalitm): change this query to actually use ppid when it is exposed
+ // by the process table.
+ static const char kPSql[] = "select pid, 0 as ppid, name from process";
+ auto p_callback = [](Iterator* it, base::StringWriter* writer) {
+ uint32_t pid = static_cast<uint32_t>(it->Get(0 /* col */).long_value);
+ uint32_t ppid = static_cast<uint32_t>(it->Get(1 /* col */).long_value);
+ const auto& name_col = it->Get(2 /* col */);
+ auto name_view = name_col.type == trace_processor::SqlValue::kString
+ ? base::StringView(name_col.string_value)
+ : base::StringView();
+ FormatProcess(pid, ppid, name_view, writer);
+ };
+ if (!q_writer.RunQuery(kPSql, p_callback))
+ return 1;
+
+ trace_writer->Write(kThreadHeader);
+
+ // Write out all the threads in the trace.
+ static const char kTSql[] =
+ "select tid, COALESCE(upid, 0), thread.name "
+ "from thread left join process using (upid)";
+ auto t_callback = [](Iterator* it, base::StringWriter* writer) {
+ uint32_t tid = static_cast<uint32_t>(it->Get(0 /* col */).long_value);
+ uint32_t tgid = static_cast<uint32_t>(it->Get(1 /* col */).long_value);
+ const auto& name_col = it->Get(2 /* col */);
+ auto name_view = name_col.type == trace_processor::SqlValue::kString
+ ? base::StringView(name_col.string_value)
+ : base::StringView();
+ FormatThread(tid, tgid, name_view, writer);
+ };
+ if (!q_writer.RunQuery(kTSql, t_callback))
+ return 1;
+
+ trace_writer->Write(kProcessDumpFooter);
+ }
+ return ExtractRawEvents(trace_writer, q_writer, wrapped_in_json,
+ truncate_keep);
+}
+
} // namespace trace_to_text
} // namespace perfetto
diff --git a/tools/trace_to_text/trace_to_text.cc b/tools/trace_to_text/trace_to_text.cc
index 2fef5a57e..e22f902c3 100644
--- a/tools/trace_to_text/trace_to_text.cc
+++ b/tools/trace_to_text/trace_to_text.cc
@@ -16,192 +16,198 @@
#include "tools/trace_to_text/trace_to_text.h"
-#include <google/protobuf/compiler/importer.h>
-#include <google/protobuf/dynamic_message.h>
-#include <google/protobuf/io/zero_copy_stream_impl.h>
-#include <google/protobuf/text_format.h>
-
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/scoped_file.h"
-#include "tools/trace_to_text/proto_full_utils.h"
+#include "src/protozero/proto_ring_buffer.h"
+#include "tools/trace_to_text/trace.descriptor.h"
#include "tools/trace_to_text/utils.h"
#include "protos/perfetto/trace/trace.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
-#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
-#include <zlib.h>
-#endif
+#include "src/trace_processor/forwarding_trace_parser.h"
+#include "src/trace_processor/util/descriptors.h"
+#include "src/trace_processor/util/gzip_utils.h"
+#include "src/trace_processor/util/protozero_to_text.h"
namespace perfetto {
namespace trace_to_text {
-
namespace {
-using google::protobuf::Descriptor;
-using google::protobuf::DynamicMessageFactory;
-using google::protobuf::FieldDescriptor;
-using google::protobuf::FileDescriptor;
-using google::protobuf::Message;
-using google::protobuf::Reflection;
-using google::protobuf::TextFormat;
-using google::protobuf::compiler::DiskSourceTree;
-using google::protobuf::compiler::Importer;
-using google::protobuf::io::OstreamOutputStream;
-using google::protobuf::io::ZeroCopyOutputStream;
-
-inline void WriteToZeroCopyOutput(ZeroCopyOutputStream* output,
- const char* str,
- size_t length) {
- if (length == 0)
- return;
-
- void* data;
- int size = 0;
- size_t bytes_to_copy = 0;
- while (length) {
- output->Next(&data, &size);
- bytes_to_copy = std::min(length, static_cast<size_t>(size));
- memcpy(data, str, bytes_to_copy);
- length -= bytes_to_copy;
- str += bytes_to_copy;
- }
- output->BackUp(size - static_cast<int>(bytes_to_copy));
-}
-
-constexpr char kCompressedPacketsPrefix[] = "compressed_packets {\n";
-constexpr char kCompressedPacketsSuffix[] = "}\n";
-
-constexpr char kIndentedPacketPrefix[] = " packet {\n";
-constexpr char kIndentedPacketSuffix[] = " }\n";
-constexpr char kPacketPrefix[] = "packet {\n";
-constexpr char kPacketSuffix[] = "}\n";
+using perfetto::trace_processor::DescriptorPool;
+using trace_processor::TraceType;
+using trace_processor::util::GzipDecompressor;
-void PrintCompressedPackets(const std::string& packets,
- Message* compressed_msg_scratch,
- ZeroCopyOutputStream* output) {
-#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
- uint8_t out[4096];
- std::vector<uint8_t> data;
+template <size_t N>
+static void WriteToOutput(std::ostream* output, const char (&str)[N]) {
+ output->write(str, sizeof(str) - 1);
+}
- z_stream stream{};
- stream.next_in =
- const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(packets.data()));
- stream.avail_in = static_cast<unsigned int>(packets.length());
+// Online algorithm to covert trace binary to text format.
+// Usage:
+// - Feed the trace-binary in a sequence of memblock, and it will continue to
+// write the output in given std::ostream*.
+class OnlineTraceToText {
+ public:
+ OnlineTraceToText(std::ostream* output) : output_(output) {
+ pool_.AddFromFileDescriptorSet(kTraceDescriptor.data(),
+ kTraceDescriptor.size());
+ }
+ OnlineTraceToText(const OnlineTraceToText&) = delete;
+ OnlineTraceToText& operator=(const OnlineTraceToText&) = delete;
+ void Feed(const uint8_t* data, size_t len);
+ bool ok() const { return ok_; }
+
+ private:
+ std::string TracePacketToText(protozero::ConstBytes packet,
+ uint32_t indent_depth);
+ void PrintCompressedPackets(protozero::ConstBytes packets);
+
+ bool ok_ = true;
+ std::ostream* output_;
+ protozero::ProtoRingBuffer ring_buffer_;
+ DescriptorPool pool_;
+ size_t bytes_processed_ = 0;
+ size_t packet_ = 0;
+};
+
+std::string OnlineTraceToText::TracePacketToText(protozero::ConstBytes packet,
+ uint32_t indent_depth) {
+ namespace pb0_to_text = trace_processor::protozero_to_text;
+ return pb0_to_text::ProtozeroToText(pool_, ".perfetto.protos.TracePacket",
+ packet, pb0_to_text::kIncludeNewLines,
+ indent_depth);
+}
- if (inflateInit(&stream) != Z_OK) {
- PERFETTO_ELOG("Error when initiliazing zlib to decompress packets");
- return;
+void OnlineTraceToText::PrintCompressedPackets(protozero::ConstBytes packets) {
+ WriteToOutput(output_, "compressed_packets {\n");
+ if (trace_processor::util::IsGzipSupported()) {
+ std::vector<uint8_t> whole_data =
+ GzipDecompressor::DecompressFully(packets.data, packets.size);
+ protos::pbzero::Trace::Decoder decoder(whole_data.data(),
+ whole_data.size());
+ for (auto it = decoder.packet(); it; ++it) {
+ WriteToOutput(output_, " packet {\n");
+ std::string text = TracePacketToText(*it, 2);
+ output_->write(text.data(), std::streamsize(text.size()));
+ WriteToOutput(output_, "\n }\n");
+ }
+ } else {
+ static const char kErrMsg[] =
+ "Cannot decode compressed packets. zlib not enabled in the build "
+ "config";
+ WriteToOutput(output_, kErrMsg);
+ static bool log_once = [] {
+ PERFETTO_ELOG("%s", kErrMsg);
+ return true;
+ }();
+ base::ignore_result(log_once);
}
+ WriteToOutput(output_, "}\n");
+}
- int ret;
- do {
- stream.next_out = out;
- stream.avail_out = sizeof(out);
- ret = inflate(&stream, Z_NO_FLUSH);
- if (ret != Z_STREAM_END && ret != Z_OK) {
- PERFETTO_ELOG("Error when decompressing packets");
+void OnlineTraceToText::Feed(const uint8_t* data, size_t len) {
+ ring_buffer_.Append(data, static_cast<size_t>(len));
+ while (true) {
+ auto token = ring_buffer_.ReadMessage();
+ if (token.fatal_framing_error) {
+ PERFETTO_ELOG("Failed to tokenize trace packet");
+ ok_ = false;
return;
}
- data.insert(data.end(), out, out + (sizeof(out) - stream.avail_out));
- } while (ret != Z_STREAM_END);
- inflateEnd(&stream);
-
- protos::pbzero::Trace::Decoder decoder(data.data(), data.size());
- WriteToZeroCopyOutput(output, kCompressedPacketsPrefix,
- sizeof(kCompressedPacketsPrefix) - 1);
- TextFormat::Printer printer;
- printer.SetInitialIndentLevel(2);
- for (auto it = decoder.packet(); it; ++it) {
- protozero::ConstBytes cb = *it;
- compressed_msg_scratch->ParseFromArray(cb.data, static_cast<int>(cb.size));
- WriteToZeroCopyOutput(output, kIndentedPacketPrefix,
- sizeof(kIndentedPacketPrefix) - 1);
- printer.Print(*compressed_msg_scratch, output);
- WriteToZeroCopyOutput(output, kIndentedPacketSuffix,
- sizeof(kIndentedPacketSuffix) - 1);
+ if (!token.valid()) {
+ // no need to set `ok_ = false` here because this just means
+ // we've run out of packets in the ring buffer.
+ break;
+ }
+
+ if (token.field_id != protos::pbzero::Trace::kPacketFieldNumber) {
+ PERFETTO_ELOG("Skipping invalid field");
+ continue;
+ }
+ protos::pbzero::TracePacket::Decoder decoder(token.start, token.len);
+ bytes_processed_ += token.len;
+ if ((packet_++ & 0x3f) == 0) {
+ fprintf(stderr, "Processing trace: %8zu KB%c", bytes_processed_ / 1024,
+ kProgressChar);
+ fflush(stderr);
+ }
+ if (decoder.has_compressed_packets()) {
+ PrintCompressedPackets(decoder.compressed_packets());
+ } else {
+ WriteToOutput(output_, "packet {\n");
+ protozero::ConstBytes packet = {token.start, token.len};
+ std::string text = TracePacketToText(packet, 1 /* indent_depth */);
+ output_->write(text.data(), std::streamsize(text.size()));
+ WriteToOutput(output_, "\n}\n");
+ }
}
- WriteToZeroCopyOutput(output, kCompressedPacketsSuffix,
- sizeof(kCompressedPacketsSuffix) - 1);
-#else
- base::ignore_result(packets);
- base::ignore_result(compressed_msg_scratch);
- base::ignore_result(kIndentedPacketPrefix);
- base::ignore_result(kIndentedPacketSuffix);
- WriteToZeroCopyOutput(output, kCompressedPacketsPrefix,
- sizeof(kCompressedPacketsPrefix) - 1);
- static const char kErrMsg[] =
- "Cannot decode compressed packets. zlib not enabled in the build config";
- WriteToZeroCopyOutput(output, kErrMsg, sizeof(kErrMsg) - 1);
- WriteToZeroCopyOutput(output, kCompressedPacketsSuffix,
- sizeof(kCompressedPacketsSuffix) - 1);
- static bool log_once = [] {
- PERFETTO_ELOG("%s", kErrMsg);
- return true;
- }();
- base::ignore_result(log_once);
-#endif // PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
}
-} // namespace
+class InputReader {
+ public:
+ InputReader(std::istream* input) : input_(input) {}
+ // Request the input-stream to read next |len_limit| bytes and load
+ // it in |data|. It also updates the |len| with actual number of bytes loaded
+ // in |data|. This can be less than requested |len_limit| if we have reached
+ // at the end of the file.
+ bool Read(uint8_t* data, uint32_t* len, uint32_t len_limit) {
+ if (input_->eof())
+ return false;
+ input_->read(reinterpret_cast<char*>(data), std::streamsize(len_limit));
+ if (input_->bad() || (input_->fail() && !input_->eof())) {
+ PERFETTO_ELOG("Failed while reading trace");
+ ok_ = false;
+ return false;
+ }
+ *len = uint32_t(input_->gcount());
+ return true;
+ }
+ bool ok() const { return ok_; }
-int TraceToText(std::istream* input, std::ostream* output) {
- const std::string proto_path = "protos/perfetto/trace/trace_packet.proto";
+ private:
+ std::istream* input_;
+ bool ok_ = true;
+};
- if (!base::OpenFile(proto_path, O_RDONLY)) {
- PERFETTO_ELOG("Cannot open %s.", proto_path.c_str());
- PERFETTO_ELOG(
- "Text mode only works from the perfetto directory. Googlers, see "
- "b/131425913");
- return 1;
- }
+} // namespace
- DiskSourceTree dst;
- dst.MapPath("", "");
- MultiFileErrorCollectorImpl mfe;
- Importer importer(&dst, &mfe);
- const FileDescriptor* parsed_file =
- importer.Import("protos/perfetto/trace/trace_packet.proto");
-
- DynamicMessageFactory dmf;
- const Descriptor* trace_descriptor = parsed_file->message_type(0);
- const Message* root = dmf.GetPrototype(trace_descriptor);
- OstreamOutputStream zero_copy_output(output);
- OstreamOutputStream* zero_copy_output_ptr = &zero_copy_output;
- Message* msg = root->New();
-
- constexpr uint32_t kCompressedPacketFieldDescriptor = 50;
- const Reflection* reflect = msg->GetReflection();
- const FieldDescriptor* compressed_desc =
- trace_descriptor->FindFieldByNumber(kCompressedPacketFieldDescriptor);
- Message* compressed_msg_scratch = root->New();
- std::string compressed_packet_scratch;
-
- TextFormat::Printer printer;
- printer.SetInitialIndentLevel(1);
- ForEachPacketBlobInTrace(
- input, [msg, reflect, compressed_desc, zero_copy_output_ptr,
- &compressed_packet_scratch, compressed_msg_scratch,
- &printer](std::unique_ptr<char[]> buf, size_t size) {
- if (!msg->ParseFromArray(buf.get(), static_cast<int>(size))) {
- PERFETTO_ELOG("Skipping invalid packet");
- return;
- }
- if (reflect->HasField(*msg, compressed_desc)) {
- const auto& compressed_packets = reflect->GetStringReference(
- *msg, compressed_desc, &compressed_packet_scratch);
- PrintCompressedPackets(compressed_packets, compressed_msg_scratch,
- zero_copy_output_ptr);
- } else {
- WriteToZeroCopyOutput(zero_copy_output_ptr, kPacketPrefix,
- sizeof(kPacketPrefix) - 1);
- printer.Print(*msg, zero_copy_output_ptr);
- WriteToZeroCopyOutput(zero_copy_output_ptr, kPacketSuffix,
- sizeof(kPacketSuffix) - 1);
- }
- });
- return 0;
+bool TraceToText(std::istream* input, std::ostream* output) {
+ constexpr size_t kMaxMsgSize = protozero::ProtoRingBuffer::kMaxMsgSize;
+ std::unique_ptr<uint8_t[]> buffer(new uint8_t[kMaxMsgSize]);
+ uint32_t buffer_len = 0;
+
+ InputReader input_reader(input);
+ OnlineTraceToText online_trace_to_text(output);
+
+ input_reader.Read(buffer.get(), &buffer_len, kMaxMsgSize);
+ TraceType type = trace_processor::GuessTraceType(buffer.get(), buffer_len);
+
+ if (type == TraceType::kGzipTraceType) {
+ GzipDecompressor decompressor;
+ auto consumer = [&](const uint8_t* data, size_t len) {
+ online_trace_to_text.Feed(data, len);
+ };
+ using ResultCode = GzipDecompressor::ResultCode;
+ do {
+ ResultCode code =
+ decompressor.FeedAndExtract(buffer.get(), buffer_len, consumer);
+ if (code == ResultCode::kError || !online_trace_to_text.ok())
+ return false;
+ } while (input_reader.Read(buffer.get(), &buffer_len, kMaxMsgSize));
+ return input_reader.ok();
+ } else if (type == TraceType::kProtoTraceType) {
+ do {
+ online_trace_to_text.Feed(buffer.get(), buffer_len);
+ if (!online_trace_to_text.ok())
+ return false;
+ } while (input_reader.Read(buffer.get(), &buffer_len, kMaxMsgSize));
+ return input_reader.ok();
+ } else {
+ PERFETTO_ELOG("Unrecognised file.");
+ return false;
+ }
}
} // namespace trace_to_text
diff --git a/tools/trace_to_text/trace_to_text.h b/tools/trace_to_text/trace_to_text.h
index 2be24ada1..d0f35e029 100644
--- a/tools/trace_to_text/trace_to_text.h
+++ b/tools/trace_to_text/trace_to_text.h
@@ -22,7 +22,8 @@
namespace perfetto {
namespace trace_to_text {
-int TraceToText(std::istream* input, std::ostream* output);
+// Returns true in case of success.
+bool TraceToText(std::istream* input, std::ostream* output);
} // namespace trace_to_text
} // namespace perfetto
diff --git a/tools/trace_to_text/trace_to_text_unittest.cc b/tools/trace_to_text/trace_to_text_unittest.cc
new file mode 100644
index 000000000..0066c0ce7
--- /dev/null
+++ b/tools/trace_to_text/trace_to_text_unittest.cc
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tools/trace_to_text/trace_to_text.h"
+
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/hash.h"
+#include "test/gtest_and_gmock.h"
+
+#include <fstream>
+
+using std::string;
+
+namespace perfetto {
+namespace trace_to_text {
+
+// Given a file, compute the checksum/hash of file.
+// Learn more @ base::Hash.
+// Precondition: File should exist and be accessible.
+static uint64_t FileHash(const string& filename) {
+ base::Hash hash;
+ std::ifstream input_f(filename, std::ios::binary);
+ PERFETTO_DCHECK(input_f.good());
+ char buffer[4096];
+ while (!input_f.eof()) {
+ input_f.read(buffer, sizeof(buffer));
+ if (input_f.gcount() > 0) {
+ hash.Update(buffer, size_t(input_f.gcount()));
+ }
+ }
+ return hash.digest();
+}
+
+TEST(TraceToText, DISABLED_Basic) {
+ auto tmp_file = "/tmp/trace_" + std::to_string(rand()) + ".txt";
+ auto input_file_names = {"test/data/example_android_trace_30s.pb.gz",
+ "test/data/example_android_trace_30s.pb"};
+ PERFETTO_LOG("tmp_file = %s.", tmp_file.c_str());
+ for (auto filename : input_file_names) {
+ {
+ std::ifstream input_f(filename, std::ios::binary);
+ std::ofstream output_f(tmp_file, std::ios::out | std::ios::binary);
+ EXPECT_TRUE(TraceToText(&input_f, &output_f));
+ PERFETTO_LOG("Processed %s", filename);
+ }
+ EXPECT_EQ(0xCD794377594BC7DCull, FileHash(tmp_file));
+ remove(tmp_file.c_str());
+ }
+}
+
+} // namespace trace_to_text
+} // namespace perfetto
diff --git a/tools/trace_to_text/utils.cc b/tools/trace_to_text/utils.cc
index ff1ae61ed..410e898fd 100644
--- a/tools/trace_to_text/utils.cc
+++ b/tools/trace_to_text/utils.cc
@@ -16,9 +16,9 @@
#include "tools/trace_to_text/utils.h"
-#include <inttypes.h>
#include <stdio.h>
+#include <cinttypes>
#include <memory>
#include <ostream>
#include <set>
@@ -48,52 +48,6 @@ constexpr size_t kCompressionBufferSize = 500 * 1024;
} // namespace
-void ForEachPacketBlobInTrace(
- std::istream* input,
- const std::function<void(std::unique_ptr<char[]>, size_t)>& f) {
- size_t bytes_processed = 0;
- // The trace stream can be very large. We cannot just pass it in one go to
- // libprotobuf as that will refuse to parse messages > 64MB. However we know
- // that a trace is merely a sequence of TracePackets. Here we just manually
- // tokenize the repeated TracePacket messages and parse them individually
- // using libprotobuf.
- for (uint32_t i = 0;; i++) {
- if ((i & 0x3f) == 0) {
- fprintf(stderr, "Processing trace: %8zu KB%c", bytes_processed / 1024,
- kProgressChar);
- fflush(stderr);
- }
- // A TracePacket consists in one byte stating its field id and type ...
- char preamble;
- input->get(preamble);
- if (!input->good())
- break;
- bytes_processed++;
- PERFETTO_DCHECK(preamble == 0x0a); // Field ID:1, type:length delimited.
-
- // ... a varint stating its size ...
- uint32_t field_size = 0;
- uint32_t shift = 0;
- for (;;) {
- char c = 0;
- input->get(c);
- field_size |= static_cast<uint32_t>(c & 0x7f) << shift;
- shift += 7;
- bytes_processed++;
- if (!(c & 0x80))
- break;
- }
-
- // ... and the actual TracePacket itself.
- std::unique_ptr<char[]> buf(new char[field_size]);
- input->read(buf.get(), static_cast<std::streamsize>(field_size));
- bytes_processed += field_size;
-
- f(std::move(buf), field_size);
- }
-}
-
-
bool ReadTrace(trace_processor::TraceProcessor* tp, std::istream* input) {
// 1MB chunk size seems the best tradeoff on a MacBook Pro 2013 - i7 2.8 GHz.
constexpr size_t kChunkSize = 1024 * 1024;
diff --git a/tools/trace_to_text/utils.h b/tools/trace_to_text/utils.h
index f95c3d828..063b89136 100644
--- a/tools/trace_to_text/utils.h
+++ b/tools/trace_to_text/utils.h
@@ -53,11 +53,6 @@ constexpr char kProgressChar = '\n';
constexpr char kProgressChar = '\r';
#endif
-void ForEachPacketBlobInTrace(
- std::istream* input,
- const std::function<void(std::unique_ptr<char[]>, size_t)>&);
-
-
bool ReadTrace(trace_processor::TraceProcessor* tp, std::istream* input);
void IngestTraceOrDie(trace_processor::TraceProcessor* tp,
const std::string& trace_proto);
diff --git a/tools/tracebox b/tools/tracebox
new file mode 100755
index 000000000..8dc234e85
--- /dev/null
+++ b/tools/tracebox
@@ -0,0 +1,208 @@
+#!/usr/bin/env python3
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This file should do the same thing when being invoked in any of these ways:
+# ./tracebox
+# python tracebox
+# bash tracebox
+# cat ./tracebox | bash
+# cat ./tracebox | python -
+
+BASH_FALLBACK = """ "
+exec python3 - "$@" <<'#'EOF
+#"""
+
+TOOL_NAME = 'tracebox'
+
+# BEGIN_SECTION_GENERATED_BY(roll-prebuilts)
+# Revision: v25.0
+PERFETTO_PREBUILT_MANIFEST = [{
+ 'tool':
+ 'tracebox',
+ 'arch':
+ 'mac-amd64',
+ 'file_name':
+ 'tracebox',
+ 'file_size':
+ 1382584,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/mac-amd64/tracebox',
+ 'sha256':
+ '2b5eecebd92810d6f88598904fc52db4930f5f234bcb749c839eb25ebaf42a8c',
+ 'platform':
+ 'darwin',
+ 'machine': ['x86_64']
+}, {
+ 'tool':
+ 'tracebox',
+ 'arch':
+ 'mac-arm64',
+ 'file_name':
+ 'tracebox',
+ 'file_size':
+ 1275896,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/mac-arm64/tracebox',
+ 'sha256':
+ '51049ce25a123b8990658bddbb52f5984e80c8c4e2eb06780f22534218cdbd1d',
+ 'platform':
+ 'darwin',
+ 'machine': ['arm64']
+}, {
+ 'tool':
+ 'tracebox',
+ 'arch':
+ 'linux-amd64',
+ 'file_name':
+ 'tracebox',
+ 'file_size':
+ 1786784,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-amd64/tracebox',
+ 'sha256':
+ '0df104d808715733cf717d5f2808e48e57bf20a851b49e1e579c516a34f4f9f9',
+ 'platform':
+ 'linux',
+ 'machine': ['x86_64']
+}, {
+ 'tool':
+ 'tracebox',
+ 'arch':
+ 'linux-amd64',
+ 'file_name':
+ 'tracebox',
+ 'file_size':
+ 1786784,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-amd64/tracebox',
+ 'sha256':
+ '0df104d808715733cf717d5f2808e48e57bf20a851b49e1e579c516a34f4f9f9',
+ 'platform':
+ 'linux',
+ 'machine': ['x86_64']
+}, {
+ 'tool':
+ 'tracebox',
+ 'arch':
+ 'linux-arm',
+ 'file_name':
+ 'tracebox',
+ 'file_size':
+ 1032796,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-arm/tracebox',
+ 'sha256':
+ '4db159c84073f95e5f704137bff4c97aa32a714a9c93ba77f99eeedf9f3fc714',
+ 'platform':
+ 'linux',
+ 'machine': ['armv6l', 'armv7l', 'armv8l']
+}, {
+ 'tool':
+ 'tracebox',
+ 'arch':
+ 'linux-arm64',
+ 'file_name':
+ 'tracebox',
+ 'file_size':
+ 1663696,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-arm64/tracebox',
+ 'sha256':
+ '75b7d877808a927962d15f8d5659ccce082e07797305cc739809aef98853bfce',
+ 'platform':
+ 'linux',
+ 'machine': ['aarch64']
+}]
+
+
+# DO NOT EDIT. If you wish to make edits to this code, you need to change only
+# //tools/get_perfetto_prebuilt.py and run /tools/roll-prebuilts to regenerate
+# all the others scripts this is embedded into.
+def get_perfetto_prebuilt(tool_name, soft_fail=False, arch=None):
+ """ Downloads the prebuilt, if necessary, and returns its path on disk. """
+
+ # The first time this is invoked, it downloads the |url| and caches it into
+ # ~/.perfetto/prebuilts/$tool_name. On subsequent invocations it just runs the
+ # cached version.
+ def download_or_get_cached(file_name, url, sha256):
+ import os, hashlib, subprocess
+ dir = os.path.join(
+ os.path.expanduser('~'), '.local', 'share', 'perfetto', 'prebuilts')
+ os.makedirs(dir, exist_ok=True)
+ bin_path = os.path.join(dir, file_name)
+ sha256_path = os.path.join(dir, file_name + '.sha256')
+ needs_download = True
+
+ # Avoid recomputing the SHA-256 on each invocation. The SHA-256 of the last
+ # download is cached into file_name.sha256, just check if that matches.
+ if os.path.exists(bin_path) and os.path.exists(sha256_path):
+ with open(sha256_path, 'rb') as f:
+ digest = f.read().decode()
+ if digest == sha256:
+ needs_download = False
+
+ if needs_download:
+ # Either the filed doesn't exist or the SHA256 doesn't match.
+ tmp_path = bin_path + '.tmp'
+ print('Downloading ' + url)
+ subprocess.check_call(['curl', '-f', '-L', '-#', '-o', tmp_path, url])
+ with open(tmp_path, 'rb') as fd:
+ actual_sha256 = hashlib.sha256(fd.read()).hexdigest()
+ if actual_sha256 != sha256:
+ raise Exception('Checksum mismatch for %s (actual: %s, expected: %s)' %
+ (url, actual_sha256, sha256))
+ os.chmod(tmp_path, 0o755)
+ os.rename(tmp_path, bin_path)
+ with open(sha256_path, 'w') as f:
+ f.write(sha256)
+ return bin_path
+ # --- end of download_or_get_cached() ---
+
+ # --- get_perfetto_prebuilt() function starts here. ---
+ import os, platform, sys
+ plat = sys.platform.lower()
+ machine = platform.machine().lower()
+ manifest_entry = None
+ for entry in PERFETTO_PREBUILT_MANIFEST:
+ # If the caller overrides the arch, just match that (for Android prebuilts).
+ if arch and entry.get('arch') == arch:
+ manifest_entry = entry
+ break
+ # Otherwise guess the local machine arch.
+ if entry.get('tool') == tool_name and entry.get(
+ 'platform') == plat and machine in entry.get('machine', []):
+ manifest_entry = entry
+ break
+ if manifest_entry is None:
+ if soft_fail:
+ return None
+ raise Exception(
+ ('No prebuilts available for %s-%s\n' % (plat, machine)) +
+ 'See https://perfetto.dev/docs/contributing/build-instructions')
+
+ return download_or_get_cached(
+ file_name=manifest_entry['file_name'],
+ url=manifest_entry['url'],
+ sha256=manifest_entry['sha256'])
+
+
+# END_SECTION_GENERATED_BY(roll-prebuilts)
+
+if __name__ == '__main__':
+ import sys, os
+ bin_path = get_perfetto_prebuilt(TOOL_NAME)
+ os.execv(bin_path, [bin_path] + sys.argv[1:])
+
+#EOF
diff --git a/tools/traceconv b/tools/traceconv
index 9887ec13b..ea13c776c 100755
--- a/tools/traceconv
+++ b/tools/traceconv
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright (C) 2019 The Android Open Source Project
+# Copyright (C) 2021 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -24,73 +24,153 @@ BASH_FALLBACK = """ "
exec python3 - "$@" <<'#'EOF
#"""
-import hashlib
-import os
-import sys
-import subprocess
-import tempfile
-import platform
-
-
-TRACE_TO_TEXT_SHAS = {
- 'linux': '7e3e10dfb324e31723efd63ac25037856e06eba0',
- 'mac': '21f0f42dd019b4f09addd404a114fbf2322ca8a4',
-}
-TRACE_TO_TEXT_PATH = tempfile.gettempdir()
-TRACE_TO_TEXT_BASE_URL = ('https://storage.googleapis.com/perfetto/')
-
-
-def DownloadURL(url, out_file):
- subprocess.check_call(['curl', '-L', '-#', '-o', out_file, url])
-
-
-def check_hash(file_name, sha_value):
- with open(file_name, 'rb') as fd:
- file_hash = hashlib.sha1(fd.read()).hexdigest()
- return file_hash == sha_value
-
-
-def load_trace_to_text(platform):
- sha_value = TRACE_TO_TEXT_SHAS[platform]
- file_name = 'trace_to_text-' + platform + '-' + sha_value
- local_file = os.path.join(TRACE_TO_TEXT_PATH, file_name)
-
- if os.path.exists(local_file):
- if not check_hash(local_file, sha_value):
- os.remove(local_file)
- else:
- return local_file
-
- url = TRACE_TO_TEXT_BASE_URL + file_name
- DownloadURL(url, local_file)
- if not check_hash(local_file, sha_value):
- os.remove(local_file)
- raise ValueError("Invalid signature.")
- os.chmod(local_file, 0o755)
- return local_file
-
-
-def main(argv):
- os_name = None
- if sys.platform.startswith('linux'):
- os_name = 'linux'
- elif sys.platform.startswith('darwin'):
- os_name = 'mac'
- else:
- print("Invalid platform: {}".format(sys.platform))
- return 1
-
- arch = platform.machine()
- if arch not in ['x86_64', 'amd64']:
- print("Prebuilts are only available for x86_64 (found '{}' instead).".format(arch))
- print("Follow https://perfetto.dev/docs/contributing/build-instructions to build locally.")
- return 1
-
- trace_to_text_binary = load_trace_to_text(os_name)
- os.execv(trace_to_text_binary, [trace_to_text_binary] + argv[1:])
-
+TOOL_NAME = 'trace_to_text'
+
+# BEGIN_SECTION_GENERATED_BY(roll-prebuilts)
+# Revision: v25.0
+PERFETTO_PREBUILT_MANIFEST = [{
+ 'tool':
+ 'trace_to_text',
+ 'arch':
+ 'mac-amd64',
+ 'file_name':
+ 'trace_to_text',
+ 'file_size':
+ 6525752,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/mac-amd64/trace_to_text',
+ 'sha256':
+ '64ccf6bac87825145691c6533412e514891f82300d68ff7ce69e8d2ca69aaf62',
+ 'platform':
+ 'darwin',
+ 'machine': ['x86_64']
+}, {
+ 'tool':
+ 'trace_to_text',
+ 'arch':
+ 'mac-arm64',
+ 'file_name':
+ 'trace_to_text',
+ 'file_size':
+ 5661424,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/mac-arm64/trace_to_text',
+ 'sha256':
+ 'fbb6d256c96cdc296f2faec2965d16a1527c4900e66a33aca979ff1c336a9f2f',
+ 'platform':
+ 'darwin',
+ 'machine': ['arm64']
+}, {
+ 'tool':
+ 'trace_to_text',
+ 'arch':
+ 'linux-amd64',
+ 'file_name':
+ 'trace_to_text',
+ 'file_size':
+ 6939560,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-amd64/trace_to_text',
+ 'sha256':
+ '109f4ff3bbd47633b0c08a338f1230e69d529ddf1584656ed45d8a59acaaabeb',
+ 'platform':
+ 'linux',
+ 'machine': ['x86_64']
+}, {
+ 'tool':
+ 'trace_to_text',
+ 'arch':
+ 'windows-amd64',
+ 'file_name':
+ 'trace_to_text.exe',
+ 'file_size':
+ 5925888,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/windows-amd64/trace_to_text.exe',
+ 'sha256':
+ '29e50ec4d8e28c7c322ba13273afcce80c63fe7d9f182b83af0e2077b4d2b952',
+ 'platform':
+ 'win32',
+ 'machine': ['amd64']
+}]
+
+
+# DO NOT EDIT. If you wish to make edits to this code, you need to change only
+# //tools/get_perfetto_prebuilt.py and run /tools/roll-prebuilts to regenerate
+# all the others scripts this is embedded into.
+def get_perfetto_prebuilt(tool_name, soft_fail=False, arch=None):
+ """ Downloads the prebuilt, if necessary, and returns its path on disk. """
+
+ # The first time this is invoked, it downloads the |url| and caches it into
+ # ~/.perfetto/prebuilts/$tool_name. On subsequent invocations it just runs the
+ # cached version.
+ def download_or_get_cached(file_name, url, sha256):
+ import os, hashlib, subprocess
+ dir = os.path.join(
+ os.path.expanduser('~'), '.local', 'share', 'perfetto', 'prebuilts')
+ os.makedirs(dir, exist_ok=True)
+ bin_path = os.path.join(dir, file_name)
+ sha256_path = os.path.join(dir, file_name + '.sha256')
+ needs_download = True
+
+ # Avoid recomputing the SHA-256 on each invocation. The SHA-256 of the last
+ # download is cached into file_name.sha256, just check if that matches.
+ if os.path.exists(bin_path) and os.path.exists(sha256_path):
+ with open(sha256_path, 'rb') as f:
+ digest = f.read().decode()
+ if digest == sha256:
+ needs_download = False
+
+ if needs_download:
+ # Either the filed doesn't exist or the SHA256 doesn't match.
+ tmp_path = bin_path + '.tmp'
+ print('Downloading ' + url)
+ subprocess.check_call(['curl', '-f', '-L', '-#', '-o', tmp_path, url])
+ with open(tmp_path, 'rb') as fd:
+ actual_sha256 = hashlib.sha256(fd.read()).hexdigest()
+ if actual_sha256 != sha256:
+ raise Exception('Checksum mismatch for %s (actual: %s, expected: %s)' %
+ (url, actual_sha256, sha256))
+ os.chmod(tmp_path, 0o755)
+ os.rename(tmp_path, bin_path)
+ with open(sha256_path, 'w') as f:
+ f.write(sha256)
+ return bin_path
+ # --- end of download_or_get_cached() ---
+
+ # --- get_perfetto_prebuilt() function starts here. ---
+ import os, platform, sys
+ plat = sys.platform.lower()
+ machine = platform.machine().lower()
+ manifest_entry = None
+ for entry in PERFETTO_PREBUILT_MANIFEST:
+ # If the caller overrides the arch, just match that (for Android prebuilts).
+ if arch and entry.get('arch') == arch:
+ manifest_entry = entry
+ break
+ # Otherwise guess the local machine arch.
+ if entry.get('tool') == tool_name and entry.get(
+ 'platform') == plat and machine in entry.get('machine', []):
+ manifest_entry = entry
+ break
+ if manifest_entry is None:
+ if soft_fail:
+ return None
+ raise Exception(
+ ('No prebuilts available for %s-%s\n' % (plat, machine)) +
+ 'See https://perfetto.dev/docs/contributing/build-instructions')
+
+ return download_or_get_cached(
+ file_name=manifest_entry['file_name'],
+ url=manifest_entry['url'],
+ sha256=manifest_entry['sha256'])
+
+
+# END_SECTION_GENERATED_BY(roll-prebuilts)
if __name__ == '__main__':
- sys.exit(main(sys.argv))
+ import sys, os
+ bin_path = get_perfetto_prebuilt(TOOL_NAME)
+ os.execv(bin_path, [bin_path] + sys.argv[1:])
#EOF
diff --git a/tools/update_trace_processor b/tools/update_trace_processor
deleted file mode 100755
index 3968efa1d..000000000
--- a/tools/update_trace_processor
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/bash
-
-set -e
-
-DIR=$(mktemp -d out/perfetto.XXXXXX)
-
-function cleanup {
- rm -rf "$DIR"
- echo "Deleted temp working directory $DIR"
-}
-
-#trap cleanup EXIT
-
-function is_mac {
- ! test -d /proc
- return $?
-}
-
-tools/gn gen $DIR --args='is_clang=true is_debug=false'
-tools/ninja -C $DIR trace_processor_shell
-
-if is_mac; then
- platform=mac
-else
- platform=linux
- strip $DIR/trace_processor_shell
-fi
-
-if which shasum; then
- NEW_SHA=$(shasum $DIR/trace_processor_shell | cut -f1 -d' ') # Mac OS
-else
- NEW_SHA=$(sha1sum $DIR/trace_processor_shell | cut -f1 -d' ') # Linux
-fi
-
-name=trace_processor_shell-$platform-$NEW_SHA
-
-gsutil cp $DIR/trace_processor_shell gs://perfetto/$name
-gsutil acl ch -u AllUsers:R gs://perfetto/$name
-
-echo 'Now run the following command to update tools/trace_processor:'
-echo "sed \"s/'$platform': '[^']*',/'$platform': '$NEW_SHA',/\" --in-place tools/trace_processor"
diff --git a/tools/update_traceconv b/tools/update_traceconv
deleted file mode 100755
index 6f397f70f..000000000
--- a/tools/update_traceconv
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/bash
-
-set -e
-
-DIR=$(mktemp -d out/perfetto.XXXXXX)
-
-function cleanup {
- rm -rf "$DIR"
- echo "Deleted temp working directory $DIR"
-}
-
-#trap cleanup EXIT
-
-function is_mac {
- ! test -d /proc
- return $?
-}
-
-tools/gn gen $DIR --args='is_clang=true is_debug=false'
-tools/ninja -C $DIR trace_to_text
-
-if is_mac; then
- platform=mac
-else
- platform=linux
- strip $DIR/trace_to_text
-fi
-
-if which shasum; then
- NEW_SHA=$(shasum $DIR/trace_to_text | cut -f1 -d' ') # Mac OS
-else
- NEW_SHA=$(sha1sum $DIR/trace_to_text | cut -f1 -d' ') # Linux
-fi
-
-name=trace_to_text-$platform-$NEW_SHA
-
-gsutil cp $DIR/trace_to_text gs://perfetto/$name
-gsutil cp $DIR/trace_to_text gs://chromium-telemetry/binary_dependencies/$name
-gsutil acl ch -u AllUsers:R gs://perfetto/$name
-gsutil acl ch -u AllUsers:R gs://chromium-telemetry/binary_dependencies/$name
-
-echo 'Now run the following command to update tools/traceconv:'
-echo "sed \"s/'$platform': '[^']*',/'$platform': '$NEW_SHA',/\" --in-place tools/traceconv"
-
-echo 'Now run the following command to update tools/heap_profile:'
-echo "sed \"s/'$platform': '[^']*',/'$platform': '$NEW_SHA',/\" --in-place tools/heap_profile"
diff --git a/tools/write_version_header.py b/tools/write_version_header.py
index dd02a69e9..7dc8783b2 100755
--- a/tools/write_version_header.py
+++ b/tools/write_version_header.py
@@ -20,11 +20,10 @@ generates a source header (or in the case of --ts_out a TypeScript file) that
contains:
- The version number (e.g. v9.0) obtained parsing the CHANGELOG file.
- The git HEAD's commit-ish (e.g. 6b330b772b0e973f79c70ba2e9bb2b0110c6715d)
-- The number of CLs from the release tag to HEAD.
-The latter is concatenated to the version number to distinguish builds made
-fully from release tags (e.g., v9.0.0) vs builds made from the main branch which
-are N cls ahead of the latest monthly release (e.g., v9.0.42).
+The latter is concatenated to the version number to disambiguate builds made
+from release tags vs builds made from the main branch vs UI builds made from the
+ui-canary/ui-stable branch.
"""
import argparse
@@ -56,30 +55,17 @@ def get_latest_release(changelog_path):
raise Exception('Failed to fetch Perfetto version from %s' % changelog_path)
-def get_git_info(last_release_tag):
- """Returns a tuple ('deadbeef', '1234').
-
- The first value is the SHA1 of the HEAD. The second is the number of CLs from
- the passed |last_release_tag| to HEAD."""
+def get_git_sha1(commitish):
+ """Returns the SHA1 of the provided commit-ish"""
commit_sha1 = SCM_REV_NOT_AVAILABLE
- commits_since_release = ''
git_dir = os.path.join(PROJECT_ROOT, '.git')
if os.path.exists(git_dir):
try:
- commit_sha1 = subprocess.check_output(['git', 'rev-parse', 'HEAD'],
+ commit_sha1 = subprocess.check_output(['git', 'rev-parse', commitish],
cwd=PROJECT_ROOT).strip().decode()
- with open(os.devnull, 'wb') as devnull:
- commits_since_release = subprocess.check_output(
- [
- 'git', 'rev-list', '--count',
- 'refs/tags/%s..HEAD' % last_release_tag
- ],
- cwd=PROJECT_ROOT,
- stderr=devnull).strip().decode()
except subprocess.CalledProcessError:
pass
-
- return (commit_sha1, commits_since_release)
+ return commit_sha1
def write_if_unchanged(path, content):
@@ -95,6 +81,7 @@ def write_if_unchanged(path, content):
def main():
parser = argparse.ArgumentParser()
+ parser.add_argument('--check_git', action='store_true')
parser.add_argument(
'--no_git',
action='store_true',
@@ -105,19 +92,23 @@ def main():
parser.add_argument('--changelog', help='Path to CHANGELOG.')
args = parser.parse_args()
+ if args.check_git:
+ has_git = os.path.exists(os.path.join(PROJECT_ROOT, '.git', 'HEAD'))
+ print('1' if has_git else '0')
+ return 0
+
release = get_latest_release(args.changelog)
+
if args.no_git:
- git_sha1, commits_since_release = (SCM_REV_NOT_AVAILABLE, '')
+ head_sha1 = SCM_REV_NOT_AVAILABLE
else:
- git_sha1, commits_since_release = get_git_info(release)
+ head_sha1 = get_git_sha1('HEAD') # SCM_REV_NOT_AVAILABLE on failure.
- # Try to compute the number of commits since the last release. This can fail
- # in some environments (e.g. in android builds) because the bots pull only
- # the main branch and don't pull the whole list of tags.
- if commits_since_release:
- version = '%s.%s' % (release, commits_since_release) # e.g., 'v9.0.42'.
- else:
+ if head_sha1 == SCM_REV_NOT_AVAILABLE:
version = release # e.g., 'v9.0'.
+ else:
+ sha1_abbrev = head_sha1[:9]
+ version = f'{release}-{sha1_abbrev}' # e.g., 'v9.0-adeadbeef'.
if args.cpp_out:
guard = '%s_' % args.cpp_out.upper()
@@ -129,7 +120,7 @@ def main():
lines.append('#define %s' % guard)
lines.append('')
lines.append('#define PERFETTO_VERSION_STRING() "%s"' % version)
- lines.append('#define PERFETTO_VERSION_SCM_REVISION() "%s"' % git_sha1)
+ lines.append('#define PERFETTO_VERSION_SCM_REVISION() "%s"' % head_sha1)
lines.append('')
lines.append('#endif // %s' % guard)
lines.append('')
@@ -139,7 +130,7 @@ def main():
if args.ts_out:
lines = []
lines.append('export const VERSION = "%s";' % version)
- lines.append('export const SCM_REVISION = "%s";' % git_sha1)
+ lines.append('export const SCM_REVISION = "%s";' % head_sha1)
content = '\n'.join(lines)
write_if_unchanged(args.ts_out, content)
diff --git a/traced_perf.rc b/traced_perf.rc
index cc8d4e872..7b0ec6a99 100644
--- a/traced_perf.rc
+++ b/traced_perf.rc
@@ -27,7 +27,7 @@ service traced_perf /system/bin/traced_perf
user nobody
group nobody readproc readtracefs
capabilities KILL DAC_READ_SEARCH
- writepid /dev/cpuset/foreground/tasks
+ task_profiles ProcessCapacityHigh
# Daemon run state:
# * initially off
diff --git a/ui/OWNERS b/ui/OWNERS
index 973653f54..7b9c12ba0 100644
--- a/ui/OWNERS
+++ b/ui/OWNERS
@@ -1,4 +1,8 @@
hjd@google.com
-eseckler@google.com
-dproy@google.com
primiano@google.com
+
+# Chrome-related bits (but also good escalations for many other UI changes).
+ddrone@google.com
+dproy@google.com
+eseckler@google.com
+nuskos@google.com
diff --git a/ui/PRESUBMIT.py b/ui/PRESUBMIT.py
index a4d6df0e4..d12758a3c 100644
--- a/ui/PRESUBMIT.py
+++ b/ui/PRESUBMIT.py
@@ -12,13 +12,27 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from __future__ import print_function
+import time
import subprocess
from os.path import relpath
+def RunAndReportIfLong(func, *args, **kargs):
+ start = time.time()
+ results = func(*args, **kargs)
+ end = time.time()
+ limit = 0.5 # seconds
+ name = func.__name__
+ runtime = end - start
+ if runtime > limit:
+ print("{} took >{:.2}s ({:.2}s)".format(name, limit, runtime))
+ return results
+
+
def CheckChange(input, output):
results = []
- results += CheckTslint(input, output)
+ results += RunAndReportIfLong(CheckTslint, input, output)
return results
diff --git a/ui/README.md b/ui/README.md
index 3fed4698f..e64d31c93 100644
--- a/ui/README.md
+++ b/ui/README.md
@@ -1,35 +1,47 @@
# Perfetto UI
-Quick Start
------------
-Run:
+## Quick Start
```bash
$ git clone https://android.googlesource.com/platform/external/perfetto/
$ cd perfetto
-$ tools/install-build-deps --ui
-$ tools/gn gen out/debug --args='is_debug=true'
-$ tools/ninja -C out/debug ui
+
+# Will build into ./out/ui by default. Can be changed with --out path/
+# The final bundle will be available at ./ui/out/dist/.
+# The build script creates a symlink from ./ui/out to $OUT_PATH/ui/.
+ui/build
+
+# This will automatically build the UI. There is no need to manually run
+# ui/build before running ui/run-dev-server.
+ui/run-dev-server
```
-For more details on `gn` configs see
-[Build Instructions](../docs/contributing/build-instructions.md).
+Then navigate to `http://localhost:10000`.
+
+See also https://perfetto.dev/docs/contributing/build-instructions#ui-development
+
+## Unit tests
-To run the tests:
```bash
-$ out/debug/ui_unittests
-$ out/debug/ui_tests
+ui/run-unittests # Add --watch to run them in watch mode.
```
-To run the tests in watch mode:
+## Integration tests (browser screenshot difftests)
+
```bash
-$ out/debug/ui_unittests --watch
+run-integrationtests
```
-Finally run:
+To rebaseline screenshots after a UI change
```bash
-$ ./ui/run-dev-server out/debug
+ui/run-integrationtests --rebaseline
+
+tools/test_data upload
+
+git add -A
+
+git commit
```
-and navigate to `localhost:10000`.
+See also https://perfetto.dev/docs/contributing/testing#ui-pixel-diff-tests
diff --git a/ui/build.js b/ui/build.js
index 28f0456b8..19abb7a66 100644
--- a/ui/build.js
+++ b/ui/build.js
@@ -58,9 +58,9 @@
// +----------------------+ | +----------+ +---------+ +--------------------+|
// | src/assets/*.png | | | assets/ | |*.wasm.js| | frontend_bundle.js ||
// +----------------------+ | | *.css | |*.wasm | +--------------------+|
-// | buildtools/typefaces |-->| | *.png | +---------+ |controller_bundle.js||
+// | buildtools/typefaces |-->| | *.png | +---------+ | engine_bundle.js ||
// +----------------------+ | | *.woff2 | +--------------------+|
-// | buildtools/legacy_tv | | | tv.html | | engine_bundle.js ||
+// | buildtools/legacy_tv | | | tv.html | |traceconv_bundle.js ||
// +----------------------+ | +----------+ +--------------------+|
// +------------------------------------------------+
@@ -75,14 +75,16 @@ const pjoin = path.join;
const ROOT_DIR = path.dirname(__dirname); // The repo root.
const VERSION_SCRIPT = pjoin(ROOT_DIR, 'tools/write_version_header.py');
+const GEN_IMPORTS_SCRIPT = pjoin(ROOT_DIR, 'tools/gen_ui_imports');
const cfg = {
watch: false,
verbose: false,
debug: false,
startHttpServer: false,
+ httpServerListenHost: '127.0.0.1',
+ httpServerListenPort: 10000,
wasmModules: ['trace_processor', 'trace_to_text'],
- testConfigs: ['jest.unit.config.js'],
// The fields below will be changed by main() after cmdline parsing.
// Directory structure:
@@ -117,21 +119,26 @@ const RULES = [
let tasks = [];
let tasksTot = 0, tasksRan = 0;
-let serverStarted = false;
let httpWatches = [];
let tStart = Date.now();
let subprocesses = [];
-function main() {
+async function main() {
const parser = new argparse.ArgumentParser();
parser.addArgument('--out', {help: 'Output directory'});
parser.addArgument(['--watch', '-w'], {action: 'storeTrue'});
parser.addArgument(['--serve', '-s'], {action: 'storeTrue'});
+ parser.addArgument('--serve-host', {help: '--serve bind host'});
+ parser.addArgument('--serve-port', {help: '--serve bind port', type: 'int'});
parser.addArgument(['--verbose', '-v'], {action: 'storeTrue'});
parser.addArgument(['--no-build', '-n'], {action: 'storeTrue'});
parser.addArgument(['--no-wasm', '-W'], {action: 'storeTrue'});
- parser.addArgument(['--run-tests', '-t'], {action: 'storeTrue'});
+ parser.addArgument(['--run-unittests', '-t'], {action: 'storeTrue'});
+ parser.addArgument(['--run-integrationtests', '-T'], {action: 'storeTrue'});
parser.addArgument(['--debug', '-d'], {action: 'storeTrue'});
+ parser.addArgument(['--interactive', '-i'], {action: 'storeTrue'});
+ parser.addArgument(['--rebaseline', '-r'], {action: 'storeTrue'});
+ parser.addArgument(['--no-depscheck'], {action: 'storeTrue'});
const args = parser.parseArgs();
const clean = !args.no_build;
@@ -148,6 +155,18 @@ function main() {
cfg.verbose = !!args.verbose;
cfg.debug = !!args.debug;
cfg.startHttpServer = args.serve;
+ if (args.serve_host) {
+ cfg.httpServerListenHost = args.serve_host
+ }
+ if (args.serve_port) {
+ cfg.httpServerListenPort = args.serve_port
+ }
+ if (args.interactive) {
+ process.env.PERFETTO_UI_TESTS_INTERACTIVE = '1';
+ }
+ if (args.rebaseline) {
+ process.env.PERFETTO_UI_TESTS_REBASELINE = '1';
+ }
process.on('SIGINT', () => {
console.log('\nSIGINT received. Killing all child processes and exiting');
@@ -157,11 +176,27 @@ function main() {
process.exit(130); // 130 -> Same behavior of bash when killed by SIGINT.
});
- // Check that deps are current before starting.
- const installBuildDeps = pjoin(ROOT_DIR, 'tools/install-build-deps');
- const checkDepsPath = pjoin(cfg.outDir, '.check_deps');
- const depsArgs = [`--check-only=${checkDepsPath}`, '--ui'];
- exec(installBuildDeps, depsArgs);
+ if (!args.no_depscheck) {
+ // Check that deps are current before starting.
+ const installBuildDeps = pjoin(ROOT_DIR, 'tools/install-build-deps');
+ const checkDepsPath = pjoin(cfg.outDir, '.check_deps');
+ let args = [installBuildDeps, `--check-only=${checkDepsPath}`, '--ui'];
+
+ if (process.platform === "darwin") {
+ const result = child_process.spawnSync("arch", ["-arm64", "true"]);
+ const isArm64Capable = result.status === 0;
+ if (isArm64Capable) {
+ const archArgs = [
+ "arch",
+ "-arch",
+ "arm64",
+ ];
+ args = archArgs.concat(args);
+ }
+ }
+ const cmd = args.shift();
+ exec(cmd, args);
+ }
console.log('Entering', cfg.outDir);
process.chdir(cfg.outDir);
@@ -179,6 +214,7 @@ function main() {
scanDir('ui/src/chrome_extension');
scanDir('buildtools/typefaces');
scanDir('buildtools/catapult_trace_viewer');
+ generateImports('ui/src/tracks', 'all_tracks.ts');
compileProtos();
genVersion();
transpileTsProject('ui');
@@ -192,8 +228,25 @@ function main() {
scanDir(cfg.outDistRootDir);
}
- if (args.run_tests) {
- runTests();
+
+ // We should enter the loop only in watch mode, where tsc and rollup are
+ // asynchronous because they run in watch mode.
+ const tStart = Date.now();
+ while (!isDistComplete()) {
+ const secs = Math.ceil((Date.now() - tStart) / 1000);
+ process.stdout.write(`Waiting for first build to complete... ${secs} s\r`);
+ await new Promise(r => setTimeout(r, 500));
+ }
+ if (cfg.watch) console.log('\nFirst build completed!');
+
+ if (cfg.startHttpServer) {
+ startServer();
+ }
+ if (args.run_unittests) {
+ runTests('jest.unittest.config.js');
+ }
+ if (args.run_integrationtests) {
+ runTests('jest.integrationtest.config.js');
}
}
@@ -201,12 +254,17 @@ function main() {
// Build rules
// -----------
-function runTests() {
- const args =
- ['--rootDir', cfg.outTscDir, '--verbose', '--runInBand', '--forceExit'];
- for (const cfgFile of cfg.testConfigs) {
- args.push('--projects', pjoin(ROOT_DIR, 'ui/config', cfgFile));
- }
+function runTests(cfgFile) {
+ const args = [
+ '--rootDir',
+ cfg.outTscDir,
+ '--verbose',
+ '--runInBand',
+ '--detectOpenHandles',
+ '--forceExit',
+ '--projects',
+ pjoin(ROOT_DIR, 'ui/config', cfgFile)
+ ];
if (cfg.watch) {
args.push('--watchAll');
addTask(execNode, ['jest', args, {async: true}]);
@@ -275,6 +333,19 @@ function compileProtos() {
addTask(execNode, ['pbts', pbtsArgs]);
}
+function generateImports(dir, name) {
+ // We have to use the symlink (ui/src/gen) rather than cfg.outGenDir
+ // below since we want to generate the correct relative imports. For example:
+ // ui/src/frontend/foo.ts
+ // import '../gen/all_plugins.ts';
+ // ui/src/gen/all_plugins.ts (aka ui/out/tsc/gen/all_plugins.ts)
+ // import '../frontend/some_plugin.ts';
+ const dstTs = pjoin(ROOT_DIR, 'ui/src/gen', name);
+ const inputDir = pjoin(ROOT_DIR, dir);
+ const args = [GEN_IMPORTS_SCRIPT, inputDir, '--out', dstTs];
+ addTask(exec, ['python3', args]);
+}
+
// Generates a .ts source that defines the VERSION and SCM_REVISION constants.
function genVersion() {
const cmd = 'python3';
@@ -284,8 +355,14 @@ function genVersion() {
}
function updateSymlinks() {
+ // /ui/out -> /out/ui.
mklink(cfg.outUiDir, pjoin(ROOT_DIR, 'ui/out'));
+ // /out/ui/test/data -> /test/data (For UI tests).
+ mklink(
+ pjoin(ROOT_DIR, 'test/data'),
+ pjoin(ensureDir(pjoin(cfg.outDir, 'test')), 'data'));
+
// Creates a out/dist_version -> out/dist/v1.2.3 symlink, so rollup config
// can point to that without having to know the current version number.
mklink(
@@ -371,8 +448,9 @@ function genServiceWorkerManifestJson() {
}
function startServer() {
- const port = 10000;
- console.log(`Starting HTTP server on http://localhost:${port}`);
+ console.log(
+ 'Starting HTTP server on',
+ `http://${cfg.httpServerListenHost}:${cfg.httpServerListenPort}`);
http.createServer(function(req, res) {
console.debug(req.method, req.url);
let uri = req.url.split('?', 1)[0];
@@ -397,7 +475,21 @@ function startServer() {
return;
}
- const absPath = path.normalize(path.join(cfg.outDistRootDir, uri));
+ let absPath = path.normalize(path.join(cfg.outDistRootDir, uri));
+ // We want to be able to use the data in '/test/' for e2e tests.
+ // However, we don't want do create a symlink into the 'dist/' dir,
+ // because 'dist/' gets shipped on the production server.
+ if (uri.startsWith('/test/')) {
+ absPath = pjoin(ROOT_DIR, uri);
+ }
+
+ // Don't serve contents outside of the project root (b/221101533).
+ if (path.relative(ROOT_DIR, absPath).startsWith('..')) {
+ res.writeHead(403);
+ res.end('403 Forbidden - Request path outside of the repo root');
+ return;
+ }
+
fs.readFile(absPath, function(err, data) {
if (err) {
res.writeHead(404);
@@ -424,7 +516,25 @@ function startServer() {
res.end();
});
})
- .listen(port, '127.0.0.1');
+ .listen(cfg.httpServerListenPort, cfg.httpServerListenHost);
+}
+
+function isDistComplete() {
+ const requiredArtifacts = [
+ 'frontend_bundle.js',
+ 'engine_bundle.js',
+ 'traceconv_bundle.js',
+ 'trace_processor.wasm',
+ 'perfetto.css',
+ ];
+ const relPaths = new Set();
+ walk(cfg.outDistDir, absPath => {
+ relPaths.add(path.relative(cfg.outDistDir, absPath));
+ });
+ for (const fName of requiredArtifacts) {
+ if (!relPaths.has(fName)) return false;
+ }
+ return true;
}
// Called whenever a change in the out/dist directory is detected. It sends a
@@ -476,11 +586,6 @@ function runTasks() {
console.log(`${ts} ${BRT}${++tasksRan}/${tasksTot}${RST}\t${descr}`);
task.func.apply(/*this=*/ undefined, task.args);
}
- // Start the web server once reaching quiescence.
- if (tasks.length === 0 && !serverStarted && cfg.startHttpServer) {
- serverStarted = true;
- startServer();
- }
}
// Executes all the RULES that match the given |absPath|.
diff --git a/ui/config/.gitignore b/ui/config/.gitignore
new file mode 100644
index 000000000..acd163cfb
--- /dev/null
+++ b/ui/config/.gitignore
@@ -0,0 +1 @@
+/jest.individual.unit.config.js
diff --git a/ui/config/headless_environment.js b/ui/config/headless_environment.js
deleted file mode 100644
index 6c4f3ece2..000000000
--- a/ui/config/headless_environment.js
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-const NodeEnvironment = require('jest-environment-node');
-const puppeteer = require('puppeteer');
-
-module.exports = class HeadlessEnvironment extends NodeEnvironment {
- constructor(config) {
- super(config);
- }
-
- async setup() {
- await super.setup();
- this.global.__BROWSER__ = await puppeteer.launch();
- }
-
- async teardown() {
- await this.global.__BROWSER__.close();
- await super.teardown();
- }
-
- runScript(script) {
- return super.runScript(script);
- }
-}
diff --git a/ui/config/headless_setup.js b/ui/config/headless_setup.js
deleted file mode 100644
index 7f8f93c1d..000000000
--- a/ui/config/headless_setup.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-module.exports = async function() {
-}
-
diff --git a/ui/config/headless_teardown.js b/ui/config/headless_teardown.js
deleted file mode 100644
index 5fb4f1ac6..000000000
--- a/ui/config/headless_teardown.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-module.exports = async function() {
- console.log("End!");
-}
diff --git a/ui/config/integrationtest_env.js b/ui/config/integrationtest_env.js
new file mode 100644
index 000000000..b7509ee8d
--- /dev/null
+++ b/ui/config/integrationtest_env.js
@@ -0,0 +1,65 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+const NodeEnvironment = require('jest-environment-node');
+const puppeteer = require('puppeteer');
+
+module.exports = class IntegrationtestEnvironment extends NodeEnvironment {
+ constructor(config) {
+ super(config);
+ }
+
+ async setup() {
+ await super.setup();
+ const headless = process.env.PERFETTO_UI_TESTS_INTERACTIVE !== '1';
+ if (headless) {
+ console.log('Starting Perfetto UI tests in headless mode.');
+ console.log(
+ 'Pass --interactive to run-integrationtests or set ' +
+ 'PERFETTO_UI_TESTS_INTERACTIVE=1 to inspect the behavior ' +
+ 'in a visible Chrome window');
+ }
+ this.global.__BROWSER__ = await puppeteer.launch({
+ args: [
+ '--window-size=1920,1080',
+ '--disable-accelerated-2d-canvas',
+ '--disable-gpu',
+ '--no-sandbox', // Disable sandbox to run in Docker.
+ '--disable-setuid-sandbox',
+ '--font-render-hinting=none',
+ '--enable-benchmarking', // Disable finch and other sources of non
+ // determinism.
+ ],
+
+ // This is so screenshot in --interactive and headles mode match. The
+ // scrollbars are never part of the screenshot, but without this cmdline
+ // switch, in headless mode we don't get any blank space (as if it was
+ // overflow:hidden) and that changes the layout of the page.
+ ignoreDefaultArgs: ['--hide-scrollbars'],
+
+ headless: headless,
+ });
+ }
+
+ async teardown() {
+ if (this.global.__BROWSER__) {
+ await this.global.__BROWSER__.close();
+ }
+ await super.teardown();
+ }
+
+ runScript(script) {
+ return super.runScript(script);
+ }
+}
diff --git a/ui/config/integrationtest_setup.js b/ui/config/integrationtest_setup.js
new file mode 100644
index 000000000..e4cd7e888
--- /dev/null
+++ b/ui/config/integrationtest_setup.js
@@ -0,0 +1,57 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+const path = require('path');
+const http = require('http');
+const child_process = require('child_process');
+
+module.exports = async function() {
+ // Start the local HTTP server.
+ const ROOT_DIR = path.dirname(path.dirname(__dirname));
+ const node = path.join(ROOT_DIR, 'ui', 'node');
+ const args = [
+ path.join(ROOT_DIR, 'ui', 'build.js'),
+ '--serve',
+ '--no-build',
+ '--out=.'
+ ];
+ const spwOpts = {stdio: ['ignore', 'inherit', 'inherit']};
+ const srvProc = child_process.spawn(node, args, spwOpts);
+ global.__DEV_SERVER__ = srvProc;
+
+ // Wait for the HTTP server to be ready.
+ let attempts = 10;
+ for (; attempts > 0; attempts--) {
+ await new Promise(r => setTimeout(r, 1000));
+ try {
+ await new Promise((resolve, reject) => {
+ const req = http.request('http://127.0.0.1:10000/frontend_bundle.js');
+ req.end();
+ req.on('error', err => reject(err));
+ req.on('finish', () => resolve());
+ });
+ break;
+ } catch (err) {
+ console.error('Waiting for HTTP server to come up', err.message);
+ continue;
+ }
+ }
+ if (attempts == 0) {
+ throw new Error('HTTP server didn\'t come up');
+ }
+ if (srvProc.exitCode !== null) {
+ throw new Error(
+ `The dev server unexpectedly exited, code=${srvProc.exitCode}`);
+ }
+}
diff --git a/ui/config/integrationtest_teardown.js b/ui/config/integrationtest_teardown.js
new file mode 100644
index 000000000..6d152ddd4
--- /dev/null
+++ b/ui/config/integrationtest_teardown.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+module.exports = async function() {
+ const proc = global.__DEV_SERVER__;
+ // Kill the HTTP server.
+ proc.kill();
+ for (;;) {
+ if (proc.exitCode !== null || proc.killed) break;
+ console.log('Waiting for dev server termination');
+ await new Promise(r => setTimeout(r, 1000));
+ }
+}
diff --git a/ui/config/jest.headless.config.js b/ui/config/jest.headless.config.js
deleted file mode 100644
index 723ab253d..000000000
--- a/ui/config/jest.headless.config.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-module.exports = {
- transform: {},
- testRegex: '.*_headlesstest.js$',
- globalSetup: './headless_setup.js',
- globalTeardown: './headless_teardown.js',
- testEnvironment: './headless_environment.js'
-}
diff --git a/ui/config/jest.individual.unit.config.js b/ui/config/jest.individual.unit.config.js
deleted file mode 100644
index 7d9d2f53a..000000000
--- a/ui/config/jest.individual.unit.config.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (C) 2021 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-const path = require('path');
-
-// to be used for running individual unit tests from VsCode or from an IDE
-module.exports = {
- 'roots': [path.dirname(__dirname) + '/src'],
- 'testMatch': ['**/*unittest.ts'],
- 'transform': {'^.+\\.(ts|tsx)$': 'ts-jest'},
-}
diff --git a/ui/config/jest.integrationtest.config.js b/ui/config/jest.integrationtest.config.js
new file mode 100644
index 000000000..079abaf8d
--- /dev/null
+++ b/ui/config/jest.integrationtest.config.js
@@ -0,0 +1,21 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+module.exports = {
+ transform: {},
+ testRegex: '.*_integrationtest.js$',
+ globalSetup: __dirname + '/integrationtest_setup.js',
+ globalTeardown: __dirname + '/integrationtest_teardown.js',
+ testEnvironment: __dirname + '/integrationtest_env.js',
+}
diff --git a/ui/config/jest.jsdom.config.js b/ui/config/jest.jsdom.config.js
deleted file mode 100644
index dd07d8382..000000000
--- a/ui/config/jest.jsdom.config.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-module.exports = {
- transform: {},
- testRegex: '_jsdomtest.js$',
- testEnvironment: 'jsdom'
-}
diff --git a/ui/config/jest.unit.config.js b/ui/config/jest.unit.config.js
deleted file mode 100644
index a2ddb9561..000000000
--- a/ui/config/jest.unit.config.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-module.exports = {
- transform: {},
- testRegex: '.*_unittest.js$',
- testEnvironment: 'node',
- verbose: true,
-}
diff --git a/ui/config/jest.unittest.config.js b/ui/config/jest.unittest.config.js
new file mode 100644
index 000000000..fc1bd3502
--- /dev/null
+++ b/ui/config/jest.unittest.config.js
@@ -0,0 +1,19 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+module.exports = {
+ transform: {},
+ testRegex: '_(unittest|jsdomtest)[.]js$',
+ testEnvironment: 'jsdom'
+}
diff --git a/ui/config/rollup.config.js b/ui/config/rollup.config.js
index 380aa916f..7a28ba4da 100644
--- a/ui/config/rollup.config.js
+++ b/ui/config/rollup.config.js
@@ -48,15 +48,33 @@ function defBundle(bundle, distDir) {
'crypto',
]
}),
- // Protobufjs's inquire() uses eval but that's not really needed in
- // the browser.
- // See https://github.com/protobufjs/protobuf.js/issues/593
+
replace({
- patterns: [{test: /eval\(.*\(moduleName\);/g, replace: 'undefined;'}]
+ patterns: [
+ // Protobufjs's inquire() uses eval but that's not really needed in
+ // the browser. https://github.com/protobufjs/protobuf.js/issues/593
+ {test: /eval\(.*\(moduleName\);/g, replace: 'undefined;'},
+
+ // Immer entry point has a if (process.env.NODE_ENV === 'production')
+ // but |process| is not defined in the browser. Bypass.
+ // https://github.com/immerjs/immer/issues/557
+ {test: /process\.env\.NODE_ENV/g, replace: '\'production\''},
+ ]
}),
+
// Translate source maps to point back to the .ts sources.
sourcemaps(),
],
+ onwarn: function(warning, warn) {
+ // Ignore circular dependency warnings coming from third party code.
+ if (warning.code === 'CIRCULAR_DEPENDENCY' &&
+ warning.importer.includes('node_modules')) {
+ return;
+ }
+
+ // Call the default warning handler for all remaining warnings.
+ warn(warning);
+ }
};
}
@@ -86,6 +104,7 @@ export default [
defBundle('frontend', 'dist_version'),
defBundle('controller', 'dist_version'),
defBundle('engine', 'dist_version'),
+ defBundle('traceconv', 'dist_version'),
defBundle('chrome_extension', 'chrome_extension'),
defServiceWorkerBundle(),
]
diff --git a/ui/package-lock.json b/ui/package-lock.json
index 4e89a3a3c..dba56b4d2 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -13,35 +13,35 @@
"@babel/highlight": "^7.12.13"
}
},
+ "@babel/compat-data": {
+ "version": "7.14.4",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.4.tgz",
+ "integrity": "sha512-i2wXrWQNkH6JplJQGn3Rd2I4Pij8GdHkXwHMxm+zV5YG/Jci+bCNrWZEWC4o+umiDkRrRs4dVzH3X4GP7vyjQQ==",
+ "dev": true
+ },
"@babel/core": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.13.tgz",
- "integrity": "sha512-BQKE9kXkPlXHPeqissfxo0lySWJcYdEP0hdtJOH/iJfDdhOCcgtNCjftCJg3qqauB4h+lz2N6ixM++b9DN1Tcw==",
+ "version": "7.14.3",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.3.tgz",
+ "integrity": "sha512-jB5AmTKOCSJIZ72sd78ECEhuPiDMKlQdDI/4QRI6lzYATx5SSogS1oQA2AoPecRCknm30gHi2l+QVvNUu3wZAg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.12.13",
- "@babel/generator": "^7.12.13",
- "@babel/helper-module-transforms": "^7.12.13",
- "@babel/helpers": "^7.12.13",
- "@babel/parser": "^7.12.13",
+ "@babel/generator": "^7.14.3",
+ "@babel/helper-compilation-targets": "^7.13.16",
+ "@babel/helper-module-transforms": "^7.14.2",
+ "@babel/helpers": "^7.14.0",
+ "@babel/parser": "^7.14.3",
"@babel/template": "^7.12.13",
- "@babel/traverse": "^7.12.13",
- "@babel/types": "^7.12.13",
+ "@babel/traverse": "^7.14.2",
+ "@babel/types": "^7.14.2",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
- "gensync": "^1.0.0-beta.1",
+ "gensync": "^1.0.0-beta.2",
"json5": "^2.1.2",
- "lodash": "^4.17.19",
- "semver": "^5.4.1",
+ "semver": "^6.3.0",
"source-map": "^0.5.0"
},
"dependencies": {
- "semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
- "dev": true
- },
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
@@ -51,12 +51,12 @@
}
},
"@babel/generator": {
- "version": "7.12.15",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz",
- "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==",
+ "version": "7.14.3",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz",
+ "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13",
+ "@babel/types": "^7.14.2",
"jsesc": "^2.5.1",
"source-map": "^0.5.0"
},
@@ -69,15 +69,27 @@
}
}
},
+ "@babel/helper-compilation-targets": {
+ "version": "7.14.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.4.tgz",
+ "integrity": "sha512-JgdzOYZ/qGaKTVkn5qEDV/SXAh8KcyUVkCoSWGN8T3bwrgd6m+/dJa2kVGi6RJYJgEYPBdZ84BZp9dUjNWkBaA==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.14.4",
+ "@babel/helper-validator-option": "^7.12.17",
+ "browserslist": "^4.16.6",
+ "semver": "^6.3.0"
+ }
+ },
"@babel/helper-function-name": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz",
- "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==",
+ "version": "7.14.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz",
+ "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==",
"dev": true,
"requires": {
"@babel/helper-get-function-arity": "^7.12.13",
"@babel/template": "^7.12.13",
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.14.2"
}
},
"@babel/helper-get-function-arity": {
@@ -90,38 +102,45 @@
}
},
"@babel/helper-member-expression-to-functions": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.13.tgz",
- "integrity": "sha512-B+7nN0gIL8FZ8SvMcF+EPyB21KnCcZHQZFczCxbiNGV/O0rsrSBlWGLzmtBJ3GMjSVMIm4lpFhR+VdVBuIsUcQ==",
+ "version": "7.13.12",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz",
+ "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.13.12"
}
},
"@babel/helper-module-imports": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz",
- "integrity": "sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g==",
+ "version": "7.13.12",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz",
+ "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.13.12"
}
},
"@babel/helper-module-transforms": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.13.tgz",
- "integrity": "sha512-acKF7EjqOR67ASIlDTupwkKM1eUisNAjaSduo5Cz+793ikfnpe7p4Q7B7EWU2PCoSTPWsQkR7hRUWEIZPiVLGA==",
+ "version": "7.14.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.2.tgz",
+ "integrity": "sha512-OznJUda/soKXv0XhpvzGWDnml4Qnwp16GN+D/kZIdLsWoHj05kyu8Rm5kXmMef+rVJZ0+4pSGLkeixdqNUATDA==",
"dev": true,
"requires": {
- "@babel/helper-module-imports": "^7.12.13",
- "@babel/helper-replace-supers": "^7.12.13",
- "@babel/helper-simple-access": "^7.12.13",
+ "@babel/helper-module-imports": "^7.13.12",
+ "@babel/helper-replace-supers": "^7.13.12",
+ "@babel/helper-simple-access": "^7.13.12",
"@babel/helper-split-export-declaration": "^7.12.13",
- "@babel/helper-validator-identifier": "^7.12.11",
+ "@babel/helper-validator-identifier": "^7.14.0",
"@babel/template": "^7.12.13",
- "@babel/traverse": "^7.12.13",
- "@babel/types": "^7.12.13",
- "lodash": "^4.17.19"
+ "@babel/traverse": "^7.14.2",
+ "@babel/types": "^7.14.2"
+ },
+ "dependencies": {
+ "@babel/helper-validator-identifier": {
+ "version": "7.14.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
+ "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "dev": true
+ }
}
},
"@babel/helper-optimise-call-expression": {
@@ -134,30 +153,30 @@
}
},
"@babel/helper-plugin-utils": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.12.13.tgz",
- "integrity": "sha512-C+10MXCXJLiR6IeG9+Wiejt9jmtFpxUc3MQqCmPY8hfCjyUGl9kT+B2okzEZrtykiwrc4dbCPdDoz0A/HQbDaA==",
+ "version": "7.13.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz",
+ "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==",
"dev": true
},
"@babel/helper-replace-supers": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz",
- "integrity": "sha512-pctAOIAMVStI2TMLhozPKbf5yTEXc0OJa0eENheb4w09SrgOWEs+P4nTOZYJQCqs8JlErGLDPDJTiGIp3ygbLg==",
+ "version": "7.14.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.4.tgz",
+ "integrity": "sha512-zZ7uHCWlxfEAAOVDYQpEf/uyi1dmeC7fX4nCf2iz9drnCwi1zvwXL3HwWWNXUQEJ1k23yVn3VbddiI9iJEXaTQ==",
"dev": true,
"requires": {
- "@babel/helper-member-expression-to-functions": "^7.12.13",
+ "@babel/helper-member-expression-to-functions": "^7.13.12",
"@babel/helper-optimise-call-expression": "^7.12.13",
- "@babel/traverse": "^7.12.13",
- "@babel/types": "^7.12.13"
+ "@babel/traverse": "^7.14.2",
+ "@babel/types": "^7.14.4"
}
},
"@babel/helper-simple-access": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.13.tgz",
- "integrity": "sha512-0ski5dyYIHEfwpWGx5GPWhH35j342JaflmCeQmsPWcrOQDtCN6C1zKAVRFVbK53lPW2c9TsuLLSUDf0tIGJ5hA==",
+ "version": "7.13.12",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz",
+ "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.13.12"
}
},
"@babel/helper-split-export-declaration": {
@@ -175,15 +194,21 @@
"integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==",
"dev": true
},
+ "@babel/helper-validator-option": {
+ "version": "7.12.17",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz",
+ "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==",
+ "dev": true
+ },
"@babel/helpers": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.13.tgz",
- "integrity": "sha512-oohVzLRZ3GQEk4Cjhfs9YkJA4TdIDTObdBEZGrd6F/T0GPSnuV6l22eMcxlvcvzVIPH3VTtxbseudM1zIE+rPQ==",
+ "version": "7.14.0",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.0.tgz",
+ "integrity": "sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg==",
"dev": true,
"requires": {
"@babel/template": "^7.12.13",
- "@babel/traverse": "^7.12.13",
- "@babel/types": "^7.12.13"
+ "@babel/traverse": "^7.14.0",
+ "@babel/types": "^7.14.0"
}
},
"@babel/highlight": {
@@ -250,9 +275,9 @@
}
},
"@babel/parser": {
- "version": "7.12.15",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz",
- "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==",
+ "version": "7.14.4",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.4.tgz",
+ "integrity": "sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA==",
"dev": true
},
"@babel/plugin-syntax-async-generators": {
@@ -354,6 +379,15 @@
"@babel/helper-plugin-utils": "^7.8.0"
}
},
+ "@babel/plugin-syntax-top-level-await": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz",
+ "integrity": "sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.12.13"
+ }
+ },
"@babel/template": {
"version": "7.12.13",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz",
@@ -366,31 +400,37 @@
}
},
"@babel/traverse": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz",
- "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==",
+ "version": "7.14.2",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz",
+ "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.12.13",
- "@babel/generator": "^7.12.13",
- "@babel/helper-function-name": "^7.12.13",
+ "@babel/generator": "^7.14.2",
+ "@babel/helper-function-name": "^7.14.2",
"@babel/helper-split-export-declaration": "^7.12.13",
- "@babel/parser": "^7.12.13",
- "@babel/types": "^7.12.13",
+ "@babel/parser": "^7.14.2",
+ "@babel/types": "^7.14.2",
"debug": "^4.1.0",
- "globals": "^11.1.0",
- "lodash": "^4.17.19"
+ "globals": "^11.1.0"
}
},
"@babel/types": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz",
- "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==",
+ "version": "7.14.4",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
+ "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.12.11",
- "lodash": "^4.17.19",
+ "@babel/helper-validator-identifier": "^7.14.0",
"to-fast-properties": "^2.0.0"
+ },
+ "dependencies": {
+ "@babel/helper-validator-identifier": {
+ "version": "7.14.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
+ "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "dev": true
+ }
}
},
"@bcoe/v8-coverage": {
@@ -423,132 +463,135 @@
}
},
"@istanbuljs/schema": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz",
- "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==",
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
"dev": true
},
"@jest/console": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz",
- "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz",
+ "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==",
"dev": true,
"requires": {
- "@jest/types": "^25.5.0",
- "chalk": "^3.0.0",
- "jest-message-util": "^25.5.0",
- "jest-util": "^25.5.0",
+ "@jest/types": "^26.6.2",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "jest-message-util": "^26.6.2",
+ "jest-util": "^26.6.2",
"slash": "^3.0.0"
}
},
"@jest/core": {
- "version": "25.5.4",
- "resolved": "https://registry.npmjs.org/@jest/core/-/core-25.5.4.tgz",
- "integrity": "sha512-3uSo7laYxF00Dg/DMgbn4xMJKmDdWvZnf89n8Xj/5/AeQ2dOQmn6b6Hkj/MleyzZWXpwv+WSdYWl4cLsy2JsoA==",
+ "version": "26.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz",
+ "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==",
"dev": true,
"requires": {
- "@jest/console": "^25.5.0",
- "@jest/reporters": "^25.5.1",
- "@jest/test-result": "^25.5.0",
- "@jest/transform": "^25.5.1",
- "@jest/types": "^25.5.0",
+ "@jest/console": "^26.6.2",
+ "@jest/reporters": "^26.6.2",
+ "@jest/test-result": "^26.6.2",
+ "@jest/transform": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "@types/node": "*",
"ansi-escapes": "^4.2.1",
- "chalk": "^3.0.0",
+ "chalk": "^4.0.0",
"exit": "^0.1.2",
"graceful-fs": "^4.2.4",
- "jest-changed-files": "^25.5.0",
- "jest-config": "^25.5.4",
- "jest-haste-map": "^25.5.1",
- "jest-message-util": "^25.5.0",
- "jest-regex-util": "^25.2.6",
- "jest-resolve": "^25.5.1",
- "jest-resolve-dependencies": "^25.5.4",
- "jest-runner": "^25.5.4",
- "jest-runtime": "^25.5.4",
- "jest-snapshot": "^25.5.1",
- "jest-util": "^25.5.0",
- "jest-validate": "^25.5.0",
- "jest-watcher": "^25.5.0",
+ "jest-changed-files": "^26.6.2",
+ "jest-config": "^26.6.3",
+ "jest-haste-map": "^26.6.2",
+ "jest-message-util": "^26.6.2",
+ "jest-regex-util": "^26.0.0",
+ "jest-resolve": "^26.6.2",
+ "jest-resolve-dependencies": "^26.6.3",
+ "jest-runner": "^26.6.3",
+ "jest-runtime": "^26.6.3",
+ "jest-snapshot": "^26.6.2",
+ "jest-util": "^26.6.2",
+ "jest-validate": "^26.6.2",
+ "jest-watcher": "^26.6.2",
"micromatch": "^4.0.2",
"p-each-series": "^2.1.0",
- "realpath-native": "^2.0.0",
"rimraf": "^3.0.0",
"slash": "^3.0.0",
"strip-ansi": "^6.0.0"
}
},
"@jest/environment": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz",
- "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz",
+ "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==",
"dev": true,
"requires": {
- "@jest/fake-timers": "^25.5.0",
- "@jest/types": "^25.5.0",
- "jest-mock": "^25.5.0"
+ "@jest/fake-timers": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "@types/node": "*",
+ "jest-mock": "^26.6.2"
}
},
"@jest/fake-timers": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz",
- "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz",
+ "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==",
"dev": true,
"requires": {
- "@jest/types": "^25.5.0",
- "jest-message-util": "^25.5.0",
- "jest-mock": "^25.5.0",
- "jest-util": "^25.5.0",
- "lolex": "^5.0.0"
+ "@jest/types": "^26.6.2",
+ "@sinonjs/fake-timers": "^6.0.1",
+ "@types/node": "*",
+ "jest-message-util": "^26.6.2",
+ "jest-mock": "^26.6.2",
+ "jest-util": "^26.6.2"
}
},
"@jest/globals": {
- "version": "25.5.2",
- "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz",
- "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz",
+ "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==",
"dev": true,
"requires": {
- "@jest/environment": "^25.5.0",
- "@jest/types": "^25.5.0",
- "expect": "^25.5.0"
+ "@jest/environment": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "expect": "^26.6.2"
}
},
"@jest/reporters": {
- "version": "25.5.1",
- "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-25.5.1.tgz",
- "integrity": "sha512-3jbd8pPDTuhYJ7vqiHXbSwTJQNavczPs+f1kRprRDxETeE3u6srJ+f0NPuwvOmk+lmunZzPkYWIFZDLHQPkviw==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz",
+ "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==",
"dev": true,
"requires": {
"@bcoe/v8-coverage": "^0.2.3",
- "@jest/console": "^25.5.0",
- "@jest/test-result": "^25.5.0",
- "@jest/transform": "^25.5.1",
- "@jest/types": "^25.5.0",
- "chalk": "^3.0.0",
+ "@jest/console": "^26.6.2",
+ "@jest/test-result": "^26.6.2",
+ "@jest/transform": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "chalk": "^4.0.0",
"collect-v8-coverage": "^1.0.0",
"exit": "^0.1.2",
"glob": "^7.1.2",
"graceful-fs": "^4.2.4",
"istanbul-lib-coverage": "^3.0.0",
- "istanbul-lib-instrument": "^4.0.0",
+ "istanbul-lib-instrument": "^4.0.3",
"istanbul-lib-report": "^3.0.0",
"istanbul-lib-source-maps": "^4.0.0",
"istanbul-reports": "^3.0.2",
- "jest-haste-map": "^25.5.1",
- "jest-resolve": "^25.5.1",
- "jest-util": "^25.5.0",
- "jest-worker": "^25.5.0",
- "node-notifier": "^6.0.0",
+ "jest-haste-map": "^26.6.2",
+ "jest-resolve": "^26.6.2",
+ "jest-util": "^26.6.2",
+ "jest-worker": "^26.6.2",
+ "node-notifier": "^8.0.0",
"slash": "^3.0.0",
"source-map": "^0.6.0",
- "string-length": "^3.1.0",
+ "string-length": "^4.0.1",
"terminal-link": "^2.0.0",
- "v8-to-istanbul": "^4.1.3"
+ "v8-to-istanbul": "^7.0.0"
}
},
"@jest/source-map": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz",
- "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz",
+ "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==",
"dev": true,
"requires": {
"callsites": "^3.0.0",
@@ -557,64 +600,64 @@
}
},
"@jest/test-result": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz",
- "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz",
+ "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==",
"dev": true,
"requires": {
- "@jest/console": "^25.5.0",
- "@jest/types": "^25.5.0",
+ "@jest/console": "^26.6.2",
+ "@jest/types": "^26.6.2",
"@types/istanbul-lib-coverage": "^2.0.0",
"collect-v8-coverage": "^1.0.0"
}
},
"@jest/test-sequencer": {
- "version": "25.5.4",
- "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.5.4.tgz",
- "integrity": "sha512-pTJGEkSeg1EkCO2YWq6hbFvKNXk8ejqlxiOg1jBNLnWrgXOkdY6UmqZpwGFXNnRt9B8nO1uWMzLLZ4eCmhkPNA==",
+ "version": "26.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz",
+ "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==",
"dev": true,
"requires": {
- "@jest/test-result": "^25.5.0",
+ "@jest/test-result": "^26.6.2",
"graceful-fs": "^4.2.4",
- "jest-haste-map": "^25.5.1",
- "jest-runner": "^25.5.4",
- "jest-runtime": "^25.5.4"
+ "jest-haste-map": "^26.6.2",
+ "jest-runner": "^26.6.3",
+ "jest-runtime": "^26.6.3"
}
},
"@jest/transform": {
- "version": "25.5.1",
- "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz",
- "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz",
+ "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==",
"dev": true,
"requires": {
"@babel/core": "^7.1.0",
- "@jest/types": "^25.5.0",
+ "@jest/types": "^26.6.2",
"babel-plugin-istanbul": "^6.0.0",
- "chalk": "^3.0.0",
+ "chalk": "^4.0.0",
"convert-source-map": "^1.4.0",
"fast-json-stable-stringify": "^2.0.0",
"graceful-fs": "^4.2.4",
- "jest-haste-map": "^25.5.1",
- "jest-regex-util": "^25.2.6",
- "jest-util": "^25.5.0",
+ "jest-haste-map": "^26.6.2",
+ "jest-regex-util": "^26.0.0",
+ "jest-util": "^26.6.2",
"micromatch": "^4.0.2",
"pirates": "^4.0.1",
- "realpath-native": "^2.0.0",
"slash": "^3.0.0",
"source-map": "^0.6.1",
"write-file-atomic": "^3.0.0"
}
},
"@jest/types": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz",
- "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
"@types/yargs": "^15.0.0",
- "chalk": "^3.0.0"
+ "chalk": "^4.0.0"
}
},
"@protobufjs/aspromise": {
@@ -713,23 +756,38 @@
}
},
"@sinonjs/commons": {
- "version": "1.8.2",
- "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.2.tgz",
- "integrity": "sha512-sruwd86RJHdsVf/AtBoijDmUqJp3B6hF/DGC23C+JaegnDHaZyewCjoVGTdg3J0uz3Zs7NnIT05OBOmML72lQw==",
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz",
+ "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==",
"dev": true,
"requires": {
"type-detect": "4.0.8"
}
},
+ "@sinonjs/fake-timers": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz",
+ "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1.7.0"
+ }
+ },
+ "@tootallnate/once": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
+ "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
+ "dev": true
+ },
"@tsundoku/micromodal_types": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/@tsundoku/micromodal_types/-/micromodal_types-0.0.1.tgz",
"integrity": "sha512-9k95tyHczZp/Uwu7SysnekpA2/o/y5gb/jMwqoLuTlJqwIVwnxfpsfmxc/bMfHnct7ESSqmRUJ1qYnUPD9Z7og=="
},
"@types/babel__core": {
- "version": "7.1.12",
- "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.12.tgz",
- "integrity": "sha512-wMTHiiTiBAAPebqaPiPDLFA4LYPKr6Ph0Xq/6rq1Ur3v66HXyG+clfR9CNETkD7MQS8ZHvpQOtA53DLws5WAEQ==",
+ "version": "7.1.14",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.14.tgz",
+ "integrity": "sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g==",
"dev": true,
"requires": {
"@babel/parser": "^7.1.0",
@@ -759,9 +817,9 @@
}
},
"@types/babel__traverse": {
- "version": "7.11.0",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.0.tgz",
- "integrity": "sha512-kSjgDMZONiIfSH1Nxcr5JIRMwUetDki63FSQfpTCz8ogF3Ulqm8+mr5f78dUYs6vMiB6gBusQqfQmBvHZj/lwg==",
+ "version": "7.11.1",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.1.tgz",
+ "integrity": "sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw==",
"dev": true,
"requires": {
"@babel/types": "^7.3.0"
@@ -808,9 +866,9 @@
"integrity": "sha1-wFTor02d11205jq8dviFFocU1LM="
},
"@types/graceful-fs": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.4.tgz",
- "integrity": "sha512-mWA/4zFQhfvOA8zWkXobwJvBD7vzcxgrOQ0J5CH1votGqdq9m7+FwtGaqyCZqC3NyyBkc9z4m+iry4LlqcMWJg==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz",
+ "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==",
"dev": true,
"requires": {
"@types/node": "*"
@@ -832,20 +890,23 @@
}
},
"@types/istanbul-reports": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz",
- "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
"dev": true,
"requires": {
- "@types/istanbul-lib-coverage": "*",
"@types/istanbul-lib-report": "*"
}
},
"@types/jest": {
- "version": "22.2.3",
- "resolved": "https://registry.npmjs.org/@types/jest/-/jest-22.2.3.tgz",
- "integrity": "sha512-e74sM9W/4qqWB6D4TWV9FQk0WoHtX1X4FJpbjxucMSVJHtFjbQOH3H6yp+xno4br0AKG0wz/kPtaN599GUOvAg==",
- "dev": true
+ "version": "26.0.23",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.23.tgz",
+ "integrity": "sha512-ZHLmWMJ9jJ9PTiT58juykZpL7KjwJywFN3Rr2pTSkyQfydf/rk22yS7W8p5DaVUMQ2BQC7oYiU3FjbTM/mYrOA==",
+ "dev": true,
+ "requires": {
+ "jest-diff": "^26.0.0",
+ "pretty-format": "^26.0.0"
+ }
},
"@types/long": {
"version": "4.0.1",
@@ -873,16 +934,25 @@
"resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.1.tgz",
"integrity": "sha512-GdZbRSJ3Cv5fiwT6I0SQ3ckeN2PWNqxd26W9Z2fCK1tGrrasGy4puvNFtnddqH9UJFMQYXxEuuB7B8UK+LLwSg=="
},
+ "@types/pixelmatch": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/@types/pixelmatch/-/pixelmatch-5.2.3.tgz",
+ "integrity": "sha512-p+nAQVYK/DUx7+s1Xyu9dqAg0gobf7VmJ+iDA4lljg1o4XRgQHr7R2h1NwFt3gdNOZiftxWB11+0TuZqXYf19w==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
"@types/prettier": {
- "version": "1.19.1",
- "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz",
- "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==",
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz",
+ "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==",
"dev": true
},
"@types/puppeteer": {
- "version": "1.20.7",
- "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-1.20.7.tgz",
- "integrity": "sha512-LCfP/Zf/y4I/hG8ARR8htPYa1wpLpUkysJo9TffmQssVz8c1b9uDNU4benDHSldiz7HVAMek1DCWz7KbqEUg3w==",
+ "version": "5.4.3",
+ "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-5.4.3.tgz",
+ "integrity": "sha512-3nE8YgR9DIsgttLW+eJf6mnXxq8Ge+27m5SU3knWmrlfl6+KOG0Bf9f7Ua7K+C4BnaTMAh3/UpySqdAYvrsvjg==",
"dev": true,
"requires": {
"@types/node": "*"
@@ -898,9 +968,9 @@
}
},
"@types/stack-utils": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
- "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz",
+ "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==",
"dev": true
},
"@types/uuid": {
@@ -928,6 +998,16 @@
"integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==",
"dev": true
},
+ "@types/yauzl": {
+ "version": "2.9.1",
+ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz",
+ "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
"abab": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
@@ -941,42 +1021,42 @@
"dev": true
},
"acorn": {
- "version": "7.4.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
- "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.3.0.tgz",
+ "integrity": "sha512-tqPKHZ5CaBJw0Xmy0ZZvLs1qTV+BNFSyvn77ASXkpBNfIRk8ev26fKrD9iLGwGA9zedPao52GSHzq8lyZG0NUw==",
"dev": true
},
"acorn-globals": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz",
- "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz",
+ "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==",
"dev": true,
"requires": {
- "acorn": "^6.0.1",
- "acorn-walk": "^6.0.1"
+ "acorn": "^7.1.1",
+ "acorn-walk": "^7.1.1"
},
"dependencies": {
"acorn": {
- "version": "6.4.2",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
- "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
"dev": true
}
}
},
"acorn-walk": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz",
- "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
"dev": true
},
"agent-base": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
- "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"dev": true,
"requires": {
- "es6-promisify": "^5.0.0"
+ "debug": "4"
}
},
"ajv": {
@@ -998,18 +1078,18 @@
"dev": true
},
"ansi-escapes": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
- "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
"dev": true,
"requires": {
- "type-fest": "^0.11.0"
+ "type-fest": "^0.21.3"
},
"dependencies": {
"type-fest": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
- "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==",
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
"dev": true
}
}
@@ -1030,9 +1110,9 @@
}
},
"anymatch": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
- "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
"dev": true,
"requires": {
"normalize-path": "^3.0.0",
@@ -1082,12 +1162,6 @@
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
"dev": true
},
- "array-equal": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
- "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=",
- "dev": true
- },
"array-filter": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz",
@@ -1126,24 +1200,12 @@
"integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
"dev": true
},
- "astral-regex": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
- "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
- "dev": true
- },
"async-foreach": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
"integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=",
"dev": true
},
- "async-limiter": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
- "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
- "dev": true
- },
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -1177,17 +1239,17 @@
"dev": true
},
"babel-jest": {
- "version": "25.5.1",
- "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz",
- "integrity": "sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==",
+ "version": "26.6.3",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz",
+ "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==",
"dev": true,
"requires": {
- "@jest/transform": "^25.5.1",
- "@jest/types": "^25.5.0",
+ "@jest/transform": "^26.6.2",
+ "@jest/types": "^26.6.2",
"@types/babel__core": "^7.1.7",
"babel-plugin-istanbul": "^6.0.0",
- "babel-preset-jest": "^25.5.0",
- "chalk": "^3.0.0",
+ "babel-preset-jest": "^26.6.2",
+ "chalk": "^4.0.0",
"graceful-fs": "^4.2.4",
"slash": "^3.0.0"
}
@@ -1206,20 +1268,21 @@
}
},
"babel-plugin-jest-hoist": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz",
- "integrity": "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz",
+ "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==",
"dev": true,
"requires": {
"@babel/template": "^7.3.3",
"@babel/types": "^7.3.3",
+ "@types/babel__core": "^7.0.0",
"@types/babel__traverse": "^7.0.6"
}
},
"babel-preset-current-node-syntax": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.4.tgz",
- "integrity": "sha512-5/INNCYhUGqw7VbVjT/hb3ucjgkVHKXY7lX3ZjlN4gm565VyFmJUrJ/h+h16ECVB38R/9SF6aACydpKMLZ/c9w==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz",
+ "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==",
"dev": true,
"requires": {
"@babel/plugin-syntax-async-generators": "^7.8.4",
@@ -1232,17 +1295,18 @@
"@babel/plugin-syntax-numeric-separator": "^7.8.3",
"@babel/plugin-syntax-object-rest-spread": "^7.8.3",
"@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3"
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-syntax-top-level-await": "^7.8.3"
}
},
"babel-preset-jest": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz",
- "integrity": "sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz",
+ "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==",
"dev": true,
"requires": {
- "babel-plugin-jest-hoist": "^25.5.0",
- "babel-preset-current-node-syntax": "^0.1.2"
+ "babel-plugin-jest-hoist": "^26.6.2",
+ "babel-preset-current-node-syntax": "^1.0.0"
}
},
"balanced-match": {
@@ -1306,6 +1370,12 @@
}
}
},
+ "base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "dev": true
+ },
"bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
@@ -1315,6 +1385,30 @@
"tweetnacl": "^0.14.3"
}
},
+ "bl": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+ "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
+ }
+ },
"block-stream": {
"version": "0.0.9",
"resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
@@ -1349,30 +1443,17 @@
"integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==",
"dev": true
},
- "browser-resolve": {
- "version": "1.11.3",
- "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz",
- "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==",
+ "browserslist": {
+ "version": "4.16.6",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
+ "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
"dev": true,
"requires": {
- "resolve": "1.1.7"
- },
- "dependencies": {
- "resolve": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
- "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
- "dev": true
- }
- }
- },
- "bs-logger": {
- "version": "0.2.6",
- "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
- "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
- "dev": true,
- "requires": {
- "fast-json-stable-stringify": "2.x"
+ "caniuse-lite": "^1.0.30001219",
+ "colorette": "^1.2.2",
+ "electron-to-chromium": "^1.3.723",
+ "escalade": "^3.1.1",
+ "node-releases": "^1.1.71"
}
},
"bser": {
@@ -1384,6 +1465,16 @@
"node-int64": "^0.4.0"
}
},
+ "buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
"buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
@@ -1458,6 +1549,12 @@
}
}
},
+ "caniuse-lite": {
+ "version": "1.0.30001233",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001233.tgz",
+ "integrity": "sha512-BmkbxLfStqiPA7IEzQpIk0UFZFf3A4E6fzjPJ6OR+bFC2L8ES9J8zGA/asoi47p8XDVkev+WJo2I2Nc8c/34Yg==",
+ "dev": true
+ },
"capture-exit": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",
@@ -1474,21 +1571,39 @@
"dev": true
},
"chalk": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
- "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
+ "char-regex": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
+ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
+ "dev": true
+ },
+ "chownr": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+ "dev": true
+ },
"ci-info": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
"integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
"dev": true
},
+ "cjs-module-lexer": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz",
+ "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==",
+ "dev": true
+ },
"class-utils": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
@@ -1564,6 +1679,12 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
+ "colorette": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
+ "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
+ "dev": true
+ },
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -1597,18 +1718,6 @@
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
- "concat-stream": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
- "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
- "dev": true,
- "requires": {
- "buffer-from": "^1.0.0",
- "inherits": "^2.0.3",
- "readable-stream": "^2.2.2",
- "typedarray": "^0.0.6"
- }
- },
"console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
@@ -1662,15 +1771,6 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true
- },
- "which": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
- "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
- "dev": true,
- "requires": {
- "isexe": "^2.0.0"
- }
}
}
},
@@ -1719,14 +1819,14 @@
}
},
"data-urls": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz",
- "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz",
+ "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==",
"dev": true,
"requires": {
- "abab": "^2.0.0",
- "whatwg-mimetype": "^2.2.0",
- "whatwg-url": "^7.0.0"
+ "abab": "^2.0.3",
+ "whatwg-mimetype": "^2.3.0",
+ "whatwg-url": "^8.0.0"
}
},
"debug": {
@@ -1744,6 +1844,12 @@
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
"dev": true
},
+ "decimal.js": {
+ "version": "10.2.1",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz",
+ "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==",
+ "dev": true
+ },
"decode-uri-component": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
@@ -1847,9 +1953,9 @@
"dev": true
},
"diff-sequences": {
- "version": "25.2.6",
- "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz",
- "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz",
+ "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==",
"dev": true
},
"dingusjs": {
@@ -1859,12 +1965,20 @@
"dev": true
},
"domexception": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
- "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz",
+ "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==",
"dev": true,
"requires": {
- "webidl-conversions": "^4.0.2"
+ "webidl-conversions": "^5.0.0"
+ },
+ "dependencies": {
+ "webidl-conversions": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz",
+ "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==",
+ "dev": true
+ }
}
},
"ecc-jsbn": {
@@ -1877,6 +1991,18 @@
"safer-buffer": "^2.1.0"
}
},
+ "electron-to-chromium": {
+ "version": "1.3.747",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.747.tgz",
+ "integrity": "sha512-+K1vnBc08GNYxCWwdRe9o3Ml30DhsNyK/qIl/NE1Dic+qCy9ZREcqGNiV4jiLiAdALK1DUG3pakJHGkJUd9QQw==",
+ "dev": true
+ },
+ "emittery": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz",
+ "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==",
+ "dev": true
+ },
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -1932,21 +2058,12 @@
"is-symbol": "^1.0.2"
}
},
- "es6-promise": {
- "version": "4.2.8",
- "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
- "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==",
+ "escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
"dev": true
},
- "es6-promisify": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
- "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
- "dev": true,
- "requires": {
- "es6-promise": "^4.0.3"
- }
- },
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
@@ -1954,13 +2071,13 @@
"dev": true
},
"escodegen": {
- "version": "1.14.3",
- "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz",
- "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz",
+ "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==",
"dev": true,
"requires": {
"esprima": "^4.0.1",
- "estraverse": "^4.2.0",
+ "estraverse": "^5.2.0",
"esutils": "^2.0.2",
"optionator": "^0.8.1",
"source-map": "~0.6.1"
@@ -1973,9 +2090,9 @@
"dev": true
},
"estraverse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
- "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+ "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
"dev": true
},
"estree-walker": {
@@ -1996,9 +2113,9 @@
"integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg=="
},
"exec-sh": {
- "version": "0.3.4",
- "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz",
- "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==",
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz",
+ "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==",
"dev": true
},
"execa": {
@@ -2073,17 +2190,17 @@
}
},
"expect": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz",
- "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz",
+ "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==",
"dev": true,
"requires": {
- "@jest/types": "^25.5.0",
+ "@jest/types": "^26.6.2",
"ansi-styles": "^4.0.0",
- "jest-get-type": "^25.2.6",
- "jest-matcher-utils": "^25.5.0",
- "jest-message-util": "^25.5.0",
- "jest-regex-util": "^25.2.6"
+ "jest-get-type": "^26.3.0",
+ "jest-matcher-utils": "^26.6.2",
+ "jest-message-util": "^26.6.2",
+ "jest-regex-util": "^26.0.0"
}
},
"extend": {
@@ -2179,31 +2296,25 @@
}
},
"extract-zip": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz",
- "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
+ "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
"dev": true,
"requires": {
- "concat-stream": "^1.6.2",
- "debug": "^2.6.9",
- "mkdirp": "^0.5.4",
+ "@types/yauzl": "^2.9.1",
+ "debug": "^4.1.1",
+ "get-stream": "^5.1.0",
"yauzl": "^2.10.0"
},
"dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"dev": true,
"requires": {
- "ms": "2.0.0"
+ "pump": "^3.0.0"
}
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
- "dev": true
}
}
},
@@ -2305,6 +2416,12 @@
"map-cache": "^0.2.2"
}
},
+ "fs-constants": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
+ "dev": true
+ },
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -2621,9 +2738,9 @@
}
},
"hosted-git-info": {
- "version": "2.8.8",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
- "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
+ "version": "2.8.9",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
"dev": true
},
"hsluv": {
@@ -2632,12 +2749,12 @@
"integrity": "sha512-ERcanKLAszD2XN3Vh5r5Szkrv9q0oSTudmP0rkiKAGM/3NMc9FLmMZBB7TSqTaXJfSDBOreYTfjezCOYbRKqlw=="
},
"html-encoding-sniffer": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
- "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz",
+ "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==",
"dev": true,
"requires": {
- "whatwg-encoding": "^1.0.1"
+ "whatwg-encoding": "^1.0.5"
}
},
"html-escaper": {
@@ -2646,6 +2763,17 @@
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
"dev": true
},
+ "http-proxy-agent": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
+ "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
+ "dev": true,
+ "requires": {
+ "@tootallnate/once": "1",
+ "agent-base": "6",
+ "debug": "4"
+ }
+ },
"http-signature": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
@@ -2658,24 +2786,13 @@
}
},
"https-proxy-agent": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz",
- "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
+ "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
"dev": true,
"requires": {
- "agent-base": "^4.3.0",
- "debug": "^3.1.0"
- },
- "dependencies": {
- "debug": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
- "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
- "dev": true,
- "requires": {
- "ms": "^2.1.1"
- }
- }
+ "agent-base": "6",
+ "debug": "4"
}
},
"human-signals": {
@@ -2693,10 +2810,16 @@
"safer-buffer": ">= 2.1.2 < 3"
}
},
+ "ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "dev": true
+ },
"immer": {
- "version": "1.12.1",
- "resolved": "https://registry.npmjs.org/immer/-/immer-1.12.1.tgz",
- "integrity": "sha512-3fmKM6ovaqDt0CdC9daXpNi5x/YCYS3i4cwLdTVkhJdk5jrDXoPs7lCm3IqM3yhfSnz4tjjxbRG2CziQ7m8ztg=="
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.5.tgz",
+ "integrity": "sha512-2WuIehr2y4lmYz9gaQzetPR2ECniCifk4ORaQbU3g5EalLt+0IVTosEPJ5BoYl/75ky2mivzdRzV8wWgQGOSYQ=="
},
"import-local": {
"version": "3.0.2",
@@ -2744,12 +2867,6 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
- "ip-regex": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
- "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
- "dev": true
- },
"is-accessor-descriptor": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
@@ -2858,9 +2975,9 @@
}
},
"is-docker": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz",
- "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==",
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+ "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
"dev": true,
"optional": true
},
@@ -2919,6 +3036,12 @@
"isobject": "^3.0.1"
}
},
+ "is-potential-custom-element-name": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
+ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
+ "dev": true
+ },
"is-reference": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
@@ -3066,48 +3189,47 @@
}
},
"jest": {
- "version": "25.5.4",
- "resolved": "https://registry.npmjs.org/jest/-/jest-25.5.4.tgz",
- "integrity": "sha512-hHFJROBTqZahnO+X+PMtT6G2/ztqAZJveGqz//FnWWHurizkD05PQGzRZOhF3XP6z7SJmL+5tCfW8qV06JypwQ==",
+ "version": "26.6.3",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz",
+ "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==",
"dev": true,
"requires": {
- "@jest/core": "^25.5.4",
+ "@jest/core": "^26.6.3",
"import-local": "^3.0.2",
- "jest-cli": "^25.5.4"
+ "jest-cli": "^26.6.3"
},
"dependencies": {
"jest-cli": {
- "version": "25.5.4",
- "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-25.5.4.tgz",
- "integrity": "sha512-rG8uJkIiOUpnREh1768/N3n27Cm+xPFkSNFO91tgg+8o2rXeVLStz+vkXkGr4UtzH6t1SNbjwoiswd7p4AhHTw==",
+ "version": "26.6.3",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz",
+ "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==",
"dev": true,
"requires": {
- "@jest/core": "^25.5.4",
- "@jest/test-result": "^25.5.0",
- "@jest/types": "^25.5.0",
- "chalk": "^3.0.0",
+ "@jest/core": "^26.6.3",
+ "@jest/test-result": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "chalk": "^4.0.0",
"exit": "^0.1.2",
"graceful-fs": "^4.2.4",
"import-local": "^3.0.2",
"is-ci": "^2.0.0",
- "jest-config": "^25.5.4",
- "jest-util": "^25.5.0",
- "jest-validate": "^25.5.0",
+ "jest-config": "^26.6.3",
+ "jest-util": "^26.6.2",
+ "jest-validate": "^26.6.2",
"prompts": "^2.0.1",
- "realpath-native": "^2.0.0",
- "yargs": "^15.3.1"
+ "yargs": "^15.4.1"
}
}
}
},
"jest-changed-files": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-25.5.0.tgz",
- "integrity": "sha512-EOw9QEqapsDT7mKF162m8HFzRPbmP8qJQny6ldVOdOVBz3ACgPm/1nAn5fPQ/NDaYhX/AHkrGwwkCncpAVSXcw==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz",
+ "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==",
"dev": true,
"requires": {
- "@jest/types": "^25.5.0",
- "execa": "^3.2.0",
+ "@jest/types": "^26.6.2",
+ "execa": "^4.0.0",
"throat": "^5.0.0"
},
"dependencies": {
@@ -3123,9 +3245,9 @@
}
},
"execa": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz",
- "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
+ "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
"dev": true,
"requires": {
"cross-spawn": "^7.0.0",
@@ -3135,7 +3257,6 @@
"merge-stream": "^2.0.0",
"npm-run-path": "^4.0.0",
"onetime": "^5.1.0",
- "p-finally": "^2.0.0",
"signal-exit": "^3.0.2",
"strip-final-newline": "^2.0.0"
}
@@ -3164,12 +3285,6 @@
"path-key": "^3.0.0"
}
},
- "p-finally": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz",
- "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==",
- "dev": true
- },
"path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
@@ -3190,195 +3305,208 @@
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
}
}
},
"jest-config": {
- "version": "25.5.4",
- "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.5.4.tgz",
- "integrity": "sha512-SZwR91SwcdK6bz7Gco8qL7YY2sx8tFJYzvg216DLihTWf+LKY/DoJXpM9nTzYakSyfblbqeU48p/p7Jzy05Atg==",
+ "version": "26.6.3",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz",
+ "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==",
"dev": true,
"requires": {
"@babel/core": "^7.1.0",
- "@jest/test-sequencer": "^25.5.4",
- "@jest/types": "^25.5.0",
- "babel-jest": "^25.5.1",
- "chalk": "^3.0.0",
+ "@jest/test-sequencer": "^26.6.3",
+ "@jest/types": "^26.6.2",
+ "babel-jest": "^26.6.3",
+ "chalk": "^4.0.0",
"deepmerge": "^4.2.2",
"glob": "^7.1.1",
"graceful-fs": "^4.2.4",
- "jest-environment-jsdom": "^25.5.0",
- "jest-environment-node": "^25.5.0",
- "jest-get-type": "^25.2.6",
- "jest-jasmine2": "^25.5.4",
- "jest-regex-util": "^25.2.6",
- "jest-resolve": "^25.5.1",
- "jest-util": "^25.5.0",
- "jest-validate": "^25.5.0",
+ "jest-environment-jsdom": "^26.6.2",
+ "jest-environment-node": "^26.6.2",
+ "jest-get-type": "^26.3.0",
+ "jest-jasmine2": "^26.6.3",
+ "jest-regex-util": "^26.0.0",
+ "jest-resolve": "^26.6.2",
+ "jest-util": "^26.6.2",
+ "jest-validate": "^26.6.2",
"micromatch": "^4.0.2",
- "pretty-format": "^25.5.0",
- "realpath-native": "^2.0.0"
+ "pretty-format": "^26.6.2"
}
},
"jest-diff": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz",
- "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz",
+ "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==",
"dev": true,
"requires": {
- "chalk": "^3.0.0",
- "diff-sequences": "^25.2.6",
- "jest-get-type": "^25.2.6",
- "pretty-format": "^25.5.0"
+ "chalk": "^4.0.0",
+ "diff-sequences": "^26.6.2",
+ "jest-get-type": "^26.3.0",
+ "pretty-format": "^26.6.2"
}
},
"jest-docblock": {
- "version": "25.3.0",
- "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.3.0.tgz",
- "integrity": "sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg==",
+ "version": "26.0.0",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz",
+ "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==",
"dev": true,
"requires": {
"detect-newline": "^3.0.0"
}
},
"jest-each": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz",
- "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz",
+ "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==",
"dev": true,
"requires": {
- "@jest/types": "^25.5.0",
- "chalk": "^3.0.0",
- "jest-get-type": "^25.2.6",
- "jest-util": "^25.5.0",
- "pretty-format": "^25.5.0"
+ "@jest/types": "^26.6.2",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^26.3.0",
+ "jest-util": "^26.6.2",
+ "pretty-format": "^26.6.2"
}
},
"jest-environment-jsdom": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.5.0.tgz",
- "integrity": "sha512-7Jr02ydaq4jaWMZLY+Skn8wL5nVIYpWvmeatOHL3tOcV3Zw8sjnPpx+ZdeBfc457p8jCR9J6YCc+Lga0oIy62A==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz",
+ "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==",
"dev": true,
"requires": {
- "@jest/environment": "^25.5.0",
- "@jest/fake-timers": "^25.5.0",
- "@jest/types": "^25.5.0",
- "jest-mock": "^25.5.0",
- "jest-util": "^25.5.0",
- "jsdom": "^15.2.1"
+ "@jest/environment": "^26.6.2",
+ "@jest/fake-timers": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "@types/node": "*",
+ "jest-mock": "^26.6.2",
+ "jest-util": "^26.6.2",
+ "jsdom": "^16.4.0"
}
},
"jest-environment-node": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.5.0.tgz",
- "integrity": "sha512-iuxK6rQR2En9EID+2k+IBs5fCFd919gVVK5BeND82fYeLWPqvRcFNPKu9+gxTwfB5XwBGBvZ0HFQa+cHtIoslA==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz",
+ "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==",
"dev": true,
"requires": {
- "@jest/environment": "^25.5.0",
- "@jest/fake-timers": "^25.5.0",
- "@jest/types": "^25.5.0",
- "jest-mock": "^25.5.0",
- "jest-util": "^25.5.0",
- "semver": "^6.3.0"
+ "@jest/environment": "^26.6.2",
+ "@jest/fake-timers": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "@types/node": "*",
+ "jest-mock": "^26.6.2",
+ "jest-util": "^26.6.2"
}
},
"jest-get-type": {
- "version": "25.2.6",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz",
- "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==",
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz",
+ "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==",
"dev": true
},
"jest-haste-map": {
- "version": "25.5.1",
- "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz",
- "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz",
+ "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==",
"dev": true,
"requires": {
- "@jest/types": "^25.5.0",
+ "@jest/types": "^26.6.2",
"@types/graceful-fs": "^4.1.2",
+ "@types/node": "*",
"anymatch": "^3.0.3",
"fb-watchman": "^2.0.0",
"fsevents": "^2.1.2",
"graceful-fs": "^4.2.4",
- "jest-serializer": "^25.5.0",
- "jest-util": "^25.5.0",
- "jest-worker": "^25.5.0",
+ "jest-regex-util": "^26.0.0",
+ "jest-serializer": "^26.6.2",
+ "jest-util": "^26.6.2",
+ "jest-worker": "^26.6.2",
"micromatch": "^4.0.2",
"sane": "^4.0.3",
- "walker": "^1.0.7",
- "which": "^2.0.2"
+ "walker": "^1.0.7"
}
},
"jest-jasmine2": {
- "version": "25.5.4",
- "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.5.4.tgz",
- "integrity": "sha512-9acbWEfbmS8UpdcfqnDO+uBUgKa/9hcRh983IHdM+pKmJPL77G0sWAAK0V0kr5LK3a8cSBfkFSoncXwQlRZfkQ==",
+ "version": "26.6.3",
+ "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz",
+ "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==",
"dev": true,
"requires": {
"@babel/traverse": "^7.1.0",
- "@jest/environment": "^25.5.0",
- "@jest/source-map": "^25.5.0",
- "@jest/test-result": "^25.5.0",
- "@jest/types": "^25.5.0",
- "chalk": "^3.0.0",
+ "@jest/environment": "^26.6.2",
+ "@jest/source-map": "^26.6.2",
+ "@jest/test-result": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
"co": "^4.6.0",
- "expect": "^25.5.0",
+ "expect": "^26.6.2",
"is-generator-fn": "^2.0.0",
- "jest-each": "^25.5.0",
- "jest-matcher-utils": "^25.5.0",
- "jest-message-util": "^25.5.0",
- "jest-runtime": "^25.5.4",
- "jest-snapshot": "^25.5.1",
- "jest-util": "^25.5.0",
- "pretty-format": "^25.5.0",
+ "jest-each": "^26.6.2",
+ "jest-matcher-utils": "^26.6.2",
+ "jest-message-util": "^26.6.2",
+ "jest-runtime": "^26.6.3",
+ "jest-snapshot": "^26.6.2",
+ "jest-util": "^26.6.2",
+ "pretty-format": "^26.6.2",
"throat": "^5.0.0"
}
},
"jest-leak-detector": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.5.0.tgz",
- "integrity": "sha512-rV7JdLsanS8OkdDpZtgBf61L5xZ4NnYLBq72r6ldxahJWWczZjXawRsoHyXzibM5ed7C2QRjpp6ypgwGdKyoVA==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz",
+ "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==",
"dev": true,
"requires": {
- "jest-get-type": "^25.2.6",
- "pretty-format": "^25.5.0"
+ "jest-get-type": "^26.3.0",
+ "pretty-format": "^26.6.2"
}
},
"jest-matcher-utils": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz",
- "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz",
+ "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==",
"dev": true,
"requires": {
- "chalk": "^3.0.0",
- "jest-diff": "^25.5.0",
- "jest-get-type": "^25.2.6",
- "pretty-format": "^25.5.0"
+ "chalk": "^4.0.0",
+ "jest-diff": "^26.6.2",
+ "jest-get-type": "^26.3.0",
+ "pretty-format": "^26.6.2"
}
},
"jest-message-util": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz",
- "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz",
+ "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
- "@jest/types": "^25.5.0",
- "@types/stack-utils": "^1.0.1",
- "chalk": "^3.0.0",
+ "@jest/types": "^26.6.2",
+ "@types/stack-utils": "^2.0.0",
+ "chalk": "^4.0.0",
"graceful-fs": "^4.2.4",
"micromatch": "^4.0.2",
+ "pretty-format": "^26.6.2",
"slash": "^3.0.0",
- "stack-utils": "^1.0.1"
+ "stack-utils": "^2.0.2"
}
},
"jest-mock": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz",
- "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz",
+ "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==",
"dev": true,
"requires": {
- "@jest/types": "^25.5.0"
+ "@jest/types": "^26.6.2",
+ "@types/node": "*"
}
},
"jest-pnp-resolver": {
@@ -3388,179 +3516,219 @@
"dev": true
},
"jest-regex-util": {
- "version": "25.2.6",
- "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz",
- "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==",
+ "version": "26.0.0",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz",
+ "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==",
"dev": true
},
"jest-resolve": {
- "version": "25.5.1",
- "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz",
- "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz",
+ "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==",
"dev": true,
"requires": {
- "@jest/types": "^25.5.0",
- "browser-resolve": "^1.11.3",
- "chalk": "^3.0.0",
+ "@jest/types": "^26.6.2",
+ "chalk": "^4.0.0",
"graceful-fs": "^4.2.4",
- "jest-pnp-resolver": "^1.2.1",
+ "jest-pnp-resolver": "^1.2.2",
+ "jest-util": "^26.6.2",
"read-pkg-up": "^7.0.1",
- "realpath-native": "^2.0.0",
- "resolve": "^1.17.0",
+ "resolve": "^1.18.1",
"slash": "^3.0.0"
}
},
"jest-resolve-dependencies": {
- "version": "25.5.4",
- "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-25.5.4.tgz",
- "integrity": "sha512-yFmbPd+DAQjJQg88HveObcGBA32nqNZ02fjYmtL16t1xw9bAttSn5UGRRhzMHIQbsep7znWvAvnD4kDqOFM0Uw==",
+ "version": "26.6.3",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz",
+ "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==",
"dev": true,
"requires": {
- "@jest/types": "^25.5.0",
- "jest-regex-util": "^25.2.6",
- "jest-snapshot": "^25.5.1"
+ "@jest/types": "^26.6.2",
+ "jest-regex-util": "^26.0.0",
+ "jest-snapshot": "^26.6.2"
}
},
"jest-runner": {
- "version": "25.5.4",
- "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.5.4.tgz",
- "integrity": "sha512-V/2R7fKZo6blP8E9BL9vJ8aTU4TH2beuqGNxHbxi6t14XzTb+x90B3FRgdvuHm41GY8ch4xxvf0ATH4hdpjTqg==",
- "dev": true,
- "requires": {
- "@jest/console": "^25.5.0",
- "@jest/environment": "^25.5.0",
- "@jest/test-result": "^25.5.0",
- "@jest/types": "^25.5.0",
- "chalk": "^3.0.0",
+ "version": "26.6.3",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz",
+ "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^26.6.2",
+ "@jest/environment": "^26.6.2",
+ "@jest/test-result": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "emittery": "^0.7.1",
"exit": "^0.1.2",
"graceful-fs": "^4.2.4",
- "jest-config": "^25.5.4",
- "jest-docblock": "^25.3.0",
- "jest-haste-map": "^25.5.1",
- "jest-jasmine2": "^25.5.4",
- "jest-leak-detector": "^25.5.0",
- "jest-message-util": "^25.5.0",
- "jest-resolve": "^25.5.1",
- "jest-runtime": "^25.5.4",
- "jest-util": "^25.5.0",
- "jest-worker": "^25.5.0",
+ "jest-config": "^26.6.3",
+ "jest-docblock": "^26.0.0",
+ "jest-haste-map": "^26.6.2",
+ "jest-leak-detector": "^26.6.2",
+ "jest-message-util": "^26.6.2",
+ "jest-resolve": "^26.6.2",
+ "jest-runtime": "^26.6.3",
+ "jest-util": "^26.6.2",
+ "jest-worker": "^26.6.2",
"source-map-support": "^0.5.6",
"throat": "^5.0.0"
}
},
"jest-runtime": {
- "version": "25.5.4",
- "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz",
- "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==",
- "dev": true,
- "requires": {
- "@jest/console": "^25.5.0",
- "@jest/environment": "^25.5.0",
- "@jest/globals": "^25.5.2",
- "@jest/source-map": "^25.5.0",
- "@jest/test-result": "^25.5.0",
- "@jest/transform": "^25.5.1",
- "@jest/types": "^25.5.0",
+ "version": "26.6.3",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz",
+ "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^26.6.2",
+ "@jest/environment": "^26.6.2",
+ "@jest/fake-timers": "^26.6.2",
+ "@jest/globals": "^26.6.2",
+ "@jest/source-map": "^26.6.2",
+ "@jest/test-result": "^26.6.2",
+ "@jest/transform": "^26.6.2",
+ "@jest/types": "^26.6.2",
"@types/yargs": "^15.0.0",
- "chalk": "^3.0.0",
+ "chalk": "^4.0.0",
+ "cjs-module-lexer": "^0.6.0",
"collect-v8-coverage": "^1.0.0",
"exit": "^0.1.2",
"glob": "^7.1.3",
"graceful-fs": "^4.2.4",
- "jest-config": "^25.5.4",
- "jest-haste-map": "^25.5.1",
- "jest-message-util": "^25.5.0",
- "jest-mock": "^25.5.0",
- "jest-regex-util": "^25.2.6",
- "jest-resolve": "^25.5.1",
- "jest-snapshot": "^25.5.1",
- "jest-util": "^25.5.0",
- "jest-validate": "^25.5.0",
- "realpath-native": "^2.0.0",
+ "jest-config": "^26.6.3",
+ "jest-haste-map": "^26.6.2",
+ "jest-message-util": "^26.6.2",
+ "jest-mock": "^26.6.2",
+ "jest-regex-util": "^26.0.0",
+ "jest-resolve": "^26.6.2",
+ "jest-snapshot": "^26.6.2",
+ "jest-util": "^26.6.2",
+ "jest-validate": "^26.6.2",
"slash": "^3.0.0",
"strip-bom": "^4.0.0",
- "yargs": "^15.3.1"
+ "yargs": "^15.4.1"
}
},
"jest-serializer": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz",
- "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz",
+ "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==",
"dev": true,
"requires": {
+ "@types/node": "*",
"graceful-fs": "^4.2.4"
}
},
"jest-snapshot": {
- "version": "25.5.1",
- "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz",
- "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz",
+ "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==",
"dev": true,
"requires": {
"@babel/types": "^7.0.0",
- "@jest/types": "^25.5.0",
- "@types/prettier": "^1.19.0",
- "chalk": "^3.0.0",
- "expect": "^25.5.0",
+ "@jest/types": "^26.6.2",
+ "@types/babel__traverse": "^7.0.4",
+ "@types/prettier": "^2.0.0",
+ "chalk": "^4.0.0",
+ "expect": "^26.6.2",
"graceful-fs": "^4.2.4",
- "jest-diff": "^25.5.0",
- "jest-get-type": "^25.2.6",
- "jest-matcher-utils": "^25.5.0",
- "jest-message-util": "^25.5.0",
- "jest-resolve": "^25.5.1",
- "make-dir": "^3.0.0",
+ "jest-diff": "^26.6.2",
+ "jest-get-type": "^26.3.0",
+ "jest-haste-map": "^26.6.2",
+ "jest-matcher-utils": "^26.6.2",
+ "jest-message-util": "^26.6.2",
+ "jest-resolve": "^26.6.2",
"natural-compare": "^1.4.0",
- "pretty-format": "^25.5.0",
- "semver": "^6.3.0"
+ "pretty-format": "^26.6.2",
+ "semver": "^7.3.2"
+ },
+ "dependencies": {
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ }
}
},
"jest-util": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz",
- "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz",
+ "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==",
"dev": true,
"requires": {
- "@jest/types": "^25.5.0",
- "chalk": "^3.0.0",
+ "@jest/types": "^26.6.2",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
"graceful-fs": "^4.2.4",
"is-ci": "^2.0.0",
- "make-dir": "^3.0.0"
+ "micromatch": "^4.0.2"
}
},
"jest-validate": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz",
- "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz",
+ "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==",
"dev": true,
"requires": {
- "@jest/types": "^25.5.0",
- "camelcase": "^5.3.1",
- "chalk": "^3.0.0",
- "jest-get-type": "^25.2.6",
+ "@jest/types": "^26.6.2",
+ "camelcase": "^6.0.0",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^26.3.0",
"leven": "^3.1.0",
- "pretty-format": "^25.5.0"
+ "pretty-format": "^26.6.2"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
+ "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==",
+ "dev": true
+ }
}
},
"jest-watcher": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-25.5.0.tgz",
- "integrity": "sha512-XrSfJnVASEl+5+bb51V0Q7WQx65dTSk7NL4yDdVjPnRNpM0hG+ncFmDYJo9O8jaSRcAitVbuVawyXCRoxGrT5Q==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz",
+ "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==",
"dev": true,
"requires": {
- "@jest/test-result": "^25.5.0",
- "@jest/types": "^25.5.0",
+ "@jest/test-result": "^26.6.2",
+ "@jest/types": "^26.6.2",
+ "@types/node": "*",
"ansi-escapes": "^4.2.1",
- "chalk": "^3.0.0",
- "jest-util": "^25.5.0",
- "string-length": "^3.1.0"
+ "chalk": "^4.0.0",
+ "jest-util": "^26.6.2",
+ "string-length": "^4.0.1"
}
},
"jest-worker": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz",
- "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
+ "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==",
"dev": true,
"requires": {
+ "@types/node": "*",
"merge-stream": "^2.0.0",
"supports-color": "^7.0.0"
}
@@ -3594,37 +3762,51 @@
"dev": true
},
"jsdom": {
- "version": "15.2.1",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz",
- "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==",
- "dev": true,
- "requires": {
- "abab": "^2.0.0",
- "acorn": "^7.1.0",
- "acorn-globals": "^4.3.2",
- "array-equal": "^1.0.0",
- "cssom": "^0.4.1",
- "cssstyle": "^2.0.0",
- "data-urls": "^1.1.0",
- "domexception": "^1.0.1",
- "escodegen": "^1.11.1",
- "html-encoding-sniffer": "^1.0.2",
+ "version": "16.6.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.6.0.tgz",
+ "integrity": "sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg==",
+ "dev": true,
+ "requires": {
+ "abab": "^2.0.5",
+ "acorn": "^8.2.4",
+ "acorn-globals": "^6.0.0",
+ "cssom": "^0.4.4",
+ "cssstyle": "^2.3.0",
+ "data-urls": "^2.0.0",
+ "decimal.js": "^10.2.1",
+ "domexception": "^2.0.1",
+ "escodegen": "^2.0.0",
+ "form-data": "^3.0.0",
+ "html-encoding-sniffer": "^2.0.1",
+ "http-proxy-agent": "^4.0.1",
+ "https-proxy-agent": "^5.0.0",
+ "is-potential-custom-element-name": "^1.0.1",
"nwsapi": "^2.2.0",
- "parse5": "5.1.0",
- "pn": "^1.1.0",
- "request": "^2.88.0",
- "request-promise-native": "^1.0.7",
- "saxes": "^3.1.9",
- "symbol-tree": "^3.2.2",
- "tough-cookie": "^3.0.1",
- "w3c-hr-time": "^1.0.1",
- "w3c-xmlserializer": "^1.1.2",
- "webidl-conversions": "^4.0.2",
+ "parse5": "6.0.1",
+ "saxes": "^5.0.1",
+ "symbol-tree": "^3.2.4",
+ "tough-cookie": "^4.0.0",
+ "w3c-hr-time": "^1.0.2",
+ "w3c-xmlserializer": "^2.0.0",
+ "webidl-conversions": "^6.1.0",
"whatwg-encoding": "^1.0.5",
"whatwg-mimetype": "^2.3.0",
- "whatwg-url": "^7.0.0",
- "ws": "^7.0.0",
+ "whatwg-url": "^8.5.0",
+ "ws": "^7.4.5",
"xml-name-validator": "^3.0.0"
+ },
+ "dependencies": {
+ "form-data": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
+ "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+ "dev": true,
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ }
+ }
}
},
"jsesc": {
@@ -3755,32 +3937,11 @@
}
},
"lodash": {
- "version": "4.17.20",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
- "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
- "dev": true
- },
- "lodash.memoize": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
- "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
- "lodash.sortby": {
- "version": "4.7.0",
- "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
- "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
- "dev": true
- },
- "lolex": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz",
- "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==",
- "dev": true,
- "requires": {
- "@sinonjs/commons": "^1.7.0"
- }
- },
"long": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
@@ -3824,12 +3985,6 @@
"semver": "^6.0.0"
}
},
- "make-error": {
- "version": "1.3.6",
- "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
- "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
- "dev": true
- },
"makeerror": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz",
@@ -3927,13 +4082,21 @@
"dev": true
},
"micromatch": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
- "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
+ "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
"dev": true,
"requires": {
"braces": "^3.0.1",
- "picomatch": "^2.0.5"
+ "picomatch": "^2.2.3"
+ },
+ "dependencies": {
+ "picomatch": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
+ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
+ "dev": true
+ }
}
},
"micromodal": {
@@ -3941,12 +4104,6 @@
"resolved": "https://registry.npmjs.org/micromodal/-/micromodal-0.4.6.tgz",
"integrity": "sha512-2VDso2a22jWPpqwuWT/4RomVpoU3Bl9qF9D01xzwlNp5UVsImeA0gY4nSpF44vqcQtQOtkiMUV9EZkAJSRxBsg=="
},
- "mime": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.0.tgz",
- "integrity": "sha512-ft3WayFSFUVBuJj7BMLKAQcSlItKtfjsKDDsii3rqFDAZ7t11zRe8ASw/GlmivGwVUYtwkQrxiGGpL6gFvB0ag==",
- "dev": true
- },
"mime-db": {
"version": "1.45.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz",
@@ -4061,6 +4218,12 @@
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
"dev": true
},
+ "node-fetch": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
+ "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
+ "dev": true
+ },
"node-gyp": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
@@ -4113,6 +4276,15 @@
"integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=",
"dev": true
},
+ "node-libpng": {
+ "version": "0.2.18",
+ "resolved": "https://registry.npmjs.org/node-libpng/-/node-libpng-0.2.18.tgz",
+ "integrity": "sha512-nr2j+Qn68ocw/0mfj09Yg8AEEdjrrQYMnFAWi8wLpwe2FMdLr36OFalIEkrJnwpqQxDybfqw7l1GH2wJ98wUIw==",
+ "dev": true,
+ "requires": {
+ "request": "^2.88.2"
+ }
+ },
"node-modules-regexp": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz",
@@ -4120,31 +4292,72 @@
"dev": true
},
"node-notifier": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-6.0.0.tgz",
- "integrity": "sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw==",
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz",
+ "integrity": "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==",
"dev": true,
"optional": true,
"requires": {
"growly": "^1.3.0",
- "is-wsl": "^2.1.1",
- "semver": "^6.3.0",
+ "is-wsl": "^2.2.0",
+ "semver": "^7.3.2",
"shellwords": "^0.1.1",
- "which": "^1.3.1"
+ "uuid": "^8.3.0",
+ "which": "^2.0.2"
},
"dependencies": {
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "dev": true,
+ "optional": true
+ },
"which": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
- "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"optional": true,
"requires": {
"isexe": "^2.0.0"
}
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true,
+ "optional": true
}
}
},
+ "node-releases": {
+ "version": "1.1.72",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz",
+ "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==",
+ "dev": true
+ },
"node-sass": {
"version": "4.14.1",
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz",
@@ -4500,9 +4713,9 @@
}
},
"parse5": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz",
- "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
"dev": true
},
"pascalcase": {
@@ -4530,9 +4743,9 @@
"dev": true
},
"path-parse": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
- "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
"path-type": {
@@ -4594,6 +4807,15 @@
"node-modules-regexp": "^1.0.0"
}
},
+ "pixelmatch": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.2.1.tgz",
+ "integrity": "sha512-WjcAdYSnKrrdDdqTcVEY7aB7UhhwjYQKYhHiBXdJef0MOaQeYpUdQ+iVyBLa5YBKS8MPVPPMX7rpOByISLpeEQ==",
+ "dev": true,
+ "requires": {
+ "pngjs": "^4.0.1"
+ }
+ },
"pkg-dir": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
@@ -4603,10 +4825,10 @@
"find-up": "^4.0.0"
}
},
- "pn": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
- "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
+ "pngjs": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-4.0.1.tgz",
+ "integrity": "sha512-rf5+2/ioHeQxR6IxuYNYGFytUyG3lma/WW1nsmjeHlWwtb2aByla6dkVc8pmJ9nplzkTA0q2xx7mMWrOTqT4Gg==",
"dev": true
},
"posix-character-classes": {
@@ -4622,15 +4844,15 @@
"dev": true
},
"pretty-format": {
- "version": "25.5.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz",
- "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==",
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz",
+ "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==",
"dev": true,
"requires": {
- "@jest/types": "^25.5.0",
+ "@jest/types": "^26.6.2",
"ansi-regex": "^5.0.0",
"ansi-styles": "^4.0.0",
- "react-is": "^16.12.0"
+ "react-is": "^17.0.1"
},
"dependencies": {
"ansi-regex": {
@@ -4648,15 +4870,15 @@
"dev": true
},
"progress": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
- "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz",
+ "integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==",
"dev": true
},
"prompts": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz",
- "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz",
+ "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==",
"dev": true,
"requires": {
"kleur": "^3.0.3",
@@ -4725,38 +4947,36 @@
"dev": true
},
"puppeteer": {
- "version": "1.20.0",
- "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.20.0.tgz",
- "integrity": "sha512-bt48RDBy2eIwZPrkgbcwHtb51mj2nKvHOPMaSH2IsWiv7lOG9k9zhaRzpDZafrk05ajMc3cu+lSQYYOfH2DkVQ==",
- "dev": true,
- "requires": {
- "debug": "^4.1.0",
- "extract-zip": "^1.6.6",
- "https-proxy-agent": "^2.2.1",
- "mime": "^2.0.3",
- "progress": "^2.0.1",
- "proxy-from-env": "^1.0.0",
- "rimraf": "^2.6.1",
- "ws": "^6.1.0"
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-10.0.0.tgz",
+ "integrity": "sha512-AxHvCb9IWmmP3gMW+epxdj92Gglii+6Z4sb+W+zc2hTTu10HF0yg6hGXot5O74uYkVqG3lfDRLfnRpi6WOwi5A==",
+ "dev": true,
+ "requires": {
+ "debug": "4.3.1",
+ "devtools-protocol": "0.0.883894",
+ "extract-zip": "2.0.1",
+ "https-proxy-agent": "5.0.0",
+ "node-fetch": "2.6.1",
+ "pkg-dir": "4.2.0",
+ "progress": "2.0.1",
+ "proxy-from-env": "1.1.0",
+ "rimraf": "3.0.2",
+ "tar-fs": "2.0.0",
+ "unbzip2-stream": "1.3.3",
+ "ws": "7.4.6"
},
"dependencies": {
- "rimraf": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
- "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
- "dev": true,
- "requires": {
- "glob": "^7.1.3"
- }
+ "devtools-protocol": {
+ "version": "0.0.883894",
+ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.883894.tgz",
+ "integrity": "sha512-33idhm54QJzf3Q7QofMgCvIVSd2o9H3kQPWaKT/fhoZh+digc+WSiMhbkeG3iN79WY4Hwr9G05NpbhEVrsOYAg==",
+ "dev": true
},
"ws": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
- "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
- "dev": true,
- "requires": {
- "async-limiter": "~1.0.0"
- }
+ "version": "7.4.6",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
+ "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
+ "dev": true
}
}
},
@@ -4767,9 +4987,9 @@
"dev": true
},
"react-is": {
- "version": "16.13.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
"dev": true
},
"read-pkg": {
@@ -4826,12 +5046,6 @@
}
}
},
- "realpath-native": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz",
- "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==",
- "dev": true
- },
"redent": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
@@ -4859,9 +5073,9 @@
"dev": true
},
"repeat-element": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
- "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz",
+ "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==",
"dev": true
},
"repeat-string": {
@@ -4919,38 +5133,6 @@
}
}
},
- "request-promise-core": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
- "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
- "dev": true,
- "requires": {
- "lodash": "^4.17.19"
- }
- },
- "request-promise-native": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz",
- "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==",
- "dev": true,
- "requires": {
- "request-promise-core": "1.1.4",
- "stealthy-require": "^1.1.1",
- "tough-cookie": "^2.3.3"
- },
- "dependencies": {
- "tough-cookie": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
- "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
- "dev": true,
- "requires": {
- "psl": "^1.1.28",
- "punycode": "^2.1.1"
- }
- }
- }
- },
"require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -5400,12 +5582,12 @@
}
},
"saxes": {
- "version": "3.1.11",
- "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz",
- "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==",
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
+ "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==",
"dev": true,
"requires": {
- "xmlchars": "^2.1.1"
+ "xmlchars": "^2.2.0"
}
},
"scss-tokenizer": {
@@ -5738,9 +5920,9 @@
}
},
"stack-utils": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.4.tgz",
- "integrity": "sha512-IPDJfugEGbfizBwBZRZ3xpccMdRyP5lqsBWXGQWimVjua/ccLCeMOAVjlc1R7LxFjo5sEDhyNIXd8mo/AiDS9w==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz",
+ "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==",
"dev": true,
"requires": {
"escape-string-regexp": "^2.0.0"
@@ -5784,54 +5966,20 @@
"readable-stream": "^2.0.1"
}
},
- "stealthy-require": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
- "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
- "dev": true
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- },
- "dependencies": {
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- }
- }
- },
"string-length": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz",
- "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
+ "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
"dev": true,
"requires": {
- "astral-regex": "^1.0.0",
- "strip-ansi": "^5.2.0"
- },
- "dependencies": {
- "strip-ansi": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
- "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
- "dev": true,
- "requires": {
- "ansi-regex": "^4.1.0"
- }
- }
+ "char-regex": "^1.0.2",
+ "strip-ansi": "^6.0.0"
}
},
"string-width": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
- "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
+ "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
"dev": true,
"requires": {
"emoji-regex": "^8.0.0",
@@ -5857,6 +6005,23 @@
"define-properties": "^1.1.3"
}
},
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ }
+ }
+ },
"strip-ansi": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
@@ -5911,9 +6076,9 @@
}
},
"supports-hyperlinks": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz",
- "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz",
+ "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==",
"dev": true,
"requires": {
"has-flag": "^4.0.0",
@@ -5937,6 +6102,44 @@
"inherits": "2"
}
},
+ "tar-fs": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz",
+ "integrity": "sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==",
+ "dev": true,
+ "requires": {
+ "chownr": "^1.1.1",
+ "mkdirp": "^0.5.1",
+ "pump": "^3.0.0",
+ "tar-stream": "^2.0.0"
+ }
+ },
+ "tar-stream": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
+ "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+ "dev": true,
+ "requires": {
+ "bl": "^4.0.3",
+ "end-of-stream": "^1.4.1",
+ "fs-constants": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.1.1"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
+ }
+ },
"terminal-link": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
@@ -5964,6 +6167,12 @@
"integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==",
"dev": true
},
+ "through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+ "dev": true
+ },
"tmpl": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz",
@@ -6018,23 +6227,23 @@
}
},
"tough-cookie": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
- "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
+ "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==",
"dev": true,
"requires": {
- "ip-regex": "^2.1.0",
- "psl": "^1.1.28",
- "punycode": "^2.1.1"
+ "psl": "^1.1.33",
+ "punycode": "^2.1.1",
+ "universalify": "^0.1.2"
}
},
"tr46": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
- "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz",
+ "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==",
"dev": true,
"requires": {
- "punycode": "^2.1.0"
+ "punycode": "^2.1.1"
}
},
"trim-newlines": {
@@ -6052,28 +6261,10 @@
"glob": "^7.1.2"
}
},
- "ts-jest": {
- "version": "25.5.1",
- "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-25.5.1.tgz",
- "integrity": "sha512-kHEUlZMK8fn8vkxDjwbHlxXRB9dHYpyzqKIGDNxbzs+Rz+ssNDSDNusEK8Fk/sDd4xE6iKoQLfFkFVaskmTJyw==",
- "dev": true,
- "requires": {
- "bs-logger": "0.x",
- "buffer-from": "1.x",
- "fast-json-stable-stringify": "2.x",
- "json5": "2.x",
- "lodash.memoize": "4.x",
- "make-error": "1.x",
- "micromatch": "4.x",
- "mkdirp": "0.x",
- "semver": "6.x",
- "yargs-parser": "18.x"
- }
- },
"tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz",
+ "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==",
"dev": true
},
"tslint": {
@@ -6158,6 +6349,12 @@
"requires": {
"has-flag": "^3.0.0"
}
+ },
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
}
}
},
@@ -6168,6 +6365,14 @@
"dev": true,
"requires": {
"tslib": "^1.8.1"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ }
}
},
"tunnel-agent": {
@@ -6206,12 +6411,6 @@
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"dev": true
},
- "typedarray": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
- "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
- "dev": true
- },
"typedarray-to-buffer": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
@@ -6222,11 +6421,21 @@
}
},
"typescript": {
- "version": "3.9.7",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz",
- "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==",
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz",
+ "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==",
"dev": true
},
+ "unbzip2-stream": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz",
+ "integrity": "sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.2.1",
+ "through": "^2.3.8"
+ }
+ },
"union-value": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
@@ -6239,6 +6448,12 @@
"set-value": "^2.0.1"
}
},
+ "universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+ "dev": true
+ },
"unset-value": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
@@ -6325,9 +6540,9 @@
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
},
"v8-to-istanbul": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz",
- "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==",
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz",
+ "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.1",
@@ -6380,13 +6595,11 @@
}
},
"w3c-xmlserializer": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz",
- "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz",
+ "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==",
"dev": true,
"requires": {
- "domexception": "^1.0.1",
- "webidl-conversions": "^4.0.2",
"xml-name-validator": "^3.0.0"
}
},
@@ -6400,9 +6613,9 @@
}
},
"webidl-conversions": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
- "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
+ "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==",
"dev": true
},
"whatwg-encoding": {
@@ -6421,20 +6634,20 @@
"dev": true
},
"whatwg-url": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
- "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.5.0.tgz",
+ "integrity": "sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg==",
"dev": true,
"requires": {
- "lodash.sortby": "^4.7.0",
- "tr46": "^1.0.1",
- "webidl-conversions": "^4.0.2"
+ "lodash": "^4.7.0",
+ "tr46": "^2.0.2",
+ "webidl-conversions": "^6.1.0"
}
},
"which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
"dev": true,
"requires": {
"isexe": "^2.0.0"
@@ -6538,9 +6751,9 @@
}
},
"ws": {
- "version": "7.4.3",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.3.tgz",
- "integrity": "sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA==",
+ "version": "7.4.6",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
+ "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
"dev": true
},
"xml-name-validator": {
diff --git a/ui/package.json b/ui/package.json
index 4a2cadfca..0f14f33b1 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -20,7 +20,7 @@
"devtools-protocol": "0.0.847576",
"events": "^3.1.0",
"hsluv": "^0.1.0",
- "immer": "^1.12.1",
+ "immer": "^9.0.2",
"micromodal": "^0.4.6",
"mithril": "^2.0.4",
"noice-json-rpc": "^1.2.0",
@@ -32,23 +32,25 @@
"devDependencies": {
"@rollup/plugin-commonjs": "^14.0.0",
"@rollup/plugin-node-resolve": "^8.4.0",
- "@types/jest": "^22.2.3",
- "@types/puppeteer": "^1.20.6",
+ "@types/jest": "^26.0.23",
+ "@types/pixelmatch": "^5.2.3",
+ "@types/puppeteer": "^5.4.3",
"dingusjs": "^0.0.3",
- "jest": "^25.5.4",
+ "jest": "^26.6.3",
+ "node-libpng": "^0.2.18",
"node-sass": "^4.14.1",
"node-watch": "^0.7.1",
- "puppeteer": "^1.20.0",
+ "pixelmatch": "^5.2.1",
+ "puppeteer": "^10.0.0",
"rollup": "^2.38.5",
"rollup-plugin-re": "^1.0.7",
"rollup-plugin-sourcemaps": "^0.6.3",
- "ts-jest": "^25.5.1",
- "tslib": "^1.13.0",
+ "tslib": "^2.2.0",
"tslint": "^5.20.1",
- "typescript": "^3.9.3"
+ "typescript": "^4.2.4"
},
"scripts": {
"build": "node build.js",
- "test": "node build.js --run-tests"
+ "test": "node build.js --run-unittests"
}
}
diff --git a/ui/release/OWNERS b/ui/release/OWNERS
index fe8fd0485..9d27999f5 100644
--- a/ui/release/OWNERS
+++ b/ui/release/OWNERS
@@ -1,7 +1,7 @@
set noparent
eseckler@google.com
hjd@google.com
-oysteine@google.com
-nyquist@google.com
+lalitm@google.com
+octaviant@google.com
primiano@google.com
skyostil@google.com
diff --git a/ui/release/channels.json b/ui/release/channels.json
index ffb232fdc..362b27977 100644
--- a/ui/release/channels.json
+++ b/ui/release/channels.json
@@ -2,11 +2,11 @@
"channels": [
{
"name": "stable",
- "rev": "465b9a4473353091c7048b53ad90607295f86a4a"
+ "rev": "d1f7cc5758b10aa536178aaccc01ea8b90d42b58"
},
{
"name": "canary",
- "rev": "a284e65f883e7c543c2619115be1ee0fbe5644a3"
+ "rev": "ff45349b21ea7dbae1731464e0efd96458468817"
},
{
"name": "autopush",
@@ -14,3 +14,4 @@
}
]
}
+
diff --git a/ui/run-all-tests b/ui/run-all-tests
new file mode 100755
index 000000000..7974fa1d4
--- /dev/null
+++ b/ui/run-all-tests
@@ -0,0 +1,20 @@
+#!/bin/bash
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+UI_DIR="$(cd -P ${BASH_SOURCE[0]%/*}; pwd)"
+
+$UI_DIR/node $UI_DIR/build.js "$@" # Build just once.
+$UI_DIR/node $UI_DIR/build.js --no-build --run-unittests "$@"
+$UI_DIR/node $UI_DIR/build.js --no-build --run-integrationtests "$@"
diff --git a/ui/run-integrationtests b/ui/run-integrationtests
new file mode 100755
index 000000000..abcbf4ace
--- /dev/null
+++ b/ui/run-integrationtests
@@ -0,0 +1,18 @@
+#!/bin/bash
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+UI_DIR="$(cd -P ${BASH_SOURCE[0]%/*}; pwd)"
+
+$UI_DIR/node $UI_DIR/build.js --run-integrationtests "$@"
diff --git a/ui/run-tests b/ui/run-tests
deleted file mode 100755
index d06f7d2fa..000000000
--- a/ui/run-tests
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/bash
-# Copyright (C) 2021 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-UI_DIR="$(cd -P ${BASH_SOURCE[0]%/*}; pwd)"
-
-$UI_DIR/node $UI_DIR/build.js --run-tests "$@"
diff --git a/ui/run-unittests b/ui/run-unittests
new file mode 100755
index 000000000..7ebdf42a3
--- /dev/null
+++ b/ui/run-unittests
@@ -0,0 +1,18 @@
+#!/bin/bash
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+UI_DIR="$(cd -P ${BASH_SOURCE[0]%/*}; pwd)"
+
+$UI_DIR/node $UI_DIR/build.js --run-unittests "$@"
diff --git a/ui/src/assets/common.scss b/ui/src/assets/common.scss
index 032489916..46f9db40b 100644
--- a/ui/src/assets/common.scss
+++ b/ui/src/assets/common.scss
@@ -70,7 +70,7 @@
* {
box-sizing: border-box;
- -webkit-tap-highlight-color: none;
+ -webkit-tap-highlight-color: transparent;
touch-action: none;
}
@@ -87,10 +87,20 @@ body>main {
width: 100%;
padding: 0;
margin: 0;
- user-select: none;
overscroll-behavior: none;
}
+pre, code {
+ font-family: var(--monospace-font);
+}
+
+// This is to minimize Mac vs Linux Chrome Headless rendering differences
+// when running UI intergrationtests via puppeteer.
+body.testing {
+ -webkit-font-smoothing: antialiased !important;
+ font-kerning: none !important;
+}
+
h1,
h2,
h3 {
@@ -148,17 +158,13 @@ button.close {
.full-page-loading-screen {
position: absolute;
- background: #3e4a5a;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
- background-image: url('assets/logo-3d.png');
- background-attachment: fixed;
- background-repeat: no-repeat;
- background-position: center;
+ background: #3e4a5a url('assets/logo-3d.png') no-repeat fixed center;
}
.page {
@@ -177,40 +183,7 @@ button.close {
overflow: hidden;
}
-.video-panel {
- position: relative;
- background-color: #262f3c;
-}
-
-.video-panel-setting {
- position: sticky;
- word-wrap: break-word;
- font-weight: 400;
- font-size: 15px;
- font-family: 'Raleway', sans-serif;
- line-height: 1.5;
- padding: 10px 10px 0px 10px;
- width: 320px;
- color: #fff
-}
-
-.video-panel-message {
- position: sticky;
- word-wrap: break-word;
- font-weight: 400;
- font-size: 12px;
- font-family: 'Raleway', sans-serif;
- line-height: 1.5;
- padding: 10px 10px 10px 10px;
- width: 320px;
- border-bottom: 1px solid #404854;
- color: #b4b7ba;
-}
-
.alerts {
- * {
- user-select: text;
- }
grid-area: alerts;
background-color: #f2f2f2;
>div {
@@ -230,15 +203,76 @@ button.close {
.query-table-container {
width: 100%;
- overflow-x: auto;
}
.query-table {
width: 100%;
- border-collapse: collapse;
font-size: 14px;
border: 0;
+ &.pivot-table{
+ thead, i {
+ cursor: pointer;
+ td.drop-location {
+ background-color: hsla(210, 38%, 95%, 1);
+ }
+ .total-aggregation {
+ white-space: pre;
+ font-weight: 600;
+ font-size: 12px
+ }
+ }
+ td {
+ height: 25px;
+ }
+ .disabled {
+ cursor: default;
+ }
+ .dropdown {
+ display: inline-block;
+ position: relative;
+ }
+ .indent {
+ display: inline-block;
+ // 24px is the width of expand_more/expand_less icon to pad out cells
+ // without the button
+ width: 24px;
+ }
+ .popup-menu {
+ position: absolute;
+ background-color: white;
+ right: 0;
+ box-shadow: 0 0 4px 0 #999;
+
+ &.closed {
+ display: none;
+ }
+
+ &.open {
+ display: block;
+ }
+
+ button {
+ border-radius: 0;
+ margin: 0;
+ height: auto;
+ background: transparent;
+ color: #111;
+ font-size: 12px;
+ padding: 0.4em 1em;
+ white-space: nowrap;
+ width: 100%;
+ text-align: right;
+ line-height: 1;
+
+ &:hover {
+ background: #c7d0db;
+ }
+ }
+ }
+ }
thead td {
+ position: sticky;
+ top: 0;
background-color: hsl(214, 22%, 90%);
color: #262f3c;
text-align: center;
@@ -318,6 +352,14 @@ button.close {
background-color: #ebeef9;
}
+ .chip {
+ background-color: #bed6ff;
+ border-radius: 3px;
+ font-size: smaller;
+ padding: 0 0.1rem;
+ margin-left: 1ch;
+ }
+
h1 {
grid-area: title;
color: hsl(213, 22%, 30%);
@@ -405,6 +447,7 @@ canvas.main-canvas {
.panels {
grid-area: space;
+ user-select: none;
}
.panel {
@@ -434,6 +477,10 @@ canvas.main-canvas {
height: 20px;
}
+.x-scrollable {
+ overflow-x: auto;
+}
+
header.overview {
display: flex;
align-content: center;
@@ -454,15 +501,10 @@ header.overview {
color: hsl(213, 22%, 40%);
}
span.code {
- user-select: text;
flex-grow: 1;
}
}
-.query-error {
- user-select: text;
-}
-
button.query-ctrl {
background: #262f3c;
color: white;
@@ -476,7 +518,7 @@ button.query-ctrl {
.debug-panel-border {
position: absolute;
- top: 0px;
+ top: 0;
height: 100%;
width: 100%;
border: 1px solid rgba(69, 187, 73, 0.5);
@@ -490,7 +532,7 @@ button.query-ctrl {
left: 0;
width: 600px;
color: var(--stroke-color);
- font-family: monospace;
+ font-family: var(--monospace-font);
padding: 10px 24px;
z-index: 100;
background-color: rgba(27, 28, 29, 0.90);
@@ -514,13 +556,13 @@ button.query-ctrl {
border-bottom: 1px solid var(--stroke-color);
}
div {
- margin: 2px 0px;
+ margin: 2px 0;
}
table, td, th {
border: 1px solid var(--stroke-color);
text-align: center;
padding: 4px;
- margin: 4px 0px;
+ margin: 4px 0;
}
table {
border-collapse: collapse;
@@ -564,6 +606,9 @@ button.query-ctrl {
.track-button {
color: white;
}
+ span.chip {
+ color: #121212;
+ }
}
.shell {
padding: 4px 4px;
@@ -573,7 +618,21 @@ button.query-ctrl {
align-items: center;
line-height: 1;
width: var(--track-shell-width);
+ min-height: 40px;
transition: background-color .4s;
+
+ .track-title {
+ user-select: text;
+ }
+
+ .chip {
+ background-color: #bed6ff;
+ border-radius: 3px;
+ font-size: smaller;
+ padding: 0 0.1rem;
+ margin-left: 1ch;
+ }
+
h1 {
grid-area: title;
@include track_shell_title();
@@ -597,6 +656,13 @@ button.query-ctrl {
background-color: #ebeef9;
}
}
+ .track-content {
+ display: grid;
+ span {
+ @include track_shell_title();
+ align-self: center;
+ }
+ }
}
.time-selection-panel {
@@ -642,3 +708,143 @@ button.query-ctrl {
.disallow-selection {
user-select: none;
}
+
+.pivot-table-redux {
+ user-select: text;
+
+ button.mode-button {
+ border-radius: 10px;
+ padding: 7px;
+ margin: 5px;
+ background-color: #c7d0db;
+ }
+
+ &.edit {
+ padding: 10px;
+ display: flex;
+ }
+
+ &.query-error {
+ color: red;
+ }
+
+ .total-values {
+ text-align: right;
+ padding-right: 10px;
+ }
+
+ .empty-result {
+ padding: 10px;
+ }
+}
+
+.pivot-table-editor-container {
+ font: inherit;
+ width: 670px;
+ height: 420px;
+ h2 {
+ font-weight: bold;
+ text-align: left;
+ }
+ label {
+ cursor: pointer;
+ }
+ select {
+ font-weight: 100;
+ margin: 3px;
+ color: #333;
+ font-size: 15px;
+ align-items: center;
+ cursor: pointer;
+ }
+ span:nth-of-type(2) {
+ margin-left: 1rem;
+ }
+ section.table-group {
+ display: table-row;
+ table {
+ margin: 15px;
+ td {
+ width: 300px;
+ font-size: 17px;
+ cursor: pointer;
+ &.drop-location {
+ background-color: hsla(0, 0%, 85%, 1);
+ }
+ }
+ th {
+ text-align: center;
+ width: 300px;
+ border-bottom: 1px solid rgba(60, 76, 92, 0.4);
+ }
+ &:first-child {
+ float: left;
+ }
+ &:last-child {
+ float: right;
+ }
+ }
+ }
+ .scroll {
+ height: 150px;
+ overflow: auto;
+ }
+ section.button-group {
+ text-align: center;
+ button {
+ background-color: #262f3c;
+ color: #fff;
+ border-radius: 10px;
+ padding: 2px 5px;
+ font-weight: bold;
+ font-size: 13px;
+ min-width: 7em;
+ margin-right: 1rem;
+ }
+ }
+ section {
+ margin: 1rem;
+ }
+}
+
+.pivot-table-tab {
+ button {
+ background: #262f3c;
+ color: white;
+ border-radius: 10px;
+ font-size: 12px;
+ height: 20px;
+ line-height: 18px;
+ min-width: 7em;
+ margin: 0.2rem;
+ &:disabled {
+ opacity: 0.75;
+ cursor: default;
+ }
+ }
+ span {
+ flex-grow: 1;
+ }
+}
+
+.pivot-table-spinner {
+ display: inline-block;
+ vertical-align: middle;
+ box-sizing: border-box;
+ width: 18px;
+ height: 18px;
+ margin-left: 10px;
+ border-radius: 50%;
+ border: 2px solid #408ee0;
+ border-color: #408ee0 transparent;
+ animation: spinner 1.25s linear infinite;
+ @keyframes spinner {
+ 0% { transform: rotate(0deg); }
+ 100% { transform: rotate(360deg); }
+ }
+}
+
+.allow-white-space {
+ white-space: pre
+}
+
diff --git a/ui/src/assets/details.scss b/ui/src/assets/details.scss
index 85206d039..a6ff835d6 100644
--- a/ui/src/assets/details.scss
+++ b/ui/src/assets/details.scss
@@ -21,6 +21,9 @@
border: 1px solid rgba(0,0,0,0.1);
border-bottom: none;
cursor: row-resize;
+ // Disable user selection since this handle is draggable to resize the
+ // bottom panels.
+ user-select: none;
height: 28px;
min-height: 28px;
display: grid;
@@ -35,10 +38,10 @@
.tab {
font-family: 'Roboto Condensed', sans-serif;
color: #3c4b5d;
- padding: 3px 10px 0px 10px;
+ padding: 3px 10px 0 10px;
margin-top: 3px;
font-size: 13px;
- border-radius: 5px 5px 0px 0px;
+ border-radius: 5px 5px 0 0;
background-color: hsla(0, 0%, 75%, 1);
border-top: solid 1px hsla(0, 0%, 75%, 1);
border-left: solid 1px hsla(0, 0%, 75%, 1);
@@ -98,7 +101,6 @@
font-family: 'Roboto Condensed', sans-serif;
font-weight: 300;
color: #3c4b5d;
- user-select: text;
.material-icons {
@include transition(0.3s);
@@ -120,7 +122,7 @@
.details-panel-heading {
padding: 10px 0 5px 0;
position: sticky;
- top: 0px;
+ top: 0;
display: flex;
background: white;
&.aggregation {
@@ -171,12 +173,12 @@
width: 50%;
}
}
- &.heap-profile {
+ &.flamegraph-profile {
display: flex;
justify-content: space-between;
align-content: center;
height: 30px;
- padding: 0px;
+ padding: 0;
font-size: 12px;
* {
align-self: center;
@@ -193,7 +195,7 @@
width: fit-content;
height: 20px;
padding: 3px;
- padding-top: 0px;
+ padding-top: 0;
margin: 2px;
font-size: 12px;
opacity: 0.5;
@@ -220,6 +222,14 @@
justify-self: end;
margin-right: 10px;
}
+ .selected {
+ justify-self: end;
+ margin-right: 10px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ width: 200px;
+ }
}
}
@@ -228,21 +238,41 @@
font-size: 14px;
line-height: 18px;
width: 100%;
+ // Aggregation panel uses multiple table elements that need to be aligned,
+ // which is done by using fixed table layout.
+ table-layout: fixed;
word-wrap: break-word;
- padding: 0px 10px;
+ padding: 0 10px;
tr:hover {
- background-color: hsl(214, 22%, 90%);
+ td, th {
+ background-color: hsl(214, 22%, 90%);
+
+ &.no-highlight {
+ background-color: white;
+ }
+ }
}
th {
text-align: left;
width: 30%;
font-weight: normal;
+ vertical-align: top;
+ }
+ td.value {
+ white-space: pre-wrap;
+ }
+ td.padding {
+ min-width: 10px;
}
.array-index {
text-align: right;
}
}
+ .auto-layout {
+ table-layout: auto;
+ }
+
button {
background-color: #262f3c;
color: #fff;
@@ -370,7 +400,7 @@ table.half-width {
header {
position: sticky;
- top: 0px;
+ top: 0;
z-index: 1;
background-color: white;
color: #3c4b5d;
diff --git a/ui/src/assets/flags_page.scss b/ui/src/assets/flags_page.scss
new file mode 100644
index 000000000..3750dbd5f
--- /dev/null
+++ b/ui/src/assets/flags_page.scss
@@ -0,0 +1,73 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+.flags-page {
+ overflow-y: scroll;
+}
+
+.flags-content {
+ max-width: 90ch;
+ width: 60%;
+ margin: 0 auto;
+ padding: 3rem;
+ display: grid;
+ grid-row-gap: 1rem;
+
+ h1 {
+ font-size: larger;
+ }
+
+ button {
+ background: none;
+ border: 1px solid rgb(218, 220, 224);
+ border-radius: 3px;
+ color: rgb(25, 103, 210);
+ font-size: .8125rem;
+ padding: 8px 12px;
+ cursor: pointer;
+ font-weight: 500;
+ }
+}
+
+.flag-widget {
+ display: grid;
+ grid-template:
+ "title control" auto
+ "description control" auto / 1fr auto;
+
+ row-gap: 0.5rem;
+ align-content: center;
+
+ select {
+ grid-area: control;
+ background: white;
+ border: 1px solid rgb(25, 103, 210);
+ color: rgb(25, 103, 210);
+ font-size: .8125rem;
+ height: 1.625rem;
+ letter-spacing: .01em;
+ max-width: 150px;
+ text-align-last: center;
+ width: 100%;
+ }
+
+ label {
+ font-weight: bold;
+ }
+
+ .description {
+ font-size: smaller;
+ }
+}
+
diff --git a/ui/src/assets/home_page.scss b/ui/src/assets/home_page.scss
index 8eed245a2..f76137c35 100644
--- a/ui/src/assets/home_page.scss
+++ b/ui/src/assets/home_page.scss
@@ -86,7 +86,8 @@
z-index: 2;
text-transform: uppercase;
font-size: 16px;
- font-weight: 200;
+ font-family: 'Raleway';
+ font-weight: 400;
letter-spacing: 0.3px;
}
@@ -108,7 +109,7 @@
opacity: 0;
color: #da4534;
font-weight: 400;
- @include transition;
+ @include transition();
&.show { opacity: 1; }
}
} // .channel-select
diff --git a/ui/src/assets/index.html b/ui/src/assets/index.html
index 2e9329f2f..817945f96 100644
--- a/ui/src/assets/index.html
+++ b/ui/src/assets/index.html
@@ -13,9 +13,10 @@
error reporting.
-->
<style>
- #app_load_failure {opacity:0;transition:opacity 1s ease;position:absolute;background:#080082;top:0;left:0;width:100%;height:100%;bottom:0;right:0;margin:0;opacity:0;user-select:text}
- #app_load_failure > pre {color:#fff;position:absolute;margin:auto;white-space:pre-wrap;top:50%;transform:translate(0,-50%);max-width:90vw;width:880px;left:0;right:0;font-size:16px;line-height:30px;font-weight:700}
+ #app_load_failure {opacity:0;transition:opacity 1s ease;position:absolute;overflow:auto;background:#080082;top:0;left:0;width:100%;height:100%;bottom:0;right:0;margin:0;opacity:0;user-select:text}
+ #app_load_failure > pre {color:#fff;position:absolute;margin:auto;white-space:pre-wrap;top:10vh;max-width:90vw;width:880px;left:0;right:0;font-size:16px;line-height:30px;font-weight:700}
#app_load_failure > pre span {background:#fff;color:#080082;padding:2px}
+ #app_load_failure_dbg { overflow-wrap: break-word; font-size: 12px; line-height: 1; font-weight: initial;}
#app_load_failure a {color:#fff}
#app_load { position: absolute; top: 0; left: 0; right:0; bottom: 0; background-color: #2c3e50;}
#app_load_spinner { margin: 30vh auto; width: 150px; height: 150px; border: 3px solid rgba(255,255,255,.3); border-radius: 50%; border-top-color: #fff; animation: app_load_spin 1s ease-in-out infinite; }
diff --git a/ui/src/assets/metrics_page.scss b/ui/src/assets/metrics_page.scss
index 4881d46be..e9ccf583b 100644
--- a/ui/src/assets/metrics_page.scss
+++ b/ui/src/assets/metrics_page.scss
@@ -40,7 +40,6 @@
font-family: 'Roboto Mono';
line-height: 1.5em;
border-radius: 5px;
- user-select: text;
overflow-x: auto;
&.metric-error {
color: #EF6C00;
diff --git a/ui/src/assets/modal.scss b/ui/src/assets/modal.scss
index 0f54b002d..20a80a8ab 100644
--- a/ui/src/assets/modal.scss
+++ b/ui/src/assets/modal.scss
@@ -94,15 +94,11 @@
-moz-osx-font-smoothing: grayscale;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
- -webkit-transform: translateZ(0);
transform: translateZ(0);
- transition: -webkit-transform .25s ease-out;
transition: transform .25s ease-out;
- transition: transform .25s ease-out,-webkit-transform .25s ease-out;
}
.modal-btn:focus, .modal-btn:hover {
- -webkit-transform: scale(1.05);
transform: scale(1.05);
}
@@ -151,7 +147,8 @@
animation: mmfadeIn .3s cubic-bezier(0.0, 0.0, 0.2, 1);
}
-.micromodal-slide[aria-hidden="false"] .modal-container {
+.micromodal-slide[aria-hidden="false"] .modal-container,
+.micromodal-slide[aria-hidden="false"] .partial-modal-container {
animation: mmslideIn .3s cubic-bezier(0, 0, .2, 1);
}
@@ -159,11 +156,13 @@
animation: mmfadeOut .3s cubic-bezier(0.0, 0.0, 0.2, 1);
}
-.micromodal-slide[aria-hidden="true"] .modal-container {
+.micromodal-slide[aria-hidden="true"] .modal-container,
+.micromodal-slide[aria-hidden="true"] .partial-modal-container {
animation: mmslideOut .3s cubic-bezier(0, 0, .2, 1);
}
.micromodal-slide .modal-container,
+.micromodal-slide .partial-modal-container,
.micromodal-slide .modal-overlay {
will-change: transform;
}
@@ -187,7 +186,6 @@
.modal-pre {
white-space: pre-line;
font-size: 13px;
- user-select: text;
}
.modal-logs, .modal-bash {
@@ -195,8 +193,7 @@
border: 1px solid #999;
background: #eee;
font-size: 10px;
- font-family: monospace;
- -webkit-user-select: text;
+ font-family: var(--monospace-font);
margin-top: 10px;
margin-bottom: 10px;
min-height: 50px;
@@ -221,3 +218,32 @@
.modal-small {
font-size: 11px;
}
+
+.partial-modal-overlay {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: rgba(0,0,0,0.6);
+ display: flex;
+ justify-content: center;
+ z-index: 999;
+}
+
+.partial-modal-container {
+ background-color: #fff;
+ margin-top: 1vh;
+ padding: 30px 30px 20px 30px;
+ max-width: 90vw;
+ height: fit-content;
+ border-radius: 4px;
+ overflow-y: auto;
+ box-sizing: border-box;
+}
+
+.partial-modal-header {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
diff --git a/ui/src/assets/perfetto.scss b/ui/src/assets/perfetto.scss
index d3cc23a10..24ae99af8 100644
--- a/ui/src/assets/perfetto.scss
+++ b/ui/src/assets/perfetto.scss
@@ -23,3 +23,4 @@
@import 'modal';
@import 'details';
@import 'trace_info_page';
+@import 'flags_page';
diff --git a/ui/src/assets/record.scss b/ui/src/assets/record.scss
index 6b0a762aa..9a14090bd 100644
--- a/ui/src/assets/record.scss
+++ b/ui/src/assets/record.scss
@@ -90,12 +90,12 @@
&:hover {
background-color: hsl(88, 50%, 84%);
- box-shadow: 0 0 4px 0px #999;
+ box-shadow: 0 0 4px 0 #999;
}
&.selected {
background-color: hsl(88, 50%, 67%);
- box-shadow: 0 0 4px 0px #999;
+ box-shadow: 0 0 4px 0 #999;
}
&.disabled {
@@ -116,7 +116,7 @@
}
label, select, button {
- font-weight: 100;
+ font-weight: 300;
margin: 3px;
color: #333;
font-size: 17px;
@@ -140,7 +140,7 @@
padding: 4px;
height: 30px;
&:hover, &:active {
- box-shadow: 0 0 4px 0px #ccc;
+ box-shadow: 0 0 4px 0 #ccc;
background-color: #fafafa;
}
i {
@@ -201,7 +201,6 @@
li {
@include transition();
- display: block;
height: 55px;
padding: 0 1em;
font-size: 15px;
@@ -291,11 +290,17 @@
height: auto;
width: 100%;
- padding: 0px;
+ padding: 0;
display: flex;
align-items: center;
}
+ .parsing-errors {
+ padding: 1em;
+ border: 1px solid #dc143c;
+ color: #dc143c;
+ }
+
.title-config {
display: inline-block;
margin: var(--record-section-padding);
@@ -304,19 +309,23 @@
}
.config-button {
- border-radius: 10px;
+ border-radius: 100%;
margin-right: 10px;
text-align: center;
justify-items: center;
font-family: 'Raleway', sans-serif;
padding: 7px;
- width: 75px;
- &:hover {
- box-shadow: 0 0 4px 0px #999;
+ &:hover:enabled {
+ box-shadow: 0 0 3px 0 #aaa;
+ }
+
+ &:not(:enabled) {
+ background-color: hsl(0, 0%, 83%);
+ color: hsl(0, 0%, 50%);
}
- &.load {
+ &.load:enabled {
background-color: hsl(88, 50%, 67%);
}
@@ -325,9 +334,23 @@
}
&.save {
- width: 160px;
- background-color: hsl(197, 50%, 67%);
+ &.long {
+ width: 160px;
+ }
+
+ &:enabled {
+ background-color: hsl(197, 50%, 67%);
+ }
}
+
+ &.reset {
+ width: 300px;
+ background-color: hsl(0, 50%, 67%);
+ }
+ }
+
+ .reset-wrapper {
+ padding: 1em;
}
.input-config {
@@ -335,11 +358,11 @@
margin-bottom: 20px;
display: flex;
align-items: center;
- padding: 0px;
+ padding: 0;
input {
border-radius: 20px;
- border-color: #0000003d;
+ border: 1px solid #eee;
line-height: 36px;
padding: 0 10px;
font-size: 18px;
@@ -395,6 +418,11 @@
padding-top: var(--record-section-padding);
padding-bottom: var(--record-section-padding);
+ &.compact {
+ padding-top: 10px;
+ padding-bottom: 10px;
+ }
+
&:nth-of-type(2n) {
background-color: #f9f9f9;
}
@@ -456,7 +484,7 @@
height: 26px;
border-radius: 100px;
background: #f5f5f5;
- box-shadow: 0px 3px 3px rgba(0,0,0,0.15);
+ box-shadow: 0 3px 3px rgba(0,0,0,0.15);
content: '';
transition: all 0.3s ease;
}
@@ -554,7 +582,7 @@
height: 20px;
border-radius: 100px;
background: #f5f5f5;
- box-shadow: 0px 3px 3px rgba(0,0,0,0.15);
+ box-shadow: 0 3px 3px rgba(0,0,0,0.15);
content: '';
transition: all 0.3s ease;
}
@@ -608,13 +636,12 @@
&:hover {
background-color: hsl(88, 50%, 84%);
- box-shadow: 0 0 4px 0px #999;
+ box-shadow: 0 0 4px 0 #999;
}
&.selected {
- background-color: hsl(207, 90%, 74%);
background-color: hsl(88, 50%, 67%);
- box-shadow: 0 0 4px 0px #999;
+ box-shadow: 0 0 4px 0 #999;
}
img {
@@ -689,7 +716,7 @@
width: 100%;
appearance: none;
-webkit-appearance: none;
- scroll-snap-type: mandatory;
+ scroll-snap-type: x mandatory;
background-color : transparent;
outline: none;
margin-left: -10px;
@@ -697,7 +724,6 @@
&::-webkit-slider-runnable-track {
margin: 10px;
- border-radius: 1px;
width: 100%;
height: 10px;
background-color : #ddd;
@@ -785,23 +811,46 @@
}
}
+ .chrome-categories {
+ margin: var(--record-section-padding) 0;
+
+ display: flex;
+ flex-direction: row;
+
+ .categories-list {
+ width: 50%;
+
+ h3 {
+ margin: 6px 0;
+ }
+
+ .config-button {
+ border-radius: 10px;
+ border: 1px solid #eee;
+ margin: 0 5px;
+ font-size: .8rem;
+ }
+
+ .checkboxes {
+ list-style-type: none;
+ padding: 0;
+ font-size: .9rem;
+
+ li {
+ margin: 6px 0;
+ }
+ input {
+ margin-right: 8px;
+ }
+ }
+ }
+ }
+
.dropdown {
border: 1px solid #eee;
outline: none;
-webkit-appearance: none;
- &:not(.multicolumn) {
- overflow: hidden;
- height: 25px;
- padding: 0 5px;
- &:focus, &:hover {
- height: 30vh;
- position: absolute;
- overflow: auto;
- box-shadow: 0 0 15px 0 #eee;
- }
- }
-
option, optgroup {
@include transition();
min-height: 25px;
@@ -823,6 +872,23 @@
}
}
+ &.singlecolumn {
+ margin: var(--record-section-padding) 0;
+ padding: 0;
+ max-width: 100%;
+ width: 100%;
+ overflow-y: auto;
+ height: 400px;
+ optgroup {
+ display: grid;
+ padding: 0;
+ grid-template-columns: 1fr;
+ }
+ option {
+ margin: 0;
+ }
+ }
+
&.multicolumn {
padding: 0;
max-width: 100%;
@@ -879,6 +945,11 @@
&::placeholder { color: #aaa; }
}
+ textarea.atrace-apps-list {
+ margin-top: 16px;
+ height: 100px;
+ }
+
.code-snippet {
display: grid;
position: relative;
@@ -886,7 +957,6 @@
margin: var(--record-section-padding);
background-color: #111;
border-radius: 4px;
- user-select: text;
box-shadow: 0 0 12px #999;
@keyframes ripple{
@@ -905,7 +975,7 @@
}
&.no-top-bar {
- white-space: 'pre';
+ white-space: pre;
&::before {
height: 0;
}
@@ -1012,12 +1082,12 @@
&:hover {
background-color: hsl(88, 50%, 84%);
- box-shadow: 0 0 4px 0px #999;
+ box-shadow: 0 0 4px 0 #999;
}
&.selected {
background-color: hsl(88, 50%, 67%);
- box-shadow: 0 0 4px 0px #999;
+ box-shadow: 0 0 4px 0 #999;
}
}
}
@@ -1034,7 +1104,7 @@
background-color: hsl(88, 50%, 67%);
&:hover {
- box-shadow: 0 0 4px 0px #999;
+ box-shadow: 0 0 4px 0 #999;
}
}
@@ -1055,10 +1125,10 @@
}
} // record-section
-.inline-chip {
+.inline-chip {
@include transition();
&:hover, &:active {
- box-shadow: 0 0 2px 0px #ccc;
+ box-shadow: 0 0 2px 0 #ccc;
background-color: #fafafa;
}
diff --git a/ui/src/assets/sidebar.scss b/ui/src/assets/sidebar.scss
index 8bded2ff4..760dc163d 100644
--- a/ui/src/assets/sidebar.scss
+++ b/ui/src/assets/sidebar.scss
@@ -29,26 +29,28 @@
}
input[type=file] { display:none; }
>header {
- font-family: 'Raleway', sans-serif;
+ font-family: 'Roboto Condensed', sans-serif;
+ font-weight: 700;
+ font-size: 24px;
height: var(--topbar-height);
line-height: var(--topbar-height);
vertical-align: middle;
padding: 0 20px;
color: #fff;
- font-weight: 400;
- font-size: 24px;
- letter-spacing: 0.5px;
overflow: visible;
.brand {
height: 40px;
margin-top: 4px;
}
+ &::before {
+ z-index: 10;
+ }
&.canary::before, &.autopush::before {
display: block;
position: absolute;
font-size: 10px;
line-height: 10px;
- font-family: 'Roboto', sans-serif;
+ font-family: 'Raleway', sans-serif;
left: 155px;
top: 7px;
}
@@ -130,6 +132,13 @@
margin-top: 8px;
font-weight: 400;
}
+ &:before {
+ @include material-icon('expand_more');
+ float: right;
+ color: rgba(255, 255, 255, 0.3);
+ margin-right: 12px;
+ margin-top: -4px;
+ }
}
&:hover {
background-color: #373f4b;
@@ -137,9 +146,16 @@
&.expanded {
background-color: #19212b;
max-height: unset;
- .section-header h2 {
+ .section-header {
+ h2 {
opacity: 0;
+ }
+
+ &:before {
+ content: 'expand_less';
+ }
}
+
.section-content {
pointer-events: inherit;
opacity: 1;
@@ -183,7 +199,7 @@
margin-left: 10px;
border-radius: 50%;
border: 2px solid #b4b7ba;
- border-color: #b4b7ba transparent #b4b7ba transparent;
+ border-color: #b4b7ba transparent;
animation: pending-spinner 1.25s linear infinite;
}
@keyframes pending-spinner {
@@ -205,7 +221,6 @@
white-space: break-spaces;
font-family: 'Roboto Condensed', sans-serif;
word-break: break-all;
- user-select: text;
font-weight: 300;
letter-spacing: 0;
margin-top: -10px;
@@ -270,7 +285,7 @@
right: 8px;
bottom: 3px;
font-size: 12px;
- font-family: 'Roboto Condensed', 'Roboto', sans-serif;
+ font-family: 'Roboto Condensed', sans-serif;
a {
color: rgba(255, 255, 255, 0.5);
text-decoration: none;
@@ -280,6 +295,12 @@
}
}
+// Hide the footer when running integration tests, as the version code and the
+// tiny text with pending queries can fail the screenshot diff test.
+body.testing .sidebar-footer {
+ visibility: hidden;
+}
+
.keycap {
background-color: #fafbfc;
border: 1px solid #d1d5da;
diff --git a/ui/src/assets/topbar.scss b/ui/src/assets/topbar.scss
index 4ab39078c..27dd63c1f 100644
--- a/ui/src/assets/topbar.scss
+++ b/ui/src/assets/topbar.scss
@@ -22,7 +22,7 @@
z-index: 3;
overflow: visible;
background-color: hsl(215, 1%, 95%);
- box-shadow: 0px -3px 14px 2px #bbb;
+ box-shadow: 0 -3px 14px 2px #bbb;
min-height: var(--topbar-height);
display: flex;
justify-content: center;
diff --git a/ui/src/assets/trace_info_page.scss b/ui/src/assets/trace_info_page.scss
index 38c6f9d65..84ee72f44 100644
--- a/ui/src/assets/trace_info_page.scss
+++ b/ui/src/assets/trace_info_page.scss
@@ -16,7 +16,6 @@
overflow-y: auto;
overflow-x: hidden;
padding: 0 20px;
- user-select: text;
section {
margin: 20px auto;
diff --git a/ui/src/assets/typefaces.scss b/ui/src/assets/typefaces.scss
index 5e4ba16f6..a8661b904 100644
--- a/ui/src/assets/typefaces.scss
+++ b/ui/src/assets/typefaces.scss
@@ -11,7 +11,7 @@
font-family: 'Raleway';
font-style: normal;
font-weight: 100;
- src: local('Raleway Thin'), local('Raleway-Thin'), url(assets/Raleway-Thin.woff2) format('woff2');
+ src: url(assets/Raleway-Thin.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@@ -20,7 +20,43 @@
font-family: 'Raleway';
font-style: normal;
font-weight: 400;
- src: local('Raleway'), local('Raleway-Regular'), url(assets/Raleway-Regular.woff2) format('woff2');
+ src: url(assets/Raleway-Regular.woff2) format('woff2');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+/* latin */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 100;
+ src: url(assets/Roboto-100.woff2) format('woff2');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+/* latin */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 300;
+ src: url(assets/Roboto-300.woff2) format('woff2');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+/* latin */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ src: url(assets/Roboto-400.woff2) format('woff2');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+/* latin */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 500;
+ src: url(assets/Roboto-500.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@@ -29,7 +65,7 @@
font-family: 'Roboto Condensed';
font-style: normal;
font-weight: 300;
- src: local('Roboto Condensed Light'), local('RobotoCondensed-Light'), url(assets/RobotoCondensed-Light.woff2) format('woff2');
+ src: url(assets/RobotoCondensed-Light.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@@ -38,7 +74,7 @@
font-family: 'Roboto Condensed';
font-style: normal;
font-weight: 400;
- src: local('Roboto Condensed'), local('RobotoCondensed-Regular'), url(assets/RobotoCondensed-Regular.woff2) format('woff2');
+ src: url(assets/RobotoCondensed-Regular.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@@ -47,12 +83,11 @@
font-family: 'Roboto Mono';
font-style: normal;
font-weight: 400;
- src: local('Roboto Mono'), local('RobotoMono-Regular'), url(assets/RobotoMono-Regular.woff2) format('woff2');
+ src: url(assets/RobotoMono-Regular.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
.material-icons {
- font-display: block;
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
diff --git a/ui/src/base/generic_set.ts b/ui/src/base/generic_set.ts
new file mode 100644
index 000000000..714835f05
--- /dev/null
+++ b/ui/src/base/generic_set.ts
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ES6 Set does not allow to reasonably store compound objects; this class
+// rectifies the problem by implementing generic set on top of Map and an
+// injective function from objects of generic type to strings.
+export class GenericSet<T> {
+ interner: (t: T) => string;
+
+ // Passed function should be injective (as in never having the same output for
+ // two different inputs).
+ constructor(interner: (t: T) => string) {
+ this.interner = interner;
+ }
+
+ backingMap = new Map<string, T>();
+
+ has(column: T): boolean {
+ return this.backingMap.has(this.interner(column));
+ }
+
+ add(column: T) {
+ this.backingMap.set(this.interner(column), column);
+ }
+
+ delete(column: T) {
+ this.backingMap.delete(this.interner(column));
+ }
+
+ values(): Iterable<T> {
+ return this.backingMap.values();
+ }
+}
diff --git a/ui/src/base/remote.ts b/ui/src/base/remote.ts
deleted file mode 100644
index 578bd19da..000000000
--- a/ui/src/base/remote.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import {defer, Deferred} from './deferred';
-
-interface RemoteResponse {
- id: number;
- result: {};
-}
-
-/**
- * A proxy for an object that lives on another thread.
- */
-export class Remote {
- private nextRequestId: number;
- private port: MessagePort;
- // tslint:disable-next-line no-any
- private deferredRequests: Map<number, Deferred<any>>;
-
- constructor(port: MessagePort) {
- this.nextRequestId = 0;
- this.deferredRequests = new Map();
- this.port = port;
- this.port.onmessage = (event: MessageEvent) => {
- this.receive(event.data);
- };
- }
-
- /**
- * Invoke method with name |method| with |args| on the remote object.
- * Optionally set |transferList| to transfer those objects.
- */
- // tslint:disable-next-line no-any
- send<T extends any>(
- method: string,
- args: Array<{}>, transferList?: Transferable[]): Promise<T> {
- const d = defer<T>();
- this.deferredRequests.set(this.nextRequestId, d);
- const message = {
- responseId: this.nextRequestId,
- method,
- args,
- };
- if (transferList === undefined) {
- this.port.postMessage(message);
- } else {
- this.port.postMessage(message, transferList);
- }
- this.nextRequestId += 1;
- return d;
- }
-
- private receive(response: RemoteResponse): void {
- const d = this.deferredRequests.get(response.id);
- if (!d) throw new Error(`No deferred response with ID ${response.id}`);
- this.deferredRequests.delete(response.id);
- d.resolve(response.result);
- }
-}
-
-/**
- * Given a MessagePort |port| where the other end is owned by a Remote
- * (see above) turn each incoming MessageEvent into a call on |handler|
- * and post the result back to the calling thread.
- */
-export function forwardRemoteCalls(
- port: MessagePort,
- // tslint:disable-next-line no-any
- handler: {[key: string]: any}) {
- port.onmessage = (msg: MessageEvent) => {
- const method = msg.data.method;
- const id = msg.data.responseId;
- const args = msg.data.args || [];
- if (method === undefined || id === undefined) {
- throw new Error(`Invalid call method: ${method} id: ${id}`);
- }
-
- if (!(handler[method] instanceof Function)) {
- throw new Error(`Method not known: ${method}(${args})`);
- }
-
- const result = handler[method].apply(handler, args);
- const transferList = [];
-
- if (result !== undefined && result.port instanceof MessagePort) {
- transferList.push(result.port);
- }
-
- port.postMessage(
- {
- id,
- result,
- },
- transferList);
- };
-}
diff --git a/ui/src/base/string_utils.ts b/ui/src/base/string_utils.ts
index bf44d97ec..27e261402 100644
--- a/ui/src/base/string_utils.ts
+++ b/ui/src/base/string_utils.ts
@@ -27,11 +27,11 @@ import {assertTrue} from './logging';
// TextDecoder/Decoder requires the full DOM and isn't available in all types
// of tests. Use fallback implementation from protbufjs.
-let UTF8Decoder: {decode: (buf: Uint8Array) => string;};
-let UTF8Encoder: {encode: (str: string) => Uint8Array;};
+let Utf8Decoder: {decode: (buf: Uint8Array) => string;};
+let Utf8Encoder: {encode: (str: string) => Uint8Array;};
try {
- UTF8Decoder = new TextDecoder('utf-8');
- UTF8Encoder = new TextEncoder();
+ Utf8Decoder = new TextDecoder('utf-8');
+ Utf8Encoder = new TextEncoder();
} catch (_) {
if (typeof process === 'undefined') {
// Silence the warning when we know we are running under NodeJS.
@@ -39,8 +39,8 @@ try {
'Using fallback UTF8 Encoder/Decoder, This should happen only in ' +
'tests and NodeJS-based environments, not in browsers.');
}
- UTF8Decoder = {decode: (buf: Uint8Array) => utf8Read(buf, 0, buf.length)};
- UTF8Encoder = {
+ Utf8Decoder = {decode: (buf: Uint8Array) => utf8Read(buf, 0, buf.length)};
+ Utf8Encoder = {
encode: (str: string) => {
const arr = new Uint8Array(utf8Len(str));
const written = utf8Write(str, arr, 0);
@@ -62,13 +62,13 @@ export function base64Decode(str: string): Uint8Array {
}
export function utf8Encode(str: string): Uint8Array {
- return UTF8Encoder.encode(str);
+ return Utf8Encoder.encode(str);
}
// Note: not all byte sequences can be converted to<>from UTF8. This can be
// used only with valid unicode strings, not arbitrary byte buffers.
export function utf8Decode(buffer: Uint8Array): string {
- return UTF8Decoder.decode(buffer);
+ return Utf8Decoder.decode(buffer);
}
// The binaryEncode/Decode functions below allow to encode an arbitrary binary
@@ -96,3 +96,14 @@ export function binaryDecode(str: string): Uint8Array {
}
return buf;
}
+
+// A function used to interpolate strings into SQL query. The only replacement
+// is done is that single quote replaced with two single quotes, according to
+// SQLite documentation:
+// https://www.sqlite.org/lang_expr.html#literal_values_constants_
+//
+// The purpose of this function is to use in simple comparisons, to escape
+// strings used in GLOB clauses see escapeQuery function.
+export function sqliteString(str: string): string {
+ return `'${str.replace('\'', '\'\'')}'`;
+}
diff --git a/ui/src/base/string_utils_unittest.ts b/ui/src/base/string_utils_unittest.ts
index c8dce8efd..4265a6231 100644
--- a/ui/src/base/string_utils_unittest.ts
+++ b/ui/src/base/string_utils_unittest.ts
@@ -17,6 +17,7 @@ import {
base64Encode,
binaryDecode,
binaryEncode,
+ sqliteString,
utf8Decode,
utf8Encode,
} from './string_utils';
@@ -73,3 +74,8 @@ test('string_utils.binaryEncodeAndDecode', () => {
expect(binaryDecode(encodedStr)).toEqual(buf);
expect(binaryDecode(encodedThroughJson)).toEqual(buf);
});
+
+test('string_utils.sqliteString', () => {
+ expect(sqliteString('that\'s it')).toEqual('\'that\'\'s it\'');
+ expect(sqliteString('no quotes')).toEqual('\'no quotes\'');
+});
diff --git a/ui/src/chrome_extension/chrome_tracing_controller.ts b/ui/src/chrome_extension/chrome_tracing_controller.ts
index 73642abd0..412ef0c70 100644
--- a/ui/src/chrome_extension/chrome_tracing_controller.ts
+++ b/ui/src/chrome_extension/chrome_tracing_controller.ts
@@ -41,6 +41,8 @@ export class ChromeTracingController extends RpcConsumerPort {
private api: ProtocolProxyApi.ProtocolApi;
private devtoolsSocket: DevToolsSocket;
private lastBufferUsageEvent: Protocol.Tracing.BufferUsageEvent|undefined;
+ private tracingSessionOngoing = false;
+ private tracingSessionId = 0;
constructor(port: chrome.runtime.Port) {
super({
@@ -60,6 +62,9 @@ export class ChromeTracingController extends RpcConsumerPort {
this.api = rpcClient.api();
this.api.Tracing.on('tracingComplete', this.onTracingComplete.bind(this));
this.api.Tracing.on('bufferUsage', this.onBufferUsage.bind(this));
+ this.uiPort.onDisconnect.addListener(() => {
+ this.devtoolsSocket.detach();
+ });
}
handleCommand(methodName: string, requestData: Uint8Array) {
@@ -180,10 +185,20 @@ export class ChromeTracingController extends RpcConsumerPort {
}
async disableTracing() {
- await this.api.Tracing.end();
+ await this.endTracing(this.tracingSessionId);
this.sendMessage({type: 'DisableTracingResponse'});
}
+ async endTracing(tracingSessionId: number) {
+ if (tracingSessionId !== this.tracingSessionId) {
+ return;
+ }
+ if (this.tracingSessionOngoing) {
+ await this.api.Tracing.end();
+ }
+ this.tracingSessionOngoing = false;
+ }
+
getTraceStats() {
let percentFull = 0; // If the statistics are not available yet, it is 0.
if (this.lastBufferUsageEvent && this.lastBufferUsageEvent.percentFull) {
@@ -253,16 +268,20 @@ export class ChromeTracingController extends RpcConsumerPort {
bufferUsageReportingInterval: 200
};
+ const traceConfig = TraceConfig.decode(traceConfigProto);
if (browserSupportsPerfettoConfig()) {
const configEncoded = base64Encode(traceConfigProto);
await this.api.Tracing.start(
{perfettoConfig: configEncoded, ...requestParams});
+ this.tracingSessionOngoing = true;
+ const tracingSessionId = ++this.tracingSessionId;
+ setTimeout(
+ () => this.endTracing(tracingSessionId), traceConfig.durationMs);
} else {
console.log(
'Used Chrome version is too old to support ' +
'perfettoConfig parameter. Using chrome config only instead.');
- const traceConfig = TraceConfig.decode(traceConfigProto);
if (hasSystemDataSourceConfig(traceConfig)) {
this.sendErrorMessage(
'System tracing is not supported by this Chrome version. Choose' +
diff --git a/ui/src/chrome_extension/manifest.json b/ui/src/chrome_extension/manifest.json
index 62b405ea0..3da07f7c6 100644
--- a/ui/src/chrome_extension/manifest.json
+++ b/ui/src/chrome_extension/manifest.json
@@ -2,7 +2,7 @@
"name": "Perfetto UI",
"key":"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhm3X7qutsrskke84ltokTObnFJakd/d0XFQ6Ox2wQueHTGJM5GUNPTY/x8bdreNtGnfzvt/Sd0vABbR0wsS6lz5yY+g6ksMXJnigFe9N7uz8E3KojDrl3xYjIe+mkiJo8yxxzPydgb7GjQ6jmsX3g+yjj67kXzm9rZFkmoZ5WmqwBZlguPYVRN/W8CIIqBZkC3Qmq6uSG7b/g93YbwqmTmGiL2sAzgvXtqvDOD6503abtQkRC795E4VjJd+ffyeRH38fAEz5ZIrA6GJsfmov1TZTIu1NTwqylSpBYl5as7C6gpmuxDV4SvHvGT2hMQuIufDhZhErjI3B7bcX+XLe1wIDAQAB",
"description": "Enables the Perfetto trace viewer (https://ui.perfetto.dev) to record Chrome browser traces.",
- "version": "0.0.0.13",
+ "version": "0.0.0.14",
"manifest_version": 2,
"minimum_chrome_version": "81.0.4022.0",
"permissions": [
diff --git a/ui/src/common/actions.ts b/ui/src/common/actions.ts
index e982bc9d9..8366f6588 100644
--- a/ui/src/common/actions.ts
+++ b/ui/src/common/actions.ts
@@ -16,7 +16,7 @@ import {Draft} from 'immer';
import {assertExists, assertTrue} from '../base/logging';
import {randomColor} from '../common/colorizer';
-import {ConvertTrace, ConvertTraceToPprof} from '../controller/trace_converter';
+import {RecordConfig} from '../controller/record_config_types';
import {ACTUAL_FRAMES_SLICE_TRACK_KIND} from '../tracks/actual_frames/common';
import {ASYNC_SLICE_TRACK_KIND} from '../tracks/async_slices/common';
import {COUNTER_TRACK_KIND} from '../tracks/counter/common';
@@ -26,32 +26,42 @@ import {
} from '../tracks/expected_frames/common';
import {HEAP_PROFILE_TRACK_KIND} from '../tracks/heap_profile/common';
import {
+ PERF_SAMPLES_PROFILE_TRACK_KIND
+} from '../tracks/perf_samples_profile/common';
+import {
PROCESS_SCHEDULING_TRACK_KIND
} from '../tracks/process_scheduling/common';
import {PROCESS_SUMMARY_TRACK} from '../tracks/process_summary/common';
-import {DEFAULT_VIEWING_OPTION} from './flamegraph_util';
+import {createEmptyState} from './empty_state';
+import {DEFAULT_VIEWING_OPTION, PERF_SAMPLES_KEY} from './flamegraph_util';
+import {
+ AggregationAttrs,
+ PivotAttrs,
+ SubQueryAttrs,
+ TableAttrs
+} from './pivot_table_common';
import {
AdbRecordingTarget,
Area,
CallsiteInfo,
- createEmptyState,
EngineMode,
- HeapProfileFlamegraphViewingOption,
+ FlamegraphStateViewingOption,
+ LoadedConfig,
LogsPagination,
NewEngineMode,
OmniboxState,
- RecordConfig,
+ PivotTableReduxState,
RecordingTarget,
SCROLLING_TRACK_GROUP,
State,
Status,
- TraceSource,
TraceTime,
TrackKindPriority,
TrackState,
VisibleState,
} from './state';
+import {toNs} from './time';
type StateDraft = Draft<State>;
@@ -62,32 +72,38 @@ const highPriorityTrackOrder = [
ACTUAL_FRAMES_SLICE_TRACK_KIND
];
-const lowPriorityTrackOrder =
- [HEAP_PROFILE_TRACK_KIND, COUNTER_TRACK_KIND, ASYNC_SLICE_TRACK_KIND];
+const lowPriorityTrackOrder = [
+ PERF_SAMPLES_PROFILE_TRACK_KIND,
+ HEAP_PROFILE_TRACK_KIND,
+ COUNTER_TRACK_KIND,
+ ASYNC_SLICE_TRACK_KIND
+];
export interface AddTrackArgs {
id?: string;
engineId: string;
kind: string;
name: string;
+ labels?: string[];
trackKindPriority: TrackKindPriority;
trackGroup?: string;
config: {};
}
export interface PostedTrace {
+ buffer: ArrayBuffer;
title: string;
fileName?: string;
url?: string;
- buffer: ArrayBuffer;
+ uuid?: string;
+ localOnly?: boolean;
}
function clearTraceState(state: StateDraft) {
const nextId = state.nextId;
const recordConfig = state.recordConfig;
- const route = state.route;
const recordingTarget = state.recordingTarget;
- const updateChromeCategories = state.updateChromeCategories;
+ const fetchChromeCategories = state.fetchChromeCategories;
const extensionInstalled = state.extensionInstalled;
const availableAdbDevices = state.availableAdbDevices;
const chromeCategories = state.chromeCategories;
@@ -96,9 +112,8 @@ function clearTraceState(state: StateDraft) {
Object.assign(state, createEmptyState());
state.nextId = nextId;
state.recordConfig = recordConfig;
- state.route = route;
state.recordingTarget = recordingTarget;
- state.updateChromeCategories = updateChromeCategories;
+ state.fetchChromeCategories = fetchChromeCategories;
state.extensionInstalled = extensionInstalled;
state.availableAdbDevices = availableAdbDevices;
state.chromeCategories = chromeCategories;
@@ -121,10 +136,6 @@ function rankIndex<T>(element: T, array: T[]): number {
export const StateActions = {
- navigate(state: StateDraft, args: {route: string}): void {
- state.route = args.route;
- },
-
openTraceFromFile(state: StateDraft, args: {file: File}): void {
clearTraceState(state);
const id = `${state.nextId++}`;
@@ -133,7 +144,6 @@ export const StateActions = {
ready: false,
source: {type: 'FILE', file: args.file},
};
- state.route = `/viewer`;
},
openTraceFromBuffer(state: StateDraft, args: PostedTrace): void {
@@ -144,7 +154,6 @@ export const StateActions = {
ready: false,
source: {type: 'ARRAY_BUFFER', ...args},
};
- state.route = `/viewer`;
},
openTraceFromUrl(state: StateDraft, args: {url: string}): void {
@@ -155,7 +164,6 @@ export const StateActions = {
ready: false,
source: {type: 'URL', url: args.url},
};
- state.route = `/viewer`;
},
openTraceFromHttpRpc(state: StateDraft, _args: {}): void {
@@ -166,29 +174,26 @@ export const StateActions = {
ready: false,
source: {type: 'HTTP_RPC'},
};
- state.route = `/viewer`;
},
- openVideoFromFile(state: StateDraft, args: {file: File}): void {
- state.video = URL.createObjectURL(args.file);
- state.videoEnabled = true;
+ setTraceUuid(state: StateDraft, args: {traceUuid: string}) {
+ state.traceUuid = args.traceUuid;
},
- // TODO(b/141359485): Actions should only modify state.
- convertTraceToJson(
- state: StateDraft, args: {file: Blob, truncate?: 'start'|'end'}): void {
- state.traceConversionInProgress = true;
- ConvertTrace(args.file, 'json', args.truncate);
- },
-
- convertTraceToPprof(
- _: StateDraft,
- args: {pid: number, src: TraceSource, ts1: number, ts2?: number}): void {
- ConvertTraceToPprof(args.pid, args.src, args.ts1, args.ts2);
- },
+ fillUiTrackIdByTraceTrackId(
+ state: StateDraft, trackState: TrackState, uiTrackId: string) {
+ const config = trackState.config as {trackId: number};
+ if (config.trackId !== undefined) {
+ state.uiTrackIdByTraceTrackId[config.trackId] = uiTrackId;
+ return;
+ }
- clearConversionInProgress(state: StateDraft, _args: {}): void {
- state.traceConversionInProgress = false;
+ const multiple = trackState.config as {trackIds: number[]};
+ if (multiple.trackIds !== undefined) {
+ for (const trackId of multiple.trackIds) {
+ state.uiTrackIdByTraceTrackId[trackId] = uiTrackId;
+ }
+ }
},
addTracks(state: StateDraft, args: {tracks: AddTrackArgs[]}) {
@@ -196,6 +201,7 @@ export const StateActions = {
const id = track.id === undefined ? `${state.nextId++}` : track.id;
track.id = id;
state.tracks[id] = track as TrackState;
+ this.fillUiTrackIdByTraceTrackId(state, track as TrackState, id);
if (track.trackGroup === SCROLLING_TRACK_GROUP) {
state.scrollingTracks.push(id);
} else if (track.trackGroup !== undefined) {
@@ -218,6 +224,7 @@ export const StateActions = {
trackGroup: args.trackGroup,
config: args.config,
};
+ this.fillUiTrackIdByTraceTrackId(state, state.tracks[id], id);
if (args.trackGroup === SCROLLING_TRACK_GROUP) {
state.scrollingTracks.push(id);
} else if (args.trackGroup !== undefined) {
@@ -399,6 +406,8 @@ export const StateActions = {
}
},
+ // TODO(hjd): engine.ready should be a published thing. If it's part
+ // of the state it interacts badly with permalinks.
setEngineReady(
state: StateDraft,
args: {engineId: string; ready: boolean, mode: EngineMode}): void {
@@ -463,10 +472,19 @@ export const StateActions = {
// tslint:disable-next-line no-any
(state as any)[key] = (args.newState as any)[key];
}
+
+ // If we're loading from a permalink then none of the engines can
+ // possibly be ready:
+ for (const engine of Object.values(state.engines)) {
+ engine.ready = false;
+ }
},
- setRecordConfig(state: StateDraft, args: {config: RecordConfig;}): void {
+ setRecordConfig(
+ state: StateDraft,
+ args: {config: RecordConfig, configType?: LoadedConfig}): void {
state.recordConfig = args.config;
+ state.lastLoadedConfig = args.configType || {type: 'NONE'};
},
selectNote(state: StateDraft, args: {id: string}): void {
@@ -478,9 +496,7 @@ export const StateActions = {
}
},
- addNote(
- state: StateDraft,
- args: {timestamp: number, color: string, isMovie: boolean}): void {
+ addNote(state: StateDraft, args: {timestamp: number, color: string}): void {
const id = `${state.nextNoteId++}`;
state.notes[id] = {
noteType: 'DEFAULT',
@@ -489,9 +505,6 @@ export const StateActions = {
color: args.color,
text: '',
};
- if (args.isMovie) {
- state.videoNoteIds.push(id);
- }
this.selectNote(state, {id});
},
@@ -545,34 +558,6 @@ export const StateActions = {
};
},
- toggleVideo(state: StateDraft, _: {}): void {
- state.videoEnabled = !state.videoEnabled;
- if (!state.videoEnabled) {
- state.video = null;
- state.flagPauseEnabled = false;
- state.scrubbingEnabled = false;
- state.videoNoteIds.forEach(id => {
- this.removeNote(state, {id});
- });
- }
- },
-
- toggleFlagPause(state: StateDraft, _: {}): void {
- if (state.video != null) {
- state.flagPauseEnabled = !state.flagPauseEnabled;
- }
- },
-
- toggleScrubbing(state: StateDraft, _: {}): void {
- if (state.video != null) {
- state.scrubbingEnabled = !state.scrubbingEnabled;
- }
- },
-
- setVideoOffset(state: StateDraft, args: {offset: number}): void {
- state.videoOffset = args.offset;
- },
-
changeNoteColor(state: StateDraft, args: {id: string, newColor: string}):
void {
const note = state.notes[args.id];
@@ -588,11 +573,6 @@ export const StateActions = {
removeNote(state: StateDraft, args: {id: string}): void {
if (state.notes[args.id] === undefined) return;
- if (state.notes[args.id].noteType === 'MOVIE') {
- state.videoNoteIds = state.videoNoteIds.filter(id => {
- return id !== args.id;
- });
- }
delete state.notes[args.id];
// For regular notes, we clear the current selection but for an area note
// we only want to clear the note/marking and leave the area selected.
@@ -638,14 +618,49 @@ export const StateActions = {
ts: args.ts,
type: args.type,
};
- state.currentHeapProfileFlamegraph = {
- kind: 'HEAP_PROFILE_FLAMEGRAPH',
+ this.openFlamegraph(state, {
+ type: args.type,
+ startNs: toNs(state.traceTime.startSec),
+ endNs: args.ts,
+ upids: [args.upid],
+ viewingOption: DEFAULT_VIEWING_OPTION
+ });
+ },
+
+ selectPerfSamples(
+ state: StateDraft,
+ args: {id: number, upid: number, ts: number, type: string}): void {
+ state.currentSelection = {
+ kind: 'PERF_SAMPLES',
id: args.id,
upid: args.upid,
ts: args.ts,
type: args.type,
- viewingOption: DEFAULT_VIEWING_OPTION,
- focusRegex: '',
+ };
+ this.openFlamegraph(state, {
+ type: args.type,
+ startNs: toNs(state.traceTime.startSec),
+ endNs: args.ts,
+ upids: [args.upid],
+ viewingOption: PERF_SAMPLES_KEY
+ });
+ },
+
+ openFlamegraph(state: StateDraft, args: {
+ upids: number[],
+ startNs: number,
+ endNs: number,
+ type: string,
+ viewingOption: FlamegraphStateViewingOption
+ }): void {
+ state.currentFlamegraphState = {
+ kind: 'FLAMEGRAPH_STATE',
+ upids: args.upids,
+ startNs: args.startNs,
+ endNs: args.endNs,
+ type: args.type,
+ viewingOption: args.viewingOption,
+ focusRegex: ''
};
},
@@ -659,27 +674,28 @@ export const StateActions = {
};
},
- expandHeapProfileFlamegraph(
+ expandFlamegraphState(
state: StateDraft, args: {expandedCallsite?: CallsiteInfo}): void {
- if (state.currentHeapProfileFlamegraph === null) return;
- state.currentHeapProfileFlamegraph.expandedCallsite = args.expandedCallsite;
+ if (state.currentFlamegraphState === null) return;
+ state.currentFlamegraphState.expandedCallsite = args.expandedCallsite;
},
- changeViewHeapProfileFlamegraph(
- state: StateDraft,
- args: {viewingOption: HeapProfileFlamegraphViewingOption}): void {
- if (state.currentHeapProfileFlamegraph === null) return;
- state.currentHeapProfileFlamegraph.viewingOption = args.viewingOption;
- },
+ changeViewFlamegraphState(
+ state: StateDraft, args: {viewingOption: FlamegraphStateViewingOption}):
+ void {
+ if (state.currentFlamegraphState === null) return;
+ state.currentFlamegraphState.viewingOption = args.viewingOption;
+ },
- changeFocusHeapProfileFlamegraph(
- state: StateDraft, args: {focusRegex: string}): void {
- if (state.currentHeapProfileFlamegraph === null) return;
- state.currentHeapProfileFlamegraph.focusRegex = args.focusRegex;
- },
+ changeFocusFlamegraphState(state: StateDraft, args: {focusRegex: string}):
+ void {
+ if (state.currentFlamegraphState === null) return;
+ state.currentFlamegraphState.focusRegex = args.focusRegex;
+ },
selectChromeSlice(
- state: StateDraft, args: {id: number, trackId: string, table: string}):
+ state: StateDraft,
+ args: {id: number, trackId: string, table: string, scroll?: boolean}):
void {
state.currentSelection = {
kind: 'CHROME_SLICE',
@@ -687,8 +703,13 @@ export const StateActions = {
trackId: args.trackId,
table: args.table
};
+ state.pendingScrollId = args.scroll ? args.id : undefined;
},
+ clearPendingScrollId(state: StateDraft, _: {}): void {
+ state.pendingScrollId = undefined;
+ },
+
selectThreadState(state: StateDraft, args: {id: number, trackId: string}):
void {
state.currentSelection = {
@@ -733,8 +754,8 @@ export const StateActions = {
state.recordingTarget = args.target;
},
- setUpdateChromeCategories(state: StateDraft, args: {update: boolean}): void {
- state.updateChromeCategories = args.update;
+ setFetchChromeCategories(state: StateDraft, args: {fetch: boolean}): void {
+ state.fetchChromeCategories = args.fetch;
},
setAvailableAdbDevices(
@@ -806,7 +827,7 @@ export const StateActions = {
},
setVisibleTraceTime(state: StateDraft, args: VisibleState): void {
- state.frontendLocalState.visibleState = args;
+ state.frontendLocalState.visibleState = {...args};
},
setChromeCategories(state: StateDraft, args: {categories: string[]}): void {
@@ -841,10 +862,11 @@ export const StateActions = {
state.metrics.requestedMetric = undefined;
},
- setAvailableMetrics(state: StateDraft, args: {metrics: string[]}): void {
- state.metrics.availableMetrics = args.metrics;
- if (args.metrics.length > 0) state.metrics.selectedIndex = 0;
- },
+ setAvailableMetrics(state: StateDraft, args: {availableMetrics: string[]}):
+ void {
+ state.metrics.availableMetrics = args.availableMetrics;
+ if (args.availableMetrics.length > 0) state.metrics.selectedIndex = 0;
+ },
setMetricSelectedIndex(state: StateDraft, args: {index: number}): void {
if (!state.metrics.availableMetrics ||
@@ -853,6 +875,142 @@ export const StateActions = {
}
state.metrics.selectedIndex = args.index;
},
+
+ togglePerfDebug(state: StateDraft, _: {}): void {
+ state.perfDebug = !state.perfDebug;
+ },
+
+ toggleSidebar(state: StateDraft, _: {}): void {
+ state.sidebarVisible = !state.sidebarVisible;
+ },
+
+ setHoveredUtidAndPid(state: StateDraft, args: {utid: number, pid: number}) {
+ state.hoveredPid = args.pid;
+ state.hoveredUtid = args.utid;
+ },
+
+ setHighlightedSliceId(state: StateDraft, args: {sliceId: number}) {
+ state.highlightedSliceId = args.sliceId;
+ },
+
+ setHighlightedFlowLeftId(state: StateDraft, args: {flowId: number}) {
+ state.focusedFlowIdLeft = args.flowId;
+ },
+
+ setHighlightedFlowRightId(state: StateDraft, args: {flowId: number}) {
+ state.focusedFlowIdRight = args.flowId;
+ },
+
+ setSearchIndex(state: StateDraft, args: {index: number}) {
+ state.searchIndex = args.index;
+ },
+
+ setHoveredLogsTimestamp(state: StateDraft, args: {ts: number}) {
+ state.hoveredLogsTimestamp = args.ts;
+ },
+
+ setHoveredNoteTimestamp(state: StateDraft, args: {ts: number}) {
+ state.hoveredNoteTimestamp = args.ts;
+ },
+
+ setCurrentTab(state: StateDraft, args: {tab: string|undefined}) {
+ state.currentTab = args.tab;
+ },
+
+ toggleAllTrackGroups(state: StateDraft, args: {collapsed: boolean}) {
+ for (const [_, group] of Object.entries(state.trackGroups)) {
+ group.collapsed = args.collapsed;
+ }
+ },
+
+ togglePivotTableRedux(state: StateDraft, args: {selectionArea: Area|null}) {
+ state.pivotTableRedux.selectionArea = args.selectionArea;
+ },
+
+ addNewPivotTable(state: StateDraft, args: {
+ name: string,
+ pivotTableId: string,
+ selectedPivots: PivotAttrs[],
+ selectedAggregations: AggregationAttrs[],
+ traceTime?: TraceTime,
+ selectedTrackIds?: number[]
+ }): void {
+ state.pivotTable[args.pivotTableId] = {
+ id: args.pivotTableId,
+ name: args.name,
+ selectedPivots: args.selectedPivots,
+ selectedAggregations: args.selectedAggregations,
+ isLoadingQuery: false,
+ traceTime: args.traceTime,
+ selectedTrackIds: args.selectedTrackIds
+ };
+ },
+
+ deletePivotTable(state: StateDraft, args: {pivotTableId: string}): void {
+ delete state.pivotTable[args.pivotTableId];
+ },
+
+ resetPivotTableRequest(state: StateDraft, args: {pivotTableId: string}):
+ void {
+ if (state.pivotTable[args.pivotTableId] !== undefined) {
+ state.pivotTable[args.pivotTableId].requestedAction = undefined;
+ }
+ },
+
+ setPivotTableRequest(
+ state: StateDraft,
+ args: {pivotTableId: string, action: string, attrs?: SubQueryAttrs}):
+ void {
+ state.pivotTable[args.pivotTableId].requestedAction = {
+ action: args.action,
+ attrs: args.attrs
+ };
+ },
+
+ setAvailablePivotTableColumns(
+ state: StateDraft,
+ args: {availableColumns: TableAttrs[], availableAggregations: string[]}):
+ void {
+ state.pivotTableConfig.availableColumns = args.availableColumns;
+ state.pivotTableConfig.availableAggregations =
+ args.availableAggregations;
+ },
+
+ toggleQueryLoading(state: StateDraft, args: {pivotTableId: string}): void {
+ state.pivotTable[args.pivotTableId].isLoadingQuery =
+ !state.pivotTable[args.pivotTableId].isLoadingQuery;
+ },
+
+ setSelectedPivotsAndAggregations(state: StateDraft, args: {
+ pivotTableId: string,
+ selectedPivots: PivotAttrs[],
+ selectedAggregations: AggregationAttrs[]
+ }) {
+ state.pivotTable[args.pivotTableId].selectedPivots =
+ args.selectedPivots.map(pivot => Object.assign({}, pivot));
+ state.pivotTable[args.pivotTableId].selectedAggregations =
+ args.selectedAggregations.map(
+ aggregation => Object.assign({}, aggregation));
+ },
+
+ setPivotTableRange(state: StateDraft, args: {
+ pivotTableId: string,
+ traceTime?: TraceTime,
+ selectedTrackIds?: number[]
+ }) {
+ const pivotTable = state.pivotTable[args.pivotTableId];
+ pivotTable.traceTime = args.traceTime;
+ pivotTable.selectedTrackIds = args.selectedTrackIds;
+ },
+
+ setPivotStateReduxState(
+ state: StateDraft, args: {pivotTableState: PivotTableReduxState}) {
+ state.pivotTableRedux = args.pivotTableState;
+ },
+
+ dismissFlamegraphModal(state: StateDraft, _: {}) {
+ state.flamegraphModalDismissed = true;
+ }
};
// When we are on the frontend side, we don't really want to execute the
diff --git a/ui/src/common/actions_unittest.ts b/ui/src/common/actions_unittest.ts
index 8cf6acfb5..53e8f65d5 100644
--- a/ui/src/common/actions_unittest.ts
+++ b/ui/src/common/actions_unittest.ts
@@ -14,6 +14,7 @@
import {produce} from 'immer';
+import {assertExists} from '../base/logging';
import {SLICE_TRACK_KIND} from '../tracks/chrome_slices/common';
import {HEAP_PROFILE_TRACK_KIND} from '../tracks/heap_profile/common';
import {
@@ -22,8 +23,8 @@ import {
import {THREAD_STATE_TRACK_KIND} from '../tracks/thread_state/common';
import {StateActions} from './actions';
+import {createEmptyState} from './empty_state';
import {
- createEmptyState,
SCROLLING_TRACK_GROUP,
State,
TraceUrlSource,
@@ -81,13 +82,6 @@ function pinnedAndScrollingTracks(
return state;
}
-test('navigate', () => {
- const after = produce(createEmptyState(), draft => {
- StateActions.navigate(draft, {route: '/foo'});
- });
- expect(after.route).toBe('/foo');
-});
-
test('add scrolling tracks', () => {
const once = produce(createEmptyState(), draft => {
StateActions.addTrack(draft, {
@@ -278,7 +272,6 @@ test('open trace', () => {
expect(engineKeys.length).toBe(1);
expect((after.engines[engineKeys[0]].source as TraceUrlSource).url)
.toBe('https://example.com/bar');
- expect(after.route).toBe('/viewer');
expect(after.recordConfig).toBe(recordConfig);
});
@@ -311,7 +304,6 @@ test('open second trace from file', () => {
.toBe('https://example.com/foo');
expect(thrice.pinnedTracks.length).toBe(0);
expect(thrice.scrollingTracks.length).toBe(0);
- expect(thrice.route).toBe('/viewer');
});
test('setEngineReady with missing engine is ignored', () => {
@@ -426,3 +418,29 @@ test('sortTracksByTidThenName', () => {
expect(after.trackGroups['g'].tracks).toEqual(['a', 'a', 'c', 'b']);
});
+
+test('perf samples open flamegraph', () => {
+ const state = createEmptyState();
+ const perfType = 'perf';
+
+ const afterSelectingPerf = produce(state, draft => {
+ StateActions.selectPerfSamples(
+ draft, {id: 0, upid: 0, ts: 0, type: perfType});
+ });
+
+ expect(assertExists(afterSelectingPerf.currentFlamegraphState).type)
+ .toBe(perfType);
+});
+
+test('heap profile opens flamegraph', () => {
+ const state = createEmptyState();
+ const heapType = 'graph';
+
+ const afterSelectingPerf = produce(state, draft => {
+ StateActions.selectHeapProfile(
+ draft, {id: 0, upid: 0, ts: 0, type: heapType});
+ });
+
+ expect(assertExists(afterSelectingPerf.currentFlamegraphState).type)
+ .toBe(heapType);
+});
diff --git a/ui/src/common/aggregation_data.ts b/ui/src/common/aggregation_data.ts
index 88878573b..28f761f95 100644
--- a/ui/src/common/aggregation_data.ts
+++ b/ui/src/common/aggregation_data.ts
@@ -55,6 +55,10 @@ export interface AggregateData {
extra?: ThreadStateExtra;
}
+export function isEmptyData(data: AggregateData) {
+ return data.columns.length === 0 || data.columns[0].data.length === 0;
+}
+
export interface ThreadStateExtra {
kind: 'THREAD_STATE';
states: string[];
diff --git a/ui/src/common/arg_types.ts b/ui/src/common/arg_types.ts
index 6ca6a049a..864dc4b2b 100644
--- a/ui/src/common/arg_types.ts
+++ b/ui/src/common/arg_types.ts
@@ -22,9 +22,9 @@ export interface ArgsTreeMap {
}
export function isArgTreeArray(item: ArgsTree): item is ArgsTreeArray {
- return typeof item === 'object' && item.length !== undefined;
+ return typeof item === 'object' && Array.isArray(item);
}
export function isArgTreeMap(item: ArgsTree): item is ArgsTreeMap {
- return typeof item === 'object' && item.length === undefined;
+ return typeof item === 'object' && !Array.isArray(item);
}
diff --git a/ui/src/common/cache_manager.ts b/ui/src/common/cache_manager.ts
new file mode 100644
index 000000000..d946253e5
--- /dev/null
+++ b/ui/src/common/cache_manager.ts
@@ -0,0 +1,119 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * This file deals with caching traces in the browser's Cache storage. The
+ * traces are cached so that the UI can gracefully reload a trace when the tab
+ * containing it is discarded by Chrome(e.g. because the tab was not used for a
+ * long time) or when the user accidentally hits reload.
+ */
+import {assertExists} from '../base/logging';
+import {TraceArrayBufferSource, TraceSource} from './state';
+
+const TRACE_CACHE_NAME = 'cached_traces';
+const TRACE_CACHE_SIZE = 10;
+
+export async function cacheTrace(
+ traceSource: TraceSource, traceUuid: string): Promise<boolean> {
+ let trace, title = '', fileName = '', url = '', contentLength = 0,
+ localOnly = false;
+ switch (traceSource.type) {
+ case 'ARRAY_BUFFER':
+ trace = traceSource.buffer;
+ title = traceSource.title;
+ fileName = traceSource.fileName || '';
+ url = traceSource.url || '';
+ contentLength = traceSource.buffer.byteLength;
+ localOnly = traceSource.localOnly || false;
+ break;
+ case 'FILE':
+ trace = await traceSource.file.arrayBuffer();
+ title = traceSource.file.name;
+ contentLength = traceSource.file.size;
+ break;
+ default:
+ return false;
+ }
+ assertExists(trace);
+
+ const headers = new Headers([
+ ['x-trace-title', title],
+ ['x-trace-url', url],
+ ['x-trace-filename', fileName],
+ ['x-trace-local-only', `${localOnly}`],
+ ['content-type', 'application/octet-stream'],
+ ['content-length', `${contentLength}`],
+ [
+ 'expires',
+ // Expires in a week from now (now = upload time)
+ (new Date((new Date()).getTime() + (1000 * 60 * 60 * 24 * 7)))
+ .toUTCString()
+ ]
+ ]);
+ const traceCache = await caches.open(TRACE_CACHE_NAME);
+ await deleteStaleEntries(traceCache);
+ await traceCache.put(
+ `/_${TRACE_CACHE_NAME}/${traceUuid}`, new Response(trace, {headers}));
+ return true;
+}
+
+export async function tryGetTrace(traceUuid: string):
+ Promise<TraceArrayBufferSource|undefined> {
+ await deleteStaleEntries(await caches.open(TRACE_CACHE_NAME));
+ const response = await caches.match(
+ `/_${TRACE_CACHE_NAME}/${traceUuid}`, {cacheName: TRACE_CACHE_NAME});
+
+ if (!response) return undefined;
+ return {
+ type: 'ARRAY_BUFFER',
+ buffer: await response.arrayBuffer(),
+ title: response.headers.get('x-trace-title') || '',
+ fileName: response.headers.get('x-trace-filename') || undefined,
+ url: response.headers.get('x-trace-url') || undefined,
+ uuid: traceUuid,
+ localOnly: response.headers.get('x-trace-local-only') === 'true'
+ };
+}
+
+async function deleteStaleEntries(traceCache: Cache) {
+ /*
+ * Loop through stored caches and invalidate all but the most recent 10.
+ */
+ const keys = await traceCache.keys();
+ const storedTraces: Array<{key: Request, date: Date}> = [];
+ for (const key of keys) {
+ const existingTrace = assertExists(await traceCache.match(key));
+ const expiryDate =
+ new Date(assertExists(existingTrace.headers.get('expires')));
+ if (expiryDate < new Date()) {
+ await traceCache.delete(key);
+ } else {
+ storedTraces.push({key, date: expiryDate});
+ }
+ }
+
+ if (storedTraces.length <= TRACE_CACHE_SIZE) return;
+
+ /*
+ * Sort the traces descending by time, such that most recent ones are placed
+ * at the beginning. Then, take traces from TRACE_CACHE_SIZE onwards and
+ * delete them from cache.
+ */
+ const oldTraces =
+ storedTraces.sort((a, b) => b.date.getTime() - a.date.getTime())
+ .slice(TRACE_CACHE_SIZE);
+ for (const oldTrace of oldTraces) {
+ await traceCache.delete(oldTrace.key);
+ }
+}
diff --git a/ui/src/common/canvas_utils.ts b/ui/src/common/canvas_utils.ts
index 96c0fc97f..aef36a0dd 100644
--- a/ui/src/common/canvas_utils.ts
+++ b/ui/src/common/canvas_utils.ts
@@ -71,22 +71,20 @@ export function drawIncompleteSlice(
ctx: CanvasRenderingContext2D,
x: number,
y: number,
- length: number,
width: number,
- color: string) {
+ height: number) {
ctx.beginPath();
- ctx.fillStyle = color;
- const triangleSize = width / 4;
+ const triangleSize = height / 4;
ctx.moveTo(x, y);
- ctx.lineTo(x + length, y);
- ctx.lineTo(x + length - 3, y + triangleSize * 0.5);
- ctx.lineTo(x + length, y + triangleSize);
- ctx.lineTo(x + length - 3, y + (triangleSize * 1.5));
- ctx.lineTo(x + length, y + 2 * triangleSize);
- ctx.lineTo(x + length - 3, y + (triangleSize * 2.5));
- ctx.lineTo(x + length, y + 3 * triangleSize);
- ctx.lineTo(x + length - 3, y + (triangleSize * 3.5));
- ctx.lineTo(x + length, y + 4 * triangleSize);
- ctx.lineTo(x, y + width);
+ ctx.lineTo(x + width, y);
+ ctx.lineTo(x + width - 3, y + triangleSize * 0.5);
+ ctx.lineTo(x + width, y + triangleSize);
+ ctx.lineTo(x + width - 3, y + (triangleSize * 1.5));
+ ctx.lineTo(x + width, y + 2 * triangleSize);
+ ctx.lineTo(x + width - 3, y + (triangleSize * 2.5));
+ ctx.lineTo(x + width, y + 3 * triangleSize);
+ ctx.lineTo(x + width - 3, y + (triangleSize * 3.5));
+ ctx.lineTo(x + width, y + 4 * triangleSize);
+ ctx.lineTo(x, y + height);
ctx.fill();
-} \ No newline at end of file
+}
diff --git a/ui/src/common/channels.ts b/ui/src/common/channels.ts
new file mode 100644
index 000000000..ad0837c56
--- /dev/null
+++ b/ui/src/common/channels.ts
@@ -0,0 +1,49 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {globals} from '../frontend/globals';
+
+const DEFAULT_CHANNEL = 'stable';
+const CHANNEL_KEY = 'perfettoUiChannel';
+
+let currentChannel: string|undefined = undefined;
+let nextChannel: string|undefined = undefined;
+
+// This is the channel the UI is currently running. It doesn't change once the
+// UI has been loaded.
+export function getCurrentChannel(): string {
+ if (currentChannel === undefined) {
+ currentChannel = localStorage.getItem(CHANNEL_KEY) || DEFAULT_CHANNEL;
+ }
+ return currentChannel;
+}
+
+// This is the channel that will be applied on reload.
+export function getNextChannel(): string {
+ if (nextChannel !== undefined) {
+ return nextChannel;
+ }
+ return getCurrentChannel();
+}
+
+export function channelChanged(): boolean {
+ return getCurrentChannel() !== getNextChannel();
+}
+
+export function setChannel(channel: string): void {
+ getCurrentChannel(); // Cache the current channel before mangling next one.
+ nextChannel = channel;
+ localStorage.setItem(CHANNEL_KEY, channel);
+ globals.rafScheduler.scheduleFullRedraw();
+}
diff --git a/ui/src/common/colorizer.ts b/ui/src/common/colorizer.ts
index 9adde3887..0c30df8ef 100644
--- a/ui/src/common/colorizer.ts
+++ b/ui/src/common/colorizer.ts
@@ -43,7 +43,7 @@ const MD_PALETTE: Color[] = [
{c: 'yellow', h: 54, s: 100, l: 62},
];
-const GREY_COLOR: Color = {
+export const GRAY_COLOR: Color = {
c: 'grey',
h: 0,
s: 0,
@@ -129,7 +129,7 @@ export function colorForTid(tid: number): Color {
export function colorForThread(thread?: {pid?: number, tid: number}): Color {
if (thread === undefined) {
- return Object.assign({}, GREY_COLOR);
+ return Object.assign({}, GRAY_COLOR);
}
const tid = thread.pid ? thread.pid : thread.tid;
return colorForTid(tid);
@@ -159,3 +159,27 @@ export function hslForSlice(
const lightness = isSelected ? 30 : hash(sliceName + 'x', 40) + 40;
return [hue, saturation, lightness];
}
+
+// Lightens the color for thread slices to represent wall time.
+export function hslForThreadIdleSlice(
+ hue: number,
+ saturation: number,
+ lightness: number,
+ isSelected: boolean|null): [number, number, number] {
+ // Increase lightness by 80% when selected and 40% otherwise,
+ // without exceeding 88.
+ let newLightness = isSelected ? lightness * 1.8 : lightness * 1.4;
+ newLightness = Math.min(newLightness, 88);
+ return [hue, saturation, newLightness];
+}
+
+export function colorToStr(color: Color) {
+ if (color.a !== undefined) {
+ return `hsla(${color.h}, ${color.s}%, ${color.l}%, ${color.a})`;
+ }
+ return `hsl(${color.h}, ${color.s}%, ${color.l}%)`;
+}
+
+export function colorCompare(x: Color, y: Color) {
+ return (x.h - y.h) || (x.s - y.s) || (x.l - y.l);
+}
diff --git a/ui/src/common/conversion_jobs.ts b/ui/src/common/conversion_jobs.ts
new file mode 100644
index 000000000..efb56e271
--- /dev/null
+++ b/ui/src/common/conversion_jobs.ts
@@ -0,0 +1,26 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+export enum ConversionJobStatus {
+ InProgress = 'InProgress',
+ NotRunning = 'NotRunning',
+}
+
+export type ConversionJobName = 'convert_systrace'|'convert_json'|
+ 'open_in_legacy'|'convert_pprof'|'create_permalink';
+
+export interface ConversionJobStatusUpdate {
+ jobName: ConversionJobName;
+ jobStatus: ConversionJobStatus;
+}
diff --git a/ui/src/common/empty_state.ts b/ui/src/common/empty_state.ts
new file mode 100644
index 000000000..ac287d2dc
--- /dev/null
+++ b/ui/src/common/empty_state.ts
@@ -0,0 +1,109 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {createEmptyRecordConfig} from '../controller/record_config_types';
+import {
+ autosaveConfigStore,
+ recordTargetStore
+} from '../frontend/record_config';
+
+import {featureFlags} from './feature_flags';
+import {defaultTraceTime, State, STATE_VERSION} from './state';
+
+const AUTOLOAD_STARTED_CONFIG_FLAG = featureFlags.register({
+ id: 'autoloadStartedConfig',
+ name: 'Auto-load last used recording config',
+ description: 'Starting a recording automatically saves its configuration. ' +
+ 'This flag controls whether this config is automatically loaded.',
+ defaultValue: true,
+});
+
+export function createEmptyState(): State {
+ return {
+ version: STATE_VERSION,
+ nextId: 0,
+ nextNoteId: 1, // 0 is reserved for ephemeral area marking.
+ nextAreaId: 0,
+ newEngineMode: 'USE_HTTP_RPC_IF_AVAILABLE',
+ engines: {},
+ traceTime: {...defaultTraceTime},
+ tracks: {},
+ uiTrackIdByTraceTrackId: {},
+ aggregatePreferences: {},
+ trackGroups: {},
+ visibleTracks: [],
+ pinnedTracks: [],
+ scrollingTracks: [],
+ areas: {},
+ queries: {},
+ metrics: {},
+ permalink: {},
+ notes: {},
+ pivotTableConfig: {},
+ pivotTable: {},
+
+ recordConfig: AUTOLOAD_STARTED_CONFIG_FLAG.get() ?
+ autosaveConfigStore.get() :
+ createEmptyRecordConfig(),
+ displayConfigAsPbtxt: false,
+ lastLoadedConfig: {type: 'NONE'},
+
+ frontendLocalState: {
+ omniboxState: {
+ lastUpdate: 0,
+ omnibox: '',
+ mode: 'SEARCH',
+ },
+
+ visibleState: {
+ ...defaultTraceTime,
+ lastUpdate: 0,
+ resolution: 0,
+ },
+ },
+
+ logsPagination: {
+ offset: 0,
+ count: 0,
+ },
+
+ status: {msg: '', timestamp: 0},
+ currentSelection: null,
+ currentFlamegraphState: null,
+ traceConversionInProgress: false,
+
+ perfDebug: false,
+ sidebarVisible: true,
+ hoveredUtid: -1,
+ hoveredPid: -1,
+ hoveredLogsTimestamp: -1,
+ hoveredNoteTimestamp: -1,
+ highlightedSliceId: -1,
+ focusedFlowIdLeft: -1,
+ focusedFlowIdRight: -1,
+ searchIndex: -1,
+
+ recordingInProgress: false,
+ recordingCancelled: false,
+ extensionInstalled: false,
+ flamegraphModalDismissed: false,
+ recordingTarget: recordTargetStore.getValidTarget(),
+ availableAdbDevices: [],
+
+ fetchChromeCategories: false,
+ chromeCategories: undefined,
+ pivotTableRedux:
+ {selectionArea: null, query: null, queryId: 0, queryResult: null},
+ };
+} \ No newline at end of file
diff --git a/ui/src/common/engine.ts b/ui/src/common/engine.ts
index 3d387d44b..01c12073e 100644
--- a/ui/src/common/engine.ts
+++ b/ui/src/common/engine.ts
@@ -12,15 +12,29 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import {defer, Deferred} from '../base/deferred';
+import {assertExists, assertTrue} from '../base/logging';
+import {perfetto} from '../gen/protos';
+
+import {ProtoRingBuffer} from './proto_ring_buffer';
import {
ComputeMetricArgs,
ComputeMetricResult,
- RawQueryArgs,
- RawQueryResult
+ QueryArgs,
} from './protos';
-import {iter, NUM_NULL, slowlyCountRows, STR} from './query_iterator';
+import {NUM, NUM_NULL, STR} from './query_result';
+import {
+ createQueryResult,
+ QueryError,
+ QueryResult,
+ WritableQueryResult,
+} from './query_result';
import {TimeSpan} from './time';
+import TraceProcessorRpc = perfetto.protos.TraceProcessorRpc;
+import TraceProcessorRpcStream = perfetto.protos.TraceProcessorRpcStream;
+import TPM = perfetto.protos.TraceProcessorRpc.TraceProcessorMethod;
+
export interface LoadingTracker {
beginLoading(): void;
endLoading(): void;
@@ -31,124 +45,287 @@ export class NullLoadingTracker implements LoadingTracker {
endLoading(): void {}
}
-export class QueryError extends Error {}
+
+// This is used to skip the decoding of queryResult from protobufjs and deal
+// with it ourselves. See the comment below around `QueryResult.decode = ...`.
+interface QueryResultBypass {
+ rawQueryResult: Uint8Array;
+}
/**
* Abstract interface of a trace proccessor.
* This is the TypeScript equivalent of src/trace_processor/rpc.h.
- *
- * Engine also defines helpers for the most common service methods
- * (e.g. query).
+ * There are two concrete implementations:
+ * 1. WasmEngineProxy: creates a Wasm module and interacts over postMessage().
+ * 2. HttpRpcEngine: connects to an external `trace_processor_shell --httpd`.
+ * and interacts via fetch().
+ * In both cases, we have a byte-oriented pipe to interact with TraceProcessor.
+ * The derived class is only expected to deal with these two functions:
+ * 1. Implement the abstract rpcSendRequestBytes() function, sending the
+ * proto-encoded TraceProcessorRpc requests to the TraceProcessor instance.
+ * 2. Call onRpcResponseBytes() when response data is received.
*/
export abstract class Engine {
abstract readonly id: string;
private _cpus?: number[];
private _numGpus?: number;
private loadingTracker: LoadingTracker;
+ private txSeqId = 0;
+ private rxSeqId = 0;
+ private rxBuf = new ProtoRingBuffer();
+ private pendingParses = new Array<Deferred<void>>();
+ private pendingEOFs = new Array<Deferred<void>>();
+ private pendingQueries = new Array<WritableQueryResult>();
+ private pendingRestoreTables = new Array<Deferred<void>>();
+ private pendingComputeMetrics = new Array<Deferred<ComputeMetricResult>>();
constructor(tracker?: LoadingTracker) {
this.loadingTracker = tracker ? tracker : new NullLoadingTracker();
}
/**
- * Push trace data into the engine. The engine is supposed to automatically
- * figure out the type of the trace (JSON vs Protobuf).
+ * Called to send data to the TraceProcessor instance. This turns into a
+ * postMessage() or a HTTP request, depending on the Engine implementation.
*/
- abstract parse(data: Uint8Array): Promise<void>;
+ abstract rpcSendRequestBytes(data: Uint8Array): void;
/**
- * Notify the engine no more data is coming.
+ * Called when an inbound message is received by the Engine implementation
+ * (e.g. onmessage for the Wasm case, on when HTTP replies are received for
+ * the HTTP+RPC case).
*/
- abstract notifyEof(): void;
+ onRpcResponseBytes(dataWillBeRetained: Uint8Array) {
+ // Note: when hitting the fastpath inside ProtoRingBuffer, the |data| buffer
+ // is returned back by readMessage() (% subarray()-ing it) and held onto by
+ // other classes (e.g., QueryResult). For both fetch() and Wasm we are fine
+ // because every response creates a new buffer.
+ this.rxBuf.append(dataWillBeRetained);
+ for (;;) {
+ const msg = this.rxBuf.readMessage();
+ if (msg === undefined) break;
+ this.onRpcResponseMessage(msg);
+ }
+ }
- /**
- * Resets the trace processor state by destroying any table/views created by
- * the UI after loading.
+ /*
+ * Parses a response message.
+ * |rpcMsgEncoded| is a sub-array to to the start of a TraceProcessorRpc
+ * proto-encoded message (without the proto preamble and varint size).
*/
- abstract restoreInitialTables(): void;
+ private onRpcResponseMessage(rpcMsgEncoded: Uint8Array) {
+ // Here we override the protobufjs-generated code to skip the parsing of the
+ // new streaming QueryResult and instead passing it through like a buffer.
+ // This is the overall problem: All trace processor responses are wrapped
+ // into a perfetto.protos.TraceProcessorRpc proto message. In all cases %
+ // TPM_QUERY_STREAMING, we want protobufjs to decode the proto bytes and
+ // give us a structured object. In the case of TPM_QUERY_STREAMING, instead,
+ // we want to deal with the proto parsing ourselves using the new
+ // QueryResult.appendResultBatch() method, because that handled streaming
+ // results more efficiently and skips several copies.
+ // By overriding the decode method below, we achieve two things:
+ // 1. We avoid protobufjs decoding the TraceProcessorRpc.query_result field.
+ // 2. We stash (a view of) the original buffer into the |rawQueryResult| so
+ // the `case TPM_QUERY_STREAMING` below can take it.
+ perfetto.protos.QueryResult.decode =
+ (reader: protobuf.Reader, length: number) => {
+ const res =
+ perfetto.protos.QueryResult.create() as {} as QueryResultBypass;
+ res.rawQueryResult =
+ reader.buf.subarray(reader.pos, reader.pos + length);
+ // All this works only if protobufjs returns the original ArrayBuffer
+ // from |rpcMsgEncoded|. It should be always the case given the
+ // current implementation. This check mainly guards against future
+ // behavioral changes of protobufjs. We don't want to accidentally
+ // hold onto some internal protobufjs buffer. We are fine holding
+ // onto |rpcMsgEncoded| because those come from ProtoRingBuffer which
+ // is buffer-retention-friendly.
+ assertTrue(res.rawQueryResult.buffer === rpcMsgEncoded.buffer);
+ reader.pos += length;
+ return res as {} as perfetto.protos.QueryResult;
+ };
- /*
- * Performs a SQL query and retruns a proto-encoded RawQueryResult object.
+ const rpc = TraceProcessorRpc.decode(rpcMsgEncoded);
+
+ if (rpc.fatalError !== undefined && rpc.fatalError.length > 0) {
+ throw new Error(`${rpc.fatalError}`);
+ }
+
+ // Allow restarting sequences from zero (when reloading the browser).
+ if (rpc.seq !== this.rxSeqId + 1 && this.rxSeqId !== 0 && rpc.seq !== 0) {
+ // "(ERR:rpc_seq)" is intercepted by error_dialog.ts to show a more
+ // graceful and actionable error.
+ throw new Error(`RPC sequence id mismatch cur=${rpc.seq} last=${
+ this.rxSeqId} (ERR:rpc_seq)`);
+ }
+
+ this.rxSeqId = rpc.seq;
+
+ let isFinalResponse = true;
+
+ switch (rpc.response) {
+ case TPM.TPM_APPEND_TRACE_DATA:
+ const appendResult = assertExists(rpc.appendResult);
+ const pendingPromise = assertExists(this.pendingParses.shift());
+ if (appendResult.error && appendResult.error.length > 0) {
+ pendingPromise.reject(appendResult.error);
+ } else {
+ pendingPromise.resolve();
+ }
+ break;
+ case TPM.TPM_FINALIZE_TRACE_DATA:
+ assertExists(this.pendingEOFs.shift()).resolve();
+ break;
+ case TPM.TPM_RESTORE_INITIAL_TABLES:
+ assertExists(this.pendingRestoreTables.shift()).resolve();
+ break;
+ case TPM.TPM_QUERY_STREAMING:
+ const qRes = assertExists(rpc.queryResult) as {} as QueryResultBypass;
+ const pendingQuery = assertExists(this.pendingQueries[0]);
+ pendingQuery.appendResultBatch(qRes.rawQueryResult);
+ if (pendingQuery.isComplete()) {
+ this.pendingQueries.shift();
+ } else {
+ isFinalResponse = false;
+ }
+ break;
+ case TPM.TPM_COMPUTE_METRIC:
+ const metricRes = assertExists(rpc.metricResult) as ComputeMetricResult;
+ if (metricRes.error && metricRes.error.length > 0) {
+ throw new QueryError(`ComputeMetric() error: ${metricRes.error}`, {
+ query: 'COMPUTE_METRIC',
+ });
+ }
+ assertExists(this.pendingComputeMetrics.shift()).resolve(metricRes);
+ break;
+ default:
+ console.log(
+ 'Unexpected TraceProcessor response received: ', rpc.response);
+ break;
+ } // switch(rpc.response);
+
+ if (isFinalResponse) {
+ this.loadingTracker.endLoading();
+ }
+ }
+
+ /**
+ * TraceProcessor methods below this point.
+ * The methods below are called by the various controllers in the UI and
+ * deal with marshalling / unmarshaling requests to/from TraceProcessor.
*/
- abstract rawQuery(rawQueryArgs: Uint8Array): Promise<Uint8Array>;
- /*
- * Performs computation of metrics and returns metric result and any errors.
- * Metric result is a proto binary or text encoded TraceMetrics object.
+
+ /**
+ * Push trace data into the engine. The engine is supposed to automatically
+ * figure out the type of the trace (JSON vs Protobuf).
*/
- abstract rawComputeMetric(computeMetricArgs: Uint8Array): Promise<Uint8Array>;
+ parse(data: Uint8Array): Promise<void> {
+ const asyncRes = defer<void>();
+ this.pendingParses.push(asyncRes);
+ const rpc = TraceProcessorRpc.create();
+ rpc.request = TPM.TPM_APPEND_TRACE_DATA;
+ rpc.appendTraceData = data;
+ this.rpcSendRequest(rpc);
+ return asyncRes; // Linearize with the worker.
+ }
/**
- * Shorthand for sending a SQL query to the engine.
- * Deals with {,un}marshalling of request/response args.
+ * Notify the engine that we reached the end of the trace.
+ * Called after the last parse() call.
*/
- async query(sqlQuery: string): Promise<RawQueryResult> {
- const result = await this.uncheckedQuery(sqlQuery);
- if (result.error) {
- throw new QueryError(`Query error "${sqlQuery}": ${result.error}`);
- }
- return result;
+ notifyEof(): Promise<void> {
+ const asyncRes = defer<void>();
+ this.pendingEOFs.push(asyncRes);
+ const rpc = TraceProcessorRpc.create();
+ rpc.request = TPM.TPM_FINALIZE_TRACE_DATA;
+ this.rpcSendRequest(rpc);
+ return asyncRes; // Linearize with the worker.
}
- // This method is for noncritical queries that shouldn't throw an error
- // on failure. The caller must handle the failure.
- async uncheckedQuery(sqlQuery: string): Promise<RawQueryResult> {
- this.loadingTracker.beginLoading();
- try {
- const args = new RawQueryArgs();
- args.sqlQuery = sqlQuery;
- args.timeQueuedNs = Math.floor(performance.now() * 1e6);
- const argsEncoded = RawQueryArgs.encode(args).finish();
- const respEncoded = await this.rawQuery(argsEncoded);
- const result = RawQueryResult.decode(respEncoded);
- return result;
- } finally {
- this.loadingTracker.endLoading();
- }
+ /**
+ * Resets the trace processor state by destroying any table/views created by
+ * the UI after loading.
+ */
+ restoreInitialTables(): Promise<void> {
+ const asyncRes = defer<void>();
+ this.pendingRestoreTables.push(asyncRes);
+ const rpc = TraceProcessorRpc.create();
+ rpc.request = TPM.TPM_RESTORE_INITIAL_TABLES;
+ this.rpcSendRequest(rpc);
+ return asyncRes; // Linearize with the worker.
}
/**
* Shorthand for sending a compute metrics request to the engine.
- * Deals with {,un}marshalling of request/response args.
*/
async computeMetric(metrics: string[]): Promise<ComputeMetricResult> {
- const args = new ComputeMetricArgs();
+ const asyncRes = defer<ComputeMetricResult>();
+ this.pendingComputeMetrics.push(asyncRes);
+ const rpc = TraceProcessorRpc.create();
+ rpc.request = TPM.TPM_COMPUTE_METRIC;
+ const args = rpc.computeMetricArgs = new ComputeMetricArgs();
args.metricNames = metrics;
args.format = ComputeMetricArgs.ResultFormat.TEXTPROTO;
- const argsEncoded = ComputeMetricArgs.encode(args).finish();
- const respEncoded = await this.rawComputeMetric(argsEncoded);
- const result = ComputeMetricResult.decode(respEncoded);
- if (result.error.length > 0) {
- throw new QueryError(result.error);
- }
+ this.rpcSendRequest(rpc);
+ return asyncRes;
+ }
+
+ /*
+ * Issues a streaming query and retrieve results in batches.
+ * The returned QueryResult object will be populated over time with batches
+ * of rows (each batch conveys ~128KB of data and a variable number of rows).
+ * The caller can decide whether to wait that all batches have been received
+ * (by awaiting the returned object or calling result.waitAllRows()) or handle
+ * the rows incrementally.
+ *
+ * Example usage:
+ * const res = engine.query('SELECT foo, bar FROM table');
+ * console.log(res.numRows()); // Will print 0 because we didn't await.
+ * await(res.waitAllRows());
+ * console.log(res.numRows()); // Will print the total number of rows.
+ *
+ * for (const it = res.iter({foo: NUM, bar:STR}); it.valid(); it.next()) {
+ * console.log(it.foo, it.bar);
+ * }
+ */
+ query(sqlQuery: string): Promise<QueryResult>&QueryResult {
+ const rpc = TraceProcessorRpc.create();
+ rpc.request = TPM.TPM_QUERY_STREAMING;
+ rpc.queryArgs = new QueryArgs();
+ rpc.queryArgs.sqlQuery = sqlQuery;
+ const result = createQueryResult({
+ query: sqlQuery,
+ });
+ this.pendingQueries.push(result);
+ this.rpcSendRequest(rpc);
return result;
}
- async queryOneRow(query: string): Promise<number[]> {
- const result = await this.query(query);
- const res: number[] = [];
- if (slowlyCountRows(result) === 0) return res;
- for (const col of result.columns) {
- if (col.longValues!.length === 0) {
- console.error(
- `queryOneRow should only be used for queries that return long values
- : ${query}`);
- throw new Error(
- `queryOneRow should only be used for queries that return long values
- : ${query}`);
- }
- res.push(+col.longValues![0]);
- }
- return res;
+ /**
+ * Marshals the TraceProcessorRpc request arguments and sends the request
+ * to the concrete Engine (Wasm or HTTP).
+ */
+ private rpcSendRequest(rpc: TraceProcessorRpc) {
+ rpc.seq = this.txSeqId++;
+ // Each message is wrapped in a TraceProcessorRpcStream to add the varint
+ // preamble with the size, which allows tokenization on the other end.
+ const outerProto = TraceProcessorRpcStream.create();
+ outerProto.msg.push(rpc);
+ const buf = TraceProcessorRpcStream.encode(outerProto).finish();
+ this.loadingTracker.beginLoading();
+ this.rpcSendRequestBytes(buf);
}
// TODO(hjd): When streaming must invalidate this somehow.
async getCpus(): Promise<number[]> {
if (!this._cpus) {
- const result =
- await this.query('select distinct(cpu) from sched order by cpu;');
- if (slowlyCountRows(result) === 0) return [];
- this._cpus = result.columns[0].longValues!.map(n => +n);
+ const cpus = [];
+ const queryRes = await this.query(
+ 'select distinct(cpu) as cpu from sched order by cpu;');
+ for (const it = queryRes.iter({cpu: NUM}); it.valid(); it.next()) {
+ cpus.push(it.cpu);
+ }
+ this._cpus = cpus;
}
return this._cpus;
}
@@ -160,7 +337,7 @@ export abstract class Engine {
from gpu_counter_track
where name = 'gpufreq';
`);
- this._numGpus = +result.columns[0].longValues![0];
+ this._numGpus = result.firstRow({gpuCount: NUM}).gpuCount;
}
return this._numGpus;
}
@@ -168,26 +345,33 @@ export abstract class Engine {
// TODO: This should live in code that's more specific to chrome, instead of
// in engine.
async getNumberOfProcesses(): Promise<number> {
- const result = await this.query('select count(*) from process;');
- return +result.columns[0].longValues![0];
+ const result = await this.query('select count(*) as cnt from process;');
+ return result.firstRow({cnt: NUM}).cnt;
}
async getTraceTimeBounds(): Promise<TimeSpan> {
- const query = `select start_ts, end_ts from trace_bounds`;
- const res = (await this.queryOneRow(query));
- return new TimeSpan(res[0] / 1e9, res[1] / 1e9);
+ const result = await this.query(
+ `select start_ts as startTs, end_ts as endTs from trace_bounds`);
+ const bounds = result.firstRow({
+ startTs: NUM,
+ endTs: NUM,
+ });
+ return new TimeSpan(bounds.startTs / 1e9, bounds.endTs / 1e9);
}
async getTracingMetadataTimeBounds(): Promise<TimeSpan> {
- const query = await this.query(`select name, int_value from metadata
+ const queryRes = await this.query(`select
+ name,
+ int_value as intValue
+ from metadata
where name = 'tracing_started_ns' or name = 'tracing_disabled_ns'
or name = 'all_data_source_started_ns'`);
let startBound = -Infinity;
let endBound = Infinity;
- const it = iter({'name': STR, 'int_value': NUM_NULL}, query);
+ const it = queryRes.iter({'name': STR, 'intValue': NUM_NULL});
for (; it.valid(); it.next()) {
- const columnName = it.row.name;
- const timestamp = it.row.int_value;
+ const columnName = it.name;
+ const timestamp = it.intValue;
if (timestamp === null) continue;
if (columnName === 'tracing_disabled_ns') {
endBound = Math.min(endBound, timestamp / 1e9);
diff --git a/ui/src/common/feature_flags.ts b/ui/src/common/feature_flags.ts
new file mode 100644
index 000000000..1dfb28e82
--- /dev/null
+++ b/ui/src/common/feature_flags.ts
@@ -0,0 +1,236 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// This file should not import anything else. Since the flags will be used from
+// ~everywhere and the are "statically" initialized (i.e. files construct Flags
+// at import time) if this file starts importing anything we will quickly run
+// into issues with initialization order which will be a pain.
+
+interface FlagSettings {
+ id: string;
+ defaultValue: boolean;
+ description: string;
+ name?: string;
+ devOnly?: boolean;
+}
+
+export enum OverrideState {
+ DEFAULT = 'DEFAULT',
+ TRUE = 'OVERRIDE_TRUE',
+ FALSE = 'OVERRIDE_FALSE',
+}
+
+export interface FlagStore {
+ load(): object;
+ save(o: object): void;
+}
+
+// Stored state for a number of flags.
+interface FlagOverrides {
+ [id: string]: OverrideState;
+}
+
+// Check if the given object is a valid FlagOverrides.
+// This is necessary since someone could modify the persisted flags
+// behind our backs.
+function isFlagOverrides(o: object): o is FlagOverrides {
+ const states =
+ [OverrideState.TRUE.toString(), OverrideState.FALSE.toString()];
+ for (const v of Object.values(o)) {
+ if (typeof v !== 'string' || !states.includes(v)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+class Flags {
+ private store: FlagStore;
+ private flags: Map<string, FlagImpl>;
+ private overrides: FlagOverrides;
+
+ constructor(store: FlagStore) {
+ this.store = store;
+ this.flags = new Map();
+ this.overrides = {};
+ this.load();
+ }
+
+ register(settings: FlagSettings): Flag {
+ const id = settings.id;
+ if (this.flags.has(id)) {
+ throw new Error(`Flag with id "${id}" is already registered.`);
+ }
+
+ const saved = this.overrides[id];
+ const state = saved === undefined ? OverrideState.DEFAULT : saved;
+ const flag = new FlagImpl(this, state, settings);
+ this.flags.set(id, flag);
+ return flag;
+ }
+
+ allFlags(): Flag[] {
+ const includeDevFlags =
+ ['127.0.0.1', '::1', 'localhost'].includes(window.location.hostname);
+ return [...this.flags.values()].filter(
+ flag => includeDevFlags || !flag.devOnly);
+ }
+
+ resetAll() {
+ for (const flag of this.flags.values()) {
+ flag.state = OverrideState.DEFAULT;
+ }
+ this.save();
+ }
+
+ load(): void {
+ const o = this.store.load();
+ if (isFlagOverrides(o)) {
+ this.overrides = o;
+ }
+ }
+
+ save(): void {
+ for (const flag of this.flags.values()) {
+ if (flag.isOverridden()) {
+ this.overrides[flag.id] = flag.state;
+ } else {
+ delete this.overrides[flag.id];
+ }
+ }
+
+ this.store.save(this.overrides);
+ }
+}
+
+export interface Flag {
+ // A unique identifier for this flag ("magicSorting")
+ readonly id: string;
+
+ // The name of the flag the user sees ("New track sorting algorithm")
+ readonly name: string;
+
+ // A longer description which is displayed to the user.
+ // "Sort tracks using an embedded tfLite model based on your expression
+ // while waiting for the trace to load."
+ readonly description: string;
+
+ // Whether the flag defaults to true or false.
+ // If !flag.isOverridden() then flag.get() === flag.defaultValue
+ readonly defaultValue: boolean;
+
+ // Get the current value of the flag.
+ get(): boolean;
+
+ // Override the flag and persist the new value.
+ set(value: boolean): void;
+
+ // If the flag has been overridden.
+ // Note: A flag can be overridden to its default value.
+ isOverridden(): boolean;
+
+ // Reset the flag to its default setting.
+ reset(): void;
+
+ // Get the current state of the flag.
+ overriddenState(): OverrideState;
+}
+
+class FlagImpl implements Flag {
+ registry: Flags;
+ state: OverrideState;
+
+ readonly id: string;
+ readonly name: string;
+ readonly description: string;
+ readonly defaultValue: boolean;
+ readonly devOnly: boolean;
+
+ constructor(registry: Flags, state: OverrideState, settings: FlagSettings) {
+ this.registry = registry;
+ this.id = settings.id;
+ this.state = state;
+ this.description = settings.description;
+ this.defaultValue = settings.defaultValue;
+ this.name = settings.name || settings.id;
+ this.devOnly = settings.devOnly || false;
+ }
+
+ get(): boolean {
+ switch (this.state) {
+ case OverrideState.TRUE:
+ return true;
+ case OverrideState.FALSE:
+ return false;
+ case OverrideState.DEFAULT:
+ default:
+ return this.defaultValue;
+ }
+ }
+
+ set(value: boolean): void {
+ const next = value ? OverrideState.TRUE : OverrideState.FALSE;
+ if (this.state === next) {
+ return;
+ }
+ this.state = next;
+ this.registry.save();
+ }
+
+ overriddenState(): OverrideState {
+ return this.state;
+ }
+
+ reset() {
+ this.state = OverrideState.DEFAULT;
+ this.registry.save();
+ }
+
+ isOverridden(): boolean {
+ return this.state !== OverrideState.DEFAULT;
+ }
+}
+
+class LocalStorageStore implements FlagStore {
+ static KEY = 'perfettoFeatureFlags';
+
+ load(): object {
+ const s = localStorage.getItem(LocalStorageStore.KEY);
+ let parsed: object;
+ try {
+ parsed = JSON.parse(s || '{}');
+ } catch (e) {
+ return {};
+ }
+ if (typeof parsed !== 'object' || parsed === null) {
+ return {};
+ }
+ return parsed;
+ }
+
+ save(o: object): void {
+ const s = JSON.stringify(o);
+ localStorage.setItem(LocalStorageStore.KEY, s);
+ }
+}
+
+export const FlagsForTesting = Flags;
+export const featureFlags = new Flags(new LocalStorageStore());
+
+export const PERF_SAMPLE_FLAG = featureFlags.register({
+ id: 'perfSampleFlamegraph',
+ name: 'Perf Sample Flamegraph',
+ description: 'Show flamegraph generated by a perf sample.',
+ defaultValue: true
+});
diff --git a/ui/src/common/feature_flags_unittest.ts b/ui/src/common/feature_flags_unittest.ts
new file mode 100644
index 000000000..d2cb97beb
--- /dev/null
+++ b/ui/src/common/feature_flags_unittest.ts
@@ -0,0 +1,118 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {FlagsForTesting as Flags, FlagStore} from './feature_flags';
+
+class TestFlagStore implements FlagStore {
+ o: object = {};
+
+ load(): object {
+ return this.o;
+ }
+
+ save(o: object): void {
+ this.o = o;
+ }
+}
+
+test('create flag', () => {
+ const flags = new Flags(new TestFlagStore());
+ const myFlag = flags.register({
+ id: 'myFlag',
+ defaultValue: false,
+ description: '',
+ });
+ expect(myFlag.get()).toEqual(false);
+ expect(myFlag.isOverridden()).toEqual(false);
+});
+
+test('registering the same flag twice is an error', () => {
+ const flags = new Flags(new TestFlagStore());
+ flags.register({
+ id: 'foo',
+ defaultValue: false,
+ description: '',
+ });
+ expect(() => flags.register({
+ id: 'foo',
+ defaultValue: false,
+ description: '',
+ })).toThrow('Flag with id "foo" is already registered.');
+});
+
+test('can override', () => {
+ const flags = new Flags(new TestFlagStore());
+ const foo = flags.register({
+ id: 'foo',
+ defaultValue: false,
+ description: '',
+ });
+ foo.set(true);
+ expect(foo.isOverridden()).toEqual(true);
+ expect(foo.get()).toEqual(true);
+});
+
+test('overrides are persisted', () => {
+ const store = new TestFlagStore();
+ const flagsA = new Flags(store);
+ const fooA = flagsA.register({
+ id: 'foo',
+ defaultValue: true,
+ description: 'some description',
+ });
+
+ fooA.set(true);
+
+ const flagsB = new Flags(store);
+ const fooB = flagsB.register({
+ id: 'foo',
+ defaultValue: false,
+ description: 'a new description',
+ });
+
+ expect(fooB.get()).toEqual(true);
+ expect(fooB.isOverridden()).toEqual(true);
+});
+
+test('flags can be reset', () => {
+ const flags = new Flags(new TestFlagStore());
+ const foo = flags.register({
+ id: 'foo',
+ defaultValue: false,
+ description: 'some description',
+ });
+
+ foo.set(false);
+ foo.reset();
+ expect(foo.get()).toEqual(false);
+ expect(foo.isOverridden()).toEqual(false);
+});
+
+test('corrupt store is ignored', () => {
+ class Store {
+ load(): object {
+ return {'foo': 'bad state'};
+ }
+
+ save(_: object): void {}
+ }
+ const flags = new Flags(new Store());
+ const foo = flags.register({
+ id: 'foo',
+ defaultValue: false,
+ description: 'some description',
+ });
+
+ expect(foo.isOverridden()).toEqual(false);
+});
diff --git a/ui/src/common/flamegraph_util.ts b/ui/src/common/flamegraph_util.ts
index f08342813..c8070ff2b 100644
--- a/ui/src/common/flamegraph_util.ts
+++ b/ui/src/common/flamegraph_util.ts
@@ -12,12 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {CallsiteInfo} from '../common/state';
+import {CallsiteInfo} from './state';
export const SPACE_MEMORY_ALLOCATED_NOT_FREED_KEY = 'SPACE';
export const ALLOC_SPACE_MEMORY_ALLOCATED_KEY = 'ALLOC_SPACE';
export const OBJECTS_ALLOCATED_NOT_FREED_KEY = 'OBJECTS';
export const OBJECTS_ALLOCATED_KEY = 'ALLOC_OBJECTS';
+export const PERF_SAMPLES_KEY = 'PERF_SAMPLES';
export const DEFAULT_VIEWING_OPTION = SPACE_MEMORY_ALLOCATED_NOT_FREED_KEY;
@@ -103,7 +104,8 @@ function copyCallsite(callsite: CallsiteInfo): CallsiteInfo {
mapping: callsite.mapping,
selfSize: callsite.selfSize,
merged: callsite.merged,
- highlighted: callsite.highlighted
+ highlighted: callsite.highlighted,
+ location: callsite.location
};
}
diff --git a/ui/src/common/http_rpc_engine.ts b/ui/src/common/http_rpc_engine.ts
index bd1f6dd6a..436dd42d8 100644
--- a/ui/src/common/http_rpc_engine.ts
+++ b/ui/src/common/http_rpc_engine.ts
@@ -12,133 +12,73 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {defer, Deferred} from '../base/deferred';
import {fetchWithTimeout} from '../base/http_utils';
-import {assertExists, assertTrue} from '../base/logging';
+import {assertExists} from '../base/logging';
import {StatusResult} from '../common/protos';
import {Engine, LoadingTracker} from './engine';
export const RPC_URL = 'http://127.0.0.1:9001/';
+export const WS_URL = 'ws://127.0.0.1:9001/websocket';
+
const RPC_CONNECT_TIMEOUT_MS = 2000;
export interface HttpRpcState {
connected: boolean;
- loadedTraceName?: string;
+ status?: StatusResult;
failure?: string;
}
-interface QueuedRequest {
- methodName: string;
- reqData?: Uint8Array;
- resp: Deferred<Uint8Array>;
- id: number;
-}
-
export class HttpRpcEngine extends Engine {
readonly id: string;
- private nextReqId = 0;
- private requestQueue = new Array<QueuedRequest>();
- private pendingRequest?: QueuedRequest = undefined;
errorHandler: (err: string) => void = () => {};
+ private requestQueue = new Array<Uint8Array>();
+ private websocket?: WebSocket;
+ private connected = false;
constructor(id: string, loadingTracker?: LoadingTracker) {
super(loadingTracker);
this.id = id;
}
- async parse(data: Uint8Array): Promise<void> {
- await this.enqueueRequest('parse', data);
- }
-
- async notifyEof(): Promise<void> {
- await this.enqueueRequest('notify_eof');
- }
-
- async restoreInitialTables(): Promise<void> {
- await this.enqueueRequest('restore_initial_tables');
- }
-
- rawQuery(rawQueryArgs: Uint8Array): Promise<Uint8Array> {
- return this.enqueueRequest('raw_query', rawQueryArgs);
- }
-
- rawComputeMetric(rawComputeMetricArgs: Uint8Array): Promise<Uint8Array> {
- return this.enqueueRequest('compute_metric', rawComputeMetricArgs);
- }
-
- async enableMetatrace(): Promise<void> {
- await this.enqueueRequest('enable_metatrace');
- }
-
- disableAndReadMetatrace(): Promise<Uint8Array> {
- return this.enqueueRequest('disable_and_read_metatrace');
- }
+ rpcSendRequestBytes(data: Uint8Array): void {
+ if (this.websocket === undefined) {
+ this.websocket = new WebSocket(WS_URL);
+ this.websocket.onopen = () => this.onWebsocketConnected();
+ this.websocket.onmessage = (e) => this.onWebsocketMessage(e);
+ this.websocket.onclose = (e) =>
+ this.errorHandler(`Websocket closed (${e.code}: ${e.reason})`);
+ this.websocket.onerror = (e) =>
+ this.errorHandler(`WebSocket error: ${e}`);
+ }
- enqueueRequest(methodName: string, data?: Uint8Array): Promise<Uint8Array> {
- const resp = defer<Uint8Array>();
- const req:
- QueuedRequest = {methodName, reqData: data, resp, id: this.nextReqId++};
- if (this.pendingRequest === undefined) {
- this.beginFetch(req);
+ if (this.connected) {
+ this.websocket.send(data);
} else {
- this.requestQueue.push(req);
+ this.requestQueue.push(data); // onWebsocketConnected() will flush this.
}
- return resp;
}
- private beginFetch(req: QueuedRequest) {
- assertTrue(this.pendingRequest === undefined);
- this.pendingRequest = req;
- const methodName = req.methodName.toLowerCase();
- // Deliberately not using fetchWithTimeout() here. These queries can be
- // arbitrarily long.
- // Deliberately not setting cache: no-cache. Doing so invalidates also the
- // CORS pre-flight responses, causing one OPTIONS request for each POST.
- // no-cache is also useless because trace-processor's replies are already
- // marked as no-cache and browsers generally already assume that POST
- // requests are not idempotent.
- fetch(RPC_URL + methodName, {
- method: 'post',
- headers: {
- 'Content-Type': 'application/x-protobuf',
- 'X-Seq-Id': `${req.id}`, // Used only for debugging.
- },
- body: req.reqData || new Uint8Array(),
- })
- .then(resp => this.endFetch(resp, req.id))
- .catch(err => this.errorHandler(err));
- }
-
- private endFetch(resp: Response, expectedReqId: number) {
- const req = assertExists(this.pendingRequest);
- this.pendingRequest = undefined;
- assertTrue(expectedReqId === req.id);
- if (resp.status !== 200) {
- req.resp.reject(`HTTP ${resp.status} - ${resp.statusText}`);
- return;
+ private onWebsocketConnected() {
+ for (;;) {
+ const queuedMsg = this.requestQueue.shift();
+ if (queuedMsg === undefined) break;
+ assertExists(this.websocket).send(queuedMsg);
}
- resp.arrayBuffer().then(arrBuf => {
- // Note: another request can sneak in via enqueueRequest() between the
- // arrayBuffer() call and this continuation. At this point
- // this.pendingRequest might be set again.
- // If not (the most common case) submit the next queued request, if any.
- this.maybeSubmitNextQueuedRequest();
- req.resp.resolve(new Uint8Array(arrBuf));
- });
+ this.connected = true;
}
- private maybeSubmitNextQueuedRequest() {
- if (this.pendingRequest === undefined && this.requestQueue.length > 0) {
- this.beginFetch(this.requestQueue.shift()!);
- }
+ private onWebsocketMessage(e: MessageEvent) {
+ assertExists(e.data as Blob).arrayBuffer().then(buf => {
+ super.onRpcResponseBytes(new Uint8Array(buf));
+ });
}
static async checkConnection(): Promise<HttpRpcState> {
const httpRpcState: HttpRpcState = {connected: false};
console.info(
`It's safe to ignore the ERR_CONNECTION_REFUSED on ${RPC_URL} below. ` +
- `That might happen while probing the exernal native accelerator. The ` +
+ `That might happen while probing the external native accelerator. The ` +
`error is non-fatal and unlikely to be the culprit for any UI bug.`);
try {
const resp = await fetchWithTimeout(
@@ -149,11 +89,8 @@ export class HttpRpcEngine extends Engine {
httpRpcState.failure = `${resp.status} - ${resp.statusText}`;
} else {
const buf = new Uint8Array(await resp.arrayBuffer());
- const status = StatusResult.decode(buf);
httpRpcState.connected = true;
- if (status.loadedTraceName) {
- httpRpcState.loadedTraceName = status.loadedTraceName;
- }
+ httpRpcState.status = StatusResult.decode(buf);
}
} catch (err) {
httpRpcState.failure = `${err}`;
diff --git a/ui/src/common/immer_init.ts b/ui/src/common/immer_init.ts
new file mode 100644
index 000000000..9b8817c61
--- /dev/null
+++ b/ui/src/common/immer_init.ts
@@ -0,0 +1,29 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use size file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {enableMapSet, enablePatches, setAutoFreeze} from 'immer';
+
+export function initializeImmerJs() {
+ enablePatches();
+
+ // TODO(primiano): re-enable this, requires fixing some bugs that this bubbles
+ // up. This is a new feature of immer which freezes object after a produce().
+ // Unfortunately we piled up a bunch of bugs where we shallow-copy objects
+ // from the global state (which is frozen) and later try to update the copies.
+ // By doing so, we accidentally the local copy of global state, which is
+ // supposed to be immutable.
+ setAutoFreeze(false);
+
+ enableMapSet();
+}
diff --git a/ui/src/common/pivot_table_common.ts b/ui/src/common/pivot_table_common.ts
new file mode 100644
index 000000000..ac463e5b1
--- /dev/null
+++ b/ui/src/common/pivot_table_common.ts
@@ -0,0 +1,186 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {getHiddenPivotAlias} from './pivot_table_query_generator';
+import {Row} from './query_result';
+
+export const AVAILABLE_TABLES = ['slice'];
+export const AVAILABLE_AGGREGATIONS = ['COUNT', 'SUM', 'AVG', 'MIN', 'MAX'];
+export const WHERE_FILTERS = ['slice.dur != -1'];
+export const SLICE_STACK_HELPER_COLUMNS =
+ ['depth', 'stack_id', 'parent_stack_id'];
+export const SLICE_STACK_COLUMN = 'name (stack)';
+export const DEFAULT_PIVOT_TABLE_ID = 'pivot-table';
+export const SLICE_AGGREGATION_PIVOT_TABLE_ID = 'pivot-table-slices';
+
+export interface AggregationAttrs {
+ tableName: string;
+ columnName: string;
+ aggregation: string;
+ order: string;
+}
+
+export interface PivotAttrs {
+ tableName: string;
+ columnName: string;
+ isStackPivot: boolean;
+}
+
+export interface TableAttrs {
+ tableName: string;
+ columns: string[];
+}
+
+export interface ColumnAttrs {
+ name: string;
+ index: number;
+ tableName: string;
+ columnName: string;
+ aggregation?: string;
+ order?: string;
+ isStackColumn: boolean;
+}
+
+export interface RowAttrs {
+ row: Row;
+ expandableColumns: Set<string>; // Columns at which the row can be expanded.
+ expandedRows: Map<string, {
+ isExpanded: boolean,
+ rows: RowAttrs[]
+ }>; // Contains the expanded rows of each expanded expandableColumn.
+ whereFilters: Map<string, string>; // Where filters of each column that
+ // joins the row with its parent.
+ loadingColumn?: string;
+ depth: number;
+}
+
+export interface SubQueryAttrs {
+ rowIndices: number[];
+ columnIdx: number;
+ value: string;
+ expandedRowColumns: string[];
+}
+
+export interface SubQueryAttrs {
+ rowIndices: number[];
+ columnIdx: number;
+ value: string;
+}
+
+export interface PivotTableQueryResponse {
+ columns: ColumnAttrs[];
+ error?: string;
+ durationMs: number;
+ rows: RowAttrs[];
+ totalAggregations?: Row;
+}
+
+// Determine if the column provided is a stack column that can be expanded
+// into descendants.
+export function isStackPivot(tableName: string, columnName: string) {
+ if (tableName === 'slice' && columnName === SLICE_STACK_COLUMN) {
+ return true;
+ }
+ return false;
+}
+
+// Get the helper columns that are needed to expand a stack pivot.
+export function getHiddenStackHelperColumns(pivot: PivotAttrs) {
+ const hiddenColumns: Array<{pivotAttrs: PivotAttrs, columnAlias: string}> =
+ [];
+ if (pivot.tableName === 'slice') {
+ for (const column of SLICE_STACK_HELPER_COLUMNS) {
+ const pivotAttrs = {
+ tableName: pivot.tableName,
+ columnName: column,
+ isStackPivot: false
+ };
+ hiddenColumns.push(
+ {pivotAttrs, columnAlias: getHiddenPivotAlias(pivotAttrs)});
+ }
+ }
+ return hiddenColumns;
+}
+
+// Removing unnecessary columns from table and adding stack column if it exists.
+export function removeHiddenAndAddStackColumns(
+ tableName: string, columns: string[]) {
+ if (tableName === 'slice') {
+ // Removing "cat" and "slice_id" to maintain the original schema of the
+ // slice table that's compatible with descendant_slice_by_stack table.
+ columns = columns.filter(
+ column => ['stack_id', 'parent_stack_id', 'cat', 'slice_id'].includes(
+ column) === false);
+ columns.push(SLICE_STACK_COLUMN);
+ }
+ return columns;
+}
+
+// Get a list of tables that include the descendants that need to be queried.
+export function getDescendantsTables(pivots: PivotAttrs[], stackId: string) {
+ const descendantsTables = [...AVAILABLE_TABLES];
+ let descendantsTable = 'undefined_table';
+ let replaceIdx = -1;
+ if (pivots.length > 0 && pivots[0].tableName === 'slice') {
+ // Replace slice table with descendants table.
+ descendantsTable = `descendant_slice_by_stack(${stackId}) AS slice`;
+ replaceIdx = descendantsTables.indexOf('slice');
+ if (replaceIdx === -1) {
+ throw Error('Slice table not found.');
+ }
+ }
+ if (pivots.length === 0 ||
+ !isStackPivot(pivots[0].tableName, pivots[0].columnName) ||
+ replaceIdx === -1) {
+ throw Error('Invalid Arguments to "getDescendantsTables"');
+ }
+ descendantsTables[replaceIdx] = descendantsTable;
+ return descendantsTables;
+}
+
+// Get the stack id column in the stack pivot table.
+export function getStackColumn(pivot: PivotAttrs) {
+ if (pivot.tableName === 'slice') {
+ return {tableName: 'slice', columnName: 'stack_id', isStackPivot: false};
+ }
+ throw Error('"getStackColumn" called on pivot that is not a stack column.');
+}
+
+// Get the parent stack id column in the stack pivot table.
+export function getParentStackColumn(pivot: PivotAttrs) {
+ if (pivot.tableName === 'slice') {
+ return {
+ tableName: 'slice',
+ columnName: 'parent_stack_id',
+ isStackPivot: false
+ };
+ }
+ throw Error(
+ '"getParentStackColumn" called on pivot that is not a stack column.');
+}
+
+// Get the depth column in the stack pivot table.
+export function getStackDepthColumn(pivot: PivotAttrs) {
+ if (pivot.tableName === 'slice') {
+ return {tableName: 'slice', columnName: 'depth', isStackPivot: false};
+ }
+ throw Error(
+ '"getStackDepthColumn" called on pivot that is not a stack column.');
+}
+
+// Get a where filter that restricts the query by the given stack id.
+export function getParentStackWhereFilter(pivot: PivotAttrs, stackId: string) {
+ const stackColumn = getStackColumn(pivot);
+ return `${stackColumn.tableName}.${stackColumn.columnName} = ${stackId}`;
+}
diff --git a/ui/src/common/pivot_table_query_generator.ts b/ui/src/common/pivot_table_query_generator.ts
new file mode 100644
index 000000000..dd6f71d07
--- /dev/null
+++ b/ui/src/common/pivot_table_query_generator.ts
@@ -0,0 +1,320 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {
+ AggregationAttrs,
+ AVAILABLE_TABLES,
+ getHiddenStackHelperColumns,
+ getParentStackWhereFilter,
+ getStackColumn,
+ getStackDepthColumn,
+ PivotAttrs,
+} from './pivot_table_common';
+
+export function getPivotAlias(pivot: PivotAttrs): string {
+ return `${pivot.tableName} ${pivot.columnName}`;
+}
+
+export function getHiddenPivotAlias(pivot: PivotAttrs) {
+ return getPivotAlias(pivot) + ' (hidden)';
+}
+
+export function getAggregationAlias(aggregation: AggregationAttrs): string {
+ return `${aggregation.tableName} ${aggregation.columnName} (${
+ aggregation.aggregation})`;
+}
+
+export function getSqlPivotAlias(pivot: PivotAttrs): string {
+ return `"${getPivotAlias(pivot)}"`;
+}
+
+export function getSqlHiddenPivotAlias(pivot: PivotAttrs): string {
+ return `"${getHiddenPivotAlias(pivot)}"`;
+}
+
+export function getSqlAggregationAlias(aggregation: AggregationAttrs): string {
+ return `"${getAggregationAlias(aggregation)}"`;
+}
+
+export function getAggregationOverStackAlias(aggregation: AggregationAttrs):
+ string {
+ return `${getAggregationAlias(aggregation)} (stack)`;
+}
+
+export function getSqlAggregationOverStackAlias(aggregation: AggregationAttrs):
+ string {
+ return `"${getAggregationOverStackAlias(aggregation)}"`;
+}
+
+export function getTotalAggregationAlias(aggregation: AggregationAttrs):
+ string {
+ return `${getAggregationAlias(aggregation)} (total)`;
+}
+
+export function getSqlTotalAggregationAlias(aggregation: AggregationAttrs):
+ string {
+ return `"${getTotalAggregationAlias(aggregation)}"`;
+}
+
+// Returns an array of pivot aliases along with any additional pivot aliases.
+export function getSqlAliasedPivotColumns(pivots: PivotAttrs[]): string[] {
+ const pivotCols = [];
+ for (const pivot of pivots) {
+ pivotCols.push(getSqlPivotAlias(pivot));
+ if (pivot.isStackPivot) {
+ pivotCols.push(...getHiddenStackHelperColumns(pivot).map(
+ column => `"${column.columnAlias}"`));
+ }
+ }
+ return pivotCols;
+}
+
+export function getAliasedPivotColumns(pivots: PivotAttrs[]) {
+ const pivotCols: Array<{pivotAttrs: PivotAttrs, columnAlias: string}> = [];
+ for (const pivot of pivots) {
+ pivotCols.push({pivotAttrs: pivot, columnAlias: getPivotAlias(pivot)});
+ if (pivot.isStackPivot) {
+ pivotCols.push(...getHiddenStackHelperColumns(pivot));
+ }
+ }
+ return pivotCols;
+}
+
+// Returns an array of aggregation aliases along with total aggregations if
+// necessary.
+function getSqlAliasedAggregationsColumns(
+ aggregations: AggregationAttrs[],
+ hasPivotsSelected: boolean,
+ isStackQuery: boolean): string[] {
+ const aggCols =
+ aggregations.map(aggregation => getSqlAggregationAlias(aggregation));
+
+ if (hasPivotsSelected) {
+ aggCols.push(...aggregations.map(
+ aggregation => getSqlTotalAggregationAlias(aggregation)));
+ }
+
+ if (isStackQuery) {
+ aggCols.push(...aggregations.map(
+ aggregation => getSqlAggregationOverStackAlias(aggregation)));
+ }
+ return aggCols;
+}
+
+export class PivotTableQueryGenerator {
+ // Generates a query that selects all pivots and aggregations and joins any
+ // tables needed by them together. All pivots are renamed into the format
+ // tableName columnName and all aggregations are renamed into
+ // tableName columnName (aggregation) (see getPivotAlias or
+ // getAggregationAlias).
+ private generateJoinQuery(
+ pivots: PivotAttrs[], aggregations: AggregationAttrs[],
+ whereFilters: string[], joinTables: string[]): string {
+
+ const pivotCols = [];
+ for (const pivot of pivots) {
+ if (pivot.isStackPivot) {
+ pivotCols.push(
+ `${pivot.tableName}.name AS ` +
+ `${getSqlPivotAlias(pivot)}`);
+
+ pivotCols.push(...getHiddenStackHelperColumns(pivot).map(
+ column => `${column.pivotAttrs.tableName}.${
+ column.pivotAttrs.columnName} AS "${column.columnAlias}"`));
+ } else {
+ pivotCols.push(
+ `${pivot.tableName}.${pivot.columnName} AS ` +
+ `${getSqlPivotAlias(pivot)}`);
+ }
+ }
+
+ const aggCols = [];
+ for (const aggregation of aggregations) {
+ aggCols.push(
+ `${aggregation.tableName}.${aggregation.columnName} AS ` +
+ `${getSqlAggregationAlias(aggregation)}`);
+ }
+
+ return `
+ SELECT
+ ${pivotCols.concat(aggCols).join(',\n ')}
+ FROM
+ ${joinTables.join(',\n ')}
+ WHERE
+ ${whereFilters.join(' AND\n ')}
+ `;
+ }
+
+ // Partitions the aggregations from the subquery generateJoinQuery over
+ // all sets of appended pivots ({pivot1}, {pivot1, pivot2}, etc).
+ private generateAggregationQuery(
+ pivots: PivotAttrs[], aggregations: AggregationAttrs[],
+ whereFilters: string[], joinTables: string[],
+ isStackQuery: boolean): string {
+ // No need for this query if there are no aggregations.
+ if (aggregations.length === 0) {
+ return this.generateJoinQuery(
+ pivots, aggregations, whereFilters, joinTables);
+ }
+
+ const pivotCols = getSqlAliasedPivotColumns(pivots);
+ let partitionByPivotCols = pivotCols;
+ if (pivots.length > 0 && pivots[0].isStackPivot) {
+ partitionByPivotCols = [];
+ partitionByPivotCols.push(
+ getSqlHiddenPivotAlias(getStackColumn(pivots[0])));
+ partitionByPivotCols.push(...getSqlAliasedPivotColumns(pivots.slice(1)));
+ }
+
+ const aggCols = [];
+ for (const aggregation of aggregations) {
+ const aggColPrefix =
+ `${aggregation.aggregation}(${getSqlAggregationAlias(aggregation)})`;
+
+ if (pivots.length === 0) {
+ // Don't partition over pivots if there are no pivots.
+ aggCols.push(
+ `${aggColPrefix} AS ${getSqlAggregationAlias(aggregation)}`);
+ continue;
+ }
+
+ // Add total aggregations column.
+ aggCols.push(
+ `${aggColPrefix} OVER () AS ` +
+ `${getSqlTotalAggregationAlias(aggregation)}`);
+
+ // Add aggregation over stack column.
+ if (isStackQuery) {
+ aggCols.push(
+ `${aggColPrefix} OVER (PARTITION BY ` +
+ `${partitionByPivotCols[0]}) AS ` +
+ `${getSqlAggregationOverStackAlias(aggregation)}`);
+ }
+
+ aggCols.push(
+ `${aggColPrefix} OVER (PARTITION BY ` +
+ `${partitionByPivotCols.join(', ')}) AS ` +
+ `${getSqlAggregationAlias(aggregation)}`);
+ }
+
+ return `
+ SELECT
+ ${pivotCols.concat(aggCols).join(',\n ')}
+ FROM (
+ ${
+ this.generateJoinQuery(pivots, aggregations, whereFilters, joinTables)}
+ )
+ `;
+ }
+
+ // Takes a list of pivots and aggregations and generates a query that
+ // extracts all pivots and aggregation partitions and groups by all
+ // columns and orders by each aggregation as requested.
+ private generateQueryImpl(
+ pivots: PivotAttrs[], aggregations: AggregationAttrs[],
+ whereFilters: string[], joinTables: string[], isStackQuery: boolean,
+ orderBy: boolean): string {
+ // No need to generate query if there is no selected pivots or
+ // aggregations.
+ if (pivots.length === 0 && aggregations.length === 0) {
+ return '';
+ }
+
+
+ const pivotCols = getSqlAliasedPivotColumns(pivots);
+ const aggCols = getSqlAliasedAggregationsColumns(
+ aggregations,
+ /* has_pivots_selected = */ pivots.length > 0,
+ isStackQuery);
+
+ const aggregationsGroupBy =
+ aggregations.map(aggregation => getSqlAggregationAlias(aggregation));
+
+ let query = `
+ SELECT
+ ${pivotCols.concat(aggCols).join(',\n ')}
+ FROM (
+ ${
+ this.generateAggregationQuery(
+ pivots, aggregations, whereFilters, joinTables, isStackQuery)}
+ )
+ GROUP BY
+ ${pivotCols.concat(aggregationsGroupBy).join(', ')}
+ `;
+
+ const pivotsOrderBy = [];
+
+ // Sort by depth first if generating a stack query, to ensure that the
+ // parents appear first before their children and allow us to nest the
+ // results into an expandable structure.
+ if (orderBy && isStackQuery) {
+ pivotsOrderBy.push(
+ `${getSqlHiddenPivotAlias(getStackDepthColumn(pivots[0]))} ASC`);
+ }
+
+ // For each aggregation we order by either 'DESC' or 'ASC' as
+ // requested (DESC by default).
+ const orderString = (aggregation: AggregationAttrs) =>
+ `${getSqlAggregationAlias(aggregation)} ` +
+ `${aggregation.order}`;
+ const aggregationsOrderBy =
+ aggregations.map(aggregation => orderString(aggregation));
+
+ if (orderBy && pivotsOrderBy.length + aggregationsOrderBy.length > 0) {
+ query += `
+ ORDER BY
+ ${pivotsOrderBy.concat(aggregationsOrderBy).join(', ')}
+ `;
+ }
+ return query;
+ }
+
+ generateQuery(
+ pivots: PivotAttrs[], aggregations: AggregationAttrs[],
+ whereFilters: string[], joinTables: string[]) {
+ return this.generateQueryImpl(
+ pivots,
+ aggregations,
+ whereFilters,
+ joinTables,
+ /* is_stack_query = */ false,
+ /* order_by = */ true);
+ }
+
+ generateStackQuery(
+ pivots: PivotAttrs[], aggregations: AggregationAttrs[],
+ whereFilters: string[], joinTables: string[], stackId: string) {
+ const stackQuery = this.generateQueryImpl(
+ pivots,
+ aggregations,
+ whereFilters,
+ joinTables,
+ /* is_stack_query = */ true,
+ /* order_by = */ true);
+
+ // Query the next column rows for the parent row.
+ if (pivots.length > 1) {
+ const stackPivot = pivots[0];
+ const currStackQuery = this.generateQueryImpl(
+ pivots,
+ aggregations,
+ whereFilters.concat(getParentStackWhereFilter(stackPivot, stackId)),
+ AVAILABLE_TABLES,
+ /* is_stack_query = */ true,
+ /* order_by = */ false);
+ return `${currStackQuery} UNION ALL ${stackQuery}`;
+ }
+ return stackQuery;
+ }
+} \ No newline at end of file
diff --git a/ui/src/common/pivot_table_query_generator_unittest.ts b/ui/src/common/pivot_table_query_generator_unittest.ts
new file mode 100644
index 000000000..42b95af03
--- /dev/null
+++ b/ui/src/common/pivot_table_query_generator_unittest.ts
@@ -0,0 +1,306 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {
+ AggregationAttrs,
+ PivotAttrs,
+ SLICE_STACK_COLUMN,
+ WHERE_FILTERS,
+} from './pivot_table_common';
+import {PivotTableQueryGenerator} from './pivot_table_query_generator';
+
+const TABLES = ['slice'];
+
+// Normalize query for comparison by replacing repeated whitespace characters
+// with a single space.
+function normalize(s: string): string {
+ return s.replace(/\s+/g, ' ');
+}
+
+function expectQueryEqual(actual: string, expected: string) {
+ expect(normalize(actual)).toEqual(normalize(expected));
+}
+
+test('Generate query with pivots and aggregations', () => {
+ const pivotTableQueryGenerator = new PivotTableQueryGenerator();
+ const selectedPivots: PivotAttrs[] = [
+ {tableName: 'slice', columnName: 'type', isStackPivot: false},
+ {tableName: 'slice', columnName: 'id', isStackPivot: false}
+ ];
+ const selectedAggregations: AggregationAttrs[] = [
+ {aggregation: 'SUM', tableName: 'slice', columnName: 'dur', order: 'DESC'}
+ ];
+ const expectedQuery = `
+ SELECT
+ "slice type",
+ "slice id",
+ "slice dur (SUM)",
+ "slice dur (SUM) (total)"
+ FROM (
+ SELECT
+ "slice type",
+ "slice id",
+ SUM("slice dur (SUM)") OVER () AS "slice dur (SUM) (total)",
+ SUM("slice dur (SUM)")
+ OVER (PARTITION BY "slice type", "slice id")
+ AS "slice dur (SUM)"
+ FROM (
+ SELECT
+ slice.type AS "slice type",
+ slice.id AS "slice id",
+ slice.dur AS "slice dur (SUM)"
+ FROM
+ slice
+ WHERE
+ slice.dur != -1
+ )
+ )
+ GROUP BY "slice type", "slice id", "slice dur (SUM)"
+ ORDER BY "slice dur (SUM)" DESC
+ `;
+ expectQueryEqual(
+ pivotTableQueryGenerator.generateQuery(
+ selectedPivots, selectedAggregations, WHERE_FILTERS, TABLES),
+ expectedQuery);
+});
+
+test('Generate query with pivots', () => {
+ const pivotTableQueryGenerator = new PivotTableQueryGenerator();
+ const selectedPivots: PivotAttrs[] = [
+ {tableName: 'slice', columnName: 'type', isStackPivot: false},
+ {tableName: 'slice', columnName: 'id', isStackPivot: false}
+ ];
+ const selectedAggregations: AggregationAttrs[] = [];
+ const expectedQuery = `
+ SELECT
+ "slice type",
+ "slice id"
+ FROM (
+ SELECT
+ slice.type AS "slice type",
+ slice.id AS "slice id"
+ FROM
+ slice
+ WHERE
+ slice.dur != -1
+ )
+ GROUP BY "slice type", "slice id"
+ `;
+ expectQueryEqual(
+ pivotTableQueryGenerator.generateQuery(
+ selectedPivots, selectedAggregations, WHERE_FILTERS, TABLES),
+ expectedQuery);
+});
+
+test('Generate query with aggregations', () => {
+ const pivotTableQueryGenerator = new PivotTableQueryGenerator();
+ const selectedPivots: PivotAttrs[] = [];
+ const selectedAggregations: AggregationAttrs[] = [
+ {aggregation: 'SUM', tableName: 'slice', columnName: 'dur', order: 'DESC'},
+ {aggregation: 'MAX', tableName: 'slice', columnName: 'dur', order: 'ASC'}
+ ];
+ const expectedQuery = `
+ SELECT
+ "slice dur (SUM)",
+ "slice dur (MAX)"
+ FROM (
+ SELECT
+ SUM("slice dur (SUM)") AS "slice dur (SUM)",
+ MAX("slice dur (MAX)") AS "slice dur (MAX)"
+ FROM (
+ SELECT
+ slice.dur AS "slice dur (SUM)",
+ slice.dur AS "slice dur (MAX)"
+ FROM
+ slice
+ WHERE
+ slice.dur != -1
+ )
+ )
+ GROUP BY "slice dur (SUM)", "slice dur (MAX)"
+ ORDER BY "slice dur (SUM)" DESC, "slice dur (MAX)" ASC
+ `;
+ expectQueryEqual(
+ pivotTableQueryGenerator.generateQuery(
+ selectedPivots, selectedAggregations, WHERE_FILTERS, TABLES),
+ expectedQuery);
+});
+
+test('Generate a query with stack pivot', () => {
+ const pivotTableQueryGenerator = new PivotTableQueryGenerator();
+ const selectedPivots: PivotAttrs[] = [
+ {tableName: 'slice', columnName: SLICE_STACK_COLUMN, isStackPivot: true},
+ {tableName: 'slice', columnName: 'category', isStackPivot: false}
+ ];
+ const selectedAggregations: AggregationAttrs[] = [
+ {aggregation: 'COUNT', tableName: 'slice', columnName: 'id', order: 'DESC'},
+ ];
+ const expectedQuery = `
+ SELECT
+ "slice name (stack)",
+ "slice depth (hidden)",
+ "slice stack_id (hidden)",
+ "slice parent_stack_id (hidden)",
+ "slice category",
+ "slice id (COUNT)",
+ "slice id (COUNT) (total)"
+ FROM (
+ SELECT
+ "slice name (stack)",
+ "slice depth (hidden)",
+ "slice stack_id (hidden)",
+ "slice parent_stack_id (hidden)",
+ "slice category",
+ COUNT("slice id (COUNT)") OVER () AS "slice id (COUNT) (total)",
+ COUNT("slice id (COUNT)")
+ OVER (PARTITION BY "slice stack_id (hidden)", "slice category")
+ AS "slice id (COUNT)"
+ FROM (
+ SELECT
+ slice.name AS "slice name (stack)",
+ slice.depth AS "slice depth (hidden)",
+ slice.stack_id AS "slice stack_id (hidden)",
+ slice.parent_stack_id AS "slice parent_stack_id (hidden)",
+ slice.category AS "slice category",
+ slice.id AS "slice id (COUNT)"
+ FROM
+ slice
+ WHERE
+ slice.dur != -1
+ )
+ )
+ GROUP BY "slice name (stack)",
+ "slice depth (hidden)",
+ "slice stack_id (hidden)",
+ "slice parent_stack_id (hidden)",
+ "slice category",
+ "slice id (COUNT)"
+ ORDER BY "slice id (COUNT)" DESC
+ `;
+ expectQueryEqual(
+ pivotTableQueryGenerator.generateQuery(
+ selectedPivots, selectedAggregations, WHERE_FILTERS, TABLES),
+ expectedQuery);
+});
+
+test('Generate a descendant stack query', () => {
+ const pivotTableQueryGenerator = new PivotTableQueryGenerator();
+ const selectedPivots: PivotAttrs[] = [
+ {tableName: 'slice', columnName: SLICE_STACK_COLUMN, isStackPivot: true},
+ ];
+ const selectedAggregations: AggregationAttrs[] = [];
+ const expectedQuery = `
+ SELECT
+ "slice name (stack)",
+ "slice depth (hidden)",
+ "slice stack_id (hidden)",
+ "slice parent_stack_id (hidden)"
+ FROM (
+ SELECT
+ slice.name AS "slice name (stack)",
+ slice.depth AS "slice depth (hidden)",
+ slice.stack_id AS "slice stack_id (hidden)",
+ slice.parent_stack_id AS "slice parent_stack_id (hidden)"
+ FROM
+ descendant_slice_by_stack(stack_id) AS slice
+ WHERE
+ slice.dur != -1
+ )
+ GROUP BY "slice name (stack)",
+ "slice depth (hidden)",
+ "slice stack_id (hidden)",
+ "slice parent_stack_id (hidden)"
+ ORDER BY "slice depth (hidden)" ASC
+ `;
+
+ const table = ['descendant_slice_by_stack(stack_id) AS slice'];
+ expectQueryEqual(
+ pivotTableQueryGenerator.generateStackQuery(
+ selectedPivots,
+ selectedAggregations,
+ WHERE_FILTERS,
+ table,
+ /* stack_id = */ 'stack_id'),
+ expectedQuery);
+});
+
+test('Generate a descendant stack query with another pivot', () => {
+ const pivotTableQueryGenerator = new PivotTableQueryGenerator();
+ const selectedPivots: PivotAttrs[] = [
+ {tableName: 'slice', columnName: SLICE_STACK_COLUMN, isStackPivot: true},
+ {tableName: 'slice', columnName: 'category', isStackPivot: false}
+ ];
+ const selectedAggregations: AggregationAttrs[] = [];
+ const expectedQuery = `
+ SELECT
+ "slice name (stack)",
+ "slice depth (hidden)",
+ "slice stack_id (hidden)",
+ "slice parent_stack_id (hidden)",
+ "slice category"
+ FROM (
+ SELECT
+ slice.name AS "slice name (stack)",
+ slice.depth AS "slice depth (hidden)",
+ slice.stack_id AS "slice stack_id (hidden)",
+ slice.parent_stack_id AS "slice parent_stack_id (hidden)",
+ slice.category AS "slice category"
+ FROM
+ slice
+ WHERE
+ slice.dur != -1 AND
+ slice.stack_id = stack_id
+ )
+ GROUP BY "slice name (stack)",
+ "slice depth (hidden)",
+ "slice stack_id (hidden)",
+ "slice parent_stack_id (hidden)",
+ "slice category"
+ UNION ALL
+ SELECT
+ "slice name (stack)",
+ "slice depth (hidden)",
+ "slice stack_id (hidden)",
+ "slice parent_stack_id (hidden)",
+ "slice category"
+ FROM (
+ SELECT
+ slice.name AS "slice name (stack)",
+ slice.depth AS "slice depth (hidden)",
+ slice.stack_id AS "slice stack_id (hidden)",
+ slice.parent_stack_id AS "slice parent_stack_id (hidden)",
+ slice.category AS "slice category"
+ FROM
+ descendant_slice_by_stack(stack_id) AS slice
+ WHERE
+ slice.dur != -1
+ )
+ GROUP BY "slice name (stack)",
+ "slice depth (hidden)",
+ "slice stack_id (hidden)",
+ "slice parent_stack_id (hidden)",
+ "slice category"
+ ORDER BY "slice depth (hidden)" ASC
+ `;
+
+ const table = ['descendant_slice_by_stack(stack_id) AS slice'];
+ expectQueryEqual(
+ pivotTableQueryGenerator.generateStackQuery(
+ selectedPivots,
+ selectedAggregations,
+ WHERE_FILTERS,
+ table,
+ /* stack_id = */ 'stack_id'),
+ expectedQuery);
+});
diff --git a/ui/src/common/proto_ring_buffer.ts b/ui/src/common/proto_ring_buffer.ts
new file mode 100644
index 000000000..b03c1c9dc
--- /dev/null
+++ b/ui/src/common/proto_ring_buffer.ts
@@ -0,0 +1,156 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {assertTrue} from '../base/logging';
+
+// This class is the TypeScript equivalent of the identically-named C++ class in
+// //protozero/proto_ring_buffer.h. See comments in that header for a detailed
+// description. The architecture is identical.
+
+const kGrowBytes = 128 * 1024;
+const kMaxMsgSize = 64 * 1024 * 1024;
+
+export class ProtoRingBuffer {
+ private buf = new Uint8Array(kGrowBytes);
+ private fastpath?: Uint8Array;
+ private rd = 0;
+ private wr = 0;
+
+ // The caller must call ReadMessage() after each append() call.
+ // The |data| might be either copied in the internal ring buffer or returned
+ // (% subarray()) to the next ReadMessage() call.
+ append(data: Uint8Array) {
+ assertTrue(this.wr <= this.buf.length);
+ assertTrue(this.rd <= this.wr);
+
+ // If the last call to ReadMessage() consumed all the data in the buffer and
+ // there are no incomplete messages pending, restart from the beginning
+ // rather than keep ringing. This is the most common case.
+ if (this.rd === this.wr) {
+ this.rd = this.wr = 0;
+ }
+
+ // The caller is expected to issue a ReadMessage() after each append().
+ const dataLen = data.length;
+ if (dataLen === 0) return;
+ assertTrue(this.fastpath === undefined);
+ if (this.rd === this.wr) {
+ const msg = ProtoRingBuffer.tryReadMessage(data, 0, dataLen);
+ if (msg !== undefined &&
+ ((msg.byteOffset + msg.length) === (data.byteOffset + dataLen))) {
+ // Fastpath: in many cases, the underlying stream will effectively
+ // preserve the atomicity of messages for most small messages.
+ // In this case we can avoid the extra buffer roundtrip and return the
+ // original array (actually a subarray that skips the proto header).
+ // The next call to ReadMessage() will return this.
+ this.fastpath = msg;
+ return;
+ }
+ }
+
+ let avail = this.buf.length - this.wr;
+ if (dataLen > avail) {
+ // This whole section should be hit extremely rarely.
+
+ // Try first just recompacting the buffer by moving everything to the
+ // left. This can happen if we received "a message and a bit" on each
+ // append() call.
+ this.buf.copyWithin(0, this.rd, this.wr);
+ avail += this.rd;
+ this.wr -= this.rd;
+ this.rd = 0;
+ if (dataLen > avail) {
+ // Still not enough, expand the buffer.
+ let newSize = this.buf.length;
+ while (dataLen > newSize - this.wr) {
+ newSize += kGrowBytes;
+ }
+ assertTrue(newSize <= kMaxMsgSize * 2);
+ const newBuf = new Uint8Array(newSize);
+ newBuf.set(this.buf);
+ this.buf = newBuf;
+ // No need to touch rd / wr.
+ }
+ }
+
+ // Append the received data at the end of the ring buffer.
+ this.buf.set(data, this.wr);
+ this.wr += dataLen;
+ }
+
+ // Tries to extract a message from the ring buffer. If there is no message,
+ // or if the current message is still incomplete, returns undefined.
+ // The caller is expected to call this in a loop until it returns undefined.
+ // Note that a single write to Append() can yield more than one message
+ // (see ProtoRingBufferTest.CoalescingStream in the unittest).
+ readMessage(): Uint8Array|undefined {
+ if (this.fastpath !== undefined) {
+ assertTrue(this.rd === this.wr);
+ const msg = this.fastpath;
+ this.fastpath = undefined;
+ return msg;
+ }
+ assertTrue(this.rd <= this.wr);
+ if (this.rd >= this.wr) {
+ return undefined; // Completely empty.
+ }
+ const msg = ProtoRingBuffer.tryReadMessage(this.buf, this.rd, this.wr);
+ if (msg === undefined) return undefined;
+ assertTrue(msg.buffer === this.buf.buffer);
+ assertTrue(this.buf.byteOffset === 0);
+ this.rd = msg.byteOffset + msg.length;
+
+ // Deliberately returning a copy of the data with slice(). In various cases
+ // (streaming query response) the caller will hold onto the returned buffer.
+ // If we get to this point, |msg| is a view of the circular buffer that we
+ // will overwrite on the next calls to append().
+ return msg.slice();
+ }
+
+ private static tryReadMessage(
+ data: Uint8Array, dataStart: number, dataEnd: number): Uint8Array
+ |undefined {
+ assertTrue(dataEnd <= data.length);
+ let pos = dataStart;
+ if (pos >= dataEnd) return undefined;
+ const tag = data[pos++]; // Assume one-byte tag.
+ if (tag >= 0x80 || (tag & 0x07) !== 2 /* len delimited */) {
+ throw new Error(
+ `RPC framing error, unexpected tag ${tag} @ offset ${pos - 1}`);
+ }
+
+ let len = 0;
+ for (let shift = 0;; shift += 7) {
+ if (pos >= dataEnd) {
+ return undefined; // Not enough data to read varint.
+ }
+ const val = data[pos++];
+ len |= ((val & 0x7f) << shift) >>> 0;
+ if (val < 0x80) break;
+ }
+
+ if (len >= kMaxMsgSize) {
+ throw new Error(
+ `RPC framing error, message too large (${len} > ${kMaxMsgSize}`);
+ }
+ const end = pos + len;
+ if (end > dataEnd) return undefined;
+
+ // This is a subarray() and not a slice() because in the |fastpath| case
+ // we want to just return the original buffer pushed by append().
+ // In the slow-path (ring-buffer) case, the readMessage() above will create
+ // a copy via slice() before returning it.
+ return data.subarray(pos, end);
+ }
+}
diff --git a/ui/src/common/proto_ring_buffer_unittest.ts b/ui/src/common/proto_ring_buffer_unittest.ts
new file mode 100644
index 000000000..6c06ae06d
--- /dev/null
+++ b/ui/src/common/proto_ring_buffer_unittest.ts
@@ -0,0 +1,140 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import * as protobuf from 'protobufjs/minimal';
+import {assertTrue} from '../base/logging';
+
+import {ProtoRingBuffer} from './proto_ring_buffer';
+
+let seed = 1;
+
+// For reproducibility.
+function Rnd(max: number) {
+ seed = seed * 16807 % 2147483647;
+ return seed % max;
+}
+
+function MakeProtoMessage(fieldId: number, len: number) {
+ const writer = protobuf.Writer.create();
+ const tag = (fieldId << 3) | 2 /*length-delimited*/;
+ assertTrue(tag < 0x80 && (tag & 7) === 2);
+ writer.uint32(tag);
+ const data = new Uint8Array(len);
+ for (let i = 0; i < len; i++) {
+ data[i] = 48 + ((fieldId + i) % 73);
+ }
+ writer.bytes(data);
+ const res = writer.finish();
+ // For whatever reason the object returned by protobufjs' Writer cannot be
+ // directly .toEqual()-ed with Uint8Arrays.
+ const buf = new Uint8Array(res.length);
+ buf.set(res);
+ return buf;
+}
+
+test('ProtoRingBufferTest.Fastpath', () => {
+ const buf = new ProtoRingBuffer();
+
+ for (let rep = 0; rep < 3; rep++) {
+ let inputBuf = MakeProtoMessage(1, 32);
+ buf.append(inputBuf);
+ let msg = buf.readMessage();
+ expect(msg).toBeDefined();
+ expect(msg).toBeInstanceOf(Uint8Array);
+ expect(msg!.length).toBe(32);
+
+ // subarray(2) is to strip the proto preamble. The returned buffer starts at
+ // the start of the payload.
+ expect(msg).toEqual(inputBuf.subarray(2));
+
+ // When we hit the fastpath, the returned message should be a subarray of
+ // the same ArrayBuffer passed to append.
+ expect(msg!.buffer).toBe(inputBuf.buffer);
+
+ inputBuf = MakeProtoMessage(2, 32);
+ buf.append(inputBuf.subarray(0, 13));
+ expect(buf.readMessage()).toBeUndefined();
+ buf.append(inputBuf.subarray(13));
+ msg = buf.readMessage();
+ expect(msg).toBeDefined();
+ expect(msg).toBeInstanceOf(Uint8Array);
+ expect(msg).toEqual(inputBuf.subarray(2));
+ expect(msg!.buffer !== inputBuf.buffer).toBeTruthy();
+ }
+});
+
+test('ProtoRingBufferTest.CoalescingStream', () => {
+ const buf = new ProtoRingBuffer();
+
+ const mergedBuf = new Uint8Array(612);
+ const expected = new Array<Uint8Array>();
+ for (let i = 1, pos = 0; i <= 6; i++) {
+ const msg = MakeProtoMessage(i, 100);
+ expected.push(msg);
+ mergedBuf.set(msg, pos);
+ pos += msg.length;
+ }
+
+ const fragLens = [120, 20, 471, 1];
+ let fragSum = 0;
+ fragLens.map(fragLen => {
+ buf.append(mergedBuf.subarray(fragSum, fragSum + fragLen));
+ fragSum += fragLen;
+ for (;;) {
+ const msg = buf.readMessage();
+ if (msg === undefined) break;
+ const exp = expected.shift();
+ expect(exp).toBeDefined();
+ expect(msg).toEqual(exp!.subarray(-1 * msg.length));
+ }
+ });
+ expect(expected.length).toEqual(0);
+});
+
+
+test('ProtoRingBufferTest.RandomSizes', () => {
+ const buf = new ProtoRingBuffer();
+ const kNumMsg = 100;
+ const mergedBuf = new Uint8Array(1024 * 1024 * 32);
+ const expectedLengths = [];
+ let mergedLen = 0;
+ for (let i = 0; i < kNumMsg; i++) {
+ const fieldId = 1 + Rnd(15); // We support only one byte tag.
+ const rndVal = Rnd(1024);
+ let len = 1 + rndVal;
+ if ((rndVal % 100) < 5) {
+ len *= 1000;
+ }
+ const msg = MakeProtoMessage(fieldId, len);
+ assertTrue(mergedBuf.length >= mergedLen + msg.length);
+ expectedLengths.push(len);
+ mergedBuf.set(msg, mergedLen);
+ mergedLen += msg.length;
+ }
+
+ for (let fragSum = 0; fragSum < mergedLen;) {
+ let fragLen = 1 + Rnd(1024 * 32);
+ fragLen = Math.min(fragLen, mergedLen - fragSum);
+ buf.append(mergedBuf.subarray(fragSum, fragSum + fragLen));
+ fragSum += fragLen;
+ for (;;) {
+ const msg = buf.readMessage();
+ if (msg === undefined) break;
+ const expLen = expectedLengths.shift();
+ expect(expLen).toBeDefined();
+ expect(msg.length).toEqual(expLen);
+ }
+ }
+ expect(expectedLengths.length).toEqual(0);
+});
diff --git a/ui/src/common/protos.ts b/ui/src/common/protos.ts
index 8b0a5fdf5..ea3c3fb63 100644
--- a/ui/src/common/protos.ts
+++ b/ui/src/common/protos.ts
@@ -13,7 +13,6 @@
// limitations under the License.
import * as protos from '../gen/protos';
-import {slowlyCountRows} from './query_iterator';
// Aliases protos to avoid the super nested namespaces.
// See https://www.typescriptlang.org/docs/handbook/namespaces.html#aliases
@@ -46,74 +45,11 @@ import TraceConfig = protos.perfetto.protos.TraceConfig;
import VmstatCounters = protos.perfetto.protos.VmstatCounters;
// Trace Processor protos.
-import IRawQueryArgs = protos.perfetto.protos.IRawQueryArgs;
-import RawQueryArgs = protos.perfetto.protos.RawQueryArgs;
-import RawQueryResult = protos.perfetto.protos.RawQueryResult;
+import QueryArgs = protos.perfetto.protos.QueryArgs;
import StatusResult = protos.perfetto.protos.StatusResult;
import ComputeMetricArgs = protos.perfetto.protos.ComputeMetricArgs;
import ComputeMetricResult = protos.perfetto.protos.ComputeMetricResult;
-// TODO(hjd): Maybe these should go in their own file.
-export interface Row { [key: string]: number|string; }
-
-const COLUMN_TYPE_STR = RawQueryResult.ColumnDesc.Type.STRING;
-const COLUMN_TYPE_DOUBLE = RawQueryResult.ColumnDesc.Type.DOUBLE;
-const COLUMN_TYPE_LONG = RawQueryResult.ColumnDesc.Type.LONG;
-
-function getCell(result: RawQueryResult, column: number, row: number): number|
- string|null {
- const values = result.columns[column];
- if (values.isNulls![row]) return null;
- switch (result.columnDescriptors[column].type) {
- case COLUMN_TYPE_LONG:
- return +values.longValues![row];
- case COLUMN_TYPE_DOUBLE:
- return +values.doubleValues![row];
- case COLUMN_TYPE_STR:
- return values.stringValues![row];
- default:
- throw new Error('Unhandled type!');
- }
-}
-
-export function rawQueryResultColumns(result: RawQueryResult): string[] {
- // Two columns can conflict on the same name, e.g.
- // select x.foo, y.foo from x join y. In that case store them using the
- // full table.column notation.
- const res = [] as string[];
- const uniqColNames = new Set<string>();
- const colNamesToDedupe = new Set<string>();
- for (const col of result.columnDescriptors) {
- const colName = col.name || '';
- if (uniqColNames.has(colName)) {
- colNamesToDedupe.add(colName);
- }
- uniqColNames.add(colName);
- }
- for (let i = 0; i < result.columnDescriptors.length; i++) {
- const colName = result.columnDescriptors[i].name || '';
- if (colNamesToDedupe.has(colName)) {
- res.push(`${colName}.${i + 1}`);
- } else {
- res.push(colName);
- }
- }
- return res;
-}
-
-export function* rawQueryResultIter(result: RawQueryResult) {
- const columns: Array<[string, number]> = rawQueryResultColumns(result).map(
- (name, i): [string, number] => [name, i]);
- for (let rowNum = 0; rowNum < slowlyCountRows(result); rowNum++) {
- const row: Row = {};
- for (const [name, colNum] of columns) {
- const cell = getCell(result, colNum, rowNum);
- row[name] = cell === null ? '[NULL]' : cell;
- }
- yield row;
- }
-}
-
export {
AndroidLogConfig,
AndroidLogId,
@@ -130,7 +66,6 @@ export {
IAndroidPowerConfig,
IBufferConfig,
IProcessStatsConfig,
- IRawQueryArgs,
ISysStatsConfig,
ITraceConfig,
JavaContinuousDumpConfig,
@@ -138,8 +73,7 @@ export {
MeminfoCounters,
NativeContinuousDumpConfig,
ProcessStatsConfig,
- RawQueryArgs,
- RawQueryResult,
+ QueryArgs,
StatCounters,
StatusResult,
SysStatsConfig,
diff --git a/ui/src/common/queries.ts b/ui/src/common/queries.ts
index 8ad01b643..a91b12625 100644
--- a/ui/src/common/queries.ts
+++ b/ui/src/common/queries.ts
@@ -12,7 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {Row} from './protos';
+import {Engine} from './engine';
+import {Row} from './query_result';
+
+const MAX_DISPLAY_ROWS = 10000;
export interface QueryResponse {
id: string;
@@ -22,4 +25,53 @@ export interface QueryResponse {
durationMs: number;
columns: string[];
rows: Row[];
+ statementCount: number;
+ statementWithOutputCount: number;
}
+
+export async function runQuery(
+ queryId: string, sqlQuery: string, engine: Engine): Promise<QueryResponse> {
+ const startMs = performance.now();
+ const queryRes = engine.query(sqlQuery);
+
+ // TODO(primiano): once the controller thread is gone we should pass down
+ // the result objects directly to the frontend, iterate over the result
+ // and deal with pagination there. For now we keep the old behavior and
+ // truncate to 10k rows.
+
+ try {
+ await queryRes.waitAllRows();
+ } catch {
+ // In the case of a query error we don't want the exception to bubble up
+ // as a crash. The |queryRes| object will be populated anyways.
+ // queryRes.error() is used to tell if the query errored or not. If it
+ // errored, the frontend will show a graceful message instead.
+ }
+
+ const durationMs = performance.now() - startMs;
+ const rows: Row[] = [];
+ const columns = queryRes.columns();
+ let numRows = 0;
+ for (const iter = queryRes.iter({}); iter.valid(); iter.next()) {
+ const row: Row = {};
+ for (const colName of columns) {
+ const value = iter.get(colName);
+ row[colName] = value === null ? 'NULL' : value;
+ }
+ rows.push(row);
+ if (++numRows >= MAX_DISPLAY_ROWS) break;
+ }
+
+ const result: QueryResponse = {
+ id: queryId,
+ query: sqlQuery,
+ durationMs,
+ error: queryRes.error(),
+ totalRowCount: queryRes.numRows(),
+ columns,
+ rows,
+ statementCount: queryRes.statementCount(),
+ statementWithOutputCount: queryRes.statementWithOutputCount(),
+ };
+ return result;
+} \ No newline at end of file
diff --git a/ui/src/common/query_iterator.ts b/ui/src/common/query_iterator.ts
deleted file mode 100644
index 10029a541..000000000
--- a/ui/src/common/query_iterator.ts
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import {assertTrue} from '../base/logging';
-
-import {RawQueryResult} from './protos';
-
-// Union of all the query result formats that we can turn into forward
-// iterators.
-// TODO(hjd): Replace someOtherEncoding place holder with the real new
-// format.
-type QueryResult = RawQueryResult|{someOtherEncoding: string};
-
-// One row extracted from an SQL result:
-interface Row {
- [key: string]: string|number|null;
-}
-
-// API:
-// const result = await engine.query("select 42 as n;");
-// const it = iter({"answer": NUM}, result);
-// for (; it.valid(); it.next()) {
-// console.log(it.row.answer);
-// }
-export interface RowIterator<T extends Row> {
- valid(): boolean;
- next(): void;
- row: T;
-}
-
-export const NUM = 0;
-export const STR = 'str';
-export const NUM_NULL: number|null = 1;
-export const STR_NULL: string|null = 'str_null';
-export type ColumnType =
- (typeof NUM)|(typeof STR)|(typeof NUM_NULL)|(typeof STR_NULL);
-
-// Exported for testing
-export function findColumnIndex(
- result: RawQueryResult, name: string, columnType: number|null|string):
- number {
- let matchingDescriptorIndex = -1;
- const disallowNulls = columnType === STR || columnType === NUM;
- const expectsStrings = columnType === STR || columnType === STR_NULL;
- const expectsNumbers = columnType === NUM || columnType === NUM_NULL;
- const isEmpty = +result.numRecords === 0;
-
- for (let i = 0; i < result.columnDescriptors.length; ++i) {
- const descriptor = result.columnDescriptors[i];
- const column = result.columns[i];
- if (descriptor.name !== name) {
- continue;
- }
-
- const hasDoubles = column.doubleValues && column.doubleValues.length;
- const hasLongs = column.longValues && column.longValues.length;
- const hasStrings = column.stringValues && column.stringValues.length;
-
- if (matchingDescriptorIndex !== -1) {
- throw new Error(`Multiple columns with the name ${name}`);
- }
-
- if (expectsStrings && !hasStrings && !isEmpty) {
- throw new Error(`Expected strings for column ${name} but found numbers`);
- }
-
- if (expectsNumbers && !hasDoubles && !hasLongs && !isEmpty) {
- throw new Error(`Expected numbers for column ${name} but found strings`);
- }
-
- if (disallowNulls) {
- for (let j = 0; j < +result.numRecords; ++j) {
- if (column.isNulls![j] === true) {
- throw new Error(`Column ${name} contains nulls`);
- }
- }
- }
- matchingDescriptorIndex = i;
- }
-
- if (matchingDescriptorIndex === -1) {
- throw new Error(`No column with name ${name} found in result.`);
- }
-
- return matchingDescriptorIndex;
-}
-
-class ColumnarRowIterator {
- row: Row;
- private i_: number;
- private rowCount_: number;
- private columnCount_: number;
- private columnNames_: string[];
- private columns_: Array<number[]|string[]>;
- private nullColumns_: boolean[][];
-
- constructor(querySpec: Row, queryResult: RawQueryResult) {
- const row: Row = querySpec;
- this.row = row;
- this.i_ = 0;
- this.rowCount_ = +queryResult.numRecords;
- this.columnCount_ = 0;
- this.columnNames_ = [];
- this.columns_ = [];
- this.nullColumns_ = [];
-
- for (const [columnName, columnType] of Object.entries(querySpec)) {
- const index = findColumnIndex(queryResult, columnName, columnType);
- const column = queryResult.columns[index];
- this.columnCount_++;
- this.columnNames_.push(columnName);
- let values: string[]|Array<number|Long> = [];
- const isNum = columnType === NUM || columnType === NUM_NULL;
- const isString = columnType === STR || columnType === STR_NULL;
- if (isNum && column.longValues &&
- column.longValues.length === this.rowCount_) {
- values = column.longValues;
- }
- if (isNum && column.doubleValues &&
- column.doubleValues.length === this.rowCount_) {
- values = column.doubleValues;
- }
- if (isString && column.stringValues &&
- column.stringValues.length === this.rowCount_) {
- values = column.stringValues;
- }
- this.columns_.push(values as string[]);
- this.nullColumns_.push(column.isNulls!);
- }
- if (this.rowCount_ > 0) {
- for (let j = 0; j < this.columnCount_; ++j) {
- const name = this.columnNames_[j];
- const isNull = this.nullColumns_[j][this.i_];
- this.row[name] = isNull ? null : this.columns_[j][this.i_];
- }
- }
- }
-
- valid(): boolean {
- return this.i_ < this.rowCount_;
- }
-
- next(): void {
- this.i_++;
- for (let j = 0; j < this.columnCount_; ++j) {
- const name = this.columnNames_[j];
- const isNull = this.nullColumns_[j][this.i_];
- this.row[name] = isNull ? null : this.columns_[j][this.i_];
- }
- }
-}
-
-// Deliberately not exported, use iter() below to make code easy to switch
-// to other queryResult formats.
-function iterFromColumns<T extends Row>(
- querySpec: T, queryResult: RawQueryResult): RowIterator<T> {
- const iter = new ColumnarRowIterator(querySpec, queryResult);
- return iter as unknown as RowIterator<T>;
-}
-
-// Deliberately not exported, use iterUntyped() below to make code easy to
-// switch to other queryResult formats.
-function iterUntypedFromColumns(result: RawQueryResult): RowIterator<Row> {
- const spec: Row = {};
- const desc = result.columnDescriptors;
- for (let i = 0; i < desc.length; ++i) {
- const name = desc[i].name;
- if (!name) {
- continue;
- }
- spec[name] = desc[i].type === 3 ? STR_NULL : NUM_NULL;
- }
- const iter = new ColumnarRowIterator(spec, result);
- return iter as unknown as RowIterator<Row>;
-}
-
-function isColumnarQueryResult(result: QueryResult): result is RawQueryResult {
- return (result as RawQueryResult).columnDescriptors !== undefined;
-}
-
-export function iterUntyped(result: QueryResult): RowIterator<Row> {
- if (isColumnarQueryResult(result)) {
- return iterUntypedFromColumns(result);
- } else {
- throw new Error('Unsuported format');
- }
-}
-
-export function iter<T extends Row>(
- spec: T, result: QueryResult): RowIterator<T> {
- if (isColumnarQueryResult(result)) {
- return iterFromColumns(spec, result);
- } else {
- throw new Error('Unsuported format');
- }
-}
-
-export function slowlyCountRows(result: QueryResult): number {
- if (isColumnarQueryResult(result)) {
- // This isn't actually slow for columnar data but it might be for other
- // formats.
- return +result.numRecords;
- } else {
- throw new Error('Unsuported format');
- }
-}
-
-export function singleRow<T extends Row>(spec: T, result: QueryResult): T|
- undefined {
- const numRows = slowlyCountRows(result);
- if (numRows === 0) {
- return undefined;
- }
- if (numRows > 1) {
- throw new Error(
- `Attempted to extract single row but more than ${numRows} rows found.`);
- }
- const it = iter(spec, result);
- assertTrue(it.valid());
- return it.row;
-}
-
-export function singleRowUntyped(result: QueryResult): Row|undefined {
- const numRows = slowlyCountRows(result);
- if (numRows === 0) {
- return undefined;
- }
- if (numRows > 1) {
- throw new Error(
- `Attempted to extract single row but more than ${numRows} rows found.`);
- }
- const it = iterUntyped(result);
- assertTrue(it.valid());
- return it.row;
-}
diff --git a/ui/src/common/query_iterator_unittest.ts b/ui/src/common/query_iterator_unittest.ts
deleted file mode 100644
index 402a2e99d..000000000
--- a/ui/src/common/query_iterator_unittest.ts
+++ /dev/null
@@ -1,235 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import {RawQueryResult} from './protos';
-import {
- findColumnIndex,
- iter,
- NUM,
- NUM_NULL,
- slowlyCountRows,
- STR,
- STR_NULL
-} from './query_iterator';
-
-const COLUMN_TYPE_STR = RawQueryResult.ColumnDesc.Type.STRING;
-const COLUMN_TYPE_DOUBLE = RawQueryResult.ColumnDesc.Type.DOUBLE;
-const COLUMN_TYPE_LONG = RawQueryResult.ColumnDesc.Type.LONG;
-
-test('Columnar iteration slowlyCountRows', () => {
- const r = new RawQueryResult({
- columnDescriptors: [{
- name: 'string_column',
- type: COLUMN_TYPE_STR,
- }],
- numRecords: 1,
- columns: [{
- stringValues: ['foo'],
- isNulls: [false],
- }],
- });
-
- expect(slowlyCountRows(r)).toBe(1);
-});
-
-test('Columnar iteration findColumnIndex', () => {
- const r = new RawQueryResult({
- columnDescriptors: [
- {
- name: 'strings',
- type: COLUMN_TYPE_STR,
- },
- {
- name: 'doubles',
- type: COLUMN_TYPE_DOUBLE,
- },
- {
- name: 'longs',
- type: COLUMN_TYPE_LONG,
- },
- {
- name: 'nullable_strings',
- type: COLUMN_TYPE_STR,
- },
- {
- name: 'nullable_doubles',
- type: COLUMN_TYPE_DOUBLE,
- },
- {
- name: 'nullable_longs',
- type: COLUMN_TYPE_LONG,
- },
- {
- name: 'twin',
- type: COLUMN_TYPE_LONG,
- },
- {
- name: 'twin',
- type: COLUMN_TYPE_STR,
- }
- ],
- numRecords: 1,
- columns: [
- {
- stringValues: ['foo'],
- isNulls: [false],
- },
- {
- doubleValues: [1],
- isNulls: [false],
- },
- {
- longValues: [1],
- isNulls: [false],
- },
- {
- stringValues: [''],
- isNulls: [true],
- },
- {
- doubleValues: [0],
- isNulls: [true],
- },
- {
- longValues: [0],
- isNulls: [true],
- },
- {
- doubleValues: [0],
- isNulls: [false],
- },
- {
- stringValues: [''],
- isNulls: [false],
- }
- ],
- });
-
- expect(findColumnIndex(r, 'strings', STR)).toBe(0);
- expect(findColumnIndex(r, 'doubles', NUM)).toBe(1);
- expect(findColumnIndex(r, 'longs', NUM)).toBe(2);
-
- expect(findColumnIndex(r, 'nullable_strings', STR_NULL)).toBe(3);
- expect(findColumnIndex(r, 'nullable_doubles', NUM_NULL)).toBe(4);
- expect(findColumnIndex(r, 'nullable_longs', NUM_NULL)).toBe(5);
-
- expect(() => findColumnIndex(r, 'no such col', NUM)).toThrow(Error);
-
- // It's allowable to expect nulls but for the whole column to be non-null...
- expect(findColumnIndex(r, 'strings', STR_NULL)).toBe(0);
- expect(findColumnIndex(r, 'doubles', NUM_NULL)).toBe(1);
- expect(findColumnIndex(r, 'longs', NUM_NULL)).toBe(2);
-
- // ...but if we expect no-nulls there shouldn't be even one:
- expect(() => findColumnIndex(r, 'nullable_strings', STR)).toThrow(Error);
- expect(() => findColumnIndex(r, 'nullable_doubles', NUM)).toThrow(Error);
- expect(() => findColumnIndex(r, 'nullable_longs', NUM)).toThrow(Error);
-
- // If multiple columns have the desired name we error even if we could
- // distinguish based on the type:
- expect(() => findColumnIndex(r, 'twin', NUM)).toThrow(Error);
-
- expect(() => findColumnIndex(r, 'strings', NUM)).toThrow(Error);
- expect(() => findColumnIndex(r, 'longs', STR)).toThrow(Error);
- expect(() => findColumnIndex(r, 'doubles', STR)).toThrow(Error);
-});
-
-test('Columnar iteration over two rows', () => {
- const r = new RawQueryResult({
- columnDescriptors: [{
- name: 'name',
- type: COLUMN_TYPE_STR,
- }],
- numRecords: 2,
- columns: [{
- stringValues: ['Alice', 'Bob'],
- isNulls: [false, false],
- }],
- });
-
- const it = iter({'name': STR}, r);
-
- expect(it.valid()).toBe(true);
- const name: string = it.row.name;
- expect(name).toBe('Alice');
- it.next();
-
- expect(it.valid()).toBe(true);
- expect(it.row.name).toBe('Bob');
- it.next();
-
- expect(it.valid()).toBe(false);
-});
-
-test('Columnar iteration over empty query set', () => {
- const r = new RawQueryResult({
- columnDescriptors: [{
- name: 'emptyColumn',
- type: COLUMN_TYPE_STR,
- }],
- numRecords: 0,
- columns: [{
- stringValues: [],
- isNulls: [],
- }],
- });
-
- {
- const it = iter({'emptyColumn': STR}, r);
- expect(it.valid()).toBe(false);
- }
-
- {
- const it = iter({'emptyColumn': NUM}, r);
- expect(it.valid()).toBe(false);
- }
-
- {
- const it = iter({'emptyColumn': NUM_NULL}, r);
- expect(it.valid()).toBe(false);
- }
-
- {
- const it = iter({'emptyColumn': STR_NULL}, r);
- expect(it.valid()).toBe(false);
- }
-});
-
-test('Columnar iteration first row is null', () => {
- const r = new RawQueryResult({
- columnDescriptors: [{
- name: 'numbers',
- type: COLUMN_TYPE_STR,
- }],
- numRecords: 2,
- columns: [{
- stringValues: ['[NULL]'],
- doubleValues: [0],
- longValues: [0, 1],
- isNulls: [true, false],
- }],
- });
-
- const it = iter({'numbers': NUM_NULL}, r);
-
- expect(it.valid()).toBe(true);
- expect(it.row.numbers).toBe(null);
- it.next();
-
- expect(it.valid()).toBe(true);
- expect(it.row.numbers).toBe(1);
- it.next();
-
- expect(it.valid()).toBe(false);
-});
diff --git a/ui/src/common/query_result.ts b/ui/src/common/query_result.ts
new file mode 100644
index 000000000..73f0a98c7
--- /dev/null
+++ b/ui/src/common/query_result.ts
@@ -0,0 +1,822 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// This file deals with deserialization and iteration of the proto-encoded
+// byte buffer that is returned by TraceProcessor when invoking the
+// TPM_QUERY_STREAMING method. The returned |query_result| buffer is optimized
+// for being moved cheaply across workers and decoded on-the-flight as we step
+// through the iterator.
+// See comments around QueryResult in trace_processor.proto for more details.
+
+// The classes in this file are organized as follows:
+//
+// QueryResultImpl:
+// The object returned by the Engine.query(sql) method.
+// This object is a holder of row data. Batches of raw get appended
+// incrementally as they are received by the remote TraceProcessor instance.
+// QueryResultImpl also deals with asynchronicity of queries and allows callers
+// to obtain a promise that waits for more (or all) rows.
+// At any point in time the following objects hold a reference to QueryResult:
+// - The Engine: for appending row batches.
+// - UI code, typically controllers, who make queries.
+//
+// ResultBatch:
+// Hold the data, returned by the remote TraceProcessor instance, for a number
+// of rows (TP typically chunks the results in batches of 128KB).
+// A QueryResultImpl holds exclusively ResultBatches for a given query.
+// ResultBatch is not exposed externally, it's just an internal representation
+// that helps with proto decoding. ResultBatch is immutable after it gets
+// appended and decoded. The iteration state is held by the RowIteratorImpl.
+//
+// RowIteratorImpl:
+// Decouples the data owned by QueryResultImpl (and its ResultBatch(es)) from
+// the iteration state. The iterator effectively is the union of a ResultBatch
+// and the row number in it. Rows within the batch are decoded as the user calls
+// next(). When getting at the end of the batch, it takes care of switching to
+// the next batch (if any) within the QueryResultImpl.
+// This object is part of the API exposed to tracks / controllers.
+
+import * as protobuf from 'protobufjs/minimal';
+
+import {defer, Deferred} from '../base/deferred';
+import {assertExists, assertFalse, assertTrue} from '../base/logging';
+import {utf8Decode} from '../base/string_utils';
+
+export const NUM = 0;
+export const STR = 'str';
+export const NUM_NULL: number|null = 1;
+export const STR_NULL: string|null = 'str_null';
+
+export type ColumnType = string|number|null;
+
+// Info that could help debug a query error. For example the query
+// in question, the stack where the query was issued, the active
+// plugin etc.
+export interface QueryErrorInfo {
+ query: string;
+}
+
+export class QueryError extends Error {
+ readonly query: string;
+
+ constructor(message: string, info: QueryErrorInfo) {
+ super(message);
+ this.query = info.query;
+ }
+
+ toString() {
+ return `Query: ${this.query}\n` + super.toString();
+ }
+}
+
+// One row extracted from an SQL result:
+export interface Row {
+ [key: string]: ColumnType;
+}
+
+// The methods that any iterator has to implement.
+export interface RowIteratorBase {
+ valid(): boolean;
+ next(): void;
+
+ // Reflection support for cases where the column names are not known upfront
+ // (e.g. the query result table for user-provided SQL queries).
+ // It throws if the passed column name doesn't exist.
+ // Example usage:
+ // for (const it = queryResult.iter({}); it.valid(); it.next()) {
+ // for (const columnName : queryResult.columns()) {
+ // console.log(it.get(columnName));
+ get(columnName: string): ColumnType;
+}
+
+// A RowIterator is a type that has all the fields defined in the query spec
+// plus the valid() and next() operators. This is to ultimately allow the
+// clients to do:
+// const result = await engine.query("select name, surname, id from people;");
+// const iter = queryResult.iter({name: STR, surname: STR, id: NUM});
+// for (; iter.valid(); iter.next())
+// console.log(iter.name, iter.surname);
+export type RowIterator<T extends Row> = RowIteratorBase&T;
+
+function columnTypeToString(t: ColumnType): string {
+ switch (t) {
+ case NUM:
+ return 'NUM';
+ case NUM_NULL:
+ return 'NUM_NULL';
+ case STR:
+ return 'STR';
+ case STR_NULL:
+ return 'STR_NULL';
+ default:
+ return `INVALID(${t})`;
+ }
+}
+
+// Disable Long.js support in protobuf. This seems to be enabled only in tests
+// but not in production code. In any case, for now we want casting to number
+// accepting the 2**53 limitation. This is consistent with passing
+// --force-number in the protobuf.js codegen invocation in //ui/BUILD.gn .
+// See also https://github.com/protobufjs/protobuf.js/issues/1253 .
+(protobuf.util as {} as {Long: undefined}).Long = undefined;
+protobuf.configure();
+
+// This has to match CellType in trace_processor.proto.
+enum CellType {
+ CELL_NULL = 1,
+ CELL_VARINT = 2,
+ CELL_FLOAT64 = 3,
+ CELL_STRING = 4,
+ CELL_BLOB = 5,
+}
+
+const CELL_TYPE_NAMES =
+ ['UNKNOWN', 'NULL', 'VARINT', 'FLOAT64', 'STRING', 'BLOB'];
+
+const TAG_LEN_DELIM = 2;
+
+// This is the interface exposed to readers (e.g. tracks). The underlying object
+// (QueryResultImpl) owns the result data. This allows to obtain iterators on
+// that. In future it will allow to wait for incremental updates (new rows being
+// fetched) for streaming queries.
+export interface QueryResult {
+ // Obtains an iterator.
+ // TODO(primiano): this should have an option to destruct data as we read. In
+ // the case of a long query (e.g. `SELECT * FROM sched` in the query prompt)
+ // we don't want to accumulate everything in memory. OTOH UI tracks want to
+ // keep the data around so they can redraw them on each animation frame. For
+ // now we keep everything in memory in the QueryResultImpl object.
+ // iter<T extends Row>(spec: T): RowIterator<T>;
+ iter<T extends Row>(spec: T): RowIterator<T>;
+
+ // Like iter() for queries that expect only one row. It embeds the valid()
+ // check (i.e. throws if no rows are available) and returns directly the
+ // first result.
+ firstRow<T extends Row>(spec: T): T;
+
+ // If != undefined the query errored out and error() contains the message.
+ error(): string|undefined;
+
+ // Returns the number of rows accumulated so far. Note that this number can
+ // change over time as more batches are received. It becomes stable only
+ // when isComplete() returns true or after waitAllRows() is resolved.
+ numRows(): number;
+
+ // If true all rows have been fetched. Calling iter() will iterate through the
+ // last row. If false, iter() will return an iterator which might iterate
+ // through some rows (or none) but will surely not reach the end.
+
+ isComplete(): boolean;
+
+ // Returns a promise that is resolved only when all rows (i.e. all batches)
+ // have been fetched. The promise return value is always the object iself.
+ waitAllRows(): Promise<QueryResult>;
+
+ // Can return an empty array if called before the first batch is resolved.
+ // This should be called only after having awaited for at least one batch.
+ columns(): string[];
+
+ // Returns the number of SQL statements in the query
+ // (e.g. 2 'if SELECT 1; SELECT 2;')
+ statementCount(): number;
+
+ // Returns the number of SQL statement that produced output rows. This number
+ // is <= statementCount().
+ statementWithOutputCount(): number;
+
+ // TODO(primiano): next CLs will introduce a waitMoreRows() to allow tracks
+ // to await until some more data (but not necessarily all) is available. For
+ // now everything uses waitAllRows().
+}
+
+// Interface exposed to engine.ts to pump in the data as new row batches arrive.
+export interface WritableQueryResult extends QueryResult {
+ // |resBytes| is a proto-encoded trace_processor.QueryResult message.
+ // The overall flow looks as follows:
+ // - The user calls engine.query('select ...') and gets a QueryResult back.
+ // - The query call posts a message to the worker that runs the SQL engine (
+ // or sends a HTTP request in case of the RPC+HTTP interface).
+ // - The returned QueryResult object is initially empty.
+ // - Over time, the sql engine will postMessage() back results in batches.
+ // - Each bach will end up calling this appendResultBatch() method.
+ // - If there is any pending promise (e.g. the caller called
+ // queryResult.waitAllRows()), this call will awake them (if this is the
+ // last batch).
+ appendResultBatch(resBytes: Uint8Array): void;
+}
+
+// The actual implementation, which bridges together the reader side and the
+// writer side (the one exposed to the Engine). This is the same object so that
+// when the engine pumps new row batches we can resolve pending promises that
+// readers (e.g. track code) are waiting for.
+class QueryResultImpl implements QueryResult, WritableQueryResult {
+ columnNames: string[] = [];
+ private _error?: string;
+ private _numRows = 0;
+ private _isComplete = false;
+ private _errorInfo: QueryErrorInfo;
+ private _statementCount = 0;
+ private _statementWithOutputCount = 0;
+
+ constructor(errorInfo: QueryErrorInfo) {
+ this._errorInfo = errorInfo;
+ }
+
+ // --- QueryResult implementation.
+
+ // TODO(primiano): for the moment new batches are appended but old batches
+ // are never removed. This won't work with abnormally large result sets, as
+ // it will stash all rows in memory. We could switch to a model where the
+ // iterator is destructive and deletes batch objects once iterating past the
+ // end of each batch. If we do that, than we need to assign monotonic IDs to
+ // batches. Also if we do that, we should prevent creating more than one
+ // iterator for a QueryResult.
+ batches: ResultBatch[] = [];
+
+ // Promise awaiting on waitAllRows(). This should be resolved only when the
+ // last result batch has been been retrieved.
+ private allRowsPromise?: Deferred<QueryResult>;
+
+ isComplete(): boolean {
+ return this._isComplete;
+ }
+ numRows(): number {
+ return this._numRows;
+ }
+ error(): string|undefined {
+ return this._error;
+ }
+ columns(): string[] {
+ return this.columnNames;
+ }
+ statementCount(): number {
+ return this._statementCount;
+ }
+ statementWithOutputCount(): number {
+ return this._statementWithOutputCount;
+ }
+
+ iter<T extends Row>(spec: T): RowIterator<T> {
+ const impl = new RowIteratorImplWithRowData(spec, this);
+ return impl as {} as RowIterator<T>;
+ }
+
+ firstRow<T extends Row>(spec: T): T {
+ const impl = new RowIteratorImplWithRowData(spec, this);
+ assertTrue(impl.valid());
+ return impl as {} as RowIterator<T>as T;
+ }
+
+ // Can be called only once.
+ waitAllRows(): Promise<QueryResult> {
+ assertTrue(this.allRowsPromise === undefined);
+ this.allRowsPromise = defer<QueryResult>();
+ if (this._isComplete) {
+ this.resolveOrReject(this.allRowsPromise, this);
+ }
+ return this.allRowsPromise;
+ }
+
+ // --- WritableQueryResult implementation.
+
+ // Called by the engine when a new QueryResult is available. Note that a
+ // single Query() call can yield >1 QueryResult due to result batching
+ // if more than ~64K of data are returned, e.g. when returning O(M) rows.
+ // |resBytes| is a proto-encoded trace_processor.QueryResult message.
+ // It is fine to retain the resBytes without slicing a copy, because
+ // ProtoRingBuffer does the slice() for us (or passes through the buffer
+ // coming from postMessage() (Wasm case) of fetch() (HTTP+RPC case).
+ appendResultBatch(resBytes: Uint8Array) {
+ const reader = protobuf.Reader.create(resBytes);
+ assertTrue(reader.pos === 0);
+ const columnNamesEmptyAtStartOfBatch = this.columnNames.length === 0;
+ const columnNamesSet = new Set<string>();
+ while (reader.pos < reader.len) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1: // column_names
+ // Only the first batch should contain the column names. If this fires
+ // something is going wrong in the handling of the batch stream.
+ assertTrue(columnNamesEmptyAtStartOfBatch);
+ const origColName = reader.string();
+ let colName = origColName;
+ // In some rare cases two columns can have the same name (b/194891824)
+ // e.g. `select 1 as x, 2 as x`. These queries don't happen in the
+ // UI code, but they can happen when the user types a query (e.g.
+ // with a join). The most practical thing we can do here is renaming
+ // the columns with a suffix. Keeping the same name will break when
+ // iterating, because column names become iterator object keys.
+ for (let i = 1; columnNamesSet.has(colName); ++i) {
+ colName = `${origColName}_${i}`;
+ assertTrue(i < 100); // Give up at some point;
+ }
+ columnNamesSet.add(colName);
+ this.columnNames.push(colName);
+ break;
+ case 2: // error
+ // The query has errored only if the |error| field is non-empty.
+ // In protos, we don't distinguish between non-present and empty.
+ // Make sure we don't propagate ambiguous empty strings to JS.
+ const err = reader.string();
+ this._error = (err !== undefined && err.length) ? err : undefined;
+ break;
+ case 3: // batch
+ const batchLen = reader.uint32();
+ const batchRaw = resBytes.subarray(reader.pos, reader.pos + batchLen);
+ reader.pos += batchLen;
+
+ // The ResultBatch ctor parses the CellsBatch submessage.
+ const parsedBatch = new ResultBatch(batchRaw);
+ this.batches.push(parsedBatch);
+ this._isComplete = parsedBatch.isLastBatch;
+
+ // In theory one could construct a valid proto serializing the column
+ // names after the cell batches. In practice the QueryResultSerializer
+ // doesn't do that so it's not worth complicating the code.
+ const numColumns = this.columnNames.length;
+ if (numColumns !== 0) {
+ assertTrue(parsedBatch.numCells % numColumns === 0);
+ this._numRows += parsedBatch.numCells / numColumns;
+ } else {
+ // numColumns == 0 is plausible for queries like CREATE TABLE ... .
+ assertTrue(parsedBatch.numCells === 0);
+ }
+ break;
+
+ case 4:
+ this._statementCount = reader.uint32();
+ break;
+
+ case 5:
+ this._statementWithOutputCount = reader.uint32();
+ break;
+
+ default:
+ console.warn(`Unexpected QueryResult field ${tag >>> 3}`);
+ reader.skipType(tag & 7);
+ break;
+ } // switch (tag)
+ } // while (pos < end)
+
+ if (this._isComplete && this.allRowsPromise !== undefined) {
+ this.resolveOrReject(this.allRowsPromise, this);
+ }
+ }
+
+ ensureAllRowsPromise(): Promise<QueryResult> {
+ if (this.allRowsPromise === undefined) {
+ this.waitAllRows(); // Will populate |this.allRowsPromise|.
+ }
+ return assertExists(this.allRowsPromise);
+ }
+
+ private resolveOrReject(promise: Deferred<QueryResult>, arg: QueryResult) {
+ if (this._error === undefined) {
+ promise.resolve(arg);
+ } else {
+ promise.reject(new QueryError(this._error, this._errorInfo));
+ }
+ }
+}
+
+// This class holds onto a received result batch (a Uint8Array) and does some
+// partial parsing to tokenize the various cell groups. This parsing mainly
+// consists of identifying and caching the offsets of each cell group and
+// initializing the varint decoders. This half parsing is done to keep the
+// iterator's next() fast, without decoding everything into memory.
+// This is an internal implementation detail and is not exposed outside. The
+// RowIteratorImpl uses this class to iterate through batches (this class takes
+// care of iterating within a batch, RowIteratorImpl takes care of switching
+// batches when needed).
+// Note: at any point in time there can be more than one ResultIterator
+// referencing the same batch. The batch must be immutable.
+class ResultBatch {
+ readonly isLastBatch: boolean = false;
+ readonly batchBytes: Uint8Array;
+ readonly cellTypesOff: number = 0;
+ readonly cellTypesLen: number = 0;
+ readonly varintOff: number = 0;
+ readonly varintLen: number = 0;
+ readonly float64Cells = new Float64Array();
+ readonly blobCells: Uint8Array[] = [];
+ readonly stringCells: string[] = [];
+
+ // batchBytes is a trace_processor.QueryResult.CellsBatch proto.
+ constructor(batchBytes: Uint8Array) {
+ this.batchBytes = batchBytes;
+ const reader = protobuf.Reader.create(batchBytes);
+ assertTrue(reader.pos === 0);
+ const end = reader.len;
+
+ // Here we deconstruct the proto by hand. The CellsBatch is carefully
+ // designed to allow a very fast parsing from the TS side. We pack all cells
+ // of the same types together, so we can do only one call (per batch) to
+ // TextDecoder.decode(), we can overlay a memory-aligned typedarray for
+ // float values and can quickly tell and type-check the cell types.
+ // One row = N cells (we know the number upfront from the outer message).
+ // Each bach contains always an integer multiple of N cells (i.e. rows are
+ // never fragmented across different batches).
+ while (reader.pos < end) {
+ const tag = reader.uint32();
+ switch (tag >>> 3) {
+ case 1: // cell types, a packed array containing one CellType per cell.
+ assertTrue((tag & 7) === TAG_LEN_DELIM); // Must be packed varint.
+ this.cellTypesLen = reader.uint32();
+ this.cellTypesOff = reader.pos;
+ reader.pos += this.cellTypesLen;
+ break;
+
+ case 2: // varint_cells, a packed varint buffer.
+ assertTrue((tag & 7) === TAG_LEN_DELIM); // Must be packed varint.
+ const packLen = reader.uint32();
+ this.varintOff = reader.pos;
+ this.varintLen = packLen;
+ assertTrue(reader.buf === batchBytes);
+ assertTrue(
+ this.varintOff + this.varintLen <=
+ batchBytes.byteOffset + batchBytes.byteLength);
+ reader.pos += packLen;
+ break;
+
+ case 3: // float64_cells, a 64-bit aligned packed fixed64 buffer.
+ assertTrue((tag & 7) === TAG_LEN_DELIM); // Must be packed varint.
+ const f64Len = reader.uint32();
+ assertTrue(f64Len % 8 === 0);
+ // Float64Array's constructor is evil: the offset is in bytes but the
+ // length is in 8-byte words.
+ const f64Words = f64Len / 8;
+ const f64Off = batchBytes.byteOffset + reader.pos;
+ if (f64Off % 8 === 0) {
+ this.float64Cells =
+ new Float64Array(batchBytes.buffer, f64Off, f64Words);
+ } else {
+ // When using the production code in trace_processor's rpc.cc, the
+ // float64 should be 8-bytes aligned. The slow-path case is only for
+ // tests.
+ const slice = batchBytes.buffer.slice(f64Off, f64Off + f64Len);
+ this.float64Cells = new Float64Array(slice);
+ }
+ reader.pos += f64Len;
+ break;
+
+ case 4: // blob_cells: one entry per blob.
+ assertTrue((tag & 7) === TAG_LEN_DELIM);
+ // protobufjs's bytes() under the hoods calls slice() and creates
+ // a copy. Fine here as blobs are rare and not a fastpath.
+ this.blobCells.push(new Uint8Array(reader.bytes()));
+ break;
+
+ case 5: // string_cells: all the string cells concatenated with \0s.
+ assertTrue((tag & 7) === TAG_LEN_DELIM);
+ const strLen = reader.uint32();
+ assertTrue(reader.pos + strLen <= end);
+ const subArr = batchBytes.subarray(reader.pos, reader.pos + strLen);
+ assertTrue(subArr.length === strLen);
+ // The reason why we do this split rather than creating one string
+ // per entry is that utf8 decoding has some non-negligible cost. See
+ // go/postmessage-benchmark .
+ this.stringCells = utf8Decode(subArr).split('\0');
+ reader.pos += strLen;
+ break;
+
+ case 6: // is_last_batch (boolean).
+ this.isLastBatch = !!reader.bool();
+ break;
+
+ case 7: // padding for realignment, skip silently.
+ reader.skipType(tag & 7);
+ break;
+
+ default:
+ console.warn(`Unexpected QueryResult.CellsBatch field ${tag >>> 3}`);
+ reader.skipType(tag & 7);
+ break;
+ } // switch(tag)
+ } // while (pos < end)
+ }
+
+ get numCells() {
+ return this.cellTypesLen;
+ }
+}
+
+class RowIteratorImpl implements RowIteratorBase {
+ // The spec passed to the iter call containing the expected types, e.g.:
+ // {'colA': NUM, 'colB': NUM_NULL, 'colC': STRING}.
+ // This doesn't ever change.
+ readonly rowSpec: Row;
+
+ // The object that holds the current row. This points to the parent
+ // RowIteratorImplWithRowData instance that created this class.
+ rowData: Row;
+
+ // The QueryResult object we are reading data from. The engine will pump
+ // batches over time into this object.
+ private resultObj: QueryResultImpl;
+
+ // All the member variables in the group below point to the identically-named
+ // members in result.batch[batchIdx]. This is to avoid indirection layers in
+ // the next() hotpath, so we can do this.float64Cells vs
+ // this.resultObj.batch[this.batchIdx].float64Cells.
+ // These are re-set every time tryMoveToNextBatch() is called (and succeeds).
+ private batchIdx = -1; // The batch index within |result.batches[]|.
+ private batchBytes = new Uint8Array();
+ private columnNames: string[] = [];
+ private numColumns = 0;
+ private cellTypesEnd = -1; // -1 so the 1st next() hits tryMoveToNextBatch().
+ private float64Cells = new Float64Array();
+ private varIntReader = protobuf.Reader.create(this.batchBytes);
+ private blobCells: Uint8Array[] = [];
+ private stringCells: string[] = [];
+
+ // These members instead are incremented as we read cells from next(). They
+ // are the mutable state of the iterator.
+ private nextCellTypeOff = 0;
+ private nextFloat64Cell = 0;
+ private nextStringCell = 0;
+ private nextBlobCell = 0;
+ private isValid = false;
+
+ constructor(querySpec: Row, rowData: Row, res: QueryResultImpl) {
+ Object.assign(this, querySpec);
+ this.rowData = rowData;
+ this.rowSpec = {...querySpec}; // ... -> Copy all the key/value pairs.
+ this.resultObj = res;
+ this.next();
+ }
+
+ valid(): boolean {
+ return this.isValid;
+ }
+
+
+ get(columnName: string): ColumnType {
+ const res = this.rowData[columnName];
+ if (res === undefined) {
+ throw new Error(
+ `Column '${columnName}' doesn't exist. ` +
+ `Actual columns: [${this.columnNames.join(',')}]`);
+ }
+ return res;
+ }
+
+ // Moves the cursor next by one row and updates |isValid|.
+ // When this fails to move, two cases are possible:
+ // 1. We reached the end of the result set (this is the case if
+ // QueryResult.isComplete() == true when this fails).
+ // 2. We reached the end of the current batch, but more rows might come later
+ // (if QueryResult.isComplete() == false).
+ next() {
+ // At some point we might reach the end of the current batch, but the next
+ // batch might be available already. In this case we want next() to
+ // transparently move on to the next batch.
+ while (this.nextCellTypeOff + this.numColumns > this.cellTypesEnd) {
+ // If TraceProcessor is behaving well, we should never end up in a
+ // situation where we have leftover cells. TP is expected to serialize
+ // whole rows in each QueryResult batch and NOT truncate them midway.
+ // If this assert fires the TP RPC logic has a bug.
+ assertTrue(
+ this.nextCellTypeOff === this.cellTypesEnd ||
+ this.cellTypesEnd === -1);
+ if (!this.tryMoveToNextBatch()) {
+ this.isValid = false;
+ return;
+ }
+ }
+
+ const rowData = this.rowData;
+ const numColumns = this.numColumns;
+
+ // Read the current row.
+ for (let i = 0; i < numColumns; i++) {
+ const cellType = this.batchBytes[this.nextCellTypeOff++];
+ const colName = this.columnNames[i];
+
+ switch (cellType) {
+ case CellType.CELL_NULL:
+ rowData[colName] = null;
+ break;
+
+ case CellType.CELL_VARINT:
+ const val = this.varIntReader.int64();
+ // This is very subtle. The return type of int64 can be either a
+ // number or a Long.js {high:number, low:number} if Long.js support is
+ // enabled. The default state seems different in node and browser.
+ // We force-disable Long.js support in the top of this source file.
+ rowData[colName] = val as {} as number;
+ break;
+
+ case CellType.CELL_FLOAT64:
+ rowData[colName] = this.float64Cells[this.nextFloat64Cell++];
+ break;
+
+ case CellType.CELL_STRING:
+ rowData[colName] = this.stringCells[this.nextStringCell++];
+ break;
+
+ case CellType.CELL_BLOB:
+ const blob = this.blobCells[this.nextBlobCell++];
+ throw new Error(`TODO implement BLOB support (${blob})`);
+ // outRow[colName] = blob;
+ break;
+
+ default:
+ throw new Error(`Invalid cell type ${cellType}`);
+ }
+ } // For (cells)
+ this.isValid = true;
+ }
+
+ private tryMoveToNextBatch(): boolean {
+ const nextBatchIdx = this.batchIdx + 1;
+ if (nextBatchIdx >= this.resultObj.batches.length) {
+ return false;
+ }
+
+ this.columnNames = this.resultObj.columnNames;
+ this.numColumns = this.columnNames.length;
+
+ this.batchIdx = nextBatchIdx;
+ const batch = assertExists(this.resultObj.batches[nextBatchIdx]);
+ this.batchBytes = batch.batchBytes;
+ this.nextCellTypeOff = batch.cellTypesOff;
+ this.cellTypesEnd = batch.cellTypesOff + batch.cellTypesLen;
+ this.float64Cells = batch.float64Cells;
+ this.blobCells = batch.blobCells;
+ this.stringCells = batch.stringCells;
+ this.varIntReader = protobuf.Reader.create(batch.batchBytes);
+ this.varIntReader.pos = batch.varintOff;
+ this.varIntReader.len = batch.varintOff + batch.varintLen;
+ this.nextFloat64Cell = 0;
+ this.nextStringCell = 0;
+ this.nextBlobCell = 0;
+
+ // Check that all the expected columns are present.
+ for (const expectedCol of Object.keys(this.rowSpec)) {
+ if (this.columnNames.indexOf(expectedCol) < 0) {
+ throw new Error(
+ `Column ${expectedCol} not found in the SQL result ` +
+ `set {${this.columnNames.join(' ')}}`);
+ }
+ }
+
+ // Check that the cells types are consistent.
+ const numColumns = this.numColumns;
+ if (batch.numCells === 0) {
+ // This can happen if the query result contains just an error. In this
+ // an empty batch with isLastBatch=true is appended as an EOF marker.
+ // In theory TraceProcessor could return an empty batch in the middle and
+ // that would be fine from a protocol viewpoint. In practice, no code path
+ // does that today so it doesn't make sense trying supporting it with a
+ // recursive call to tryMoveToNextBatch().
+ assertTrue(batch.isLastBatch);
+ return false;
+ }
+
+ assertTrue(numColumns > 0);
+ for (let i = this.nextCellTypeOff; i < this.cellTypesEnd; i++) {
+ const col = (i - this.nextCellTypeOff) % numColumns;
+ const colName = this.columnNames[col];
+ const actualType = this.batchBytes[i] as CellType;
+ const expType = this.rowSpec[colName];
+
+ // If undefined, the caller doesn't want to read this column at all, so
+ // it can be whatever.
+ if (expType === undefined) continue;
+
+ let err = '';
+ if (actualType === CellType.CELL_NULL &&
+ (expType !== STR_NULL && expType !== NUM_NULL)) {
+ err = 'SQL value is NULL but that was not expected' +
+ ` (expected type: ${columnTypeToString(expType)}). ` +
+ 'Did you intend to use NUM_NULL or STR_NULL?';
+ } else if (
+ ((actualType === CellType.CELL_VARINT ||
+ actualType === CellType.CELL_FLOAT64) &&
+ (expType !== NUM && expType !== NUM_NULL)) ||
+ ((actualType === CellType.CELL_STRING) &&
+ (expType !== STR && expType !== STR_NULL))) {
+ err = `Incompatible cell type. Expected: ${
+ columnTypeToString(
+ expType)} actual: ${CELL_TYPE_NAMES[actualType]}`;
+ }
+ if (err.length > 0) {
+ throw new Error(
+ `Error @ row: ${Math.floor(i / numColumns)} col: '` +
+ `${colName}': ${err}`);
+ }
+ }
+ return true;
+ }
+}
+
+// This is the object ultimately returned to the client when calling
+// QueryResult.iter(...).
+// The only reason why this is disjoint from RowIteratorImpl is to avoid
+// naming collisions between the members variables required by RowIteratorImpl
+// and the column names returned by the iterator.
+class RowIteratorImplWithRowData implements RowIteratorBase {
+ private _impl: RowIteratorImpl;
+
+ next: () => void;
+ valid: () => boolean;
+ get: (columnName: string) => ColumnType;
+
+ constructor(querySpec: Row, res: QueryResultImpl) {
+ const thisAsRow = this as {} as Row;
+ Object.assign(thisAsRow, querySpec);
+ this._impl = new RowIteratorImpl(querySpec, thisAsRow, res);
+ this.next = this._impl.next.bind(this._impl);
+ this.valid = this._impl.valid.bind(this._impl);
+ this.get = this._impl.get.bind(this._impl);
+ }
+}
+
+// This is a proxy object that wraps QueryResultImpl, adding await-ability.
+// This is so that:
+// 1. Clients that just want to await for the full result set can just call
+// await engine.query('...') and will get a QueryResult that is guaranteed
+// to be complete.
+// 2. Clients that know how to handle the streaming can use it straight away.
+class WaitableQueryResultImpl implements QueryResult, WritableQueryResult,
+ PromiseLike<QueryResult> {
+ private impl: QueryResultImpl;
+ private thenCalled = false;
+
+ constructor(errorInfo: QueryErrorInfo) {
+ this.impl = new QueryResultImpl(errorInfo);
+ }
+
+ // QueryResult implementation. Proxies all calls to the impl object.
+ iter<T extends Row>(spec: T) {
+  return this.impl.iter(spec);
+ }
+ firstRow<T extends Row>(spec: T) {
+  return this.impl.firstRow(spec);
+ }
+ waitAllRows() {
+  return this.impl.waitAllRows();
+ }
+ isComplete() {
+  return this.impl.isComplete();
+ }
+ numRows() {
+  return this.impl.numRows();
+ }
+ columns() {
+ return this.impl.columns();
+ }
+ error() {
+  return this.impl.error();
+ }
+ statementCount() {
+ return this.impl.statementCount();
+ }
+ statementWithOutputCount() {
+ return this.impl.statementWithOutputCount();
+ }
+
+ // WritableQueryResult implementation.
+ appendResultBatch(resBytes: Uint8Array) {
+ return this.impl.appendResultBatch(resBytes);
+ }
+
+ // PromiseLike<QueryResult> implementaton.
+
+ // tslint:disable-next-line no-any
+ then(onfulfilled: any, onrejected: any): any {
+ assertFalse(this.thenCalled);
+ this.thenCalled = true;
+ return this.impl.ensureAllRowsPromise().then(onfulfilled, onrejected);
+ }
+
+ // tslint:disable-next-line no-any
+ catch(error: any): any {
+ return this.impl.ensureAllRowsPromise().catch(error);
+ }
+
+ // tslint:disable-next-line no-any
+ finally(callback: () => void): any {
+ return this.impl.ensureAllRowsPromise().finally(callback);
+ }
+
+ get[Symbol.toStringTag](): string {
+ return 'Promise<WaitableQueryResult>';
+ }
+}
+
+export function createQueryResult(errorInfo: QueryErrorInfo): QueryResult&
+ Promise<QueryResult>&WritableQueryResult {
+ return new WaitableQueryResultImpl(errorInfo);
+}
diff --git a/ui/src/common/query_result_unittest.ts b/ui/src/common/query_result_unittest.ts
new file mode 100644
index 000000000..b71f26b3c
--- /dev/null
+++ b/ui/src/common/query_result_unittest.ts
@@ -0,0 +1,302 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import * as protoNamespace from '../gen/protos';
+
+import {createQueryResult, NUM, NUM_NULL, STR, STR_NULL} from './query_result';
+
+const T = protoNamespace.perfetto.protos.QueryResult.CellsBatch.CellType;
+const QueryResultProto = protoNamespace.perfetto.protos.QueryResult;
+
+test('QueryResult.SimpleOneRow', () => {
+ const batch = QueryResultProto.CellsBatch.create({
+ cells: [T.CELL_STRING, T.CELL_VARINT, T.CELL_STRING, T.CELL_FLOAT64],
+ varintCells: [42],
+ stringCells: ['the foo', 'the bar'].join('\0'),
+ float64Cells: [42.42],
+ isLastBatch: true,
+ });
+ const resProto = QueryResultProto.create({
+ columnNames: ['a_str', 'b_int', 'c_str', 'd_float'],
+ batch: [batch],
+ });
+
+ const qr = createQueryResult({query: 'Some query'});
+ qr.appendResultBatch(QueryResultProto.encode(resProto).finish());
+ expect(qr.isComplete()).toBe(true);
+ expect(qr.numRows()).toBe(1);
+
+ // First try iterating without selecting any column.
+ {
+ const iter = qr.iter({});
+ expect(iter.valid()).toBe(true);
+ iter.next();
+ expect(iter.valid()).toBe(false);
+ }
+
+ // Then select only two of them.
+ {
+ const iter = qr.iter({c_str: STR, d_float: NUM});
+ expect(iter.valid()).toBe(true);
+ expect(iter.c_str).toBe('the bar');
+ expect(iter.d_float).toBeCloseTo(42.42);
+ iter.next();
+ expect(iter.valid()).toBe(false);
+ }
+
+ // If a column is not present in the result set, iter() should throw.
+ expect(() => qr.iter({nx: NUM})).toThrowError(/\bnx\b.*not found/);
+});
+
+test('QueryResult.BigNumbers', () => {
+ const numAndExpectedStr = [
+ [0, '0'],
+ [-1, '-1'],
+ [-1000, '-1000'],
+ [1e12, '1000000000000'],
+ [1e12 * -1, '-1000000000000'],
+ [((1 << 31) - 1) | 0, '2147483647'],
+ [1 << 31, '-2147483648'],
+ [Number.MAX_SAFE_INTEGER, '9007199254740991'],
+ [Number.MIN_SAFE_INTEGER, '-9007199254740991'],
+ ];
+ const batch = QueryResultProto.CellsBatch.create({
+ cells: new Array<number>(numAndExpectedStr.length).fill(T.CELL_VARINT),
+ varintCells: numAndExpectedStr.map(x => x[0]) as number[],
+ isLastBatch: true,
+ });
+ const resProto = QueryResultProto.create({
+ columnNames: ['n'],
+ batch: [batch],
+ });
+
+ const qr = createQueryResult({query: 'Some query'});
+ qr.appendResultBatch(QueryResultProto.encode(resProto).finish());
+ const actual: string[] = [];
+ for (const iter = qr.iter({n: NUM}); iter.valid(); iter.next()) {
+ actual.push(BigInt(iter.n).toString());
+ }
+ expect(actual).toEqual(numAndExpectedStr.map(x => x[1]) as string[]);
+});
+
+test('QueryResult.Floats', () => {
+ const floats = [
+ 0.0,
+ 1.0,
+ -1.0,
+ 3.14159265358,
+ Number.MIN_SAFE_INTEGER,
+ Number.MAX_SAFE_INTEGER,
+ Number.NEGATIVE_INFINITY,
+ Number.POSITIVE_INFINITY,
+ Number.NaN,
+ ];
+ const batch = QueryResultProto.CellsBatch.create({
+ cells: new Array<number>(floats.length).fill(T.CELL_FLOAT64),
+ float64Cells: floats,
+ isLastBatch: true,
+ });
+ const resProto = QueryResultProto.create({
+ columnNames: ['n'],
+ batch: [batch],
+ });
+
+ const qr = createQueryResult({query: 'Some query'});
+ qr.appendResultBatch(QueryResultProto.encode(resProto).finish());
+ const actual: number[] = [];
+ for (const iter = qr.iter({n: NUM}); iter.valid(); iter.next()) {
+ actual.push(iter.n);
+ }
+ expect(actual).toEqual(floats);
+});
+
+test('QueryResult.Strings', () => {
+ const strings = [
+ 'a',
+ '',
+ '',
+ 'hello world',
+ 'In einem Bächlein helle da schoß in froher Eil',
+ '色ã¯åŒ‚ã¸ã©æ•£ã‚Šã¬ã‚‹ã‚’我ãŒä¸–誰ãžå¸¸ãªã‚‰ã‚“有為ã®å¥¥å±±ä»Šæ—¥è¶Šãˆã¦æµ…ã夢見ã˜é…”ã²ã‚‚ã›ãš'
+ ];
+ const batch = QueryResultProto.CellsBatch.create({
+ cells: new Array<number>(strings.length).fill(T.CELL_STRING),
+ stringCells: strings.join('\0'),
+ isLastBatch: true,
+ });
+ const resProto = QueryResultProto.create({
+ columnNames: ['s'],
+ batch: [batch],
+ });
+
+ const qr = createQueryResult({query: 'Some query'});
+ qr.appendResultBatch(QueryResultProto.encode(resProto).finish());
+ const actual: string[] = [];
+ for (const iter = qr.iter({s: STR}); iter.valid(); iter.next()) {
+ actual.push(iter.s);
+ }
+ expect(actual).toEqual(strings);
+});
+
+test('QueryResult.NullChecks', () => {
+ const cells: number[] = [];
+ cells.push(T.CELL_VARINT, T.CELL_NULL);
+ cells.push(T.CELL_NULL, T.CELL_STRING);
+ cells.push(T.CELL_VARINT, T.CELL_STRING);
+ const batch = QueryResultProto.CellsBatch.create({
+ cells,
+ varintCells: [1, 2],
+ stringCells: ['a', 'b'].join('\0'),
+ isLastBatch: true,
+ });
+ const resProto = QueryResultProto.create({
+ columnNames: ['n', 's'],
+ batch: [batch],
+ });
+
+ const qr = createQueryResult({query: 'Some query'});
+ qr.appendResultBatch(QueryResultProto.encode(resProto).finish());
+ const actualNums = new Array<number|null>();
+ const actualStrings = new Array<string|null>();
+ for (const iter = qr.iter({n: NUM_NULL, s: STR_NULL}); iter.valid();
+ iter.next()) {
+ actualNums.push(iter.n);
+ actualStrings.push(iter.s);
+ }
+ expect(actualNums).toEqual([1, null, 2]);
+ expect(actualStrings).toEqual([null, 'a', 'b']);
+
+ // Check that using NUM / STR throws.
+ expect(() => qr.iter({n: NUM_NULL, s: STR}))
+ .toThrowError(/col: 's'.*is NULL.*not expected/);
+ expect(() => qr.iter({n: NUM, s: STR_NULL}))
+ .toThrowError(/col: 'n'.*is NULL.*not expected/);
+ expect(qr.iter({n: NUM_NULL})).toBeTruthy();
+ expect(qr.iter({s: STR_NULL})).toBeTruthy();
+});
+
+test('QueryResult.EarlyError', () => {
+ const resProto = QueryResultProto.create({
+ columnNames: [],
+ batch: [{isLastBatch: true}],
+ error: 'Oh dear, this SQL query is too complicated, I give up',
+ });
+ const qr = createQueryResult({query: 'Some query'});
+ qr.appendResultBatch(QueryResultProto.encode(resProto).finish());
+ expect(qr.error()).toContain('Oh dear');
+ expect(qr.isComplete()).toBe(true);
+ const iter = qr.iter({});
+ expect(iter.valid()).toBe(false);
+});
+
+test('QueryResult.LateError', () => {
+ const resProto = QueryResultProto.create({
+ columnNames: ['n'],
+ batch: [
+ {
+ cells: [T.CELL_VARINT],
+ varintCells: [1],
+ },
+ {
+ cells: [T.CELL_VARINT],
+ varintCells: [2],
+ isLastBatch: true,
+ },
+ ],
+ error: 'I tried, I was getting there, but then I failed',
+ });
+ const qr = createQueryResult({query: 'Some query'});
+ qr.appendResultBatch(QueryResultProto.encode(resProto).finish());
+ expect(qr.error()).toContain('I failed');
+ const rows: number[] = [];
+ for (const iter = qr.iter({n: NUM}); iter.valid(); iter.next()) {
+ rows.push(iter.n);
+ }
+ expect(rows).toEqual([1, 2]);
+ expect(qr.isComplete()).toBe(true);
+});
+
+
+test('QueryResult.MultipleBatches', async () => {
+ const batch1 = QueryResultProto.create({
+ columnNames: ['n'],
+ batch: [{
+ cells: [T.CELL_VARINT],
+ varintCells: [1],
+ isLastBatch: false,
+ }],
+ });
+ const batch2 = QueryResultProto.create({
+ batch: [{
+ cells: [T.CELL_VARINT],
+ varintCells: [2],
+ isLastBatch: true,
+ }],
+ });
+
+ const qr = createQueryResult({query: 'Some query'});
+ expect(qr.isComplete()).toBe(false);
+
+ qr.appendResultBatch(QueryResultProto.encode(batch1).finish());
+ qr.appendResultBatch(QueryResultProto.encode(batch2).finish());
+
+ const awaitRes = await qr;
+
+ expect(awaitRes.isComplete()).toBe(true);
+ expect(qr.isComplete()).toBe(true);
+
+ expect(awaitRes.numRows()).toBe(2);
+ expect(qr.numRows()).toBe(2);
+});
+
+
+// Regression test for b/194891824 .
+test('QueryResult.DuplicateColumnNames', () => {
+ const batch = QueryResultProto.CellsBatch.create({
+ cells: [
+ T.CELL_VARINT,
+ T.CELL_STRING,
+ T.CELL_FLOAT64,
+ T.CELL_STRING,
+ T.CELL_STRING
+ ],
+ varintCells: [42],
+ stringCells: ['a', 'b', 'c'].join('\0'),
+ float64Cells: [4.2],
+ isLastBatch: true,
+ });
+ const resProto = QueryResultProto.create({
+ columnNames: ['x', 'y', 'x', 'x', 'y'],
+ batch: [batch],
+ });
+
+ const qr = createQueryResult({query: 'Some query'});
+ qr.appendResultBatch(QueryResultProto.encode(resProto).finish());
+ expect(qr.isComplete()).toBe(true);
+ expect(qr.numRows()).toBe(1);
+ expect(qr.columns()).toEqual(['x', 'y', 'x_1', 'x_2', 'y_1']);
+ // First try iterating without selecting any column.
+ {
+ const iter = qr.iter({x: NUM, y: STR, x_1: NUM, x_2: STR, y_1: STR});
+ expect(iter.valid()).toBe(true);
+ expect(iter.x).toBe(42);
+ expect(iter.y).toBe('a');
+ expect(iter.x_1).toBe(4.2);
+ expect(iter.x_2).toBe('b');
+ expect(iter.y_1).toBe('c');
+ iter.next();
+ expect(iter.valid()).toBe(false);
+ }
+ expect(() => qr.iter({x_3: NUM})).toThrowError(/\bx_3\b.*not found/);
+});
diff --git a/ui/src/common/search_data.ts b/ui/src/common/search_data.ts
index 70bfb7f26..0969c1d44 100644
--- a/ui/src/common/search_data.ts
+++ b/ui/src/common/search_data.ts
@@ -19,9 +19,9 @@ export interface SearchSummary {
}
export interface CurrentSearchResults {
- sliceIds: number[];
- tsStarts: number[];
- utids: number[];
+ sliceIds: Float64Array;
+ tsStarts: Float64Array;
+ utids: Float64Array;
trackIds: string[];
sources: string[];
totalResults: number;
diff --git a/ui/src/common/state.ts b/ui/src/common/state.ts
index 347c904d1..ef7edcdeb 100644
--- a/ui/src/common/state.ts
+++ b/ui/src/common/state.ts
@@ -12,6 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import {assertTrue} from '../base/logging';
+import {PivotTree} from '../controller/pivot_table_redux_controller';
+import {RecordConfig} from '../controller/record_config_types';
+
+import {
+ AggregationAttrs,
+ PivotAttrs,
+ SubQueryAttrs,
+ TableAttrs
+} from './pivot_table_common';
+
/**
* A plain js object, holding objects of type |Class| keyed by string id.
* We use this instead of using |Map| object since it is simpler and faster to
@@ -23,8 +34,9 @@ export type Timestamped<T> = {
[P in keyof T]: T[P];
}&{lastUpdate: number};
-export type OmniboxState =
- Timestamped<{omnibox: string; mode: 'SEARCH' | 'COMMAND'}>;
+export type OmniboxMode = 'SEARCH'|'COMMAND';
+
+export type OmniboxState = Timestamped<{omnibox: string; mode: OmniboxMode}>;
export type VisibleState =
Timestamped<{startSec: number; endSec: number; resolution: number;}>;
@@ -52,7 +64,23 @@ export interface Area {
export const MAX_TIME = 180;
// 3: TrackKindPriority and related sorting changes.
-export const STATE_VERSION = 3;
+// 5: Move a large number of items off frontendLocalState and onto state.
+// 6: Common PivotTableConfig and pivot table specific PivotTableState.
+// 7: Split Chrome categories in two and add 'symbolize ksyms' flag.
+// 8: Rename several variables
+// "[...]HeapProfileFlamegraph[...]" -> "[...]Flamegraph[...]".
+// 9: Add a field to track last loaded recording profile name
+// 10: Change last loaded profile tracking type to accommodate auto-save.
+// 11: Rename updateChromeCategories to fetchChromeCategories.
+// 12: Add a field to cache mapping from UI track ID to trace track ID in order
+// to speed up flow arrows rendering.
+// 13: FlamegraphState changed to support area selection.
+// 14: Changed the type of uiTrackIdByTraceTrackId from `Map` to an object with
+// typed key/value because a `Map` does not preserve type during
+// serialisation+deserialisation.
+// 15: Added state for Pivot Table V2
+// 16: Added boolean tracking if the flamegraph modal was dismissed
+export const STATE_VERSION = 16;
export const SCROLLING_TRACK_GROUP = 'ScrollingTracks';
@@ -64,11 +92,13 @@ export enum TrackKindPriority {
'MAIN_THREAD' = 0,
'RENDER_THREAD' = 1,
'GPU_COMPLETION' = 2,
- 'ORDINARY' = 3
+ 'CHROME_IO_THREAD' = 3,
+ 'CHROME_COMPOSITOR' = 4,
+ 'ORDINARY' = 5
}
-export type HeapProfileFlamegraphViewingOption =
- 'SPACE'|'ALLOC_SPACE'|'OBJECTS'|'ALLOC_OBJECTS';
+export type FlamegraphStateViewingOption =
+ 'SPACE'|'ALLOC_SPACE'|'OBJECTS'|'ALLOC_OBJECTS'|'PERF_SAMPLES';
export interface CallsiteInfo {
id: number;
@@ -80,6 +110,7 @@ export interface CallsiteInfo {
mapping: string;
merged: boolean;
highlighted: boolean;
+ location?: string;
}
export interface TraceFileSource {
@@ -89,10 +120,20 @@ export interface TraceFileSource {
export interface TraceArrayBufferSource {
type: 'ARRAY_BUFFER';
+ buffer: ArrayBuffer;
title: string;
url?: string;
fileName?: string;
- buffer: ArrayBuffer;
+
+ // |uuid| is set only when loading via ?local_cache_key=1234. When set,
+ // this matches global.state.traceUuid, with the exception of the following
+ // time window: When a trace T1 is loaded and the user loads another trace T2,
+ // this |uuid| will be == T2, but the globals.state.traceUuid will be
+ // temporarily == T1 until T2 has been loaded (consistently to what happens
+ // with all other state fields).
+ uuid?: string;
+ // if |localOnly| is true then the trace should not be shared or downloaded.
+ localOnly?: boolean;
}
export interface TraceUrlSource {
@@ -112,9 +153,13 @@ export interface TrackState {
engineId: string;
kind: string;
name: string;
+ labels?: string[];
trackKindPriority: TrackKindPriority;
trackGroup?: string;
- config: {};
+ config: {
+ trackId?: number;
+ trackIds?: number[];
+ };
}
export interface TrackGroupState {
@@ -162,7 +207,7 @@ export interface Status {
}
export interface Note {
- noteType: 'DEFAULT'|'MOVIE';
+ noteType: 'DEFAULT';
id: string;
timestamp: number;
color: string;
@@ -202,13 +247,21 @@ export interface HeapProfileSelection {
type: string;
}
-export interface HeapProfileFlamegraph {
- kind: 'HEAP_PROFILE_FLAMEGRAPH';
+export interface PerfSamplesSelection {
+ kind: 'PERF_SAMPLES';
id: number;
upid: number;
ts: number;
type: string;
- viewingOption: HeapProfileFlamegraphViewingOption;
+}
+
+export interface FlamegraphState {
+ kind: 'FLAMEGRAPH_STATE';
+ upids: number[];
+ startNs: number;
+ endNs: number;
+ type: string;
+ viewingOption: FlamegraphStateViewingOption;
focusRegex: string;
expandedCallsite?: CallsiteInfo;
}
@@ -234,7 +287,8 @@ export interface ThreadStateSelection {
type Selection =
(NoteSelection|SliceSelection|CounterSelection|HeapProfileSelection|
CpuProfileSampleSelection|ChromeSliceSelection|ThreadStateSelection|
- AreaSelection)&{trackId?: string};
+ AreaSelection|PerfSamplesSelection)&{trackId?: string};
+export type SelectionKind = Selection['kind']; // 'THREAD_STATE' | 'SLICE' ...
export interface LogsPagination {
offset: number;
@@ -266,11 +320,79 @@ export interface MetricsState {
requestedMetric?: string; // Unset after metric request is handled.
}
+export interface PivotTableConfig {
+ availableColumns?: TableAttrs[]; // Undefined until list is loaded.
+ availableAggregations?: string[]; // Undefined until list is loaded.
+}
+
+export interface PivotTableState {
+ id: string;
+ name: string;
+ selectedPivots: PivotAttrs[];
+ selectedAggregations: AggregationAttrs[];
+ requestedAction?: // Unset after pivot table column request is handled.
+ {action: string, attrs?: SubQueryAttrs};
+ isLoadingQuery: boolean;
+ traceTime?: TraceTime;
+ selectedTrackIds?: number[];
+}
+
+// Auxiliary metadata needed to parse the query result, as well as to render it
+// correctly. Generated together with the text of query and passed without the
+// change to the query response.
+export interface PivotTableReduxQueryMetadata {
+ tableName: string;
+ pivotColumns: string[];
+ aggregationColumns: string[];
+}
+
+// Everything that's necessary to run the query for pivot table
+export interface PivotTableReduxQuery {
+ text: string;
+ metadata: PivotTableReduxQueryMetadata;
+}
+
+// Pivot table query result
+export interface PivotTableReduxResult {
+ // Hierarchical pivot structure on top of rows
+ tree: PivotTree;
+ // Copy of the query metadata from the request, bundled up with the query
+ // result to ensure the correct rendering.
+ metadata: PivotTableReduxQueryMetadata;
+}
+
+export interface PivotTableReduxState {
+ // Currently selected area, if null, pivot table is not going to be visible.
+ selectionArea: Area|null;
+ // Increasing identifier of the query request, used to avoid performing the
+ // same query more than once.
+ queryId: number;
+ // Query request
+ query: PivotTableReduxQuery|null;
+ // Query response
+ queryResult: PivotTableReduxResult|null;
+}
+
+export interface LoadedConfigNone {
+ type: 'NONE';
+}
+
+export interface LoadedConfigAutomatic {
+ type: 'AUTOMATIC';
+}
+
+export interface LoadedConfigNamed {
+ type: 'NAMED';
+ name: string;
+}
+
+export type LoadedConfig =
+ LoadedConfigNone|LoadedConfigAutomatic|LoadedConfigNamed;
+
export interface State {
// tslint:disable-next-line:no-any
[key: string]: any;
version: number;
- route: string|null;
nextId: number;
nextNoteId: number;
nextAreaId: number;
@@ -280,6 +402,7 @@ export interface State {
*/
recordConfig: RecordConfig;
displayConfigAsPbtxt: boolean;
+ lastLoadedConfig: LoadedConfig;
/**
* Open traces.
@@ -287,8 +410,10 @@ export interface State {
newEngineMode: NewEngineMode;
engines: ObjectById<EngineConfig>;
traceTime: TraceTime;
+ traceUuid?: string;
trackGroups: ObjectById<TrackGroupState>;
tracks: ObjectById<TrackState>;
+ uiTrackIdByTraceTrackId: {[key: number]: string;};
areas: ObjectById<AreaById>;
aggregatePreferences: ObjectById<AggregationState>;
visibleTracks: string[];
@@ -302,9 +427,12 @@ export interface State {
notes: ObjectById<Note|AreaNote>;
status: Status;
currentSelection: Selection|null;
- currentHeapProfileFlamegraph: HeapProfileFlamegraph|null;
+ currentFlamegraphState: FlamegraphState|null;
logsPagination: LogsPagination;
traceConversionInProgress: boolean;
+ pivotTableConfig: PivotTableConfig;
+ pivotTable: ObjectById<PivotTableState>;
+ pivotTableRedux: PivotTableReduxState;
/**
* This state is updated on the frontend at 60Hz and eventually syncronised to
@@ -314,12 +442,24 @@ export interface State {
*/
frontendLocalState: FrontendLocalState;
- video: string | null;
- videoEnabled: boolean;
- videoOffset: number;
- videoNoteIds: string[];
- scrubbingEnabled: boolean;
- flagPauseEnabled: boolean;
+ // Show track perf debugging overlay
+ perfDebug: boolean;
+
+ // Show the sidebar extended
+ sidebarVisible: boolean;
+
+ // Hovered and focused events
+ hoveredUtid: number;
+ hoveredPid: number;
+ hoveredLogsTimestamp: number;
+ hoveredNoteTimestamp: number;
+ highlightedSliceId: number;
+ focusedFlowIdLeft: number;
+ focusedFlowIdRight: number;
+ pendingScrollId?: number;
+
+ searchIndex: number;
+ currentTab?: string;
/**
* Trace recording
@@ -327,12 +467,13 @@ export interface State {
recordingInProgress: boolean;
recordingCancelled: boolean;
extensionInstalled: boolean;
+ flamegraphModalDismissed: boolean;
recordingTarget: RecordingTarget;
availableAdbDevices: AdbRecordingTarget[];
lastRecordingError?: string;
recordingStatus?: string;
- updateChromeCategories: boolean;
+ fetchChromeCategories: boolean;
chromeCategories: string[]|undefined;
analyzePageQuery?: string;
}
@@ -346,7 +487,12 @@ export declare type RecordMode =
'STOP_WHEN_FULL' | 'RING_BUFFER' | 'LONG_TRACE';
// 'Q','P','O' for Android, 'L' for Linux, 'C' for Chrome.
-export declare type TargetOs = 'Q' | 'P' | 'O' | 'C' | 'L' | 'CrOS';
+export declare type TargetOs = 'S' | 'R' | 'Q' | 'P' | 'O' | 'C' | 'L' | 'CrOS';
+
+export function isTargetOsAtLeast(target: RecordingTarget, osVersion: string) {
+ assertTrue(osVersion.length === 1);
+ return target.os >= osVersion;
+}
export function isAndroidP(target: RecordingTarget) {
return target.os === 'P';
@@ -370,154 +516,23 @@ export function isLinuxTarget(target: RecordingTarget) {
export function isAdbTarget(target: RecordingTarget):
target is AdbRecordingTarget {
- if ((target as AdbRecordingTarget).serial) return true;
- return false;
+ return !!(target as AdbRecordingTarget).serial;
}
export function hasActiveProbes(config: RecordConfig) {
- const fieldsWithEmptyResult = new Set<string>(['hpBlockClient']);
- for (const key in config) {
+ const fieldsWithEmptyResult =
+ new Set<string>(['hpBlockClient', 'allAtraceApps']);
+ let key: keyof RecordConfig;
+ for (key in config) {
if (typeof (config[key]) === 'boolean' && config[key] === true &&
!fieldsWithEmptyResult.has(key)) {
return true;
}
}
- return false;
-}
-
-export interface RecordConfig {
- [key: string]: null|number|boolean|string|string[];
-
- // Global settings
- mode: RecordMode;
- durationMs: number;
- bufferSizeMb: number;
- maxFileSizeMb: number; // Only for mode == 'LONG_TRACE'.
- fileWritePeriodMs: number; // Only for mode == 'LONG_TRACE'.
-
- cpuSched: boolean;
- cpuFreq: boolean;
- cpuCoarse: boolean;
- cpuCoarsePollMs: number;
- cpuSyscall: boolean;
-
- screenRecord: boolean;
-
- gpuFreq: boolean;
- gpuMemTotal: boolean;
-
- ftrace: boolean;
- atrace: boolean;
- ftraceEvents: string[];
- ftraceExtraEvents: string;
- atraceCats: string[];
- atraceApps: string;
- ftraceBufferSizeKb: number;
- ftraceDrainPeriodMs: number;
- androidLogs: boolean;
- androidLogBuffers: string[];
- androidFrameTimeline: boolean;
-
- batteryDrain: boolean;
- batteryDrainPollMs: number;
-
- boardSensors: boolean;
-
- memHiFreq: boolean;
- memLmk: boolean;
- meminfo: boolean;
- meminfoPeriodMs: number;
- meminfoCounters: string[];
- vmstat: boolean;
- vmstatPeriodMs: number;
- vmstatCounters: string[];
-
- heapProfiling: boolean;
- hpSamplingIntervalBytes: number;
- hpProcesses: string;
- hpContinuousDumpsPhase: number;
- hpContinuousDumpsInterval: number;
- hpSharedMemoryBuffer: number;
- hpBlockClient: boolean;
- hpAllHeaps: boolean;
-
- javaHeapDump: boolean;
- jpProcesses: string;
- jpContinuousDumpsPhase: number;
- jpContinuousDumpsInterval: number;
-
- procStats: boolean;
- procStatsPeriodMs: number;
-
- chromeCategoriesSelected: string[];
-}
-
-export function createEmptyRecordConfig(): RecordConfig {
- return {
- mode: 'STOP_WHEN_FULL',
- durationMs: 10000.0,
- maxFileSizeMb: 100,
- fileWritePeriodMs: 2500,
- bufferSizeMb: 64.0,
-
- cpuSched: false,
- cpuFreq: false,
- cpuSyscall: false,
-
- screenRecord: false,
-
- gpuFreq: false,
- gpuMemTotal: false,
-
- ftrace: false,
- atrace: false,
- ftraceEvents: [],
- ftraceExtraEvents: '',
- atraceCats: [],
- atraceApps: '',
- ftraceBufferSizeKb: 2 * 1024,
- ftraceDrainPeriodMs: 250,
- androidLogs: false,
- androidLogBuffers: [],
- androidFrameTimeline: false,
-
- cpuCoarse: false,
- cpuCoarsePollMs: 1000,
-
- batteryDrain: false,
- batteryDrainPollMs: 1000,
-
- boardSensors: false,
-
- memHiFreq: false,
- meminfo: false,
- meminfoPeriodMs: 1000,
- meminfoCounters: [],
-
- vmstat: false,
- vmstatPeriodMs: 1000,
- vmstatCounters: [],
-
- heapProfiling: false,
- hpSamplingIntervalBytes: 4096,
- hpProcesses: '',
- hpContinuousDumpsPhase: 0,
- hpContinuousDumpsInterval: 0,
- hpSharedMemoryBuffer: 8 * 1048576,
- hpBlockClient: true,
- hpAllHeaps: false,
-
- javaHeapDump: false,
- jpProcesses: '',
- jpContinuousDumpsPhase: 0,
- jpContinuousDumpsInterval: 0,
-
- memLmk: false,
- procStats: false,
- procStatsPeriodMs: 1000,
-
- chromeCategoriesSelected: [],
- };
+ if (config.chromeCategoriesSelected.length > 0) {
+ return true;
+ }
+ return config.chromeHighOverheadCategoriesSelected.length > 0;
}
export function getDefaultRecordingTargets(): RecordingTarget[] {
@@ -532,7 +547,7 @@ export function getDefaultRecordingTargets(): RecordingTarget[] {
}
export function getBuiltinChromeCategoryList(): string[] {
- // List of static Chrome categories, last updated at Chromium 81.0.4021.0 from
+ // List of static Chrome categories, last updated at 2021-09-09 from HEAD of
// Chromium's //base/trace_event/builtin_categories.h.
return [
'accessibility',
@@ -546,11 +561,12 @@ export function getBuiltinChromeCategoryList(): string[] {
'blink.animations',
'blink.bindings',
'blink.console',
- 'blink_gc',
'blink.net',
- 'blink_style',
+ 'blink.resource',
'blink.user_timing',
'blink.worker',
+ 'blink_gc',
+ 'blink_style',
'Blob',
'browser',
'browsing_data',
@@ -582,10 +598,10 @@ export function getBuiltinChromeCategoryList(): string[] {
'drmcursor',
'dwrite',
'DXVA_Decoding',
- 'EarlyJava',
'evdev',
'event',
'exo',
+ 'extensions',
'explore_sites',
'FileSystem',
'file_system_provider',
@@ -643,6 +659,7 @@ export function getBuiltinChromeCategoryList(): string[] {
'RLZ',
'safe_browsing',
'screenlock_monitor',
+ 'segmentation_platform',
'sequence_manager',
'service_manager',
'ServiceWorker',
@@ -657,7 +674,7 @@ export function getBuiltinChromeCategoryList(): string[] {
'stadia_rtc',
'startup',
'sync',
- 'sync_lock_contention',
+ 'system_apps',
'test_gpu',
'thread_pool',
'toplevel',
@@ -680,6 +697,7 @@ export function getBuiltinChromeCategoryList(): string[] {
'disabled-by-default-animation-worklet',
'disabled-by-default-audio',
'disabled-by-default-audio-worklet',
+ 'disabled-by-default-base',
'disabled-by-default-blink.debug',
'disabled-by-default-blink.debug.display_lock',
'disabled-by-default-blink.debug.layout',
@@ -716,7 +734,6 @@ export function getBuiltinChromeCategoryList(): string[] {
'disabled-by-default-gpu.service',
'disabled-by-default-gpu.vulkan.vma',
'disabled-by-default-histogram_samples',
- 'disabled-by-default-ipc.flow',
'disabled-by-default-java-heap-profiler',
'disabled-by-default-layer-element',
'disabled-by-default-layout_shift.debug',
@@ -743,12 +760,10 @@ export function getBuiltinChromeCategoryList(): string[] {
'disabled-by-default-SyncFileSystem',
'disabled-by-default-system_stats',
'disabled-by-default-thread_pool_diagnostics',
- 'disabled-by-default-toplevel.flow',
'disabled-by-default-toplevel.ipc',
'disabled-by-default-user_action_samples',
'disabled-by-default-v8.compile',
'disabled-by-default-v8.cpu_profiler',
- 'disabled-by-default-v8.cpu_profiler.hires',
'disabled-by-default-v8.gc',
'disabled-by-default-v8.gc_stats',
'disabled-by-default-v8.ic_stats',
@@ -757,12 +772,11 @@ export function getBuiltinChromeCategoryList(): string[] {
'disabled-by-default-v8.runtime_stats_sampling',
'disabled-by-default-v8.stack_trace',
'disabled-by-default-v8.turbofan',
- 'disabled-by-default-v8.wasm',
'disabled-by-default-v8.wasm.detailed',
'disabled-by-default-v8.wasm.turbofan',
'disabled-by-default-video_and_image_capture',
- 'disabled-by-default-viz.debug.overlay_planes',
'disabled-by-default-viz.gpu_composite_time',
+ 'disabled-by-default-viz.debug.overlay_planes',
'disabled-by-default-viz.hit_testing_flow',
'disabled-by-default-viz.overdraw',
'disabled-by-default-viz.quads',
@@ -776,72 +790,6 @@ export function getBuiltinChromeCategoryList(): string[] {
];
}
-export function createEmptyState(): State {
- return {
- version: STATE_VERSION,
- route: null,
- nextId: 0,
- nextNoteId: 1, // 0 is reserved for ephemeral area marking.
- nextAreaId: 0,
- newEngineMode: 'USE_HTTP_RPC_IF_AVAILABLE',
- engines: {},
- traceTime: {...defaultTraceTime},
- tracks: {},
- aggregatePreferences: {},
- trackGroups: {},
- visibleTracks: [],
- pinnedTracks: [],
- scrollingTracks: [],
- areas: {},
- queries: {},
- metrics: {},
- permalink: {},
- notes: {},
-
- recordConfig: createEmptyRecordConfig(),
- displayConfigAsPbtxt: false,
-
- frontendLocalState: {
- omniboxState: {
- lastUpdate: 0,
- omnibox: '',
- mode: 'SEARCH',
- },
-
- visibleState: {
- ...defaultTraceTime,
- lastUpdate: 0,
- resolution: 0,
- },
- },
-
- logsPagination: {
- offset: 0,
- count: 0,
- },
-
- status: {msg: '', timestamp: 0},
- currentSelection: null,
- currentHeapProfileFlamegraph: null,
- traceConversionInProgress: false,
-
- video: null,
- videoEnabled: false,
- videoOffset: 0,
- videoNoteIds: [],
- scrubbingEnabled: false,
- flagPauseEnabled: false,
- recordingInProgress: false,
- recordingCancelled: false,
- extensionInstalled: false,
- recordingTarget: getDefaultRecordingTargets()[0],
- availableAdbDevices: [],
-
- updateChromeCategories: false,
- chromeCategories: undefined,
- };
-}
-
export function getContainingTrackId(state: State, trackId: string): null|
string {
const track = state.tracks[trackId];
diff --git a/ui/src/common/state_unittest.ts b/ui/src/common/state_unittest.ts
index 2f94a6e14..046f864b0 100644
--- a/ui/src/common/state_unittest.ts
+++ b/ui/src/common/state_unittest.ts
@@ -12,12 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {
- createEmptyState,
- getContainingTrackId,
- State,
- TrackKindPriority
-} from './state';
+import {createEmptyState} from './empty_state';
+import {getContainingTrackId, State, TrackKindPriority} from './state';
test('createEmptyState', () => {
const state: State = createEmptyState();
diff --git a/ui/src/common/time.ts b/ui/src/common/time.ts
index fce992dab..2a0a45b64 100644
--- a/ui/src/common/time.ts
+++ b/ui/src/common/time.ts
@@ -54,7 +54,7 @@ export function formatTimestamp(sec: number) {
// TODO(hjd): Rename to formatTimestampWithUnits
// 1000000023ns -> "1s 23ns"
-export function timeToCode(sec: number) {
+export function timeToCode(sec: number): string {
let result = '';
let ns = Math.round(sec * 1e9);
if (ns < 1) return '0s';
diff --git a/ui/src/common/upload_utils.ts b/ui/src/common/upload_utils.ts
index 03a9e39c8..d817084be 100644
--- a/ui/src/common/upload_utils.ts
+++ b/ui/src/common/upload_utils.ts
@@ -12,9 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import {RecordConfig} from '../controller/record_config_types';
+
export const BUCKET_NAME = 'perfetto-ui-data';
import * as uuidv4 from 'uuid/v4';
-import {State, RecordConfig} from './state';
+import {State} from './state';
export async function saveTrace(trace: File|ArrayBuffer): Promise<string> {
// TODO(hjd): This should probably also be a hash but that requires
diff --git a/ui/src/common/wasm_engine_proxy.ts b/ui/src/common/wasm_engine_proxy.ts
index 43f7b85cb..92c7157d0 100644
--- a/ui/src/common/wasm_engine_proxy.ts
+++ b/ui/src/common/wasm_engine_proxy.ts
@@ -12,60 +12,38 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {defer, Deferred} from '../base/deferred';
-import {assertTrue} from '../base/logging';
-import {WasmBridgeRequest, WasmBridgeResponse} from '../engine/wasm_bridge';
+import {assertExists, assertTrue} from '../base/logging';
import {Engine, LoadingTracker} from './engine';
+import {EngineWorkerInitMessage} from './worker_messages';
-const activeWorkers = new Map<string, Worker>();
-let warmWorker: null|Worker = null;
+let bundlePath: string;
+let idleWasmWorker: Worker;
+let activeWasmWorker: Worker;
-function createWorker(): Worker {
- return new Worker('engine_bundle.js');
+export function initWasm(root: string) {
+ bundlePath = root + 'engine_bundle.js';
+ idleWasmWorker = new Worker(bundlePath);
}
-// Take the warm engine and start creating a new WASM engine in the background
-// for the next call.
-export function createWasmEngine(id: string): Worker {
- if (warmWorker === null) {
- throw new Error('warmupWasmEngine() not called');
- }
- if (activeWorkers.has(id)) {
- throw new Error(`Duplicate worker ID ${id}`);
- }
- const activeWorker = warmWorker;
- warmWorker = createWorker();
- activeWorkers.set(id, activeWorker);
- return activeWorker;
-}
+// This method is called trace_controller whenever a new trace is loaded.
+export function resetEngineWorker(): MessagePort {
+ const channel = new MessageChannel();
+ const port = channel.port1;
-export function destroyWasmEngine(id: string) {
- if (!activeWorkers.has(id)) {
- throw new Error(`Cannot find worker ID ${id}`);
- }
- activeWorkers.get(id)!.terminate();
- activeWorkers.delete(id);
-}
-
-/**
- * It's quite slow to compile WASM and (in Chrome) this happens every time
- * a worker thread attempts to load a WASM module since there is no way to
- * cache the compiled code currently. To mitigate this we can always keep a
- * WASM backend 'ready to go' just waiting to be provided with a trace file.
- * warmupWasmEngineWorker (together with getWasmEngineWorker)
- * implement this behaviour.
- */
-export function warmupWasmEngine(): void {
- if (warmWorker !== null) {
- throw new Error('warmupWasmEngine() already called');
+ // We keep always an idle worker around, the first one is created by the
+ // main() below, so we can hide the latency of the Wasm initialization.
+ if (activeWasmWorker !== undefined) {
+ activeWasmWorker.terminate();
}
- warmWorker = createWorker();
-}
-interface PendingRequest {
- id: number;
- respHandler: Deferred<Uint8Array>;
+ // Swap the active worker with the idle one and create a new idle worker
+ // for the next trace.
+ activeWasmWorker = assertExists(idleWasmWorker);
+ const msg: EngineWorkerInitMessage = {enginePort: port};
+ activeWasmWorker.postMessage(msg, [port]);
+ idleWasmWorker = new Worker(bundlePath);
+ return channel.port2;
}
/**
@@ -74,83 +52,24 @@ interface PendingRequest {
*/
export class WasmEngineProxy extends Engine {
readonly id: string;
- private readonly worker: Worker;
- private pendingRequests = new Array<PendingRequest>();
- private nextRequestId = 0;
+ private port: MessagePort;
- constructor(id: string, worker: Worker, loadingTracker?: LoadingTracker) {
+ constructor(id: string, port: MessagePort, loadingTracker?: LoadingTracker) {
super(loadingTracker);
this.id = id;
- this.worker = worker;
- this.worker.onmessage = this.onMessage.bind(this);
- }
-
- async parse(reqData: Uint8Array): Promise<void> {
- // We don't care about the response data (the method is actually a void). We
- // just want to linearize and wait for the call to have been completed on
- // the worker.
- await this.queueRequest('trace_processor_parse', reqData);
- }
-
- async notifyEof(): Promise<void> {
- // We don't care about the response data (the method is actually a void). We
- // just want to linearize and wait for the call to have been completed on
- // the worker.
- await this.queueRequest('trace_processor_notify_eof', new Uint8Array());
- }
-
- restoreInitialTables(): Promise<void> {
- // We should never get here, restoreInitialTables() should be called only
- // when using the HttpRpcEngine.
- throw new Error('restoreInitialTables() not supported by the WASM engine');
- }
-
- rawQuery(rawQueryArgs: Uint8Array): Promise<Uint8Array> {
- return this.queueRequest('trace_processor_raw_query', rawQueryArgs);
- }
-
- rawComputeMetric(rawComputeMetric: Uint8Array): Promise<Uint8Array> {
- return this.queueRequest(
- 'trace_processor_compute_metric', rawComputeMetric);
- }
-
- async enableMetatrace(): Promise<void> {
- await this.queueRequest(
- 'trace_processor_enable_metatrace', new Uint8Array());
- }
-
- disableAndReadMetatrace(): Promise<Uint8Array> {
- return this.queueRequest(
- 'trace_processor_disable_and_read_metatrace', new Uint8Array());
- }
-
- // Enqueues a request to the worker queue via postMessage(). The returned
- // promised will be resolved once the worker replies to the postMessage()
- // with the paylad of the response, a proto-encoded object which wraps the
- // method return value (e.g., RawQueryResult for SQL query results).
- private queueRequest(methodName: string, reqData: Uint8Array):
- Deferred<Uint8Array> {
- const respHandler = defer<Uint8Array>();
- const id = this.nextRequestId++;
- const request: WasmBridgeRequest = {id, methodName, data: reqData};
- this.pendingRequests.push({id, respHandler});
- this.worker.postMessage(request);
- return respHandler;
+ this.port = port;
+ this.port.onmessage = this.onMessage.bind(this);
}
onMessage(m: MessageEvent) {
- const response = m.data as WasmBridgeResponse;
- assertTrue(this.pendingRequests.length > 0);
- const request = this.pendingRequests.shift()!;
-
- // Requests should be executed and ACKed by the worker in the same order
- // they came in.
- assertTrue(request.id === response.id);
+ assertTrue(m.data instanceof Uint8Array);
+ super.onRpcResponseBytes(m.data as Uint8Array);
+ }
- // If the Wasm call fails (e.g. hits a PERFETTO_CHECK) it will throw an
- // error in wasm_bridge.ts and show the crash dialog. In no case we can
- // gracefully handle a Wasm crash, so we fail fast there rather than
- // propagating the error here rejecting the promise.
- request.respHandler.resolve(response.data);
+ rpcSendRequestBytes(data: Uint8Array): void {
+ // We deliberately don't use a transfer list because protobufjs reuses the
+ // same buffer when encoding messages (which is good, because creating a new
+ // TypedArray for each decode operation would be too expensive).
+ this.port.postMessage(data);
}
}
diff --git a/ui/src/common/worker_messages.ts b/ui/src/common/worker_messages.ts
new file mode 100644
index 000000000..b90f6b28f
--- /dev/null
+++ b/ui/src/common/worker_messages.ts
@@ -0,0 +1,44 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// This file defines the API of messages exchanged between frontend and
+// {engine, controller} worker when bootstrapping the workers.
+// Those messages are sent only once. The rest of the communication happens
+// over the MessagePort(s) that are sent in the init message.
+
+// This is so we can create all the workers in a central place in the frontend
+// (Safari still doesn't spawning workers from other workers) but then let them
+// communicate by sending the right MessagePort to them.
+
+// Frontend -> Engine initialization message.
+export interface EngineWorkerInitMessage {
+ // The port used to receive engine messages (e.g., query commands).
+ // The controller owns the other end of the MessageChannel
+ // (see resetEngineWorker()).
+ enginePort: MessagePort;
+}
+
+// Frontend -> Controller initialization message.
+export interface ControllerWorkerInitMessage {
+ // For receiving dispatch() commands from the frontend. This is where most of
+ // the frontend <> controller interaction happens.
+ controllerPort: MessagePort;
+
+ // For controller <> Chrome extension communication.
+ extensionPort: MessagePort;
+
+ // For reporting errors back to the frontend. This is a dedicated port to
+ // reduce depdencies on the business logic behind the other ports.
+ errorReportingPort: MessagePort;
+}
diff --git a/ui/src/controller/adb.ts b/ui/src/controller/adb.ts
index 5ed615260..9bcc708c1 100644
--- a/ui/src/controller/adb.ts
+++ b/ui/src/controller/adb.ts
@@ -14,6 +14,8 @@
import {_TextDecoder, _TextEncoder} from 'custom_utils';
+import {assertExists} from '../base/logging';
+
import {Adb, AdbMsg, AdbStream, CmdType} from './adb_interfaces';
const textEncoder = new _TextEncoder();
@@ -72,7 +74,8 @@ export class AdbOverWebUsb implements Adb {
useChecksum = true;
private lastStreamId = 0;
- private dev: USBDevice|undefined;
+ private dev?: USBDevice;
+ private usbInterfaceNumber?: number;
private usbReadEndpoint = -1;
private usbWriteEpEndpoint = -1;
private filter = {
@@ -114,11 +117,10 @@ export class AdbOverWebUsb implements Adb {
this.key = await AdbOverWebUsb.initKey();
await this.dev.open();
- await this.dev.reset(); // The reset is done so that we can claim the
- // device before adb server can.
const {configValue, usbInterfaceNumber, endpoints} =
this.findInterfaceAndEndpoint();
+ this.usbInterfaceNumber = usbInterfaceNumber;
this.usbReadEndpoint = this.findEndpointNumber(endpoints, 'in');
this.usbWriteEpEndpoint = this.findEndpointNumber(endpoints, 'out');
@@ -137,13 +139,19 @@ export class AdbOverWebUsb implements Adb {
}
async disconnect(): Promise<void> {
+ if (this.state === AdbState.DISCONNECTED) {
+ return;
+ }
this.state = AdbState.DISCONNECTED;
if (!this.dev) return;
new Map(this.streams).forEach((stream, _id) => stream.setClosed());
console.assert(this.streams.size === 0);
+
+ await this.dev.releaseInterface(assertExists(this.usbInterfaceNumber));
this.dev = undefined;
+ this.usbInterfaceNumber = undefined;
}
async startAuthentication() {
@@ -295,7 +303,7 @@ export class AdbOverWebUsb implements Adb {
stream.onClose = () => {};
resolve(stream);
};
- stream.onClose = () => reject();
+ stream.onClose = () => reject(`Failed to openStream svc=${svc}`);
});
}
@@ -352,9 +360,7 @@ export class AdbOverWebUsb implements Adb {
};
const key = await crypto.subtle.generateKey(
- keySpec, /*extractable=*/ true, ['sign', 'verify']) as
- CryptoKeyPair;
-
+ keySpec, /*extractable=*/ true, ['sign', 'verify']);
return key;
}
diff --git a/ui/src/controller/adb_base_controller.ts b/ui/src/controller/adb_base_controller.ts
index a429d22ab..2ef278265 100644
--- a/ui/src/controller/adb_base_controller.ts
+++ b/ui/src/controller/adb_base_controller.ts
@@ -21,10 +21,11 @@ import {ReadBuffersResponse} from './consumer_port_types';
import {globals} from './globals';
import {Consumer, RpcConsumerPort} from './record_controller_interfaces';
-export enum AdbAuthState {
- DISCONNECTED,
+export enum AdbConnectionState {
+ READY_TO_CONNECT,
AUTH_IN_PROGRESS,
CONNECTED,
+ CLOSED
}
interface Command {
@@ -39,23 +40,39 @@ export abstract class AdbBaseConsumerPort extends RpcConsumerPort {
private commandQueue: Command[] = [];
protected adb: Adb;
- protected state = AdbAuthState.DISCONNECTED;
+ protected state = AdbConnectionState.READY_TO_CONNECT;
protected device?: USBDevice;
- constructor(adb: Adb, consumer: Consumer) {
+ protected constructor(adb: Adb, consumer: Consumer) {
super(consumer);
this.adb = adb;
}
async handleCommand(method: string, params: Uint8Array) {
try {
+ if (method === 'FreeBuffers') {
+ // When we finish tracing, we disconnect the adb device interface.
+ // Otherwise, we will keep holding the device interface and won't allow
+ // adb to access it. https://wicg.github.io/webusb/#abusing-a-device
+ // "Lastly, since USB devices are unable to distinguish requests from
+ // multiple sources, operating systems only allow a USB interface to
+ // have a single owning user-space or kernel-space driver."
+ this.state = AdbConnectionState.CLOSED;
+ await this.adb.disconnect();
+ } else if (method === 'EnableTracing') {
+ this.state = AdbConnectionState.READY_TO_CONNECT;
+ }
+
+ if (this.state === AdbConnectionState.CLOSED) return;
+
this.commandQueue.push({method, params});
- if (this.state === AdbAuthState.DISCONNECTED ||
+
+ if (this.state === AdbConnectionState.READY_TO_CONNECT ||
this.deviceDisconnected()) {
- this.state = AdbAuthState.AUTH_IN_PROGRESS;
+ this.state = AdbConnectionState.AUTH_IN_PROGRESS;
this.device = await this.findDevice();
if (!this.device) {
- this.state = AdbAuthState.DISCONNECTED;
+ this.state = AdbConnectionState.READY_TO_CONNECT;
const target = globals.state.recordingTarget;
throw Error(`Device with serial ${
isAdbTarget(target) ? target.serial : 'n/a'} not found.`);
@@ -71,20 +88,20 @@ export abstract class AdbBaseConsumerPort extends RpcConsumerPort {
throw Error('Recording not in progress after adb authorization.');
}
- this.state = AdbAuthState.CONNECTED;
+ this.state = AdbConnectionState.CONNECTED;
this.sendStatus('Device connected.');
}
- if (this.state === AdbAuthState.AUTH_IN_PROGRESS) return;
+ if (this.state === AdbConnectionState.AUTH_IN_PROGRESS) return;
- console.assert(this.state === AdbAuthState.CONNECTED);
+ console.assert(this.state === AdbConnectionState.CONNECTED);
for (const cmd of this.commandQueue) this.invoke(cmd.method, cmd.params);
this.commandQueue = [];
} catch (e) {
this.commandQueue = [];
- this.state = AdbAuthState.DISCONNECTED;
+ this.state = AdbConnectionState.READY_TO_CONNECT;
this.sendErrorMessage(e.message);
}
}
diff --git a/ui/src/controller/adb_shell_controller.ts b/ui/src/controller/adb_shell_controller.ts
index 9b457e77d..16cf6baa5 100644
--- a/ui/src/controller/adb_shell_controller.ts
+++ b/ui/src/controller/adb_shell_controller.ts
@@ -17,7 +17,7 @@ import {_TextDecoder} from 'custom_utils';
import {base64Encode} from '../base/string_utils';
import {extractTraceConfig} from '../base/trace_config_utils';
-import {AdbAuthState, AdbBaseConsumerPort} from './adb_base_controller';
+import {AdbBaseConsumerPort, AdbConnectionState} from './adb_base_controller';
import {Adb, AdbStream} from './adb_interfaces';
import {ReadBuffersResponse} from './consumer_port_types';
import {Consumer} from './record_controller_interfaces';
@@ -42,7 +42,7 @@ export class AdbConsumerPort extends AdbBaseConsumerPort {
async invoke(method: string, params: Uint8Array) {
// ADB connection & authentication is handled by the superclass.
- console.assert(this.state === AdbAuthState.CONNECTED);
+ console.assert(this.state === AdbConnectionState.CONNECTED);
switch (method) {
case 'EnableTracing':
diff --git a/ui/src/controller/adb_socket_controller.ts b/ui/src/controller/adb_socket_controller.ts
index f517f7ac4..9bedf3005 100644
--- a/ui/src/controller/adb_socket_controller.ts
+++ b/ui/src/controller/adb_socket_controller.ts
@@ -16,7 +16,7 @@ import * as protobuf from 'protobufjs/minimal';
import {perfetto} from '../gen/protos';
-import {AdbAuthState, AdbBaseConsumerPort} from './adb_base_controller';
+import {AdbBaseConsumerPort, AdbConnectionState} from './adb_base_controller';
import {Adb, AdbStream} from './adb_interfaces';
import {
isReadBuffersResponse,
@@ -84,7 +84,7 @@ export class AdbSocketConsumerPort extends AdbBaseConsumerPort {
async invoke(method: string, params: Uint8Array) {
// ADB connection & authentication is handled by the superclass.
- console.assert(this.state === AdbAuthState.CONNECTED);
+ console.assert(this.state === AdbConnectionState.CONNECTED);
this.socketCommandQueue.push({method, params});
if (this.socketState === SocketState.BINDING_IN_PROGRESS) return;
@@ -302,7 +302,7 @@ export class AdbSocketConsumerPort extends AdbBaseConsumerPort {
msgBindService: new perfetto.protos.IPCFrame.BindService(
{serviceName: 'ConsumerPort'})
});
- return new Promise((resolve, _) => {
+ return new Promise<void>((resolve, _) => {
this.resolveBindingPromise = resolve;
this.sendFrame(frame);
});
diff --git a/ui/src/controller/aggregation/aggregation_controller.ts b/ui/src/controller/aggregation/aggregation_controller.ts
index 0892e370e..af41ec7de 100644
--- a/ui/src/controller/aggregation/aggregation_controller.ts
+++ b/ui/src/controller/aggregation/aggregation_controller.ts
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import {Actions} from '../../common/actions';
import {
AggregateData,
Column,
@@ -19,8 +20,13 @@ import {
ThreadStateExtra,
} from '../../common/aggregation_data';
import {Engine} from '../../common/engine';
-import {slowlyCountRows} from '../../common/query_iterator';
+import {
+ SLICE_AGGREGATION_PIVOT_TABLE_ID
+} from '../../common/pivot_table_common';
+import {NUM} from '../../common/query_result';
import {Area, Sorting} from '../../common/state';
+import {publishAggregateData} from '../../frontend/publish';
+import {AreaSelectionHandler} from '../area_selection_handler';
import {Controller} from '../controller';
import {globals} from '../globals';
@@ -29,18 +35,20 @@ export interface AggregationControllerArgs {
kind: string;
}
+function isStringColumn(column: Column): boolean {
+ return column.kind === 'STRING' || column.kind === 'STATE';
+}
+
export abstract class AggregationController extends Controller<'main'> {
readonly kind: string;
- private previousArea?: Area;
+ private areaSelectionHandler: AreaSelectionHandler;
private previousSorting?: Sorting;
private requestingData = false;
private queuedRequest = false;
- abstract async createAggregateView(engine: Engine, area: Area):
- Promise<boolean>;
+ abstract createAggregateView(engine: Engine, area: Area): Promise<boolean>;
- abstract async getExtra(engine: Engine, area: Area):
- Promise<ThreadStateExtra|void>;
+ abstract getExtra(engine: Engine, area: Area): Promise<ThreadStateExtra|void>;
abstract getTabName(): string;
abstract getDefaultSorting(): Sorting;
@@ -49,12 +57,15 @@ export abstract class AggregationController extends Controller<'main'> {
constructor(private args: AggregationControllerArgs) {
super('main');
this.kind = this.args.kind;
+ this.areaSelectionHandler = new AreaSelectionHandler();
}
run() {
const selection = globals.state.currentSelection;
if (selection === null || selection.kind !== 'AREA') {
- globals.publish('AggregateData', {
+ globals.dispatch(Actions.deletePivotTable(
+ {pivotTableId: SLICE_AGGREGATION_PIVOT_TABLE_ID}));
+ publishAggregateData({
data: {
tabName: this.getTabName(),
columns: [],
@@ -65,25 +76,21 @@ export abstract class AggregationController extends Controller<'main'> {
});
return;
}
- const selectedArea = globals.state.areas[selection.areaId];
const aggregatePreferences =
globals.state.aggregatePreferences[this.args.kind];
- const areaChanged = this.previousArea !== selectedArea;
const sortingChanged = aggregatePreferences &&
this.previousSorting !== aggregatePreferences.sorting;
- if (!areaChanged && !sortingChanged) return;
+ const [hasAreaChanged, area] = this.areaSelectionHandler.getAreaChange();
+ if ((!hasAreaChanged && !sortingChanged) || !area) return;
if (this.requestingData) {
this.queuedRequest = true;
} else {
this.requestingData = true;
if (sortingChanged) this.previousSorting = aggregatePreferences.sorting;
- if (areaChanged) this.previousArea = Object.assign({}, selectedArea);
- this.getAggregateData(selectedArea, areaChanged)
- .then(
- data => globals.publish(
- 'AggregateData', {data, kind: this.args.kind}))
+ this.getAggregateData(area, hasAreaChanged)
+ .then(data => publishAggregateData({data, kind: this.args.kind}))
.finally(() => {
this.requestingData = false;
if (this.queuedRequest) {
@@ -119,7 +126,7 @@ export abstract class AggregationController extends Controller<'main'> {
const query = `select ${colIds} from ${this.kind} order by ${sorting}`;
const result = await this.args.engine.query(query);
- const numRows = slowlyCountRows(result);
+ const numRows = result.numRows();
const columns = defs.map(def => this.columnFromColumnDef(def, numRows));
const columnSums = await Promise.all(defs.map(def => this.getSum(def)));
const extraData = await this.getExtra(this.args.engine, area);
@@ -137,28 +144,28 @@ export abstract class AggregationController extends Controller<'main'> {
return idx;
}
- for (let row = 0; row < numRows; row++) {
- const cols = result.columns;
- for (let col = 0; col < result.columns.length; col++) {
- if (cols[col].stringValues && cols[col].stringValues!.length > 0) {
- data.columns[col].data[row] =
- internString(cols[col].stringValues![row]);
- } else if (cols[col].longValues && cols[col].longValues!.length > 0) {
- data.columns[col].data[row] = cols[col].longValues![row];
- } else if (
- cols[col].doubleValues && cols[col].doubleValues!.length > 0) {
- data.columns[col].data[row] = cols[col].doubleValues![row];
+ const it = result.iter({});
+ for (let i = 0; it.valid(); it.next(), ++i) {
+ for (const column of data.columns) {
+ const item = it.get(column.columnId);
+ if (item === null) {
+ column.data[i] = isStringColumn(column) ? internString('NULL') : 0;
+ } else if (typeof item === 'string') {
+ column.data[i] = internString(item);
+ } else {
+ column.data[i] = item;
}
}
}
+
return data;
}
async getSum(def: ColumnDef): Promise<string> {
if (!def.sum) return '';
- const result = await this.args.engine.queryOneRow(
- `select sum(${def.columnId}) from ${this.kind}`);
- let sum = result[0];
+ const result = await this.args.engine.query(
+ `select ifnull(sum(${def.columnId}), 0) as s from ${this.kind}`);
+ let sum = result.firstRow({s: NUM}).s;
if (def.kind === 'TIMESTAMP_NS') {
sum = sum / 1e6;
}
diff --git a/ui/src/controller/aggregation/frame_aggregation_controller.ts b/ui/src/controller/aggregation/frame_aggregation_controller.ts
new file mode 100644
index 000000000..cca211013
--- /dev/null
+++ b/ui/src/controller/aggregation/frame_aggregation_controller.ts
@@ -0,0 +1,103 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {ColumnDef} from '../../common/aggregation_data';
+import {Engine} from '../../common/engine';
+import {Area, Sorting} from '../../common/state';
+import {toNs} from '../../common/time';
+import {
+ ACTUAL_FRAMES_SLICE_TRACK_KIND,
+ Config
+} from '../../tracks/actual_frames/common';
+import {globals} from '../globals';
+
+import {AggregationController} from './aggregation_controller';
+
+export class FrameAggregationController extends AggregationController {
+ async createAggregateView(engine: Engine, area: Area) {
+ await engine.query(`drop view if exists ${this.kind};`);
+
+ const selectedSqlTrackIds = [];
+ for (const trackId of area.tracks) {
+ const track = globals.state.tracks[trackId];
+ // Track will be undefined for track groups.
+ if (track !== undefined &&
+ track.kind === ACTUAL_FRAMES_SLICE_TRACK_KIND) {
+ selectedSqlTrackIds.push((track.config as Config).trackIds);
+ }
+ }
+ if (selectedSqlTrackIds.length === 0) return false;
+
+ const query = `create view ${this.kind} as
+ SELECT
+ jank_type,
+ count(1) as occurrences,
+ MIN(dur) as minDur,
+ AVG(dur) as meanDur,
+ MAX(dur) as maxDur
+ FROM actual_frame_timeline_slice
+ WHERE track_id IN (${selectedSqlTrackIds}) AND
+ ts + dur > ${toNs(area.startSec)} AND
+ ts < ${toNs(area.endSec)} group by jank_type`;
+
+ await engine.query(query);
+ return true;
+ }
+
+ getTabName() {
+ return 'Frames';
+ }
+
+ async getExtra() {}
+
+ getDefaultSorting(): Sorting {
+ return {column: 'occurrences', direction: 'DESC'};
+ }
+
+ getColumnDefinitions(): ColumnDef[] {
+ return [
+ {
+ title: 'Jank Type',
+ kind: 'STRING',
+ columnConstructor: Uint16Array,
+ columnId: 'jank_type',
+ },
+ {
+ title: 'Min duration',
+ kind: 'NUMBER',
+ columnConstructor: Uint16Array,
+ columnId: 'minDur',
+ },
+ {
+ title: 'Max duration',
+ kind: 'NUMBER',
+ columnConstructor: Uint16Array,
+ columnId: 'maxDur',
+ },
+ {
+ title: 'Mean duration',
+ kind: 'NUMBER',
+ columnConstructor: Uint16Array,
+ columnId: 'meanDur',
+ },
+ {
+ title: 'Occurrences',
+ kind: 'NUMBER',
+ columnConstructor: Uint16Array,
+ columnId: 'occurrences',
+ sum: true
+ }
+ ];
+ }
+}
diff --git a/ui/src/controller/aggregation/slice_aggregation_controller.ts b/ui/src/controller/aggregation/slice_aggregation_controller.ts
index f3b280799..313e0ceac 100644
--- a/ui/src/controller/aggregation/slice_aggregation_controller.ts
+++ b/ui/src/controller/aggregation/slice_aggregation_controller.ts
@@ -12,10 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import {Actions} from '../../common/actions';
import {ColumnDef} from '../../common/aggregation_data';
import {Engine} from '../../common/engine';
+import {
+ SLICE_AGGREGATION_PIVOT_TABLE_ID
+} from '../../common/pivot_table_common';
import {Area, Sorting} from '../../common/state';
import {toNs} from '../../common/time';
+import {PIVOT_TABLE_FLAG} from '../../frontend/keyboard_event_handler';
import {
ASYNC_SLICE_TRACK_KIND,
Config as AsyncSliceConfig
@@ -28,28 +33,63 @@ import {globals} from '../globals';
import {AggregationController} from './aggregation_controller';
-export class SliceAggregationController extends AggregationController {
- async createAggregateView(engine: Engine, area: Area) {
- await engine.query(`drop view if exists ${this.kind};`);
+function addPivotTableOnAreaSelection(
+ selectedTrackIds: number[], startSec: number, endSec: number) {
+ const selectedPivots =
+ [{tableName: 'slice', columnName: 'name', isStackPivot: false}];
- const selectedTrackIds = [];
- for (const trackId of area.tracks) {
- const track = globals.state.tracks[trackId];
- // Track will be undefined for track groups.
- if (track !== undefined) {
- if (track.kind === SLICE_TRACK_KIND) {
- selectedTrackIds.push((track.config as SliceConfig).trackId);
- }
- if (track.kind === ASYNC_SLICE_TRACK_KIND) {
- const config = track.config as AsyncSliceConfig;
- for (const id of config.trackIds) {
- selectedTrackIds.push(id);
- }
+ const selectedAggregations = [
+ {tableName: 'slice', columnName: 'dur', aggregation: 'SUM', order: 'DESC'},
+ {tableName: 'slice', columnName: 'dur', aggregation: 'AVG', order: 'DESC'},
+ {tableName: 'slice', columnName: 'id', aggregation: 'COUNT', order: 'DESC'}
+ ];
+
+ globals.dispatch(Actions.addNewPivotTable({
+ name: 'Pivot Table - Slices',
+ pivotTableId: SLICE_AGGREGATION_PIVOT_TABLE_ID,
+ selectedPivots,
+ selectedAggregations,
+ traceTime: {startSec, endSec},
+ selectedTrackIds
+ }));
+
+ globals.dispatch(Actions.setPivotTableRequest(
+ {pivotTableId: SLICE_AGGREGATION_PIVOT_TABLE_ID, action: 'QUERY'}));
+}
+
+export function getSelectedTrackIds(area: Area): number[] {
+ const selectedTrackIds = [];
+ for (const trackId of area.tracks) {
+ const track = globals.state.tracks[trackId];
+ // Track will be undefined for track groups.
+ if (track !== undefined) {
+ if (track.kind === SLICE_TRACK_KIND) {
+ selectedTrackIds.push((track.config as SliceConfig).trackId);
+ }
+ if (track.kind === ASYNC_SLICE_TRACK_KIND) {
+ const config = track.config as AsyncSliceConfig;
+ for (const id of config.trackIds) {
+ selectedTrackIds.push(id);
}
}
}
+ }
+ return selectedTrackIds;
+}
+
+export class SliceAggregationController extends AggregationController {
+ async createAggregateView(engine: Engine, area: Area) {
+ await engine.query(`drop view if exists ${this.kind};`);
+
+ const selectedTrackIds = getSelectedTrackIds(area);
+
if (selectedTrackIds.length === 0) return false;
+ if (PIVOT_TABLE_FLAG.get()) {
+ addPivotTableOnAreaSelection(
+ selectedTrackIds, area.startSec, area.endSec);
+ }
+
const query = `create view ${this.kind} as
SELECT
name,
diff --git a/ui/src/controller/aggregation/thread_aggregation_controller.ts b/ui/src/controller/aggregation/thread_aggregation_controller.ts
index 03eb9353b..ff7bd6f34 100644
--- a/ui/src/controller/aggregation/thread_aggregation_controller.ts
+++ b/ui/src/controller/aggregation/thread_aggregation_controller.ts
@@ -14,7 +14,7 @@
import {ColumnDef, ThreadStateExtra} from '../../common/aggregation_data';
import {Engine} from '../../common/engine';
-import {slowlyCountRows} from '../../common/query_iterator';
+import {NUM, NUM_NULL, STR_NULL} from '../../common/query_result';
import {Area, Sorting} from '../../common/state';
import {translateState} from '../../common/thread_state';
import {toNs} from '../../common/time';
@@ -73,31 +73,37 @@ export class ThreadAggregationController extends AggregationController {
this.setThreadStateUtids(area.tracks);
if (this.utids === undefined || this.utids.length === 0) return;
- const query = `select state, io_wait, sum(dur) as total_dur from process
+ const query =
+ `select state, io_wait as ioWait, sum(dur) as totalDur from process
JOIN thread USING(upid)
JOIN thread_state USING(utid)
WHERE utid IN (${this.utids}) AND thread_state.ts + thread_state.dur > ${
- toNs(area.startSec)} AND
+ toNs(area.startSec)} AND
thread_state.ts < ${toNs(area.endSec)}
GROUP BY state, io_wait`;
const result = await engine.query(query);
- const numRows = slowlyCountRows(result);
+
+ const it = result.iter({
+ state: STR_NULL,
+ ioWait: NUM_NULL,
+ totalDur: NUM,
+ });
const summary: ThreadStateExtra = {
kind: 'THREAD_STATE',
states: [],
- values: new Float64Array(numRows),
+ values: new Float64Array(result.numRows()),
totalMs: 0
};
- for (let row = 0; row < numRows; row++) {
- const state = result.columns[0].stringValues![row];
- const ioWait = result.columns[1].isNulls![row] ?
- undefined :
- !!result.columns[1].longValues![row];
+ summary.totalMs = 0;
+ for (let i = 0; it.valid(); ++i, it.next()) {
+ const state = it.state == null ? undefined : it.state;
+ const ioWait = it.ioWait === null ? undefined : it.ioWait > 0;
summary.states.push(translateState(state, ioWait));
- summary.values[row] = result.columns[2].longValues![row] / 1000000; // ms
+ const ms = it.totalDur / 1000000;
+ summary.values[i] = ms;
+ summary.totalMs += ms;
}
- summary.totalMs = summary.values.reduce((a, b) => a + b, 0);
return summary;
}
diff --git a/ui/src/controller/area_selection_handler.ts b/ui/src/controller/area_selection_handler.ts
new file mode 100644
index 000000000..3f5368d4b
--- /dev/null
+++ b/ui/src/controller/area_selection_handler.ts
@@ -0,0 +1,57 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {Area, AreaById} from '../common/state';
+import {globals as frontendGlobals} from '../frontend/globals';
+
+export class AreaSelectionHandler {
+ private previousArea?: Area;
+
+ getAreaChange(): [boolean, AreaById|undefined] {
+ const currentSelection = frontendGlobals.state.currentSelection;
+ if (currentSelection === null || currentSelection.kind !== 'AREA') {
+ return [false, undefined];
+ }
+
+ const selectedArea = frontendGlobals.state.areas[currentSelection.areaId];
+ // Area is considered changed if:
+ // 1. The new area is defined and the old area undefined.
+ // 2. The new area is undefined and the old area defined (viceversa from 1).
+ // 3. Both areas are defined but their start or end times differ.
+ // 4. Both areas are defined but their tracks differ.
+ let hasAreaChanged = (!!this.previousArea !== !!selectedArea);
+ if (selectedArea && this.previousArea) {
+ // There seems to be an issue with clang-format http://shortn/_Pt98d5MCjG
+ // where `a ||= b` is formatted to `a || = b`, by inserting a space which
+ // breaks the operator.
+ // Therefore, we are using the pattern `a = a || b` instead.
+ hasAreaChanged = hasAreaChanged ||
+ selectedArea.startSec !== this.previousArea.startSec;
+ hasAreaChanged =
+ hasAreaChanged || selectedArea.endSec !== this.previousArea.endSec;
+ hasAreaChanged = hasAreaChanged ||
+ selectedArea.tracks.length !== this.previousArea.tracks.length;
+ for (let i = 0; i < selectedArea.tracks.length; ++i) {
+ hasAreaChanged = hasAreaChanged ||
+ selectedArea.tracks[i] !== this.previousArea.tracks[i];
+ }
+ }
+
+ if (hasAreaChanged) {
+ this.previousArea = selectedArea;
+ }
+
+ return [hasAreaChanged, selectedArea];
+ }
+}
diff --git a/ui/src/controller/area_selection_handler_unittest.ts b/ui/src/controller/area_selection_handler_unittest.ts
new file mode 100644
index 000000000..bbc315989
--- /dev/null
+++ b/ui/src/controller/area_selection_handler_unittest.ts
@@ -0,0 +1,136 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {AreaById} from '../common/state';
+import {globals as frontendGlobals} from '../frontend/globals';
+
+import {AreaSelectionHandler} from './area_selection_handler';
+import {createEmptyState} from '../common/empty_state';
+
+test('validAreaAfterUndefinedArea', () => {
+ const areaId = '0';
+ const latestArea: AreaById = {startSec: 0, endSec: 1, tracks: [], id: areaId};
+ frontendGlobals.state = createEmptyState();
+ frontendGlobals.state.currentSelection = {kind: 'AREA', areaId};
+ frontendGlobals.state.areas[areaId] = latestArea;
+
+ const areaSelectionHandler = new AreaSelectionHandler();
+ const [hasAreaChanged, selectedArea] = areaSelectionHandler.getAreaChange();
+
+ expect(hasAreaChanged).toEqual(true);
+ expect(selectedArea).toEqual(latestArea);
+});
+
+test('UndefinedAreaAfterValidArea', () => {
+ const previousAreaId = '0';
+ const previous:
+ AreaById = {startSec: 0, endSec: 1, tracks: [], id: previousAreaId};
+ frontendGlobals.state = createEmptyState();
+ frontendGlobals.state.currentSelection = {
+ kind: 'AREA',
+ areaId: previousAreaId
+ };
+ frontendGlobals.state.areas[previousAreaId] = previous;
+ const areaSelectionHandler = new AreaSelectionHandler();
+ areaSelectionHandler.getAreaChange();
+
+ const currentAreaId = '1';
+ frontendGlobals.state.currentSelection = {
+ kind: 'AREA',
+ areaId: currentAreaId
+ };
+ const [hasAreaChanged, selectedArea] = areaSelectionHandler.getAreaChange();
+
+ expect(hasAreaChanged).toEqual(true);
+ expect(selectedArea).toEqual(undefined);
+});
+
+test('UndefinedAreaAfterUndefinedArea', () => {
+ frontendGlobals.state.currentSelection = {kind: 'AREA', areaId: '0'};
+ const areaSelectionHandler = new AreaSelectionHandler();
+ areaSelectionHandler.getAreaChange();
+
+ frontendGlobals.state.currentSelection = {kind: 'AREA', areaId: '1'};
+ const [hasAreaChanged, selectedArea] = areaSelectionHandler.getAreaChange();
+
+ expect(hasAreaChanged).toEqual(true);
+ expect(selectedArea).toEqual(undefined);
+});
+
+test('validAreaAfterValidArea', () => {
+ const previousAreaId = '0';
+ const previous:
+ AreaById = {startSec: 0, endSec: 1, tracks: [], id: previousAreaId};
+ frontendGlobals.state = createEmptyState();
+ frontendGlobals.state.currentSelection = {
+ kind: 'AREA',
+ areaId: previousAreaId
+ };
+ frontendGlobals.state.areas[previousAreaId] = previous;
+ const areaSelectionHandler = new AreaSelectionHandler();
+ areaSelectionHandler.getAreaChange();
+
+ const currentAreaId = '1';
+ const current:
+ AreaById = {startSec: 1, endSec: 2, tracks: [], id: currentAreaId};
+ frontendGlobals.state.currentSelection = {
+ kind: 'AREA',
+ areaId: currentAreaId
+ };
+ frontendGlobals.state.areas[currentAreaId] = current;
+ const [hasAreaChanged, selectedArea] = areaSelectionHandler.getAreaChange();
+
+ expect(hasAreaChanged).toEqual(true);
+ expect(selectedArea).toEqual(current);
+});
+
+test('sameAreaSelected', () => {
+ const previousAreaId = '0';
+ const previous:
+ AreaById = {startSec: 0, endSec: 1, tracks: [], id: previousAreaId};
+ frontendGlobals.state = createEmptyState();
+ frontendGlobals.state.currentSelection = {
+ kind: 'AREA',
+ areaId: previousAreaId
+ };
+ frontendGlobals.state.areas[previousAreaId] = previous;
+ const areaSelectionHandler = new AreaSelectionHandler();
+ areaSelectionHandler.getAreaChange();
+
+ const currentAreaId = '0';
+ const current:
+ AreaById = {startSec: 0, endSec: 1, tracks: [], id: currentAreaId};
+ frontendGlobals.state.currentSelection = {
+ kind: 'AREA',
+ areaId: currentAreaId
+ };
+ frontendGlobals.state.areas[currentAreaId] = current;
+ const [hasAreaChanged, selectedArea] = areaSelectionHandler.getAreaChange();
+
+ expect(hasAreaChanged).toEqual(false);
+ expect(selectedArea).toEqual(current);
+});
+
+test('NonAreaSelectionAfterUndefinedArea', () => {
+ frontendGlobals.state.currentSelection = {kind: 'AREA', areaId: '0'};
+ const areaSelectionHandler = new AreaSelectionHandler();
+ areaSelectionHandler.getAreaChange();
+
+ frontendGlobals.state
+ .currentSelection = {kind: 'COUNTER', leftTs: 0, rightTs: 0, id: 1};
+ const [hasAreaChanged, selectedArea] = areaSelectionHandler.getAreaChange();
+
+ expect(hasAreaChanged).toEqual(false);
+ expect(selectedArea).toEqual(undefined);
+});
diff --git a/ui/src/controller/chrome_proxy_record_controller.ts b/ui/src/controller/chrome_proxy_record_controller.ts
index 4934cc032..5ea3548bb 100644
--- a/ui/src/controller/chrome_proxy_record_controller.ts
+++ b/ui/src/controller/chrome_proxy_record_controller.ts
@@ -13,15 +13,14 @@
// limitations under the License.
import {binaryDecode, binaryEncode} from '../base/string_utils';
-import {Actions} from '../common/actions';
import {TRACE_SUFFIX} from '../common/constants';
import {
ConsumerPortResponse,
+ hasProperty,
isReadBuffersResponse,
Typed
} from './consumer_port_types';
-import {globals} from './globals';
import {Consumer, RpcConsumerPort} from './record_controller_interfaces';
export interface ChromeExtensionError extends Typed {
@@ -47,8 +46,18 @@ function isStatus(obj: Typed): obj is ChromeExtensionStatus {
return obj.type === 'ChromeExtensionStatus';
}
-function isGetCategoriesResponse(obj: Typed): obj is GetCategoriesResponse {
- return obj.type === 'GetCategoriesResponse';
+function isObject(obj: unknown): obj is object {
+ return typeof obj === 'object' && obj !== null;
+}
+
+export function isGetCategoriesResponse(obj: unknown):
+ obj is GetCategoriesResponse {
+ if (!(isObject(obj) && hasProperty(obj, 'type') &&
+ obj.type === 'GetCategoriesResponse')) {
+ return false;
+ }
+
+ return hasProperty(obj, 'categories') && Array.isArray(obj.categories);
}
// This class acts as a proxy from the record controller (running in a worker),
@@ -79,10 +88,6 @@ export class ChromeExtensionConsumerPort extends RpcConsumerPort {
this.sendStatus(message.data.status);
return;
}
- if (isGetCategoriesResponse(message.data)) {
- globals.dispatch(Actions.setChromeCategories(message.data));
- return;
- }
// In this else branch message.data will be a ConsumerPortResponse.
if (isReadBuffersResponse(message.data) && message.data.slices) {
diff --git a/ui/src/controller/consumer_port_types.ts b/ui/src/controller/consumer_port_types.ts
index cb054e1ba..8b3cd453c 100644
--- a/ui/src/controller/consumer_port_types.ts
+++ b/ui/src/controller/consumer_port_types.ts
@@ -18,6 +18,17 @@ export interface Typed {
type: string;
}
+// A type guard that can be used in order to be able to access the property of
+// an object in a checked manner.
+export function hasProperty<T extends object, P extends string>(
+ obj: T, prop: P): obj is T&{[prop in P]: unknown} {
+ return obj.hasOwnProperty(prop);
+}
+
+export function isTyped(obj: object): obj is Typed {
+ return obj.hasOwnProperty('type');
+}
+
export interface ReadBuffersResponse extends
Typed, perfetto.protos.IReadBuffersResponse {}
export interface EnableTracingResponse extends
@@ -48,11 +59,6 @@ export function isGetTraceStatsResponse(obj: Typed):
return obj.type === 'GetTraceStatsResponse';
}
-export function isGetCategoriesResponse(obj: Typed):
- obj is GetCategoriesResponse {
- return obj.type === 'GetCategoriesResponse';
-}
-
export function isFreeBuffersResponse(obj: Typed): obj is FreeBuffersResponse {
return obj.type === 'FreeBuffersResponse';
}
diff --git a/ui/src/controller/cpu_profile_controller.ts b/ui/src/controller/cpu_profile_controller.ts
index 05e03e9d5..932fb6473 100644
--- a/ui/src/controller/cpu_profile_controller.ts
+++ b/ui/src/controller/cpu_profile_controller.ts
@@ -13,9 +13,10 @@
// limitations under the License.
import {Engine} from '../common/engine';
-import {slowlyCountRows} from '../common/query_iterator';
+import {NUM, STR} from '../common/query_result';
import {CallsiteInfo, CpuProfileSampleSelection} from '../common/state';
import {CpuProfileDetails} from '../frontend/globals';
+import {publishCpuProfileDetails} from '../frontend/publish';
import {Controller} from './controller';
import {globals} from './globals';
@@ -50,7 +51,7 @@ export class CpuProfileController extends Controller<'main'> {
}
this.requestingData = true;
- globals.publish('CpuProfileDetails', {});
+ publishCpuProfileDetails({});
this.lastSelectedSample = this.copyCpuProfileSample(selection);
this.getSampleData(selectedSample.id)
@@ -65,7 +66,7 @@ export class CpuProfileController extends Controller<'main'> {
stack: sampleData,
};
- globals.publish('CpuProfileDetails', cpuProfileDetails);
+ publishCpuProfileDetails(cpuProfileDetails);
}
})
.finally(() => {
@@ -106,7 +107,7 @@ export class CpuProfileController extends Controller<'main'> {
// 5. Sort the query by the depth of the callstack frames.
const sampleQuery = `
SELECT
- samples.id,
+ samples.id as id,
IFNULL(
(
SELECT name
@@ -115,8 +116,8 @@ export class CpuProfileController extends Controller<'main'> {
LIMIT 1
),
spf.name
- ) AS frame_name,
- spm.name AS mapping_name
+ ) AS name,
+ spm.name AS mapping
FROM cpu_profile_stack_sample AS samples
LEFT JOIN (
SELECT
@@ -143,24 +144,26 @@ export class CpuProfileController extends Controller<'main'> {
const callsites = await this.args.engine.query(sampleQuery);
- if (slowlyCountRows(callsites) < 1) {
+ if (callsites.numRows() === 0) {
return undefined;
}
- const sampleData: CallsiteInfo[] = new Array();
- for (let i = 0; i < slowlyCountRows(callsites); i++) {
- const id = +callsites.columns[0].longValues![i];
- const name = callsites.columns[1].stringValues![i];
- const mapping = callsites.columns[2].stringValues![i];
+ const it = callsites.iter({
+ id: NUM,
+ name: STR,
+ mapping: STR,
+ });
+ const sampleData: CallsiteInfo[] = new Array();
+ for (; it.valid(); it.next()) {
sampleData.push({
- id,
+ id: it.id,
totalSize: 0,
depth: 0,
parentId: 0,
- name,
+ name: it.name,
selfSize: 0,
- mapping,
+ mapping: it.mapping,
merged: false,
highlighted: false
});
diff --git a/ui/src/controller/flamegraph_controller.ts b/ui/src/controller/flamegraph_controller.ts
new file mode 100644
index 000000000..cb74e41f6
--- /dev/null
+++ b/ui/src/controller/flamegraph_controller.ts
@@ -0,0 +1,481 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {Actions} from '../common/actions';
+import {Engine} from '../common/engine';
+import {
+ ALLOC_SPACE_MEMORY_ALLOCATED_KEY,
+ DEFAULT_VIEWING_OPTION,
+ expandCallsites,
+ findRootSize,
+ mergeCallsites,
+ OBJECTS_ALLOCATED_KEY,
+ OBJECTS_ALLOCATED_NOT_FREED_KEY,
+ PERF_SAMPLES_KEY,
+ SPACE_MEMORY_ALLOCATED_NOT_FREED_KEY
+} from '../common/flamegraph_util';
+import {NUM, STR} from '../common/query_result';
+import {CallsiteInfo, FlamegraphState} from '../common/state';
+import {toNs} from '../common/time';
+import {
+ FlamegraphDetails,
+ globals as frontendGlobals
+} from '../frontend/globals';
+import {publishFlamegraphDetails} from '../frontend/publish';
+import {
+ Config as PerfSampleConfig,
+ PERF_SAMPLES_PROFILE_TRACK_KIND
+} from '../tracks/perf_samples_profile/common';
+
+import {AreaSelectionHandler} from './area_selection_handler';
+import {Controller} from './controller';
+import {globals} from './globals';
+
+export interface FlamegraphControllerArgs {
+ engine: Engine;
+}
+const MIN_PIXEL_DISPLAYED = 1;
+
+class TablesCache {
+ private engine: Engine;
+ private cache: Map<string, string>;
+ private prefix: string;
+ private tableId: number;
+ private cacheSizeLimit: number;
+
+ constructor(engine: Engine, prefix: string) {
+ this.engine = engine;
+ this.cache = new Map<string, string>();
+ this.prefix = prefix;
+ this.tableId = 0;
+ this.cacheSizeLimit = 10;
+ }
+
+ async getTableName(query: string): Promise<string> {
+ let tableName = this.cache.get(query);
+ if (tableName === undefined) {
+ // TODO(hjd): This should be LRU.
+ if (this.cache.size > this.cacheSizeLimit) {
+ for (const name of this.cache.values()) {
+ await this.engine.query(`drop table ${name}`);
+ }
+ this.cache.clear();
+ }
+ tableName = `${this.prefix}_${this.tableId++}`;
+ await this.engine.query(
+ `create temp table if not exists ${tableName} as ${query}`);
+ this.cache.set(query, tableName);
+ }
+ return tableName;
+ }
+}
+
+export class FlamegraphController extends Controller<'main'> {
+ private flamegraphDatasets: Map<string, CallsiteInfo[]> = new Map();
+ private lastSelectedFlamegraphState?: FlamegraphState;
+ private requestingData = false;
+ private queuedRequest = false;
+ private flamegraphDetails: FlamegraphDetails = {};
+ private areaSelectionHandler: AreaSelectionHandler;
+ private cache: TablesCache;
+
+ constructor(private args: FlamegraphControllerArgs) {
+ super('main');
+ this.cache = new TablesCache(args.engine, 'grouped_callsites');
+ this.areaSelectionHandler = new AreaSelectionHandler();
+ }
+
+ run() {
+ const [hasAreaChanged, area] = this.areaSelectionHandler.getAreaChange();
+ if (hasAreaChanged) {
+ const upids = [];
+ if (!area) {
+ this.checkCompletionAndPublishFlamegraph(
+ {...frontendGlobals.flamegraphDetails, isInAreaSelection: false});
+ return;
+ }
+ for (const trackId of area.tracks) {
+ const trackState = frontendGlobals.state.tracks[trackId];
+ if (!trackState ||
+ trackState.kind !== PERF_SAMPLES_PROFILE_TRACK_KIND) {
+ continue;
+ }
+ upids.push((trackState.config as PerfSampleConfig).upid);
+ }
+ if (upids.length === 0) {
+ this.checkCompletionAndPublishFlamegraph(
+ {...frontendGlobals.flamegraphDetails, isInAreaSelection: false});
+ return;
+ }
+ frontendGlobals.dispatch(Actions.openFlamegraph({
+ upids,
+ startNs: toNs(area.startSec),
+ endNs: toNs(area.endSec),
+ type: 'perf',
+ viewingOption: PERF_SAMPLES_KEY
+ }));
+ }
+ const selection = frontendGlobals.state.currentFlamegraphState;
+ if (!selection || !this.shouldRequestData(selection)) {
+ return;
+ }
+ if (this.requestingData) {
+ this.queuedRequest = true;
+ return;
+ }
+ this.requestingData = true;
+
+ this.assembleFlamegraphDetails(selection, hasAreaChanged);
+ }
+
+ private async assembleFlamegraphDetails(
+ selection: FlamegraphState, hasAreaChanged: boolean) {
+ const selectedFlamegraphState = {...selection};
+ const flamegraphMetadata = await this.getFlamegraphMetadata(
+ selection.type,
+ selectedFlamegraphState.startNs,
+ selectedFlamegraphState.endNs,
+ selectedFlamegraphState.upids);
+ if (flamegraphMetadata !== undefined) {
+ Object.assign(this.flamegraphDetails, flamegraphMetadata);
+ }
+
+ // TODO(hjd): Clean this up.
+ if (this.lastSelectedFlamegraphState &&
+ this.lastSelectedFlamegraphState.focusRegex !== selection.focusRegex) {
+ this.flamegraphDatasets.clear();
+ }
+
+ this.lastSelectedFlamegraphState = {...selection};
+
+ const expandedId = selectedFlamegraphState.expandedCallsite ?
+ selectedFlamegraphState.expandedCallsite.id :
+ -1;
+ const rootSize = selectedFlamegraphState.expandedCallsite === undefined ?
+ undefined :
+ selectedFlamegraphState.expandedCallsite.totalSize;
+
+ const key = `${selectedFlamegraphState.upids};${
+ selectedFlamegraphState.startNs};${selectedFlamegraphState.endNs}`;
+
+ try {
+ const flamegraphData = await this.getFlamegraphData(
+ key,
+ selectedFlamegraphState.viewingOption ?
+ selectedFlamegraphState.viewingOption :
+ DEFAULT_VIEWING_OPTION,
+ selection.startNs,
+ selection.endNs,
+ selectedFlamegraphState.upids,
+ selectedFlamegraphState.type,
+ selectedFlamegraphState.focusRegex);
+ if (flamegraphData !== undefined && selection &&
+ selection.kind === selectedFlamegraphState.kind &&
+ selection.startNs === selectedFlamegraphState.startNs &&
+ selection.endNs === selectedFlamegraphState.endNs) {
+ const expandedFlamegraphData =
+ expandCallsites(flamegraphData, expandedId);
+ this.prepareAndMergeCallsites(
+ expandedFlamegraphData,
+ this.lastSelectedFlamegraphState.viewingOption,
+ hasAreaChanged,
+ rootSize,
+ this.lastSelectedFlamegraphState.expandedCallsite);
+ }
+ } finally {
+ this.requestingData = false;
+ if (this.queuedRequest) {
+ this.queuedRequest = false;
+ this.run();
+ }
+ }
+ }
+
+ private shouldRequestData(selection: FlamegraphState) {
+ return selection.kind === 'FLAMEGRAPH_STATE' &&
+ (this.lastSelectedFlamegraphState === undefined ||
+ (this.lastSelectedFlamegraphState.startNs !== selection.startNs ||
+ this.lastSelectedFlamegraphState.endNs !== selection.endNs ||
+ this.lastSelectedFlamegraphState.type !== selection.type ||
+ !FlamegraphController.areArraysEqual(
+ this.lastSelectedFlamegraphState.upids, selection.upids) ||
+ this.lastSelectedFlamegraphState.viewingOption !==
+ selection.viewingOption ||
+ this.lastSelectedFlamegraphState.focusRegex !==
+ selection.focusRegex ||
+ this.lastSelectedFlamegraphState.expandedCallsite !==
+ selection.expandedCallsite));
+ }
+
+ private prepareAndMergeCallsites(
+ flamegraphData: CallsiteInfo[],
+ viewingOption: string|undefined = DEFAULT_VIEWING_OPTION,
+ hasAreaChanged: boolean, rootSize?: number,
+ expandedCallsite?: CallsiteInfo) {
+ this.flamegraphDetails.flamegraph = mergeCallsites(
+ flamegraphData, this.getMinSizeDisplayed(flamegraphData, rootSize));
+ this.flamegraphDetails.expandedCallsite = expandedCallsite;
+ this.flamegraphDetails.viewingOption = viewingOption;
+ this.flamegraphDetails.isInAreaSelection = hasAreaChanged;
+ this.checkCompletionAndPublishFlamegraph(this.flamegraphDetails);
+ }
+
+ private async checkCompletionAndPublishFlamegraph(flamegraphDetails:
+ FlamegraphDetails) {
+ flamegraphDetails.graphIncomplete =
+ (await this.args.engine.query(`select value from stats
+ where severity = 'error' and name = 'heap_graph_non_finalized_graph'`))
+ .firstRow({value: NUM})
+ .value > 0;
+ publishFlamegraphDetails(flamegraphDetails);
+ }
+
+ async getFlamegraphData(
+ baseKey: string, viewingOption: string, startNs: number, endNs: number,
+ upids: number[], type: string,
+ focusRegex: string): Promise<CallsiteInfo[]> {
+ let currentData: CallsiteInfo[];
+ const key = `${baseKey}-${viewingOption}`;
+ if (this.flamegraphDatasets.has(key)) {
+ currentData = this.flamegraphDatasets.get(key)!;
+ } else {
+ // TODO(hjd): Show loading state.
+
+ // Collecting data for drawing flamegraph for selected profile.
+ // Data needs to be in following format:
+ // id, name, parent_id, depth, total_size
+ const tableName = await this.prepareViewsAndTables(
+ startNs, endNs, upids, type, focusRegex);
+ currentData = await this.getFlamegraphDataFromTables(
+ tableName, viewingOption, focusRegex);
+ this.flamegraphDatasets.set(key, currentData);
+ }
+ return currentData;
+ }
+
+ async getFlamegraphDataFromTables(
+ tableName: string, viewingOption = DEFAULT_VIEWING_OPTION,
+ focusRegex: string) {
+ let orderBy = '';
+ let totalColumnName: 'cumulativeSize'|'cumulativeAllocSize'|
+ 'cumulativeCount'|'cumulativeAllocCount' = 'cumulativeSize';
+ let selfColumnName: 'size'|'count' = 'size';
+ // TODO(fmayer): Improve performance so this is no longer necessary.
+ // Alternatively consider collapsing frames of the same label.
+ const maxDepth = 100;
+ switch (viewingOption) {
+ case ALLOC_SPACE_MEMORY_ALLOCATED_KEY:
+ orderBy = `where cumulative_alloc_size > 0 and depth < ${
+ maxDepth} order by depth, parent_id,
+ cumulative_alloc_size desc, name`;
+ totalColumnName = 'cumulativeAllocSize';
+ selfColumnName = 'size';
+ break;
+ case OBJECTS_ALLOCATED_NOT_FREED_KEY:
+ orderBy = `where cumulative_count > 0 and depth < ${
+ maxDepth} order by depth, parent_id,
+ cumulative_count desc, name`;
+ totalColumnName = 'cumulativeCount';
+ selfColumnName = 'count';
+ break;
+ case OBJECTS_ALLOCATED_KEY:
+ orderBy = `where cumulative_alloc_count > 0 and depth < ${
+ maxDepth} order by depth, parent_id,
+ cumulative_alloc_count desc, name`;
+ totalColumnName = 'cumulativeAllocCount';
+ selfColumnName = 'count';
+ break;
+ case PERF_SAMPLES_KEY:
+ case SPACE_MEMORY_ALLOCATED_NOT_FREED_KEY:
+ orderBy = `where cumulative_size > 0 and depth < ${
+ maxDepth} order by depth, parent_id,
+ cumulative_size desc, name`;
+ totalColumnName = 'cumulativeSize';
+ selfColumnName = 'size';
+ break;
+ default:
+ break;
+ }
+
+ const callsites = await this.args.engine.query(`
+ SELECT
+ id as hash,
+ IFNULL(IFNULL(DEMANGLE(name), name), '[NULL]') as name,
+ IFNULL(parent_id, -1) as parentHash,
+ depth,
+ cumulative_size as cumulativeSize,
+ cumulative_alloc_size as cumulativeAllocSize,
+ cumulative_count as cumulativeCount,
+ cumulative_alloc_count as cumulativeAllocCount,
+ map_name as mapping,
+ size,
+ count,
+ IFNULL(source_file, '') as sourceFile,
+ IFNULL(line_number, -1) as lineNumber
+ from ${tableName} ${orderBy}`);
+
+ const flamegraphData: CallsiteInfo[] = [];
+ const hashToindex: Map<number, number> = new Map();
+ const it = callsites.iter({
+ hash: NUM,
+ name: STR,
+ parentHash: NUM,
+ depth: NUM,
+ cumulativeSize: NUM,
+ cumulativeAllocSize: NUM,
+ cumulativeCount: NUM,
+ cumulativeAllocCount: NUM,
+ mapping: STR,
+ sourceFile: STR,
+ lineNumber: NUM,
+ size: NUM,
+ count: NUM,
+ });
+ for (let i = 0; it.valid(); ++i, it.next()) {
+ const hash = it.hash;
+ let name = it.name;
+ const parentHash = it.parentHash;
+ const depth = it.depth;
+ const totalSize = it[totalColumnName];
+ const selfSize = it[selfColumnName];
+ const mapping = it.mapping;
+ const highlighted = focusRegex !== '' &&
+ name.toLocaleLowerCase().includes(focusRegex.toLocaleLowerCase());
+ const parentId =
+ hashToindex.has(+parentHash) ? hashToindex.get(+parentHash)! : -1;
+
+ let location: string|undefined;
+ if (/[a-zA-Z]/i.test(it.sourceFile)) {
+ location = it.sourceFile;
+ if (it.lineNumber !== -1) {
+ location += `:${it.lineNumber}`;
+ }
+ }
+
+ if (depth === maxDepth - 1) {
+ name += ' [tree truncated]';
+ }
+ // Instead of hash, we will store index of callsite in this original array
+ // as an id of callsite. That way, we have quicker access to parent and it
+ // will stay unique:
+ hashToindex.set(hash, i);
+
+ flamegraphData.push({
+ id: i,
+ totalSize,
+ depth,
+ parentId,
+ name,
+ selfSize,
+ mapping,
+ merged: false,
+ highlighted,
+ location
+ });
+ }
+ return flamegraphData;
+ }
+
+ private async prepareViewsAndTables(
+ startNs: number, endNs: number, upids: number[], type: string,
+ focusRegex: string): Promise<string> {
+ // Creating unique names for views so we can reuse and not delete them
+ // for each marker.
+ let focusRegexConditional = '';
+ if (focusRegex !== '') {
+ focusRegexConditional = `and focus_str = '${focusRegex}'`;
+ }
+
+ /*
+ * TODO(octaviant) this branching should be eliminated for simplicity.
+ */
+ if (type === 'perf') {
+ let upidConditional = `upid = ${upids[0]}`;
+ if (upids.length > 1) {
+ upidConditional =
+ `upid_group = '${FlamegraphController.serializeUpidGroup(upids)}'`;
+ }
+ return this.cache.getTableName(
+ `select id, name, map_name, parent_id, depth, cumulative_size,
+ cumulative_alloc_size, cumulative_count, cumulative_alloc_count,
+ size, alloc_size, count, alloc_count, source_file, line_number
+ from experimental_flamegraph
+ where profile_type = '${type}' and ${startNs} <= ts and ts <= ${
+ endNs} and ${upidConditional}
+ ${focusRegexConditional}`);
+ }
+ return this.cache.getTableName(
+ `select id, name, map_name, parent_id, depth, cumulative_size,
+ cumulative_alloc_size, cumulative_count, cumulative_alloc_count,
+ size, alloc_size, count, alloc_count, source_file, line_number
+ from experimental_flamegraph
+ where profile_type = '${type}'
+ and ts = ${endNs}
+ and upid = ${upids[0]}
+ ${focusRegexConditional}`);
+ }
+
+ getMinSizeDisplayed(flamegraphData: CallsiteInfo[], rootSize?: number):
+ number {
+ const timeState = globals.state.frontendLocalState.visibleState;
+ let width = (timeState.endSec - timeState.startSec) / timeState.resolution;
+ // TODO(168048193): Remove screen size hack:
+ width = Math.max(width, 800);
+ if (rootSize === undefined) {
+ rootSize = findRootSize(flamegraphData);
+ }
+ return MIN_PIXEL_DISPLAYED * rootSize / width;
+ }
+
+ async getFlamegraphMetadata(
+ type: string, startNs: number, endNs: number, upids: number[]) {
+ // Don't do anything if selection of the marker stayed the same.
+ if ((this.lastSelectedFlamegraphState !== undefined &&
+ ((this.lastSelectedFlamegraphState.startNs === startNs &&
+ this.lastSelectedFlamegraphState.endNs === endNs &&
+ FlamegraphController.areArraysEqual(
+ this.lastSelectedFlamegraphState.upids, upids))))) {
+ return undefined;
+ }
+
+ // Collecting data for more information about profile, such as:
+ // total memory allocated, memory that is allocated and not freed.
+ const upidGroup = FlamegraphController.serializeUpidGroup(upids);
+
+ const result = await this.args.engine.query(
+ `select pid from process where upid in (${upidGroup})`);
+ const it = result.iter({pid: NUM});
+ const pids = [];
+ for (let i = 0; it.valid(); ++i, it.next()) {
+ pids.push(it.pid);
+ }
+ return {startNs, durNs: endNs - startNs, pids, upids, type};
+ }
+
+ private static areArraysEqual(a: number[], b: number[]) {
+ if (a.length !== b.length) {
+ return false;
+ }
+ for (let i = 0; i < a.length; i++) {
+ if (a[i] !== b[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static serializeUpidGroup(upids: number[]) {
+ return new Array(upids).join();
+ }
+}
diff --git a/ui/src/controller/flow_events_controller.ts b/ui/src/controller/flow_events_controller.ts
index 87dd298a1..a2c5bd415 100644
--- a/ui/src/controller/flow_events_controller.ts
+++ b/ui/src/controller/flow_events_controller.ts
@@ -13,10 +13,12 @@
// limitations under the License.
import {Engine} from '../common/engine';
-import {slowlyCountRows} from '../common/query_iterator';
+import {featureFlags} from '../common/feature_flags';
+import {NUM, STR_NULL} from '../common/query_result';
import {Area} from '../common/state';
import {fromNs, toNs} from '../common/time';
import {Flow} from '../frontend/globals';
+import {publishConnectedFlows, publishSelectedFlows} from '../frontend/publish';
import {
ACTUAL_FRAMES_SLICE_TRACK_KIND,
Config as ActualConfig
@@ -33,6 +35,15 @@ export interface FlowEventsControllerArgs {
engine: Engine;
}
+const SHOW_INDIRECT_PRECEDING_FLOWS_FLAG = featureFlags.register({
+ id: 'showIndirectPrecedingFlows',
+ name: 'Show indirect preceding flows',
+ description: 'Show indirect preceding flows (connected through ancestor ' +
+ 'slices) when a slice is selected.',
+ defaultValue: false,
+});
+
+
export class FlowEventsController extends Controller<'main'> {
private lastSelectedSliceId?: number;
private lastSelectedArea?: Area;
@@ -43,34 +54,65 @@ export class FlowEventsController extends Controller<'main'> {
}
queryFlowEvents(query: string, callback: (flows: Flow[]) => void) {
- this.args.engine.query(query).then(res => {
+ this.args.engine.query(query).then(result => {
const flows: Flow[] = [];
- for (let i = 0; i < slowlyCountRows(res); i++) {
- const beginSliceId = res.columns[0].longValues![i];
- const beginTrackId = res.columns[1].longValues![i];
- const beginSliceName = res.columns[2].stringValues![i];
- const beginSliceCategory = res.columns[3].stringValues![i];
- const beginSliceStartTs = fromNs(res.columns[4].longValues![i]);
- const beginSliceEndTs = fromNs(res.columns[5].longValues![i]);
- const beginDepth = res.columns[6].longValues![i];
-
- const endSliceId = res.columns[7].longValues![i];
- const endTrackId = res.columns[8].longValues![i];
- const endSliceName = res.columns[9].stringValues![i];
- const endSliceCategory = res.columns[10].stringValues![i];
- const endSliceStartTs = fromNs(res.columns[11].longValues![i]);
- const endSliceEndTs = fromNs(res.columns[12].longValues![i]);
- const endDepth = res.columns[13].longValues![i];
+ const it = result.iter({
+ beginSliceId: NUM,
+ beginTrackId: NUM,
+ beginSliceName: STR_NULL,
+ beginSliceCategory: STR_NULL,
+ beginSliceStartTs: NUM,
+ beginSliceEndTs: NUM,
+ beginDepth: NUM,
+ beginThreadName: STR_NULL,
+ beginProcessName: STR_NULL,
+ endSliceId: NUM,
+ endTrackId: NUM,
+ endSliceName: STR_NULL,
+ endSliceCategory: STR_NULL,
+ endSliceStartTs: NUM,
+ endSliceEndTs: NUM,
+ endDepth: NUM,
+ endThreadName: STR_NULL,
+ endProcessName: STR_NULL,
+ name: STR_NULL,
+ category: STR_NULL,
+ id: NUM,
+ });
+ for (; it.valid(); it.next()) {
+ const beginSliceId = it.beginSliceId;
+ const beginTrackId = it.beginTrackId;
+ const beginSliceName =
+ it.beginSliceName === null ? 'NULL' : it.beginSliceName;
+ const beginSliceCategory =
+ it.beginSliceCategory === null ? 'NULL' : it.beginSliceCategory;
+ const beginSliceStartTs = fromNs(it.beginSliceStartTs);
+ const beginSliceEndTs = fromNs(it.beginSliceEndTs);
+ const beginDepth = it.beginDepth;
+ const beginThreadName =
+ it.beginThreadName === null ? 'NULL' : it.beginThreadName;
+ const beginProcessName =
+ it.beginProcessName === null ? 'NULL' : it.beginProcessName;
+
+ const endSliceId = it.endSliceId;
+ const endTrackId = it.endTrackId;
+ const endSliceName =
+ it.endSliceName === null ? 'NULL' : it.endSliceName;
+ const endSliceCategory =
+ it.endSliceCategory === null ? 'NULL' : it.endSliceCategory;
+ const endSliceStartTs = fromNs(it.endSliceStartTs);
+ const endSliceEndTs = fromNs(it.endSliceEndTs);
+ const endDepth = it.endDepth;
+ const endThreadName =
+ it.endThreadName === null ? 'NULL' : it.endThreadName;
+ const endProcessName =
+ it.endProcessName === null ? 'NULL' : it.endProcessName;
// Category and name present only in version 1 flow events
// It is most likelly NULL for all other versions
- const category = res.columns[14].isNulls![i] ?
- undefined :
- res.columns[14].stringValues![i];
- const name = res.columns[15].isNulls![i] ?
- undefined :
- res.columns[15].stringValues![i];
- const id = res.columns[16].longValues![i];
+ const category = it.category === null ? undefined : it.category;
+ const name = it.name === null ? undefined : it.name;
+ const id = it.id;
flows.push({
id,
@@ -81,7 +123,9 @@ export class FlowEventsController extends Controller<'main'> {
sliceCategory: beginSliceCategory,
sliceStartTs: beginSliceStartTs,
sliceEndTs: beginSliceEndTs,
- depth: beginDepth
+ depth: beginDepth,
+ threadName: beginThreadName,
+ processName: beginProcessName
},
end: {
trackId: endTrackId,
@@ -90,8 +134,11 @@ export class FlowEventsController extends Controller<'main'> {
sliceCategory: endSliceCategory,
sliceStartTs: endSliceStartTs,
sliceEndTs: endSliceEndTs,
- depth: endDepth
+ depth: endDepth,
+ threadName: endThreadName,
+ processName: endProcessName
},
+ dur: endSliceStartTs - beginSliceEndTs,
category,
name
});
@@ -108,21 +155,49 @@ export class FlowEventsController extends Controller<'main'> {
this.lastSelectedSliceId = sliceId;
this.lastSelectedKind = 'CHROME_SLICE';
+ const connectedFlows = SHOW_INDIRECT_PRECEDING_FLOWS_FLAG.get() ?
+ `(
+ select * from directly_connected_flow(${sliceId})
+ union
+ select * from preceding_flow(${sliceId})
+ )` :
+ `directly_connected_flow(${sliceId})`;
+
const query = `
select
- f.slice_out, t1.track_id, t1.name,
- t1.category, t1.ts, (t1.ts+t1.dur), t1.depth,
- f.slice_in, t2.track_id, t2.name,
- t2.category, t2.ts, (t2.ts+t2.dur), t2.depth,
- extract_arg(f.arg_set_id, 'cat'),
- extract_arg(f.arg_set_id, 'name'),
- f.id
- from directly_connected_flow(${sliceId}) f
+ f.slice_out as beginSliceId,
+ t1.track_id as beginTrackId,
+ t1.name as beginSliceName,
+ t1.category as beginSliceCategory,
+ t1.ts as beginSliceStartTs,
+ (t1.ts+t1.dur) as beginSliceEndTs,
+ t1.depth as beginDepth,
+ (thread_out.name || ' ' || thread_out.tid) as beginThreadName,
+ (process_out.name || ' ' || process_out.pid) as beginProcessName,
+ f.slice_in as endSliceId,
+ t2.track_id as endTrackId,
+ t2.name as endSliceName,
+ t2.category as endSliceCategory,
+ t2.ts as endSliceStartTs,
+ (t2.ts+t2.dur) as endSliceEndTs,
+ t2.depth as endDepth,
+ (thread_in.name || ' ' || thread_in.tid) as endThreadName,
+ (process_in.name || ' ' || process_in.pid) as endProcessName,
+ extract_arg(f.arg_set_id, 'cat') as category,
+ extract_arg(f.arg_set_id, 'name') as name,
+ f.id as id
+ from ${connectedFlows} f
join slice t1 on f.slice_out = t1.slice_id
join slice t2 on f.slice_in = t2.slice_id
+ left join thread_track track_out on track_out.id = t1.track_id
+ left join thread thread_out on thread_out.utid = track_out.utid
+ left join thread_track track_in on track_in.id = t2.track_id
+ left join thread thread_in on thread_in.utid = track_in.utid
+ left join process process_out on process_out.upid = thread_out.upid
+ left join process process_in on process_in.upid = thread_in.upid
`;
this.queryFlowEvents(
- query, (flows: Flow[]) => globals.publish('ConnectedFlows', flows));
+ query, (flows: Flow[]) => publishConnectedFlows(flows));
}
areaSelected(areaId: string) {
@@ -161,13 +236,27 @@ export class FlowEventsController extends Controller<'main'> {
const query = `
select
- f.slice_out, t1.track_id, t1.name,
- t1.category, t1.ts, (t1.ts+t1.dur), t1.depth,
- f.slice_in, t2.track_id, t2.name,
- t2.category, t2.ts, (t2.ts+t2.dur), t2.depth,
- extract_arg(f.arg_set_id, 'cat'),
- extract_arg(f.arg_set_id, 'name'),
- f.id
+ f.slice_out as beginSliceId,
+ t1.track_id as beginTrackId,
+ t1.name as beginSliceName,
+ t1.category as beginSliceCategory,
+ t1.ts as beginSliceStartTs,
+ (t1.ts+t1.dur) as beginSliceEndTs,
+ t1.depth as beginDepth,
+ NULL as beginThreadName,
+ NULL as beginProcessName,
+ f.slice_in as endSliceId,
+ t2.track_id as endTrackId,
+ t2.name as endSliceName,
+ t2.category as endSliceCategory,
+ t2.ts as endSliceStartTs,
+ (t2.ts+t2.dur) as endSliceEndTs,
+ t2.depth as endDepth,
+ NULL as endThreadName,
+ NULL as endProcessName,
+ extract_arg(f.arg_set_id, 'cat') as category,
+ extract_arg(f.arg_set_id, 'name') as name,
+ f.id as id
from flow f
join slice t1 on f.slice_out = t1.slice_id
join slice t2 on f.slice_in = t2.slice_id
@@ -178,29 +267,31 @@ export class FlowEventsController extends Controller<'main'> {
(t2.track_id in ${tracks}
and (t2.ts <= ${endNs} and t2.ts >= ${startNs}))
`;
- this.queryFlowEvents(
- query, (flows: Flow[]) => globals.publish('SelectedFlows', flows));
+ this.queryFlowEvents(query, (flows: Flow[]) => publishSelectedFlows(flows));
}
refreshVisibleFlows() {
const selection = globals.state.currentSelection;
if (!selection) {
this.lastSelectedKind = 'NONE';
- globals.publish('ConnectedFlows', []);
- globals.publish('SelectedFlows', []);
+ publishConnectedFlows([]);
+ publishSelectedFlows([]);
return;
}
- if (selection && selection.kind === 'CHROME_SLICE') {
+ // TODO(b/155483804): This is a hack as annotation slices don't contain
+ // flows. We should tidy this up when fixing this bug.
+ if (selection && selection.kind === 'CHROME_SLICE' &&
+ selection.table !== 'annotation') {
this.sliceSelected(selection.id);
} else {
- globals.publish('ConnectedFlows', []);
+ publishConnectedFlows([]);
}
if (selection && selection.kind === 'AREA') {
this.areaSelected(selection.areaId);
} else {
- globals.publish('SelectedFlows', []);
+ publishSelectedFlows([]);
}
}
diff --git a/ui/src/controller/globals.ts b/ui/src/controller/globals.ts
index 606dab400..84564a805 100644
--- a/ui/src/controller/globals.ts
+++ b/ui/src/controller/globals.ts
@@ -12,25 +12,19 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {Patch, produce} from 'immer';
+import {applyPatches, Patch} from 'immer';
import {assertExists} from '../base/logging';
-import {Remote} from '../base/remote';
-import {DeferredAction, StateActions} from '../common/actions';
-import {createEmptyState, State} from '../common/state';
-import {ControllerAny} from './controller';
+import {DeferredAction} from '../common/actions';
+import {createEmptyState} from '../common/empty_state';
+import {State} from '../common/state';
+import {globals as frontendGlobals} from '../frontend/globals';
-type PublishKinds = 'OverviewData'|'TrackData'|'Threads'|'QueryResult'|
- 'LegacyTrace'|'SliceDetails'|'CounterDetails'|'HeapProfileDetails'|
- 'HeapProfileFlamegraph'|'FileDownload'|'Loading'|'Search'|'BufferUsage'|
- 'RecordingLog'|'SearchResult'|'AggregateData'|'CpuProfileDetails'|
- 'TraceErrors'|'UpdateChromeCategories'|'ConnectedFlows'|'SelectedFlows'|
- 'ThreadStateDetails'|'MetricError'|'MetricResult';
+import {ControllerAny} from './controller';
export interface App {
state: State;
dispatch(action: DeferredAction): void;
- publish(what: PublishKinds, data: {}, transferList?: Array<{}>): void;
}
/**
@@ -39,28 +33,30 @@ export interface App {
class Globals implements App {
private _state?: State;
private _rootController?: ControllerAny;
- private _frontend?: Remote;
private _runningControllers = false;
- private _queuedActions = new Array<DeferredAction>();
- initialize(rootController: ControllerAny, frontendProxy: Remote) {
+ initialize(rootController: ControllerAny) {
this._rootController = rootController;
- this._frontend = frontendProxy;
this._state = createEmptyState();
}
dispatch(action: DeferredAction): void {
- this.dispatchMultiple([action]);
+ frontendGlobals.dispatch(action);
}
+ // Send the passed dispatch actions to the frontend. The frontend logic
+ // will run the actions, compute the new state and invoke patchState() so
+ // our copy is updated.
dispatchMultiple(actions: DeferredAction[]): void {
- this._queuedActions = this._queuedActions.concat(actions);
-
- // If we are in the middle of running the controllers, queue the actions
- // and run them at the end of the run, so the state is atomically updated
- // only at the end and all controllers see the same state.
- if (this._runningControllers) return;
+ for (const action of actions) {
+ this.dispatch(action);
+ }
+ }
+ // This is called by the frontend logic which now owns and handle the
+ // source-of-truth state, to give us an update on the newer state updates.
+ patchState(patches: Patch[]): void {
+ this._state = applyPatches(assertExists(this._state), patches);
this.runControllers();
}
@@ -68,21 +64,9 @@ class Globals implements App {
if (this._runningControllers) throw new Error('Re-entrant call detected');
// Run controllers locally until all state machines reach quiescence.
- let runAgain = false;
- const patches: Patch[] = [];
- for (let iter = 0; runAgain || this._queuedActions.length > 0; iter++) {
+ let runAgain = true;
+ for (let iter = 0; runAgain; iter++) {
if (iter > 100) throw new Error('Controllers are stuck in a livelock');
- const actions = this._queuedActions;
- this._queuedActions = new Array<DeferredAction>();
-
- for (const action of actions) {
- const originalLength = patches.length;
- const morePatches = this.applyAction(action);
- patches.length += morePatches.length;
- for (let i = 0; i < morePatches.length; ++i) {
- patches[i + originalLength] = morePatches[i];
- }
- }
this._runningControllers = true;
try {
runAgain = assertExists(this._rootController).invoke();
@@ -90,42 +74,12 @@ class Globals implements App {
this._runningControllers = false;
}
}
- assertExists(this._frontend).send<void>('patchState', [patches]);
- }
-
- // TODO: this needs to be cleaned up.
- publish(what: PublishKinds, data: {}, transferList?: Transferable[]) {
- assertExists(this._frontend)
- .send<void>(`publish${what}`, [data], transferList);
}
get state(): State {
return assertExists(this._state);
}
- applyAction(action: DeferredAction): Patch[] {
- assertExists(this._state);
- const patches: Patch[] = [];
-
- // 'produce' creates a immer proxy which wraps the current state turning
- // all imperative mutations of the state done in the callback into
- // immutable changes to the returned state.
- this._state = produce(
- this.state,
- draft => {
- // tslint:disable-next-line no-any
- (StateActions as any)[action.type](draft, action.args);
- },
- (morePatches, _) => {
- const originalLength = patches.length;
- patches.length += morePatches.length;
- for (let i = 0; i < morePatches.length; ++i) {
- patches[i + originalLength] = morePatches[i];
- }
- });
- return patches;
- }
-
resetForTesting() {
this._state = undefined;
this._rootController = undefined;
diff --git a/ui/src/controller/heap_profile_controller.ts b/ui/src/controller/heap_profile_controller.ts
deleted file mode 100644
index c424b8f82..000000000
--- a/ui/src/controller/heap_profile_controller.ts
+++ /dev/null
@@ -1,357 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import {Engine} from '../common/engine';
-import {
- ALLOC_SPACE_MEMORY_ALLOCATED_KEY,
- DEFAULT_VIEWING_OPTION,
- expandCallsites,
- findRootSize,
- mergeCallsites,
- OBJECTS_ALLOCATED_KEY,
- OBJECTS_ALLOCATED_NOT_FREED_KEY,
- SPACE_MEMORY_ALLOCATED_NOT_FREED_KEY
-} from '../common/flamegraph_util';
-import {slowlyCountRows} from '../common/query_iterator';
-import {CallsiteInfo, HeapProfileFlamegraph} from '../common/state';
-import {fromNs} from '../common/time';
-import {HeapProfileDetails} from '../frontend/globals';
-
-import {Controller} from './controller';
-import {globals} from './globals';
-
-export interface HeapProfileControllerArgs {
- engine: Engine;
-}
-const MIN_PIXEL_DISPLAYED = 1;
-
-class TablesCache {
- private engine: Engine;
- private cache: Map<string, string>;
- private prefix: string;
- private tableId: number;
- private cacheSizeLimit: number;
-
- constructor(engine: Engine, prefix: string) {
- this.engine = engine;
- this.cache = new Map<string, string>();
- this.prefix = prefix;
- this.tableId = 0;
- this.cacheSizeLimit = 10;
- }
-
- async getTableName(query: string): Promise<string> {
- let tableName = this.cache.get(query);
- if (tableName === undefined) {
- // TODO(hjd): This should be LRU.
- if (this.cache.size > this.cacheSizeLimit) {
- for (const name of this.cache.values()) {
- await this.engine.query(`drop table ${name}`);
- }
- this.cache.clear();
- }
- tableName = `${this.prefix}_${this.tableId++}`;
- await this.engine.query(
- `create temp table if not exists ${tableName} as ${query}`);
- this.cache.set(query, tableName);
- }
- return tableName;
- }
-}
-
-export class HeapProfileController extends Controller<'main'> {
- private flamegraphDatasets: Map<string, CallsiteInfo[]> = new Map();
- private lastSelectedHeapProfile?: HeapProfileFlamegraph;
- private requestingData = false;
- private queuedRequest = false;
- private heapProfileDetails: HeapProfileDetails = {};
- private cache: TablesCache;
-
- constructor(private args: HeapProfileControllerArgs) {
- super('main');
- this.cache = new TablesCache(args.engine, 'grouped_callsites');
- }
-
- run() {
- const selection = globals.state.currentHeapProfileFlamegraph;
-
- if (!selection) return;
-
- if (this.shouldRequestData(selection)) {
- if (this.requestingData) {
- this.queuedRequest = true;
- } else {
- this.requestingData = true;
- const selectedHeapProfile: HeapProfileFlamegraph =
- this.copyHeapProfile(selection);
-
- this.getHeapProfileMetadata(
- selection.type,
- selectedHeapProfile.ts,
- selectedHeapProfile.upid)
- .then(result => {
- if (result !== undefined) {
- Object.assign(this.heapProfileDetails, result);
- }
-
- // TODO(hjd): Clean this up.
- if (this.lastSelectedHeapProfile &&
- this.lastSelectedHeapProfile.focusRegex !==
- selection.focusRegex) {
- this.flamegraphDatasets.clear();
- }
-
- this.lastSelectedHeapProfile = this.copyHeapProfile(selection);
-
- const expandedId = selectedHeapProfile.expandedCallsite ?
- selectedHeapProfile.expandedCallsite.id :
- -1;
- const rootSize =
- selectedHeapProfile.expandedCallsite === undefined ?
- undefined :
- selectedHeapProfile.expandedCallsite.totalSize;
-
- const key =
- `${selectedHeapProfile.upid};${selectedHeapProfile.ts}`;
-
- this.getFlamegraphData(
- key,
- selectedHeapProfile.viewingOption ?
- selectedHeapProfile.viewingOption :
- DEFAULT_VIEWING_OPTION,
- selection.ts,
- selectedHeapProfile.upid,
- selectedHeapProfile.type,
- selectedHeapProfile.focusRegex)
- .then(flamegraphData => {
- if (flamegraphData !== undefined && selection &&
- selection.kind === selectedHeapProfile.kind &&
- selection.id === selectedHeapProfile.id &&
- selection.ts === selectedHeapProfile.ts) {
- const expandedFlamegraphData =
- expandCallsites(flamegraphData, expandedId);
- this.prepareAndMergeCallsites(
- expandedFlamegraphData,
- this.lastSelectedHeapProfile!.viewingOption,
- rootSize,
- this.lastSelectedHeapProfile!.expandedCallsite);
- }
- })
- .finally(() => {
- this.requestingData = false;
- if (this.queuedRequest) {
- this.queuedRequest = false;
- this.run();
- }
- });
- });
- }
- }
- }
-
- private copyHeapProfile(heapProfile: HeapProfileFlamegraph):
- HeapProfileFlamegraph {
- return {
- kind: heapProfile.kind,
- id: heapProfile.id,
- upid: heapProfile.upid,
- ts: heapProfile.ts,
- type: heapProfile.type,
- expandedCallsite: heapProfile.expandedCallsite,
- viewingOption: heapProfile.viewingOption,
- focusRegex: heapProfile.focusRegex,
- };
- }
-
- private shouldRequestData(selection: HeapProfileFlamegraph) {
- return selection.kind === 'HEAP_PROFILE_FLAMEGRAPH' &&
- (this.lastSelectedHeapProfile === undefined ||
- (this.lastSelectedHeapProfile !== undefined &&
- (this.lastSelectedHeapProfile.id !== selection.id ||
- this.lastSelectedHeapProfile.ts !== selection.ts ||
- this.lastSelectedHeapProfile.type !== selection.type ||
- this.lastSelectedHeapProfile.upid !== selection.upid ||
- this.lastSelectedHeapProfile.viewingOption !==
- selection.viewingOption ||
- this.lastSelectedHeapProfile.focusRegex !== selection.focusRegex ||
- this.lastSelectedHeapProfile.expandedCallsite !==
- selection.expandedCallsite)));
- }
-
- private prepareAndMergeCallsites(
- flamegraphData: CallsiteInfo[],
- viewingOption: string|undefined = DEFAULT_VIEWING_OPTION,
- rootSize?: number, expandedCallsite?: CallsiteInfo) {
- const mergedFlamegraphData = mergeCallsites(
- flamegraphData, this.getMinSizeDisplayed(flamegraphData, rootSize));
- this.heapProfileDetails.flamegraph = mergedFlamegraphData;
- this.heapProfileDetails.expandedCallsite = expandedCallsite;
- this.heapProfileDetails.viewingOption = viewingOption;
- globals.publish('HeapProfileDetails', this.heapProfileDetails);
- }
-
-
- async getFlamegraphData(
- baseKey: string, viewingOption: string, ts: number, upid: number,
- type: string, focusRegex: string): Promise<CallsiteInfo[]> {
- let currentData: CallsiteInfo[];
- const key = `${baseKey}-${viewingOption}`;
- if (this.flamegraphDatasets.has(key)) {
- currentData = this.flamegraphDatasets.get(key)!;
- } else {
- // TODO(hjd): Show loading state.
-
- // Collecting data for drawing flamegraph for selected heap profile.
- // Data needs to be in following format:
- // id, name, parent_id, depth, total_size
- const tableName =
- await this.prepareViewsAndTables(ts, upid, type, focusRegex);
- currentData = await this.getFlamegraphDataFromTables(
- tableName, viewingOption, focusRegex);
- this.flamegraphDatasets.set(key, currentData);
- }
- return currentData;
- }
-
- async getFlamegraphDataFromTables(
- tableName: string, viewingOption = DEFAULT_VIEWING_OPTION,
- focusRegex: string) {
- let orderBy = '';
- let sizeIndex = 4;
- let selfIndex = 9;
- // TODO(fmayer): Improve performance so this is no longer necessary.
- // Alternatively consider collapsing frames of the same label.
- const maxDepth = 100;
- switch (viewingOption) {
- case SPACE_MEMORY_ALLOCATED_NOT_FREED_KEY:
- orderBy = `where cumulative_size > 0 and depth < ${
- maxDepth} order by depth, parent_id,
- cumulative_size desc, name`;
- sizeIndex = 4;
- selfIndex = 9;
- break;
- case ALLOC_SPACE_MEMORY_ALLOCATED_KEY:
- orderBy = `where cumulative_alloc_size > 0 and depth < ${
- maxDepth} order by depth, parent_id,
- cumulative_alloc_size desc, name`;
- sizeIndex = 5;
- selfIndex = 9;
- break;
- case OBJECTS_ALLOCATED_NOT_FREED_KEY:
- orderBy = `where cumulative_count > 0 and depth < ${
- maxDepth} order by depth, parent_id,
- cumulative_count desc, name`;
- sizeIndex = 6;
- selfIndex = 10;
- break;
- case OBJECTS_ALLOCATED_KEY:
- orderBy = `where cumulative_alloc_count > 0 and depth < ${
- maxDepth} order by depth, parent_id,
- cumulative_alloc_count desc, name`;
- sizeIndex = 7;
- selfIndex = 10;
- break;
- default:
- break;
- }
-
- const callsites = await this.args.engine.query(
- `SELECT id, IFNULL(DEMANGLE(name), name), IFNULL(parent_id, -1), depth,
- cumulative_size, cumulative_alloc_size, cumulative_count,
- cumulative_alloc_count, map_name, size, count from ${tableName} ${
- orderBy}`);
-
- const flamegraphData: CallsiteInfo[] = new Array();
- const hashToindex: Map<number, number> = new Map();
- for (let i = 0; i < slowlyCountRows(callsites); i++) {
- const hash = callsites.columns[0].longValues![i];
- let name = callsites.columns[1].stringValues![i];
- const parentHash = callsites.columns[2].longValues![i];
- const depth = +callsites.columns[3].longValues![i];
- const totalSize = +callsites.columns[sizeIndex].longValues![i];
- const mapping = callsites.columns[8].stringValues![i];
- const selfSize = +callsites.columns[selfIndex].longValues![i];
- const highlighted = focusRegex !== '' &&
- name.toLocaleLowerCase().includes(focusRegex.toLocaleLowerCase());
- const parentId =
- hashToindex.has(+parentHash) ? hashToindex.get(+parentHash)! : -1;
- if (depth === maxDepth - 1) {
- name += ' [tree truncated]';
- }
- hashToindex.set(+hash, i);
- // Instead of hash, we will store index of callsite in this original array
- // as an id of callsite. That way, we have quicker access to parent and it
- // will stay unique.
- flamegraphData.push({
- id: i,
- totalSize,
- depth,
- parentId,
- name,
- selfSize,
- mapping,
- merged: false,
- highlighted
- });
- }
- return flamegraphData;
- }
-
- private async prepareViewsAndTables(
- ts: number, upid: number, type: string,
- focusRegex: string): Promise<string> {
- // Creating unique names for views so we can reuse and not delete them
- // for each marker.
- let whereClause = '';
- if (focusRegex !== '') {
- whereClause = `where focus_str = '${focusRegex}'`;
- }
-
- return this.cache.getTableName(
- `select id, name, map_name, parent_id, depth, cumulative_size,
- cumulative_alloc_size, cumulative_count, cumulative_alloc_count,
- size, alloc_size, count, alloc_count
- from experimental_flamegraph(${ts}, ${upid}, '${type}') ${
- whereClause}`);
- }
-
- getMinSizeDisplayed(flamegraphData: CallsiteInfo[], rootSize?: number):
- number {
- const timeState = globals.state.frontendLocalState.visibleState;
- let width = (timeState.endSec - timeState.startSec) / timeState.resolution;
- // TODO(168048193): Remove screen size hack:
- width = Math.max(width, 800);
- if (rootSize === undefined) {
- rootSize = findRootSize(flamegraphData);
- }
- return MIN_PIXEL_DISPLAYED * rootSize / width;
- }
-
- async getHeapProfileMetadata(type: string, ts: number, upid: number) {
- // Don't do anything if selection of the marker stayed the same.
- if ((this.lastSelectedHeapProfile !== undefined &&
- ((this.lastSelectedHeapProfile.ts === ts &&
- this.lastSelectedHeapProfile.upid === upid)))) {
- return undefined;
- }
-
- // Collecting data for more information about heap profile, such as:
- // total memory allocated, memory that is allocated and not freed.
- const pidValue = await this.args.engine.query(
- `select pid from process where upid = ${upid}`);
- const pid = pidValue.columns[0].longValues![0];
- const startTime = fromNs(ts) - globals.state.traceTime.startSec;
- return {ts: startTime, tsNs: ts, pid, upid, type};
- }
-}
diff --git a/ui/src/controller/index.ts b/ui/src/controller/index.ts
index bf655b45d..5b4bbdd4b 100644
--- a/ui/src/controller/index.ts
+++ b/ui/src/controller/index.ts
@@ -12,47 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import '../tracks/all_controller';
-
-import {reportError, setErrorHandler} from '../base/logging';
-import {Remote} from '../base/remote';
-import {warmupWasmEngine} from '../common/wasm_engine_proxy';
+import '../gen/all_tracks';
+import {assertTrue} from '../base/logging';
+import {ControllerWorkerInitMessage} from '../common/worker_messages';
import {AppController} from './app_controller';
import {globals} from './globals';
-interface OnMessageArg {
- data: {
- frontendPort: MessagePort; controllerPort: MessagePort;
- extensionPort: MessagePort;
- errorReportingPort: MessagePort;
- };
-}
-
-function main() {
- self.addEventListener('error', e => reportError(e));
- self.addEventListener('unhandledrejection', e => reportError(e));
- warmupWasmEngine();
- let initialized = false;
- self.onmessage = ({data}: OnMessageArg) => {
- if (initialized) {
- console.error('Already initialized');
- return;
- }
- initialized = true;
- const frontendPort = data.frontendPort;
- const controllerPort = data.controllerPort;
- const extensionPort = data.extensionPort;
- const errorReportingPort = data.errorReportingPort;
- setErrorHandler((err: string) => errorReportingPort.postMessage(err));
- const frontend = new Remote(frontendPort);
- controllerPort.onmessage = ({data}) => globals.dispatch(data);
-
- globals.initialize(new AppController(extensionPort), frontend);
- };
+let initialized = false;
+export function initController(init: ControllerWorkerInitMessage) {
+ assertTrue(!initialized);
+ initialized = true;
+ const controllerPort = init.controllerPort;
+ const extensionPort = init.extensionPort;
+ controllerPort.onmessage = ({data}) => globals.patchState(data);
+ globals.initialize(new AppController(extensionPort));
}
-main();
// For devtools-based debugging.
-(self as {} as {globals: {}}).globals = globals;
+(self as {} as {controllerGlobals: {}}).controllerGlobals = globals;
diff --git a/ui/src/controller/loading_manager.ts b/ui/src/controller/loading_manager.ts
index 3814933d0..5b0e0cf18 100644
--- a/ui/src/controller/loading_manager.ts
+++ b/ui/src/controller/loading_manager.ts
@@ -13,7 +13,7 @@
// limitations under the License.
import {LoadingTracker} from '../common/engine';
-import {globals} from './globals';
+import {publishLoading} from '../frontend/publish';
// Used to keep track of whether the engine is currently querying.
export class LoadingManager implements LoadingTracker {
@@ -38,7 +38,7 @@ export class LoadingManager implements LoadingTracker {
if (this.numQueuedQueries === 0 ||
Math.abs(this.numLastUpdate - this.numQueuedQueries) > 2) {
this.numLastUpdate = this.numQueuedQueries;
- globals.publish('Loading', this.numQueuedQueries);
+ publishLoading(this.numQueuedQueries);
}
}
}
diff --git a/ui/src/controller/logs_controller.ts b/ui/src/controller/logs_controller.ts
index 7d1d49f6d..50deb2b94 100644
--- a/ui/src/controller/logs_controller.ts
+++ b/ui/src/controller/logs_controller.ts
@@ -20,8 +20,9 @@ import {
LogEntriesKey,
LogExistsKey
} from '../common/logs';
-import {slowlyCountRows} from '../common/query_iterator';
+import {NUM, STR} from '../common/query_result';
import {fromNs, TimeSpan, toNsCeil, toNsFloor} from '../common/time';
+import {publishTrackData} from '../frontend/publish';
import {Controller} from './controller';
import {App} from './globals';
@@ -31,21 +32,28 @@ async function updateLogBounds(
const vizStartNs = toNsFloor(span.start);
const vizEndNs = toNsCeil(span.end);
- const countResult = await engine.queryOneRow(`
- select min(ts), max(ts), count(ts)
+ const countResult = await engine.query(`
+ select
+ ifnull(min(ts), 0) as minTs,
+ ifnull(max(ts), 0) as maxTs,
+ count(ts) as countTs
from android_logs where ts >= ${vizStartNs} and ts <= ${vizEndNs}`);
- const firstRowNs = countResult[0];
- const lastRowNs = countResult[1];
- const total = countResult[2];
+ const countRow = countResult.firstRow({minTs: NUM, maxTs: NUM, countTs: NUM});
- const minResult = await engine.queryOneRow(`
- select max(ts) from android_logs where ts < ${vizStartNs}`);
- const startNs = minResult[0];
+ const firstRowNs = countRow.minTs;
+ const lastRowNs = countRow.maxTs;
+ const total = countRow.countTs;
- const maxResult = await engine.queryOneRow(`
- select min(ts) from android_logs where ts > ${vizEndNs}`);
- const endNs = maxResult[0];
+ const minResult = await engine.query(`
+ select ifnull(max(ts), 0) as maxTs from android_logs where ts < ${
+ vizStartNs}`);
+ const startNs = minResult.firstRow({maxTs: NUM}).maxTs;
+
+ const maxResult = await engine.query(`
+ select ifnull(min(ts), 0) as minTs from android_logs where ts > ${
+ vizEndNs}`);
+ const endNs = maxResult.firstRow({minTs: NUM}).minTs;
const trace = await engine.getTraceTimeBounds();
const startTs = startNs ? fromNs(startNs) : trace.start;
@@ -68,26 +76,30 @@ async function updateLogEntries(
const vizEndNs = toNsCeil(span.end);
const vizSqlBounds = `ts >= ${vizStartNs} and ts <= ${vizEndNs}`;
- const rowsResult =
- await engine.query(`select ts, prio, tag, msg from android_logs
+ const rowsResult = await engine.query(`
+ select
+ ts,
+ prio,
+ ifnull(tag, '[NULL]') as tag,
+ ifnull(msg, '[NULL]') as msg
+ from android_logs
where ${vizSqlBounds}
order by ts
- limit ${pagination.start}, ${pagination.count}`);
-
- if (!slowlyCountRows(rowsResult)) {
- return {
- offset: pagination.start,
- timestamps: [],
- priorities: [],
- tags: [],
- messages: [],
- };
- }
+ limit ${pagination.start}, ${pagination.count}
+ `);
- const timestamps = rowsResult.columns[0].longValues!;
- const priorities = rowsResult.columns[1].longValues!;
- const tags = rowsResult.columns[2].stringValues!;
- const messages = rowsResult.columns[3].stringValues!;
+ const timestamps = [];
+ const priorities = [];
+ const tags = [];
+ const messages = [];
+
+ const it = rowsResult.iter({ts: NUM, prio: NUM, tag: STR, msg: STR});
+ for (; it.valid(); it.next()) {
+ timestamps.push(it.ts);
+ priorities.push(it.prio);
+ tags.push(it.tag);
+ messages.push(it.msg);
+ }
return {
offset: pagination.start,
@@ -158,7 +170,7 @@ export class LogsController extends Controller<'main'> {
this.pagination = new Pagination(0, 0);
this.hasAnyLogs().then(exists => {
this.hasLogs = exists;
- this.app.publish('TrackData', {
+ publishTrackData({
id: LogExistsKey,
data: {
exists,
@@ -168,10 +180,10 @@ export class LogsController extends Controller<'main'> {
}
async hasAnyLogs() {
- const result = await this.engine.queryOneRow(`
- select count(*) from android_logs
+ const result = await this.engine.query(`
+ select count(*) as cnt from android_logs
`);
- return result[0] > 0;
+ return result.firstRow({cnt: NUM}).cnt > 0;
}
run() {
@@ -202,7 +214,7 @@ export class LogsController extends Controller<'main'> {
this.span = newSpan;
updateLogBounds(this.engine, newSpan).then(data => {
if (!newSpan.equals(this.span)) return;
- this.app.publish('TrackData', {
+ publishTrackData({
id: LogBoundsKey,
data,
});
@@ -216,7 +228,7 @@ export class LogsController extends Controller<'main'> {
updateLogEntries(this.engine, newSpan, this.pagination).then(data => {
if (!this.pagination.contains(requestedPagination)) return;
- this.app.publish('TrackData', {
+ publishTrackData({
id: LogEntriesKey,
data,
});
diff --git a/ui/src/controller/metrics_controller.ts b/ui/src/controller/metrics_controller.ts
index 6d0e835a5..d0e091659 100644
--- a/ui/src/controller/metrics_controller.ts
+++ b/ui/src/controller/metrics_controller.ts
@@ -13,8 +13,9 @@
// limitations under the License.
import {Actions} from '../common/actions';
-import {Engine, QueryError} from '../common/engine';
-import {iter, STR} from '../common/query_iterator';
+import {Engine} from '../common/engine';
+import {QueryError} from '../common/query_result';
+import {publishMetricResult} from '../frontend/publish';
import {Controller} from './controller';
import {globals} from './globals';
@@ -26,27 +27,7 @@ export class MetricsController extends Controller<'main'> {
constructor(args: {engine: Engine}) {
super('main');
this.engine = args.engine;
- this.setup().finally(() => {
- this.run();
- });
- }
-
- private async getMetricNames() {
- const metrics = [];
- const it = iter(
- {
- name: STR,
- },
- await this.engine.query('select name from trace_metrics'));
- for (; it.valid(); it.next()) {
- metrics.push(it.row.name);
- }
- return metrics;
- }
-
- private async setup() {
- const metrics = await this.getMetricNames();
- globals.dispatch(Actions.setAvailableMetrics({metrics}));
+ this.run();
}
private async computeMetric(name: string) {
@@ -54,14 +35,15 @@ export class MetricsController extends Controller<'main'> {
this.currentlyRunningMetric = name;
try {
const metricResult = await this.engine.computeMetric([name]);
- globals.publish(
- 'MetricResult',
- {name, resultString: metricResult.metricsAsPrototext});
+ publishMetricResult({
+ name,
+ resultString: metricResult.metricsAsPrototext,
+ });
} catch (e) {
if (e instanceof QueryError) {
// Reroute error to be displated differently when metric is run through
// metric page.
- globals.publish('MetricResult', {name, error: e.message});
+ publishMetricResult({name, error: e.message});
} else {
throw e;
}
diff --git a/ui/src/controller/permalink_controller.ts b/ui/src/controller/permalink_controller.ts
index a3904430d..cfb87dd16 100644
--- a/ui/src/controller/permalink_controller.ts
+++ b/ui/src/controller/permalink_controller.ts
@@ -16,18 +16,23 @@ import {produce} from 'immer';
import {assertExists} from '../base/logging';
import {Actions} from '../common/actions';
-import {createEmptyState, State} from '../common/state';
-import {RecordConfig, STATE_VERSION} from '../common/state';
+import {ConversionJobStatus} from '../common/conversion_jobs';
+import {createEmptyState} from '../common/empty_state';
+import {State} from '../common/state';
+import {STATE_VERSION} from '../common/state';
import {
BUCKET_NAME,
saveState,
saveTrace,
toSha256
} from '../common/upload_utils';
+import {publishConversionJobStatusUpdate} from '../frontend/publish';
+import {Router} from '../frontend/router';
import {Controller} from './controller';
import {globals} from './globals';
-import {validateRecordConfig} from './validate_config';
+import {RecordConfig, recordConfigValidator} from './record_config_types';
+import {runValidator} from './validators';
export class PermalinkController extends Controller<'main'> {
private lastRequestId?: string;
@@ -48,10 +53,22 @@ export class PermalinkController extends Controller<'main'> {
const isRecordingConfig =
assertExists(globals.state.permalink.isRecordingConfig);
+ const jobName = 'create_permalink';
+ publishConversionJobStatusUpdate({
+ jobName,
+ jobStatus: ConversionJobStatus.InProgress,
+ });
+
PermalinkController.createPermalink(isRecordingConfig)
- .then(((hash: string) => {
+ .then(hash => {
globals.dispatch(Actions.setPermalink({requestId, hash}));
- }));
+ })
+ .finally(() => {
+ publishConversionJobStatusUpdate({
+ jobName,
+ jobStatus: ConversionJobStatus.NotRunning,
+ });
+ });
return;
}
@@ -61,14 +78,11 @@ export class PermalinkController extends Controller<'main'> {
if (PermalinkController.isRecordConfig(stateOrConfig)) {
// This permalink state only contains a RecordConfig. Show the
// recording page with the config, but keep other state as-is.
- const validConfig = validateRecordConfig(stateOrConfig);
- if (validConfig.errorMessage) {
- // TODO(bsebastien): Show a warning message to the user in the UI.
- console.warn(validConfig.errorMessage);
- }
- globals.dispatch(
- Actions.setRecordConfig({config: validConfig.config}));
- globals.dispatch(Actions.navigate({route: '/record'}));
+ const validConfig =
+ runValidator(recordConfigValidator, stateOrConfig as unknown)
+ .result;
+ globals.dispatch(Actions.setRecordConfig({config: validConfig}));
+ Router.navigate('#!/record');
return;
}
globals.dispatch(Actions.setState({newState: stateOrConfig}));
@@ -99,7 +113,8 @@ export class PermalinkController extends Controller<'main'> {
stateOrConfig.mode);
}
- private static async createPermalink(isRecordingConfig: boolean) {
+ private static async createPermalink(isRecordingConfig: boolean):
+ Promise<string> {
let uploadState: State|RecordConfig = globals.state;
if (isRecordingConfig) {
diff --git a/ui/src/controller/pivot_table_controller.ts b/ui/src/controller/pivot_table_controller.ts
new file mode 100644
index 000000000..78abb2469
--- /dev/null
+++ b/ui/src/controller/pivot_table_controller.ts
@@ -0,0 +1,755 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {Actions} from '../common/actions';
+import {Engine} from '../common/engine';
+import {
+ AggregationAttrs,
+ AVAILABLE_AGGREGATIONS,
+ AVAILABLE_TABLES,
+ getDescendantsTables,
+ getParentStackColumn,
+ getStackColumn,
+ getStackDepthColumn,
+ PivotAttrs,
+ PivotTableQueryResponse,
+ removeHiddenAndAddStackColumns,
+ RowAttrs,
+ WHERE_FILTERS
+} from '../common/pivot_table_common';
+import {
+ getAggregationAlias,
+ getAggregationOverStackAlias,
+ getAliasedPivotColumns,
+ getHiddenPivotAlias,
+ getPivotAlias,
+ getTotalAggregationAlias,
+ PivotTableQueryGenerator
+} from '../common/pivot_table_query_generator';
+import {
+ QueryResponse,
+ runQuery,
+} from '../common/queries';
+import {Row} from '../common/query_result';
+import {toNs} from '../common/time';
+import {PivotTableHelper} from '../frontend/pivot_table_helper';
+import {publishPivotTableHelper, publishQueryResult} from '../frontend/publish';
+
+import {Controller} from './controller';
+import {globals} from './globals';
+
+export interface PivotTableControllerArgs {
+ pivotTableId: string;
+ engine: Engine;
+}
+
+function getExpandableColumn(
+ pivotTableId: string, queriedPivots: PivotAttrs[]): string|undefined {
+ if (queriedPivots.length === 0) {
+ return undefined;
+ }
+ const selectedPivots = globals.state.pivotTable[pivotTableId].selectedPivots;
+ const lastPivot = getPivotAlias(selectedPivots[selectedPivots.length - 1]);
+ const lastQueriedPivot =
+ getPivotAlias(queriedPivots[queriedPivots.length - 1]);
+ if (lastQueriedPivot !== lastPivot) {
+ return lastQueriedPivot;
+ }
+ return undefined;
+}
+
+function getRowWhereFilters(
+ queriedPivots: PivotAttrs[], row: Row, parentRow?: RowAttrs) {
+ let whereFilters = new Map();
+
+ // Add all the row's parent whereFilers.
+ if (parentRow) {
+ whereFilters = new Map(parentRow.whereFilters);
+ }
+
+ // Add whereFilters for all the queried pivots and any hidden pivots without
+ // the stack pivots.
+ getAliasedPivotColumns(queriedPivots)
+ .filter(pivot => !pivot.pivotAttrs.isStackPivot)
+ .forEach(
+ pivot => whereFilters.set(
+ pivot.columnAlias,
+ `CAST(${pivot.pivotAttrs.tableName}.${
+ pivot.pivotAttrs.columnName} AS TEXT) = '${
+ row[pivot.columnAlias]!.toString()}'`));
+
+ return whereFilters;
+}
+
+function getPivotTableQueryResponseRows(
+ pivotTableId: string,
+ rows: Row[],
+ queriedPivots: PivotAttrs[],
+ parentRow?: RowAttrs) {
+ const expandableColumns = new Set<string>();
+ if (queriedPivots.length > 0 && queriedPivots[0].isStackPivot) {
+ // Make the stack column expandable.
+ expandableColumns.add(getPivotAlias(queriedPivots[0]));
+ }
+ // Add expandable column after the stack column if it exists.
+ const expandableColumn = getExpandableColumn(pivotTableId, queriedPivots);
+ if (expandableColumn !== undefined) {
+ expandableColumns.add(expandableColumn);
+ }
+
+ const newRows: RowAttrs[] = [];
+ for (const row of rows) {
+ newRows.push({
+ row,
+ expandableColumns,
+ depth: 0,
+ whereFilters: getRowWhereFilters(queriedPivots, row, parentRow),
+ expandedRows: new Map()
+ });
+ }
+ return newRows;
+}
+
+function getPivotTableQueryResponse(
+ pivotTableId: string,
+ queryResp: QueryResponse,
+ queriedPivots: PivotAttrs[],
+ parentRow?: RowAttrs): PivotTableQueryResponse {
+ const columns = [];
+ const pivotTable = globals.state.pivotTable[pivotTableId];
+
+ for (let i = 0; i < pivotTable.selectedPivots.length; ++i) {
+ const pivot = pivotTable.selectedPivots[i];
+ columns.push({
+ name: getPivotAlias(pivot),
+ index: i,
+ tableName: pivot.tableName,
+ columnName: pivot.columnName,
+ isStackColumn: pivot.isStackPivot
+ });
+ }
+
+ for (let i = 0; i < pivotTable.selectedAggregations.length; ++i) {
+ const aggregation = pivotTable.selectedAggregations[i];
+ columns.push({
+ name: getAggregationAlias(aggregation),
+ index: i,
+ tableName: aggregation.tableName,
+ columnName: aggregation.columnName,
+ aggregation: aggregation.aggregation,
+ order: aggregation.order,
+ isStackColumn: false
+ });
+ }
+
+ return {
+ columns,
+ rows: getPivotTableQueryResponseRows(
+ pivotTableId, queryResp.rows, queriedPivots, parentRow),
+ error: queryResp.error,
+ durationMs: queryResp.durationMs
+ };
+}
+
+function getRowInPivotTableQueryResponse(
+ queryResp: PivotTableQueryResponse,
+ rowIndices: number[],
+ expandedRowColumns: string[]) {
+ if (rowIndices.length === 0) {
+ throw new Error('Row indicies should have at least one index.');
+ }
+
+ let row = queryResp.rows[rowIndices[0]];
+
+ // expandedRowColumns and rowIndices should refer to the same rows minus the
+ // initial row index that specifies the row in the query response.
+ if (rowIndices.length !== expandedRowColumns.length + 1) {
+ throw Error(`expandedRowColumns length "${
+ expandedRowColumns.length}" should be less than rowIndicies length "${
+ rowIndices.length}" by one.`);
+ }
+
+ for (let i = 1; i < rowIndices.length; ++i) {
+ const expandedRow = row.expandedRows.get(expandedRowColumns[i - 1]);
+ if (expandedRow === undefined || expandedRow.rows.length <= rowIndices[i]) {
+ throw new Error(`Expanded row index "${rowIndices[i]}" at row column "${
+ expandedRowColumns[i - 1]}" is out of bounds.`);
+ }
+ row = expandedRow.rows[rowIndices[i]];
+ }
+ return row;
+}
+
+function getDescendantRows(
+ pivotTableId: string,
+ respRows: Row[],
+ parentRow: RowAttrs,
+ queriedPivots: PivotAttrs[],
+ queriedAggregations: AggregationAttrs[]) {
+ const stackPivot = queriedPivots[0];
+ if (stackPivot === undefined || !stackPivot.isStackPivot) {
+ throw Error('Queried pivot is not a stack pivot');
+ }
+
+ const stackIdColumn = getHiddenPivotAlias(getStackColumn(stackPivot));
+
+ const parentStackIdColumn =
+ getHiddenPivotAlias(getParentStackColumn(stackPivot));
+
+ const depthColumn = getHiddenPivotAlias(getStackDepthColumn(stackPivot));
+
+ const stackColumn = getPivotAlias(stackPivot); // "name (stack)" column.
+
+ const parentDepth = Number(parentRow.row[depthColumn]?.toString());
+ if (!Number.isInteger(parentDepth)) {
+ throw Error('Parent row has undefined depth.');
+ }
+
+ const parentRowStackId = parentRow.row[stackIdColumn]?.toString();
+ if (parentRowStackId === undefined) {
+ throw Error('Parent row has undefined stack_id.');
+ }
+
+ const nextPivot = queriedPivots[1];
+ let nextColumnName = '';
+ if (nextPivot !== undefined) {
+ nextColumnName = getPivotAlias(nextPivot);
+ }
+
+ const newRows: Map<string, RowAttrs> = new Map();
+ for (const row of respRows) {
+ const depth = Number(row[depthColumn]?.toString());
+ const stackId = row[stackIdColumn]?.toString();
+ const parentStackId = row[parentStackIdColumn]?.toString();
+ if (!Number.isInteger(depth)) {
+ throw Error('Descendant result has undefined depth.');
+ }
+ if (!stackId || !parentStackId) {
+ throw Error('Descendant result has undefined stack or parent stack id.');
+ }
+
+ const expandableColumns = new Set<string>();
+ // Get expandable column after the stack column if it exists.
+ const expandableColumn = getExpandableColumn(pivotTableId, queriedPivots);
+ if (expandableColumn !== undefined) {
+ expandableColumns.add(expandableColumn);
+ }
+
+ const newRow: RowAttrs = {
+ row: Object.assign({}, row),
+ depth: depth - parentDepth,
+ whereFilters: getRowWhereFilters(queriedPivots, row, parentRow),
+ expandedRows: new Map(),
+ expandableColumns
+ };
+
+ // If we have already added the stackId, we need to extract and nest its
+ // next column values in its expanded rows.
+ if (newRows.has(stackId)) {
+ newRow.row[stackColumn] = null;
+ const parent = newRows.get(stackId)!;
+ let nextColumnRows = parent.expandedRows.get(nextColumnName);
+ if (nextColumnRows === undefined) {
+ // Since the parent row has more than one value for the next column,
+ // we nest the values in rows under the parent row instead of inline
+ // with it.
+ // Making a new row to hold the next column value.
+ const row = Object.assign({}, parent.row);
+ const nextColumnRow: RowAttrs = {
+ row: Object.assign({}, row),
+ depth: depth - parentDepth,
+ whereFilters: getRowWhereFilters(queriedPivots, row, parentRow),
+ expandedRows: new Map(),
+ expandableColumns
+ };
+ parent.row[nextColumnName] = null;
+ // Modify the parent row to show the aggregation over stack rows instead
+ // of the partitioned aggregations.
+ for (const aggregation of queriedAggregations) {
+ parent.row[getAggregationAlias(aggregation)] =
+ parent.row[getAggregationOverStackAlias(aggregation)];
+ }
+ nextColumnRow.row[stackColumn] = null;
+ if (nextColumnRow.row[nextColumnName] !== undefined) {
+ parent.expandedRows.set(
+ nextColumnName, {isExpanded: true, rows: [nextColumnRow]});
+ }
+ nextColumnRows = parent.expandedRows.get(nextColumnName);
+ }
+ newRow.expandableColumns = expandableColumns;
+
+ nextColumnRows!.rows.push(newRow);
+ }
+
+ // If we have already added the parentStackId, we need to nest the row
+ // in its parent's expanded rows.
+ // This works because we sort the result of the descendants query by
+ // depth, insuring that if the stack_id has a parent other than the
+ // parent row, its parent will show up first.
+ if (newRows.has(parentStackId)) {
+ const parent = newRows.get(parentStackId)!;
+ let descendants = parent.expandedRows.get(stackColumn);
+ if (descendants === undefined) {
+ parent.expandedRows.set(stackColumn, {isExpanded: true, rows: []});
+ descendants = parent.expandedRows.get(stackColumn);
+ }
+ descendants!.rows.push(newRow);
+ parent.expandableColumns.add(stackColumn);
+
+ // Unexpand if parent has more than one child.
+ if (descendants!.rows.length > 1) {
+ descendants!.isExpanded = false;
+ if (parent.expandedRows.has(nextColumnName)) {
+ parent.expandedRows.get(nextColumnName)!.isExpanded = false;
+ }
+ }
+ }
+
+ if (!newRows.has(stackId)) {
+ newRows.set(stackId, newRow);
+ }
+ }
+
+ // Get only direct descendants of the parent row. The rest is nested inside
+ // the descendants.
+ const descendantRows =
+ Array.from(newRows.values())
+ .filter(
+ row => row.row[parentStackIdColumn]?.toString() ===
+ parentRowStackId);
+ // Get the next column values of the parent row.
+ let nextColumnRows;
+ if (newRows.has(parentRowStackId)) {
+ if (newRows.get(parentRowStackId)!.expandedRows.has(nextColumnName)) {
+ nextColumnRows =
+ newRows.get(parentRowStackId)!.expandedRows.get(nextColumnName)!.rows;
+ } else {
+ // If the next column value is inline with the parent row.
+ nextColumnRows = [newRows.get(parentRowStackId)!];
+ }
+ }
+ return {descendantRows, nextColumnRows};
+}
+
+function getPivotColumns(
+ pivotTableId: string, columnIdx: number, isStackQuery: boolean) {
+ const selectedPivots = globals.state.pivotTable[pivotTableId].selectedPivots;
+ // Slice returns the pivot at columnIdx if it exists, and an empty
+ // array if columnIdx is out of bounds.
+ const pivots = selectedPivots.slice(columnIdx, columnIdx + 1);
+ if (isStackQuery) {
+ // Adds the next pivot, if it exists, to be queried with the stack query.
+ pivots.push(...selectedPivots.slice(columnIdx + 1, columnIdx + 2));
+ }
+ return pivots;
+}
+
+function getWhereFilters(
+ pivotTableId: string,
+ parentRowWhereFilters: Map<string, string>,
+ pivots: PivotAttrs[],
+ isStackQuery: boolean) {
+ const whereFiltersMap = new Map(parentRowWhereFilters);
+
+ // Remove any existing where filters for the pivots to query.
+ getAliasedPivotColumns(pivots).forEach(
+ pivotAlias => whereFiltersMap.delete(pivotAlias.columnAlias));
+
+ const whereFilters = Array.from(whereFiltersMap.values());
+
+ if (pivots.length > 0 && pivots[0].isStackPivot && !isStackQuery) {
+ // Only query top level slices, descendants can be generated
+ // when expanded.
+ const orderColumn = getStackDepthColumn(pivots[0]);
+ whereFilters.push(`${orderColumn.tableName}.${orderColumn.columnName} = 0`);
+ }
+
+ // Add global where filters
+ whereFilters.push(...WHERE_FILTERS);
+
+ // Add area restrictions where filters if set.
+ const pivotTable = globals.state.pivotTable[pivotTableId];
+ if (pivotTable.selectedTrackIds) {
+ whereFilters.push(`slice.track_id IN (${pivotTable.selectedTrackIds})`);
+ }
+ if (pivotTable.traceTime) {
+ whereFilters.push(
+ `slice.ts + slice.dur > ${toNs(pivotTable.traceTime.startSec)}`);
+ whereFilters.push(`slice.ts < ${toNs(pivotTable.traceTime.endSec)}`);
+ }
+
+ return whereFilters;
+}
+
+export class PivotTableController extends Controller<'main'> {
+ private pivotTableId: string;
+ private pivotTableQueryGenerator = new PivotTableQueryGenerator();
+ private engine: Engine;
+ private queryResp?: PivotTableQueryResponse;
+
+ constructor(args: PivotTableControllerArgs) {
+ super('main');
+ this.engine = args.engine;
+ this.pivotTableId = args.pivotTableId;
+ this.setup().then(() => {
+ this.run();
+ });
+ }
+
+ run() {
+ const {requestedAction} = globals.state.pivotTable[this.pivotTableId];
+ const pivotTable = globals.state.pivotTable[this.pivotTableId];
+ if (!requestedAction) return;
+ globals.dispatch(
+ Actions.resetPivotTableRequest({pivotTableId: this.pivotTableId}));
+ switch (requestedAction.action) {
+ case 'DESCENDANTS':
+ const descendantsAttrs = requestedAction.attrs;
+ if (descendantsAttrs === undefined) {
+ throw Error('No attributes provided for descendants query.');
+ }
+ if (this.queryResp === undefined) {
+ throw Error(
+ 'Descendants query requested without setting the main query.');
+ }
+
+ const stackPivot =
+ pivotTable.selectedPivots[descendantsAttrs.columnIdx];
+ const stackColumnName = getPivotAlias(stackPivot);
+
+ const nextPivot =
+ pivotTable.selectedPivots[descendantsAttrs.columnIdx + 1];
+ let nextColumnName = '';
+ if (nextPivot !== undefined) {
+ nextColumnName = getPivotAlias(nextPivot);
+ }
+
+ const ancestorRow = getRowInPivotTableQueryResponse(
+ this.queryResp,
+ descendantsAttrs.rowIndices,
+ descendantsAttrs.expandedRowColumns);
+
+ // No need to query if the row has been expanded before.
+ if (ancestorRow.expandedRows.has(stackColumnName)) {
+ ancestorRow.expandedRows.get(stackColumnName)!.isExpanded = true;
+ if (ancestorRow.expandedRows.has(nextColumnName) &&
+ !ancestorRow.expandableColumns.has(nextColumnName)) {
+ ancestorRow.expandedRows.get(nextColumnName)!.isExpanded = true;
+ }
+ break;
+ }
+
+ const descendantsPivots = getPivotColumns(
+ this.pivotTableId,
+ descendantsAttrs.columnIdx,
+ /* is_stack_query = */ true);
+
+ if (descendantsPivots.length === 0) {
+ throw Error(
+ `Descendant operation at column index "${
+ descendantsAttrs
+ .columnIdx}" should only be allowed if there are` +
+ `are more columns to query.`);
+ }
+
+ const descendantsWhereFilters = getWhereFilters(
+ this.pivotTableId,
+ ancestorRow.whereFilters,
+ descendantsPivots,
+ /* is_stack_query = */ true);
+
+ const stackIdColumn = getHiddenPivotAlias(getStackColumn(stackPivot));
+
+ const stackId = ancestorRow.row[stackIdColumn]?.toString();
+ if (stackId === undefined) {
+ throw Error(`"${
+ getPivotAlias(
+ stackPivot)}" row has undefined stack id at column "${
+ stackIdColumn}".`);
+ }
+
+ const descendantsTables =
+ getDescendantsTables(descendantsPivots, stackId);
+
+ // Query the descendants and the next column if it exists.
+ const descendantsQuery =
+ this.pivotTableQueryGenerator.generateStackQuery(
+ descendantsPivots,
+ pivotTable.selectedAggregations,
+ descendantsWhereFilters,
+ descendantsTables,
+ stackId);
+
+ ancestorRow.loadingColumn = stackColumnName;
+
+ runQuery(this.pivotTableId, descendantsQuery, this.engine)
+ .then(resp => {
+ // Query resulting from query generator should always be valid.
+ if (resp.error) {
+ throw Error(`Pivot table descendants query ${
+ descendantsQuery} resulted in SQL error: ${resp.error}`);
+ }
+
+ const printDescendantsQuery =
+ descendantsQuery.length <= 1024 ? descendantsQuery : '';
+ console.log(`Descendants query${printDescendantsQuery} took ${
+ resp.durationMs} ms`);
+
+ const {descendantRows, nextColumnRows} = getDescendantRows(
+ this.pivotTableId,
+ resp.rows,
+ ancestorRow,
+ descendantsPivots,
+ pivotTable.selectedAggregations);
+ // Set descendant rows.
+ ancestorRow.expandedRows.set(
+ stackColumnName, {isExpanded: true, rows: descendantRows});
+ // Set the next pivot row(s), if they exist, inside the parent
+ // row.
+ if (nextColumnRows !== undefined) {
+ if (nextColumnRows.length <= 1) {
+ // If there is only one value for the next column of the
+ // parent row, add it to the same row as the parent.
+ ancestorRow.row = nextColumnRows[0].row;
+ ancestorRow.expandableColumns = new Set([
+ ...nextColumnRows[0].expandableColumns,
+ ...ancestorRow.expandableColumns
+ ]);
+ } else {
+ ancestorRow.expandedRows.set(
+ nextColumnName, {isExpanded: true, rows: nextColumnRows});
+ }
+ }
+ ancestorRow.loadingColumn = undefined;
+
+ this.queryResp!.durationMs += resp.durationMs;
+ });
+ break;
+
+ case 'EXPAND':
+ const expandAttrs = requestedAction.attrs;
+ if (expandAttrs === undefined) {
+ throw Error('No attributes provided for expand query.');
+ }
+ if (this.queryResp === undefined) {
+ throw Error('Expand query requested without setting the main query.');
+ }
+
+ const expandColumnName =
+ getPivotAlias(pivotTable.selectedPivots[expandAttrs.columnIdx]);
+
+ const expandRow = getRowInPivotTableQueryResponse(
+ this.queryResp,
+ expandAttrs.rowIndices,
+ expandAttrs.expandedRowColumns);
+
+ // No need to query if the row has been expanded before.
+ if (expandRow.expandedRows.has(expandColumnName)) {
+ expandRow.expandedRows.get(expandColumnName)!.isExpanded = true;
+ break;
+ }
+
+ const expandPivots = getPivotColumns(
+ this.pivotTableId,
+ expandAttrs.columnIdx + 1,
+ /* is_stack_query = */ false);
+
+ if (expandPivots.length === 0) {
+ throw Error(
+ `Expand operation at column index "${
+ expandAttrs.columnIdx}" should only be allowed if there are` +
+ `are more columns to query.`);
+ }
+
+ const expandWhereFilters = getWhereFilters(
+ this.pivotTableId,
+ expandRow.whereFilters,
+ expandPivots,
+ /* is_stack_query = */ false);
+
+ const expandQuery = this.pivotTableQueryGenerator.generateQuery(
+ expandPivots,
+ pivotTable.selectedAggregations,
+ expandWhereFilters,
+ AVAILABLE_TABLES);
+
+ expandRow.loadingColumn =
+ getPivotAlias(pivotTable.selectedPivots[expandAttrs.columnIdx]);
+
+ runQuery(this.pivotTableId, expandQuery, this.engine).then(resp => {
+ // Query resulting from query generator should always be valid.
+ if (resp.error) {
+ throw Error(`Pivot table expand query ${
+ expandQuery} resulted in SQL error: ${resp.error}`);
+ }
+ const printExpandQuery =
+ expandQuery.length <= 1024 ? expandQuery : '';
+ console.log(
+ `Expand query${printExpandQuery} took ${resp.durationMs} ms`);
+
+ expandRow.expandedRows.set(expandColumnName, {
+ isExpanded: true,
+ rows: getPivotTableQueryResponseRows(
+ this.pivotTableId, resp.rows, expandPivots, expandRow)
+ });
+ expandRow.loadingColumn = undefined;
+
+ this.queryResp!.durationMs += resp.durationMs;
+ });
+ break;
+
+ case 'UNEXPAND':
+ const unexpandAttrs = requestedAction.attrs;
+ if (unexpandAttrs === undefined) {
+ throw Error('No attributes provided for unexpand query.');
+ }
+ if (this.queryResp === undefined) {
+ throw Error(
+ 'Unexpand query requested without setting the main query.');
+ }
+
+ const unexpandPivot =
+ pivotTable.selectedPivots[unexpandAttrs.columnIdx];
+ const unexpandColumnName = getPivotAlias(unexpandPivot);
+
+ const unexpandRow = getRowInPivotTableQueryResponse(
+ this.queryResp,
+ unexpandAttrs.rowIndices,
+ unexpandAttrs.expandedRowColumns);
+
+ if (unexpandRow.expandedRows.has(unexpandColumnName)) {
+ unexpandRow.expandedRows.get(unexpandColumnName)!.isExpanded = false;
+ const nextPivot =
+ pivotTable.selectedPivots[unexpandAttrs.columnIdx + 1];
+ let nextColumnName = '';
+ if (nextPivot !== undefined) {
+ nextColumnName = getPivotAlias(nextPivot);
+ }
+ // Unexpand the next column rows if they are nested inside the
+ // parent expanded row, but no expandable column exists for the
+ // next column.
+ if (unexpandPivot.isStackPivot &&
+ unexpandRow.expandedRows.has(nextColumnName) &&
+ !unexpandRow.expandableColumns.has(nextColumnName)) {
+ unexpandRow.expandedRows.get(nextColumnName)!.isExpanded = false;
+ }
+ } else {
+ throw Error('Unexpand request called on already undexpanded row.');
+ }
+ break;
+
+ case 'QUERY':
+ // Generates and executes new query based on selectedPivots and
+ // selectedAggregations.
+
+ const pivots = getPivotColumns(
+ this.pivotTableId,
+ /* column_idx = */ 0,
+ /* is_stack_query = */ false);
+
+ const whereFilers = getWhereFilters(
+ this.pivotTableId,
+ /*parent_row_where_Filters = */ new Map(),
+ pivots,
+ /* is_stack_query = */ false);
+
+ const query = this.pivotTableQueryGenerator.generateQuery(
+ pivots,
+ pivotTable.selectedAggregations,
+ whereFilers,
+ AVAILABLE_TABLES);
+
+ if (query !== '') {
+ globals.dispatch(
+ Actions.toggleQueryLoading({pivotTableId: this.pivotTableId}));
+ runQuery(this.pivotTableId, query, this.engine).then(resp => {
+ // Query resulting from query generator should always be valid.
+ if (resp.error) {
+ throw Error(`Pivot table query ${query} resulted in SQL error: ${
+ resp.error}`);
+ }
+
+ const printQuery = query.length <= 1024 ? query : '';
+ console.log(`Query${printQuery} took ${resp.durationMs} ms`);
+ const data =
+ getPivotTableQueryResponse(this.pivotTableId, resp, pivots);
+
+ if (pivotTable.selectedAggregations.length > 0 &&
+ resp.rows.length > 0) {
+ const totalAggregationsRow = Object.assign({}, resp.rows[0]);
+
+ // Modify the total aggregations row to show the total
+ // aggregations.
+ if (pivotTable.selectedPivots.length > 0) {
+ for (const aggregation of pivotTable.selectedAggregations) {
+ totalAggregationsRow[getAggregationAlias(aggregation)] =
+ totalAggregationsRow[getTotalAggregationAlias(
+ aggregation)];
+ }
+ }
+ data.totalAggregations = totalAggregationsRow;
+ }
+
+ publishQueryResult({id: this.pivotTableId, data});
+
+ this.queryResp = data;
+
+ globals.dispatch(
+ Actions.toggleQueryLoading({pivotTableId: this.pivotTableId}));
+ });
+ } else {
+ publishQueryResult({id: this.pivotTableId, data: undefined});
+ }
+ break;
+
+ default:
+ throw new Error(`Unexpected requested action ${requestedAction}`);
+ }
+ }
+
+ private async setup(): Promise<void> {
+ const pivotTable = globals.state.pivotTable[this.pivotTableId];
+ const selectedPivots = pivotTable.selectedPivots;
+ const selectedAggregations = pivotTable.selectedAggregations;
+ let availableColumns = globals.state.pivotTableConfig.availableColumns;
+ // No need to retrieve table columns if they are already stored.
+ // Only needed when first pivot table is created.
+ if (availableColumns === undefined) {
+ availableColumns = [];
+ for (const table of AVAILABLE_TABLES) {
+ const columns = await this.getColumnsForTable(table);
+ if (columns.length > 0) {
+ availableColumns.push({tableName: table, columns});
+ }
+ }
+ globals.dispatch(Actions.setAvailablePivotTableColumns(
+ {availableColumns, availableAggregations: AVAILABLE_AGGREGATIONS}));
+ }
+ publishPivotTableHelper({
+ id: this.pivotTableId,
+ data: new PivotTableHelper(
+ this.pivotTableId,
+ availableColumns,
+ AVAILABLE_AGGREGATIONS,
+ selectedPivots,
+ selectedAggregations)
+ });
+ }
+
+ private async getColumnsForTable(tableName: string): Promise<string[]> {
+ const query = `select * from ${tableName} limit 0;`;
+ const resp = await runQuery(this.pivotTableId, query, this.engine);
+ return removeHiddenAndAddStackColumns(tableName, resp.columns);
+ }
+}
diff --git a/ui/src/controller/pivot_table_redux_controller.ts b/ui/src/controller/pivot_table_redux_controller.ts
new file mode 100644
index 000000000..4d17bf1f8
--- /dev/null
+++ b/ui/src/controller/pivot_table_redux_controller.ts
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {Actions} from '../common/actions';
+import {Engine} from '../common/engine';
+import {featureFlags} from '../common/feature_flags';
+import {ColumnType} from '../common/query_result';
+import {
+ PivotTableReduxQueryMetadata,
+ PivotTableReduxResult
+} from '../common/state';
+import {aggregationIndex} from '../frontend/pivot_table_redux_query_generator';
+
+import {Controller} from './controller';
+import {globals} from './globals';
+
+export const PIVOT_TABLE_REDUX_FLAG = featureFlags.register({
+ id: 'pivotTableRedux',
+ name: 'Pivot tables V2',
+ description: 'Second version of pivot table',
+ defaultValue: false,
+});
+
+// Node in the hierarchical pivot tree. Only leaf nodes contain data from the
+// query result.
+export interface PivotTree {
+ // Whether the node should be collapsed in the UI, false by default and can
+ // be toggled with the button.
+ isCollapsed: boolean;
+
+ // Non-empty only in internal nodes.
+ children: Map<ColumnType, PivotTree>;
+ aggregates: ColumnType[];
+
+ // Non-empty only in leaf nodes.
+ rows: ColumnType[][];
+}
+
+// Auxiliary class to build the tree from query response.
+class TreeBuilder {
+ private readonly root: PivotTree;
+ lastRow: ColumnType[];
+ pivotColumns: number;
+ aggregateColumns: number;
+
+ constructor(
+ pivotColumns: number, aggregateColumns: number, firstRow: ColumnType[]) {
+ this.pivotColumns = pivotColumns;
+ this.aggregateColumns = aggregateColumns;
+ this.root = this.createNode(0, firstRow);
+ let tree = this.root;
+ for (let i = 0; i + 1 < this.pivotColumns; i++) {
+ const value = firstRow[i];
+ tree = TreeBuilder.insertChild(
+ tree, value, this.createNode(i + 1, firstRow));
+ }
+ this.lastRow = firstRow;
+ }
+
+ // Add incoming row to the tree being built.
+ ingestRow(row: ColumnType[]) {
+ let tree = this.root;
+ for (let i = 0; i + 1 < this.pivotColumns; i++) {
+ const nextTree = tree.children.get(row[i]);
+ if (nextTree === undefined) {
+ // Insert the new node into the tree, and make variable `tree` point
+ // to the newly created node.
+ tree =
+ TreeBuilder.insertChild(tree, row[i], this.createNode(i + 1, row));
+ } else {
+ tree = nextTree;
+ }
+ }
+ tree.rows.push(row);
+ this.lastRow = row;
+ }
+
+ build(): PivotTree {
+ return this.root;
+ }
+
+ // Helper method that inserts child node into the tree and returns it, used
+ // for more concise modification of local variable pointing to the current
+ // node being built.
+ static insertChild(tree: PivotTree, key: ColumnType, child: PivotTree):
+ PivotTree {
+ tree.children.set(key, child);
+ return child;
+ }
+
+ // Initialize PivotTree from a row.
+ createNode(depth: number, row: ColumnType[]): PivotTree {
+ const aggregates = [];
+
+ for (let j = 0; j < this.aggregateColumns; j++) {
+ aggregates.push(row[aggregationIndex(this.pivotColumns, j, depth)]);
+ }
+
+ return {
+ isCollapsed: false,
+ children: new Map(),
+ aggregates,
+ rows: [],
+ };
+ }
+}
+
+function createEmptyQueryResult(metadata: PivotTableReduxQueryMetadata):
+ PivotTableReduxResult {
+ return {
+ tree: {
+ aggregates: [],
+ isCollapsed: false,
+ children: new Map(),
+ rows: [],
+ },
+ metadata
+ };
+}
+
+
+// Controller responsible for showing the panel with pivot table, as well as
+// executing its queries and post-processing query results.
+export class PivotTableReduxController extends Controller<{}> {
+ engine: Engine;
+ lastStartedQueryId: number;
+
+ constructor(args: {engine: Engine}) {
+ super({});
+ this.engine = args.engine;
+ this.lastStartedQueryId = 0;
+ }
+
+ run() {
+ if (!PIVOT_TABLE_REDUX_FLAG.get()) {
+ return;
+ }
+
+ const pivotTableState = globals.state.pivotTableRedux;
+ if (pivotTableState.queryId > this.lastStartedQueryId &&
+ pivotTableState.query !== null) {
+ this.lastStartedQueryId = pivotTableState.queryId;
+ const query = pivotTableState.query;
+
+ this.engine.query(query.text).then(async (result) => {
+ try {
+ await result.waitAllRows();
+ } catch {
+ // waitAllRows() frequently throws an exception, which is ignored in
+ // its other calls, so it's ignored here as well.
+ }
+
+ const columns = result.columns();
+
+ const it = result.iter({});
+ function nextRow(): ColumnType[] {
+ const row: ColumnType[] = [];
+ for (const column of columns) {
+ row.push(it.get(column));
+ }
+ it.next();
+ return row;
+ }
+
+ if (!it.valid()) {
+ // Iterator is invalid after creation; means that there are no rows
+ // satisfying filtering criteria. Return an empty tree.
+ globals.dispatch(Actions.setPivotStateReduxState({
+ pivotTableState: {
+ queryId: this.lastStartedQueryId,
+ query: null,
+ queryResult: createEmptyQueryResult(query.metadata),
+ selectionArea: pivotTableState.selectionArea
+ }
+ }));
+ return;
+ }
+
+ const treeBuilder = new TreeBuilder(
+ query.metadata.pivotColumns.length,
+ query.metadata.aggregationColumns.length,
+ nextRow());
+ while (it.valid()) {
+ treeBuilder.ingestRow(nextRow());
+ }
+
+ globals.dispatch(Actions.setPivotStateReduxState({
+ pivotTableState: {
+ queryId: this.lastStartedQueryId,
+ query: null,
+ queryResult: {
+ tree: treeBuilder.build(),
+ metadata: query.metadata,
+ },
+ selectionArea: pivotTableState.selectionArea
+ }
+ }));
+ });
+ }
+
+ const selection = globals.state.currentSelection;
+ if (selection !== null && selection.kind === 'AREA') {
+ const enabledArea = globals.state.areas[selection.areaId];
+ globals.dispatch(
+ Actions.togglePivotTableRedux({selectionArea: enabledArea}));
+ } else {
+ globals.dispatch(Actions.togglePivotTableRedux({selectionArea: null}));
+ }
+ }
+} \ No newline at end of file
diff --git a/ui/src/controller/query_controller.ts b/ui/src/controller/query_controller.ts
index c4bd9d485..b551a11ac 100644
--- a/ui/src/controller/query_controller.ts
+++ b/ui/src/controller/query_controller.ts
@@ -15,9 +15,8 @@
import {assertExists} from '../base/logging';
import {Actions} from '../common/actions';
import {Engine} from '../common/engine';
-import {rawQueryResultColumns, rawQueryResultIter, Row} from '../common/protos';
-import {QueryResponse} from '../common/queries';
-import {slowlyCountRows} from '../common/query_iterator';
+import {runQuery} from '../common/queries';
+import {publishQueryResult} from '../frontend/publish';
import {Controller} from './controller';
import {globals} from './globals';
@@ -36,11 +35,13 @@ export class QueryController extends Controller<'init'|'querying'> {
switch (this.state) {
case 'init':
const config = assertExists(globals.state.queries[this.args.queryId]);
- this.runQuery(config.query).then(result => {
- console.log(`Query ${config.query} took ${result.durationMs} ms`);
- globals.publish('QueryResult', {id: this.args.queryId, data: result});
- globals.dispatch(Actions.deleteQuery({queryId: this.args.queryId}));
- });
+ runQuery(this.args.queryId, config.query, this.args.engine)
+ .then(result => {
+ console.log(`Query ${config.query} took ${result.durationMs} ms`);
+ publishQueryResult({id: this.args.queryId, data: result});
+ globals.dispatch(
+ Actions.deleteQuery({queryId: this.args.queryId}));
+ });
this.setState('querying');
break;
@@ -53,33 +54,4 @@ export class QueryController extends Controller<'init'|'querying'> {
throw new Error(`Unexpected state ${this.state}`);
}
}
-
- private async runQuery(sqlQuery: string) {
- const startMs = performance.now();
- const rawResult = await this.args.engine.uncheckedQuery(sqlQuery);
- const durationMs = performance.now() - startMs;
- const columns = rawQueryResultColumns(rawResult);
- const rows =
- QueryController.firstN<Row>(10000, rawQueryResultIter(rawResult));
- const result: QueryResponse = {
- id: this.args.queryId,
- query: sqlQuery,
- durationMs,
- error: rawResult.error,
- totalRowCount: slowlyCountRows(rawResult),
- columns,
- rows,
- };
- return result;
- }
-
- private static firstN<T>(n: number, iter: IterableIterator<T>): T[] {
- const list = [];
- for (let i = 0; i < n; i++) {
- const {done, value} = iter.next();
- if (done) break;
- list.push(value);
- }
- return list;
- }
}
diff --git a/ui/src/controller/record_config_types.ts b/ui/src/controller/record_config_types.ts
new file mode 100644
index 000000000..546095787
--- /dev/null
+++ b/ui/src/controller/record_config_types.ts
@@ -0,0 +1,112 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {
+ oneOf,
+ num,
+ bool,
+ arrayOf,
+ str,
+ requiredStr,
+ record,
+ runValidator,
+ ValidatedType
+} from './validators';
+
+const recordModes = ['STOP_WHEN_FULL', 'RING_BUFFER', 'LONG_TRACE'] as const;
+export const recordConfigValidator = record({
+ mode: oneOf(recordModes, 'STOP_WHEN_FULL'),
+ durationMs: num(10000.0),
+ maxFileSizeMb: num(100),
+ fileWritePeriodMs: num(2500),
+ bufferSizeMb: num(64.0),
+
+ cpuSched: bool(),
+ cpuFreq: bool(),
+ cpuSyscall: bool(),
+
+ gpuFreq: bool(),
+ gpuMemTotal: bool(),
+
+ ftrace: bool(),
+ atrace: bool(),
+ ftraceEvents: arrayOf(str()),
+ ftraceExtraEvents: str(),
+ atraceCats: arrayOf(str()),
+ allAtraceApps: bool(true),
+ atraceApps: str(),
+ ftraceBufferSizeKb: num(2 * 1024),
+ ftraceDrainPeriodMs: num(250),
+ androidLogs: bool(),
+ androidLogBuffers: arrayOf(str()),
+ androidFrameTimeline: bool(),
+
+ cpuCoarse: bool(),
+ cpuCoarsePollMs: num(1000),
+
+ batteryDrain: bool(),
+ batteryDrainPollMs: num(1000),
+
+ boardSensors: bool(),
+
+ memHiFreq: bool(),
+ meminfo: bool(),
+ meminfoPeriodMs: num(1000),
+ meminfoCounters: arrayOf(str()),
+
+ vmstat: bool(),
+ vmstatPeriodMs: num(1000),
+ vmstatCounters: arrayOf(str()),
+
+ heapProfiling: bool(),
+ hpSamplingIntervalBytes: num(4096),
+ hpProcesses: str(),
+ hpContinuousDumpsPhase: num(),
+ hpContinuousDumpsInterval: num(),
+ hpSharedMemoryBuffer: num(8 * 1048576),
+ hpBlockClient: bool(true),
+ hpAllHeaps: bool(),
+
+ javaHeapDump: bool(),
+ jpProcesses: str(),
+ jpContinuousDumpsPhase: num(),
+ jpContinuousDumpsInterval: num(),
+
+ memLmk: bool(),
+ procStats: bool(),
+ procStatsPeriodMs: num(1000),
+
+ chromeCategoriesSelected: arrayOf(str()),
+ chromeHighOverheadCategoriesSelected: arrayOf(str()),
+
+ chromeLogs: bool(),
+ taskScheduling: bool(),
+ ipcFlows: bool(),
+ jsExecution: bool(),
+ webContentRendering: bool(),
+ uiRendering: bool(),
+ inputEvents: bool(),
+ navigationAndLoading: bool(),
+
+ symbolizeKsyms: bool(),
+});
+export const namedRecordConfigValidator = record(
+ {title: requiredStr, key: requiredStr, config: recordConfigValidator});
+export type NamedRecordConfig =
+ ValidatedType<typeof namedRecordConfigValidator>;
+export type RecordConfig = ValidatedType<typeof recordConfigValidator>;
+
+export function createEmptyRecordConfig(): RecordConfig {
+ return runValidator(recordConfigValidator, {}).result;
+}
diff --git a/ui/src/controller/record_controller.ts b/ui/src/controller/record_controller.ts
index a124ecfdf..f1631a86b 100644
--- a/ui/src/controller/record_controller.ts
+++ b/ui/src/controller/record_controller.ts
@@ -43,9 +43,11 @@ import {
isAndroidP,
isChromeTarget,
isCrOSTarget,
- RecordConfig,
+ isLinuxTarget,
+ isTargetOsAtLeast,
RecordingTarget
} from '../common/state';
+import {publishBufferUsage, publishTrackData} from '../frontend/publish';
import {AdbOverWebUsb} from './adb';
import {AdbConsumerPort} from './adb_shell_controller';
@@ -62,6 +64,7 @@ import {
} from './consumer_port_types';
import {Controller} from './controller';
import {App, globals} from './globals';
+import {RecordConfig} from './record_config_types';
import {Consumer, RpcConsumerPort} from './record_controller_interfaces';
type RPCImplMethod = (Method|rpc.ServiceMethod<Message<{}>, Message<{}>>);
@@ -114,6 +117,8 @@ export function genConfig(
const atraceApps = new Set<string>();
const chromeCategories = new Set<string>();
uiCfg.chromeCategoriesSelected.forEach(it => chromeCategories.add(it));
+ uiCfg.chromeHighOverheadCategoriesSelected.forEach(
+ it => chromeCategories.add(it));
let procThreadAssociationPolling = false;
let procThreadAssociationFtrace = false;
@@ -122,6 +127,10 @@ export function genConfig(
if (uiCfg.cpuSched) {
procThreadAssociationPolling = true;
procThreadAssociationFtrace = true;
+ uiCfg.ftrace = true;
+ if (isTargetOsAtLeast(target, 'S')) {
+ uiCfg.symbolizeKsyms = true;
+ }
ftraceEvents.add('sched/sched_switch');
ftraceEvents.add('power/suspend_resume');
ftraceEvents.add('sched/sched_wakeup');
@@ -156,25 +165,22 @@ export function genConfig(
ftraceEvents.add('raw_syscalls/sys_exit');
}
- if (procThreadAssociationFtrace) {
- ftraceEvents.add('sched/sched_process_exit');
- ftraceEvents.add('sched/sched_process_free');
- ftraceEvents.add('task/task_newtask');
- ftraceEvents.add('task/task_rename');
- }
-
if (uiCfg.batteryDrain) {
const ds = new TraceConfig.DataSource();
ds.config = new DataSourceConfig();
- ds.config.name = 'android.power';
- ds.config.androidPowerConfig = new AndroidPowerConfig();
- ds.config.androidPowerConfig.batteryPollMs = uiCfg.batteryDrainPollMs;
- ds.config.androidPowerConfig.batteryCounters = [
- AndroidPowerConfig.BatteryCounters.BATTERY_COUNTER_CAPACITY_PERCENT,
- AndroidPowerConfig.BatteryCounters.BATTERY_COUNTER_CHARGE,
- AndroidPowerConfig.BatteryCounters.BATTERY_COUNTER_CURRENT,
- ];
- ds.config.androidPowerConfig.collectPowerRails = true;
+ if (isCrOSTarget(target) || isLinuxTarget(target)) {
+ ds.config.name = 'linux.sysfs_power';
+ } else {
+ ds.config.name = 'android.power';
+ ds.config.androidPowerConfig = new AndroidPowerConfig();
+ ds.config.androidPowerConfig.batteryPollMs = uiCfg.batteryDrainPollMs;
+ ds.config.androidPowerConfig.batteryCounters = [
+ AndroidPowerConfig.BatteryCounters.BATTERY_COUNTER_CAPACITY_PERCENT,
+ AndroidPowerConfig.BatteryCounters.BATTERY_COUNTER_CHARGE,
+ AndroidPowerConfig.BatteryCounters.BATTERY_COUNTER_CURRENT,
+ ];
+ ds.config.androidPowerConfig.collectPowerRails = true;
+ }
if (!isChromeTarget(target) || isCrOSTarget(target)) {
protoCfg.dataSources.push(ds);
}
@@ -192,7 +198,7 @@ export function genConfig(
let sysStatsCfg: SysStatsConfig|undefined = undefined;
if (uiCfg.cpuCoarse) {
- if (sysStatsCfg === undefined) sysStatsCfg = new SysStatsConfig();
+ sysStatsCfg = new SysStatsConfig();
sysStatsCfg.statPeriodMs = uiCfg.cpuCoarsePollMs;
sysStatsCfg.statCounters = [
SysStatsConfig.StatCounters.STAT_CPU_TIMES,
@@ -211,6 +217,13 @@ export function genConfig(
ftraceEvents.add('kmem/ion_heap_shrink');
}
+ if (procThreadAssociationFtrace) {
+ ftraceEvents.add('sched/sched_process_exit');
+ ftraceEvents.add('sched/sched_process_free');
+ ftraceEvents.add('task/task_newtask');
+ ftraceEvents.add('task/task_rename');
+ }
+
if (uiCfg.meminfo) {
if (sysStatsCfg === undefined) sysStatsCfg = new SysStatsConfig();
sysStatsCfg.meminfoPeriodMs = uiCfg.meminfoPeriodMs;
@@ -393,7 +406,7 @@ export function genConfig(
}
if (chromeCategories.size !== 0) {
- let chromeRecordMode = '';
+ let chromeRecordMode;
if (uiCfg.mode === 'STOP_WHEN_FULL') {
chromeRecordMode = 'record-until-full';
} else {
@@ -430,10 +443,22 @@ export function genConfig(
metadataDs.config.chromeConfig = new ChromeConfig();
metadataDs.config.chromeConfig.traceConfig = traceConfigJson;
protoCfg.dataSources.push(metadataDs);
- }
- if (uiCfg.screenRecord) {
- atraceCats.add('gfx');
+ if (chromeCategories.has('disabled-by-default-memory-infra')) {
+ const memoryDs = new TraceConfig.DataSource();
+ memoryDs.config = new DataSourceConfig();
+ memoryDs.config.name = 'org.chromium.memory_instrumentation';
+ memoryDs.config.chromeConfig = new ChromeConfig();
+ memoryDs.config.chromeConfig.traceConfig = traceConfigJson;
+ protoCfg.dataSources.push(memoryDs);
+
+ const HeapProfDs = new TraceConfig.DataSource();
+ HeapProfDs.config = new DataSourceConfig();
+ HeapProfDs.config.name = 'org.chromium.native_heap_profiler';
+ HeapProfDs.config.chromeConfig = new ChromeConfig();
+ HeapProfDs.config.chromeConfig.traceConfig = traceConfigJson;
+ protoCfg.dataSources.push(HeapProfDs);
+ }
}
// Keep these last. The stages above can enrich them.
@@ -467,7 +492,8 @@ export function genConfig(
protoCfg.dataSources.push(ds);
}
- if (uiCfg.ftrace || uiCfg.atraceApps.length > 0 || ftraceEvents.size > 0 ||
+ // TODO(octaviant): move all this logic in a follow up CL.
+ if (uiCfg.ftrace || uiCfg.atrace || ftraceEvents.size > 0 ||
atraceCats.size > 0 || atraceApps.size > 0) {
const ds = new TraceConfig.DataSource();
ds.config = new DataSourceConfig();
@@ -478,12 +504,24 @@ export function genConfig(
if (uiCfg.ftrace) {
ds.config.ftraceConfig.bufferSizeKb = uiCfg.ftraceBufferSizeKb;
ds.config.ftraceConfig.drainPeriodMs = uiCfg.ftraceDrainPeriodMs;
+ if (uiCfg.symbolizeKsyms) {
+ ds.config.ftraceConfig.symbolizeKsyms = true;
+ ftraceEvents.add('sched/sched_blocked_reason');
+ }
for (const line of uiCfg.ftraceExtraEvents.split('\n')) {
if (line.trim().length > 0) ftraceEvents.add(line.trim());
}
}
- for (const line of uiCfg.atraceApps.split('\n')) {
- if (line.trim().length > 0) atraceApps.add(line.trim());
+
+ if (uiCfg.atrace) {
+ if (uiCfg.allAtraceApps) {
+ atraceApps.clear();
+ atraceApps.add('*');
+ } else {
+ for (const line of uiCfg.atraceApps.split('\n')) {
+ if (line.trim().length > 0) atraceApps.add(line.trim());
+ }
+ }
}
if (atraceCats.size > 0 || atraceApps.size > 0) {
@@ -584,13 +622,14 @@ export function toPbtxt(configBuffer: Uint8Array): string {
export class RecordController extends Controller<'main'> implements Consumer {
private app: App;
private config: RecordConfig|null = null;
- private extensionPort: MessagePort;
+ private readonly extensionPort: MessagePort;
private recordingInProgress = false;
private consumerPort: ConsumerPort;
private traceBuffer: Uint8Array[] = [];
private bufferUpdateInterval: ReturnType<typeof setTimeout>|undefined;
private adb = new AdbOverWebUsb();
private recordedTraceSuffix = TRACE_SUFFIX;
+ private fetchedCategories = false;
// We have a different controller for each targetOS. The correct one will be
// created when needed, and stored here. When the key is a string, it is the
@@ -608,11 +647,12 @@ export class RecordController extends Controller<'main'> implements Consumer {
run() {
// TODO(eseckler): Use ConsumerPort's QueryServiceState instead
// of posting a custom extension message to retrieve the category list.
- if (this.app.state.updateChromeCategories === true) {
+ if (this.app.state.fetchChromeCategories && !this.fetchedCategories) {
+ this.fetchedCategories = true;
if (this.app.state.extensionInstalled) {
this.extensionPort.postMessage({method: 'GetCategories'});
}
- globals.dispatch(Actions.setUpdateChromeCategories({update: false}));
+ globals.dispatch(Actions.setFetchChromeCategories({fetch: false}));
}
if (this.app.state.recordConfig === this.config &&
this.app.state.recordingInProgress === this.recordingInProgress) {
@@ -632,7 +672,7 @@ export class RecordController extends Controller<'main'> implements Consumer {
`;
const traceConfig = genConfig(this.config, this.app.state.recordingTarget);
// TODO(hjd): This should not be TrackData after we unify the stores.
- this.app.publish('TrackData', {
+ publishTrackData({
id: 'config',
data: {
commandline,
@@ -683,13 +723,16 @@ export class RecordController extends Controller<'main'> implements Consumer {
// TODO(nicomazz): handle this as intended by consumer_port.proto.
console.assert(data.slices.length === 1);
if (data.slices[0].data) this.traceBuffer.push(data.slices[0].data);
+ // The line underneath is 'misusing' the format ReadBuffersResponse.
+ // The boolean field 'lastSliceForPacket' is used as 'lastPacketInTrace'.
+ // See http://shortn/_53WB8A1aIr.
if (data.slices[0].lastSliceForPacket) this.onTraceComplete();
} else if (isEnableTracingResponse(data)) {
this.readBuffers();
} else if (isGetTraceStatsResponse(data)) {
const percentage = this.getBufferUsagePercentage(data);
if (percentage) {
- globals.publish('BufferUsage', {percentage});
+ publishBufferUsage({percentage});
}
} else if (isFreeBuffersResponse(data)) {
// No action required.
@@ -744,6 +787,7 @@ export class RecordController extends Controller<'main'> implements Consumer {
}
onError(message: string) {
+ // TODO(octaviant): b/204998302
console.error('Error in record controller: ', message);
globals.dispatch(
Actions.setLastRecordingError({error: message.substr(0, 150)}));
@@ -764,7 +808,7 @@ export class RecordController extends Controller<'main'> implements Consumer {
// protocol. Actually, there is no full consumer_port implementation, but
// only the support to start tracing and fetch the file.
async getTargetController(target: RecordingTarget): Promise<RpcConsumerPort> {
- const identifier = this.getTargetIdentifier(target);
+ const identifier = RecordController.getTargetIdentifier(target);
// The reason why caching the target 'record controller' Promise is that
// multiple rcp calls can happen while we are trying to understand if an
@@ -798,7 +842,7 @@ export class RecordController extends Controller<'main'> implements Consumer {
return controllerPromise;
}
- private getTargetIdentifier(target: RecordingTarget): string {
+ private static getTargetIdentifier(target: RecordingTarget): string {
return isAdbTarget(target) ? target.serial : target.os;
}
diff --git a/ui/src/controller/record_controller_interfaces.ts b/ui/src/controller/record_controller_interfaces.ts
index 2dd2c91c3..e9662fdfb 100644
--- a/ui/src/controller/record_controller_interfaces.ts
+++ b/ui/src/controller/record_controller_interfaces.ts
@@ -15,7 +15,6 @@
import {TRACE_SUFFIX} from '../common/constants';
import {ConsumerPortResponse} from './consumer_port_types';
-export type ConsumerPortCallback = (_: ConsumerPortResponse) => void;
export type ErrorCallback = (_: string) => void;
export type StatusCallback = (_: string) => void;
@@ -24,7 +23,7 @@ export abstract class RpcConsumerPort {
// This is done by the 3 "send" methods in this abstract class.
private consumerPortListener: Consumer;
- constructor(consumerPortListener: Consumer) {
+ protected constructor(consumerPortListener: Consumer) {
this.consumerPortListener = consumerPortListener;
}
diff --git a/ui/src/controller/record_controller_jsdomtest.ts b/ui/src/controller/record_controller_jsdomtest.ts
index 6d6e7801f..e1a3b80cd 100644
--- a/ui/src/controller/record_controller_jsdomtest.ts
+++ b/ui/src/controller/record_controller_jsdomtest.ts
@@ -12,21 +12,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {dingus} from 'dingusjs';
-
import {assertExists} from '../base/logging';
import {TraceConfig} from '../common/protos';
-import {createEmptyRecordConfig, RecordConfig} from '../common/state';
-import {App} from './globals';
-import {genConfigProto, RecordController, toPbtxt} from './record_controller';
+import {createEmptyRecordConfig} from './record_config_types';
+import {genConfigProto, toPbtxt} from './record_controller';
test('encodeConfig', () => {
const config = createEmptyRecordConfig();
- config.durationSeconds = 10;
+ config.durationMs = 20000;
const result =
TraceConfig.decode(genConfigProto(config, {os: 'Q', name: 'Android Q'}));
- expect(result.durationMs).toBe(10000);
+ expect(result.durationMs).toBe(20000);
});
test('SysConfig', () => {
@@ -42,6 +39,60 @@ test('SysConfig', () => {
expect(ftraceEvents.includes('raw_syscalls/sys_exit')).toBe(true);
});
+test('cpu scheduling includes kSyms if OS >= S', () => {
+ const config = createEmptyRecordConfig();
+ config.cpuSched = true;
+ const result =
+ TraceConfig.decode(genConfigProto(config, {os: 'S', name: 'Android S'}));
+ const sources = assertExists(result.dataSources);
+ const srcConfig = assertExists(sources[1].config);
+ const ftraceConfig = assertExists(srcConfig.ftraceConfig);
+ const ftraceEvents = assertExists(ftraceConfig.ftraceEvents);
+ expect(ftraceConfig.symbolizeKsyms).toBe(true);
+ expect(ftraceEvents.includes('sched/sched_blocked_reason')).toBe(true);
+});
+
+test('cpu scheduling does not include kSyms if OS <= S', () => {
+ const config = createEmptyRecordConfig();
+ config.cpuSched = true;
+ const result =
+ TraceConfig.decode(genConfigProto(config, {os: 'Q', name: 'Android Q'}));
+ const sources = assertExists(result.dataSources);
+ const srcConfig = assertExists(sources[1].config);
+ const ftraceConfig = assertExists(srcConfig.ftraceConfig);
+ const ftraceEvents = assertExists(ftraceConfig.ftraceEvents);
+ expect(ftraceConfig.symbolizeKsyms).toBe(false);
+ expect(ftraceEvents.includes('sched/sched_blocked_reason')).toBe(false);
+});
+
+test('kSyms can be enabled individually', () => {
+ const config = createEmptyRecordConfig();
+ config.ftrace = true;
+ config.symbolizeKsyms = true;
+ const result =
+ TraceConfig.decode(genConfigProto(config, {os: 'Q', name: 'Android Q'}));
+ const sources = assertExists(result.dataSources);
+ const srcConfig = assertExists(sources[0].config);
+ const ftraceConfig = assertExists(srcConfig.ftraceConfig);
+ const ftraceEvents = assertExists(ftraceConfig.ftraceEvents);
+ expect(ftraceConfig.symbolizeKsyms).toBe(true);
+ expect(ftraceEvents.includes('sched/sched_blocked_reason')).toBe(true);
+});
+
+test('kSyms can be disabled individually', () => {
+ const config = createEmptyRecordConfig();
+ config.ftrace = true;
+ config.symbolizeKsyms = false;
+ const result =
+ TraceConfig.decode(genConfigProto(config, {os: 'Q', name: 'Android Q'}));
+ const sources = assertExists(result.dataSources);
+ const srcConfig = assertExists(sources[0].config);
+ const ftraceConfig = assertExists(srcConfig.ftraceConfig);
+ const ftraceEvents = assertExists(ftraceConfig.ftraceEvents);
+ expect(ftraceConfig.symbolizeKsyms).toBe(false);
+ expect(ftraceEvents.includes('sched/sched_blocked_reason')).toBe(false);
+});
+
test('toPbtxt', () => {
const config = {
durationMs: 1000,
@@ -90,21 +141,6 @@ max_file_size_bytes: 43
`);
});
-test('RecordController', () => {
- const app = dingus<App>('globals');
- (app.state.recordConfig as RecordConfig) = createEmptyRecordConfig();
- const m: MessageChannel = dingus<MessageChannel>('extensionPort');
- const controller = new RecordController({app, extensionPort: m.port1});
- controller.run();
- controller.run();
- controller.run();
- // tslint:disable-next-line no-any
- const calls = app.calls.filter((call: any) => call[0] === 'publish()');
- expect(calls.length).toBe(1);
- // TODO(hjd): Fix up dingus to have a more sensible API.
- expect(calls[0][1][0]).toEqual('TrackData');
-});
-
test('ChromeConfig', () => {
const config = createEmptyRecordConfig();
config.ipcFlows = true;
@@ -134,7 +170,8 @@ test('ChromeConfig', () => {
test('ChromeMemoryConfig', () => {
const config = createEmptyRecordConfig();
- config.chromeCategoriesSelected = ['disabled-by-default-memory-infra'];
+ config.chromeHighOverheadCategoriesSelected =
+ ['disabled-by-default-memory-infra'];
const result =
TraceConfig.decode(genConfigProto(config, {os: 'C', name: 'Chrome'}));
const sources = assertExists(result.dataSources);
@@ -149,12 +186,25 @@ test('ChromeMemoryConfig', () => {
const chromeConfigM = assertExists(metadataConfigSource.chromeConfig);
const traceConfigM = assertExists(chromeConfigM.traceConfig);
- const expectedTraceConfig = '{"record_mode":"record-until-full",' +
- '"included_categories":["disabled-by-default-memory-infra"],' +
- '"memory_dump_config":{"triggers":' +
- '[{"mode":"detailed","periodic_interval_ms":10000}]}}';
+ const miConfigSource = assertExists(sources[2].config);
+ expect(miConfigSource.name).toBe('org.chromium.memory_instrumentation');
+ const chromeConfigI = assertExists(miConfigSource.chromeConfig);
+ const traceConfigI = assertExists(chromeConfigI.traceConfig);
+
+ const hpConfigSource = assertExists(sources[3].config);
+ expect(hpConfigSource.name).toBe('org.chromium.native_heap_profiler');
+ const chromeConfigH = assertExists(hpConfigSource.chromeConfig);
+ const traceConfigH = assertExists(chromeConfigH.traceConfig);
+
+ const expectedTraceConfig = '{\"record_mode\":\"record-until-full\",' +
+ '\"included_categories\":[\"disabled-by-default-memory-infra\"],' +
+ '\"memory_dump_config\":{\"allowed_dump_modes\":[\"background\",' +
+ '\"light\",\"detailed\"],\"triggers\":[{\"min_time_between_dumps_ms\":' +
+ '10000,\"mode\":\"detailed\",\"type\":\"periodic_interval\"}]}}';
expect(traceConfigM).toEqual(expectedTraceConfig);
expect(traceConfig).toEqual(expectedTraceConfig);
+ expect(traceConfigI).toEqual(expectedTraceConfig);
+ expect(traceConfigH).toEqual(expectedTraceConfig);
});
test('ChromeConfigRingBuffer', () => {
@@ -184,7 +234,6 @@ test('ChromeConfigRingBuffer', () => {
expect(traceConfig).toEqual(expectedTraceConfig);
});
-
test('ChromeConfigLongTrace', () => {
const config = createEmptyRecordConfig();
config.ipcFlows = true;
diff --git a/ui/src/controller/search_controller.ts b/ui/src/controller/search_controller.ts
index 06f2d7a29..6bf532690 100644
--- a/ui/src/controller/search_controller.ts
+++ b/ui/src/controller/search_controller.ts
@@ -14,9 +14,10 @@
import {TRACE_MARGIN_TIME_S} from '../common/constants';
import {Engine} from '../common/engine';
-import {slowlyCountRows} from '../common/query_iterator';
+import {NUM, STR} from '../common/query_result';
import {CurrentSearchResults, SearchSummary} from '../common/search_data';
import {TimeSpan} from '../common/time';
+import {publishSearch, publishSearchResult} from '../frontend/publish';
import {Controller} from './controller';
import {App} from './globals';
@@ -92,12 +93,12 @@ export class SearchController extends Controller<'main'> {
this.previousResolution = newResolution;
this.previousSearch = newSearch;
if (newSearch === '' || newSearch.length < 4) {
- this.app.publish('Search', {
+ publishSearch({
tsStarts: new Float64Array(0),
tsEnds: new Float64Array(0),
count: new Uint8Array(0),
});
- this.app.publish('SearchResult', {
+ publishSearchResult({
sliceIds: new Float64Array(0),
tsStarts: new Float64Array(0),
utids: new Float64Array(0),
@@ -125,12 +126,12 @@ export class SearchController extends Controller<'main'> {
this.updateInProgress = true;
const computeSummary =
this.update(newSearch, startNs, endNs, newResolution).then(summary => {
- this.app.publish('Search', summary);
+ publishSearch(summary);
});
const computeResults =
this.specificSearch(newSearch).then(searchResults => {
- this.app.publish('SearchResult', searchResults);
+ publishSearchResult(searchResults);
});
Promise.all([computeSummary, computeResults])
@@ -151,22 +152,26 @@ export class SearchController extends Controller<'main'> {
startNs = Math.floor(startNs / quantumNs) * quantumNs;
+ const windowDur = Math.max(endNs - startNs, 1);
await this.query(`update search_summary_window set
window_start=${startNs},
- window_dur=${endNs - startNs},
+ window_dur=${windowDur},
quantum=${quantumNs}
where rowid = 0;`);
- const rawUtidResult = await this.query(`select utid from thread join process
+ const utidRes = await this.query(`select utid from thread join process
using(upid) where thread.name like ${searchLiteral}
or process.name like ${searchLiteral}`);
- const utids = [...rawUtidResult.columns[0].longValues!];
+ const utids = [];
+ for (const it = utidRes.iter({utid: NUM}); it.valid(); it.next()) {
+ utids.push(it.utid);
+ }
const cpus = await this.engine.getCpus();
const maxCpu = Math.max(...cpus, -1);
- const rawResult = await this.query(`
+ const res = await this.query(`
select
(quantum_ts * ${quantumNs} + ${startNs})/1e9 as tsStart,
((quantum_ts+1) * ${quantumNs} + ${startNs})/1e9 as tsEnd,
@@ -185,18 +190,18 @@ export class SearchController extends Controller<'main'> {
group by quantum_ts
order by quantum_ts;`);
- const numRows = slowlyCountRows(rawResult);
+ const numRows = res.numRows();
const summary = {
tsStarts: new Float64Array(numRows),
tsEnds: new Float64Array(numRows),
count: new Uint8Array(numRows)
};
- const columns = rawResult.columns;
- for (let row = 0; row < numRows; row++) {
- summary.tsStarts[row] = +columns[0].doubleValues![row];
- summary.tsEnds[row] = +columns[1].doubleValues![row];
- summary.count[row] = +columns[2].longValues![row];
+ const it = res.iter({tsStart: NUM, tsEnd: NUM, count: NUM});
+ for (let row = 0; it.valid(); it.next(), ++row) {
+ summary.tsStarts[row] = it.tsStart;
+ summary.tsEnds[row] = it.tsEnd;
+ summary.count[row] = it.count;
}
return summary;
}
@@ -212,13 +217,12 @@ export class SearchController extends Controller<'main'> {
cpuToTrackId.set((track.config as {cpu: number}).cpu, track.id);
continue;
}
- if (track.kind === 'ChromeSliceTrack') {
- const config = (track.config as {trackId: number});
+ const config = track.config || {};
+ if (config.trackId !== undefined) {
engineTrackIdToTrackId.set(config.trackId, track.id);
continue;
}
- if (track.kind === 'AsyncSliceTrack') {
- const config = (track.config as {trackIds: number[]});
+ if (config.trackIds !== undefined) {
for (const trackId of config.trackIds) {
engineTrackIdToTrackId.set(trackId, track.id);
}
@@ -226,78 +230,80 @@ export class SearchController extends Controller<'main'> {
}
}
- const rawUtidResult = await this.query(`select utid from thread join process
+ const utidRes = await this.query(`select utid from thread join process
using(upid) where
thread.name like ${searchLiteral} or
process.name like ${searchLiteral}`);
- const utids = [...rawUtidResult.columns[0].longValues!];
+ const utids = [];
+ for (const it = utidRes.iter({utid: NUM}); it.valid(); it.next()) {
+ utids.push(it.utid);
+ }
- const rawResult = await this.query(`
+ const queryRes = await this.query(`
select
- id as slice_id,
+ id as sliceId,
ts,
'cpu' as source,
- cpu as source_id,
+ cpu as sourceId,
utid
from sched where utid in (${utids.join(',')})
union
select
- slice_id,
+ slice_id as sliceId,
ts,
'track' as source,
- track_id as source_id,
+ track_id as sourceId,
0 as utid
from slice
where slice.name like ${searchLiteral}
+ ${isNaN(Number(search)) ? '' : `or sliceId = ${search}`}
union
select
- slice_id,
+ slice_id as sliceId,
ts,
'track' as source,
- track_id as source_id,
+ track_id as sourceId,
0 as utid
from slice
join args using(arg_set_id)
where string_value like ${searchLiteral}
order by ts`);
- const numRows = slowlyCountRows(rawResult);
-
+ const rows = queryRes.numRows();
const searchResults: CurrentSearchResults = {
- sliceIds: [],
- tsStarts: [],
- utids: [],
+ sliceIds: new Float64Array(rows),
+ tsStarts: new Float64Array(rows),
+ utids: new Float64Array(rows),
trackIds: [],
sources: [],
- totalResults: +numRows,
+ totalResults: 0,
};
- const columns = rawResult.columns;
- for (let row = 0; row < numRows; row++) {
- const source = columns[2].stringValues![row];
- const sourceId = +columns[3].longValues![row];
+ const it = queryRes.iter(
+ {sliceId: NUM, ts: NUM, source: STR, sourceId: NUM, utid: NUM});
+ for (; it.valid(); it.next()) {
let trackId = undefined;
- if (source === 'cpu') {
- trackId = cpuToTrackId.get(sourceId);
- } else if (source === 'track') {
- trackId = engineTrackIdToTrackId.get(sourceId);
+ if (it.source === 'cpu') {
+ trackId = cpuToTrackId.get(it.sourceId);
+ } else if (it.source === 'track') {
+ trackId = engineTrackIdToTrackId.get(it.sourceId);
}
+ // The .get() calls above could return undefined, this isn't just an else.
if (trackId === undefined) {
- searchResults.totalResults--;
continue;
}
+ const i = searchResults.totalResults++;
searchResults.trackIds.push(trackId);
- searchResults.sources.push(source);
- searchResults.sliceIds.push(+columns[0].longValues![row]);
- searchResults.tsStarts.push(+columns[1].longValues![row]);
- searchResults.utids.push(+columns[4].longValues![row]);
+ searchResults.sources.push(it.source);
+ searchResults.sliceIds[i] = it.sliceId;
+ searchResults.tsStarts[i] = it.ts;
+ searchResults.utids[i] = it.utid;
}
return searchResults;
}
-
private async query(query: string) {
const result = await this.engine.query(query);
return result;
diff --git a/ui/src/controller/selection_controller.ts b/ui/src/controller/selection_controller.ts
index 0366df1a6..a940716d3 100644
--- a/ui/src/controller/selection_controller.ts
+++ b/ui/src/controller/selection_controller.ts
@@ -12,23 +12,24 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import {assertTrue} from '../base/logging';
import {Arg, Args} from '../common/arg_types';
import {Engine} from '../common/engine';
import {
NUM,
- singleRow,
- singleRowUntyped,
- slowlyCountRows,
- STR
-} from '../common/query_iterator';
+ NUM_NULL,
+ STR,
+ STR_NULL,
+} from '../common/query_result';
import {ChromeSliceSelection} from '../common/state';
import {translateState} from '../common/thread_state';
import {fromNs, toNs} from '../common/time';
+import {SliceDetails, ThreadStateDetails} from '../frontend/globals';
import {
- CounterDetails,
- SliceDetails,
- ThreadStateDetails
-} from '../frontend/globals';
+ publishCounterDetails,
+ publishSliceDetails,
+ publishThreadStateDetails
+} from '../frontend/publish';
import {SLICE_TRACK_KIND} from '../tracks/chrome_slices/common';
import {parseArgs} from './args_parser';
@@ -39,6 +40,19 @@ export interface SelectionControllerArgs {
engine: Engine;
}
+interface ThreadDetails {
+ tid: number;
+ threadName?: string;
+}
+
+interface ProcessDetails {
+ pid?: number;
+ processName?: string;
+ uid?: number;
+ packageName?: string;
+ versionCode?: number;
+}
+
// This class queries the TP for the details on a specific slice that has
// been clicked.
export class SelectionController extends Controller<'main'> {
@@ -68,14 +82,12 @@ export class SelectionController extends Controller<'main'> {
if (selectedId === undefined) return;
if (selection.kind === 'COUNTER') {
- const selected: CounterDetails = {};
this.counterDetails(selection.leftTs, selection.rightTs, selection.id)
.then(results => {
if (results !== undefined && selection &&
selection.kind === selectedKind &&
selection.id === selectedId) {
- Object.assign(selected, results);
- globals.publish('CounterDetails', selected);
+ publishCounterDetails(results);
}
});
} else if (selection.kind === 'SLICE') {
@@ -101,23 +113,23 @@ export class SelectionController extends Controller<'main'> {
promisedDescription = Promise.resolve(new Map());
promisedArgs = Promise.resolve(new Map());
} else {
- const typeResult = singleRow(
- {
- leafTable: STR,
- argSetId: NUM,
- },
- await this.args.engine.query(`
+ const result = await this.args.engine.query(`
SELECT
type as leafTable,
arg_set_id as argSetId
- FROM slice WHERE id = ${selectedId}`));
+ FROM slice WHERE id = ${selectedId}`);
- if (typeResult === undefined) {
+ if (result.numRows() === 0) {
return;
}
- leafTable = typeResult.leafTable;
- const argSetId = typeResult.argSetId;
+ const row = result.firstRow({
+ leafTable: STR,
+ argSetId: NUM,
+ });
+
+ leafTable = row.leafTable;
+ const argSetId = row.argSetId;
promisedDescription = this.describeSlice(selectedId);
promisedArgs = this.getArgs(argSetId);
}
@@ -129,10 +141,9 @@ export class SelectionController extends Controller<'main'> {
const [details, args, description] =
await Promise.all([promisedDetails, promisedArgs, promisedDescription]);
- const row = singleRowUntyped(details);
- if (row === undefined) {
- return;
- }
+ if (details.numRows() <= 0) return;
+ const rowIter = details.iter({});
+ assertTrue(rowIter.valid());
// A few columns are hard coded as part of the SliceDetails interface.
// Long term these should be handled generically as args but for now
@@ -141,24 +152,39 @@ export class SelectionController extends Controller<'main'> {
let dur = undefined;
let name = undefined;
let category = undefined;
+ // tslint:disable-next-line:variable-name
+ let thread_dur = undefined;
+ // tslint:disable-next-line:variable-name
+ let thread_ts = undefined;
+ let trackId = undefined;
- for (const [k, v] of Object.entries(row)) {
+ for (const k of details.columns()) {
+ const v = rowIter.get(k);
switch (k) {
case 'id':
break;
case 'ts':
ts = fromNs(Number(v)) - globals.state.traceTime.startSec;
break;
+ case 'thread_ts':
+ thread_ts = fromNs(Number(v));
+ break;
case 'name':
name = `${v}`;
break;
case 'dur':
dur = fromNs(Number(v));
break;
+ case 'thread_dur':
+ thread_dur = fromNs(Number(v));
+ break;
case 'category':
case 'cat':
category = `${v}`;
break;
+ case 'track_id':
+ trackId = Number(v);
+ break;
default:
args.set(k, `${v}`);
}
@@ -168,17 +194,57 @@ export class SelectionController extends Controller<'main'> {
const selected: SliceDetails = {
id: selectedId,
ts,
+ thread_ts,
dur,
+ thread_dur,
name,
category,
args,
argsTree,
- description,
+ description
};
+ if (trackId !== undefined) {
+ const columnInfo = (await this.args.engine.query(`
+ WITH
+ leafTrackTable AS (SELECT type FROM track WHERE id = ${trackId}),
+ cols AS (
+ SELECT name
+ FROM pragma_table_info((SELECT type FROM leafTrackTable))
+ )
+ SELECT
+ type as leafTrackTable,
+ 'upid' in cols AS hasUpid,
+ 'utid' in cols AS hasUtid
+ FROM leafTrackTable
+ `)).firstRow({hasUpid: NUM, hasUtid: NUM, leafTrackTable: STR});
+ const hasUpid = columnInfo.hasUpid !== 0;
+ const hasUtid = columnInfo.hasUtid !== 0;
+
+ if (hasUtid) {
+ const utid = (await this.args.engine.query(`
+ SELECT utid
+ FROM ${columnInfo.leafTrackTable}
+ WHERE id = ${trackId};
+ `)).firstRow({
+ utid: NUM
+ }).utid;
+ Object.assign(selected, await this.computeThreadDetails(utid));
+ } else if (hasUpid) {
+ const upid = (await this.args.engine.query(`
+ SELECT upid
+ FROM ${columnInfo.leafTrackTable}
+ WHERE id = ${trackId};
+ `)).firstRow({
+ upid: NUM
+ }).upid;
+ Object.assign(selected, await this.computeProcessDetails(upid));
+ }
+ }
+
// Check selection is still the same on completion of query.
if (selection === globals.state.currentSelection) {
- globals.publish('SliceDetails', selected);
+ publishSliceDetails(selected);
}
}
@@ -186,14 +252,17 @@ export class SelectionController extends Controller<'main'> {
const map = new Map<string, string>();
if (id === -1) return map;
const query = `
- select description, doc_link
+ select
+ ifnull(description, '') as description,
+ ifnull(doc_link, '') as docLink
from describe_slice
where slice_id = ${id}
`;
const result = await this.args.engine.query(query);
- for (let i = 0; i < slowlyCountRows(result); i++) {
- const description = result.columns[0].stringValues![i];
- const docLink = result.columns[1].stringValues![i];
+ const it = result.iter({description: STR, docLink: STR});
+ for (; it.valid(); it.next()) {
+ const description = it.description;
+ const docLink = it.docLink;
map.set('Description', description);
map.set('Documentation', docLink);
}
@@ -205,14 +274,18 @@ export class SelectionController extends Controller<'main'> {
const query = `
select
key AS name,
- CAST(COALESCE(int_value, string_value, real_value) AS text) AS value
+ display_value AS value
FROM args
WHERE arg_set_id = ${argId}
`;
const result = await this.args.engine.query(query);
- for (let i = 0; i < slowlyCountRows(result); i++) {
- const name = result.columns[0].stringValues![i];
- const value = result.columns[1].stringValues![i];
+ const it = result.iter({
+ name: STR,
+ value: STR_NULL,
+ });
+ for (; it.valid(); it.next()) {
+ const name = it.name;
+ const value = it.value || 'NULL';
if (name === 'destination slice id' && !isNaN(Number(value))) {
const destTrackId = await this.getDestTrackId(value);
args.set(
@@ -226,10 +299,10 @@ export class SelectionController extends Controller<'main'> {
}
async getDestTrackId(sliceId: string): Promise<string> {
- const trackIdQuery = `select track_id from slice
+ const trackIdQuery = `select track_id as trackId from slice
where slice_id = ${sliceId}`;
- const destResult = await this.args.engine.query(trackIdQuery);
- const trackIdTp = destResult.columns[0].longValues![0];
+ const result = await this.args.engine.query(trackIdQuery);
+ const trackIdTp = result.firstRow({trackId: NUM}).trackId;
// TODO(hjd): If we had a consistent mapping from TP track_id
// UI track id for slice tracks this would be unnecessary.
let trackId = '';
@@ -247,101 +320,124 @@ export class SelectionController extends Controller<'main'> {
const query = `
SELECT
ts,
- thread_state.dur,
+ thread_state.dur as dur,
state,
- io_wait,
- thread_state.utid,
- thread_state.cpu,
- sched.id,
- thread_state.blocked_function
+ io_wait as ioWait,
+ thread_state.utid as utid,
+ thread_state.cpu as cpu,
+ sched.id as id,
+ thread_state.blocked_function as blockedFunction
from thread_state
left join sched using(ts) where thread_state.id = ${id}
`;
- this.args.engine.query(query).then(result => {
- const selection = globals.state.currentSelection;
- const cols = result.columns;
- if (slowlyCountRows(result) === 1 && selection) {
- const ts = cols[0].longValues![0];
- const timeFromStart = fromNs(ts) - globals.state.traceTime.startSec;
- const dur = fromNs(cols[1].longValues![0]);
- const stateStr = cols[2].stringValues![0];
- const ioWait =
- cols[3].isNulls![0] ? undefined : !!cols[3].longValues![0];
- const state = translateState(stateStr, ioWait);
- const utid = cols[4].longValues![0];
- const cpu = cols[5].isNulls![0] ? undefined : cols[5].longValues![0];
- const sliceId =
- cols[6].isNulls![0] ? undefined : cols[6].longValues![0];
- const blockedFunction =
- cols[7].isNulls![0] ? undefined : cols[7].stringValues![0];
- const selected: ThreadStateDetails = {
- ts: timeFromStart,
- dur,
- state,
- utid,
- cpu,
- sliceId,
- blockedFunction
- };
- globals.publish('ThreadStateDetails', selected);
- }
- });
+ const result = await this.args.engine.query(query);
+
+ const selection = globals.state.currentSelection;
+ if (result.numRows() > 0 && selection) {
+ const row = result.firstRow({
+ ts: NUM,
+ dur: NUM,
+ state: STR_NULL,
+ ioWait: NUM_NULL,
+ utid: NUM,
+ cpu: NUM_NULL,
+ id: NUM_NULL,
+ blockedFunction: STR_NULL,
+ });
+ const ts = row.ts;
+ const timeFromStart = fromNs(ts) - globals.state.traceTime.startSec;
+ const dur = fromNs(row.dur);
+ const ioWait = row.ioWait === null ? undefined : row.ioWait > 0;
+ const state = translateState(row.state || undefined, ioWait);
+ const utid = row.utid;
+ const cpu = row.cpu === null ? undefined : row.cpu;
+ const sliceId = row.id === null ? undefined : row.id;
+ const blockedFunction =
+ row.blockedFunction === null ? undefined : row.blockedFunction;
+ const selected: ThreadStateDetails =
+ {ts: timeFromStart, dur, state, utid, cpu, sliceId, blockedFunction};
+ publishThreadStateDetails(selected);
+ }
}
async sliceDetails(id: number) {
- const sqlQuery = `SELECT ts, dur, priority, end_state, utid, cpu,
- thread_state.id FROM sched join thread_state using(ts, utid, dur, cpu)
+ const sqlQuery = `SELECT
+ ts,
+ dur,
+ priority,
+ end_state as endState,
+ utid,
+ cpu,
+ thread_state.id as threadStateId
+ FROM sched join thread_state using(ts, utid, dur, cpu)
WHERE sched.id = ${id}`;
- this.args.engine.query(sqlQuery).then(result => {
- // Check selection is still the same on completion of query.
- const selection = globals.state.currentSelection;
- if (slowlyCountRows(result) === 1 && selection) {
- const ts = result.columns[0].longValues![0];
- const timeFromStart = fromNs(ts) - globals.state.traceTime.startSec;
- const dur = fromNs(result.columns[1].longValues![0]);
- const priority = result.columns[2].longValues![0];
- const endState = result.columns[3].stringValues![0];
- const utid = result.columns[4].longValues![0];
- const cpu = result.columns[5].longValues![0];
- const threadStateId = result.columns[6].longValues![0];
- const selected: SliceDetails = {
- ts: timeFromStart,
- dur,
- priority,
- endState,
- cpu,
- id,
- utid,
- threadStateId
- };
- this.schedulingDetails(ts, utid)
- .then(wakeResult => {
- Object.assign(selected, wakeResult);
- })
- .finally(() => {
- globals.publish('SliceDetails', selected);
- });
- }
- });
+ const result = await this.args.engine.query(sqlQuery);
+ // Check selection is still the same on completion of query.
+ const selection = globals.state.currentSelection;
+ if (result.numRows() > 0 && selection) {
+ const row = result.firstRow({
+ ts: NUM,
+ dur: NUM,
+ priority: NUM,
+ endState: STR,
+ utid: NUM,
+ cpu: NUM,
+ threadStateId: NUM,
+ });
+ const ts = row.ts;
+ const timeFromStart = fromNs(ts) - globals.state.traceTime.startSec;
+ const dur = fromNs(row.dur);
+ const priority = row.priority;
+ const endState = row.endState;
+ const utid = row.utid;
+ const cpu = row.cpu;
+ const threadStateId = row.threadStateId;
+ const selected: SliceDetails = {
+ ts: timeFromStart,
+ dur,
+ priority,
+ endState,
+ cpu,
+ id,
+ utid,
+ threadStateId
+ };
+ Object.assign(selected, await this.computeThreadDetails(utid));
+
+ this.schedulingDetails(ts, utid)
+ .then(wakeResult => {
+ Object.assign(selected, wakeResult);
+ })
+ .finally(() => {
+ publishSliceDetails(selected);
+ });
+ }
}
async counterDetails(ts: number, rightTs: number, id: number) {
const counter = await this.args.engine.query(
- `SELECT value, track_id FROM counter WHERE id = ${id}`);
- const value = counter.columns[0].doubleValues![0];
- const trackId = counter.columns[1].longValues![0];
+ `SELECT value, track_id as trackId FROM counter WHERE id = ${id}`);
+ const row = counter.iter({
+ value: NUM,
+ trackId: NUM,
+ });
+ const value = row.value;
+ const trackId = row.trackId;
// Finding previous value. If there isn't previous one, it will return 0 for
// ts and value.
- const previous = await this.args.engine.query(
- `SELECT MAX(ts), value FROM counter WHERE ts < ${ts} and track_id = ${
- trackId}`);
- const previousValue = previous.columns[1].doubleValues![0];
+ const previous = await this.args.engine.query(`SELECT
+ MAX(ts),
+ IFNULL(value, 0) as value
+ FROM counter WHERE ts < ${ts} and track_id = ${trackId}`);
+ const previousValue = previous.firstRow({value: NUM}).value;
const endTs =
rightTs !== -1 ? rightTs : toNs(globals.state.traceTime.endSec);
const delta = value - previousValue;
const duration = endTs - ts;
const startTime = fromNs(ts) - globals.state.traceTime.startSec;
- return {startTime, value, delta, duration};
+ const uiTrackId = globals.state.uiTrackIdByTraceTrackId[trackId];
+ const name = uiTrackId ? globals.state.tracks[uiTrackId].name : undefined;
+ return {startTime, value, delta, duration, name};
}
async schedulingDetails(ts: number, utid: number|Long) {
@@ -350,8 +446,8 @@ export class SelectionController extends Controller<'main'> {
`select * from instants where name = 'sched_waking' limit 1`);
const wakeup = await this.args.engine.query(
`select * from instants where name = 'sched_wakeup' limit 1`);
- if (slowlyCountRows(waking) === 0) {
- if (slowlyCountRows(wakeup) === 0) return undefined;
+ if (waking.numRows() === 0) {
+ if (wakeup.numRows() === 0) return undefined;
// Only use sched_wakeup if waking is not in the trace.
event = 'sched_wakeup';
}
@@ -359,32 +455,94 @@ export class SelectionController extends Controller<'main'> {
// Find the ts of the first sched_wakeup before the current slice.
const queryWakeupTs = `select ts from instants where name = '${event}'
and ref = ${utid} and ts < ${ts} order by ts desc limit 1`;
- const wakeupRow = await this.args.engine.queryOneRow(queryWakeupTs);
+ const wakeResult = await this.args.engine.query(queryWakeupTs);
+ if (wakeResult.numRows() === 0) {
+ return undefined;
+ }
+ const wakeupTs = wakeResult.firstRow({ts: NUM}).ts;
+
// Find the previous sched slice for the current utid.
const queryPrevSched = `select ts from sched where utid = ${utid}
and ts < ${ts} order by ts desc limit 1`;
- const prevSchedRow = await this.args.engine.queryOneRow(queryPrevSched);
+ const prevSchedResult = await this.args.engine.query(queryPrevSched);
+
// If this is the first sched slice for this utid or if the wakeup found
// was after the previous slice then we know the wakeup was for this slice.
- if (wakeupRow[0] === undefined ||
- (prevSchedRow[0] !== undefined && wakeupRow[0] < prevSchedRow[0])) {
+ if (prevSchedResult.numRows() === 0 ||
+ wakeupTs < prevSchedResult.firstRow({ts: NUM}).ts) {
return undefined;
}
- const wakeupTs = wakeupRow[0];
// Find the sched slice with the utid of the waker running when the
// sched wakeup occurred. This is the waker.
- const queryWaker = `select utid, cpu from sched where utid =
- (select utid from raw where name = '${event}' and ts = ${wakeupTs})
+ let queryWaker = `select utid, cpu from sched where utid =
+ (select EXTRACT_ARG(arg_set_id, 'waker_utid') from instants where name =
+ '${event}' and ts = ${wakeupTs})
and ts < ${wakeupTs} and ts + dur >= ${wakeupTs};`;
- const wakerRow = await this.args.engine.queryOneRow(queryWaker);
- if (wakerRow) {
- return {
- wakeupTs: fromNs(wakeupTs),
- wakerUtid: wakerRow[0],
- wakerCpu: wakerRow[1]
- };
- } else {
+ let wakerResult = await this.args.engine.query(queryWaker);
+ if (wakerResult.numRows() === 0) {
+ // An old version of trace processor (that does not populate the
+ // 'waker_utid' arg) might be in use. Try getting the same info from the
+ // raw table).
+ // TODO(b/206390308): Remove this workaround when
+ // TRACE_PROCESSOR_CURRENT_API_VERSION is incremented.
+ queryWaker = `select utid, cpu from sched where utid =
+ (select utid from raw where name = '${event}' and ts = ${wakeupTs})
+ and ts < ${wakeupTs} and ts + dur >= ${wakeupTs};`;
+ wakerResult = await this.args.engine.query(queryWaker);
+ }
+ if (wakerResult.numRows() === 0) {
return undefined;
}
+ const wakerRow = wakerResult.firstRow({utid: NUM, cpu: NUM});
+ return {
+ wakeupTs: fromNs(wakeupTs),
+ wakerUtid: wakerRow.utid,
+ wakerCpu: wakerRow.cpu
+ };
+ }
+
+ async computeThreadDetails(utid: number):
+ Promise<ThreadDetails&ProcessDetails> {
+ const threadInfo = (await this.args.engine.query(`
+ SELECT tid, name, upid
+ FROM thread
+ WHERE utid = ${utid};
+ `)).firstRow({tid: NUM, name: STR_NULL, upid: NUM_NULL});
+ const threadDetails = {
+ tid: threadInfo.tid,
+ threadName: threadInfo.name || undefined
+ };
+ if (threadInfo.upid) {
+ return Object.assign(
+ {}, threadDetails, await this.computeProcessDetails(threadInfo.upid));
+ }
+ return threadDetails;
+ }
+
+ async computeProcessDetails(upid: number): Promise<ProcessDetails> {
+ const details: ProcessDetails = {};
+ const processResult = (await this.args.engine.query(`
+ SELECT pid, name, uid FROM process WHERE upid = ${upid};
+ `)).firstRow({pid: NUM, name: STR_NULL, uid: NUM_NULL});
+ details.pid = processResult.pid;
+ details.processName = processResult.name || undefined;
+ if (processResult.uid === null) {
+ return details;
+ }
+ details.uid = processResult.uid;
+
+ const packageResult = (await this.args.engine.query(`
+ SELECT package_name, version_code
+ FROM package_list WHERE uid = ${details.uid};
+ `));
+ // The package_list table is not populated in some traces so we need to
+ // check if the result has returned any rows.
+ if (packageResult.numRows() > 0) {
+ const packageDetails =
+ packageResult.firstRow({package_name: STR, version_code: NUM});
+ details.packageName = packageDetails.package_name;
+ details.versionCode = packageDetails.version_code;
+ }
+ return details;
}
}
diff --git a/ui/src/controller/trace_controller.ts b/ui/src/controller/trace_controller.ts
index 65558b2b0..fb4002195 100644
--- a/ui/src/controller/trace_controller.ts
+++ b/ui/src/controller/trace_controller.ts
@@ -12,26 +12,32 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import '../tracks/all_controller';
-
-import {assertExists, assertTrue} from '../base/logging';
+import { assertExists, assertTrue } from '../base/logging';
import {
Actions,
DeferredAction,
} from '../common/actions';
-import {TRACE_MARGIN_TIME_S} from '../common/constants';
-import {Engine, QueryError} from '../common/engine';
-import {HttpRpcEngine} from '../common/http_rpc_engine';
-import {slowlyCountRows} from '../common/query_iterator';
-import {EngineMode} from '../common/state';
-import {toNs, toNsCeil, toNsFloor} from '../common/time';
-import {TimeSpan} from '../common/time';
+import { cacheTrace } from '../common/cache_manager';
+import { TRACE_MARGIN_TIME_S } from '../common/constants';
+import { Engine } from '../common/engine';
+import { featureFlags, Flag, PERF_SAMPLE_FLAG } from '../common/feature_flags';
+import { HttpRpcEngine } from '../common/http_rpc_engine';
+import { NUM, NUM_NULL, QueryError, STR, STR_NULL } from '../common/query_result';
+import { EngineMode } from '../common/state';
+import { TimeSpan, toNs, toNsCeil, toNsFloor } from '../common/time';
+import { resetEngineWorker, WasmEngineProxy } from '../common/wasm_engine_proxy';
+import {
+ globals as frontendGlobals,
+ QuantizedLoad,
+ ThreadDesc
+} from '../frontend/globals';
import {
- createWasmEngine,
- destroyWasmEngine,
- WasmEngineProxy
-} from '../common/wasm_engine_proxy';
-import {QuantizedLoad, ThreadDesc} from '../frontend/globals';
+ publishHasFtrace,
+ publishMetricError,
+ publishOverviewData,
+ publishThreads
+} from '../frontend/publish';
+import { Router } from '../frontend/router';
import {
CounterAggregationController
@@ -43,28 +49,36 @@ import {
CpuByProcessAggregationController
} from './aggregation/cpu_by_process_aggregation_controller';
import {
+ FrameAggregationController
+} from './aggregation/frame_aggregation_controller';
+import {
SliceAggregationController
} from './aggregation/slice_aggregation_controller';
import {
ThreadAggregationController
} from './aggregation/thread_aggregation_controller';
-import {Child, Children, Controller} from './controller';
+import { Child, Children, Controller } from './controller';
import {
CpuProfileController,
CpuProfileControllerArgs
} from './cpu_profile_controller';
import {
+ FlamegraphController,
+ FlamegraphControllerArgs
+} from './flamegraph_controller';
+import {
FlowEventsController,
FlowEventsControllerArgs
} from './flow_events_controller';
-import {globals} from './globals';
+import { globals } from './globals';
+import { LoadingManager } from './loading_manager';
+import { LogsController } from './logs_controller';
+import { MetricsController } from './metrics_controller';
import {
- HeapProfileController,
- HeapProfileControllerArgs
-} from './heap_profile_controller';
-import {LoadingManager} from './loading_manager';
-import {LogsController} from './logs_controller';
-import {MetricsController} from './metrics_controller';
+ PivotTableController,
+ PivotTableControllerArgs
+} from './pivot_table_controller';
+import {PivotTableReduxController} from './pivot_table_redux_controller';
import {QueryController, QueryControllerArgs} from './query_controller';
import {SearchController} from './search_controller';
import {
@@ -80,10 +94,40 @@ import {
TraceHttpStream,
TraceStream
} from './trace_stream';
-import {TrackControllerArgs, trackControllerRegistry} from './track_controller';
-import {decideTracks} from './track_decider';
-
-type States = 'init'|'loading_trace'|'ready';
+import { TrackControllerArgs, trackControllerRegistry } from './track_controller';
+import { decideTracks } from './track_decider';
+
+type States = 'init' | 'loading_trace' | 'ready';
+
+const METRICS = [
+ 'android_startup',
+ 'android_ion',
+ 'android_lmk',
+ 'android_dma_heap',
+ 'android_thread_time_in_state',
+ 'android_surfaceflinger',
+ 'android_batt',
+ 'android_sysui_cuj',
+ 'android_jank',
+ 'android_camera',
+ 'android_other_traces',
+ 'chrome_dropped_frames',
+ 'chrome_long_latency',
+ 'trace_metadata',
+ 'android_trusty_workqueues',
+];
+const FLAGGED_METRICS: Array<[Flag, string]> = METRICS.map(m => {
+ const id = `forceMetric${m}`;
+ let name = m.split('_').join(' ') + ' metric';
+ name = name[0].toUpperCase() + name.slice(1);
+ const flag = featureFlags.register({
+ id,
+ name,
+ description: `Overrides running the '${m}' metric at import time.`,
+ defaultValue: true,
+ });
+ return [flag, m];
+});
// TraceController handles handshakes with the frontend for everything that
// concerns a single trace. It owns the WASM trace processor engine, handles
@@ -98,28 +142,22 @@ export class TraceController extends Controller<States> {
this.engineId = engineId;
}
- onDestroy() {
- if (this.engine instanceof WasmEngineProxy) {
- destroyWasmEngine(this.engine.id);
- }
- }
-
run() {
const engineCfg = assertExists(globals.state.engines[this.engineId]);
switch (this.state) {
case 'init':
this.loadTrace()
- .then(mode => {
- globals.dispatch(Actions.setEngineReady({
- engineId: this.engineId,
- ready: true,
- mode,
- }));
- })
- .catch(err => {
- this.updateStatus(`${err}`);
- throw err;
- });
+ .then(mode => {
+ globals.dispatch(Actions.setEngineReady({
+ engineId: this.engineId,
+ ready: true,
+ mode,
+ }));
+ })
+ .catch(err => {
+ this.updateStatus(`${err}`);
+ throw err;
+ });
this.updateStatus('Opening trace');
this.setState('loading_trace');
break;
@@ -134,7 +172,6 @@ export class TraceController extends Controller<States> {
case 'ready':
// At this point we are ready to serve queries and handle tracks.
const engine = assertExists(this.engine);
- assertTrue(engineCfg.ready);
const childControllers: Children = [];
// Create a TrackController for each track.
@@ -143,63 +180,78 @@ export class TraceController extends Controller<States> {
if (trackCfg.engineId !== this.engineId) continue;
if (!trackControllerRegistry.has(trackCfg.kind)) continue;
const trackCtlFactory = trackControllerRegistry.get(trackCfg.kind);
- const trackArgs: TrackControllerArgs = {trackId, engine};
+ const trackArgs: TrackControllerArgs = { trackId, engine };
childControllers.push(Child(trackId, trackCtlFactory, trackArgs));
}
// Create a QueryController for each query.
for (const queryId of Object.keys(globals.state.queries)) {
- const queryArgs: QueryControllerArgs = {queryId, engine};
+ const queryArgs: QueryControllerArgs = { queryId, engine };
childControllers.push(Child(queryId, QueryController, queryArgs));
}
- const selectionArgs: SelectionControllerArgs = {engine};
+ const selectionArgs: SelectionControllerArgs = { engine };
childControllers.push(
- Child('selection', SelectionController, selectionArgs));
+ Child('selection', SelectionController, selectionArgs));
- const flowEventsArgs: FlowEventsControllerArgs = {engine};
+ const flowEventsArgs: FlowEventsControllerArgs = { engine };
childControllers.push(
- Child('flowEvents', FlowEventsController, flowEventsArgs));
+ Child('flowEvents', FlowEventsController, flowEventsArgs));
- const cpuProfileArgs: CpuProfileControllerArgs = {engine};
+ const cpuProfileArgs: CpuProfileControllerArgs = { engine };
childControllers.push(
- Child('cpuProfile', CpuProfileController, cpuProfileArgs));
+ Child('cpuProfile', CpuProfileController, cpuProfileArgs));
- const heapProfileArgs: HeapProfileControllerArgs = {engine};
+ const flamegraphArgs: FlamegraphControllerArgs = { engine };
childControllers.push(
- Child('heapProfile', HeapProfileController, heapProfileArgs));
+ Child('flamegraph', FlamegraphController, flamegraphArgs));
+ childControllers.push(Child(
+ 'cpu_aggregation',
+ CpuAggregationController,
+ { engine, kind: 'cpu_aggregation' }));
childControllers.push(Child(
- 'cpu_aggregation',
- CpuAggregationController,
- {engine, kind: 'cpu_aggregation'}));
+ 'thread_aggregation',
+ ThreadAggregationController,
+ { engine, kind: 'thread_state_aggregation' }));
childControllers.push(Child(
- 'thread_aggregation',
- ThreadAggregationController,
- {engine, kind: 'thread_state_aggregation'}));
+ 'cpu_process_aggregation',
+ CpuByProcessAggregationController,
+ { engine, kind: 'cpu_by_process_aggregation' }));
childControllers.push(Child(
- 'cpu_process_aggregation',
- CpuByProcessAggregationController,
- {engine, kind: 'cpu_by_process_aggregation'}));
+ 'slice_aggregation',
+ SliceAggregationController,
+ { engine, kind: 'slice_aggregation' }));
childControllers.push(Child(
- 'slice_aggregation',
- SliceAggregationController,
- {engine, kind: 'slice_aggregation'}));
+ 'counter_aggregation',
+ CounterAggregationController,
+ { engine, kind: 'counter_aggregation' }));
childControllers.push(Child(
- 'counter_aggregation',
- CounterAggregationController,
- {engine, kind: 'counter_aggregation'}));
+ 'frame_aggregation',
+ FrameAggregationController,
+ { engine, kind: 'frame_aggregation' }));
childControllers.push(Child('search', SearchController, {
engine,
app: globals,
}));
+ childControllers.push(
+ Child('pivot_table_redux', PivotTableReduxController, {engine}));
childControllers.push(Child('logs', LogsController, {
engine,
app: globals,
}));
childControllers.push(
- Child('traceError', TraceErrorController, {engine}));
- childControllers.push(Child('metrics', MetricsController, {engine}));
+ Child('traceError', TraceErrorController, { engine }));
+ childControllers.push(Child('metrics', MetricsController, { engine }));
+
+ // Create a PivotTableController for each pivot table.
+ for (const pivotTableId of Object.keys(globals.state.pivotTable)) {
+ const pivotTableArgs:
+ PivotTableControllerArgs = { pivotTableId, engine };
+ childControllers.push(
+ Child(pivotTableId, PivotTableController, pivotTableArgs));
+ }
+
return childControllers;
default:
@@ -208,6 +260,10 @@ export class TraceController extends Controller<States> {
return;
}
+ onDestroy() {
+ frontendGlobals.engines.delete(this.engineId);
+ }
+
private async loadTrace(): Promise<EngineMode> {
this.updateStatus('Creating trace processor');
// Check if there is any instance of the trace_processor_shell running in
@@ -217,33 +273,33 @@ export class TraceController extends Controller<States> {
if (globals.state.newEngineMode === 'USE_HTTP_RPC_IF_AVAILABLE') {
useRpc = (await HttpRpcEngine.checkConnection()).connected;
}
+ let engine;
if (useRpc) {
console.log('Opening trace using native accelerator over HTTP+RPC');
engineMode = 'HTTP_RPC';
- const engine =
- new HttpRpcEngine(this.engineId, LoadingManager.getInstance);
+ engine = new HttpRpcEngine(this.engineId, LoadingManager.getInstance);
engine.errorHandler = (err) => {
globals.dispatch(
- Actions.setEngineFailed({mode: 'HTTP_RPC', failure: `${err}`}));
+ Actions.setEngineFailed({ mode: 'HTTP_RPC', failure: `${err}` }));
throw err;
};
- this.engine = engine;
} else {
console.log('Opening trace using built-in WASM engine');
engineMode = 'WASM';
- this.engine = new WasmEngineProxy(
- this.engineId,
- createWasmEngine(this.engineId),
- LoadingManager.getInstance);
+ const enginePort = resetEngineWorker();
+ engine = new WasmEngineProxy(
+ this.engineId, enginePort, LoadingManager.getInstance);
}
+ this.engine = engine;
+ frontendGlobals.engines.set(this.engineId, engine);
globals.dispatch(Actions.setEngineReady({
engineId: this.engineId,
ready: false,
mode: engineMode,
}));
const engineCfg = assertExists(globals.state.engines[this.engineId]);
- let traceStream: TraceStream|undefined;
+ let traceStream: TraceStream | undefined;
if (engineCfg.source.type === 'FILE') {
traceStream = new TraceFileStream(engineCfg.source.file);
} else if (engineCfg.source.type === 'ARRAY_BUFFER') {
@@ -263,7 +319,7 @@ export class TraceController extends Controller<States> {
// file/stream and we just want to jump to the loading phase.
if (traceStream !== undefined) {
const tStart = performance.now();
- for (;;) {
+ for (; ;) {
const res = await traceStream.readChunk();
await this.engine.parse(res.data);
const elapsed = (performance.now() - tStart) / 1000;
@@ -284,6 +340,9 @@ export class TraceController extends Controller<States> {
await this.engine.restoreInitialTables();
}
+ // traceUuid will be '' if the trace is not cacheable (URL or RPC).
+ const traceUuid = await this.cacheCurrentTrace();
+
const traceTime = await this.engine.getTraceTimeBounds();
let startSec = traceTime.start;
let endSec = traceTime.end;
@@ -293,9 +352,18 @@ export class TraceController extends Controller<States> {
startSec,
endSec,
};
+
+ const emptyOmniboxState = {
+ omnibox: '',
+ mode: frontendGlobals.state.frontendLocalState.omniboxState.mode ||
+ 'SEARCH',
+ lastUpdate: Date.now() / 1000
+ };
+
const actions: DeferredAction[] = [
- Actions.setTraceTime(traceTimeState),
- Actions.navigate({route: '/viewer'}),
+ Actions.setOmnibox(emptyOmniboxState),
+ Actions.setTraceUuid({ traceUuid }),
+ Actions.setTraceTime(traceTimeState)
];
let visibleStartSec = startSec;
@@ -303,9 +371,9 @@ export class TraceController extends Controller<States> {
const mdTime = await this.engine.getTracingMetadataTimeBounds();
// make sure the bounds hold
if (Math.max(visibleStartSec, mdTime.start - TRACE_MARGIN_TIME_S) <
- Math.min(visibleEndSec, mdTime.end + TRACE_MARGIN_TIME_S)) {
+ Math.min(visibleEndSec, mdTime.end + TRACE_MARGIN_TIME_S)) {
visibleStartSec =
- Math.max(visibleStartSec, mdTime.start - TRACE_MARGIN_TIME_S);
+ Math.max(visibleStartSec, mdTime.start - TRACE_MARGIN_TIME_S);
visibleEndSec = Math.min(visibleEndSec, mdTime.end + TRACE_MARGIN_TIME_S);
}
@@ -320,13 +388,14 @@ export class TraceController extends Controller<States> {
}));
globals.dispatchMultiple(actions);
+ Router.navigate(`#!/viewer?local_cache_key=${traceUuid}`);
// Make sure the helper views are available before we start adding tracks.
await this.initialiseHelperViews();
{
// When we reload from a permalink don't create extra tracks:
- const {pinnedTracks, tracks} = globals.state;
+ const { pinnedTracks, tracks } = globals.state;
if (!pinnedTracks.length && !Object.keys(tracks).length) {
await this.listTracks();
}
@@ -334,12 +403,49 @@ export class TraceController extends Controller<States> {
await this.listThreads();
await this.loadTimelineOverview(traceTime);
+
+ {
+ // A quick heuristic to check if the trace has ftrace events. This is
+ // based on the assumption that most traces that have ftrace either:
+ // - Are proto traces captured via perfetto, in which case traced_probes
+ // emits ftrace per-cpu stats that end up in the stats table.
+ // - Have a raw event with non-zero cpu or utid.
+ // Notes:
+ // - The "+1 > 1" is to avoid pushing down the constraints to the "raw"
+ // table, which would compute a full column filter without being aware
+ // of the limit 1, and instead delegate the filtering to the iterator.
+ const query = `select '_' as _ from raw
+ where cpu + 1 > 1 or utid + 1 > 1 limit 1`;
+ const result = await assertExists(this.engine).query(query);
+ const hasFtrace = result.numRows() > 0;
+ publishHasFtrace(hasFtrace);
+ }
+
+ globals.dispatch(Actions.removeDebugTrack({}));
globals.dispatch(Actions.sortThreadTracks({}));
+
await this.selectFirstHeapProfile();
+ if (PERF_SAMPLE_FLAG.get()) {
+ await this.selectPerfSample();
+ }
return engineMode;
}
+ private async selectPerfSample() {
+ const query = `select ts, upid
+ from perf_sample
+ join thread using (utid)
+ order by ts desc limit 1`;
+ const profile = await assertExists(this.engine).query(query);
+ if (profile.numRows() !== 1) return;
+ const row = profile.firstRow({ ts: NUM, upid: NUM });
+ const ts = row.ts;
+ const upid = row.upid;
+ globals.dispatch(
+ Actions.selectPerfSamples({ id: 0, upid, ts, type: 'perf' }));
+ }
+
private async selectFirstHeapProfile() {
const query = `select * from
(select distinct(ts) as ts, 'native' as type,
@@ -348,11 +454,12 @@ export class TraceController extends Controller<States> {
select distinct(graph_sample_ts) as ts, 'graph' as type, upid from
heap_graph_object) order by ts limit 1`;
const profile = await assertExists(this.engine).query(query);
- if (profile.numRecords !== 1) return;
- const ts = profile.columns[0].longValues![0];
- const type = profile.columns[1].stringValues![0];
- const upid = profile.columns[2].longValues![0];
- globals.dispatch(Actions.selectHeapProfile({id: 0, upid, ts, type}));
+ if (profile.numRows() !== 1) return;
+ const row = profile.firstRow({ ts: NUM, type: STR, upid: NUM });
+ const ts = row.ts;
+ const type = row.type;
+ const upid = row.upid;
+ globals.dispatch(Actions.selectHeapProfile({ id: 0, upid, ts, type }));
}
private async listTracks() {
@@ -364,26 +471,38 @@ export class TraceController extends Controller<States> {
private async listThreads() {
this.updateStatus('Reading thread list');
- const sqlQuery = `select utid, tid, pid, thread.name,
+ const query = `select
+ utid,
+ tid,
+ pid,
+ ifnull(thread.name, '') as threadName,
ifnull(
case when length(process.name) > 0 then process.name else null end,
- thread.name),
- process.cmdline
+ thread.name) as procName,
+ process.cmdline as cmdline
from (select * from thread order by upid) as thread
left join (select * from process order by upid) as process
using(upid)`;
- const threadRows = await assertExists(this.engine).query(sqlQuery);
+ const result = await assertExists(this.engine).query(query);
const threads: ThreadDesc[] = [];
- for (let i = 0; i < slowlyCountRows(threadRows); i++) {
- const utid = threadRows.columns[0].longValues![i];
- const tid = threadRows.columns[1].longValues![i];
- const pid = threadRows.columns[2].longValues![i];
- const threadName = threadRows.columns[3].stringValues![i];
- const procName = threadRows.columns[4].stringValues![i];
- const cmdline = threadRows.columns[5].stringValues![i];
- threads.push({utid, tid, threadName, pid, procName, cmdline});
- } // for (record ...)
- globals.publish('Threads', threads);
+ const it = result.iter({
+ utid: NUM,
+ tid: NUM,
+ pid: NUM_NULL,
+ threadName: STR,
+ procName: STR_NULL,
+ cmdline: STR_NULL,
+ });
+ for (; it.valid(); it.next()) {
+ const utid = it.utid;
+ const tid = it.tid;
+ const pid = it.pid === null ? undefined : it.pid;
+ const threadName = it.threadName;
+ const procName = it.procName === null ? undefined : it.procName;
+ const cmdline = it.cmdline === null ? undefined : it.cmdline;
+ threads.push({ utid, tid, threadName, pid, procName, cmdline });
+ }
+ publishThreads(threads);
}
private async loadTimelineOverview(traceTime: TimeSpan) {
@@ -393,27 +512,28 @@ export class TraceController extends Controller<States> {
let hasSchedOverview = false;
for (let step = 0; step < numSteps; step++) {
this.updateStatus(
- 'Loading overview ' +
- `${Math.round((step + 1) / numSteps * 1000) / 10}%`);
+ 'Loading overview ' +
+ `${Math.round((step + 1) / numSteps * 1000) / 10}%`);
const startSec = traceTime.start + step * stepSec;
const startNs = toNsFloor(startSec);
const endSec = startSec + stepSec;
const endNs = toNsCeil(endSec);
// Sched overview.
- const schedRows = await engine.query(
- `select sum(dur)/${stepSec}/1e9, cpu from sched ` +
- `where ts >= ${startNs} and ts < ${endNs} and utid != 0 ` +
- 'group by cpu order by cpu');
- const schedData: {[key: string]: QuantizedLoad} = {};
- for (let i = 0; i < slowlyCountRows(schedRows); i++) {
- const load = schedRows.columns[0].doubleValues![i];
- const cpu = schedRows.columns[1].longValues![i];
- schedData[cpu] = {startSec, endSec, load};
+ const schedResult = await engine.query(
+ `select sum(dur)/${stepSec}/1e9 as load, cpu from sched ` +
+ `where ts >= ${startNs} and ts < ${endNs} and utid != 0 ` +
+ 'group by cpu order by cpu');
+ const schedData: { [key: string]: QuantizedLoad } = {};
+ const it = schedResult.iter({ load: NUM, cpu: NUM });
+ for (; it.valid(); it.next()) {
+ const load = it.load;
+ const cpu = it.cpu;
+ schedData[cpu] = { startSec, endSec, load };
hasSchedOverview = true;
- } // for (record ...)
- globals.publish('OverviewData', schedData);
- } // for (step ...)
+ }
+ publishOverviewData(schedData);
+ }
if (hasSchedOverview) {
return;
@@ -422,27 +542,29 @@ export class TraceController extends Controller<States> {
// Slices overview.
const traceStartNs = toNs(traceTime.start);
const stepSecNs = toNs(stepSec);
- const sliceSummaryQuery = await engine.query(`select
+ const sliceResult = await engine.query(`select
bucket,
upid,
- sum(utid_sum) / cast(${stepSecNs} as float) as upid_sum
+ ifnull(sum(utid_sum) / cast(${stepSecNs} as float), 0) as load
from thread
inner join (
select
- cast((ts - ${traceStartNs})/${stepSecNs} as int) as bucket,
+ ifnull(cast((ts - ${traceStartNs})/${stepSecNs} as int), 0) as bucket,
sum(dur) as utid_sum,
utid
from slice
inner join thread_track on slice.track_id = thread_track.id
group by bucket, utid
) using(utid)
+ where upid is not null
group by bucket, upid`);
- const slicesData: {[key: string]: QuantizedLoad[]} = {};
- for (let i = 0; i < slowlyCountRows(sliceSummaryQuery); i++) {
- const bucket = sliceSummaryQuery.columns[0].longValues![i];
- const upid = sliceSummaryQuery.columns[1].longValues![i];
- const load = sliceSummaryQuery.columns[2].doubleValues![i];
+ const slicesData: { [key: string]: QuantizedLoad[] } = {};
+ const it = sliceResult.iter({ bucket: NUM, upid: NUM, load: NUM });
+ for (; it.valid(); it.next()) {
+ const bucket = it.bucket;
+ const upid = it.upid;
+ const load = it.load;
const startSec = traceTime.start + stepSec * bucket;
const endSec = startSec + stepSec;
@@ -452,9 +574,30 @@ export class TraceController extends Controller<States> {
if (loadArray === undefined) {
loadArray = slicesData[upidStr] = [];
}
- loadArray.push({startSec, endSec, load});
+ loadArray.push({ startSec, endSec, load });
+ }
+ publishOverviewData(slicesData);
+ }
+
+ private async cacheCurrentTrace(): Promise<string> {
+ const engine = assertExists(this.engine);
+ const result = await engine.query(`select str_value as uuid from metadata
+ where name = 'trace_uuid'`);
+ if (result.numRows() === 0) {
+ // One of the cases covered is an empty trace.
+ return '';
+ }
+ const traceUuid = result.firstRow({ uuid: STR }).uuid;
+ const engineConfig = assertExists(globals.state.engines[engine.id]);
+ if (!(await cacheTrace(engineConfig.source, traceUuid))) {
+ // If the trace is not cacheable (cacheable means it has been opened from
+ // URL or RPC) only append '?local_cache_key' to the URL, without the
+ // local_cache_key value. Doing otherwise would cause an error if the tab
+ // is discarded or the user hits the reload button because the trace is
+ // not in the cache.
+ return '';
}
- globals.publish('OverviewData', slicesData);
+ return traceUuid;
}
async initialiseHelperViews() {
@@ -479,7 +622,8 @@ export class TraceController extends Controller<States> {
id INTEGER PRIMARY KEY,
name STRING,
__metric_name STRING,
- upid INTEGER
+ upid INTEGER,
+ group_name STRING
);
`);
@@ -507,15 +651,20 @@ export class TraceController extends Controller<States> {
);
`);
- for (const metric
- of ['android_startup',
- 'android_ion',
- 'android_dma_heap',
- 'android_thread_time_in_state',
- 'android_surfaceflinger',
- 'android_batt',
- 'android_sysui_cuj',
- 'android_jank']) {
+
+ const availableMetrics = [];
+ const metricsResult = await engine.query('select name from trace_metrics');
+ for (const it = metricsResult.iter({name: STR}); it.valid(); it.next()) {
+ availableMetrics.push(it.name);
+ }
+ globals.dispatch(Actions.setAvailableMetrics({availableMetrics}));
+
+ const availableMetricsSet = new Set<string>(availableMetrics);
+ for (const [flag, metric] of FLAGGED_METRICS) {
+ if (!flag.get() || !availableMetricsSet.has(metric)) {
+ continue;
+ }
+
this.updateStatus(`Computing ${metric} metric`);
try {
// We don't care about the actual result of metric here as we are just
@@ -523,7 +672,7 @@ export class TraceController extends Controller<States> {
await engine.computeMetric([metric]);
} catch (e) {
if (e instanceof QueryError) {
- globals.publish('MetricError', 'MetricError: ' + e.message);
+ publishMetricError('MetricError: ' + e.message);
continue;
} else {
throw e;
@@ -536,22 +685,31 @@ export class TraceController extends Controller<States> {
let hasSliceName = false;
let hasDur = false;
let hasUpid = false;
- for (let i = 0; i < slowlyCountRows(result); i++) {
- const name = result.columns[1].stringValues![i];
+ let hasValue = false;
+ let hasGroupName = false;
+ const it = result.iter({ name: STR });
+ for (; it.valid(); it.next()) {
+ const name = it.name;
hasSliceName = hasSliceName || name === 'slice_name';
hasDur = hasDur || name === 'dur';
hasUpid = hasUpid || name === 'upid';
+ hasValue = hasValue || name === 'value';
+ hasGroupName = hasGroupName || name === 'group_name';
}
const upidColumnSelect = hasUpid ? 'upid' : '0 AS upid';
const upidColumnWhere = hasUpid ? 'upid' : '0';
+ const groupNameColumn =
+ hasGroupName ? 'group_name' : 'NULL AS group_name';
if (hasSliceName && hasDur) {
await engine.query(`
- INSERT INTO annotation_slice_track(name, __metric_name, upid)
+ INSERT INTO annotation_slice_track(
+ name, __metric_name, upid, group_name)
SELECT DISTINCT
track_name,
'${metric}' as metric_name,
- ${upidColumnSelect}
+ ${upidColumnSelect},
+ ${groupNameColumn}
FROM ${metric}_event
WHERE track_type = 'slice'
`);
@@ -571,42 +729,42 @@ export class TraceController extends Controller<States> {
`);
}
- const hasValue = result.columnDescriptors.some(x => x.name === 'value');
if (hasValue) {
const minMax = await engine.query(`
- SELECT MIN(value) as min_value, MAX(value) as max_value
- FROM ${metric}_event
- WHERE ${upidColumnWhere} != 0`);
- const min = minMax.columns[0].longValues![0];
- const max = minMax.columns[1].longValues![0];
+ SELECT
+ IFNULL(MIN(value), 0) as minValue,
+ IFNULL(MAX(value), 0) as maxValue
+ FROM ${metric}_event
+ WHERE ${upidColumnWhere} != 0`);
+ const row = minMax.firstRow({ minValue: NUM, maxValue: NUM });
await engine.query(`
- INSERT INTO annotation_counter_track(
- name, __metric_name, min_value, max_value, upid)
- SELECT DISTINCT
- track_name,
- '${metric}' as metric_name,
- CASE ${upidColumnWhere} WHEN 0 THEN NULL ELSE ${min} END,
- CASE ${upidColumnWhere} WHEN 0 THEN NULL ELSE ${max} END,
- ${upidColumnSelect}
- FROM ${metric}_event
- WHERE track_type = 'counter'
- `);
+ INSERT INTO annotation_counter_track(
+ name, __metric_name, min_value, max_value, upid)
+ SELECT DISTINCT
+ track_name,
+ '${metric}' as metric_name,
+ CASE ${upidColumnWhere} WHEN 0 THEN NULL ELSE ${row.minValue} END,
+ CASE ${upidColumnWhere} WHEN 0 THEN NULL ELSE ${row.maxValue} END,
+ ${upidColumnSelect}
+ FROM ${metric}_event
+ WHERE track_type = 'counter'
+ `);
await engine.query(`
- INSERT INTO annotation_counter(id, track_id, ts, value)
- SELECT
- -1 as id,
- t.id AS track_id,
- ts,
- value
- FROM ${metric}_event a
- JOIN annotation_counter_track t
- ON a.track_name = t.name AND t.__metric_name = '${metric}'
- ORDER BY t.id, ts
- `);
+ INSERT INTO annotation_counter(id, track_id, ts, value)
+ SELECT
+ -1 as id,
+ t.id AS track_id,
+ ts,
+ value
+ FROM ${metric}_event a
+ JOIN annotation_counter_track t
+ ON a.track_name = t.name AND t.__metric_name = '${metric}'
+ ORDER BY t.id, ts
+ `);
}
} catch (e) {
if (e instanceof QueryError) {
- globals.publish('MetricError', 'MetricError: ' + e.message);
+ publishMetricError('MetricError: ' + e.message);
} else {
throw e;
}
@@ -621,5 +779,3 @@ export class TraceController extends Controller<States> {
}));
}
}
-
-
diff --git a/ui/src/controller/trace_converter.ts b/ui/src/controller/trace_converter.ts
deleted file mode 100644
index 889b76b7b..000000000
--- a/ui/src/controller/trace_converter.ts
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import {defer} from '../base/deferred';
-import {assertExists} from '../base/logging';
-import {Actions} from '../common/actions';
-import {TraceSource} from '../common/state';
-import * as trace_to_text from '../gen/trace_to_text';
-
-import {globals} from './globals';
-
-type Format = 'json'|'systrace';
-
-export function ConvertTrace(
- trace: Blob, format: Format, truncate?: 'start'|'end') {
- const outPath = '/trace.json';
- const args: string[] = [format];
- if (truncate !== undefined) {
- args.push('--truncate', truncate);
- }
- args.push('/fs/trace.proto', outPath);
- runTraceconv(trace, args).then(module => {
- const fsNode = module.FS.lookupPath(outPath).node;
- const data = fsNode.contents.buffer;
- const size = fsNode.usedBytes;
- globals.publish('LegacyTrace', {data, size}, /*transfer=*/[data]);
- module.FS.unlink(outPath);
- });
-}
-
-export function ConvertTraceToPprof(
- pid: number, src: TraceSource, ts1: number, ts2?: number) {
- const timestamps = `${ts1}${ts2 === undefined ? '' : `,${ts2}`}`;
- const args = [
- 'profile',
- `--pid`,
- `${pid}`,
- `--timestamps`,
- timestamps,
- '/fs/trace.proto'
- ];
- generateBlob(src).then(traceBlob => {
- runTraceconv(traceBlob, args).then(module => {
- const heapDirName =
- Object.keys(module.FS.lookupPath('/tmp/').node.contents)[0];
- const heapDirContents =
- module.FS.lookupPath(`/tmp/${heapDirName}`).node.contents;
- const heapDumpFiles = Object.keys(heapDirContents);
- let fileNum = 0;
- heapDumpFiles.forEach(heapDump => {
- const fileContents =
- module.FS.lookupPath(`/tmp/${heapDirName}/${heapDump}`)
- .node.contents;
- fileNum++;
- const fileName = `/heap_dump.${fileNum}.${pid}.pb`;
- downloadFile(new Blob([fileContents]), fileName);
- });
- });
- });
-}
-
-async function runTraceconv(trace: Blob, args: string[]) {
- const deferredRuntimeInitialized = defer<void>();
- const module = trace_to_text({
- noInitialRun: true,
- locateFile: (s: string) => s,
- print: updateStatus,
- printErr: updateStatus,
- onRuntimeInitialized: () => deferredRuntimeInitialized.resolve()
- });
- await deferredRuntimeInitialized;
- module.FS.mkdir('/fs');
- module.FS.mount(
- assertExists(module.FS.filesystems.WORKERFS),
- {blobs: [{name: 'trace.proto', data: trace}]},
- '/fs');
- updateStatus('Converting trace');
- module.callMain(args);
- updateStatus('Trace conversion completed');
- return module;
-}
-
-async function generateBlob(src: TraceSource) {
- let blob: Blob = new Blob();
- if (src.type === 'URL') {
- const resp = await fetch(src.url);
- if (resp.status !== 200) {
- throw new Error(`fetch() failed with HTTP error ${resp.status}`);
- }
- blob = await resp.blob();
- } else if (src.type === 'ARRAY_BUFFER') {
- blob = new Blob([new Uint8Array(src.buffer, 0, src.buffer.byteLength)]);
- } else if (src.type === 'FILE') {
- blob = src.file;
- } else {
- throw new Error(`Conversion not supported for ${JSON.stringify(src)}`);
- }
- return blob;
-}
-
-function downloadFile(file: Blob, name: string) {
- globals.publish('FileDownload', {file, name});
-}
-
-function updateStatus(msg: {}) {
- console.log(msg);
- globals.dispatch(Actions.updateStatus({
- msg: msg.toString(),
- timestamp: Date.now() / 1000,
- }));
-}
diff --git a/ui/src/controller/trace_error_controller.ts b/ui/src/controller/trace_error_controller.ts
index a8bb80bf8..6b6f461d1 100644
--- a/ui/src/controller/trace_error_controller.ts
+++ b/ui/src/controller/trace_error_controller.ts
@@ -13,9 +13,10 @@
// limitations under the License.
import {Engine} from '../common/engine';
+import {NUM} from '../common/query_result';
+import {publishTraceErrors} from '../frontend/publish';
import {Controller} from './controller';
-import {globals} from './globals';
export interface TraceErrorControllerArgs {
engine: Engine;
@@ -32,10 +33,13 @@ export class TraceErrorController extends Controller<'main'> {
return;
}
this.hasRun = true;
- this.args.engine
- .queryOneRow(`SELECT sum(value) FROM stats WHERE severity != 'info'`)
+ const engine = this.args.engine;
+ engine
+ .query(
+ `SELECT sum(value) as sumValue FROM stats WHERE severity != 'info'`)
.then(result => {
- globals.publish('TraceErrors', result[0]);
+ const errors = result.firstRow({sumValue: NUM}).sumValue;
+ publishTraceErrors(errors);
});
}
}
diff --git a/ui/src/controller/trace_stream.ts b/ui/src/controller/trace_stream.ts
index 34c386102..f6c9da60c 100644
--- a/ui/src/controller/trace_stream.ts
+++ b/ui/src/controller/trace_stream.ts
@@ -100,7 +100,7 @@ export class TraceHttpStream implements TraceStream {
private bytesRead = 0;
private bytesTotal = 0;
private uri: string;
- private httpStream?: ReadableStreamReader;
+ private httpStream?: ReadableStreamReader<Uint8Array>;
constructor(uri: string) {
assertTrue(uri.startsWith('http://') || uri.startsWith('https://'));
@@ -116,8 +116,7 @@ export class TraceHttpStream implements TraceStream {
}
const len = response.headers.get('Content-Length');
this.bytesTotal = len ? Number.parseInt(len, 10) : 0;
- // tslint:disable-next-line no-any
- this.httpStream = (response.body as any).getReader();
+ this.httpStream = response.body!.getReader();
}
let eof = false;
@@ -128,8 +127,7 @@ export class TraceHttpStream implements TraceStream {
// TraceProcessor. Here we accumulate chunks until we get at least 32mb
// or hit EOF.
while (!eof && bytesRead < 32 * 1024 * 1024) {
- const res = (await this.httpStream!.read()) as
- {value?: Uint8Array, done: boolean};
+ const res = await this.httpStream.read();
if (res.value) {
chunks.push(res.value);
bytesRead += res.value.length;
diff --git a/ui/src/controller/track_controller.ts b/ui/src/controller/track_controller.ts
index 75ee194c5..fd6aae6e8 100644
--- a/ui/src/controller/track_controller.ts
+++ b/ui/src/controller/track_controller.ts
@@ -18,6 +18,7 @@ import {Registry} from '../common/registry';
import {TraceTime, TrackState} from '../common/state';
import {fromNs, toNs} from '../common/time';
import {LIMIT, TrackData} from '../common/track_data';
+import {publishTrackData} from '../frontend/publish';
import {Controller} from './controller';
import {ControllerFactory} from './controller';
@@ -68,7 +69,7 @@ export abstract class TrackController<
// Must be overridden by the track implementation. Is invoked when the track
// frontend runs out of cached data. The derived track controller is expected
// to publish new track data in response to this call.
- abstract async onBoundsChange(start: number, end: number, resolution: number):
+ abstract onBoundsChange(start: number, end: number, resolution: number):
Promise<Data>;
get trackState(): TrackState {
@@ -93,7 +94,7 @@ export abstract class TrackController<
publish(data: Data): void {
this.data = data;
- globals.publish('TrackData', {id: this.trackId, data});
+ publishTrackData({id: this.trackId, data});
}
/**
@@ -151,7 +152,7 @@ export abstract class TrackController<
globals.state.frontendLocalState.visibleState.resolution;
}
- // Decides, based on the the length of the trace and the number of rows
+ // Decides, based on the length of the trace and the number of rows
// provided whether a TrackController subclass should cache its quantized
// data. Returns the bucket size (in ns) if caching should happen and
// undefined otherwise.
diff --git a/ui/src/controller/track_decider.ts b/ui/src/controller/track_decider.ts
index 26f343b65..88a44ceb3 100644
--- a/ui/src/controller/track_decider.ts
+++ b/ui/src/controller/track_decider.ts
@@ -13,22 +13,21 @@
// limitations under the License.
import * as uuidv4 from 'uuid/v4';
-import {assertExists} from '../base/logging';
+import {assertExists} from '../base/logging';
import {
Actions,
AddTrackArgs,
DeferredAction,
} from '../common/actions';
import {Engine} from '../common/engine';
+import {featureFlags, PERF_SAMPLE_FLAG} from '../common/feature_flags';
import {
- iter,
NUM,
NUM_NULL,
- slowlyCountRows,
STR,
STR_NULL,
-} from '../common/query_iterator';
+} from '../common/query_result';
import {SCROLLING_TRACK_GROUP, TrackKindPriority} from '../common/state';
import {ACTUAL_FRAMES_SLICE_TRACK_KIND} from '../tracks/actual_frames/common';
import {ANDROID_LOGS_TRACK_KIND} from '../tracks/android_log/common';
@@ -43,11 +42,21 @@ import {
} from '../tracks/expected_frames/common';
import {HEAP_PROFILE_TRACK_KIND} from '../tracks/heap_profile/common';
import {
+ PERF_SAMPLES_PROFILE_TRACK_KIND
+} from '../tracks/perf_samples_profile/common';
+import {
PROCESS_SCHEDULING_TRACK_KIND
} from '../tracks/process_scheduling/common';
import {PROCESS_SUMMARY_TRACK} from '../tracks/process_summary/common';
import {THREAD_STATE_TRACK_KIND} from '../tracks/thread_state/common';
+const TRACKS_V2_FLAG = featureFlags.register({
+ id: 'tracksV2',
+ name: 'Tracks V2',
+ description: 'Show tracks built on top of the Track V2 API.',
+ defaultValue: false,
+});
+
const MEM_DMA_COUNTER_NAME = 'mem.dma_heap';
const MEM_DMA = 'mem.dma_buffer';
const MEM_ION = 'mem.ion';
@@ -149,39 +158,41 @@ class TrackDecider {
async addCpuFreqTracks(): Promise<void> {
const cpus = await this.engine.getCpus();
- const maxCpuFreq = await this.engine.query(`
- select max(value)
+ const maxCpuFreqResult = await this.engine.query(`
+ select ifnull(max(value), 0) as freq
from counter c
inner join cpu_counter_track t on c.track_id = t.id
where name = 'cpufreq';
`);
+ const maxCpuFreq = maxCpuFreqResult.firstRow({freq: NUM}).freq;
for (const cpu of cpus) {
// Only add a cpu freq track if we have
// cpu freq data.
// TODO(hjd): Find a way to display cpu idle
// events even if there are no cpu freq events.
- const cpuFreqIdle = await this.engine.query(`
+ const cpuFreqIdleResult = await this.engine.query(`
select
- id as cpu_freq_id,
+ id as cpuFreqId,
(
select id
from cpu_counter_track
where name = 'cpuidle'
and cpu = ${cpu}
limit 1
- ) as cpu_idle_id
+ ) as cpuIdleId
from cpu_counter_track
where name = 'cpufreq' and cpu = ${cpu}
limit 1;
`);
- if (slowlyCountRows(cpuFreqIdle) > 0) {
- const freqTrackId = +cpuFreqIdle.columns[0].longValues![0];
- const idleTrackExists: boolean = !cpuFreqIdle.columns[1].isNulls![0];
- const idleTrackId = idleTrackExists ?
- +cpuFreqIdle.columns[1].longValues![0] :
- undefined;
+ if (cpuFreqIdleResult.numRows() > 0) {
+ const row = cpuFreqIdleResult.firstRow({
+ cpuFreqId: NUM,
+ cpuIdleId: NUM_NULL,
+ });
+ const freqTrackId = row.cpuFreqId;
+ const idleTrackId = row.cpuIdleId === null ? undefined : row.cpuIdleId;
this.tracksToAdd.push({
engineId: this.engineId,
@@ -191,7 +202,7 @@ class TrackDecider {
trackGroup: SCROLLING_TRACK_GROUP,
config: {
cpu,
- maximumValue: +maxCpuFreq.columns[0].doubleValues![0],
+ maximumValue: maxCpuFreq,
freqTrackId,
idleTrackId,
}
@@ -203,25 +214,30 @@ class TrackDecider {
async addGlobalAsyncTracks(): Promise<void> {
const rawGlobalAsyncTracks = await this.engine.query(`
SELECT
- t.name,
- t.track_ids,
- MAX(experimental_slice_layout.layout_depth) as max_depth
+ t.name as name,
+ t.track_ids as trackIds,
+ MAX(experimental_slice_layout.layout_depth) as maxDepth
FROM (
SELECT name, GROUP_CONCAT(track.id) AS track_ids
FROM track
- WHERE track.type = "track"
+ WHERE track.type = "track" or track.type = "gpu_track"
GROUP BY name
) AS t CROSS JOIN experimental_slice_layout
WHERE t.track_ids = experimental_slice_layout.filter_track_ids
- GROUP BY t.track_ids;
+ GROUP BY t.track_ids
+ ORDER BY t.name;
`);
- for (let i = 0; i < slowlyCountRows(rawGlobalAsyncTracks); i++) {
- const name = rawGlobalAsyncTracks.columns[0].isNulls![i] ?
- undefined :
- rawGlobalAsyncTracks.columns[0].stringValues![i];
- const rawTrackIds = rawGlobalAsyncTracks.columns[1].stringValues![i];
+ const it = rawGlobalAsyncTracks.iter({
+ name: STR_NULL,
+ trackIds: STR,
+ maxDepth: NUM,
+ });
+
+ for (; it.valid(); it.next()) {
+ const name = it.name === null ? undefined : it.name;
+ const rawTrackIds = it.trackIds;
const trackIds = rawTrackIds.split(',').map(v => Number(v));
- const maxDepth = +rawGlobalAsyncTracks.columns[2].longValues![i];
+ const maxDepth = it.maxDepth;
const kind = ASYNC_SLICE_TRACK_KIND;
const track = {
engineId: this.engineId,
@@ -240,23 +256,26 @@ class TrackDecider {
async addGpuFreqTracks(): Promise<void> {
const numGpus = await this.engine.getNumberOfGpus();
- const maxGpuFreq = await this.engine.query(`
- select max(value)
+ const maxGpuFreqResult = await this.engine.query(`
+ select ifnull(max(value), 0) as maximumValue
from counter c
inner join gpu_counter_track t on c.track_id = t.id
where name = 'gpufreq';
`);
+ const maximumValue =
+ maxGpuFreqResult.firstRow({maximumValue: NUM}).maximumValue;
for (let gpu = 0; gpu < numGpus; gpu++) {
// Only add a gpu freq track if we have
// gpu freq data.
- const freqExists = await this.engine.query(`
+ const freqExistsResult = await this.engine.query(`
select id
from gpu_counter_track
where name = 'gpufreq' and gpu_id = ${gpu}
limit 1;
`);
- if (slowlyCountRows(freqExists) > 0) {
+ if (freqExistsResult.numRows() > 0) {
+ const trackId = freqExistsResult.firstRow({id: NUM}).id;
this.tracksToAdd.push({
engineId: this.engineId,
kind: COUNTER_TRACK_KIND,
@@ -264,8 +283,8 @@ class TrackDecider {
trackKindPriority: TrackKindPriority.ORDINARY,
trackGroup: SCROLLING_TRACK_GROUP,
config: {
- trackId: +freqExists.columns[0].longValues![0],
- maximumValue: +maxGpuFreq.columns[0].doubleValues![0],
+ trackId,
+ maximumValue,
}
});
}
@@ -276,16 +295,61 @@ class TrackDecider {
// Add global or GPU counter tracks that are not bound to any pid/tid.
const globalCounters = await this.engine.query(`
select name, id
- from counter_track
- where type = 'counter_track'
- union
- select name, id
- from gpu_counter_track
- where name != 'gpufreq'
+ from (
+ select name, id
+ from counter_track
+ where type = 'counter_track'
+ union
+ select name, id
+ from gpu_counter_track
+ where name != 'gpufreq'
+ )
+ order by name
+ `);
+
+ const it = globalCounters.iter({
+ name: STR,
+ id: NUM,
+ });
+
+ for (; it.valid(); it.next()) {
+ const name = it.name;
+ const trackId = it.id;
+ this.tracksToAdd.push({
+ engineId: this.engineId,
+ kind: COUNTER_TRACK_KIND,
+ name,
+ trackKindPriority: TrackDecider.inferTrackKindPriority(name),
+ trackGroup: SCROLLING_TRACK_GROUP,
+ config: {
+ name,
+ trackId,
+ }
+ });
+ }
+ }
+
+ async addCpuPerfCounterTracks(): Promise<void> {
+ // Perf counter tracks are bound to CPUs, follow the scheduling and
+ // frequency track naming convention ("Cpu N ...").
+ // Note: we might not have a track for a given cpu if no data was seen from
+ // it. This might look surprising in the UI, but placeholder tracks are
+ // wasteful as there's no way of collapsing global counter tracks at the
+ // moment.
+ const result = await this.engine.query(`
+ select printf("Cpu %u %s", cpu, name) as name, id
+ from perf_counter_track as pct
+ order by perf_session_id asc, pct.name asc, cpu asc
`);
- for (let i = 0; i < slowlyCountRows(globalCounters); i++) {
- const name = globalCounters.columns[0].stringValues![i];
- const trackId = +globalCounters.columns[1].longValues![i];
+
+ const it = result.iter({
+ name: STR,
+ id: NUM,
+ });
+
+ for (; it.valid(); it.next()) {
+ const name = it.name;
+ const trackId = it.id;
this.tracksToAdd.push({
engineId: this.engineId,
kind: COUNTER_TRACK_KIND,
@@ -345,9 +409,11 @@ class TrackDecider {
}
async addLogsTrack(): Promise<void> {
- const logCount =
- await this.engine.query(`select count(1) from android_logs`);
- if (logCount.columns[0].longValues![0] > 0) {
+ const result =
+ await this.engine.query(`select count(1) as cnt from android_logs`);
+ const count = result.firstRow({cnt: NUM}).cnt;
+
+ if (count > 0) {
this.tracksToAdd.push({
engineId: this.engineId,
kind: ANDROID_LOGS_TRACK_KIND,
@@ -360,19 +426,60 @@ class TrackDecider {
}
async addAnnotationTracks(): Promise<void> {
- const annotationSliceRows = await this.engine.query(`
- SELECT id, name, upid FROM annotation_slice_track`);
- for (let i = 0; i < slowlyCountRows(annotationSliceRows); i++) {
- const id = annotationSliceRows.columns[0].longValues![i];
- const name = annotationSliceRows.columns[1].stringValues![i];
- const upid = annotationSliceRows.columns[2].longValues![i];
+ const sliceResult = await this.engine.query(`
+ select id, name, upid, group_name
+ from annotation_slice_track
+ order by name
+ `);
+
+ const sliceIt = sliceResult.iter({
+ id: NUM,
+ name: STR,
+ upid: NUM,
+ group_name: STR_NULL,
+ });
+
+ interface GroupIds {
+ id: string;
+ summaryTrackId: string;
+ }
+
+ const groupNameToIds = new Map<string, GroupIds>();
+
+ for (; sliceIt.valid(); sliceIt.next()) {
+ const id = sliceIt.id;
+ const name = sliceIt.name;
+ const upid = sliceIt.upid;
+ const groupName = sliceIt.group_name;
+
+ let summaryTrackId = undefined;
+ let trackGroupId =
+ upid === 0 ? SCROLLING_TRACK_GROUP : this.upidToUuid.get(upid);
+
+ if (groupName) {
+ // If this is the first track encountered for a certain group,
+ // create an id for the group and use this track as the group's
+ // summary track.
+ const groupIds = groupNameToIds.get(groupName);
+ if (groupIds) {
+ trackGroupId = groupIds.id;
+ } else {
+ trackGroupId = uuidv4();
+ summaryTrackId = uuidv4();
+ groupNameToIds.set(groupName, {
+ id: trackGroupId,
+ summaryTrackId,
+ });
+ }
+ }
+
this.tracksToAdd.push({
+ id: summaryTrackId,
engineId: this.engineId,
kind: SLICE_TRACK_KIND,
name,
trackKindPriority: TrackDecider.inferTrackKindPriority(name),
- trackGroup: upid === 0 ? SCROLLING_TRACK_GROUP :
- this.upidToUuid.get(upid),
+ trackGroup: trackGroupId,
config: {
maxDepth: 0,
namespace: 'annotation',
@@ -381,19 +488,42 @@ class TrackDecider {
});
}
- const annotationCounterRows = await this.engine.query(`
- SELECT id, name, upid, min_value, max_value
+ for (const [groupName, groupIds] of groupNameToIds) {
+ const addGroup = Actions.addTrackGroup({
+ engineId: this.engineId,
+ summaryTrackId: groupIds.summaryTrackId,
+ name: groupName,
+ id: groupIds.id,
+ collapsed: true,
+ });
+ this.addTrackGroupActions.push(addGroup);
+ }
+
+ const counterResult = await this.engine.query(`
+ SELECT
+ id,
+ name,
+ upid,
+ min_value as minValue,
+ max_value as maxValue
FROM annotation_counter_track`);
- for (let i = 0; i < slowlyCountRows(annotationCounterRows); i++) {
- const id = annotationCounterRows.columns[0].longValues![i];
- const name = annotationCounterRows.columns[1].stringValues![i];
- const upid = annotationCounterRows.columns[2].longValues![i];
- const minimumValue = annotationCounterRows.columns[3].isNulls![i] ?
- undefined :
- annotationCounterRows.columns[3].doubleValues![i];
- const maximumValue = annotationCounterRows.columns[4].isNulls![i] ?
- undefined :
- annotationCounterRows.columns[4].doubleValues![i];
+
+ const counterIt = counterResult.iter({
+ id: NUM,
+ name: STR,
+ upid: NUM,
+ minValue: NUM_NULL,
+ maxValue: NUM_NULL,
+ });
+
+ for (; counterIt.valid(); counterIt.next()) {
+ const id = counterIt.id;
+ const name = counterIt.name;
+ const upid = counterIt.upid;
+ const minimumValue =
+ counterIt.minValue === null ? undefined : counterIt.minValue;
+ const maximumValue =
+ counterIt.maxValue === null ? undefined : counterIt.maxValue;
this.tracksToAdd.push({
engineId: this.engineId,
kind: 'CounterTrack',
@@ -413,7 +543,7 @@ class TrackDecider {
}
async addThreadStateTracks(): Promise<void> {
- const query = await this.engine.query(`
+ const result = await this.engine.query(`
select
utid,
tid,
@@ -427,22 +557,19 @@ class TrackDecider {
where utid != 0
group by utid`);
- const it = iter(
- {
- utid: NUM,
- upid: NUM_NULL,
- tid: NUM_NULL,
- pid: NUM_NULL,
- threadName: STR_NULL,
- },
- query);
- for (let i = 0; it.valid(); ++i, it.next()) {
- const row = it.row;
- const utid = row.utid;
- const tid = row.tid;
- const upid = row.upid;
- const pid = row.pid;
- const threadName = row.threadName;
+ const it = result.iter({
+ utid: NUM,
+ upid: NUM_NULL,
+ tid: NUM_NULL,
+ pid: NUM_NULL,
+ threadName: STR_NULL,
+ });
+ for (; it.valid(); it.next()) {
+ const utid = it.utid;
+ const tid = it.tid;
+ const upid = it.upid;
+ const pid = it.pid;
+ const threadName = it.threadName;
const uuid = this.getUuidUnchecked(utid, upid);
if (uuid === undefined) {
// If a thread has no scheduling activity (i.e. the sched table has zero
@@ -464,7 +591,7 @@ class TrackDecider {
}
async addThreadCpuSampleTracks(): Promise<void> {
- const query = await this.engine.query(`
+ const result = await this.engine.query(`
select
utid,
tid,
@@ -479,19 +606,16 @@ class TrackDecider {
where utid != 0
group by utid`);
- const it = iter(
- {
- utid: NUM,
- upid: NUM_NULL,
- tid: NUM_NULL,
- threadName: STR_NULL,
- },
- query);
- for (let i = 0; it.valid(); ++i, it.next()) {
- const row = it.row;
- const utid = row.utid;
- const upid = row.upid;
- const threadName = row.threadName;
+ const it = result.iter({
+ utid: NUM,
+ upid: NUM_NULL,
+ tid: NUM_NULL,
+ threadName: STR_NULL,
+ });
+ for (; it.valid(); it.next()) {
+ const utid = it.utid;
+ const upid = it.upid;
+ const threadName = it.threadName;
const uuid = this.getUuid(utid, upid);
this.tracksToAdd.push({
engineId: this.engineId,
@@ -506,7 +630,7 @@ class TrackDecider {
}
async addThreadCounterTracks(): Promise<void> {
- const query = await this.engine.query(`
+ const result = await this.engine.query(`
select
thread_counter_track.name as trackName,
utid,
@@ -522,29 +646,26 @@ class TrackDecider {
where thread_counter_track.name not in ('time_in_state', 'thread_time')
`);
- const it = iter(
- {
- trackName: STR_NULL,
- utid: NUM,
- upid: NUM_NULL,
- tid: NUM_NULL,
- threadName: STR_NULL,
- startTs: NUM_NULL,
- trackId: NUM,
- endTs: NUM_NULL,
- },
- query);
- for (let i = 0; it.valid(); ++i, it.next()) {
- const row = it.row;
- const utid = row.utid;
- const tid = row.tid;
- const upid = row.upid;
- const trackId = row.trackId;
- const trackName = row.trackName;
- const threadName = row.threadName;
+ const it = result.iter({
+ trackName: STR_NULL,
+ utid: NUM,
+ upid: NUM_NULL,
+ tid: NUM_NULL,
+ threadName: STR_NULL,
+ startTs: NUM_NULL,
+ trackId: NUM,
+ endTs: NUM_NULL,
+ });
+ for (; it.valid(); it.next()) {
+ const utid = it.utid;
+ const tid = it.tid;
+ const upid = it.upid;
+ const trackId = it.trackId;
+ const trackName = it.trackName;
+ const threadName = it.threadName;
const uuid = this.getUuid(utid, upid);
- const startTs = row.startTs === null ? undefined : row.startTs;
- const endTs = row.endTs === null ? undefined : row.endTs;
+ const startTs = it.startTs === null ? undefined : it.startTs;
+ const endTs = it.endTs === null ? undefined : it.endTs;
const kind = COUNTER_TRACK_KIND;
const name = TrackDecider.getTrackName(
{name: trackName, utid, tid, kind, threadName, threadTrack: true});
@@ -560,7 +681,7 @@ class TrackDecider {
}
async addProcessAsyncSliceTracks(): Promise<void> {
- const query = await this.engine.query(`
+ const result = await this.engine.query(`
select
process_track.upid as upid,
process_track.name as trackName,
@@ -569,38 +690,37 @@ class TrackDecider {
process.pid as pid
from process_track
left join process using(upid)
- where process_track.name not like "% Timeline"
+ where
+ process_track.name is null or
+ process_track.name not like "% Timeline"
group by
process_track.upid,
process_track.name
`);
- const it = iter(
- {
- upid: NUM,
- trackName: STR_NULL,
- trackIds: STR,
- processName: STR_NULL,
- pid: NUM_NULL,
- },
- query);
- for (let i = 0; it.valid(); ++i, it.next()) {
- const row = it.row;
- const upid = row.upid;
- const trackName = row.trackName;
- const rawTrackIds = row.trackIds;
+ const it = result.iter({
+ upid: NUM,
+ trackName: STR_NULL,
+ trackIds: STR,
+ processName: STR_NULL,
+ pid: NUM_NULL,
+ });
+ for (; it.valid(); it.next()) {
+ const upid = it.upid;
+ const trackName = it.trackName;
+ const rawTrackIds = it.trackIds;
const trackIds = rawTrackIds.split(',').map(v => Number(v));
- const processName = row.processName;
- const pid = row.pid;
+ const processName = it.processName;
+ const pid = it.pid;
const uuid = this.getUuid(0, upid);
// TODO(hjd): 1+N queries are bad in the track_decider
const depthResult = await this.engine.query(`
- SELECT MAX(layout_depth) as max_depth
+ SELECT IFNULL(MAX(layout_depth), 0) as depth
FROM experimental_slice_layout('${rawTrackIds}');
`);
- const maxDepth = +depthResult.columns[0].longValues![0];
+ const maxDepth = depthResult.firstRow({depth: NUM}).depth;
const kind = ASYNC_SLICE_TRACK_KIND;
const name = TrackDecider.getTrackName(
@@ -620,7 +740,7 @@ class TrackDecider {
}
async addActualFramesTracks(): Promise<void> {
- const query = await this.engine.query(`
+ const result = await this.engine.query(`
select
upid,
trackName,
@@ -640,32 +760,29 @@ class TrackDecider {
) left join process using(upid)
`);
- const it = iter(
- {
- upid: NUM,
- trackName: STR_NULL,
- trackIds: STR,
- processName: STR_NULL,
- pid: NUM_NULL,
- },
- query);
- for (let i = 0; it.valid(); ++i, it.next()) {
- const row = it.row;
- const upid = row.upid;
- const trackName = row.trackName;
- const rawTrackIds = row.trackIds;
+ const it = result.iter({
+ upid: NUM,
+ trackName: STR_NULL,
+ trackIds: STR,
+ processName: STR_NULL,
+ pid: NUM_NULL,
+ });
+ for (; it.valid(); it.next()) {
+ const upid = it.upid;
+ const trackName = it.trackName;
+ const rawTrackIds = it.trackIds;
const trackIds = rawTrackIds.split(',').map(v => Number(v));
- const processName = row.processName;
- const pid = row.pid;
+ const processName = it.processName;
+ const pid = it.pid;
const uuid = this.getUuid(0, upid);
// TODO(hjd): 1+N queries are bad in the track_decider
const depthResult = await this.engine.query(`
- SELECT MAX(layout_depth) as max_depth
+ SELECT IFNULL(MAX(layout_depth), 0) as depth
FROM experimental_slice_layout('${rawTrackIds}');
`);
- const maxDepth = +depthResult.columns[0].longValues![0];
+ const maxDepth = depthResult.firstRow({depth: NUM}).depth;
const kind = ACTUAL_FRAMES_SLICE_TRACK_KIND;
const name = TrackDecider.getTrackName(
@@ -685,7 +802,7 @@ class TrackDecider {
}
async addExpectedFramesTracks(): Promise<void> {
- const query = await this.engine.query(`
+ const result = await this.engine.query(`
select
upid,
trackName,
@@ -705,32 +822,30 @@ class TrackDecider {
) left join process using(upid)
`);
- const it = iter(
- {
- upid: NUM,
- trackName: STR_NULL,
- trackIds: STR,
- processName: STR_NULL,
- pid: NUM_NULL,
- },
- query);
- for (let i = 0; it.valid(); ++i, it.next()) {
- const row = it.row;
- const upid = row.upid;
- const trackName = row.trackName;
- const rawTrackIds = row.trackIds;
+ const it = result.iter({
+ upid: NUM,
+ trackName: STR_NULL,
+ trackIds: STR,
+ processName: STR_NULL,
+ pid: NUM_NULL,
+ });
+
+ for (; it.valid(); it.next()) {
+ const upid = it.upid;
+ const trackName = it.trackName;
+ const rawTrackIds = it.trackIds;
const trackIds = rawTrackIds.split(',').map(v => Number(v));
- const processName = row.processName;
- const pid = row.pid;
+ const processName = it.processName;
+ const pid = it.pid;
const uuid = this.getUuid(0, upid);
// TODO(hjd): 1+N queries are bad in the track_decider
const depthResult = await this.engine.query(`
- SELECT MAX(layout_depth) as max_depth
+ SELECT IFNULL(MAX(layout_depth), 0) as depth
FROM experimental_slice_layout('${rawTrackIds}');
`);
- const maxDepth = +depthResult.columns[0].longValues![0];
+ const maxDepth = depthResult.firstRow({depth: NUM}).depth;
const kind = EXPECTED_FRAMES_SLICE_TRACK_KIND;
const name = TrackDecider.getTrackName(
@@ -750,45 +865,46 @@ class TrackDecider {
}
async addThreadSliceTracks(): Promise<void> {
- const query = await this.engine.query(`
+ const result = await this.engine.query(`
select
thread_track.utid as utid,
thread_track.id as trackId,
thread_track.name as trackName,
tid,
thread.name as threadName,
- max(depth) as maxDepth,
+ max(slice.depth) as maxDepth,
+ (count(thread_slice.id) = count(slice.id)) as onlyThreadSlice,
process.upid as upid,
process.pid as pid
from slice
join thread_track on slice.track_id = thread_track.id
join thread using(utid)
left join process using(upid)
+ left join thread_slice on slice.id = thread_slice.id
group by thread_track.id
`);
- const it = iter(
- {
- utid: NUM,
- trackId: NUM,
- trackName: STR_NULL,
- tid: NUM_NULL,
- threadName: STR_NULL,
- maxDepth: NUM,
- upid: NUM_NULL,
- pid: NUM_NULL,
- },
- query);
- for (let i = 0; it.valid(); ++i, it.next()) {
- const row = it.row;
- const utid = row.utid;
- const trackId = row.trackId;
- const trackName = row.trackName;
- const tid = row.tid;
- const threadName = row.threadName;
- const upid = row.upid;
- const pid = row.pid;
- const maxDepth = row.maxDepth;
+ const it = result.iter({
+ utid: NUM,
+ trackId: NUM,
+ trackName: STR_NULL,
+ tid: NUM_NULL,
+ threadName: STR_NULL,
+ maxDepth: NUM,
+ upid: NUM_NULL,
+ pid: NUM_NULL,
+ onlyThreadSlice: NUM,
+ });
+ for (; it.valid(); it.next()) {
+ const utid = it.utid;
+ const trackId = it.trackId;
+ const trackName = it.trackName;
+ const tid = it.tid;
+ const threadName = it.threadName;
+ const upid = it.upid;
+ const pid = it.pid;
+ const maxDepth = it.maxDepth;
+ const onlyThreadSlice = it.onlyThreadSlice;
const trackKindPriority =
TrackDecider.inferTrackKindPriority(threadName, tid, pid);
@@ -803,13 +919,24 @@ class TrackDecider {
name,
trackGroup: uuid,
trackKindPriority,
- config: {trackId, maxDepth, tid}
+ config: {trackId, maxDepth, tid, isThreadSlice: onlyThreadSlice === 1}
});
+
+ if (TRACKS_V2_FLAG.get()) {
+ this.tracksToAdd.push({
+ engineId: this.engineId,
+ kind: 'GenericSliceTrack',
+ name,
+ trackGroup: uuid,
+ trackKindPriority,
+ config: {sqlTrackId: trackId},
+ });
+ }
}
}
async addProcessCounterTracks(): Promise<void> {
- const query = await this.engine.query(`
+ const result = await this.engine.query(`
select
process_counter_track.id as trackId,
process_counter_track.name as trackName,
@@ -821,27 +948,24 @@ class TrackDecider {
from process_counter_track
join process using(upid);
`);
- const it = iter(
- {
- trackId: NUM,
- trackName: STR_NULL,
- upid: NUM,
- pid: NUM_NULL,
- processName: STR_NULL,
- startTs: NUM_NULL,
- endTs: NUM_NULL,
- },
- query);
+ const it = result.iter({
+ trackId: NUM,
+ trackName: STR_NULL,
+ upid: NUM,
+ pid: NUM_NULL,
+ processName: STR_NULL,
+ startTs: NUM_NULL,
+ endTs: NUM_NULL,
+ });
for (let i = 0; it.valid(); ++i, it.next()) {
- const row = it.row;
- const pid = row.pid;
- const upid = row.upid;
- const trackId = row.trackId;
- const trackName = row.trackName;
- const processName = row.processName;
+ const pid = it.pid;
+ const upid = it.upid;
+ const trackId = it.trackId;
+ const trackName = it.trackName;
+ const processName = it.processName;
const uuid = this.getUuid(0, upid);
- const startTs = row.startTs === null ? undefined : row.startTs;
- const endTs = row.endTs === null ? undefined : row.endTs;
+ const startTs = it.startTs === null ? undefined : it.startTs;
+ const endTs = it.endTs === null ? undefined : it.endTs;
const kind = COUNTER_TRACK_KIND;
const name = TrackDecider.getTrackName(
{name: trackName, upid, pid, kind, processName});
@@ -862,14 +986,13 @@ class TrackDecider {
}
async addProcessHeapProfileTracks(): Promise<void> {
- const query = await this.engine.query(`
+ const result = await this.engine.query(`
select distinct(upid) from heap_profile_allocation
union
select distinct(upid) from heap_graph_object
`);
- const it = iter({upid: NUM}, query);
- for (let i = 0; it.valid(); ++i, it.next()) {
- const upid = it.row.upid;
+ for (const it = result.iter({upid: NUM}); it.valid(); it.next()) {
+ const upid = it.upid;
const uuid = this.getUuid(0, upid);
this.tracksToAdd.push({
engineId: this.engineId,
@@ -882,6 +1005,26 @@ class TrackDecider {
}
}
+ async addProcessPerfSamplesTracks(): Promise<void> {
+ const result = await this.engine.query(`
+ select distinct(process.upid) from process
+ join thread on process.upid = thread.upid
+ join perf_sample on thread.utid = perf_sample.utid
+ `);
+ for (const it = result.iter({upid: NUM}); it.valid(); it.next()) {
+ const upid = it.upid;
+ const uuid = this.getUuid(0, upid);
+ this.tracksToAdd.push({
+ engineId: this.engineId,
+ kind: PERF_SAMPLES_PROFILE_TRACK_KIND,
+ trackKindPriority: TrackKindPriority.ORDINARY,
+ name: `Perf Samples`,
+ trackGroup: uuid,
+ config: {upid}
+ });
+ }
+ }
+
getUuidUnchecked(utid: number, upid: number|null) {
return upid === null ? this.utidToUuid.get(utid) :
this.upidToUuid.get(upid);
@@ -910,11 +1053,12 @@ class TrackDecider {
// by upid
// or (if upid is null) by utid
// the groups should be sorted by:
+ // Chrome-based process rank based on process names (e.g. Browser)
// has a heap profile or not
// total cpu time *for the whole parent process*
// upid
// utid
- const query = await this.engine.query(`
+ const result = await this.engine.query(`
select
the_tracks.upid,
the_tracks.utid,
@@ -923,7 +1067,14 @@ class TrackDecider {
process.pid as pid,
thread.tid as tid,
process.name as processName,
- thread.name as threadName
+ thread.name as threadName,
+ process.arg_set_id as argSetId,
+ (case process.name
+ when 'Browser' then 3
+ when 'Gpu' then 2
+ when 'Renderer' then 1
+ else 0
+ end) as chromeProcessRank
from (
select upid, 0 as utid from process_track
union
@@ -935,6 +1086,10 @@ class TrackDecider {
union
select upid, utid from sched join thread using(utid) group by utid
union
+ select distinct(process.upid), 0 as utid from process
+ join thread on process.upid = thread.upid
+ join perf_sample on thread.utid = perf_sample.utid
+ union
select upid, utid from (
select distinct(utid) from cpu_profile_stack_sample
) join thread using(utid)
@@ -947,7 +1102,7 @@ class TrackDecider {
from sched join thread using(utid)
group by upid
) using(upid)
- left join (select upid, sum(value) as total_cycles
+ left join (select upid, max(value) as total_cycles
from android_thread_time_in_state_event
group by upid
) using(upid)
@@ -965,6 +1120,7 @@ class TrackDecider {
left join thread using(utid)
left join process using(upid)
order by
+ chromeProcessRank desc,
hasHeapProfiles desc,
total_dur desc,
total_cycles desc,
@@ -972,28 +1128,41 @@ class TrackDecider {
the_tracks.utid;
`);
- const it = iter(
- {
- utid: NUM,
- upid: NUM_NULL,
- tid: NUM_NULL,
- pid: NUM_NULL,
- threadName: STR_NULL,
- processName: STR_NULL,
- hasSched: NUM_NULL,
- hasHeapProfiles: NUM_NULL,
- },
- query);
- for (let i = 0; it.valid(); ++i, it.next()) {
- const row = it.row;
- const utid = row.utid;
- const tid = row.tid;
- const upid = row.upid;
- const pid = row.pid;
- const threadName = row.threadName;
- const processName = row.processName;
- const hasSched = !!row.hasSched;
- const hasHeapProfiles = !!row.hasHeapProfiles;
+ const it = result.iter({
+ utid: NUM,
+ upid: NUM_NULL,
+ tid: NUM_NULL,
+ pid: NUM_NULL,
+ threadName: STR_NULL,
+ processName: STR_NULL,
+ hasSched: NUM_NULL,
+ hasHeapProfiles: NUM_NULL,
+ argSetId: NUM_NULL
+ });
+ for (; it.valid(); it.next()) {
+ const utid = it.utid;
+ const tid = it.tid;
+ const upid = it.upid;
+ const pid = it.pid;
+ const threadName = it.threadName;
+ const processName = it.processName;
+ const hasSched = !!it.hasSched;
+ const hasHeapProfiles = !!it.hasHeapProfiles;
+
+ const labels = [];
+ if (it.argSetId !== null) {
+ const result = await this.engine.query(`
+ select string_value as label
+ from args
+ where arg_set_id = ${it.argSetId}
+ `);
+ const argIt = result.iter({label: STR_NULL});
+ for (; argIt.valid(); argIt.next()) {
+ if (argIt.label !== null) {
+ labels.push(argIt.label);
+ }
+ }
+ }
// Group by upid if present else by utid.
let pUuid =
@@ -1014,6 +1183,7 @@ class TrackDecider {
trackKindPriority: TrackDecider.inferTrackKindPriority(threadName),
name: `${upid === null ? tid : pid} summary`,
config: {pidForColor, upid, utid, tid},
+ labels,
});
const name = TrackDecider.getTrackName(
@@ -1023,6 +1193,9 @@ class TrackDecider {
summaryTrackId,
name,
id: pUuid,
+ // Perf profiling tracks remain collapsed, otherwise we would have too
+ // many expanded process tracks for some perf traces, leading to
+ // jankyness.
collapsed: !hasHeapProfiles,
});
@@ -1038,6 +1211,8 @@ class TrackDecider {
await this.addGlobalAsyncTracks();
await this.addGpuFreqTracks();
await this.addGlobalCounterTracks();
+ await this.addCpuPerfCounterTracks();
+ await this.addAnnotationTracks();
await this.groupGlobalIonTracks();
// Create the per-process track groups. Note that this won't necessarily
@@ -1047,6 +1222,9 @@ class TrackDecider {
await this.addProcessTrackGroups();
await this.addProcessHeapProfileTracks();
+ if (PERF_SAMPLE_FLAG.get()) {
+ await this.addProcessPerfSamplesTracks();
+ }
await this.addProcessCounterTracks();
await this.addProcessAsyncSliceTracks();
await this.addActualFramesTracks();
@@ -1056,7 +1234,6 @@ class TrackDecider {
await this.addThreadSliceTracks();
await this.addThreadCpuSampleTracks();
await this.addLogsTrack();
- await this.addAnnotationTracks();
this.addTrackGroupActions.push(
Actions.addTracks({tracks: this.tracksToAdd}));
@@ -1073,6 +1250,24 @@ class TrackDecider {
return TrackKindPriority.ORDINARY;
}
+ // Chrome main threads should always come first within their process.
+ if (threadName === 'CrBrowserMain' || threadName === 'CrRendererMain' ||
+ threadName === 'CrGpuMain') {
+ return TrackKindPriority.MAIN_THREAD;
+ }
+
+ // Chrome IO threads should always come immediately after the main thread.
+ if (threadName === 'Chrome_ChildIOThread' ||
+ threadName === 'Chrome_IOThread') {
+ return TrackKindPriority.CHROME_IO_THREAD;
+ }
+
+ // A Chrome process can have only one compositor thread, so we want to put
+ // it next to other named processes.
+ if (threadName === 'Compositor' || threadName === 'VizCompositorThread') {
+ return TrackKindPriority.CHROME_COMPOSITOR;
+ }
+
switch (true) {
case /.*RenderThread.*/.test(threadName):
return TrackKindPriority.RENDER_THREAD;
diff --git a/ui/src/controller/validate_config.ts b/ui/src/controller/validate_config.ts
deleted file mode 100644
index 015131fce..000000000
--- a/ui/src/controller/validate_config.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import {createEmptyRecordConfig, RecordConfig} from '../common/state';
-
-interface RecordConfigValidationResult {
- config: RecordConfig;
- errorMessage?: string;
-}
-
-export function validateRecordConfig(
- config: {[key: string]: string|number|boolean|string[]|null}):
- RecordConfigValidationResult {
- // Remove the keys that are not in both createEmptyRecordConfig and
- // config.
- const newConfig: RecordConfig = createEmptyRecordConfig();
- const ignoredKeys: string[] = [];
- // TODO(bsebastien): Also check that types of properties match.
- Object.entries(newConfig).forEach(([key, value]) => {
- if (key in config && typeof value === typeof config[key]) {
- newConfig[key] = config[key];
- } else {
- ignoredKeys.push(key);
- }
- });
-
- // Check if config has additional keys that are not in
- // createEmptyRecordConfig().
- for (const key of Object.keys(config)) {
- if (!(key in newConfig)) {
- ignoredKeys.push(key);
- }
- }
-
- if (ignoredKeys.length > 0) {
- // At least return an empty RecordConfig if nothing match.
- return {
- errorMessage: 'Warning: Loaded config contains incompatible keys.\n\
- It may have been created with an older version of the UI.\n\
- Ignored keys: ' +
- ignoredKeys.join(' '),
- config: newConfig,
- };
- }
- return {config: newConfig};
-}
diff --git a/ui/src/controller/validate_config_jsdomtest.ts b/ui/src/controller/validate_config_jsdomtest.ts
deleted file mode 100644
index 370d54a0f..000000000
--- a/ui/src/controller/validate_config_jsdomtest.ts
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import {createEmptyRecordConfig, RecordConfig} from '../common/state';
-import {validateRecordConfig} from './validate_config';
-
-test('validateRecordConfig test valid keys config', () => {
- const config: RecordConfig = createEmptyRecordConfig();
- const validationResult = validateRecordConfig(config);
-
- expect('errorMessage' in validationResult).toEqual(false);
-
- for (const key of Object.keys(validationResult.config)) {
- expect(key in config).toEqual(true);
- }
-});
-
-test('validateRecordConfig test no key config', () => {
- const emptyRecord: RecordConfig = createEmptyRecordConfig();
- const validationResult = validateRecordConfig({});
-
- expect('errorMessage' in validationResult).toEqual(true);
-
- for (const key of Object.keys(emptyRecord)) {
- expect(key in validationResult.config).toEqual(true);
- }
-});
-
-test('validateRecordConfig test some valid key config', () => {
- const emptyRecord: RecordConfig = createEmptyRecordConfig();
- const validationResult = validateRecordConfig({
- 'durationMs': 5.0,
- 'cpuSched': true,
- });
-
- expect('errorMessage' in validationResult).toEqual(true);
-
- expect(validationResult.config.durationMs).toEqual(5.0);
- expect(validationResult.config.cpuSched).toEqual(true);
-
- for (const key of Object.keys(emptyRecord)) {
- if (['durationMs', 'cpuSched'].includes(key) === false) {
- expect(validationResult.config[key]).toEqual(emptyRecord[key]);
- }
- expect(key in validationResult.config).toEqual(true);
- }
-});
-
-test('validateRecordConfig test some invalid key config', () => {
- const emptyRecord: RecordConfig = createEmptyRecordConfig();
- const validationResult = validateRecordConfig({
- 'durationMs': 5.0,
- 'invalidKey': 0,
- 'cpuSched': true,
- 'anotherInvalidKey': 'foobar',
- });
-
- expect('errorMessage' in validationResult).toEqual(true);
-
- expect(validationResult.config.durationMs).toEqual(5.0);
- expect(validationResult.config.cpuSched).toEqual(true);
- expect('invalidKey' in validationResult.config).toEqual(false);
- expect('anotherInvalidKey' in validationResult.config).toEqual(false);
-
- for (const key of Object.keys(emptyRecord)) {
- if (['durationMs', 'cpuSched'].includes(key) === false) {
- expect(validationResult.config[key]).toEqual(emptyRecord[key]);
- }
- expect(key in validationResult.config).toEqual(true);
- }
-});
-
-test('validateRecordConfig test only invalid key config', () => {
- const emptyRecord: RecordConfig = createEmptyRecordConfig();
- const validationResult = validateRecordConfig({
- 'invalidKey': 0,
- 'anotherInvalidKey': 'foobar',
- });
-
- expect('errorMessage' in validationResult).toEqual(true);
-
- expect('invalidKey' in validationResult.config).toEqual(false);
- expect('anotherInvalidKey' in validationResult.config).toEqual(false);
-
- for (const key of Object.keys(emptyRecord)) {
- expect(validationResult.config[key]).toEqual(emptyRecord[key]);
- expect(key in validationResult.config).toEqual(true);
- }
-});
diff --git a/ui/src/controller/validators.ts b/ui/src/controller/validators.ts
new file mode 100644
index 000000000..c35c69dd3
--- /dev/null
+++ b/ui/src/controller/validators.ts
@@ -0,0 +1,267 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Execution context of object validator
+interface ValidatorContext {
+ // Path to the current value starting from the root. Object field names are
+ // stored as is, array indices are wrapped to square brackets. Represented
+ // as an array to avoid unnecessary string concatenation: parts are going to
+ // be concatenated into a single string when reporting errors, which should
+ // not happen on a happy path.
+ // Example: ["config", "androidLogBuffers", "1"] when parsing object
+ // accessible through expression `root.config.androidLogBuffers[1]`
+ path: string[];
+
+ // Paths from the root to extraneous keys in a validated object.
+ extraKeys: string[];
+
+ // Paths from the root to keys containing values of wrong type in validated
+ // object.
+ invalidKeys: string[];
+}
+
+// Validator accepting arbitrary data structure and returning a typed value.
+// Can throw an error if a part of the value does not have a reasonable
+// default.
+export interface Validator<T> {
+ validate(input: unknown, context: ValidatorContext): T;
+}
+
+// Helper function to flatten array of path chunks into a single string
+// Example: ["config", "androidLogBuffers", "1"] is mapped to
+// "config.androidLogBuffers[1]".
+function renderPath(path: string[]): string {
+ let result = '';
+ for (let i = 0; i < path.length; i++) {
+ if (i > 0 && !path[i].startsWith('[')) {
+ result += '.';
+ }
+ result += path[i];
+ }
+ return result;
+}
+
+export class ValidationError extends Error {}
+
+// Abstract class for validating simple values, such as strings and booleans.
+// Allows to avoid repetition of most of the code related to validation of
+// these.
+abstract class PrimitiveValidator<T> implements Validator<T> {
+ defaultValue: T;
+ required: boolean;
+
+ constructor(defaultValue: T, required: boolean) {
+ this.defaultValue = defaultValue;
+ this.required = required;
+ }
+
+ // Abstract method that checks whether passed input has correct type.
+ abstract predicate(input: unknown): input is T;
+
+ validate(input: unknown, context: ValidatorContext): T {
+ if (this.predicate(input)) {
+ return input;
+ }
+ if (this.required) {
+ throw new ValidationError(renderPath(context.path));
+ }
+ if (input !== undefined) {
+ // The value is defined, but does not conform to the expected type;
+ // proceed with returning the default value but report the key.
+ context.invalidKeys.push(renderPath(context.path));
+ }
+ return this.defaultValue;
+ }
+}
+
+
+class StringValidator extends PrimitiveValidator<string> {
+ predicate(input: unknown): input is string {
+ return typeof input === 'string';
+ }
+}
+
+class NumberValidator extends PrimitiveValidator<number> {
+ predicate(input: unknown): input is number {
+ return typeof input === 'number';
+ }
+}
+
+class BooleanValidator extends PrimitiveValidator<boolean> {
+ predicate(input: unknown): input is boolean {
+ return typeof input === 'boolean';
+ }
+}
+
+// Type-level function returning resulting type of a validator.
+export type ValidatedType<T> = T extends Validator<infer S>? S : never;
+
+// Type-level function traversing a record of validator and returning record
+// with the same keys and valid types.
+export type RecordValidatedType<T> = {
+ [k in keyof T]: ValidatedType<T[k]>
+};
+
+// Combinator for validators: takes a record of validators, and returns a
+// validator for a record where record's fields passed to validator with the
+// same name.
+//
+// Generic parameter T is instantiated to type of record of validators, and
+// should be provided implicitly by type inference due to verbosity of its
+// instantiations.
+class RecordValidator<T extends Record<string, Validator<unknown>>> implements
+ Validator<RecordValidatedType<T>> {
+ validators: T;
+
+ constructor(validators: T) {
+ this.validators = validators;
+ }
+
+ validate(input: unknown, context: ValidatorContext): RecordValidatedType<T> {
+ // If value is missing or of incorrect type, empty record is still processed
+ // in the loop below to initialize default fields of the nested object.
+ let o: object = {};
+ if (typeof input === 'object' && input !== null) {
+ o = input;
+ } else if (input !== undefined) {
+ context.invalidKeys.push(renderPath(context.path));
+ }
+
+ const result: Partial<RecordValidatedType<T>> = {};
+ // Separate declaration is required to avoid assigning `string` type to `k`.
+ for (const k in this.validators) {
+ if (this.validators.hasOwnProperty(k)) {
+ context.path.push(k);
+ const validator = this.validators[k];
+
+ // Accessing value of `k` of `o` is safe because `undefined` values are
+ // considered to indicate a missing value and handled appropriately by
+ // every provided validator.
+ const valid =
+ validator.validate((o as Record<string, unknown>)[k], context);
+
+ result[k] = valid as ValidatedType<T[string]>;
+ context.path.pop();
+ }
+ }
+
+ // Check if passed object has any extra keys to be reported as such.
+ for (const key of Object.keys(o)) {
+ if (!this.validators.hasOwnProperty(key)) {
+ context.path.push(key);
+ context.extraKeys.push(renderPath(context.path));
+ context.path.pop();
+ }
+ }
+ return result as RecordValidatedType<T>;
+ }
+}
+
+// Validator checking whether a value is one of preset values. Used in order to
+// provide easy validation for union of literal types.
+class OneOfValidator<T> implements Validator<T> {
+ validValues: readonly T[];
+ defaultValue: T;
+
+ constructor(validValues: readonly T[], defaultValue: T) {
+ this.defaultValue = defaultValue;
+ this.validValues = validValues;
+ }
+
+ validate(input: unknown, context: ValidatorContext): T {
+ if (this.validValues.includes(input as T)) {
+ return input as T;
+ } else if (input !== undefined) {
+ context.invalidKeys.push(renderPath(context.path));
+ }
+ return this.defaultValue;
+ }
+}
+
+// Validator for an array of elements, applying the same element validator for
+// each element of an array. Uses empty array as a default value.
+class ArrayValidator<T> implements Validator<T[]> {
+ elementValidator: Validator<T>;
+
+ constructor(elementValidator: Validator<T>) {
+ this.elementValidator = elementValidator;
+ }
+
+ validate(input: unknown, context: ValidatorContext): T[] {
+ const result: T[] = [];
+ if (Array.isArray(input)) {
+ for (let i = 0; i < input.length; i++) {
+ context.path.push(`[${i}]`);
+ result.push(this.elementValidator.validate(input[i], context));
+ context.path.pop();
+ }
+ } else if (input !== undefined) {
+ context.invalidKeys.push(renderPath(context.path));
+ }
+ return result;
+ }
+}
+
+// Wrapper container for validation result contaiting diagnostic information in
+// addition to the resulting typed value.
+export interface ValidationResult<T> {
+ result: T;
+ invalidKeys: string[];
+ extraKeys: string[];
+}
+
+// Wrapper for running a validator initializing the context.
+export function runValidator<T>(
+ validator: Validator<T>, input: unknown): ValidationResult<T> {
+ const context: ValidatorContext = {
+ path: [],
+ invalidKeys: [],
+ extraKeys: [],
+ };
+ const result = validator.validate(input, context);
+ return {
+ result,
+ invalidKeys: context.invalidKeys,
+ extraKeys: context.extraKeys,
+ };
+}
+
+// Shorthands for the validator classes above enabling concise notation.
+export function str(defaultValue = ''): StringValidator {
+ return new StringValidator(defaultValue, false);
+}
+
+export const requiredStr = new StringValidator('', true);
+
+export function num(defaultValue = 0): NumberValidator {
+ return new NumberValidator(defaultValue, false);
+}
+
+export function bool(defaultValue = false): BooleanValidator {
+ return new BooleanValidator(defaultValue, false);
+}
+
+export function record<T extends Record<string, Validator<unknown>>>(
+ validators: T): RecordValidator<T> {
+ return new RecordValidator<T>(validators);
+}
+
+export function oneOf<T>(
+ values: readonly T[], defaultValue: T): OneOfValidator<T> {
+ return new OneOfValidator<T>(values, defaultValue);
+}
+
+export function arrayOf<T>(elementValidator: Validator<T>): ArrayValidator<T> {
+ return new ArrayValidator<T>(elementValidator);
+}
diff --git a/ui/src/controller/validators_unittest.ts b/ui/src/controller/validators_unittest.ts
new file mode 100644
index 000000000..4d54c5cf8
--- /dev/null
+++ b/ui/src/controller/validators_unittest.ts
@@ -0,0 +1,109 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {
+ arrayOf,
+ num,
+ oneOf,
+ record,
+ requiredStr,
+ runValidator,
+ ValidatedType,
+ ValidationError
+} from './validators';
+
+const colors = ['RED', 'GREEN', 'BLUE'] as const;
+
+type Color = typeof colors[number];
+
+const point = record({
+ id: requiredStr,
+ color: oneOf<Color>(colors, 'RED'),
+ x: num(),
+ y: num(1),
+ properties: record({mass: num(10)})
+});
+
+type Point = ValidatedType<typeof point>;
+
+const nested =
+ record({deeply: record({nested: record({array: arrayOf(point)})})});
+
+test('validator ensures presence of required fields', () => {
+ expect(() => {
+ runValidator(point, {});
+ }).toThrow(ValidationError);
+});
+
+test('validator ensures correct type of required fields', () => {
+ expect(() => {
+ runValidator(point, {id: 0});
+ }).toThrow(ValidationError);
+});
+
+test('validator fills default values', () => {
+ const p: Point = runValidator(point, {id: 'test'}).result;
+
+ expect(p.color).toEqual('RED');
+ expect(p.x).toEqual(0);
+ expect(p.y).toEqual(1);
+ expect(p.properties.mass).toEqual(10);
+});
+
+test('validator uses provided values', () => {
+ const p: Point =
+ runValidator(
+ point,
+ {id: 'test', x: 100, y: 200, color: 'GREEN', properties: {mass: 20}})
+ .result;
+
+ expect(p.color).toEqual('GREEN');
+ expect(p.x).toEqual(100);
+ expect(p.y).toEqual(200);
+ expect(p.properties.mass).toEqual(20);
+});
+
+test('validator keeps information about extra and invalid keys', () => {
+ const result = runValidator(point, {
+ id: 'test',
+ x: 'should not be a string',
+ extra: 'should not be here',
+ properties: {mass: 'should be a number', weight: 'should not be here'}
+ });
+
+ expect(result.extraKeys).toContain('extra');
+ expect(result.extraKeys).toContain('properties.weight');
+ expect(result.invalidKeys).toContain('x');
+ expect(result.invalidKeys).toContain('properties.mass');
+});
+
+test('validator correctly keeps track of path when reporting keys', () => {
+ const result = runValidator(nested, {
+ extra1: 0,
+ deeply: {
+ extra2: 1,
+ nested: {
+ array: [
+ {id: 'point1', x: 'should not be a string'},
+ {id: 'point2', extra3: 'should not be here'}
+ ]
+ }
+ }
+ });
+
+ expect(result.extraKeys).toContain('extra1');
+ expect(result.extraKeys).toContain('deeply.extra2');
+ expect(result.extraKeys).toContain('deeply.nested.array[1].extra3');
+ expect(result.invalidKeys).toContain('deeply.nested.array[0].x');
+});
diff --git a/ui/src/engine/index.ts b/ui/src/engine/index.ts
index 7c4916b72..8a7c27e60 100644
--- a/ui/src/engine/index.ts
+++ b/ui/src/engine/index.ts
@@ -12,32 +12,30 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import * as init_trace_processor from '../gen/trace_processor';
+import {assertExists} from '../base/logging';
+import {EngineWorkerInitMessage} from '../common/worker_messages';
+import {WasmBridge} from './wasm_bridge';
-import {WasmBridge, WasmBridgeRequest} from './wasm_bridge';
+const selfWorker = self as {} as Worker;
+const wasmBridge = new WasmBridge();
-// tslint:disable no-any
-// Proxy all messages to WasmBridge#callWasm.
-const anySelf = (self as any);
+// There are two message handlers here:
+// 1. The Worker (self.onmessage) handler.
+// 2. The MessagePort handler.
+// When the app bootstraps, frontend/index.ts creates a MessageChannel and sends
+// one end to the controller (the other worker) and the other end to us, so that
+// the controller can interact with the Wasm worker without roundtrips through
+// the frontend.
+// The sequence of actions is the following:
+// 1. The frontend does one postMessage({port: MessagePort}) on the Worker
+// scope. This message transfers the MessagePort (whose other end is
+// connected to the Conotroller). This is the only postMessage we'll ever
+// receive here.
+// 2. All the other messages (i.e. the TraceProcessor RPC binary pipe) will be
+// received on the MessagePort.
-// Messages can arrive before we are initialized, queue these for later.
-const msgQueue: MessageEvent[] = [];
-anySelf.onmessage = (msg: MessageEvent) => {
- msgQueue.push(msg);
+// Receives the boostrap message from the frontend with the MessagePort.
+selfWorker.onmessage = (msg: MessageEvent) => {
+ const port = assertExists((msg.data as EngineWorkerInitMessage).enginePort);
+ wasmBridge.initialize(port);
};
-
-const bridge = new WasmBridge(init_trace_processor);
-bridge.whenInitialized.then(() => {
- const handleMsg = (msg: MessageEvent) => {
- const request: WasmBridgeRequest = msg.data;
- anySelf.postMessage(bridge.callWasm(request));
- };
-
- // Dispatch queued messages.
- let msg;
- while (msg = msgQueue.shift()) {
- handleMsg(msg);
- }
-
- anySelf.onmessage = handleMsg;
-});
diff --git a/ui/src/engine/wasm_bridge.ts b/ui/src/engine/wasm_bridge.ts
index fe896b169..79e7e6580 100644
--- a/ui/src/engine/wasm_bridge.ts
+++ b/ui/src/engine/wasm_bridge.ts
@@ -23,33 +23,29 @@ import * as init_trace_processor from '../gen/trace_processor';
// HEAPU8[reqBufferAddr, +REQ_BUFFER_SIZE].
const REQ_BUF_SIZE = 32 * 1024 * 1024;
-export interface WasmBridgeRequest {
- id: number;
- methodName: string;
- data: Uint8Array;
-}
-
-export interface WasmBridgeResponse {
- id: number;
- data: Uint8Array;
-}
-
+// The end-to-end interaction between JS and Wasm is as follows:
+// - [JS] Inbound data received by the worker (onmessage() in engine/index.ts).
+// - [JS] onRpcDataReceived() (this file)
+// - [C++] trace_processor_on_rpc_request (wasm_bridge.cc)
+// - [C++] some TraceProcessor::method()
+// for (batch in result_rows)
+// - [C++] RpcResponseFunction(bytes) (wasm_bridge.cc)
+// - [JS] onReply() (this file)
+// - [JS] postMessage() (this file)
export class WasmBridge {
// When this promise has resolved it is safe to call callWasm.
whenInitialized: Promise<void>;
private aborted: boolean;
- private currentRequestResult: WasmBridgeResponse|null;
private connection: init_trace_processor.Module;
private reqBufferAddr = 0;
private lastStderr: string[] = [];
+ private messagePort?: MessagePort;
- constructor(init: init_trace_processor.InitWasm) {
+ constructor() {
this.aborted = false;
- this.currentRequestResult = null;
-
const deferredRuntimeInitialized = defer<void>();
- this.connection = init({
+ this.connection = init_trace_processor({
locateFile: (s: string) => s,
print: (line: string) => console.log(line),
printErr: (line: string) => this.appendAndLogErr(line),
@@ -58,49 +54,61 @@ export class WasmBridge {
this.whenInitialized = deferredRuntimeInitialized.then(() => {
const fn = this.connection.addFunction(this.onReply.bind(this), 'vii');
this.reqBufferAddr = this.connection.ccall(
- 'Initialize',
+ 'trace_processor_rpc_init',
/*return=*/ 'number',
/*args=*/['number', 'number'],
[fn, REQ_BUF_SIZE]);
});
}
- callWasm(req: WasmBridgeRequest): WasmBridgeResponse {
+ initialize(port: MessagePort) {
+ // Ensure that initialize() is called only once.
+ assertTrue(this.messagePort === undefined);
+ this.messagePort = port;
+ // Note: setting .onmessage implicitly calls port.start() and dispatches the
+ // queued messages. addEventListener('message') doesn't.
+ this.messagePort.onmessage = this.onMessage.bind(this);
+ }
+
+ onMessage(msg: MessageEvent) {
if (this.aborted) {
throw new Error('Wasm module crashed');
}
- assertTrue(req.data.length <= REQ_BUF_SIZE);
- const endAddr = this.reqBufferAddr + req.data.length;
- this.connection.HEAPU8.subarray(this.reqBufferAddr, endAddr).set(req.data);
- try {
- this.connection.ccall(
- req.methodName, // C method name.
- 'void', // Return type.
- ['number'], // Arg types.
- [req.data.length] // Args.
- );
- const result = assertExists(this.currentRequestResult);
- this.currentRequestResult = null;
- result.id = req.id;
- return result;
- } catch (err) {
- this.aborted = true;
- let abortReason = `${err}`;
- if (err instanceof Error) {
- abortReason = `${err.name}: ${err.message}\n${err.stack}`;
+ assertTrue(msg.data instanceof Uint8Array);
+ const data = msg.data as Uint8Array;
+ let wrSize = 0;
+ // If the request data is larger than our JS<>Wasm interop buffer, split it
+ // into multiple writes. The RPC channel is byte-oriented and is designed to
+ // deal with arbitrary fragmentations.
+ while (wrSize < data.length) {
+ const sliceLen = Math.min(data.length - wrSize, REQ_BUF_SIZE);
+ const dataSlice = data.subarray(wrSize, wrSize + sliceLen);
+ this.connection.HEAPU8.set(dataSlice, this.reqBufferAddr);
+ wrSize += sliceLen;
+ try {
+ this.connection.ccall(
+ 'trace_processor_on_rpc_request', // C function name.
+ 'void', // Return type.
+ ['number'], // Arg types.
+ [sliceLen] // Args.
+ );
+ } catch (err) {
+ this.aborted = true;
+ let abortReason = `${err}`;
+ if (err instanceof Error) {
+ abortReason = `${err.name}: ${err.message}\n${err.stack}`;
+ }
+ abortReason += '\n\nstderr: \n' + this.lastStderr.join('\n');
+ throw new Error(abortReason);
}
- abortReason += '\n\nstderr: \n' + this.lastStderr.join('\n');
- throw new Error(abortReason);
- }
+ } // while(wrSize < data.length)
}
- // This is invoked from ccall in the same call stack as callWasm.
+ // This function is bound and passed to Initialize and is called by the C++
+ // code while in the ccall(trace_processor_on_rpc_request).
private onReply(heapPtr: number, size: number) {
const data = this.connection.HEAPU8.slice(heapPtr, heapPtr + size);
- this.currentRequestResult = {
- id: 0, // Will be set by callWasm()'s epilogue.
- data,
- };
+ assertExists(this.messagePort).postMessage(data, [data.buffer]);
}
private appendAndLogErr(line: string) {
diff --git a/ui/src/frontend/analytics.ts b/ui/src/frontend/analytics.ts
index 076ed4891..a16c624f4 100644
--- a/ui/src/frontend/analytics.ts
+++ b/ui/src/frontend/analytics.ts
@@ -12,18 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import {getCurrentChannel} from '../common/channels';
import {globals} from '../frontend/globals';
import * as version from '../gen/perfetto_version';
+import {Router} from './router';
+
type TraceCategories = 'Trace Actions'|'Record Trace'|'User Actions';
const ANALYTICS_ID = 'UA-137828855-1';
const PAGE_TITLE = 'no-page-title';
export function initAnalytics() {
- // Only initialize logging on prod or staging
- if (window.location.origin.startsWith('http://localhost:') ||
- window.location.origin.endsWith('.perfetto.dev') ||
- window.location.origin.endsWith('staging-dot-perfetto-ui.appspot.com')) {
+ // Only initialize logging on the official site and on localhost (to catch
+ // analytics bugs when testing locally).
+ // Skip analytics is the fragment has "testing=1", this is used by UI tests.
+ if ((window.location.origin.startsWith('http://localhost:') ||
+ window.location.origin.endsWith('.perfetto.dev')) &&
+ !globals.testing) {
return new AnalyticsImpl();
}
return new NullAnalytics();
@@ -40,6 +45,7 @@ export interface Analytics {
updatePath(_: string): void;
logEvent(_x: TraceCategories|null, _y: string): void;
logError(_x: string, _y?: boolean): void;
+ isEnabled(): boolean;
}
export class NullAnalytics implements Analytics {
@@ -47,6 +53,9 @@ export class NullAnalytics implements Analytics {
updatePath(_: string) {}
logEvent(_x: TraceCategories|null, _y: string) {}
logError(_x: string) {}
+ isEnabled(): boolean {
+ return false;
+ }
}
class AnalyticsImpl implements Analytics {
@@ -81,7 +90,7 @@ class AnalyticsImpl implements Analytics {
script.src = 'https://www.googletagmanager.com/gtag/js?id=' + ANALYTICS_ID;
script.defer = true;
document.head.appendChild(script);
- const route = globals.state.route || '/';
+ const route = Router.parseUrl(window.location.href).page || '/';
console.log(
`GA initialized. route=${route}`,
`isInternalUser=${globals.isInternalUser}`);
@@ -97,7 +106,7 @@ class AnalyticsImpl implements Analytics {
page_title: PAGE_TITLE,
dimension1: globals.isInternalUser ? '1' : '0',
dimension2: version.VERSION,
- dimension3: globals.channel,
+ dimension3: getCurrentChannel(),
});
this.updatePath(route);
}
@@ -114,4 +123,8 @@ class AnalyticsImpl implements Analytics {
logError(description: string, fatal = true) {
gtagGlobals.gtag('event', 'exception', {description, fatal});
}
+
+ isEnabled(): boolean {
+ return true;
+ }
}
diff --git a/ui/src/frontend/analyze_page.ts b/ui/src/frontend/analyze_page.ts
index 2585ebcf7..c46465125 100644
--- a/ui/src/frontend/analyze_page.ts
+++ b/ui/src/frontend/analyze_page.ts
@@ -26,6 +26,7 @@ const INPUT_MIN_LINES = 2;
const INPUT_MAX_LINES = 10;
const INPUT_LINE_HEIGHT_EM = 1.2;
const TAB_SPACES = 2;
+const TAB_SPACES_STRING = ' '.repeat(TAB_SPACES);
const QUERY_ID = 'analyze-page-query';
class QueryInput implements m.ClassComponent {
@@ -35,10 +36,14 @@ class QueryInput implements m.ClassComponent {
static onKeyDown(e: Event) {
const event = e as KeyboardEvent;
const target = e.target as HTMLTextAreaElement;
+ const {selectionStart, selectionEnd} = target;
if (event.code === 'Enter' && (event.metaKey || event.ctrlKey)) {
event.preventDefault();
- const query = target.value;
+ let query = target.value;
+ if (selectionEnd > selectionStart) {
+ query = query.substring(selectionStart, selectionEnd);
+ }
if (!query) return;
globals.dispatch(
Actions.executeQuery({engineId: '0', queryId: QUERY_ID, query}));
@@ -47,14 +52,62 @@ class QueryInput implements m.ClassComponent {
if (event.code === 'Tab') {
// Handle tabs to insert spaces.
event.preventDefault();
- const whitespace = ' '.repeat(TAB_SPACES);
- const {selectionStart, selectionEnd} = target;
- target.value = target.value.substring(0, selectionStart) + whitespace +
- target.value.substring(selectionEnd);
- target.selectionEnd = selectionStart + TAB_SPACES;
+ const lastLineBreak = target.value.lastIndexOf('\n', selectionEnd);
+
+ if (selectionStart === selectionEnd || lastLineBreak < selectionStart) {
+ // Selection does not contain line breaks, therefore is on a single
+ // line. In this case, replace the selection with spaces. Replacement is
+ // done via document.execCommand as opposed to direct manipulation of
+ // element's value attribute because modifying latter programmatically
+ // drops the edit history which breaks undo/redo functionality.
+ document.execCommand('insertText', false, TAB_SPACES_STRING);
+ } else {
+ this.handleMultilineTab(target, event);
+ }
}
}
+ // Handle Tab press when the current selection is multiline: find all the
+ // lines intersecting with the selection, and either indent or dedent (if
+ // Shift key is held) them.
+ private static handleMultilineTab(
+ target: HTMLTextAreaElement, event: KeyboardEvent) {
+ const {selectionStart, selectionEnd} = target;
+ const firstLineBreak = target.value.lastIndexOf('\n', selectionStart - 1);
+
+ // If no line break is found (selection begins at the first line),
+ // replacementStart would have the correct value of 0.
+ const replacementStart = firstLineBreak + 1;
+ const replacement = target.value.substring(replacementStart, selectionEnd)
+ .split('\n')
+ .map((line) => {
+ if (event.shiftKey) {
+ // When Shift is held, remove whitespace at the
+ // beginning
+ return this.dedent(line);
+ } else {
+ return TAB_SPACES_STRING + line;
+ }
+ })
+ .join('\n');
+ // Select the range to be replaced.
+ target.setSelectionRange(replacementStart, selectionEnd);
+ document.execCommand('insertText', false, replacement);
+ // Restore the selection to match the previous selection, allowing to chain
+ // indent operations by just pressing Tab several times.
+ target.setSelectionRange(
+ replacementStart, replacementStart + replacement.length);
+ }
+
+ // Chop off up to TAB_SPACES leading spaces from a string.
+ private static dedent(line: string): string {
+ let i = 0;
+ while (i < line.length && i < TAB_SPACES && line[i] === ' ') {
+ i++;
+ }
+ return line.substring(i);
+ }
+
onInput(textareaValue: string) {
const textareaLines = textareaValue.split('\n').length;
const clampedNumLines =
diff --git a/ui/src/frontend/android_bug_tool.ts b/ui/src/frontend/android_bug_tool.ts
index ff63f5825..4c86873e8 100644
--- a/ui/src/frontend/android_bug_tool.ts
+++ b/ui/src/frontend/android_bug_tool.ts
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import {defer} from '../base/deferred';
enum WebContentScriptMessageType {
diff --git a/ui/src/frontend/base_slice_track.ts b/ui/src/frontend/base_slice_track.ts
new file mode 100644
index 000000000..0b113660c
--- /dev/null
+++ b/ui/src/frontend/base_slice_track.ts
@@ -0,0 +1,735 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {assertExists} from '../base/logging';
+import {Actions} from '../common/actions';
+import {cropText, drawIncompleteSlice} from '../common/canvas_utils';
+import {colorCompare, colorToStr, GRAY_COLOR} from '../common/colorizer';
+import {NUM, QueryResult} from '../common/query_result';
+import {SelectionKind} from '../common/state';
+import {fromNs, toNs} from '../common/time';
+
+import {checkerboardExcept} from './checkerboard';
+import {globals} from './globals';
+import {Slice} from './slice';
+import {DEFAULT_SLICE_LAYOUT, SliceLayout} from './slice_layout';
+import {NewTrackArgs, SliceRect, Track} from './track';
+
+// The common class that underpins all tracks drawing slices.
+
+export const SLICE_FLAGS_INCOMPLETE = 1;
+export const SLICE_FLAGS_INSTANT = 2;
+
+// Slices smaller than this don't get any text:
+const SLICE_MIN_WIDTH_FOR_TEXT_PX = 5;
+// Slices smaller than this aren't rendered at all.
+const SLICE_MIN_WIDTH_PX = 0.1;
+const CHEVRON_WIDTH_PX = 10;
+const DEFAULT_SLICE_COLOR = GRAY_COLOR;
+
+// TODO(hjd): Implement caching.
+
+// The minimal set of columns that any table/view must expose to render tracks.
+// Note: this class assumes that, at the SQL level, slices are:
+// - Not temporally overlapping (unless they are nested at inner depth).
+// - Strictly stacked (i.e. a slice at depth N+1 cannot be larger than any
+// slices at depth 0..N.
+// If you need temporally overlapping slices, look at AsyncSliceTrack, which
+// merges several tracks into one visual track.
+export const BASE_SLICE_ROW = {
+ id: NUM, // The slice ID, for selection / lookups.
+ tsq: NUM, // Quantized |ts|. This class owns the quantization logic.
+ ts: NUM, // Start time in nanoseconds.
+ dur: NUM, // Duration in nanoseconds. -1 = incomplete, 0 = instant.
+ depth: NUM, // Vertical depth.
+};
+
+export type BaseSliceRow = typeof BASE_SLICE_ROW;
+
+// These properties change @ 60FPS and shouldn't be touched by the subclass.
+// since the Impl doesn't see every frame attempting to reason on them in a
+// subclass will run in to issues.
+interface SliceInternal {
+ x: number;
+ w: number;
+}
+
+// We use this to avoid exposing subclasses to the properties that live on
+// SliceInternal. Within BaseSliceTrack the underlying storage and private
+// methods use CastInternal<T['slice']> (i.e. whatever the subclass requests
+// plus our implementation fields) but when we call 'virtual' methods that
+// the subclass should implement we use just T['slice'] hiding x & w.
+type CastInternal<S extends Slice> = S&SliceInternal;
+
+// The meta-type which describes the types used to extend the BaseSliceTrack.
+// Derived classes can extend this interface to override these types if needed.
+export interface BaseSliceTrackTypes {
+ slice: Slice;
+ row: BaseSliceRow;
+ config: {};
+}
+
+export abstract class BaseSliceTrack<T extends BaseSliceTrackTypes =
+ BaseSliceTrackTypes> extends
+ Track<T['config']> {
+ // This is the slice cache.
+ private slices = new Array<CastInternal<T['slice']>>();
+ protected sliceLayout: SliceLayout = {...DEFAULT_SLICE_LAYOUT};
+
+ // These are the over-skirted cached bounds.
+ private slicesStartNs = -1;
+ private slicesEndNs = -1;
+ private slicesBucketNs = -1;
+
+ private readonly tableName: string;
+ private maxDurNs = 0;
+ private sqlState: 'UNINITIALIZED'|'INITIALIZING'|'QUERY_PENDING'|
+ 'QUERY_DONE' = 'UNINITIALIZED';
+ private extraSqlColumns: string[];
+
+ private charWidth = -1;
+ private hoverPos?: {x: number, y: number};
+ protected hoveredSlice?: T['slice'];
+ private hoverTooltip: string[] = [];
+ private maxDataDepth = 0;
+
+ // Computed layout.
+ private computedTrackHeight = 0;
+ private computedSliceHeight = 0;
+ private computedRowSpacing = 0;
+
+ // True if this track (and any views tables it might have created) has been
+ // destroyed. This is unfortunately error prone (since we must manually check
+ // this between each query).
+ // TODO(hjd): Replace once we have cancellable query sequences.
+ private isDestroyed = false;
+
+ // TODO(hjd): Remove when updating selection.
+ // We shouldn't know here about CHROME_SLICE. Maybe should be set by
+ // whatever deals with that. Dunno the namespace of selection is weird. For
+ // most cases in non-ambiguous (because most things are a 'slice'). But some
+ // others (e.g. THREAD_SLICE) have their own ID namespace so we need this.
+ protected selectionKinds: SelectionKind[] = ['SLICE', 'CHROME_SLICE'];
+
+ // Extension points.
+ // Each extension point should take a dedicated argument type (e.g.,
+ // OnSliceOverArgs {slice?: T['slice']}) so it makes future extensions
+ // non-API-breaking (e.g. if we want to add the X position).
+ abstract initSqlTable(_tableName: string): Promise<void>;
+ getRowSpec(): T['row'] {
+ return BASE_SLICE_ROW;
+ }
+ onSliceOver(_args: OnSliceOverArgs<T['slice']>): void {}
+ onSliceOut(_args: OnSliceOutArgs<T['slice']>): void {}
+ onSliceClick(_args: OnSliceClickArgs<T['slice']>): void {}
+ prepareSlices(slices: Array<T['slice']>): void {
+ this.highlightHovererdAndSameTitle(slices);
+ }
+
+ // TODO(hjd): Remove.
+ drawSchedLatencyArrow(
+ _: CanvasRenderingContext2D, _selectedSlice?: T['slice']): void {}
+
+ constructor(args: NewTrackArgs) {
+ super(args);
+ this.frontendOnly = true; // Disable auto checkerboarding.
+ this.tableName = `track_${this.trackId}`.replace(/[^a-zA-Z0-9_]+/g, '_');
+
+ // Work out the extra columns.
+ // This is the union of the embedder-defined columns and the base columns
+ // we know about (ts, dur, ...).
+ const allCols = Object.keys(this.getRowSpec());
+ const baseCols = Object.keys(BASE_SLICE_ROW);
+ this.extraSqlColumns = allCols.filter(key => !baseCols.includes(key));
+ }
+
+ setSliceLayout(sliceLayout: SliceLayout) {
+ if (sliceLayout.minDepth > sliceLayout.maxDepth) {
+ const {maxDepth, minDepth} = sliceLayout;
+ throw new Error(`minDepth ${minDepth} must be <= maxDepth ${maxDepth}`);
+ }
+ this.sliceLayout = sliceLayout;
+ }
+
+ onFullRedraw(): void {
+ // TODO(hjd): Call this only when cache changes. See discussion:
+ // What we want to do here is give the Impl a chance to colour the slice,
+ // e.g. depending on the currently selected thread or process.
+ // Here's an interesting thought. We have two options here:
+ // A) We could pass only the vizSlices, but then we'd have to call this
+ // @ 60FPS (because vizSlices changes as we pan).
+ // B) We could call this only on full redraws (when the state changes),
+ // but then the track needs to process *all* cached slices, not just
+ // the visible ones. It's okay now (it's a 2x factor) but might get
+ // worse if we cache several layers of slices at various resolutions.
+ // But there's an escape, I think. I think the right thing to do is:
+ // - For now call it on the full slices, but only on full redraws.
+ // - When we get caching, call it every time we switch "cached quantization
+ // level", which is a way in the middle between 60FPS and full redraws..
+ // Overall the API contract of this prepareSlices() call is:
+ // - I am going to draw these slices in the near future.
+ // - I am not going to draw any slice that I haven't passed here first.
+ // - This is guaranteed to be called at least on every state change.
+ // - This is NOT guaranteed to be called on every frame. For instance you
+ // cannot use this to do some colour-based animation.
+
+ // Give a chance to the embedder to change colors and other stuff.
+ this.prepareSlices(this.slices);
+ }
+
+ renderCanvas(ctx: CanvasRenderingContext2D): void {
+ // TODO(hjd): fonts and colors should come from the CSS and not hardcoded
+ // here.
+ const {timeScale} = globals.frontendLocalState;
+ const vizTime = globals.frontendLocalState.visibleWindowTime;
+
+ // If the visible time range is outside the cached area, requests
+ // asynchronously new data from the SQL engine.
+ this.maybeRequestData();
+
+ // In any case, draw whatever we have (which might be stale/incomplete).
+
+ // If the cached trace slices don't fully cover the visible time range,
+ // show a gray rectangle with a "Loading..." label.
+ checkerboardExcept(
+ ctx,
+ this.getHeight(),
+ timeScale.timeToPx(vizTime.start),
+ timeScale.timeToPx(vizTime.end),
+ timeScale.timeToPx(fromNs(this.slicesStartNs)),
+ timeScale.timeToPx(fromNs(this.slicesEndNs)));
+
+ let charWidth = this.charWidth;
+ if (charWidth < 0) {
+ // TODO(hjd): Centralize font measurement/invalidation.
+ ctx.font = '12px Roboto Condensed';
+ charWidth = this.charWidth = ctx.measureText('dbpqaouk').width / 8;
+ }
+
+ // Filter only the visible slices. |this.slices| will have more slices than
+ // needed because maybeRequestData() over-fetches to handle small pan/zooms.
+ // We don't want to waste time drawing slices that are off screen.
+ const vizSlices = this.getVisibleSlicesInternal(vizTime.start, vizTime.end);
+
+ let selection = globals.state.currentSelection;
+
+ if (!selection || !this.selectionKinds.includes(selection.kind)) {
+ selection = null;
+ }
+
+ // Believe it or not, doing 4xO(N) passes is ~2x faster than trying to draw
+ // everything in one go. The key is that state changes operations on the
+ // canvas (e.g., color, fonts) dominate any number crunching we do in JS.
+
+ this.updateSliceAndTrackHeight();
+ const sliceHeight = this.computedSliceHeight;
+ const padding = this.sliceLayout.padding;
+ const rowSpacing = this.computedRowSpacing;
+
+ // First pass: compute geometry of slices.
+ let selSlice: CastInternal<T['slice']>|undefined;
+
+ // pxEnd is the last visible pixel in the visible viewport. Drawing
+ // anything < 0 or > pxEnd doesn't produce any visible effect as it goes
+ // beyond the visible portion of the canvas.
+ const pxEnd = Math.floor(timeScale.timeToPx(vizTime.end));
+
+ for (const slice of vizSlices) {
+ // Compute the basic geometry for any visible slice, even if only
+ // partially visible. This might end up with a negative x if the
+ // slice starts before the visible time or with a width that overflows
+ // pxEnd.
+ slice.x = timeScale.timeToPx(slice.startS);
+ slice.w = timeScale.deltaTimeToPx(slice.durationS);
+ if (slice.flags & SLICE_FLAGS_INSTANT) {
+ // In the case of an instant slice, set the slice geometry on the
+ // bounding box that will contain the chevron.
+ slice.x -= CHEVRON_WIDTH_PX / 2;
+ slice.w = CHEVRON_WIDTH_PX;
+ } else {
+ // If the slice is an actual slice, intersect the slice geometry with
+ // the visible viewport (this affects only the first and last slice).
+ // This is so that text is always centered even if we are zoomed in.
+ // Visually if we have
+ // [ visible viewport ]
+ // [ slice ]
+ // The resulting geometry will be:
+ // [slice]
+ // So that the slice title stays within the visible region.
+ const sliceVizLimit = Math.min(slice.x + slice.w, pxEnd);
+ slice.x = Math.max(slice.x, 0);
+ slice.w = sliceVizLimit - slice.x;
+ }
+
+ if (selection && (selection as {id: number}).id === slice.id) {
+ selSlice = slice;
+ }
+ }
+
+ // Second pass: fill slices by color.
+ // The .slice() turned out to be an unintended pun.
+ const vizSlicesByColor = vizSlices.slice();
+ vizSlicesByColor.sort((a, b) => colorCompare(a.color, b.color));
+ let lastColor = undefined;
+ for (const slice of vizSlicesByColor) {
+ if (slice.color !== lastColor) {
+ lastColor = slice.color;
+ ctx.fillStyle = colorToStr(slice.color);
+ }
+ const y = padding + slice.depth * (sliceHeight + rowSpacing);
+ if (slice.flags & SLICE_FLAGS_INSTANT) {
+ this.drawChevron(ctx, slice.x, y, sliceHeight);
+ } else if (slice.flags & SLICE_FLAGS_INCOMPLETE) {
+ const w = Math.max(slice.w - 2, 2);
+ drawIncompleteSlice(ctx, slice.x, y, w, sliceHeight);
+ } else if (slice.w > SLICE_MIN_WIDTH_PX) {
+ ctx.fillRect(slice.x, y, slice.w, sliceHeight);
+ }
+ }
+
+ // Third pass, draw the titles (e.g., process name for sched slices).
+ ctx.fillStyle = '#fff';
+ ctx.textAlign = 'center';
+ ctx.font = '12px Roboto Condensed';
+ ctx.textBaseline = 'middle';
+ for (const slice of vizSlices) {
+ if ((slice.flags & SLICE_FLAGS_INSTANT) || !slice.title ||
+ slice.w < SLICE_MIN_WIDTH_FOR_TEXT_PX) {
+ continue;
+ }
+
+ const title = cropText(slice.title, charWidth, slice.w);
+ const rectXCenter = slice.x + slice.w / 2;
+ const y = padding + slice.depth * (sliceHeight + rowSpacing);
+ const yDiv = slice.subTitle ? 3 : 2;
+ const yMidPoint = Math.floor(y + sliceHeight / yDiv) - 0.5;
+ ctx.fillText(title, rectXCenter, yMidPoint);
+ }
+
+ // Fourth pass, draw the subtitles (e.g., thread name for sched slices).
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.6)';
+ ctx.font = '10px Roboto Condensed';
+ for (const slice of vizSlices) {
+ if (slice.w < SLICE_MIN_WIDTH_FOR_TEXT_PX || !slice.subTitle ||
+ (slice.flags & SLICE_FLAGS_INSTANT)) {
+ continue;
+ }
+ const rectXCenter = slice.x + slice.w / 2;
+ const subTitle = cropText(slice.subTitle, charWidth, slice.w);
+ const y = padding + slice.depth * (sliceHeight + rowSpacing);
+ const yMidPoint = Math.ceil(y + sliceHeight * 2 / 3) + 1.5;
+ ctx.fillText(subTitle, rectXCenter, yMidPoint);
+ }
+
+ // Draw a thicker border around the selected slice (or chevron).
+ if (selSlice !== undefined) {
+ const color = selSlice.color;
+ const y = padding + selSlice.depth * (sliceHeight + rowSpacing);
+ ctx.strokeStyle = `hsl(${color.h}, ${color.s}%, 30%)`;
+ ctx.beginPath();
+ const THICKNESS = 3;
+ ctx.lineWidth = THICKNESS;
+ ctx.strokeRect(
+ selSlice.x, y - THICKNESS / 2, selSlice.w, sliceHeight + THICKNESS);
+ ctx.closePath();
+ }
+
+ // TODO(hjd): Remove this.
+ // The only thing this does is drawing the sched latency arrow. We should
+ // have some abstraction for that arrow (ideally the same we'd use for
+ // flows).
+ this.drawSchedLatencyArrow(ctx, selSlice);
+
+ // If a slice is hovered, draw the tooltip.
+ const tooltip = this.hoverTooltip;
+ if (this.hoveredSlice !== undefined && tooltip.length > 0 &&
+ this.hoverPos !== undefined) {
+ if (tooltip.length === 1) {
+ this.drawTrackHoverTooltip(ctx, this.hoverPos, tooltip[0]);
+ } else {
+ this.drawTrackHoverTooltip(ctx, this.hoverPos, tooltip[0], tooltip[1]);
+ }
+ } // if (howSlice)
+ }
+
+ onDestroy() {
+ super.onDestroy();
+ this.isDestroyed = true;
+ this.engine.query(`DROP VIEW IF EXISTS ${this.tableName}`);
+ }
+
+ // This method figures out if the visible window is outside the bounds of
+ // the cached data and if so issues new queries (i.e. sorta subsumes the
+ // onBoundsChange).
+ async maybeRequestData() {
+ // Important: this method is async and is invoked on every frame. Care
+ // must be taken to avoid piling up queries on every frame, hence the FSM.
+ if (this.sqlState === 'UNINITIALIZED') {
+ this.sqlState = 'INITIALIZING';
+
+ if (this.isDestroyed) {
+ return;
+ }
+ await this.initSqlTable(this.tableName);
+
+ if (this.isDestroyed) {
+ return;
+ }
+ const queryRes = await this.engine.query(`select
+ ifnull(max(dur), 0) as maxDur, count(1) as rowCount
+ from ${this.tableName}`);
+ const row = queryRes.firstRow({maxDur: NUM, rowCount: NUM});
+ this.maxDurNs = row.maxDur;
+ this.sqlState = 'QUERY_DONE';
+ } else if (
+ this.sqlState === 'INITIALIZING' || this.sqlState === 'QUERY_PENDING') {
+ return;
+ }
+
+ const resolutionNs = toNs(globals.getCurResolution());
+ const vizTime = globals.frontendLocalState.visibleWindowTime;
+
+ const startNs = toNs(vizTime.start);
+ const endNs = toNs(vizTime.end);
+
+ // TODO(hjd): figure out / centralize the resolution steps.
+ // Will handle this at the same time as cacheing.
+ const bucketNs = resolutionNs;
+
+ if (startNs >= this.slicesStartNs && endNs <= this.slicesEndNs &&
+ bucketNs === this.slicesBucketNs) {
+ return; // We have the data already, no need to re-query
+ }
+
+ this.sqlState = 'QUERY_PENDING';
+ const queryTsq = `(ts + ${bucketNs / 2}) / ${bucketNs} * ${bucketNs}`;
+
+ const extraCols = this.extraSqlColumns.join(',');
+ let depthCol = 'depth';
+ let maybeGroupByDepth = 'depth, ';
+ const layout = this.sliceLayout;
+ const isFlat = (layout.maxDepth - layout.minDepth) <= 1;
+ // maxDepth === minDepth only makes sense if track is empty which on the
+ // one hand isn't very useful (and so maybe should be an error) on the
+ // other hand I can see it happening if someone does:
+ // minDepth = min(slices.depth); maxDepth = max(slices.depth);
+ // and slices is empty, so we treat that as flat.
+ if (isFlat) {
+ depthCol = `${this.sliceLayout.minDepth} as depth`;
+ maybeGroupByDepth = '';
+ }
+
+ // TODO(hjd): Re-reason and improve this query:
+ // - Materialize the unfinished slices one off.
+ // - Avoid the union if we know we don't have any -1 slices.
+ // - Maybe we don't need the union at all and can deal in TS?
+ if (this.isDestroyed) {
+ return;
+ }
+ const queryRes = await this.engine.query(`
+ with q1 as (
+ select
+ ${queryTsq} as tsq,
+ ts,
+ max(dur) as dur,
+ id,
+ ${depthCol}
+ ${extraCols ? ',' + extraCols : ''}
+ from ${this.tableName}
+ where
+ ts >= ${startNs - this.maxDurNs /* - durNs */} and
+ ts <= ${endNs /* + durNs */}
+ group by ${maybeGroupByDepth} tsq
+ order by tsq),
+ q2 as (
+ select
+ ${queryTsq} as tsq,
+ ts,
+ -1 as dur,
+ id,
+ ${depthCol}
+ ${extraCols ? ',' + extraCols : ''}
+ from ${this.tableName}
+ where dur = -1
+ group by ${maybeGroupByDepth} tsq
+ )
+ select min(dur) as _unused, * from
+ (select * from q1 union all select * from q2)
+ group by ${maybeGroupByDepth} tsq
+ order by tsq
+ `);
+ this.convertQueryResultToSlices(queryRes, startNs, endNs, bucketNs);
+ this.sqlState = 'QUERY_DONE';
+ globals.rafScheduler.scheduleRedraw();
+ }
+
+ // Here convert each row to a Slice. We do what we can do generically
+ // in the base class, and delegate the rest to the impl via that rowToSlice()
+ // abstract call.
+ convertQueryResultToSlices(
+ queryRes: QueryResult, startNs: number, endNs: number, bucketNs: number) {
+ const slices = new Array<CastInternal<T['slice']>>(queryRes.numRows());
+ const it = queryRes.iter(this.getRowSpec());
+
+ let maxDataDepth = this.maxDataDepth;
+ this.slicesStartNs = startNs;
+ this.slicesEndNs = endNs;
+ this.slicesBucketNs = bucketNs;
+ for (let i = 0; it.valid(); it.next(), ++i) {
+ maxDataDepth = Math.max(maxDataDepth, it.depth);
+
+ // Construct the base slice. The Impl will construct and return the full
+ // derived T["slice"] (e.g. CpuSlice) in the rowToSlice() method.
+ slices[i] = this.rowToSliceInternal(it);
+ }
+ this.maxDataDepth = maxDataDepth;
+ this.slices = slices;
+ }
+
+ private rowToSliceInternal(row: T['row']): CastInternal<T['slice']> {
+ const slice = this.rowToSlice(row) as CastInternal<T['slice']>;
+ slice.x = -1;
+ slice.w = -1;
+ return slice;
+ }
+
+ rowToSlice(row: T['row']): T['slice'] {
+ const startNsQ = row.tsq;
+ const startNs = row.ts;
+ let flags = 0;
+ let durNs: number;
+ if (row.dur === -1) {
+ durNs = toNs(globals.state.traceTime.endSec) - startNs;
+ flags |= SLICE_FLAGS_INCOMPLETE;
+ } else {
+ flags |= (row.dur === 0) ? SLICE_FLAGS_INSTANT : 0;
+ durNs = row.dur;
+ }
+ const endNs = startNs + durNs;
+ const bucketNs = this.slicesBucketNs;
+ let endNsQ = Math.floor((endNs + bucketNs / 2 - 1) / bucketNs) * bucketNs;
+ endNsQ = Math.max(endNsQ, startNsQ + bucketNs);
+
+ return {
+ id: row.id,
+ startS: fromNs(startNsQ),
+ durationS: fromNs(endNsQ - startNsQ),
+ flags,
+ depth: row.depth,
+ title: '',
+ subTitle: '',
+
+ // The derived class doesn't need to initialize these. They are
+ // rewritten on every renderCanvas() call. We just need to initialize
+ // them to something.
+ baseColor: DEFAULT_SLICE_COLOR,
+ color: DEFAULT_SLICE_COLOR,
+ };
+ }
+
+ private findSlice({x, y}: {x: number, y: number}): undefined|Slice {
+ const trackHeight = this.computedTrackHeight;
+ const sliceHeight = this.computedSliceHeight;
+ const padding = this.sliceLayout.padding;
+ const rowSpacing = this.computedRowSpacing;
+
+ // Need at least a draw pass to resolve the slice layout.
+ if (sliceHeight === 0) {
+ return undefined;
+ }
+
+ if (y >= padding && y <= trackHeight - padding) {
+ const depth = Math.floor((y - padding) / (sliceHeight + rowSpacing));
+ for (const slice of this.slices) {
+ if (slice.depth === depth && slice.x <= x && x <= slice.x + slice.w) {
+ return slice;
+ }
+ }
+ }
+
+ return undefined;
+ }
+
+ onMouseMove(position: {x: number, y: number}): void {
+ this.hoverPos = position;
+ this.updateHoveredSlice(this.findSlice(position));
+ }
+
+ onMouseOut(): void {
+ this.updateHoveredSlice(undefined);
+ }
+
+ private updateHoveredSlice(slice?: T['slice']): void {
+ const lastHoveredSlice = this.hoveredSlice;
+ this.hoveredSlice = slice;
+
+ // Only notify the Impl if the hovered slice changes:
+ if (slice === lastHoveredSlice) return;
+
+ if (this.hoveredSlice === undefined) {
+ globals.dispatch(Actions.setHighlightedSliceId({sliceId: -1}));
+ this.onSliceOut({slice: assertExists(lastHoveredSlice)});
+ this.hoverTooltip = [];
+ this.hoverPos = undefined;
+ } else {
+ const args: OnSliceOverArgs<T['slice']> = {slice: this.hoveredSlice};
+ globals.dispatch(
+ Actions.setHighlightedSliceId({sliceId: this.hoveredSlice.id}));
+ this.onSliceOver(args);
+ this.hoverTooltip = args.tooltip || [];
+ }
+ }
+
+ onMouseClick(position: {x: number, y: number}): boolean {
+ const slice = this.findSlice(position);
+ if (slice === undefined) {
+ return false;
+ }
+ const args: OnSliceClickArgs<T['slice']> = {slice};
+ this.onSliceClick(args);
+ return true;
+ }
+
+ private getVisibleSlicesInternal(startS: number, endS: number):
+ Array<CastInternal<T['slice']>> {
+ return this.getVisibleSlices(startS, endS);
+ }
+
+ getVisibleSlices(startS: number, endS: number):
+ Array<CastInternal<T['slice']>> {
+ let startIdx = -1;
+ let endIdx = -1;
+ let i = 0;
+
+ // TODO(hjd): binary search.
+ for (const slice of this.slices) {
+ if (startIdx < 0 && slice.startS + slice.durationS >= startS) {
+ startIdx = i;
+ }
+ if (slice.startS <= endS) {
+ endIdx = i + 1;
+ } else if (slice.startS > endS) {
+ endIdx = i;
+ break;
+ }
+ i++;
+ }
+ return this.slices.slice(startIdx, endIdx);
+ }
+
+ private updateSliceAndTrackHeight() {
+ const lay = this.sliceLayout;
+
+ const rows =
+ Math.min(Math.max(this.maxDataDepth + 1, lay.minDepth), lay.maxDepth);
+
+ // Compute the track height.
+ let trackHeight;
+ if (lay.heightMode === 'FIXED') {
+ trackHeight = lay.fixedHeight;
+ } else {
+ trackHeight = 2 * lay.padding + rows * (lay.sliceHeight + lay.rowSpacing);
+ }
+
+ // Compute the slice height.
+ let sliceHeight: number;
+ let rowSpacing: number = lay.rowSpacing;
+ if (lay.heightMode === 'FIXED') {
+ const rowHeight = (trackHeight - 2 * lay.padding) / rows;
+ sliceHeight = Math.floor(Math.max(rowHeight - lay.rowSpacing, 0.5));
+ rowSpacing = Math.max(lay.rowSpacing, rowHeight - sliceHeight);
+ rowSpacing = Math.floor(rowSpacing * 2) / 2;
+ } else {
+ sliceHeight = lay.sliceHeight;
+ }
+ this.computedSliceHeight = sliceHeight;
+ this.computedTrackHeight = trackHeight;
+ this.computedRowSpacing = rowSpacing;
+ }
+
+ private drawChevron(
+ ctx: CanvasRenderingContext2D, x: number, y: number, h: number) {
+ // Draw an upward facing chevrons, in order: A, B, C, D, and back to A.
+ // . (x, y)
+ // A
+ // ###
+ // ##C##
+ // ## ##
+ // D B
+ // . (x + CHEVRON_WIDTH_PX, y + h)
+ const HALF_CHEVRON_WIDTH_PX = CHEVRON_WIDTH_PX / 2;
+ const midX = x + HALF_CHEVRON_WIDTH_PX;
+ ctx.beginPath();
+ ctx.moveTo(midX, y); // A.
+ ctx.lineTo(x + CHEVRON_WIDTH_PX, y + h); // B.
+ ctx.lineTo(midX, y + h - HALF_CHEVRON_WIDTH_PX); // C.
+ ctx.lineTo(x, y + h); // D.
+ ctx.lineTo(midX, y); // Back to A.
+ ctx.closePath();
+ ctx.fill();
+ }
+
+ // This is a good default implemenation for highlighting slices. By default
+ // prepareSlices() calls this. However, if the XxxSliceTrack impl overrides
+ // prepareSlices() this gives them a chance to call the highlighting witout
+ // having to reimplement it.
+ protected highlightHovererdAndSameTitle(slices: Slice[]) {
+ for (const slice of slices) {
+ const isHovering = globals.state.highlightedSliceId === slice.id ||
+ (this.hoveredSlice && this.hoveredSlice.title === slice.title);
+ if (isHovering) {
+ slice.color = {
+ c: slice.baseColor.c,
+ h: slice.baseColor.h,
+ s: slice.baseColor.s,
+ l: 30
+ };
+ } else {
+ slice.color = slice.baseColor;
+ }
+ }
+ }
+
+ getHeight(): number {
+ this.updateSliceAndTrackHeight();
+ return this.computedTrackHeight;
+ }
+
+ getSliceRect(_tStart: number, _tEnd: number, _depth: number): SliceRect
+ |undefined {
+ // TODO(hjd): Implement this as part of updating flow events.
+ return undefined;
+ }
+}
+
+// This is the argument passed to onSliceOver(args).
+// This is really a workaround for the fact that TypeScript doesn't allow
+// inner types within a class (whether the class is templated or not).
+export interface OnSliceOverArgs<S extends Slice> {
+ // Input args (BaseSliceTrack -> Impl):
+ slice: S; // The slice being hovered.
+
+ // Output args (Impl -> BaseSliceTrack):
+ tooltip?: string[]; // One entry per row, up to a max of 2.
+}
+
+export interface OnSliceOutArgs<S extends Slice> {
+ // Input args (BaseSliceTrack -> Impl):
+ slice: S; // The slice which is not hovered anymore.
+}
+
+export interface OnSliceClickArgs<S extends Slice> {
+ // Input args (BaseSliceTrack -> Impl):
+ slice: S; // The slice which is clicked.
+}
diff --git a/ui/src/frontend/checkerboard.ts b/ui/src/frontend/checkerboard.ts
index d2717596a..7ce182bc5 100644
--- a/ui/src/frontend/checkerboard.ts
+++ b/ui/src/frontend/checkerboard.ts
@@ -33,11 +33,12 @@ export function checkerboard(
if (LOADING_TEXT_WIDTH === 0) {
LOADING_TEXT_WIDTH = ctx.measureText(LOADING_TEXT).width;
}
- ctx.fillText(
- LOADING_TEXT,
- leftPx + widthPx / 2 - LOADING_TEXT_WIDTH,
- heightPx / 2,
- widthPx);
+ if (LOADING_TEXT_WIDTH <= widthPx) {
+ ctx.fillText(
+ LOADING_TEXT,
+ leftPx + widthPx / 2 - LOADING_TEXT_WIDTH / 2,
+ heightPx / 2);
+ }
ctx.textBaseline = oldBaseline;
}
diff --git a/ui/src/frontend/chrome_slice_panel.ts b/ui/src/frontend/chrome_slice_panel.ts
index 0a6c31f45..76f092074 100644
--- a/ui/src/frontend/chrome_slice_panel.ts
+++ b/ui/src/frontend/chrome_slice_panel.ts
@@ -16,11 +16,12 @@ import * as m from 'mithril';
import {Actions} from '../common/actions';
import {Arg, ArgsTree, isArgTreeArray, isArgTreeMap} from '../common/arg_types';
-import {timeToCode, toNs} from '../common/time';
+import {timeToCode} from '../common/time';
import {globals, SliceDetails} from './globals';
-import {Panel, PanelSize} from './panel';
+import {PanelSize} from './panel';
import {verticalScrollToTrack} from './scroll_helper';
+import {SlicePanel} from './slice_panel';
// Table row contents is one of two things:
// 1. Key-value pair
@@ -42,18 +43,33 @@ function isTableHeader(contents: RowContents): contents is TableHeader {
return contents.kind === 'TableHeader';
}
+function appendPrefix(p1: string, p2: string): string {
+ if (p1.length === 0) {
+ return p2;
+ }
+ return `${p1}.${p2}`;
+}
+
+
+// During building the table, sometimes we want to add an extra cell to the
+// table. It might be either an index of array element (represented as number),
+// a special indentation cell to ensure minimum column width when indenting
+// an object ('whitespace' literal) or just be absent ('none' literal).
+type ExtraCell = number|'whitespace'|'none';
+
interface Row {
// How many columns (empty or with an index) precede a key
indentLevel: number;
- // Index if the current row is an element of array
- index: number;
+ extraCell: ExtraCell;
+ // Optional tooltip to be displayed on the key. Used to display the full key,
+ // which has to be reconstructed from the information that might not even be
+ // visible on the screen otherwise.
+ tooltip?: string;
contents: RowContents;
}
class TableBuilder {
- // Stack contains indices inside repeated fields, or -1 if the appropriate
- // index is already displayed.
- stack: number[] = [];
+ stack: ExtraCell[] = [];
// Row data generated by builder
rows: Row[] = [];
@@ -63,37 +79,42 @@ class TableBuilder {
// Add a key-value pair into the table
add(key: string, value: Arg) {
- this.rows.push(
- {indentLevel: 0, index: -1, contents: {kind: 'KVPair', key, value}});
+ this.rows.push({
+ indentLevel: 0,
+ extraCell: 'none',
+ contents: {kind: 'KVPair', key, value},
+ });
}
// Add arguments tree into the table
addTree(tree: ArgsTree) {
- this.addTreeInternal(tree, '');
+ this.addTreeInternal(tree, '', '');
}
// Return indent level and index for a fresh row
- private prepareRow(): [number, number] {
+ private prepareRow(): [number, ExtraCell] {
const level = this.stack.length;
- let index = -1;
+ let index: ExtraCell = 'none';
if (level > 0) {
index = this.stack[level - 1];
if (index !== -1) {
- this.stack[level - 1] = -1;
+ this.stack[level - 1] = 'none';
}
}
this.maxIndent = Math.max(this.maxIndent, level);
return [level, index];
}
- private addTreeInternal(record: ArgsTree, prefix: string) {
+ private addTreeInternal(
+ record: ArgsTree, prefix: string, completePrefix: string) {
if (isArgTreeArray(record)) {
// Add the current prefix as a separate row
const row = this.prepareRow();
this.rows.push({
indentLevel: row[0],
- index: row[1],
- contents: {kind: 'TableHeader', header: prefix}
+ extraCell: row[1],
+ contents: {kind: 'TableHeader', header: prefix},
+ tooltip: completePrefix
});
for (let i = 0; i < record.length; i++) {
@@ -101,28 +122,55 @@ class TableBuilder {
this.stack.push(i);
// Prefix is empty for array elements because we don't want to repeat
// the common prefix
- this.addTreeInternal(record[i], '');
+ this.addTreeInternal(record[i], '', `${completePrefix}[${i}]`);
this.stack.pop();
}
} else if (isArgTreeMap(record)) {
- for (const [key, value] of Object.entries(record)) {
- // If the prefix was non-empty, we have to add dot at the end as well.
- const newPrefix = (prefix === '') ? key : prefix + '.' + key;
- this.addTreeInternal(value, newPrefix);
+ const entries = Object.entries(record);
+ if (entries.length === 1) {
+ // Don't want to create a level of indirection in case object contains
+ // only one value; think of it like file browser in IDEs not showing
+ // intermediate nodes for common hierarchy corresponding to Java package
+ // prefix (e.g. "com/google/perfetto").
+ //
+ // In this case, add key as a prefix part.
+ const [key, value] = entries[0];
+ this.addTreeInternal(
+ value,
+ appendPrefix(prefix, key),
+ appendPrefix(completePrefix, key));
+ } else {
+ if (prefix.length > 0) {
+ const row = this.prepareRow();
+ this.rows.push({
+ indentLevel: row[0],
+ extraCell: row[1],
+ contents: {kind: 'TableHeader', header: prefix},
+ tooltip: completePrefix
+ });
+ this.stack.push('whitespace');
+ }
+ for (const [key, value] of entries) {
+ this.addTreeInternal(value, key, appendPrefix(completePrefix, key));
+ }
+ if (prefix.length > 0) {
+ this.stack.pop();
+ }
}
} else {
// Leaf value in the tree: add to the table
const row = this.prepareRow();
this.rows.push({
indentLevel: row[0],
- index: row[1],
- contents: {kind: 'KVPair', key: prefix, value: record}
+ extraCell: row[1],
+ contents: {kind: 'KVPair', key: prefix, value: record},
+ tooltip: completePrefix
});
}
}
}
-export class ChromeSliceDetailsPanel extends Panel {
+export class ChromeSliceDetailsPanel extends SlicePanel {
view() {
const sliceInfo = globals.sliceDetails;
if (sliceInfo.ts !== undefined && sliceInfo.dur !== undefined &&
@@ -136,9 +184,28 @@ export class ChromeSliceDetailsPanel extends Panel {
sliceInfo.category);
builder.add('Start time', timeToCode(sliceInfo.ts));
builder.add(
- 'Duration',
- toNs(sliceInfo.dur) === -1 ? '-1 (Did not end)' :
- timeToCode(sliceInfo.dur));
+ 'Duration', this.computeDuration(sliceInfo.ts, sliceInfo.dur));
+ if (sliceInfo.thread_ts !== undefined &&
+ sliceInfo.thread_dur !== undefined) {
+ // If we have valid thread duration, also display a percentage of
+ // |thread_dur| compared to |dur|.
+ const threadDurFractionSuffix = sliceInfo.thread_dur === -1 ?
+ '' :
+ ` (${(sliceInfo.thread_dur / sliceInfo.dur * 100).toFixed(2)}%)`;
+ builder.add(
+ 'Thread duration',
+ this.computeDuration(sliceInfo.thread_ts, sliceInfo.thread_dur) +
+ threadDurFractionSuffix);
+ }
+
+ for (const [key, value] of this.getProcessThreadDetails(sliceInfo)) {
+ if (value !== undefined) {
+ builder.add(key, value);
+ }
+ }
+
+ builder.add(
+ 'Slice ID', sliceInfo.id ? sliceInfo.id.toString() : 'Unknown');
if (sliceInfo.description) {
this.fillDescription(sliceInfo.description, builder);
}
@@ -185,29 +252,33 @@ export class ChromeSliceDetailsPanel extends Panel {
for (const row of builder.rows) {
const renderedRow: m.Vnode[] = [];
let indent = row.indentLevel;
- if (row.index !== -1) {
+ if (row.extraCell !== 'none') {
indent--;
}
if (indent > 0) {
- renderedRow.push(m('td', {colspan: indent}));
+ renderedRow.push(m('td.no-highlight', {colspan: indent}));
}
- if (row.index !== -1) {
- renderedRow.push(m('td', {class: 'array-index'}, `[${row.index}]`));
+
+ if (row.extraCell === 'whitespace') {
+ renderedRow.push(m('td.no-highlight.padding', {class: 'array-index'}));
+ } else if (row.extraCell !== 'none') {
+ renderedRow.push(m('td', {class: 'array-index'}, `[${row.extraCell}]`));
}
+
if (isTableHeader(row.contents)) {
- renderedRow.push(
- m('th',
- {colspan: keyColumnCount + 1 - row.indentLevel},
- row.contents.header));
+ renderedRow.push(m(
+ 'th',
+ {colspan: keyColumnCount + 1 - row.indentLevel, title: row.tooltip},
+ row.contents.header));
} else {
renderedRow.push(
m('th',
- {colspan: keyColumnCount - row.indentLevel},
+ {colspan: keyColumnCount - row.indentLevel, title: row.tooltip},
row.contents.key));
const value = row.contents.value;
if (typeof value === 'string') {
- renderedRow.push(m('td', value));
+ renderedRow.push(m('td.value', value));
} else {
// Type of value being a record is not propagated into the callback
// for some reason, extracting necessary parts as constants instead.
@@ -235,7 +306,7 @@ export class ChromeSliceDetailsPanel extends Panel {
rows.push(m('tr', renderedRow));
}
- return m('table.half-width', rows);
+ return m('table.half-width.auto-layout', rows);
}
fillDescription(description: Map<string, string>, builder: TableBuilder) {
diff --git a/ui/src/frontend/clipboard.ts b/ui/src/frontend/clipboard.ts
index 28d70be8c..7c9a61dc7 100644
--- a/ui/src/frontend/clipboard.ts
+++ b/ui/src/frontend/clipboard.ts
@@ -12,6 +12,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import {Actions} from '../common/actions';
+import {QueryResponse} from '../common/queries';
+
+import {globals} from './globals';
+
+export function onClickCopy(url: string) {
+ return (e: Event) => {
+ e.preventDefault();
+ copyToClipboard(url);
+ globals.dispatch(Actions.updateStatus(
+ {msg: 'Link copied into the clipboard', timestamp: Date.now() / 1000}));
+ };
+}
+
export async function copyToClipboard(text: string): Promise<void> {
try {
// TODO(hjd): Fix typescript type for navigator.
@@ -21,3 +35,31 @@ export async function copyToClipboard(text: string): Promise<void> {
console.error(`Failed to copy "${text}" to clipboard: ${err}`);
}
}
+
+export async function queryResponseToClipboard(resp: QueryResponse):
+ Promise<void> {
+ const lines: string[][] = [];
+ lines.push(resp.columns);
+ for (const row of resp.rows) {
+ const line = [];
+ for (const col of resp.columns) {
+ const value = row[col];
+ line.push(value === null ? 'NULL' : value.toString());
+ }
+ lines.push(line);
+ }
+ copyToClipboard(lines.map(line => line.join('\t')).join('\n'));
+}
+
+export function download(file: File, name?: string): void {
+ const url = URL.createObjectURL(file);
+ const a = document.createElement('a');
+ a.href = url;
+ a.download = name === undefined ? file.name : name;
+ document.body.appendChild(a);
+ a.click();
+ document.body.removeChild(a);
+ URL.revokeObjectURL(url);
+}
+
+
diff --git a/ui/src/frontend/cookie_consent.ts b/ui/src/frontend/cookie_consent.ts
index 3ea5ecf24..607b46fbf 100644
--- a/ui/src/frontend/cookie_consent.ts
+++ b/ui/src/frontend/cookie_consent.ts
@@ -21,10 +21,15 @@ const COOKIE_ACK_KEY = 'cookieAck';
export class CookieConsent implements m.ClassComponent {
private showCookieConsent = true;
- view() {
- if (this.showCookieConsent) {
- this.showCookieConsent = localStorage.getItem(COOKIE_ACK_KEY) === null;
+ oninit() {
+ this.showCookieConsent = true;
+ if (!globals.logging.isEnabled() ||
+ localStorage.getItem(COOKIE_ACK_KEY) === 'true') {
+ this.showCookieConsent = false;
}
+ }
+
+ view() {
if (!this.showCookieConsent) return;
return m(
'.cookie-consent',
diff --git a/ui/src/frontend/counter_panel.ts b/ui/src/frontend/counter_panel.ts
index 4a3ccd73b..eb5d9918f 100644
--- a/ui/src/frontend/counter_panel.ts
+++ b/ui/src/frontend/counter_panel.ts
@@ -25,8 +25,8 @@ export class CounterDetailsPanel extends Panel<CounterDetailsPanelAttrs> {
view() {
const counterInfo = globals.counterDetails;
if (counterInfo && counterInfo.startTime &&
- counterInfo.value !== undefined && counterInfo.delta !== undefined &&
- counterInfo.duration !== undefined) {
+ counterInfo.name !== undefined && counterInfo.value !== undefined &&
+ counterInfo.delta !== undefined && counterInfo.duration !== undefined) {
return m(
'.details-panel',
m('.details-panel-heading', m('h2', `Counter Details`)),
@@ -34,6 +34,7 @@ export class CounterDetailsPanel extends Panel<CounterDetailsPanelAttrs> {
'.details-table',
[m('table.half-width',
[
+ m('tr', m('th', `Name`), m('td', `${counterInfo.name}`)),
m('tr',
m('th', `Start time`),
m('td', `${timeToCode(counterInfo.startTime)}`)),
diff --git a/ui/src/frontend/details_panel.ts b/ui/src/frontend/details_panel.ts
index 9332c00fc..c364d97eb 100644
--- a/ui/src/frontend/details_panel.ts
+++ b/ui/src/frontend/details_panel.ts
@@ -15,30 +15,38 @@
import * as m from 'mithril';
import {QueryResponse} from 'src/common/queries';
+import {Actions} from '../common/actions';
+import {isEmptyData} from '../common/aggregation_data';
import {LogExists, LogExistsKey} from '../common/logs';
+import {DEFAULT_PIVOT_TABLE_ID} from '../common/pivot_table_common';
import {AggregationPanel} from './aggregation_panel';
import {ChromeSliceDetailsPanel} from './chrome_slice_panel';
import {CounterDetailsPanel} from './counter_panel';
import {CpuProfileDetailsPanel} from './cpu_profile_panel';
import {DragGestureHandler} from './drag_gesture_handler';
+import {FlamegraphDetailsPanel} from './flamegraph_panel';
import {
FlowEventsAreaSelectedPanel,
FlowEventsPanel
} from './flow_events_panel';
import {globals} from './globals';
-import {HeapProfileDetailsPanel} from './heap_profile_panel';
import {LogPanel} from './logs_panel';
+import {showModal} from './modal';
import {NotesEditorPanel} from './notes_panel';
import {AnyAttrsVnode, PanelContainer} from './panel_container';
+import {PivotTable} from './pivot_table';
+import {ColumnDisplay, ColumnPicker} from './pivot_table_editor';
+import {PivotTableHelper} from './pivot_table_helper';
+import {PivotTableRedux} from './pivot_table_redux';
import {QueryTable} from './query_table';
-import {SliceDetailsPanel} from './slice_panel';
+import {SliceDetailsPanel} from './slice_details_panel';
import {ThreadStatePanel} from './thread_state_panel';
const UP_ICON = 'keyboard_arrow_up';
const DOWN_ICON = 'keyboard_arrow_down';
const DRAG_HANDLE_HEIGHT_PX = 28;
-const DEFAULT_DETAILS_HEIGHT_PX = 230 + DRAG_HANDLE_HEIGHT_PX;
+const DEFAULT_DETAILS_HEIGHT_PX = 280 + DRAG_HANDLE_HEIGHT_PX;
function getFullScreenHeight() {
const panelContainer =
@@ -55,6 +63,38 @@ function hasLogs(): boolean {
return data && data.exists;
}
+function showPivotTableEditorModal(helper?: PivotTableHelper) {
+ if (helper !== undefined && helper.editPivotTableModalOpen) {
+ let content;
+ if (helper.availableColumns.length === 0 ||
+ helper.availableAggregations.length === 0) {
+ content =
+ m('.pivot-table-editor-container',
+ helper.availableColumns.length === 0 ?
+ m('div', 'No columns available.') :
+ null,
+ helper.availableAggregations.length === 0 ?
+ m('div', 'No aggregations available.') :
+ null);
+ } else {
+ const attrs = {helper};
+ content =
+ m('.pivot-table-editor-container',
+ m(ColumnPicker, attrs),
+ m(ColumnDisplay, attrs));
+ }
+
+ showModal({
+ title: 'Edit Pivot Table',
+ content,
+ buttons: [],
+ }).finally(() => {
+ helper.toggleEditPivotTableModal();
+ globals.rafScheduler.scheduleFullRedraw();
+ });
+ }
+}
+
interface Tab {
key: string;
name: string;
@@ -64,6 +104,7 @@ interface DragHandleAttrs {
height: number;
resize: (height: number) => void;
tabs: Tab[];
+ currentTabKey?: string;
}
class DragHandle implements m.ClassComponent<DragHandleAttrs> {
@@ -113,26 +154,15 @@ class DragHandle implements m.ClassComponent<DragHandleAttrs> {
view({attrs}: m.CVnode<DragHandleAttrs>) {
const icon = this.isClosed ? UP_ICON : DOWN_ICON;
const title = this.isClosed ? 'Show panel' : 'Hide panel';
- const activeTabExists = globals.frontendLocalState.currentTab &&
- attrs.tabs.map(tab => tab.key)
- .includes(globals.frontendLocalState.currentTab);
- if (!activeTabExists) {
- globals.frontendLocalState.currentTab = undefined;
- }
const renderTab = (tab: Tab) => {
- if (globals.frontendLocalState.currentTab === tab.key ||
- globals.frontendLocalState.currentTab === undefined &&
- attrs.tabs.keys().next().value === tab.key) {
- // Update currentTab in case we didn't have one before.
- globals.frontendLocalState.currentTab = tab.key;
+ if (attrs.currentTabKey === tab.key) {
return m('.tab[active]', tab.name);
}
return m(
'.tab',
{
onclick: () => {
- globals.frontendLocalState.currentTab = tab.key;
- globals.rafScheduler.scheduleFullRedraw();
+ globals.dispatch(Actions.setCurrentTab({tab: tab.key}));
}
},
tab.name);
@@ -178,8 +208,6 @@ class DragHandle implements m.ClassComponent<DragHandleAttrs> {
export class DetailsPanel implements m.ClassComponent {
private detailsHeight = DEFAULT_DETAILS_HEIGHT_PX;
- // Used to set details panel to default height on selection.
- private showDetailsPanel = true;
view() {
interface DetailsPanel {
@@ -213,6 +241,13 @@ export class DetailsPanel implements m.ClassComponent {
})
});
}
+ if (globals.flamegraphDetails.isInAreaSelection) {
+ detailsPanels.push({
+ key: 'flamegraph_selection',
+ name: 'Flamegraph Selection',
+ vnode: m(FlamegraphDetailsPanel, {key: 'flamegraph'})
+ });
+ }
break;
case 'SLICE':
detailsPanels.push({
@@ -232,11 +267,12 @@ export class DetailsPanel implements m.ClassComponent {
})
});
break;
+ case 'PERF_SAMPLES':
case 'HEAP_PROFILE':
detailsPanels.push({
key: 'current_selection',
name: 'Current Selection',
- vnode: m(HeapProfileDetailsPanel, {key: 'heap_profile'})
+ vnode: m(FlamegraphDetailsPanel, {key: 'flamegraph'})
});
break;
case 'CPU_PROFILE_SAMPLE':
@@ -284,6 +320,35 @@ export class DetailsPanel implements m.ClassComponent {
});
}
+ if (globals.state.pivotTableRedux.selectionArea !== null) {
+ detailsPanels.push({
+ key: 'pivot_table_redux',
+ name: 'Pivot Table',
+ vnode: m(PivotTableRedux, {
+ key: 'pivot_table_redux',
+ selectionArea: globals.state.pivotTableRedux.selectionArea
+ })
+ });
+ }
+
+ for (const pivotTableId of Object.keys(globals.state.pivotTable)) {
+ const pivotTable = globals.state.pivotTable[pivotTableId];
+ const helper = globals.pivotTableHelper.get(pivotTableId);
+ if (pivotTableId !== DEFAULT_PIVOT_TABLE_ID ||
+ globals.frontendLocalState.showPivotTable) {
+ if (helper !== undefined) {
+ helper.setSelectedPivotsAndAggregations(
+ pivotTable.selectedPivots, pivotTable.selectedAggregations);
+ }
+ detailsPanels.push({
+ key: pivotTableId,
+ name: pivotTable.name,
+ vnode: m(PivotTable, {key: pivotTableId, pivotTableId, helper})
+ });
+ }
+ showPivotTableEditorModal(helper);
+ }
+
if (globals.connectedFlows.length > 0) {
detailsPanels.push({
key: 'bound_flows',
@@ -293,7 +358,7 @@ export class DetailsPanel implements m.ClassComponent {
}
for (const [key, value] of globals.aggregateDataStore.entries()) {
- if (value.columns.length > 0 && value.columns[0].data.length > 0) {
+ if (!isEmptyData(value)) {
detailsPanels.push({
key: value.tabName,
name: value.tabName,
@@ -307,18 +372,17 @@ export class DetailsPanel implements m.ClassComponent {
detailsPanels.push({
key: 'selected_flows',
name: 'Flow Events',
- vnode: m(FlowEventsAreaSelectedPanel)
+ vnode: m(FlowEventsAreaSelectedPanel, {key: 'flow_events_area'})
});
}
- this.showDetailsPanel = detailsPanels.length > 0;
-
- const currentTabDetails = detailsPanels.filter(
- tab => tab.key === globals.frontendLocalState.currentTab)[0];
+ let currentTabDetails =
+ detailsPanels.find(tab => tab.key === globals.state.currentTab);
+ if (currentTabDetails === undefined && detailsPanels.length > 0) {
+ currentTabDetails = detailsPanels[0];
+ }
- const panel = currentTabDetails ?
- currentTabDetails.vnode :
- detailsPanels.values().next().value?.vnode;
+ const panel = currentTabDetails?.vnode;
const panels = panel ? [panel] : [];
return m(
@@ -326,7 +390,7 @@ export class DetailsPanel implements m.ClassComponent {
{
style: {
height: `${this.detailsHeight}px`,
- display: this.showDetailsPanel ? null : 'none'
+ display: detailsPanels.length > 0 ? null : 'none'
}
},
m(DragHandle, {
@@ -337,8 +401,9 @@ export class DetailsPanel implements m.ClassComponent {
tabs: detailsPanels.map(tab => {
return {key: tab.key, name: tab.name};
}),
+ currentTabKey: currentTabDetails?.key
}),
- m('.details-panel-container',
+ m('.details-panel-container.x-scrollable',
m(PanelContainer, {doesScroll: true, panels, kind: 'DETAILS'})));
}
}
diff --git a/ui/src/frontend/error_dialog.ts b/ui/src/frontend/error_dialog.ts
index 9fba9a07b..aa763bdec 100644
--- a/ui/src/frontend/error_dialog.ts
+++ b/ui/src/frontend/error_dialog.ts
@@ -52,6 +52,11 @@ export function maybeShowErrorDialog(errLog: string) {
return;
}
+ if (errLog.includes('(ERR:rpc_seq)')) {
+ showRpcSequencingError();
+ return;
+ }
+
if (timeLastReport > 0 && now - timeLastReport <= MIN_REPORT_PERIOD_MS) {
queuedErrors.unshift(errLog);
if (queuedErrors.length > ERR_QUEUE_MAX_LEN) queuedErrors.pop();
@@ -250,3 +255,19 @@ function showWebUSBError() {
buttons: []
});
}
+
+function showRpcSequencingError() {
+ showModal({
+ title: 'A TraceProcessor RPC error occurred',
+ content: m(
+ 'div',
+ m('p', 'The trace processor RPC sequence ID was broken'),
+ m('p', `This can happen when using a HTTP trace processor instance and
+either accidentally sharing this between multiple tabs or
+restarting the trace processor while still in use by UI.`),
+ m('p', `Please refresh this tab and ensure that trace processor is used
+at most one tab at a time.`),
+ ),
+ buttons: []
+ });
+}
diff --git a/ui/src/frontend/file_drop_handler.ts b/ui/src/frontend/file_drop_handler.ts
index 8eccc4d3f..89f38c049 100644
--- a/ui/src/frontend/file_drop_handler.ts
+++ b/ui/src/frontend/file_drop_handler.ts
@@ -42,7 +42,6 @@ export function installFileDropHandler() {
if (evt.dataTransfer && dragEventHasFiles(evt)) {
const file = evt.dataTransfer.files[0];
if (file) {
- globals.frontendLocalState.localOnlyMode = false;
globals.dispatch(Actions.openTraceFromFile({file}));
}
}
diff --git a/ui/src/frontend/flags_page.ts b/ui/src/frontend/flags_page.ts
new file mode 100644
index 000000000..5c04d99f6
--- /dev/null
+++ b/ui/src/frontend/flags_page.ts
@@ -0,0 +1,142 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import * as m from 'mithril';
+
+import {channelChanged, getNextChannel, setChannel} from '../common/channels';
+import {featureFlags, Flag, OverrideState} from '../common/feature_flags';
+
+import {globals} from './globals';
+import {createPage} from './pages';
+
+const RELEASE_PROCESS_URL =
+ 'https://perfetto.dev/docs/visualization/perfetto-ui-release-process';
+
+interface FlagOption {
+ id: string;
+ name: string;
+}
+
+interface SelectWidgetAttrs {
+ label: string;
+ description: m.Children;
+ options: FlagOption[];
+ selected: string;
+ onSelect: (id: string) => void;
+}
+
+class SelectWidget implements m.ClassComponent<SelectWidgetAttrs> {
+ view(vnode: m.Vnode<SelectWidgetAttrs>) {
+ const attrs = vnode.attrs;
+ return m(
+ '.flag-widget',
+ m('label', attrs.label),
+ m(
+ 'select',
+ {
+ onchange: (e: InputEvent) => {
+ const value = (e.target as HTMLSelectElement).value;
+ attrs.onSelect(value);
+ globals.rafScheduler.scheduleFullRedraw();
+ },
+ },
+ attrs.options.map(o => {
+ const selected = o.id === attrs.selected;
+ return m('option', {value: o.id, selected}, o.name);
+ }),
+ ),
+ m('.description', attrs.description),
+ );
+ }
+}
+
+interface FlagWidgetAttrs {
+ flag: Flag;
+}
+
+class FlagWidget implements m.ClassComponent<FlagWidgetAttrs> {
+ view(vnode: m.Vnode<FlagWidgetAttrs>) {
+ const flag = vnode.attrs.flag;
+ const defaultState = flag.defaultValue ? 'Enabled' : 'Disabled';
+ return m(SelectWidget, {
+ label: flag.name,
+ description: flag.description,
+ options: [
+ {id: OverrideState.DEFAULT, name: `Default (${defaultState})`},
+ {id: OverrideState.TRUE, name: 'Enabled'},
+ {id: OverrideState.FALSE, name: 'Disabled'},
+ ],
+ selected: flag.overriddenState(),
+ onSelect: (value: string) => {
+ switch (value) {
+ case OverrideState.TRUE:
+ flag.set(true);
+ break;
+ case OverrideState.FALSE:
+ flag.set(false);
+ break;
+ default:
+ case OverrideState.DEFAULT:
+ flag.reset();
+ break;
+ }
+ }
+ });
+ }
+}
+
+export const FlagsPage = createPage({
+ view() {
+ const needsReload = channelChanged();
+ return m(
+ '.flags-page',
+ m(
+ '.flags-content',
+ m('h1', 'Feature flags'),
+ needsReload &&
+ [
+ m('h2', 'Please reload for your changes to take effect'),
+ ],
+ m(SelectWidget, {
+ label: 'Release channel',
+ description: [
+ 'Which release channel of the UI to use. See ',
+ m('a',
+ {
+ href: RELEASE_PROCESS_URL,
+ },
+ 'Release Process'),
+ ' for more information.'
+ ],
+ options: [
+ {id: 'stable', name: 'Stable (default)'},
+ {id: 'canary', name: 'Canary'},
+ {id: 'autopush', name: 'Autopush'},
+ ],
+ selected: getNextChannel(),
+ onSelect: id => setChannel(id),
+ }),
+ m('button',
+ {
+ onclick: () => {
+ featureFlags.resetAll();
+ globals.rafScheduler.scheduleFullRedraw();
+ },
+ },
+ 'Reset all below'),
+
+ featureFlags.allFlags().map(flag => m(FlagWidget, {flag})),
+ ));
+ }
+});
diff --git a/ui/src/frontend/flamegraph.ts b/ui/src/frontend/flamegraph.ts
index 77e209a49..afa5f7f6b 100644
--- a/ui/src/frontend/flamegraph.ts
+++ b/ui/src/frontend/flamegraph.ts
@@ -33,7 +33,7 @@ interface CallsiteInfoWidth {
// below the box.
const NODE_HEIGHT = 18;
-export const HEAP_PROFILE_HOVERED_COLOR = 'hsl(224, 45%, 55%)';
+export const FLAMEGRAPH_HOVERED_COLOR = 'hsl(224, 45%, 55%)';
export function findRootSize(data: CallsiteInfo[]) {
let totalSize = 0;
@@ -267,19 +267,21 @@ export class Flamegraph {
const offsetPx = 4;
const lines: string[] = [];
- let lineSplitter: LineSplitter;
- const nameText = this.getCallsiteName(this.hoveredCallsite);
- const nameTextSize = ctx.measureText(nameText);
- lineSplitter =
- splitIfTooBig(nameText, width - paddingPx, nameTextSize.width);
- let textWidth = lineSplitter.lineWidth;
- lines.push(...lineSplitter.lines);
-
- const mappingText = this.hoveredCallsite.mapping;
- lineSplitter =
- splitIfTooBig(mappingText, width, ctx.measureText(mappingText).width);
- textWidth = Math.max(textWidth, lineSplitter.lineWidth);
- lines.push(...lineSplitter.lines);
+
+ let textWidth = this.addToTooltip(
+ this.getCallsiteName(this.hoveredCallsite),
+ width - paddingPx,
+ ctx,
+ lines);
+ if (this.hoveredCallsite.location != null) {
+ textWidth = Math.max(
+ textWidth,
+ this.addToTooltip(
+ this.hoveredCallsite.location, width, ctx, lines));
+ }
+ textWidth = Math.max(
+ textWidth,
+ this.addToTooltip(this.hoveredCallsite.mapping, width, ctx, lines));
if (this.nodeRendering.totalSize !== undefined) {
const percentage =
@@ -289,10 +291,8 @@ export class Flamegraph {
this.hoveredCallsite.totalSize,
unit,
unit === 'B' ? 1024 : 1000)} (${percentage.toFixed(2)}%)`;
- lineSplitter = splitIfTooBig(
- totalSizeText, width, ctx.measureText(totalSizeText).width);
- textWidth = Math.max(textWidth, lineSplitter.lineWidth);
- lines.push(...lineSplitter.lines);
+ textWidth = Math.max(
+ textWidth, this.addToTooltip(totalSizeText, width, ctx, lines));
}
if (this.nodeRendering.selfSize !== undefined &&
@@ -304,10 +304,8 @@ export class Flamegraph {
this.hoveredCallsite.selfSize,
unit,
unit === 'B' ? 1024 : 1000)} (${selfPercentage.toFixed(2)}%)`;
- lineSplitter = splitIfTooBig(
- selfSizeText, width, ctx.measureText(selfSizeText).width);
- textWidth = Math.max(textWidth, lineSplitter.lineWidth);
- lines.push(...lineSplitter.lines);
+ textWidth = Math.max(
+ textWidth, this.addToTooltip(selfSizeText, width, ctx, lines));
}
// Compute a line height as the bounding box height + 50%:
@@ -344,6 +342,15 @@ export class Flamegraph {
}
}
+ private addToTooltip(
+ text: string, width: number, ctx: CanvasRenderingContext2D,
+ lines: string[]): number {
+ const lineSplitter: LineSplitter =
+ splitIfTooBig(text, width, ctx.measureText(text).width);
+ lines.push(...lineSplitter.lines);
+ return lineSplitter.lineWidth;
+ }
+
private getCallsiteName(value: CallsiteInfo): string {
return value.name === undefined || value.name === '' ? 'unknown' :
value.name;
diff --git a/ui/src/frontend/flamegraph_panel.ts b/ui/src/frontend/flamegraph_panel.ts
new file mode 100644
index 000000000..368ab3221
--- /dev/null
+++ b/ui/src/frontend/flamegraph_panel.ts
@@ -0,0 +1,340 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use size file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import * as m from 'mithril';
+
+import {assertExists, assertTrue} from '../base/logging';
+import {Actions} from '../common/actions';
+import {
+ ALLOC_SPACE_MEMORY_ALLOCATED_KEY,
+ OBJECTS_ALLOCATED_KEY,
+ OBJECTS_ALLOCATED_NOT_FREED_KEY,
+ PERF_SAMPLES_KEY,
+ SPACE_MEMORY_ALLOCATED_NOT_FREED_KEY,
+} from '../common/flamegraph_util';
+import {CallsiteInfo, FlamegraphStateViewingOption} from '../common/state';
+import {timeToCode} from '../common/time';
+
+import {PerfettoMouseEvent} from './events';
+import {Flamegraph, NodeRendering} from './flamegraph';
+import {globals} from './globals';
+import {showPartialModal} from './modal';
+import {Panel, PanelSize} from './panel';
+import {debounce} from './rate_limiters';
+import {Router} from './router';
+import {getCurrentTrace} from './sidebar';
+import {convertTraceToPprofAndDownload} from './trace_converter';
+
+interface FlamegraphDetailsPanelAttrs {}
+
+const HEADER_HEIGHT = 30;
+
+enum ProfileType {
+ NATIVE_HEAP_PROFILE = 'native',
+ JAVA_HEAP_GRAPH = 'graph',
+ PERF_SAMPLE = 'perf'
+}
+
+function isProfileType(s: string): s is ProfileType {
+ return Object.values(ProfileType).includes(s as ProfileType);
+}
+
+function toProfileType(s: string): ProfileType {
+ if (!isProfileType(s)) {
+ throw new Error('Unknown type ${s}');
+ }
+ return s;
+}
+
+function toSelectedCallsite(c: CallsiteInfo|undefined): string {
+ if (c !== undefined && c.name !== undefined) {
+ return c.name;
+ }
+ return '(none)';
+}
+
+const RENDER_SELF_AND_TOTAL: NodeRendering = {
+ selfSize: 'Self',
+ totalSize: 'Total',
+};
+const RENDER_OBJ_COUNT: NodeRendering = {
+ selfSize: 'Self objects',
+ totalSize: 'Subtree objects',
+};
+
+export class FlamegraphDetailsPanel extends Panel<FlamegraphDetailsPanelAttrs> {
+ private profileType?: ProfileType = undefined;
+ private ts = 0;
+ private pids: number[] = [];
+ private flamegraph: Flamegraph = new Flamegraph([]);
+ private focusRegex = '';
+ private updateFocusRegexDebounced = debounce(() => {
+ this.updateFocusRegex();
+ }, 20);
+
+ view() {
+ const flamegraphDetails = globals.flamegraphDetails;
+ if (flamegraphDetails && flamegraphDetails.type !== undefined &&
+ flamegraphDetails.startNs !== undefined &&
+ flamegraphDetails.durNs !== undefined &&
+ flamegraphDetails.pids !== undefined &&
+ flamegraphDetails.upids !== undefined) {
+ this.profileType = toProfileType(flamegraphDetails.type);
+ this.ts = flamegraphDetails.durNs;
+ this.pids = flamegraphDetails.pids;
+ if (flamegraphDetails.flamegraph) {
+ this.flamegraph.updateDataIfChanged(
+ this.nodeRendering(), flamegraphDetails.flamegraph);
+ }
+ const height = flamegraphDetails.flamegraph ?
+ this.flamegraph.getHeight() + HEADER_HEIGHT :
+ 0;
+ return m(
+ '.details-panel',
+ {
+ onclick: (e: PerfettoMouseEvent) => {
+ if (this.flamegraph !== undefined) {
+ this.onMouseClick({y: e.layerY, x: e.layerX});
+ }
+ return false;
+ },
+ onmousemove: (e: PerfettoMouseEvent) => {
+ if (this.flamegraph !== undefined) {
+ this.onMouseMove({y: e.layerY, x: e.layerX});
+ globals.rafScheduler.scheduleRedraw();
+ }
+ },
+ onmouseout: () => {
+ if (this.flamegraph !== undefined) {
+ this.onMouseOut();
+ }
+ }
+ },
+ this.maybeShowModal(flamegraphDetails.graphIncomplete),
+ m('.details-panel-heading.flamegraph-profile',
+ {onclick: (e: MouseEvent) => e.stopPropagation()},
+ [
+ m('div.options',
+ [
+ m('div.title', this.getTitle()),
+ this.getViewingOptionButtons(),
+ ]),
+ m('div.details',
+ [
+ m('div.selected',
+ `Selected function: ${
+ toSelectedCallsite(
+ flamegraphDetails.expandedCallsite)}`),
+ m('div.time',
+ `Snapshot time: ${timeToCode(flamegraphDetails.durNs)}`),
+ m('input[type=text][placeholder=Focus]', {
+ oninput: (e: Event) => {
+ const target = (e.target as HTMLInputElement);
+ this.focusRegex = target.value;
+ this.updateFocusRegexDebounced();
+ },
+ // Required to stop hot-key handling:
+ onkeydown: (e: Event) => e.stopPropagation(),
+ }),
+ this.profileType === ProfileType.NATIVE_HEAP_PROFILE ?
+ m('button.download',
+ {
+ onclick: () => {
+ this.downloadPprof();
+ }
+ },
+ m('i.material-icons', 'file_download'),
+ 'Download profile') :
+ null
+ ]),
+ ]),
+ m(`div[style=height:${height}px]`),
+ );
+ } else {
+ return m(
+ '.details-panel',
+ m('.details-panel-heading', m('h2', `Flamegraph Profile`)));
+ }
+ }
+
+
+ private maybeShowModal(graphIncomplete?: boolean): m.Vnode|undefined {
+ if (!graphIncomplete || globals.state.flamegraphModalDismissed) {
+ return undefined;
+ }
+ return showPartialModal({
+ title: 'The flamegraph is incomplete',
+ content:
+ m('div',
+ m('div',
+ 'The current trace does not have a fully formed flamegraph.')),
+ buttons: [
+ {
+ text: 'Show the errors',
+ primary: true,
+ id: 'incomplete_graph_show',
+ action: () => {
+ Router.navigate('#!/info');
+ }
+ },
+ {
+ text: 'Skip',
+ primary: false,
+ id: 'incomplete_graph_skip',
+ action: () => {
+ globals.dispatch(Actions.dismissFlamegraphModal({}));
+ globals.rafScheduler.scheduleFullRedraw();
+ }
+ }
+ ],
+ });
+ }
+
+ private getTitle(): string {
+ switch (this.profileType!) {
+ case ProfileType.NATIVE_HEAP_PROFILE:
+ return 'Heap Profile:';
+ case ProfileType.JAVA_HEAP_GRAPH:
+ return 'Java Heap:';
+ case ProfileType.PERF_SAMPLE:
+ return 'Perf sample:';
+ default:
+ throw new Error('unknown type');
+ }
+ }
+
+ private nodeRendering(): NodeRendering {
+ if (this.profileType === undefined) {
+ return {};
+ }
+ const viewingOption = globals.state.currentFlamegraphState!.viewingOption;
+ switch (this.profileType) {
+ case ProfileType.JAVA_HEAP_GRAPH:
+ if (viewingOption === OBJECTS_ALLOCATED_NOT_FREED_KEY) {
+ return RENDER_OBJ_COUNT;
+ } else {
+ return RENDER_SELF_AND_TOTAL;
+ }
+ case ProfileType.NATIVE_HEAP_PROFILE:
+ case ProfileType.PERF_SAMPLE:
+ return RENDER_SELF_AND_TOTAL;
+ default:
+ throw new Error('unknown type');
+ }
+ }
+
+ private updateFocusRegex() {
+ globals.dispatch(Actions.changeFocusFlamegraphState({
+ focusRegex: this.focusRegex,
+ }));
+ }
+
+ getViewingOptionButtons(): m.Children {
+ return m(
+ 'div',
+ ...FlamegraphDetailsPanel.selectViewingOptions(
+ assertExists(this.profileType)));
+ }
+
+ downloadPprof() {
+ const engine = Object.values(globals.state.engines)[0];
+ if (!engine) return;
+ getCurrentTrace()
+ .then(file => {
+ assertTrue(
+ this.pids.length === 1,
+ 'Native profiles can only contain one pid.');
+ convertTraceToPprofAndDownload(file, this.pids[0], this.ts);
+ })
+ .catch(error => {
+ throw new Error(`Failed to get current trace ${error}`);
+ });
+ }
+
+ private changeFlamegraphData() {
+ const data = globals.flamegraphDetails;
+ const flamegraphData = data.flamegraph === undefined ? [] : data.flamegraph;
+ this.flamegraph.updateDataIfChanged(
+ this.nodeRendering(), flamegraphData, data.expandedCallsite);
+ }
+
+ renderCanvas(ctx: CanvasRenderingContext2D, size: PanelSize) {
+ this.changeFlamegraphData();
+ const current = globals.state.currentFlamegraphState;
+ if (current === null) return;
+ const unit =
+ current.viewingOption === SPACE_MEMORY_ALLOCATED_NOT_FREED_KEY ||
+ current.viewingOption === ALLOC_SPACE_MEMORY_ALLOCATED_KEY ?
+ 'B' :
+ '';
+ this.flamegraph.draw(ctx, size.width, size.height, 0, HEADER_HEIGHT, unit);
+ }
+
+ onMouseClick({x, y}: {x: number, y: number}): boolean {
+ const expandedCallsite = this.flamegraph.onMouseClick({x, y});
+ globals.dispatch(Actions.expandFlamegraphState({expandedCallsite}));
+ return true;
+ }
+
+ onMouseMove({x, y}: {x: number, y: number}): boolean {
+ this.flamegraph.onMouseMove({x, y});
+ return true;
+ }
+
+ onMouseOut() {
+ this.flamegraph.onMouseOut();
+ }
+
+ private static selectViewingOptions(profileType: ProfileType) {
+ switch (profileType) {
+ case ProfileType.PERF_SAMPLE:
+ return [this.buildButtonComponent(PERF_SAMPLES_KEY, 'samples')];
+ case ProfileType.JAVA_HEAP_GRAPH:
+ return [
+ this.buildButtonComponent(
+ SPACE_MEMORY_ALLOCATED_NOT_FREED_KEY, 'space'),
+ this.buildButtonComponent(OBJECTS_ALLOCATED_NOT_FREED_KEY, 'objects')
+ ];
+ case ProfileType.NATIVE_HEAP_PROFILE:
+ return [
+ this.buildButtonComponent(
+ SPACE_MEMORY_ALLOCATED_NOT_FREED_KEY, 'space'),
+ this.buildButtonComponent(OBJECTS_ALLOCATED_NOT_FREED_KEY, 'objects'),
+ this.buildButtonComponent(
+ ALLOC_SPACE_MEMORY_ALLOCATED_KEY, 'alloc space'),
+ this.buildButtonComponent(OBJECTS_ALLOCATED_KEY, 'alloc objects')
+ ];
+ default:
+ throw new Error(`Unexpected profile type ${profileType}`);
+ }
+ }
+
+ private static buildButtonComponent(
+ viewingOption: FlamegraphStateViewingOption, text: string) {
+ const buttonsClass =
+ (globals.state.currentFlamegraphState &&
+ globals.state.currentFlamegraphState.viewingOption === viewingOption) ?
+ '.chosen' :
+ '';
+ return m(
+ `button${buttonsClass}`,
+ {
+ onclick: () => {
+ globals.dispatch(
+ Actions.changeViewFlamegraphState({viewingOption}));
+ }
+ },
+ text);
+ }
+}
diff --git a/ui/src/frontend/flow_events_panel.ts b/ui/src/frontend/flow_events_panel.ts
index 6f1546869..c7783b977 100644
--- a/ui/src/frontend/flow_events_panel.ts
+++ b/ui/src/frontend/flow_events_panel.ts
@@ -15,11 +15,11 @@
import * as m from 'mithril';
import {Actions} from '../common/actions';
+import {timeToCode} from '../common/time';
import {Flow, globals} from './globals';
import {BLANK_CHECKBOX, CHECKBOX} from './icons';
import {Panel, PanelSize} from './panel';
-import {findUiTrackId} from './scroll_helper';
export const ALL_CATEGORIES = '_all_';
@@ -44,7 +44,7 @@ export class FlowEventsPanel extends Panel {
}
const flowClickHandler = (sliceId: number, trackId: number) => {
- const uiTrackId = findUiTrackId(trackId);
+ const uiTrackId = globals.state.uiTrackIdByTraceTrackId[trackId];
if (uiTrackId) {
globals.makeSelection(
Actions.selectChromeSlice(
@@ -59,8 +59,13 @@ export class FlowEventsPanel extends Panel {
const columns = [
m('th', 'Direction'),
+ m('th', 'Duration'),
m('th', 'Connected Slice ID'),
- m('th', 'Connected Slice Name')
+ m('th', 'Connected Slice Name'),
+ m('th', 'Thread Out'),
+ m('th', 'Thread In'),
+ m('th', 'Process Out'),
+ m('th', 'Process In')
];
if (haveCategories) {
@@ -82,15 +87,21 @@ export class FlowEventsPanel extends Panel {
const args = {
onclick: () => flowClickHandler(otherEnd.sliceId, otherEnd.trackId),
- onmousemove: () =>
- globals.frontendLocalState.setHighlightedSliceId(otherEnd.sliceId),
- onmouseleave: () => globals.frontendLocalState.setHighlightedSliceId(-1)
+ onmousemove: () => globals.dispatch(
+ Actions.setHighlightedSliceId({sliceId: otherEnd.sliceId})),
+ onmouseleave: () =>
+ globals.dispatch(Actions.setHighlightedSliceId({sliceId: -1})),
};
const data = [
m('td.flow-link', args, outgoing ? 'Outgoing' : 'Incoming'),
+ m('td.flow-link', args, timeToCode(flow.dur)),
m('td.flow-link', args, otherEnd.sliceId.toString()),
- m('td.flow-link', args, otherEnd.sliceName)
+ m('td.flow-link', args, otherEnd.sliceName),
+ m('td.flow-link', args, flow.begin.threadName),
+ m('td.flow-link', args, flow.end.threadName),
+ m('td.flow-link', args, flow.begin.processName),
+ m('td.flow-link', args, flow.end.processName)
];
if (haveCategories) {
@@ -103,7 +114,7 @@ export class FlowEventsPanel extends Panel {
return m('.details-panel', [
m('.details-panel-heading', m('h2', `Flow events`)),
- m('.flow-events-table', m('table.half-width', rows))
+ m('.flow-events-table', m('table', rows))
]);
}
diff --git a/ui/src/frontend/flow_events_renderer.ts b/ui/src/frontend/flow_events_renderer.ts
index 33b7dab57..1d2a71925 100644
--- a/ui/src/frontend/flow_events_renderer.ts
+++ b/ui/src/frontend/flow_events_renderer.ts
@@ -16,7 +16,6 @@ import {TRACK_SHELL_WIDTH} from './css_constants';
import {ALL_CATEGORIES, getFlowCategories} from './flow_events_panel';
import {Flow, FlowPoint, globals} from './globals';
import {PanelVNode} from './panel';
-import {findUiTrackId} from './scroll_helper';
import {SliceRect} from './track';
import {TrackGroupPanel} from './track_group_panel';
import {TrackPanel} from './track_panel';
@@ -98,7 +97,7 @@ export class FlowEventsRendererArgs {
export class FlowEventsRenderer {
private getTrackGroupIdByTrackId(trackId: number): string|undefined {
- const uiTrackId = findUiTrackId(trackId);
+ const uiTrackId = globals.state.uiTrackIdByTraceTrackId[trackId];
return uiTrackId ? globals.state.tracks[uiTrackId].trackGroup : undefined;
}
@@ -212,11 +211,10 @@ export class FlowEventsRenderer {
y: endYConnection.y,
dir: endDir
};
- const highlighted =
- flow.end.sliceId === globals.frontendLocalState.highlightedSliceId ||
- flow.begin.sliceId === globals.frontendLocalState.highlightedSliceId;
- const focused = flow.id === globals.frontendLocalState.focusedFlowIdLeft ||
- flow.id === globals.frontendLocalState.focusedFlowIdRight;
+ const highlighted = flow.end.sliceId === globals.state.highlightedSliceId ||
+ flow.begin.sliceId === globals.state.highlightedSliceId;
+ const focused = flow.id === globals.state.focusedFlowIdLeft ||
+ flow.id === globals.state.focusedFlowIdRight;
let intensity = DEFAULT_FLOW_INTENSITY;
let width = DEFAULT_FLOW_WIDTH;
@@ -265,8 +263,11 @@ export class FlowEventsRenderer {
begin: {x: number, y: number, dir: LineDirection},
end: {x: number, y: number, dir: LineDirection}, hue: number,
intensity: number, width: number) {
+ const hasArrowHead = Math.abs(begin.x - end.x) > 3 * TRIANGLE_SIZE;
const END_OFFSET =
- (end.dir === 'RIGHT' || end.dir === 'LEFT' ? TRIANGLE_SIZE : 0);
+ (((end.dir === 'RIGHT' || end.dir === 'LEFT') && hasArrowHead) ?
+ TRIANGLE_SIZE :
+ 0);
const color = `hsl(${hue}, 50%, ${intensity}%)`;
// draw curved line from begin to end (bezier curve)
ctx.strokeStyle = color;
@@ -302,17 +303,23 @@ export class FlowEventsRenderer {
ctx.arc(end.x, end.y, CIRCLE_RADIUS, 0, 2 * Math.PI);
ctx.closePath();
ctx.fill();
- } else {
- const dx = this.getDeltaX(end.dir, TRIANGLE_SIZE);
- const dy = this.getDeltaY(end.dir, TRIANGLE_SIZE);
- // draw small triangle
- ctx.fillStyle = color;
- ctx.beginPath();
- ctx.moveTo(end.x, end.y);
- ctx.lineTo(end.x - dx - dy, end.y + dx - dy);
- ctx.lineTo(end.x - dx + dy, end.y - dx - dy);
- ctx.closePath();
- ctx.fill();
+ } else if (hasArrowHead) {
+ this.drawArrowHead(end, ctx, color);
}
}
+
+ private drawArrowHead(
+ end: {x: number; y: number; dir: LineDirection},
+ ctx: CanvasRenderingContext2D, color: string) {
+ const dx = this.getDeltaX(end.dir, TRIANGLE_SIZE);
+ const dy = this.getDeltaY(end.dir, TRIANGLE_SIZE);
+ // draw small triangle
+ ctx.fillStyle = color;
+ ctx.beginPath();
+ ctx.moveTo(end.x, end.y);
+ ctx.lineTo(end.x - dx - dy, end.y + dx - dy);
+ ctx.lineTo(end.x - dx + dy, end.y - dx - dy);
+ ctx.closePath();
+ ctx.fill();
+ }
}
diff --git a/ui/src/frontend/frontend_local_state.ts b/ui/src/frontend/frontend_local_state.ts
index 4349f8177..b09327bc8 100644
--- a/ui/src/frontend/frontend_local_state.ts
+++ b/ui/src/frontend/frontend_local_state.ts
@@ -35,7 +35,10 @@ interface Range {
function chooseLatest<T extends Timestamped<{}>>(current: T, next: T): T {
if (next !== current && next.lastUpdate > current.lastUpdate) {
- return next;
+ // |next| is from state. Callers may mutate the return value of
+ // this function so we need to clone |next| to prevent bad mutations
+ // of state:
+ return Object.assign({}, next);
}
return current;
}
@@ -65,26 +68,14 @@ function calculateScrollbarWidth() {
export class FrontendLocalState {
visibleWindowTime = new TimeSpan(0, 10);
timeScale = new TimeScale(this.visibleWindowTime, [0, 0]);
- perfDebug = false;
- hoveredUtid = -1;
- hoveredPid = -1;
- hoveredLogsTimestamp = -1;
- hoveredNoteTimestamp = -1;
- highlightedSliceId = -1;
- focusedFlowIdLeft = -1;
- focusedFlowIdRight = -1;
- vidTimestamp = -1;
- localOnlyMode = false;
- sidebarVisible = true;
showPanningHint = false;
showCookieConsent = false;
visibleTracks = new Set<string>();
prevVisibleTracks = new Set<string>();
- searchIndex = -1;
- currentTab?: string;
scrollToTrackId?: string|number;
httpRpcState: HttpRpcState = {connected: false};
newVersionAvailable = false;
+ showPivotTable = false;
// This is used to calculate the tracks within a Y range for area selection.
areaY: Range = {};
@@ -117,70 +108,15 @@ export class FrontendLocalState {
return this.scrollBarWidth;
}
- togglePerfDebug() {
- this.perfDebug = !this.perfDebug;
- globals.rafScheduler.scheduleFullRedraw();
- }
-
- setHoveredUtidAndPid(utid: number, pid: number) {
- this.hoveredUtid = utid;
- this.hoveredPid = pid;
- globals.rafScheduler.scheduleRedraw();
- }
-
- setHighlightedSliceId(sliceId: number) {
- this.highlightedSliceId = sliceId;
- globals.rafScheduler.scheduleRedraw();
- }
-
- setHighlightedFlowLeftId(flowId: number) {
- this.focusedFlowIdLeft = flowId;
- globals.rafScheduler.scheduleFullRedraw();
- }
-
- setHighlightedFlowRightId(flowId: number) {
- this.focusedFlowIdRight = flowId;
+ setHttpRpcState(httpRpcState: HttpRpcState) {
+ this.httpRpcState = httpRpcState;
globals.rafScheduler.scheduleFullRedraw();
}
- // Sets the timestamp at which a vertical line will be drawn.
- setHoveredLogsTimestamp(ts: number) {
- if (this.hoveredLogsTimestamp === ts) return;
- this.hoveredLogsTimestamp = ts;
- globals.rafScheduler.scheduleRedraw();
- }
-
- setHoveredNoteTimestamp(ts: number) {
- if (this.hoveredNoteTimestamp === ts) return;
- this.hoveredNoteTimestamp = ts;
- globals.rafScheduler.scheduleRedraw();
- }
-
- setVidTimestamp(ts: number) {
- if (this.vidTimestamp === ts) return;
- this.vidTimestamp = ts;
- globals.rafScheduler.scheduleRedraw();
- }
-
addVisibleTrack(trackId: string) {
this.visibleTracks.add(trackId);
}
- setSearchIndex(index: number) {
- this.searchIndex = index;
- globals.rafScheduler.scheduleRedraw();
- }
-
- toggleSidebar() {
- this.sidebarVisible = !this.sidebarVisible;
- globals.rafScheduler.scheduleFullRedraw();
- }
-
- setHttpRpcState(httpRpcState: HttpRpcState) {
- this.httpRpcState = httpRpcState;
- globals.rafScheduler.scheduleFullRedraw();
- }
-
// Called when beginning a canvas redraw.
clearVisibleTracks() {
this.visibleTracks.clear();
@@ -197,10 +133,24 @@ export class FrontendLocalState {
}
}
+ togglePivotTable() {
+ this.showPivotTable = !this.showPivotTable;
+ globals.rafScheduler.scheduleFullRedraw();
+ }
+
mergeState(state: FrontendState): void {
+ // This is unfortunately subtle. This class mutates this._visibleState.
+ // Since we may not mutate |state| (in order to make immer's immutable
+ // updates work) this means that we have to make a copy of the visibleState.
+ // when updating it. We don't want to have to do that unnecessarily so
+ // chooseLatest returns a shallow clone of state.visibleState *only* when
+ // that is the newer state. All of these complications should vanish when
+ // we remove this class.
+ const previousVisibleState = this._visibleState;
this._omniboxState = chooseLatest(this._omniboxState, state.omniboxState);
this._visibleState = chooseLatest(this._visibleState, state.visibleState);
- if (this._visibleState === state.visibleState) {
+ const visibleStateWasUpdated = previousVisibleState !== this._visibleState;
+ if (visibleStateWasUpdated) {
this.updateLocalTime(
new TimeSpan(this._visibleState.startSec, this._visibleState.endSec));
}
@@ -225,7 +175,7 @@ export class FrontendLocalState {
}
private setOmniboxDebounced = debounce(() => {
- globals.dispatch(Actions.setOmnibox(this._omniboxState));
+ globals.dispatch(Actions.setOmnibox({...this._omniboxState}));
}, 20);
setOmnibox(value: string, mode: 'SEARCH'|'COMMAND') {
diff --git a/ui/src/frontend/globals.ts b/ui/src/frontend/globals.ts
index dd1e85876..71e2a342b 100644
--- a/ui/src/frontend/globals.ts
+++ b/ui/src/frontend/globals.ts
@@ -13,27 +13,39 @@
// limitations under the License.
import {assertExists} from '../base/logging';
-import {DeferredAction} from '../common/actions';
+import {Actions, DeferredAction} from '../common/actions';
import {AggregateData} from '../common/aggregation_data';
import {Args, ArgsTree} from '../common/arg_types';
+import {
+ ConversionJobName,
+ ConversionJobStatus
+} from '../common/conversion_jobs';
+import {createEmptyState} from '../common/empty_state';
+import {Engine} from '../common/engine';
import {MetricResult} from '../common/metric_data';
import {CurrentSearchResults, SearchSummary} from '../common/search_data';
-import {CallsiteInfo, createEmptyState, State} from '../common/state';
+import {CallsiteInfo, State} from '../common/state';
import {fromNs, toNs} from '../common/time';
-import {Analytics, initAnalytics} from '../frontend/analytics';
+import {Analytics, initAnalytics} from './analytics';
import {FrontendLocalState} from './frontend_local_state';
+import {PivotTableHelper} from './pivot_table_helper';
import {RafScheduler} from './raf_scheduler';
+import {Router} from './router';
import {ServiceWorkerController} from './service_worker_controller';
type Dispatch = (action: DeferredAction) => void;
type TrackDataStore = Map<string, {}>;
-type QueryResultsStore = Map<string, {}>;
+type QueryResultsStore = Map<string, {}|undefined>;
+type PivotTableHelperStore = Map<string, PivotTableHelper>;
type AggregateDataStore = Map<string, AggregateData>;
type Description = Map<string, string>;
+
export interface SliceDetails {
ts?: number;
dur?: number;
+ thread_ts?: number;
+ thread_dur?: number;
priority?: number;
endState?: string;
cpu?: number;
@@ -45,6 +57,13 @@ export interface SliceDetails {
wakerCpu?: number;
category?: string;
name?: string;
+ tid?: number;
+ threadName?: string;
+ pid?: number;
+ processName?: string;
+ uid?: number;
+ packageName?: string;
+ versionCode?: number;
args?: Args;
argsTree?: ArgsTree;
description?: Description;
@@ -58,6 +77,12 @@ export interface FlowPoint {
sliceId: number;
sliceStartTs: number;
sliceEndTs: number;
+ // Thread and process info. Only set in sliceSelected not in areaSelected as
+ // the latter doesn't display per-flow info and it'd be a waste to join
+ // additional tables for undisplayed info in that case. Nothing precludes
+ // adding this in a future iteration however.
+ threadName: string;
+ processName: string;
depth: number;
}
@@ -67,6 +92,7 @@ export interface Flow {
begin: FlowPoint;
end: FlowPoint;
+ dur: number;
category?: string;
name?: string;
@@ -77,6 +103,7 @@ export interface CounterDetails {
value?: number;
delta?: number;
duration?: number;
+ name?: string;
}
export interface ThreadStateDetails {
@@ -89,17 +116,23 @@ export interface ThreadStateDetails {
blockedFunction?: string;
}
-export interface HeapProfileDetails {
+export interface FlamegraphDetails {
type?: string;
id?: number;
- ts?: number;
- tsNs?: number;
- pid?: number;
- upid?: number;
+ startNs?: number;
+ durNs?: number;
+ pids?: number[];
+ upids?: number[];
flamegraph?: CallsiteInfo[];
expandedCallsite?: CallsiteInfo;
viewingOption?: string;
expandedId?: number;
+ // isInAreaSelection is true if a flamegraph is part of the current area
+ // selection.
+ isInAreaSelection?: boolean;
+ // When heap_graph_non_finalized_graph has a count >0, we mark the graph
+ // as incomplete.
+ graphIncomplete?: boolean;
}
export interface CpuProfileDetails {
@@ -129,7 +162,14 @@ type ThreadMap = Map<number, ThreadDesc>;
function getRoot() {
// Works out the root directory where the content should be served from
// e.g. `http://origin/v1.2.3/`.
- let root = (document.currentScript as HTMLScriptElement).src;
+ const script = document.currentScript as HTMLScriptElement;
+
+ // Needed for DOM tests, that do not have script element.
+ if (script === null) {
+ return '';
+ }
+
+ let root = script.src;
root = root.substr(0, root.lastIndexOf('/') + 1);
return root;
}
@@ -140,19 +180,19 @@ function getRoot() {
class Globals {
readonly root = getRoot();
+ private _testing = false;
private _dispatch?: Dispatch = undefined;
- private _controllerWorker?: Worker = undefined;
private _state?: State = undefined;
private _frontendLocalState?: FrontendLocalState = undefined;
private _rafScheduler?: RafScheduler = undefined;
private _serviceWorkerController?: ServiceWorkerController = undefined;
private _logging?: Analytics = undefined;
private _isInternalUser: boolean|undefined = undefined;
- private _channel: string|undefined = undefined;
// TODO(hjd): Unify trackDataStore, queryResults, overviewStore, threads.
private _trackDataStore?: TrackDataStore = undefined;
private _queryResults?: QueryResultsStore = undefined;
+ private _pivotTableHelper?: PivotTableHelperStore = undefined;
private _overviewStore?: OverviewStore = undefined;
private _aggregateDataStore?: AggregateDataStore = undefined;
private _threadMap?: ThreadMap = undefined;
@@ -162,7 +202,7 @@ class Globals {
private _selectedFlows?: Flow[] = undefined;
private _visibleFlowCategories?: Map<string, boolean> = undefined;
private _counterDetails?: CounterDetails = undefined;
- private _heapProfileDetails?: HeapProfileDetails = undefined;
+ private _flamegraphDetails?: FlamegraphDetails = undefined;
private _cpuProfileDetails?: CpuProfileDetails = undefined;
private _numQueriesQueued = 0;
private _bufferUsage?: number = undefined;
@@ -170,11 +210,17 @@ class Globals {
private _traceErrors?: number = undefined;
private _metricError?: string = undefined;
private _metricResult?: MetricResult = undefined;
+ private _hasFtrace?: boolean = undefined;
+ private _jobStatus?: Map<ConversionJobName, ConversionJobStatus> = undefined;
+ private _router?: Router = undefined;
+
+ // TODO(hjd): Remove once we no longer need to update UUID on redraw.
+ private _publishRedraw?: () => void = undefined;
private _currentSearchResults: CurrentSearchResults = {
- sliceIds: [],
- tsStarts: [],
- utids: [],
+ sliceIds: new Float64Array(0),
+ tsStarts: new Float64Array(0),
+ utids: new Float64Array(0),
trackIds: [],
sources: [],
totalResults: 0,
@@ -185,18 +231,23 @@ class Globals {
count: new Uint8Array(0),
};
- initialize(dispatch: Dispatch, controllerWorker: Worker) {
+ engines = new Map<string, Engine>();
+
+ initialize(dispatch: Dispatch, router: Router) {
this._dispatch = dispatch;
- this._controllerWorker = controllerWorker;
+ this._router = router;
this._state = createEmptyState();
this._frontendLocalState = new FrontendLocalState();
this._rafScheduler = new RafScheduler();
this._serviceWorkerController = new ServiceWorkerController();
+ this._testing =
+ self.location && self.location.search.indexOf('testing=1') >= 0;
this._logging = initAnalytics();
// TODO(hjd): Unify trackDataStore, queryResults, overviewStore, threads.
this._trackDataStore = new Map<string, {}>();
this._queryResults = new Map<string, {}>();
+ this._pivotTableHelper = new Map<string, PivotTableHelper>();
this._overviewStore = new Map<string, QuantizedLoad[]>();
this._aggregateDataStore = new Map<string, AggregateData>();
this._threadMap = new Map<number, ThreadDesc>();
@@ -206,8 +257,21 @@ class Globals {
this._visibleFlowCategories = new Map<string, boolean>();
this._counterDetails = {};
this._threadStateDetails = {};
- this._heapProfileDetails = {};
+ this._flamegraphDetails = {};
this._cpuProfileDetails = {};
+ this.engines.clear();
+ }
+
+ get router(): Router {
+ return assertExists(this._router);
+ }
+
+ get publishRedraw(): () => void {
+ return this._publishRedraw || (() => {});
+ }
+
+ set publishRedraw(f: () => void) {
+ this._publishRedraw = f;
}
get state(): State {
@@ -251,6 +315,10 @@ class Globals {
return assertExists(this._queryResults);
}
+ get pivotTableHelper(): PivotTableHelperStore {
+ return assertExists(this._pivotTableHelper);
+ }
+
get threads() {
return assertExists(this._threadMap);
}
@@ -307,12 +375,12 @@ class Globals {
return assertExists(this._aggregateDataStore);
}
- get heapProfileDetails() {
- return assertExists(this._heapProfileDetails);
+ get flamegraphDetails() {
+ return assertExists(this._flamegraphDetails);
}
- set heapProfileDetails(click: HeapProfileDetails) {
- this._heapProfileDetails = assertExists(click);
+ set flamegraphDetails(click: FlamegraphDetails) {
+ this._flamegraphDetails = assertExists(click);
}
get traceErrors() {
@@ -371,6 +439,34 @@ class Globals {
this._currentSearchResults = results;
}
+ get hasFtrace(): boolean {
+ return !!this._hasFtrace;
+ }
+
+ set hasFtrace(value: boolean) {
+ this._hasFtrace = value;
+ }
+
+ getConversionJobStatus(name: ConversionJobName): ConversionJobStatus {
+ return this.getJobStatusMap().get(name) || ConversionJobStatus.NotRunning;
+ }
+
+ setConversionJobStatus(name: ConversionJobName, status: ConversionJobStatus) {
+ const map = this.getJobStatusMap();
+ if (status === ConversionJobStatus.NotRunning) {
+ map.delete(name);
+ } else {
+ map.set(name, status);
+ }
+ }
+
+ private getJobStatusMap(): Map<ConversionJobName, ConversionJobStatus> {
+ if (!this._jobStatus) {
+ this._jobStatus = new Map();
+ }
+ return this._jobStatus;
+ }
+
setBufferUsage(bufferUsage: number) {
this._bufferUsage = bufferUsage;
}
@@ -420,9 +516,9 @@ class Globals {
makeSelection(action: DeferredAction<{}>, tabToOpen = 'current_selection') {
// A new selection should cancel the current search selection.
- globals.frontendLocalState.searchIndex = -1;
- globals.frontendLocalState.currentTab =
- action.type === 'deselect' ? undefined : tabToOpen;
+ globals.dispatch(Actions.setSearchIndex({index: -1}));
+ const tab = action.type === 'deselect' ? undefined : tabToOpen;
+ globals.dispatch(Actions.setCurrentTab({tab}));
globals.dispatch(action);
}
@@ -436,6 +532,7 @@ class Globals {
// TODO(hjd): Unify trackDataStore, queryResults, overviewStore, threads.
this._trackDataStore = undefined;
this._queryResults = undefined;
+ this._pivotTableHelper = undefined;
this._overviewStore = undefined;
this._threadMap = undefined;
this._sliceDetails = undefined;
@@ -444,9 +541,9 @@ class Globals {
this._numQueriesQueued = 0;
this._metricResult = undefined;
this._currentSearchResults = {
- sliceIds: [],
- tsStarts: [],
- utids: [],
+ sliceIds: new Float64Array(0),
+ tsStarts: new Float64Array(0),
+ utids: new Float64Array(0),
trackIds: [],
sources: [],
totalResults: 0,
@@ -471,11 +568,8 @@ class Globals {
this._isInternalUser = value;
}
- get channel() {
- if (this._channel === undefined) {
- this._channel = localStorage.getItem('perfettoUiChannel') || 'stable';
- }
- return this._channel;
+ get testing() {
+ return this._testing;
}
// Used when switching to the legacy TraceViewer UI.
@@ -483,7 +577,6 @@ class Globals {
// however pending RAFs and workers seem to outlive the |window| and need to
// be cleaned up explicitly.
shutdown() {
- this._controllerWorker!.terminate();
this._rafScheduler!.shutdown();
}
}
diff --git a/ui/src/frontend/heap_profile_panel.ts b/ui/src/frontend/heap_profile_panel.ts
deleted file mode 100644
index 3957dce27..000000000
--- a/ui/src/frontend/heap_profile_panel.ts
+++ /dev/null
@@ -1,278 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use size file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import * as m from 'mithril';
-
-import {Actions} from '../common/actions';
-import {
- ALLOC_SPACE_MEMORY_ALLOCATED_KEY,
- OBJECTS_ALLOCATED_KEY,
- OBJECTS_ALLOCATED_NOT_FREED_KEY,
- SPACE_MEMORY_ALLOCATED_NOT_FREED_KEY,
-} from '../common/flamegraph_util';
-import {HeapProfileFlamegraphViewingOption} from '../common/state';
-import {timeToCode} from '../common/time';
-
-import {PerfettoMouseEvent} from './events';
-import {Flamegraph, NodeRendering} from './flamegraph';
-import {globals} from './globals';
-import {Panel, PanelSize} from './panel';
-import {debounce} from './rate_limiters';
-
-interface HeapProfileDetailsPanelAttrs {}
-
-const HEADER_HEIGHT = 30;
-
-enum ProfileType {
- NATIVE_HEAP_PROFILE = 'native',
- JAVA_HEAP_GRAPH = 'graph',
-}
-
-function isProfileType(s: string): s is ProfileType {
- return Object.values(ProfileType).includes(s as ProfileType);
-}
-
-function toProfileType(s: string): ProfileType {
- if (!isProfileType(s)) {
- throw new Error('Unknown type ${s}');
- }
- return s;
-}
-
-const RENDER_SELF_AND_TOTAL: NodeRendering = {
- selfSize: 'Self',
- totalSize: 'Total',
-};
-const RENDER_OBJ_COUNT: NodeRendering = {
- selfSize: 'Self objects',
- totalSize: 'Subtree objects',
-};
-
-export class HeapProfileDetailsPanel extends
- Panel<HeapProfileDetailsPanelAttrs> {
- private profileType?: ProfileType = undefined;
- private ts = 0;
- private pid = 0;
- private flamegraph: Flamegraph = new Flamegraph([]);
- private focusRegex = '';
- private updateFocusRegexDebounced = debounce(() => {
- this.updateFocusRegex();
- }, 20);
-
- view() {
- const heapDumpInfo = globals.heapProfileDetails;
- if (heapDumpInfo && heapDumpInfo.type !== undefined &&
- heapDumpInfo.ts !== undefined && heapDumpInfo.tsNs !== undefined &&
- heapDumpInfo.pid !== undefined && heapDumpInfo.upid !== undefined) {
- this.profileType = toProfileType(heapDumpInfo.type);
- this.ts = heapDumpInfo.tsNs;
- this.pid = heapDumpInfo.pid;
- if (heapDumpInfo.flamegraph) {
- this.flamegraph.updateDataIfChanged(
- this.nodeRendering(), heapDumpInfo.flamegraph);
- }
- const height = heapDumpInfo.flamegraph ?
- this.flamegraph.getHeight() + HEADER_HEIGHT :
- 0;
- return m(
- '.details-panel',
- {
- onclick: (e: PerfettoMouseEvent) => {
- if (this.flamegraph !== undefined) {
- this.onMouseClick({y: e.layerY, x: e.layerX});
- }
- return false;
- },
- onmousemove: (e: PerfettoMouseEvent) => {
- if (this.flamegraph !== undefined) {
- this.onMouseMove({y: e.layerY, x: e.layerX});
- globals.rafScheduler.scheduleRedraw();
- }
- },
- onmouseout: () => {
- if (this.flamegraph !== undefined) {
- this.onMouseOut();
- }
- }
- },
- m('.details-panel-heading.heap-profile',
- {onclick: (e: MouseEvent) => e.stopPropagation()},
- [
- m('div.options',
- [
- m('div.title', this.getTitle()),
- this.getViewingOptionButtons(),
- ]),
- m('div.details',
- [
- m('div.time',
- `Snapshot time: ${timeToCode(heapDumpInfo.ts)}`),
- m('input[type=text][placeholder=Focus]', {
- oninput: (e: Event) => {
- const target = (e.target as HTMLInputElement);
- this.focusRegex = target.value;
- this.updateFocusRegexDebounced();
- },
- // Required to stop hot-key handling:
- onkeydown: (e: Event) => e.stopPropagation(),
- }),
- this.profileType === ProfileType.NATIVE_HEAP_PROFILE ?
- m('button.download',
- {
- onclick: () => {
- this.downloadPprof();
- }
- },
- m('i.material-icons', 'file_download'),
- 'Download profile') :
- null
- ]),
- ]),
- m(`div[style=height:${height}px]`),
- );
- } else {
- return m(
- '.details-panel',
- m('.details-panel-heading', m('h2', `Heap Profile`)));
- }
- }
-
- private getTitle(): string {
- switch (this.profileType!) {
- case ProfileType.NATIVE_HEAP_PROFILE:
- return 'Heap Profile:';
- case ProfileType.JAVA_HEAP_GRAPH:
- return 'Java Heap:';
- default:
- throw new Error('unknown type');
- }
- }
-
- private nodeRendering(): NodeRendering {
- if (this.profileType === undefined) {
- return {};
- }
- const viewingOption =
- globals.state.currentHeapProfileFlamegraph!.viewingOption;
- switch (this.profileType) {
- case ProfileType.NATIVE_HEAP_PROFILE:
- return RENDER_SELF_AND_TOTAL;
- case ProfileType.JAVA_HEAP_GRAPH:
- if (viewingOption === OBJECTS_ALLOCATED_NOT_FREED_KEY) {
- return RENDER_OBJ_COUNT;
- } else {
- return RENDER_SELF_AND_TOTAL;
- }
- default:
- throw new Error('unknown type');
- }
- }
-
- private updateFocusRegex() {
- globals.dispatch(Actions.changeFocusHeapProfileFlamegraph({
- focusRegex: this.focusRegex,
- }));
- }
-
- getButtonsClass(button: HeapProfileFlamegraphViewingOption): string {
- if (globals.state.currentHeapProfileFlamegraph === null) return '';
- return globals.state.currentHeapProfileFlamegraph.viewingOption === button ?
- '.chosen' :
- '';
- }
-
- getViewingOptionButtons(): m.Children {
- const viewingOptions = [
- m(`button${this.getButtonsClass(SPACE_MEMORY_ALLOCATED_NOT_FREED_KEY)}`,
- {
- onclick: () => {
- this.changeViewingOption(SPACE_MEMORY_ALLOCATED_NOT_FREED_KEY);
- }
- },
- 'space'),
- m(`button${this.getButtonsClass(OBJECTS_ALLOCATED_NOT_FREED_KEY)}`,
- {
- onclick: () => {
- this.changeViewingOption(OBJECTS_ALLOCATED_NOT_FREED_KEY);
- }
- },
- 'objects'),
- ];
-
- if (this.profileType === ProfileType.NATIVE_HEAP_PROFILE) {
- viewingOptions.push(
- m(`button${this.getButtonsClass(ALLOC_SPACE_MEMORY_ALLOCATED_KEY)}`,
- {
- onclick: () => {
- this.changeViewingOption(ALLOC_SPACE_MEMORY_ALLOCATED_KEY);
- }
- },
- 'alloc space'),
- m(`button${this.getButtonsClass(OBJECTS_ALLOCATED_KEY)}`,
- {
- onclick: () => {
- this.changeViewingOption(OBJECTS_ALLOCATED_KEY);
- }
- },
- 'alloc objects'));
- }
- return m('div', ...viewingOptions);
- }
-
- changeViewingOption(viewingOption: HeapProfileFlamegraphViewingOption) {
- globals.dispatch(Actions.changeViewHeapProfileFlamegraph({viewingOption}));
- }
-
- downloadPprof() {
- const engine = Object.values(globals.state.engines)[0];
- if (!engine) return;
- const src = engine.source;
- globals.dispatch(
- Actions.convertTraceToPprof({pid: this.pid, ts1: this.ts, src}));
- }
-
- private changeFlamegraphData() {
- const data = globals.heapProfileDetails;
- const flamegraphData = data.flamegraph === undefined ? [] : data.flamegraph;
- this.flamegraph.updateDataIfChanged(
- this.nodeRendering(), flamegraphData, data.expandedCallsite);
- }
-
- renderCanvas(ctx: CanvasRenderingContext2D, size: PanelSize) {
- this.changeFlamegraphData();
- const current = globals.state.currentHeapProfileFlamegraph;
- if (current === null) return;
- const unit =
- current.viewingOption === SPACE_MEMORY_ALLOCATED_NOT_FREED_KEY ||
- current.viewingOption === ALLOC_SPACE_MEMORY_ALLOCATED_KEY ?
- 'B' :
- '';
- this.flamegraph.draw(ctx, size.width, size.height, 0, HEADER_HEIGHT, unit);
- }
-
- onMouseClick({x, y}: {x: number, y: number}): boolean {
- const expandedCallsite = this.flamegraph.onMouseClick({x, y});
- globals.dispatch(Actions.expandHeapProfileFlamegraph({expandedCallsite}));
- return true;
- }
-
- onMouseMove({x, y}: {x: number, y: number}): boolean {
- this.flamegraph.onMouseMove({x, y});
- return true;
- }
-
- onMouseOut() {
- this.flamegraph.onMouseOut();
- }
-}
diff --git a/ui/src/frontend/help_modal.ts b/ui/src/frontend/help_modal.ts
index a562f478e..62dbab1a8 100644
--- a/ui/src/frontend/help_modal.ts
+++ b/ui/src/frontend/help_modal.ts
@@ -16,6 +16,7 @@
import * as m from 'mithril';
import {globals} from './globals';
+import {PIVOT_TABLE_FLAG} from './keyboard_event_handler';
import {hideModel, showModal} from './modal';
let helpModelOpen = false;
@@ -91,6 +92,12 @@ function showHelp() {
keycap('m'),
' (with event or area selected)'),
m('td', 'Mark the area (persistently)')),
+ m('tr',
+ m('td', keycap('Ctrl'), ' + ', keycap('b')),
+ m('td', 'Toggle display of sidebar')),
+ PIVOT_TABLE_FLAG.get() ?
+ m('tr', m('td', keycap('p')), m('td', 'Show pivot table')) :
+ null,
m('tr', m('td', keycap('?')), m('td', 'Show help')),
)),
buttons: [],
diff --git a/ui/src/frontend/home_page.ts b/ui/src/frontend/home_page.ts
index 91a318605..9cf48cf28 100644
--- a/ui/src/frontend/home_page.ts
+++ b/ui/src/frontend/home_page.ts
@@ -13,11 +13,12 @@
// limitations under the License.
import * as m from 'mithril';
-import {globals} from './globals';
+import {channelChanged, getNextChannel, setChannel} from '../common/channels';
+
+import {globals} from './globals';
import {createPage} from './pages';
-let channelChanged = false;
export const HomePage = createPage({
view() {
@@ -37,7 +38,7 @@ export const HomePage = createPage({
mkChan('canary'),
m('.highlight'),
),
- m(`.home-page-reload${channelChanged ? '.show' : ''}`,
+ m(`.home-page-reload${channelChanged() ? '.show' : ''}`,
'You need to reload the page for the changes to have effect'),
),
),
@@ -48,17 +49,13 @@ export const HomePage = createPage({
});
function mkChan(chan: string) {
- const checked =
- !channelChanged && globals.channel === chan ? '[checked=true]' : '';
+ const checked = getNextChannel() === chan ? '[checked=true]' : '';
return [
- m(`input[type=radio][name=chan][id=chan_${chan}]${checked}`,
- {onchange: () => changeChannel(chan)}),
+ m(`input[type=radio][name=chan][id=chan_${chan}]${checked}`, {
+ onchange: () => {
+ setChannel(chan);
+ }
+ }),
m(`label[for=chan_${chan}]`, chan),
];
}
-
-function changeChannel(chan: string) {
- localStorage.setItem('perfettoUiChannel', chan);
- channelChanged = true;
- globals.rafScheduler.scheduleFullRedraw();
-}
diff --git a/ui/src/frontend/index.ts b/ui/src/frontend/index.ts
index 5b2814e1a..15ad0cf73 100644
--- a/ui/src/frontend/index.ts
+++ b/ui/src/frontend/index.ts
@@ -12,257 +12,110 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import '../tracks/all_frontend';
-
-import {applyPatches, Patch} from 'immer';
+import {Patch, produce} from 'immer';
import * as m from 'mithril';
import {defer} from '../base/deferred';
import {assertExists, reportError, setErrorHandler} from '../base/logging';
-import {forwardRemoteCalls} from '../base/remote';
-import {Actions} from '../common/actions';
-import {AggregateData} from '../common/aggregation_data';
+import {Actions, DeferredAction, StateActions} from '../common/actions';
+import {createEmptyState} from '../common/empty_state';
+import {initializeImmerJs} from '../common/immer_init';
+import {State} from '../common/state';
+import {initWasm} from '../common/wasm_engine_proxy';
+import {ControllerWorkerInitMessage} from '../common/worker_messages';
import {
- LogBoundsKey,
- LogEntriesKey,
- LogExists,
- LogExistsKey
-} from '../common/logs';
-import {MetricResult} from '../common/metric_data';
-import {CurrentSearchResults, SearchSummary} from '../common/search_data';
+ isGetCategoriesResponse
+} from '../controller/chrome_proxy_record_controller';
+import {initController} from '../controller/index';
import {AnalyzePage} from './analyze_page';
-import {loadAndroidBugToolInfo} from './android_bug_tool';
import {initCssConstants} from './css_constants';
import {maybeShowErrorDialog} from './error_dialog';
import {installFileDropHandler} from './file_drop_handler';
-import {
- CounterDetails,
- CpuProfileDetails,
- Flow,
- globals,
- HeapProfileDetails,
- QuantizedLoad,
- SliceDetails,
- ThreadDesc,
- ThreadStateDetails
-} from './globals';
+import {FlagsPage} from './flags_page';
+import {globals} from './globals';
import {HomePage} from './home_page';
-import {openBufferWithLegacyTraceViewer} from './legacy_trace_viewer';
import {initLiveReloadIfLocalhost} from './live_reload';
import {MetricsPage} from './metrics_page';
import {postMessageHandler} from './post_message_handler';
import {RecordPage, updateAvailableAdbDevices} from './record_page';
import {Router} from './router';
import {CheckHttpRpcConnection} from './rpc_http_dialog';
-import {taskTracker} from './task_tracker';
import {TraceInfoPage} from './trace_info_page';
+import {maybeOpenTraceFromRoute} from './trace_url_handler';
import {ViewerPage} from './viewer_page';
const EXTENSION_ID = 'lfmkphfpdbjijhpomgecfikhfohaoine';
-function isLocalhostTraceUrl(url: string): boolean {
- return ['127.0.0.1', 'localhost'].includes((new URL(url)).hostname);
-}
-
-/**
- * The API the main thread exposes to the controller.
- */
class FrontendApi {
- constructor(private router: Router) {}
-
- patchState(patches: Patch[]) {
- const oldState = globals.state;
- globals.state = applyPatches(globals.state, patches);
-
- // If the visible time in the global state has been updated more recently
- // than the visible time handled by the frontend @ 60fps, update it. This
- // typically happens when restoring the state from a permalink.
- globals.frontendLocalState.mergeState(globals.state.frontendLocalState);
+ private port: MessagePort;
+ private state: State;
- // Only redraw if something other than the frontendLocalState changed.
- for (const key in globals.state) {
- if (key !== 'frontendLocalState' && key !== 'visibleTracks' &&
- oldState[key] !== globals.state[key]) {
- this.redraw();
- return;
- }
- }
+ constructor(port: MessagePort) {
+ this.state = createEmptyState();
+ this.port = port;
}
- // TODO: we can't have a publish method for each batch of data that we don't
- // want to keep in the global state. Figure out a more generic and type-safe
- // mechanism to achieve this.
-
- publishOverviewData(data: {[key: string]: QuantizedLoad|QuantizedLoad[]}) {
- for (const [key, value] of Object.entries(data)) {
- if (!globals.overviewStore.has(key)) {
- globals.overviewStore.set(key, []);
- }
- if (value instanceof Array) {
- globals.overviewStore.get(key)!.push(...value);
- } else {
- globals.overviewStore.get(key)!.push(value);
+ dispatchMultiple(actions: DeferredAction[]) {
+ const oldState = this.state;
+ const patches: Patch[] = [];
+ for (const action of actions) {
+ const originalLength = patches.length;
+ const morePatches = this.applyAction(action);
+ patches.length += morePatches.length;
+ for (let i = 0; i < morePatches.length; ++i) {
+ patches[i + originalLength] = morePatches[i];
}
}
- globals.rafScheduler.scheduleRedraw();
- }
- publishTrackData(args: {id: string, data: {}}) {
- globals.setTrackData(args.id, args.data);
- if ([LogExistsKey, LogBoundsKey, LogEntriesKey].includes(args.id)) {
- const data = globals.trackDataStore.get(LogExistsKey) as LogExists;
- if (data && data.exists) globals.rafScheduler.scheduleFullRedraw();
- } else {
- globals.rafScheduler.scheduleRedraw();
+ if (this.state === oldState) {
+ return;
}
- }
-
- publishQueryResult(args: {id: string, data: {}}) {
- globals.queryResults.set(args.id, args.data);
- this.redraw();
- }
-
- publishThreads(data: ThreadDesc[]) {
- globals.threads.clear();
- data.forEach(thread => {
- globals.threads.set(thread.utid, thread);
- });
- this.redraw();
- }
-
- publishSliceDetails(click: SliceDetails) {
- globals.sliceDetails = click;
- this.redraw();
- }
- publishThreadStateDetails(click: ThreadStateDetails) {
- globals.threadStateDetails = click;
- this.redraw();
- }
+ // Update overall state.
+ globals.state = this.state;
- publishConnectedFlows(connectedFlows: Flow[]) {
- globals.connectedFlows = connectedFlows;
- // Call resetFlowFocus() each time connectedFlows is updated to correctly
- // navigate using hotkeys.
- this.resetFlowFocus();
- this.redraw();
- }
+ // If the visible time in the global state has been updated more recently
+ // than the visible time handled by the frontend @ 60fps, update it. This
+ // typically happens when restoring the state from a permalink.
+ globals.frontendLocalState.mergeState(this.state.frontendLocalState);
- // If a chrome slice is selected and we have any flows in connectedFlows
- // we will find the flows on the right and left of that slice to set a default
- // focus. In all other cases the focusedFlowId(Left|Right) will be set to -1.
- resetFlowFocus() {
- globals.frontendLocalState.focusedFlowIdLeft = -1;
- globals.frontendLocalState.focusedFlowIdRight = -1;
- if (globals.state.currentSelection?.kind === 'CHROME_SLICE') {
- const sliceId = globals.state.currentSelection.id;
- for (const flow of globals.connectedFlows) {
- if (flow.begin.sliceId === sliceId) {
- globals.frontendLocalState.focusedFlowIdRight = flow.id;
- }
- if (flow.end.sliceId === sliceId) {
- globals.frontendLocalState.focusedFlowIdLeft = flow.id;
- }
+ // Only redraw if something other than the frontendLocalState changed.
+ for (const key in this.state) {
+ if (key !== 'frontendLocalState' && key !== 'visibleTracks' &&
+ oldState[key] !== this.state[key]) {
+ globals.rafScheduler.scheduleFullRedraw();
+ break;
}
}
- }
-
- publishSelectedFlows(selectedFlows: Flow[]) {
- globals.selectedFlows = selectedFlows;
- this.redraw();
- }
-
- publishCounterDetails(click: CounterDetails) {
- globals.counterDetails = click;
- this.redraw();
- }
-
- publishHeapProfileDetails(click: HeapProfileDetails) {
- globals.heapProfileDetails = click;
- this.redraw();
- }
-
- publishCpuProfileDetails(details: CpuProfileDetails) {
- globals.cpuProfileDetails = details;
- this.redraw();
- }
-
- publishFileDownload(args: {file: File, name?: string}) {
- const url = URL.createObjectURL(args.file);
- const a = document.createElement('a');
- a.href = url;
- a.download = args.name !== undefined ? args.name : args.file.name;
- document.body.appendChild(a);
- a.click();
- document.body.removeChild(a);
- URL.revokeObjectURL(url);
- }
-
- publishLoading(numQueuedQueries: number) {
- globals.numQueuedQueries = numQueuedQueries;
- // TODO(hjd): Clean up loadingAnimation given that this now causes a full
- // redraw anyways. Also this should probably just go via the global state.
- globals.rafScheduler.scheduleFullRedraw();
- }
-
- // For opening JSON/HTML traces with the legacy catapult viewer.
- publishLegacyTrace(args: {data: ArrayBuffer, size: number}) {
- const arr = new Uint8Array(args.data, 0, args.size);
- const str = (new TextDecoder('utf-8')).decode(arr);
- openBufferWithLegacyTraceViewer('trace.json', str, 0);
- globals.dispatch(Actions.clearConversionInProgress({}));
- }
-
- publishBufferUsage(args: {percentage: number}) {
- globals.setBufferUsage(args.percentage);
- this.redraw();
- }
-
- publishSearch(args: SearchSummary) {
- globals.searchSummary = args;
- this.redraw();
- }
-
- publishSearchResult(args: CurrentSearchResults) {
- globals.currentSearchResults = args;
- this.redraw();
- }
-
- publishRecordingLog(args: {logs: string}) {
- globals.setRecordingLog(args.logs);
- this.redraw();
- }
- publishTraceErrors(numErrors: number) {
- globals.setTraceErrors(numErrors);
- this.redraw();
- }
-
- publishMetricError(error: string) {
- globals.setMetricError(error);
- globals.logging.logError(error, false);
- this.redraw();
- }
-
- publishMetricResult(metricResult: MetricResult) {
- globals.setMetricResult(metricResult);
- this.redraw();
+ if (patches.length > 0) {
+ this.port.postMessage(patches);
+ }
}
- publishAggregateData(args: {data: AggregateData, kind: string}) {
- globals.setAggregateData(args.kind, args.data);
- this.redraw();
+ private applyAction(action: DeferredAction): Patch[] {
+ const patches: Patch[] = [];
+
+ // 'produce' creates a immer proxy which wraps the current state turning
+ // all imperative mutations of the state done in the callback into
+ // immutable changes to the returned state.
+ this.state = produce(
+ this.state,
+ draft => {
+ // tslint:disable-next-line no-any
+ (StateActions as any)[action.type](draft, action.args);
+ },
+ (morePatches, _) => {
+ const originalLength = patches.length;
+ patches.length += morePatches.length;
+ for (let i = 0; i < morePatches.length; ++i) {
+ patches[i + originalLength] = morePatches[i];
+ }
+ });
+ return patches;
}
- private redraw(): void {
- if (globals.state.route &&
- globals.state.route !== this.router.getRouteFromHash()) {
- this.router.setRouteOnHash(globals.state.route);
- }
-
- globals.rafScheduler.scheduleFullRedraw();
- }
}
function setExtensionAvailability(available: boolean) {
@@ -281,6 +134,9 @@ function setupContentSecurityPolicy() {
],
'script-src': [
`'self'`,
+ // TODO(b/201596551): this is required for Wasm after crrev.com/c/3179051
+ // and should be replaced with 'wasm-unsafe-eval'.
+ `'unsafe-eval'`,
'https://*.google.com',
'https://*.googleusercontent.com',
'https://www.googletagmanager.com',
@@ -290,6 +146,7 @@ function setupContentSecurityPolicy() {
'connect-src': [
`'self'`,
'http://127.0.0.1:9001', // For trace_processor_shell --httpd.
+ 'ws://127.0.0.1:9001', // Ditto, for the websocket RPC.
'https://www.google-analytics.com',
'https://*.googleapis.com', // For Google Cloud Storage fetches.
'blob:',
@@ -345,8 +202,6 @@ function main() {
window.addEventListener('error', e => reportError(e));
window.addEventListener('unhandledrejection', e => reportError(e));
- const controller = new Worker(globals.root + 'controller_bundle.js');
- const frontendChannel = new MessageChannel();
const controllerChannel = new MessageChannel();
const extensionLocalChannel = new MessageChannel();
const errorReportingChannel = new MessageChannel();
@@ -354,38 +209,39 @@ function main() {
errorReportingChannel.port2.onmessage = (e) =>
maybeShowErrorDialog(`${e.data}`);
- controller.postMessage(
- {
- frontendPort: frontendChannel.port1,
- controllerPort: controllerChannel.port1,
- extensionPort: extensionLocalChannel.port1,
- errorReportingPort: errorReportingChannel.port1,
- },
- [
- frontendChannel.port1,
- controllerChannel.port1,
- extensionLocalChannel.port1,
- errorReportingChannel.port1,
- ]);
-
- const dispatch =
- controllerChannel.port2.postMessage.bind(controllerChannel.port2);
- globals.initialize(dispatch, controller);
+ const msg: ControllerWorkerInitMessage = {
+ controllerPort: controllerChannel.port1,
+ extensionPort: extensionLocalChannel.port1,
+ errorReportingPort: errorReportingChannel.port1,
+ };
+
+ initWasm(globals.root);
+ initializeImmerJs();
+
+ initController(msg);
+
+ const dispatch = (action: DeferredAction) => {
+ frontendApi.dispatchMultiple([action]);
+ };
+
+ const router = new Router({
+ '/': HomePage,
+ '/viewer': ViewerPage,
+ '/record': RecordPage,
+ '/query': AnalyzePage,
+ '/flags': FlagsPage,
+ '/metrics': MetricsPage,
+ '/info': TraceInfoPage,
+ });
+ router.onRouteChanged = (route) => {
+ globals.rafScheduler.scheduleFullRedraw();
+ maybeOpenTraceFromRoute(route);
+ };
+ globals.initialize(dispatch, router);
globals.serviceWorkerController.install();
- const router = new Router(
- '/',
- {
- '/': HomePage,
- '/viewer': ViewerPage,
- '/record': RecordPage,
- '/query': AnalyzePage,
- '/metrics': MetricsPage,
- '/info': TraceInfoPage,
- },
- dispatch,
- globals.logging);
- forwardRemoteCalls(frontendChannel.port2, new FrontendApi(router));
+ const frontendApi = new FrontendApi(controllerChannel.port2);
+ globals.publishRedraw = () => globals.rafScheduler.scheduleFullRedraw();
// We proxy messages between the extension and the controller because the
// controller's worker can't access chrome.runtime.
@@ -404,6 +260,10 @@ function main() {
// This forwards the messages from the extension to the controller.
extensionPort.onMessage.addListener(
(message: object, _port: chrome.runtime.Port) => {
+ if (isGetCategoriesResponse(message)) {
+ globals.dispatch(Actions.setChromeCategories(message));
+ return;
+ }
extensionLocalChannel.port2.postMessage(message);
});
}
@@ -423,73 +283,25 @@ function main() {
if (e.ctrlKey) e.preventDefault();
}, {passive: false});
- cssLoadPromise.then(() => onCssLoaded(router));
+ cssLoadPromise.then(() => onCssLoaded());
+
+ if (globals.testing) {
+ document.body.classList.add('testing');
+ }
}
-function onCssLoaded(router: Router) {
+
+function onCssLoaded() {
initCssConstants();
// Clear all the contents of the initial page (e.g. the <pre> error message)
// And replace it with the root <main> element which will be used by mithril.
document.body.innerHTML = '<main></main>';
const main = assertExists(document.body.querySelector('main'));
- globals.rafScheduler.domRedraw = () =>
- m.render(main, m(router.resolve(globals.state.route)));
-
- router.navigateToCurrentHash();
-
- // /?s=xxxx for permalinks.
- const stateHash = Router.param('s');
- const urlHash = Router.param('url');
- const androidBugTool = Router.param('openFromAndroidBugTool');
- if (typeof stateHash === 'string' && stateHash) {
- globals.dispatch(Actions.loadPermalink({
- hash: stateHash,
- }));
- } else if (typeof urlHash === 'string' && urlHash) {
- if (isLocalhostTraceUrl(urlHash)) {
- const fileName = urlHash.split('/').pop() || 'local_trace.pftrace';
- const request = fetch(urlHash)
- .then(response => response.blob())
- .then(blob => {
- globals.dispatch(Actions.openTraceFromFile({
- file: new File([blob], fileName),
- }));
- })
- .catch(e => alert(`Could not load local trace ${e}`));
- taskTracker.trackPromise(request, 'Downloading local trace');
- } else {
- globals.dispatch(Actions.openTraceFromUrl({
- url: urlHash,
- }));
- }
- } else if (androidBugTool) {
- // TODO(hjd): Unify updateStatus and TaskTracker
- globals.dispatch(Actions.updateStatus({
- msg: 'Loading trace from ABT extension',
- timestamp: Date.now() / 1000
- }));
- const loadInfo = loadAndroidBugToolInfo();
- taskTracker.trackPromise(loadInfo, 'Loading trace from ABT extension');
- loadInfo
- .then(info => {
- globals.dispatch(Actions.openTraceFromFile({
- file: info.file,
- }));
- })
- .catch(e => {
- console.error(e);
- });
- }
-
- // Add support for opening traces from postMessage().
- window.addEventListener('message', postMessageHandler, {passive: true});
+ globals.rafScheduler.domRedraw = () => {
+ m.render(main, globals.router.resolve());
+ };
- // Will update the chip on the sidebar footer that notifies that the RPC is
- // connected. Has no effect on the controller (which will repeat this check
- // before creating a new engine).
- CheckHttpRpcConnection();
initLiveReloadIfLocalhost();
-
updateAvailableAdbDevices();
try {
navigator.usb.addEventListener(
@@ -499,7 +311,31 @@ function onCssLoaded(router: Router) {
} catch (e) {
console.error('WebUSB API not supported');
}
- installFileDropHandler();
+
+ // Will update the chip on the sidebar footer that notifies that the RPC is
+ // connected. Has no effect on the controller (which will repeat this check
+ // before creating a new engine).
+ // Don't auto-open any trace URLs until we get a response here because we may
+ // accidentially clober the state of an open trace processor instance
+ // otherwise.
+ CheckHttpRpcConnection().then(() => {
+ installFileDropHandler();
+
+ // Don't allow postMessage or opening trace from route when the user says
+ // that they want to reuse the already loaded trace in trace processor.
+ const values = Object.values(globals.state.engines);
+ if (values.length > 0 &&
+ globals.state.engines[values.length - 1].source.type === 'HTTP_RPC') {
+ return;
+ }
+
+ // Add support for opening traces from postMessage().
+ window.addEventListener('message', postMessageHandler, {passive: true});
+
+ // Handles the initial ?local_cache_key=123 or ?s=permalink or ?url=...
+ // cases.
+ maybeOpenTraceFromRoute(Router.parseUrl(window.location.href));
+ });
}
main();
diff --git a/ui/src/frontend/keyboard_event_handler.ts b/ui/src/frontend/keyboard_event_handler.ts
index 7d82ac233..0bbb98e19 100644
--- a/ui/src/frontend/keyboard_event_handler.ts
+++ b/ui/src/frontend/keyboard_event_handler.ts
@@ -13,17 +13,25 @@
// limitations under the License.
import {Actions} from '../common/actions';
+import {featureFlags} from '../common/feature_flags';
+import {DEFAULT_PIVOT_TABLE_ID} from '../common/pivot_table_common';
import {Area} from '../common/state';
import {Flow, globals} from './globals';
import {toggleHelp} from './help_modal';
import {
- findUiTrackId,
horizontalScrollAndZoomToRange,
verticalScrollToTrack
} from './scroll_helper';
import {executeSearch} from './search_handler';
+export const PIVOT_TABLE_FLAG = featureFlags.register({
+ id: 'pivotTables',
+ name: 'Pivot tables',
+ description: 'Show experimental pivot table details tab.',
+ defaultValue: false,
+});
+
const INSTANT_FOCUS_DURATION_S = 1 / 1e9; // 1 ns.
type Direction = 'Forward'|'Backward';
@@ -32,37 +40,28 @@ type Direction = 'Forward'|'Backward';
export function handleKey(e: KeyboardEvent, down: boolean) {
const key = e.key.toLowerCase();
const selection = globals.state.currentSelection;
- if (down && 'm' === key) {
+ const noModifiers = !(e.ctrlKey || e.metaKey || e.altKey || e.shiftKey);
+ const ctrlOrMeta = (e.ctrlKey || e.metaKey) && !(e.altKey || e.shiftKey);
+ // No other modifiers other than possibly Shift.
+ const maybeShift = !(e.ctrlKey || e.metaKey || e.altKey);
+
+ if (down && 'm' === key && maybeShift) {
if (selection && selection.kind === 'AREA') {
globals.dispatch(Actions.toggleMarkCurrentArea({persistent: e.shiftKey}));
} else if (selection) {
lockSliceSpan(e.shiftKey);
}
}
- if (down && 'f' === key) {
+ if (down && 'f' === key && noModifiers) {
findCurrentSelection();
}
- if (down && 'v' === key) {
- globals.dispatch(Actions.toggleVideo({}));
- }
- if (down && 'p' === key) {
- globals.dispatch(Actions.toggleFlagPause({}));
- }
- if (down && 't' === key) {
- globals.dispatch(Actions.toggleScrubbing({}));
- if (globals.frontendLocalState.vidTimestamp < 0) {
- globals.frontendLocalState.setVidTimestamp(Number.MAX_SAFE_INTEGER);
- } else {
- globals.frontendLocalState.setVidTimestamp(Number.MIN_SAFE_INTEGER);
- }
+ if (down && 'b' === key && ctrlOrMeta) {
+ globals.dispatch(Actions.toggleSidebar({}));
}
- if (down && 'b' === key && (e.ctrlKey || e.metaKey)) {
- globals.frontendLocalState.toggleSidebar();
- }
- if (down && '?' === key) {
+ if (down && '?' === key && maybeShift) {
toggleHelp();
}
- if (down && 'enter' === key) {
+ if (down && 'enter' === key && maybeShift) {
e.preventDefault();
executeSearch(e.shiftKey);
}
@@ -71,18 +70,29 @@ export function handleKey(e: KeyboardEvent, down: boolean) {
globals.makeSelection(Actions.deselect({}));
globals.dispatch(Actions.removeNote({id: '0'}));
}
- if (down && ']' === key) {
- if (e.ctrlKey) {
- focusOtherFlow('Forward');
- } else {
- moveByFocusedFlow('Forward');
- }
+ if (down && ']' === key && ctrlOrMeta) {
+ focusOtherFlow('Forward');
+ }
+ if (down && ']' === key && noModifiers) {
+ moveByFocusedFlow('Forward');
+ }
+ if (down && '[' === key && ctrlOrMeta) {
+ focusOtherFlow('Backward');
}
- if (down && '[' === key) {
- if (e.ctrlKey) {
- focusOtherFlow('Backward');
- } else {
- moveByFocusedFlow('Backward');
+ if (down && '[' === key && noModifiers) {
+ moveByFocusedFlow('Backward');
+ }
+ if (down && 'p' === key && noModifiers && PIVOT_TABLE_FLAG.get()) {
+ e.preventDefault();
+ globals.frontendLocalState.togglePivotTable();
+ const pivotTableId = DEFAULT_PIVOT_TABLE_ID;
+ if (globals.state.pivotTable[pivotTableId] === undefined) {
+ globals.dispatch(Actions.addNewPivotTable({
+ name: 'Pivot Table',
+ pivotTableId,
+ selectedPivots: [],
+ selectedAggregations: []
+ }));
}
}
}
@@ -125,18 +135,18 @@ function focusOtherFlow(direction: Direction) {
flow.end.sliceId === sliceId && direction === 'Backward');
if (direction === 'Backward') {
- const nextFlowId = findAnotherFlowExcept(
- boundFlows, globals.frontendLocalState.focusedFlowIdLeft);
- globals.frontendLocalState.setHighlightedFlowLeftId(nextFlowId);
+ const nextFlowId =
+ findAnotherFlowExcept(boundFlows, globals.state.focusedFlowIdLeft);
+ globals.dispatch(Actions.setHighlightedFlowLeftId({flowId: nextFlowId}));
} else {
- const nextFlowId = findAnotherFlowExcept(
- boundFlows, globals.frontendLocalState.focusedFlowIdRight);
- globals.frontendLocalState.setHighlightedFlowRightId(nextFlowId);
+ const nextFlowId =
+ findAnotherFlowExcept(boundFlows, globals.state.focusedFlowIdRight);
+ globals.dispatch(Actions.setHighlightedFlowRightId({flowId: nextFlowId}));
}
}
// Select the slice connected to the flow in focus
-function moveByFocusedFlow(direction: Direction) {
+function moveByFocusedFlow(direction: Direction): void {
if (!globals.state.currentSelection ||
globals.state.currentSelection.kind !== 'CHROME_SLICE') {
return;
@@ -144,9 +154,8 @@ function moveByFocusedFlow(direction: Direction) {
const sliceId = globals.state.currentSelection.id;
const flowId =
- (direction === 'Backward' ?
- globals.frontendLocalState.focusedFlowIdLeft :
- globals.frontendLocalState.focusedFlowIdRight);
+ (direction === 'Backward' ? globals.state.focusedFlowIdLeft :
+ globals.state.focusedFlowIdRight);
if (sliceId === -1 || flowId === -1) {
return;
@@ -156,40 +165,64 @@ function moveByFocusedFlow(direction: Direction) {
for (const flow of globals.connectedFlows) {
if (flow.id === flowId) {
const flowPoint = (direction === 'Backward' ? flow.begin : flow.end);
- const uiTrackId = findUiTrackId(flowPoint.trackId);
+ const uiTrackId =
+ globals.state.uiTrackIdByTraceTrackId[flowPoint.trackId];
if (uiTrackId) {
- globals.makeSelection(Actions.selectChromeSlice(
- {id: flowPoint.sliceId, trackId: uiTrackId, table: 'slice'}));
+ globals.makeSelection(Actions.selectChromeSlice({
+ id: flowPoint.sliceId,
+ trackId: uiTrackId,
+ table: 'slice',
+ scroll: true
+ }));
}
}
}
}
-function findTimeRangeOfSelection() {
+function findTimeRangeOfSelection(): {startTs: number, endTs: number} {
const selection = globals.state.currentSelection;
let startTs = -1;
let endTs = -1;
- if (selection !== null) {
- if (selection.kind === 'SLICE' || selection.kind === 'CHROME_SLICE') {
- const slice = globals.sliceDetails;
- if (slice.ts && slice.dur !== undefined && slice.dur > 0) {
- startTs = slice.ts + globals.state.traceTime.startSec;
- endTs = startTs + slice.dur;
- } else if (slice.ts) {
- startTs = slice.ts + globals.state.traceTime.startSec;
- endTs = startTs + INSTANT_FOCUS_DURATION_S;
- }
- } else if (selection.kind === 'THREAD_STATE') {
- const threadState = globals.threadStateDetails;
- if (threadState.ts && threadState.dur) {
- startTs = threadState.ts + globals.state.traceTime.startSec;
- endTs = startTs + threadState.dur;
- }
- } else if (selection.kind === 'COUNTER') {
- startTs = selection.leftTs;
- endTs = selection.rightTs;
+ if (selection === null) {
+ return {startTs, endTs};
+ } else if (selection.kind === 'SLICE' || selection.kind === 'CHROME_SLICE') {
+ const slice = globals.sliceDetails;
+ if (slice.ts && slice.dur !== undefined && slice.dur > 0) {
+ startTs = slice.ts + globals.state.traceTime.startSec;
+ endTs = startTs + slice.dur;
+ } else if (slice.ts) {
+ startTs = slice.ts + globals.state.traceTime.startSec;
+ // This will handle either:
+ // a)slice.dur === -1 -> unfinished slice
+ // b)slice.dur === 0 -> instant event
+ endTs = slice.dur === -1 ? globals.state.traceTime.endSec :
+ startTs + INSTANT_FOCUS_DURATION_S;
+ }
+ } else if (selection.kind === 'THREAD_STATE') {
+ const threadState = globals.threadStateDetails;
+ if (threadState.ts && threadState.dur) {
+ startTs = threadState.ts + globals.state.traceTime.startSec;
+ endTs = startTs + threadState.dur;
+ }
+ } else if (selection.kind === 'COUNTER') {
+ startTs = selection.leftTs;
+ endTs = selection.rightTs;
+ } else if (selection.kind === 'AREA') {
+ const selectedArea = globals.state.areas[selection.areaId];
+ if (selectedArea) {
+ startTs = selectedArea.startSec;
+ endTs = selectedArea.endSec;
+ }
+ } else if (selection.kind === 'NOTE') {
+ const selectedNote = globals.state.notes[selection.id];
+ // Notes can either be default or area notes. Area notes are handled
+ // above in the AREA case.
+ if (selectedNote && selectedNote.noteType === 'DEFAULT') {
+ startTs = selectedNote.timestamp;
+ endTs = selectedNote.timestamp + INSTANT_FOCUS_DURATION_S;
}
}
+
return {startTs, endTs};
}
@@ -206,7 +239,7 @@ function lockSliceSpan(persistent = false) {
}
}
-function findCurrentSelection() {
+export function findCurrentSelection() {
const selection = globals.state.currentSelection;
if (selection === null) return;
diff --git a/ui/src/frontend/live_reload.ts b/ui/src/frontend/live_reload.ts
index c30b6e0f9..36306ac6e 100644
--- a/ui/src/frontend/live_reload.ts
+++ b/ui/src/frontend/live_reload.ts
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import {featureFlags} from '../common/feature_flags';
+
let lastReloadDialogTime = 0;
const kMinTimeBetweenDialogsMs = 10000;
const changedPaths = new Set<string>();
@@ -46,6 +48,16 @@ function reloadCSS() {
parent.appendChild(css);
}
+const rapidReloadFlag = featureFlags.register({
+ id: 'rapidReload',
+ name: 'Development: rapid live reload',
+ defaultValue: false,
+ description: 'During development, instantly reload the page on change. ' +
+ 'Enables lower latency of live reload at the cost of potential ' +
+ 'multiple re-reloads.',
+ devOnly: true,
+});
+
function reloadDelayed() {
setTimeout(() => {
let pathsStr = '';
@@ -54,10 +66,11 @@ function reloadDelayed() {
}
changedPaths.clear();
if (Date.now() - lastReloadDialogTime < kMinTimeBetweenDialogsMs) return;
- const reload = confirm(`${pathsStr}changed, click to reload`);
+ const reload =
+ rapidReloadFlag.get() || confirm(`${pathsStr}changed, click to reload`);
lastReloadDialogTime = Date.now();
if (reload) {
window.location.reload();
}
- }, 1000);
+ }, rapidReloadFlag.get() ? 0 : 1000);
}
diff --git a/ui/src/frontend/logs_panel.ts b/ui/src/frontend/logs_panel.ts
index 3087935e3..2a1c664c4 100644
--- a/ui/src/frontend/logs_panel.ts
+++ b/ui/src/frontend/logs_panel.ts
@@ -81,11 +81,11 @@ export class LogPanel extends Panel<{}> {
}
onRowOver(ts: number) {
- globals.frontendLocalState.setHoveredLogsTimestamp(ts);
+ globals.dispatch(Actions.setHoveredLogsTimestamp({ts}));
}
onRowOut() {
- globals.frontendLocalState.setHoveredLogsTimestamp(-1);
+ globals.dispatch(Actions.setHoveredLogsTimestamp({ts: -1}));
}
private totalRows():
diff --git a/ui/src/frontend/modal.ts b/ui/src/frontend/modal.ts
index 69482e358..40badd9a2 100644
--- a/ui/src/frontend/modal.ts
+++ b/ui/src/frontend/modal.ts
@@ -84,3 +84,13 @@ function makeButtons(buttonDefinition: Button[]): Array<m.Vnode<Button>> {
});
return buttons;
}
+
+export function showPartialModal(attrs: ModalDefinition): m.Vnode {
+ return m(
+ '.partial-modal-overlay',
+ {tabindex: -1},
+ m('.partial-modal-container',
+ m('header.partial-modal-header', m('h2.modal-title', attrs.title)),
+ m('main.modal-content', attrs.content),
+ m('footer.modal-footer', ...makeButtons(attrs.buttons))));
+}
diff --git a/ui/src/frontend/named_slice_track.ts b/ui/src/frontend/named_slice_track.ts
new file mode 100644
index 000000000..90534ad2c
--- /dev/null
+++ b/ui/src/frontend/named_slice_track.ts
@@ -0,0 +1,85 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {Actions} from '../common/actions';
+import {
+ Color,
+ hslForSlice,
+} from '../common/colorizer';
+import {STR_NULL} from '../common/query_result';
+
+import {
+ BASE_SLICE_ROW,
+ BaseSliceTrack,
+ BaseSliceTrackTypes,
+ OnSliceClickArgs,
+ OnSliceOverArgs,
+} from './base_slice_track';
+import {globals} from './globals';
+import {NewTrackArgs} from './track';
+
+export const NAMED_SLICE_ROW = {
+ // Base columns (tsq, ts, dur, id, depth).
+ ...BASE_SLICE_ROW,
+
+ // Impl-specific columns.
+ name: STR_NULL,
+};
+export type NamedSliceRow = typeof NAMED_SLICE_ROW;
+
+export interface NamedSliceTrackTypes extends BaseSliceTrackTypes {
+ row: NamedSliceRow;
+}
+
+export abstract class NamedSliceTrack<
+ T extends NamedSliceTrackTypes = NamedSliceTrackTypes> extends
+ BaseSliceTrack<T> {
+ constructor(args: NewTrackArgs) {
+ super(args);
+ }
+
+ // This is used by the base class to call iter().
+ getRowSpec(): T['row'] {
+ return NAMED_SLICE_ROW;
+ }
+
+ // Converts a SQL result row to an "Impl" Slice.
+ rowToSlice(row: T['row']): T['slice'] {
+ const baseSlice = super.rowToSlice(row);
+ // Ignore PIDs or numeric arguments when hashing.
+ const name = row.name || '';
+ const nameForHashing = name.replace(/\s?\d+/g, '');
+ const hsl = hslForSlice(nameForHashing, /*isSelected=*/ false);
+ // We cache the color so we hash only once per query.
+ const baseColor: Color = {c: '', h: hsl[0], s: hsl[1], l: hsl[2]};
+ return {...baseSlice, title: name, baseColor};
+ }
+
+ onSliceOver(args: OnSliceOverArgs<T['slice']>) {
+ const name = args.slice.title;
+ args.tooltip = [name];
+ }
+
+ onSliceClick(args: OnSliceClickArgs<T['slice']>) {
+ globals.makeSelection(Actions.selectChromeSlice({
+ id: args.slice.id,
+ trackId: this.trackId,
+
+ // |table| here can be either 'slice' or 'annotation'. The
+ // AnnotationSliceTrack overrides the onSliceClick and sets this to
+ // 'annotation'
+ table: 'slice',
+ }));
+ }
+}
diff --git a/ui/src/frontend/notes_panel.ts b/ui/src/frontend/notes_panel.ts
index 55dc47ad8..44489cbcc 100644
--- a/ui/src/frontend/notes_panel.ts
+++ b/ui/src/frontend/notes_panel.ts
@@ -24,12 +24,11 @@ import {PerfettoMouseEvent} from './events';
import {globals} from './globals';
import {gridlines} from './gridline_helper';
import {Panel, PanelSize} from './panel';
+import {isTraceLoaded} from './sidebar';
const FLAG_WIDTH = 16;
const AREA_TRIANGLE_WIDTH = 10;
-const MOVIE_WIDTH = 16;
const FLAG = `\uE153`;
-const MOVIE = '\uE8DA';
function toSummary(s: string) {
const newlineIndex = s.indexOf('\n') > 0 ? s.indexOf('\n') : s.length;
@@ -50,11 +49,6 @@ export class NotesPanel extends Panel {
oncreate({dom}: m.CVnodeDOM) {
dom.addEventListener('mousemove', (e: Event) => {
this.hoveredX = (e as PerfettoMouseEvent).layerX - TRACK_SHELL_WIDTH;
- if (globals.state.scrubbingEnabled) {
- const timescale = globals.frontendLocalState.timeScale;
- const timestamp = timescale.pxToTime(this.hoveredX);
- globals.frontendLocalState.setVidTimestamp(timestamp);
- }
globals.rafScheduler.scheduleRedraw();
}, {passive: true});
dom.addEventListener('mouseenter', (e: Event) => {
@@ -63,19 +57,35 @@ export class NotesPanel extends Panel {
});
dom.addEventListener('mouseout', () => {
this.hoveredX = null;
- globals.frontendLocalState.setHoveredNoteTimestamp(-1);
- globals.rafScheduler.scheduleRedraw();
+ globals.dispatch(Actions.setHoveredNoteTimestamp({ts: -1}));
}, {passive: true});
}
view() {
- return m('.notes-panel', {
- onclick: (e: PerfettoMouseEvent) => {
- const isMovie = globals.state.flagPauseEnabled;
- this.onClick(e.layerX - TRACK_SHELL_WIDTH, e.layerY, isMovie);
- e.stopPropagation();
- },
- });
+ const allCollapsed = Object.values(globals.state.trackGroups)
+ .every((group) => group.collapsed);
+
+ return m(
+ '.notes-panel',
+ {
+ onclick: (e: PerfettoMouseEvent) => {
+ this.onClick(e.layerX - TRACK_SHELL_WIDTH, e.layerY);
+ e.stopPropagation();
+ },
+ },
+ isTraceLoaded() ?
+ m('button',
+ {
+ onclick: (e: Event) => {
+ e.preventDefault();
+ globals.dispatch(
+ Actions.toggleAllTrackGroups({collapsed: !allCollapsed}));
+ }
+ },
+ m('i.material-icons',
+ {title: allCollapsed ? 'Expand all' : 'Collapse all'},
+ allCollapsed ? 'unfold_more' : 'unfold_less')) :
+ '');
}
renderCanvas(ctx: CanvasRenderingContext2D, size: PanelSize) {
@@ -124,8 +134,7 @@ export class NotesPanel extends Panel {
note.color,
isSelected);
} else {
- this.drawFlag(
- ctx, left, size.height, note.color, note.noteType, isSelected);
+ this.drawFlag(ctx, left, size.height, note.color, isSelected);
}
if (note.text) {
@@ -142,17 +151,18 @@ export class NotesPanel extends Panel {
// A real note is hovered so we don't need to see the preview line.
// TODO(hjd): Change cursor to pointer here.
- if (aNoteIsHovered) globals.frontendLocalState.setHoveredNoteTimestamp(-1);
+ if (aNoteIsHovered) {
+ globals.dispatch(Actions.setHoveredNoteTimestamp({ts: -1}));
+ }
// View preview note flag when hovering on notes panel.
if (!aNoteIsHovered && this.hoveredX !== null) {
const timestamp = timeScale.pxToTime(this.hoveredX);
if (timeScale.timeInBounds(timestamp)) {
- globals.frontendLocalState.setHoveredNoteTimestamp(timestamp);
+ globals.dispatch(Actions.setHoveredNoteTimestamp({ts: timestamp}));
const x = timeScale.timeToPx(timestamp);
const left = Math.floor(x + TRACK_SHELL_WIDTH);
- this.drawFlag(
- ctx, left, size.height, '#aaa', 'DEFAULT', /* fill */ true);
+ this.drawFlag(ctx, left, size.height, '#aaa', /* fill */ true);
}
}
}
@@ -194,7 +204,7 @@ export class NotesPanel extends Panel {
private drawFlag(
ctx: CanvasRenderingContext2D, x: number, height: number, color: string,
- noteType: 'DEFAULT'|'AREA'|'MOVIE', fill?: boolean) {
+ fill?: boolean) {
const prevFont = ctx.font;
const prevBaseline = ctx.textBaseline;
ctx.textBaseline = 'alphabetic';
@@ -206,26 +216,21 @@ export class NotesPanel extends Panel {
// exactly at the x value. This adjusts for that.
const iconPadding = 6;
if (fill) {
- ctx.fillText(
- noteType === 'MOVIE' ? MOVIE : FLAG, x - iconPadding, height + 2);
+ ctx.fillText(FLAG, x - iconPadding, height + 2);
} else {
- ctx.strokeText(
- noteType === 'MOVIE' ? MOVIE : FLAG, x - iconPadding, height + 2.5);
+ ctx.strokeText(FLAG, x - iconPadding, height + 2.5);
}
ctx.font = prevFont;
ctx.textBaseline = prevBaseline;
}
- private onClick(x: number, _: number, isMovie: boolean) {
+ private onClick(x: number, _: number) {
if (x < 0) return;
const timeScale = globals.frontendLocalState.timeScale;
const timestamp = timeScale.pxToTime(x);
for (const note of Object.values(globals.state.notes)) {
if (this.hoveredX && this.mouseOverNote(this.hoveredX, note)) {
- if (note.noteType === 'MOVIE') {
- globals.frontendLocalState.setVidTimestamp(note.timestamp);
- }
if (note.noteType === 'AREA') {
globals.makeSelection(
Actions.reSelectArea({areaId: note.areaId, noteId: note.id}));
@@ -235,11 +240,8 @@ export class NotesPanel extends Panel {
return;
}
}
- if (isMovie) {
- globals.frontendLocalState.setVidTimestamp(timestamp);
- }
const color = randomColor();
- globals.makeSelection(Actions.addNote({timestamp, color, isMovie}));
+ globals.makeSelection(Actions.addNote({timestamp, color}));
}
private mouseOverNote(x: number, note: AreaNote|Note): boolean {
@@ -251,7 +253,7 @@ export class NotesPanel extends Panel {
(timeScale.timeToPx(noteArea.endSec) > x &&
x > timeScale.timeToPx(noteArea.endSec) - AREA_TRIANGLE_WIDTH);
} else {
- const width = (note.noteType === 'MOVIE') ? MOVIE_WIDTH : FLAG_WIDTH;
+ const width = FLAG_WIDTH;
return noteX <= x && x < noteX + width;
}
}
@@ -298,7 +300,7 @@ export class NotesEditorPanel extends Panel<NotesEditorPanelAttrs> {
{
onclick: () => {
globals.dispatch(Actions.removeNote({id: attrs.id}));
- globals.frontendLocalState.currentTab = undefined;
+ globals.dispatch(Actions.setCurrentTab({tab: undefined}));
globals.rafScheduler.scheduleFullRedraw();
}
},
diff --git a/ui/src/frontend/pages.ts b/ui/src/frontend/pages.ts
index c59542024..6d5448b16 100644
--- a/ui/src/frontend/pages.ts
+++ b/ui/src/frontend/pages.ts
@@ -16,6 +16,7 @@ import * as m from 'mithril';
import {Actions} from '../common/actions';
+import {onClickCopy} from './clipboard';
import {CookieConsent} from './cookie_consent';
import {globals} from './globals';
import {Sidebar} from './sidebar';
@@ -25,9 +26,10 @@ function renderPermalink(): m.Children {
const permalink = globals.state.permalink;
if (!permalink.requestId || !permalink.hash) return null;
const url = `${self.location.origin}/#!/?s=${permalink.hash}`;
+ const linkProps = {title: 'Click to copy the URL', onclick: onClickCopy(url)};
return m('.alert-permalink', [
- m('div', 'Permalink: ', m(`a[href=${url}]`, url)),
+ m('div', 'Permalink: ', m(`a[href=${url}]`, linkProps, url)),
m('button',
{
onclick: () => globals.dispatch(Actions.clearPermalink({})),
@@ -45,17 +47,18 @@ class Alerts implements m.ClassComponent {
/**
* Wrap component with common UI elements (nav bar etc).
*/
-export function createPage(component: m.Component): m.Component {
+export function createPage(component: m.Component<PageAttrs>):
+ m.Component<PageAttrs> {
const pageComponent = {
- view() {
+ view({attrs}: m.Vnode<PageAttrs>) {
const children = [
m(Sidebar),
m(Topbar),
m(Alerts),
- m(component),
+ m(component, attrs),
m(CookieConsent),
];
- if (globals.frontendLocalState.perfDebug) {
+ if (globals.state.perfDebug) {
children.push(m('.perf-stats'));
}
return children;
@@ -64,3 +67,7 @@ export function createPage(component: m.Component): m.Component {
return pageComponent;
}
+
+export interface PageAttrs {
+ subpage?: string;
+}
diff --git a/ui/src/frontend/pan_and_zoom_handler.ts b/ui/src/frontend/pan_and_zoom_handler.ts
index 166a3ce19..cbbb0ae4a 100644
--- a/ui/src/frontend/pan_and_zoom_handler.ts
+++ b/ui/src/frontend/pan_and_zoom_handler.ts
@@ -211,8 +211,7 @@ export class PanAndZoomHandler {
}
private onMouseMove(e: MouseEvent) {
- const pageOffset =
- globals.frontendLocalState.sidebarVisible ? this.contentOffsetX : 0;
+ const pageOffset = globals.state.sidebarVisible ? this.contentOffsetX : 0;
// We can't use layerX here because there are many layers in this element.
this.mousePositionX = e.clientX - pageOffset;
// Only change the cursor when hovering, the DragGestureHandler handles
diff --git a/ui/src/frontend/panel_container.ts b/ui/src/frontend/panel_container.ts
index 2131c106e..662cd5413 100644
--- a/ui/src/frontend/panel_container.ts
+++ b/ui/src/frontend/panel_container.ts
@@ -14,7 +14,7 @@
import * as m from 'mithril';
-import {assertExists, assertTrue} from '../base/logging';
+import {assertExists, assertFalse, assertTrue} from '../base/logging';
import {TOPBAR_HEIGHT, TRACK_SHELL_WIDTH} from './css_constants';
import {
@@ -22,7 +22,7 @@ import {
FlowEventsRendererArgs
} from './flow_events_renderer';
import {globals} from './globals';
-import {isPanelVNode, Panel, PanelSize, PanelVNode} from './panel';
+import {isPanelVNode, Panel, PanelSize} from './panel';
import {
debugNow,
perfDebug,
@@ -47,8 +47,9 @@ export interface Attrs {
kind: 'TRACKS'|'OVERVIEW'|'DETAILS';
}
-interface PanelPosition {
- id: string;
+interface PanelInfo {
+ id: string; // Can be == '' for singleton panels.
+ vnode: AnyAttrsVnode;
height: number;
width: number;
x: number;
@@ -60,7 +61,8 @@ export class PanelContainer implements m.ClassComponent<Attrs> {
private parentWidth = 0;
private parentHeight = 0;
private scrollTop = 0;
- private panelPositions: PanelPosition[] = [];
+ private panelInfos: PanelInfo[] = [];
+ private panelByKey = new Map<string, AnyAttrsVnode>();
private totalPanelHeight = 0;
private canvasHeight = 0;
@@ -95,13 +97,13 @@ export class PanelContainer implements m.ClassComponent<Attrs> {
const minY = Math.min(startY, endY);
const maxY = Math.max(startY, endY);
const panels: AnyAttrsVnode[] = [];
- for (let i = 0; i < this.panelPositions.length; i++) {
- const pos = this.panelPositions[i];
+ for (let i = 0; i < this.panelInfos.length; i++) {
+ const pos = this.panelInfos[i];
const realPosX = pos.x - TRACK_SHELL_WIDTH;
if (realPosX + pos.width >= minX && realPosX <= maxX &&
pos.y + pos.height >= minY && pos.y <= maxY &&
- this.attrs.panels[i].attrs.selectable) {
- panels.push(this.attrs.panels[i]);
+ pos.vnode.attrs.selectable) {
+ panels.push(pos.vnode);
}
}
return panels;
@@ -114,15 +116,14 @@ export class PanelContainer implements m.ClassComponent<Attrs> {
if (area === undefined ||
globals.frontendLocalState.areaY.start === undefined ||
globals.frontendLocalState.areaY.end === undefined ||
- this.panelPositions.length === 0) {
+ this.panelInfos.length === 0) {
return;
}
// Only get panels from the current panel container if the selection began
// in this container.
- const panelContainerTop = this.panelPositions[0].y;
- const panelContainerBottom =
- this.panelPositions[this.panelPositions.length - 1].y +
- this.panelPositions[this.panelPositions.length - 1].height;
+ const panelContainerTop = this.panelInfos[0].y;
+ const panelContainerBottom = this.panelInfos[this.panelInfos.length - 1].y +
+ this.panelInfos[this.panelInfos.length - 1].height;
if (globals.frontendLocalState.areaY.start + TOPBAR_HEIGHT <
panelContainerTop ||
globals.frontendLocalState.areaY.start + TOPBAR_HEIGHT >
@@ -217,18 +218,26 @@ export class PanelContainer implements m.ClassComponent<Attrs> {
view({attrs}: m.CVnode<Attrs>) {
this.attrs = attrs;
- const renderPanel = (panel: m.Vnode) => perfDebug() ?
- m('.panel',
- {key: panel.key},
- [panel, m('.debug-panel-border', {key: 'debug-panel-border'})]) :
- m('.panel', {key: panel.key}, panel);
+ this.panelByKey.clear();
+ const children = [];
+ for (const panel of attrs.panels) {
+ const key = assertExists(panel.key) as string;
+ assertFalse(this.panelByKey.has(key));
+ this.panelByKey.set(key, panel);
+ children.push(
+ m('.panel',
+ {key: panel.key, 'data-key': panel.key},
+ perfDebug() ?
+ [panel, m('.debug-panel-border', {key: 'debug-panel-border'})] :
+ panel));
+ }
return [
m(
'.scroll-limiter',
m('canvas.main-canvas'),
),
- m('.panels', attrs.panels.map(renderPanel))
+ m('.panels', children)
];
}
@@ -301,19 +310,26 @@ export class PanelContainer implements m.ClassComponent<Attrs> {
*/
private readPanelHeightsFromDom(dom: Element): boolean {
const prevHeight = this.totalPanelHeight;
- this.panelPositions = [];
+ this.panelInfos = [];
this.totalPanelHeight = 0;
- const panels = dom.parentElement!.querySelectorAll('.panel');
- assertTrue(panels.length === this.attrs.panels.length);
- for (let i = 0; i < panels.length; i++) {
- const rect = panels[i].getBoundingClientRect();
- const id = this.attrs.panels[i].attrs.id ||
- this.attrs.panels[i].attrs.trackGroupId;
- this.panelPositions[i] =
- {id, height: rect.height, width: rect.width, x: rect.x, y: rect.y};
+ dom.parentElement!.querySelectorAll('.panel').forEach(panel => {
+ const key = assertExists(panel.getAttribute('data-key'));
+ const vnode = assertExists(this.panelByKey.get(key));
+
+ // NOTE: the id can be undefined for singletons like overview timeline.
+ const id = vnode.attrs.id || vnode.attrs.trackGroupId || '';
+ const rect = panel.getBoundingClientRect();
+ this.panelInfos.push({
+ id,
+ height: rect.height,
+ width: rect.width,
+ x: rect.x,
+ y: rect.y,
+ vnode
+ });
this.totalPanelHeight += rect.height;
- }
+ });
return this.totalPanelHeight !== prevHeight;
}
@@ -332,23 +348,19 @@ export class PanelContainer implements m.ClassComponent<Attrs> {
this.handleAreaSelection();
let panelYStart = 0;
- const panels = assertExists(this.attrs).panels;
- assertTrue(panels.length === this.panelPositions.length);
let totalOnCanvas = 0;
const flowEventsRendererArgs =
new FlowEventsRendererArgs(this.parentWidth, this.canvasHeight);
- for (let i = 0; i < panels.length; i++) {
- const panel = panels[i];
- const panelHeight = this.panelPositions[i].height;
+ for (let i = 0; i < this.panelInfos.length; i++) {
+ const panel = this.panelInfos[i].vnode;
+ const panelHeight = this.panelInfos[i].height;
const yStartOnCanvas = panelYStart - canvasYStart;
if (!isPanelVNode(panel)) {
throw new Error('Vnode passed to panel container is not a panel');
}
- // TODO(hjd): This cast should be unnecessary given the type guard above.
- const p = panel as PanelVNode<{}>;
- flowEventsRendererArgs.registerPanel(p, yStartOnCanvas, panelHeight);
+ flowEventsRendererArgs.registerPanel(panel, yStartOnCanvas, panelHeight);
if (!this.overlapsCanvas(yStartOnCanvas, yStartOnCanvas + panelHeight)) {
panelYStart += panelHeight;
@@ -364,9 +376,9 @@ export class PanelContainer implements m.ClassComponent<Attrs> {
clipRect.rect(0, 0, size.width, size.height);
this.ctx.clip(clipRect);
const beforeRender = debugNow();
- p.state.renderCanvas(this.ctx, size, p);
+ panel.state.renderCanvas(this.ctx, size, panel);
this.updatePanelStats(
- i, p.state, debugNow() - beforeRender, this.ctx, size);
+ i, panel.state, debugNow() - beforeRender, this.ctx, size);
this.ctx.restore();
panelYStart += panelHeight;
}
@@ -375,7 +387,7 @@ export class PanelContainer implements m.ClassComponent<Attrs> {
this.flowEventsRenderer.render(this.ctx, flowEventsRendererArgs);
// Collect performance as the last thing we do.
const redrawDur = debugNow() - redrawStart;
- this.updatePerfStats(redrawDur, panels.length, totalOnCanvas);
+ this.updatePerfStats(redrawDur, this.panelInfos.length, totalOnCanvas);
}
// The panels each draw on the canvas but some details need to be drawn across
@@ -388,24 +400,22 @@ export class PanelContainer implements m.ClassComponent<Attrs> {
globals.frontendLocalState.areaY.end === undefined) {
return;
}
- if (this.panelPositions.length === 0 || area.tracks.length === 0) return;
+ if (this.panelInfos.length === 0 || area.tracks.length === 0) return;
// Find the minY and maxY of the selected tracks in this panel container.
- const panelContainerTop = this.panelPositions[0].y;
- const panelContainerBottom =
- this.panelPositions[this.panelPositions.length - 1].y +
- this.panelPositions[this.panelPositions.length - 1].height;
+ const panelContainerTop = this.panelInfos[0].y;
+ const panelContainerBottom = this.panelInfos[this.panelInfos.length - 1].y +
+ this.panelInfos[this.panelInfos.length - 1].height;
let selectedTracksMinY = panelContainerBottom;
let selectedTracksMaxY = panelContainerTop;
let trackFromCurrentContainerSelected = false;
- for (let i = 0; i < this.panelPositions.length; i++) {
- if (area.tracks.includes(this.panelPositions[i].id)) {
+ for (let i = 0; i < this.panelInfos.length; i++) {
+ if (area.tracks.includes(this.panelInfos[i].id)) {
trackFromCurrentContainerSelected = true;
- selectedTracksMinY =
- Math.min(selectedTracksMinY, this.panelPositions[i].y);
+ selectedTracksMinY = Math.min(selectedTracksMinY, this.panelInfos[i].y);
selectedTracksMaxY = Math.max(
selectedTracksMaxY,
- this.panelPositions[i].y + this.panelPositions[i].height);
+ this.panelInfos[i].y + this.panelInfos[i].height);
}
}
diff --git a/ui/src/frontend/perf.ts b/ui/src/frontend/perf.ts
index 8ab8c4ab4..d884a5ff9 100644
--- a/ui/src/frontend/perf.ts
+++ b/ui/src/frontend/perf.ts
@@ -15,13 +15,14 @@
import * as m from 'mithril';
+import {Actions} from '../common/actions';
import {globals} from './globals';
import {PanelContainer} from './panel_container';
/**
* Shorthand for if globals perf debug mode is on.
*/
-export const perfDebug = () => globals.frontendLocalState.perfDebug;
+export const perfDebug = () => globals.state.perfDebug;
/**
* Returns performance.now() if perfDebug is enabled, otherwise 0.
@@ -113,7 +114,7 @@ class PerfDisplay {
m('section', globals.rafScheduler.renderPerfStats()),
m('button.close-button',
{
- onclick: () => globals.frontendLocalState.togglePerfDebug(),
+ onclick: () => globals.dispatch(Actions.togglePerfDebug({})),
},
m('i.material-icons', 'close')),
this.containers.map((c, i) => m('section', c.renderPerfStats(i)))
diff --git a/ui/src/frontend/pivot_table.ts b/ui/src/frontend/pivot_table.ts
new file mode 100644
index 000000000..4c9f885aa
--- /dev/null
+++ b/ui/src/frontend/pivot_table.ts
@@ -0,0 +1,342 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import * as m from 'mithril';
+
+import {Actions} from '../common/actions';
+import {
+ ColumnAttrs,
+ PivotTableQueryResponse,
+ RowAttrs,
+} from '../common/pivot_table_common';
+
+import {globals} from './globals';
+import {Panel} from './panel';
+import {
+ PivotTableHelper,
+} from './pivot_table_helper';
+import {PopupMenuButton} from './popup_menu';
+
+interface ExpandableCellAttrs {
+ pivotTableId: string;
+ row: RowAttrs;
+ column: ColumnAttrs;
+ rowIndices: number[];
+ expandedRowColumns: string[];
+}
+
+interface PivotTableRowAttrs {
+ pivotTableId: string;
+ row: RowAttrs;
+ columns: ColumnAttrs[];
+ rowIndices: number[];
+ expandedRowColumns: string[];
+}
+
+interface PivotTableBodyAttrs {
+ pivotTableId: string;
+ rows: RowAttrs[];
+ columns: ColumnAttrs[];
+ rowIndices: number[];
+ expandedRowColumns: string[];
+}
+
+interface PivotTableHeaderAttrs {
+ helper: PivotTableHelper;
+}
+
+interface PivotTableAttrs {
+ pivotTableId: string;
+ helper?: PivotTableHelper;
+}
+
+class PivotTableHeader implements m.ClassComponent<PivotTableHeaderAttrs> {
+ view(vnode: m.Vnode<PivotTableHeaderAttrs>) {
+ const {helper} = vnode.attrs;
+ const pivotTableId = helper.pivotTableId;
+ const pivotTable = globals.state.pivotTable[pivotTableId];
+ const resp =
+ globals.queryResults.get(pivotTableId) as PivotTableQueryResponse;
+
+ const cols = [];
+ for (const column of resp.columns) {
+ const isPivot = column.aggregation === undefined;
+ const cellContents = [m('span', column.name)];
+ if (!isPivot) {
+ const items = [{
+ text: column.order === 'DESC' ? 'Sort \u25B2' : 'Sort \u25BC',
+ callback: () => {
+ if (!pivotTable.isLoadingQuery) {
+ helper.togglePivotTableAggregationSorting(column.index);
+ helper.queryPivotTableChanges();
+ }
+ }
+ }];
+
+ for (const aggregation of helper.availableAggregations) {
+ if (aggregation === column.aggregation) {
+ continue;
+ }
+
+ items.push({
+ text: aggregation,
+ callback: () => {
+ helper.changeAggregation(column.index, aggregation);
+ helper.queryPivotTableChanges();
+ }
+ });
+ }
+ cellContents.push(m(PopupMenuButton, {icon: 'arrow_drop_down', items}));
+ if (resp.totalAggregations !== undefined) {
+ cellContents.push(
+ m('.total-aggregation',
+ `(${resp.totalAggregations[column.name]})`));
+ }
+ }
+ cols.push(
+ m('td',
+ {
+ class: pivotTable.isLoadingQuery ? 'disabled' : '',
+ draggable: !pivotTable.isLoadingQuery,
+ ondragstart: (e: DragEvent) => {
+ helper.selectedColumnOnDrag(e, isPivot, column.index);
+ },
+ ondrop: (e: DragEvent) => {
+ helper.removeHighlightFromDropLocation(e);
+ helper.selectedColumnOnDrop(e, isPivot, column.index);
+ helper.queryPivotTableChanges();
+ },
+ ondragenter: (e: DragEvent) => {
+ helper.highlightDropLocation(e, isPivot);
+ },
+ ondragleave: (e: DragEvent) => {
+ helper.removeHighlightFromDropLocation(e);
+ }
+ },
+ cellContents));
+ }
+ return m('tr', cols);
+ }
+}
+
+class ExpandableCell implements m.ClassComponent<ExpandableCellAttrs> {
+ view(vnode: m.Vnode<ExpandableCellAttrs>) {
+ const {pivotTableId, row, column, rowIndices, expandedRowColumns} =
+ vnode.attrs;
+ const pivotTable = globals.state.pivotTable[pivotTableId];
+ let expandIcon = 'expand_more';
+ if (row.expandedRows.has(column.name)) {
+ expandIcon = row.expandedRows.get(column.name)!.isExpanded ?
+ 'expand_less' :
+ 'expand_more';
+ }
+ let spinnerVisibility = 'hidden';
+ let animationState = 'paused';
+ if (row.loadingColumn === column.name) {
+ spinnerVisibility = 'visible';
+ animationState = 'running';
+ }
+ const padValue = new Array(row.depth * 2).join(' ');
+
+ return m(
+ 'td.allow-white-space',
+ padValue,
+ m('i.material-icons',
+ {
+ class: pivotTable.isLoadingQuery ? 'disabled' : '',
+ onclick: () => {
+ if (pivotTable.isLoadingQuery) {
+ return;
+ }
+ const value = row.row[column.name]?.toString();
+ if (value === undefined) {
+ throw Error('Expanded row has undefined value.');
+ }
+ if (row.expandedRows.has(column.name) &&
+ row.expandedRows.get(column.name)!.isExpanded) {
+ globals.dispatch(Actions.setPivotTableRequest({
+ pivotTableId,
+ action: 'UNEXPAND',
+ attrs: {
+ rowIndices,
+ columnIdx: column.index,
+ value,
+ expandedRowColumns
+ }
+ }));
+ } else {
+ globals.dispatch(Actions.setPivotTableRequest({
+ pivotTableId,
+ action: column.isStackColumn ? 'DESCENDANTS' : 'EXPAND',
+ attrs: {
+ rowIndices,
+ columnIdx: column.index,
+ value,
+ expandedRowColumns
+ }
+ }));
+ }
+ },
+ },
+ expandIcon),
+ ' ',
+ row.row[column.name],
+ ' ',
+ // Adds a loading spinner while querying the expanded column.
+ m('.pivot-table-spinner', {
+ style: {
+ visibility: spinnerVisibility,
+ animationPlayState: animationState
+ }
+ }));
+ }
+}
+
+class PivotTableRow implements m.ClassComponent<PivotTableRowAttrs> {
+ view(vnode: m.Vnode<PivotTableRowAttrs>) {
+ const cells = [];
+ const {pivotTableId, row, columns, rowIndices, expandedRowColumns} =
+ vnode.attrs;
+
+ for (const column of columns) {
+ if (row.row[column.name] === undefined &&
+ row.expandableColumns.has(column.name)) {
+ throw Error(
+ `Row data at expandable column "${column.name}" is undefined.`);
+ }
+ if (row.row[column.name] === undefined || row.row[column.name] === null) {
+ cells.push(m('td', ''));
+ continue;
+ }
+ if (row.expandableColumns.has(column.name)) {
+ cells.push(
+ m(ExpandableCell,
+ {pivotTableId, row, column, rowIndices, expandedRowColumns}));
+ continue;
+ }
+
+ let value = row.row[column.name]!.toString();
+ if (column.aggregation === undefined) {
+ // For each indentation level add 2 spaces, if we have an expansion
+ // button add 3 spaces to cover the icon size.
+ let padding = 2 * row.depth;
+ if (row.depth > 0 && column.isStackColumn) {
+ padding += 3;
+ }
+ value = value.padStart(padding + value.length, ' ');
+ }
+ cells.push(m('td.allow-white-space', value));
+ }
+ return m('tr', cells);
+ }
+}
+
+class PivotTableBody implements m.ClassComponent<PivotTableBodyAttrs> {
+ view(vnode: m.Vnode<PivotTableBodyAttrs>): m.Children {
+ const pivotTableRows = [];
+ const {pivotTableId, rows, columns, rowIndices, expandedRowColumns} =
+ vnode.attrs;
+ for (let i = 0; i < rows.length; ++i) {
+ pivotTableRows.push(m(PivotTableRow, {
+ pivotTableId,
+ row: rows[i],
+ columns,
+ rowIndices: rowIndices.concat(i),
+ expandedRowColumns
+ }));
+ for (const column of columns.slice().reverse()) {
+ const expandedRows = rows[i].expandedRows.get(column.name);
+ if (expandedRows !== undefined && expandedRows.isExpanded) {
+ pivotTableRows.push(m(PivotTableBody, {
+ pivotTableId,
+ rows: expandedRows.rows,
+ columns,
+ rowIndices: rowIndices.concat(i),
+ expandedRowColumns: expandedRowColumns.concat(column.name)
+ }));
+ }
+ }
+ }
+ return pivotTableRows;
+ }
+}
+
+export class PivotTable extends Panel<PivotTableAttrs> {
+ view(vnode: m.CVnode<PivotTableAttrs>) {
+ const {pivotTableId, helper} = vnode.attrs;
+ const pivotTable = globals.state.pivotTable[pivotTableId];
+ const resp =
+ globals.queryResults.get(pivotTableId) as PivotTableQueryResponse;
+
+ let body;
+ let header;
+ if (helper !== undefined && resp !== undefined) {
+ header = m(PivotTableHeader, {helper});
+ body = m(PivotTableBody, {
+ pivotTableId,
+ rows: resp.rows,
+ columns: resp.columns,
+ rowIndices: [],
+ expandedRowColumns: []
+ });
+ }
+
+ const startSec = pivotTable.traceTime ? pivotTable.traceTime.startSec :
+ globals.state.traceTime.startSec;
+ const endSec = pivotTable.traceTime ? pivotTable.traceTime.endSec :
+ globals.state.traceTime.endSec;
+
+ return m(
+ 'div.pivot-table-tab',
+ m(
+ 'header.overview',
+ m('span',
+ m('button',
+ {
+ disabled: helper === undefined || pivotTable.isLoadingQuery,
+ onclick: () => {
+ if (helper !== undefined) {
+ helper.toggleEditPivotTableModal();
+ globals.rafScheduler.scheduleFullRedraw();
+ }
+ }
+ },
+ 'Edit'),
+ ' ',
+ (pivotTable.isLoadingQuery ? m('.pivot-table-spinner') : null),
+ (resp !== undefined && !pivotTable.isLoadingQuery ?
+ m('span.code',
+ `Query took ${Math.round(resp.durationMs)} ms -`) :
+ null),
+ m('span.code', `Selected range: ${endSec - startSec} s`)),
+ m('button',
+ {
+ disabled: helper === undefined || pivotTable.isLoadingQuery,
+ onclick: () => {
+ globals.frontendLocalState.togglePivotTable();
+ globals.queryResults.delete(pivotTableId);
+ globals.pivotTableHelper.delete(pivotTableId);
+ globals.dispatch(Actions.deletePivotTable({pivotTableId}));
+ }
+ },
+ 'Close'),
+ ),
+ m('.query-table-container',
+ m('table.query-table.pivot-table',
+ m('thead', header),
+ m('tbody', body))));
+ }
+
+ renderCanvas() {}
+}
diff --git a/ui/src/frontend/pivot_table_editor.ts b/ui/src/frontend/pivot_table_editor.ts
new file mode 100644
index 000000000..64a8c6753
--- /dev/null
+++ b/ui/src/frontend/pivot_table_editor.ts
@@ -0,0 +1,251 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import * as m from 'mithril';
+import {isStackPivot} from '../common/pivot_table_common';
+
+import {globals} from './globals';
+import {hideModel} from './modal';
+import {
+ PivotTableHelper,
+} from './pivot_table_helper';
+
+interface PivotTableEditorAttrs {
+ helper: PivotTableHelper;
+}
+
+export class ColumnPicker implements m.ClassComponent<PivotTableEditorAttrs> {
+ view(vnode: m.Vnode<PivotTableEditorAttrs>) {
+ const {helper} = vnode.attrs;
+
+ // Fills available aggregations options in aggregation select.
+ const aggregationOptions = [];
+ for (const aggregation of helper.availableAggregations) {
+ aggregationOptions.push(
+ m('option', {value: aggregation, key: aggregation}, aggregation));
+ }
+
+ // Fills available columns options divided according to their table in
+ // column select.
+ const columnOptionGroup = [];
+ for (const {tableName, columns} of helper.availableColumns) {
+ const options = [];
+ for (const column of columns) {
+ // We can't aggregate a stack column.
+ const hidden = !helper.isPivot && isStackPivot(tableName, column);
+ options.push(m('option', {value: column, key: column, hidden}, column));
+ }
+ columnOptionGroup.push(m('optgroup', {label: tableName}, options));
+ }
+
+ return m(
+ 'div',
+ m(
+ 'section',
+ m('h2', 'Select column type: '),
+ // Pivot radio button.
+ m(
+ 'span',
+ m(`input[type=radio][name=type][id=pivot]`, {
+ checked: helper.isPivot,
+ onchange: () => {
+ helper.togglePivotSelection();
+ globals.rafScheduler.scheduleFullRedraw();
+ }
+ }),
+ m(`label[for=pivot]`, 'Pivot'),
+ ),
+ // Aggregation radio button.
+ m('span', m(`input[type=radio][name=type][id=aggregation]`, {
+ checked: !helper.isPivot,
+ onchange: () => {
+ helper.togglePivotSelection();
+ globals.rafScheduler.scheduleFullRedraw();
+ }
+ })),
+ m(`label[for=aggregation]`, 'Aggregation'),
+ ),
+ m(
+ 'section',
+ m('h2', 'Select a column: '),
+ // Aggregation select.
+ m('select',
+ {
+ disabled: helper.isPivot,
+ selectedIndex: helper.selectedAggregationIndex,
+ onchange: (e: InputEvent) => {
+ helper.setSelectedPivotTableAggregationIndex(
+ (e.target as HTMLSelectElement).selectedIndex);
+ }
+ },
+ aggregationOptions),
+ ' ',
+ // Column select.
+ m('select',
+ {
+ selectedIndex: helper.selectedColumnIndex,
+ onchange: (e: InputEvent) => {
+ helper.setSelectedPivotTableColumnIndex(
+ (e.target as HTMLSelectElement).selectedIndex);
+ }
+ },
+ columnOptionGroup),
+ ),
+ m('section.button-group',
+ // Button to toggle selected column.
+ m('button',
+ {
+ onclick: () => {
+ helper.updatePivotTableColumnOnSelectedIndex();
+ globals.rafScheduler.scheduleFullRedraw();
+ }
+ },
+ 'Add/Remove'),
+ // Button to clear table and all selected columns.
+ m('button',
+ {
+ onclick: () => {
+ helper.clearPivotTableColumns();
+ globals.rafScheduler.scheduleFullRedraw();
+ }
+ },
+ 'Clear')));
+ }
+}
+
+export class ColumnDisplay implements m.ClassComponent<PivotTableEditorAttrs> {
+ view(vnode: m.Vnode<PivotTableEditorAttrs>) {
+ const {helper} = vnode.attrs;
+ const selectedPivotsDisplay = [];
+ const selectedAggregationsDisplay = [];
+
+ for (let i = 0; i < helper.selectedPivots.length; ++i) {
+ const columnAttrs = helper.selectedPivots[i];
+ selectedPivotsDisplay.push(m(
+ 'tr',
+ m('td',
+ {
+ draggable: true,
+ ondragstart: (e: DragEvent) => {
+ helper.selectedColumnOnDrag(e, true, i);
+ },
+ ondrop: (e: DragEvent) => {
+ helper.removeHighlightFromDropLocation(e);
+ helper.selectedColumnOnDrop(e, true, i);
+ globals.rafScheduler.scheduleFullRedraw();
+ },
+ onclick: () => {
+ helper.selectPivotTableColumn(columnAttrs);
+ globals.rafScheduler.scheduleFullRedraw();
+ },
+ ondragenter: (e: DragEvent) => {
+ helper.highlightDropLocation(e, true);
+ },
+ ondragleave: (e: DragEvent) => {
+ helper.removeHighlightFromDropLocation(e);
+ }
+ },
+ m('i.material-icons',
+ {
+ onclick: () => {
+ helper.updatePivotTableColumnOnColumnAttributes(columnAttrs);
+ globals.rafScheduler.scheduleFullRedraw();
+ },
+ },
+ 'remove'),
+ ' ',
+ `${columnAttrs.tableName} ${columnAttrs.columnName}`)));
+ }
+
+ for (let i = 0; i < helper.selectedAggregations.length; ++i) {
+ const columnAttrs = helper.selectedAggregations[i];
+ const sortIcon = helper.selectedAggregations[i].order === 'DESC' ?
+ 'arrow_drop_down' :
+ 'arrow_drop_up';
+ selectedAggregationsDisplay.push(m(
+ 'tr',
+ m('td',
+ {
+ draggable: 'true',
+ ondragstart: (e: DragEvent) => {
+ helper.selectedColumnOnDrag(e, false, i);
+ },
+ ondrop: (e: DragEvent) => {
+ helper.removeHighlightFromDropLocation(e);
+ helper.selectedColumnOnDrop(e, false, i);
+ globals.rafScheduler.scheduleFullRedraw();
+ },
+ onclick: () => {
+ helper.selectPivotTableColumn(columnAttrs);
+ globals.rafScheduler.scheduleFullRedraw();
+ },
+ ondragenter: (e: DragEvent) => {
+ helper.highlightDropLocation(e, false);
+ },
+ ondragleave: (e: DragEvent) => {
+ helper.removeHighlightFromDropLocation(e);
+ }
+ },
+ m('i.material-icons',
+ {
+ onclick: () => {
+ helper.updatePivotTableColumnOnColumnAttributes(columnAttrs);
+ globals.rafScheduler.scheduleFullRedraw();
+ },
+ },
+ 'remove'),
+ ' ',
+ `${columnAttrs.tableName} ${columnAttrs.columnName} (${
+ columnAttrs.aggregation})`,
+ m('i.material-icons',
+ {
+ onclick: () => {
+ helper.togglePivotTableAggregationSorting(i);
+ globals.rafScheduler.scheduleFullRedraw();
+ }
+ },
+ sortIcon))));
+ }
+
+ return m(
+ 'div',
+ m('section.table-group',
+ // Table that displays selected pivots.
+ m('table',
+ m('thead', m('tr', m('th', 'Selected Pivots'))),
+ m('div.scroll', m('tbody', selectedPivotsDisplay))),
+ // Table that displays selected aggregations.
+ m('table',
+ m('thead', m('tr', m('th', 'Selected Aggregations'))),
+ m('div.scroll', m('tbody', selectedAggregationsDisplay)))),
+ m('section.button-group',
+ // Button to toggle selected column.
+ m('button',
+ {
+ onclick: () => {
+ helper.queryPivotTableChanges();
+ hideModel();
+ }
+ },
+ 'Query'),
+ // Button to clear table and all selected columns.
+ m('button',
+ {
+ onclick: () => {
+ hideModel();
+ }
+ },
+ 'Cancel')));
+ }
+}
diff --git a/ui/src/frontend/pivot_table_helper.ts b/ui/src/frontend/pivot_table_helper.ts
new file mode 100644
index 000000000..88fd527e9
--- /dev/null
+++ b/ui/src/frontend/pivot_table_helper.ts
@@ -0,0 +1,363 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {Actions} from '../common/actions';
+import {
+ AggregationAttrs,
+ isStackPivot,
+ PivotAttrs,
+ TableAttrs
+} from '../common/pivot_table_common';
+import {globals} from './globals';
+
+export function isAggregationAttrs(attrs: PivotAttrs|AggregationAttrs):
+ attrs is AggregationAttrs {
+ return (attrs as AggregationAttrs).aggregation !== undefined;
+}
+
+function equalTableAttrs(
+ left: PivotAttrs|AggregationAttrs, right: PivotAttrs|AggregationAttrs) {
+ if (left.columnName !== right.columnName) {
+ return false;
+ }
+
+ if (left.tableName !== right.tableName) {
+ return false;
+ }
+
+ if (isAggregationAttrs(left) && isAggregationAttrs(right)) {
+ if (left.aggregation !== right.aggregation) {
+ return false;
+ }
+ }
+ return true;
+}
+
+export function getDataTransferType(isPivot: boolean) {
+ if (isPivot) {
+ return 'perfetto/pivot-table-dragged-pivot';
+ }
+ return 'perfetto/pivot-table-dragged-aggregation';
+}
+
+export class PivotTableHelper {
+ readonly pivotTableId: string;
+ readonly availableColumns: TableAttrs[];
+ readonly availableAggregations: string[];
+ readonly totalColumnsCount = 0;
+
+ private _selectedPivots: PivotAttrs[] = [];
+ private _selectedAggregations: AggregationAttrs[] = [];
+ private _isPivot = true;
+ private _selectedColumnIndex = 0;
+ private _selectedAggregationIndex = 0;
+ private _editPivotTableModalOpen = false;
+
+ constructor(
+ pivotTableId: string, availableColumns: TableAttrs[],
+ availableAggregations: string[], selectedPivots: PivotAttrs[],
+ selectedAggregations: AggregationAttrs[]) {
+ this.pivotTableId = pivotTableId;
+ this.availableColumns = availableColumns;
+ for (const table of this.availableColumns) {
+ this.totalColumnsCount += table.columns.length;
+ }
+ this.availableAggregations = availableAggregations;
+ this.setSelectedPivotsAndAggregations(selectedPivots, selectedAggregations);
+ }
+
+ // Sets selected pivots and aggregations if the editor modal is not open.
+ setSelectedPivotsAndAggregations(
+ selectedPivots: PivotAttrs[], selectedAggregations: AggregationAttrs[]) {
+ if (!this.editPivotTableModalOpen) {
+ // Making a copy of selectedPivots and selectedAggregations to preserve
+ // the original state.
+ this._selectedPivots =
+ selectedPivots.map(pivot => Object.assign({}, pivot));
+ this._selectedAggregations = selectedAggregations.map(
+ aggregation => Object.assign({}, aggregation));
+ }
+ }
+
+ // Dictates if the selected indexes refer to a pivot or aggregation.
+ togglePivotSelection() {
+ this._isPivot = !this._isPivot;
+ if (!this._isPivot) {
+ const selectedColumn = this.getSelectedPivotTableColumnAttrs();
+ if (isStackPivot(selectedColumn.tableName, selectedColumn.columnName)) {
+ this._selectedColumnIndex = Math.max(0, this._selectedColumnIndex - 1);
+ }
+ }
+ }
+
+ setSelectedPivotTableColumnIndex(index: number) {
+ if (index < 0 && index >= this.totalColumnsCount) {
+ throw Error(`Selected column index "${index}" out of bounds.`);
+ }
+ this._selectedColumnIndex = index;
+ }
+
+ setSelectedPivotTableAggregationIndex(index: number) {
+ if (index < 0 && index >= this.availableAggregations.length) {
+ throw Error(`Selected aggregation index "${index}" out of bounds.`);
+ }
+ this._selectedAggregationIndex = index;
+ }
+
+ // Get column attributes on selectedColumnIndex and
+ // selectedAggregationIndex.
+ getSelectedPivotTableColumnAttrs(): PivotAttrs|AggregationAttrs {
+ let tableName, columnName;
+ // Finds column index relative to its table.
+ let colIdx = this._selectedColumnIndex;
+ for (const {tableName: tblName, columns} of this.availableColumns) {
+ if (colIdx < columns.length) {
+ tableName = tblName;
+ columnName = columns[colIdx];
+ break;
+ }
+ colIdx -= columns.length;
+ }
+ if (tableName === undefined || columnName === undefined) {
+ throw Error(
+ 'Pivot table selected column does not exist in availableColumns.');
+ }
+
+ // Get aggregation if selected column is not a pivot, undefined otherwise.
+ if (!this._isPivot) {
+ const aggregation =
+ this.availableAggregations[this._selectedAggregationIndex];
+ return {tableName, columnName, aggregation, order: 'DESC'};
+ }
+
+ return {
+ tableName,
+ columnName,
+ isStackPivot: isStackPivot(tableName, columnName)
+ };
+ }
+
+ // Adds column based on selected index to selectedPivots or
+ // selectedAggregations if it doesn't already exist, remove otherwise.
+ updatePivotTableColumnOnSelectedIndex() {
+ const columnAttrs = this.getSelectedPivotTableColumnAttrs();
+ this.updatePivotTableColumnOnColumnAttributes(columnAttrs);
+ }
+
+ // Adds column based on column attributes to selectedPivots or
+ // selectedAggregations if it doesn't already exist, remove otherwise.
+ updatePivotTableColumnOnColumnAttributes(columnAttrs: PivotAttrs|
+ AggregationAttrs) {
+ let storage: Array<PivotAttrs|AggregationAttrs>;
+ let attrs: PivotAttrs|AggregationAttrs;
+ if (isAggregationAttrs(columnAttrs)) {
+ if (isStackPivot(columnAttrs.tableName, columnAttrs.columnName)) {
+ throw Error(
+ `Stack column "${columnAttrs.tableName} ${
+ columnAttrs.columnName}" should not ` +
+ `be added as an aggregation.`);
+ }
+ storage = this._selectedAggregations;
+ attrs = {
+ tableName: columnAttrs.tableName,
+ columnName: columnAttrs.columnName,
+ aggregation: columnAttrs.aggregation,
+ order: columnAttrs.order
+ };
+ } else {
+ storage = this._selectedPivots;
+ attrs = {
+ tableName: columnAttrs.tableName,
+ columnName: columnAttrs.columnName,
+ isStackPivot: columnAttrs.isStackPivot
+ };
+ }
+ const index =
+ storage.findIndex(element => equalTableAttrs(element, columnAttrs));
+
+ if (index === -1) {
+ storage.push(attrs);
+ } else {
+ storage.splice(index, 1);
+ }
+ }
+
+ clearPivotTableColumns() {
+ this._selectedPivots = [];
+ this._selectedAggregations = [];
+ }
+
+ // Changes aggregation sorting from DESC to ASC and vice versa.
+ togglePivotTableAggregationSorting(index: number) {
+ if (index < 0 || index >= this._selectedAggregations.length) {
+ throw Error(`Column index "${index}" is out of bounds.`);
+ }
+ this._selectedAggregations[index].order =
+ this._selectedAggregations[index].order === 'DESC' ? 'ASC' : 'DESC';
+ }
+
+ // Change aggregation function to existing column.
+ changeAggregation(index: number, aggregation: string) {
+ if (index < 0 || index >= this._selectedAggregations.length) {
+ throw Error(`Column index "${index}" is out of bounds.`);
+ }
+ this._selectedAggregations[index].aggregation = aggregation;
+ }
+
+ // Moves target column to the requested destination.
+ reorderPivotTableDraggedColumn(
+ isPivot: boolean, targetColumnIdx: number, destinationColumnIdx: number) {
+ let storage: Array<PivotAttrs|AggregationAttrs>;
+ if (isPivot) {
+ storage = this._selectedPivots;
+ } else {
+ storage = this._selectedAggregations;
+ }
+
+ if (targetColumnIdx < 0 || targetColumnIdx >= storage.length) {
+ throw Error(`Target column index "${targetColumnIdx}" out of bounds.`);
+ }
+ if (destinationColumnIdx < 0 || destinationColumnIdx >= storage.length) {
+ throw Error(
+ `Destination column index "${destinationColumnIdx}" out of bounds.`);
+ }
+
+ const targetColumn: PivotAttrs|AggregationAttrs = storage[targetColumnIdx];
+ storage.splice(targetColumnIdx, 1);
+ storage.splice(destinationColumnIdx, 0, targetColumn);
+ }
+
+ selectedColumnOnDrag(e: DragEvent, isPivot: boolean, targetIdx: number) {
+ const dataTransferType = getDataTransferType(isPivot);
+ if (e.dataTransfer === null) {
+ return;
+ }
+ e.dataTransfer.setData(dataTransferType, targetIdx.toString());
+ }
+
+ selectedColumnOnDrop(
+ e: DragEvent, isPivot: boolean, destinationColumnIdx: number) {
+ const dataTransferType = getDataTransferType(isPivot);
+ if (e.dataTransfer === null) {
+ return;
+ }
+ // Prevents dragging pivots to aggregations and vice versa.
+ if (!e.dataTransfer.types.includes(dataTransferType)) {
+ return;
+ }
+
+ const targetColumnIdxString = e.dataTransfer.getData(dataTransferType);
+ const targetColumnIdx = Number(targetColumnIdxString);
+ if (!Number.isInteger(targetColumnIdx)) {
+ throw Error(
+ `Target column index "${targetColumnIdxString}" is not valid.`);
+ }
+
+ this.reorderPivotTableDraggedColumn(
+ isPivot, targetColumnIdx, destinationColumnIdx);
+ e.dataTransfer.clearData(dataTransferType);
+ }
+
+
+ // Highlights valid drop locations when dragging over them.
+ highlightDropLocation(e: DragEvent, isPivot: boolean) {
+ if (e.dataTransfer === null) {
+ return;
+ }
+ // Prevents highlighting aggregations when dragging pivots over them
+ // and vice versa.
+ if (!e.dataTransfer.types.includes(getDataTransferType(isPivot))) {
+ return;
+ }
+ (e.target as HTMLTableDataCellElement).classList.add('drop-location');
+ }
+
+ removeHighlightFromDropLocation(e: DragEvent) {
+ (e.target as HTMLTableDataCellElement).classList.remove('drop-location');
+ }
+
+ // Gets column index in availableColumns based on its attributes.
+ getColumnIndex(columnAttrs: PivotAttrs|AggregationAttrs) {
+ let index = 0;
+ for (const {tableName, columns} of this.availableColumns) {
+ if (tableName === columnAttrs.tableName) {
+ const colIdx =
+ columns.findIndex(column => column === columnAttrs.columnName);
+ return colIdx === -1 ? -1 : index + colIdx;
+ }
+ index += columns.length;
+ }
+ return -1;
+ }
+
+ selectPivotTableColumn(columnAttrs: PivotAttrs|AggregationAttrs) {
+ this._isPivot = !isAggregationAttrs(columnAttrs);
+
+ const colIndex = this.getColumnIndex(columnAttrs);
+ if (colIndex === -1) {
+ throw Error(`Selected column "${columnAttrs.tableName} ${
+ columnAttrs.columnName}" not found in availableColumns.`);
+ }
+ this.setSelectedPivotTableColumnIndex(colIndex);
+
+ if (isAggregationAttrs(columnAttrs)) {
+ const aggIndex = this.availableAggregations.findIndex(
+ aggregation => aggregation === columnAttrs.aggregation);
+ if (aggIndex === -1) {
+ throw Error(`Selected aggregation "${
+ columnAttrs.aggregation}" not found in availableAggregations.`);
+ }
+ this.setSelectedPivotTableAggregationIndex(aggIndex);
+ }
+ }
+
+ queryPivotTableChanges() {
+ globals.dispatch(Actions.setSelectedPivotsAndAggregations({
+ pivotTableId: this.pivotTableId,
+ selectedPivots: this._selectedPivots,
+ selectedAggregations: this._selectedAggregations
+ }));
+ globals.dispatch(Actions.setPivotTableRequest(
+ {pivotTableId: this.pivotTableId, action: 'QUERY'}));
+ }
+
+ toggleEditPivotTableModal() {
+ this._editPivotTableModalOpen = !this._editPivotTableModalOpen;
+ }
+
+ get selectedPivots() {
+ return this._selectedPivots.map(pivot => Object.assign({}, pivot));
+ }
+
+ get selectedAggregations() {
+ return this._selectedAggregations.map(
+ aggregation => Object.assign({}, aggregation));
+ }
+
+ get isPivot() {
+ return this._isPivot;
+ }
+
+ get selectedColumnIndex() {
+ return this._selectedColumnIndex;
+ }
+
+ get selectedAggregationIndex() {
+ return this._selectedAggregationIndex;
+ }
+
+ get editPivotTableModalOpen() {
+ return this._editPivotTableModalOpen;
+ }
+}
diff --git a/ui/src/frontend/pivot_table_helper_unittest.ts b/ui/src/frontend/pivot_table_helper_unittest.ts
new file mode 100644
index 000000000..2f45b1f9a
--- /dev/null
+++ b/ui/src/frontend/pivot_table_helper_unittest.ts
@@ -0,0 +1,139 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {SLICE_STACK_COLUMN, TableAttrs} from '../common/pivot_table_common';
+import {PivotTableHelper} from './pivot_table_helper';
+
+const AVAILABLE_COLUMNS: TableAttrs[] =
+ [{tableName: 'slice', columns: ['id', 'type', 'dur', SLICE_STACK_COLUMN]}];
+const ID_COL_IDX = 0;
+const TYPE_COL_IDX = 1;
+const DUR_COL_IDX = 2;
+const STACK_COL_IDX = 3;
+
+const AVAILABLE_AGGREGATIONS = ['SUM', 'AVG'];
+const SUM_AGG_IDX = 0;
+const AVG_AGG_IDX = 1;
+
+function createNewHelper() {
+ return new PivotTableHelper(
+ 'pivotTable', AVAILABLE_COLUMNS, AVAILABLE_AGGREGATIONS, [], []);
+}
+
+test('Update selected pivots based on selected indices', () => {
+ const helper = createNewHelper();
+ helper.setSelectedPivotTableColumnIndex(ID_COL_IDX);
+
+ helper.updatePivotTableColumnOnSelectedIndex();
+ expect(helper.selectedPivots).toEqual([
+ {tableName: 'slice', columnName: 'id', isStackPivot: false}
+ ]);
+
+ helper.updatePivotTableColumnOnSelectedIndex();
+ expect(helper.selectedPivots).toEqual([]);
+});
+
+test('Update selected aggregations based on selected indices', () => {
+ const helper = createNewHelper();
+ helper.togglePivotSelection();
+ helper.setSelectedPivotTableColumnIndex(DUR_COL_IDX);
+ helper.setSelectedPivotTableAggregationIndex(SUM_AGG_IDX);
+
+ helper.updatePivotTableColumnOnSelectedIndex();
+ expect(helper.selectedAggregations).toEqual([
+ {tableName: 'slice', columnName: 'dur', aggregation: 'SUM', order: 'DESC'}
+ ]);
+
+ helper.updatePivotTableColumnOnSelectedIndex();
+ expect(helper.selectedAggregations).toEqual([]);
+});
+
+test('Change aggregation sorting based on aggregation index', () => {
+ const helper = createNewHelper();
+ helper.togglePivotSelection();
+ helper.setSelectedPivotTableColumnIndex(DUR_COL_IDX);
+ helper.setSelectedPivotTableAggregationIndex(SUM_AGG_IDX);
+ helper.updatePivotTableColumnOnSelectedIndex();
+
+ expect(helper.selectedAggregations).toEqual([
+ {tableName: 'slice', columnName: 'dur', aggregation: 'SUM', order: 'DESC'}
+ ]);
+ helper.togglePivotTableAggregationSorting(0);
+ expect(helper.selectedAggregations).toEqual([
+ {tableName: 'slice', columnName: 'dur', aggregation: 'SUM', order: 'ASC'}
+ ]);
+});
+
+test(
+ 'Changing aggregation sorting with invalid index results in an error',
+ () => {
+ const helper = createNewHelper();
+ expect(() => helper.togglePivotTableAggregationSorting(1))
+ .toThrow('Column index "1" is out of bounds.');
+ });
+
+test('Reorder columns based on target and destination indices', () => {
+ const helper = createNewHelper();
+ helper.setSelectedPivotTableColumnIndex(ID_COL_IDX);
+ helper.updatePivotTableColumnOnSelectedIndex();
+ helper.setSelectedPivotTableColumnIndex(TYPE_COL_IDX);
+ helper.updatePivotTableColumnOnSelectedIndex();
+
+ expect(helper.selectedPivots).toEqual([
+ {tableName: 'slice', columnName: 'id', isStackPivot: false},
+ {tableName: 'slice', columnName: 'type', isStackPivot: false}
+ ]);
+ helper.reorderPivotTableDraggedColumn(true, 0, 1);
+ expect(helper.selectedPivots).toEqual([
+ {tableName: 'slice', columnName: 'type', isStackPivot: false},
+ {tableName: 'slice', columnName: 'id', isStackPivot: false}
+ ]);
+});
+
+test('Reordering columns with invalid indices results in an error', () => {
+ const helper = createNewHelper();
+ expect(() => helper.reorderPivotTableDraggedColumn(true, 0, 1))
+ .toThrow('Target column index "0" out of bounds.');
+});
+
+test('Select column based on attributes', () => {
+ const helper = createNewHelper();
+ helper.selectPivotTableColumn({
+ tableName: 'slice',
+ columnName: 'dur',
+ aggregation: 'AVG',
+ order: 'DESC'
+ });
+ expect(helper.isPivot).toEqual(false);
+ expect(helper.selectedColumnIndex).toEqual(DUR_COL_IDX);
+ expect(helper.selectedAggregationIndex).toEqual(AVG_AGG_IDX);
+});
+
+test('Selecting a column with invalid attributes results in an error', () => {
+ const helper = createNewHelper();
+ expect(
+ () => helper.selectPivotTableColumn(
+ {tableName: 'foo', columnName: 'bar', isStackPivot: false}))
+ .toThrow('Selected column "foo bar" not found in availableColumns.');
+});
+
+test('Selecting stack column sets isStackPivot', () => {
+ const helper = createNewHelper();
+ helper.setSelectedPivotTableColumnIndex(STACK_COL_IDX);
+
+ helper.updatePivotTableColumnOnSelectedIndex();
+ expect(helper.selectedPivots).toEqual([
+ {tableName: 'slice', columnName: SLICE_STACK_COLUMN, isStackPivot: true}
+ ]);
+});
diff --git a/ui/src/frontend/pivot_table_redux.ts b/ui/src/frontend/pivot_table_redux.ts
new file mode 100644
index 000000000..2bdae1b9c
--- /dev/null
+++ b/ui/src/frontend/pivot_table_redux.ts
@@ -0,0 +1,387 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import * as m from 'mithril';
+
+import {GenericSet} from '../base/generic_set';
+import {sqliteString} from '../base/string_utils';
+import {Actions} from '../common/actions';
+import {ColumnType} from '../common/query_result';
+import {
+ Area,
+ PivotTableReduxQuery,
+ PivotTableReduxResult
+} from '../common/state';
+import {PivotTree} from '../controller/pivot_table_redux_controller';
+
+import {globals} from './globals';
+import {Panel} from './panel';
+import {
+ aggregationIndex,
+ areaFilter,
+ createColumnSet,
+ generateQuery,
+ QueryGeneratorError,
+ sliceAggregationColumns,
+ Table,
+ TableColumn,
+ tables,
+ threadSliceAggregationColumns
+} from './pivot_table_redux_query_generator';
+
+interface ColumnSetCheckboxAttrs {
+ set: GenericSet<TableColumn>;
+ setKey: TableColumn;
+}
+
+interface PathItem {
+ tree: PivotTree;
+ nextKey: ColumnType;
+}
+
+// Helper component that controls whether a particular key is present in a
+// ColumnSet.
+class ColumnSetCheckbox implements m.ClassComponent<ColumnSetCheckboxAttrs> {
+ view({attrs}: m.Vnode<ColumnSetCheckboxAttrs>) {
+ return m('input[type=checkbox]', {
+ onclick: (e: InputEvent) => {
+ const target = e.target as HTMLInputElement;
+ if (target.checked) {
+ attrs.set.add(attrs.setKey);
+ } else {
+ attrs.set.delete(attrs.setKey);
+ }
+ globals.rafScheduler.scheduleFullRedraw();
+ },
+ checked: attrs.set.has(attrs.setKey)
+ });
+ }
+}
+
+interface PivotTableReduxAttrs {
+ selectionArea: Area;
+}
+
+interface DrillFilter {
+ column: string;
+ value: ColumnType;
+}
+
+// Convert DrillFilter to SQL condition to be used in WHERE clause.
+function renderDrillFilter(filter: DrillFilter): string {
+ if (filter.value === null) {
+ return `${filter.column} IS NULL`;
+ } else if (typeof filter.value === 'number') {
+ return `${filter.column} = ${filter.value}`;
+ }
+ return `${filter.column} = ${sqliteString(filter.value)}`;
+}
+
+export class PivotTableRedux extends Panel<PivotTableReduxAttrs> {
+ selectedPivotsMap = createColumnSet();
+ selectedAggregations = createColumnSet();
+ constrainToArea = true;
+ editMode = true;
+
+ renderCanvas(): void {}
+
+ generateQuery(attrs: PivotTableReduxAttrs): PivotTableReduxQuery {
+ return generateQuery(
+ this.selectedPivotsMap,
+ this.selectedAggregations,
+ attrs.selectionArea,
+ this.constrainToArea);
+ }
+
+ runQuery(attrs: PivotTableReduxAttrs) {
+ try {
+ const query = this.generateQuery(attrs);
+ const lastPivotTableState = globals.state.pivotTableRedux;
+ globals.dispatch(Actions.setPivotStateReduxState({
+ pivotTableState: {
+ query,
+ queryId: lastPivotTableState.queryId + 1,
+ selectionArea: lastPivotTableState.selectionArea,
+ queryResult: null
+ }
+ }));
+ } catch (e) {
+ console.log(e);
+ }
+ }
+
+ renderTablePivotColumns(t: Table) {
+ return m(
+ 'li',
+ t.name,
+ m('ul',
+ t.columns.map(
+ col =>
+ m('li',
+ m(ColumnSetCheckbox, {
+ set: this.selectedPivotsMap,
+ setKey: [t.name, col],
+ }),
+ col))));
+ }
+
+ renderResultsView(attrs: PivotTableReduxAttrs) {
+ return m(
+ '.pivot-table-redux',
+ m('button.mode-button',
+ {
+ onclick: () => {
+ this.editMode = true;
+ globals.rafScheduler.scheduleFullRedraw();
+ }
+ },
+ 'Edit'),
+ this.renderResultsTable(attrs));
+ }
+
+ renderDrillDownCell(
+ area: Area, result: PivotTableReduxResult, filters: DrillFilter[]) {
+ return m(
+ 'td',
+ m('button',
+ {
+ title: 'All corresponding slices',
+ onclick: () => {
+ const queryFilters = filters.map(renderDrillFilter);
+ if (this.constrainToArea) {
+ queryFilters.push(areaFilter(area));
+ }
+ const query = `
+ select * from ${result.metadata.tableName}
+ where ${queryFilters.join(' and \n')}
+ `;
+ // TODO(ddrone): the UI of running query as if it was a canned or
+ // custom query is a temporary one, replace with a proper UI.
+ globals.dispatch(Actions.executeQuery({
+ engineId: '0',
+ queryId: 'command',
+ query,
+ }));
+ }
+ },
+ m('i.material-icons', 'arrow_right')));
+ }
+
+ renderSectionRow(
+ area: Area, path: PathItem[], tree: PivotTree,
+ result: PivotTableReduxResult): m.Vnode {
+ const renderedCells = [];
+ for (let j = 0; j + 1 < path.length; j++) {
+ renderedCells.push(m('td', m('span.indent', ' '), `${path[j].nextKey}`));
+ }
+
+ const treeDepth = result.metadata.pivotColumns.length;
+ const colspan = treeDepth - path.length + 1;
+ const button =
+ m('button',
+ {
+ onclick: () => {
+ tree.isCollapsed = !tree.isCollapsed;
+ globals.rafScheduler.scheduleFullRedraw();
+ }
+ },
+ m('i.material-icons',
+ tree.isCollapsed ? 'expand_more' : 'expand_less'));
+
+ renderedCells.push(
+ m('td', {colspan}, button, `${path[path.length - 1].nextKey}`));
+
+ for (const value of tree.aggregates) {
+ renderedCells.push(m('td', `${value}`));
+ }
+
+ const drillFilters: DrillFilter[] = [];
+ for (let i = 0; i < path.length; i++) {
+ drillFilters.push({
+ value: `${path[i].nextKey}`,
+ column: result.metadata.pivotColumns[i]
+ });
+ }
+
+ renderedCells.push(this.renderDrillDownCell(area, result, drillFilters));
+ return m('tr', renderedCells);
+ }
+
+ renderTree(
+ area: Area, path: PathItem[], tree: PivotTree,
+ result: PivotTableReduxResult, sink: m.Vnode[]) {
+ if (tree.isCollapsed) {
+ sink.push(this.renderSectionRow(area, path, tree, result));
+ return;
+ }
+ if (tree.children.size > 0) {
+ // Avoid rendering the intermediate results row for the root of tree
+ // and in case there's only one child subtree.
+ if (!tree.isCollapsed && path.length > 0 && tree.children.size !== 1) {
+ sink.push(this.renderSectionRow(area, path, tree, result));
+ }
+ for (const [key, childTree] of tree.children.entries()) {
+ path.push({tree: childTree, nextKey: key});
+ this.renderTree(area, path, childTree, result, sink);
+ path.pop();
+ }
+ return;
+ }
+
+ // Avoid rendering the intermediate results row if it has only one leaf
+ // row.
+ if (!tree.isCollapsed && path.length > 0 && tree.rows.length > 1) {
+ sink.push(this.renderSectionRow(area, path, tree, result));
+ }
+ for (const row of tree.rows) {
+ const renderedCells = [];
+ const drillFilters: DrillFilter[] = [];
+ const treeDepth = result.metadata.pivotColumns.length;
+ for (let j = 0; j < treeDepth; j++) {
+ if (j < path.length) {
+ renderedCells.push(m('td', m('span.indent', ' '), `${row[j]}`));
+ } else {
+ renderedCells.push(m(`td`, `${row[j]}`));
+ }
+ drillFilters.push(
+ {column: result.metadata.pivotColumns[j], value: row[j]});
+ }
+ for (let j = 0; j < result.metadata.aggregationColumns.length; j++) {
+ const value = row[aggregationIndex(treeDepth, j, treeDepth)];
+ renderedCells.push(m('td', `${value}`));
+ }
+
+ renderedCells.push(this.renderDrillDownCell(area, result, drillFilters));
+ sink.push(m('tr', renderedCells));
+ }
+ }
+
+ renderTotalsRow(queryResult: PivotTableReduxResult) {
+ const overallValuesRow =
+ [m('td.total-values',
+ {'colspan': queryResult.metadata.pivotColumns.length},
+ m('strong', 'Total values:'))];
+ for (const aggValue of queryResult.tree.aggregates) {
+ overallValuesRow.push(m('td', `${aggValue}`));
+ }
+ overallValuesRow.push(m('td'));
+ return m('tr', overallValuesRow);
+ }
+
+ renderResultsTable(attrs: PivotTableReduxAttrs) {
+ const state = globals.state.pivotTableRedux;
+ if (state.query !== null || state.queryResult === null) {
+ return m('div', 'Loading...');
+ }
+
+ const renderedRows: m.Vnode[] = [];
+ const tree = state.queryResult.tree;
+
+ if (tree.children.size === 0 && tree.rows.length === 0) {
+ // Empty result, render a special message
+ return m('.empty-result', 'No slices in the current selection.');
+ }
+
+ this.renderTree(
+ attrs.selectionArea, [], tree, state.queryResult, renderedRows);
+
+ const allColumns = state.queryResult.metadata.pivotColumns.concat(
+ state.queryResult.metadata.aggregationColumns);
+ return m(
+ 'table.query-table.pivot-table',
+ m('thead', m('tr', allColumns.map(column => m('td', column)), m('td'))),
+ m('tbody', this.renderTotalsRow(state.queryResult), renderedRows));
+ }
+
+ renderQuery(attrs: PivotTableReduxAttrs): m.Vnode {
+ // Prepare a button to switch to results mode.
+ let innerElement =
+ m('button.mode-button',
+ {
+ onclick: () => {
+ this.editMode = false;
+ this.runQuery(attrs);
+ globals.rafScheduler.scheduleFullRedraw();
+ }
+ },
+ 'Execute');
+ try {
+ this.generateQuery(attrs);
+ } catch (e) {
+ if (e instanceof QueryGeneratorError) {
+ // If query generation fails, show an error message instead of a button.
+ innerElement = m('div.query-error', e.message);
+ } else {
+ throw e;
+ }
+ }
+
+ return m(
+ 'div',
+ m('div',
+ m('input', {
+ type: 'checkbox',
+ id: 'constrain-to-selection',
+ checked: this.constrainToArea,
+ onclick: (e: InputEvent) => {
+ const checkbox = e.target as HTMLInputElement;
+ this.constrainToArea = checkbox.checked;
+ }
+ }),
+ m('label',
+ {
+ 'for': 'constrain-to-selection',
+ },
+ 'Constrain to current time range')),
+ innerElement);
+ }
+
+ view({attrs}: m.Vnode<PivotTableReduxAttrs>) {
+ return this.editMode ? this.renderEditView(attrs) :
+ this.renderResultsView(attrs);
+ }
+
+ renderEditView(attrs: PivotTableReduxAttrs) {
+ return m(
+ '.pivot-table-redux.edit',
+ m('div',
+ m('h2', 'Pivots'),
+ m('ul',
+ tables.map(
+ t => this.renderTablePivotColumns(t),
+ ))),
+ m('div',
+ m('h2', 'Aggregations'),
+ m('ul',
+ ...sliceAggregationColumns.map(
+ t =>
+ m('li',
+ m(ColumnSetCheckbox, {
+ set: this.selectedAggregations,
+ setKey: ['slice', t],
+ }),
+ t)),
+ ...threadSliceAggregationColumns.map(
+ t =>
+ m('li',
+ m(ColumnSetCheckbox, {
+ set: this.selectedAggregations,
+ setKey: ['thread_slice', t],
+ }),
+ `thread_slice.${t}`)))),
+ this.renderQuery(attrs));
+ }
+} \ No newline at end of file
diff --git a/ui/src/frontend/pivot_table_redux_query_generator.ts b/ui/src/frontend/pivot_table_redux_query_generator.ts
new file mode 100644
index 000000000..c92243d6e
--- /dev/null
+++ b/ui/src/frontend/pivot_table_redux_query_generator.ts
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {GenericSet} from '../base/generic_set';
+import {Area, PivotTableReduxQuery} from '../common/state';
+import {toNs} from '../common/time';
+import {
+ getSelectedTrackIds
+} from '../controller/aggregation/slice_aggregation_controller';
+
+export interface Table {
+ name: string;
+ columns: string[];
+}
+
+export const sliceTable = {
+ name: 'slice',
+ columns: ['type', 'ts', 'dur', 'category', 'name']
+};
+
+// Columns of `slice` table available for aggregation.
+export const sliceAggregationColumns = ['ts', 'dur', 'depth'];
+
+// Columns of `thread_slice` table available for aggregation.
+export const threadSliceAggregationColumns = [
+ 'thread_ts',
+ 'thread_dur',
+ 'thread_instruction_count',
+ 'thread_instruction_delta'
+];
+
+// List of available tables to query, used to populate selectors of pivot
+// columns in the UI.
+export const tables: Table[] = [
+ sliceTable,
+ {
+ name: 'process',
+ columns: [
+ 'type',
+ 'pid',
+ 'name',
+ 'parent_upid',
+ 'uid',
+ 'android_appid',
+ 'cmdline'
+ ]
+ },
+ {name: 'thread', columns: ['type', 'name', 'tid', 'upid', 'is_main_thread']},
+ {name: 'thread_track', columns: ['type', 'name', 'utid']},
+];
+
+// Pair of table name and column name.
+export type TableColumn = [string, string];
+
+export function createColumnSet(): GenericSet<TableColumn> {
+ return new GenericSet((column: TableColumn) => `${column[0]}.${column[1]}`);
+}
+
+// Exception thrown by query generator in case incoming parameters are not
+// suitable in order to build a correct query; these are caught by the UI and
+// displayed to the user.
+export class QueryGeneratorError extends Error {}
+
+// Internal column name for different rollover levels of aggregate columns.
+function aggregationAlias(
+ aggregationIndex: number, rolloverLevel: number): string {
+ return `agg_${aggregationIndex}_level_${rolloverLevel}`;
+}
+
+export function areaFilter(area: Area): string {
+ return `
+ ts > ${toNs(area.startSec)}
+ and ts < ${toNs(area.endSec)}
+ and track_id in (${getSelectedTrackIds(area).join(', ')})
+ `;
+}
+
+function generateInnerQuery(
+ pivots: string[],
+ aggregations: string[],
+ table: string,
+ includeTrack: boolean,
+ area: Area,
+ constrainToArea: boolean): string {
+ const pivotColumns = pivots.concat(includeTrack ? ['track_id'] : []);
+ const aggregationColumns: string[] = [];
+
+ for (let i = 0; i < aggregations.length; i++) {
+ const agg = aggregations[i];
+ aggregationColumns.push(`SUM(${agg}) as ${aggregationAlias(i, 0)}`);
+ }
+
+ // The condition is inverted because flipped order of literals makes JS
+ // formatter insert huge amounts of whitespace for no good reason.
+ return `
+ select
+ ${pivotColumns.concat(aggregationColumns).join(',\n')}
+ from ${table}
+ ${(constrainToArea ? `where ${areaFilter(area)}` : '')}
+ group by ${pivotColumns.join(', ')}
+ `;
+}
+
+function computeSliceTableAggregations(
+ selectedAggregations: GenericSet<TableColumn>):
+ {tableName: string, flatAggregations: string[]} {
+ let hasThreadSliceColumn = false;
+ const allColumns = [];
+ for (const [table, column] of selectedAggregations.values()) {
+ if (table === 'thread_slice') {
+ hasThreadSliceColumn = true;
+ }
+ allColumns.push(column);
+ }
+
+ return {
+ // If any aggregation column from `thread_slice` is present, it's going to
+ // be the base table for the pivot table query. Otherwise, `slice` is used.
+ // This later is going to be controllable by a UI element.
+ tableName: hasThreadSliceColumn ? 'thread_slice' : 'slice',
+ flatAggregations: allColumns
+ };
+}
+
+// Every aggregation in the request is contained in the result in (number of
+// pivots + 1) times for each rollover level. This helper function returs an
+// index of the necessary column in the response.
+export function aggregationIndex(
+ pivotColumns: number, aggregationNo: number, depth: number) {
+ return pivotColumns + aggregationNo * (pivotColumns + 1) +
+ (pivotColumns - depth);
+}
+
+export function generateQuery(
+ selectedPivots: GenericSet<TableColumn>,
+ selectedAggregations: GenericSet<TableColumn>,
+ area: Area,
+ constrainToArea: boolean): PivotTableReduxQuery {
+ const sliceTableAggregations =
+ computeSliceTableAggregations(selectedAggregations);
+ const slicePivots: string[] = [];
+ const nonSlicePivots: string[] = [];
+
+ if (sliceTableAggregations.flatAggregations.length === 0) {
+ throw new QueryGeneratorError('No aggregations selected');
+ }
+
+ for (const [table, pivot] of selectedPivots.values()) {
+ if (table === 'slice' || table === 'thread_slice') {
+ slicePivots.push(pivot);
+ } else {
+ nonSlicePivots.push(`${table}.${pivot}`);
+ }
+ }
+
+ if (slicePivots.length === 0 && nonSlicePivots.length === 0) {
+ throw new QueryGeneratorError('No pivots selected');
+ }
+
+ const outerAggregations = [];
+ const prefixedSlicePivots = slicePivots.map(p => `preaggregated.${p}`);
+ const totalPivotsArray = nonSlicePivots.concat(prefixedSlicePivots);
+ for (let i = 0; i < sliceTableAggregations.flatAggregations.length; i++) {
+ const agg = `preaggregated.${aggregationAlias(i, 0)}`;
+ outerAggregations.push(`SUM(${agg}) as ${aggregationAlias(i, 0)}`);
+
+ for (let level = 1; level < totalPivotsArray.length; level++) {
+ // Peculiar form "SUM(SUM(agg)) over (partition by columns)" here means
+ // following: inner SUM(agg) is an aggregation that is going to collapse
+ // tracks with the same pivot values, which is going to be post-aggregated
+ // by the set of columns by outer **window** SUM function.
+
+ // Need to use complicated query syntax can be avoided by having yet
+ // another nested subquery computing only aggregation values with window
+ // functions in the wrapper, but the generation code is going to be more
+ // complex; so complexity of the query is traded for complexity of the
+ // query generator.
+ outerAggregations.push(`SUM(SUM(${agg})) over (partition by ${
+ totalPivotsArray.slice(0, totalPivotsArray.length - level)
+ .join(', ')}) as ${aggregationAlias(i, level)}`);
+ }
+
+ outerAggregations.push(`SUM(SUM(${agg})) over () as ${
+ aggregationAlias(i, totalPivotsArray.length)}`);
+ }
+
+ const joins = `
+ join thread_track on thread_track.id = preaggregated.track_id
+ join thread using (utid)
+ join process using (upid)
+ `;
+
+ const text = `
+ select
+ ${
+ nonSlicePivots.concat(prefixedSlicePivots, outerAggregations).join(',\n')}
+ from (
+ ${
+ generateInnerQuery(
+ slicePivots,
+ sliceTableAggregations.flatAggregations,
+ sliceTableAggregations.tableName,
+ nonSlicePivots.length > 0,
+ area,
+ constrainToArea)}
+ ) preaggregated
+ ${nonSlicePivots.length > 0 ? joins : ''}
+ group by ${nonSlicePivots.concat(prefixedSlicePivots).join(', ')}
+ `;
+
+ return {
+ text,
+ metadata: {
+ tableName: sliceTableAggregations.tableName,
+ pivotColumns: nonSlicePivots.concat(slicePivots.map(
+ column => `${sliceTableAggregations.tableName}.${column}`)),
+ aggregationColumns: sliceTableAggregations.flatAggregations.map(
+ agg => `SUM(${sliceTableAggregations.tableName}.${agg})`)
+ }
+ };
+}
diff --git a/ui/src/frontend/popup_menu.ts b/ui/src/frontend/popup_menu.ts
new file mode 100644
index 000000000..dffbec137
--- /dev/null
+++ b/ui/src/frontend/popup_menu.ts
@@ -0,0 +1,120 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import * as m from 'mithril';
+import {globals} from './globals';
+
+interface PopupMenuItem {
+ // Display text
+ text: string;
+ // Action on menu item click
+ callback: () => void;
+}
+
+interface PopupMenuButtonAttrs {
+ // Icon for button opening a menu
+ icon: string;
+ // List of popup menu items
+ items: PopupMenuItem[];
+}
+
+// To ensure having at most one popup menu on the screen at a time, we need to
+// listen to click events on the whole page and close currently opened popup, if
+// there's any. This class, used as a singleton, does exactly that.
+class PopupHolder {
+ // Invariant: global listener should be register if and only if this.popup is
+ // not undefined.
+ popup: PopupMenuButton|undefined = undefined;
+ initialized = false;
+ listener: (e: MouseEvent) => void;
+
+ constructor() {
+ this.listener = (e: MouseEvent) => {
+ // Only handle those events that are not part of dropdown menu themselves.
+ const hasDropdown =
+ e.composedPath().find(PopupHolder.isDropdownElement) !== undefined;
+ if (!hasDropdown) {
+ this.ensureHidden();
+ }
+ };
+ }
+
+ static isDropdownElement(target: EventTarget) {
+ if (target instanceof HTMLElement) {
+ return target.tagName === 'DIV' && target.classList.contains('dropdown');
+ }
+ return false;
+ }
+
+ ensureHidden() {
+ if (this.popup !== undefined) {
+ this.popup.setVisible(false);
+ }
+ }
+
+ clear() {
+ if (this.popup !== undefined) {
+ this.popup = undefined;
+ window.removeEventListener('click', this.listener);
+ }
+ }
+
+ showPopup(popup: PopupMenuButton) {
+ this.ensureHidden();
+ this.popup = popup;
+ window.addEventListener('click', this.listener);
+ }
+}
+
+// Singleton instance of PopupHolder
+const popupHolder = new PopupHolder();
+
+// Component that displays a button that shows a popup menu on click.
+export class PopupMenuButton implements m.ClassComponent<PopupMenuButtonAttrs> {
+ popupShown = false;
+
+ setVisible(visible: boolean) {
+ this.popupShown = visible;
+ if (this.popupShown) {
+ popupHolder.showPopup(this);
+ } else {
+ popupHolder.clear();
+ }
+ globals.rafScheduler.scheduleFullRedraw();
+ }
+
+ view(vnode: m.Vnode<PopupMenuButtonAttrs, this>) {
+ return m(
+ '.dropdown',
+ m('i.material-icons',
+ {
+ onclick: () => {
+ this.setVisible(!this.popupShown);
+ }
+ },
+ vnode.attrs.icon),
+ m(this.popupShown ? '.popup-menu.opened' : '.popup-menu.closed',
+ vnode.attrs.items.map(
+ item =>
+ m('button',
+ {
+ onclick: () => {
+ item.callback();
+ // Hide the menu item after the action has been invoked
+ this.setVisible(false);
+ }
+ },
+ item.text))));
+ }
+}
diff --git a/ui/src/frontend/post_message_handler.ts b/ui/src/frontend/post_message_handler.ts
index f4ff21479..56269e388 100644
--- a/ui/src/frontend/post_message_handler.ts
+++ b/ui/src/frontend/post_message_handler.ts
@@ -30,6 +30,7 @@ function isTrustedOrigin(origin: string): boolean {
'https://chrometto.googleplex.com',
'https://uma.googleplex.com',
];
+ if (origin === window.origin) return true;
if (TRUSTED_ORIGINS.includes(origin)) return true;
if (new URL(origin).hostname.endsWith('corp.google.com')) return true;
return false;
@@ -91,10 +92,18 @@ export function postMessageHandler(messageEvent: MessageEvent) {
throw new Error('Incoming message trace buffer is empty');
}
+ /* Removing this event listener to avoid callers posting the trace multiple
+ * times. If the callers add an event listener which upon receiving 'PONG'
+ * posts the trace to ui.perfetto.dev, the callers can receive multiple 'PONG'
+ * messages and accidentally post the trace multiple times. This was part of
+ * the cause of b/182502595.
+ */
+ window.removeEventListener('message', postMessageHandler);
+
const openTrace = () => {
// For external traces, we need to disable other features such as
// downloading and sharing a trace.
- globals.frontendLocalState.localOnlyMode = true;
+ postedTrace.localOnly = true;
globals.dispatch(Actions.openTraceFromBuffer(postedTrace));
};
@@ -130,7 +139,7 @@ function sanitizePostedTrace(postedTrace: PostedTrace): PostedTrace {
}
function sanitizeString(str: string): string {
- return str.replace(/[^A-Za-z0-9.\-_#:/?=&;% ]/g, ' ');
+ return str.replace(/[^A-Za-z0-9.\-_#:/?=&;%+ ]/g, ' ');
}
// tslint:disable:no-any
diff --git a/ui/src/frontend/publish.ts b/ui/src/frontend/publish.ts
new file mode 100644
index 000000000..af2c86ad6
--- /dev/null
+++ b/ui/src/frontend/publish.ts
@@ -0,0 +1,204 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {Actions} from '../common/actions';
+import {AggregateData, isEmptyData} from '../common/aggregation_data';
+import {ConversionJobStatusUpdate} from '../common/conversion_jobs';
+import {
+ LogBoundsKey,
+ LogEntriesKey,
+ LogExists,
+ LogExistsKey
+} from '../common/logs';
+import {MetricResult} from '../common/metric_data';
+import {CurrentSearchResults, SearchSummary} from '../common/search_data';
+
+import {
+ CounterDetails,
+ CpuProfileDetails,
+ FlamegraphDetails,
+ Flow,
+ globals,
+ QuantizedLoad,
+ SliceDetails,
+ ThreadDesc,
+ ThreadStateDetails
+} from './globals';
+import {findCurrentSelection} from './keyboard_event_handler';
+import {PivotTableHelper} from './pivot_table_helper';
+
+export function publishOverviewData(
+ data: {[key: string]: QuantizedLoad|QuantizedLoad[]}) {
+ for (const [key, value] of Object.entries(data)) {
+ if (!globals.overviewStore.has(key)) {
+ globals.overviewStore.set(key, []);
+ }
+ if (value instanceof Array) {
+ globals.overviewStore.get(key)!.push(...value);
+ } else {
+ globals.overviewStore.get(key)!.push(value);
+ }
+ }
+ globals.rafScheduler.scheduleRedraw();
+}
+
+export function publishTrackData(args: {id: string, data: {}}) {
+ globals.setTrackData(args.id, args.data);
+ if ([LogExistsKey, LogBoundsKey, LogEntriesKey].includes(args.id)) {
+ const data = globals.trackDataStore.get(LogExistsKey) as LogExists;
+ if (data && data.exists) globals.rafScheduler.scheduleFullRedraw();
+ } else {
+ globals.rafScheduler.scheduleRedraw();
+ }
+}
+
+export function publishMetricResult(metricResult: MetricResult) {
+ globals.setMetricResult(metricResult);
+ globals.publishRedraw();
+}
+
+export function publishSelectedFlows(selectedFlows: Flow[]) {
+ globals.selectedFlows = selectedFlows;
+ globals.publishRedraw();
+}
+
+export function publishCounterDetails(click: CounterDetails) {
+ globals.counterDetails = click;
+ globals.publishRedraw();
+}
+
+export function publishFlamegraphDetails(click: FlamegraphDetails) {
+ globals.flamegraphDetails = click;
+ globals.publishRedraw();
+}
+
+export function publishCpuProfileDetails(details: CpuProfileDetails) {
+ globals.cpuProfileDetails = details;
+ globals.publishRedraw();
+}
+
+export function publishHasFtrace(hasFtrace: boolean) {
+ globals.hasFtrace = hasFtrace;
+ globals.publishRedraw();
+}
+
+export function publishConversionJobStatusUpdate(
+ job: ConversionJobStatusUpdate) {
+ globals.setConversionJobStatus(job.jobName, job.jobStatus);
+ globals.publishRedraw();
+}
+
+export function publishLoading(numQueuedQueries: number) {
+ globals.numQueuedQueries = numQueuedQueries;
+ // TODO(hjd): Clean up loadingAnimation given that this now causes a full
+ // redraw anyways. Also this should probably just go via the global state.
+ globals.rafScheduler.scheduleFullRedraw();
+}
+
+export function publishBufferUsage(args: {percentage: number}) {
+ globals.setBufferUsage(args.percentage);
+ globals.publishRedraw();
+}
+
+export function publishSearch(args: SearchSummary) {
+ globals.searchSummary = args;
+ globals.publishRedraw();
+}
+
+export function publishSearchResult(args: CurrentSearchResults) {
+ globals.currentSearchResults = args;
+ globals.publishRedraw();
+}
+
+export function publishRecordingLog(args: {logs: string}) {
+ globals.setRecordingLog(args.logs);
+ globals.publishRedraw();
+}
+
+export function publishTraceErrors(numErrors: number) {
+ globals.setTraceErrors(numErrors);
+ globals.publishRedraw();
+}
+
+export function publishMetricError(error: string) {
+ globals.setMetricError(error);
+ globals.logging.logError(error, false);
+ globals.publishRedraw();
+}
+
+export function publishAggregateData(
+ args: {data: AggregateData, kind: string}) {
+ globals.setAggregateData(args.kind, args.data);
+ if (!isEmptyData(args.data)) {
+ globals.dispatch(Actions.setCurrentTab({tab: args.data.tabName}));
+ }
+ globals.publishRedraw();
+}
+
+export function publishQueryResult(args: {id: string, data?: {}}) {
+ globals.queryResults.set(args.id, args.data);
+ globals.dispatch(Actions.setCurrentTab({tab: 'query_result'}));
+ globals.publishRedraw();
+}
+
+export function publishPivotTableHelper(
+ args: {id: string, data: PivotTableHelper}) {
+ globals.pivotTableHelper.set(args.id, args.data);
+ globals.publishRedraw();
+}
+
+export function publishThreads(data: ThreadDesc[]) {
+ globals.threads.clear();
+ data.forEach(thread => {
+ globals.threads.set(thread.utid, thread);
+ });
+ globals.publishRedraw();
+}
+
+export function publishSliceDetails(click: SliceDetails) {
+ globals.sliceDetails = click;
+ const id = click.id;
+ if (id !== undefined && id === globals.state.pendingScrollId) {
+ findCurrentSelection();
+ globals.dispatch(Actions.clearPendingScrollId({id: undefined}));
+ }
+ globals.publishRedraw();
+}
+
+export function publishThreadStateDetails(click: ThreadStateDetails) {
+ globals.threadStateDetails = click;
+ globals.publishRedraw();
+}
+
+export function publishConnectedFlows(connectedFlows: Flow[]) {
+ globals.connectedFlows = connectedFlows;
+ // If a chrome slice is selected and we have any flows in connectedFlows
+ // we will find the flows on the right and left of that slice to set a default
+ // focus. In all other cases the focusedFlowId(Left|Right) will be set to -1.
+ globals.dispatch(Actions.setHighlightedFlowLeftId({flowId: -1}));
+ globals.dispatch(Actions.setHighlightedFlowRightId({flowId: -1}));
+ if (globals.state.currentSelection?.kind === 'CHROME_SLICE') {
+ const sliceId = globals.state.currentSelection.id;
+ for (const flow of globals.connectedFlows) {
+ if (flow.begin.sliceId === sliceId) {
+ globals.dispatch(Actions.setHighlightedFlowRightId({flowId: flow.id}));
+ }
+ if (flow.end.sliceId === sliceId) {
+ globals.dispatch(Actions.setHighlightedFlowLeftId({flowId: flow.id}));
+ }
+ }
+ }
+
+ globals.publishRedraw();
+}
diff --git a/ui/src/frontend/query_table.ts b/ui/src/frontend/query_table.ts
index f69a8ba51..a70f9fbcf 100644
--- a/ui/src/frontend/query_table.ts
+++ b/ui/src/frontend/query_table.ts
@@ -16,15 +16,15 @@
import * as m from 'mithril';
import {Actions} from '../common/actions';
-import {Row} from '../common/protos';
import {QueryResponse} from '../common/queries';
+import {Row} from '../common/query_result';
import {fromNs} from '../common/time';
-import {copyToClipboard} from './clipboard';
+import {queryResponseToClipboard} from './clipboard';
import {globals} from './globals';
import {Panel} from './panel';
+import {Router} from './router';
import {
- findUiTrackId,
horizontalScrollAndZoomToRange,
verticalScrollToTrack
} from './scroll_helper';
@@ -46,7 +46,7 @@ class QueryTableRow implements m.ClassComponent<QueryTableRowAttrs> {
static rowOnClickHandler(
event: Event, row: Row, nextTab: 'CurrentSelection'|'QueryResults') {
// TODO(dproy): Make click handler work from analyze page.
- if (globals.state.route !== '/viewer') return;
+ if (Router.parseUrl(window.location.href).page !== '/viewer') return;
// If the click bubbles up to the pan and zoom handler that will deselect
// the slice.
event.stopPropagation();
@@ -56,8 +56,8 @@ class QueryTableRow implements m.ClassComponent<QueryTableRowAttrs> {
const sliceDur = fromNs(Math.max(row.dur as number, 1));
const sliceEnd = sliceStart + sliceDur;
const trackId = row.track_id as number;
- const uiTrackId = findUiTrackId(trackId);
- if (uiTrackId === null) return;
+ const uiTrackId = globals.state.uiTrackIdByTraceTrackId[trackId];
+ if (uiTrackId === undefined) return;
verticalScrollToTrack(uiTrackId, true);
horizontalScrollAndZoomToRange(sliceStart, sliceEnd);
let sliceId: number|undefined;
@@ -70,7 +70,7 @@ class QueryTableRow implements m.ClassComponent<QueryTableRowAttrs> {
globals.makeSelection(
Actions.selectChromeSlice(
{id: sliceId, trackId: uiTrackId, table: 'slice'}),
- nextTab === 'QueryResults' ? globals.frontendLocalState.currentTab :
+ nextTab === 'QueryResults' ? globals.state.currentTab :
'current_selection');
}
}
@@ -135,43 +135,45 @@ export class QueryTable extends Panel<QueryTableAttrs> {
rows.push(m(QueryTableRow, {row: resp.rows[i], columns: resp.columns}));
}
+ const headers = [
+ m(
+ 'header.overview',
+ `Query result - ${Math.round(resp.durationMs)} ms`,
+ m('span.code', resp.query),
+ resp.error ? null :
+ m('button.query-ctrl',
+ {
+ onclick: () => {
+ queryResponseToClipboard(resp);
+ },
+ },
+ 'Copy as .tsv'),
+ m('button.query-ctrl',
+ {
+ onclick: () => {
+ globals.queryResults.delete(queryId);
+ globals.rafScheduler.scheduleFullRedraw();
+ }
+ },
+ 'Close'),
+ ),
+ ];
+
+
+ if (resp.statementWithOutputCount > 1) {
+ headers.push(
+ m('header.overview',
+ `${resp.statementWithOutputCount} out of ${resp.statementCount} ` +
+ `statements returned a result. Only the results for the last ` +
+ `statement are displayed in the table below.`));
+ }
+
return m(
'div',
- m(
- 'header.overview',
- `Query result - ${Math.round(resp.durationMs)} ms`,
- m('span.code', resp.query),
- resp.error ?
- null :
- m('button.query-ctrl',
- {
- onclick: () => {
- const lines: string[][] = [];
- lines.push(resp.columns);
- for (const row of resp.rows) {
- const line = [];
- for (const col of resp.columns) {
- line.push(row[col].toString());
- }
- lines.push(line);
- }
- copyToClipboard(
- lines.map(line => line.join('\t')).join('\n'));
- },
- },
- 'Copy as .tsv'),
- m('button.query-ctrl',
- {
- onclick: () => {
- globals.queryResults.delete(queryId);
- globals.rafScheduler.scheduleFullRedraw();
- }
- },
- 'Close'),
- ),
+ ...headers,
resp.error ?
m('.query-error', `SQL error: ${resp.error}`) :
- m('.query-table-container',
+ m('.query-table-container.x-scrollable',
m('table.query-table', m('thead', header), m('tbody', rows))));
}
diff --git a/ui/src/frontend/raf_scheduler.ts b/ui/src/frontend/raf_scheduler.ts
index dd708c227..eccf094ae 100644
--- a/ui/src/frontend/raf_scheduler.ts
+++ b/ui/src/frontend/raf_scheduler.ts
@@ -115,6 +115,10 @@ export class RafScheduler {
}
}
+ get hasPendingRedraws(): boolean {
+ return this.isRedrawing || this.hasScheduledNextFrame;
+ }
+
private syncCanvasRedraw(nowMs: number) {
const redrawStart = debugNow();
if (this.isRedrawing) return;
diff --git a/ui/src/frontend/record_config.ts b/ui/src/frontend/record_config.ts
index 029f6f02a..a200b4734 100644
--- a/ui/src/frontend/record_config.ts
+++ b/ui/src/frontend/record_config.ts
@@ -12,57 +12,67 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {RecordConfig} from '../common/state';
-import {validateRecordConfig} from '../controller/validate_config';
+import {getDefaultRecordingTargets, RecordingTarget} from '../common/state';
+import {
+ createEmptyRecordConfig,
+ NamedRecordConfig,
+ namedRecordConfigValidator,
+ RecordConfig,
+ recordConfigValidator
+} from '../controller/record_config_types';
+import {runValidator, ValidationResult} from '../controller/validators';
const LOCAL_STORAGE_RECORD_CONFIGS_KEY = 'recordConfigs';
+const LOCAL_STORAGE_AUTOSAVE_CONFIG_KEY = 'autosaveConfig';
+const LOCAL_STORAGE_RECORD_TARGET_OS_KEY = 'recordTargetOS';
-class NamedRecordConfig {
- title: string;
- config: RecordConfig;
- key: string;
+export class RecordConfigStore {
+ recordConfigs: Array<ValidationResult<NamedRecordConfig>>;
+ recordConfigNames: Set<string>;
- constructor(title: string, config: RecordConfig, key: string) {
- this.title = title;
- this.config = this.validateData(config);
- this.key = key;
+ constructor() {
+ this.recordConfigs = [];
+ this.recordConfigNames = new Set();
+ this.reloadFromLocalStorage();
}
- private validateData(config: {}): RecordConfig {
- const validConfig = validateRecordConfig(config);
- if (validConfig.errorMessage) {
- // TODO(bsebastien): Show a warning message to the user in the UI.
- console.warn(validConfig.errorMessage);
- }
- return validConfig.config;
+ private _save() {
+ window.localStorage.setItem(
+ LOCAL_STORAGE_RECORD_CONFIGS_KEY,
+ JSON.stringify(this.recordConfigs.map((x) => x.result)));
}
- static isValid(jsonObject: object): jsonObject is NamedRecordConfig {
- return (jsonObject as NamedRecordConfig).title !== undefined &&
- (jsonObject as NamedRecordConfig).config !== undefined &&
- (jsonObject as NamedRecordConfig).key !== undefined;
- }
-}
+ save(recordConfig: RecordConfig, title?: string): void {
+ // We reload from local storage in case of concurrent
+ // modifications of local storage from a different tab.
+ this.reloadFromLocalStorage();
-export class RecordConfigStore {
- recordConfigs: NamedRecordConfig[];
+ const savedTitle = title ? title : new Date().toJSON();
+ const config: NamedRecordConfig = {
+ title: savedTitle,
+ config: recordConfig,
+ key: new Date().toJSON()
+ };
- constructor() {
- this.recordConfigs = [];
- this.reloadFromLocalStorage();
+ this.recordConfigs.push({result: config, invalidKeys: [], extraKeys: []});
+ this.recordConfigNames.add(savedTitle);
+
+ this._save();
}
- save(recordConfig: RecordConfig, title?: string): void {
+ overwrite(recordConfig: RecordConfig, key: string) {
// We reload from local storage in case of concurrent
// modifications of local storage from a different tab.
this.reloadFromLocalStorage();
- const config = new NamedRecordConfig(
- title ? title : new Date().toJSON(), recordConfig, new Date().toJSON());
+ const found = this.recordConfigs.find((e) => e.result.key === key);
+ if (found === undefined) {
+ throw new Error('trying to overwrite non-existing config');
+ }
+
+ found.result.config = recordConfig;
- this.recordConfigs.push(config);
- window.localStorage.setItem(
- LOCAL_STORAGE_RECORD_CONFIGS_KEY, JSON.stringify(this.recordConfigs));
+ this._save();
}
delete(key: string): void {
@@ -72,16 +82,16 @@ export class RecordConfigStore {
let idx = -1;
for (let i = 0; i < this.recordConfigs.length; ++i) {
- if (this.recordConfigs[i].key === key) {
+ if (this.recordConfigs[i].result.key === key) {
idx = i;
break;
}
}
if (idx !== -1) {
+ this.recordConfigNames.delete(this.recordConfigs[idx].result.title);
this.recordConfigs.splice(idx, 1);
- window.localStorage.setItem(
- LOCAL_STORAGE_RECORD_CONFIGS_KEY, JSON.stringify(this.recordConfigs));
+ this._save();
} else {
// TODO(bsebastien): Show a warning message to the user in the UI.
console.warn('The config selected doesn\'t exist any more');
@@ -90,8 +100,8 @@ export class RecordConfigStore {
private clearRecordConfigs(): void {
this.recordConfigs = [];
- window.localStorage.setItem(
- LOCAL_STORAGE_RECORD_CONFIGS_KEY, JSON.stringify([]));
+ this.recordConfigNames.clear();
+ this._save();
}
reloadFromLocalStorage(): void {
@@ -99,8 +109,11 @@ export class RecordConfigStore {
window.localStorage.getItem(LOCAL_STORAGE_RECORD_CONFIGS_KEY);
if (configsLocalStorage) {
+ this.recordConfigNames.clear();
+
try {
- const validConfigLocalStorage: NamedRecordConfig[] = [];
+ const validConfigLocalStorage:
+ Array<ValidationResult<NamedRecordConfig>> = [];
const parsedConfigsLocalStorage = JSON.parse(configsLocalStorage);
// Check if it's an array.
@@ -110,19 +123,20 @@ export class RecordConfigStore {
}
for (let i = 0; i < parsedConfigsLocalStorage.length; ++i) {
- if (!NamedRecordConfig.isValid(parsedConfigsLocalStorage[i])) {
- continue;
+ try {
+ validConfigLocalStorage.push(runValidator(
+ namedRecordConfigValidator, parsedConfigsLocalStorage[i]));
+ } catch {
+ // Parsing failed with unrecoverable error (e.g. title or key are
+ // missing), ignore the result.
+ console.log(
+ 'Validation of saved record config has failed: ' +
+ JSON.stringify(parsedConfigsLocalStorage[i]));
}
- validConfigLocalStorage.push(new NamedRecordConfig(
- parsedConfigsLocalStorage[i].title,
- parsedConfigsLocalStorage[i].config,
- parsedConfigsLocalStorage[i].key));
}
this.recordConfigs = validConfigLocalStorage;
- window.localStorage.setItem(
- LOCAL_STORAGE_RECORD_CONFIGS_KEY,
- JSON.stringify(validConfigLocalStorage));
+ this._save();
} catch (e) {
this.clearRecordConfigs();
}
@@ -130,8 +144,78 @@ export class RecordConfigStore {
this.clearRecordConfigs();
}
}
+
+ canSave(title: string) {
+ return !this.recordConfigNames.has(title);
+ }
}
// This class is a singleton to avoid many instances
// conflicting as they attempt to edit localStorage.
export const recordConfigStore = new RecordConfigStore();
+
+export class AutosaveConfigStore {
+ config: RecordConfig;
+
+ // Whether the current config is a default one or has been saved before.
+ // Used to determine whether the button to load "last started config" should
+ // be present in the recording profiles list.
+ hasSavedConfig: boolean;
+
+ constructor() {
+ this.hasSavedConfig = false;
+ this.config = createEmptyRecordConfig();
+ const savedItem =
+ window.localStorage.getItem(LOCAL_STORAGE_AUTOSAVE_CONFIG_KEY);
+ if (savedItem === null) {
+ return;
+ }
+ const parsed = JSON.parse(savedItem);
+ if (parsed !== null && typeof parsed === 'object') {
+ this.config = runValidator(recordConfigValidator, parsed).result;
+ this.hasSavedConfig = true;
+ }
+ }
+
+ get(): RecordConfig {
+ return this.config;
+ }
+
+ save(newConfig: RecordConfig) {
+ window.localStorage.setItem(
+ LOCAL_STORAGE_AUTOSAVE_CONFIG_KEY, JSON.stringify(newConfig));
+ this.config = newConfig;
+ this.hasSavedConfig = true;
+ }
+}
+
+export const autosaveConfigStore = new AutosaveConfigStore();
+
+export class RecordTargetStore {
+ recordTargetOS: string|null;
+
+ constructor() {
+ this.recordTargetOS =
+ window.localStorage.getItem(LOCAL_STORAGE_RECORD_TARGET_OS_KEY);
+ }
+
+ get(): string|null {
+ return this.recordTargetOS;
+ }
+
+ getValidTarget(): RecordingTarget {
+ const validTargets = getDefaultRecordingTargets();
+ const savedOS = this.get();
+
+ const validSavedTarget = validTargets.find((el) => el.os === savedOS);
+ return validSavedTarget || validTargets[0];
+ }
+
+ save(newTargetOS: string) {
+ window.localStorage.setItem(
+ LOCAL_STORAGE_RECORD_TARGET_OS_KEY, newTargetOS);
+ this.recordTargetOS = newTargetOS;
+ }
+}
+
+export const recordTargetStore = new RecordTargetStore();
diff --git a/ui/src/frontend/record_page.ts b/ui/src/frontend/record_page.ts
index 182a66b6a..d9b2d952e 100644
--- a/ui/src/frontend/record_page.ts
+++ b/ui/src/frontend/record_page.ts
@@ -17,6 +17,7 @@ import {produce} from 'immer';
import * as m from 'mithril';
import {Actions} from '../common/actions';
+import {featureFlags} from '../common/feature_flags';
import {MeminfoCounters, VmstatCounters} from '../common/protos';
import {
AdbRecordingTarget,
@@ -28,16 +29,29 @@ import {
isAndroidTarget,
isChromeTarget,
isCrOSTarget,
- RecordingTarget
+ isLinuxTarget,
+ LoadedConfig,
+ MAX_TIME,
+ RecordingTarget,
+ RecordMode
} from '../common/state';
-import {MAX_TIME, RecordMode} from '../common/state';
import {AdbOverWebUsb} from '../controller/adb';
+import {
+ createEmptyRecordConfig,
+ RecordConfig
+} from '../controller/record_config_types';
import {globals} from './globals';
-import {createPage} from './pages';
-import {recordConfigStore} from './record_config';
+import {createPage, PageAttrs} from './pages';
+import {
+ autosaveConfigStore,
+ recordConfigStore,
+ recordTargetStore
+} from './record_config';
import {
+ CategoriesCheckboxList,
CodeSnippet,
+ CompactProbe,
Dropdown,
DropdownAttrs,
Probe,
@@ -49,9 +63,13 @@ import {
Toggle,
ToggleAttrs
} from './record_widgets';
-import {Router} from './router';
-const LOCAL_STORAGE_SHOW_CONFIG = 'showConfigs';
+const PERSIST_CONFIG_FLAG = featureFlags.register({
+ id: 'persistConfigsUI',
+ name: 'Config persistence UI',
+ description: 'Show experimental config persistence UI on the record page.',
+ defaultValue: true,
+});
const POLL_INTERVAL_MS = [250, 500, 1000, 2500, 5000, 30000, 60000];
@@ -586,6 +604,21 @@ function MemorySettings(cssClass: string) {
} as DropdownAttrs)));
}
+function AtraceAppsList() {
+ if (globals.state.recordConfig.allAtraceApps) {
+ return m('div');
+ }
+
+ return m(Textarea, {
+ placeholder: 'Apps to profile, one per line, e.g.:\n' +
+ 'com.android.phone\n' +
+ 'lmkd\n' +
+ 'com.android.nfc',
+ cssClass: '.atrace-apps-list',
+ set: (cfg, val) => cfg.atraceApps = val,
+ get: (cfg) => cfg.atraceApps,
+ } as TextareaAttrs);
+}
function AndroidSettings(cssClass: string) {
return m(
@@ -606,13 +639,13 @@ function AndroidSettings(cssClass: string) {
set: (cfg, val) => cfg.atraceCats = val,
get: (cfg) => cfg.atraceCats
} as DropdownAttrs),
- m(Textarea, {
- placeholder: 'Extra apps to profile, one per line, e.g.:\n' +
- 'com.android.phone\n' +
- 'com.android.nfc',
- set: (cfg, val) => cfg.atraceApps = val,
- get: (cfg) => cfg.atraceApps
- } as TextareaAttrs)),
+ m(Toggle, {
+ title: 'Record events from all Android apps and services',
+ descr: '',
+ setEnabled: (cfg, val) => cfg.allAtraceApps = val,
+ isEnabled: (cfg) => cfg.allAtraceApps,
+ } as ToggleAttrs),
+ AtraceAppsList()),
m(Probe,
{
title: 'Event log (logcat)',
@@ -643,67 +676,46 @@ function AndroidSettings(cssClass: string) {
function ChromeSettings(cssClass: string) {
return m(
`.record-section${cssClass}`,
- m(Probe, {
+ CompactProbe({
title: 'Task scheduling',
- img: null,
- descr: `Records events about task scheduling and execution on all
- threads`,
setEnabled: (cfg, val) => cfg.taskScheduling = val,
- isEnabled: (cfg) => cfg.taskScheduling
- } as ProbeAttrs),
- m(Probe, {
+ isEnabled: (cfg) => cfg.taskScheduling,
+ }),
+ CompactProbe({
title: 'IPC flows',
- img: null,
- descr: `Records flow events for passing of IPC messages between
- processes.`,
setEnabled: (cfg, val) => cfg.ipcFlows = val,
isEnabled: (cfg) => cfg.ipcFlows
- } as ProbeAttrs),
- m(Probe, {
+ }),
+ CompactProbe({
title: 'Javascript execution',
- img: null,
- descr: `Records events about Javascript execution in the renderer
- processes.`,
setEnabled: (cfg, val) => cfg.jsExecution = val,
isEnabled: (cfg) => cfg.jsExecution
- } as ProbeAttrs),
- m(Probe, {
- title: 'Web content rendering',
- img: null,
- descr: `Records events about rendering, layout, and compositing of
- web content in Blink.`,
+ }),
+ CompactProbe({
+ title: 'Web content rendering, layout and compositing',
setEnabled: (cfg, val) => cfg.webContentRendering = val,
isEnabled: (cfg) => cfg.webContentRendering
- } as ProbeAttrs),
- m(Probe, {
- title: 'UI rendering & compositing',
- img: null,
- descr: `Records events about rendering of browser UI surfaces and
- compositing of surfaces.`,
+ }),
+ CompactProbe({
+ title: 'UI rendering & surface compositing',
setEnabled: (cfg, val) => cfg.uiRendering = val,
isEnabled: (cfg) => cfg.uiRendering
- } as ProbeAttrs),
- m(Probe, {
+ }),
+ CompactProbe({
title: 'Input events',
- img: null,
- descr: `Records input events and their flow between processes.`,
setEnabled: (cfg, val) => cfg.inputEvents = val,
isEnabled: (cfg) => cfg.inputEvents
- } as ProbeAttrs),
- m(Probe, {
+ }),
+ CompactProbe({
title: 'Navigation & Loading',
- img: null,
- descr: `Records network events for navigations and resources.`,
setEnabled: (cfg, val) => cfg.navigationAndLoading = val,
isEnabled: (cfg) => cfg.navigationAndLoading
- } as ProbeAttrs),
- m(Probe, {
+ }),
+ CompactProbe({
title: 'Chrome Logs',
- img: null,
- descr: `Records Chrome log messages`,
setEnabled: (cfg, val) => cfg.chromeLogs = val,
isEnabled: (cfg) => cfg.chromeLogs
- } as ProbeAttrs),
+ }),
ChromeCategoriesSelection());
}
@@ -716,34 +728,34 @@ function ChromeCategoriesSelection() {
categories = getBuiltinChromeCategoryList();
}
- // Show "disabled-by-default" categories last.
- const categoriesMap = new Map<string, string>();
- const disabledByDefaultCategories: string[] = [];
+ const defaultCategories = new Map<string, string>();
+ const disabledByDefaultCategories = new Map<string, string>();
const disabledPrefix = 'disabled-by-default-';
categories.forEach(cat => {
if (cat.startsWith(disabledPrefix)) {
- disabledByDefaultCategories.push(cat);
+ disabledByDefaultCategories.set(cat, cat.replace(disabledPrefix, ''));
} else {
- categoriesMap.set(cat, cat);
+ defaultCategories.set(cat, cat);
}
});
- disabledByDefaultCategories.forEach(cat => {
- categoriesMap.set(
- cat, `${cat.replace(disabledPrefix, '')} (high overhead)`);
- });
- return m(Dropdown, {
- title: 'Additional Chrome categories',
- cssClass: '.multicolumn.two-columns',
- options: categoriesMap,
- set: (cfg, val) => cfg.chromeCategoriesSelected = val,
- get: (cfg) => cfg.chromeCategoriesSelected
- } as DropdownAttrs);
+ return m(
+ '.chrome-categories',
+ m(CategoriesCheckboxList, {
+ categories: defaultCategories,
+ title: 'Additional categories',
+ get: (cfg) => cfg.chromeCategoriesSelected,
+ set: (cfg, val) => cfg.chromeCategoriesSelected = val,
+ }),
+ m(CategoriesCheckboxList, {
+ categories: disabledByDefaultCategories,
+ title: 'High overhead categories',
+ get: (cfg) => cfg.chromeHighOverheadCategoriesSelected,
+ set: (cfg, val) => cfg.chromeHighOverheadCategoriesSelected = val,
+ }));
}
function AdvancedSettings(cssClass: string) {
- const S = (x: number) => x * 1000;
- const M = (x: number) => x * 1000 * 60;
return m(
`.record-section${cssClass}`,
m(Probe,
@@ -756,6 +768,14 @@ function AdvancedSettings(cssClass: string) {
setEnabled: (cfg, val) => cfg.ftrace = val,
isEnabled: (cfg) => cfg.ftrace
} as ProbeAttrs,
+ m(Toggle, {
+ title: 'Resolve kernel symbols',
+ cssClass: '.thin',
+ descr: `Enables lookup via /proc/kallsyms for workqueue,
+ sched_blocked_reason and other events (userdebug/eng builds only).`,
+ setEnabled: (cfg, val) => cfg.symbolizeKsyms = val,
+ isEnabled: (cfg) => cfg.symbolizeKsyms
+ } as ToggleAttrs),
m(Slider, {
title: 'Buf size',
cssClass: '.thin',
@@ -785,27 +805,7 @@ function AdvancedSettings(cssClass: string) {
'kmem/*',
set: (cfg, val) => cfg.ftraceExtraEvents = val,
get: (cfg) => cfg.ftraceExtraEvents
- } as TextareaAttrs)),
- globals.state.videoEnabled ?
- m(Probe,
- {
- title: 'Screen recording',
- img: null,
- descr: `Records the screen along with running a trace. Max
- time of recording is 3 minutes (180 seconds).`,
- setEnabled: (cfg, val) => cfg.screenRecord = val,
- isEnabled: (cfg) => cfg.screenRecord,
- } as ProbeAttrs,
- m(Slider, {
- title: 'Max duration',
- icon: 'timer',
- values: [S(10), S(15), S(30), S(60), M(2), M(3)],
- isTime: true,
- unit: 'm:s',
- set: (cfg, val) => cfg.durationMs = val,
- get: (cfg) => cfg.durationMs,
- } as SliderAttrs)) :
- null);
+ } as TextareaAttrs)));
}
function RecordHeader() {
@@ -877,10 +877,11 @@ function onTargetChange(target: string) {
getDefaultRecordingTargets()[0];
if (isChromeTarget(recordingTarget)) {
- globals.dispatch(Actions.setUpdateChromeCategories({update: true}));
+ globals.dispatch(Actions.setFetchChromeCategories({fetch: true}));
}
globals.dispatch(Actions.setRecordingTarget({target: recordingTarget}));
+ recordTargetStore.save(target);
globals.rafScheduler.scheduleFullRedraw();
}
@@ -888,7 +889,7 @@ function Instructions(cssClass: string) {
return m(
`.record-section.instructions${cssClass}`,
m('header', 'Recording command'),
- localStorage.hasOwnProperty(LOCAL_STORAGE_SHOW_CONFIG) ?
+ PERSIST_CONFIG_FLAG.get() ?
m('button.permalinkconfig',
{
onclick: () => {
@@ -904,37 +905,88 @@ function Instructions(cssClass: string) {
recordingLog());
}
+function loadedConfigEqual(cfg1: LoadedConfig, cfg2: LoadedConfig): boolean {
+ return cfg1.type === 'NAMED' && cfg2.type === 'NAMED' ?
+ cfg1.name === cfg2.name :
+ cfg1.type === cfg2.type;
+}
+
+function loadConfigButton(
+ config: RecordConfig, configType: LoadedConfig): m.Vnode {
+ return m(
+ 'button',
+ {
+ class: 'config-button',
+ title: 'Apply configuration settings',
+ disabled: loadedConfigEqual(configType, globals.state.lastLoadedConfig),
+ onclick: () => {
+ globals.dispatch(Actions.setRecordConfig({config, configType}));
+ globals.rafScheduler.scheduleFullRedraw();
+ }
+ },
+ m('i.material-icons', 'file_upload'));
+}
+
function displayRecordConfigs() {
- return recordConfigStore.recordConfigs.map((item) => {
- return m('.config', [
+ const configs = [];
+ if (autosaveConfigStore.hasSavedConfig) {
+ configs.push(m('.config', [
+ m('span.title-config', m('strong', 'Latest started recording')),
+ loadConfigButton(autosaveConfigStore.get(), {type: 'AUTOMATIC'}),
+ ]));
+ }
+ for (const validated of recordConfigStore.recordConfigs) {
+ const item = validated.result;
+ configs.push(m('.config', [
m('span.title-config', item.title),
+ loadConfigButton(item.config, {type: 'NAMED', name: item.title}),
m('button',
{
- class: 'config-button load',
+ class: 'config-button',
+ title: 'Overwrite configuration with current settings',
onclick: () => {
- globals.dispatch(Actions.setRecordConfig({config: item.config}));
- globals.rafScheduler.scheduleFullRedraw();
+ if (confirm(`Overwrite config "${
+ item.title}" with current settings?`)) {
+ recordConfigStore.overwrite(globals.state.recordConfig, item.key);
+ globals.dispatch(Actions.setRecordConfig({
+ config: item.config,
+ configType: {type: 'NAMED', name: item.title}
+ }));
+ globals.rafScheduler.scheduleFullRedraw();
+ }
}
},
- 'load'),
+ m('i.material-icons', 'save')),
m('button',
{
- class: 'config-button delete',
+ class: 'config-button',
+ title: 'Remove configuration',
onclick: () => {
recordConfigStore.delete(item.key);
globals.rafScheduler.scheduleFullRedraw();
}
},
- 'delete'),
- ]);
- });
-}
+ m('i.material-icons', 'delete')),
+ ]));
+
+ const errorItems = [];
+ for (const extraKey of validated.extraKeys) {
+ errorItems.push(m('li', `${extraKey} is unrecognised`));
+ }
+ for (const invalidKey of validated.invalidKeys) {
+ errorItems.push(m('li', `${invalidKey} contained an invalid value`));
+ }
-function getSavedConfigList() {
- if (recordConfigStore.recordConfigs.length === 0) {
- return [];
+ if (errorItems.length > 0) {
+ configs.push(
+ m('.parsing-errors',
+ 'One or more errors have been found while loading configuration "' +
+ item.title + '". Loading is possible, but make sure to check ' +
+ 'the settings afterwards.',
+ m('ul', errorItems)));
+ }
}
- return displayRecordConfigs();
+ return configs;
}
export const ConfigTitleState = {
@@ -951,6 +1003,7 @@ export const ConfigTitleState = {
};
function Configurations(cssClass: string) {
+ const canSave = recordConfigStore.canSave(ConfigTitleState.getTitle());
return m(
`.record-section${cssClass}`,
m('header', 'Save and load configurations'),
@@ -961,11 +1014,15 @@ function Configurations(cssClass: string) {
placeholder: 'Title for config',
oninput() {
ConfigTitleState.setTitle(this.value);
+ globals.rafScheduler.scheduleFullRedraw();
}
}),
m('button',
{
- class: 'config-button save',
+ class: 'config-button',
+ disabled: !canSave,
+ title: canSave ? 'Save current config' :
+ 'Duplicate name, saving disabled',
onclick: () => {
recordConfigStore.save(
globals.state.recordConfig, ConfigTitleState.getTitle());
@@ -973,9 +1030,26 @@ function Configurations(cssClass: string) {
ConfigTitleState.clearTitle();
}
},
- 'Save current config')
+ m('i.material-icons', 'save')),
+ m('button',
+ {
+ class: 'config-button',
+ title: 'Clear current configuration',
+ onclick: () => {
+ if (confirm(
+ 'Current configuration will be cleared. ' +
+ 'Are you sure?')) {
+ globals.dispatch(Actions.setRecordConfig({
+ config: createEmptyRecordConfig(),
+ configType: {type: 'NONE'}
+ }));
+ globals.rafScheduler.scheduleFullRedraw();
+ }
+ }
+ },
+ m('i.material-icons', 'delete_forever'))
]),
- getSavedConfigList());
+ displayRecordConfigs());
}
function BufferUsageProgressBar() {
@@ -1115,12 +1189,6 @@ function getRecordCommand(target: RecordingTarget) {
const pbBase64 = data ? data.pbBase64 : '';
const pbtx = data ? data.pbtxt : '';
let cmd = '';
- if (cfg.screenRecord) {
- // Half-second delay to ensure Perfetto starts tracing before screenrecord
- // starts recording
- cmd += `(sleep 0.5 && adb shell screenrecord --time-limit ${time}`;
- cmd += ' "/sdcard/tracescr.mp4") &\\\n';
- }
if (isAndroidP(target)) {
cmd += `echo '${pbBase64}' | \n`;
cmd += 'base64 --decode | \n';
@@ -1180,8 +1248,9 @@ function StopCancelButtons() {
}
function onStartRecordingPressed() {
- location.href = '#!/record?p=instructions';
+ location.href = '#!/record/instructions';
globals.rafScheduler.scheduleFullRedraw();
+ autosaveConfigStore.save(globals.state.recordConfig);
const target = globals.state.recordingTarget;
if (isAndroidTarget(target) || isChromeTarget(target)) {
@@ -1297,13 +1366,65 @@ function selectAndroidDeviceIfAvailable(
function recordMenu(routePage: string) {
const target = globals.state.recordingTarget;
const chromeProbe =
- m('a[href="#!/record?p=chrome"]',
+ m('a[href="#!/record/chrome"]',
m(`li${routePage === 'chrome' ? '.active' : ''}`,
m('i.material-icons', 'laptop_chromebook'),
m('.title', 'Chrome'),
m('.sub', 'Chrome traces')));
+ const cpuProbe =
+ m('a[href="#!/record/cpu"]',
+ m(`li${routePage === 'cpu' ? '.active' : ''}`,
+ m('i.material-icons', 'subtitles'),
+ m('.title', 'CPU'),
+ m('.sub', 'CPU usage, scheduling, wakeups')));
+ const gpuProbe =
+ m('a[href="#!/record/gpu"]',
+ m(`li${routePage === 'gpu' ? '.active' : ''}`,
+ m('i.material-icons', 'aspect_ratio'),
+ m('.title', 'GPU'),
+ m('.sub', 'GPU frequency, memory')));
+ const powerProbe =
+ m('a[href="#!/record/power"]',
+ m(`li${routePage === 'power' ? '.active' : ''}`,
+ m('i.material-icons', 'battery_charging_full'),
+ m('.title', 'Power'),
+ m('.sub', 'Battery and other energy counters')));
+ const memoryProbe =
+ m('a[href="#!/record/memory"]',
+ m(`li${routePage === 'memory' ? '.active' : ''}`,
+ m('i.material-icons', 'memory'),
+ m('.title', 'Memory'),
+ m('.sub', 'Physical mem, VM, LMK')));
+ const androidProbe =
+ m('a[href="#!/record/android"]',
+ m(`li${routePage === 'android' ? '.active' : ''}`,
+ m('i.material-icons', 'android'),
+ m('.title', 'Android apps & svcs'),
+ m('.sub', 'atrace and logcat')));
+ const advancedProbe =
+ m('a[href="#!/record/advanced"]',
+ m(`li${routePage === 'advanced' ? '.active' : ''}`,
+ m('i.material-icons', 'settings'),
+ m('.title', 'Advanced settings'),
+ m('.sub', 'Complicated stuff for wizards')));
const recInProgress = globals.state.recordingInProgress;
+ const probes = [];
+ if (isCrOSTarget(target) || isLinuxTarget(target)) {
+ probes.push(cpuProbe, powerProbe, memoryProbe, chromeProbe, advancedProbe);
+ } else if (isChromeTarget(target)) {
+ probes.push(chromeProbe);
+ } else {
+ probes.push(
+ cpuProbe,
+ gpuProbe,
+ powerProbe,
+ memoryProbe,
+ androidProbe,
+ chromeProbe,
+ advancedProbe);
+ }
+
return m(
'.record-menu',
{
@@ -1312,68 +1433,35 @@ function recordMenu(routePage: string) {
},
m('header', 'Trace config'),
m('ul',
- m('a[href="#!/record?p=buffers"]',
+ m('a[href="#!/record/buffers"]',
m(`li${routePage === 'buffers' ? '.active' : ''}`,
m('i.material-icons', 'tune'),
m('.title', 'Recording settings'),
m('.sub', 'Buffer mode, size and duration'))),
- m('a[href="#!/record?p=instructions"]',
+ m('a[href="#!/record/instructions"]',
m(`li${routePage === 'instructions' ? '.active' : ''}`,
m('i.material-icons.rec', 'fiber_manual_record'),
m('.title', 'Recording command'),
m('.sub', 'Manually record trace'))),
- localStorage.hasOwnProperty(LOCAL_STORAGE_SHOW_CONFIG) ?
- m('a[href="#!/record?p=config"]',
+ PERSIST_CONFIG_FLAG.get() ?
+ m('a[href="#!/record/config"]',
{
onclick: () => {
recordConfigStore.reloadFromLocalStorage();
}
},
m(`li${routePage === 'config' ? '.active' : ''}`,
- m('i.material-icons', 'tune'),
+ m('i.material-icons', 'save'),
m('.title', 'Saved configs'),
m('.sub', 'Manage local configs'))) :
null),
m('header', 'Probes'),
- m('ul',
- isChromeTarget(target) && !isCrOSTarget(target) ? [chromeProbe] : [
- m('a[href="#!/record?p=cpu"]',
- m(`li${routePage === 'cpu' ? '.active' : ''}`,
- m('i.material-icons', 'subtitles'),
- m('.title', 'CPU'),
- m('.sub', 'CPU usage, scheduling, wakeups'))),
- m('a[href="#!/record?p=gpu"]',
- m(`li${routePage === 'gpu' ? '.active' : ''}`,
- m('i.material-icons', 'aspect_ratio'),
- m('.title', 'GPU'),
- m('.sub', 'GPU frequency, memory'))),
- m('a[href="#!/record?p=power"]',
- m(`li${routePage === 'power' ? '.active' : ''}`,
- m('i.material-icons', 'battery_charging_full'),
- m('.title', 'Power'),
- m('.sub', 'Battery and other energy counters'))),
- m('a[href="#!/record?p=memory"]',
- m(`li${routePage === 'memory' ? '.active' : ''}`,
- m('i.material-icons', 'memory'),
- m('.title', 'Memory'),
- m('.sub', 'Physical mem, VM, LMK'))),
- m('a[href="#!/record?p=android"]',
- m(`li${routePage === 'android' ? '.active' : ''}`,
- m('i.material-icons', 'android'),
- m('.title', 'Android apps & svcs'),
- m('.sub', 'atrace and logcat'))),
- chromeProbe,
- m('a[href="#!/record?p=advanced"]',
- m(`li${routePage === 'advanced' ? '.active' : ''}`,
- m('i.material-icons', 'settings'),
- m('.title', 'Advanced settings'),
- m('.sub', 'Complicated stuff for wizards')))
- ]));
+ m('ul', probes));
}
export const RecordPage = createPage({
- view() {
+ view({attrs}: m.Vnode<PageAttrs>) {
const SECTIONS: {[property: string]: (cssClass: string) => m.Child} = {
buffers: RecSettings,
instructions: Instructions,
@@ -1388,8 +1476,8 @@ export const RecordPage = createPage({
};
const pages: m.Children = [];
- const routePageParam = Router.param('p');
- let routePage = typeof routePageParam === 'string' ? routePageParam : '';
+ // we need to remove the `/` character from the route
+ let routePage = attrs.subpage ? attrs.subpage.substr(1) : '';
if (!Object.keys(SECTIONS).includes(routePage)) {
routePage = 'buffers';
}
diff --git a/ui/src/frontend/record_widgets.ts b/ui/src/frontend/record_widgets.ts
index b10708058..d175ea6e2 100644
--- a/ui/src/frontend/record_widgets.ts
+++ b/ui/src/frontend/record_widgets.ts
@@ -15,17 +15,20 @@
import {Draft, produce} from 'immer';
import * as m from 'mithril';
+import {assertExists} from '../base/logging';
import {Actions} from '../common/actions';
-import {RecordConfig} from '../common/state';
+import {RecordConfig} from '../controller/record_config_types';
import {copyToClipboard} from './clipboard';
import {globals} from './globals';
-import {assertExists} from '../base/logging';
-
declare type Setter<T> = (draft: Draft<RecordConfig>, val: T) => void;
declare type Getter<T> = (cfg: RecordConfig) => T;
+function defaultSort(a: string, b: string) {
+ return a.localeCompare(b);
+}
+
// +---------------------------------------------------------------------------+
// | Docs link with 'i' in circle icon. |
// +---------------------------------------------------------------------------+
@@ -51,6 +54,7 @@ class DocsChip implements m.ClassComponent<DocsChipAttrs> {
export interface ProbeAttrs {
title: string;
img: string|null;
+ compact?: boolean;
descr: m.Children;
isEnabled: Getter<boolean>;
setEnabled: Setter<boolean>;
@@ -68,7 +72,7 @@ export class Probe implements m.ClassComponent<ProbeAttrs> {
const enabled = attrs.isEnabled(globals.state.recordConfig);
return m(
- `.probe${enabled ? '.enabled' : ''}`,
+ `.probe${attrs.compact ? '.compact' : ''}${enabled ? '.enabled' : ''}`,
attrs.img && m('img', {
src: `${globals.root}assets/${attrs.img}`,
onclick: () => onToggle(!enabled),
@@ -81,10 +85,27 @@ export class Probe implements m.ClassComponent<ProbeAttrs> {
},
}),
m('span', attrs.title)),
- m('div', m('div', attrs.descr), m('.probe-config', children)));
+ attrs.compact ?
+ '' :
+ m('div', m('div', attrs.descr), m('.probe-config', children)));
}
}
+export function CompactProbe(args: {
+ title: string,
+ isEnabled: Getter<boolean>,
+ setEnabled: Setter<boolean>
+}) {
+ return m(Probe, {
+ title: args.title,
+ img: null,
+ compact: true,
+ descr: '',
+ isEnabled: args.isEnabled,
+ setEnabled: args.setEnabled
+ } as ProbeAttrs);
+}
+
// +-------------------------------------------------------------+
// | Toggle: an on/off switch.
// +-------------------------------------------------------------+
@@ -220,13 +241,14 @@ export interface DropdownAttrs {
title: string;
cssClass?: string;
options: Map<string, string>;
+ sort?: (a: string, b: string) => number;
get: Getter<string[]>;
set: Setter<string[]>;
}
export class Dropdown implements m.ClassComponent<DropdownAttrs> {
resetScroll(dom: HTMLSelectElement) {
- // Chrome seems to override the scroll offset on creation without this,
+ // Chrome seems to override the scroll offset on creationa, b without this,
// even though we call it after having marked the options as selected.
setTimeout(() => {
// Don't reset the scroll position if the element is still focused.
@@ -252,7 +274,8 @@ export class Dropdown implements m.ClassComponent<DropdownAttrs> {
const selItems = attrs.get(globals.state.recordConfig);
let numSelected = 0;
const entries = [...attrs.options.entries()];
- entries.sort((a, b) => a[1].localeCompare(b[1]));
+ const f = attrs.sort === undefined ? defaultSort : attrs.sort;
+ entries.sort((a, b) => f(a[1], b[1]));
for (const [key, label] of entries) {
const opts = {value: key, selected: false};
if (selItems.includes(key)) {
@@ -335,3 +358,74 @@ export class CodeSnippet implements m.ClassComponent<CodeSnippetAttrs> {
);
}
}
+
+
+interface CategoriesCheckboxListParams {
+ categories: Map<string, string>;
+ title: string;
+ get: Getter<string[]>;
+ set: Setter<string[]>;
+}
+
+export class CategoriesCheckboxList implements
+ m.ClassComponent<CategoriesCheckboxListParams> {
+ updateValue(
+ attrs: CategoriesCheckboxListParams, value: string, enabled: boolean) {
+ const traceCfg = produce(globals.state.recordConfig, draft => {
+ const values = attrs.get(draft);
+ const index = values.indexOf(value);
+ if (enabled && index === -1) {
+ values.push(value);
+ }
+ if (!enabled && index !== -1) {
+ values.splice(index, 1);
+ }
+ });
+ globals.dispatch(Actions.setRecordConfig({config: traceCfg}));
+ }
+
+ view({attrs}: m.CVnode<CategoriesCheckboxListParams>) {
+ const enabled = new Set(attrs.get(globals.state.recordConfig));
+ return m(
+ '.categories-list',
+ m('h3',
+ attrs.title,
+ m('button.config-button',
+ {
+ onclick: () => {
+ const config = produce(globals.state.recordConfig, draft => {
+ attrs.set(draft, Array.from(attrs.categories.keys()));
+ });
+ globals.dispatch(Actions.setRecordConfig({config}));
+ }
+ },
+ 'All'),
+ m('button.config-button',
+ {
+ onclick: () => {
+ const config = produce(globals.state.recordConfig, draft => {
+ attrs.set(draft, []);
+ });
+ globals.dispatch(Actions.setRecordConfig({config}));
+ },
+ },
+ 'None')),
+ m('ul.checkboxes',
+ Array.from(attrs.categories.entries()).map(([key, value]) => {
+ const id = `category-checkbox-${key}`;
+ return m(
+ 'label',
+ {'for': id},
+ m('li',
+ m('input[type=checkbox]', {
+ id,
+ checked: enabled.has(key),
+ onclick: (e: InputEvent) => {
+ const target = e.target as HTMLInputElement;
+ this.updateValue(attrs, key, target.checked);
+ }
+ }),
+ value));
+ })));
+ }
+}
diff --git a/ui/src/frontend/router.ts b/ui/src/frontend/router.ts
index 1c6a539d9..5a260c1aa 100644
--- a/ui/src/frontend/router.ts
+++ b/ui/src/frontend/router.ts
@@ -13,83 +13,207 @@
// limitations under the License.
import * as m from 'mithril';
+import {assertExists, assertTrue} from '../base/logging';
+import {PageAttrs} from './pages';
-import {Actions, DeferredAction} from '../common/actions';
-import {Analytics} from '../frontend/analytics';
+export const ROUTE_PREFIX = '#!';
+const DEFAULT_ROUTE = '/';
-interface RouteMap {
- [route: string]: m.Component;
+/*
+ * A broken down representation of a route.
+ * For instance: #!/record/gpu?local_cache_key=a0b1
+ * becomes: {page: '/record', subpage: '/gpu', args: {local_cache_key: 'a0b1'}}
+ */
+export interface Route {
+ page: string;
+ subpage: string;
+ args: RouteArgs;
}
-export const ROUTE_PREFIX = '#!';
+/*
+ * The set of args that can be set on the route via #!/page?a=1&b2.
+ * Route args are orthogonal to pages (i.e. should NOT make sense only in a
+ * only within a specific page, use /page/subpages for that).
+ * Args are !== the querystring (location.search) which is sent to the
+ * server. The route args are NOT sent to the HTTP server.
+ * Given this URL:
+ * http://host/?foo=1&bar=2#!/page/subpage?local_cache_key=a0b1&baz=3.
+ *
+ * location.search = 'foo=1&bar=2'.
+ * This is seen by the HTTP server. We really don't use querystrings as the
+ * perfetto UI is client only.
+ *
+ * location.hash = '#!/page/subpage?local_cache_key=a0b1'.
+ * This is client-only. All the routing logic in the Perfetto UI uses only
+ * this.
+ */
+export interface RouteArgs {
+ // The local_cache_key is special and is persisted across navigations.
+ local_cache_key?: string;
+
+ // These are transient and are really set only on startup.
+ openFromAndroidBugTool?: string;
+ s?: string; // For permalinks.
+ p?: string; // DEPRECATED: for #!/record?p=cpu subpages (b/191255021).
+ url?: string; // For fetching traces from Cloud Storage.
+}
+export interface RoutesMap {
+ [key: string]: m.Component<PageAttrs>;
+}
+
+/*
+ * This router does two things:
+ * 1) Maps fragment paths (#!/page/subpage) to Mithril components.
+ * The route map is passed to the ctor and is later used when calling the
+ * resolve() method.
+ *
+ * 2) Handles the (optional) args, e.g. #!/page?arg=1&arg2=2.
+ * Route args are carry information that is orthogonal to the page (e.g. the
+ * trace id).
+ * local_cache_key has some special treatment: once a URL has a local_cache_key,
+ * it gets automatically appended to further navigations that don't have one.
+ * For instance if the current url is #!/viewer?local_cache_key=1234 and a later
+ * action (either user-initiated or code-initited) navigates to #!/info, the
+ * rotuer will automatically replace the history entry with
+ * #!/info?local_cache_key=1234.
+ * This is to keep propagating the trace id across page changes, for handling
+ * tab discards (b/175041881).
+ *
+ * This class does NOT deal with the "load a trace when the url contains ?url=
+ * or ?local_cache_key=". That logic lives in trace_url_handler.ts, which is
+ * triggered by Router.onRouteChanged().
+ */
export class Router {
- constructor(
- private defaultRoute: string, private routes: RouteMap,
- private dispatch: (a: DeferredAction) => void,
- private logging: Analytics) {
- if (!(defaultRoute in routes)) {
- throw Error('routes must define a component for defaultRoute.');
- }
+ private readonly recentChanges: number[] = [];
+ private routes: RoutesMap;
+
+ // frontend/index.ts calls maybeOpenTraceFromRoute() + redraw here.
+ // This event is decoupled for testing and to avoid circular deps.
+ onRouteChanged: (route: Route) => (void) = () => {};
- window.onhashchange = () => this.navigateToCurrentHash();
+ constructor(routes: RoutesMap) {
+ assertExists(routes[DEFAULT_ROUTE]);
+ this.routes = routes;
+ window.onhashchange = (e: HashChangeEvent) => this.onHashChange(e);
}
- /**
- * Parses and returns the current route string from |window.location.hash|.
- * May return routes that are not defined in |this.routes|.
- */
- getRouteFromHash(): string {
- const prefixLength = ROUTE_PREFIX.length;
- const hash = window.location.hash;
+ private onHashChange(e: HashChangeEvent) {
+ this.crashIfLivelock();
+
+ const oldRoute = Router.parseUrl(e.oldURL);
+ const newRoute = Router.parseUrl(e.newURL);
- // Do not try to parse route if prefix doesn't match.
- if (hash.substring(0, prefixLength) !== ROUTE_PREFIX) return '';
+ if (newRoute.args.local_cache_key === undefined &&
+ oldRoute.args.local_cache_key) {
+ // Propagate `local_cache_key across` navigations. When a trace is loaded,
+ // the URL becomes #!/viewer?local_cache_key=123. `local_cache_key` allows
+ // reopening the trace from cache in the case of a reload or discard.
+ // When using the UI we can hit "bare" links (e.g. just '#!/info') which
+ // don't have the trace_uuid:
+ // - When clicking on an <a> element from the sidebar.
+ // - When the code calls Router.navigate().
+ // - When the user pastes a URL from docs page.
+ // In all these cases we want to keep propagating the `local_cache_key`.
+ // We do so by re-setting the `local_cache_key` and doing a
+ // location.replace which overwrites the history entry (note
+ // location.replace is NOT just a String.replace operation).
+ newRoute.args.local_cache_key = oldRoute.args.local_cache_key;
+ }
+
+ const args = m.buildQueryString(newRoute.args);
+ let normalizedFragment = `#!${newRoute.page}${newRoute.subpage}`;
+ normalizedFragment += args.length > 0 ? '?' + args : '';
+ if (!e.newURL.endsWith(normalizedFragment)) {
+ location.replace(normalizedFragment);
+ return;
+ }
- return hash.split('?')[0].substring(prefixLength);
+ this.onRouteChanged(newRoute);
}
/**
- * Sets |route| on |window.location.hash|. If |route| if not defined in
- * |this.routes|, dispatches a navigation to |this.defaultRoute|.
+ * Returns the component for the current route in the URL.
+ * If no route matches the URL, returns a component corresponding to
+ * |this.defaultRoute|.
*/
- setRouteOnHash(route: string) {
- history.pushState(undefined, "", ROUTE_PREFIX + route);
- this.logging.updatePath(route);
-
- if (!(route in this.routes)) {
- console.info(
- `Route ${route} not known redirecting to ${this.defaultRoute}.`);
- this.dispatch(Actions.navigate({route: this.defaultRoute}));
+ resolve(): m.Vnode<PageAttrs> {
+ const route = Router.parseFragment(location.hash);
+ let component = this.routes[route.page];
+ if (component === undefined) {
+ component = assertExists(this.routes[DEFAULT_ROUTE]);
}
+ return m(component, {subpage: route.subpage} as PageAttrs);
}
- /**
- * Dispatches navigation action to |this.getRouteFromHash()| if that is
- * defined in |this.routes|, otherwise to |this.defaultRoute|.
- */
- navigateToCurrentHash() {
- const hashRoute = this.getRouteFromHash();
- const newRoute = hashRoute in this.routes ? hashRoute : this.defaultRoute;
- this.dispatch(Actions.navigate({route: newRoute}));
- // TODO(dproy): Handle case when new route has a permalink.
+ static navigate(newHash: string) {
+ assertTrue(newHash.startsWith(ROUTE_PREFIX));
+ window.location.hash = newHash;
}
- /**
- * Returns the component for given |route|. If |route| is not defined, returns
- * component of |this.defaultRoute|.
+ /*
+ * Breaks down a fragment into a Route object.
+ * Sample input:
+ * '#!/record/gpu?local_cache_key=abcd-1234'
+ * Sample output:
+ * {page: '/record', subpage: '/gpu', args: {local_cache_key: 'abcd-1234'}}
*/
- resolve(route: string|null): m.Component {
- if (!route || !(route in this.routes)) {
- return this.routes[this.defaultRoute];
+ static parseFragment(hash: string): Route {
+ const prefixLength = ROUTE_PREFIX.length;
+ let route = '';
+ if (hash.startsWith(ROUTE_PREFIX)) {
+ route = hash.substr(prefixLength).split('?')[0];
+ }
+
+ let page = route;
+ let subpage = '';
+ const splittingPoint = route.indexOf('/', 1);
+ if (splittingPoint > 0) {
+ page = route.substr(0, splittingPoint);
+ subpage = route.substr(splittingPoint);
+ }
+
+ const argsStart = hash.indexOf('?');
+ const argsStr = argsStart < 0 ? '' : hash.substr(argsStart + 1);
+ const args = argsStr ? m.parseQueryString(hash.substr(argsStart)) : {};
+
+ // TODO(primiano): remove this in mid-2022. trace_id is the same concept of
+ // local_cache_key. Just at some point we renamed it to make it more obvious
+ // to people that those URLs cannot be copy-pasted in bugs. For now this
+ // handles cases of reloading pages from old version.
+ if ('trace_id' in args) {
+ if (!('local_cache_key' in args)) {
+ args['local_cache_key'] = args['trace_id'];
+ }
+ delete args['trace_id'];
}
- return this.routes[route];
+
+ return {page, subpage, args};
+ }
+
+ /*
+ * Like parseFragment() but takes a full URL.
+ */
+ static parseUrl(url: string): Route {
+ const hashPos = url.indexOf('#');
+ const fragment = hashPos < 0 ? '' : url.substr(hashPos);
+ return Router.parseFragment(fragment);
}
- static param(key: string) {
- const hash = window.location.hash;
- const paramStart = hash.indexOf('?');
- if (paramStart === -1) return undefined;
- return m.parseQueryString(hash.substring(paramStart))[key];
+ /*
+ * Throws if EVENT_LIMIT onhashchange events occur within WINDOW_MS.
+ */
+ private crashIfLivelock() {
+ const WINDOW_MS = 1000;
+ const EVENT_LIMIT = 20;
+ const now = Date.now();
+ while (this.recentChanges.length > 0 &&
+ now - this.recentChanges[0] > WINDOW_MS) {
+ this.recentChanges.shift();
+ }
+ this.recentChanges.push(now);
+ if (this.recentChanges.length > EVENT_LIMIT) {
+ throw new Error('History rewriting livelock');
+ }
}
}
diff --git a/ui/src/frontend/router_jsdomtest.ts b/ui/src/frontend/router_jsdomtest.ts
deleted file mode 100644
index 0d77e5bf9..000000000
--- a/ui/src/frontend/router_jsdomtest.ts
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import {dingus} from 'dingusjs';
-
-import {Actions, DeferredAction} from '../common/actions';
-
-import {NullAnalytics} from './analytics';
-import {Router} from './router';
-
-const mockComponent = {
- view() {}
-};
-
-const fakeDispatch = () => {};
-
-const mockLogging = new NullAnalytics();
-
-beforeEach(() => {
- window.onhashchange = null;
- window.location.hash = '';
-});
-
-test('Default route must be defined', () => {
- expect(
- () => new Router('/a', {'/b': mockComponent}, fakeDispatch, mockLogging))
- .toThrow();
-});
-
-test('Resolves empty route to default component', () => {
- const router =
- new Router('/a', {'/a': mockComponent}, fakeDispatch, mockLogging);
- expect(router.resolve('')).toBe(mockComponent);
- expect(router.resolve(null)).toBe(mockComponent);
-});
-
-test('Parse route from hash', () => {
- const router =
- new Router('/', {'/': mockComponent}, fakeDispatch, mockLogging);
- window.location.hash = '#!/foobar?s=42';
- expect(router.getRouteFromHash()).toBe('/foobar');
-
- window.location.hash = '/foobar'; // Invalid prefix.
- expect(router.getRouteFromHash()).toBe('');
-});
-
-test('Set valid route on hash', () => {
- const dispatch = dingus<(a: DeferredAction) => void>();
- const router = new Router(
- '/',
- {
- '/': mockComponent,
- '/a': mockComponent,
- },
- dispatch,
- mockLogging);
- const prevHistoryLength = window.history.length;
-
- router.setRouteOnHash('/a');
- expect(window.location.hash).toBe('#!/a');
- expect(window.history.length).toBe(prevHistoryLength + 1);
- // No navigation action should be dispatched.
- expect(dispatch.calls.length).toBe(0);
-});
-
-test('Redirects to default for invalid route in setRouteOnHash ', () => {
- const dispatch = dingus<(a: DeferredAction) => void>();
- // const dispatch = () => {console.log("action received")};
-
- const router = new Router('/', {'/': mockComponent}, dispatch, mockLogging);
- router.setRouteOnHash('foo');
- expect(dispatch.calls.length).toBe(1);
- expect(dispatch.calls[0][1].length).toBeGreaterThanOrEqual(1);
- expect(dispatch.calls[0][1][0]).toEqual(Actions.navigate({route: '/'}));
-});
-
-test('Navigate on hash change', done => {
- const mockDispatch = (a: DeferredAction) => {
- expect(a).toEqual(Actions.navigate({route: '/viewer'}));
- done();
- };
- new Router(
- '/',
- {
- '/': mockComponent,
- '/viewer': mockComponent,
- },
- mockDispatch,
- mockLogging);
- window.location.hash = '#!/viewer';
-});
-
-test('Redirects to default when invalid route set in window location', done => {
- const mockDispatch = (a: DeferredAction) => {
- expect(a).toEqual(Actions.navigate({route: '/'}));
- done();
- };
-
- new Router(
- '/',
- {
- '/': mockComponent,
- '/viewer': mockComponent,
- },
- mockDispatch,
- mockLogging);
-
- window.location.hash = '#invalid';
-});
-
-test('navigateToCurrentHash with valid current route', () => {
- const dispatch = dingus<(a: DeferredAction) => void>();
- window.location.hash = '#!/b';
- const router = new Router(
- '/', {'/': mockComponent, '/b': mockComponent}, dispatch, mockLogging);
- router.navigateToCurrentHash();
- expect(dispatch.calls[0][1][0]).toEqual(Actions.navigate({route: '/b'}));
-});
-
-test('navigateToCurrentHash with invalid current route', () => {
- const dispatch = dingus<(a: DeferredAction) => void>();
- window.location.hash = '#!/invalid';
- const router = new Router('/', {'/': mockComponent}, dispatch, mockLogging);
- router.navigateToCurrentHash();
- expect(dispatch.calls[0][1][0]).toEqual(Actions.navigate({route: '/'}));
-});
-
-test('Params parsing', () => {
- window.location.hash = '#!/foo?a=123&b=42&c=a?b?c';
- expect(Router.param('a')).toBe('123');
- expect(Router.param('b')).toBe('42');
- expect(Router.param('c')).toBe('a?b?c');
-});
diff --git a/ui/src/frontend/router_unittest.ts b/ui/src/frontend/router_unittest.ts
new file mode 100644
index 000000000..28bf10746
--- /dev/null
+++ b/ui/src/frontend/router_unittest.ts
@@ -0,0 +1,106 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {Router} from './router';
+
+const mockComponent = {
+ view() {}
+};
+
+beforeEach(() => {
+ window.location.hash = '';
+});
+
+test('Default route must be defined', () => {
+ expect(() => new Router({'/a': mockComponent})).toThrow();
+});
+
+test('Resolves empty route to default component', () => {
+ const router = new Router({'/': mockComponent});
+ window.location.hash = '';
+ expect(router.resolve().tag).toBe(mockComponent);
+});
+
+test('Resolves subpage route to component of main page', () => {
+ const nonDefaultComponent = {view() {}};
+ const router = new Router({
+ '/': mockComponent,
+ '/a': nonDefaultComponent,
+ });
+ window.location.hash = '#!/a/subpage';
+ expect(router.resolve().tag).toBe(nonDefaultComponent);
+ expect(router.resolve().attrs.subpage).toBe('/subpage');
+});
+
+test('Pass empty subpage if not found in URL', () => {
+ const nonDefaultComponent = {view() {}};
+ const router = new Router({
+ '/': mockComponent,
+ '/a': nonDefaultComponent,
+ });
+ window.location.hash = '#!/a';
+ expect(router.resolve().tag).toBe(nonDefaultComponent);
+ expect(router.resolve().attrs.subpage).toBe('');
+});
+
+test('Args parsing', () => {
+ const url = 'http://localhost/#!/foo?p=123&s=42&url=a?b?c';
+ const args = Router.parseUrl(url).args;
+ expect(args.p).toBe('123');
+ expect(args.s).toBe('42');
+ expect(args.url).toBe('a?b?c');
+});
+
+test('empty route broken into empty components', () => {
+ const {page, subpage, args} = Router.parseFragment('');
+ expect(page).toBe('');
+ expect(subpage).toBe('');
+ expect(args).toEqual({});
+});
+
+test('invalid route broken into empty components', () => {
+ const {page, subpage, args} = Router.parseFragment('/bla');
+ expect(page).toBe('');
+ expect(subpage).toBe('');
+ expect(args).toEqual({});
+});
+
+test('simple route has page defined', () => {
+ const {page, subpage, args} = Router.parseFragment('#!/record');
+ expect(page).toBe('/record');
+ expect(subpage).toBe('');
+ expect(args).toEqual({});
+});
+
+test('simple route has both components defined', () => {
+ const {page, subpage, args} = Router.parseFragment('#!/record/memory');
+ expect(page).toBe('/record');
+ expect(subpage).toBe('/memory');
+ expect(args).toEqual({});
+});
+
+test('route broken at first slash', () => {
+ const {page, subpage, args} = Router.parseFragment('#!/record/memory/stuff');
+ expect(page).toBe('/record');
+ expect(subpage).toBe('/memory/stuff');
+ expect(args).toEqual({});
+});
+
+test('parameters separated from route', () => {
+ const {page, subpage, args} =
+ Router.parseFragment('#!/record/memory?url=http://localhost:1234/aaaa');
+ expect(page).toBe('/record');
+ expect(subpage).toBe('/memory');
+ expect(args).toEqual({url: 'http://localhost:1234/aaaa'});
+});
diff --git a/ui/src/frontend/rpc_http_dialog.ts b/ui/src/frontend/rpc_http_dialog.ts
index 40e903628..30a25b385 100644
--- a/ui/src/frontend/rpc_http_dialog.ts
+++ b/ui/src/frontend/rpc_http_dialog.ts
@@ -12,15 +12,21 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import '../tracks/all_frontend';
import * as m from 'mithril';
+import {assertExists} from '../base/logging';
import {Actions} from '../common/actions';
import {HttpRpcEngine, RPC_URL} from '../common/http_rpc_engine';
+import {StatusResult} from '../common/protos';
+import * as version from '../gen/perfetto_version';
+import {perfetto} from '../gen/protos';
import {globals} from './globals';
import {showModal} from './modal';
+const CURRENT_API_VERSION = perfetto.protos.TraceProcessorApiVersion
+ .TRACE_PROCESSOR_CURRENT_API_VERSION;
+
const PROMPT = `Trace Processor Native Accelerator detected on ${RPC_URL} with:
$loadedTraceName
@@ -43,6 +49,28 @@ Using the native accelerator has some minor caveats:
too old. Get the latest version from get.perfetto.dev/trace_processor.
`;
+
+const MSG_TOO_OLD = `The Trace Processor instance on ${RPC_URL} is too old.
+
+This UI requires TraceProcessor features that are not present in the
+Trace Processor native accelerator you are currently running.
+If you continue, this is almost surely going to cause UI failures.
+
+Please update your local Trace Processor binary:
+
+curl -LO https://get.perfetto.dev/trace_processor
+chmod +x ./trace_processor
+./trace_processor --httpd
+
+UI version: ${version.VERSION}
+TraceProcessor RPC API required: ${CURRENT_API_VERSION} or higher
+
+TraceProcessor version: $tpVersion
+RPC API: $tpApi
+`;
+
+let forceUseOldVersion = false;
+
// Try to connect to the external Trace Processor HTTP RPC accelerator (if
// available, often it isn't). If connected it will populate the
// |httpRpcState| in the frontend local state. In turn that will show the UI
@@ -53,41 +81,81 @@ too old. Get the latest version from get.perfetto.dev/trace_processor.
export async function CheckHttpRpcConnection(): Promise<void> {
const state = await HttpRpcEngine.checkConnection();
globals.frontendLocalState.setHttpRpcState(state);
+ if (!state.connected) return;
+ const tpStatus = assertExists(state.status);
+
+ if (tpStatus.apiVersion < CURRENT_API_VERSION) {
+ await showDialogTraceProcessorTooOld(tpStatus);
+ if (!forceUseOldVersion) return;
+ }
- // If a trace is already loaded in the trace processor (e.g., the user
- // launched trace_processor_shell -D trace_file.pftrace), prompt the user to
- // initialize the UI with the already-loaded trace.
- if (state.connected && state.loadedTraceName) {
- showModal({
- title: 'Use Trace Processor Native Acceleration?',
- content:
- m('.modal-pre',
- PROMPT.replace('$loadedTraceName', state.loadedTraceName)),
- buttons: [
- {
- text: 'YES, use loaded trace',
- primary: true,
- id: 'rpc_load',
- action: () => {
- globals.dispatch(Actions.openTraceFromHttpRpc({}));
- }
- },
- {
- text: 'YES, but reset state',
- primary: false,
- id: 'rpc_reset',
- action: () => {}
- },
- {
- text: 'NO, Use builtin WASM',
- primary: false,
- id: 'rpc_force_wasm',
- action: () => {
- globals.dispatch(
- Actions.setNewEngineMode({mode: 'FORCE_BUILTIN_WASM'}));
- }
- },
- ],
- });
+ if (tpStatus.loadedTraceName) {
+ // If a trace is already loaded in the trace processor (e.g., the user
+ // launched trace_processor_shell -D trace_file.pftrace), prompt the user to
+ // initialize the UI with the already-loaded trace.
+ return showDialogToUsePreloadedTrace(tpStatus);
}
}
+
+async function showDialogTraceProcessorTooOld(tpStatus: StatusResult) {
+ return showModal({
+ title: 'Your Trace Processor binary is outdated',
+ content:
+ m('.modal-pre',
+ MSG_TOO_OLD.replace('$tpVersion', tpStatus.humanReadableVersion)
+ .replace('$tpApi', `${tpStatus.apiVersion}`)),
+ buttons: [
+ {
+ text: 'Use builtin Wasm',
+ primary: true,
+ id: 'tp_old_wasm',
+ action: () => {
+ globals.dispatch(
+ Actions.setNewEngineMode({mode: 'FORCE_BUILTIN_WASM'}));
+ }
+ },
+ {
+ text: 'Use old version regardless (might crash)',
+ primary: false,
+ id: 'tp_old_cont',
+ action: () => {
+ forceUseOldVersion = true;
+ }
+ },
+ ],
+ });
+}
+
+async function showDialogToUsePreloadedTrace(tpStatus: StatusResult) {
+ return showModal({
+ title: 'Use Trace Processor Native Acceleration?',
+ content:
+ m('.modal-pre',
+ PROMPT.replace('$loadedTraceName', tpStatus.loadedTraceName)),
+ buttons: [
+ {
+ text: 'YES, use loaded trace',
+ primary: true,
+ id: 'rpc_load',
+ action: () => {
+ globals.dispatch(Actions.openTraceFromHttpRpc({}));
+ }
+ },
+ {
+ text: 'YES, but reset state',
+ primary: false,
+ id: 'rpc_reset',
+ action: () => {}
+ },
+ {
+ text: 'NO, Use builtin Wasm',
+ primary: false,
+ id: 'rpc_force_wasm',
+ action: () => {
+ globals.dispatch(
+ Actions.setNewEngineMode({mode: 'FORCE_BUILTIN_WASM'}));
+ }
+ },
+ ],
+ });
+}
diff --git a/ui/src/frontend/scroll_helper.ts b/ui/src/frontend/scroll_helper.ts
index be24399d5..3db08a728 100644
--- a/ui/src/frontend/scroll_helper.ts
+++ b/ui/src/frontend/scroll_helper.ts
@@ -107,21 +107,3 @@ export function scrollToTrackAndTs(
}
horizontalScrollToTs(ts);
}
-
-/**
- * Returns the UI track Id that is associated with the given |traceTrackId| in
- * the trace_processor. Due to concepts like Async tracks and TrackGroups this
- * is not always a one to one mapping.
- */
-export function findUiTrackId(traceTrackId: number) {
- for (const [uiTrackId, trackState] of Object.entries(globals.state.tracks)) {
- const config = trackState.config as {trackId: number};
- if (config.trackId === traceTrackId) return uiTrackId;
- const multiple = trackState.config as {trackIds: number[]};
- if (multiple.trackIds !== undefined &&
- multiple.trackIds.includes(traceTrackId)) {
- return uiTrackId;
- }
- }
- return null;
-}
diff --git a/ui/src/frontend/search_handler.ts b/ui/src/frontend/search_handler.ts
index cfdc2599e..1655c69d0 100644
--- a/ui/src/frontend/search_handler.ts
+++ b/ui/src/frontend/search_handler.ts
@@ -20,17 +20,18 @@ import {globals} from './globals';
import {scrollToTrackAndTs} from './scroll_helper';
function setToPrevious(current: number) {
- globals.frontendLocalState.setSearchIndex(Math.max(current - 1, 0));
+ const index = Math.max(current - 1, 0);
+ globals.dispatch(Actions.setSearchIndex({index}));
}
function setToNext(current: number) {
- globals.frontendLocalState.setSearchIndex(
- Math.min(current + 1, globals.currentSearchResults.totalResults - 1));
+ const index =
+ Math.min(current + 1, globals.currentSearchResults.totalResults - 1);
+ globals.dispatch(Actions.setSearchIndex({index}));
}
export function executeSearch(reverse = false) {
- const state = globals.frontendLocalState;
- const index = state.searchIndex;
+ const index = globals.state.searchIndex;
const startNs = toNs(globals.frontendLocalState.visibleWindowTime.start);
const endNs = toNs(globals.frontendLocalState.visibleWindowTime.end);
const currentTs = globals.currentSearchResults.tsStarts[index];
@@ -42,14 +43,20 @@ export function executeSearch(reverse = false) {
const [smaller,] =
searchSegment(globals.currentSearchResults.tsStarts, endNs);
// If there is no item in the viewport just go to the previous.
- smaller === -1 ? setToPrevious(index) :
- globals.frontendLocalState.setSearchIndex(smaller);
+ if (smaller === -1) {
+ setToPrevious(index);
+ } else {
+ globals.dispatch(Actions.setSearchIndex({index: smaller}));
+ }
} else {
const [, larger] =
searchSegment(globals.currentSearchResults.tsStarts, startNs);
// If there is no item in the viewport just go to the next.
- larger === -1 ? setToNext(index) :
- globals.frontendLocalState.setSearchIndex(larger);
+ if (larger === -1) {
+ setToNext(index);
+ } else {
+ globals.dispatch(Actions.setSearchIndex({index: larger}));
+ }
}
} else {
// If the currentTs is in the viewport, increment the index.
@@ -72,7 +79,7 @@ export function executeSearch(reverse = false) {
}
function moveViewportToCurrentSearch() {
- const searchIndex = globals.frontendLocalState.searchIndex;
+ const searchIndex = globals.state.searchIndex;
if (searchIndex === -1) return;
const currentTs = globals.currentSearchResults.tsStarts[searchIndex];
const trackId = globals.currentSearchResults.trackIds[searchIndex];
@@ -80,8 +87,7 @@ function moveViewportToCurrentSearch() {
}
function selectCurrentSearchResult() {
- const state = globals.frontendLocalState;
- const searchIndex = state.searchIndex;
+ const searchIndex = globals.state.searchIndex;
const source = globals.currentSearchResults.sources[searchIndex];
const currentId = globals.currentSearchResults.sliceIds[searchIndex];
const trackId = globals.currentSearchResults.trackIds[searchIndex];
diff --git a/ui/src/frontend/service_worker_controller.ts b/ui/src/frontend/service_worker_controller.ts
index bc11ee33c..66abfc976 100644
--- a/ui/src/frontend/service_worker_controller.ts
+++ b/ui/src/frontend/service_worker_controller.ts
@@ -43,6 +43,9 @@ export class ServiceWorkerController {
}
} else {
await caches.delete(BYPASS_ID);
+ if (window.localStorage) {
+ window.localStorage.setItem('bypassDisabled', '1');
+ }
this.install();
}
globals.rafScheduler.scheduleFullRedraw();
@@ -81,6 +84,16 @@ export class ServiceWorkerController {
return;
}
+ // If this is localhost disable the service worker by default, unless the
+ // user manually re-enabled it (in which case bypassDisabled = '1').
+ const hostname = location.hostname;
+ const isLocalhost = ['127.0.0.1', '::1', 'localhost'].includes(hostname);
+ const bypassDisabled = window.localStorage &&
+ window.localStorage.getItem('bypassDisabled') === '1';
+ if (isLocalhost && !bypassDisabled) {
+ await this.setBypass(true); // Will cause the check below to bail out.
+ }
+
if (await caches.has(BYPASS_ID)) {
this._bypassed = true;
console.log('Skipping service worker registration, disabled by the user');
diff --git a/ui/src/frontend/sidebar.ts b/ui/src/frontend/sidebar.ts
index b9f8d0fcb..653ee6119 100644
--- a/ui/src/frontend/sidebar.ts
+++ b/ui/src/frontend/sidebar.ts
@@ -16,13 +16,14 @@ import * as m from 'mithril';
import {assertExists, assertTrue} from '../base/logging';
import {Actions} from '../common/actions';
+import {getCurrentChannel} from '../common/channels';
import {TRACE_SUFFIX} from '../common/constants';
-import {QueryResponse} from '../common/queries';
+import {ConversionJobStatus} from '../common/conversion_jobs';
import {EngineMode, TraceArrayBufferSource} from '../common/state';
import * as version from '../gen/perfetto_version';
import {Animation} from './animation';
-import {copyToClipboard} from './clipboard';
+import {onClickCopy} from './clipboard';
import {globals} from './globals';
import {toggleHelp} from './help_modal';
import {
@@ -30,7 +31,13 @@ import {
openFileWithLegacyTraceViewer,
} from './legacy_trace_viewer';
import {showModal} from './modal';
+import {Router} from './router';
import {isDownloadable, isShareable} from './trace_attrs';
+import {
+ convertToJson,
+ convertTraceToJsonAndDownload,
+ convertTraceToSystraceAndDownload
+} from './trace_converter';
const ALL_PROCESSES_QUERY = 'select name, pid from process order by name;';
@@ -93,11 +100,13 @@ const SQL_STATS = `
with first as (select started as ts from sqlstats limit 1)
select query,
round((max(ended - started, 0))/1e6) as runtime_ms,
- round((max(started - queued, 0))/1e6) as latency_ms,
round((started - first.ts)/1e6) as t_start_ms
from sqlstats, first
order by started desc`;
+const GITILES_URL =
+ 'https://android.googlesource.com/platform/external/perfetto';
+
let lastTabTitle = '';
function createCannedQuery(query: string): (_: Event) => void {
@@ -127,7 +136,27 @@ const EXAMPLE_ANDROID_TRACE_URL =
const EXAMPLE_CHROME_TRACE_URL =
'https://storage.googleapis.com/perfetto-misc/example_chrome_trace_4s_1.json';
-const SECTIONS = [
+interface SectionItem {
+ t: string;
+ a: string|((e: Event) => void);
+ i: string;
+ isPending?: () => boolean;
+ isVisible?: () => boolean;
+ internalUserOnly?: boolean;
+ checkDownloadDisabled?: boolean;
+}
+
+interface Section {
+ title: string;
+ summary: string;
+ items: SectionItem[];
+ expanded?: boolean;
+ hideIfNoTraceLoaded?: boolean;
+ appendOpenedTraceTitle?: boolean;
+}
+
+const SECTIONS: Section[] = [
+
{
title: 'Navigation',
summary: 'Open or record a new trace',
@@ -142,6 +171,7 @@ const SECTIONS = [
{t: 'Record new trace', a: navigateRecord, i: 'fiber_smart_record'},
],
},
+
{
title: 'Current Trace',
summary: 'Actions on the current trace',
@@ -155,6 +185,8 @@ const SECTIONS = [
a: shareTrace,
i: 'share',
internalUserOnly: true,
+ isPending: () => globals.getConversionJobStatus('create_permalink') ===
+ ConversionJobStatus.InProgress,
},
{
t: 'Download',
@@ -162,12 +194,47 @@ const SECTIONS = [
i: 'file_download',
checkDownloadDisabled: true,
},
- {t: 'Legacy UI', a: openCurrentTraceWithOldUI, i: 'filter_none'},
{t: 'Query (SQL)', a: navigateAnalyze, i: 'control_camera'},
{t: 'Metrics', a: navigateMetrics, i: 'speed'},
{t: 'Info and stats', a: navigateInfo, i: 'info'},
],
},
+
+ {
+ title: 'Convert trace',
+ summary: 'Convert to other formats',
+ expanded: true,
+ hideIfNoTraceLoaded: true,
+ items: [
+ {
+ t: 'Switch to legacy UI',
+ a: openCurrentTraceWithOldUI,
+ i: 'filter_none',
+ isPending: () => globals.getConversionJobStatus('open_in_legacy') ===
+ ConversionJobStatus.InProgress,
+ },
+ {
+ t: 'Convert to .json',
+ a: convertTraceToJson,
+ i: 'file_download',
+ isPending: () => globals.getConversionJobStatus('convert_json') ===
+ ConversionJobStatus.InProgress,
+ checkDownloadDisabled: true,
+ },
+
+ {
+ t: 'Convert to .systrace',
+ a: convertTraceToSystrace,
+ i: 'file_download',
+ isVisible: () => globals.hasFtrace,
+ isPending: () => globals.getConversionJobStatus('convert_systrace') ===
+ ConversionJobStatus.InProgress,
+ checkDownloadDisabled: true,
+ },
+
+ ],
+ },
+
{
title: 'Example Traces',
expanded: true,
@@ -185,158 +252,173 @@ const SECTIONS = [
},
],
},
+
{
- title: 'Sample queries',
- summary: 'Compute summary statistics',
+ title: 'Support',
+ expanded: true,
+ summary: 'Documentation & Bugs',
items: [
+ {t: 'Keyboard shortcuts', a: openHelp, i: 'help'},
+ {t: 'Documentation', a: 'https://perfetto.dev', i: 'find_in_page'},
+ {t: 'Flags', a: navigateFlags, i: 'emoji_flags'},
{
- t: 'Show Debug Track',
- a: showDebugTrack(),
- i: 'view_day',
+ t: 'Report a bug',
+ a: 'https://goto.google.com/perfetto-ui-bug',
+ i: 'bug_report'
},
+ ],
+ },
+
+ {
+ title: 'Sample queries',
+ summary: 'Compute summary statistics',
+ items: [
+ {t: 'Show Debug Track', a: showDebugTrack(), i: 'view_day'},
{
t: 'All Processes',
a: createCannedQuery(ALL_PROCESSES_QUERY),
- i: 'search',
+ i: 'search'
},
{
t: 'CPU Time by process',
a: createCannedQuery(CPU_TIME_FOR_PROCESSES),
- i: 'search',
+ i: 'search'
},
{
t: 'Cycles by p-state by CPU',
a: createCannedQuery(CYCLES_PER_P_STATE_PER_CPU),
- i: 'search',
+ i: 'search'
},
{
t: 'CPU Time by CPU by process',
a: createCannedQuery(CPU_TIME_BY_CPU_BY_PROCESS),
- i: 'search',
+ i: 'search'
},
{
t: 'Heap Graph: Bytes per type',
a: createCannedQuery(HEAP_GRAPH_BYTES_PER_TYPE),
- i: 'search',
+ i: 'search'
},
{
t: 'Debug SQL performance',
a: createCannedQuery(SQL_STATS),
- i: 'bug_report',
- },
- ],
- },
- {
- title: 'Support',
- summary: 'Documentation & Bugs',
- items: [
- {
- t: 'Controls',
- a: openHelp,
- i: 'help',
- },
- {
- t: 'Documentation',
- a: 'https://perfetto.dev',
- i: 'find_in_page',
- },
- {
- t: 'Report a bug',
- a: 'https://goto.google.com/perfetto-ui-bug',
- i: 'bug_report',
+ i: 'bug_report'
},
],
},
];
-const vidSection = {
- title: 'Video',
- summary: 'Open a screen recording',
- expanded: true,
- items: [
- {t: 'Open video file', a: popupVideoSelectionDialog, i: 'folder_open'},
- ],
-};
-
function openHelp(e: Event) {
e.preventDefault();
toggleHelp();
}
function getFileElement(): HTMLInputElement {
- return document.querySelector('input[type=file]')! as HTMLInputElement;
+ return assertExists(
+ document.querySelector<HTMLInputElement>('input[type=file]'));
}
function popupFileSelectionDialog(e: Event) {
e.preventDefault();
delete getFileElement().dataset['useCatapultLegacyUi'];
- delete getFileElement().dataset['video'];
getFileElement().click();
}
function popupFileSelectionDialogOldUI(e: Event) {
e.preventDefault();
- delete getFileElement().dataset['video'];
getFileElement().dataset['useCatapultLegacyUi'] = '1';
getFileElement().click();
}
-function openCurrentTraceWithOldUI(e: Event) {
- e.preventDefault();
- console.assert(isTraceLoaded());
- globals.logging.logEvent('Trace Actions', 'Open current trace in legacy UI');
- if (!isTraceLoaded) return;
- const engine = Object.values(globals.state.engines)[0];
+function downloadTraceFromUrl(url: string): Promise<File> {
+ return m.request({
+ method: 'GET',
+ url,
+ // TODO(hjd): Once mithril is updated we can use responseType here rather
+ // than using config and remove the extract below.
+ config: xhr => {
+ xhr.responseType = 'blob';
+ xhr.onprogress = progress => {
+ const percent = (100 * progress.loaded / progress.total).toFixed(1);
+ globals.dispatch(Actions.updateStatus({
+ msg: `Downloading trace ${percent}%`,
+ timestamp: Date.now() / 1000,
+ }));
+ };
+ },
+ extract: xhr => {
+ return xhr.response;
+ }
+ });
+}
+
+export async function getCurrentTrace(): Promise<Blob> {
+ // Caller must check engine exists.
+ const engine = assertExists(Object.values(globals.state.engines)[0]);
const src = engine.source;
if (src.type === 'ARRAY_BUFFER') {
- openInOldUIWithSizeCheck(new Blob([src.buffer]));
+ return new Blob([src.buffer]);
} else if (src.type === 'FILE') {
- openInOldUIWithSizeCheck(src.file);
+ return src.file;
} else if (src.type === 'URL') {
- m.request({
- method: 'GET',
- url: src.url,
- // TODO(hjd): Once mithril is updated we can use responseType here rather
- // than using config and remove the extract below.
- config: xhr => {
- xhr.responseType = 'blob';
- xhr.onprogress = progress => {
- const percent = (100 * progress.loaded / progress.total).toFixed(1);
- globals.dispatch(Actions.updateStatus({
- msg: `Downloading trace ${percent}%`,
- timestamp: Date.now() / 1000,
- }));
- };
- },
- extract: xhr => {
- return xhr.response;
- }
- }).then(result => {
- openInOldUIWithSizeCheck(result as Blob);
- });
+ return downloadTraceFromUrl(src.url);
} else {
throw new Error(`Loading to catapult from source with type ${src.type}`);
}
}
-function isTraceLoaded(): boolean {
- const engine = Object.values(globals.state.engines)[0];
- return engine !== undefined;
+function openCurrentTraceWithOldUI(e: Event) {
+ e.preventDefault();
+ assertTrue(isTraceLoaded());
+ globals.logging.logEvent('Trace Actions', 'Open current trace in legacy UI');
+ if (!isTraceLoaded) return;
+ getCurrentTrace()
+ .then(file => {
+ openInOldUIWithSizeCheck(file);
+ })
+ .catch(error => {
+ throw new Error(`Failed to get current trace ${error}`);
+ });
}
-function popupVideoSelectionDialog(e: Event) {
+function convertTraceToSystrace(e: Event) {
e.preventDefault();
- delete getFileElement().dataset['useCatapultLegacyUi'];
- getFileElement().dataset['video'] = '1';
- getFileElement().click();
+ assertTrue(isTraceLoaded());
+ globals.logging.logEvent('Trace Actions', 'Convert to .systrace');
+ if (!isTraceLoaded) return;
+ getCurrentTrace()
+ .then(file => {
+ convertTraceToSystraceAndDownload(file);
+ })
+ .catch(error => {
+ throw new Error(`Failed to get current trace ${error}`);
+ });
+}
+
+function convertTraceToJson(e: Event) {
+ e.preventDefault();
+ assertTrue(isTraceLoaded());
+ globals.logging.logEvent('Trace Actions', 'Convert to .json');
+ if (!isTraceLoaded) return;
+ getCurrentTrace()
+ .then(file => {
+ convertTraceToJsonAndDownload(file);
+ })
+ .catch(error => {
+ throw new Error(`Failed to get current trace ${error}`);
+ });
+}
+
+export function isTraceLoaded(): boolean {
+ const engine = Object.values(globals.state.engines)[0];
+ return engine !== undefined;
}
function openTraceUrl(url: string): (e: Event) => void {
return e => {
globals.logging.logEvent('Trace Actions', 'Open example trace');
e.preventDefault();
- globals.frontendLocalState.localOnlyMode = false;
globals.dispatch(Actions.openTraceFromUrl({url}));
};
}
@@ -350,34 +432,11 @@ function onInputElementFileSelectionChanged(e: Event) {
// Reset the value so onchange will be fired with the same file.
e.target.value = '';
- globals.frontendLocalState.localOnlyMode = false;
-
if (e.target.dataset['useCatapultLegacyUi'] === '1') {
openWithLegacyUi(file);
return;
}
- if (e.target.dataset['video'] === '1') {
- // TODO(hjd): Update this to use a controller and publish.
- globals.dispatch(Actions.executeQuery({
- engineId: '0', queryId: 'command',
- query: `select ts from slices where name = 'first_frame' union ` +
- `select start_ts from trace_bounds`}));
- setTimeout(() => {
- const resp = globals.queryResults.get('command') as QueryResponse;
- // First value is screenrecord trace event timestamp
- // and second value is trace boundary's start timestamp
- const offset = (Number(resp.rows[1]['ts'].toString()) -
- Number(resp.rows[0]['ts'].toString())) /
- 1e9;
- globals.queryResults.delete('command');
- globals.rafScheduler.scheduleFullRedraw();
- globals.dispatch(Actions.deleteQuery({queryId: 'command'}));
- globals.dispatch(Actions.setVideoOffset({offset}));
- }, 1000);
- globals.dispatch(Actions.openVideoFromFile({file}));
- return;
- }
globals.logging.logEvent('Trace Actions', 'Open trace from file');
globals.dispatch(Actions.openTraceFromFile({file}));
}
@@ -395,7 +454,7 @@ async function openWithLegacyUi(file: File) {
function openInOldUIWithSizeCheck(trace: Blob) {
// Perfetto traces smaller than 50mb can be safely opened in the legacy UI.
if (trace.size < 1024 * 1024 * 50) {
- globals.dispatch(Actions.convertTraceToJson({file: trace}));
+ convertToJson(trace);
return;
}
@@ -423,7 +482,7 @@ function openInOldUIWithSizeCheck(trace: Blob) {
primary: false,
id: 'open',
action: () => {
- globals.dispatch(Actions.convertTraceToJson({file: trace}));
+ convertToJson(trace);
}
},
{
@@ -431,8 +490,7 @@ function openInOldUIWithSizeCheck(trace: Blob) {
primary: true,
id: 'truncate-start',
action: () => {
- globals.dispatch(
- Actions.convertTraceToJson({file: trace, truncate: 'start'}));
+ convertToJson(trace, /*truncate*/ 'start');
}
},
{
@@ -440,8 +498,7 @@ function openInOldUIWithSizeCheck(trace: Blob) {
primary: true,
id: 'truncate-end',
action: () => {
- globals.dispatch(
- Actions.convertTraceToJson({file: trace, truncate: 'end'}));
+ convertToJson(trace, /*truncate*/ 'end');
}
}
@@ -452,27 +509,32 @@ function openInOldUIWithSizeCheck(trace: Blob) {
function navigateRecord(e: Event) {
e.preventDefault();
- globals.dispatch(Actions.navigate({route: '/record'}));
+ Router.navigate('#!/record');
}
function navigateAnalyze(e: Event) {
e.preventDefault();
- globals.dispatch(Actions.navigate({route: '/query'}));
+ Router.navigate('#!/query');
+}
+
+function navigateFlags(e: Event) {
+ e.preventDefault();
+ Router.navigate('#!/flags');
}
function navigateMetrics(e: Event) {
e.preventDefault();
- globals.dispatch(Actions.navigate({route: '/metrics'}));
+ Router.navigate('#!/metrics');
}
function navigateInfo(e: Event) {
e.preventDefault();
- globals.dispatch(Actions.navigate({route: '/info'}));
+ Router.navigate('#!/info');
}
function navigateViewer(e: Event) {
e.preventDefault();
- globals.dispatch(Actions.navigate({route: '/viewer'}));
+ Router.navigate('#!/viewer');
}
function shareTrace(e: Event) {
@@ -504,7 +566,7 @@ function shareTrace(e: Event) {
if (!isShareable() || !isTraceLoaded()) return;
const result = confirm(
- `Upload the trace and generate a permalink. ` +
+ `Upload UI state and generate a permalink. ` +
`The trace will be accessible by anybody with the permalink.`);
if (result) {
globals.logging.logEvent('Trace Actions', 'Create permalink');
@@ -679,7 +741,7 @@ const SidebarFooter: m.Component = {
'.sidebar-footer',
m('button',
{
- onclick: () => globals.frontendLocalState.togglePerfDebug(),
+ onclick: () => globals.dispatch(Actions.togglePerfDebug({})),
},
m('i.material-icons',
{title: 'Toggle Perf Debug Mode'},
@@ -690,12 +752,11 @@ const SidebarFooter: m.Component = {
'.version',
m('a',
{
- href: `https://github.com/google/perfetto/tree/${
- version.SCM_REVISION}/ui`,
- title: `Channel: ${globals.channel}`,
+ href: `${GITILES_URL}/+/${version.SCM_REVISION}/ui`,
+ title: `Channel: ${getCurrentChannel()}`,
target: '_blank',
},
- `${version.VERSION}`),
+ `${version.VERSION.substr(0, 11)}`),
),
);
}
@@ -711,22 +772,25 @@ export class Sidebar implements m.ClassComponent {
if (section.hideIfNoTraceLoaded && !isTraceLoaded()) continue;
const vdomItems = [];
for (const item of section.items) {
+ if (item.isVisible !== undefined && !item.isVisible()) {
+ continue;
+ }
let css = '';
let attrs = {
onclick: typeof item.a === 'function' ? item.a : null,
href: typeof item.a === 'string' ? item.a : '#',
target: typeof item.a === 'string' ? '_blank' : null,
disabled: false,
+ id: item.t.toLowerCase().replace(/[^\w]/g, '_')
};
- if (item.a === openCurrentTraceWithOldUI &&
- globals.state.traceConversionInProgress) {
+ if (item.isPending && item.isPending()) {
attrs.onclick = e => e.preventDefault();
css = '.pending';
}
- if ((item as {internalUserOnly: boolean}).internalUserOnly === true) {
- if (!globals.isInternalUser) continue;
+ if (item.internalUserOnly && !globals.isInternalUser) {
+ continue;
}
- if (!isDownloadable() && item.hasOwnProperty('checkDownloadDisabled')) {
+ if (item.checkDownloadDisabled && !isDownloadable()) {
attrs = {
onclick: e => {
e.preventDefault();
@@ -735,6 +799,7 @@ export class Sidebar implements m.ClassComponent {
href: '#',
target: null,
disabled: true,
+ id: ''
};
}
vdomItems.push(m(
@@ -788,59 +853,32 @@ export class Sidebar implements m.ClassComponent {
m('h2', section.summary)),
m('.section-content', m('ul', vdomItems))));
}
- if (globals.state.videoEnabled) {
- const videoVdomItems = [];
- for (const item of vidSection.items) {
- videoVdomItems.push(
- m('li',
- m(`a`,
- {
- onclick: typeof item.a === 'function' ? item.a : null,
- href: typeof item.a === 'string' ? item.a : '#',
- },
- m('i.material-icons', item.i),
- item.t)));
- }
- vdomSections.push(
- m(`section${vidSection.expanded ? '.expanded' : ''}`,
- m('.section-header',
- {
- onclick: () => {
- vidSection.expanded = !vidSection.expanded;
- globals.rafScheduler.scheduleFullRedraw();
- }
- },
- m('h1', vidSection.title),
- m('h2', vidSection.summary), ),
- m('.section-content', m('ul', videoVdomItems))));
- }
return m(
'nav.sidebar',
{
- class: globals.frontendLocalState.sidebarVisible ? 'show-sidebar' :
- 'hide-sidebar',
+ class: globals.state.sidebarVisible ? 'show-sidebar' : 'hide-sidebar',
// 150 here matches --sidebar-timing in the css.
ontransitionstart: () => this._redrawWhileAnimating.start(150),
ontransitionend: () => this._redrawWhileAnimating.stop(),
},
m(
- `header.${globals.channel}`,
+ `header.${getCurrentChannel()}`,
m(`img[src=${globals.root}assets/brand.png].brand`),
m('button.sidebar-button',
{
onclick: () => {
- globals.frontendLocalState.toggleSidebar();
+ globals.dispatch(Actions.toggleSidebar({}));
},
},
m('i.material-icons',
{
- title: globals.frontendLocalState.sidebarVisible ?
- 'Hide menu' :
- 'Show menu',
+ title: globals.state.sidebarVisible ? 'Hide menu' :
+ 'Show menu',
},
'menu')),
),
- m('input[type=file]', {onchange: onInputElementFileSelectionChanged}),
+ m('input.trace_file[type=file]',
+ {onchange: onInputElementFileSelectionChanged}),
m('.sidebar-scroll',
m(
'.sidebar-scroll-container',
@@ -859,14 +897,7 @@ function createTraceLink(title: string, url: string) {
href: url,
title: 'Click to copy the URL',
target: '_blank',
- onclick: (e: Event) => {
- e.preventDefault();
- copyToClipboard(url);
- globals.dispatch(Actions.updateStatus({
- msg: 'Link copied into the clipboard',
- timestamp: Date.now() / 1000,
- }));
- },
+ onclick: onClickCopy(url)
};
return m('a.trace-file-name', linkProps, title);
}
diff --git a/ui/src/frontend/slice.ts b/ui/src/frontend/slice.ts
new file mode 100644
index 000000000..5b660ef0e
--- /dev/null
+++ b/ui/src/frontend/slice.ts
@@ -0,0 +1,31 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {Color} from '../common/colorizer';
+
+export interface Slice {
+ // These properties are updated only once per query result when the Slice
+ // object is created and don't change afterwards.
+ readonly id: number;
+ readonly startS: number;
+ readonly durationS: number;
+ readonly depth: number;
+ readonly flags: number;
+
+ // These can be changed by the Impl.
+ title: string;
+ subTitle: string;
+ baseColor: Color;
+ color: Color;
+}
diff --git a/ui/src/frontend/slice_details_panel.ts b/ui/src/frontend/slice_details_panel.ts
new file mode 100644
index 000000000..6526ba097
--- /dev/null
+++ b/ui/src/frontend/slice_details_panel.ts
@@ -0,0 +1,177 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use size file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import * as m from 'mithril';
+
+import {Actions} from '../common/actions';
+import {drawDoubleHeadedArrow} from '../common/canvas_utils';
+import {translateState} from '../common/thread_state';
+import {timeToCode, toNs} from '../common/time';
+
+import {globals, SliceDetails, ThreadDesc} from './globals';
+import {PanelSize} from './panel';
+import {scrollToTrackAndTs} from './scroll_helper';
+import {SlicePanel} from './slice_panel';
+
+export class SliceDetailsPanel extends SlicePanel {
+ view() {
+ const sliceInfo = globals.sliceDetails;
+ if (sliceInfo.utid === undefined) return;
+ const threadInfo = globals.threads.get(sliceInfo.utid);
+
+ return m(
+ '.details-panel',
+ m('.details-panel-heading',
+ m('h2.split', `Slice Details`),
+ (sliceInfo.wakeupTs && sliceInfo.wakerUtid) ?
+ m('h2.split', 'Scheduling Latency') :
+ ''),
+ this.getDetails(sliceInfo, threadInfo));
+ }
+
+ getDetails(sliceInfo: SliceDetails, threadInfo: ThreadDesc|undefined) {
+ if (!threadInfo || sliceInfo.ts === undefined ||
+ sliceInfo.dur === undefined) {
+ return null;
+ } else {
+ const tableRows = [
+ m('tr',
+ m('th', `Process`),
+ m('td', `${threadInfo.procName} [${threadInfo.pid}]`)),
+ m('tr',
+ m('th', `Thread`),
+ m('td',
+ `${threadInfo.threadName} [${threadInfo.tid}]`,
+ m('i.material-icons.grey',
+ {onclick: () => this.goToThread(), title: 'Go to thread'},
+ 'call_made'))),
+ m('tr', m('th', `Cmdline`), m('td', threadInfo.cmdline)),
+ m('tr', m('th', `Start time`), m('td', `${timeToCode(sliceInfo.ts)}`)),
+ m('tr',
+ m('th', `Duration`),
+ m('td', this.computeDuration(sliceInfo.ts, sliceInfo.dur))),
+ (sliceInfo.thread_dur === undefined ||
+ sliceInfo.thread_ts === undefined) ?
+ '' :
+ m('tr',
+ m('th', 'Thread duration'),
+ m('td',
+ this.computeDuration(
+ sliceInfo.thread_ts, sliceInfo.thread_dur))),
+ m('tr', m('th', `Prio`), m('td', `${sliceInfo.priority}`)),
+ m('tr',
+ m('th', `End State`),
+ m('td', translateState(sliceInfo.endState))),
+ m('tr',
+ m('th', `Slice ID`),
+ m('td', sliceInfo.id ? sliceInfo.id.toString() : 'Unknown'))
+ ];
+
+ for (const [key, value] of this.getProcessThreadDetails(sliceInfo)) {
+ if (value !== undefined) {
+ tableRows.push(m('tr', m('th', key), m('td', value)));
+ }
+ }
+
+ return m(
+ '.details-table',
+ m('table.half-width', tableRows),
+ );
+ }
+ }
+
+ goToThread() {
+ const sliceInfo = globals.sliceDetails;
+ if (sliceInfo.utid === undefined) return;
+ const threadInfo = globals.threads.get(sliceInfo.utid);
+
+ if (sliceInfo.id === undefined || sliceInfo.ts === undefined ||
+ sliceInfo.dur === undefined || sliceInfo.cpu === undefined ||
+ threadInfo === undefined) {
+ return;
+ }
+
+ let trackId: string|number|undefined;
+ for (const track of Object.values(globals.state.tracks)) {
+ if (track.kind === 'ThreadStateTrack' &&
+ (track.config as {utid: number}).utid === threadInfo.utid) {
+ trackId = track.id;
+ }
+ }
+
+ if (trackId && sliceInfo.threadStateId) {
+ globals.makeSelection(Actions.selectThreadState({
+ id: sliceInfo.threadStateId,
+ trackId: trackId.toString(),
+ }));
+
+ scrollToTrackAndTs(
+ trackId, toNs(sliceInfo.ts + globals.state.traceTime.startSec), true);
+ }
+ }
+
+
+ renderCanvas(ctx: CanvasRenderingContext2D, size: PanelSize) {
+ const details = globals.sliceDetails;
+ // Show expanded details on the scheduling of the currently selected slice.
+ if (details.wakeupTs && details.wakerUtid !== undefined) {
+ const threadInfo = globals.threads.get(details.wakerUtid);
+ // Draw diamond and vertical line.
+ const startDraw = {x: size.width / 2 + 20, y: 52};
+ ctx.beginPath();
+ ctx.moveTo(startDraw.x, startDraw.y + 28);
+ ctx.fillStyle = 'black';
+ ctx.lineTo(startDraw.x + 6, startDraw.y + 20);
+ ctx.lineTo(startDraw.x, startDraw.y + 12);
+ ctx.lineTo(startDraw.x - 6, startDraw.y + 20);
+ ctx.fill();
+ ctx.closePath();
+ ctx.fillRect(startDraw.x - 1, startDraw.y, 2, 100);
+
+ // Wakeup explanation text.
+ ctx.font = '13px Roboto Condensed';
+ ctx.fillStyle = '#3c4b5d';
+ if (threadInfo) {
+ const displayText = `Wakeup @ ${
+ timeToCode(
+ details.wakeupTs - globals.state.traceTime.startSec)} on CPU ${
+ details.wakerCpu} by`;
+ const processText = `P: ${threadInfo.procName} [${threadInfo.pid}]`;
+ const threadText = `T: ${threadInfo.threadName} [${threadInfo.tid}]`;
+ ctx.fillText(displayText, startDraw.x + 20, startDraw.y + 20);
+ ctx.fillText(processText, startDraw.x + 20, startDraw.y + 37);
+ ctx.fillText(threadText, startDraw.x + 20, startDraw.y + 55);
+ }
+
+ // Draw latency arrow and explanation text.
+ drawDoubleHeadedArrow(ctx, startDraw.x, startDraw.y + 80, 60, true);
+ if (details.ts) {
+ const displayLatency = `Scheduling latency: ${
+ timeToCode(
+ details.ts -
+ (details.wakeupTs - globals.state.traceTime.startSec))}`;
+ ctx.fillText(displayLatency, startDraw.x + 70, startDraw.y + 86);
+ const explain1 =
+ 'This is the interval from when the task became eligible to run';
+ const explain2 =
+ '(e.g. because of notifying a wait queue it was suspended on) to';
+ const explain3 = 'when it started running.';
+ ctx.font = '10px Roboto Condensed';
+ ctx.fillText(explain1, startDraw.x + 70, startDraw.y + 86 + 16);
+ ctx.fillText(explain2, startDraw.x + 70, startDraw.y + 86 + 16 + 12);
+ ctx.fillText(explain3, startDraw.x + 70, startDraw.y + 86 + 16 + 24);
+ }
+ }
+ }
+}
diff --git a/ui/src/frontend/slice_layout.ts b/ui/src/frontend/slice_layout.ts
new file mode 100644
index 000000000..1f286174e
--- /dev/null
+++ b/ui/src/frontend/slice_layout.ts
@@ -0,0 +1,76 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+export interface SliceLayoutBase {
+ padding: number; // top/bottom pixel padding between slices and track.
+ rowSpacing: number; // Spacing between rows.
+ minDepth: number; // Minimum depth a slice can be (normally zero)
+ // Maximum depth a slice can be plus 1 (a half open range with minDepth).
+ // We have a optimization for when maxDepth - minDepth == 1 so it is useful
+ // to set this correctly:
+ maxDepth: number;
+}
+
+export const SLICE_LAYOUT_BASE_DEFAULTS: SliceLayoutBase = Object.freeze({
+ padding: 3,
+ rowSpacing: 0,
+ minDepth: 0,
+ // A realistic bound to avoid tracks with unlimited height. If somebody wants
+ // extremely deep tracks they need to change this explicitly.
+ maxDepth: 128,
+});
+
+export interface SliceLayoutFixed extends SliceLayoutBase {
+ heightMode: 'FIXED';
+ fixedHeight: number; // Outer height of the track.
+}
+
+export const SLICE_LAYOUT_FIXED_DEFAULTS: SliceLayoutFixed = Object.freeze({
+ ...SLICE_LAYOUT_BASE_DEFAULTS,
+ heightMode: 'FIXED',
+ fixedHeight: 30,
+});
+
+export interface SliceLayoutFitContent extends SliceLayoutBase {
+ heightMode: 'FIT_CONTENT';
+ sliceHeight: number; // Only when heightMode = 'FIT_CONTENT'.
+}
+
+export const SLICE_LAYOUT_FIT_CONTENT_DEFAULTS: SliceLayoutFitContent =
+ Object.freeze({
+ ...SLICE_LAYOUT_BASE_DEFAULTS,
+ heightMode: 'FIT_CONTENT',
+ sliceHeight: 18,
+ });
+
+export interface SliceLayoutFlat extends SliceLayoutBase {
+ heightMode: 'FIXED';
+ fixedHeight: number; // Outer height of the track.
+ minDepth: 0;
+ maxDepth: 1;
+}
+
+export const SLICE_LAYOUT_FLAT_DEFAULTS: SliceLayoutFlat = Object.freeze({
+ ...SLICE_LAYOUT_BASE_DEFAULTS,
+ minDepth: 0,
+ maxDepth: 1,
+ heightMode: 'FIXED',
+ fixedHeight: 30,
+});
+
+export type SliceLayout =
+ SliceLayoutFixed|SliceLayoutFitContent|SliceLayoutFlat;
+
+export const DEFAULT_SLICE_LAYOUT: SliceLayout =
+ SLICE_LAYOUT_FIT_CONTENT_DEFAULTS;
diff --git a/ui/src/frontend/slice_panel.ts b/ui/src/frontend/slice_panel.ts
index 775c829b7..1f649c699 100644
--- a/ui/src/frontend/slice_panel.ts
+++ b/ui/src/frontend/slice_panel.ts
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 The Android Open Source Project
+// Copyright (C) 2021 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use size file except in compliance with the License.
@@ -12,149 +12,28 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import * as m from 'mithril';
-
-import {Actions} from '../common/actions';
-import {drawDoubleHeadedArrow} from '../common/canvas_utils';
-import {translateState} from '../common/thread_state';
import {timeToCode, toNs} from '../common/time';
-import {globals, SliceDetails, ThreadDesc} from './globals';
-import {Panel, PanelSize} from './panel';
-import {scrollToTrackAndTs} from './scroll_helper';
-
-export class SliceDetailsPanel extends Panel {
- view() {
- const sliceInfo = globals.sliceDetails;
- if (sliceInfo.utid === undefined) return;
- const threadInfo = globals.threads.get(sliceInfo.utid);
-
- return m(
- '.details-panel',
- m('.details-panel-heading',
- m('h2.split', `Slice Details`),
- (sliceInfo.wakeupTs && sliceInfo.wakerUtid) ?
- m('h2.split', 'Scheduling Latency') :
- ''),
- this.getDetails(sliceInfo, threadInfo));
- }
+import {globals, SliceDetails} from './globals';
+import {Panel} from './panel';
- getDetails(sliceInfo: SliceDetails, threadInfo: ThreadDesc|undefined) {
- if (!threadInfo || sliceInfo.ts === undefined ||
- sliceInfo.dur === undefined) {
- return null;
- } else {
- return m(
- '.details-table',
- m('table.half-width',
- [
- m('tr',
- m('th', `Process`),
- m('td', `${threadInfo.procName} [${threadInfo.pid}]`)),
- m('tr',
- m('th', `Thread`),
- m('td',
- `${threadInfo.threadName} [${threadInfo.tid}]`,
- m('i.material-icons.grey',
- {onclick: () => this.goToThread(), title: 'Go to thread'},
- 'call_made'))),
- m('tr', m('th', `Cmdline`), m('td', threadInfo.cmdline)),
- m('tr',
- m('th', `Start time`),
- m('td', `${timeToCode(sliceInfo.ts)}`)),
- m('tr',
- m('th', `Duration`),
- m('td', `${timeToCode(sliceInfo.dur)}`)),
- m('tr', m('th', `Prio`), m('td', `${sliceInfo.priority}`)),
- m('tr',
- m('th', `End State`),
- m('td', translateState(sliceInfo.endState)))
- ]),
- );
- }
+export abstract class SlicePanel extends Panel {
+ protected computeDuration(ts: number, dur: number): string {
+ return toNs(dur) === -1 ?
+ `${globals.state.traceTime.endSec - ts} (Did not end)` :
+ timeToCode(dur);
}
- goToThread() {
- const sliceInfo = globals.sliceDetails;
- if (sliceInfo.utid === undefined) return;
- const threadInfo = globals.threads.get(sliceInfo.utid);
-
- if (sliceInfo.id === undefined || sliceInfo.ts === undefined ||
- sliceInfo.dur === undefined || sliceInfo.cpu === undefined ||
- threadInfo === undefined) {
- return;
- }
-
- let trackId: string|number|undefined;
- for (const track of Object.values(globals.state.tracks)) {
- if (track.kind === 'ThreadStateTrack' &&
- (track.config as {utid: number}).utid === threadInfo.utid) {
- trackId = track.id;
- }
- }
-
- if (trackId && sliceInfo.threadStateId) {
- globals.makeSelection(Actions.selectThreadState({
- id: sliceInfo.threadStateId,
- trackId: trackId.toString(),
- }));
-
- scrollToTrackAndTs(
- trackId, toNs(sliceInfo.ts + globals.state.traceTime.startSec), true);
- }
- }
-
-
- renderCanvas(ctx: CanvasRenderingContext2D, size: PanelSize) {
- const details = globals.sliceDetails;
- // Show expanded details on the scheduling of the currently selected slice.
- if (details.wakeupTs && details.wakerUtid !== undefined) {
- const threadInfo = globals.threads.get(details.wakerUtid);
- // Draw diamond and vertical line.
- const startDraw = {x: size.width / 2 + 20, y: 52};
- ctx.beginPath();
- ctx.moveTo(startDraw.x, startDraw.y + 28);
- ctx.fillStyle = 'black';
- ctx.lineTo(startDraw.x + 6, startDraw.y + 20);
- ctx.lineTo(startDraw.x, startDraw.y + 12);
- ctx.lineTo(startDraw.x - 6, startDraw.y + 20);
- ctx.fill();
- ctx.closePath();
- ctx.fillRect(startDraw.x - 1, startDraw.y, 2, 100);
-
- // Wakeup explanation text.
- ctx.font = '13px Roboto Condensed';
- ctx.fillStyle = '#3c4b5d';
- if (threadInfo) {
- const displayText = `Wakeup @ ${
- timeToCode(
- details.wakeupTs - globals.state.traceTime.startSec)} on CPU ${
- details.wakerCpu} by`;
- const processText = `P: ${threadInfo.procName} [${threadInfo.pid}]`;
- const threadText = `T: ${threadInfo.threadName} [${threadInfo.tid}]`;
- ctx.fillText(displayText, startDraw.x + 20, startDraw.y + 20);
- ctx.fillText(processText, startDraw.x + 20, startDraw.y + 37);
- ctx.fillText(threadText, startDraw.x + 20, startDraw.y + 55);
- }
-
- // Draw latency arrow and explanation text.
- drawDoubleHeadedArrow(ctx, startDraw.x, startDraw.y + 80, 60, true);
- if (details.ts) {
- const displayLatency = `Scheduling latency: ${
- timeToCode(
- details.ts -
- (details.wakeupTs - globals.state.traceTime.startSec))}`;
- ctx.fillText(displayLatency, startDraw.x + 70, startDraw.y + 86);
- const explain1 =
- 'This is the interval from when the task became eligible to run';
- const explain2 =
- '(e.g. because of notifying a wait queue it was suspended on) to';
- const explain3 = 'when it started running.';
- ctx.font = '10px Roboto Condensed';
- ctx.fillText(explain1, startDraw.x + 70, startDraw.y + 86 + 16);
- ctx.fillText(explain2, startDraw.x + 70, startDraw.y + 86 + 16 + 12);
- ctx.fillText(explain3, startDraw.x + 70, startDraw.y + 86 + 16 + 24);
- }
- }
+ protected getProcessThreadDetails(sliceInfo: SliceDetails) {
+ return new Map<string, string|undefined>([
+ ['Thread', `${sliceInfo.threadName} ${sliceInfo.tid}`],
+ ['Process', `${sliceInfo.processName} ${sliceInfo.pid}`],
+ ['User ID', sliceInfo.uid ? String(sliceInfo.uid) : undefined],
+ ['Package name', sliceInfo.packageName],
+ [
+ 'Version code',
+ sliceInfo.versionCode ? String(sliceInfo.versionCode) : undefined
+ ]
+ ]);
}
}
diff --git a/ui/src/frontend/tickmark_panel.ts b/ui/src/frontend/tickmark_panel.ts
index 32fa051dc..6cc8037c3 100644
--- a/ui/src/frontend/tickmark_panel.ts
+++ b/ui/src/frontend/tickmark_panel.ts
@@ -53,7 +53,7 @@ export class TickmarkPanel extends Panel {
Math.ceil(rectEnd - rectStart),
size.height);
}
- const index = globals.frontendLocalState.searchIndex;
+ const index = globals.state.searchIndex;
const startSec = fromNs(globals.currentSearchResults.tsStarts[index]);
const triangleStart =
Math.max(timeScale.timeToPx(startSec), 0) + TRACK_SHELL_WIDTH;
diff --git a/ui/src/frontend/time_scale.ts b/ui/src/frontend/time_scale.ts
index c5e92a751..cdf3ca28b 100644
--- a/ui/src/frontend/time_scale.ts
+++ b/ui/src/frontend/time_scale.ts
@@ -15,7 +15,7 @@
import {assertFalse, assertTrue} from '../base/logging';
import {TimeSpan} from '../common/time';
-const MAX_ZOOM_SPAN_SEC = 1e-6; // 1us.
+const MAX_ZOOM_SPAN_SEC = 1e-8; // 10 ns.
/**
* Defines a mapping between number and seconds for the entire application.
diff --git a/ui/src/frontend/time_scale_unittest.ts b/ui/src/frontend/time_scale_unittest.ts
index c6b382285..7a1be031d 100644
--- a/ui/src/frontend/time_scale_unittest.ts
+++ b/ui/src/frontend/time_scale_unittest.ts
@@ -73,5 +73,5 @@ test('it clamps zoom in', () => {
const scale = new TimeScale(span, [200, 300]);
const newSpan = computeZoom(scale, span, 0.0000000001, 225);
expect((newSpan.end - newSpan.start) / 2 + newSpan.start).toBeCloseTo(1010);
- expect(newSpan.end - newSpan.start).toBeCloseTo(1e-6, 8);
+ expect(newSpan.end - newSpan.start).toBeCloseTo(1e-8);
});
diff --git a/ui/src/frontend/time_selection_panel.ts b/ui/src/frontend/time_selection_panel.ts
index 8ec07482d..65ac83edf 100644
--- a/ui/src/frontend/time_selection_panel.ts
+++ b/ui/src/frontend/time_selection_panel.ts
@@ -142,9 +142,8 @@ export class TimeSelectionPanel extends Panel {
this.renderSpan(ctx, size, new TimeSpan(start, end));
}
- if (globals.frontendLocalState.hoveredLogsTimestamp !== -1) {
- this.renderHover(
- ctx, size, globals.frontendLocalState.hoveredLogsTimestamp);
+ if (globals.state.hoveredLogsTimestamp !== -1) {
+ this.renderHover(ctx, size, globals.state.hoveredLogsTimestamp);
}
for (const note of Object.values(globals.state.notes)) {
diff --git a/ui/src/frontend/topbar.ts b/ui/src/frontend/topbar.ts
index 1f9d3518b..9cb29bf74 100644
--- a/ui/src/frontend/topbar.ts
+++ b/ui/src/frontend/topbar.ts
@@ -107,7 +107,6 @@ class Omnibox implements m.ClassComponent {
}
const commandMode = mode === COMMAND;
- const state = globals.frontendLocalState;
return m(
`.omnibox${commandMode ? '.command-mode' : ''}`,
m('input', {
@@ -117,9 +116,8 @@ class Omnibox implements m.ClassComponent {
globals.frontendLocalState.setOmnibox(
value, commandMode ? 'COMMAND' : 'SEARCH');
if (mode === SEARCH) {
- globals.frontendLocalState.setSearchIndex(-1);
displayStepThrough = value.length >= 4;
- globals.rafScheduler.scheduleFullRedraw();
+ globals.dispatch(Actions.setSearchIndex({index: -1}));
}
},
value: globals.frontendLocalState.omnibox,
@@ -131,11 +129,11 @@ class Omnibox implements m.ClassComponent {
`${
globals.currentSearchResults.totalResults === 0 ?
'0 / 0' :
- `${state.searchIndex + 1} / ${
+ `${globals.state.searchIndex + 1} / ${
globals.currentSearchResults.totalResults}`}`),
m('button',
{
- disabled: state.searchIndex <= 0,
+ disabled: globals.state.searchIndex <= 0,
onclick: () => {
executeSearch(true /* reverse direction */);
}
@@ -143,7 +141,7 @@ class Omnibox implements m.ClassComponent {
m('i.material-icons.left', 'keyboard_arrow_left')),
m('button',
{
- disabled: state.searchIndex ===
+ disabled: globals.state.searchIndex ===
globals.currentSearchResults.totalResults - 1,
onclick: () => {
executeSearch();
@@ -252,9 +250,7 @@ export class Topbar implements m.ClassComponent {
view() {
return m(
'.topbar',
- {
- class: globals.frontendLocalState.sidebarVisible ? '' : 'hide-sidebar'
- },
+ {class: globals.state.sidebarVisible ? '' : 'hide-sidebar'},
globals.frontendLocalState.newVersionAvailable ?
m(NewVersionNotification) :
m(Omnibox),
diff --git a/ui/src/frontend/trace_attrs.ts b/ui/src/frontend/trace_attrs.ts
index 2d6ffcfa7..9cc729258 100644
--- a/ui/src/frontend/trace_attrs.ts
+++ b/ui/src/frontend/trace_attrs.ts
@@ -19,8 +19,11 @@ export function isShareable() {
}
export function isDownloadable() {
- if (globals.frontendLocalState.localOnlyMode) return false;
const engine = Object.values(globals.state.engines)[0];
+ if (engine && engine.source.type === 'ARRAY_BUFFER' &&
+ engine.source.localOnly) {
+ return false;
+ }
if (engine && engine.source.type === 'HTTP_RPC') return false;
return true;
} \ No newline at end of file
diff --git a/ui/src/frontend/trace_converter.ts b/ui/src/frontend/trace_converter.ts
new file mode 100644
index 000000000..237e39dc3
--- /dev/null
+++ b/ui/src/frontend/trace_converter.ts
@@ -0,0 +1,115 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {Actions} from '../common/actions';
+import {
+ ConversionJobName,
+ ConversionJobStatus
+} from '../common/conversion_jobs';
+
+import {maybeShowErrorDialog} from './error_dialog';
+import {download} from './clipboard';
+import {globals} from './globals';
+import {openBufferWithLegacyTraceViewer} from './legacy_trace_viewer';
+
+type Args =
+ UpdateStatusArgs|UpdateJobStatusArgs|DownloadFileArgs|OpenTraceInLegacyArgs|ErrorArgs;
+
+interface UpdateStatusArgs {
+ kind: 'updateStatus';
+ status: string;
+}
+
+interface UpdateJobStatusArgs {
+ kind: 'updateJobStatus';
+ name: ConversionJobName;
+ status: ConversionJobStatus;
+}
+
+interface DownloadFileArgs {
+ kind: 'downloadFile';
+ buffer: Uint8Array;
+ name: string;
+}
+
+interface OpenTraceInLegacyArgs {
+ kind: 'openTraceInLegacy';
+ buffer: Uint8Array;
+}
+
+interface ErrorArgs {
+ kind: 'error';
+ error: string;
+}
+
+
+function handleOnMessage(msg: MessageEvent): void {
+ const args: Args = msg.data;
+ if (args.kind === 'updateStatus') {
+ globals.dispatch(Actions.updateStatus({
+ msg: args.status,
+ timestamp: Date.now() / 1000,
+ }));
+ } else if (args.kind === 'updateJobStatus') {
+ globals.setConversionJobStatus(args.name, args.status);
+ } else if (args.kind === 'downloadFile') {
+ download(new File([new Blob([args.buffer])], args.name));
+ } else if (args.kind === 'openTraceInLegacy') {
+ const str = (new TextDecoder('utf-8')).decode(args.buffer);
+ openBufferWithLegacyTraceViewer('trace.json', str, 0);
+ } else if (args.kind === 'error') {
+ maybeShowErrorDialog(args.error);
+ } else {
+ throw new Error(`Unhandled message ${JSON.stringify(args)}`);
+ }
+}
+
+function makeWorkerAndPost(msg: unknown) {
+ const worker = new Worker(globals.root + 'traceconv_bundle.js');
+ worker.onmessage = handleOnMessage;
+ worker.postMessage(msg);
+}
+
+export function convertTraceToJsonAndDownload(trace: Blob) {
+ makeWorkerAndPost({
+ kind: 'ConvertTraceAndDownload',
+ trace,
+ format: 'json',
+ });
+}
+
+export function convertTraceToSystraceAndDownload(trace: Blob) {
+ makeWorkerAndPost({
+ kind: 'ConvertTraceAndDownload',
+ trace,
+ format: 'systrace',
+ });
+}
+
+export function convertToJson(trace: Blob, truncate?: 'start'|'end') {
+ makeWorkerAndPost({
+ kind: 'ConvertTraceAndOpenInLegacy',
+ trace,
+ truncate,
+ });
+}
+
+export function convertTraceToPprofAndDownload(trace: Blob, pid: number, ts: number) {
+ makeWorkerAndPost({
+ kind: 'ConvertTraceToPprof',
+ trace,
+ pid,
+ ts,
+ });
+}
diff --git a/ui/src/frontend/trace_url_handler.ts b/ui/src/frontend/trace_url_handler.ts
new file mode 100644
index 000000000..690d74340
--- /dev/null
+++ b/ui/src/frontend/trace_url_handler.ts
@@ -0,0 +1,239 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import * as m from 'mithril';
+
+import {Actions} from '../common/actions';
+import {tryGetTrace} from '../common/cache_manager';
+
+import {loadAndroidBugToolInfo} from './android_bug_tool';
+import {globals} from './globals';
+import {showModal} from './modal';
+import {Route, Router} from './router';
+import {taskTracker} from './task_tracker';
+
+
+export function maybeOpenTraceFromRoute(route: Route) {
+ if (route.args.s) {
+ // /?s=xxxx for permalinks.
+ globals.dispatch(Actions.loadPermalink({hash: route.args.s}));
+ return;
+ }
+
+ if (route.args.url) {
+ // /?url=https://commondatastorage.googleapis.com/bucket/trace
+ // This really works only for GCS because the Content Security Policy
+ // forbids any other url.
+ loadTraceFromUrl(route.args.url);
+ return;
+ }
+
+ if (route.args.openFromAndroidBugTool) {
+ // Handles interaction with the Android Bug Tool extension. See b/163421158.
+ openTraceFromAndroidBugTool();
+ return;
+ }
+
+ if (route.args.p && route.page === '/record') {
+ // Handles backwards compatibility for old URLs (linked from various docs),
+ // generated before we switched URL scheme. e.g., 'record?p=power' vs
+ // 'record/power'. See b/191255021#comment2.
+ Router.navigate(`#!/record/${route.args.p}`);
+ return;
+ }
+
+ if (route.args.local_cache_key) {
+ // Handles the case of loading traces from the cache storage.
+ maybeOpenCachedTrace(route.args.local_cache_key);
+ return;
+ }
+}
+
+
+/*
+ * openCachedTrace(uuid) is called: (1) on startup, from frontend/index.ts; (2)
+ * every time the fragment changes (from Router.onRouteChange).
+ * This function must be idempotent (imagine this is called on every frame).
+ * It must take decision based on the app state, not on URL change events.
+ * Fragment changes are handled by the union of Router.onHashChange() and this
+ * function, as follows:
+ * 1. '' -> URL without a ?local_cache_key=xxx arg:
+ * - no effect (except redrawing)
+ * 2. URL without local_cache_key -> URL with local_cache_key:
+ * - Load cached trace (without prompting any dialog).
+ * - Show a (graceful) error dialog in the case of cache misses.
+ * 3. '' -> URL with a ?local_cache_key=xxx arg:
+ * - Same as case 2.
+ * 4. URL with local_cache_key=1 -> URL with local_cache_key=2:
+ * a) If 2 != uuid of the trace currently loaded (globals.state.traceUuid):
+ * - Ask the user if they intend to switch trace and load 2.
+ * b) If 2 == uuid of current trace (e.g., after a new trace has loaded):
+ * - no effect (except redrawing).
+ * 5. URL with local_cache_key -> URL without local_cache_key:
+ * - Redirect to ?local_cache_key=1234 where 1234 is the UUID of the previous
+ * URL (this might or might not match globals.state.traceUuid).
+ *
+ * Backward navigation cases:
+ * 6. URL without local_cache_key <- URL with local_cache_key:
+ * - Same as case 5.
+ * 7. URL with local_cache_key=1 <- URL with local_cache_key=2:
+ * - Same as case 4a: go back to local_cache_key=1 but ask the user to confirm.
+ * 8. landing page <- URL with local_cache_key:
+ * - Same as case 5: re-append the local_cache_key.
+ */
+async function maybeOpenCachedTrace(traceUuid: string) {
+ if (traceUuid === globals.state.traceUuid) {
+ // Do nothing, matches the currently loaded trace.
+ return;
+ }
+
+ if (traceUuid === '') {
+ // This can happen if we switch from an empty UI state to an invalid UUID
+ // (e.g. due to a cache miss, below). This can also happen if the user just
+ // types /#!/viewer?local_cache_key=.
+ return;
+ }
+
+ // This handles the case when a trace T1 is loaded and then the url is set to
+ // ?local_cache_key=T2. In that case globals.state.traceUuid remains set to T1
+ // until T2 has been loaded by the trace processor (can take several seconds).
+ // This early out prevents to re-trigger the openTraceFromXXX() action if the
+ // URL changes (e.g. if the user navigates back/fwd) while the new trace is
+ // being loaded.
+ for (const eng of Object.values(globals.state.engines)) {
+ if (eng.source.type === 'ARRAY_BUFFER' && eng.source.uuid === traceUuid) {
+ return;
+ }
+ }
+
+ // Fetch the trace from the cache storage. If available load it. If not, show
+ // a dialog informing the user about the cache miss.
+ const maybeTrace = await tryGetTrace(traceUuid);
+
+ const navigateToOldTraceUuid = () => {
+ Router.navigate(
+ `#!/viewer?local_cache_key=${globals.state.traceUuid || ''}`);
+ };
+
+ if (!maybeTrace) {
+ showModal({
+ title: 'Could not find the trace in the cache storage',
+ content: m(
+ 'div',
+ m('p',
+ 'You are trying to load a cached trace by setting the ' +
+ '?local_cache_key argument in the URL.'),
+ m('p', 'Unfortunately the trace wasn\'t in the cache storage.'),
+ m('p',
+ 'This can happen if a tab was discarded and wasn\'t opened ' +
+ 'for too long, or if you just mis-pasted the URL.'),
+ m('pre', `Trace UUID: ${traceUuid}`),
+ ),
+ buttons: [],
+ });
+ navigateToOldTraceUuid();
+ return;
+ }
+
+ // If the UI is in a blank state (no trace has been ever opened), just load
+ // the trace without showing any further dialog. This is the case of tab
+ // discarding, reloading or pasting a url with a local_cache_key in an empty
+ // instance.
+ if (globals.state.traceUuid === undefined) {
+ globals.dispatch(Actions.openTraceFromBuffer(maybeTrace));
+ return;
+ }
+
+ // If, instead, another trace is loaded, ask confirmation to the user.
+ // Switching to another trace clears the UI state. It can be quite annoying to
+ // lose the UI state by accidentally navigating back too much.
+ let hasOpenedNewTrace = false;
+
+ await showModal({
+ title: 'You are about to load a different trace and reset the UI state',
+ content: m(
+ 'div',
+ m('p',
+ 'You are seeing this because you either pasted a URL with ' +
+ 'a different ?local_cache_key=xxx argument or because you hit ' +
+ 'the history back/fwd button and reached a different trace.'),
+ m('p',
+ 'If you continue another trace will be loaded and the UI ' +
+ 'state will be cleared.'),
+ m('pre',
+ `Old trace: ${globals.state.traceUuid || '<no trace>'}\n` +
+ `New trace: ${traceUuid}`),
+ ),
+ buttons: [
+ {
+ text: 'Continue',
+ primary: true,
+ id: 'trace_id_open',
+ action: () => {
+ hasOpenedNewTrace = true;
+ globals.dispatch(Actions.openTraceFromBuffer(maybeTrace));
+ }
+ },
+ {text: 'Cancel', primary: false, id: 'trace_id_cancel', action: () => {}},
+ ],
+ });
+
+ if (!hasOpenedNewTrace) {
+ // We handle this after the modal await rather than in the cancel button
+ // action so this has effect even if the user clicks Esc or clicks outside
+ // of the modal dialog and dismisses it.
+ navigateToOldTraceUuid();
+ }
+}
+
+function loadTraceFromUrl(url: string) {
+ const isLocalhostTraceUrl =
+ ['127.0.0.1', 'localhost'].includes((new URL(url)).hostname);
+
+ if (isLocalhostTraceUrl) {
+ // This handles the special case of tools/record_android_trace serving the
+ // traces from a local webserver and killing it immediately after having
+ // seen the HTTP GET request. In those cases store the trace as a file, so
+ // when users click on share we don't fail the re-fetch().
+ const fileName = url.split('/').pop() || 'local_trace.pftrace';
+ const request = fetch(url)
+ .then(response => response.blob())
+ .then(blob => {
+ globals.dispatch(Actions.openTraceFromFile({
+ file: new File([blob], fileName),
+ }));
+ })
+ .catch(e => alert(`Could not load local trace ${e}`));
+ taskTracker.trackPromise(request, 'Downloading local trace');
+ } else {
+ globals.dispatch(Actions.openTraceFromUrl({url}));
+ }
+}
+
+function openTraceFromAndroidBugTool() {
+ // TODO(hjd): Unify updateStatus and TaskTracker
+ globals.dispatch(Actions.updateStatus(
+ {msg: 'Loading trace from ABT extension', timestamp: Date.now() / 1000}));
+ const loadInfo = loadAndroidBugToolInfo();
+ taskTracker.trackPromise(loadInfo, 'Loading trace from ABT extension');
+ loadInfo
+ .then(info => {
+ globals.dispatch(Actions.openTraceFromFile({
+ file: info.file,
+ }));
+ })
+ .catch(e => {
+ console.error(e);
+ });
+}
diff --git a/ui/src/frontend/track.ts b/ui/src/frontend/track.ts
index 2f491ae99..0c5716a5e 100644
--- a/ui/src/frontend/track.ts
+++ b/ui/src/frontend/track.ts
@@ -13,14 +13,25 @@
// limitations under the License.
import * as m from 'mithril';
+
+import {assertExists} from '../base/logging';
+import {Engine} from '../common/engine';
import {TrackState} from '../common/state';
import {TrackData} from '../common/track_data';
-import {checkerboard} from './checkerboard';
+import {checkerboard} from './checkerboard';
import {globals} from './globals';
import {TrackButtonAttrs} from './track_panel';
/**
+ * Args passed to the track constructors when creating a new track.
+ */
+export interface NewTrackArgs {
+ trackId: string;
+ engine: Engine;
+}
+
+/**
* This interface forces track implementations to have some static properties.
* Typescript does not have abstract static members, which is why this needs to
* be in a separate interface.
@@ -30,9 +41,9 @@ export interface TrackCreator {
// case we ever minify our code.
readonly kind: string;
- // We need the |create| method because the stored value in the registry is an
- // abstract class, and we cannot call 'new' on an abstract class.
- create(TrackState: TrackState): Track;
+ // We need the |create| method because the stored value in the registry can be
+ // an abstract class, and we cannot call 'new' on an abstract class.
+ create(args: NewTrackArgs): Track;
}
export interface SliceRect {
@@ -47,21 +58,54 @@ export interface SliceRect {
* The abstract class that needs to be implemented by all tracks.
*/
export abstract class Track<Config = {}, Data extends TrackData = TrackData> {
- private trackId: string;
- constructor(trackState: TrackState) {
- this.trackId = trackState.id;
+ // The UI-generated track ID (not to be confused with the SQL track.id).
+ protected readonly trackId: string;
+ protected readonly engine: Engine;
+
+ // When true this is a new controller-less track type.
+ // TODO(hjd): eventually all tracks will be controller-less and this
+ // should be removed then.
+ protected frontendOnly = false;
+
+ // Caches the last state.track[this.trackId]. This is to deal with track
+ // deletion, see comments in trackState() below.
+ private lastTrackState: TrackState;
+
+ constructor(args: NewTrackArgs) {
+ this.trackId = args.trackId;
+ this.engine = args.engine;
+ this.lastTrackState = assertExists(globals.state.tracks[this.trackId]);
}
+
+ // Last call the track will receive. Called just before the last reference to
+ // this object is removed.
+ onDestroy() {}
+
protected abstract renderCanvas(ctx: CanvasRenderingContext2D): void;
protected get trackState(): TrackState {
- return globals.state.tracks[this.trackId];
+ // We can end up in a state where a Track is still in the mithril renderer
+ // tree but its corresponding state has been deleted. This can happen in the
+ // interval of time between a track being removed from the state and the
+ // next animation frame that would remove the Track object. If a mouse event
+ // is dispatched in the meanwhile (or a promise is resolved), we need to be
+ // able to access the state. Hence the caching logic here.
+ const trackState = globals.state.tracks[this.trackId];
+ if (trackState === undefined) {
+ return this.lastTrackState;
+ }
+ this.lastTrackState = trackState;
+ return trackState;
}
get config(): Config {
- return globals.state.tracks[this.trackId].config as Config;
+ return this.trackState.config as Config;
}
data(): Data|undefined {
+ if (this.frontendOnly) {
+ return undefined;
+ }
return globals.trackDataStore.get(this.trackId) as Data;
}
@@ -83,11 +127,13 @@ export abstract class Track<Config = {}, Data extends TrackData = TrackData> {
return false;
}
- onMouseOut() {}
+ onMouseOut(): void {}
+
+ onFullRedraw(): void {}
render(ctx: CanvasRenderingContext2D) {
globals.frontendLocalState.addVisibleTrack(this.trackState.id);
- if (this.data() === undefined) {
+ if (this.data() === undefined && !this.frontendOnly) {
const {visibleWindowTime, timeScale} = globals.frontendLocalState;
const startPx = Math.floor(timeScale.timeToPx(visibleWindowTime.start));
const endPx = Math.ceil(timeScale.timeToPx(visibleWindowTime.end));
@@ -98,37 +144,64 @@ export abstract class Track<Config = {}, Data extends TrackData = TrackData> {
}
drawTrackHoverTooltip(
- ctx: CanvasRenderingContext2D, xPos: number, text: string,
+ ctx: CanvasRenderingContext2D, pos: {x: number, y: number}, text: string,
text2?: string) {
ctx.font = '10px Roboto Condensed';
- const textWidth = ctx.measureText(text).width;
- let width = textWidth;
- let textYPos = this.getHeight() / 2;
+ ctx.textBaseline = 'middle';
+ ctx.textAlign = 'left';
+
+ // TODO(hjd): Avoid measuring text all the time (just use monospace?)
+ const textMetrics = ctx.measureText(text);
+ const text2Metrics = ctx.measureText(text2 || '');
+
+ // Padding on each side of the box containing the tooltip:
+ const paddingPx = 4;
+ // Figure out the width of the tool tip box:
+ let width = Math.max(textMetrics.width, text2Metrics.width);
+ width += paddingPx * 2;
+
+ // and the height:
+ let height = 0;
+ height += textMetrics.fontBoundingBoxAscent;
+ height += textMetrics.fontBoundingBoxDescent;
if (text2 !== undefined) {
- const text2Width = ctx.measureText(text2).width;
- width = Math.max(textWidth, text2Width);
- textYPos = this.getHeight() / 2 - 6;
+ height += text2Metrics.fontBoundingBoxAscent;
+ height += text2Metrics.fontBoundingBoxDescent;
}
+ height += paddingPx * 2;
+
+ let x = pos.x;
+ let y = pos.y;
+
+ // Move box to the top right of the mouse:
+ x += 10;
+ y -= 10;
- // Move tooltip over if it would go off the right edge of the viewport.
- const rectWidth = width + 16;
+ // Ensure the box is on screen:
const endPx = globals.frontendLocalState.timeScale.endPx;
- if (xPos + rectWidth > endPx) {
- xPos -= (xPos + rectWidth - endPx);
+ if (x + width > endPx) {
+ x -= x + width - endPx;
+ }
+ if (y < 0) {
+ y = 0;
+ }
+ if (y + height > this.getHeight()) {
+ y -= y + height - this.getHeight();
}
+ // Draw everything:
ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';
- const rectMargin = this.getHeight() / 12;
- ctx.fillRect(
- xPos, rectMargin, rectWidth, this.getHeight() - rectMargin * 2);
- ctx.fillStyle = 'hsl(200, 50%, 40%)';
- ctx.textAlign = 'left';
- ctx.textBaseline = 'middle';
- ctx.fillText(text, xPos + 8, textYPos);
+ ctx.fillRect(x, y, width, height);
+ ctx.fillStyle = 'hsl(200, 50%, 40%)';
+ ctx.fillText(
+ text, x + paddingPx, y + paddingPx + textMetrics.fontBoundingBoxAscent);
if (text2 !== undefined) {
- ctx.fillText(text2, xPos + 8, this.getHeight() / 2 + 6);
+ const yOffsetPx = textMetrics.fontBoundingBoxAscent +
+ textMetrics.fontBoundingBoxDescent +
+ text2Metrics.fontBoundingBoxAscent;
+ ctx.fillText(text2, x + paddingPx, y + paddingPx + yOffsetPx);
}
}
diff --git a/ui/src/frontend/track_group_panel.ts b/ui/src/frontend/track_group_panel.ts
index c65af875d..e078a5545 100644
--- a/ui/src/frontend/track_group_panel.ts
+++ b/ui/src/frontend/track_group_panel.ts
@@ -49,13 +49,18 @@ export class TrackGroupPanel extends Panel<Attrs> {
private readonly trackGroupId: string;
private shellWidth = 0;
private backgroundColor = '#ffffff'; // Updated from CSS later.
- private summaryTrack: Track;
+ private summaryTrack: Track|undefined;
constructor({attrs}: m.CVnode<Attrs>) {
super();
this.trackGroupId = attrs.trackGroupId;
const trackCreator = trackRegistry.get(this.summaryTrackState.kind);
- this.summaryTrack = trackCreator.create(this.summaryTrackState);
+ const engineId = this.summaryTrackState.engineId;
+ const engine = globals.engines.get(engineId);
+ if (engine !== undefined) {
+ this.summaryTrack =
+ trackCreator.create({trackId: this.summaryTrackState.id, engine});
+ }
}
get trackGroupState(): TrackGroupState {
@@ -76,10 +81,9 @@ export class TrackGroupPanel extends Panel<Attrs> {
// The shell should be highlighted if the current search result is inside
// this track group.
let highlightClass = '';
- const searchIndex = globals.frontendLocalState.searchIndex;
+ const searchIndex = globals.state.searchIndex;
if (searchIndex !== -1) {
- const trackId = globals.currentSearchResults
- .trackIds[globals.frontendLocalState.searchIndex];
+ const trackId = globals.currentSearchResults.trackIds[searchIndex];
const parentTrackId = getContainingTrackId(globals.state, trackId);
if (parentTrackId === attrs.trackGroupId) {
highlightClass = 'flash';
@@ -102,6 +106,12 @@ export class TrackGroupPanel extends Panel<Attrs> {
}
}
+ let child = null;
+ if (this.summaryTrackState.labels &&
+ this.summaryTrackState.labels.length > 0) {
+ child = m('span', this.summaryTrackState.labels.join(', '));
+ }
+
return m(
`.track-group-panel[collapsed=${collapsed}]`,
{id: 'track_' + this.trackGroupId},
@@ -119,11 +129,11 @@ export class TrackGroupPanel extends Panel<Attrs> {
m('.fold-button',
m('i.material-icons',
this.trackGroupState.collapsed ? EXPAND_DOWN : EXPAND_UP)),
- m('h1',
- {
- title: name,
- },
- name),
+ m('h1.track-title',
+ {title: name},
+ name,
+ ('namespace' in this.summaryTrackState.config) &&
+ m('span.chip', 'metric')),
selection && selection.kind === 'AREA' ?
m('i.material-icons.track-button',
{
@@ -136,7 +146,10 @@ export class TrackGroupPanel extends Panel<Attrs> {
checkBox) :
''),
- this.summaryTrack ? m(TrackContent, {track: this.summaryTrack}) : null);
+ this.summaryTrack ? m(TrackContent,
+ {track: this.summaryTrack},
+ this.trackGroupState.collapsed ? '' : child) :
+ null);
}
oncreate(vnode: m.CVnodeDOM<Attrs>) {
@@ -154,6 +167,16 @@ export class TrackGroupPanel extends Panel<Attrs> {
this.backgroundColor =
getComputedStyle(dom).getPropertyValue('--expanded-background');
}
+ if (this.summaryTrack !== undefined) {
+ this.summaryTrack.onFullRedraw();
+ }
+ }
+
+ onremove() {
+ if (this.summaryTrack !== undefined) {
+ this.summaryTrack.onDestroy();
+ this.summaryTrack = undefined;
+ }
}
highlightIfTrackSelected(ctx: CanvasRenderingContext2D, size: PanelSize) {
@@ -201,19 +224,19 @@ export class TrackGroupPanel extends Panel<Attrs> {
const localState = globals.frontendLocalState;
// Draw vertical line when hovering on the notes panel.
- if (localState.hoveredNoteTimestamp !== -1) {
+ if (globals.state.hoveredNoteTimestamp !== -1) {
drawVerticalLineAtTime(
ctx,
localState.timeScale,
- localState.hoveredNoteTimestamp,
+ globals.state.hoveredNoteTimestamp,
size.height,
`#aaa`);
}
- if (localState.hoveredLogsTimestamp !== -1) {
+ if (globals.state.hoveredLogsTimestamp !== -1) {
drawVerticalLineAtTime(
ctx,
localState.timeScale,
- localState.hoveredLogsTimestamp,
+ globals.state.hoveredLogsTimestamp,
size.height,
`#344596`);
}
diff --git a/ui/src/frontend/track_panel.ts b/ui/src/frontend/track_panel.ts
index e982f9907..e4796286e 100644
--- a/ui/src/frontend/track_panel.ts
+++ b/ui/src/frontend/track_panel.ts
@@ -61,10 +61,9 @@ class TrackShell implements m.ClassComponent<TrackShellAttrs> {
// The shell should be highlighted if the current search result is inside
// this track.
let highlightClass = '';
- const searchIndex = globals.frontendLocalState.searchIndex;
+ const searchIndex = globals.state.searchIndex;
if (searchIndex !== -1) {
- const trackId = globals.currentSearchResults
- .trackIds[globals.frontendLocalState.searchIndex];
+ const trackId = globals.currentSearchResults.trackIds[searchIndex];
if (trackId === attrs.trackState.id) {
highlightClass = 'flash';
}
@@ -83,11 +82,15 @@ class TrackShell implements m.ClassComponent<TrackShellAttrs> {
ondragleave: this.ondragleave.bind(this),
ondrop: this.ondrop.bind(this),
},
- m('h1',
- {
- title: attrs.trackState.name,
- },
- attrs.trackState.name),
+ m(
+ 'h1',
+ {
+ title: attrs.trackState.name,
+ },
+ attrs.trackState.name,
+ ('namespace' in attrs.trackState.config) &&
+ m('span.chip', 'metric'),
+ ),
m('.track-buttons',
attrs.track.getTrackShellButtons(),
m(TrackButton, {
@@ -179,47 +182,53 @@ export class TrackContent implements m.ClassComponent<TrackContentAttrs> {
private mouseDownY?: number;
private selectionOccurred = false;
- view({attrs}: m.CVnode<TrackContentAttrs>) {
- return m('.track-content', {
- onmousemove: (e: PerfettoMouseEvent) => {
- attrs.track.onMouseMove({x: e.layerX - TRACK_SHELL_WIDTH, y: e.layerY});
- globals.rafScheduler.scheduleRedraw();
- },
- onmouseout: () => {
- attrs.track.onMouseOut();
- globals.rafScheduler.scheduleRedraw();
- },
- onmousedown: (e: PerfettoMouseEvent) => {
- this.mouseDownX = e.layerX;
- this.mouseDownY = e.layerY;
- },
- onmouseup: (e: PerfettoMouseEvent) => {
- if (this.mouseDownX === undefined || this.mouseDownY === undefined) {
- return;
- }
- if (Math.abs(e.layerX - this.mouseDownX) > 1 ||
- Math.abs(e.layerY - this.mouseDownY) > 1) {
- this.selectionOccurred = true;
- }
- this.mouseDownX = undefined;
- this.mouseDownY = undefined;
- },
- onclick: (e: PerfettoMouseEvent) => {
- // This click event occurs after any selection mouse up/drag events
- // so we have to look if the mouse moved during this click to know
- // if a selection occurred.
- if (this.selectionOccurred) {
- this.selectionOccurred = false;
- return;
- }
- // Returns true if something was selected, so stop propagation.
- if (attrs.track.onMouseClick(
- {x: e.layerX - TRACK_SHELL_WIDTH, y: e.layerY})) {
- e.stopPropagation();
- }
- globals.rafScheduler.scheduleRedraw();
- }
- });
+ view(node: m.CVnode<TrackContentAttrs>) {
+ const attrs = node.attrs;
+ return m(
+ '.track-content',
+ {
+ onmousemove: (e: PerfettoMouseEvent) => {
+ attrs.track.onMouseMove(
+ {x: e.layerX - TRACK_SHELL_WIDTH, y: e.layerY});
+ globals.rafScheduler.scheduleRedraw();
+ },
+ onmouseout: () => {
+ attrs.track.onMouseOut();
+ globals.rafScheduler.scheduleRedraw();
+ },
+ onmousedown: (e: PerfettoMouseEvent) => {
+ this.mouseDownX = e.layerX;
+ this.mouseDownY = e.layerY;
+ },
+ onmouseup: (e: PerfettoMouseEvent) => {
+ if (this.mouseDownX === undefined ||
+ this.mouseDownY === undefined) {
+ return;
+ }
+ if (Math.abs(e.layerX - this.mouseDownX) > 1 ||
+ Math.abs(e.layerY - this.mouseDownY) > 1) {
+ this.selectionOccurred = true;
+ }
+ this.mouseDownX = undefined;
+ this.mouseDownY = undefined;
+ },
+ onclick: (e: PerfettoMouseEvent) => {
+ // This click event occurs after any selection mouse up/drag events
+ // so we have to look if the mouse moved during this click to know
+ // if a selection occurred.
+ if (this.selectionOccurred) {
+ this.selectionOccurred = false;
+ return;
+ }
+ // Returns true if something was selected, so stop propagation.
+ if (attrs.track.onMouseClick(
+ {x: e.layerX - TRACK_SHELL_WIDTH, y: e.layerY})) {
+ e.stopPropagation();
+ }
+ globals.rafScheduler.scheduleRedraw();
+ }
+ },
+ node.children);
}
}
@@ -276,25 +285,63 @@ interface TrackPanelAttrs {
}
export class TrackPanel extends Panel<TrackPanelAttrs> {
- private track: Track;
- private trackState: TrackState;
+ // TODO(hjd): It would be nicer if these could not be undefined here.
+ // We should implement a NullTrack which can be used if the trackState
+ // has disappeared.
+ private track: Track|undefined;
+ private trackState: TrackState|undefined;
+
constructor(vnode: m.CVnode<TrackPanelAttrs>) {
super();
- this.trackState = globals.state.tracks[vnode.attrs.id];
- const trackCreator = trackRegistry.get(this.trackState.kind);
- this.track = trackCreator.create(this.trackState);
+ const trackId = vnode.attrs.id;
+ const trackState = globals.state.tracks[trackId];
+ if (trackState === undefined) {
+ return;
+ }
+ const engine = globals.engines.get(trackState.engineId);
+ if (engine === undefined) {
+ return;
+ }
+ const trackCreator = trackRegistry.get(trackState.kind);
+ this.track = trackCreator.create({trackId, engine});
+ this.trackState = trackState;
}
view() {
+ if (this.track === undefined || this.trackState === undefined) {
+ return m('div', 'No such track');
+ }
return m(TrackComponent, {trackState: this.trackState, track: this.track});
}
+ oncreate() {
+ if (this.track !== undefined) {
+ this.track.onFullRedraw();
+ }
+ }
+
+ onupdate() {
+ if (this.track !== undefined) {
+ this.track.onFullRedraw();
+ }
+ }
+
+ onremove() {
+ if (this.track !== undefined) {
+ this.track.onDestroy();
+ this.track = undefined;
+ }
+ }
+
highlightIfTrackSelected(ctx: CanvasRenderingContext2D, size: PanelSize) {
const localState = globals.frontendLocalState;
const selection = globals.state.currentSelection;
- if (!selection || selection.kind !== 'AREA') return;
+ const trackState = this.trackState;
+ if (!selection || selection.kind !== 'AREA' || trackState === undefined) {
+ return;
+ }
const selectedArea = globals.state.areas[selection.areaId];
- if (selectedArea.tracks.includes(this.trackState.id)) {
+ if (selectedArea.tracks.includes(trackState.id)) {
const timeScale = localState.timeScale;
ctx.fillStyle = 'rgba(131, 152, 230, 0.3)';
ctx.fillRect(
@@ -316,26 +363,28 @@ export class TrackPanel extends Panel<TrackPanelAttrs> {
size.height);
ctx.translate(TRACK_SHELL_WIDTH, 0);
- this.track.render(ctx);
+ if (this.track !== undefined) {
+ this.track.render(ctx);
+ }
ctx.restore();
this.highlightIfTrackSelected(ctx, size);
const localState = globals.frontendLocalState;
// Draw vertical line when hovering on the notes panel.
- if (localState.hoveredNoteTimestamp !== -1) {
+ if (globals.state.hoveredNoteTimestamp !== -1) {
drawVerticalLineAtTime(
ctx,
localState.timeScale,
- localState.hoveredNoteTimestamp,
+ globals.state.hoveredNoteTimestamp,
size.height,
`#aaa`);
}
- if (localState.hoveredLogsTimestamp !== -1) {
+ if (globals.state.hoveredLogsTimestamp !== -1) {
drawVerticalLineAtTime(
ctx,
localState.timeScale,
- localState.hoveredLogsTimestamp,
+ globals.state.hoveredLogsTimestamp,
size.height,
`#344596`);
}
@@ -388,6 +437,9 @@ export class TrackPanel extends Panel<TrackPanelAttrs> {
getSliceRect(tStart: number, tDur: number, depth: number): SliceRect
|undefined {
+ if (this.track === undefined) {
+ return undefined;
+ }
return this.track.getSliceRect(tStart, tDur, depth);
}
}
diff --git a/ui/src/frontend/video_panel.ts b/ui/src/frontend/video_panel.ts
deleted file mode 100644
index 405258cac..000000000
--- a/ui/src/frontend/video_panel.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import * as m from 'mithril';
-
-import {Actions} from '../common/actions';
-import {randomColor} from '../common/colorizer';
-
-import {globals} from './globals';
-
-export class VideoPanel implements m.ClassComponent {
- view() {
- const vidSections = [];
- const offset = globals.state.traceTime.startSec + globals.state.videoOffset;
- vidSections.push(
- m('video', {
- class: 'video-panel',
- controls: true,
- width: 320,
- currentTime: globals.frontendLocalState.vidTimestamp - offset,
- onpause: (e: Event) => {
- const elem = e.target as HTMLVideoElement;
- if (globals.state.flagPauseEnabled && !(elem.ended)) {
- const timestamp = elem.currentTime + offset;
- const color = randomColor();
- const isMovie = true;
- globals.dispatch(Actions.addNote({timestamp, color, isMovie}));
- elem.currentTime = timestamp - offset;
- globals.frontendLocalState.setVidTimestamp(timestamp);
- }
- },
- ontimeupdate: (e: Event) => {
- const elem = e.target as HTMLVideoElement;
- if (globals.state.scrubbingEnabled) {
- elem.currentTime = globals.frontendLocalState.vidTimestamp - offset;
- }
- },
- },
- m('source', { src: globals.state.video, type: 'video/mp4' })));
- const vidMessages = [];
- const pSetting = `Pause/Flag Synchronization: `;
- const pEnabled = `When you pause the video, a video flag ` +
- `will be drawn at this position. \n Also, adding a video flag by ` +
- `clicking on the notes panel (below the time axis) will move the video ` +
- `to this position.`;
- const pDisabled = `Press 'p' to enable.`;
- const tSetting = `Timeline Scrubbing: `;
- const tEnabled = `When you hover over the notes panel, the video will ` +
- `skip to the hovered timestamp.`;
- const tDisabled = `Press 't' to enable.`;
- function makeMsg(setting: boolean, msgType: string, e: string, d: string) {
- return m('h1', { class: `video-panel-${msgType}` }, setting ? e : d);
- }
- vidMessages.push(
- makeMsg(globals.state.flagPauseEnabled, 'setting',
- pSetting.concat('Enabled'), pSetting.concat('Disabled')),
- makeMsg(globals.state.flagPauseEnabled, 'message', pEnabled, pDisabled),
- makeMsg(globals.state.scrubbingEnabled, 'setting',
- tSetting.concat('Enabled'), tSetting.concat('Disabled')),
- makeMsg(globals.state.scrubbingEnabled, 'message', tEnabled, tDisabled));
- vidSections.push(vidMessages);
- return m('.video-panel', vidSections);
- }
-}
diff --git a/ui/src/frontend/viewer_page.ts b/ui/src/frontend/viewer_page.ts
index 2d06c70ca..0cce4726e 100644
--- a/ui/src/frontend/viewer_page.ts
+++ b/ui/src/frontend/viewer_page.ts
@@ -32,7 +32,6 @@ import {TimeSelectionPanel} from './time_selection_panel';
import {DISMISSED_PANNING_HINT_KEY} from './topbar';
import {TrackGroupPanel} from './track_group_panel';
import {TrackPanel} from './track_panel';
-import {VideoPanel} from './video_panel';
const SIDEBAR_WIDTH = 256;
@@ -262,11 +261,7 @@ class TraceViewer implements m.ClassComponent {
doesScroll: true,
panels: scrollingPanels,
kind: 'TRACKS',
- }))),
- m('.video-panel',
- (globals.state.videoEnabled && globals.state.video != null) ?
- m(VideoPanel) :
- null)),
+ })))),
m(DetailsPanel));
}
}
diff --git a/ui/src/service_worker/service_worker.ts b/ui/src/service_worker/service_worker.ts
index fbe555166..b3b34762d 100644
--- a/ui/src/service_worker/service_worker.ts
+++ b/ui/src/service_worker/service_worker.ts
@@ -60,11 +60,11 @@ const INSTALL_TIMEOUT_MS = 30000;
// will get the newer version regardless, unless we hit INDEX_TIMEOUT_MS).
// The latter happens because:
// - / (index.html) is always served from the network (% timeout) and it pulls
-// /v1.2.3/frontend_bundle.js.
-// - /v1.2.3/frontend_bundle.js will register /service_worker.js?v=v1.2.3 .
+// /v1.2-sha/frontend_bundle.js.
+// - /v1.2-sha/frontend_bundle.js will register /service_worker.js?v=v1.2-sha.
// The service_worker.js script itself never changes, but the browser
// re-installs it because the version in the V? query-string argument changes.
-// The reinstallation will cache the new files from the v.1.2.3/manifest.json.
+// The reinstallation will cache the new files from the v.1.2-sha/manifest.json.
self.addEventListener('install', event => {
const doInstall = async () => {
if (await caches.has('BYPASS_SERVICE_WORKER')) {
@@ -79,20 +79,20 @@ self.addEventListener('install', event => {
}
}
- // The UI should register this as service_worker.js?v=v1.2.3. Extract the
+ // The UI should register this as service_worker.js?v=v1.2-sha. Extract the
// version number and pre-fetch all the contents for the version.
- const match = /\bv=([\w.]*)/.exec(location.search);
+ const match = /\bv=([\w.-]*)/.exec(location.search);
if (!match) {
throw new Error(
'Failed to install. Was epecting a query string like ' +
- `?v=v1.2.3 query string, got "${location.search}" instead`);
+ `?v=v1.2-sha query string, got "${location.search}" instead`);
}
await installAppVersionIntoCache(match[1]);
// skipWaiting() still waits for the install to be complete. Without this
// call, the new version would be activated only when all tabs are closed.
// Instead, we ask to activate it immediately. This is safe because the
- // subresources are versioned (e.g. /v1.2.3/frontend_bundle.js). Even if
+ // subresources are versioned (e.g. /v1.2-sha/frontend_bundle.js). Even if
// there is an old UI tab opened while we activate() a newer version, the
// activate() would just cause cache-misses, hence fetch from the network,
// for the old tab.
diff --git a/ui/src/test/example_async_unittest.ts b/ui/src/test/example_async_unittest.ts
deleted file mode 100644
index c6868c18d..000000000
--- a/ui/src/test/example_async_unittest.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-test('example async unittest', async () => {
- const result = await Promise.resolve('foo');
- expect(result).toEqual('foo');
-});
diff --git a/ui/src/test/example_dingus_unittest.ts b/ui/src/test/example_dingus_unittest.ts
deleted file mode 100644
index be42bcb44..000000000
--- a/ui/src/test/example_dingus_unittest.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import {dingus} from 'dingusjs';
-
-interface VoidFunctionWithNumberArg {
- (_: number): void;
-}
-
-class ExampleClass {
- isEven(n: number): boolean {
- return n % 2 === 0;
- }
-}
-
-function* evenNumbers(n: number, math: ExampleClass) {
- for (let i = 0; i < n; i++) {
- if (math.isEven(i)) yield i;
- }
-}
-
-/**
- * Call |f| |n| times (once with each number [0, n)).
- */
-function iterMap(f: VoidFunctionWithNumberArg, n: number): void {
- for (let i = 0; i < n; i++) {
- f(i);
- }
-}
-
-test('example dingus test', () => {
- const d = dingus<VoidFunctionWithNumberArg>();
- iterMap(d, 3);
- expect(d.calls.length).toBe(3);
- expect(d.calls.filter(([_a, args, _b]) => args[0] === 1).length).toBe(1);
-});
-
-test('example dingus test class', () => {
- const d = dingus<ExampleClass>('math');
- // Dingus returns a truthy dingus in all situations - so bear that in mind!
- expect([...evenNumbers(3, d)]).toEqual([0, 1, 2]);
-});
diff --git a/ui/src/test/example_headlesstest.ts b/ui/src/test/example_headlesstest.ts
deleted file mode 100644
index 7d71c18b5..000000000
--- a/ui/src/test/example_headlesstest.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-import * as puppeteer from 'puppeteer';
-
-declare var global: {__BROWSER__: puppeteer.Browser;};
-
-test('example headless test', async () => {
- const browser = global.__BROWSER__;
- await browser.newPage();
-});
diff --git a/ui/src/test/example_jsdomtest.ts b/ui/src/test/example_jsdomtest.ts
deleted file mode 100644
index e8fd60e2e..000000000
--- a/ui/src/test/example_jsdomtest.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-test('example jsdom test', () => {
- const element = document.createElement('div');
- expect(element).not.toBeNull();
-});
diff --git a/ui/src/test/example_unittest.ts b/ui/src/test/example_unittest.ts
deleted file mode 100644
index 5855f4085..000000000
--- a/ui/src/test/example_unittest.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-test('example unit test', () => {
- expect(1 + 1).toBe(2);
-});
diff --git a/ui/src/test/perfetto_ui_test_helper.ts b/ui/src/test/perfetto_ui_test_helper.ts
new file mode 100644
index 000000000..de4a9a814
--- /dev/null
+++ b/ui/src/test/perfetto_ui_test_helper.ts
@@ -0,0 +1,128 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import * as fs from 'fs';
+import * as net from 'net';
+import * as libpng from 'node-libpng';
+import * as path from 'path';
+import * as pixelmatch from 'pixelmatch';
+import * as puppeteer from 'puppeteer';
+
+// These constants have been hand selected by comparing the diffs of screenshots
+// between Linux on Mac. Unfortunately font-rendering is platform-specific.
+// Even though we force the same antialiasing and hinting settings, some minimal
+// differences exist.
+const DIFF_PER_PIXEL_THRESHOLD = 0.35;
+const DIFF_MAX_PIXELS = 50;
+
+// Waits for the Perfetto UI to be quiescent, using a union of heuristics:
+// - Check that the progress bar is not animating.
+// - Check that the omnibox is not showing a message.
+// - Check that no redraws are pending in our RAF scheduler.
+// - Check that all the above is satisfied for |minIdleMs| consecutive ms.
+export async function waitForPerfettoIdle(
+ page: puppeteer.Page, minIdleMs?: number) {
+ minIdleMs = minIdleMs || 3000;
+ const tickMs = 250;
+ const timeoutMs = 60000;
+ const minIdleTicks = Math.ceil(minIdleMs / tickMs);
+ const timeoutTicks = Math.ceil(timeoutMs / tickMs);
+ let consecutiveIdleTicks = 0;
+ let reasons: string[] = [];
+ for (let ticks = 0; ticks < timeoutTicks; ticks++) {
+ await new Promise(r => setTimeout(r, tickMs));
+ const isShowingMsg = !!(await page.$('.omnibox.message-mode'));
+ const isShowingAnim = !!(await page.$('.progress.progress-anim'));
+ const hasPendingRedraws =
+ await (
+ await page.evaluateHandle('globals.rafScheduler.hasPendingRedraws'))
+ .jsonValue<number>();
+
+ if (isShowingAnim || isShowingMsg || hasPendingRedraws) {
+ consecutiveIdleTicks = 0;
+ reasons = [];
+ if (isShowingAnim) {
+ reasons.push('showing progress animation');
+ }
+ if (isShowingMsg) {
+ reasons.push('showing omnibox message');
+ }
+ if (hasPendingRedraws) {
+ reasons.push('has pending redraws');
+ }
+ continue;
+ }
+ if (++consecutiveIdleTicks >= minIdleTicks) {
+ return;
+ }
+ }
+ throw new Error(
+ `waitForPerfettoIdle() failed. Did not reach idle after ${
+ timeoutMs} ms. ` +
+ `Reasons not considered idle: ${reasons.join(', ')}`);
+}
+
+export function getTestTracePath(fname: string): string {
+ const fPath = path.join('test', 'data', fname);
+ if (!fs.existsSync(fPath)) {
+ throw new Error('Could not locate trace file ' + fPath);
+ }
+ return fPath;
+}
+
+export async function compareScreenshots(
+ actualFilename: string, expectedFilename: string) {
+ if (!fs.existsSync(expectedFilename)) {
+ throw new Error(
+ `Could not find ${expectedFilename}. Run wih REBASELINE=1.`);
+ }
+ const actualImg = await libpng.readPngFile(actualFilename);
+ const expectedImg = await libpng.readPngFile(expectedFilename);
+ const {width, height} = actualImg;
+ expect(width).toEqual(expectedImg.width);
+ expect(height).toEqual(expectedImg.height);
+ const diffBuff = Buffer.alloc(actualImg.data.byteLength);
+ const diff = await pixelmatch(
+ actualImg.data, expectedImg.data, diffBuff, width, height, {
+ threshold: DIFF_PER_PIXEL_THRESHOLD
+ });
+ if (diff > DIFF_MAX_PIXELS) {
+ const diffFilename = actualFilename.replace('.png', '-diff.png');
+ libpng.writePngFile(diffFilename, diffBuff, {width, height});
+ fail(`Diff test failed on ${diffFilename}, delta: ${diff} pixels`);
+ }
+ return diff;
+}
+
+
+// If the user has a trace_processor_shell --httpd instance open, bail out,
+// as that will invalidate the test loading different data.
+export async function failIfTraceProcessorHttpdIsActive() {
+ return new Promise<void>((resolve, reject) => {
+ const client = new net.Socket();
+ client.connect(9001, '127.0.0.1', () => {
+ const err = 'trace_processor_shell --httpd detected on port 9001. ' +
+ 'Bailing out as it interferes with the tests. ' +
+ 'Please kill that and run the test again.';
+ console.error(err);
+ client.destroy();
+ reject(err);
+ });
+ client.on('error', (e: {code: string}) => {
+ expect(e.code).toBe('ECONNREFUSED');
+ resolve();
+ });
+ client.end();
+ });
+}
diff --git a/ui/src/test/ui_integrationtest.ts b/ui/src/test/ui_integrationtest.ts
new file mode 100644
index 000000000..f6a442fc5
--- /dev/null
+++ b/ui/src/test/ui_integrationtest.ts
@@ -0,0 +1,278 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import * as fs from 'fs';
+import * as path from 'path';
+import * as puppeteer from 'puppeteer';
+
+import {assertExists} from '../base/logging';
+
+import {
+ compareScreenshots,
+ failIfTraceProcessorHttpdIsActive,
+ getTestTracePath,
+ waitForPerfettoIdle
+} from './perfetto_ui_test_helper';
+
+declare var global: {__BROWSER__: puppeteer.Browser;};
+const browser = assertExists(global.__BROWSER__);
+const expectedScreenshotPath = path.join('test', 'data', 'ui-screenshots');
+
+async function getPage(): Promise<puppeteer.Page> {
+ const pages = (await browser.pages());
+ expect(pages.length).toBe(1);
+ return pages[pages.length - 1];
+}
+
+// Executed once at the beginning of the test. Navigates to the UI.
+beforeAll(async () => {
+ await failIfTraceProcessorHttpdIsActive();
+ jest.setTimeout(60000);
+ const page = await getPage();
+ await page.setViewport({width: 1920, height: 1080});
+});
+
+// After each test (regardless of nesting) capture a screenshot named after the
+// test('') name and compare the screenshot with the expected one in
+// /test/data/ui-screenshots.
+afterEach(async () => {
+ let testName = expect.getState().currentTestName;
+ testName = testName.replace(/[^a-z0-9-]/gmi, '_').toLowerCase();
+ const page = await getPage();
+
+ // cwd() is set to //out/ui when running tests, just create a subdir in there.
+ // The CI picks up this directory and uploads to GCS after every failed run.
+ const tmpDir = path.resolve('./ui-test-artifacts');
+ if (!fs.existsSync(tmpDir)) fs.mkdirSync(tmpDir);
+ const screenshotName = `ui-${testName}.png`;
+ const actualFilename = path.join(tmpDir, screenshotName);
+ const expectedFilename = path.join(expectedScreenshotPath, screenshotName);
+ await page.screenshot({path: actualFilename});
+ const rebaseline = process.env['PERFETTO_UI_TESTS_REBASELINE'] === '1';
+ if (rebaseline) {
+ console.log('Saving reference screenshot into', expectedFilename);
+ fs.copyFileSync(actualFilename, expectedFilename);
+ } else {
+ await compareScreenshots(actualFilename, expectedFilename);
+ }
+});
+
+describe('android_trace_30s', () => {
+ let page: puppeteer.Page;
+
+ beforeAll(async () => {
+ page = await getPage();
+ await page.goto('http://localhost:10000/?testing=1');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('load', async () => {
+ const file = await page.waitForSelector('input.trace_file');
+ const tracePath = getTestTracePath('example_android_trace_30s.pb');
+ assertExists(file).uploadFile(tracePath);
+ await waitForPerfettoIdle(page);
+ });
+
+ test('expand_camera', async () => {
+ await page.click('.main-canvas');
+ await page.click('h1[title="com.google.android.GoogleCamera 5506"]');
+ await page.evaluate(() => {
+ document.querySelector('.scrolling-panel-container')!.scrollTo(0, 400);
+ });
+ await waitForPerfettoIdle(page);
+ });
+
+ // TODO(198431341): Test is flaky. We should de-flake and re-enable.
+ // test('search', async () => {
+ // const page = await getPage();
+ // const searchInput = '.omnibox input';
+ // await page.focus(searchInput);
+ // await page.keyboard.type('TrimMaps');
+ // await waitForPerfettoIdle(page);
+ // for (let i = 0; i < 10; i++) {
+ // await page.keyboard.type('\n');
+ // }
+ // await waitForPerfettoIdle(page);
+ //});
+});
+
+describe('chrome_rendering_desktop', () => {
+ let page: puppeteer.Page;
+
+ beforeAll(async () => {
+ page = await getPage();
+ await page.goto('http://localhost:10000/?testing=1');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('load', async () => {
+ const page = await getPage();
+ const file = await page.waitForSelector('input.trace_file');
+ const tracePath = getTestTracePath('chrome_rendering_desktop.pftrace');
+ assertExists(file).uploadFile(tracePath);
+ await waitForPerfettoIdle(page);
+ });
+
+ test('expand_browser_proc', async () => {
+ const page = await getPage();
+ await page.click('.main-canvas');
+ await page.click('h1[title="Browser 12685"]');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('select_slice_with_flows', async () => {
+ const page = await getPage();
+ const searchInput = '.omnibox input';
+ await page.focus(searchInput);
+ await page.keyboard.type('GenerateRenderPass');
+ await waitForPerfettoIdle(page);
+ for (let i = 0; i < 3; i++) {
+ await page.keyboard.type('\n');
+ }
+ await waitForPerfettoIdle(page);
+ await page.focus('canvas');
+ await page.keyboard.type('f'); // Zoom to selection
+ await waitForPerfettoIdle(page);
+ });
+});
+
+describe('routing', () => {
+ describe('open_two_traces_then_go_back', () => {
+ let page: puppeteer.Page;
+
+ beforeAll(async () => {
+ page = await getPage();
+ await page.goto('http://localhost:10000/?testing=1');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('open_first_trace_from_url', async () => {
+ await page.goto(
+ 'http://localhost:10000/?testing=1/#!/?url=http://localhost:10000/test/data/chrome_memory_snapshot.pftrace');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('open_second_trace_from_url', async () => {
+ await page.goto(
+ 'http://localhost:10000/?testing=1#!/?url=http://localhost:10000/test/data/chrome_scroll_without_vsync.pftrace');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('access_subpage_then_go_back', async () => {
+ await waitForPerfettoIdle(page);
+ await page.goto(
+ 'http://localhost:10000/?testing=1/#!/metrics?local_cache_key=76c25a80-25dd-1eb7-2246-d7b3c7a10f91');
+ await page.goBack();
+ await waitForPerfettoIdle(page);
+ });
+ });
+
+ describe('start_from_no_trace', () => {
+ let page: puppeteer.Page;
+
+ beforeAll(async () => {
+ page = await getPage();
+ await page.goto('about:blank');
+ });
+
+ test('go_to_page_with_no_trace', async () => {
+ await page.goto('http://localhost:10000/?testing=1#!/info');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('open_trace ', async () => {
+ await page.goto(
+ 'http://localhost:10000/?testing=1#!/viewer?local_cache_key=76c25a80-25dd-1eb7-2246-d7b3c7a10f91');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('refresh', async () => {
+ await page.reload();
+ await waitForPerfettoIdle(page);
+ });
+
+ test('open_second_trace', async () => {
+ await page.goto(
+ 'http://localhost:10000/?testing=1#!/viewer?local_cache_key=00000000-0000-0000-e13c-bd7db4ff646f');
+ await waitForPerfettoIdle(page);
+
+ // click on the 'Continue' button in the interstitial
+ await page.click('[id="trace_id_open"]');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('go_back_to_first_trace', async () => {
+ await page.goBack();
+ await waitForPerfettoIdle(page);
+ // click on the 'Continue' button in the interstitial
+ await page.click('[id="trace_id_open"]');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('open_invalid_trace', async () => {
+ await page.goto(
+ 'http://localhost:10000/?testing=1#!/viewer?local_cache_key=invalid');
+ await waitForPerfettoIdle(page);
+ });
+ });
+
+ describe('navigate', () => {
+ let page: puppeteer.Page;
+
+ beforeAll(async () => {
+ page = await getPage();
+ await page.goto('http://localhost:10000/?testing=1');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('open_trace_from_url', async () => {
+ await page.goto(
+ 'http://localhost:10000/?testing=1/#!/?url=http://localhost:10000/test/data/chrome_memory_snapshot.pftrace');
+ await waitForPerfettoIdle(page);
+ });
+
+ test('navigate_back_and_forward', async () => {
+ await page.click('[id="info_and_stats"]');
+ await waitForPerfettoIdle(page);
+ await page.click('[id="metrics"]');
+ await waitForPerfettoIdle(page);
+ await page.goBack();
+ await waitForPerfettoIdle(page);
+ await page.goBack();
+ await waitForPerfettoIdle(page);
+ await page.goForward();
+ await waitForPerfettoIdle(page);
+ await page.goForward();
+ await waitForPerfettoIdle(page);
+ });
+ });
+
+ test('open_trace_and_go_back_to_landing_page', async () => {
+ const page = await getPage();
+ await page.goto('http://localhost:10000/?testing=1');
+ await page.goto(
+ 'http://localhost:10000/?testing=1#!/viewer?local_cache_key=76c25a80-25dd-1eb7-2246-d7b3c7a10f91');
+ await waitForPerfettoIdle(page);
+ await page.goBack();
+ await waitForPerfettoIdle(page);
+ });
+
+ test('open_invalid_trace_from_blank_page', async () => {
+ const page = await getPage();
+ await page.goto('about:blank');
+ await page.goto(
+ 'http://localhost:10000/?testing=1#!/viewer?local_cache_key=invalid');
+ await waitForPerfettoIdle(page);
+ });
+});
diff --git a/ui/src/traceconv/index.ts b/ui/src/traceconv/index.ts
new file mode 100644
index 000000000..c3f211ba4
--- /dev/null
+++ b/ui/src/traceconv/index.ts
@@ -0,0 +1,235 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {defer} from '../base/deferred';
+import {assertExists, reportError, setErrorHandler} from '../base/logging';
+import {
+ ConversionJobName,
+ ConversionJobStatus
+} from '../common/conversion_jobs';
+import * as trace_to_text from '../gen/trace_to_text';
+
+const selfWorker = self as {} as Worker;
+
+// TODO(hjd): The trace ends up being copied too many times due to how
+// blob works. We should reduce the number of copies.
+
+type Format = 'json'|'systrace';
+type Args = ConvertTraceAndDownloadArgs|ConvertTraceAndOpenInLegacyArgs|
+ ConvertTraceToPprofArgs;
+
+function updateStatus(status: string) {
+ selfWorker.postMessage({
+ kind: 'updateStatus',
+ status,
+ });
+}
+
+function updateJobStatus(name: ConversionJobName, status: ConversionJobStatus) {
+ selfWorker.postMessage({
+ kind: 'updateJobStatus',
+ name,
+ status,
+ });
+}
+
+function downloadFile(buffer: Uint8Array, name: string) {
+ selfWorker.postMessage({
+ kind: 'downloadFile',
+ buffer,
+ name,
+ }, [buffer.buffer]);
+}
+
+function openTraceInLegacy(buffer: Uint8Array) {
+ selfWorker.postMessage({
+ kind: 'openTraceInLegacy',
+ buffer,
+ });
+}
+
+function forwardError(error: string) {
+ selfWorker.postMessage({
+ kind: 'error',
+ error,
+ });
+}
+
+function fsNodeToBuffer(fsNode: trace_to_text.FileSystemNode): Uint8Array {
+ const fileSize = assertExists(fsNode.usedBytes);
+ return new Uint8Array(fsNode.contents.buffer, 0, fileSize);
+}
+
+async function runTraceconv(trace: Blob, args: string[]) {
+ const deferredRuntimeInitialized = defer<void>();
+ const module = trace_to_text({
+ noInitialRun: true,
+ locateFile: (s: string) => s,
+ print: updateStatus,
+ printErr: updateStatus,
+ onRuntimeInitialized: () => deferredRuntimeInitialized.resolve()
+ });
+ await deferredRuntimeInitialized;
+ module.FS.mkdir('/fs');
+ module.FS.mount(
+ assertExists(module.FS.filesystems.WORKERFS),
+ {blobs: [{name: 'trace.proto', data: trace}]},
+ '/fs');
+ updateStatus('Converting trace');
+ module.callMain(args);
+ updateStatus('Trace conversion completed');
+ return module;
+}
+
+interface ConvertTraceAndDownloadArgs {
+ kind: 'ConvertTraceAndDownload';
+ trace: Blob;
+ format: Format;
+ truncate?: 'start'|'end';
+}
+
+function isConvertTraceAndDownload(msg: Args):
+ msg is ConvertTraceAndDownloadArgs {
+ if (msg.kind !== 'ConvertTraceAndDownload') {
+ return false;
+ }
+ if (msg.trace === undefined) {
+ throw new Error('ConvertTraceAndDownloadArgs missing trace');
+ }
+ if (msg.format !== 'json' && msg.format !== 'systrace') {
+ throw new Error('ConvertTraceAndDownloadArgs has bad format');
+ }
+ return true;
+}
+
+async function ConvertTraceAndDownload(
+ trace: Blob,
+ format: Format,
+ truncate?: 'start'|'end'): Promise<void> {
+ const jobName = format === 'json' ? 'convert_json' : 'convert_systrace';
+ updateJobStatus(jobName, ConversionJobStatus.InProgress);
+ const outPath = '/trace.json';
+ const args: string[] = [format];
+ if (truncate !== undefined) {
+ args.push('--truncate', truncate);
+ }
+ args.push('/fs/trace.proto', outPath);
+ try {
+ const module = await runTraceconv(trace, args);
+ const fsNode = module.FS.lookupPath(outPath).node;
+ downloadFile(fsNodeToBuffer(fsNode), `trace.${format}`);
+ module.FS.unlink(outPath);
+ } finally {
+ updateJobStatus(jobName, ConversionJobStatus.NotRunning);
+ }
+}
+
+interface ConvertTraceAndOpenInLegacyArgs {
+ kind: 'ConvertTraceAndOpenInLegacy';
+ trace: Blob;
+ truncate?: 'start'|'end';
+}
+
+function isConvertTraceAndOpenInLegacy(msg: Args):
+ msg is ConvertTraceAndOpenInLegacyArgs {
+ if (msg.kind !== 'ConvertTraceAndOpenInLegacy') {
+ return false;
+ }
+ return true;
+}
+
+async function ConvertTraceAndOpenInLegacy(
+trace: Blob, truncate?: 'start'|'end') {
+ const jobName = 'open_in_legacy';
+ updateJobStatus(jobName, ConversionJobStatus.InProgress);
+ const outPath = '/trace.json';
+ const args: string[] = ['json'];
+ if (truncate !== undefined) {
+ args.push('--truncate', truncate);
+ }
+ args.push('/fs/trace.proto', outPath);
+ try {
+ const module = await runTraceconv( trace, args);
+ const fsNode = module.FS.lookupPath(outPath).node;
+ const data = fsNode.contents.buffer;
+ const size = fsNode.usedBytes;
+ const buffer = new Uint8Array(data, 0, size);
+ openTraceInLegacy(buffer);
+ module.FS.unlink(outPath);
+ } finally {
+ updateJobStatus(jobName, ConversionJobStatus.NotRunning);
+ }
+}
+
+interface ConvertTraceToPprofArgs {
+ kind: 'ConvertTraceToPprof';
+ trace: Blob;
+ pid: number;
+ ts: number;
+}
+
+function isConvertTraceToPprof(msg: Args): msg is ConvertTraceToPprofArgs {
+ if (msg.kind !== 'ConvertTraceToPprof') {
+ return false;
+ }
+ return true;
+}
+
+async function ConvertTraceToPprof(
+trace: Blob, pid: number, ts: number) {
+ const jobName = 'convert_pprof';
+ updateJobStatus(jobName, ConversionJobStatus.InProgress);
+ const args = [
+ 'profile',
+ `--pid`,
+ `${pid}`,
+ `--timestamps`,
+ `${ts}`,
+ '/fs/trace.proto'
+ ];
+
+ try {
+ const module = await runTraceconv(trace, args);
+ const heapDirName =
+ Object.keys(module.FS.lookupPath('/tmp/').node.contents)[0];
+ const heapDirContents =
+ module.FS.lookupPath(`/tmp/${heapDirName}`).node.contents;
+ const heapDumpFiles = Object.keys(heapDirContents);
+ for (let i = 0; i < heapDumpFiles.length; ++i) {
+ const heapDump = heapDumpFiles[i];
+ const fileNode =
+ module.FS.lookupPath(`/tmp/${heapDirName}/${heapDump}`).node;
+ const fileName = `/heap_dump.${i}.${pid}.pb`;
+ downloadFile(fsNodeToBuffer(fileNode), fileName);
+ }
+ } finally {
+ updateJobStatus(jobName, ConversionJobStatus.NotRunning);
+ }
+}
+
+selfWorker.onmessage = (msg: MessageEvent) => {
+ self.addEventListener('error', e => reportError(e));
+ self.addEventListener('unhandledrejection', e => reportError(e));
+ setErrorHandler((err: string) => forwardError(err));
+ const args = msg.data as Args;
+ if (isConvertTraceAndDownload(args)) {
+ ConvertTraceAndDownload(args.trace, args.format, args.truncate);
+ } else if (isConvertTraceAndOpenInLegacy(args)) {
+ ConvertTraceAndOpenInLegacy(args.trace, args.truncate);
+ } else if (isConvertTraceToPprof(args)) {
+ ConvertTraceToPprof(args.trace, args.pid, args.ts);
+ } else {
+ throw new Error(`Unknown method call ${JSON.stringify(args)}`);
+ }
+};
diff --git a/ui/src/tracks/actual_frames/controller.ts b/ui/src/tracks/actual_frames/controller.ts
index b436fbedd..4920c2f07 100644
--- a/ui/src/tracks/actual_frames/controller.ts
+++ b/ui/src/tracks/actual_frames/controller.ts
@@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {assertTrue} from '../../base/logging';
-import {slowlyCountRows} from '../../common/query_iterator';
+import {NUM, NUM_NULL, STR} from '../../common/query_result';
import {fromNs, toNs} from '../../common/time';
import {
TrackController,
@@ -46,26 +45,26 @@ class ActualFramesSliceTrackController extends TrackController<Config, Data> {
if (this.maxDurNs === 0) {
const maxDurResult = await this.query(`
- select max(iif(dur = -1, (SELECT end_ts FROM trace_bounds) - ts, dur))
+ select
+ max(iif(dur = -1, (SELECT end_ts FROM trace_bounds) - ts, dur))
+ as maxDur
from experimental_slice_layout
where filter_track_ids = '${this.config.trackIds.join(',')}'
`);
- if (slowlyCountRows(maxDurResult) === 1) {
- this.maxDurNs = maxDurResult.columns[0].longValues![0];
- }
+ this.maxDurNs = maxDurResult.firstRow({maxDur: NUM_NULL}).maxDur || 0;
}
const rawResult = await this.query(`
SELECT
(s.ts + ${bucketNs / 2}) / ${bucketNs} * ${bucketNs} as tsq,
- s.ts,
+ s.ts as ts,
max(iif(s.dur = -1, (SELECT end_ts FROM trace_bounds) - s.ts, s.dur))
as dur,
- s.layout_depth,
- s.name,
- s.id,
- s.dur = 0 as is_instant,
- s.dur = -1 as is_incomplete,
+ s.layout_depth as layoutDepth,
+ s.name as name,
+ s.id as id,
+ s.dur = 0 as isInstant,
+ s.dur = -1 as isIncomplete,
CASE afs.jank_tag
WHEN 'Self Jank' THEN '${RED_COLOR}'
WHEN 'Other Jank' THEN '${YELLOW_COLOR}'
@@ -85,7 +84,7 @@ class ActualFramesSliceTrackController extends TrackController<Config, Data> {
order by tsq, s.layout_depth
`);
- const numRows = slowlyCountRows(rawResult);
+ const numRows = rawResult.numRows();
const slices: Data = {
start,
end,
@@ -112,26 +111,34 @@ class ActualFramesSliceTrackController extends TrackController<Config, Data> {
return idx;
}
- const cols = rawResult.columns;
- for (let row = 0; row < numRows; row++) {
- const startNsQ = +cols[0].longValues![row];
- const startNs = +cols[1].longValues![row];
- const durNs = +cols[2].longValues![row];
+ const it = rawResult.iter({
+ 'tsq': NUM,
+ 'ts': NUM,
+ 'dur': NUM,
+ 'layoutDepth': NUM,
+ 'id': NUM,
+ 'name': STR,
+ 'isInstant': NUM,
+ 'isIncomplete': NUM,
+ 'color': STR,
+ });
+ for (let i = 0; it.valid(); i++, it.next()) {
+ const startNsQ = it.tsq;
+ const startNs = it.ts;
+ const durNs = it.dur;
const endNs = startNs + durNs;
let endNsQ = Math.floor((endNs + bucketNs / 2 - 1) / bucketNs) * bucketNs;
endNsQ = Math.max(endNsQ, startNsQ + bucketNs);
- assertTrue(startNsQ !== endNsQ);
-
- slices.starts[row] = fromNs(startNsQ);
- slices.ends[row] = fromNs(endNsQ);
- slices.depths[row] = +cols[3].longValues![row];
- slices.titles[row] = internString(cols[4].stringValues![row]);
- slices.colors![row] = internString(cols[8].stringValues![row]);
- slices.sliceIds[row] = +cols[5].longValues![row];
- slices.isInstant[row] = +cols[6].longValues![row];
- slices.isIncomplete[row] = +cols[7].longValues![row];
+ slices.starts[i] = fromNs(startNsQ);
+ slices.ends[i] = fromNs(endNsQ);
+ slices.depths[i] = it.layoutDepth;
+ slices.titles[i] = internString(it.name);
+ slices.colors![i] = internString(it.color);
+ slices.sliceIds[i] = it.id;
+ slices.isInstant[i] = it.isInstant;
+ slices.isIncomplete[i] = it.isIncomplete;
}
return slices;
}
diff --git a/ui/src/tracks/actual_frames/frontend.ts b/ui/src/tracks/actual_frames/frontend.ts
index 3c9159849..d9b9fbaac 100644
--- a/ui/src/tracks/actual_frames/frontend.ts
+++ b/ui/src/tracks/actual_frames/frontend.ts
@@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {TrackState} from '../../common/state';
-import {Track} from '../../frontend/track';
+import {NewTrackArgs, Track} from '../../frontend/track';
import {trackRegistry} from '../../frontend/track_registry';
import {ChromeSliceTrack} from '../chrome_slices/frontend';
@@ -21,8 +20,8 @@ import {ACTUAL_FRAMES_SLICE_TRACK_KIND} from './common';
export class ActualFramesSliceTrack extends ChromeSliceTrack {
static readonly kind = ACTUAL_FRAMES_SLICE_TRACK_KIND;
- static create(trackState: TrackState): Track {
- return new ActualFramesSliceTrack(trackState);
+ static create(args: NewTrackArgs): Track {
+ return new ActualFramesSliceTrack(args);
}
}
diff --git a/ui/src/tracks/actual_frames/index.ts b/ui/src/tracks/actual_frames/index.ts
new file mode 100644
index 000000000..308406efb
--- /dev/null
+++ b/ui/src/tracks/actual_frames/index.ts
@@ -0,0 +1,16 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import './controller';
+import './frontend';
diff --git a/ui/src/tracks/all_controller.ts b/ui/src/tracks/all_controller.ts
deleted file mode 100644
index ca0b5c5b2..000000000
--- a/ui/src/tracks/all_controller.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Import all currently implemented tracks. After implemeting a new track, an
-// import statement for it needs to be added here.
-import './android_log/controller';
-import './chrome_slices/controller';
-import './counter/controller';
-import './heap_profile/controller';
-import './cpu_freq/controller';
-import './cpu_profile/controller';
-import './cpu_slices/controller';
-import './process_scheduling/controller';
-import './process_summary/controller';
-import './thread_state/controller';
-import './async_slices/controller';
-import './debug_slices/controller';
-import './actual_frames/controller';
-import './expected_frames/controller';
diff --git a/ui/src/tracks/all_frontend.ts b/ui/src/tracks/all_frontend.ts
deleted file mode 100644
index 6af4d2209..000000000
--- a/ui/src/tracks/all_frontend.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Import all currently implemented tracks. After implemeting a new track, an
-// import statement for it needs to be added here.
-import './android_log/frontend';
-import './chrome_slices/frontend';
-import './counter/frontend';
-import './heap_profile/frontend';
-import './cpu_freq/frontend';
-import './cpu_profile/frontend';
-import './cpu_slices/frontend';
-import './process_scheduling/frontend';
-import './process_summary/frontend';
-import './thread_state/frontend';
-import './async_slices/frontend';
-import './debug_slices/frontend';
-import './actual_frames/frontend';
-import './expected_frames/frontend';
diff --git a/ui/src/tracks/android_log/controller.ts b/ui/src/tracks/android_log/controller.ts
index afd235cef..b1ca9d268 100644
--- a/ui/src/tracks/android_log/controller.ts
+++ b/ui/src/tracks/android_log/controller.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {slowlyCountRows} from '../../common/query_iterator';
+import {NUM} from '../../common/query_result';
import {fromNs, toNsCeil, toNsFloor} from '../../common/time';
import {LIMIT} from '../../common/track_data';
import {
@@ -33,17 +33,17 @@ class AndroidLogTrackController extends TrackController<Config, Data> {
// |resolution| is in s/px the frontend wants.
const quantNs = toNsCeil(resolution);
- const rawResult = await this.query(`
+ const queryRes = await this.query(`
select
- cast(ts / ${quantNs} as integer) * ${quantNs} as ts_quant,
+ cast(ts / ${quantNs} as integer) * ${quantNs} as tsQuant,
prio,
- count(prio)
+ count(prio) as numEvents
from android_logs
where ts >= ${startNs} and ts <= ${endNs}
- group by ts_quant, prio
- order by ts_quant, prio limit ${LIMIT};`);
+ group by tsQuant, prio
+ order by tsQuant, prio limit ${LIMIT};`);
- const rowCount = slowlyCountRows(rawResult);
+ const rowCount = queryRes.numRows();
const result = {
start,
end,
@@ -53,12 +53,14 @@ class AndroidLogTrackController extends TrackController<Config, Data> {
timestamps: new Float64Array(rowCount),
priorities: new Uint8Array(rowCount),
};
- const cols = rawResult.columns;
- for (let i = 0; i < rowCount; i++) {
- result.timestamps[i] = fromNs(+cols[0].longValues![i]);
- const prio = Math.min(+cols[1].longValues![i], 7);
- result.priorities[i] |= (1 << prio);
- result.numEvents += +cols[2].longValues![i];
+
+
+ const it = queryRes.iter({tsQuant: NUM, prio: NUM, numEvents: NUM});
+ for (let row = 0; it.valid(); it.next(), row++) {
+ result.timestamps[row] = fromNs(it.tsQuant);
+ const prio = Math.min(it.prio, 7);
+ result.priorities[row] |= (1 << prio);
+ result.numEvents += it.numEvents;
}
return result;
}
diff --git a/ui/src/tracks/android_log/frontend.ts b/ui/src/tracks/android_log/frontend.ts
index 76f3aa7d0..0aea2fcb0 100644
--- a/ui/src/tracks/android_log/frontend.ts
+++ b/ui/src/tracks/android_log/frontend.ts
@@ -12,10 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {TrackState} from '../../common/state';
import {checkerboardExcept} from '../../frontend/checkerboard';
import {globals} from '../../frontend/globals';
-import {Track} from '../../frontend/track';
+import {NewTrackArgs, Track} from '../../frontend/track';
import {trackRegistry} from '../../frontend/track_registry';
import {ANDROID_LOGS_TRACK_KIND, Config, Data} from './common';
@@ -40,12 +39,12 @@ const EVT_PX = 2; // Width of an event tick in pixels.
class AndroidLogTrack extends Track<Config, Data> {
static readonly kind = ANDROID_LOGS_TRACK_KIND;
- static create(trackState: TrackState): AndroidLogTrack {
- return new AndroidLogTrack(trackState);
+ static create(args: NewTrackArgs): AndroidLogTrack {
+ return new AndroidLogTrack(args);
}
- constructor(trackState: TrackState) {
- super(trackState);
+ constructor(args: NewTrackArgs) {
+ super(args);
}
renderCanvas(ctx: CanvasRenderingContext2D): void {
diff --git a/ui/src/tracks/android_log/index.ts b/ui/src/tracks/android_log/index.ts
new file mode 100644
index 000000000..308406efb
--- /dev/null
+++ b/ui/src/tracks/android_log/index.ts
@@ -0,0 +1,16 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import './controller';
+import './frontend';
diff --git a/ui/src/tracks/async_slices/controller.ts b/ui/src/tracks/async_slices/controller.ts
index 50a074a28..fa819053f 100644
--- a/ui/src/tracks/async_slices/controller.ts
+++ b/ui/src/tracks/async_slices/controller.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {slowlyCountRows} from '../../common/query_iterator';
+import {NUM, NUM_NULL, STR} from '../../common/query_result';
import {fromNs, toNs} from '../../common/time';
import {
TrackController,
@@ -39,24 +39,22 @@ class AsyncSliceTrackController extends TrackController<Config, Data> {
if (this.maxDurNs === 0) {
const maxDurResult = await this.query(`
select max(iif(dur = -1, (SELECT end_ts FROM trace_bounds) - ts, dur))
- from experimental_slice_layout
+ as maxDur from experimental_slice_layout
where filter_track_ids = '${this.config.trackIds.join(',')}'
`);
- if (slowlyCountRows(maxDurResult) === 1) {
- this.maxDurNs = maxDurResult.columns[0].longValues![0];
- }
+ this.maxDurNs = maxDurResult.firstRow({maxDur: NUM_NULL}).maxDur || 0;
}
- const rawResult = await this.query(`
+ const queryRes = await this.query(`
SELECT
(ts + ${bucketNs / 2}) / ${bucketNs} * ${bucketNs} as tsq,
ts,
max(iif(dur = -1, (SELECT end_ts FROM trace_bounds) - ts, dur)) as dur,
- layout_depth,
- name,
+ layout_depth as depth,
+ ifnull(name, '[null]') as name,
id,
- dur = 0 as is_instant,
- dur = -1 as is_incomplete
+ dur = 0 as isInstant,
+ dur = -1 as isIncomplete
from experimental_slice_layout
where
filter_track_ids = '${this.config.trackIds.join(',')}' and
@@ -66,7 +64,7 @@ class AsyncSliceTrackController extends TrackController<Config, Data> {
order by tsq, layout_depth
`);
- const numRows = slowlyCountRows(rawResult);
+ const numRows = queryRes.numRows();
const slices: Data = {
start,
end,
@@ -92,31 +90,35 @@ class AsyncSliceTrackController extends TrackController<Config, Data> {
return idx;
}
- const cols = rawResult.columns;
- for (let row = 0; row < numRows; row++) {
- const startNsQ = +cols[0].longValues![row];
- const startNs = +cols[1].longValues![row];
- const durNs = +cols[2].longValues![row];
+ const it = queryRes.iter({
+ tsq: NUM,
+ ts: NUM,
+ dur: NUM,
+ depth: NUM,
+ name: STR,
+ id: NUM,
+ isInstant: NUM,
+ isIncomplete: NUM
+ });
+ for (let row = 0; it.valid(); it.next(), row++) {
+ const startNsQ = it.tsq;
+ const startNs = it.ts;
+ const durNs = it.dur;
const endNs = startNs + durNs;
let endNsQ = Math.floor((endNs + bucketNs / 2 - 1) / bucketNs) * bucketNs;
endNsQ = Math.max(endNsQ, startNsQ + bucketNs);
- if (startNsQ === endNsQ) {
- throw new Error('Should never happen');
- }
-
slices.starts[row] = fromNs(startNsQ);
slices.ends[row] = fromNs(endNsQ);
- slices.depths[row] = +cols[3].longValues![row];
- slices.titles[row] = internString(cols[4].stringValues![row]);
- slices.sliceIds[row] = +cols[5].longValues![row];
- slices.isInstant[row] = +cols[6].longValues![row];
- slices.isIncomplete[row] = +cols[7].longValues![row];
+ slices.depths[row] = it.depth;
+ slices.titles[row] = internString(it.name);
+ slices.sliceIds[row] = it.id;
+ slices.isInstant[row] = it.isInstant;
+ slices.isIncomplete[row] = it.isIncomplete;
}
return slices;
}
}
-
trackControllerRegistry.register(AsyncSliceTrackController);
diff --git a/ui/src/tracks/async_slices/frontend.ts b/ui/src/tracks/async_slices/frontend.ts
index 17d4d1456..9f02fa103 100644
--- a/ui/src/tracks/async_slices/frontend.ts
+++ b/ui/src/tracks/async_slices/frontend.ts
@@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {TrackState} from '../../common/state';
-import {Track} from '../../frontend/track';
+import {NewTrackArgs, Track} from '../../frontend/track';
import {trackRegistry} from '../../frontend/track_registry';
import {ChromeSliceTrack} from '../chrome_slices/frontend';
@@ -21,8 +20,8 @@ import {ASYNC_SLICE_TRACK_KIND} from './common';
export class AsyncSliceTrack extends ChromeSliceTrack {
static readonly kind = ASYNC_SLICE_TRACK_KIND;
- static create(trackState: TrackState): Track {
- return new AsyncSliceTrack(trackState);
+ static create(args: NewTrackArgs): Track {
+ return new AsyncSliceTrack(args);
}
}
diff --git a/ui/src/tracks/async_slices/index.ts b/ui/src/tracks/async_slices/index.ts
new file mode 100644
index 000000000..308406efb
--- /dev/null
+++ b/ui/src/tracks/async_slices/index.ts
@@ -0,0 +1,16 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import './controller';
+import './frontend';
diff --git a/ui/src/tracks/chrome_slices/common.ts b/ui/src/tracks/chrome_slices/common.ts
index 41fc2f8f5..7b8074374 100644
--- a/ui/src/tracks/chrome_slices/common.ts
+++ b/ui/src/tracks/chrome_slices/common.ts
@@ -20,6 +20,7 @@ export interface Config {
maxDepth: number;
namespace: string;
trackId: number;
+ isThreadSlice?: boolean;
}
export interface Data extends TrackData {
@@ -33,4 +34,5 @@ export interface Data extends TrackData {
colors?: Uint16Array; // Index into strings.
isInstant: Uint16Array;
isIncomplete: Uint16Array;
+ cpuTimeRatio?: Float64Array;
}
diff --git a/ui/src/tracks/chrome_slices/controller.ts b/ui/src/tracks/chrome_slices/controller.ts
index 2f293881d..5c2cc0619 100644
--- a/ui/src/tracks/chrome_slices/controller.ts
+++ b/ui/src/tracks/chrome_slices/controller.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {slowlyCountRows} from '../../common/query_iterator';
+import {NUM, NUM_NULL, STR} from '../../common/query_result';
import {fromNs, toNs} from '../../common/time';
import {
TrackController,
@@ -21,6 +21,8 @@ import {
import {Config, Data, SLICE_TRACK_KIND} from './common';
+// the lowest bucketNs gets is 2, but add some room in case of fp error
+const MIN_QUANT_NS = 3;
class ChromeSliceTrackController extends TrackController<Config, Data> {
static readonly kind = SLICE_TRACK_KIND;
@@ -36,36 +38,49 @@ class ChromeSliceTrackController extends TrackController<Config, Data> {
// ns per quantization bucket (i.e. ns per pixel). /2 * 2 is to force it to
// be an even number, so we can snap in the middle.
const bucketNs = Math.max(Math.round(resolution * 1e9 * pxSize / 2) * 2, 1);
- const tableName = this.namespaceTable('slice');
+
+ const isThreadSlice = this.config.isThreadSlice;
+ let tableName = this.namespaceTable('slice');
+ let threadDurQuery = ', dur';
+ if (isThreadSlice) {
+ tableName = this.namespaceTable('thread_slice');
+ threadDurQuery = ', iif(thread_dur IS NULL, dur, thread_dur)';
+ }
if (this.maxDurNs === 0) {
const query = `
SELECT max(iif(dur = -1, (SELECT end_ts FROM trace_bounds) - ts, dur))
- FROM ${tableName} WHERE track_id = ${this.config.trackId}`;
- const rawResult = await this.query(query);
- if (slowlyCountRows(rawResult) === 1) {
- this.maxDurNs = rawResult.columns[0].longValues![0];
- }
+ AS maxDur FROM ${tableName} WHERE track_id = ${this.config.trackId}`;
+ const queryRes = await this.query(query);
+ this.maxDurNs = queryRes.firstRow({maxDur: NUM_NULL}).maxDur || 0;
+ }
+
+ // Buckets are always even and positive, don't quantize once we zoom to
+ // nanosecond-scale, so that we can see exact sizes.
+ let tsq = `ts`;
+ if (bucketNs > MIN_QUANT_NS) {
+ tsq = `(ts + ${bucketNs / 2}) / ${bucketNs} * ${bucketNs}`;
}
const query = `
SELECT
- (ts + ${bucketNs / 2}) / ${bucketNs} * ${bucketNs} as tsq,
+ ${tsq} as tsq,
ts,
- max(iif(dur = -1, (SELECT end_ts FROM trace_bounds) - ts, dur)),
+ max(iif(dur = -1, (SELECT end_ts FROM trace_bounds) - ts, dur)) as dur,
depth,
- id as slice_id,
- name,
- dur = 0 as is_instant,
- dur = -1 as is_incomplete
+ id as sliceId,
+ ifnull(name, '[null]') as name,
+ dur = 0 as isInstant,
+ dur = -1 as isIncomplete
+ ${threadDurQuery} as threadDur
FROM ${tableName}
WHERE track_id = ${this.config.trackId} AND
ts >= (${startNs - this.maxDurNs}) AND
ts <= ${endNs}
GROUP BY depth, tsq`;
- const rawResult = await this.query(query);
+ const queryRes = await this.query(query);
- const numRows = slowlyCountRows(rawResult);
+ const numRows = queryRes.numRows();
const slices: Data = {
start,
end,
@@ -79,6 +94,7 @@ class ChromeSliceTrackController extends TrackController<Config, Data> {
titles: new Uint16Array(numRows),
isInstant: new Uint16Array(numRows),
isIncomplete: new Uint16Array(numRows),
+ cpuTimeRatio: new Float64Array(numRows)
};
const stringIndexes = new Map<string, number>();
@@ -91,33 +107,55 @@ class ChromeSliceTrackController extends TrackController<Config, Data> {
return idx;
}
- const cols = rawResult.columns;
- for (let row = 0; row < numRows; row++) {
- const startNsQ = +cols[0].longValues![row];
- const startNs = +cols[1].longValues![row];
- const durNs = +cols[2].longValues![row];
+ const it = queryRes.iter({
+ tsq: NUM,
+ ts: NUM,
+ dur: NUM,
+ depth: NUM,
+ sliceId: NUM,
+ name: STR,
+ isInstant: NUM,
+ isIncomplete: NUM,
+ threadDur: NUM
+ });
+ for (let row = 0; it.valid(); it.next(), row++) {
+ const startNsQ = it.tsq;
+ const startNs = it.ts;
+ const durNs = it.dur;
const endNs = startNs + durNs;
- const isInstant = +cols[6].longValues![row];
- const isIncomplete = +cols[7].longValues![row];
-
- let endNsQ = Math.floor((endNs + bucketNs / 2 - 1) / bucketNs) * bucketNs;
- endNsQ = Math.max(endNsQ, startNsQ + bucketNs);
-
- if (!isInstant && startNsQ === endNsQ) {
- throw new Error(
- 'Expected startNsQ and endNsQ to differ (' +
- `startNsQ: ${startNsQ}, startNs: ${startNs},` +
- ` endNsQ: ${endNsQ}, durNs: ${durNs},` +
- ` endNs: ${endNs}, bucketNs: ${bucketNs})`);
+
+ let endNsQ = endNs;
+ if (bucketNs > MIN_QUANT_NS) {
+ endNsQ = Math.floor((endNs + bucketNs / 2 - 1) / bucketNs) * bucketNs;
+ endNsQ = Math.max(endNsQ, startNsQ + bucketNs);
+ }
+
+ let isInstant = it.isInstant;
+ // Floating point rounding with large numbers of nanoseconds can mean
+ // there isn't enough precision to distinguish the start and end of a very
+ // short event so we just display the event as an instant when zoomed in
+ // rather than fail completely if the start and end time are the same.
+ if (startNsQ === endNsQ) {
+ isInstant = 1;
}
slices.starts[row] = fromNs(startNsQ);
slices.ends[row] = fromNs(endNsQ);
- slices.depths[row] = +cols[3].longValues![row];
- slices.sliceIds[row] = +cols[4].longValues![row];
- slices.titles[row] = internString(cols[5].stringValues![row]);
+ slices.depths[row] = it.depth;
+ slices.sliceIds[row] = it.sliceId;
+ slices.titles[row] = internString(it.name);
slices.isInstant[row] = isInstant;
- slices.isIncomplete[row] = isIncomplete;
+ slices.isIncomplete[row] = it.isIncomplete;
+
+ let cpuTimeRatio = 1;
+ if (!isInstant && !it.isIncomplete) {
+ // Rounding the CPU time ratio to two decimal places and ensuring
+ // it is less than or equal to one, incase the thread duration exceeds
+ // the total duration.
+ cpuTimeRatio =
+ Math.min(Math.round((it.threadDur / it.dur) * 100) / 100, 1);
+ }
+ slices.cpuTimeRatio![row] = cpuTimeRatio;
}
return slices;
}
diff --git a/ui/src/tracks/chrome_slices/frontend.ts b/ui/src/tracks/chrome_slices/frontend.ts
index 403f01bc5..dc286ff74 100644
--- a/ui/src/tracks/chrome_slices/frontend.ts
+++ b/ui/src/tracks/chrome_slices/frontend.ts
@@ -16,12 +16,11 @@ import {hsluvToHex} from 'hsluv';
import {Actions} from '../../common/actions';
import {cropText, drawIncompleteSlice} from '../../common/canvas_utils';
-import {hslForSlice} from '../../common/colorizer';
+import {hslForSlice, hslForThreadIdleSlice} from '../../common/colorizer';
import {TRACE_MARGIN_TIME_S} from '../../common/constants';
-import {TrackState} from '../../common/state';
import {checkerboardExcept} from '../../frontend/checkerboard';
import {globals} from '../../frontend/globals';
-import {SliceRect, Track} from '../../frontend/track';
+import {NewTrackArgs, SliceRect, Track} from '../../frontend/track';
import {trackRegistry} from '../../frontend/track_registry';
import {Config, Data, SLICE_TRACK_KIND} from './common';
@@ -36,14 +35,14 @@ const INNER_CHEVRON_SCALE =
export class ChromeSliceTrack extends Track<Config, Data> {
static readonly kind: string = SLICE_TRACK_KIND;
- static create(trackState: TrackState): Track {
- return new ChromeSliceTrack(trackState);
+ static create(args: NewTrackArgs): Track {
+ return new ChromeSliceTrack(args);
}
private hoveredTitleId = -1;
- constructor(trackState: TrackState) {
- super(trackState);
+ constructor(args: NewTrackArgs) {
+ super(args);
}
renderCanvas(ctx: CanvasRenderingContext2D): void {
@@ -85,6 +84,7 @@ export class ChromeSliceTrack extends Track<Config, Data> {
const isIncomplete = data.isIncomplete[i];
const title = data.strings[titleId];
const colorOverride = data.colors && data.strings[data.colors[i]];
+ const isThreadSlice = this.config.isThreadSlice;
if (isIncomplete) { // incomplete slice
tEnd = visibleWindowTime.end;
}
@@ -101,10 +101,11 @@ export class ChromeSliceTrack extends Track<Config, Data> {
const name = title.replace(/( )?\d+/g, '');
const highlighted = titleId === this.hoveredTitleId ||
- globals.frontendLocalState.highlightedSliceId === sliceId;
+ globals.state.highlightedSliceId === sliceId;
- const [hue, saturation, lightness] =
- hslForSlice(name, highlighted || isSelected);
+ const hasFocus = highlighted || isSelected;
+
+ const [hue, saturation, lightness] = hslForSlice(name, hasFocus);
let color: string;
if (colorOverride === undefined) {
@@ -150,12 +151,27 @@ export class ChromeSliceTrack extends Track<Config, Data> {
}
continue;
}
+
if (isIncomplete && rect.width > SLICE_HEIGHT / 4) {
- drawIncompleteSlice(
- ctx, rect.left, rect.top, rect.width, SLICE_HEIGHT, color);
+ drawIncompleteSlice(ctx, rect.left, rect.top, rect.width, SLICE_HEIGHT);
+ } else if (isThreadSlice) {
+ // We draw two rectangles, representing the ratio between wall time and
+ // time spent on cpu.
+ const cpuTimeRatio = data.cpuTimeRatio![i];
+ const firstPartWidth = rect.width * cpuTimeRatio;
+ const secondPartWidth = rect.width * (1 - cpuTimeRatio);
+ ctx.fillRect(rect.left, rect.top, firstPartWidth, SLICE_HEIGHT);
+ ctx.fillStyle = hsluvToHex(
+ hslForThreadIdleSlice(hue, saturation, lightness, hasFocus));
+ ctx.fillRect(
+ rect.left + firstPartWidth,
+ rect.top,
+ secondPartWidth,
+ SLICE_HEIGHT);
} else {
ctx.fillRect(rect.left, rect.top, rect.width, SLICE_HEIGHT);
}
+
// Selected case
if (isSelected) {
drawRectOnSelected = () => {
@@ -220,18 +236,19 @@ export class ChromeSliceTrack extends Track<Config, Data> {
onMouseMove({x, y}: {x: number, y: number}) {
this.hoveredTitleId = -1;
- globals.frontendLocalState.setHighlightedSliceId(-1);
+ globals.dispatch(Actions.setHighlightedSliceId({sliceId: -1}));
const sliceIndex = this.getSliceIndex({x, y});
if (sliceIndex === undefined) return;
const data = this.data();
if (data === undefined) return;
this.hoveredTitleId = data.titles[sliceIndex];
- globals.frontendLocalState.setHighlightedSliceId(data.sliceIds[sliceIndex]);
+ const sliceId = data.sliceIds[sliceIndex];
+ globals.dispatch(Actions.setHighlightedSliceId({sliceId}));
}
onMouseOut() {
this.hoveredTitleId = -1;
- globals.frontendLocalState.setHighlightedSliceId(-1);
+ globals.dispatch(Actions.setHighlightedSliceId({sliceId: -1}));
}
onMouseClick({x, y}: {x: number, y: number}): boolean {
diff --git a/ui/src/tracks/chrome_slices/index.ts b/ui/src/tracks/chrome_slices/index.ts
new file mode 100644
index 000000000..308406efb
--- /dev/null
+++ b/ui/src/tracks/chrome_slices/index.ts
@@ -0,0 +1,16 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import './controller';
+import './frontend';
diff --git a/ui/src/tracks/counter/controller.ts b/ui/src/tracks/counter/controller.ts
index 22dffe26e..016a9e79a 100644
--- a/ui/src/tracks/counter/controller.ts
+++ b/ui/src/tracks/counter/controller.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {iter, NUM, slowlyCountRows} from '../../common/query_iterator';
+import {NUM, NUM_NULL} from '../../common/query_result';
import {fromNs, toNs} from '../../common/time';
import {
TrackController,
@@ -76,29 +76,29 @@ class CounterTrackController extends TrackController<Config, Data> {
select
max(
iif(dur != -1, dur, (select end_ts from trace_bounds) - ts)
- )
+ ) as maxDur
from ${this.tableName('counter_view')}
`);
- if (slowlyCountRows(maxDurResult) === 1) {
- this.maxDurNs = maxDurResult.columns[0].longValues![0];
- }
+ this.maxDurNs = maxDurResult.firstRow({maxDur: NUM_NULL}).maxDur || 0;
- const result = await this.query(`
+ const queryRes = await this.query(`
select
- max(value) as maxValue,
- min(value) as minValue,
- max(delta) as maxDelta,
- min(delta) as minDelta
+ ifnull(max(value), 0) as maxValue,
+ ifnull(min(value), 0) as minValue,
+ ifnull(max(delta), 0) as maxDelta,
+ ifnull(min(delta), 0) as minDelta
from ${this.tableName('counter_view')}`);
- this.maximumValueSeen = +result.columns[0].doubleValues![0];
- this.minimumValueSeen = +result.columns[1].doubleValues![0];
- this.maximumDeltaSeen = +result.columns[2].doubleValues![0];
- this.minimumDeltaSeen = +result.columns[3].doubleValues![0];
+ const row = queryRes.firstRow(
+ {maxValue: NUM, minValue: NUM, maxDelta: NUM, minDelta: NUM});
+ this.maximumValueSeen = row.maxValue;
+ this.minimumValueSeen = row.minValue;
+ this.maximumDeltaSeen = row.maxDelta;
+ this.minimumDeltaSeen = row.minDelta;
this.setup = true;
}
- const rawResult = await this.query(`
+ const queryRes = await this.query(`
select
(ts + ${bucketNs / 2}) / ${bucketNs} * ${bucketNs} as tsq,
min(value) as minValue,
@@ -112,7 +112,7 @@ class CounterTrackController extends TrackController<Config, Data> {
order by tsq
`);
- const numRows = slowlyCountRows(rawResult);
+ const numRows = queryRes.numRows();
const data: Data = {
start,
@@ -131,25 +131,22 @@ class CounterTrackController extends TrackController<Config, Data> {
totalDeltas: new Float64Array(numRows),
};
- const it = iter(
- {
- 'tsq': NUM,
- 'lastId': NUM,
- 'minValue': NUM,
- 'maxValue': NUM,
- 'lastValue': NUM,
- 'totalDelta': NUM,
- },
- rawResult);
- for (let i = 0; it.valid(); ++i, it.next()) {
- data.timestamps[i] = fromNs(it.row.tsq);
- data.lastIds[i] = it.row.lastId;
- data.minValues[i] = it.row.minValue;
- data.maxValues[i] = it.row.maxValue;
- data.lastValues[i] = it.row.lastValue;
- data.totalDeltas[i] = it.row.totalDelta;
+ const it = queryRes.iter({
+ 'tsq': NUM,
+ 'lastId': NUM,
+ 'minValue': NUM,
+ 'maxValue': NUM,
+ 'lastValue': NUM,
+ 'totalDelta': NUM,
+ });
+ for (let row = 0; it.valid(); it.next(), row++) {
+ data.timestamps[row] = fromNs(it.tsq);
+ data.lastIds[row] = it.lastId;
+ data.minValues[row] = it.minValue;
+ data.maxValues[row] = it.maxValue;
+ data.lastValues[row] = it.lastValue;
+ data.totalDeltas[row] = it.totalDelta;
}
-
return data;
}
diff --git a/ui/src/tracks/counter/frontend.ts b/ui/src/tracks/counter/frontend.ts
index 186b1e1da..45908a680 100644
--- a/ui/src/tracks/counter/frontend.ts
+++ b/ui/src/tracks/counter/frontend.ts
@@ -17,11 +17,10 @@ import * as m from 'mithril';
import {searchSegment} from '../../base/binary_search';
import {assertTrue} from '../../base/logging';
import {Actions} from '../../common/actions';
-import {TrackState} from '../../common/state';
import {toNs} from '../../common/time';
import {checkerboardExcept} from '../../frontend/checkerboard';
import {globals} from '../../frontend/globals';
-import {Track} from '../../frontend/track';
+import {NewTrackArgs, Track} from '../../frontend/track';
import {TrackButton, TrackButtonAttrs} from '../../frontend/track_panel';
import {trackRegistry} from '../../frontend/track_registry';
@@ -81,17 +80,17 @@ function getCounterScaleAttribute(scale?: CounterScaleOptions):
class CounterTrack extends Track<Config, Data> {
static readonly kind = COUNTER_TRACK_KIND;
- static create(trackState: TrackState): CounterTrack {
- return new CounterTrack(trackState);
+ static create(args: NewTrackArgs): CounterTrack {
+ return new CounterTrack(args);
}
- private mouseXpos = 0;
+ private mousePos = {x: 0, y: 0};
private hoveredValue: number|undefined = undefined;
private hoveredTs: number|undefined = undefined;
private hoveredTsEnd: number|undefined = undefined;
- constructor(trackState: TrackState) {
- super(trackState);
+ constructor(args: NewTrackArgs) {
+ super(args);
}
getHeight() {
@@ -262,7 +261,7 @@ class CounterTrack extends Track<Config, Data> {
ctx.stroke();
// Draw the tooltip.
- this.drawTrackHoverTooltip(ctx, this.mouseXpos, text);
+ this.drawTrackHoverTooltip(ctx, this.mousePos, text);
}
// Write the Y scale on the top left corner.
@@ -297,12 +296,12 @@ class CounterTrack extends Track<Config, Data> {
timeScale.timeToPx(data.end));
}
- onMouseMove({x}: {x: number, y: number}) {
+ onMouseMove(pos: {x: number, y: number}) {
const data = this.data();
if (data === undefined) return;
- this.mouseXpos = x;
+ this.mousePos = pos;
const {timeScale} = globals.frontendLocalState;
- const time = timeScale.pxToTime(x);
+ const time = timeScale.pxToTime(pos.x);
const values = this.config.scale === 'DELTA_FROM_PREVIOUS' ?
data.totalDeltas :
diff --git a/ui/src/tracks/counter/index.ts b/ui/src/tracks/counter/index.ts
new file mode 100644
index 000000000..308406efb
--- /dev/null
+++ b/ui/src/tracks/counter/index.ts
@@ -0,0 +1,16 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import './controller';
+import './frontend';
diff --git a/ui/src/tracks/cpu_freq/controller.ts b/ui/src/tracks/cpu_freq/controller.ts
index 08ca0b563..d5a29de7d 100644
--- a/ui/src/tracks/cpu_freq/controller.ts
+++ b/ui/src/tracks/cpu_freq/controller.ts
@@ -13,8 +13,7 @@
// limitations under the License.
import {assertTrue} from '../../base/logging';
-import {RawQueryResult} from '../../common/protos';
-import {iter, NUM, slowlyCountRows} from '../../common/query_iterator';
+import {NUM, NUM_NULL, QueryResult} from '../../common/query_result';
import {fromNs, toNs} from '../../common/time';
import {
TrackController,
@@ -41,30 +40,37 @@ class CpuFreqTrackController extends TrackController<Config, Data> {
this.maximumValueSeen = await this.queryMaxFrequency();
this.maxDurNs = await this.queryMaxSourceDur();
- const result = await this.query(`
- select max(ts), dur, count(1)
+ const iter = (await this.query(`
+ select max(ts) as maxTs, dur, count(1) as rowCount
from ${this.tableName('freq_idle')}
- `);
- this.maxTsEndNs =
- result.columns[0].longValues![0] + result.columns[1].longValues![0];
+ `)).firstRow({maxTs: NUM_NULL, dur: NUM_NULL, rowCount: NUM});
+ if (iter.maxTs === null || iter.dur === null) {
+ // We shoulnd't really hit this because trackDecider shouldn't create
+ // the track in the first place if there are no entries. But could happen
+ // if only one cpu has no cpufreq data.
+ return;
+ }
+ this.maxTsEndNs = iter.maxTs + iter.dur;
- const rowCount = result.columns[2].longValues![0];
+ const rowCount = iter.rowCount;
const bucketNs = this.cachedBucketSizeNs(rowCount);
if (bucketNs === undefined) {
return;
}
+
await this.query(`
create table ${this.tableName('freq_idle_cached')} as
select
- (ts + ${bucketNs / 2}) / ${bucketNs} * ${bucketNs} as cached_tsq,
- min(freq_value) as min_freq,
- max(freq_value) as max_freq,
- value_at_max_ts(ts, freq_value) as last_freq,
- value_at_max_ts(ts, idle_value) as last_idle_value
+ (ts + ${bucketNs / 2}) / ${bucketNs} * ${bucketNs} as cachedTsq,
+ min(freqValue) as minFreq,
+ max(freqValue) as maxFreq,
+ value_at_max_ts(ts, freqValue) as lastFreq,
+ value_at_max_ts(ts, idleValue) as lastIdleValue
from ${this.tableName('freq_idle')}
- group by cached_tsq
- order by cached_tsq
+ group by cachedTsq
+ order by cachedTsq
`);
+
this.cachedBucketNs = bucketNs;
}
@@ -82,10 +88,10 @@ class CpuFreqTrackController extends TrackController<Config, Data> {
// be an even number, so we can snap in the middle.
const bucketNs =
Math.max(Math.round(resolutionNs * this.pxSize() / 2) * 2, 1);
-
const freqResult = await this.queryData(startNs, endNs, bucketNs);
+ assertTrue(freqResult.isComplete());
- const numRows = slowlyCountRows(freqResult);
+ const numRows = freqResult.numRows();
const data: Data = {
start,
end,
@@ -100,68 +106,68 @@ class CpuFreqTrackController extends TrackController<Config, Data> {
lastIdleValues: new Int8Array(numRows),
};
- const it = iter(
- {
- 'tsq': NUM,
- 'minFreq': NUM,
- 'maxFreq': NUM,
- 'lastFreq': NUM,
- 'lastIdleValue': NUM,
- },
- freqResult);
+ const it = freqResult.iter({
+ 'tsq': NUM,
+ 'minFreq': NUM,
+ 'maxFreq': NUM,
+ 'lastFreq': NUM,
+ 'lastIdleValue': NUM,
+ });
for (let i = 0; it.valid(); ++i, it.next()) {
- data.timestamps[i] = fromNs(it.row.tsq);
- data.minFreqKHz[i] = it.row.minFreq;
- data.maxFreqKHz[i] = it.row.maxFreq;
- data.lastFreqKHz[i] = it.row.lastFreq;
- data.lastIdleValues[i] = it.row.lastIdleValue;
+ data.timestamps[i] = fromNs(it.tsq);
+ data.minFreqKHz[i] = it.minFreq;
+ data.maxFreqKHz[i] = it.maxFreq;
+ data.lastFreqKHz[i] = it.lastFreq;
+ data.lastIdleValues[i] = it.lastIdleValue;
}
+
return data;
}
private async queryData(startNs: number, endNs: number, bucketNs: number):
- Promise<RawQueryResult> {
+ Promise<QueryResult> {
const isCached = this.cachedBucketNs <= bucketNs;
if (isCached) {
return this.query(`
select
- cached_tsq / ${bucketNs} * ${bucketNs} as tsq,
- min(min_freq) as minFreq,
- max(max_freq) as maxFreq,
- value_at_max_ts(cached_tsq, last_freq) as lastFreq,
- value_at_max_ts(cached_tsq, last_idle_value) as lastIdleValue
+ cachedTsq / ${bucketNs} * ${bucketNs} as tsq,
+ min(minFreq) as minFreq,
+ max(maxFreq) as maxFreq,
+ value_at_max_ts(cachedTsq, lastFreq) as lastFreq,
+ value_at_max_ts(cachedTsq, lastIdleValue) as lastIdleValue
from ${this.tableName('freq_idle_cached')}
where
- cached_tsq >= ${startNs - this.maxDurNs} and
- cached_tsq <= ${endNs}
+ cachedTsq >= ${startNs - this.maxDurNs} and
+ cachedTsq <= ${endNs}
group by tsq
order by tsq
`);
}
-
const minTsFreq = await this.query(`
- select ifnull(max(ts), 0) from ${this.tableName('freq')}
+ select ifnull(max(ts), 0) as minTs from ${this.tableName('freq')}
where ts < ${startNs}
`);
- let minTs = minTsFreq.columns[0].longValues![0];
+
+ let minTs = minTsFreq.iter({minTs: NUM}).minTs;
if (this.config.idleTrackId !== undefined) {
const minTsIdle = await this.query(`
- select ifnull(max(ts), 0) from ${this.tableName('idle')}
+ select ifnull(max(ts), 0) as minTs from ${this.tableName('idle')}
where ts < ${startNs}
`);
- minTs = Math.min(minTsIdle.columns[0].longValues![0], minTs);
+ minTs = Math.min(minTsIdle.iter({minTs: NUM}).minTs, minTs);
}
+
const geqConstraint = this.config.idleTrackId === undefined ?
`ts >= ${minTs}` :
`source_geq(ts, ${minTs})`;
return this.query(`
select
(ts + ${bucketNs / 2}) / ${bucketNs} * ${bucketNs} as tsq,
- min(freq_value) as minFreq,
- max(freq_value) as maxFreq,
- value_at_max_ts(ts, freq_value) as lastFreq,
- value_at_max_ts(ts, idle_value) as lastIdleValue
+ min(freqValue) as minFreq,
+ max(freqValue) as maxFreq,
+ value_at_max_ts(ts, freqValue) as lastFreq,
+ value_at_max_ts(ts, idleValue) as lastIdleValue
from ${this.tableName('freq_idle')}
where
${geqConstraint} and
@@ -173,23 +179,23 @@ class CpuFreqTrackController extends TrackController<Config, Data> {
private async queryMaxFrequency(): Promise<number> {
const result = await this.query(`
- select max(freq_value)
+ select max(freqValue) as maxFreq
from ${this.tableName('freq')}
`);
- return result.columns[0].doubleValues![0];
+ return result.firstRow({'maxFreq': NUM_NULL}).maxFreq || 0;
}
private async queryMaxSourceDur(): Promise<number> {
- const maxDurFreqResult =
- await this.query(`select max(dur) from ${this.tableName('freq')}`);
- const maxFreqDurNs = maxDurFreqResult.columns[0].longValues![0];
+ const maxDurFreqResult = await this.query(
+ `select ifnull(max(dur), 0) as maxDur from ${this.tableName('freq')}`);
+ const maxDurNs = maxDurFreqResult.firstRow({'maxDur': NUM}).maxDur;
if (this.config.idleTrackId === undefined) {
- return maxFreqDurNs;
+ return maxDurNs;
}
- const maxDurIdleResult =
- await this.query(`select max(dur) from ${this.tableName('idle')}`);
- return Math.max(maxFreqDurNs, maxDurIdleResult.columns[0].longValues![0]);
+ const maxDurIdleResult = await this.query(
+ `select ifnull(max(dur), 0) as maxDur from ${this.tableName('idle')}`);
+ return Math.max(maxDurNs, maxDurIdleResult.firstRow({maxDur: NUM}).maxDur);
}
private async createFreqIdleViews() {
@@ -197,7 +203,7 @@ class CpuFreqTrackController extends TrackController<Config, Data> {
select
ts,
dur,
- value as freq_value
+ value as freqValue
from experimental_counter_dur c
where track_id = ${this.config.freqTrackId};
`);
@@ -207,8 +213,8 @@ class CpuFreqTrackController extends TrackController<Config, Data> {
select
ts,
dur,
- -1 as idle_value,
- freq_value
+ -1 as idleValue,
+ freqValue
from ${this.tableName('freq')};
`);
return;
@@ -219,7 +225,7 @@ class CpuFreqTrackController extends TrackController<Config, Data> {
select
ts,
dur,
- iif(value = 4294967295, -1, cast(value as int)) as idle_value
+ iif(value = 4294967295, -1, cast(value as int)) as idleValue
from experimental_counter_dur c
where track_id = ${this.config.idleTrackId};
`);
diff --git a/ui/src/tracks/cpu_freq/frontend.ts b/ui/src/tracks/cpu_freq/frontend.ts
index 4e5c9e49e..c8b2d7484 100644
--- a/ui/src/tracks/cpu_freq/frontend.ts
+++ b/ui/src/tracks/cpu_freq/frontend.ts
@@ -15,10 +15,9 @@
import {searchSegment} from '../../base/binary_search';
import {assertTrue} from '../../base/logging';
import {hueForCpu} from '../../common/colorizer';
-import {TrackState} from '../../common/state';
import {checkerboardExcept} from '../../frontend/checkerboard';
import {globals} from '../../frontend/globals';
-import {Track} from '../../frontend/track';
+import {NewTrackArgs, Track} from '../../frontend/track';
import {trackRegistry} from '../../frontend/track_registry';
import {
@@ -33,18 +32,18 @@ const RECT_HEIGHT = 20;
class CpuFreqTrack extends Track<Config, Data> {
static readonly kind = CPU_FREQ_TRACK_KIND;
- static create(trackState: TrackState): CpuFreqTrack {
- return new CpuFreqTrack(trackState);
+ static create(args: NewTrackArgs): CpuFreqTrack {
+ return new CpuFreqTrack(args);
}
- private mouseXpos = 0;
+ private mousePos = {x: 0, y: 0};
private hoveredValue: number|undefined = undefined;
private hoveredTs: number|undefined = undefined;
private hoveredTsEnd: number|undefined = undefined;
private hoveredIdle: number|undefined = undefined;
- constructor(trackState: TrackState) {
- super(trackState);
+ constructor(args: NewTrackArgs) {
+ super(args);
}
getHeight() {
@@ -83,7 +82,7 @@ class CpuFreqTrack extends Track<Config, Data> {
// Draw the CPU frequency graph.
const hue = hueForCpu(this.config.cpu);
let saturation = 45;
- if (globals.frontendLocalState.hoveredUtid !== -1) {
+ if (globals.state.hoveredUtid !== -1) {
saturation = 0;
}
ctx.fillStyle = `hsl(${hue}, ${saturation}%, 70%)`;
@@ -193,7 +192,7 @@ class CpuFreqTrack extends Track<Config, Data> {
}
// Draw the tooltip.
- this.drawTrackHoverTooltip(ctx, this.mouseXpos, text);
+ this.drawTrackHoverTooltip(ctx, this.mousePos, text);
}
// Write the Y scale on the top left corner.
@@ -215,12 +214,12 @@ class CpuFreqTrack extends Track<Config, Data> {
timeScale.timeToPx(data.end));
}
- onMouseMove({x}: {x: number, y: number}) {
+ onMouseMove(pos: {x: number, y: number}) {
const data = this.data();
if (data === undefined) return;
- this.mouseXpos = x;
+ this.mousePos = pos;
const {timeScale} = globals.frontendLocalState;
- const time = timeScale.pxToTime(x);
+ const time = timeScale.pxToTime(pos.x);
const [left, right] = searchSegment(data.timestamps, time);
this.hoveredTs = left === -1 ? undefined : data.timestamps[left];
diff --git a/ui/src/tracks/cpu_freq/index.ts b/ui/src/tracks/cpu_freq/index.ts
new file mode 100644
index 000000000..308406efb
--- /dev/null
+++ b/ui/src/tracks/cpu_freq/index.ts
@@ -0,0 +1,16 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import './controller';
+import './frontend';
diff --git a/ui/src/tracks/cpu_profile/controller.ts b/ui/src/tracks/cpu_profile/controller.ts
index 070cedba9..4e68e5f0b 100644
--- a/ui/src/tracks/cpu_profile/controller.ts
+++ b/ui/src/tracks/cpu_profile/controller.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {slowlyCountRows} from '../../common/query_iterator';
+import {NUM} from '../../common/query_result';
import {
TrackController,
trackControllerRegistry
@@ -28,13 +28,16 @@ class CpuProfileTrackController extends TrackController<Config, Data> {
static readonly kind = CPU_PROFILE_TRACK_KIND;
async onBoundsChange(start: number, end: number, resolution: number):
Promise<Data> {
- const query = `select id, ts, callsite_id from cpu_profile_stack_sample
- where utid = ${this.config.utid}
- order by ts`;
+ const query = `select
+ id,
+ ts,
+ callsite_id as callsiteId
+ from cpu_profile_stack_sample
+ where utid = ${this.config.utid}
+ order by ts`;
const result = await this.query(query);
-
- const numRows = slowlyCountRows(result);
+ const numRows = result.numRows();
const data: Data = {
start,
end,
@@ -45,10 +48,11 @@ class CpuProfileTrackController extends TrackController<Config, Data> {
callsiteId: new Uint32Array(numRows),
};
- for (let row = 0; row < numRows; row++) {
- data.ids[row] = +result.columns[0].longValues![row];
- data.tsStarts[row] = +result.columns[1].longValues![row];
- data.callsiteId[row] = +result.columns[2].longValues![row];
+ const it = result.iter({id: NUM, ts: NUM, callsiteId: NUM});
+ for (let row = 0; it.valid(); it.next(), ++row) {
+ data.ids[row] = it.id;
+ data.tsStarts[row] = it.ts;
+ data.callsiteId[row] = it.callsiteId;
}
return data;
diff --git a/ui/src/tracks/cpu_profile/frontend.ts b/ui/src/tracks/cpu_profile/frontend.ts
index f0cc6afae..cbaabb10d 100644
--- a/ui/src/tracks/cpu_profile/frontend.ts
+++ b/ui/src/tracks/cpu_profile/frontend.ts
@@ -17,15 +17,15 @@ import {hsluvToHex} from 'hsluv';
import {searchSegment} from '../../base/binary_search';
import {Actions} from '../../common/actions';
import {hslForSlice} from '../../common/colorizer';
-import {TrackState} from '../../common/state';
import {fromNs, toNs} from '../../common/time';
import {globals} from '../../frontend/globals';
import {TimeScale} from '../../frontend/time_scale';
-import {Track} from '../../frontend/track';
+import {NewTrackArgs, Track} from '../../frontend/track';
import {trackRegistry} from '../../frontend/track_registry';
import {Config, CPU_PROFILE_TRACK_KIND, Data} from './common';
+const BAR_HEIGHT = 3;
const MARGIN_TOP = 4.5;
const RECT_HEIGHT = 30.5;
@@ -35,16 +35,16 @@ function colorForSample(callsiteId: number, isHovered: boolean): string {
class CpuProfileTrack extends Track<Config, Data> {
static readonly kind = CPU_PROFILE_TRACK_KIND;
- static create(trackState: TrackState): CpuProfileTrack {
- return new CpuProfileTrack(trackState);
+ static create(args: NewTrackArgs): CpuProfileTrack {
+ return new CpuProfileTrack(args);
}
- private centerY = this.getHeight() / 2;
- private markerWidth = (this.getHeight() - MARGIN_TOP) / 2;
+ private centerY = this.getHeight() / 2 + BAR_HEIGHT;
+ private markerWidth = (this.getHeight() - MARGIN_TOP - BAR_HEIGHT) / 2;
private hoveredTs: number|undefined = undefined;
- constructor(trackState: TrackState) {
- super(trackState);
+ constructor(args: NewTrackArgs) {
+ super(args);
}
getHeight() {
@@ -74,6 +74,26 @@ class CpuProfileTrack extends Track<Config, Data> {
strokeWidth,
data.callsiteId[i]);
}
+
+ let startX = data.tsStarts.length ? data.tsStarts[0] : -1;
+ let endX = data.tsStarts.length ? data.tsStarts[0] : -1;
+ let lastCallsiteId = data.callsiteId.length ? data.callsiteId[0] : -1;
+ for (let i = 0; i < data.tsStarts.length; i++) {
+ const centerX = data.tsStarts[i];
+ const callsiteId = data.callsiteId[i];
+ if (lastCallsiteId !== callsiteId) {
+ if (startX !== endX) {
+ const leftPx = timeScale.timeToPx(fromNs(startX)) - this.markerWidth;
+ const rightPx = timeScale.timeToPx(fromNs(endX)) + this.markerWidth;
+ const width = rightPx - leftPx;
+ ctx.fillStyle = colorForSample(lastCallsiteId, false);
+ ctx.fillRect(leftPx, MARGIN_TOP, width, BAR_HEIGHT);
+ }
+ startX = centerX;
+ }
+ endX = centerX;
+ lastCallsiteId = callsiteId;
+ }
}
drawMarker(
diff --git a/ui/src/tracks/cpu_profile/index.ts b/ui/src/tracks/cpu_profile/index.ts
new file mode 100644
index 000000000..308406efb
--- /dev/null
+++ b/ui/src/tracks/cpu_profile/index.ts
@@ -0,0 +1,16 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import './controller';
+import './frontend';
diff --git a/ui/src/tracks/cpu_slices/controller.ts b/ui/src/tracks/cpu_slices/controller.ts
index 1389cb44a..9dc89bf61 100644
--- a/ui/src/tracks/cpu_slices/controller.ts
+++ b/ui/src/tracks/cpu_slices/controller.ts
@@ -13,7 +13,7 @@
// limitations under the License.
import {assertTrue} from '../../base/logging';
-import {slowlyCountRows} from '../../common/query_iterator';
+import {NUM} from '../../common/query_result';
import {fromNs, toNs} from '../../common/time';
import {
TrackController,
@@ -40,13 +40,13 @@ class CpuSliceTrackController extends TrackController<Config, Data> {
where cpu = ${this.config.cpu} and utid != 0
`);
- const rawResult = await this.query(`
- select max(dur), count(1)
+ const queryRes = await this.query(`
+ select ifnull(max(dur), 0) as maxDur, count(1) as rowCount
from ${this.tableName('sched')}
`);
- this.maxDurNs = rawResult.columns[0].longValues![0];
-
- const rowCount = rawResult.columns[1].longValues![0];
+ const row = queryRes.firstRow({maxDur: NUM, rowCount: NUM});
+ this.maxDurNs = row.maxDur;
+ const rowCount = row.rowCount;
const bucketNs = this.cachedBucketSizeNs(rowCount);
if (bucketNs === undefined) {
return;
@@ -88,9 +88,9 @@ class CpuSliceTrackController extends TrackController<Config, Data> {
`(ts + ${bucketNs / 2}) / ${bucketNs} * ${bucketNs}`;
const queryTable =
isCached ? this.tableName('sched_cached') : this.tableName('sched');
- const constainColumn = isCached ? 'cached_tsq' : 'ts';
+ const constraintColumn = isCached ? 'cached_tsq' : 'ts';
- const rawResult = await this.query(`
+ const queryRes = await this.query(`
select
${queryTsq} as tsq,
ts,
@@ -99,13 +99,13 @@ class CpuSliceTrackController extends TrackController<Config, Data> {
id
from ${queryTable}
where
- ${constainColumn} >= ${startNs - this.maxDurNs} and
- ${constainColumn} <= ${endNs}
+ ${constraintColumn} >= ${startNs - this.maxDurNs} and
+ ${constraintColumn} <= ${endNs}
group by tsq
order by tsq
`);
- const numRows = slowlyCountRows(rawResult);
+ const numRows = queryRes.numRows();
const slices: Data = {
start,
end,
@@ -117,24 +117,20 @@ class CpuSliceTrackController extends TrackController<Config, Data> {
utids: new Uint32Array(numRows),
};
- const cols = rawResult.columns;
- for (let row = 0; row < numRows; row++) {
- const startNsQ = +cols[0].longValues![row];
- const startNs = +cols[1].longValues![row];
- const durNs = +cols[2].longValues![row];
+ const it = queryRes.iter({tsq: NUM, ts: NUM, dur: NUM, utid: NUM, id: NUM});
+ for (let row = 0; it.valid(); it.next(), row++) {
+ const startNsQ = it.tsq;
+ const startNs = it.ts;
+ const durNs = it.dur;
const endNs = startNs + durNs;
let endNsQ = Math.floor((endNs + bucketNs / 2 - 1) / bucketNs) * bucketNs;
endNsQ = Math.max(endNsQ, startNsQ + bucketNs);
- if (startNsQ === endNsQ) {
- throw new Error('Should never happen');
- }
-
slices.starts[row] = fromNs(startNsQ);
slices.ends[row] = fromNs(endNsQ);
- slices.utids[row] = +cols[3].longValues![row];
- slices.ids[row] = +cols[4].longValues![row];
+ slices.utids[row] = it.utid;
+ slices.ids[row] = it.id;
}
return slices;
diff --git a/ui/src/tracks/cpu_slices/frontend.ts b/ui/src/tracks/cpu_slices/frontend.ts
index b6ca8d78e..16f140c4f 100644
--- a/ui/src/tracks/cpu_slices/frontend.ts
+++ b/ui/src/tracks/cpu_slices/frontend.ts
@@ -17,11 +17,10 @@ import {assertTrue} from '../../base/logging';
import {Actions} from '../../common/actions';
import {cropText, drawDoubleHeadedArrow} from '../../common/canvas_utils';
import {colorForThread} from '../../common/colorizer';
-import {TrackState} from '../../common/state';
import {timeToString} from '../../common/time';
import {checkerboardExcept} from '../../frontend/checkerboard';
import {globals} from '../../frontend/globals';
-import {Track} from '../../frontend/track';
+import {NewTrackArgs, Track} from '../../frontend/track';
import {trackRegistry} from '../../frontend/track_registry';
import {
@@ -36,15 +35,15 @@ const TRACK_HEIGHT = MARGIN_TOP * 2 + RECT_HEIGHT;
class CpuSliceTrack extends Track<Config, Data> {
static readonly kind = CPU_SLICE_TRACK_KIND;
- static create(trackState: TrackState): CpuSliceTrack {
- return new CpuSliceTrack(trackState);
+ static create(args: NewTrackArgs): CpuSliceTrack {
+ return new CpuSliceTrack(args);
}
- private mouseXpos?: number;
+ private mousePos?: {x: number, y: number};
private utidHoveredInThisTrack = -1;
- constructor(trackState: TrackState) {
- super(trackState);
+ constructor(args: NewTrackArgs) {
+ super(args);
}
getHeight(): number {
@@ -99,9 +98,9 @@ class CpuSliceTrack extends Track<Config, Data> {
const threadInfo = globals.threads.get(utid);
const pid = threadInfo && threadInfo.pid ? threadInfo.pid : -1;
- const isHovering = globals.frontendLocalState.hoveredUtid !== -1;
- const isThreadHovered = globals.frontendLocalState.hoveredUtid === utid;
- const isProcessHovered = globals.frontendLocalState.hoveredPid === pid;
+ const isHovering = globals.state.hoveredUtid !== -1;
+ const isThreadHovered = globals.state.hoveredUtid === utid;
+ const isProcessHovered = globals.state.hoveredPid === pid;
const color = colorForThread(threadInfo);
if (isHovering && !isThreadHovered) {
if (!isProcessHovered) {
@@ -212,28 +211,28 @@ class CpuSliceTrack extends Track<Config, Data> {
}
const hoveredThread = globals.threads.get(this.utidHoveredInThisTrack);
- if (hoveredThread !== undefined && this.mouseXpos !== undefined) {
+ if (hoveredThread !== undefined && this.mousePos !== undefined) {
const tidText = `T: ${hoveredThread.threadName} [${hoveredThread.tid}]`;
if (hoveredThread.pid) {
const pidText = `P: ${hoveredThread.procName} [${hoveredThread.pid}]`;
- this.drawTrackHoverTooltip(ctx, this.mouseXpos, pidText, tidText);
+ this.drawTrackHoverTooltip(ctx, this.mousePos, pidText, tidText);
} else {
- this.drawTrackHoverTooltip(ctx, this.mouseXpos, tidText);
+ this.drawTrackHoverTooltip(ctx, this.mousePos, tidText);
}
}
}
- onMouseMove({x, y}: {x: number, y: number}) {
+ onMouseMove(pos: {x: number, y: number}) {
const data = this.data();
- this.mouseXpos = x;
+ this.mousePos = pos;
if (data === undefined) return;
const {timeScale} = globals.frontendLocalState;
- if (y < MARGIN_TOP || y > MARGIN_TOP + RECT_HEIGHT) {
+ if (pos.y < MARGIN_TOP || pos.y > MARGIN_TOP + RECT_HEIGHT) {
this.utidHoveredInThisTrack = -1;
- globals.frontendLocalState.setHoveredUtidAndPid(-1, -1);
+ globals.dispatch(Actions.setHoveredUtidAndPid({utid: -1, pid: -1}));
return;
}
- const t = timeScale.pxToTime(x);
+ const t = timeScale.pxToTime(pos.x);
let hoveredUtid = -1;
for (let i = 0; i < data.starts.length; i++) {
@@ -248,13 +247,14 @@ class CpuSliceTrack extends Track<Config, Data> {
this.utidHoveredInThisTrack = hoveredUtid;
const threadInfo = globals.threads.get(hoveredUtid);
const hoveredPid = threadInfo ? (threadInfo.pid ? threadInfo.pid : -1) : -1;
- globals.frontendLocalState.setHoveredUtidAndPid(hoveredUtid, hoveredPid);
+ globals.dispatch(
+ Actions.setHoveredUtidAndPid({utid: hoveredUtid, pid: hoveredPid}));
}
onMouseOut() {
this.utidHoveredInThisTrack = -1;
- globals.frontendLocalState.setHoveredUtidAndPid(-1, -1);
- this.mouseXpos = 0;
+ globals.dispatch(Actions.setHoveredUtidAndPid({utid: -1, pid: -1}));
+ this.mousePos = undefined;
}
onMouseClick({x}: {x: number}) {
diff --git a/ui/src/tracks/cpu_slices/index.ts b/ui/src/tracks/cpu_slices/index.ts
new file mode 100644
index 000000000..308406efb
--- /dev/null
+++ b/ui/src/tracks/cpu_slices/index.ts
@@ -0,0 +1,16 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import './controller';
+import './frontend';
diff --git a/ui/src/tracks/debug_slices/controller.ts b/ui/src/tracks/debug_slices/controller.ts
index 0afcb5513..0b761a3e8 100644
--- a/ui/src/tracks/debug_slices/controller.ts
+++ b/ui/src/tracks/debug_slices/controller.ts
@@ -12,9 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {assertTrue} from '../../base/logging';
import {Actions} from '../../common/actions';
-import {slowlyCountRows} from '../../common/query_iterator';
+import {NUM, NUM_NULL, STR} from '../../common/query_result';
import {fromNs, toNs} from '../../common/time';
import {globals} from '../../controller/globals';
import {
@@ -28,28 +27,26 @@ class DebugSliceTrackController extends TrackController<Config, Data> {
static readonly kind = DEBUG_SLICE_TRACK_KIND;
async onReload() {
- const rawResult = await this.query(`select max(depth) from debug_slices`);
- const maxDepth = (slowlyCountRows(rawResult) === 0) ?
- 1 :
- rawResult.columns[0].longValues![0];
+ const rawResult = await this.query(
+ `select ifnull(max(depth), 1) as maxDepth from debug_slices`);
+ const maxDepth = rawResult.firstRow({maxDepth: NUM}).maxDepth;
globals.dispatch(
Actions.updateTrackConfig({id: this.trackId, config: {maxDepth}}));
}
async onBoundsChange(start: number, end: number, resolution: number):
Promise<Data> {
- const rawResult = await this.query(`select id, name, ts,
- iif(dur = -1, (SELECT end_ts FROM trace_bounds) - ts, dur),
- depth from debug_slices where
- (ts + dur) >= ${toNs(start)} and ts <= ${toNs(end)}`);
+ const queryRes = await this.query(`select
+ ifnull(id, -1) as id,
+ ifnull(name, '[null]') as name,
+ ts,
+ iif(dur = -1, (SELECT end_ts FROM trace_bounds) - ts, dur) as dur,
+ ifnull(depth, 0) as depth
+ from debug_slices
+ where (ts + dur) >= ${toNs(start)} and ts <= ${toNs(end)}`);
- assertTrue(rawResult.columns.length === 5);
- const [idCol, nameCol, tsCol, durCol, depthCol] = rawResult.columns;
- const idValues = idCol.longValues! || idCol.doubleValues!;
- const tsValues = tsCol.longValues! || tsCol.doubleValues!;
- const durValues = durCol.longValues! || durCol.doubleValues!;
+ const numRows = queryRes.numRows();
- const numRows = slowlyCountRows(rawResult);
const slices: Data = {
start,
end,
@@ -75,24 +72,24 @@ class DebugSliceTrackController extends TrackController<Config, Data> {
return idx;
}
- for (let i = 0; i < slowlyCountRows(rawResult); i++) {
+ const it = queryRes.iter(
+ {id: NUM, name: STR, ts: NUM_NULL, dur: NUM_NULL, depth: NUM});
+ for (let row = 0; it.valid(); it.next(), row++) {
let sliceStart: number, sliceEnd: number;
- if (tsCol.isNulls![i] || durCol.isNulls![i]) {
+ if (it.ts === null || it.dur === null) {
sliceStart = sliceEnd = -1;
} else {
- sliceStart = tsValues[i];
- const sliceDur = durValues[i];
- sliceEnd = sliceStart + sliceDur;
+ sliceStart = it.ts;
+ sliceEnd = sliceStart + it.dur;
}
- slices.sliceIds[i] = idCol.isNulls![i] ? -1 : idValues[i];
- slices.starts[i] = fromNs(sliceStart);
- slices.ends[i] = fromNs(sliceEnd);
- slices.depths[i] = depthCol.isNulls![i] ? 0 : depthCol.longValues![i];
- const sliceName =
- nameCol.isNulls![i] ? '[null]' : nameCol.stringValues![i];
- slices.titles[i] = internString(sliceName);
- slices.isInstant[i] = 0;
- slices.isIncomplete[i] = 0;
+ slices.sliceIds[row] = it.id;
+ slices.starts[row] = fromNs(sliceStart);
+ slices.ends[row] = fromNs(sliceEnd);
+ slices.depths[row] = it.depth;
+ const sliceName = it.name;
+ slices.titles[row] = internString(sliceName);
+ slices.isInstant[row] = 0;
+ slices.isIncomplete[row] = 0;
}
return slices;
diff --git a/ui/src/tracks/debug_slices/frontend.ts b/ui/src/tracks/debug_slices/frontend.ts
index bdda433bc..5f20beea9 100644
--- a/ui/src/tracks/debug_slices/frontend.ts
+++ b/ui/src/tracks/debug_slices/frontend.ts
@@ -15,9 +15,8 @@
import * as m from 'mithril';
import {Actions} from '../../common/actions';
-import {TrackState} from '../../common/state';
import {globals} from '../../frontend/globals';
-import {Track} from '../../frontend/track';
+import {NewTrackArgs, Track} from '../../frontend/track';
import {TrackButton, TrackButtonAttrs} from '../../frontend/track_panel';
import {trackRegistry} from '../../frontend/track_registry';
import {ChromeSliceTrack} from '../chrome_slices/frontend';
@@ -26,8 +25,8 @@ import {DEBUG_SLICE_TRACK_KIND} from './common';
export class DebugSliceTrack extends ChromeSliceTrack {
static readonly kind = DEBUG_SLICE_TRACK_KIND;
- static create(trackState: TrackState): Track {
- return new DebugSliceTrack(trackState);
+ static create(args: NewTrackArgs): Track {
+ return new DebugSliceTrack(args);
}
getTrackShellButtons(): Array<m.Vnode<TrackButtonAttrs>> {
diff --git a/ui/src/tracks/debug_slices/index.ts b/ui/src/tracks/debug_slices/index.ts
new file mode 100644
index 000000000..308406efb
--- /dev/null
+++ b/ui/src/tracks/debug_slices/index.ts
@@ -0,0 +1,16 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import './controller';
+import './frontend';
diff --git a/ui/src/tracks/expected_frames/controller.ts b/ui/src/tracks/expected_frames/controller.ts
index 532eaa081..3265c98bb 100644
--- a/ui/src/tracks/expected_frames/controller.ts
+++ b/ui/src/tracks/expected_frames/controller.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {slowlyCountRows} from '../../common/query_iterator';
+import {NUM, NUM_NULL, STR} from '../../common/query_result';
import {fromNs, toNs} from '../../common/time';
import {
TrackController,
@@ -39,24 +39,23 @@ class ExpectedFramesSliceTrackController extends TrackController<Config, Data> {
if (this.maxDurNs === 0) {
const maxDurResult = await this.query(`
select max(iif(dur = -1, (SELECT end_ts FROM trace_bounds) - ts, dur))
+ as maxDur
from experimental_slice_layout
where filter_track_ids = '${this.config.trackIds.join(',')}'
`);
- if (slowlyCountRows(maxDurResult) === 1) {
- this.maxDurNs = maxDurResult.columns[0].longValues![0];
- }
+ this.maxDurNs = maxDurResult.firstRow({maxDur: NUM_NULL}).maxDur || 0;
}
- const rawResult = await this.query(`
+ const queryRes = await this.query(`
SELECT
(ts + ${bucketNs / 2}) / ${bucketNs} * ${bucketNs} as tsq,
ts,
max(iif(dur = -1, (SELECT end_ts FROM trace_bounds) - ts, dur)) as dur,
- layout_depth,
+ layout_depth as layoutDepth,
name,
id,
- dur = 0 as is_instant,
- dur = -1 as is_incomplete
+ dur = 0 as isInstant,
+ dur = -1 as isIncomplete
from experimental_slice_layout
where
filter_track_ids = '${this.config.trackIds.join(',')}' and
@@ -66,7 +65,7 @@ class ExpectedFramesSliceTrackController extends TrackController<Config, Data> {
order by tsq, layout_depth
`);
- const numRows = slowlyCountRows(rawResult);
+ const numRows = queryRes.numRows();
const slices: Data = {
start,
end,
@@ -94,27 +93,32 @@ class ExpectedFramesSliceTrackController extends TrackController<Config, Data> {
}
const greenIndex = internString('#4CAF50');
- const cols = rawResult.columns;
- for (let row = 0; row < numRows; row++) {
- const startNsQ = +cols[0].longValues![row];
- const startNs = +cols[1].longValues![row];
- const durNs = +cols[2].longValues![row];
+ const it = queryRes.iter({
+ tsq: NUM,
+ ts: NUM,
+ dur: NUM,
+ layoutDepth: NUM,
+ id: NUM,
+ name: STR,
+ isInstant: NUM,
+ isIncomplete: NUM,
+ });
+ for (let row = 0; it.valid(); it.next(), ++row) {
+ const startNsQ = it.tsq;
+ const startNs = it.ts;
+ const durNs = it.dur;
const endNs = startNs + durNs;
let endNsQ = Math.floor((endNs + bucketNs / 2 - 1) / bucketNs) * bucketNs;
endNsQ = Math.max(endNsQ, startNsQ + bucketNs);
- if (startNsQ === endNsQ) {
- throw new Error('Should never happen');
- }
-
slices.starts[row] = fromNs(startNsQ);
slices.ends[row] = fromNs(endNsQ);
- slices.depths[row] = +cols[3].longValues![row];
- slices.titles[row] = internString(cols[4].stringValues![row]);
- slices.sliceIds[row] = +cols[5].longValues![row];
- slices.isInstant[row] = +cols[6].longValues![row];
- slices.isIncomplete[row] = +cols[7].longValues![row];
+ slices.depths[row] = it.layoutDepth;
+ slices.titles[row] = internString(it.name);
+ slices.sliceIds[row] = it.id;
+ slices.isInstant[row] = it.isInstant;
+ slices.isIncomplete[row] = it.isIncomplete;
slices.colors![row] = greenIndex;
}
return slices;
diff --git a/ui/src/tracks/expected_frames/frontend.ts b/ui/src/tracks/expected_frames/frontend.ts
index 441f0983f..219a017a4 100644
--- a/ui/src/tracks/expected_frames/frontend.ts
+++ b/ui/src/tracks/expected_frames/frontend.ts
@@ -11,8 +11,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {TrackState} from '../../common/state';
-import {Track} from '../../frontend/track';
+import {NewTrackArgs, Track} from '../../frontend/track';
import {trackRegistry} from '../../frontend/track_registry';
import {ChromeSliceTrack} from '../chrome_slices/frontend';
@@ -20,8 +19,8 @@ import {EXPECTED_FRAMES_SLICE_TRACK_KIND} from './common';
export class ExpectedFramesSliceTrack extends ChromeSliceTrack {
static readonly kind = EXPECTED_FRAMES_SLICE_TRACK_KIND;
- static create(trackState: TrackState): Track {
- return new ExpectedFramesSliceTrack(trackState);
+ static create(args: NewTrackArgs): Track {
+ return new ExpectedFramesSliceTrack(args);
}
}
diff --git a/ui/src/tracks/expected_frames/index.ts b/ui/src/tracks/expected_frames/index.ts
new file mode 100644
index 000000000..308406efb
--- /dev/null
+++ b/ui/src/tracks/expected_frames/index.ts
@@ -0,0 +1,16 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import './controller';
+import './frontend';
diff --git a/ui/src/tracks/generic_slice_track/index.ts b/ui/src/tracks/generic_slice_track/index.ts
new file mode 100644
index 000000000..aaff6ff75
--- /dev/null
+++ b/ui/src/tracks/generic_slice_track/index.ts
@@ -0,0 +1,48 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {
+ NamedSliceTrack,
+ NamedSliceTrackTypes
+} from '../../frontend/named_slice_track';
+import {NewTrackArgs} from '../../frontend/track';
+import {trackRegistry} from '../../frontend/track_registry';
+
+export interface GenericSliceTrackConfig {
+ sqlTrackId: number;
+}
+
+export interface GenericSliceTrackTypes extends NamedSliceTrackTypes {
+ config: GenericSliceTrackConfig;
+}
+
+export class GenericSliceTrack extends NamedSliceTrack<GenericSliceTrackTypes> {
+ static readonly kind = 'GenericSliceTrack';
+ static create(args: NewTrackArgs) {
+ return new GenericSliceTrack(args);
+ }
+
+ constructor(args: NewTrackArgs) {
+ super(args);
+ }
+
+ async initSqlTable(tableName: string): Promise<void> {
+ const sql = `create view ${tableName} as
+ select ts, dur, id, depth, ifnull(name, '') as name
+ from slice where track_id = ${this.config.sqlTrackId}`;
+ await this.engine.query(sql);
+ }
+}
+
+trackRegistry.register(GenericSliceTrack);
diff --git a/ui/src/tracks/heap_profile/controller.ts b/ui/src/tracks/heap_profile/controller.ts
index 2422af101..a79dc3df6 100644
--- a/ui/src/tracks/heap_profile/controller.ts
+++ b/ui/src/tracks/heap_profile/controller.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {slowlyCountRows} from '../../common/query_iterator';
+import {NUM, STR} from '../../common/query_result';
import {
TrackController,
trackControllerRegistry
@@ -38,7 +38,7 @@ class HeapProfileTrackController extends TrackController<Config, Data> {
types: new Array<string>()
};
}
- const result = await this.query(`
+ const queryRes = await this.query(`
select * from
(select distinct(ts) as ts, 'native' as type from heap_profile_allocation
where upid = ${this.config.upid}
@@ -46,7 +46,7 @@ class HeapProfileTrackController extends TrackController<Config, Data> {
select distinct(graph_sample_ts) as ts, 'graph' as type from
heap_graph_object
where upid = ${this.config.upid}) order by ts`);
- const numRows = slowlyCountRows(result);
+ const numRows = queryRes.numRows();
const data: Data = {
start,
end,
@@ -56,11 +56,11 @@ class HeapProfileTrackController extends TrackController<Config, Data> {
types: new Array<string>(numRows),
};
- for (let row = 0; row < numRows; row++) {
- data.tsStarts[row] = +result.columns[0].longValues![row];
- data.types[row] = result.columns[1].stringValues![row];
+ const it = queryRes.iter({ts: NUM, type: STR});
+ for (let row = 0; it.valid(); it.next(), row++) {
+ data.tsStarts[row] = it.ts;
+ data.types[row] = it.type;
}
-
return data;
}
}
diff --git a/ui/src/tracks/heap_profile/frontend.ts b/ui/src/tracks/heap_profile/frontend.ts
index c9c74667f..2b88f1324 100644
--- a/ui/src/tracks/heap_profile/frontend.ts
+++ b/ui/src/tracks/heap_profile/frontend.ts
@@ -14,12 +14,11 @@
import {searchSegment} from '../../base/binary_search';
import {Actions} from '../../common/actions';
-import {TrackState} from '../../common/state';
import {fromNs, toNs} from '../../common/time';
-import {HEAP_PROFILE_HOVERED_COLOR} from '../../frontend/flamegraph';
+import {FLAMEGRAPH_HOVERED_COLOR} from '../../frontend/flamegraph';
import {globals} from '../../frontend/globals';
import {TimeScale} from '../../frontend/time_scale';
-import {Track} from '../../frontend/track';
+import {NewTrackArgs, Track} from '../../frontend/track';
import {trackRegistry} from '../../frontend/track_registry';
import {Config, Data, HEAP_PROFILE_TRACK_KIND} from './common';
@@ -32,16 +31,16 @@ const RECT_HEIGHT = 30.5;
class HeapProfileTrack extends Track<Config, Data> {
static readonly kind = HEAP_PROFILE_TRACK_KIND;
- static create(trackState: TrackState): HeapProfileTrack {
- return new HeapProfileTrack(trackState);
+ static create(args: NewTrackArgs): HeapProfileTrack {
+ return new HeapProfileTrack(args);
}
private centerY = this.getHeight() / 2;
private markerWidth = (this.getHeight() - MARGIN_TOP) / 2;
private hoveredTs: number|undefined = undefined;
- constructor(trackState: TrackState) {
- super(trackState);
+ constructor(args: NewTrackArgs) {
+ super(args);
}
getHeight() {
@@ -82,10 +81,10 @@ class HeapProfileTrack extends Track<Config, Data> {
ctx.lineTo(x + this.markerWidth, y);
ctx.lineTo(x, y - this.markerWidth);
ctx.closePath();
- ctx.fillStyle = isHovered ? HEAP_PROFILE_HOVERED_COLOR : HEAP_PROFILE_COLOR;
+ ctx.fillStyle = isHovered ? FLAMEGRAPH_HOVERED_COLOR : HEAP_PROFILE_COLOR;
ctx.fill();
if (strokeWidth > 0) {
- ctx.strokeStyle = HEAP_PROFILE_HOVERED_COLOR;
+ ctx.strokeStyle = FLAMEGRAPH_HOVERED_COLOR;
ctx.lineWidth = strokeWidth;
ctx.stroke();
}
diff --git a/ui/src/tracks/heap_profile/index.ts b/ui/src/tracks/heap_profile/index.ts
new file mode 100644
index 000000000..308406efb
--- /dev/null
+++ b/ui/src/tracks/heap_profile/index.ts
@@ -0,0 +1,16 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import './controller';
+import './frontend';
diff --git a/ui/src/tracks/perf_samples_profile/common.ts b/ui/src/tracks/perf_samples_profile/common.ts
new file mode 100644
index 000000000..116944519
--- /dev/null
+++ b/ui/src/tracks/perf_samples_profile/common.ts
@@ -0,0 +1,24 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+import {TrackData} from '../../common/track_data';
+
+export const PERF_SAMPLES_PROFILE_TRACK_KIND = 'PerfSamplesProfileTrack';
+
+export interface Data extends TrackData {
+ tsStartsNs: Float64Array;
+}
+
+export interface Config {
+ upid: number;
+}
diff --git a/ui/src/tracks/perf_samples_profile/controller.ts b/ui/src/tracks/perf_samples_profile/controller.ts
new file mode 100644
index 000000000..5122d1586
--- /dev/null
+++ b/ui/src/tracks/perf_samples_profile/controller.ts
@@ -0,0 +1,62 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {NUM} from '../../common/query_result';
+import {
+ TrackController,
+ trackControllerRegistry
+} from '../../controller/track_controller';
+
+import {
+ Config,
+ Data,
+ PERF_SAMPLES_PROFILE_TRACK_KIND,
+} from './common';
+
+class PerfSamplesProfileTrackController extends TrackController<Config, Data> {
+ static readonly kind = PERF_SAMPLES_PROFILE_TRACK_KIND;
+ async onBoundsChange(start: number, end: number, resolution: number):
+ Promise<Data> {
+ if (this.config.upid === undefined) {
+ return {
+ start,
+ end,
+ resolution,
+ length: 0,
+ tsStartsNs: new Float64Array()
+ };
+ }
+ const queryRes = await this.query(`
+ select ts, upid from perf_sample
+ join thread using (utid)
+ where upid = ${this.config.upid}
+ order by ts`);
+ const numRows = queryRes.numRows();
+ const data: Data = {
+ start,
+ end,
+ resolution,
+ length: numRows,
+ tsStartsNs: new Float64Array(numRows)
+ };
+
+ const it = queryRes.iter({ts: NUM});
+ for (let row = 0; it.valid(); it.next(), row++) {
+ data.tsStartsNs[row] = it.ts;
+ }
+ return data;
+ }
+}
+
+trackControllerRegistry.register(PerfSamplesProfileTrackController);
diff --git a/ui/src/tracks/perf_samples_profile/frontend.ts b/ui/src/tracks/perf_samples_profile/frontend.ts
new file mode 100644
index 000000000..822e17d9c
--- /dev/null
+++ b/ui/src/tracks/perf_samples_profile/frontend.ts
@@ -0,0 +1,152 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {searchSegment} from '../../base/binary_search';
+import {Actions} from '../../common/actions';
+import {fromNs, toNs} from '../../common/time';
+import {FLAMEGRAPH_HOVERED_COLOR} from '../../frontend/flamegraph';
+import {globals} from '../../frontend/globals';
+import {TimeScale} from '../../frontend/time_scale';
+import {NewTrackArgs, Track} from '../../frontend/track';
+import {trackRegistry} from '../../frontend/track_registry';
+
+import {Config, Data, PERF_SAMPLES_PROFILE_TRACK_KIND} from './common';
+
+const PERP_SAMPLE_COLOR = 'hsl(224, 45%, 70%)';
+
+// 0.5 Makes the horizontal lines sharp.
+const MARGIN_TOP = 4.5;
+const RECT_HEIGHT = 30.5;
+
+class PerfSamplesProfileTrack extends Track<Config, Data> {
+ static readonly kind = PERF_SAMPLES_PROFILE_TRACK_KIND;
+ static create(args: NewTrackArgs): PerfSamplesProfileTrack {
+ return new PerfSamplesProfileTrack(args);
+ }
+
+ private centerY = this.getHeight() / 2;
+ private markerWidth = (this.getHeight() - MARGIN_TOP) / 2;
+ private hoveredTs: number|undefined = undefined;
+
+ constructor(args: NewTrackArgs) {
+ super(args);
+ }
+
+ getHeight() {
+ return MARGIN_TOP + RECT_HEIGHT - 1;
+ }
+
+ renderCanvas(ctx: CanvasRenderingContext2D): void {
+ const {
+ timeScale,
+ } = globals.frontendLocalState;
+ const data = this.data();
+
+ if (data === undefined) return;
+
+ for (let i = 0; i < data.tsStartsNs.length; i++) {
+ const centerX = data.tsStartsNs[i];
+ const selection = globals.state.currentSelection;
+ const isHovered = this.hoveredTs === centerX;
+ const isSelected = selection !== null &&
+ selection.kind === 'PERF_SAMPLES' && selection.ts === centerX;
+ const strokeWidth = isSelected ? 3 : 0;
+ this.drawMarker(
+ ctx,
+ timeScale.timeToPx(fromNs(centerX)),
+ this.centerY,
+ isHovered,
+ strokeWidth);
+ }
+ }
+
+ drawMarker(
+ ctx: CanvasRenderingContext2D, x: number, y: number, isHovered: boolean,
+ strokeWidth: number): void {
+ ctx.beginPath();
+ ctx.moveTo(x, y - this.markerWidth);
+ ctx.lineTo(x - this.markerWidth, y);
+ ctx.lineTo(x, y + this.markerWidth);
+ ctx.lineTo(x + this.markerWidth, y);
+ ctx.lineTo(x, y - this.markerWidth);
+ ctx.closePath();
+ ctx.fillStyle = isHovered ? FLAMEGRAPH_HOVERED_COLOR : PERP_SAMPLE_COLOR;
+ ctx.fill();
+ if (strokeWidth > 0) {
+ ctx.strokeStyle = FLAMEGRAPH_HOVERED_COLOR;
+ ctx.lineWidth = strokeWidth;
+ ctx.stroke();
+ }
+ }
+
+ onMouseMove({x, y}: {x: number, y: number}) {
+ const data = this.data();
+ if (data === undefined) return;
+ const {timeScale} = globals.frontendLocalState;
+ const time = toNs(timeScale.pxToTime(x));
+ const [left, right] = searchSegment(data.tsStartsNs, time);
+ const index = this.findTimestampIndex(left, timeScale, data, x, y, right);
+ this.hoveredTs = index === -1 ? undefined : data.tsStartsNs[index];
+ }
+
+ onMouseOut() {
+ this.hoveredTs = undefined;
+ }
+
+ onMouseClick({x, y}: {x: number, y: number}) {
+ const data = this.data();
+ if (data === undefined) return false;
+ const {timeScale} = globals.frontendLocalState;
+
+ const time = toNs(timeScale.pxToTime(x));
+ const [left, right] = searchSegment(data.tsStartsNs, time);
+
+ const index = this.findTimestampIndex(left, timeScale, data, x, y, right);
+
+ if (index !== -1) {
+ const ts = data.tsStartsNs[index];
+ globals.makeSelection(Actions.selectPerfSamples(
+ {id: index, upid: this.config.upid, ts, type: 'perf'}));
+ return true;
+ }
+ return false;
+ }
+
+ // If the markers overlap the rightmost one will be selected.
+ findTimestampIndex(
+ left: number, timeScale: TimeScale, data: Data, x: number, y: number,
+ right: number): number {
+ let index = -1;
+ if (left !== -1) {
+ const centerX = timeScale.timeToPx(fromNs(data.tsStartsNs[left]));
+ if (this.isInMarker(x, y, centerX)) {
+ index = left;
+ }
+ }
+ if (right !== -1) {
+ const centerX = timeScale.timeToPx(fromNs(data.tsStartsNs[right]));
+ if (this.isInMarker(x, y, centerX)) {
+ index = right;
+ }
+ }
+ return index;
+ }
+
+ isInMarker(x: number, y: number, centerX: number) {
+ return Math.abs(x - centerX) + Math.abs(y - this.centerY) <=
+ this.markerWidth;
+ }
+}
+
+trackRegistry.register(PerfSamplesProfileTrack);
diff --git a/ui/src/tracks/perf_samples_profile/index.ts b/ui/src/tracks/perf_samples_profile/index.ts
new file mode 100644
index 000000000..308406efb
--- /dev/null
+++ b/ui/src/tracks/perf_samples_profile/index.ts
@@ -0,0 +1,16 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import './controller';
+import './frontend';
diff --git a/ui/src/tracks/process_scheduling/controller.ts b/ui/src/tracks/process_scheduling/controller.ts
index c7676ed73..13ecee9f8 100644
--- a/ui/src/tracks/process_scheduling/controller.ts
+++ b/ui/src/tracks/process_scheduling/controller.ts
@@ -13,8 +13,7 @@
// limitations under the License.
import {assertTrue} from '../../base/logging';
-import {RawQueryResult} from '../../common/protos';
-import {slowlyCountRows} from '../../common/query_iterator';
+import {NUM, QueryResult} from '../../common/query_result';
import {fromNs, toNs} from '../../common/time';
import {
TrackController,
@@ -45,13 +44,14 @@ class ProcessSchedulingTrackController extends TrackController<Config, Data> {
assertTrue(cpus.length > 0);
this.maxCpu = Math.max(...cpus) + 1;
- const result = await this.query(`
- select max(dur), count(1)
+ const result = (await this.query(`
+ select ifnull(max(dur), 0) as maxDur, count(1) as count
from ${this.tableName('process_sched')}
- `);
- this.maxDurNs = result.columns[0].longValues![0];
+ `)).iter({maxDur: NUM, count: NUM});
+ assertTrue(result.valid());
+ this.maxDurNs = result.maxDur;
- const rowCount = result.columns[1].longValues![0];
+ const rowCount = result.count;
const bucketNs = this.cachedBucketSizeNs(rowCount);
if (bucketNs === undefined) {
return;
@@ -88,9 +88,8 @@ class ProcessSchedulingTrackController extends TrackController<Config, Data> {
const bucketNs =
Math.max(Math.round(resolutionNs * this.pxSize() / 2) * 2, 1);
- const rawResult = await this.queryData(startNs, endNs, bucketNs);
-
- const numRows = slowlyCountRows(rawResult);
+ const queryRes = await this.queryData(startNs, endNs, bucketNs);
+ const numRows = queryRes.numRows();
const slices: Data = {
kind: 'slice',
start,
@@ -104,37 +103,40 @@ class ProcessSchedulingTrackController extends TrackController<Config, Data> {
utids: new Uint32Array(numRows),
};
- const cols = rawResult.columns;
- for (let row = 0; row < numRows; row++) {
- const startNsQ = +cols[0].longValues![row];
- const startNs = +cols[1].longValues![row];
- const durNs = +cols[2].longValues![row];
+ const it = queryRes.iter({
+ tsq: NUM,
+ ts: NUM,
+ dur: NUM,
+ cpu: NUM,
+ utid: NUM,
+ });
+
+ for (let row = 0; it.valid(); it.next(), row++) {
+ const startNsQ = it.tsq;
+ const startNs = it.ts;
+ const durNs = it.dur;
const endNs = startNs + durNs;
let endNsQ = Math.floor((endNs + bucketNs / 2 - 1) / bucketNs) * bucketNs;
endNsQ = Math.max(endNsQ, startNsQ + bucketNs);
- if (startNsQ === endNsQ) {
- throw new Error('Should never happen');
- }
-
slices.starts[row] = fromNs(startNsQ);
slices.ends[row] = fromNs(endNsQ);
- slices.cpus[row] = +cols[3].longValues![row];
- slices.utids[row] = +cols[4].longValues![row];
+ slices.cpus[row] = it.cpu;
+ slices.utids[row] = it.utid;
slices.end = Math.max(slices.ends[row], slices.end);
}
return slices;
}
private queryData(startNs: number, endNs: number, bucketNs: number):
- Promise<RawQueryResult> {
+ Promise<QueryResult> {
const isCached = this.cachedBucketNs <= bucketNs;
const tsq = isCached ? `cached_tsq / ${bucketNs} * ${bucketNs}` :
`(ts + ${bucketNs / 2}) / ${bucketNs} * ${bucketNs}`;
const queryTable = isCached ? this.tableName('process_sched_cached') :
this.tableName('process_sched');
- const constainColumn = isCached ? 'cached_tsq' : 'ts';
+ const constraintColumn = isCached ? 'cached_tsq' : 'ts';
return this.query(`
select
${tsq} as tsq,
@@ -144,8 +146,8 @@ class ProcessSchedulingTrackController extends TrackController<Config, Data> {
utid
from ${queryTable}
where
- ${constainColumn} >= ${startNs - this.maxDurNs} and
- ${constainColumn} <= ${endNs}
+ ${constraintColumn} >= ${startNs - this.maxDurNs} and
+ ${constraintColumn} <= ${endNs}
group by tsq, cpu
order by tsq, cpu
`);
diff --git a/ui/src/tracks/process_scheduling/frontend.ts b/ui/src/tracks/process_scheduling/frontend.ts
index e7c4eb135..b83b12891 100644
--- a/ui/src/tracks/process_scheduling/frontend.ts
+++ b/ui/src/tracks/process_scheduling/frontend.ts
@@ -14,11 +14,11 @@
import {searchEq, searchRange, searchSegment} from '../../base/binary_search';
import {assertTrue} from '../../base/logging';
+import {Actions} from '../../common/actions';
import {colorForThread} from '../../common/colorizer';
-import {TrackState} from '../../common/state';
import {checkerboardExcept} from '../../frontend/checkerboard';
import {globals} from '../../frontend/globals';
-import {Track} from '../../frontend/track';
+import {NewTrackArgs, Track} from '../../frontend/track';
import {trackRegistry} from '../../frontend/track_registry';
import {
@@ -33,15 +33,15 @@ const TRACK_HEIGHT = MARGIN_TOP * 2 + RECT_HEIGHT;
class ProcessSchedulingTrack extends Track<Config, Data> {
static readonly kind = PROCESS_SCHEDULING_TRACK_KIND;
- static create(trackState: TrackState): ProcessSchedulingTrack {
- return new ProcessSchedulingTrack(trackState);
+ static create(args: NewTrackArgs): ProcessSchedulingTrack {
+ return new ProcessSchedulingTrack(args);
}
- private mouseXpos?: number;
+ private mousePos?: {x: number, y: number};
private utidHoveredInThisTrack = -1;
- constructor(trackState: TrackState) {
- super(trackState);
+ constructor(args: NewTrackArgs) {
+ super(args);
}
getHeight(): number {
@@ -91,9 +91,9 @@ class ProcessSchedulingTrack extends Track<Config, Data> {
const threadInfo = globals.threads.get(utid);
const pid = (threadInfo ? threadInfo.pid : -1) || -1;
- const isHovering = globals.frontendLocalState.hoveredUtid !== -1;
- const isThreadHovered = globals.frontendLocalState.hoveredUtid === utid;
- const isProcessHovered = globals.frontendLocalState.hoveredPid === pid;
+ const isHovering = globals.state.hoveredUtid !== -1;
+ const isThreadHovered = globals.state.hoveredUtid === utid;
+ const isProcessHovered = globals.state.hoveredPid === pid;
const color = colorForThread(threadInfo);
if (isHovering && !isThreadHovered) {
if (!isProcessHovered) {
@@ -113,37 +113,36 @@ class ProcessSchedulingTrack extends Track<Config, Data> {
}
const hoveredThread = globals.threads.get(this.utidHoveredInThisTrack);
- if (hoveredThread !== undefined && this.mouseXpos !== undefined) {
+ if (hoveredThread !== undefined && this.mousePos !== undefined) {
const tidText = `T: ${hoveredThread.threadName} [${hoveredThread.tid}]`;
if (hoveredThread.pid) {
const pidText = `P: ${hoveredThread.procName} [${hoveredThread.pid}]`;
- this.drawTrackHoverTooltip(ctx, this.mouseXpos, pidText, tidText);
+ this.drawTrackHoverTooltip(ctx, this.mousePos, pidText, tidText);
} else {
- this.drawTrackHoverTooltip(ctx, this.mouseXpos, tidText);
+ this.drawTrackHoverTooltip(ctx, this.mousePos, tidText);
}
}
}
-
- onMouseMove({x, y}: {x: number, y: number}) {
+ onMouseMove(pos: {x: number, y: number}) {
const data = this.data();
- this.mouseXpos = x;
+ this.mousePos = pos;
if (data === undefined) return;
- if (y < MARGIN_TOP || y > MARGIN_TOP + RECT_HEIGHT) {
+ if (pos.y < MARGIN_TOP || pos.y > MARGIN_TOP + RECT_HEIGHT) {
this.utidHoveredInThisTrack = -1;
- globals.frontendLocalState.setHoveredUtidAndPid(-1, -1);
+ globals.dispatch(Actions.setHoveredUtidAndPid({utid: -1, pid: -1}));
return;
}
const cpuTrackHeight = Math.floor(RECT_HEIGHT / data.maxCpu);
- const cpu = Math.floor((y - MARGIN_TOP) / (cpuTrackHeight + 1));
+ const cpu = Math.floor((pos.y - MARGIN_TOP) / (cpuTrackHeight + 1));
const {timeScale} = globals.frontendLocalState;
- const t = timeScale.pxToTime(x);
+ const t = timeScale.pxToTime(pos.x);
const [i, j] = searchRange(data.starts, t, searchEq(data.cpus, cpu));
if (i === j || i >= data.starts.length || t > data.ends[i]) {
this.utidHoveredInThisTrack = -1;
- globals.frontendLocalState.setHoveredUtidAndPid(-1, -1);
+ globals.dispatch(Actions.setHoveredUtidAndPid({utid: -1, pid: -1}));
return;
}
@@ -151,13 +150,13 @@ class ProcessSchedulingTrack extends Track<Config, Data> {
this.utidHoveredInThisTrack = utid;
const threadInfo = globals.threads.get(utid);
const pid = threadInfo ? (threadInfo.pid ? threadInfo.pid : -1) : -1;
- globals.frontendLocalState.setHoveredUtidAndPid(utid, pid);
+ globals.dispatch(Actions.setHoveredUtidAndPid({utid, pid}));
}
onMouseOut() {
this.utidHoveredInThisTrack = -1;
- globals.frontendLocalState.setHoveredUtidAndPid(-1, -1);
- this.mouseXpos = 0;
+ globals.dispatch(Actions.setHoveredUtidAndPid({utid: -1, pid: -1}));
+ this.mousePos = undefined;
}
}
diff --git a/ui/src/tracks/process_scheduling/index.ts b/ui/src/tracks/process_scheduling/index.ts
new file mode 100644
index 000000000..308406efb
--- /dev/null
+++ b/ui/src/tracks/process_scheduling/index.ts
@@ -0,0 +1,16 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import './controller';
+import './frontend';
diff --git a/ui/src/tracks/process_summary/controller.ts b/ui/src/tracks/process_summary/controller.ts
index 75242fe15..8241562f2 100644
--- a/ui/src/tracks/process_summary/controller.ts
+++ b/ui/src/tracks/process_summary/controller.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {slowlyCountRows} from '../../common/query_iterator';
+import {NUM} from '../../common/query_result';
import {fromNs, toNs} from '../../common/time';
import {LIMIT} from '../../common/track_data';
import {
@@ -46,12 +46,18 @@ class ProcessSummaryTrackController extends TrackController<Config, Data> {
if (this.config.upid) {
const threadQuery = await this.query(
`select utid from thread where upid=${this.config.upid}`);
- utids = threadQuery.columns[0].longValues!;
+ utids = [];
+ for (const it = threadQuery.iter({utid: NUM}); it.valid(); it.next()) {
+ utids.push(it.utid);
+ }
}
const trackQuery = await this.query(
`select id from thread_track where utid in (${utids.join(',')})`);
- const tracks = trackQuery.columns[0].longValues!;
+ const tracks = [];
+ for (const it = trackQuery.iter({id: NUM}); it.valid(); it.next()) {
+ tracks.push(it.id);
+ }
const processSliceView = this.tableName('process_slice_view');
await this.query(
@@ -73,7 +79,7 @@ class ProcessSummaryTrackController extends TrackController<Config, Data> {
const windowStartNs = Math.floor(startNs / bucketSizeNs) * bucketSizeNs;
const windowDurNs = Math.max(1, endNs - windowStartNs);
- this.query(`update ${this.tableName('window')} set
+ await this.query(`update ${this.tableName('window')} set
window_start=${windowStartNs},
window_dur=${windowDurNs},
quantum=${bucketSizeNs}
@@ -98,9 +104,6 @@ class ProcessSummaryTrackController extends TrackController<Config, Data> {
group by quantum_ts
limit ${LIMIT}`;
- const rawResult = await this.query(query);
- const numRows = slowlyCountRows(rawResult);
-
const summary: Data = {
start,
end,
@@ -109,14 +112,17 @@ class ProcessSummaryTrackController extends TrackController<Config, Data> {
bucketSizeSeconds: fromNs(bucketSizeNs),
utilizations: new Float64Array(numBuckets),
};
- const cols = rawResult.columns;
- for (let row = 0; row < numRows; row++) {
- const bucket = +cols[0].longValues![row];
+
+ const queryRes = await this.query(query);
+ const it = queryRes.iter({bucket: NUM, utilization: NUM});
+ for (; it.valid(); it.next()) {
+ const bucket = it.bucket;
if (bucket > numBuckets) {
continue;
}
- summary.utilizations[bucket] = +cols[1].doubleValues![row];
+ summary.utilizations[bucket] = it.utilization;
}
+
return summary;
}
diff --git a/ui/src/tracks/process_summary/frontend.ts b/ui/src/tracks/process_summary/frontend.ts
index 0a259cac2..b6d10f590 100644
--- a/ui/src/tracks/process_summary/frontend.ts
+++ b/ui/src/tracks/process_summary/frontend.ts
@@ -13,10 +13,9 @@
// limitations under the License.
import {colorForTid} from '../../common/colorizer';
-import {TrackState} from '../../common/state';
import {checkerboardExcept} from '../../frontend/checkerboard';
import {globals} from '../../frontend/globals';
-import {Track} from '../../frontend/track';
+import {NewTrackArgs, Track} from '../../frontend/track';
import {trackRegistry} from '../../frontend/track_registry';
import {
@@ -32,12 +31,12 @@ const SUMMARY_HEIGHT = TRACK_HEIGHT - MARGIN_TOP;
class ProcessSummaryTrack extends Track<Config, Data> {
static readonly kind = PROCESS_SUMMARY_TRACK;
- static create(trackState: TrackState): ProcessSummaryTrack {
- return new ProcessSummaryTrack(trackState);
+ static create(args: NewTrackArgs): ProcessSummaryTrack {
+ return new ProcessSummaryTrack(args);
}
- constructor(trackState: TrackState) {
- super(trackState);
+ constructor(args: NewTrackArgs) {
+ super(args);
}
getHeight(): number {
diff --git a/ui/src/tracks/process_summary/index.ts b/ui/src/tracks/process_summary/index.ts
new file mode 100644
index 000000000..308406efb
--- /dev/null
+++ b/ui/src/tracks/process_summary/index.ts
@@ -0,0 +1,16 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import './controller';
+import './frontend';
diff --git a/ui/src/tracks/thread_state/controller.ts b/ui/src/tracks/thread_state/controller.ts
index a4718c68f..da8ff02be 100644
--- a/ui/src/tracks/thread_state/controller.ts
+++ b/ui/src/tracks/thread_state/controller.ts
@@ -13,13 +13,7 @@
// limitations under the License.
import {assertFalse} from '../../base/logging';
-import {
- iter,
- NUM,
- NUM_NULL,
- slowlyCountRows,
- STR_NULL
-} from '../../common/query_iterator';
+import {NUM, NUM_NULL, STR_NULL} from '../../common/query_result';
import {translateState} from '../../common/thread_state';
import {fromNs, toNs} from '../../common/time';
import {
@@ -47,16 +41,16 @@ class ThreadStateTrackController extends TrackController<Config, Data> {
dur,
cpu,
state,
- io_wait
+ io_wait as ioWait
from thread_state
where utid = ${this.config.utid} and utid != 0
`);
- const rawResult = await this.query(`
- select max(dur)
+ const queryRes = await this.query(`
+ select ifnull(max(dur), 0) as maxDur
from ${this.tableName('thread_state')}
`);
- this.maxDurNs = rawResult.columns[0].longValues![0];
+ this.maxDurNs = queryRes.firstRow({maxDur: NUM}).maxDur;
}
async onBoundsChange(start: number, end: number, resolution: number):
@@ -74,21 +68,22 @@ class ThreadStateTrackController extends TrackController<Config, Data> {
select
(ts + ${bucketNs / 2}) / ${bucketNs} * ${bucketNs} as tsq,
ts,
+ state = 'S' as is_sleep,
max(dur) as dur,
- cast(cpu as integer) as cpu,
+ ifnull(cast(cpu as integer), -1) as cpu,
state,
- io_wait,
- id
+ ioWait,
+ ifnull(id, -1) as id
from ${this.tableName('thread_state')}
where
ts >= ${startNs - this.maxDurNs} and
ts <= ${endNs}
- group by tsq, state, io_wait
- order by tsq, state, io_wait
+ group by tsq, is_sleep
+ order by tsq
`;
- const result = await this.query(query);
- const numRows = slowlyCountRows(result);
+ const queryRes = await this.query(query);
+ const numRows = queryRes.numRows();
const data: Data = {
start,
@@ -103,9 +98,11 @@ class ThreadStateTrackController extends TrackController<Config, Data> {
cpu: new Int8Array(numRows),
};
- const stringIndexes =
- new Map<{shortState: string, ioWait: boolean | undefined}, number>();
- function internState(shortState: string, ioWait: boolean|undefined) {
+ const stringIndexes = new Map<
+ {shortState: string | undefined; ioWait: boolean | undefined},
+ number>();
+ function internState(
+ shortState: string|undefined, ioWait: boolean|undefined) {
let idx = stringIndexes.get({shortState, ioWait});
if (idx !== undefined) return idx;
idx = data.strings.length;
@@ -113,31 +110,28 @@ class ThreadStateTrackController extends TrackController<Config, Data> {
stringIndexes.set({shortState, ioWait}, idx);
return idx;
}
- iter(
- {
- 'ts': NUM,
- 'dur': NUM,
- 'cpu': NUM_NULL,
- 'state': STR_NULL,
- 'io_wait': NUM_NULL,
- 'id': NUM_NULL,
- },
- result);
- for (let row = 0; row < numRows; row++) {
- const cols = result.columns;
- const startNsQ = +cols[0].longValues![row];
- const startNs = +cols[1].longValues![row];
- const durNs = +cols[2].longValues![row];
+ const it = queryRes.iter({
+ 'tsq': NUM,
+ 'ts': NUM,
+ 'dur': NUM,
+ 'cpu': NUM,
+ 'state': STR_NULL,
+ 'ioWait': NUM_NULL,
+ 'id': NUM,
+ });
+ for (let row = 0; it.valid(); it.next(), row++) {
+ const startNsQ = it.tsq;
+ const startNs = it.ts;
+ const durNs = it.dur;
const endNs = startNs + durNs;
let endNsQ = Math.floor((endNs + bucketNs / 2 - 1) / bucketNs) * bucketNs;
endNsQ = Math.max(endNsQ, startNsQ + bucketNs);
- const cpu = cols[3].isNulls![row] ? -1 : cols[3].longValues![row];
- const state = cols[4].stringValues![row];
- const ioWait =
- cols[5].isNulls![row] ? undefined : !!cols[5].longValues![row];
- const id = cols[6].isNulls![row] ? -1 : cols[6].longValues![row];
+ const cpu = it.cpu;
+ const state = it.state || undefined;
+ const ioWait = it.ioWait === null ? undefined : !!it.ioWait;
+ const id = it.id;
// We should never have the end timestamp being the same as the bucket
// start.
@@ -153,7 +147,7 @@ class ThreadStateTrackController extends TrackController<Config, Data> {
}
async onDestroy() {
- await this.query(`drop table if exists ${this.tableName('thread_state')}`);
+ await this.query(`drop view if exists ${this.tableName('thread_state')}`);
}
}
diff --git a/ui/src/tracks/thread_state/frontend.ts b/ui/src/tracks/thread_state/frontend.ts
index 038301099..937258882 100644
--- a/ui/src/tracks/thread_state/frontend.ts
+++ b/ui/src/tracks/thread_state/frontend.ts
@@ -16,10 +16,9 @@ import {search} from '../../base/binary_search';
import {Actions} from '../../common/actions';
import {cropText} from '../../common/canvas_utils';
import {colorForState} from '../../common/colorizer';
-import {TrackState} from '../../common/state';
import {checkerboardExcept} from '../../frontend/checkerboard';
import {globals} from '../../frontend/globals';
-import {Track} from '../../frontend/track';
+import {NewTrackArgs, Track} from '../../frontend/track';
import {trackRegistry} from '../../frontend/track_registry';
import {
@@ -34,12 +33,12 @@ const EXCESS_WIDTH = 10;
class ThreadStateTrack extends Track<Config, Data> {
static readonly kind = THREAD_STATE_TRACK_KIND;
- static create(trackState: TrackState): ThreadStateTrack {
- return new ThreadStateTrack(trackState);
+ static create(args: NewTrackArgs): ThreadStateTrack {
+ return new ThreadStateTrack(args);
}
- constructor(trackState: TrackState) {
- super(trackState);
+ constructor(args: NewTrackArgs) {
+ super(args);
}
getHeight(): number {
@@ -70,6 +69,14 @@ class ThreadStateTrack extends Track<Config, Data> {
ctx.font = '10px Roboto Condensed';
for (let i = 0; i < data.starts.length; i++) {
+ // NOTE: Unlike userspace and scheduling slices, thread state slices are
+ // allowed to overlap; specifically, sleeping slices are allowed to
+ // overlap with non-sleeping slices. We do this because otherwise
+ // sleeping slices generally dominate traces making it seem like there are
+ // no running/runnable etc. slices until you zoom in. By drawing both,
+ // we get a more accurate representation of the trace and prevent weird
+ // artifacts when zooming.
+ // See b/201793731 for an example of why we do this.
const tStart = data.starts[i];
const tEnd = data.ends[i];
const state = data.strings[data.state[i]];
@@ -81,6 +88,7 @@ class ThreadStateTrack extends Track<Config, Data> {
if (state === 'x') continue;
const rectStart = timeScale.timeToPx(tStart);
const rectEnd = timeScale.timeToPx(tEnd);
+ const rectWidth = rectEnd - rectStart;
const currentSelection = globals.state.currentSelection;
const isSelected = currentSelection &&
@@ -95,7 +103,6 @@ class ThreadStateTrack extends Track<Config, Data> {
}
ctx.fillStyle = colorStr;
- const rectWidth = rectEnd - rectStart;
ctx.fillRect(rectStart, MARGIN_TOP, rectWidth, RECT_HEIGHT);
// Don't render text when we have less than 10px to play with.
diff --git a/ui/src/tracks/thread_state/index.ts b/ui/src/tracks/thread_state/index.ts
new file mode 100644
index 000000000..308406efb
--- /dev/null
+++ b/ui/src/tracks/thread_state/index.ts
@@ -0,0 +1,16 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import './controller';
+import './frontend';
diff --git a/ui/tsconfig.base.json b/ui/tsconfig.base.json
index 075b1b39c..cd522457d 100644
--- a/ui/tsconfig.base.json
+++ b/ui/tsconfig.base.json
@@ -8,6 +8,7 @@
"allowJs": true,
"declaration": false, // Generates corresponding '.d.ts' file.
"sourceMap": true, // Generates corresponding '.map' file.
+ "inlineSources": true, // Adds source code to the '.map' file.
"removeComments": false, // Do not emit comments to output.
"importHelpers": true, // Import emit helpers from 'tslib'.
"downlevelIteration": true, // Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'.